Added dotted decimal schema field, not handling locales ZTK-1.1
authorThierry Florac <tflorac@ulthar.net>
Mon, 11 Jun 2012 12:52:56 +0200
branchZTK-1.1
changeset 145 1c7e8bef0027
parent 144 2d61d9ba66c4
child 146 d3083b645607
Added dotted decimal schema field, not handling locales
ztfy/utils/configure.zcml
ztfy/utils/schema.py
--- a/ztfy/utils/configure.zcml	Thu Apr 12 00:33:54 2012 +0200
+++ b/ztfy/utils/configure.zcml	Mon Jun 11 12:52:56 2012 +0200
@@ -14,6 +14,11 @@
 		name="ZTFY encodings"
 		component=".encoding.EncodingsVocabulary" />
 
+	<!-- Custom schema fields -->
+	<adapter
+		factory=".schema.DottedDecimalDataConverter"
+		trusted="True" />
+
 	<!-- Sub-packages -->
 	<include package=".tal" />
 
--- a/ztfy/utils/schema.py	Thu Apr 12 00:33:54 2012 +0200
+++ b/ztfy/utils/schema.py	Mon Jun 11 12:52:56 2012 +0200
@@ -15,16 +15,20 @@
 
 
 # import standard packages
+import decimal
 import string
 
 # import Zope3 interfaces
-from zope.schema.interfaces import ITextLine
+from z3c.form.interfaces import IWidget
+from zope.schema.interfaces import ITextLine, IDecimal
 
 # import local interfaces
 
 # import Zope3 packages
+from z3c.form.converter import BaseDataConverter, FormatterValidationError
+from zope.component import adapts
 from zope.interface import implements
-from zope.schema import TextLine
+from zope.schema import TextLine, Decimal
 from zope.schema._bootstrapfields import InvalidValue
 
 # import local packages
@@ -41,6 +45,10 @@
         return str(value)
 
 
+#
+# Color field
+#
+
 class IColorField(ITextLine):
     """Marker interface for color fields"""
 
@@ -60,3 +68,43 @@
             if v not in string.hexdigits:
                 raise InvalidValue, _("Color value must contain only valid color codes (numbers or letters between 'A' end 'F')")
         super(ColorField, self)._validate(value)
+
+
+#
+# Pointed decimal field
+#
+
+class IDottedDecimalField(IDecimal):
+    """Marker interface for dotted decimal fields"""
+
+
+class DottedDecimalField(Decimal):
+    """Dotted decimal field"""
+
+    implements(IDottedDecimalField)
+
+
+class DottedDecimalDataConverter(BaseDataConverter):
+    """Dotted decimal field data converter"""
+
+    adapts(IDottedDecimalField, IWidget)
+
+    errorMessage = _('The entered value is not a valid decimal literal.')
+
+    def __init__(self, field, widget):
+        super(DottedDecimalDataConverter, self).__init__(field, widget)
+
+    def toWidgetValue(self, value):
+        if not value:
+            return self.field.missing_value
+        return str(value)
+
+    def toFieldValue(self, value):
+        if value is self.field.missing_value:
+            return u''
+        if not value:
+            return None
+        try:
+            return decimal.Decimal(value)
+        except decimal.InvalidOperation:
+            raise FormatterValidationError(self.errorMessage, value)