Change attempted to simplify branding distribution, but based node
branding on final view. To be able to rewrite, node branding must be
based on source views positions before applying inheritance.

Reintroduce manual generation of xpath in distribute_branding as
ElementTree.getpath() can't handle it.

Note: why isn't branding distribution performed during initial views
reading (e.g. inherit_branding)? Surely that would obviate the need
for special casing and manually creating paths no?

bzr revid: xmo@openerp.com-20130919130847-3t8zfpv9m9pcibg0
This commit is contained in:
Xavier Morel 2013-09-19 15:08:47 +02:00
parent 4b89b246a8
commit 724bbffc88
2 changed files with 46 additions and 4 deletions

View File

@ -18,6 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import collections
import copy
import logging
import os
@ -260,6 +261,8 @@ class view(osv.osv):
else:
node.set('data-oe-id', str(view_id))
node.set('data-oe-xpath', xpath)
node.set('data-oe-model', 'ir.ui.view')
node.set('data-oe-field', 'arch')
return specs_tree
@ -682,13 +685,18 @@ class view(osv.osv):
r = self.read_combined(cr, uid, id_, fields=['arch'], context=context)
return r['arch']
def distribute_branding(self, e, branding=None):
def distribute_branding(self, e, branding=None, parent_xpath='',
index_map=misc.ConstantMapping(1)):
if e.get('t-ignore') or e.tag == 'head':
# TODO: find a better name and check if we have a string to boolean helper
return
node_path = e.get('data-oe-xpath')
if node_path is None:
node_path = "%s/%s[%d]" % (parent_xpath, e.tag, index_map[e.tag])
if branding and not (e.get('data-oe-model') or e.get('t-field')):
e.attrib.update(branding)
e.set('data-oe-xpath', e.getroottree().getpath(e))
e.set('data-oe-xpath', node_path)
if not e.get('data-oe-model'): return
# if a branded element contains branded elements distribute own
@ -702,8 +710,14 @@ class view(osv.osv):
if e.get(attribute))
if 't-raw' not in e.attrib:
# TODO: collections.Counter if remove p2.6 compat
# running index by tag type, for XPath query generation
indexes = collections.defaultdict(lambda: 0)
for child in e.iterchildren(tag=etree.Element):
self.distribute_branding(child, distributed_branding)
indexes[child.tag] += 1
self.distribute_branding(child, distributed_branding,
parent_xpath=node_path,
index_map=indexes)
def is_node_branded(self, node):
""" Finds out whether a node is branded or qweb-active (bears a

View File

@ -35,7 +35,7 @@ import sys
import threading
import time
import zipfile
from collections import defaultdict
from collections import defaultdict, Mapping
from datetime import datetime
from itertools import islice, izip, groupby
from lxml import etree
@ -1066,4 +1066,32 @@ def stripped_sys_argv(*strip_args):
return [x for i, x in enumerate(args) if not strip(args, i)]
class ConstantMapping(Mapping):
"""
An immutable mapping returning the provided value for every single key.
Useful for default value to methods
"""
__slots__ = ['_value']
def __init__(self, val):
self._value = val
def __len__(self):
"""
defaultdict updates its length for each individually requested key, is
that really useful?
"""
return 0
def __iter__(self):
"""
same as len, defaultdict udpates its iterable keyset with each key
requested, is there a point for this?
"""
return iter([])
def __getitem__(self, item):
return self._value
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: