I wanted to be able to inherit a form, and actually add some fields into an existing page. At the moment the code only supports inserting an entire new page, or removing a page.
The attached patch allows this. It also allows removing fields from a view. As an example, consider this: <?xml version="1.0" ?> <terp> <data> <record model="ir.ui.view" id="product_normal_form_view"> <field name="name">product.normal.form</field> <field name="model">product.product</field> <field name="inherit_id" ref="product.product_normal_form_view" /> <field name="type">form</field> <field name="arch" type="xml"> <page string="Information" position="update"> <field name="pattern_repeat" digits="(3, 0)" position="before" target="volume"/> <field name="width" digits="(3, 0)"/> <field target="volume" position="remove" /> <field target="weight" position="remove" /> <field target="weight_net" position="remove" /> </page> </field> </record> </data> </terp> This will update the 'Information' page of product_normal_form_view: - add a new field 'pattern_repeat' before 'volume' - add a new field 'width' after that - remove the fields 'volume', 'weight' and 'weight_net' I know it is a bit odd, but I hope someone finds it useful! It seems to me that it is useful to be able to have a module which removes fields from the standard view to simplify things for certain configurations. Patch is for 4.2.2 Index: bin/osv/orm.py =================================================================== --- bin/osv/orm.py (revision 704) +++ bin/osv/orm.py (working copy) @@ -1416,6 +1416,8 @@ def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False): if not context: context={} + + # this handles applying changes to 'src' based on the information in 'inherit' def _inherit_apply(src, inherit): def _find(node, node2): if node.nodeType==node.ELEMENT_NODE and node.localName==node2.localName: @@ -1433,17 +1435,81 @@ res = _find(child, node2) if res: return res return None + + def _findChild(node, name): + for child in node.childNodes: + if child.nodeType==child.ELEMENT_NODE: + if child.localName == 'field': + cname = None + if child.hasAttribute('name'): + cname = child.getAttribute('name') + if cname == name: + return child + return None + + # updates the given node according to the details in the child + # either an existing child of node is removed, or the given child is added + + # the child may have position = remove/before/after (default is 'after') + # and target = a child of node + # + # remove target - removes the target node + # after target - inserts child after the target + # before target - inserts child before the target + # + # returns the node newly created, or None + def _updatePage(node, child, target_node): + # the child is a field + # work out whether to replace, insert or remove + if child.nodeType!=child.ELEMENT_NODE: + return + # position=remove/after/before + # other_field=field name to remove, or field to put this one after/before + pos = None + if child.hasAttribute('position'): + pos = child.getAttribute('position') + target = None + if child.hasAttribute('target'): + target = child.getAttribute('target') + target_node = _findChild(node, target) + if pos != None and not target_node: + raise AttributeError, "Couldn't find target '%s' in parent view !" % target + # handle remove + if pos == 'remove': + target_node.parentNode.removeChild(target_node) + target_node = None + else: + # before or after + sib = pos == 'before' and target_node or target_node.nextSibling + if sib: + target_node = node.insertBefore(child, sib) + else: + # not found or not specified, so add to the end + target_node = node.appendChild(child) + return target_node + + # src is the main form, dest is the one which inherits it + # we use dest to change src + # dest does not change doc_src = dom.minidom.parseString(src) doc_dest = dom.minidom.parseString(inherit) + + # work through each of the child nodes, updating the dest as required for node2 in doc_dest.childNodes: if not node2.nodeType==node2.ELEMENT_NODE: continue + + # find the corresponding node in the source doc node = _find(doc_src, node2) if node: + # the node is probably a page + # use the default position 'inside', meaning we add a new page pos = 'inside' if node2.hasAttribute('position'): pos = node2.getAttribute('position') + + # handle replacing a page - we add the new one before the old one, and then remove the old one if pos=='replace': parent = node.parentNode for child in node2.childNodes: @@ -1451,17 +1517,28 @@ parent.insertBefore(child, node) parent.removeChild(node) else: + # pos is inside, after, before or update + # start with an unknown target + target_node = None for child in node2.childNodes: + # each child is a page + # we work out where this page should be if child.nodeType==child.ELEMENT_NODE: - if pos=='inside': + if pos=='update': + # we need to update the fields within this page + target_node = _updatePage(node, child, target_node) + elif pos=='inside': + # add a new page inside this one node.appendChild(child) elif pos=='after': + # add a new page after a given one sib = node.nextSibling if sib: node.parentNode.insertBefore(child, sib) else: node.parentNode.appendChild(child) elif pos=='before': + # add a new page before a given one node.parentNode.insertBefore(child, node) else: raise AttributeError, 'Unknown position in inherited view %s !' % pos ------------------------ -- Simon Glass Christchurch New Zealand _______________________________________________ Tinyerp-users mailing list http://tiny.be/mailman/listinfo/tinyerp-users
