diff -r ad9170e4838b trytond/trytond/ir/ui/tree.rnc --- a/trytond/trytond/ir/ui/tree.rnc Tue Aug 30 14:38:04 2016 +0200 +++ b/trytond/trytond/ir/ui/tree.rnc Mon Feb 13 11:11:10 2017 +0100 @@ -9,6 +9,7 @@ attlist.tree &= attribute on_write { text }? attlist.tree &= attribute editable { "top" | "bottom" }? attlist.tree &= attribute sequence { text }? +attlist.tree &= attribute colors { text }? attlist.tree &= [ a:defaultValue = "0" ] attribute keyword_open { "0" | "1" }? attlist.tree &= @@ -62,6 +63,7 @@ attlist.field &= attribute string { text }? attlist.field &= [a:defaultValue = "1"] attribute factor { text }? attlist.field &= attribute filename { text }? +attlist.field &= attribute view_ids { text }? prefix = element prefix { attlist.affix, empty } suffix = element suffix { attlist.affix, empty } attlist.affix &= attribute string { text }? diff -r ad9170e4838b trytond/trytond/ir/ui/tree.rng --- a/trytond/trytond/ir/ui/tree.rng Tue Aug 30 14:38:04 2016 +0200 +++ b/trytond/trytond/ir/ui/tree.rng Mon Feb 13 11:11:10 2017 +0100 @@ -38,6 +38,11 @@ + + + + + 0 @@ -198,6 +203,11 @@ + + + + + diff -r ad9170e4838b trytond/trytond/ir/ui/view.py --- a/trytond/trytond/ir/ui/view.py Tue Aug 30 14:38:04 2016 +0200 +++ b/trytond/trytond/ir/ui/view.py Mon Feb 13 11:21:02 2017 +0100 @@ -155,7 +155,7 @@ } def encode(element): - for attr in ('states', 'domain', 'spell'): + for attr in ('states', 'domain', 'spell', 'colors'): if element.get(attr): try: value = PYSONDecoder().decode(element.get(attr)) diff -r b1c807b558e9 trytond/trytond/model/modelview.py --- a/trytond/trytond/model/modelview.py Wed Sep 28 08:14:45 2016 +0200 +++ b/trytond/trytond/model/modelview.py Wed Sep 28 08:19:23 2016 +0200 @@ -488,59 +488,67 @@ fields_attrs = {} else: fields_attrs = copy.deepcopy(fields_attrs) - childs = True - if element.tag in ('field', 'label', 'separator', 'group', 'suffix', - 'prefix'): + def set_view_ids(element): + view_ids = [] + if element.get('view_ids'): + for view_id in element.get('view_ids').split(','): + try: + view_ids.append(int(view_id)) + except ValueError: + view_ids.append(ModelData.get_id(*view_id.split('.'))) + element.attrib['view_ids'] = ','.join(map(str, view_ids)) + return view_ids + + def get_relation(field): + if hasattr(field, 'model_name'): + return field.model_name + elif hasattr(field, 'get_target'): + return field.get_target().__name__ + + def get_views(relation, view_ids, mode): + Relation = pool.get(relation) + views = {} + if field._type in ['one2many', 'many2many']: + # Prefetch only the first view to prevent infinite loop + if view_ids: + for view_id in view_ids: + view = Relation.fields_view_get(view_id=view_id) + views[str(view_id)] = view + break + else: + for view_type in mode: + views[view_type] = ( + Relation.fields_view_get(view_type=view_type)) + break + return views + + for attr in ('name', 'icon'): + if not element.get(attr): + continue + fields_attrs.setdefault(element.get(attr), {}) + + if element.tag == 'field' and type in ['tree', 'form']: for attr in ('name', 'icon'): - if element.get(attr): - fields_attrs.setdefault(element.get(attr), {}) - if type != 'form': - continue - try: - field = cls._fields[element.get(attr)] - if hasattr(field, 'model_name'): - relation = field.model_name - else: - relation = field.get_target().__name__ - except Exception: - relation = False - if relation and element.tag == 'field': - childs = False - views = {} - mode = (element.attrib.pop('mode', None) - or 'tree,form').split(',') - view_ids = [] - if element.get('view_ids'): - for view_id in element.get('view_ids').split(','): - try: - view_ids.append(int(view_id)) - except ValueError: - view_ids.append(ModelData.get_id( - *view_id.split('.'))) - Relation = pool.get(relation) - if (not len(element) - and type == 'form' - and field._type in ('one2many', 'many2many')): - # Prefetch only the first view to prevent infinite - # loop - if view_ids: - for view_id in view_ids: - view = Relation.fields_view_get( - view_id=view_id) - views[str(view_id)] = view - break - else: - for view_type in mode: - views[view_type] = \ - Relation.fields_view_get( - view_type=view_type) - break - element.attrib['mode'] = ','.join(mode) - element.attrib['view_ids'] = ','.join( - map(str, view_ids)) - fields_attrs[element.get(attr)].setdefault('views', {} - ).update(views) + fname = element.get(attr) + if not fname: + continue + view_ids = set_view_ids(element) + if type != 'form': + continue + try: + field = cls._fields[fname] + relation = get_relation(field) + except: + relation = False + if not relation: + continue + mode = ( + element.attrib.pop('mode', None) or 'tree,form').split(',') + views = get_views(relation, view_ids, mode) + element.attrib['mode'] = ','.join(mode) + fields_attrs[fname].setdefault('views', {}).update(views) + if type == 'tree' and element.get('name') in fields_width: element.set('width', str(fields_width[element.get('name')])) @@ -588,10 +593,9 @@ if element.get(attr): fields_attrs.setdefault(element.get(attr), {}) - if childs: - for field in element: - fields_attrs = cls.__view_look_dom(field, type, - fields_width=fields_width, fields_attrs=fields_attrs) + for field in element: + fields_attrs = cls.__view_look_dom(field, type, + fields_width=fields_width, fields_attrs=fields_attrs) return fields_attrs @staticmethod