[Checkins] SVN: z3c.multiform/Sandbox/src/z3c/multiform/ - prepare
MultiformBase for filter
Stefan Martin
s.martin at iwm-kmrc.de
Thu Dec 7 09:53:24 EST 2006
Log message for revision 71478:
- prepare MultiformBase for filter
- add MultiformWidgets to handle different widgets for display and input
- build usable containerviews like contents.html and index.html
- separate Actions and Fields of containerviews
- write test of containerviews
Changed:
_U z3c.multiform/Sandbox/src/z3c/multiform/
U z3c.multiform/Sandbox/src/z3c/multiform/README.txt
U z3c.multiform/Sandbox/src/z3c/multiform/TODO.txt
U z3c.multiform/Sandbox/src/z3c/multiform/actions.txt
U z3c.multiform/Sandbox/src/z3c/multiform/configure.zcml
U z3c.multiform/Sandbox/src/z3c/multiform/container/configure.zcml
U z3c.multiform/Sandbox/src/z3c/multiform/container/container.txt
U z3c.multiform/Sandbox/src/z3c/multiform/container/interfaces.py
U z3c.multiform/Sandbox/src/z3c/multiform/container/location.py
U z3c.multiform/Sandbox/src/z3c/multiform/container/tests.py
U z3c.multiform/Sandbox/src/z3c/multiform/container/views.py
U z3c.multiform/Sandbox/src/z3c/multiform/gridform.py
U z3c.multiform/Sandbox/src/z3c/multiform/gridform.txt
U z3c.multiform/Sandbox/src/z3c/multiform/interfaces.py
U z3c.multiform/Sandbox/src/z3c/multiform/multiform.py
U z3c.multiform/Sandbox/src/z3c/multiform/selection.py
A z3c.multiform/Sandbox/src/z3c/multiform/selection.txt
D z3c.multiform/Sandbox/src/z3c/multiform/selections.txt
U z3c.multiform/Sandbox/src/z3c/multiform/sort.py
U z3c.multiform/Sandbox/src/z3c/multiform/tests.py
-=-
Property changes on: z3c.multiform/Sandbox/src/z3c/multiform
___________________________________________________________________
Name: svn:ignore
+
.project
Modified: z3c.multiform/Sandbox/src/z3c/multiform/README.txt
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/README.txt 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/README.txt 2006-12-07 14:53:23 UTC (rev 71478)
@@ -7,12 +7,12 @@
from the Form class of the formlib package.
>>> from zope import interface, schema
- >>> from zope.app.location.interfaces import ILocation
+ >>> from zope.location.interfaces import ILocation
>>> class IOrder(interface.Interface):
... identifier = schema.Int(title=u"Identifier", readonly=True)
... name = schema.TextLine(title=u"Name")
- >>> class Order:
+ >>> class Order(object):
... interface.implements(IOrder,ILocation)
...
... def __init__(self, identifier, name=''):
@@ -22,7 +22,6 @@
>>> orderMapping = dict([(str(k),Order(k,name='n%s'%k)) for k in range(5)])
-
Let us create a new multiform class which should display IOrder objects.
>>> from zope.formlib import form
@@ -50,14 +49,13 @@
... res += '<div>%s</div>\n' % self.subForms[name](
... ignore_request=ignore_request)
... return res
- ...
-
+ ...
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()
>>> view = OrdersForm(orderMapping, request)
>>> print view()
<div>
- <div>0</div><div><input ... name="form.0.name" ... value="n0" ...</div>
+ <div>0</div><div><input ... name="form.sf.0.name" ... value="n0" ...</div>
</div>
<div>
...
@@ -66,11 +64,11 @@
If the request contains any form data, that will be reflected in the
output:
- >>> request.form['form.1.name'] = u'bob'
+ >>> request.form['form.sf.1.name'] = u'bob'
>>> print OrdersForm(orderMapping,request)()
<div>
...
- <div>1</div><div><input ... name="form.1.name" ... value="bob" ...</div>
+ <div>1</div><div><input ... name="form.sf.1.name" ... value="bob" ...</div>
...
</div>
@@ -82,7 +80,7 @@
>>> print OrdersForm(orderMapping, request)(ignore_request=True)
<div>
...
- <div>1</div><div><input ... name="form.1.name" ... value="n1" ...</div>
+ <div>1</div><div><input ... name="form.sf.1.name" ... value="n1" ...</div>
...
</div>
Modified: z3c.multiform/Sandbox/src/z3c/multiform/TODO.txt
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/TODO.txt 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/TODO.txt 2006-12-07 14:53:23 UTC (rev 71478)
@@ -7,11 +7,6 @@
Missing functionalities:
------------------------
- - customwidget for container.interfaces.IMovableLocation['__name__']
-
- Returns an inputwidget if an IInputWidget is needed and returns
- an displaywidget if an IDisplayWidget is needed.
-
- Size columns
Enable to register a size information field (ISized has only IMethods).
@@ -36,5 +31,5 @@
- sort_down and sort_up gifs from the skin
- It would be a nice feature of a skin to provides these to icons
+ It would be a nice feature of a skin to provides these two icons
Modified: z3c.multiform/Sandbox/src/z3c/multiform/actions.txt
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/actions.txt 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/actions.txt 2006-12-07 14:53:23 UTC (rev 71478)
@@ -15,7 +15,7 @@
>>> from zope.formlib import form
>>> from zope.publisher.browser import TestRequest
>>> from zope.app.form.interfaces import IInputWidget
- >>> from zope.app.location.interfaces import ILocation
+ >>> from zope.location.interfaces import ILocation
>>> from z3c.multiform import multiform
>>> from z3c.multiform.multiform import ItemFormBase,MultiFormBase
>>> from zope.app.i18n import ZopeMessageFactory as _
@@ -85,10 +85,10 @@
>>> pf = OrdersForm(orderMapping,request)
>>> print pf()
<div>
- <div>0</div><div>n0</div>...<input...name="form.n0.actions.upper"...
+ <div>0</div><div>n0</div>...<input...name="form.sf.n0.actions.upper"...
</div>
<div>
- <div>1</div><div>n1</div>...<input...name="form.n1.actions.upper"...
+ <div>1</div><div>n1</div>...<input...name="form.sf.n1.actions.upper"...
</div>
<div><input...name="form.actions.edit"...</div>
@@ -127,8 +127,8 @@
>>> request = TestRequest()
>>> request.form['form.actions.save']=u''
>>> for i in range(2):
- ... request.form['form.n%s.name' % i]='newer name %s' % i
- ... request.form['form.n%s.identifier' % i]= i
+ ... request.form['form.sf.n%s.name' % i]='newer name %s' % i
+ ... request.form['form.sf.n%s.identifier' % i]= i
>>> pf = OrdersForm(orderMapping,request)
>>> result = pf()
@@ -161,8 +161,8 @@
>>> request = TestRequest()
>>> request.form['form.actions.cancel']=u''
>>> for i in range(2):
- ... request.form['form.n%s.name' % i]='next name %s' % i
- ... request.form['form.n%s.identifier' % i]= i
+ ... request.form['form.sf.n%s.name' % i]='next name %s' % i
+ ... request.form['form.sf.n%s.identifier' % i]= i
>>> pf = OrdersForm(orderMapping,request)
>>> result = pf()
@@ -186,7 +186,7 @@
mapping.
>>> request = TestRequest()
- >>> request.form['form.n1.actions.upper']=u''
+ >>> request.form['form.sf.n1.actions.upper']=u''
>>> pf = OrdersForm(orderMapping,request)
>>> result = pf()
>>> print result
Modified: z3c.multiform/Sandbox/src/z3c/multiform/configure.zcml
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/configure.zcml 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/configure.zcml 2006-12-07 14:53:23 UTC (rev 71478)
@@ -3,24 +3,12 @@
xmlns:i18n="http://namespaces.zope.org/i18n"
i18n_domain="zope">
- <adapter for="zope.app.location.interfaces.ILocation
- zope.formlib.interfaces.IForm"
- provides=".interfaces.IFormLocation"
- factory=".selection.FormLocationProxy"
+ <adapter factory=".selection.FormLocationProxy"
trusted="true"
/>
+ <adapter factory=".selection.FormLocationSelection" />
+ <adapter factory=".sort.SchemaSorter" />
- <adapter for=".interfaces.IFormLocation"
- provides=".interfaces.ISelection"
- factory=".selection.FormLocationSelection"
- />
-
- <adapter for="zope.interface.Interface
- zope.schema.interfaces.IField"
- factory=".sort.SchemaSorter"
- provides=".interfaces.ISorter"
- />
-
<!-- namedtemplate for IParentAction -->
<adapter factory=".multiform.render_submit_button" name="render" />
Modified: z3c.multiform/Sandbox/src/z3c/multiform/container/configure.zcml
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/container/configure.zcml 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/container/configure.zcml 2006-12-07 14:53:23 UTC (rev 71478)
@@ -9,9 +9,7 @@
permission="zope.View"
class=".views.ContainerGridForm"/>
- <zope:adapter for="zope.app.location.interfaces.ILocation"
- factory=".location.MovableLocation"
- provides=".interfaces.IMovableLocation"/>
+ <zope:adapter factory=".location.MovableLocation" />
</configure>
Modified: z3c.multiform/Sandbox/src/z3c/multiform/container/container.txt
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/container/container.txt 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/container/container.txt 2006-12-07 14:53:23 UTC (rev 71478)
@@ -3,44 +3,245 @@
=====================
A container contents view implementation using multiform. This view
-provides cut, copy, paste, edit and save actions. Additionally the
-__name__ attribute of the items can be transparently changed.
+provides cut, copy, paste, delete, edit and save actions. Additionally
+the __name__ attribute of the items can be transparently changed.
-In order to test the behaviour of the ``ContainerGridForm`` we
-subclass it and override the template method.
+In order to test the behaviour of the ``ContainerGridForm`` and
+``ContainerItemForm`` we subclass these and override the template methods.
>>> from zope import interface
>>> from zope.publisher.browser import TestRequest
>>> from zope.app.container.sample import SampleContainer
>>> from zope.app.annotation.interfaces import IAttributeAnnotatable
- >>> from zope.app.dublincore.interfaces import IZopeDublinCore
- >>> from zope.app.dublincore.interfaces import IDCDescriptiveProperties
+ >>> from zope.dublincore.interfaces import IZopeDublinCore
+ >>> from zope.dublincore.interfaces import IDCDescriptiveProperties
>>> from z3c.multiform.container.views import ContainerGridForm
-
+ >>> from z3c.multiform.container.views import ContainerItemForm
+ >>> from z3c.multiform.container import views
+ >>> from z3c.multiform.interfaces import ISelection
+ ...
+ >>> class ContainerItemTest(ContainerItemForm):
+ ...
+ ... def template(self):
+ ... return '\n<div>%s</div>\n' % '</div><div>'.join([w() for w in
+ ... self.widgets] + [action.render() for action in
+ ... self.availableActions()])
+
>>> class ContainerTest(ContainerGridForm):
- ... actions = ContainerGridForm.actions.copy()
+ ...
... def template(self):
... res = u''
- ... forms = list(self.getForms())
- ... forms.sort(lambda x,y: cmp(x.prefix,y.prefix))
- ... for form in forms:
- ... res += '<div>%s</div>\n' % form.render()
+ ... for error in self.errors:
+ ... res += '<div>%s</div>\n' % error
+ ... names = sorted(self.subForms.keys())
+ ... for name in names:
+ ... res += '<div>%s</div>\n' % self.subForms[name].render()
+ ... for action in self.availableActions():
+ ... res += '<div>%s</div>\n' % action.render()
+ ... for action in self.availableSubActions():
+ ... res += '<div>%s</div>\n' % action.render()
... return res
+ ...
+ ... def getAllAvailableActionsLabel(self):
+ ... res = []
+ ... for action in self.availableActions():
+ ... res.append(action.label)
+ ... for action in self.availableSubActions():
+ ... res.append(action.label)
+ ... return res
+ ...
+ ... def getAllAvailableActions(self):
+ ... res = {}
+ ... for action in self.availableActions():
+ ... res[action.label] = action.__name__
+ ... for action in self.availableSubActions():
+ ... res[action.label] = action.__name__
+ ... return res
+
+ >>> def getAvailableActions(view):
+ ... return sorted([action.label for action in view.availableActions()])
+ >>> def getSelectionInfo(view):
+ ... return [(n, ISelection(f.context).selected) for n, f in view.subForms.items()]
+
+We need principals to test the clipboard.
+
+ >>> class DummyPrincipal(object):
+ ...
+ ... def __init__(self, id):
+ ... self.id = id
+
+ >>> from zope.app.folder import Folder, rootFolder
+ >>> root = rootFolder()
>>> c = SampleContainer()
+ >>> root['base'] = c
>>> for i in range(2):
... o = SampleContainer()
... interface.directlyProvides(o,IAttributeAnnotatable)
- ... c[u'name of %s' % i]=o
+ ... c[u'item%s' % i]=o
+ >>> dobe = DummyPrincipal(u'dobe')
+ >>> stmartin = DummyPrincipal(u'stmartin')
+ >>> stmartin.id
+ u'stmartin'
+
+First of all we get the default view
+
>>> request = TestRequest()
+ >>> request.setPrincipal(dobe)
>>> view = ContainerTest(c,request)
- >>> print view()
- <div...<td>name of 0</td>...<td>name of 1</td>...
+ >>> x = view()
+ >>> view.getAllAvailableActionsLabel()
+ [u'container-cut-button', u'container-copy-button', u'container-delete-button', u'Edit']
+ >>> defaultActions = view.getAllAvailableActions()
+ >>> getSelectionInfo(view)
+ [(u'item0', False), (u'item1', False)]
+We mark item0 and click on edit
+ >>> request = TestRequest()
+ >>> request.setPrincipal(dobe)
+ >>> request.form['form.sf.item0.selected']=u'on'
+ >>> request.form['form.sf.item1.selected.used']=u''
+ >>> request.form['form.actions.edit']=u''
+ >>> view = ContainerTest(c,request)
+ >>> x = view()
+ >>> view.getAllAvailableActionsLabel()
+ [u'Cancel', u'Save']
+ >>> getSelectionInfo(view)
+ [(u'item0', True), (u'item1', False)]
+ >>> print x
+ <div>...<td><input...id="form.sf.item0.__name__"...
+ </div>
+ <div>...<td>...>item1<...</td>...
+ </div>
+ <div><input...value="Cancel".../></div>
+ <div><input...value="Save".../></div>
+Sorry, wrong item, cancel.
+ >>> request = TestRequest()
+ >>> request.setPrincipal(dobe)
+ >>> request.form['form.sf.item0.selected']=u'on'
+ >>> request.form['form.sf.item1.selected.used']=u''
+ >>> request.form['form.actions.cancel']=u''
+ >>> view = ContainerTest(c,request)
+ >>> x = view()
+ >>> view.getAllAvailableActionsLabel()
+ [u'container-cut-button', u'container-copy-button', u'container-delete-button', u'Edit']
+We mark item1, change the title and click on save.
+
+ >>> request = TestRequest()
+ >>> request.setPrincipal(dobe)
+ >>> request.form['form.sf.item0.selected.used']=u''
+ >>> request.form['form.sf.item1.selected']=u'on'
+ >>> request.form['form.actions.save']=u''
+ >>> request.form['form.sf.item1.__name__'] = 'item1'
+ >>> request.form['form.sf.item1.title'] = 'item1newtitle'
+ >>> view = ContainerTest(c,request)
+ >>> x = view()
+ >>> view.getAllAvailableActionsLabel()
+ [u'container-cut-button', u'container-copy-button', u'container-delete-button', u'Edit']
+ >>> getSelectionInfo(view)
+ [(u'item0', False), (u'item1', False)]
+ >>> print x
+ <div>...<td>...>item0<...</td><td></td><td></td>...
+ </div>
+ <div>...<td>...>item1<...</td><td>item1newtitle</td>...
+ </div>
+ <div><input type="submit"...
+ <div><input type="submit"...
+ <div><input type="submit"...
+ <div><input type="submit"...
+
+Next, we mark item0 and click on copy
+
+ >>> request = TestRequest()
+ >>> request.setPrincipal(dobe)
+ >>> request.form['form.sf.item0.selected']=u'on'
+ >>> request.form['form.sf.item1.selected.used']=u''
+ >>> request.form[defaultActions[u'container-copy-button']]=u''
+ >>> view = ContainerTest(c,request)
+ >>> x = view()
+ >>> view.getAllAvailableActionsLabel()
+ [u'container-paste-button', u'container-cut-button', u'container-copy-button', u'container-delete-button', u'Edit']
+ >>> defaultActions = view.getAllAvailableActions()
+
+and paste it.
+ >>> request = TestRequest()
+ >>> request.setPrincipal(dobe)
+ >>> request.form['form.sf.item0.selected']=u'on'
+ >>> request.form['form.sf.item1.selected.used']=u''
+ >>> request.form[defaultActions['container-paste-button']]=u''
+ >>> view = ContainerTest(c,request)
+ >>> x = view()
+ >>> getSelectionInfo(view)
+ [(u'item0', True), (u'item1', False), (u'item0-2', False)]
+
+The name of the new item could be better:
+
+ >>> request = TestRequest()
+ >>> request.setPrincipal(dobe)
+ >>> request.form['form.sf.item0.selected']=u'on'
+ >>> request.form['form.sf.item1.selected']=u'on'
+ >>> request.form['form.sf.item0-2.selected.used']=u''
+ >>> request.form['form.sf.item0-2.__name__'] = u'item2'
+ >>> request.form['form.sf.item0-2.title'] = u''
+ >>> request.form['form.actions.save']=u''
+ >>> view = ContainerTest(c,request)
+ >>> x = view()
+ >>> print x
+ <div>...
+ </div>
+ <div>...
+ style:="background: red;"
+ title:="...Required input is missing...id="form.sf.item0-2.title"...
+ </div>
+ ...
+
+Required input in field title is missing, fill in a title and retry
+
+ >>> request = TestRequest()
+ >>> request.setPrincipal(dobe)
+ >>> request.form['form.sf.item0.selected']=u'on'
+ >>> request.form['form.sf.item1.selected']=u'on'
+ >>> request.form['form.sf.item0-2.selected']=u'on'
+ >>> request.form['form.sf.item0-2.__name__'] = u'item2'
+ >>> request.form['form.sf.item0-2.title'] = u'title'
+ >>> request.form['form.actions.save']=u''
+ >>> view = ContainerTest(c,request)
+ >>> x = view()
+ >>> getSelectionInfo(view)
+ [(u'item2', False), (u'item0', False), (u'item1', False)]
+
+We cut item2
+
+ >>> request = TestRequest()
+ >>> request.setPrincipal(dobe)
+ >>> request.form['form.sf.item2.selected']=u'on'
+ >>> request.form[defaultActions['container-cut-button']]=u''
+ >>> view = ContainerTest(c,request)
+ >>> x = view()
+
+And paste in item0
+
+ >>> request = TestRequest()
+ >>> request.setPrincipal(dobe)
+ >>> request.form[defaultActions['container-paste-button']]=u''
+ >>> view = ContainerTest(c['item0'],request)
+ >>> x = view()
+
+ >>> [key for key in c.keys()]
+ [u'item0', u'item1']
+
+ >>> [key for key in c['item0'].keys()]
+ [u'item2']
+
+
+TODO:
+-----
+- different widgets for display and input mode
+- __name__ as link in displaymode
Modified: z3c.multiform/Sandbox/src/z3c/multiform/container/interfaces.py
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/container/interfaces.py 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/container/interfaces.py 2006-12-07 14:53:23 UTC (rev 71478)
@@ -1,6 +1,6 @@
from zope import schema
from zope.interface import Interface, Attribute
-from zope.app.location.interfaces import ILocation
+from zope.location.interfaces import ILocation
class IMovableLocation(ILocation):
Modified: z3c.multiform/Sandbox/src/z3c/multiform/container/location.py
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/container/location.py 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/container/location.py 2006-12-07 14:53:23 UTC (rev 71478)
@@ -1,14 +1,17 @@
-from zope.interface import implements
+from zope import interface, component
+
from zope.security.proxy import removeSecurityProxy
-from zope.app.copypastemove.interfaces import IContainerItemRenamer
+from zope.copypastemove.interfaces import IContainerItemRenamer
+from zope.location.interfaces import ILocation
from z3c.multiform.interfaces import IFormLocation
-from interfaces import IMovableLocation
+from z3c.multiform.container.interfaces import IMovableLocation
class MovableLocation(object):
- implements(IMovableLocation)
+ interface.implements(IMovableLocation)
+ component.adapts(ILocation)
def __init__(self,context):
self.context = context
Modified: z3c.multiform/Sandbox/src/z3c/multiform/container/tests.py
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/container/tests.py 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/container/tests.py 2006-12-07 14:53:23 UTC (rev 71478)
@@ -7,16 +7,21 @@
from zope.app.testing import setup
import zope.schema.interfaces
import zope.app.form.browser
+import zope.app.form.browser.exception
import zope.publisher.interfaces.browser
import zope.app.form.interfaces
-from zope.app.dublincore.annotatableadapter import ZDCAnnotatableAdapter
-from zope.app.dublincore.interfaces import IWriteZopeDublinCore
-from zope.app.annotation.interfaces import IAnnotatable
-from zope.app.location.interfaces import ILocation
+from zope.copypastemove import PrincipalClipboard, ObjectCopier, ObjectMover, ContainerItemRenamer
+from zope.app.principalannotation import PrincipalAnnotationUtility
+from zope.app.principalannotation.interfaces import IPrincipalAnnotationUtility
+from zope.dublincore.annotatableadapter import ZDCAnnotatableAdapter
+from zope.dublincore.interfaces import IWriteZopeDublinCore
+from zope.annotation.interfaces import IAnnotatable
+from zope.annotation.interfaces import IAnnotations
+from zope.location.interfaces import ILocation
from zope.formlib import form
-from z3c.multiform import gridform,multiform,selection
-from z3c.multiform.interfaces import IFormLocation,ISelection
+from z3c.multiform import gridform, multiform, selection
+from z3c.multiform.interfaces import IFormLocation, ISelection
from interfaces import IMovableLocation
@@ -24,6 +29,14 @@
setup.placefulSetUp()
component.provideAdapter(
+ zope.app.form.browser.exception.WidgetInputErrorView,
+ [zope.app.form.interfaces.IWidgetInputError,
+ zope.publisher.interfaces.browser.IBrowserRequest,
+ ],
+ zope.app.form.browser.interfaces.IWidgetInputErrorView,
+ )
+
+ component.provideAdapter(
zope.app.form.browser.DatetimeDisplayWidget,
[zope.schema.interfaces.IDatetime,
zope.publisher.interfaces.browser.IBrowserRequest,
@@ -74,29 +87,21 @@
],
zope.app.form.interfaces.IInputWidget,
)
+ component.provideAdapter(selection.FormLocationProxy)
+ component.provideAdapter(selection.FormLocationSelection)
+ component.provideAdapter(location.MovableLocation)
+
component.provideAdapter(
- selection.FormLocationProxy,
- [zope.app.location.interfaces.ILocation,
- zope.formlib.interfaces.IForm
- ],
- IFormLocation
- )
- component.provideAdapter(
- selection.FormLocationSelection,
- [IFormLocation],
- ISelection
- )
- component.provideAdapter(
- location.MovableLocation,
- [ILocation],
- IMovableLocation
- )
- component.provideAdapter(
ZDCAnnotatableAdapter,
[IAnnotatable],
IWriteZopeDublinCore
)
-
+ component.provideAdapter(PrincipalClipboard)
+ component.provideAdapter(ObjectCopier)
+ component.provideAdapter(ObjectMover)
+ component.provideAdapter(ContainerItemRenamer)
+ component.provideUtility(PrincipalAnnotationUtility(),
+ IPrincipalAnnotationUtility)
component.provideAdapter(gridform.default_grid_template,
name="default")
Modified: z3c.multiform/Sandbox/src/z3c/multiform/container/views.py
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/container/views.py 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/container/views.py 2006-12-07 14:53:23 UTC (rev 71478)
@@ -1,20 +1,26 @@
+
import datetime
import pytz
+
+from zope import component
+
from zope.interface.common import idatetime
from zope.app.i18n import ZopeMessageFactory as _
from zope.formlib import form
-from zope.app.dublincore.interfaces import IWriteZopeDublinCore
+from zope.dublincore.interfaces import IWriteZopeDublinCore
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.event import notify
-from zope.app.event.objectevent import ObjectModifiedEvent
+from zope.lifecycleevent import ObjectModifiedEvent
from zope.app import zapi
-from zope.app.copypastemove.interfaces import IPrincipalClipboard
-from zope.app.copypastemove.interfaces import IObjectCopier
-from zope.app.copypastemove.interfaces import IObjectMover
+from zope.copypastemove.interfaces import IPrincipalClipboard
+from zope.copypastemove.interfaces import IObjectCopier
+from zope.copypastemove.interfaces import IObjectMover
from zope.app.principalannotation.interfaces import IPrincipalAnnotationUtility
from zope.app.container.interfaces import DuplicateIDError
+from zope.app.container.browser.contents import getPrincipalClipboard, getDCTitle
+from zope.app.form.browser import TextWidget, DisplayWidget
from zope.security.interfaces import Unauthorized
-from zope.app.traversing.interfaces import TraversalError
+from zope.traversing.interfaces import TraversalError
from z3c.multiform import multiform, gridform
from z3c.multiform.interfaces import ISelection
@@ -96,64 +102,33 @@
return False
-class ContainerItemForm(multiform.ItemFormBase):
+def condition_paste_action(form, action):
+ return hasClipboardContents(form, action)
+label_paste_action = _("container-paste-button")
- inputMode=False
- forceInput=['selected']
- template = ViewPageTemplateFile('griditem.pt')
- form_fields = form.Fields(ISelection['selected'],
- IMovableLocation['__name__'],
- IWriteZopeDublinCore['title'],
- IWriteZopeDublinCore['created'],
- IWriteZopeDublinCore['modified'],
- omit_readonly=False,render_context=True)
- form_fields['created'].for_display=True
- form_fields['modified'].for_display=True
+def condition_cut_action(form, action):
+ return multiform.allSubFormsDisplayMode(form, action)
+label_cut_action = _("container-cut-button")
+def condition_copy_action(form, action):
+ return multiform.allSubFormsDisplayMode(form, action)
+label_copy_action = _("container-copy-button")
+
+def condition_delete_action(form, action):
+ return multiform.allSubFormsDisplayMode(form, action)
+label_delete_action = _("container-delete-button")
- @multiform.parentAction(_('Edit'),
- condition=multiform.allSubFormsDisplayMode)
- def handle_edit_action(self, action, data):
- #print "handle_edit_action",action,data,isSelected(self,action)
- if isSelected(self,action):
- self.newInputMode = True
+def condition_cancel_action(form, action):
+ return multiform.anySubFormInputMode(form, action)
+label_cancel_action = _('Cancel')
- @multiform.parentAction(_("Save"), inputMode=True,
- condition=multiform.anySubFormInputMode)
- def handle_save_action(self, action, data):
- if not isSelected(self,action):
- return
- if form.applyChanges(self.context, self.form_fields,
- data, self.adapters):
- notify(ObjectModifiedEvent(self.context))
- formatter = self.request.locale.dates.getFormatter(
- 'dateTime', 'medium')
- try:
- time_zone = idatetime.ITZInfo(self.request)
- except TypeError:
- time_zone = pytz.UTC
- m = {'date_time':formatter.format(datetime.datetime.now(time_zone))}
- self.status = (_("Updated on ${date_time}", mapping=m),)
- else:
- self.status = (_('No changes'),)
- ISelection(self.context).selected=False
- self.newInputMode = False
-
-
-class ContainerGridForm(multiform.MultiFormBase):
-
- itemFormFactory=ContainerItemForm
-
- template = ViewPageTemplateFile('grid.pt')
-
- @form.action(_('Cancel'),condition=multiform.anySubFormInputMode)
+class ContainerActions(object):
+
def handle_cancel_action(self, action, data):
for form in self.subForms.values():
form.newInputMode = False
- @form.action(_("container-paste-button"),
- condition=hasClipboardContents)
def handle_paste_action(self, action, data):
"""Paste ojects in the user clipboard to the container"""
self.form_reset = True
@@ -201,8 +176,6 @@
_("The given name(s) %s is / are already being used" %(
str(not_pasteable_ids))),)
- @form.action(_("container-cut-button"),
- condition=multiform.allSubFormsDisplayMode)
def handle_cut_action(self, action, data):
"""move objects specified in a list of object ids"""
@@ -242,8 +215,6 @@
clipboard.clearContents()
clipboard.addItems('cut', items)
- @form.action(_("container-copy-button"),
- condition=multiform.allSubFormsDisplayMode)
def handle_copy_action(self, action, data):
"""Copy objects specified in a list of object ids"""
@@ -284,8 +255,6 @@
clipboard.clearContents()
clipboard.addItems('copy', items)
- @form.action(_("container-delete-button"),
- condition=multiform.allSubFormsDisplayMode)
def handle_delete_action(self, action, data):
"""Delete objects specified in a list of object ids"""
container = self.context
@@ -301,11 +270,146 @@
else:
self.errors = (_("You didn't specify any ids to delete."),)
+def condition_edit_action(form, action):
+ return multiform.allSubFormsDisplayMode(form, action)
+label_edit_action = _("Edit")
-def getPrincipalClipboard(request):
- """Return the clipboard based on the request."""
- user = request.principal
- annotationutil = zapi.getUtility(IPrincipalAnnotationUtility)
- annotations = annotationutil.getAnnotations(user)
- return IPrincipalClipboard(annotations)
+def condition_save_action(form, action):
+ return multiform.anySubFormInputMode(form, action)
+label_save_action = _("Save")
+
+class ContainerItemActions(object):
+
+ def handle_edit_action(self, action, data):
+ if isSelected(self,action):
+ self.newInputMode = True
+
+ def handle_save_action(self, action, data):
+
+ if not isSelected(self,action):
+ return
+ if form.applyChanges(self.context, self.form_fields,
+ data, self.adapters):
+ notify(ObjectModifiedEvent(self.context))
+ formatter = self.request.locale.dates.getFormatter(
+ 'dateTime', 'medium')
+ try:
+ time_zone = idatetime.ITZInfo(self.request)
+ except TypeError:
+ time_zone = pytz.UTC
+ m = {'date_time':formatter.format(datetime.datetime.now(time_zone))}
+ self.status = (_("Updated on ${date_time}", mapping=m),)
+ else:
+ self.status = (_('No changes'),)
+ ISelection(self.context).selected=False
+ self.newInputMode = False
+
+
+class NameTextWidget(TextWidget):
+
+ def __call__(self):
+ content = super(NameTextWidget, self).__call__()
+ # bad!
+ context = self.context.context.context
+ # zmi icon
+ zmi_icon = component.queryMultiAdapter((context, self.request), name='zmi_icon')
+ if zmi_icon is not None:
+ icon = u'<img class="itemicon" src="%s" /> ' % zmi_icon.url()
+ else:
+ icon = u''
+ return icon + content
+
+
+class NameDisplayWidget(DisplayWidget):
+
+ def __call__(self):
+ content = super(NameDisplayWidget, self).__call__()
+ # bad!
+ context = self.context.context.context
+ # zmi icon
+ zmi_icon = component.queryMultiAdapter((context, self.request), name='zmi_icon')
+ if zmi_icon is not None:
+ icon = u'<img class="itemicon" src="%s" /> ' % zmi_icon.url()
+ else:
+ icon = u''
+ # link
+ url = zapi.absoluteURL(context, self.request)
+ result = u'<a href="%s/@@SelectedManagementView.html">%s%s</a>' % (url, icon, content)
+ return result
+
+
+class ContainerItemForm(multiform.ItemFormBase,
+ ContainerItemActions):
+
+ inputMode=False
+ forceInput=['selected']
+ template = ViewPageTemplateFile('griditem.pt')
+ form_fields = form.Fields(ISelection['selected'],
+ IMovableLocation['__name__'],
+ IWriteZopeDublinCore['title'],
+ IWriteZopeDublinCore['created'],
+ IWriteZopeDublinCore['modified'],
+ omit_readonly=False,render_context=True)
+ form_fields['created'].for_display=True
+ form_fields['modified'].for_display=True
+ form_fields['__name__'].custom_widget=multiform.MultiformWidgets(
+ NameTextWidget, NameDisplayWidget)
+
+ actions = form.Actions(
+ multiform.ParentAction(label_edit_action,
+ success='handle_edit_action',
+ condition=condition_edit_action),
+ multiform.ParentAction(label_save_action,
+ inputMode=True,
+ success='handle_save_action',
+ condition=condition_save_action)
+ )
+
+
+class ContainerGridForm(multiform.MultiFormBase,
+ ContainerActions):
+
+ itemFormFactory=ContainerItemForm
+
+ template = ViewPageTemplateFile('grid.pt')
+
+ actions = form.Actions(
+ form.Action(label_cancel_action,
+ success='handle_cancel_action',
+ condition=condition_cancel_action),
+ form.Action(label_paste_action,
+ success='handle_paste_action',
+ condition=condition_paste_action),
+ form.Action(label_cut_action,
+ success='handle_cut_action',
+ condition=condition_cut_action),
+ form.Action(label_copy_action,
+ success='handle_copy_action',
+ condition=condition_copy_action),
+ form.Action(label_delete_action,
+ success='handle_delete_action',
+ condition=condition_delete_action)
+ )
+
+
+class ContainerItemIndexForm(multiform.ItemFormBase):
+
+ inputMode=False
+ template = ViewPageTemplateFile('griditem.pt')
+ form_fields = form.Fields(IMovableLocation['__name__'],
+ IWriteZopeDublinCore['title'],
+ IWriteZopeDublinCore['created'],
+ IWriteZopeDublinCore['modified'],
+ omit_readonly=False,render_context=True)
+ form_fields['created'].for_display=True
+ form_fields['modified'].for_display=True
+ form_fields['__name__'].custom_widget=NameDisplayWidget
+
+
+class ContainerIndexForm(multiform.MultiFormBase):
+
+ itemFormFactory=ContainerItemIndexForm
+
+ template = ViewPageTemplateFile('grid.pt')
+
Modified: z3c.multiform/Sandbox/src/z3c/multiform/gridform.py
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/gridform.py 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/gridform.py 2006-12-07 14:53:23 UTC (rev 71478)
@@ -1,8 +1,11 @@
-from zope.component import getMultiAdapter
-from zope.interface import implements
+
+from zope import component, interface
from zope.formlib import namedtemplate
from zope.app.pagetemplate import ViewPageTemplateFile
-from zope.app.location.interfaces import ILocation
+from zope.location.interfaces import ILocation
+
+from zc import shortcut
+
from interfaces import IGridForm, IGridItemForm, ISorter
import multiform
@@ -15,13 +18,15 @@
class GridItemFormBase(multiform.ItemFormBase):
- implements(IGridItemForm)
+
+ interface.implements(IGridItemForm)
+
template = namedtemplate.NamedTemplate('default')
class GridFormBase(multiform.MultiFormBase):
- implements(IGridForm)
+ interface.implements(IGridForm)
default_batch_size = None
default_sort_on = None
@@ -34,21 +39,19 @@
super(GridFormBase,self).__init__(context, request)
-class FilterMapping(object):
+class FilterMapping(shortcut.Shortcut):
- implements(ILocation)
+ def __init__(self, context, request, form):
+ self.__parent__ = None
+ self.__name__ = None
+ self.raw_target = context
- def __init__(self, context, request, form):
- self.context = context
- self.request = request
if ILocation.providedBy(context):
self.__parent__ = context.__parent__
self.__name__ = context.__name__
-
- else:
- self.__parent__ = None
- self.__name__ = u""
+ self.request = request
self.form = form
+
self.batch_start = request.form.get(
'%s.handle.batch_start' % form.prefix,0)
self.batch_size = request.form.get(
@@ -71,17 +74,18 @@
sortField = field
break
if sortField:
- sorter = getMultiAdapter((sortField.field.interface,
- sortField.field),ISorter)
+ sorter = component.getMultiAdapter((sortField.field.interface,
+ sortField.field),
+ ISorter)
if sorter:
- items = sorter.sort(self.context.items())
+ items = sorter.sort(self.target.items())
if self.sort_reverse:
items.reverse()
keys = []
for key, value in items:
yield key
else:
- for key in self.context.keys():
+ for key in self.target.keys():
yield key
def keys(self):
@@ -104,11 +108,11 @@
def values(self):
for k in self.keys():
- yield self.context[k]
+ yield self.target[k]
def items(self):
for k in self.keys():
- yield k, self.context[k]
+ yield k, self.target[k]
def __iter__(self):
return iter(self.keys())
@@ -116,7 +120,7 @@
def __getitem__(self, key):
'''See interface `IReadContainer`'''
if key in self.keys():
- return self.context[key]
+ return self.target[key]
else:
raise KeyError, key
@@ -139,11 +143,11 @@
def __setitem__(self, key, object):
'''See interface `IWriteContainer`'''
- self.context.__setitem__(key, object)
+ self.target.__setitem__(key, object)
def __delitem__(self, key):
'''See interface `IWriteContainer`'''
if key in self.keys():
- self.context.__delitem__(key)
+ self.target.__delitem__(key)
else:
raise KeyError, key
Modified: z3c.multiform/Sandbox/src/z3c/multiform/gridform.txt
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/gridform.txt 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/gridform.txt 2006-12-07 14:53:23 UTC (rev 71478)
@@ -10,7 +10,7 @@
>>> from zope import interface, schema
>>> from zope.formlib import form
>>> from zope.publisher.browser import TestRequest
- >>> from zope.app.location.interfaces import ILocation
+ >>> from zope.location.interfaces import ILocation
>>> from z3c.multiform.interfaces import ISelection
>>> from z3c.multiform import multiform, gridform
@@ -108,12 +108,12 @@
>>> gf.update()
>>> print gf.render()
<div>
- <div><input ... name="form.n0.selected" type="checkbox" ... /></div>
+ <div><input ... name="form.sf.n0.selected" type="checkbox" ... /></div>
<div>0</div>
<div>n0</div>
</div>
<div>
- <div><input ... name="form.n1.selected" type="checkbox" ... /></div>
+ <div><input ... name="form.sf.n1.selected" type="checkbox" ... /></div>
<div>1</div>
<div>n1</div>
...
@@ -129,18 +129,18 @@
Now we are going to select some items. And the checkbox of the ``selected``
>>> request = TestRequest()
- >>> request.form['form.n1.selected']=u'on'
- >>> request.form['form.n0.selected.used']=u''
+ >>> request.form['form.sf.n1.selected']=u'on'
+ >>> request.form['form.sf.n0.selected.used']=u''
>>> gf = OrdersForm(orderMapping,request)
>>> gf.update()
>>> print gf.render()
<div>
- <div><input... name="form.n0.selected" type="checkbox" value="on" /></div>
+ <div><input... name="form.sf.n0.selected" type="checkbox" value="on" /></div>
<div>0</div>
<div>n0</div>
</div>
<div>
- <div><input... checked="checked" ... name="form.n1.selected" ... /></div>
+ <div><input... checked="checked" ... name="form.sf.n1.selected" ... /></div>
<div>1</div>
<div>n1</div>
...
@@ -151,24 +151,24 @@
>>> request = TestRequest()
>>> request.form['form.actions.edit']=u''
- >>> request.form['form.n0.selected.used']=u''
- >>> request.form['form.n1.selected']=u'on'
- >>> request.form['form.n2.selected.used']=u''
- >>> request.form['form.n3.selected.used']=u''
+ >>> request.form['form.sf.n0.selected.used']=u''
+ >>> request.form['form.sf.n1.selected']=u'on'
+ >>> request.form['form.sf.n2.selected.used']=u''
+ >>> request.form['form.sf.n3.selected.used']=u''
>>> gf = OrdersForm(orderMapping,request)
>>> res = gf()
>>> ISelection(gf.subForms['n1'].context).selected
True
>>> print res
<div>
- <div><input... name="form.n0.selected" type="checkbox" value="on" /></div>
+ <div><input... name="form.sf.n0.selected" type="checkbox" value="on" /></div>
<div>0</div>
<div>n0</div>
</div>
<div>
- <div><input... checked="checked" ... name="form.n1.selected" ... /></div>
+ <div><input... checked="checked" ... name="form.sf.n1.selected" ... /></div>
<div>1</div>
- <div><input... name="form.n1.name" ...</div>
+ <div><input... name="form.sf.n1.name" ...</div>
...
</div>
@@ -181,19 +181,19 @@
Now we test the actions which are displayed in each row.
>>> request = TestRequest()
- >>> #request.form['form.n1.actions.singleedit']=u''
+ >>> #request.form['form.sf.n1.actions.singleedit']=u''
>>> gf = OrdersForm(orderMapping,request)
>>> res = gf()
>>> sorted([action.__name__ for action in
... gf.subForms['n1'].availableActions()])
- [u'form.n1.actions.singleedit']
+ [u'form.sf.n1.actions.singleedit']
We call the singleedit to edit a single row.
>>> request = TestRequest()
- >>> request.form['form.n0.selected.used']=u''
- >>> request.form['form.n1.selected.used']=u''
- >>> request.form['form.n1.actions.singleedit']=u''
+ >>> request.form['form.sf.n0.selected.used']=u''
+ >>> request.form['form.sf.n1.selected.used']=u''
+ >>> request.form['form.sf.n1.actions.singleedit']=u''
>>> gf = OrdersForm(orderMapping,request)
>>> res = gf()
@@ -209,12 +209,12 @@
>>> gf.update()
>>> print gf.render()
<div>
- <div><input ... name="form.n1.selected" type="checkbox" ... /></div>
+ <div><input ... name="form.sf.n1.selected" type="checkbox" ... /></div>
<div>1</div>
<div>n1</div>
</div>
<div>
- <div><input ... name="form.n2.selected" type="checkbox" ... /></div>
+ <div><input ... name="form.sf.n2.selected" type="checkbox" ... /></div>
<div>2</div>
<div>n2</div>
</div>
@@ -243,7 +243,7 @@
>>> gf.update()
>>> print gf.render()
<div>
- <div><input ... name="form.n0.selected" ...
+ <div><input ... name="form.sf.n0.selected" ...
<div>1</div>
<div>n1</div>
...
Modified: z3c.multiform/Sandbox/src/z3c/multiform/interfaces.py
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/interfaces.py 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/interfaces.py 2006-12-07 14:53:23 UTC (rev 71478)
@@ -5,21 +5,17 @@
class IMultiForm(Interface):
-
"""multiform"""
class IItemForm(Interface):
-
"""a sub form for an item of a multiform"""
class IGridItemForm(IItemForm):
-
"""an form for an item of a grid form"""
class IGridForm(IMultiForm):
-
"""a special grid multiform"""
@@ -32,7 +28,6 @@
class ISelection(Interface):
-
"""Provides information about the selection state of an object"""
selected = schema.Bool(title=_(u'Selected'),default=False)
@@ -47,3 +42,17 @@
def sort(items):
"""return the items sorted. items are (key,value) tuples"""
+
+
+class IFilter(Interface):
+ """Provides the content of the context."""
+
+ batch_start = schema.Int()
+
+ batch_size = schema.Int()
+
+ sort_on = schema.TextLine()
+
+ sort_reverse = schema.Bool(default=False)
+
+ sort_columns = schema.List()
\ No newline at end of file
Modified: z3c.multiform/Sandbox/src/z3c/multiform/multiform.py
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/multiform.py 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/multiform.py 2006-12-07 14:53:23 UTC (rev 71478)
@@ -1,56 +1,58 @@
+
import copy
-from zope import interface
-from zope.component import getMultiAdapter
-from zope.interface import implements
+
+from zope import interface, component
import zope.i18n
-from zope.app.publisher.browser import BrowserView
from zope.app import zapi
+from zope.app.form.interfaces import IInputWidget, IDisplayWidget
from zope.app.form.browser.interfaces import IWidgetInputErrorView
-from zope.formlib import form
+from zope import formlib
from zope.formlib import namedtemplate
from zope.formlib.interfaces import IBoundAction
from zope.app.i18n import ZopeMessageFactory as _
-from interfaces import *
-from interfaces import IFormLocation,IItemForm
+import interfaces
+from interfaces import IFormLocation, ISelection
+
+
def isFormDisplayMode(f,action):
return not f.inputMode
def isFormInputMode(f,action):
return f.inputMode
-def anySubFormInputMode(form,action):
- if not IMultiForm.providedBy(form):
- form = form.parentForm
- for f in form.subForms.values():
- if f.inputMode:
+def anySubFormInputMode(f,action):
+ if not interfaces.IMultiForm.providedBy(f):
+ f = f.parentForm
+ for sf in f.subForms.values():
+ if sf.inputMode:
return True
-def allSubFormsDisplayMode(form,action):
- if not IMultiForm.providedBy(form):
- form = form.parentForm
- for f in form.subForms.values():
- if f.inputMode:
+def allSubFormsDisplayMode(f,action):
+ if not interfaces.IMultiForm.providedBy(f):
+ f = f.parentForm
+ for sf in f.subForms.values():
+ if sf.inputMode:
return False
return True
-class ItemAction(form.Action):
-
+class ItemAction(formlib.form.Action):
"""an action that is rendered in the itemform object and can
handle the toggle between input and display."""
- implements(IItemAction)
+ interface.implements(interfaces.IItemAction)
+
def __init__(self, label, **options):
self.inputMode = options.pop('inputMode',None)
super(ItemAction,self).__init__(label,**options)
-class ParentAction(form.Action):
-
+class ParentAction(formlib.form.Action):
"""an action that is rendered in the parent multiform object and
is applied to all subForms"""
- implements(IParentAction)
+ interface.implements(interfaces.IParentAction)
+
def __init__(self, label, **options):
self.inputMode = options.pop('inputMode',None)
super(ParentAction,self).__init__(label,**options)
@@ -73,7 +75,7 @@
res = self.__name__ in self.form.request
return res
- at namedtemplate.implementation(IParentAction)
+ at namedtemplate.implementation(interfaces.IParentAction)
def render_submit_button(self):
if IBoundAction.providedBy(self) and not self.available():
return ''
@@ -86,7 +88,7 @@
)
-class itemAction(form.action):
+class itemAction(formlib.form.action):
def __call__(self, success):
action = ItemAction(self.label, success=success, **self.options)
@@ -94,7 +96,7 @@
return action
-class parentAction(form.action):
+class parentAction(formlib.form.action):
def __call__(self, success):
action = ParentAction(self.label, success=success, **self.options)
@@ -102,9 +104,112 @@
return action
-class ItemFormBase(form.FormBase):
+class MultiformWidgets(object):
+
+ def __init__(self, inputWidget=None, displayWidget=None):
+ self.inputWidget = inputWidget
+ self.displayWidget = displayWidget
- implements(IItemForm)
+ def __call__(self, field, request, iface):
+ if iface == IDisplayWidget:
+ return self.displayWidget(field, request)
+ else:
+ return self.inputWidget(field, request)
+
+
+def _createWidget(form_field, field, request, iface):
+ if form_field.custom_widget is None:
+ return component.getMultiAdapter((field, request), iface)
+ else:
+ if isinstance(form_field.custom_widget, MultiformWidgets):
+ return form_field.custom_widget(field, request, iface)
+ else:
+ return form_field.custom_widget(field, request)
+
+
+def setUpWidgets(form_fields,
+ form_prefix=None, context=None, request=None, form=None,
+ data=(), adapters=None, ignore_request=False):
+
+ if request is None:
+ request = form.request
+ if context is None and form is not None:
+ context = form.context
+ if form_prefix is None:
+ form_prefix = form.prefix
+
+ widgets = []
+ adapter = None
+ for form_field in form_fields:
+ field = form_field.field
+ if form_field.render_context:
+ if adapters is None:
+ adapters = {}
+
+ # Adapt context, if necessary
+ interface = field.interface
+ adapter = adapters.get(interface)
+ if adapter is None:
+ if interface is None:
+ adapter = context
+ else:
+ adapter = interface(context)
+ adapters[interface] = adapter
+ if interface is not None:
+ adapters[interface.__name__] = adapter
+ field = field.bind(adapter)
+ else:
+ field = field.bind(context)
+
+ readonly = form_field.for_display
+ readonly = readonly or (field.readonly and not form_field.for_input)
+ readonly = readonly or (
+ (form_field.render_context & formlib.form.interfaces.DISPLAY_UNWRITEABLE)
+ and not formlib.form.canWrite(context, field)
+ )
+
+ if readonly:
+ iface = IDisplayWidget
+ else:
+ iface = IInputWidget
+ widget = _createWidget(form_field, field, request, iface)
+
+# if form_field.custom_widget is not None:
+# widget = form_field.custom_widget(field, request)
+# else:
+# if readonly:
+# widget = component.getMultiAdapter((field, request),
+# IDisplayWidget)
+# else:
+# widget = component.getMultiAdapter((field, request),
+# IInputWidget)
+
+ prefix = form_prefix
+ if form_field.prefix:
+ prefix += '.' + form_field.prefix
+
+ widget.setPrefix(prefix)
+
+ if ignore_request or readonly or not widget.hasInput():
+ # Get the value to render
+ if form_field.__name__ in data:
+ widget.setRenderedValue(data[form_field.__name__])
+ elif form_field.get_rendered is not None:
+ widget.setRenderedValue(form_field.get_rendered(form))
+ elif form_field.render_context:
+ widget.setRenderedValue(field.get(adapter))
+ else:
+ widget.setRenderedValue(field.default)
+
+ widgets.append((not readonly, widget))
+
+ return formlib.form.Widgets(widgets, len(form_prefix)+1)
+
+
+class ItemFormBase(formlib.form.FormBase):
+
+ interface.implements(interfaces.IItemForm)
+
forceInput = []
parentForm = None
inputMode = None
@@ -112,19 +217,19 @@
form_fields=[]
actions = []
- def __init__(self,context,request,parentForm):
+ def __init__(self, context, request, parentForm):
# we have to copy the default fields, so that we can mutate
# them in our instance
self.form_fields = copy.deepcopy(self.__class__.form_fields)
self.request = request
- self.context = getMultiAdapter([context,self],IFormLocation)
+ self.context = component.getMultiAdapter((context, self), IFormLocation)
self.parentForm = parentForm
def update(self):
self.form_reset = False
data = {}
- errors, action = form.handleSubmit(self.actions, data, self.validate)
+ errors, action = formlib.form.handleSubmit(self.actions, data, self.validate)
self.errors = errors
if errors:
@@ -138,29 +243,33 @@
self.form_result = result
- def setUpWidgets(self,ignore_request=False):
- super(ItemFormBase,self).setUpWidgets(ignore_request)
+ def setUpWidgets(self, ignore_request=False):
+ self.adapters = {}
+ self.widgets = setUpWidgets(
+ self.form_fields, self.prefix, self.context, self.request,
+ form=self, adapters=self.adapters, ignore_request=ignore_request)
# XXX how to check for the field
if self.widgets.get('selected'):
widget = self.widgets['selected']
- widget.setRenderedValue(ISelection(self.context).selected)
+ widget.setRenderedValue(interfaces.ISelection(self.context).selected)
def availableActions(self):
# we need to override this, because we should not return the
# parentActions
- if not hasattr(self,'actions'):
+ if not hasattr(self, 'actions'):
return []
actions = [action for action in self.actions
- if not IParentAction.providedBy(action)]
- return form.availableActions(self, actions)
+ if not interfaces.IParentAction.providedBy(action)]
+ return formlib.form.availableActions(self, actions)
def availableParentActions(self):
- if not hasattr(self,'actions'):
+ if not hasattr(self, 'actions'):
return []
actions = [action for action in self.actions
- if IParentAction.providedBy(action)]
- return form.availableActions(self, actions)
+ if interfaces.IParentAction.providedBy(action)]
+ return formlib.form.availableActions(self, actions)
+
# copy from formlib with get
def availableActions(form, actions):
result = []
@@ -171,10 +280,10 @@
return result
+class MultiFormBase(formlib.form.FormBase):
-class MultiFormBase(form.FormBase):
+ interface.implements(interfaces.IMultiForm)
- implements(IMultiForm)
itemFormFactory = ItemFormBase
subForms={}
form_fields = []
@@ -183,34 +292,43 @@
subFormInputMode = {}
selection = []
actions = []
+ forms = []
+ def __init__(self, context, request):
+ super(MultiFormBase,self).__init__(context, request)
+ self.filter = self.context
+
def update(self):
+ self.forms = list(self.filter.keys())
self.checkInputMode()
self.updateSelection()
super(MultiFormBase,self).update()
preForms = list(self.getForms())
for form in preForms:
form.update()
+ self.forms = list(self.filter.keys())
postForms = list(self.getForms())
refresh = postForms != preForms
for form in postForms:
+ if form.form_reset is True:
+ refresh = True
if form.newInputMode is not None:
newInputMode = form.newInputMode
- context = self.context[form.context.__name__]
+ context = self.filter[form.context.__name__]
name = context.__name__
self.setUpForm(name, context, newInputMode,
ignore_request=True)
self.subFormInputMode[name] = newInputMode
refresh = True
- if refresh:
- self.refreshSubActionNames()
+ if refresh:
+ self.refreshSubActionNames()
def setUpWidgets(self, *args, **kw):
super(MultiFormBase,self).setUpWidgets(*args,**kw)
self.setUpForms(*args, **kw)
def setUpForm(self, name, item, inputMode, *args, **kw):
- prefix = (self.prefix and self.prefix+'.' or '') + name
+ prefix = self.prefix + '.sf.' + name
subForm = self.newSubForm(item)
if inputMode is not None and not inputMode:
forceInput = self.itemFormFactory.forceInput
@@ -223,31 +341,32 @@
self.subForms[name] = subForm
def setUpForms(self, *args, **kw):
+ self.forms = list(self.filter.keys())
self.subForms = {}
- for name, item in self.context.items():
- inputMode = self.subFormInputMode.get(name,self.itemFormFactory.inputMode)
- self.setUpForm(name, item, inputMode)
+ for key in self.forms:
+ item = self.filter[key]
+ inputMode = self.subFormInputMode.get(key, self.itemFormFactory.inputMode)
+ self.setUpForm(key, item, inputMode)
self.refreshSubActionNames()
def getForms(self):
# we have to use the keys here to support all actions that
# modifies the keys of our mapping, e.g. rename, delete
- keys = list(self.context.keys())
- deleted = filter(lambda x: x not in keys,self.subForms.keys())
+ keys = self.forms
+ deleted = filter(lambda x: x not in keys, self.subForms.keys())
for k in deleted:
del(self.subForms[k])
try:
del(self.subFormInputMode[k])
except KeyError:
pass
- for name in self.context.keys():
- if not self.subForms.has_key(name):
- self.setUpForm(name,self.context[name],
+ for key in self.forms:
+ if not self.subForms.has_key(key):
+ self.setUpForm(key, self.filter[key],
self.itemFormFactory.inputMode,
ignore_request=True)
- yield self.subForms[name]
+ yield self.subForms[key]
-
def refreshSubActionNames(self):
availableActions = set()
for subForm in self.getForms():
@@ -259,55 +378,78 @@
name = '%s.%s' % (self.prefix,action.__name__)
if name in availableActions:
self.subActionNames.append(name)
-
-
+
+ def checkInputModeAction(self, action):
+ if interfaces.IItemAction.providedBy(action):
+ for key in self.forms:
+ name = self.prefix + '.sf.' + key + action.__name__
+ if name in self.request.form:
+ return action.inputMode
+ if interfaces.IParentAction.providedBy(action):
+ name = self.prefix + '.' + action.__name__
+ if name in self.request.form:
+ return action.inputMode
+ return None
+
def checkInputMode(self):
self.subFormInputMode = {}
+ # check if any action with inputMode Flag in request
inputMode = None
- for action in self.itemFormFactory.actions:
- name = '%s.%s' % (self.prefix,action.__name__)
- if name in self.request.form and getattr(action,
- 'inputMode', None) is not None:
- inputMode = action.inputMode
- break
+ # check itemForm actions
+ if hasattr(self.itemFormFactory, 'actions'):
+ for action in self.itemFormFactory.actions:
+ if getattr(action, 'inputMode', None) is not None:
+ inputMode = self.checkInputModeAction(action)
+ if inputMode is not None:
+ break
+ # check form actions
+ if hasattr(self, 'actions'):
+ for action in self.actions:
+ if getattr(action, 'inputMode', None) is not None:
+ inputMode = self.checkInputModeAction(action)
+ if inputMode is not None:
+ break
if inputMode is None:
return
- inputField = None
- if len(self.context) > 0:
- for name, item in self.context.items():
- break
- tmpForm = self.newSubForm(item)
+
+ # check which forms in inputMode
+ if len(self.forms) > 0:
+ # get any inputfield
+ tmpForm = self.newSubForm(self.filter[self.forms[0]])
+ inputField = None
for field in tmpForm.form_fields:
if not field.for_display and field.__name__ not in tmpForm.forceInput:
inputField = field
break
- for name in self.context.keys():
- prefix = self.prefix + '.' + name + '.' + field.__name__
- self.subFormInputMode[name] = (prefix in self.request.form)
-
+ if inputField is None:
+ # should not be happen
+ return
+ for key in self.forms:
+ name = self.prefix + '.sf.' + key + '.' + inputField.__name__
+ self.subFormInputMode[key] = (name in self.request.form)
+
def updateSelection(self):
for field in self.itemFormFactory.form_fields:
- if issubclass(field.field.interface,ISelection):
- form_fields = form.Fields(field)
- for name,item in self.context.items():
+ if issubclass(field.field.interface,interfaces.ISelection):
+ form_fields = formlib.form.Fields(field)
+ for key in self.forms:
+ item = self.filter[key]
sForm = SelectionForm(item, self.request, form_fields)
- prefix = (self.prefix and self.prefix+'.' or '') + name
- sForm.setPrefix(prefix)
+ name = self.prefix + '.sf.' + key
+ sForm.setPrefix(name)
sForm.form_fields = form_fields
sForm.setUpWidgets()
data = {}
try:
- form.getWidgetsData(sForm.widgets, sForm.prefix, data)
+ formlib.form.getWidgetsData(sForm.widgets, sForm.prefix, data)
except:
pass
- form.applyChanges(sForm.context, sForm.form_fields, data)
+ formlib.form.applyChanges(sForm.context, sForm.form_fields, data)
return
- def newSubForm(self,item):
-
+ def newSubForm(self, item):
"""creates a new instance from the itemFormFactory for
temporary usage"""
-
return self.itemFormFactory(item,self.request,self)
def availableSubActions(self):
@@ -325,9 +467,10 @@
yield action
-class SelectionForm(form.FormBase):
+class SelectionForm(formlib.form.FormBase):
def __init__(self, context, request, form_fields):
self.form_fields = form_fields
self.request = request
- self.context = getMultiAdapter([context,self],IFormLocation)
+ self.context = component.getMultiAdapter((context,self), IFormLocation)
+
Modified: z3c.multiform/Sandbox/src/z3c/multiform/selection.py
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/selection.py 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/selection.py 2006-12-07 14:53:23 UTC (rev 71478)
@@ -1,12 +1,15 @@
-from zope.interface import implements
+from zope import interface, component
+
from zope.proxy import ProxyBase, getProxiedObject
from zope.security.checker import NamesChecker,defineChecker
from zope.security.proxy import removeSecurityProxy
-from zope.app.decorator import DecoratorSpecificationDescriptor
-from zope.app.decorator import DecoratedSecurityCheckerDescriptor
-from zope.app.location import location
+from zope.decorator import DecoratorSpecificationDescriptor
+from zope.decorator import DecoratedSecurityCheckerDescriptor
+from zope.location import location
+from zope.location.interfaces import ILocation
+from zope.formlib.interfaces import IForm
-from interfaces import ISelection,IFormLocation
+from z3c.multiform.interfaces import ISelection, IFormLocation
class FormLocationSelection(object):
@@ -37,7 +40,8 @@
False
"""
- implements(ISelection)
+ interface.implements(ISelection)
+ component.adapts(IFormLocation)
def __init__(self,context):
self.context = context
@@ -104,7 +108,9 @@
"""
- implements(IFormLocation)
+# interface.implements(IFormLocation)
+ interface.implementsOnly(IFormLocation)
+ component.adapts(ILocation, IForm)
__slots__ = '__form__'
__safe_for_unpickling__ = True
@@ -134,5 +140,3 @@
formLocationChecker = NamesChecker(['__form__'])
defineChecker(FormLocationProxy, formLocationChecker)
-
-
Copied: z3c.multiform/Sandbox/src/z3c/multiform/selection.txt (from rev 71090, z3c.multiform/Sandbox/src/z3c/multiform/selections.txt)
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/selections.txt 2006-11-06 15:49:14 UTC (rev 71090)
+++ z3c.multiform/Sandbox/src/z3c/multiform/selection.txt 2006-12-07 14:53:23 UTC (rev 71478)
@@ -0,0 +1,13 @@
+======================
+ Multiform Selections
+======================
+
+Selecting subforms of a multiform is a common task which is supported
+by the multiform package. Selections are implemented by the ISelection
+interface. This interface can be adapted to from objects which
+implement IFormLocation which in turn can be adapted to from ILocation
+and IForm. The IFormLocation adpater is a proxy which provides the
+``__form_name__`` attribute.
+
+The ISelection implementation in this package uses the request to
+store the selection state, by using the ILocationForm interface.
Deleted: z3c.multiform/Sandbox/src/z3c/multiform/selections.txt
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/selections.txt 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/selections.txt 2006-12-07 14:53:23 UTC (rev 71478)
@@ -1,14 +0,0 @@
-======================
- Multiform Selections
-======================
-
-Selecting subforms of a multiform is a common task which is supported
-by the multiform package. Selections are implemented by the ISelection
-interface. This interface can be adapted to from objects which
-implement IFormLocation which in turn can be adapted to from ILocation
-and IForm. The IFormLocation adpater is a proxy which provides the
-``__form_name__`` attribute.
-
-The ISelection implementation in this package uses the request to
-store the selection state, by using the ILocationForm interface.
-
Modified: z3c.multiform/Sandbox/src/z3c/multiform/sort.py
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/sort.py 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/sort.py 2006-12-07 14:53:23 UTC (rev 71478)
@@ -1,11 +1,14 @@
-from zope.interface import implements
+from zope import interface, component
+from zope.interface import Interface
+from zope.schema.interfaces import IField
-from interfaces import ISorter
+from z3c.multiform.interfaces import ISorter
class SchemaSorter(object):
- implements(ISorter)
+ interface.implements(ISorter)
+ component.adapts(Interface, IField)
def __init__(self,schema,field):
self.schema = schema
@@ -13,7 +16,6 @@
self.field = field
def sort(self,seq):
-
l = []
def _v(o):
o = self.schema(o)
Modified: z3c.multiform/Sandbox/src/z3c/multiform/tests.py
===================================================================
--- z3c.multiform/Sandbox/src/z3c/multiform/tests.py 2006-12-07 13:45:16 UTC (rev 71477)
+++ z3c.multiform/Sandbox/src/z3c/multiform/tests.py 2006-12-07 14:53:23 UTC (rev 71478)
@@ -3,7 +3,7 @@
from zope import component
from zope.testing.doctestunit import DocFileSuite, DocTestSuite
-from zope.app.testing import setup
+from zope.app.testing import setup, ztapi
import zope.schema.interfaces
import zope.app.form.browser
import zope.publisher.interfaces.browser
@@ -15,6 +15,7 @@
import multiform
import selection
import sort
+from interfaces import IFormLocation, ISelection
def setUp(test):
@@ -62,24 +63,10 @@
],
zope.app.form.interfaces.IInputWidget,
)
- component.provideAdapter(
- selection.FormLocationProxy,
- [zope.app.location.interfaces.ILocation,
- zope.formlib.interfaces.IForm
- ],
- interfaces.IFormLocation
- )
- component.provideAdapter(
- selection.FormLocationSelection,
- [interfaces.IFormLocation],
- interfaces.ISelection
- )
- component.provideAdapter(
- sort.SchemaSorter,
- [zope.interface.Interface,
- zope.schema.interfaces.IField],
- interfaces.ISorter
- )
+ component.provideAdapter(selection.FormLocationProxy)
+ component.provideAdapter(selection.FormLocationSelection)
+ component.provideAdapter(sort.SchemaSorter)
+
component.provideAdapter(gridform.default_grid_template,
name="default")
component.provideAdapter(gridform.default_griditem_template,
@@ -98,6 +85,10 @@
DocTestSuite('z3c.multiform.selection',
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
),
+ DocFileSuite('selection.txt',
+ setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
DocFileSuite('README.txt',
setUp=setUp, tearDown=tearDown,
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
More information about the Checkins
mailing list