[fix] res.config so the state of a todo is changed after being done with it, not when it's displayed.
Add the setting of states to ``skip`` (action_skip) and ``cancel`` (action_cancel) on top of ``done`` (action_next) plus a bit of documentation to the API. Also, fix res.config.users to use the right buttons/actions for its stuff, or clicking "Done" registers as having skipped the screen: create ``action_add`` event for "Add User" button, and hook "Done" to ``action_next`` with a NOOP ``execute``. bzr revid: xmo@tinyerp.com-20100126164237-0zvk4jc1dv9gqdc7
This commit is contained in:
parent
16c8091429
commit
392631cc32
|
@ -230,16 +230,31 @@
|
|||
<field colspan="4" nolabel="1" name="groups_id"/>
|
||||
</group>
|
||||
|
||||
<xpath expr='//button[@name="action_skip"]'
|
||||
position='attributes'>
|
||||
<attribute name='string'>Done</attribute>
|
||||
<attribute name='icon'>gtk-go-forward</attribute>
|
||||
</xpath>
|
||||
<xpath expr='//button[@name="action_next"]'
|
||||
position='attributes'>
|
||||
<attribute name="name">action_add</attribute>
|
||||
<attribute name='string'>Add User</attribute>
|
||||
<attribute name='icon'>gtk-add</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr='//button[@name="action_skip"]'
|
||||
position='attributes'>
|
||||
<!-- if this one is performed first, it transforms
|
||||
the action_skip into action_next, and the
|
||||
transformation of action_next to action_add,
|
||||
since it uses first-match, transforms the same
|
||||
button. And we end up with [add] [next] instead
|
||||
of [next] [add]
|
||||
|
||||
Would probably be simpler to just replace both
|
||||
by nothing and create a pair of brand new
|
||||
buttons... but we'd have to handle the groups
|
||||
around the buttons... oh well...
|
||||
-->
|
||||
<attribute name="name">action_next</attribute>
|
||||
<attribute name='string'>Done</attribute>
|
||||
<attribute name='icon'>gtk-go-forward</attribute>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -60,11 +60,30 @@ class res_config_configurable(osv.osv_memory):
|
|||
'getting next %s' % todos)
|
||||
active_todos = todos.search(cr, uid, [('state','=','open'),
|
||||
('active','=',True)],
|
||||
limit=1, context=None)
|
||||
limit=1)
|
||||
if active_todos:
|
||||
return todos.browse(cr, uid, active_todos[0], context=None)
|
||||
return None
|
||||
|
||||
def _set_previous_todo(self, cr, uid, state):
|
||||
""" lookup the previous (which is still the next at this point)
|
||||
ir.actions.todo, set it to whatever state was provided.
|
||||
|
||||
Raises
|
||||
`LookupError`: if we couldn't find *any* previous todo
|
||||
`ValueError`: if no state is provided
|
||||
anything ir_actions_todo.write can throw
|
||||
"""
|
||||
# this is ultra brittle, but apart from storing the todo id
|
||||
# into the res.config view, I'm not sure how to do it
|
||||
previous_todo = self._next_action(cr, uid)
|
||||
if not previous_todo:
|
||||
raise LookupError(_("Couldn't find previous ir.actions.todo"))
|
||||
if not state:
|
||||
raise ValueError(_("Can't set an ir.actions.todo's state to "
|
||||
"nothingness"))
|
||||
previous_todo.write({'state':state})
|
||||
|
||||
def _next(self, cr, uid):
|
||||
self.logger.notifyChannel('actions', netsvc.LOG_INFO,
|
||||
'getting next operation')
|
||||
|
@ -72,9 +91,6 @@ class res_config_configurable(osv.osv_memory):
|
|||
self.logger.notifyChannel('actions', netsvc.LOG_INFO,
|
||||
'next action is %s' % next)
|
||||
if next:
|
||||
self.pool.get('ir.actions.todo').write(cr, uid, next.id, {
|
||||
'state':'done',
|
||||
}, context=None)
|
||||
action = next.action_id
|
||||
return {
|
||||
'view_mode': action.view_mode,
|
||||
|
@ -93,21 +109,73 @@ class res_config_configurable(osv.osv_memory):
|
|||
# return the action associated with the menu
|
||||
return self.pool.get(current_user_menu.type)\
|
||||
.read(cr, uid, current_user_menu.id)
|
||||
|
||||
def next(self, cr, uid, ids, context=None):
|
||||
""" Returns the next action to execute execute (using the default
|
||||
sort order)
|
||||
"""
|
||||
return self._next(cr, uid)
|
||||
|
||||
def execute(self, cr, uid, ids, context=None):
|
||||
""" Method called when the user clicks on the ``Next`` button.
|
||||
|
||||
Execute *must* be overloaded unless ``action_next`` is overloaded
|
||||
(which is something you generally don't need to do).
|
||||
|
||||
If ``execute`` returns an action dictionary, that action is executed
|
||||
rather than just going to the next configuration item.
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
'Configuration items need to implement execute')
|
||||
def cancel(self, cr, uid, ids, context=None):
|
||||
""" Method called when the user click on the ``Skip`` button.
|
||||
|
||||
``cancel`` should be overloaded instead of ``action_skip``. As with
|
||||
``execute``, if it returns an action dictionary that action is
|
||||
executed in stead of the default (going to the next configuration item)
|
||||
|
||||
The default implementation is a NOOP.
|
||||
"""
|
||||
pass
|
||||
|
||||
def action_next(self, cr, uid, ids, context=None):
|
||||
""" Action handler for the ``next`` event.
|
||||
|
||||
Sets the status of the todo the event was sent from to
|
||||
``done``, calls ``execute`` and -- unless ``execute`` returned
|
||||
an action dictionary -- executes the action provided by calling
|
||||
``next``.
|
||||
"""
|
||||
self._set_previous_todo(cr, uid, state='done')
|
||||
next = self.execute(cr, uid, ids, context=None)
|
||||
if next: return next
|
||||
return self.next(cr, uid, ids, context=context)
|
||||
|
||||
def action_skip(self, cr, uid, ids, context=None):
|
||||
""" Action handler for the ``skip`` event.
|
||||
|
||||
Sets the status of the todo the event was sent from to
|
||||
``skip``, calls ``cancel`` and -- unless ``cancel`` returned
|
||||
an action dictionary -- executes the action provided by calling
|
||||
``next``.
|
||||
"""
|
||||
self._set_previous_todo(cr, uid, state='skip')
|
||||
next = self.cancel(cr, uid, ids, context=None)
|
||||
if next: return next
|
||||
return self.next(cr, uid, ids, context=context)
|
||||
|
||||
def action_cancel(self, cr, uid, ids, context=None):
|
||||
""" Action handler for the ``cancel`` event. That event isn't
|
||||
generated by the res.config.view.base inheritable view, the
|
||||
inherited view has to overload one of the buttons (or add one
|
||||
more).
|
||||
|
||||
Sets the status of the todo the event was sent from to
|
||||
``cancel``, calls ``cancel`` and -- unless ``cancel`` returned
|
||||
an action dictionary -- executes the action provided by calling
|
||||
``next``.
|
||||
"""
|
||||
self._set_previous_todo(cr, uid, state='cancel')
|
||||
next = self.cancel(cr, uid, ids, context=None)
|
||||
if next: return next
|
||||
return self.next(cr, uid, ids, context=context)
|
||||
|
|
|
@ -388,8 +388,11 @@ class config_users(osv.osv_memory):
|
|||
body=self.get_welcome_mail_body(
|
||||
cr, uid, context=context) % user_data,
|
||||
reply_to="no@reply.to")
|
||||
|
||||
def execute(self, cr, uid, ids, context=None):
|
||||
'Do nothing on execution, just launch the next action/todo'
|
||||
pass
|
||||
def action_add(self, cr, uid, ids, context=None):
|
||||
'Create a user, and re-display the view'
|
||||
self.create_user(cr, uid, ids[0], context=context)
|
||||
return {
|
||||
'view_type': 'form',
|
||||
|
|
Loading…
Reference in New Issue