diff --git a/CHANGELOG b/CHANGELOG index fc9de65037..91d3adb60b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add PYSON Widget * Show records names in wizard title * Add support for datetime_field to Reference * Show non editable widget as insensitive diff --git a/tryton/gui/window/view_form/view/form.py b/tryton/gui/window/view_form/view/form.py index 90ca2edf8f..fea8907c26 100644 --- a/tryton/gui/window/view_form/view/form.py +++ b/tryton/gui/window/view_form/view/form.py @@ -31,6 +31,7 @@ from .form_gtk.one2one import One2One from .form_gtk.richtextbox import RichTextBox from .form_gtk.dictionary import DictWidget from .form_gtk.multiselection import MultiSelection +from .form_gtk.pyson import PYSON from .form_gtk.state_widget import (Label, VBox, Image, Frame, ScrolledWindow, Notebook, Alignment) @@ -377,6 +378,7 @@ class ViewForm(View): 'richtext': RichTextBox, 'dict': DictWidget, 'multiselection': MultiSelection, + 'pyson': PYSON, } @classmethod diff --git a/tryton/gui/window/view_form/view/form_gtk/char.py b/tryton/gui/window/view_form/view/form_gtk/char.py index abfd97bfa8..23bb6e8224 100644 --- a/tryton/gui/window/view_form/view/form_gtk/char.py +++ b/tryton/gui/window/view_form/view/form_gtk/char.py @@ -82,9 +82,8 @@ class Char(Widget, TranslateMixin, PopdownMixin): @property def modified(self): if self.record and self.field: - entry = self.entry.get_child() if self.autocomplete else self.entry - value = entry.get_text() or '' - return self.field.get_client(self.record) != value + value = self.get_client_value(self.record, self.field) + return value != self.get_value() return False def set_value(self, record, field): @@ -96,6 +95,13 @@ class Char(Widget, TranslateMixin, PopdownMixin): entry = self.entry.get_child() if self.autocomplete else self.entry return entry.get_text() + def get_client_value(self, record, field): + if not field: + value = '' + else: + value = field.get_client(record) + return value + def display(self, record, field): super(Char, self).display(record, field) if self.autocomplete: @@ -118,11 +124,7 @@ class Char(Widget, TranslateMixin, PopdownMixin): size_entry.set_width_chars(-1) size_entry.set_max_length(0) - if not field: - value = '' - else: - value = field.get_client(record) - + value = self.get_client_value(record, field) if not self.autocomplete: self.entry.set_text(value) reset_position(self.entry) diff --git a/tryton/gui/window/view_form/view/form_gtk/integer.py b/tryton/gui/window/view_form/view/form_gtk/integer.py index fd8e80ef93..3c7b641e28 100644 --- a/tryton/gui/window/view_form/view/form_gtk/integer.py +++ b/tryton/gui/window/view_form/view/form_gtk/integer.py @@ -3,8 +3,6 @@ from .char import Char import locale -from tryton.common.entry_position import reset_position - class Integer(Char): "Integer" @@ -21,26 +19,16 @@ class Integer(Char): self.entry.connect('insert_text', self.sig_insert_text) self.factor = float(attrs.get('factor', 1)) - @property - def modified(self): - if self.record and self.field: - entry = self.entry.get_child() if self.autocomplete else self.entry - value = entry.get_text() or '' - return self.field.get_client(self.record, self.factor) != value - return False - def set_value(self, record, field): return field.set_client(record, self.entry.get_text(), factor=self.factor) - def display(self, record, field): - # skip Char call because set_text doesn't work with int - super(Char, self).display(record, field) + def get_client_value(self, record, field): if not field: - self.entry.set_text('') - return False - self.entry.set_text(field.get_client(record, factor=self.factor)) - reset_position(self.entry) + value = '' + else: + value = field.get_client(record, factor=self.factor) + return value def sig_insert_text(self, entry, new_text, new_text_length, position): value = entry.get_text() diff --git a/tryton/gui/window/view_form/view/form_gtk/pyson.py b/tryton/gui/window/view_form/view/form_gtk/pyson.py new file mode 100644 index 0000000000..5700e75e7b --- /dev/null +++ b/tryton/gui/window/view_form/view/form_gtk/pyson.py @@ -0,0 +1,42 @@ +# 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 +from .char import Char +from tryton.pyson import CONTEXT, PYSONEncoder, PYSONDecoder + + +class PYSON(Char): + + def __init__(self, view, attrs): + super(PYSON, self).__init__(view, attrs) + self.encoder = PYSONEncoder() + self.decoder = PYSONDecoder(noeval=True) + self.entry.connect('key-release-event', self.validate_pyson) + + def get_encoded_value(self): + value = self.get_value() + if not value: + return value + try: + return self.encoder.encode(eval(value, CONTEXT)) + except (ValueError, TypeError, NameError, SyntaxError): + return None + + def set_value(self, record, field): + field.set_client(record, self.get_encoded_value()) + + def get_client_value(self, record, field): + value = super(PYSON, self).get_client_value(record, field) + if value: + value = repr(self.decoder.decode(value)) + return value + + def validate_pyson(self, *args): + icon = gtk.STOCK_OK + if self.get_encoded_value() is None: + icon = gtk.STOCK_CANCEL + self.entry.set_icon_from_stock(gtk.ENTRY_ICON_SECONDARY, icon) + + def _focus_out(self): + self.validate_pyson() + super(PYSON, self)._focus_out()