--- 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)