diff --git a/browser/common.py b/browser/common.py index 641ee5f..1e400cb 100644 --- a/browser/common.py +++ b/browser/common.py @@ -613,16 +613,18 @@ class BaseView(GenericView, I18NView): # states + viewStatesPermission = 'zope.ManageContent' + @Lazy def states(self): result = [] - if not checkPermission('loops.ManageSite', self.context): - # TODO: replace by more sensible permission + if not checkPermission(self.viewStatesPermission, self.context): return result if IResource.providedBy(self.target): statesDefs = self.globalOptions('organize.stateful.resource', ()) else: - statesDefs = self.globalOptions('organize.stateful.concept', ()) + statesDefs = (self.globalOptions('organize.stateful.concept', []) + + self.typeOptions('organize.stateful', [])) for std in statesDefs: stf = component.getAdapter(self.target, IStateful, name=std) result.append(stf) diff --git a/browser/concept.py b/browser/concept.py index 9265492..0c1fe97 100644 --- a/browser/concept.py +++ b/browser/concept.py @@ -505,9 +505,9 @@ class ConceptView(BaseView): def getObjectActions(self, page=None, target=None): acts = ['info'] - acts.extend('state.' + st.statesDefinition for st in self.states) if self.globalOptions('organize.allowSendEmail'): acts.append('send_email') + acts.extend('state.' + st.statesDefinition for st in self.states) return actions.get('object', acts, view=self, page=page, target=target) actions = dict(object=getObjectActions) diff --git a/browser/concept_macros.pt b/browser/concept_macros.pt index f4f7ebd..d648679 100644 --- a/browser/concept_macros.pt +++ b/browser/concept_macros.pt @@ -107,7 +107,7 @@   Title - Type + Type Modification Date Author(s) 2011-01-10 Author - diff --git a/browser/configure.zcml b/browser/configure.zcml index f701185..9ca250b 100644 --- a/browser/configure.zcml +++ b/browser/configure.zcml @@ -583,6 +583,12 @@ class="loops.browser.form.CreateConceptForm" permission="zope.View" /> + + + permission="zope.View" /> + permission="zope.View" />
diff --git a/organize/browser/event.py b/organize/browser/event.py index 9339563..fb97b4b 100644 --- a/organize/browser/event.py +++ b/organize/browser/event.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2008 Helmut Merz helmutm@cy55.de +# Copyright (c) 2012 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 @@ -18,8 +18,6 @@ """ Definition of view classes and other browser related stuff for tasks. - -$Id$ """ import calendar @@ -174,7 +172,8 @@ class CalendarInfo(NodeView): tEvent = cm['event'] hasType = cm.getTypePredicate() start = datetime(self.selectedYear, self.selectedMonth, 1) - end = start + timedelta(31) + fday, ndays = calendar.monthrange(self.selectedYear, self.selectedMonth) + end = start + timedelta(ndays) view = self.eventListQuery if view is not None: relViews = (view.childViewFactory(r, self.request, contextIsSecond=True) diff --git a/organize/stateful/base.py b/organize/stateful/base.py index faafcda..f6da53b 100644 --- a/organize/stateful/base.py +++ b/organize/stateful/base.py @@ -31,6 +31,7 @@ from cybertools.meta.interfaces import IOptions from cybertools.stateful.base import Stateful as BaseStateful from cybertools.stateful.base import StatefulAdapter, IndexInfo from cybertools.stateful.interfaces import IStatesDefinition, ITransitionEvent +from loops.common import adapted from loops.interfaces import ILoopsObject, IConcept, IResource from loops import util @@ -65,8 +66,10 @@ class StatefulConceptIndexInfo(IndexInfo): @property def availableStatesDefinitions(self): - options = IOptions(self.context.getLoopsRoot()) - return options('organize.stateful.concept', ()) + globalOptions = IOptions(self.context.getLoopsRoot()) + typeOptions = IOptions(adapted(self.context.conceptType)) + return (globalOptions('organize.stateful.concept', []) + + typeOptions('organize.stateful', [])) class StatefulResourceIndexInfo(IndexInfo): diff --git a/organize/stateful/browser.py b/organize/stateful/browser.py index 1db6c49..1e4c49b 100644 --- a/organize/stateful/browser.py +++ b/organize/stateful/browser.py @@ -37,7 +37,8 @@ from loops.util import _ statefulActions = ('classification_quality', - 'simple_publishing',) + 'simple_publishing', + 'task_states',) class StateAction(Action): diff --git a/organize/stateful/configure.zcml b/organize/stateful/configure.zcml index 5bd50ab..e5cd542 100644 --- a/organize/stateful/configure.zcml +++ b/organize/stateful/configure.zcml @@ -35,6 +35,20 @@ set_schema="cybertools.stateful.interfaces.IStateful" /> + + + + + + + + diff --git a/organize/stateful/task.py b/organize/stateful/task.py new file mode 100644 index 0000000..7a99273 --- /dev/null +++ b/organize/stateful/task.py @@ -0,0 +1,53 @@ +# +# Copyright (c) 2012 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Basic implementations for stateful objects and adapters. +""" + +from zope import component +from zope.component import adapter +from zope.interface import implementer +from zope.traversing.api import getName + +from cybertools.stateful.definition import StatesDefinition +from cybertools.stateful.definition import State, Transition +from cybertools.stateful.interfaces import IStatesDefinition, IStateful +from loops.common import adapted +from loops.organize.stateful.base import StatefulLoopsObject + + +@implementer(IStatesDefinition) +def taskStates(): + return StatesDefinition('task_states', + State('planned', 'planned', ('finish', 'cancel'), + color='yellow'), + State('finished', 'finished', ('reopen'), + color='green'), + State('cancelled', 'cancelled', ('reopen'), + color='grey'), + Transition('finish', 'finish', 'finished'), + Transition('cancel', 'cancel', 'cancelled'), + Transition('reopen', 're-open', 'planned'), + initialState='planned') + + +class StatefulTask(StatefulLoopsObject): + + statesDefinition = 'task_states' +