From 7d3ac9112b5f19752c54db79537ecf9972fcc941 Mon Sep 17 00:00:00 2001 From: Gaetan Delannay Date: Wed, 15 Sep 2010 10:38:35 +0200 Subject: [PATCH] Allow different decimal separators for Floats. --- gen/__init__.py | 37 +++++++++++++++++++++++++++++++--- gen/plone25/mixins/__init__.py | 2 +- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/gen/__init__.py b/gen/__init__.py index 60745d8..df5adf4 100644 --- a/gen/__init__.py +++ b/gen/__init__.py @@ -664,17 +664,28 @@ class Integer(Type): if value not in nullValues: return self.pythonType(value) class Float(Type): + allowedDecimalSeps = (',', '.') def __init__(self, validator=None, multiplicity=(0,1), index=None, default=None, optional=False, editDefault=False, show=True, page='main', group=None, layouts=None, move=0, indexed=False, searchable=False, specificReadPermission=False, specificWritePermission=False, width=6, height=None, colspan=1, master=None, masterValue=None, focus=False, - historized=False, precision=None): + historized=False, precision=None, sep=(',', '.')): # The precision is the number of decimal digits. This number is used # for rendering the float, but the internal float representation is not # rounded. self.precision = precision + # The decimal separator can be a tuple if several are allowed, ie + # ('.', ',') + if type(sep) not in sequenceTypes: + self.sep = (sep,) + else: + self.sep = sep + # Check that the separator(s) are among allowed decimal separators + for sep in self.sep: + if sep not in Float.allowedDecimalSeps: + raise 'Char "%s" is not allowed as decimal separator.' % sep Type.__init__(self, validator, multiplicity, index, default, optional, editDefault, show, page, group, layouts, move, indexed, False, specificReadPermission, specificWritePermission, @@ -684,21 +695,41 @@ class Float(Type): def getFormattedValue(self, obj, value): if value in nullValues: return '' + # Determine the field separator + sep = self.sep[0] + # Produce the rounded string representation if self.precision == None: res = str(value) else: - format = '%%.%df' % appyType.precision + format = '%%.%df' % self.precision res = format % value + # Use the correct decimal separator + res = res.replace('.', sep) + # Remove the decimal part if = 0 + splitted = res.split(sep) + if len(splitted) > 1: + try: + decPart = int(splitted[1]) + if decPart == 0: + res = splitted[0] + except ValueError: + # This exception may occur when the float value has an "exp" + # part, like in this example: 4.345e-05. + pass return res def validateValue(self, obj, value): + # Replace used separator with the Python separator '.' + for sep in self.sep: value = value.replace(sep, '.') try: value = self.pythonType(value) except ValueError: return obj.translate('bad_%s' % self.pythonType.__name__) def getStorableValue(self, value): - if value not in nullValues: return self.pythonType(value) + if value not in nullValues: + for sep in self.sep: value = value.replace(sep, '.') + return self.pythonType(value) class String(Type): # Some predefined regular expressions that may be used as validators diff --git a/gen/plone25/mixins/__init__.py b/gen/plone25/mixins/__init__.py index 7aba242..248ef2d 100644 --- a/gen/plone25/mixins/__init__.py +++ b/gen/plone25/mixins/__init__.py @@ -504,7 +504,7 @@ class AbstractMixin: return css, js def getAppyTypesFromNames(self, fieldNames, asDict=True): - '''Gets the appy types names p_fieldNames.''' + '''Gets the Appy types names p_fieldNames.''' return [self.getAppyType(name, asDict) for name in fieldNames] def getAppyStates(self, phase, currentOnly=False):