diff --git a/tryton/__init__.py b/tryton/__init__.py index 130a69ece8..f7f7ce27cc 100644 --- a/tryton/__init__.py +++ b/tryton/__init__.py @@ -96,8 +96,6 @@ def get_active_text(self): return model[active][index] Gtk.ComboBox.get_active_text = get_active_text -Gtk.GenericCellRenderer.__gobject_init__ = Gtk.GenericCellRenderer.__init__ - from gi.repository import Pango diff --git a/tryton/common/cellrendererbinary.py b/tryton/common/cellrendererbinary.py index ec37bb355e..b7b3bdff0b 100644 --- a/tryton/common/cellrendererbinary.py +++ b/tryton/common/cellrendererbinary.py @@ -1,8 +1,6 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. -import gtk -import gobject -import pango +from gi.repository import Gtk, Gdk, GObject, Pango from .common import IconFactory @@ -10,31 +8,31 @@ BUTTON_BORDER = 2 BUTTON_SPACING = 1 -class CellRendererBinary(gtk.GenericCellRenderer): +class CellRendererBinary(Gtk.CellRenderer): __gproperties__ = { - 'visible': (gobject.TYPE_BOOLEAN, 'Visible', 'Visible', True, - gobject.ParamFlags.READWRITE), - 'editable': (gobject.TYPE_BOOLEAN, 'Editable', 'Editable', False, - gobject.ParamFlags.READWRITE), - 'size': (gobject.TYPE_STRING, 'Size', 'Size', '', - gobject.ParamFlags.READWRITE), - } + 'visible': (GObject.TYPE_BOOLEAN, 'Visible', 'Visible', True, + GObject.ParamFlags.READWRITE), + 'editable': (GObject.TYPE_BOOLEAN, 'Editable', 'Editable', False, + GObject.ParamFlags.READWRITE), + 'size': (GObject.TYPE_STRING, 'Size', 'Size', '', + GObject.ParamFlags.READWRITE), + } __gsignals__ = { - 'select': (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_STRING,)), - 'open': (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_STRING,)), - 'save': (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_STRING,)), - 'clear': (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_STRING,)), - } + 'select': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_NONE, + (GObject.TYPE_STRING,)), + 'open': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_NONE, + (GObject.TYPE_STRING,)), + 'save': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_NONE, + (GObject.TYPE_STRING,)), + 'clear': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_NONE, + (GObject.TYPE_STRING,)), + } def __init__(self, use_filename): - self.__gobject_init__() + Gtk.CellRenderer.__init__(self) self.visible = True self.editable = False - self.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE) + self.set_property('mode', Gtk.CellRendererMode.ACTIVATABLE) self.use_filename = use_filename self.images = {} for key, icon in ( @@ -42,9 +40,8 @@ class CellRendererBinary(gtk.GenericCellRenderer): ('open', 'tryton-open'), ('save', 'tryton-save'), ('clear', 'tryton-clear')): - # hack to get gtk.gdk.Image from stock icon img_sensitive = IconFactory.get_pixbuf( - icon, gtk.ICON_SIZE_SMALL_TOOLBAR) + icon, Gtk.IconSize.SMALL_TOOLBAR) img_insensitive = img_sensitive.copy() img_sensitive.saturate_and_pixelate(img_insensitive, 0, False) width = img_sensitive.get_width() @@ -75,18 +72,17 @@ class CellRendererBinary(gtk.GenericCellRenderer): + (2 * (BUTTON_BORDER + BUTTON_SPACING) * len(self.buttons)) - 2 * BUTTON_SPACING) - def on_get_size(self, widget, cell_area=None): + def do_get_size(self, widget, cell_area=None): if cell_area is None: return (0, 0, 30, 18) else: return (cell_area.x, cell_area.y, cell_area.width, cell_area.height) - do_get_size = on_get_size - def on_activate(self, event, widget, path, background_area, - cell_area, flags): + def do_activate( + self, event, widget, path, background_area, cell_area, flags): if event is None: - return True + return button_width = self.button_width() for index, button_name in enumerate(self.buttons): @@ -104,15 +100,13 @@ class CellRendererBinary(gtk.GenericCellRenderer): else: button_name = None if not self.visible or not button_name: - return True - if not self.editable and button_name in ('select', 'clear'): - return True - if not self.size and button_name in {'open', 'save'}: - return True - if event.type == gtk.gdk.BUTTON_PRESS: - self.emit(button_name, path) + return + elif not self.editable and button_name in ('select', 'clear'): + return + elif not self.size and button_name in {'open', 'save'}: + return + self.emit(button_name, path) return True - do_activate = on_activate def do_render(self, cr, widget, background_area, cell_area, flags): if not self.visible: @@ -137,15 +131,15 @@ class CellRendererBinary(gtk.GenericCellRenderer): lwidth = w - button_width - padding.left - padding.right if lwidth < 0: lwidth = 0 - layout.set_width(lwidth * pango.SCALE) - layout.set_ellipsize(pango.ELLIPSIZE_END) - layout.set_wrap(pango.WRAP_CHAR) - layout.set_alignment(pango.ALIGN_RIGHT) + layout.set_width(lwidth * Pango.SCALE) + layout.set_ellipsize(Pango.ELLIPSIZE_END) + layout.set_wrap(Pango.WRAP_CHAR) + layout.set_alignment(Pango.ALIGN_RIGHT) if lwidth > 0: lw, lh = layout.get_size() # Can not use get_pixel_extents - lw /= pango.SCALE - lh /= pango.SCALE + lw /= Pango.SCALE + lh /= Pango.SCALE lx = x + padding.left if self.buttons and self.buttons[0] == 'open': @@ -154,7 +148,7 @@ class CellRendererBinary(gtk.GenericCellRenderer): ly = y + padding.top + 0.5 * ( h - padding.top - padding.bottom - lh) - gtk.render_layout(context, cr, lx, ly, layout) + Gtk.render_layout(context, cr, lx, ly, layout) for index, button_name in enumerate(self.buttons): pxbf_sens, pxbf_insens, pxbf_width, pxbf_height = \ @@ -177,13 +171,13 @@ class CellRendererBinary(gtk.GenericCellRenderer): by = cell_area.y bw = pxbf_width + (2 * BUTTON_BORDER) - gtk.render_background(context, cr, bx, by, bw, h) - gtk.render_frame(context, cr, bx, by, bw, h) + Gtk.render_background(context, cr, bx, by, bw, h) + Gtk.render_frame(context, cr, bx, by, bw, h) - gtk.gdk.cairo_set_source_pixbuf( + Gdk.cairo_set_source_pixbuf( cr, pixbuf, bx + BUTTON_BORDER, by + (h - pxbf_height) / 2) cr.paint() context.restore() -gobject.type_register(CellRendererBinary) +GObject.type_register(CellRendererBinary) diff --git a/tryton/common/cellrendererbutton.py b/tryton/common/cellrendererbutton.py index 88dd377be7..a93bd6a529 100644 --- a/tryton/common/cellrendererbutton.py +++ b/tryton/common/cellrendererbutton.py @@ -1,31 +1,27 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. -import gtk -import gobject -import pango +from gi.repository import Gtk, GObject, Pango -class CellRendererButton(gtk.GenericCellRenderer): - # TODO Add keyboard editing +class CellRendererButton(Gtk.CellRenderer): __gproperties__ = { - "text": (gobject.TYPE_STRING, None, "Text", - "Displayed text", gobject.ParamFlags.READWRITE), - 'visible': (gobject.TYPE_INT, 'Visible', - 'Visible', 0, 10, 0, gobject.ParamFlags.READWRITE), - 'sensitive': (gobject.TYPE_INT, 'Sensitive', - 'Sensitive', 0, 10, 0, gobject.ParamFlags.READWRITE), - } + "text": (GObject.TYPE_STRING, None, "Text", + "Displayed text", GObject.ParamFlags.READWRITE), + 'visible': (GObject.TYPE_INT, 'Visible', + 'Visible', 0, 10, 0, GObject.ParamFlags.READWRITE), + 'sensitive': (GObject.TYPE_INT, 'Sensitive', + 'Sensitive', 0, 10, 0, GObject.ParamFlags.READWRITE), + } __gsignals__ = { - 'clicked': (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_STRING, )), - } + 'clicked': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_NONE, + (GObject.TYPE_STRING,)), + } def __init__(self, text=""): - self.__gobject_init__() + Gtk.CellRenderer.__init__(self) self.text = text - self.set_property('mode', gtk.CELL_RENDERER_MODE_EDITABLE) - self.clicking = False + self.set_property('mode', Gtk.CellRendererMode.EDITABLE) self.visible = True self.sensitive = True @@ -39,15 +35,14 @@ class CellRendererButton(gtk.GenericCellRenderer): if not self.visible: return - state = gtk.StateFlags.NORMAL - if self.clicking and flags & gtk.CELL_RENDERER_SELECTED: - state = gtk.StateFlags.ACTIVE - elif not self.sensitive: - state = gtk.StateFlags.INSENSITIVE + if not self.sensitive: + state = Gtk.StateFlags.INSENSITIVE + else: + state = Gtk.StateFlags.NORMAL context = widget.get_style_context() context.save() - context.add_class('button') + context.add_class('text-button') context.set_state(state) xpad, ypad = self.get_padding() @@ -56,18 +51,18 @@ class CellRendererButton(gtk.GenericCellRenderer): w = cell_area.width - 2 * xpad h = cell_area.height - 2 * ypad - gtk.render_background(context, cr, x, y, w, h) - gtk.render_frame(context, cr, x, y, w, h) + Gtk.render_background(context, cr, x, y, w, h) + Gtk.render_frame(context, cr, x, y, w, h) padding = context.get_padding(state) layout = widget.create_pango_layout(self.text) - layout.set_width((w - padding.left - padding.right) * pango.SCALE) - layout.set_ellipsize(pango.ELLIPSIZE_END) - layout.set_wrap(pango.WRAP_CHAR) + layout.set_width((w - padding.left - padding.right) * Pango.SCALE) + layout.set_ellipsize(Pango.EllipsizeMode.END) + layout.set_wrap(Pango.WrapMode.CHAR) lw, lh = layout.get_size() # Can not use get_pixel_extents - lw /= pango.SCALE - lh /= pango.SCALE + lw /= Pango.SCALE + lh /= Pango.SCALE if w < lw: x = x + padding.left else: @@ -75,34 +70,21 @@ class CellRendererButton(gtk.GenericCellRenderer): w - padding.left - padding.right - lw) y = y + padding.top + 0.5 * (h - padding.top - padding.bottom - lh) - gtk.render_layout(context, cr, x, y, layout) + Gtk.render_layout(context, cr, x, y, layout) context.restore() - def on_get_size(self, widget, cell_area=None): + def do_get_size(self, widget, cell_area=None): if cell_area is None: return (0, 0, 30, 18) else: return (cell_area.x, cell_area.y, cell_area.width, cell_area.height) - do_get_size = on_get_size - def on_start_editing(self, event, widget, path, background_area, - cell_area, flags): + def do_start_editing( + self, event, widget, path, background_area, cell_area, flags): if not self.visible or not self.sensitive: return - if (event is None) or ((event.type == gtk.gdk.BUTTON_PRESS) - or (event.type == gtk.gdk.KEY_PRESS - and event.keyval == gtk.keysyms.space)): - self.clicking = True - widget.queue_draw() - while gtk.events_pending(): - gtk.main_iteration() - self.emit("clicked", path) + self.emit("clicked", path) - def timeout(self, widget): - self.clicking = False - widget.queue_draw() - gobject.timeout_add(60, timeout, self, widget) - do_start_editing = on_start_editing -gobject.type_register(CellRendererButton) +GObject.type_register(CellRendererButton) diff --git a/tryton/common/cellrendererclickablepixbuf.py b/tryton/common/cellrendererclickablepixbuf.py index 11e6b2a7dc..d26b36eb53 100644 --- a/tryton/common/cellrendererclickablepixbuf.py +++ b/tryton/common/cellrendererclickablepixbuf.py @@ -1,24 +1,21 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. -import gtk -import gobject +from gi.repository import Gtk, GObject -class CellRendererClickablePixbuf(gtk.CellRendererPixbuf): +class CellRendererClickablePixbuf(Gtk.CellRendererPixbuf): __gsignals__ = { - 'clicked': (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_STRING, )), + 'clicked': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_NONE, + (GObject.TYPE_STRING, )), } def __init__(self): - super(CellRendererClickablePixbuf, self).__init__() - self.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE) + Gtk.CellRendererPixbuf.__init__(self) + self.set_property('mode', Gtk.CellRendererMode.ACTIVATABLE) - def do_activate(self, event, widget, path, background_area, cell_area, - flags): - if (event - and cell_area.x <= event.x <= cell_area.x + cell_area.width - and cell_area.y <= event.y <= cell_area.y + cell_area.height): - self.emit('clicked', path) + def do_activate( + self, event, widget, path, background_area, cell_area, flags): + self.emit('clicked', path) -gobject.type_register(CellRendererClickablePixbuf) + +GObject.type_register(CellRendererClickablePixbuf) diff --git a/tryton/common/datetime_.py b/tryton/common/datetime_.py index 749eb56442..f39ee01569 100644 --- a/tryton/common/datetime_.py +++ b/tryton/common/datetime_.py @@ -199,6 +199,8 @@ class CellRendererDate(gtk.CellRendererText): def __init__(self): self.__format = '%x' + self.__entry = None + self.__focus_out_id = 0 gtk.CellRendererText.__init__(self) @@ -215,16 +217,34 @@ class CellRendererDate(gtk.CellRendererText): def do_start_editing( self, event, widget, path, background_area, cell_area, flags): - widget = add_operators(Date()) # TODO add_operators has option - widget.props.format = self.props.format - widget.props.value = self.props.text - if self.props.background_set: - widget.modify_base(gtk.STATE_NORMAL, self.props.background_gdk) - if self.props.foreground_set: - widget.modify_fg(gtk.STATE_NORMAL, self.props.foreground_gdk) - widget.grab_focus() - widget.show() - return widget + if not self.props.editable: + return + self.__entry = add_operators(Date()) # TODO add_operators has option + self.__entry.props.format = self.props.format + self.__entry.props.value = self.props.text + self.__entry.set_has_frame(False) + self.__entry.connect('editing-done', self.__editing_done) + self.__focus_out_id = self.__entry.connect( + 'focus-out-event', self.__focus_out_event) + # XXX focus-out-event + self.__entry.show() + return self.__entry + + def __editing_done(self, entry): + self.__entry = None + if self.__focus_out_id: + entry.disconnect(self.__focus_out_id) + canceled = entry.props.editing_canceled + self.stop_editing(canceled) + if canceled: + return + # TODO emit edited + + def __focus_out_event(self, entry, event): + entry.props.editing_canceled = True + entry.editing_done() + entry.remove_widget() + return False gobject.type_register(CellRendererDate) @@ -339,7 +359,7 @@ class Time(gtk.ComboBoxEntry): gobject.type_register(Time) -class CellRendererTime(gtk.CellRendererText): +class CellRendererTime(gtk.CellRendererCombo): __gproperties__ = { 'format': (gobject.TYPE_STRING, '%X', @@ -350,6 +370,8 @@ class CellRendererTime(gtk.CellRendererText): def __init__(self): self.__format = '%X' + self.__combo = None + self.__focus_out_id = 0 gtk.CellRendererText.__init__(self) @@ -368,16 +390,28 @@ class CellRendererTime(gtk.CellRendererText): self, event, widget, path, background_area, cell_area, flags): if not self.props.editable: return - widget = add_operators(Time()) # TODO add_operators has option - widget.props.format = self.props.format - widget.props.value = self.props.text - if self.props.background_set: - widget.modify_base(gtk.STATE_NORMAL, self.props.background_gdk) - if self.props.foreground_set: - widget.modify_fg(gtk.STATE_NORMAL, self.props.foreground_gdk) - widget.grab_focus() - widget.show() - return widget + self.__combo = add_operators(Time()) # TODO add_operators has option + self.__combo.props.format = self.props.format + self.__combo.props.value = self.props.text + self.__combo.props.has_frame = False + self.__combo.connect('editing-done', self.__editing_done) + # TODO: connect to changed + self.__focus_out_id = self.__combo.connect( + 'focus-out-event', self.__focus_out_event) + self.__combo.show() + return self.__combo + + def __editing_done(self, combo): + self.__combo = None + canceled = combo.props.editing_canceled + self.stop_editing(canceled) + if canceled: + return + # TODO emit edited + + def __focus_out_event(self, combo, event): + self.__editing_done(combo) + return False gobject.type_register(CellRendererTime)