diff --git a/trytond/trytond/ir/ui/view.py b/trytond/trytond/ir/ui/view.py
index d38177a03e..603f89c5ec 100644
--- a/trytond/trytond/ir/ui/view.py
+++ b/trytond/trytond/ir/ui/view.py
@@ -4,6 +4,7 @@ import json
import os
from lxml import etree
+from sql import Literal, Null
from trytond.cache import Cache, MemoryCache
from trytond.i18n import gettext
@@ -70,8 +71,22 @@ class View(
arch = fields.Function(fields.Text('View Architecture', states={
'readonly': Bool(Eval('name')),
}, depends=['name']), 'get_arch', setter='set_arch')
+ basis = fields.Function(fields.Boolean("Basis"), 'get_basis')
inherit = fields.Many2One('ir.ui.view', 'Inherited View',
ondelete='CASCADE')
+ extensions = fields.One2Many(
+ 'ir.ui.view', 'inherit', "Extensions",
+ filter=[
+ ('basis', '=', False),
+ ],
+ domain=[
+ ('model', '=', Eval('model')),
+ ('type', '=', None),
+ ],
+ states={
+ 'invisible': ~Eval('type'),
+ },
+ order=[('id', None)])
field_childs = fields.Char('Children Field', states={
'invisible': Eval('type') != 'tree',
}, depends=['type'])
@@ -95,7 +110,8 @@ class View(
cls._buttons.update({
'show': {
'readonly': Eval('type') != 'form',
- 'depends': ['type'],
+ 'invisible': ~Eval('basis', False),
+ 'depends': ['type', 'basis'],
},
})
cls._sql_indexes.update({
@@ -116,6 +132,36 @@ class View(
def default_module():
return Transaction().context.get('module') or ''
+ def get_basis(self, name):
+ return not self.inherit or self.model != self.inherit.model
+
+ @classmethod
+ def domain_basis(cls, domain, tables):
+ table, _ = tables[None]
+ if 'inherit' not in tables:
+ inherit = cls.__table__()
+ tables['inherit'] = {
+ None: (inherit, table.inherit == inherit.id),
+ }
+ else:
+ inherit, _ = tables['inherit'][None]
+ expression = (table.inherit == Null) | (table.model != inherit.model)
+
+ _, operator, value = domain
+ if operator in {'=', '!='}:
+ if (operator == '=') != value:
+ expression = ~expression
+ elif operator in {'in', 'not in'}:
+ if True in value and False not in value:
+ pass
+ elif False in value and True not in value:
+ expression = ~expression
+ else:
+ expression = Literal(True)
+ else:
+ expression = Literal(True)
+ return expression
+
def get_rec_name(self, name):
return '%s (%s)' % (
self.model_ref.rec_name,
diff --git a/trytond/trytond/ir/ui/view.xml b/trytond/trytond/ir/ui/view.xml
index 3e5f0806a5..582c56e0c0 100644
--- a/trytond/trytond/ir/ui/view.xml
+++ b/trytond/trytond/ir/ui/view.xml
@@ -17,12 +17,21 @@ this repository contains the full copyright notices and license terms. -->
ir.ui.view
tree
+
ui_view_list
+
+ ir.ui.view
+ tree
+
+ ui_view_list_extension
+
Views
ir.action.act_window
ir.ui.view
+
+
diff --git a/trytond/trytond/ir/view/ui_view_form.xml b/trytond/trytond/ir/view/ui_view_form.xml
index 8022e3ad1b..2043876a70 100644
--- a/trytond/trytond/ir/view/ui_view_form.xml
+++ b/trytond/trytond/ir/view/ui_view_form.xml
@@ -20,5 +20,6 @@ this repository contains the full copyright notices and license terms. -->
+
diff --git a/trytond/trytond/ir/view/ui_view_list.xml b/trytond/trytond/ir/view/ui_view_list.xml
index 8a3c74870d..0d613082c0 100644
--- a/trytond/trytond/ir/view/ui_view_list.xml
+++ b/trytond/trytond/ir/view/ui_view_list.xml
@@ -5,8 +5,7 @@ this repository contains the full copyright notices and license terms. -->
-
-
+
diff --git a/trytond/trytond/ir/view/ui_view_list_extension.xml b/trytond/trytond/ir/view/ui_view_list_extension.xml
new file mode 100644
index 0000000000..1878ed95f1
--- /dev/null
+++ b/trytond/trytond/ir/view/ui_view_list_extension.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+