Back to index

plone3  3.1.7
widgets.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2006 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE.
00011 #
00012 ##############################################################################
00013 """Custom form widgets.
00014 
00015 $Id: widgets.py 77186 2007-06-28 19:06:19Z yuppie $
00016 """
00017 
00018 from zope.app.form import InputWidget
00019 from zope.app.form.browser import BrowserWidget
00020 from zope.app.form.browser import MultiSelectSetWidget
00021 from zope.app.form.browser import RadioWidget
00022 from zope.app.form.browser import TextWidget
00023 from zope.app.form.browser import TextAreaWidget
00024 from zope.app.form.interfaces import ConversionError
00025 from zope.app.form.interfaces import IInputWidget
00026 from zope.app.form.interfaces import WidgetInputError
00027 from zope.component import adapts
00028 from zope.component import getUtility
00029 from zope.interface import implementsOnly
00030 from zope.publisher.interfaces.browser import IBrowserRequest
00031 from zope.schema import Set
00032 from zope.schema import Tuple
00033 from zope.schema.interfaces import ISet
00034 from zope.schema.interfaces import ITuple
00035 
00036 from Products.CMFCore.interfaces import IMetadataTool
00037 from Products.CMFDefault.exceptions import IllegalHTML
00038 from Products.CMFDefault.utils import scrubHTML
00039 from Products.CMFDefault.utils import Message as _
00040 from schema import IEmailLine
00041 from vocabulary import SimpleVocabulary
00042 
00043 
00044 # generic widgets
00045 
00046 def ChoiceRadioWidget(field, request):
00047     return RadioWidget(field, field.vocabulary, request)
00048 
00049 
00050 class EmailInputWidget(TextWidget):
00051 
00052     implementsOnly(IInputWidget)
00053     adapts(IEmailLine, IBrowserRequest)
00054 
00055     def _toFieldValue(self, input):
00056         if input == self._missing:
00057             return self.context.missing_value
00058 
00059         try:
00060             return str(input.strip())
00061         except (AttributeError, UnicodeEncodeError), err:
00062             raise ConversionError(_(u'Invalid email address.'), err)
00063 
00064 
00065 class TextInputWidget(TextAreaWidget):
00066 
00067     def getInputValue(self):
00068         value = super(TextInputWidget, self).getInputValue()
00069         if value:
00070             try:
00071                 value = scrubHTML(value)
00072             except IllegalHTML, err:
00073                 self._error = WidgetInputError(self.context.__name__,
00074                                                self.label, err.args[0])
00075                 raise self._error
00076         return value
00077 
00078 
00079 class TupleTextAreaWidget(TextAreaWidget):
00080 
00081     implementsOnly(IInputWidget)
00082     adapts(ITuple, IBrowserRequest)
00083 
00084     def __init__(self, context, field, request):
00085         super(TupleTextAreaWidget, self).__init__(context, request)
00086 
00087     def _toFieldValue(self, input):
00088         input = super(TupleTextAreaWidget, self)._toFieldValue(input)
00089         if isinstance(input, basestring):
00090             input = tuple([ l.strip()
00091                             for l in input.splitlines() if l.strip() ])
00092 
00093         if input == ():
00094             return self.context.missing_value
00095 
00096         return input
00097 
00098     def _toFormValue(self, value):
00099         if value is not None:
00100             value = u'\n'.join(value)
00101         return super(TupleTextAreaWidget, self)._toFormValue(value)
00102 
00103 
00104 def TupleInputWidget(field, request):
00105     return TupleTextAreaWidget(field, field.value_type, request)
00106 
00107 
00108 # special widgets
00109 
00110 class SubjectInputWidget(InputWidget, BrowserWidget):
00111 
00112     implementsOnly(IInputWidget)
00113     adapts(ISet, IBrowserRequest)
00114 
00115     def __init__(self, context, request):
00116         super(SubjectInputWidget, self).__init__(context, request)
00117         self._widgets = {}
00118         self._widget_keys = (1,)
00119         self.vocabulary = ()
00120         context = getattr(self.context.context, 'context',
00121                           self.context.context)
00122         mdtool = getUtility(IMetadataTool)
00123         allowed_subjects = mdtool.listAllowedSubjects(context)
00124         if allowed_subjects:
00125             items = [ (str(v), unicode(v), unicode(v))
00126                       for v in allowed_subjects ]
00127             self.vocabulary = SimpleVocabulary.fromTitleItems(items)
00128             self._widget_keys = (0, 1)
00129 
00130     def _getWidget(self, i):
00131         if i not in self._widgets:
00132             if i == 0:
00133                 field = Set(__name__='1').bind(self.context)
00134                 widget = MultiSelectSetWidget(field, self.vocabulary,
00135                                               self.request)
00136                 widget.setPrefix(self.name)
00137                 widget.empty_marker_name = widget.name + "-empty-marker"
00138                 widget.size = 3
00139                 self._widgets[0] = widget
00140             elif i == 1:
00141                 field = Tuple(__name__='', required=False).bind(self.context)
00142                 widget = TupleInputWidget(field, self.request)
00143                 widget.name = self.name
00144                 widget.height = self.vocabulary and 2 or 6
00145                 self._widgets[1] = widget
00146         return self._widgets[i]
00147 
00148     def getInputValue(self):
00149         value = set()
00150         for k in self._widget_keys:
00151             value = set(self._getWidget(k).getInputValue() or ())|value
00152         return value
00153 
00154     def hasInput(self):
00155         value = False
00156         for k in self._widget_keys:
00157             value = self._getWidget(k).hasInput() or value
00158         return value
00159 
00160     def __call__(self):
00161         values = {0: [], 1: []}
00162         if not self._renderedValueSet():
00163             value = self.getInputValue()
00164         else:
00165             value = self._data
00166         for item in value or ():
00167             if item in self.vocabulary:
00168                 values[0].append(item)
00169             else:
00170                 values[1].append(item)
00171         for k in self._widget_keys:
00172             self._getWidget(k).setRenderedValue(set(values[k]))
00173         return '\n'.join([ self._getWidget(k)() for k in self._widget_keys ])