13 # |
13 # |
14 ############################################################################## |
14 ############################################################################## |
15 |
15 |
16 |
16 |
17 # import standard packages |
17 # import standard packages |
|
18 import decimal |
18 import string |
19 import string |
19 |
20 |
20 # import Zope3 interfaces |
21 # import Zope3 interfaces |
21 from zope.schema.interfaces import ITextLine |
22 from z3c.form.interfaces import IWidget |
|
23 from zope.schema.interfaces import ITextLine, IDecimal |
22 |
24 |
23 # import local interfaces |
25 # import local interfaces |
24 |
26 |
25 # import Zope3 packages |
27 # import Zope3 packages |
|
28 from z3c.form.converter import BaseDataConverter, FormatterValidationError |
|
29 from zope.component import adapts |
26 from zope.interface import implements |
30 from zope.interface import implements |
27 from zope.schema import TextLine |
31 from zope.schema import TextLine, Decimal |
28 from zope.schema._bootstrapfields import InvalidValue |
32 from zope.schema._bootstrapfields import InvalidValue |
29 |
33 |
30 # import local packages |
34 # import local packages |
31 |
35 |
32 from ztfy.utils import _ |
36 from ztfy.utils import _ |
58 raise InvalidValue, _("Color length must be 3 or 6 characters") |
66 raise InvalidValue, _("Color length must be 3 or 6 characters") |
59 for v in value: |
67 for v in value: |
60 if v not in string.hexdigits: |
68 if v not in string.hexdigits: |
61 raise InvalidValue, _("Color value must contain only valid color codes (numbers or letters between 'A' end 'F')") |
69 raise InvalidValue, _("Color value must contain only valid color codes (numbers or letters between 'A' end 'F')") |
62 super(ColorField, self)._validate(value) |
70 super(ColorField, self)._validate(value) |
|
71 |
|
72 |
|
73 # |
|
74 # Pointed decimal field |
|
75 # |
|
76 |
|
77 class IDottedDecimalField(IDecimal): |
|
78 """Marker interface for dotted decimal fields""" |
|
79 |
|
80 |
|
81 class DottedDecimalField(Decimal): |
|
82 """Dotted decimal field""" |
|
83 |
|
84 implements(IDottedDecimalField) |
|
85 |
|
86 |
|
87 class DottedDecimalDataConverter(BaseDataConverter): |
|
88 """Dotted decimal field data converter""" |
|
89 |
|
90 adapts(IDottedDecimalField, IWidget) |
|
91 |
|
92 errorMessage = _('The entered value is not a valid decimal literal.') |
|
93 |
|
94 def __init__(self, field, widget): |
|
95 super(DottedDecimalDataConverter, self).__init__(field, widget) |
|
96 |
|
97 def toWidgetValue(self, value): |
|
98 if not value: |
|
99 return self.field.missing_value |
|
100 return str(value) |
|
101 |
|
102 def toFieldValue(self, value): |
|
103 if value is self.field.missing_value: |
|
104 return u'' |
|
105 if not value: |
|
106 return None |
|
107 try: |
|
108 return decimal.Decimal(value) |
|
109 except decimal.InvalidOperation: |
|
110 raise FormatterValidationError(self.errorMessage, value) |