src/ztfy/utils/schema.py
branchZTK-1.1
changeset 148 d3668ecd9137
parent 145 1c7e8bef0027
child 165 9615e7d1a4ee
equal deleted inserted replaced
147:044dc196ec8a 148:d3668ecd9137
       
     1 ### -*- coding: utf-8 -*- ####################################################
       
     2 ##############################################################################
       
     3 #
       
     4 # Copyright (c) 2012 Thierry Florac <tflorac AT ulthar.net>
       
     5 # All Rights Reserved.
       
     6 #
       
     7 # This software is subject to the provisions of the Zope Public License,
       
     8 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
       
     9 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
       
    10 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    11 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
       
    12 # FOR A PARTICULAR PURPOSE.
       
    13 #
       
    14 ##############################################################################
       
    15 
       
    16 
       
    17 # import standard packages
       
    18 import decimal
       
    19 import string
       
    20 
       
    21 # import Zope3 interfaces
       
    22 from z3c.form.interfaces import IWidget
       
    23 from zope.schema.interfaces import ITextLine, IDecimal
       
    24 
       
    25 # import local interfaces
       
    26 
       
    27 # import Zope3 packages
       
    28 from z3c.form.converter import BaseDataConverter, FormatterValidationError
       
    29 from zope.component import adapts
       
    30 from zope.interface import implements
       
    31 from zope.schema import TextLine, Decimal
       
    32 from zope.schema._bootstrapfields import InvalidValue
       
    33 
       
    34 # import local packages
       
    35 
       
    36 from ztfy.utils import _
       
    37 
       
    38 
       
    39 class StringLine(TextLine):
       
    40     """String line field"""
       
    41 
       
    42     _type = str
       
    43 
       
    44     def fromUnicode(self, value):
       
    45         return str(value)
       
    46 
       
    47 
       
    48 #
       
    49 # Color field
       
    50 #
       
    51 
       
    52 class IColorField(ITextLine):
       
    53     """Marker interface for color fields"""
       
    54 
       
    55 
       
    56 class ColorField(TextLine):
       
    57     """Color field"""
       
    58 
       
    59     implements(IColorField)
       
    60 
       
    61     def __init__(self, *args, **kw):
       
    62         super(ColorField, self).__init__(max_length=6, *args, **kw)
       
    63 
       
    64     def _validate(self, value):
       
    65         if len(value) not in (3, 6):
       
    66             raise InvalidValue, _("Color length must be 3 or 6 characters")
       
    67         for v in value:
       
    68             if v not in string.hexdigits:
       
    69                 raise InvalidValue, _("Color value must contain only valid color codes (numbers or letters between 'A' end 'F')")
       
    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)