Allow different decimal separators for Floats.
This commit is contained in:
		
							parent
							
								
									0b4f6e1f79
								
							
						
					
					
						commit
						7d3ac9112b
					
				
					 2 changed files with 35 additions and 4 deletions
				
			
		|  | @ -664,17 +664,28 @@ class Integer(Type): | ||||||
|         if value not in nullValues: return self.pythonType(value) |         if value not in nullValues: return self.pythonType(value) | ||||||
| 
 | 
 | ||||||
| class Float(Type): | class Float(Type): | ||||||
|  |     allowedDecimalSeps = (',', '.') | ||||||
|     def __init__(self, validator=None, multiplicity=(0,1), index=None, |     def __init__(self, validator=None, multiplicity=(0,1), index=None, | ||||||
|                  default=None, optional=False, editDefault=False, show=True, |                  default=None, optional=False, editDefault=False, show=True, | ||||||
|                  page='main', group=None, layouts=None, move=0, indexed=False, |                  page='main', group=None, layouts=None, move=0, indexed=False, | ||||||
|                  searchable=False, specificReadPermission=False, |                  searchable=False, specificReadPermission=False, | ||||||
|                  specificWritePermission=False, width=6, height=None, |                  specificWritePermission=False, width=6, height=None, | ||||||
|                  colspan=1, master=None, masterValue=None, focus=False, |                  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 |         # The precision is the number of decimal digits. This number is used | ||||||
|         # for rendering the float, but the internal float representation is not |         # for rendering the float, but the internal float representation is not | ||||||
|         # rounded. |         # rounded. | ||||||
|         self.precision = precision |         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, |         Type.__init__(self, validator, multiplicity, index, default, optional, | ||||||
|                       editDefault, show, page, group, layouts, move, indexed, |                       editDefault, show, page, group, layouts, move, indexed, | ||||||
|                       False, specificReadPermission, specificWritePermission, |                       False, specificReadPermission, specificWritePermission, | ||||||
|  | @ -684,21 +695,41 @@ class Float(Type): | ||||||
| 
 | 
 | ||||||
|     def getFormattedValue(self, obj, value): |     def getFormattedValue(self, obj, value): | ||||||
|         if value in nullValues: return '' |         if value in nullValues: return '' | ||||||
|  |         # Determine the field separator | ||||||
|  |         sep = self.sep[0] | ||||||
|  |         # Produce the rounded string representation | ||||||
|         if self.precision == None: |         if self.precision == None: | ||||||
|             res = str(value) |             res = str(value) | ||||||
|         else: |         else: | ||||||
|             format = '%%.%df' % appyType.precision |             format = '%%.%df' % self.precision | ||||||
|             res = format % value |             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 |         return res | ||||||
| 
 | 
 | ||||||
|     def validateValue(self, obj, value): |     def validateValue(self, obj, value): | ||||||
|  |         # Replace used separator with the Python separator '.' | ||||||
|  |         for sep in self.sep: value = value.replace(sep, '.') | ||||||
|         try: |         try: | ||||||
|             value = self.pythonType(value) |             value = self.pythonType(value) | ||||||
|         except ValueError: |         except ValueError: | ||||||
|             return obj.translate('bad_%s' % self.pythonType.__name__) |             return obj.translate('bad_%s' % self.pythonType.__name__) | ||||||
| 
 | 
 | ||||||
|     def getStorableValue(self, value): |     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): | class String(Type): | ||||||
|     # Some predefined regular expressions that may be used as validators |     # Some predefined regular expressions that may be used as validators | ||||||
|  |  | ||||||
|  | @ -504,7 +504,7 @@ class AbstractMixin: | ||||||
|         return css, js |         return css, js | ||||||
| 
 | 
 | ||||||
|     def getAppyTypesFromNames(self, fieldNames, asDict=True): |     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] |         return [self.getAppyType(name, asDict) for name in fieldNames] | ||||||
| 
 | 
 | ||||||
|     def getAppyStates(self, phase, currentOnly=False): |     def getAppyStates(self, phase, currentOnly=False): | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Gaetan Delannay
						Gaetan Delannay