From 434be479f97a32987d0817bf329183fc2bbe3bf5 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 27 May 2014 11:43:08 +0200 Subject: [PATCH] [ADD] mode attribute to views Not used yet, only defined its relation to inherit_id: not inherit_id + primary -> ok not inherit_id + extension -> error inherit_id + primary -> ok inherit_id + extension -> ok --- openerp/addons/base/ir/ir_ui_view.py | 31 +++++++-- openerp/addons/base/tests/test_views.py | 88 +++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 4 deletions(-) diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py index 1a75c08c695..b8ae58d4767 100644 --- a/openerp/addons/base/ir/ir_ui_view.py +++ b/openerp/addons/base/ir/ir_ui_view.py @@ -141,6 +141,11 @@ class view(osv.osv): 'model_ids': fields.one2many('ir.model.data', 'res_id', domain=[('model','=','ir.ui.view')], auto_join=True), 'create_date': fields.datetime('Create Date', readonly=True), 'write_date': fields.datetime('Last Modification Date', readonly=True), + + 'mode': fields.selection( + [('primary', "Base view"), ('extension', "Extension View")], + string="View inheritance mode", + required=True), } _defaults = { 'priority': 16, @@ -191,8 +196,16 @@ class view(osv.osv): return False return True + def _check_mode(self, cr, uid, ids, context=None): + for v in self.read(cr, uid, ids, ['inherit_id', 'mode'], context=context): + if v['mode'] == 'extension' and not v['inherit_id']: + raise Exception( + _("A view extending nothing can not be an extension view")) + return True + _constraints = [ - (_check_xml, 'Invalid view definition', ['arch']) + (_check_xml, 'Invalid view definition', ['arch']), + (_check_mode, "Invalid mode for inheritance", ['mode', 'inherit_id']), ] def _auto_init(self, cr, context=None): @@ -201,6 +214,10 @@ class view(osv.osv): if not cr.fetchone(): cr.execute('CREATE INDEX ir_ui_view_model_type_inherit_id ON ir_ui_view (model, inherit_id)') + def _compute_defaults(self, cr, uid, values, context=None): + values.setdefault('mode', 'extension' if values.get('inherit_id') else 'primary') + return values + def create(self, cr, uid, values, context=None): if 'type' not in values: if values.get('inherit_id'): @@ -209,10 +226,13 @@ class view(osv.osv): values['type'] = etree.fromstring(values['arch']).tag if not values.get('name'): - values['name'] = "%s %s" % (values['model'], values['type']) + values['name'] = "%s %s" % (values.get('model'), values['type']) self.read_template.clear_cache(self) - return super(view, self).create(cr, uid, values, context) + return super(view, self).create( + cr, uid, + self._compute_defaults(cr, uid, values, context=context), + context=context) def write(self, cr, uid, ids, vals, context=None): if not isinstance(ids, (list, tuple)): @@ -227,7 +247,10 @@ class view(osv.osv): self.pool.get('ir.ui.view.custom').unlink(cr, uid, custom_view_ids) self.read_template.clear_cache(self) - ret = super(view, self).write(cr, uid, ids, vals, context) + ret = super(view, self).write( + cr, uid, ids, + self._compute_defaults(cr, uid, vals, context=context), + context) return ret def copy(self, cr, uid, id, default=None, context=None): diff --git a/openerp/addons/base/tests/test_views.py b/openerp/addons/base/tests/test_views.py index feb22eb2be9..29e6fe18248 100644 --- a/openerp/addons/base/tests/test_views.py +++ b/openerp/addons/base/tests/test_views.py @@ -628,6 +628,7 @@ class test_views(ViewCase): def _insert_view(self, **kw): """Insert view into database via a query to passtrough validation""" kw.pop('id', None) + kw.setdefault('mode', 'extension' if kw.get('inherit_id') else 'primary') keys = sorted(kw.keys()) fields = ','.join('"%s"' % (k.replace('"', r'\"'),) for k in keys) @@ -805,6 +806,93 @@ class test_views(ViewCase): string="Replacement title", version="7.0" )) +class ViewModeField(ViewCase): + """ + This should probably, eventually, be folded back into other test case + classes, integrating the test (or not) of the mode field to regular cases + """ + + def setUp(self): + super(ViewModeField, self).setUp() + self.Views = self.registry('ir.ui.view') + + def browse(self, id, context=None): + return self.Views.browse(self.cr, self.uid, id, context=context) + def create(self, value, context=None): + return self.Views.create(self.cr, self.uid, value, context=context) + + def testModeImplicitValue(self): + """ mode is auto-generated from inherit_id: + * inherit_id -> mode=extendion + * not inherit_id -> mode=primary + """ + view = self.browse(self.create({ + 'inherit_id': None, + 'arch': '' + })) + self.assertEqual(view.mode, 'primary') + + view2 = self.browse(self.create({ + 'inherit_id': view.id, + 'arch': '' + })) + self.assertEqual(view2.mode, 'extension') + + def testModeExplicit(self): + view = self.browse(self.create({ + 'inherit_id': None, + 'arch': '' + })) + view2 = self.browse(self.create({ + 'inherit_id': view.id, + 'mode': 'primary', + 'arch': '' + })) + self.assertEqual(view.mode, 'primary') + + with self.assertRaises(Exception): + self.create({ + 'inherit_id': None, + 'mode': 'extension', + 'arch': '' + }) + + def testPurePrimaryToExtension(self): + """ + A primary view with inherit_id=None can't be converted to extension + """ + view_pure_primary = self.browse(self.create({ + 'inherit_id': None, + 'arch': '' + })) + with self.assertRaises(Exception): + view_pure_primary.write({'mode': 'extension'}) + + def testInheritPirmaryToExtension(self): + """ + A primary view with an inherit_id can be converted to extension + """ + base = self.create({'inherit_id': None, 'arch': ''}) + view = self.browse(self.create({ + 'inherit_id': base, + 'mode': 'primary', + 'arch': '' + })) + + view.write({'mode': 'extension'}) + + def testDefaultExtensionToPrimary(self): + """ + An extension view can be converted to primary + """ + base = self.create({'inherit_id': None, 'arch': ''}) + view = self.browse(self.create({ + 'inherit_id': base, + 'arch': '' + })) + + view.write({'mode': 'primary'}) + class TestXPathExtentions(common.BaseCase): def test_hasclass(self): tree = E.node(