[ADD] mode attribute to views
authorXavier Morel <xmo@openerp.com>
Tue, 27 May 2014 09:43:08 +0000 (11:43 +0200)
committerXavier Morel <xmo@openerp.com>
Tue, 27 May 2014 09:57:01 +0000 (11:57 +0200)
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
openerp/addons/base/tests/test_views.py

index 1a75c08..b8ae58d 100644 (file)
@@ -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):
index feb22eb..29e6fe1 100644 (file)
@@ -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': '<qweb/>'
+        }))
+        self.assertEqual(view.mode, 'primary')
+
+        view2 = self.browse(self.create({
+            'inherit_id': view.id,
+            'arch': '<qweb/>'
+        }))
+        self.assertEqual(view2.mode, 'extension')
+
+    def testModeExplicit(self):
+        view = self.browse(self.create({
+            'inherit_id': None,
+            'arch': '<qweb/>'
+        }))
+        view2 = self.browse(self.create({
+            'inherit_id': view.id,
+            'mode': 'primary',
+            'arch': '<qweb/>'
+        }))
+        self.assertEqual(view.mode, 'primary')
+
+        with self.assertRaises(Exception):
+            self.create({
+                'inherit_id': None,
+                'mode': 'extension',
+                'arch': '<qweb/>'
+            })
+
+    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': '<qweb/>'
+        }))
+        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': '<qweb/>'})
+        view = self.browse(self.create({
+            'inherit_id': base,
+            'mode': 'primary',
+            'arch': '<qweb/>'
+        }))
+
+        view.write({'mode': 'extension'})
+
+    def testDefaultExtensionToPrimary(self):
+        """
+        An extension view can be converted to primary
+        """
+        base = self.create({'inherit_id': None, 'arch': '<qweb/>'})
+        view = self.browse(self.create({
+            'inherit_id': base,
+            'arch': '<qweb/>'
+        }))
+
+        view.write({'mode': 'primary'})
+
 class TestXPathExtentions(common.BaseCase):
     def test_hasclass(self):
         tree = E.node(