Add factor on number widgets
review825002
This commit is contained in:
1 parent
fe5622471c
commit
df8e1176df
5 files changed
+115
-100
No files matched your search
@@ -1,3 +1,4 @@
|
||||
* Add factor on number widgets
|
||||
* Add calendar view
|
||||
* Add URL entry
|
||||
* Remove request
|
||||
|
||||
@@ -11,6 +11,7 @@ import time
|
||||
import datetime
|
||||
import decimal
|
||||
from decimal import Decimal
|
||||
import math
|
||||
from tryton.translate import date_format
|
||||
from tryton.common import RPCExecute, RPCException
|
||||
|
||||
@@ -263,8 +264,9 @@ class TimeField(CharField):
|
||||
return record.expr_eval(self.attrs['format'])
|
||||
|
||||
|
||||
class NumberField(CharField):
|
||||
class FloatField(CharField):
|
||||
_default = None
|
||||
default_digits = (16, 2)
|
||||
|
||||
def check_required(self, record):
|
||||
state_attrs = self.get_state_attrs(record)
|
||||
@@ -277,71 +279,62 @@ class NumberField(CharField):
|
||||
def get(self, record):
|
||||
return record.value.get(self.name, self._default)
|
||||
|
||||
def digits(self, record):
|
||||
default = (16, 2)
|
||||
return tuple(y if x is None else x for x, y in zip(
|
||||
record.expr_eval(self.attrs.get('digits', default)), default))
|
||||
def digits(self, record, factor=1):
|
||||
digits = tuple(y if x is None else x for x, y in zip(
|
||||
record.expr_eval(
|
||||
self.attrs.get('digits', self.default_digits)),
|
||||
self.default_digits))
|
||||
shift = int(round(math.log(factor, 10)))
|
||||
return (digits[0] + shift, digits[1] - shift)
|
||||
|
||||
def convert(self, value):
|
||||
try:
|
||||
return locale.atof
|
||||
except ValueError:
|
||||
return self._default
|
||||
|
||||
class FloatField(NumberField):
|
||||
|
||||
def set_client(self, record, value, force_change=False):
|
||||
def set_client(self, record, value, force_change=False, factor=1):
|
||||
if isinstance(value, basestring):
|
||||
try:
|
||||
value = locale.atof(value)
|
||||
except ValueError:
|
||||
value = self._default
|
||||
value = self.convert(value)
|
||||
if value is not None:
|
||||
value /= factor
|
||||
super(FloatField, self).set_client(record, value,
|
||||
force_change=force_change)
|
||||
|
||||
def get_client(self, record):
|
||||
def get_client(self, record, factor=1):
|
||||
value = record.value.get(self.name)
|
||||
if value is not None:
|
||||
digits = self.digits(record)
|
||||
return locale.format('%.*f', (digits[1], value), True)
|
||||
digit = self.digits(record, factor=factor)[1]
|
||||
return locale.format('%.*f', (digit, value * factor), True)
|
||||
else:
|
||||
return ''
|
||||
|
||||
|
||||
class NumericField(NumberField):
|
||||
class NumericField(FloatField):
|
||||
|
||||
def set_client(self, record, value, force_change=False):
|
||||
if isinstance(value, basestring):
|
||||
try:
|
||||
value = locale.atof(value, Decimal)
|
||||
except decimal.InvalidOperation:
|
||||
value = self._default
|
||||
super(NumericField, self).set_client(record, value,
|
||||
force_change=force_change)
|
||||
def convert(self, value):
|
||||
try:
|
||||
return locale.atof(value, Decimal)
|
||||
except decimal.InvalidOperation:
|
||||
return self._default
|
||||
|
||||
def get_client(self, record):
|
||||
value = record.value.get(self.name)
|
||||
if value is not None:
|
||||
digits = self.digits(record)
|
||||
return locale.format('%.*f', (digits[1], value), True)
|
||||
else:
|
||||
return ''
|
||||
def set_client(self, record, value, force_change=False, factor=1):
|
||||
return super(NumericField, self).set_client(record, value,
|
||||
force_change=force_change, factor=Decimal(str(factor)))
|
||||
|
||||
def get_client(self, record, factor=1):
|
||||
return super(NumericField, self).get_client(record,
|
||||
factor=Decimal(str(factor)))
|
||||
|
||||
|
||||
class IntegerField(NumberField):
|
||||
class IntegerField(FloatField):
|
||||
default_digits = (16, 0)
|
||||
|
||||
def set_client(self, record, value):
|
||||
if isinstance(value, basestring):
|
||||
try:
|
||||
value = locale.atoi(value)
|
||||
except ValueError:
|
||||
value = self._default
|
||||
super(IntegerField, self).set_client(record, value)
|
||||
|
||||
def get_client(self, record):
|
||||
value = record.value.get(self.name)
|
||||
if value is not None:
|
||||
return locale.format('%d', value, True)
|
||||
else:
|
||||
return ''
|
||||
|
||||
def digits(self, record):
|
||||
return (16, 0)
|
||||
def convert(self, value):
|
||||
try:
|
||||
return locale.atoi(value)
|
||||
except ValueError:
|
||||
return self._default
|
||||
|
||||
|
||||
class BooleanField(CharField):
|
||||
|
||||
@@ -12,17 +12,11 @@ class Float(Integer):
|
||||
super(Float, self).__init__(field_name, model_name, attrs=attrs)
|
||||
self.entry.connect('key-press-event', self.key_press_event)
|
||||
|
||||
def set_value(self, record, field):
|
||||
return field.set_client(record, self.entry.get_text())
|
||||
|
||||
def display(self, record, field):
|
||||
super(Float, self).display(record, field)
|
||||
if not field:
|
||||
self.entry.set_text('')
|
||||
return False
|
||||
digits = field.digits(record)
|
||||
self.entry.set_width_chars(sum(digits))
|
||||
self.entry.set_text(field.get_client(record))
|
||||
if field:
|
||||
digits = field.digits(record, factor=self.factor)
|
||||
self.entry.set_width_chars(sum(digits))
|
||||
|
||||
def key_press_event(self, widget, event):
|
||||
for name in ('KP_Decimal', 'KP_Separator'):
|
||||
@@ -43,7 +37,7 @@ class Float(Integer):
|
||||
if new_value in ('-', decimal_point):
|
||||
return
|
||||
|
||||
digits = self.field.digits(self.record)
|
||||
digits = self.field.digits(self.record, factor=self.factor)
|
||||
|
||||
try:
|
||||
locale.atof(new_value)
|
||||
|
||||
@@ -17,9 +17,19 @@ class Integer(Char):
|
||||
self.entry.set_max_length(0)
|
||||
self.entry.set_alignment(1.0)
|
||||
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())
|
||||
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
|
||||
@@ -27,7 +37,7 @@ class Integer(Char):
|
||||
if not field:
|
||||
self.entry.set_text('')
|
||||
return False
|
||||
self.entry.set_text(field.get_client(record))
|
||||
self.entry.set_text(field.get_client(record, factor=self.factor))
|
||||
|
||||
def sig_insert_text(self, entry, new_text, new_text_length, position):
|
||||
value = entry.get_text()
|
||||
|
||||
@@ -9,7 +9,7 @@ import locale
|
||||
import gettext
|
||||
import webbrowser
|
||||
|
||||
from functools import wraps
|
||||
from functools import wraps, partial
|
||||
|
||||
from editabletree import EditableTreeView, TreeView
|
||||
from tryton.gui.window.view_form.view.interface import ParserInterface
|
||||
@@ -360,12 +360,15 @@ class Affix(object):
|
||||
|
||||
class Char(object):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None,
|
||||
renderer=None):
|
||||
super(Char, self).__init__()
|
||||
self.field_name = field_name
|
||||
self.model_name = model_name
|
||||
self.attrs = attrs or {}
|
||||
self.renderer = CellRendererText()
|
||||
if renderer is None:
|
||||
renderer = CellRendererText
|
||||
self.renderer = renderer()
|
||||
self.renderer.connect('editing-started', self.editing_started)
|
||||
self.treeview = treeview
|
||||
|
||||
@@ -469,19 +472,34 @@ class Char(object):
|
||||
|
||||
class Int(Char):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None,
|
||||
renderer=None):
|
||||
if renderer is None:
|
||||
renderer = CellRendererInteger
|
||||
super(Int, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
self.renderer = CellRendererInteger()
|
||||
self.renderer.connect('editing-started', self.editing_started)
|
||||
attrs=attrs, renderer=renderer)
|
||||
self.factor = float(attrs.get('factor', 1))
|
||||
|
||||
def get_textual_value(self, record):
|
||||
if not record:
|
||||
return ''
|
||||
return record[self.field_name].get_client(record, factor=self.factor)
|
||||
|
||||
def value_from_text(self, record, text, callback=None):
|
||||
field = record[self.field_name]
|
||||
field.set_client(record, text, factor=self.factor)
|
||||
if callback:
|
||||
callback()
|
||||
|
||||
|
||||
class Boolean(Int):
|
||||
class Boolean(Char):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None,
|
||||
renderer=None):
|
||||
if renderer is None:
|
||||
renderer = CellRendererToggle
|
||||
super(Boolean, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
self.renderer = CellRendererToggle()
|
||||
attrs=attrs, renderer=renderer)
|
||||
self.renderer.connect('toggled', self._sig_toggled)
|
||||
|
||||
def _sig_toggled(self, renderer, path):
|
||||
@@ -510,19 +528,17 @@ class URL(Char):
|
||||
|
||||
class Date(Char):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None,
|
||||
renderer=None):
|
||||
if renderer is None:
|
||||
renderer = partial(CellRendererDate, date_format())
|
||||
super(Date, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
self.renderer = CellRendererDate(date_format())
|
||||
attrs=attrs, renderer=renderer)
|
||||
self.renderer.connect('editing-started', self.editing_started)
|
||||
|
||||
|
||||
class Datetime(Date):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
super(Datetime, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
|
||||
@realized
|
||||
def setter(self, column, cell, store, iter):
|
||||
super(Datetime, self).setter(column, cell, store, iter)
|
||||
@@ -534,10 +550,6 @@ class Datetime(Date):
|
||||
|
||||
class Time(Date):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
super(Time, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
|
||||
@realized
|
||||
def setter(self, column, cell, store, iter):
|
||||
super(Time, self).setter(column, cell, store, iter)
|
||||
@@ -547,28 +559,30 @@ class Time(Date):
|
||||
self.renderer.format = time_format
|
||||
|
||||
|
||||
class Float(Char):
|
||||
class Float(Int):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None,
|
||||
renderer=None):
|
||||
if renderer is None:
|
||||
renderer = CellRendererFloat
|
||||
super(Float, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
self.renderer = CellRendererFloat()
|
||||
self.renderer.connect('editing-started', self.editing_started)
|
||||
attrs=attrs, renderer=renderer)
|
||||
|
||||
@realized
|
||||
def setter(self, column, cell, store, iter):
|
||||
super(Float, self).setter(column, cell, store, iter)
|
||||
record = store.get_value(iter, 0)
|
||||
field = record[self.field_name]
|
||||
digits = field.digits(record)
|
||||
digits = field.digits(record, factor=self.factor)
|
||||
cell.digits = digits
|
||||
|
||||
|
||||
class FloatTime(Char):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None,
|
||||
renderer=None):
|
||||
super(FloatTime, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
attrs=attrs, renderer=renderer)
|
||||
self.conv = None
|
||||
if attrs and attrs.get('float_time'):
|
||||
self.conv = rpc.CONTEXT.get(attrs['float_time'])
|
||||
@@ -588,11 +602,13 @@ class FloatTime(Char):
|
||||
|
||||
class Binary(Char):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None,
|
||||
renderer=None):
|
||||
if renderer is None:
|
||||
renderer = partial(CellRendererBinary, bool(self.filename))
|
||||
super(Binary, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
self.filename = attrs.get('filename')
|
||||
self.renderer = CellRendererBinary(bool(self.filename))
|
||||
self.renderer.connect('new', self.new_binary)
|
||||
self.renderer.connect('open', self.open_binary)
|
||||
self.renderer.connect('save', self.save_binary)
|
||||
@@ -657,12 +673,12 @@ class Binary(Char):
|
||||
|
||||
class M2O(Char):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None,
|
||||
renderer=None):
|
||||
if renderer is None and int(attrs.get('completion', 1)):
|
||||
renderer = partial(CellRendererTextCompletion, self.set_completion)
|
||||
super(M2O, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
if int(attrs.get('completion', 1)):
|
||||
self.renderer = CellRendererTextCompletion(self.set_completion)
|
||||
self.renderer.connect('editing-started', self.editing_started)
|
||||
attrs=attrs, renderer=renderer)
|
||||
|
||||
def value_from_text(self, record, text, callback=None):
|
||||
field = record.group.fields[self.field_name]
|
||||
@@ -937,9 +953,10 @@ class Selection(Char, SelectionMixin):
|
||||
|
||||
class Reference(Char, SelectionMixin):
|
||||
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None):
|
||||
def __init__(self, field_name, model_name, treeview, attrs=None,
|
||||
renderer=None):
|
||||
super(Reference, self).__init__(field_name, model_name, treeview,
|
||||
attrs=attrs)
|
||||
attrs=attrs, renderer=renderer)
|
||||
self.init_selection()
|
||||
self._selection = dict(self.selection)
|
||||
|
||||
|
||||
Reference in new issue
Block a user