diff --git a/doc/graph.t2t b/doc/graph.t2t new file mode 100644 index 0000000000..ff5063ba2e --- /dev/null +++ b/doc/graph.t2t @@ -0,0 +1,47 @@ + +== Graph view == + +The dtd that describe the xml for a graph view is stored in trytond/ir/ui/graph.dtd. + +* XML description: + +- tag "graph": + + - "type": vbar, hbar, line, pie + + - "string": the name of the graph + + - "background": an hexaecimal value for the color of the background + + - "color": the main color + + - "legend": a boolean to specify if the legend must be display + +- tag "x", "y": + + Describe the field that must be used for axis. + "x" must contain only one tag "field" and "y" must at least one but may contain many. + +- tag "field": + + - "name": the name of the field on the object to use + + - "string": allow to override the string that comes from the object + + - "key": can be used to distinguish fields with the same name but that are different with domain + + - "domain": a string that is evaluate with the object value as context. If the result is true the field value is added to the graph otherwise not + + - "fill": defined if the graph must be fill + + +* Example: + + + + + + + + + diff --git a/trytond/ir/default.py b/trytond/ir/default.py index ff48bfbc10..4e29b90377 100644 --- a/trytond/ir/default.py +++ b/trytond/ir/default.py @@ -1,5 +1,6 @@ "Default" from trytond.osv import fields, OSV +from decimal import Decimal class Default(OSV): @@ -37,6 +38,8 @@ class Default(OSV): test_clause = False continue break + ctx = {} + ctx['Decimal'] = Decimal for default in self.browse(cursor, user, default_ids, context=context): if default.field.name not in res: res[default.field.name] = eval(default.value) diff --git a/trytond/ir/ui/board.dtd b/trytond/ir/ui/board.dtd new file mode 100644 index 0000000000..7053fda7b7 --- /dev/null +++ b/trytond/ir/ui/board.dtd @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trytond/ir/ui/form.dtd b/trytond/ir/ui/form.dtd new file mode 100644 index 0000000000..9247bc527b --- /dev/null +++ b/trytond/ir/ui/form.dtd @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trytond/ir/ui/graph.dtd b/trytond/ir/ui/graph.dtd new file mode 100644 index 0000000000..24bf60eb4f --- /dev/null +++ b/trytond/ir/ui/graph.dtd @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/trytond/ir/ui/tree.dtd b/trytond/ir/ui/tree.dtd new file mode 100644 index 0000000000..751424b487 --- /dev/null +++ b/trytond/ir/ui/tree.dtd @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/trytond/ir/ui/view.py b/trytond/ir/ui/view.py index 89ede93c7c..05ec59635f 100644 --- a/trytond/ir/ui/view.py +++ b/trytond/ir/ui/view.py @@ -2,6 +2,8 @@ from trytond.osv import fields, OSV from xml import dom from difflib import SequenceMatcher +import os +from trytond.netsvc import Logger, LOG_ERROR, LOG_WARNING class View(OSV): @@ -31,8 +33,7 @@ class View(OSV): ] def default_arch(self, cursor, user, context=None): - return '\n' \ - '\n\t\n' + return '' def default_priority(self, cursor, user, context=None): return 16 @@ -59,6 +60,24 @@ class View(OSV): ('db_id', 'in', ids), ]) for view in views: + logger = Logger() + try: + from Ft.Xml.Domlette import ValidatingReader + xml = '\n\n'\ + % (view.inherit and 'data' or view.type, + os.path.dirname(__file__), + view.inherit and view.inherit.type or view.type) + xml += view.arch.strip() + try: + ValidatingReader.parseString(xml) + except Exception, exception: + logger.notify_channel('ir', LOG_ERROR, + 'Invalid xml view: %s' % (str(exception))) + return False + except: + logger.notify_channel('ir', LOG_WARNING, + 'Could not import Ft.Xml.Domlette, please install 4Suite ' \ + 'to have xml validation') try: document = dom.minidom.parseString(view.arch) except: diff --git a/trytond/osv/orm.py b/trytond/osv/orm.py index bf7efd1383..d8da2b7873 100644 --- a/trytond/osv/orm.py +++ b/trytond/osv/orm.py @@ -1208,6 +1208,9 @@ class ORM(object): obj = self.pool.get(fld_def._obj) if not obj.search(cursor, user, [('id', '=', field_value)]): continue + if isinstance(field_value, (int, long)): + field_value = obj.name_get(cursor, user, field_value, + context=context)[0] if fld_def._type in ('many2many'): obj = self.pool.get(fld_def._obj) field_value2 = [] @@ -1220,7 +1223,7 @@ class ORM(object): if fld_def._type in ('one2many'): obj = self.pool.get(fld_def._obj) field_value2 = [] - for i in range(len(field_value)): + for i in range(len(field_value or [])): field_value2.append({}) for field2 in field_value[i]: if obj._columns[field2]._type \ @@ -1229,12 +1232,41 @@ class ORM(object): if not obj2.search(cursor, user, [('id', '=', field_value[i][field2])]): continue + if isinstance(field_value[i][field2], + (int, long)): + field_value[i][field2] = obj2.name_get( + cursor, user, + field_value[i][field2], + context=context)[0] # TODO add test for many2many and one2many field_value2[i][field2] = field_value[i][field2] field_value = field_value2 value[field] = field_value + value = self._default_on_change(cursor, user, value, context=context) return value + def _default_on_change(self, cursor, user, value, context=None): + res = value.copy() + val = {} + for i in self._inherits.keys(): + val.update(self.pool.get(i)._default_on_change(cursor, user, + value, context=context)) + for field in value.keys(): + if field in self._columns: + if self._columns[field].on_change: + args = {} + for arg in self._columns[field].on_change: + args[arg] = value.get(arg, False) + val.update(getattr(self, 'on_change_' + field)(cursor, user, + [], args, context=context)) + if self._columns[field]._type in ('many2many', 'one2many'): + obj = self.pool.get(self._columns[field]._obj) + for val2 in res[field]: + val2.update(obj._default_on_change(cursor, user, + val, context=context)) + res.update(val) + return res + def unlink(self, cursor, user, ids, context=None): if context is None: context = {} diff --git a/trytond/res/user.py b/trytond/res/user.py index 739bfc1c08..eb8d634f6e 100644 --- a/trytond/res/user.py +++ b/trytond/res/user.py @@ -19,7 +19,8 @@ class User(OSV): #address_id = fields.Many2One('res.partner.address', 'Address') active = fields.Boolean('Active') action = fields.Many2One('ir.action', 'Home Action') - menu = fields.Many2One('ir.action', 'Menu Action') + menu = fields.Many2One('ir.action', 'Menu Action', + domain=[('usage','=','menu')], required=True) groups = fields.Many2Many('res.group', 'res_group_user_rel', 'uid', 'gid', 'Groups') rule_groups = fields.Many2Many('ir.rule.group', 'user_rule_group_rel', diff --git a/trytond/res/user.xml b/trytond/res/user.xml index d5842f1c42..fd31e00528 100644 --- a/trytond/res/user.xml +++ b/trytond/res/user.xml @@ -33,9 +33,7 @@