backport stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 19 May 2011 18:48:26 +0200
changeset 7406 e772a2c57b00
parent 7402 826e5663a686 (current diff)
parent 7405 8c752d113ebb (diff)
child 7412 9179ae452159
backport stable
entities/wfobjs.py
server/session.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})
--- 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)
--- 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'<br/>'.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'