[NOTSURE] move __view_look_dom_arch into ir.ui.view
Also alter BaseModel._view_look_dom_arch to proxy to method above. bzr revid: xmo@openerp.com-20130424135825-grjfgbjuc4ozzdqy
This commit is contained in:
parent
66121aaec7
commit
c08513763c
|
@ -24,9 +24,10 @@ import logging
|
|||
import itertools
|
||||
from lxml import etree
|
||||
import os
|
||||
import time
|
||||
|
||||
from openerp import tools
|
||||
from openerp.osv import fields,osv
|
||||
from openerp.osv import fields, osv, orm
|
||||
from openerp.tools import graph, SKIPPED_ELEMENT_TYPES
|
||||
from openerp.tools.safe_eval import safe_eval as eval
|
||||
from openerp.tools.translate import _
|
||||
|
@ -539,6 +540,269 @@ class view(osv.osv):
|
|||
'blank_nodes': blank_nodes,
|
||||
'node_parent_field': _Model_Field,}
|
||||
|
||||
# this really needs to be refixtored
|
||||
def __view_look_dom(self, cr, user, model, node, view_id, in_tree_view, model_fields, context=None):
|
||||
"""Return the description of the fields in the node.
|
||||
|
||||
In a normal call to this method, node is a complete view architecture
|
||||
but it is actually possible to give some sub-node (this is used so
|
||||
that the method can call itself recursively).
|
||||
|
||||
Originally, the field descriptions are drawn from the node itself.
|
||||
But there is now some code calling fields_get() in order to merge some
|
||||
of those information in the architecture.
|
||||
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
result = False
|
||||
fields = {}
|
||||
children = True
|
||||
|
||||
modifiers = {}
|
||||
Model = self.pool[model]
|
||||
|
||||
def encode(s):
|
||||
if isinstance(s, unicode):
|
||||
return s.encode('utf8')
|
||||
return s
|
||||
|
||||
def check_group(node):
|
||||
"""Apply group restrictions, may be set at view level or model level::
|
||||
* at view level this means the element should be made invisible to
|
||||
people who are not members
|
||||
* at model level (exclusively for fields, obviously), this means
|
||||
the field should be completely removed from the view, as it is
|
||||
completely unavailable for non-members
|
||||
|
||||
:return: True if field should be included in the result of fields_view_get
|
||||
"""
|
||||
if node.tag == 'field' and node.get('name') in Model._all_columns:
|
||||
column = Model._all_columns[node.get('name')].column
|
||||
if column.groups and not self.user_has_groups(cr, user,
|
||||
groups=column.groups,
|
||||
context=context):
|
||||
node.getparent().remove(node)
|
||||
fields.pop(node.get('name'), None)
|
||||
# no point processing view-level ``groups`` anymore, return
|
||||
return False
|
||||
if node.get('groups'):
|
||||
can_see = self.user_has_groups(cr, user,
|
||||
groups=node.get('groups'),
|
||||
context=context)
|
||||
if not can_see:
|
||||
node.set('invisible', '1')
|
||||
modifiers['invisible'] = True
|
||||
if 'attrs' in node.attrib:
|
||||
del(node.attrib['attrs']) #avoid making field visible later
|
||||
del(node.attrib['groups'])
|
||||
return True
|
||||
|
||||
if node.tag in ('field', 'node', 'arrow'):
|
||||
if node.get('object'):
|
||||
attrs = {}
|
||||
views = {}
|
||||
xml = "<form>"
|
||||
for f in node:
|
||||
if f.tag == 'field':
|
||||
xml += etree.tostring(f, encoding="utf-8")
|
||||
xml += "</form>"
|
||||
new_xml = etree.fromstring(encode(xml))
|
||||
ctx = context.copy()
|
||||
ctx['base_model_name'] = model
|
||||
xarch, xfields = self.__view_look_dom_arch(cr, user, node.get('object'), new_xml, view_id, ctx)
|
||||
views['form'] = {
|
||||
'arch': xarch,
|
||||
'fields': xfields
|
||||
}
|
||||
attrs = {'views': views}
|
||||
fields = xfields
|
||||
if node.get('name'):
|
||||
attrs = {}
|
||||
try:
|
||||
if node.get('name') in Model._columns:
|
||||
column = Model._columns[node.get('name')]
|
||||
else:
|
||||
column = Model._inherit_fields[node.get('name')][2]
|
||||
except Exception:
|
||||
column = False
|
||||
|
||||
if column:
|
||||
relation = self.pool[column._obj] if column._obj else None
|
||||
|
||||
children = False
|
||||
views = {}
|
||||
for f in node:
|
||||
if f.tag in ('form', 'tree', 'graph', 'kanban'):
|
||||
node.remove(f)
|
||||
ctx = context.copy()
|
||||
ctx['base_model_name'] = Model
|
||||
xarch, xfields = self.__view_look_dom_arch(cr, user, column._obj or None, f, view_id, ctx)
|
||||
views[str(f.tag)] = {
|
||||
'arch': xarch,
|
||||
'fields': xfields
|
||||
}
|
||||
attrs = {'views': views}
|
||||
if node.get('widget') and node.get('widget') == 'selection':
|
||||
# Prepare the cached selection list for the client. This needs to be
|
||||
# done even when the field is invisible to the current user, because
|
||||
# other events could need to change its value to any of the selectable ones
|
||||
# (such as on_change events, refreshes, etc.)
|
||||
|
||||
# If domain and context are strings, we keep them for client-side, otherwise
|
||||
# we evaluate them server-side to consider them when generating the list of
|
||||
# possible values
|
||||
# TODO: find a way to remove this hack, by allow dynamic domains
|
||||
dom = []
|
||||
if column._domain and not isinstance(column._domain, basestring):
|
||||
dom = list(column._domain)
|
||||
dom += eval(node.get('domain', '[]'), {'uid': user, 'time': time})
|
||||
search_context = dict(context)
|
||||
if column._context and not isinstance(column._context, basestring):
|
||||
search_context.update(column._context)
|
||||
attrs['selection'] = relation._name_search(cr, user, '', dom, context=search_context, limit=None, name_get_uid=1)
|
||||
if (node.get('required') and not int(node.get('required'))) or not column.required:
|
||||
attrs['selection'].append((False, ''))
|
||||
fields[node.get('name')] = attrs
|
||||
|
||||
field = model_fields.get(node.get('name'))
|
||||
if field:
|
||||
orm.transfer_field_to_modifiers(field, modifiers)
|
||||
|
||||
|
||||
elif node.tag in ('form', 'tree'):
|
||||
result = Model.view_header_get(cr, user, False, node.tag, context)
|
||||
if result:
|
||||
node.set('string', result)
|
||||
in_tree_view = node.tag == 'tree'
|
||||
|
||||
elif node.tag == 'calendar':
|
||||
for additional_field in ('date_start', 'date_delay', 'date_stop', 'color'):
|
||||
if node.get(additional_field):
|
||||
fields[node.get(additional_field)] = {}
|
||||
|
||||
if not check_group(node):
|
||||
# node must be removed, no need to proceed further with its children
|
||||
return fields
|
||||
|
||||
# The view architeture overrides the python model.
|
||||
# Get the attrs before they are (possibly) deleted by check_group below
|
||||
orm.transfer_node_to_modifiers(node, modifiers, context, in_tree_view)
|
||||
|
||||
# TODO remove attrs couterpart in modifiers when invisible is true ?
|
||||
|
||||
# translate view
|
||||
if 'lang' in context:
|
||||
Translations = self.pool['ir.translation']
|
||||
if node.text and node.text.strip():
|
||||
trans = Translations._get_source(cr, user, model, 'view', context['lang'], node.text.strip())
|
||||
if trans:
|
||||
node.text = node.text.replace(node.text.strip(), trans)
|
||||
if node.tail and node.tail.strip():
|
||||
trans = Translations._get_source(cr, user, model, 'view', context['lang'], node.tail.strip())
|
||||
if trans:
|
||||
node.tail = node.tail.replace(node.tail.strip(), trans)
|
||||
|
||||
if node.get('string') and not result:
|
||||
trans = Translations._get_source(cr, user, model, 'view', context['lang'], node.get('string'))
|
||||
if trans == node.get('string') and ('base_model_name' in context):
|
||||
# If translation is same as source, perhaps we'd have more luck with the alternative model name
|
||||
# (in case we are in a mixed situation, such as an inherited view where parent_view.model != model
|
||||
trans = Translations._get_source(cr, user, context['base_model_name'], 'view', context['lang'], node.get('string'))
|
||||
if trans:
|
||||
node.set('string', trans)
|
||||
|
||||
for attr_name in ('confirm', 'sum', 'avg', 'help', 'placeholder'):
|
||||
attr_value = node.get(attr_name)
|
||||
if attr_value:
|
||||
trans = Translations._get_source(cr, user, model, 'view', context['lang'], attr_value)
|
||||
if trans:
|
||||
node.set(attr_name, trans)
|
||||
|
||||
for f in node:
|
||||
if children or (node.tag == 'field' and f.tag in ('filter','separator')):
|
||||
fields.update(self.__view_look_dom(cr, user, model, f, view_id, in_tree_view, model_fields, context))
|
||||
|
||||
orm.transfer_modifiers_to_node(modifiers, node)
|
||||
return fields
|
||||
|
||||
def _disable_workflow_buttons(self, cr, user, model, node):
|
||||
""" Set the buttons in node to readonly if the user can't activate them. """
|
||||
if user == 1:
|
||||
# admin user can always activate workflow buttons
|
||||
return node
|
||||
|
||||
# TODO handle the case of more than one workflow for a model or multiple
|
||||
# transitions with different groups and same signal
|
||||
usersobj = self.pool.get('res.users')
|
||||
buttons = (n for n in node.getiterator('button') if n.get('type') != 'object')
|
||||
for button in buttons:
|
||||
user_groups = usersobj.read(cr, user, [user], ['groups_id'])[0]['groups_id']
|
||||
cr.execute("""SELECT DISTINCT t.group_id
|
||||
FROM wkf
|
||||
INNER JOIN wkf_activity a ON a.wkf_id = wkf.id
|
||||
INNER JOIN wkf_transition t ON (t.act_to = a.id)
|
||||
WHERE wkf.osv = %s
|
||||
AND t.signal = %s
|
||||
AND t.group_id is NOT NULL
|
||||
""", (model, button.get('name')))
|
||||
group_ids = [x[0] for x in cr.fetchall() if x[0]]
|
||||
can_click = not group_ids or bool(set(user_groups).intersection(group_ids))
|
||||
button.set('readonly', str(int(not can_click)))
|
||||
return node
|
||||
|
||||
def __view_look_dom_arch(self, cr, user, model, node, view_id, context=None):
|
||||
""" Return an architecture and a description of all the fields.
|
||||
|
||||
The field description combines the result of fields_get() and
|
||||
__view_look_dom().
|
||||
|
||||
:param node: the architecture as as an etree
|
||||
:return: a tuple (arch, fields) where arch is the given node as a
|
||||
string and fields is the description of all the fields.
|
||||
|
||||
"""
|
||||
fields = {}
|
||||
Model = self.pool[model]
|
||||
if node.tag == 'diagram':
|
||||
if node.getchildren()[0].tag == 'node':
|
||||
node_model = self.pool[node.getchildren()[0].get('object')]
|
||||
node_fields = node_model.fields_get(cr, user, None, context)
|
||||
fields.update(node_fields)
|
||||
if not node.get("create") and not node_model.check_access_rights(cr, user, 'create', raise_exception=False):
|
||||
node.set("create", 'false')
|
||||
if node.getchildren()[1].tag == 'arrow':
|
||||
arrow_fields = self.pool[node.getchildren()[1].get('object')].fields_get(cr, user, None, context)
|
||||
fields.update(arrow_fields)
|
||||
else:
|
||||
fields = Model.fields_get(cr, user, None, context)
|
||||
fields_def = self.__view_look_dom(cr, user, model, node, view_id, False, fields, context=context)
|
||||
node = self._disable_workflow_buttons(cr, user, model, node)
|
||||
if node.tag in ('kanban', 'tree', 'form', 'gantt'):
|
||||
for action, operation in (('create', 'create'), ('delete', 'unlink'), ('edit', 'write')):
|
||||
if not node.get(action) and not Model.check_access_rights(cr, user, operation, raise_exception=False):
|
||||
node.set(action, 'false')
|
||||
arch = etree.tostring(node, encoding="utf-8").replace('\t', '')
|
||||
for k in fields.keys():
|
||||
if k not in fields_def:
|
||||
del fields[k]
|
||||
for field in fields_def:
|
||||
if field == 'id':
|
||||
# sometime, the view may contain the (invisible) field 'id' needed for a domain (when 2 objects have cross references)
|
||||
fields['id'] = {'readonly': True, 'type': 'integer', 'string': 'ID'}
|
||||
elif field in fields:
|
||||
fields[field].update(fields_def[field])
|
||||
else:
|
||||
cr.execute('select name, model from ir_ui_view where (id=%s or inherit_id=%s) and arch like %s', (view_id, view_id, '%%%s%%' % field))
|
||||
res = cr.fetchall()[:]
|
||||
model = res[0][1]
|
||||
res.insert(0, ("Can't find field '%s' in the following view parts composing the view of object model '%s':" % (field, model), None))
|
||||
msg = "\n * ".join([r[0] for r in res])
|
||||
msg += "\n\nEither you wrongly customized this view, or some modules bringing those views are not compatible with your current data model"
|
||||
_logger.error(msg)
|
||||
raise orm.except_orm('View error', msg)
|
||||
return arch, fields
|
||||
|
||||
class view_sc(osv.osv):
|
||||
_name = 'ir.ui.view_sc'
|
||||
_columns = {
|
||||
|
|
|
@ -1697,268 +1697,6 @@ class BaseModel(object):
|
|||
return any([self.pool.get('res.users').has_group(cr, uid, group_ext_id)
|
||||
for group_ext_id in groups.split(',')])
|
||||
|
||||
def __view_look_dom(self, cr, user, model, node, view_id, in_tree_view, model_fields, context=None):
|
||||
"""Return the description of the fields in the node.
|
||||
|
||||
In a normal call to this method, node is a complete view architecture
|
||||
but it is actually possible to give some sub-node (this is used so
|
||||
that the method can call itself recursively).
|
||||
|
||||
Originally, the field descriptions are drawn from the node itself.
|
||||
But there is now some code calling fields_get() in order to merge some
|
||||
of those information in the architecture.
|
||||
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
result = False
|
||||
fields = {}
|
||||
children = True
|
||||
|
||||
modifiers = {}
|
||||
Model = self.pool[model]
|
||||
|
||||
def encode(s):
|
||||
if isinstance(s, unicode):
|
||||
return s.encode('utf8')
|
||||
return s
|
||||
|
||||
def check_group(node):
|
||||
"""Apply group restrictions, may be set at view level or model level::
|
||||
* at view level this means the element should be made invisible to
|
||||
people who are not members
|
||||
* at model level (exclusively for fields, obviously), this means
|
||||
the field should be completely removed from the view, as it is
|
||||
completely unavailable for non-members
|
||||
|
||||
:return: True if field should be included in the result of fields_view_get
|
||||
"""
|
||||
if node.tag == 'field' and node.get('name') in Model._all_columns:
|
||||
column = Model._all_columns[node.get('name')].column
|
||||
if column.groups and not self.user_has_groups(cr, user,
|
||||
groups=column.groups,
|
||||
context=context):
|
||||
node.getparent().remove(node)
|
||||
fields.pop(node.get('name'), None)
|
||||
# no point processing view-level ``groups`` anymore, return
|
||||
return False
|
||||
if node.get('groups'):
|
||||
can_see = self.user_has_groups(cr, user,
|
||||
groups=node.get('groups'),
|
||||
context=context)
|
||||
if not can_see:
|
||||
node.set('invisible', '1')
|
||||
modifiers['invisible'] = True
|
||||
if 'attrs' in node.attrib:
|
||||
del(node.attrib['attrs']) #avoid making field visible later
|
||||
del(node.attrib['groups'])
|
||||
return True
|
||||
|
||||
if node.tag in ('field', 'node', 'arrow'):
|
||||
if node.get('object'):
|
||||
attrs = {}
|
||||
views = {}
|
||||
xml = "<form>"
|
||||
for f in node:
|
||||
if f.tag == 'field':
|
||||
xml += etree.tostring(f, encoding="utf-8")
|
||||
xml += "</form>"
|
||||
new_xml = etree.fromstring(encode(xml))
|
||||
ctx = context.copy()
|
||||
ctx['base_model_name'] = model
|
||||
xarch, xfields = self.__view_look_dom_arch(cr, user, node.get('object'), new_xml, view_id, ctx)
|
||||
views['form'] = {
|
||||
'arch': xarch,
|
||||
'fields': xfields
|
||||
}
|
||||
attrs = {'views': views}
|
||||
fields = xfields
|
||||
if node.get('name'):
|
||||
attrs = {}
|
||||
try:
|
||||
if node.get('name') in Model._columns:
|
||||
column = Model._columns[node.get('name')]
|
||||
else:
|
||||
column = Model._inherit_fields[node.get('name')][2]
|
||||
except Exception:
|
||||
column = False
|
||||
|
||||
if column:
|
||||
relation = self.pool[column._obj] if column._obj else None
|
||||
|
||||
children = False
|
||||
views = {}
|
||||
for f in node:
|
||||
if f.tag in ('form', 'tree', 'graph', 'kanban'):
|
||||
node.remove(f)
|
||||
ctx = context.copy()
|
||||
ctx['base_model_name'] = Model
|
||||
xarch, xfields = self.__view_look_dom_arch(cr, user, column._obj or None, f, view_id, ctx)
|
||||
views[str(f.tag)] = {
|
||||
'arch': xarch,
|
||||
'fields': xfields
|
||||
}
|
||||
attrs = {'views': views}
|
||||
if node.get('widget') and node.get('widget') == 'selection':
|
||||
# Prepare the cached selection list for the client. This needs to be
|
||||
# done even when the field is invisible to the current user, because
|
||||
# other events could need to change its value to any of the selectable ones
|
||||
# (such as on_change events, refreshes, etc.)
|
||||
|
||||
# If domain and context are strings, we keep them for client-side, otherwise
|
||||
# we evaluate them server-side to consider them when generating the list of
|
||||
# possible values
|
||||
# TODO: find a way to remove this hack, by allow dynamic domains
|
||||
dom = []
|
||||
if column._domain and not isinstance(column._domain, basestring):
|
||||
dom = list(column._domain)
|
||||
dom += eval(node.get('domain', '[]'), {'uid': user, 'time': time})
|
||||
search_context = dict(context)
|
||||
if column._context and not isinstance(column._context, basestring):
|
||||
search_context.update(column._context)
|
||||
attrs['selection'] = relation._name_search(cr, user, '', dom, context=search_context, limit=None, name_get_uid=1)
|
||||
if (node.get('required') and not int(node.get('required'))) or not column.required:
|
||||
attrs['selection'].append((False, ''))
|
||||
fields[node.get('name')] = attrs
|
||||
|
||||
field = model_fields.get(node.get('name'))
|
||||
if field:
|
||||
transfer_field_to_modifiers(field, modifiers)
|
||||
|
||||
|
||||
elif node.tag in ('form', 'tree'):
|
||||
result = Model.view_header_get(cr, user, False, node.tag, context)
|
||||
if result:
|
||||
node.set('string', result)
|
||||
in_tree_view = node.tag == 'tree'
|
||||
|
||||
elif node.tag == 'calendar':
|
||||
for additional_field in ('date_start', 'date_delay', 'date_stop', 'color'):
|
||||
if node.get(additional_field):
|
||||
fields[node.get(additional_field)] = {}
|
||||
|
||||
if not check_group(node):
|
||||
# node must be removed, no need to proceed further with its children
|
||||
return fields
|
||||
|
||||
# The view architeture overrides the python model.
|
||||
# Get the attrs before they are (possibly) deleted by check_group below
|
||||
transfer_node_to_modifiers(node, modifiers, context, in_tree_view)
|
||||
|
||||
# TODO remove attrs couterpart in modifiers when invisible is true ?
|
||||
|
||||
# translate view
|
||||
if 'lang' in context:
|
||||
Translations = self.pool['ir.translation']
|
||||
if node.text and node.text.strip():
|
||||
trans = Translations._get_source(cr, user, model, 'view', context['lang'], node.text.strip())
|
||||
if trans:
|
||||
node.text = node.text.replace(node.text.strip(), trans)
|
||||
if node.tail and node.tail.strip():
|
||||
trans = Translations._get_source(cr, user, model, 'view', context['lang'], node.tail.strip())
|
||||
if trans:
|
||||
node.tail = node.tail.replace(node.tail.strip(), trans)
|
||||
|
||||
if node.get('string') and not result:
|
||||
trans = Translations._get_source(cr, user, model, 'view', context['lang'], node.get('string'))
|
||||
if trans == node.get('string') and ('base_model_name' in context):
|
||||
# If translation is same as source, perhaps we'd have more luck with the alternative model name
|
||||
# (in case we are in a mixed situation, such as an inherited view where parent_view.model != model
|
||||
trans = Translations._get_source(cr, user, context['base_model_name'], 'view', context['lang'], node.get('string'))
|
||||
if trans:
|
||||
node.set('string', trans)
|
||||
|
||||
for attr_name in ('confirm', 'sum', 'avg', 'help', 'placeholder'):
|
||||
attr_value = node.get(attr_name)
|
||||
if attr_value:
|
||||
trans = Translations._get_source(cr, user, model, 'view', context['lang'], attr_value)
|
||||
if trans:
|
||||
node.set(attr_name, trans)
|
||||
|
||||
for f in node:
|
||||
if children or (node.tag == 'field' and f.tag in ('filter','separator')):
|
||||
fields.update(self.__view_look_dom(cr, user, model, f, view_id, in_tree_view, model_fields, context))
|
||||
|
||||
transfer_modifiers_to_node(modifiers, node)
|
||||
return fields
|
||||
|
||||
def _disable_workflow_buttons(self, cr, user, model, node):
|
||||
""" Set the buttons in node to readonly if the user can't activate them. """
|
||||
if user == 1:
|
||||
# admin user can always activate workflow buttons
|
||||
return node
|
||||
|
||||
# TODO handle the case of more than one workflow for a model or multiple
|
||||
# transitions with different groups and same signal
|
||||
usersobj = self.pool.get('res.users')
|
||||
buttons = (n for n in node.getiterator('button') if n.get('type') != 'object')
|
||||
for button in buttons:
|
||||
user_groups = usersobj.read(cr, user, [user], ['groups_id'])[0]['groups_id']
|
||||
cr.execute("""SELECT DISTINCT t.group_id
|
||||
FROM wkf
|
||||
INNER JOIN wkf_activity a ON a.wkf_id = wkf.id
|
||||
INNER JOIN wkf_transition t ON (t.act_to = a.id)
|
||||
WHERE wkf.osv = %s
|
||||
AND t.signal = %s
|
||||
AND t.group_id is NOT NULL
|
||||
""", (model, button.get('name')))
|
||||
group_ids = [x[0] for x in cr.fetchall() if x[0]]
|
||||
can_click = not group_ids or bool(set(user_groups).intersection(group_ids))
|
||||
button.set('readonly', str(int(not can_click)))
|
||||
return node
|
||||
|
||||
def __view_look_dom_arch(self, cr, user, model, node, view_id, context=None):
|
||||
""" Return an architecture and a description of all the fields.
|
||||
|
||||
The field description combines the result of fields_get() and
|
||||
__view_look_dom().
|
||||
|
||||
:param node: the architecture as as an etree
|
||||
:return: a tuple (arch, fields) where arch is the given node as a
|
||||
string and fields is the description of all the fields.
|
||||
|
||||
"""
|
||||
fields = {}
|
||||
Model = self.pool[model]
|
||||
if node.tag == 'diagram':
|
||||
if node.getchildren()[0].tag == 'node':
|
||||
node_model = self.pool[node.getchildren()[0].get('object')]
|
||||
node_fields = node_model.fields_get(cr, user, None, context)
|
||||
fields.update(node_fields)
|
||||
if not node.get("create") and not node_model.check_access_rights(cr, user, 'create', raise_exception=False):
|
||||
node.set("create", 'false')
|
||||
if node.getchildren()[1].tag == 'arrow':
|
||||
arrow_fields = self.pool[node.getchildren()[1].get('object')].fields_get(cr, user, None, context)
|
||||
fields.update(arrow_fields)
|
||||
else:
|
||||
fields = Model.fields_get(cr, user, None, context)
|
||||
fields_def = self.__view_look_dom(cr, user, model, node, view_id, False, fields, context=context)
|
||||
node = self._disable_workflow_buttons(cr, user, model, node)
|
||||
if node.tag in ('kanban', 'tree', 'form', 'gantt'):
|
||||
for action, operation in (('create', 'create'), ('delete', 'unlink'), ('edit', 'write')):
|
||||
if not node.get(action) and not Model.check_access_rights(cr, user, operation, raise_exception=False):
|
||||
node.set(action, 'false')
|
||||
arch = etree.tostring(node, encoding="utf-8").replace('\t', '')
|
||||
for k in fields.keys():
|
||||
if k not in fields_def:
|
||||
del fields[k]
|
||||
for field in fields_def:
|
||||
if field == 'id':
|
||||
# sometime, the view may contain the (invisible) field 'id' needed for a domain (when 2 objects have cross references)
|
||||
fields['id'] = {'readonly': True, 'type': 'integer', 'string': 'ID'}
|
||||
elif field in fields:
|
||||
fields[field].update(fields_def[field])
|
||||
else:
|
||||
cr.execute('select name, model from ir_ui_view where (id=%s or inherit_id=%s) and arch like %s', (view_id, view_id, '%%%s%%' % field))
|
||||
res = cr.fetchall()[:]
|
||||
model = res[0][1]
|
||||
res.insert(0, ("Can't find field '%s' in the following view parts composing the view of object model '%s':" % (field, model), None))
|
||||
msg = "\n * ".join([r[0] for r in res])
|
||||
msg += "\n\nEither you wrongly customized this view, or some modules bringing those views are not compatible with your current data model"
|
||||
_logger.error(msg)
|
||||
raise except_orm('View error', msg)
|
||||
return arch, fields
|
||||
|
||||
def _get_default_form_view(self, cr, user, context=None):
|
||||
""" Generates a default single-line form view using all fields
|
||||
of the current model except the m2m and o2m ones.
|
||||
|
@ -2105,7 +1843,7 @@ class BaseModel(object):
|
|||
ctx = context
|
||||
if root_view.get('model') != self._name:
|
||||
ctx = dict(context, base_model_name=root_view.get('model'))
|
||||
xarch, xfields = self.__view_look_dom_arch(
|
||||
xarch, xfields = View._view__view_look_dom_arch(
|
||||
cr, user, self._name, etree.fromstring(result['arch']),
|
||||
result['view_id'], context=ctx)
|
||||
result['arch'] = xarch
|
||||
|
@ -2149,7 +1887,9 @@ class BaseModel(object):
|
|||
}
|
||||
return result
|
||||
|
||||
_view_look_dom_arch = __view_look_dom_arch
|
||||
def _view_look_dom_arch(self, cr, uid, node, view_id, context=None):
|
||||
return self['ir.ui.view']._view__view_look_dom_arch(
|
||||
cr, uid, self._name, node, view_id, context=context)
|
||||
|
||||
def search_count(self, cr, user, args, context=None):
|
||||
if not context:
|
||||
|
|
Loading…
Reference in New Issue