diff --git a/CHANGELOG b/CHANGELOG
index e798a56e38..6ff70ef9f7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,4 @@
+* Allow to inherit views from an other model
* Add user warnings
* Allow to use a list of id for copy method
* Use one lock per database
diff --git a/trytond/ir/ui/form.rnc b/trytond/ir/ui/form.rnc
index 860cb575f6..1bebb46494 100644
--- a/trytond/ir/ui/form.rnc
+++ b/trytond/ir/ui/form.rnc
@@ -245,7 +245,7 @@ child2 =
}
attlist.child2 &= empty
-data = element data { attlist.data, xpath+ }
+data = element data { attlist.data, xpath* }
attlist.data &= empty
xpath = element xpath { attlist.xpath, any }
diff --git a/trytond/ir/ui/form.rng b/trytond/ir/ui/form.rng
index d85f277dd2..326aa9ccb6 100644
--- a/trytond/ir/ui/form.rng
+++ b/trytond/ir/ui/form.rng
@@ -822,9 +822,9 @@
-
+
-
+
diff --git a/trytond/ir/ui/view.py b/trytond/ir/ui/view.py
index a16b9b9b71..231f764c0a 100644
--- a/trytond/ir/ui/view.py
+++ b/trytond/ir/ui/view.py
@@ -6,6 +6,7 @@ from difflib import SequenceMatcher
import os
import logging
from lxml import etree
+from trytond.sql_db import table_handler
class View(OSV):
@@ -23,7 +24,7 @@ class View(OSV):
('calendar', 'Calendar'),
('board', 'Board'),
], 'View Type', select=1)
- arch = fields.Text('View Architecture', required=True)
+ arch = fields.Text('View Architecture')
inherit = fields.Many2One('ir.ui.view', 'Inherited View', select=1,
ondelete='CASCADE')
field_childs = fields.Char('Childs Field', states={
@@ -44,6 +45,17 @@ class View(OSV):
})
self._order.insert(0, ('priority', 'ASC'))
+ def _auto_init(self, cursor, module_name):
+ super(View, self)._auto_init(cursor, module_name)
+ table = table_handler(cursor, self._table, self._name, module_name)
+
+ # Migration from 1.0 arch no more required
+ if 'arch' in table.table:
+ if table.table['arch']['notnull']:
+ cursor.execute('ALTER TABLE "' + self._table + '" ' \
+ 'ALTER COLUMN "arch" ' \
+ 'DROP NOT NULL')
+
def default_arch(self, cursor, user, context=None):
return ''
@@ -66,17 +78,13 @@ class View(OSV):
trans_views = {}
for trans in cursor.dictfetchall():
trans_views[trans['src']] = trans
+ if not view.arch:
+ continue
xml = view.arch.strip()
+ if not xml:
+ continue
tree = etree.fromstring(xml)
- if view.inherit:
- if view.model != view.inherit.model:
- logger = logging.getLogger('ir')
- logger.error('Invalid model "%s" ' \
- 'with inherited model "%"' % \
- (view.model, view.inherit.model))
- return False
-
# validate the tree using RelaxNG
rng_name = os.path.join(os.path.dirname(__file__),
(view.inherit and view.inherit.type or view.type) + '.rng')
diff --git a/trytond/osv/orm.py b/trytond/osv/orm.py
index ff6026a943..4068967755 100644
--- a/trytond/osv/orm.py
+++ b/trytond/osv/orm.py
@@ -2250,47 +2250,60 @@ class ORM(object):
test = True
model = True
sql_res = False
+ inherit_view_id = False
while test:
if view_id:
where = (model and (" and model='%s'" % (self._name,))) or ''
cursor.execute('SELECT arch, field_childs, id, type, ' \
- 'inherit ' \
+ 'inherit, model ' \
'FROM ir_ui_view WHERE id = %s ' + where, (view_id,))
else:
cursor.execute('SELECT arch, field_childs, id, type, ' \
- 'inherit ' \
+ 'inherit, model ' \
'FROM ir_ui_view ' \
- 'WHERE model = %s AND type = %s AND inherit IS NULL ' \
- 'ORDER BY priority',
- (self._name,view_type))
+ 'WHERE model = %s AND type = %s' \
+ 'ORDER BY inherit DESC, priority',
+ (self._name, view_type))
sql_res = cursor.fetchone()
if not sql_res:
break
test = sql_res[4]
+ if test:
+ inherit_view_id = sql_res[2]
view_id = test or sql_res[2]
model = False
# if a view was found
if sql_res:
result['type'] = sql_res[3]
- result['view_id'] = sql_res[2]
+ result['view_id'] = view_id
result['arch'] = sql_res[0]
+ if sql_res[5] != self._name:
+ inherit_obj = self.pool.get(sql_res[5])
+ result['arch'] = inherit_obj.fields_view_get(cursor, user,
+ result['view_id'], context=context)['arch']
+ view_id = inherit_view_id
+
def _inherit_apply_rec(result, inherit_id):
# get all views which inherit from (ie modify) this view
cursor.execute('SELECT arch, domain, id FROM ir_ui_view ' \
- 'WHERE inherit = %s AND model = %s ' \
- 'ORDER BY priority', (inherit_id, self._name))
+ 'WHERE (inherit = %s AND model = %s) OR ' \
+ ' (id = %s AND inherit IS NOT NULL) '
+ 'ORDER BY priority',
+ (inherit_id, self._name, inherit_id))
sql_inherit = cursor.fetchall()
- for (inherit, domain, view_id) in sql_inherit:
+ for (arch, domain, view_id) in sql_inherit:
if domain:
if not eval(domain, {'context': context}):
continue
- result = _inherit_apply(result, inherit)
- result = _inherit_apply_rec(result, view_id)
+ if not arch or not arch.strip():
+ continue
+ result = _inherit_apply(result, arch)
+ #result = _inherit_apply_rec(result, view_id)
return result
- result['arch'] = _inherit_apply_rec(result['arch'], sql_res[2])
+ result['arch'] = _inherit_apply_rec(result['arch'], view_id)
result['field_childs'] = sql_res[1] or False
# otherwise, build some kind of default view