changeset 4a71d8ca9a27 in tryton:default
details: https://hg.tryton.org/tryton?cmd=changeset;node=4a71d8ca9a27
description:
        Use Mixin to share common behavior between Form and Dict widgets

        The Integer and Float widgets of form and dict can share the same Entry
        handlers.

        issue7989
        review66511002
diffstat:

 tryton/gui/window/view_form/view/form_gtk/dictionary.py |  71 ++++------------
 tryton/gui/window/view_form/view/form_gtk/float.py      |  72 +++++++++-------
 tryton/gui/window/view_form/view/form_gtk/integer.py    |  38 +++++---
 3 files changed, 80 insertions(+), 101 deletions(-)

diffs (269 lines):

diff -r 74557f917ae5 -r 4a71d8ca9a27 
tryton/gui/window/view_form/view/form_gtk/dictionary.py
--- a/tryton/gui/window/view_form/view/form_gtk/dictionary.py   Sun Feb 03 
20:29:09 2019 +0100
+++ b/tryton/gui/window/view_form/view/form_gtk/dictionary.py   Sun Feb 03 
20:41:27 2019 +0100
@@ -10,6 +10,9 @@
 from decimal import Decimal
 
 from .widget import Widget
+from .integer import IntegerMixin
+from .float import FloatMixin
+
 from tryton.gui.window.win_search import WinSearch
 from tryton.common import Tooltips, timezoned_date, untimezoned_date, \
         IconFactory
@@ -153,29 +156,15 @@
         self.widget.set_sensitive(not readonly)
 
 
-class DictIntegerEntry(DictEntry):
+class DictIntegerEntry(IntegerMixin, DictEntry):
     expand = False
     fill = False
 
     def create_widget(self):
         widget = super(DictIntegerEntry, self).create_widget()
-        widget.set_width_chars(8)
-        widget.set_max_length(0)
-        widget.set_alignment(1.0)
-        widget.connect('insert-text', self.sig_insert_text)
+        self._prepare_entry(widget)
         return widget
 
-    def sig_insert_text(self, entry, new_text, new_text_length, position):
-        value = entry.get_text()
-        position = entry.get_position()
-        new_value = value[:position] + new_text + value[position:]
-        if new_value == '-':
-            return
-        try:
-            locale.atoi(new_value)
-        except ValueError:
-            entry.stop_emission('insert-text')
-
     def get_value(self):
         txt_value = self.widget.get_text()
         if txt_value:
@@ -194,42 +183,16 @@
         reset_position(self.widget)
 
 
-class DictFloatEntry(DictIntegerEntry):
-
-    def digits(self):
-        default = (16, 2)
-        record = self.parent_widget.record
-        if not record:
-            return default
-        return tuple(y if x is None else x for x, y in zip(
-                record.expr_eval(self.definition.get('digits', default)),
-                default))
-
-    def sig_insert_text(self, entry, new_text, new_text_length, position):
-        value = entry.get_text()
-        position = entry.get_position()
-        new_value = value[:position] + new_text + value[position:]
-        decimal_point = locale.localeconv()['decimal_point']
+class DictFloatEntry(FloatMixin, DictIntegerEntry):
 
-        if new_value in ('-', decimal_point):
-            return
-
-        digits = self.digits()
-
-        try:
-            locale.atof(new_value)
-        except ValueError:
-            entry.stop_emission('insert-text')
-            return
-
-        new_int = new_value
-        new_decimal = ''
-        if decimal_point in new_value:
-            new_int, new_decimal = new_value.rsplit(decimal_point, 1)
-
-        if (len(new_int) > digits[0]
-                or len(new_decimal) > digits[1]):
-            entry.stop_emission('insert-text')
+    @property
+    def digits(self):
+        record = self.parent_widget.record
+        if record:
+            digits = record.expr_eval(self.definition.get('digits'))
+            if not digits or any(d is None for d in digits):
+                return
+            return digits
 
     def get_value(self):
         txt_value = self.widget.get_text()
@@ -241,14 +204,14 @@
         return None
 
     def set_value(self, value):
-        digits = self.digits()
+        digits = self.digits
         if value is not None:
-            txt_val = locale.format('%.' + str(digits[1]) + 'f', value, True)
+            txt_val = locale.format('%.*f', (digits[1], value), True)
         else:
             txt_val = ''
-        self.widget.set_width_chars(sum(digits))
         self.widget.set_text(txt_val)
         reset_position(self.widget)
+        self._set_entry_width(self.widget)
 
 
 class DictNumericEntry(DictFloatEntry):
diff -r 74557f917ae5 -r 4a71d8ca9a27 
tryton/gui/window/view_form/view/form_gtk/float.py
--- a/tryton/gui/window/view_form/view/form_gtk/float.py        Sun Feb 03 
20:29:09 2019 +0100
+++ b/tryton/gui/window/view_form/view/form_gtk/float.py        Sun Feb 03 
20:41:27 2019 +0100
@@ -2,51 +2,59 @@
 # this repository contains the full copyright notices and license terms.
 import gtk
 import locale
-from .integer import Integer
+from .integer import Integer, IntegerMixin
 
 
-class Float(Integer):
-    "Float"
-
-    def __init__(self, view, attrs):
-        super(Float, self).__init__(view, attrs)
-        self.entry.connect('key-press-event', self.key_press_event)
+class FloatMixin(IntegerMixin):
+    _width_chars = 18
 
-    def display(self):
-        super(Float, self).display()
-        if self.field:
-            digits = self.field.digits(self.record, factor=self.factor)
-            if digits:
-                self.entry.set_width_chars(sum(digits))
-            else:
-                self.entry.set_width_chars(18)
+    def _prepare_entry(self, entry):
+        super()._prepare_entry(entry)
+        entry.connect('key-press-event', self._key_press_event)
 
-    def key_press_event(self, widget, event):
-        for name in ('KP_Decimal', 'KP_Separator'):
-            if event.keyval == gtk.gdk.keyval_from_name(name):
-                event.keyval = int(gtk.gdk.unicode_to_keyval(
-                    ord(locale.localeconv()['decimal_point'])))
-
-    def sig_insert_text(self, entry, new_text, new_text_length, position):
-        if not self.record:
-            entry.stop_emission('insert-text')
-            return
-
+    def _insert_text(self, entry, new_text, new_text_length, position):
         value = entry.get_text()
         position = entry.get_position()
         new_value = value[:position] + new_text + value[position:]
         decimal_point = locale.localeconv()['decimal_point']
-
-        if new_value in ('-', decimal_point):
+        if new_value in ['-', decimal_point]:
             return
-
-        digits = self.field.digits(self.record, factor=self.factor)
-
         try:
             value = locale.atof(new_value)
         except ValueError:
             entry.stop_emission('insert-text')
             return
-
+        digits = self.digits
         if digits and not (round(value, digits[1]) == float(value)):
             entry.stop_emission('insert-text')
+
+    def _key_press_event(self, entry, event):
+        for name in ['KP_Decimal', 'KP_Separator']:
+            if event.keyval == gtk.gdk.keyval_from_name(name):
+                event.keyval = int(gtk.gdk.unicode_to_keyval(
+                    ord(locale.localeconv()['decimal_point'])))
+
+    @property
+    def digits(self):
+        return NotImplementedError
+
+    def _set_entry_width(self, entry):
+        digits = self.digits
+        if digits:
+            width = sum(digits)
+        else:
+            width = self._width_chars
+        entry.set_width_chars(width)
+
+
+class Float(FloatMixin, Integer):
+    "Float"
+
+    @property
+    def digits(self):
+        if self.field and self.record:
+            return self.field.digits(self.record, factor=self.factor)
+
+    def display(self):
+        super(Float, self).display()
+        self._set_entry_width(self.entry)
diff -r 74557f917ae5 -r 4a71d8ca9a27 
tryton/gui/window/view_form/view/form_gtk/integer.py
--- a/tryton/gui/window/view_form/view/form_gtk/integer.py      Sun Feb 03 
20:29:09 2019 +0100
+++ b/tryton/gui/window/view_form/view/form_gtk/integer.py      Sun Feb 03 
20:41:27 2019 +0100
@@ -4,7 +4,28 @@
 import locale
 
 
-class Integer(Char):
+class IntegerMixin:
+    _width_chars = 8
+
+    def _prepare_entry(self, entry):
+        entry.set_width_chars(self._width_chars)
+        entry.set_max_length(0)
+        entry.set_alignment(1.0)
+        entry.connect('insert-text', self._insert_text)
+
+    def _insert_text(self, entry, new_text, new_text_length, position):
+        value = entry.get_text()
+        position = entry.get_position()
+        new_value = value[:position] + new_text + value[position:]
+        if new_value == '-':
+            return
+        try:
+            locale.atoi(new_value)
+        except ValueError:
+            entry.stop_emission('insert-text')
+
+
+class Integer(IntegerMixin, Char):
     "Integer"
 
     def __init__(self, view, attrs):
@@ -14,9 +35,7 @@
             self.entry)
         self.widget.set_child_packing(self.entry, False, False,
             padding, pack_type)
-        self.entry.set_max_length(0)
-        self.entry.set_alignment(1.0)
-        self.entry.connect('insert_text', self.sig_insert_text)
+        self._prepare_entry(self.entry)
         self.factor = float(attrs.get('factor', 1))
 
     def set_value(self):
@@ -29,14 +48,3 @@
         else:
             value = self.field.get_client(self.record, factor=self.factor)
         return value
-
-    def sig_insert_text(self, entry, new_text, new_text_length, position):
-        value = entry.get_text()
-        position = entry.get_position()
-        new_value = value[:position] + new_text + value[position:]
-        if new_value == '-':
-            return
-        try:
-            locale.atoi(new_value)
-        except ValueError:
-            entry.stop_emission('insert-text')

Reply via email to