# HG changeset patch # User Sylvain Thénault # Date 1305823706 -7200 # Node ID e772a2c57b0048c1062c7bd4a5328d3bb305b718 # Parent 826e5663a686ae1851e518ac15b04dc840b67393# Parent 8c752d113ebb943d3e11dc576235dfd54b6d2aef backport stable diff -r 826e5663a686 -r e772a2c57b00 entities/wfobjs.py --- a/entities/wfobjs.py Thu May 19 16:39:24 2011 +0200 +++ b/entities/wfobjs.py Thu May 19 18:48:26 2011 +0200 @@ -572,18 +572,31 @@ kwargs['to_state'] = self._cw.entity_from_eid(tseid) return self._cw.create_entity('TrInfo', **kwargs) - def fire_transition(self, tr, comment=None, commentformat=None): - """change the entity's state by firing transition of the given name in - entity's workflow - """ + def _get_transition(self, tr): assert self.current_workflow if isinstance(tr, basestring): _tr = self.current_workflow.transition_by_name(tr) assert _tr is not None, 'not a %s transition: %s' % ( self.__regid__, tr) tr = _tr + return tr + + def fire_transition(self, tr, comment=None, commentformat=None): + """change the entity's state by firing given transition (name or entity) + in entity's workflow + """ + tr = self._get_transition(tr) return self._add_trinfo(comment, commentformat, tr.eid) + def fire_transition_if_possible(self, tr, comment=None, commentformat=None): + """change the entity's state by firing given transition (name or entity) + in entity's workflow if this transition is possible + """ + tr = self._get_transition(tr) + if any(tr_ for tr_ in self.possible_transitions() + if tr_.eid == tr.eid): + self.fire_transition(tr) + def change_state(self, statename, comment=None, commentformat=None, tr=None): """change the entity's state to the given state (name or entity) in entity's workflow. This method should only by used by manager to fix an @@ -595,7 +608,7 @@ stateeid = statename.eid else: if not isinstance(statename, basestring): - warn('[3.5] give a state name', DeprecationWarning) + warn('[3.5] give a state name', DeprecationWarning, stacklevel=2) state = self.current_workflow.state_by_eid(statename) else: state = self.current_workflow.state_by_name(statename) @@ -605,3 +618,20 @@ stateeid = state.eid # XXX try to find matching transition? return self._add_trinfo(comment, commentformat, tr and tr.eid, stateeid) + + def set_initial_state(self, statename): + """set a newly created entity's state to the given state (name or entity) + in entity's workflow. This is useful if you don't want it to be the + workflow's initial state. + """ + assert self.current_workflow + if hasattr(statename, 'eid'): + stateeid = statename.eid + else: + state = self.current_workflow.state_by_name(statename) + if state is None: + raise WorkflowException('not a %s state: %s' % (self.__regid__, + statename)) + stateeid = state.eid + self._cw.execute('SET X in_state S WHERE X eid %(x)s, S eid %(s)s', + {'x': self.entity.eid, 's': stateeid}) diff -r 826e5663a686 -r e772a2c57b00 server/session.py --- a/server/session.py Thu May 19 16:39:24 2011 +0200 +++ b/server/session.py Thu May 19 18:48:26 2011 +0200 @@ -458,6 +458,9 @@ DEFAULT_SECURITY = object() # evaluated to true by design + def security_enabled(self, read=False, write=False): + return security_enabled(self, read=read, write=write) + def init_security(self, read, write): if read is None: oldread = None @@ -566,6 +569,11 @@ HOOKS_ALLOW_ALL = object() HOOKS_DENY_ALL = object() + def allow_all_hooks_but(self, *categories): + return hooks_control(self, self.HOOKS_ALLOW_ALL, *categories) + def deny_all_hooks_but(self, *categories): + return hooks_control(self, self.HOOKS_DENY_ALL, *categories) + @property def hooks_mode(self): return getattr(self._threaddata, 'hooks_mode', self.HOOKS_ALLOW_ALL) diff -r 826e5663a686 -r e772a2c57b00 web/views/workflow.py --- a/web/views/workflow.py Thu May 19 16:39:24 2011 +0200 +++ b/web/views/workflow.py Thu May 19 18:48:26 2011 +0200 @@ -30,7 +30,7 @@ from logilab.mtconverter import xml_escape from logilab.common.graph import escape -from cubicweb import Unauthorized, view +from cubicweb import Unauthorized from cubicweb.selectors import (has_related_entities, one_line_rset, relation_possible, match_form_params, score_entity, is_instance, adaptable) @@ -90,7 +90,7 @@ fwdgs.Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')] -class ChangeStateFormView(form.FormViewMixIn, view.EntityView): +class ChangeStateFormView(form.FormViewMixIn, EntityView): __regid__ = 'statuschange' title = _('status change') __select__ = (one_line_rset() @@ -183,6 +183,15 @@ self.entity.view('wfhistory', w=w, title=None) +class InContextWithStateView(EntityView): + """display incontext view for an entity as well as its current state""" + __regid__ = 'incontext-state' + __select__ = adaptable('IWorkflowable') + def entity_call(self, entity): + iwf = entity.cw_adapt_to('IWorkflowable') + self.w(u'%s [%s]' % (entity.view('incontext'), iwf.printable_state)) + + # workflow actions ############################################################# class WorkflowActions(action.Action): @@ -242,7 +251,7 @@ default_tab = 'wf_tab_info' -class CellView(view.EntityView): +class CellView(EntityView): __regid__ = 'cell' __select__ = is_instance('TrInfo') @@ -250,7 +259,7 @@ self.w(self.cw_rset.get_entity(row, col).view('reledit', rtype='comment')) -class StateInContextView(view.EntityView): +class StateInContextView(EntityView): """convenience trick, State's incontext view should not be clickable""" __regid__ = 'incontext' __select__ = is_instance('State') @@ -285,7 +294,7 @@ ) -class TransitionSecurityTextView(view.EntityView): +class TransitionSecurityTextView(EntityView): __regid__ = 'trsecurity' __select__ = is_instance('Transition') @@ -303,7 +312,7 @@ u'
'.join((e.dc_title() for e in entity.condition)))) -class TransitionAllowedTextView(view.EntityView): +class TransitionAllowedTextView(EntityView): __regid__ = 'trfromstates' __select__ = is_instance('Transition') @@ -434,7 +443,7 @@ return WorkflowDotPropsHandler(self._cw) -class TmpPngView(TmpFileViewMixin, view.EntityView): +class TmpPngView(TmpFileViewMixin, EntityView): __regid__ = 'tmppng' __select__ = match_form_params('tmpfile') content_type = 'image/png'