Add modelview
This commit is contained in:
1 parent
5218c3545f
commit
b137a42676
3 files changed
+371
-339
No files matched your search
@@ -1,3 +1,4 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
from model import *
|
||||
from modelview import *
|
||||
@@ -0,0 +1,368 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
from trytond.model import Model
|
||||
from trytond.tools import Cache
|
||||
from lxml import etree
|
||||
import md5
|
||||
import copy
|
||||
|
||||
def _find(tree, element):
|
||||
if element.tag == 'xpath':
|
||||
res = tree.xpath(element.get('expr'))
|
||||
if res:
|
||||
return res[0]
|
||||
return None
|
||||
|
||||
|
||||
def _inherit_apply(src, inherit):
|
||||
tree_src = etree.fromstring(src)
|
||||
tree_inherit = etree.fromstring(inherit)
|
||||
root_inherit = tree_inherit.getroottree().getroot()
|
||||
for element2 in root_inherit:
|
||||
element = _find(tree_src, element2)
|
||||
if element is not None:
|
||||
pos = element2.get('position', 'inside')
|
||||
if pos == 'replace':
|
||||
parent = element.getparent()
|
||||
next = element.getnext()
|
||||
if next is not None:
|
||||
for child in element2:
|
||||
index = parent.index(next)
|
||||
parent.insert(index, child)
|
||||
else:
|
||||
parent.extend(element2.getchildren())
|
||||
parent.remove(element)
|
||||
elif pos == 'replace_attributes':
|
||||
child = element2.getchildren()[0]
|
||||
for attr in child.attrib:
|
||||
element.set(attr, child.get(attr))
|
||||
elif pos == 'inside':
|
||||
element.extend(element2.getchildren())
|
||||
elif pos == 'after':
|
||||
parent = element.getparent()
|
||||
next = element.getnext()
|
||||
if next is not None:
|
||||
for child in element2:
|
||||
index = parent.index(next)
|
||||
parent.insert(index, child)
|
||||
else:
|
||||
parent.extend(element2.getchildren())
|
||||
elif pos == 'before':
|
||||
parent = element.getparent()
|
||||
for child in element2:
|
||||
index = parent.index(element)
|
||||
parent.insert(index, child)
|
||||
else:
|
||||
raise AttributeError('Unknown position ' \
|
||||
'in inherited view %s!' % pos)
|
||||
else:
|
||||
raise AttributeError(
|
||||
'Couldn\'t find tag (%s: %s) in parent view!' % \
|
||||
(element2.tag, element2.get('expr')))
|
||||
return etree.tostring(tree_src, encoding='utf-8')
|
||||
|
||||
|
||||
class ModelView(Model):
|
||||
"""
|
||||
Define a model with views in Tryton.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super(ModelView, self).__init__()
|
||||
self._rpc_allowed += [
|
||||
'fields_view_get',
|
||||
]
|
||||
|
||||
def fields_view_get(self, cursor, user, view_id=None, view_type='form',
|
||||
context=None, toolbar=False, hexmd5=None):
|
||||
'''
|
||||
Return a view definition
|
||||
|
||||
:param cursor: the database cursor
|
||||
:param user: the user id
|
||||
:param view_id: the id of the view, if None the first one will be used
|
||||
:param view_type: the type of the view if view_id is None
|
||||
:param context: the context
|
||||
:param toolbar: if True the result will contain a toolbar key with
|
||||
keyword action definitions for the view
|
||||
:param hexmd5: if fill, the function will return True if the result
|
||||
have the same md5
|
||||
:return: a dictionnary with keys:
|
||||
- model: the model name
|
||||
- arch: the xml description of the view
|
||||
- fields: a dictionnary with the definition of each fields
|
||||
in the view
|
||||
- toolbar: a dictionnary with the keyword action definitions
|
||||
- md5: the check sum of the dictionnary without this checksum
|
||||
'''
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
result = {'model': self._name}
|
||||
|
||||
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, model ' \
|
||||
'FROM ir_ui_view WHERE id = %s ' + where, (view_id,))
|
||||
else:
|
||||
cursor.execute('SELECT arch, field_childs, id, type, ' \
|
||||
'inherit, model ' \
|
||||
'FROM ir_ui_view ' \
|
||||
'WHERE model = %s AND type = %s' \
|
||||
'ORDER BY inherit DESC, priority ASC, id ASC',
|
||||
(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'] = view_id
|
||||
result['arch'] = sql_res[0]
|
||||
result['field_childs'] = sql_res[1] or False
|
||||
|
||||
# Check if view is not from an inherited model
|
||||
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
|
||||
|
||||
# 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) OR ' \
|
||||
' (id = %s AND inherit IS NOT NULL) '
|
||||
'ORDER BY priority ASC, id ASC',
|
||||
(view_id, self._name, view_id))
|
||||
sql_inherit = cursor.fetchall()
|
||||
for (arch, domain, view_id) in sql_inherit:
|
||||
if domain:
|
||||
if not eval(domain, {'context': context}):
|
||||
continue
|
||||
if not arch or not arch.strip():
|
||||
continue
|
||||
result['arch'] = _inherit_apply(result['arch'], arch)
|
||||
|
||||
# otherwise, build some kind of default view
|
||||
else:
|
||||
if view_type == 'form':
|
||||
res = self.fields_get(cursor, user, context=context)
|
||||
xml = '''<?xml version="1.0" encoding="utf-8"?>''' \
|
||||
'''<form string="%s">''' % (self._description,)
|
||||
for i in res:
|
||||
if i in ('create_uid', 'create_date',
|
||||
'write_uid', 'write_date', 'id'):
|
||||
continue
|
||||
if res[i]['type'] not in ('one2many', 'many2many'):
|
||||
xml += '<label name="%s"/>' % (i,)
|
||||
xml += '<field name="%s"/>' % (i,)
|
||||
if res[i]['type'] == 'text':
|
||||
xml += "<newline/>"
|
||||
xml += "</form>"
|
||||
elif view_type == 'tree':
|
||||
field = 'id'
|
||||
if self._rec_name in self._columns:
|
||||
field = self._rec_name
|
||||
xml = '''<?xml version="1.0" encoding="utf-8"?>''' \
|
||||
'''<tree string="%s"><field name="%s"/></tree>''' \
|
||||
% (self._description, field)
|
||||
elif view_type == 'calendar':
|
||||
xml = '''<?xml version="1.0" encoding="utf-8"?>''' \
|
||||
'''<calendar string="%s" date_start="%s">''' \
|
||||
'''<field name="%s"/></calendar>''' \
|
||||
% (self._description, self._date_name, self._rec_name)
|
||||
else:
|
||||
xml = ''
|
||||
result['type'] = view_type
|
||||
result['arch'] = xml
|
||||
result['field_childs'] = False
|
||||
result['view_id'] = 0
|
||||
|
||||
# Update arch and compute fields from arch
|
||||
parser = etree.XMLParser(remove_blank_text=True)
|
||||
tree = etree.fromstring(result['arch'], parser)
|
||||
xarch, xfields = self._view_look_dom_arch(cursor, user, tree,
|
||||
result['type'], context=context)
|
||||
result['arch'] = xarch
|
||||
result['fields'] = xfields
|
||||
|
||||
# Add toolbar
|
||||
if toolbar:
|
||||
action_obj = self.pool.get('ir.action.keyword')
|
||||
prints = action_obj.get_keyword(cursor, user, 'form_print',
|
||||
(self._name, 0), context=context)
|
||||
actions = action_obj.get_keyword(cursor, user, 'form_action',
|
||||
(self._name, 0), context=context)
|
||||
relates = action_obj.get_keyword(cursor, user, 'form_relate',
|
||||
(self._name, 0), context=context)
|
||||
result['toolbar'] = {
|
||||
'print': prints,
|
||||
'action': actions,
|
||||
'relate': relates,
|
||||
}
|
||||
|
||||
# Compute md5
|
||||
result['md5'] = md5.new(str(result)).hexdigest()
|
||||
if hexmd5 == result['md5']:
|
||||
return True
|
||||
return result
|
||||
|
||||
fields_view_get = Cache('orm.fields_view_get')(fields_view_get)
|
||||
|
||||
def view_header_get(self, cursor, user, value, view_type='form',
|
||||
context=None):
|
||||
"""
|
||||
Overload this method if you need a window title
|
||||
which depends on the context
|
||||
|
||||
:param cursor: the database cursor
|
||||
:param user: the user id
|
||||
:param value: the default header string
|
||||
:param view_type: the type of the view
|
||||
:param context: the context
|
||||
:return: the header string of the view
|
||||
"""
|
||||
return value
|
||||
|
||||
def _view_look_dom_arch(self, cursor, user, tree, type, context=None):
|
||||
fields_width = {}
|
||||
tree_root = tree.getroottree().getroot()
|
||||
|
||||
if type == 'tree':
|
||||
viewtreewidth_obj = self.pool.get('ir.ui.view_tree_width')
|
||||
viewtreewidth_ids = viewtreewidth_obj.search(cursor, user, [
|
||||
('model', '=', self._name),
|
||||
('user', '=', user),
|
||||
], context=context)
|
||||
for viewtreewidth in viewtreewidth_obj.browse(cursor, user,
|
||||
viewtreewidth_ids, context=context):
|
||||
if viewtreewidth.width > 0:
|
||||
fields_width[viewtreewidth.field] = viewtreewidth.width
|
||||
|
||||
fields_def = self.__view_look_dom(cursor, user, tree_root, type,
|
||||
fields_width=fields_width, context=context)
|
||||
|
||||
for field_name in fields_def.keys():
|
||||
if field_name in self._columns:
|
||||
field = self._columns[field_name]
|
||||
elif field_name in self._inherit_fields:
|
||||
field = self._inherit_fields[field_name][2]
|
||||
else:
|
||||
continue
|
||||
for depend in field.depends:
|
||||
fields_def.setdefault(depend, {'name': depend})
|
||||
|
||||
if ('active' in self._columns) or ('active' in self._inherit_fields):
|
||||
fields_def.setdefault('active', {'name': 'active', 'select': "2"})
|
||||
|
||||
arch = etree.tostring(tree, encoding='utf-8', pretty_print=False)
|
||||
fields2 = self.fields_get(cursor, user, fields_def.keys(), context)
|
||||
for field in fields_def:
|
||||
if field in fields2:
|
||||
fields2[field].update(fields_def[field])
|
||||
return arch, fields2
|
||||
|
||||
def __view_look_dom(self, cursor, user, element, type, fields_width=None,
|
||||
context=None):
|
||||
translation_obj = self.pool.get('ir.translation')
|
||||
|
||||
if fields_width is None:
|
||||
fields_width = {}
|
||||
if context is None:
|
||||
context = {}
|
||||
result = False
|
||||
fields_attrs = {}
|
||||
childs = True
|
||||
|
||||
if element.tag in ('field', 'label', 'separator', 'group'):
|
||||
for attr in ('name', 'icon'):
|
||||
if element.get(attr):
|
||||
attrs = {}
|
||||
try:
|
||||
if element.get(attr) in self._columns:
|
||||
relation = self._columns[element.get(attr)]._obj
|
||||
else:
|
||||
relation = self._inherit_fields[element.get(attr)][2]._obj
|
||||
except:
|
||||
relation = False
|
||||
if relation and element.tag == 'field':
|
||||
childs = False
|
||||
views = {}
|
||||
for field in element:
|
||||
if field.tag in ('form', 'tree', 'graph'):
|
||||
field2 = copy.copy(field)
|
||||
|
||||
def _translate_field(field):
|
||||
if field.get('string'):
|
||||
trans = translation_obj._get_source(
|
||||
cursor, self._name, 'view',
|
||||
context['language'],
|
||||
field.get('string'))
|
||||
if trans:
|
||||
field.set('string', trans)
|
||||
if field.get('sum'):
|
||||
trans = translation_obj._get_source(
|
||||
cursor, self._name, 'view',
|
||||
context['language'],
|
||||
field.get('sum'))
|
||||
if trans:
|
||||
field.set('sum', trans)
|
||||
for field_child in field:
|
||||
_translate_field(field_child)
|
||||
if 'language' in context:
|
||||
_translate_field(field2)
|
||||
|
||||
relation_obj = self.pool.get(relation)
|
||||
if hasattr(relation_obj, '_view_look_dom_arch'):
|
||||
xarch, xfields = \
|
||||
relation_obj._view_look_dom_arch(
|
||||
cursor, user,
|
||||
field2, field.tag,
|
||||
context=context)
|
||||
views[field.tag] = {
|
||||
'arch': xarch,
|
||||
'fields': xfields
|
||||
}
|
||||
element.remove(field)
|
||||
attrs = {'views': views}
|
||||
fields_attrs[element.get(attr)] = attrs
|
||||
if element.get('name') in fields_width:
|
||||
element.set('width', str(fields_width[element.get('name')]))
|
||||
|
||||
# translate view
|
||||
if ('language' in context) and not result:
|
||||
for attr in ('string', 'sum', 'confirm', 'help'):
|
||||
if element.get(attr):
|
||||
trans = translation_obj._get_source(cursor,
|
||||
self._name, 'view', context['language'],
|
||||
element.get(attr))
|
||||
if trans:
|
||||
element.set(attr, trans)
|
||||
|
||||
# Set header string
|
||||
if element.tag in ('form', 'tree', 'graph'):
|
||||
element.set('string', self.view_header_get(cursor, user,
|
||||
element.get('string') or '', view_type=element.tag,
|
||||
context=context))
|
||||
|
||||
if element.tag == 'tree' and element.get('sequence'):
|
||||
fields_attrs.setdefault(element.get('sequence'), {})
|
||||
|
||||
if childs:
|
||||
for field in element:
|
||||
fields_attrs.update(self.__view_look_dom(cursor, user, field,
|
||||
type, fields_width=fields_width, context=context))
|
||||
return fields_attrs
|
||||
+2
-339
@@ -1,15 +1,13 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
# -*- coding: utf-8 -*-
|
||||
from trytond.model import Model
|
||||
from trytond.model import ModelView
|
||||
from trytond.netsvc import LocalService
|
||||
import fields
|
||||
from trytond.tools import Cache
|
||||
import md5
|
||||
import time
|
||||
import traceback
|
||||
import datetime
|
||||
from lxml import etree
|
||||
import copy
|
||||
from trytond.sql_db import table_handler
|
||||
from decimal import Decimal
|
||||
@@ -283,7 +281,7 @@ class EvalEnvironment(dict):
|
||||
def __nonzero__(self):
|
||||
return bool(self.record)
|
||||
|
||||
class ORM(Model):
|
||||
class ORM(ModelView):
|
||||
"""
|
||||
Object relationnal mapping to postgresql module
|
||||
. Hierarchical structure
|
||||
@@ -445,7 +443,6 @@ class ORM(Model):
|
||||
'write',
|
||||
'create',
|
||||
'delete',
|
||||
'fields_view_get',
|
||||
'search',
|
||||
'name_get',
|
||||
'name_search',
|
||||
@@ -1541,340 +1538,6 @@ class ORM(Model):
|
||||
wf_service.trg_create(user, self._name, id_new, cursor, context=context)
|
||||
return id_new
|
||||
|
||||
|
||||
def view_header_get(self, cursor, user, value, view_type='form',
|
||||
context=None):
|
||||
"""
|
||||
Overload this method if you need a window title
|
||||
which depends on the context
|
||||
"""
|
||||
return False
|
||||
|
||||
def __view_look_dom(self, cursor, user, element, type, fields_width=None,
|
||||
context=None):
|
||||
translation_obj = self.pool.get('ir.translation')
|
||||
|
||||
if fields_width is None:
|
||||
fields_width = {}
|
||||
if context is None:
|
||||
context = {}
|
||||
result = False
|
||||
fields_attrs = {}
|
||||
childs = True
|
||||
|
||||
if element.tag in ('field', 'label', 'separator', 'group'):
|
||||
for attr in ('name', 'icon'):
|
||||
if element.get(attr):
|
||||
attrs = {}
|
||||
try:
|
||||
if element.get(attr) in self._columns:
|
||||
relation = self._columns[element.get(attr)]._obj
|
||||
else:
|
||||
relation = self._inherit_fields[element.get(attr)][2]._obj
|
||||
except:
|
||||
relation = False
|
||||
if relation and element.tag == 'field':
|
||||
childs = False
|
||||
views = {}
|
||||
for field in element:
|
||||
if field.tag in ('form', 'tree', 'graph'):
|
||||
field2 = copy.copy(field)
|
||||
|
||||
def _translate_field(field):
|
||||
if field.get('string'):
|
||||
trans = translation_obj._get_source(
|
||||
cursor, self._name, 'view',
|
||||
context['language'],
|
||||
field.get('string'))
|
||||
if trans:
|
||||
field.set('string', trans)
|
||||
if field.get('sum'):
|
||||
trans = translation_obj._get_source(
|
||||
cursor, self._name, 'view',
|
||||
context['language'],
|
||||
field.get('sum'))
|
||||
if trans:
|
||||
field.set('sum', trans)
|
||||
for field_child in field:
|
||||
_translate_field(field_child)
|
||||
if 'language' in context:
|
||||
_translate_field(field2)
|
||||
|
||||
xarch, xfields = self.pool.get(relation
|
||||
)._view_look_dom_arch(cursor, user,
|
||||
field2, field.tag,
|
||||
context=context)
|
||||
views[field.tag] = {
|
||||
'arch': xarch,
|
||||
'fields': xfields
|
||||
}
|
||||
element.remove(field)
|
||||
attrs = {'views': views}
|
||||
fields_attrs[element.get(attr)] = attrs
|
||||
if element.get('name') in fields_width:
|
||||
element.set('width', str(fields_width[element.get('name')]))
|
||||
|
||||
# translate view
|
||||
if ('language' in context) and not result:
|
||||
for attr in ('string', 'sum', 'confirm', 'help'):
|
||||
if element.get(attr):
|
||||
trans = translation_obj._get_source(cursor,
|
||||
self._name, 'view', context['language'],
|
||||
element.get(attr))
|
||||
if trans:
|
||||
element.set(attr, trans)
|
||||
|
||||
if element.tag in ('form', 'tree', 'graph'):
|
||||
value = ''
|
||||
if element.get('string'):
|
||||
value = element.get('string')
|
||||
result = self.view_header_get(cursor, user, value, element.tag,
|
||||
context)
|
||||
if result:
|
||||
element.set('string', result)
|
||||
if element.tag == 'tree' and element.get('sequence'):
|
||||
fields_attrs.setdefault(element.get('sequence'), {})
|
||||
|
||||
if childs:
|
||||
for field in element:
|
||||
fields_attrs.update(self.__view_look_dom(cursor, user, field,
|
||||
type, fields_width=fields_width, context=context))
|
||||
return fields_attrs
|
||||
|
||||
def _view_look_dom_arch(self, cursor, user, tree, type, context=None):
|
||||
fields_width = {}
|
||||
tree_root = tree.getroottree().getroot()
|
||||
|
||||
if type == 'tree':
|
||||
viewtreewidth_obj = self.pool.get('ir.ui.view_tree_width')
|
||||
viewtreewidth_ids = viewtreewidth_obj.search(cursor, user, [
|
||||
('model', '=', self._name),
|
||||
('user', '=', user),
|
||||
], context=context)
|
||||
for viewtreewidth in viewtreewidth_obj.browse(cursor, user,
|
||||
viewtreewidth_ids, context=context):
|
||||
if viewtreewidth.width > 0:
|
||||
fields_width[viewtreewidth.field] = viewtreewidth.width
|
||||
|
||||
fields_def = self.__view_look_dom(cursor, user, tree_root, type,
|
||||
fields_width=fields_width, context=context)
|
||||
|
||||
for field_name in fields_def.keys():
|
||||
if field_name in self._columns:
|
||||
field = self._columns[field_name]
|
||||
elif field_name in self._inherit_fields:
|
||||
field = self._inherit_fields[field_name][2]
|
||||
else:
|
||||
continue
|
||||
for depend in field.depends:
|
||||
fields_def.setdefault(depend, {'name': depend})
|
||||
|
||||
if ('active' in self._columns) or ('active' in self._inherit_fields):
|
||||
fields_def.setdefault('active', {'name': 'active', 'select': "2"})
|
||||
|
||||
arch = etree.tostring(tree, encoding='utf-8', pretty_print=False)
|
||||
fields2 = self.fields_get(cursor, user, fields_def.keys(), context)
|
||||
for field in fields_def:
|
||||
if field in fields2:
|
||||
fields2[field].update(fields_def[field])
|
||||
return arch, fields2
|
||||
|
||||
def fields_view_get(self, cursor, user, view_id=None, view_type='form',
|
||||
context=None, toolbar=False, hexmd5=None):
|
||||
'''
|
||||
Return a dict with keys:
|
||||
- arch: the xml description of the view.
|
||||
- fields: a dict with the definition of each fields.
|
||||
- toolbar: if toolbar is True, a dict with 'print', 'action', 'relate'
|
||||
keyword action defintion for the view.
|
||||
- md5: the check sum of the above dict that will be used for caching.
|
||||
view_id can specify the id of the view, if empty the system
|
||||
will select the first view
|
||||
view_type specify the type of the view if view_id is empty
|
||||
If hexmd5 is fill, the function will return True if the view have the same
|
||||
md5 or the dict.
|
||||
'''
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
def _inherit_apply(src, inherit):
|
||||
|
||||
def _find(tree, element):
|
||||
if element.tag == 'xpath':
|
||||
res = tree.xpath(element.get('expr'))
|
||||
if res:
|
||||
return res[0]
|
||||
return None
|
||||
|
||||
tree_src = etree.fromstring(src)
|
||||
tree_inherit = etree.fromstring(inherit)
|
||||
root_inherit = tree_inherit.getroottree().getroot()
|
||||
for element2 in root_inherit:
|
||||
element = _find(tree_src, element2)
|
||||
if element is not None:
|
||||
pos = element2.get('position', 'inside')
|
||||
if pos == 'replace':
|
||||
parent = element.getparent()
|
||||
next = element.getnext()
|
||||
if next is not None:
|
||||
for child in element2:
|
||||
index = parent.index(next)
|
||||
parent.insert(index, child)
|
||||
else:
|
||||
parent.extend(element2.getchildren())
|
||||
parent.remove(element)
|
||||
elif pos == 'replace_attributes':
|
||||
child = element2.getchildren()[0]
|
||||
for attr in child.attrib:
|
||||
element.set(attr, child.get(attr))
|
||||
elif pos == 'inside':
|
||||
element.extend(element2.getchildren())
|
||||
elif pos == 'after':
|
||||
parent = element.getparent()
|
||||
next = element.getnext()
|
||||
if next is not None:
|
||||
for child in element2:
|
||||
index = parent.index(next)
|
||||
parent.insert(index, child)
|
||||
else:
|
||||
parent.extend(element2.getchildren())
|
||||
elif pos == 'before':
|
||||
parent = element.getparent()
|
||||
for child in element2:
|
||||
index = parent.index(element)
|
||||
parent.insert(index, child)
|
||||
else:
|
||||
raise AttributeError('Unknown position ' \
|
||||
'in inherited view %s!' % pos)
|
||||
else:
|
||||
raise AttributeError(
|
||||
'Couldn\'t find tag (%s: %s) in parent view!' % \
|
||||
(element2.tag, element2.get('expr')))
|
||||
return etree.tostring(tree_src, encoding='utf-8')
|
||||
|
||||
result = {'type': view_type, 'model': self._name}
|
||||
|
||||
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, model ' \
|
||||
'FROM ir_ui_view WHERE id = %s ' + where, (view_id,))
|
||||
else:
|
||||
cursor.execute('SELECT arch, field_childs, id, type, ' \
|
||||
'inherit, model ' \
|
||||
'FROM ir_ui_view ' \
|
||||
'WHERE model = %s AND type = %s' \
|
||||
'ORDER BY inherit DESC, priority ASC, id ASC',
|
||||
(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'] = 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) OR ' \
|
||||
' (id = %s AND inherit IS NOT NULL) '
|
||||
'ORDER BY priority ASC, id ASC',
|
||||
(inherit_id, self._name, inherit_id))
|
||||
sql_inherit = cursor.fetchall()
|
||||
for (arch, domain, view_id) in sql_inherit:
|
||||
if domain:
|
||||
if not eval(domain, {'context': context}):
|
||||
continue
|
||||
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'], view_id)
|
||||
|
||||
result['field_childs'] = sql_res[1] or False
|
||||
# otherwise, build some kind of default view
|
||||
else:
|
||||
if view_type == 'form':
|
||||
res = self.fields_get(cursor, user, context=context)
|
||||
xml = '''<?xml version="1.0" encoding="utf-8"?>''' \
|
||||
'''<form string="%s">''' % (self._description,)
|
||||
for i in res:
|
||||
if i in ('create_uid', 'create_date',
|
||||
'write_uid', 'write_date', 'id'):
|
||||
continue
|
||||
if res[i]['type'] not in ('one2many', 'many2many'):
|
||||
xml += '<label name="%s"/>' % (i,)
|
||||
xml += '<field name="%s"/>' % (i,)
|
||||
if res[i]['type'] == 'text':
|
||||
xml += "<newline/>"
|
||||
xml += "</form>"
|
||||
elif view_type == 'tree':
|
||||
field = 'id'
|
||||
if self._rec_name in self._columns:
|
||||
field = self._rec_name
|
||||
xml = '''<?xml version="1.0" encoding="utf-8"?>''' \
|
||||
'''<tree string="%s"><field name="%s"/></tree>''' \
|
||||
% (self._description, field)
|
||||
elif view_type == 'calendar':
|
||||
xml = '''<?xml version="1.0" encoding="utf-8"?>''' \
|
||||
'''<calendar string="%s" date_start="%s">''' \
|
||||
'''<field name="%s"/></calendar>''' \
|
||||
% (self._description, self._date_name, self._rec_name)
|
||||
else:
|
||||
xml = ''
|
||||
result['type'] = view_type
|
||||
result['arch'] = xml
|
||||
result['field_childs'] = False
|
||||
result['view_id'] = 0
|
||||
|
||||
parser = etree.XMLParser(remove_blank_text=True)
|
||||
tree = etree.fromstring(result['arch'], parser)
|
||||
xarch, xfields = self._view_look_dom_arch(cursor, user, tree,
|
||||
result['type'], context=context)
|
||||
result['arch'] = xarch
|
||||
result['fields'] = xfields
|
||||
if toolbar:
|
||||
action_obj = self.pool.get('ir.action.keyword')
|
||||
prints = action_obj.get_keyword(cursor, user, 'form_print',
|
||||
(self._name, 0), context=context)
|
||||
actions = action_obj.get_keyword(cursor, user, 'form_action',
|
||||
(self._name, 0), context=context)
|
||||
relates = action_obj.get_keyword(cursor, user, 'form_relate',
|
||||
(self._name, 0), context=context)
|
||||
result['toolbar'] = {
|
||||
'print': prints,
|
||||
'action': actions,
|
||||
'relate': relates,
|
||||
}
|
||||
result['md5'] = md5.new(str(result)).hexdigest()
|
||||
if hexmd5 == result['md5']:
|
||||
return True
|
||||
return result
|
||||
|
||||
fields_view_get = Cache('orm.fields_view_get')(fields_view_get)
|
||||
|
||||
def _where_calc(self, cursor, user, args, active_test=True, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
Reference in new issue
Block a user