From 724bbffc88e444b50c1622c942b8c4554646d367 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 19 Sep 2013 15:08:47 +0200 Subject: [PATCH] [FIX] Partially revert xmo@openerp.com-20130812074509-yopeb4pxtsads4d9 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 --- openerp/addons/base/ir/ir_ui_view.py | 20 ++++++++++++++++--- openerp/tools/misc.py | 30 +++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py index 1bf642ac202..3845d916843 100644 --- a/openerp/addons/base/ir/ir_ui_view.py +++ b/openerp/addons/base/ir/ir_ui_view.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # ############################################################################## +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 diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index 65e7c38e536..bdbb4d13e0f 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -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: