20120709
========

When a state has a `required` attribute, Lino will automatically 
add a corresponding `StateAction`.
This allows for more concise code when defining simple workflows.

For example, the code to define calendar events workflow is now as this::

  add = EventState.add_item
  add('10', _("Draft"), 'draft')
  add('20', _("Scheduled"), 'scheduled',required=dict(states=['','draft']))
  add('30', _("Notified"),'notified',required=dict(states=['scheduled']))
  add('40', _("Confirmed"),'confirmed',required=dict(states=['scheduled','notified']))
  add('50', _("Took place"),'took_place',required=dict(states=['scheduled','notified','confirmed']))
  add('60', _("Rescheduled"),'rescheduled',required=dict(states=['scheduled','notified','confirmed']))
  add('70', _("Cancelled"),'cancelled',required=dict(states=['scheduled','notified','confirmed']))
  add('80', _("Absent"),'absent',required=dict(states=['scheduled','notified','confirmed']))
  add('90', _("Obsolete"),'obsolete',required=dict(states=[]))
  
Previously we had to write, for each line in above code, 
a whole method similar to the following::
  
    @dd.action(EventState.notified.text,sort_index=11,required=dict(states=['scheduled']))
    def mark_notified(self,ar):
        self.state = EventState.notified
        self.save()
        return ar.ui.success_response(refresh=True)

Since application developers will now try to avoid writing complete 
actions, a workflowed model can now define methods `allow_state_FOO` 
that can put additional requirements on a state. 
For example the following 
method on :class:`lino_xl.lib.cal.Event` causes the "Scheduled" 
action *not* to appear as long as the start_time field is empty::

    def allow_state_scheduled(self,user):
        if not self.start_time: return False
        return True
        

The "Register" and "Unregister" actions in the :mod:`lino.modlib.courses` 
module however are an example of more complex actions that must be 
defined "by hand".


TODO: 

- replace `before_state_change` by `state_changed`?

- StateAction would currently not work if workflow_state_field 
  is something else than "state".
  
- The choicelist that opens for Subscription.calendar
  still ignores the query string.   
  One new feature is 
  :attr:`lino.core.modeltools.Model.quick_search_fields`,
  though that wasn't yet the solution.