[FIX] ir.actions: fixed and documented a bit the function field computing views for actions

The previous implementation had numerous flaws and edge cases where it would
not have any useful result. The new implementation is backwards compatible
with the valid combinations of view_id, view_modes and view_id.
A unique constraint was also added to make sure that it is not possible to
specify multiple views of the same type for the same action. This was never
used, but should be prevented completely so that clients can rely on this
fact. Also a little bit of documentation was added to explain what the field
is doing.

bzr revid: odo@openerp.com-20110401124852-r0i6cclc80acoegj
This commit is contained in:
Olivier Dony 2011-04-01 14:48:52 +02:00
parent 0d9a590970
commit 11e1097c61
1 changed files with 33 additions and 12 deletions

View File

@ -168,19 +168,32 @@ class act_window(osv.osv):
]
def _views_get_fnc(self, cr, uid, ids, name, arg, context=None):
res={}
"""Returns an ordered list of the specific view modes that should be
enabled when displaying the result of this action, along with the
ID of the specific view to use for each mode, if any were required.
This function hides the logic of determining the precedence between
the view_modes string, the view_ids o2m, and the view_id m2o that can
be set on the action.
:rtype: dict in the form { action_id: list of pairs (tuples) }
:return: { action_id: [(view_id, view_mode), ...], ... }, where view_mode
is one of the possible values for ir.ui.view.type and view_id
is the ID of a specific view to use for this mode, or False for
the default one.
"""
res = {}
for act in self.browse(cr, uid, ids):
res[act.id]=[(view.view_id.id, view.view_mode) for view in act.view_ids]
res[act.id] = [(view.view_id.id, view.view_mode) for view in act.view_ids]
view_ids_modes = [view.view_mode for view in act.view_ids]
modes = act.view_mode.split(',')
if len(modes)>len(act.view_ids):
find = False
if act.view_id:
missing_modes = [mode for mode in modes if mode not in view_ids_modes]
if missing_modes:
if act.view_id and act.view_id.type in missing_modes:
# reorder missing modes to put view_id first if present
missing_modes.remove(act.view_id.type)
res[act.id].append((act.view_id.id, act.view_id.type))
for t in modes[len(act.view_ids):]:
if act.view_id and (t == act.view_id.type) and not find:
find = True
continue
res[act.id].append((False, t))
res[act.id].extend([(False, mode) for mode in missing_modes])
return res
def _search_view(self, cr, uid, ids, name, arg, context=None):
@ -257,7 +270,10 @@ class act_window(osv.osv):
help="Comma-separated list of allowed view modes, such as 'form', 'tree', 'calendar', etc. (Default: tree,form)"),
'usage': fields.char('Action Usage', size=32),
'view_ids': fields.one2many('ir.actions.act_window.view', 'act_window_id', 'Views'),
'views': fields.function(_views_get_fnc, method=True, type='binary', string='Views'),
'views': fields.function(_views_get_fnc, method=True, type='binary', string='Views',
help="This function field computes the ordered list of views that should be enabled " \
"when displaying the result of an action, federating view mode, views and " \
"reference view. The result is returned as an ordered list of pairs (view_id,view_mode)."),
'limit': fields.integer('Limit', help='Default limit for the list view'),
'auto_refresh': fields.integer('Auto-Refresh',
help='Add an auto-refresh on the view'),
@ -307,6 +323,7 @@ class act_window_view(osv.osv):
_name = 'ir.actions.act_window.view'
_table = 'ir_act_window_view'
_rec_name = 'view_id'
_order = 'sequence'
_columns = {
'sequence': fields.integer('Sequence'),
'view_id': fields.many2one('ir.ui.view', 'View'),
@ -323,7 +340,11 @@ class act_window_view(osv.osv):
_defaults = {
'multi': lambda *a: False,
}
_order = 'sequence'
def _auto_init(self, cr, context=None):
super(act_window_view, self)._auto_init(cr, context)
cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = \'act_window_view_unique_mode_per_action\'')
if not cr.fetchone():
cr.execute('CREATE UNIQUE INDEX act_window_view_unique_mode_per_action ON ir_act_window_view (act_window_id, view_mode)')
act_window_view()
class act_wizard(osv.osv):