Back to index

plone3  3.1.7
document.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 """Browser views for documents.
00014 
00015 $Id: document.py 72414 2007-02-07 10:18:25Z yuppie $
00016 """
00017 
00018 from zope.component import adapts
00019 from zope.formlib import form
00020 from zope.interface import implements
00021 from zope.interface import Interface
00022 from zope.schema import ASCIILine
00023 from zope.schema import Bytes
00024 from zope.schema import Choice
00025 from zope.schema import Text
00026 from zope.schema import TextLine
00027 
00028 from Products.CMFDefault.formlib.form import ContentEditFormBase
00029 from Products.CMFDefault.formlib.schema import ProxyFieldProperty
00030 from Products.CMFDefault.formlib.schema import SchemaAdapterBase
00031 from Products.CMFDefault.formlib.vocabulary import StaticVocabulary
00032 from Products.CMFDefault.formlib.widgets import ChoiceRadioWidget
00033 from Products.CMFDefault.formlib.widgets import TextInputWidget
00034 from Products.CMFDefault.interfaces import IMutableDocument
00035 from Products.CMFDefault.utils import Message as _
00036 
00037 from utils import decode
00038 from utils import memoize
00039 from utils import ViewBase
00040 
00041 available_text_formats = (
00042         (u'structured-text', 'structured-text', _(u'structured-text')),
00043         (u'plain', 'plain', _(u'plain text')),
00044         (u'html', 'html', _(u'html')))
00045 
00046 TextFormatVocabularyFactory = StaticVocabulary(available_text_formats)
00047 
00048 
00049 class IDocumentSchema(Interface):
00050 
00051     """Schema for document views.
00052     """
00053 
00054     safety_belt = ASCIILine(
00055         required=False)
00056 
00057     title = TextLine(
00058         title=_(u'Title'),
00059         readonly=True)
00060 
00061     description = Text(
00062         title=_(u'Description'),
00063         readonly=True)
00064 
00065     text_format = Choice(
00066         title=_(u'Format'),
00067         vocabulary='cmf.AvailableTextFormats')
00068 
00069     upload = Bytes(
00070         title=_(u'Upload'),
00071         required=False)
00072 
00073     text = Text(
00074         title=_(u'Body'),
00075         required=False,
00076         missing_value=u'')
00077 
00078 
00079 class DocumentSchemaAdapter(SchemaAdapterBase):
00080 
00081     """Adapter for IMutableDocument.
00082     """
00083 
00084     adapts(IMutableDocument)
00085     implements(IDocumentSchema)
00086 
00087     safety_belt = ProxyFieldProperty(IDocumentSchema['safety_belt'],
00088                                      '_safety_belt')
00089     title = ProxyFieldProperty(IDocumentSchema['title'], 'Title')
00090     description = ProxyFieldProperty(IDocumentSchema['description'],
00091                                      'Description')
00092     text_format = ProxyFieldProperty(IDocumentSchema['text_format'])
00093     upload = None
00094     text = ProxyFieldProperty(IDocumentSchema['text'],
00095                               'EditableBody', '_edit')
00096 
00097 
00098 class DocumentView(ViewBase):
00099 
00100     """View for IDocument.
00101     """
00102 
00103     # interface
00104 
00105     @memoize
00106     @decode
00107     def text(self):
00108         return self.context.CookedBody()
00109 
00110 
00111 class DocumentEditView(ContentEditFormBase):
00112 
00113     """Edit view for IMutableDocument.
00114     """
00115 
00116     form_fields = form.FormFields(IDocumentSchema)
00117     form_fields['text_format'].custom_widget = ChoiceRadioWidget
00118     form_fields['text'].custom_widget = TextInputWidget
00119 
00120     def setUpWidgets(self, ignore_request=False):
00121         super(DocumentEditView,
00122               self).setUpWidgets(ignore_request=ignore_request)
00123         self.widgets['safety_belt'].hide = True
00124         self.widgets['description'].height = 3
00125         self.widgets['text_format'].orientation = 'horizontal'
00126         self.widgets['upload'].displayWidth = 60
00127         self.widgets['text'].height = 20
00128 
00129     def _handle_success(self, action, data):
00130         body = data.get('upload')
00131         if body:
00132             data['text'] = body.decode(self._getDefaultCharset())
00133         changed = super(DocumentEditView, self)._handle_success(action, data)
00134         if changed:
00135             self.context.updateSafetyBelt(data.get('safety_belt'))
00136         return changed
00137 
00138     def handle_validate(self, action, data):
00139         errors = super(DocumentEditView, self).handle_validate(action, data)
00140         if errors:
00141             return errors
00142         safety_belt = self.request.form['form.safety_belt']
00143         if not self.context.isValidSafetyBelt(safety_belt):
00144             return (_(u'Intervening changes from elsewhere detected. Please '
00145                       u'refetch the document and reapply your changes.'),)
00146         # make sure applyChanges doesn't try to update safety_belt
00147         self.request.form['form.safety_belt'] = self.context._safety_belt
00148         return None