diff --git a/browser/icons/cancel.png b/browser/icons/cancel.png new file mode 100755 index 0000000..e2db55f Binary files /dev/null and b/browser/icons/cancel.png differ diff --git a/browser/icons/delete.png b/browser/icons/delete.png new file mode 100755 index 0000000..869be8b Binary files /dev/null and b/browser/icons/delete.png differ diff --git a/browser/icons/favorite.png b/browser/icons/favorite.png new file mode 100755 index 0000000..ccaf596 Binary files /dev/null and b/browser/icons/favorite.png differ diff --git a/stateful/base.py b/stateful/base.py index f31e3ba..54d11a4 100644 --- a/stateful/base.py +++ b/stateful/base.py @@ -64,6 +64,9 @@ class Stateful(object): sd = self.getStatesDefinition() return sd.getAvailableTransitionsFor(self) + def getAvailableTransitionsForUser(self): + return self.getAvailableTransitions() + def getStatesDefinition(self): return statesDefinitions.get(self.statesDefinition, None) diff --git a/stateful/definition.py b/stateful/definition.py index c3ba313..131413d 100644 --- a/stateful/definition.py +++ b/stateful/definition.py @@ -22,17 +22,21 @@ State definition implementation. $Id$ """ +from zope.component.interfaces import ObjectEvent +from zope.event import notify from zope.interface import implements from cybertools.util.jeep import Jeep from cybertools.stateful.interfaces import IState, ITransition from cybertools.stateful.interfaces import IStatesDefinition +from cybertools.stateful.interfaces import ITransitionEvent class State(object): implements(IState) + icon = None color = 'blue' def __init__(self, name, title, transitions, **kw): @@ -82,12 +86,27 @@ class StatesDefinition(object): if transition not in [t.name for t in self.getAvailableTransitionsFor(obj)]: raise ValueError("Transition '%s' is not reachable from state '%s'." % (transition, obj.getState())) - obj.state = self.transitions[transition].targetState + transObject = self.transitions[transition] + previousState = obj.state + obj.state = transObject.targetState + notify(TransitionEvent(obj, transObject, previousState)) def getAvailableTransitionsFor(self, obj): state = obj.getState() return [self.transitions[t] for t in self.states[state].transitions] + +# event + +class TransitionEvent(ObjectEvent): + + implements(ITransitionEvent) + + def __init__(self, obj, transition, previousState): + super(TransitionEvent, self).__init__(obj) + self.transition = transition + self.previousState = previousState + # dummy default states definition defaultSD = StatesDefinition('default', diff --git a/stateful/interfaces.py b/stateful/interfaces.py index 8a1d028..085bbe6 100644 --- a/stateful/interfaces.py +++ b/stateful/interfaces.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2007 Helmut Merz helmutm@cy55.de +# Copyright (c) 2008 Helmut Merz helmutm@cy55.de # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -22,6 +22,7 @@ Interfaces for the `stateful` package. $Id$ """ +from zope.component.interfaces import IObjectEvent from zope.interface import Interface, Attribute @@ -71,6 +72,12 @@ class IStateful(Interface): provide the ITransition interface. """ + def getAvailableTransitionsForUser(): + """ Return the transitions for this object that are available for + the current user. This is a subset of all available transitions + for the current state. + """ + class IHistorizable(Interface): """ An object that may record history information, e.g. when @@ -105,3 +112,10 @@ class IStatesDefinition(Interface): """ Return the transitions available for this object in its current state. """ + +class ITransitionEvent(IObjectEvent): + """ Fires when the state of an object is changed. + """ + + transition = Attribute('The transition.') + previousState = Attribute('The name of the state before the transition.') diff --git a/stateful/publishing.py b/stateful/publishing.py index 69c5128..1286b2c 100644 --- a/stateful/publishing.py +++ b/stateful/publishing.py @@ -33,11 +33,12 @@ from cybertools.stateful.interfaces import IStatesDefinition @implementer(IStatesDefinition) def simplePublishing(): return StatesDefinition('publishing', - State('private', 'private', ('show', 'archive', 'remove')), - State('draft', 'draft', ('publish', 'hide', 'archive', 'remove')), - State('published', 'published', ('retract', 'archive')), - State('archived', 'archived', ('show', 'remove')), - State('removed', 'removed', ('show',)), + State('private', 'private', ('show', 'archive', 'remove'), color='red'), + State('draft', 'draft', ('publish', 'hide', 'archive', 'remove'), + color='yellow'), + State('published', 'published', ('retract', 'archive'), color='green'), + State('archived', 'archived', ('show', 'remove'), color='lightblue'), + State('removed', 'removed', ('show',), icon='cancel.png'), Transition('show', 'show', 'draft'), Transition('hide', 'hide', 'private'), Transition('publish', 'publish', 'published'),