[Zope3-checkins] CVS: Zope3/src/zope/app/workflow/browser/stateful
- __init__.py:1.1 add.pt:1.1 addstate.pt:1.1
addtransition.pt:1.1 configure.zcml:1.1 content_filter.py:1.1
contentworkflow.py:1.1 contentworkflow_index.pt:1.1
contentworkflow_registry.pt:1.1 definition.py:1.1
definition_edit.pt:1.1 definition_index.pt:1.1
definition_states.pt:1.1 definition_transitions.pt:1.1
filterTest.pt:1.1 filteradapter.py:1.1 instance.py:1.1
instance_manage.pt:1.1 interfaces.py:1.1
published_content.pt:1.1 testobject.zcml:1.1
Philipp von Weitershausen
philikon at philikon.de
Fri Feb 27 11:50:40 EST 2004
Update of /cvs-repository/Zope3/src/zope/app/workflow/browser/stateful
In directory cvs.zope.org:/tmp/cvs-serv22977/workflow/browser/stateful
Added Files:
__init__.py add.pt addstate.pt addtransition.pt configure.zcml
content_filter.py contentworkflow.py contentworkflow_index.pt
contentworkflow_registry.pt definition.py definition_edit.pt
definition_index.pt definition_states.pt
definition_transitions.pt filterTest.pt filteradapter.py
instance.py instance_manage.pt interfaces.py
published_content.pt testobject.zcml
Log Message:
Centralized the workflow interfaces and browser views in
zope.app.workflow.
=== Added File Zope3/src/zope/app/workflow/browser/stateful/__init__.py ===
# make this directory a package
=== Added File Zope3/src/zope/app/workflow/browser/stateful/add.pt ===
<html metal:use-macro="views/standard_macros/dialog">
<body>
<div metal:fill-slot="body">
<form action="action.html" method="post">
<table class="TypeListing" cellpadding="3">
<caption i18n:translate="">Add Content</caption>
<tbody tal:repeat="info view/addingInfo">
<tr>
<td class="Selector">
<input type="radio" name="type_name"
tal:attributes="value info/action; id info/action" />
</td>
<td class="TypeName">
<label style="font-weight: bold;"
tal:attributes="for info/action">
<span tal:replace="info/title" >Folder</span>
</label>
<div class="TypeDescription" tal:content="info/description">
Folders are generic containers for content, including other
folders.
</div>
</td>
</tr>
</tbody>
<tbody tal:condition="nothing">
<tr>
<td class="Selector">
<input type="radio" name="type_name" value="" />
</td>
<td class="TypeName">
<img alt="Folder" src="../../ZMI/www/document_icon.gif" />
Document
</td>
</tr>
<tr>
<td class="Selector"><br /></td>
<td class="TypeDescription">
Documents are simple textual content.
</td>
</tr>
</tbody>
<tr>
<td><br /></td>
<td>
<input type="text" name="id"
tal:condition="view/namesAccepted"
tal:attributes="value request/id | nothing"
/>
<input type="submit" value="Add"
i18n:attributes="value add-button"/>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/workflow/browser/stateful/addstate.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title metal:fill-slot="title" i18n:translate="">Add State</title>
</head>
<body>
<div metal:fill-slot="body">
<form action="." method="post" enctype="multipart/form-data">
<div class="row">
<div class="label" i18n:translate="">Id</div>
<div class="field">
<input type="text" name="id" size="40" value="" />
</div>
</div>
<div class="row">
<div class="controls">
<input type="submit" name="action.html:method" value="Add"
i18n:attributes="value add-button"/>
</div>
</div>
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/workflow/browser/stateful/addtransition.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title metal:fill-slot="title" i18n:translate="">Add Transition</title>
</head>
<body>
<div metal:fill-slot="body">
<form action="." method="post" enctype="multipart/form-data">
<div class="row">
<div class="label" i18n:translate="">Id</div>
<div class="field">
<input type="text" name="id" size="40" value="" />
</div>
</div>
<div class="row">
<div class="label" i18n:translate="">Source Satte</div>
<div class="field">
<select name="source">
<option tal:repeat="state states"
tal:content="state" />
</select>
</div>
</div>
<div class="row">
<div class="label" i18n:translate="">Destination Satte</div>
<div class="field">
<select name="destination">
<option tal:repeat="state states"
tal:content="state" />
</select>
</div>
</div>
<div class="row">
<div class="label" i18n:translate="">Condition</div>
<div class="field">
<input type="text" name="condition" size="40" value="" />
</div>
</div>
<div class="row">
<div class="label" i18n:translate="">Permission</div>
<div class="field">
<!-- XXX: This should be really a Permission widget -->
<input type="text" name="permission" size="40" value="" />
</div>
</div>
<div class="row">
<div class="controls">
<input type="submit" name="action.html:method" value="Add"
i18n:attributes="value add-button"/>
</div>
</div>
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/workflow/browser/stateful/configure.zcml ===
<zope:configure
xmlns:zope="http://namespaces.zope.org/zope"
xmlns="http://namespaces.zope.org/browser">
<!-- Stateful Workflow Process Definition -->
<menuItem
menu="add_component"
for="zope.app.interfaces.container.IAdding"
action="StatefulProcessDefinition"
title="Stateful Process Definition"
description="A stateful workflow process definition" />
<page
for="zope.app.workflow.interfaces.stateful.IStatefulProcessDefinition"
name="index.html"
class=".definition.StatefulProcessDefinitionView"
permission="zope.ManageServices"
template="definition_index.pt" />
<editform
schema="zope.app.workflow.interfaces.stateful.IStatefulProcessDefinition"
name="edit.html"
template="definition_edit.pt"
class=".definition.RelevantDataSchemaEdit"
menu="zmi_views" title="Relevant Data Schema"
permission="zope.workflow.ManageProcessDefinitions"/>
<menuItems
for="zope.app.workflow.interfaces.stateful.IStatefulProcessDefinition"
menu="zmi_actions">
<menuItem
title="Manage States" action="states/contents.html" />
<menuItem
title="Manage Transitions" action="transitions/contents.html" />
</menuItems>
<!-- States/Transitions Container Adding Menus -->
<menu id="add_stateful_states" title="State Items"
usage="addingdialog"/>
<menu id="add_stateful_transitions" title="Transition Items"
usage="addingdialog" />
<!-- States Container -->
<view
for="zope.app.workflow.interfaces.stateful.IStatefulStatesContainer"
name="+"
menu="zmi_actions" title="Add"
class=".definition.StatesContainerAdding"
permission="zope.workflow.ManageProcessDefinitions"
allowed_attributes="addingInfo">
<page name="index.html" template="add.pt" />
<page name="action.html" attribute="action" />
</view>
<!-- State -->
<!-- nothing to edit yet
<editform
schema="zope.app.workflow.interfaces.stateful.IState"
name="edit.html"
menu="zmi_views"
label="Edit a State"
permission="zope.workflow.ManageProcessDefinitions" />
-->
<addform
name="AddState"
menu="add_stateful_states" title="Stateful State"
schema="zope.app.workflow.interfaces.stateful.IState"
class=".definition.StateAddFormHelper"
permission="zope.workflow.ManageProcessDefinitions"
content_factory="zope.app.workflow.stateful.definition.State"
arguments=""
fields="" />
<!-- Transitions Container -->
<view
for="zope.app.workflow.interfaces.stateful.IStatefulTransitionsContainer"
name="+"
menu="zmi_actions" title="Add"
class=".definition.TransitionsContainerAdding"
permission="zope.workflow.ManageProcessDefinitions"
allowed_attributes="addingInfo">
<page name="index.html" template="add.pt" />
<page name="action.html" attribute="action" />
</view>
<!-- Transition -->
<editform
schema="zope.app.workflow.interfaces.stateful.ITransition"
name="edit.html"
menu="zmi_views"
label="Edit a Transition"
permission="zope.workflow.ManageProcessDefinitions" />
<addform
name="AddTransition"
menu="add_stateful_transitions" title="Stateful Transition"
schema="zope.app.workflow.interfaces.stateful.ITransition"
permission="zope.workflow.ManageProcessDefinitions"
content_factory="zope.app.workflow.stateful.definition.Transition"
arguments="sourceState destinationState"
keyword_arguments="condition script permission triggerMode"
fields="sourceState destinationState condition script
permission triggerMode"/>
<!-- ContentWorkflowsUtility -->
<menuItem
menu="add_component"
for="zope.app.interfaces.container.IAdding"
action="ContentWorkflowsManager"
title="Content Workflows Manager"
description="An utility to manage content and workflow interaction." />
<page
name="index.html"
for="zope.app.workflow.interfaces.stateful.IContentWorkflowsManager"
class=".contentworkflow.ContentWorkflowsManagerView"
permission="zope.ManageServices"
template="contentworkflow_index.pt"
menu="zmi_views" title="Overview"/>
<page
name="registry.html"
for="zope.app.workflow.interfaces.stateful.IContentWorkflowsManager"
class=".contentworkflow.ManageContentProcessRegistry"
permission="zope.ManageServices"
template="contentworkflow_registry.pt"
menu="zmi_views" title="Content/Process Registry"/>
<!-- ProcessInstanceContainerAdaptable -->
<pages
for="zope.app.workflow.interfaces.IProcessInstanceContainerAdaptable"
permission="zope.workflow.UseProcessInstances"
class=".instance.ManagementView">
<page name="workflows.html" template="instance_manage.pt"
menu="zmi_views" title="Workflows"/>
<page name="fireTransition.html" attribute="fireTransition" />
</pages>
<page
for="zope.app.interfaces.container.IContentContainer"
permission="zope.View"
class="zope.app.workflow.browser.stateful.content_filter.FilterList"
name="published_content.html"
attribute="published_content" />
<!-- uhm ... this seems to be too generic in its definition
and not really nice as well. -->
<zope:adapter
factory=".filteradapter.FilterAdapter"
provides=".interfaces.IContentFilterAdapter"
for="zope.app.interfaces.annotation.IAttributeAnnotatable"
permission="zope.View" /> <!-- XXX is this permission right? -->
<!--include file="testobject.zcml"/-->
</zope:configure>
=== Added File Zope3/src/zope/app/workflow/browser/stateful/content_filter.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""filtering view for ProcessInstances of a stateful workflow
$Id: content_filter.py,v 1.1 2004/02/27 16:50:38 philikon Exp $
"""
from zope.component import queryAdapter
from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
from zope.app.browser.container.contents import Contents
from zope.app.workflow.interfaces import IProcessInstanceContainerAdaptable
from zope.app.workflow.interfaces import IProcessInstanceContainer
__metaclass__ = type
class FilterList(Contents):
__used_for__ = IProcessInstanceContainerAdaptable
def filterByState(self, objList, state, workflow='default'):
"""Filter a list of objects according to given workflow and state
objList ... list of objects
state ... name of a state (of the given workflow) in which the result
objects must be
workflow ... name of a workflow to which result objects must be attached
"""
res = []
for obj in objList:
adapter = queryAdapter(obj['object'], IProcessInstanceContainer)
if adapter:
for item in adapter.values():
if item.processDefinitionName != workflow:
continue
if item.status == state:
res.append(obj)
break
return res
published_content = ViewPageTemplateFile('published_content.pt')
# XXX: This method assumes you have a publishing workflow (SR)
def listPublishedItems(self):
return self.filterByState(self.listContentInfo(), 'published')
=== Added File Zope3/src/zope/app/workflow/browser/stateful/contentworkflow.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ContentWorkflow Manager views
$Id: contentworkflow.py,v 1.1 2004/02/27 16:50:38 philikon Exp $
"""
from zope.app.introspector import interfaceToName, nameToInterface
from zope.app.component.interfacefield import InterfaceField
from zope.app.i18n import ZopeMessageIDFactory as _
from zope.app.form.utility import setUpWidgets
from zope.app.services.servicenames import Workflows
from zope.component import getService
from zope.interface import Interface
from zope.publisher.browser import BrowserView
from zope.schema.vocabulary import VocabularyListField
from zope.security.proxy import trustedRemoveSecurityProxy
__metaclass__ = type
class ContentWorkflowsManagerView:
def getName(self):
return """I'm a ContentWorkflows Utility"""
class IContentProcessMapping(Interface):
iface = InterfaceField(
title=u"Content Interface",
description=u"Specifies the interface that characterizes a particular "
u"content type. Select one interface at a time.",
required=True)
name = VocabularyListField(
title = u"Process Definition Name",
description = u"The name of the process that will be available for "
u"this content type. Feel free to select several at "
u"once.",
required = True,
vocabulary = "ProcessDefinitions")
class ManageContentProcessRegistry(BrowserView):
def __init__(self, *args):
super(ManageContentProcessRegistry, self).__init__(*args)
setUpWidgets(self, IContentProcessMapping)
self.process_based = int(self.request.get('process_based', '1'))
def getProcessInterfacesMapping(self):
mapping = []
wf = getService(self.context, Workflows)
for name in wf.getProcessDefinitionNames():
ifaces = self.context.getInterfacesForProcessName(name)
ifaces = map(lambda i: interfaceToName(self.context, i), ifaces)
if ifaces:
mapping.append({'name': name, 'ifaces': ifaces})
return mapping
def getInterfaceProcessesMapping(self):
mapping = []
# Nothing bad here; we just read the registry data
registry = trustedRemoveSecurityProxy(self.context)._registry
for iface, names in registry.items():
mapping.append({'iface': interfaceToName(self.context, iface),
'names': names})
return mapping
def update(self):
status = ''
if 'ADD' in self.request:
for name in self.name_widget.getInputValue():
self.context.register(self.iface_widget.getInputValue(), name)
status = _('Mapping(s) added.')
elif 'REMOVE' in self.request:
mappings = self.request.get('mappings', [])
for entry in mappings:
split = entry.rfind(':')
name = entry[:split]
iface = nameToInterface(self.context, entry[split+1:])
self.context.unregister(iface, name)
status = _('Mapping(s) removed.')
elif 'SWITCH' in self.request:
self.request.response.setCookie('process_based',
self.request.get('other_view'))
self.process_based = int(self.request.get('other_view'))
return status
=== Added File Zope3/src/zope/app/workflow/browser/stateful/contentworkflow_index.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title metal:fill-slot="title" i18n:translate="">
Registration "Service" Control Page
</title>
</head>
<body>
<div metal:fill-slot="body">
<h1 i18n:translate="">Subscription control</h1>
<!-- XXX: Too much logic for a template -->
<span tal:condition="request/callSubscribe|nothing" tal:omit-tag="">
<span tal:define="dummy context/subscribe" tal:omit-tag=""/>
</span>
<span tal:condition="request/callUnsubscribe|nothing" tal:omit-tag="">
<span tal:define="dummy context/unsubscribe" tal:omit-tag=""/>
</span>
<form action="" method="post">
<span tal:condition="context/isSubscribed" tal:omit-tag="">
<span i18n:translate="">Subscription state: ON</span>
<input type="submit" value="Unsubscribe" name="callUnsubscribe"
i18n:attributes="value unsubscribe-button"/>
</span>
<span tal:condition="not:context/isSubscribed" tal:omit-tag="">
<span i18n:translate="">Subscription state: OFF</span>
<input type="submit" value="Subscribe" name="callSubscribe"
i18n:attributes="value unsubscribe-button"/>
</span>
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/workflow/browser/stateful/contentworkflow_registry.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title metal:fill-slot="title" i18n:translate="">
Process Definition <-> Content Type Registry
</title>
</head>
<body>
<div metal:fill-slot="body">
<p tal:define="status view/update"
tal:condition="status"
tal:content="status" />
<p i18n:translate="">
This screen let's you specify which content types (by interface) can
receive which workflows (process definitions).</p>
<form action="./@@registry.html" method="POST">
<h3 i18n:translate="">Available Mappings</h3>
<ul tal:condition="view/process_based">
<input type="hidden" name="other_view" value="0"/>
<li tal:repeat="process view/getProcessInterfacesMapping">
<b tal:content="process/name" /><br/>
<tal:block repeat="iface process/ifaces">
<input type="checkbox" name="mappings:list"
tal:attributes="value string:${process/name}:${iface}">
<d tal:replace="iface"/><br/>
</tal:block>
</li>
</ul>
<ul tal:condition="not: view/process_based">
<input type="hidden" name="other_view" value="1"/>
<li tal:repeat="iface view/getInterfaceProcessesMapping">
<b tal:content="iface/iface" /><br/>
<tal:block repeat="name iface/names">
<input type="checkbox" name="mappings:list"
tal:attributes="value string:${name}:${iface/iface}">
<d tal:replace="name"/><br/>
</tal:block>
</li>
</ul>
<div class="row">
<div class="controls" style="width: 100%">
<input type="submit" value="Switch View" name="SWITCH"
i18n:attributes="value switch-view-button" />
<input type="submit" value="Remove Mappings" name="REMOVE"
i18n:attributes="value remove-mappings-button" />
</div>
</div>
<h3 i18n:translate="">Add new Mapping</h3>
<div class="row"
tal:content="structure view/iface_widget/row" />
<div class="row"
tal:content="structure view/name_widget/row" />
<div class="row">
<div class="controls">
<input type="submit" value="Add Mappings" name="ADD"
i18n:attributes="value add-mappings-button" />
</div>
</div>
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/workflow/browser/stateful/definition.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ProcessDefinition registration adding view
$Id: definition.py,v 1.1 2004/02/27 16:50:38 philikon Exp $
"""
__metaclass__ = type
from zope.proxy import removeAllProxies
from zope.publisher.browser import BrowserView
from zope.app.browser.container.adding import Adding
from zope.app.browser.form.submit import Update
from zope.app.browser.form.editview import EditView
from zope.app.workflow.stateful.definition import State, Transition
from zope.schema import getFields
from zope.app.security.permission import PermissionField
from zope.security.checker import CheckerPublic
from zope.security.proxy import trustedRemoveSecurityProxy
from zope.app.form.utility import setUpWidget
class StatesContainerAdding(Adding):
"""Custom adding view for StatesContainer objects."""
menu_id = "add_stateful_states"
class TransitionsContainerAdding(Adding):
"""Custom adding view for TransitionsContainer objects."""
menu_id = "add_stateful_transitions"
def getProcessDefinition(self):
return self.context.getProcessDefinition()
# XXX Temporary ...
class StateAddFormHelper:
# XXX Hack to prevent from displaying an empty addform
def __call__(self, template_usage=u'', *args, **kw):
if not len(self.fieldNames):
self.request.form[Update] = 'submitted'
return self.update()
return super(StateAddFormHelper, self).__call__(template_usage,
*args, **kw)
class StatefulProcessDefinitionView(BrowserView):
def getName(self):
return """I'm a stateful ProcessInstance"""
class RelevantDataSchemaEdit(EditView):
def __init__(self, context, request):
super(RelevantDataSchemaEdit, self).__init__(context, request)
self.buildPermissionWidgets()
def buildPermissionWidgets(self):
schema = self.context.relevantDataSchema
if schema is not None:
for name, field in getFields(schema).items():
# Try to get current settings
if self.context.schemaPermissions.has_key(name):
get_perm, set_perm = self.context.schemaPermissions[name]
else:
get_perm, set_perm = None, None
# Create the Accessor Permission Widget for this field
permField = PermissionField(
__name__=name+'_get_perm',
title=u"Accessor Permission",
default=CheckerPublic,
required=False)
setUpWidget(self, name+'_get_perm', permField, value=get_perm)
# Create the Mutator Permission Widget for this field
permField = PermissionField(
__name__=name+'_set_perm',
title=u"Mutator Permission",
default=CheckerPublic,
required=False)
setUpWidget(self, name+'_set_perm', permField, value=set_perm)
def update(self):
status = ''
if Update in self.request:
status = super(RelevantDataSchemaEdit, self).update()
self.buildPermissionWidgets()
elif 'CHANGE' in self.request:
schema = self.context.relevantDataSchema
perms = trustedRemoveSecurityProxy(self.context.schemaPermissions)
for name, field in getFields(schema).items():
getPerm = getattr(
self, name+'_get_perm_widget').getInputValue()
setPerm = getattr(
self, name+'_set_perm_widget').getInputValue()
perms[name] = (getPerm, setPerm)
status = 'Fields permissions mapping updated.'
return status
def getPermissionWidgets(self):
schema = self.context.relevantDataSchema
if schema is None:
return None
info = []
for name, field in getFields(schema).items():
field = trustedRemoveSecurityProxy(field)
info.append(
{'fieldName': name,
'fieldTitle': field.title,
'getter': getattr(self, name+'_get_perm_widget'),
'setter': getattr(self, name+'_set_perm_widget')} )
return info
class AddState(BrowserView):
def action(self, id):
state = State()
self.context[id] = state
return self.request.response.redirect(self.request.URL[-2])
class AddTransition(BrowserView):
# XXX This could and should be handled by a Vocabulary Field/Widget
def getStateNames(self):
pd = self.context.getProcessDefinition()
states = removeAllProxies(pd.getStateNames())
states.sort()
return states
def action(self, id, source, destination, condition=None, permission=None):
condition = condition or None
permission = permission or None
transition = Transition(source, destination, condition, permission)
self.context[id] = transition
return self.request.response.redirect(self.request.URL[-2])
=== Added File Zope3/src/zope/app/workflow/browser/stateful/definition_edit.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title metal:fill-slot="title" i18n:translate="">
Process Definition <-> Content Type Registry
</title>
</head>
<body>
<div metal:fill-slot="body">
<p tal:define="status view/update"
tal:condition="status"
tal:content="status" />
<form action="./@@edit.html" method="POST">
<h3>Set Workflow-Relevant Data Schema</h3>
<div class="row"
tal:content="structure view/relevantDataSchema_widget/row" />
<div class="row">
<div class="controls" style="width: 100%">
<input type="submit" value="Refresh"
i18n:attributes="value refresh-button" />
<input type="submit" value="Set Schema" name="UPDATE_SUBMIT" />
</div>
</div>
<tal:block define="widgets view/getPermissionWidgets"
condition="widgets">
<h3 i18n:translate="">Map permissions to Schema fields</h3>
<tal:block repeat="widget widgets">
<h5 tal:content="string:${widget/fieldTitle} (${widget/fieldName})">
FieldName (Field Title)
</h5>
<div class="row" tal:replace="structure widget/getter/row">
<div class="label" i18n:translate="">Get Permission</div>
<div class="field">
</div>
</div>
<div class="row" tal:replace="structure widget/setter/row">
<div class="label" i18n:translate="">Set Permission</div>
<div class="field">
</div>
</div>
</tal:block>
<div class="row">
<div class="controls" style="width: 100%">
<input type="submit" value="Refresh"
i18n:attributes="value refresh-button" />
<input type="submit" value="Change" name="CHANGE"
i18n:attributes="value change-button" />
</div>
</div>
</tal:block>
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/workflow/browser/stateful/definition_index.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title metal:fill-slot="title" i18n:translate="">
Process Definition
</title>
</head>
<body>
<div metal:fill-slot="body">
<p i18n:translate="">
Process Definition:
<tal:block tal:replace="view/getName" i18n:name="name"/>
</p>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/workflow/browser/stateful/definition_states.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title metal:fill-slot="title" i18n:translate="">
Process Definition States
</title>
</head>
<body>
<div metal:fill-slot="body">
<p i18n:translate="">States</p>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/workflow/browser/stateful/definition_transitions.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title metal:fill-slot="title" i18n:translate="">
Process Definition Transitions
</title>
</head>
<body>
<div metal:fill-slot="body">
<p i18n:translate="">Transitions</p>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/workflow/browser/stateful/filterTest.pt ===
<html metal:use-macro="views/standard_macros/page">
<body>
<div metal:fill-slot="body">
<div tal:repeat="obj view/filterTest"
tal:omit-tag="">
<div tal:replace="obj"/><br />
</div>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/workflow/browser/stateful/filteradapter.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""filtering view for ProcessInstances of a stateful workflow
$Id: filteradapter.py,v 1.1 2004/02/27 16:50:38 philikon Exp $
"""
from zope.interface import implements
from zope.component import queryAdapter
from zope.app.workflow.interfaces import IProcessInstanceContainerAdaptable
from zope.app.workflow.interfaces import IProcessInstanceContainer
from interfaces import IContentFilterAdapter
__metaclass__ = type
class FilterAdapter:
__used_for__ = IProcessInstanceContainerAdaptable
implements(IContentFilterAdapter)
def __init__(self, context):
self.context = context
def filterListByState(self, objList, state, workflow='default'):
"""See IContentFilterAdapter"""
res = []
for obj in objList:
if self.filterObjectByState(obj, state, workflow):
res.append(obj)
return res
def filterObjectByState(self, object, state, workflow='default'):
"""See IContentFilterAdapter"""
adapter = queryAdapter(object, IProcessInstanceContainer)
if not adapter:
return False
for item in adapter.values():
if item.processDefinitionName != workflow:
continue
if item.status == state:
return True
return False
=== Added File Zope3/src/zope/app/workflow/browser/stateful/instance.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ProcessInstance views for a stateful workflow
$Id: instance.py,v 1.1 2004/02/27 16:50:38 philikon Exp $
"""
from zope.component import getAdapter, getService
from zope.proxy import removeAllProxies
from zope.publisher.browser import BrowserView
from zope.security.proxy import trustedRemoveSecurityProxy
from zope.schema import getFields
from zope.app.browser.form.submit import Update
from zope.app.form.utility import setUpWidget, applyWidgetsChanges
from zope.app.i18n import ZopeMessageIDFactory as _
from zope.app.interfaces.dublincore import IZopeDublinCore
from zope.app.services.servicenames import Workflows
from zope.app.workflow.interfaces import IProcessInstanceContainer
from zope.app.workflow.interfaces import IProcessInstanceContainerAdaptable
__metaclass__ = type
class ManagementView(BrowserView):
__used_for__ = IProcessInstanceContainerAdaptable
def __init__(self, context, request):
super(ManagementView, self).__init__(context, request)
workflow = self._getSelWorkflow()
if workflow.data is None:
return
schema = workflow.data.getSchema()
for name, field in getFields(schema).items():
# setUpWidget() does not mutate the field, so it is ok.
field = trustedRemoveSecurityProxy(field)
setUpWidget(self, name, field,
value=getattr(workflow.data, name))
def _extractContentInfo(self, item):
id, processInstance = item
info = {}
info['id'] = id
info['name'] = self._getTitle(
self._getProcessDefinition(processInstance))
return info
def listContentInfo(self):
return map(self._extractContentInfo,
getAdapter(self.context, IProcessInstanceContainer).items())
def getWorkflowTitle(self):
pi = self._getSelWorkflow()
if pi is None:
return None
return self._getTitle(self._getProcessDefinition(pi))
def getTransitions(self):
info = {}
pi = self._getSelWorkflow()
if pi is None:
return info
pd = self._getProcessDefinition(pi)
clean_pd = removeAllProxies(pd)
current_state = clean_pd.getState(pi.status)
adapter = getAdapter(current_state, IZopeDublinCore)
info['status'] = adapter.title or pi.status
transition_names = pi.getOutgoingTransitions()
trans_info = []
for name in transition_names:
transition = clean_pd.getTransition(name)
adapter = getAdapter(transition, IZopeDublinCore)
trans_info.append({'name':name,
'title': adapter.title or name})
info['transitions'] = trans_info
return info
def fireTransition(self):
pi = self._getSelWorkflow()
if pi is None:
return
trans = self.request.get('selTransition', None)
self.request.response.redirect('@@workflows.html?workflow=%s'
% pi.processDefinitionName)
if pi and trans:
pi.fireTransition(trans)
def _getTitle(self, obj):
return (getAdapter(obj, IZopeDublinCore).title or obj.__name___)
def _getSelWorkflow(self):
reqWorkflow = self.request.get('workflow', u'')
pi_container = getAdapter(self.context, IProcessInstanceContainer)
if reqWorkflow is u'':
available_instances = pi_container.keys()
if len(available_instances) > 0:
pi = pi_container[available_instances[0]]
else:
pi = None
else:
pi = pi_container[reqWorkflow]
return pi
def _getProcessDefinition(self, processInstance):
ws = getService(self.context, Workflows)
return ws.getProcessDefinition(processInstance.processDefinitionName)
def widgets(self):
if self._getSelWorkflow().data is None:
return []
schema = self._getSelWorkflow().data.getSchema()
return [getattr(self, name+'_widget')
for name in getFields(schema).keys()]
def update(self):
status = ''
workflow = self._getSelWorkflow()
if Update in self.request and workflow.data is not None:
schema = trustedRemoveSecurityProxy(workflow.data.getSchema())
changed = applyWidgetsChanges(
self, workflow.data, schema, names=getFields(schema).keys(),
exclude_readonly=True)
if changed:
status = _('Updated Workflow Data.')
return status
=== Added File Zope3/src/zope/app/workflow/browser/stateful/instance_manage.pt ===
<html metal:use-macro="views/standard_macros/page">
<body>
<div metal:fill-slot="body">
<h3 i18n:translate="">Workflow Options</h3>
<br/>
<div metal:define-macro="contents">
<div metal:define-macro="contents_selectWorkflow"
tal:define="workflow request/workflow | nothing">
<div tal:condition="not:workflow" tal:omit-tag="">
<form name="containerContentsForm" method="get"
action="@@workflows.html"
tal:define="container_contents view/listContentInfo"
tal:condition="container_contents">
<span i18n:translate="">Workflow:</span>
<select name="workflow" size="1">
<option tal:repeat="workflow container_contents"
tal:attributes="value workflow/id"
tal:content="workflow/name"></option>
</select>
<input type="submit" value="Choose"
i18n:attributes="value choose-button"/>
</form>
</div>
<div tal:condition="workflow" tal:omit-tag="" i18n:translate="">
Workflow:
<div tal:replace="view/getWorkflowTitle"
i18n:name="wf_title"/>
</div>
</div>
<div metal:define-macro="contents_changeState">
</div>
</div>
<br />
<div metal:define-macro="contents_transitions"
tal:define="info view/getTransitions"
tal:condition="info">
<div i18n:translate="">
Current Status:
<div tal:replace="info/status"/>
</div>
<br />
<span i18n:translate="">Possible State Changes:</span>
<form action="@@fireTransition.html" method="get">
<input type="hidden" name="workflow"
tal:attributes="value request/workflow | nothing" />
<div tal:repeat="trans info/transitions"
tal:condition="info/transitions | nothing"
tal:omit-tag="">
<input type="radio"
name="selTransition"
tal:attributes="value trans/name"/>
<span tal:replace="trans/title"/><br />
</div>
<input type="submit" value="Make Transition"
i18n:attributes="value make-transition-button"/>
</form>
</div>
<h3 i18n:translate="">Workflow-relevant Data</h3>
<p tal:define="status view/update"
tal:condition="status"
tal:content="status" />
<form name="." method="POST">
<div class="row" tal:repeat="widget view/widgets"
tal:content="structure widget/row">
<div class="label" i18n:translate="">Name</div>
<div class="field"><input type="text" style="width:100%" /></div>
</div>
<div class="row">
<div class="controls">
<input type="submit" value="Refresh"
i18n:attributes="value refresh-button" />
<input type="submit" name="UPDATE_SUBMIT" value="Submit"
i18n:attributes="value submit-button"/>
</div>
</div>
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/workflow/browser/stateful/interfaces.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Interfaces for stateful workflow.
$Id: interfaces.py,v 1.1 2004/02/27 16:50:38 philikon Exp $
"""
from zope.interface import Interface
class IContentFilterAdapter(Interface):
def filterListByState(objList, state, workflow='default'):
"""Filter a list of objects according to given workflow and state
objList ... list of objects
state ... name of a state (of the given workflow) in which the result
objects must be
workflow ... name of a workflow to which result objects must be attached
"""
def filterObjectByState(object, state, workflow='default'):
"""Filter an object according to the given workflow and state."""
=== Added File Zope3/src/zope/app/workflow/browser/stateful/published_content.pt ===
<html metal:use-macro="views/standard_macros/page">
<body>
<div metal:fill-slot="body">
<div tal:repeat="obj view/listPublishedItems" tal:omit-tag="">
<div tal:content="obj/url"/><br />
</div>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/workflow/browser/stateful/testobject.zcml ===
<zope:configure
xmlns:zope="http://namespaces.zope.org/zope"
xmlns="http://namespaces.zope.org/browser">
<addform
label="Add Test Object"
name="AddTestObject"
schema="zope.app.workflow.stateful.testobject.ITestObject"
content_factory="zope.app.workflow.stateful.testobject.TestObject"
permission="zope.ManageContent"
menu="add_content" title="Test Object"/>
<editform
schema="zope.app.workflow.stateful.testobject.ITestObject"
for="zope.app.workflow.stateful.testobject.ITestObject"
label="Change Test Object"
name="edit.html"
permission="zope.ManageContent"
menu="zmi_views" title="Edit" />
</zope:configure>
More information about the Zope3-Checkins
mailing list