diff --git a/setup.py b/setup.py index 3a735e7d4c..1f19b80136 100644 --- a/setup.py +++ b/setup.py @@ -44,7 +44,7 @@ setup(name=PACKAGE, 'trytond': ['init.sql'], 'trytond.ir': ['*.xml'], 'trytond.ir.module': ['*.xml'], - 'trytond.ir.ui': ['*.xml', '*.dtd'], + 'trytond.ir.ui': ['*.xml', '*.rng', '*.rnc'], 'trytond.res': ['*.xml'], 'trytond.webdav': ['*.xml'], 'trytond.workflow': ['*.xml'], diff --git a/trytond/ir/property.py b/trytond/ir/property.py index 77bf2468f8..774a622560 100644 --- a/trytond/ir/property.py +++ b/trytond/ir/property.py @@ -7,38 +7,16 @@ class Property(OSV): "Property" _name = 'ir.property' _description = __doc__ - name = fields.Char('Name', size=128) + name = fields.Char('Name') #TODO add function field for other type than many2one - value = fields.Reference('Value', selection='models_get2', size=128) - res = fields.Reference('Resource', selection='models_get', size=128) + value = fields.Reference('Value', selection='models_get') + res = fields.Reference('Resource', selection='models_get') field = fields.Many2One('ir.model.field', 'Field', - ondelete='cascade', required=True) - - def models_get2(self, cursor, user, context=None): - model_field_obj = self.pool.get('ir.model.field') - #TODO add domain for only reference fields - ids = model_field_obj.search(cursor, user, []) - res = [] - done = {} - for model_field in model_field_obj.browse(cursor, user, ids, - context=context): - if model_field.relation not in done: - res.append([model_field.relation, model_field.relation]) - done[model_field.relation] = True - return res + ondelete='CASCADE', required=True) def models_get(self, cursor, user, context=None): - model_field_obj = self.pool.get('ir.model.field') - #TODO add domain for only reference fields - ids = model_field_obj.search(cursor, user, []) - res = [] - done = {} - for model_field in model_field_obj.browse(cursor, user, ids, - context=context): - if model_field.model.id not in done: - res.append([model_field.model.model, - model_field.model.name]) - done[model_field.model.id] = True + cursor.execute('SELECT model, name FROM ir_model ORDER BY name ASC') + res = cursor.fetchall() + [('', '')] return res def get(self, cursor, user, name, model, res_ids=None, context=None): diff --git a/trytond/ir/ui/board.dtd b/trytond/ir/ui/board.dtd deleted file mode 100644 index 204f4b03a9..0000000000 --- a/trytond/ir/ui/board.dtd +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trytond/ir/ui/board.rnc b/trytond/ir/ui/board.rnc new file mode 100644 index 0000000000..9bd3d79d56 --- /dev/null +++ b/trytond/ir/ui/board.rnc @@ -0,0 +1,145 @@ +namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0" + +board = + element board { + attlist.board, + (image + | separator + | labe + | newline + | notebook + | group + | hpaned + | vpaned + | action)* + } +attlist.board &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.board &= [ a:defaultValue = "4" ] attribute col { text }? +image = element image { attlist.image, empty } +attlist.image &= attribute name { text } +attlist.image &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.image &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.image &= [ a:defaultValue = "0" ] attribute fill { "0" | "1" }? +attlist.image &= attribute help { text }? +attlist.image &= attribute states { text }? +separator = element separator { attlist.separator, empty } +attlist.separator &= [ a:defaultValue = "" ] attribute string { text }? +attlist.separator &= attribute name { text }? +attlist.separator &= attribute states { text }? +attlist.separator &= + [ a:defaultValue = "0.0" ] attribute align { text }? +attlist.separator &= + [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.separator &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.separator &= + [ a:defaultValue = "0" ] attribute fill { "0" | "1" }? +attlist.separator &= attribute help { text }? +label = element label { attlist.label, empty } +attlist.label &= [ a:defaultValue = "" ] attribute string { text }? +attlist.label &= attribute name { text }? +attlist.label &= attribute states { text }? +attlist.label &= [ a:defaultValue = "0.0" ] attribute align { text }? +attlist.label &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.label &= [ a:defaultValue = "0" ] attribute fill { "0" | "1" }? +attlist.label &= + [ a:defaultValue = "0" ] attribute xexpand { "0" | "1" }? +attlist.label &= [ a:defaultValue = "1" ] attribute xfill { "0" | "1" }? +attlist.label &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.label &= attribute help { text }? +newline = element newline { attlist.newline, empty } +attlist.newline &= empty +notebook = element notebook { attlist.notebook, page* } +attlist.notebook &= + attribute tabpos { "up" | "down" | "left" | "right" }? +attlist.notebook &= [ a:defaultValue = "4" ] attribute colspan { text }? +page = + element page { + attlist.page, + (image + | separator + | labe + | newline + | notebook + | group + | hpaned + | vpaned + | action)* + } +attlist.page &= attribute angle { text }? +attlist.page &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.page &= [ a:defaultValue = "4" ] attribute col { text }? +group = + element group { + attlist.group, + (image + | separator + | labe + | newline + | notebook + | group + | hpaned + | vpaned + | action)* + } +attlist.group &= attribute string { text }? +attlist.group &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.group &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.group &= [ a:defaultValue = "1" ] attribute fill { "0" | "1" }? +attlist.group &= [ a:defaultValue = "1" ] attribute rowspan { text }? +attlist.group &= [ a:defaultValue = "4" ] attribute col { text }? +hpaned = element hpaned { attlist.hpaned, child1?, child2? } +attlist.hpaned &= [ a:defaultValue = "4" ] attribute colspan { text }? +attlist.hpaned &= attribute position { text }? +vpaned = element vpaned { attlist.vpaned, child1?, child2? } +attlist.vpaned &= [ a:defaultValue = "4" ] attribute colspan { text }? +attlist.vpaned &= attribute position { text }? +child1 = + element child1 { + attlist.child1, + (image + | separator + | labe + | newline + | notebook + | group + | hpaned + | vpaned + | action)* + } +attlist.child1 &= empty +child2 = + element child2 { + attlist.child2, + (image + | separator + | labe + | newline + | notebook + | group + | hpaned + | vpaned + | action)* + } +attlist.child2 &= empty +data = element data { attlist.data, xpath+ } +attlist.data &= empty +xpath = element xpath { attlist.xpath, any } +attlist.xpath &= attribute expr { text } +attlist.xpath &= + [ a:defaultValue = "inside" ] + attribute position { "inside" | "replace" | "after" | "before" }? +action |= notAllowed +labe |= notAllowed +start = data | board | label +any = + (element * { + attribute * { text }*, + any + } + | text)* diff --git a/trytond/ir/ui/board.rng b/trytond/ir/ui/board.rng new file mode 100644 index 0000000000..8534f60a4d --- /dev/null +++ b/trytond/ir/ui/board.rng @@ -0,0 +1,477 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + up + down + left + right + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inside + replace + after + before + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trytond/ir/ui/form.dtd b/trytond/ir/ui/form.dtd deleted file mode 100644 index 461241e7ad..0000000000 --- a/trytond/ir/ui/form.dtd +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trytond/ir/ui/form.rnc b/trytond/ir/ui/form.rnc new file mode 100644 index 0000000000..961262ee11 --- /dev/null +++ b/trytond/ir/ui/form.rnc @@ -0,0 +1,256 @@ +namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0" + +form = + element form { + attlist.form, + (label + | field + | image + | separator + | newline + | button + | notebook + | group + | hpaned + | vpaned + | properties)* + } +attlist.form &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.form &= attribute on_write { text }? +attlist.form &= [ a:defaultValue = "4" ] attribute col { text }? +attlist.form &= attribute cursor { text }? + +tree = element tree { attlist.tree, field+ } +attlist.tree &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.tree &= attribute on_write { text }? +attlist.tree &= attribute editable { "top" | "bottom" }? +attlist.tree &= attribute sequence { text }? +attlist.tree &= attribute colors { text }? + +graph = element graph { attlist.graph, x, y } +attlist.graph &= + [ a:defaultValue = "vbar" ] + attribute type { "vbar" | "hbar" | "line" | "pie" }? +attlist.graph &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.graph &= + [ a:defaultValue = "#f5f5f5" ] attribute background { text }? +attlist.graph &= [ a:defaultValue = "blue" ] attribute color { text }? +attlist.graph &= + [ a:defaultValue = "1" ] attribute legend { "0" | "1" }? + +x = element x { attlist.x, field } +attlist.x &= empty + +y = element y { attlist.y, field+ } +attlist.y &= empty + +label = element label { attlist.label, empty } +attlist.label &= [ a:defaultValue = "" ] attribute string { text }? +attlist.label &= attribute name { text }? +attlist.label &= attribute states { text }? +attlist.label &= [ a:defaultValue = "0.0" ] attribute align { text }? +attlist.label &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.label &= [ a:defaultValue = "0" ] attribute fill { "0" | "1" }? +attlist.label &= + [ a:defaultValue = "0" ] attribute xexpand { "0" | "1" }? +attlist.label &= [ a:defaultValue = "1" ] attribute xfill { "0" | "1" }? +attlist.label &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.label &= attribute help { text }? + +field = element field { attlist.field, (tree | form | graph)* } +attlist.field &= attribute name { text } +attlist.field &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.field &= + attribute widget { + "date" + | "char" + | "many2one" + | "date" + | "one2many" + | "selection" + | "float" + | "numeric" + | "float_time" + | "interger" + | "datetime" + | "boolean" + | "text" + | "url" + | "email" + | "callto" + | "sip" + | "sha" + | "reference" + | "binary" + | "many2many" + | "image" + }? +attlist.field &= attribute saves { "0" | "1" }? +attlist.field &= attribute expand { "0" | "1" }? +attlist.field &= attribute fill { "0" | "1" }? +attlist.field &= attribute empty { "0" | "1" }? +attlist.field &= + [ a:defaultValue = "1" ] attribute xexpand { "0" | "1" }? +attlist.field &= [ a:defaultValue = "1" ] attribute xfill { "0" | "1" }? +attlist.field &= attribute help { text }? +attlist.field &= attribute width { text }? +attlist.field &= attribute height { text }? +attlist.field &= attribute readonly { text }? +attlist.field &= attribute required { text }? +attlist.field &= + [ a:defaultValue = "0" ] attribute tree_invisible { "0" | "1" }? +attlist.field &= attribute mode { text }? +attlist.field &= + [ a:defaultValue = "0" ] attribute completion { "0" | "1" }? +attlist.field &= + [ a:defaultValue = "0" ] attribute invisible { "0" | "1" }? +attlist.field &= attribute sum { text }? +attlist.field &= attribute key { text }? +attlist.field &= attribute domain { text }? +attlist.field &= attribute color { text }? +image = element image { attlist.image, empty } +attlist.image &= attribute name { text } +attlist.image &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.image &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.image &= [ a:defaultValue = "0" ] attribute fill { "0" | "1" }? +attlist.image &= attribute help { text }? +attlist.image &= attribute states { text }? +separator = element separator { attlist.separator, empty } +attlist.separator &= [ a:defaultValue = "" ] attribute string { text }? +attlist.separator &= attribute name { text }? +attlist.separator &= attribute states { text }? +attlist.separator &= + [ a:defaultValue = "0.0" ] attribute align { text }? +attlist.separator &= + [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.separator &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.separator &= + [ a:defaultValue = "0" ] attribute fill { "0" | "1" }? +attlist.separator &= attribute help { text }? +newline = element newline { attlist.newline, empty } +attlist.newline &= empty +button = element button { attlist.button, empty } +attlist.button &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.button &= attribute help { text }? +attlist.button &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.button &= attribute icon { text }? +attlist.button &= + [ a:defaultValue = "workflow" ] + attribute type { "workflow" | "object" | "action" }? +attlist.button &= attribute confirm { text }? +attlist.button &= attribute name { text } +attlist.button &= attribute states { text }? +notebook = element notebook { attlist.notebook, page* } +attlist.notebook &= + attribute tabpos { "up" | "down" | "left" | "right" }? +attlist.notebook &= [ a:defaultValue = "4" ] attribute colspan { text }? +page = + element page { + attlist.page, + (label + | field + | image + | separator + | newline + | button + | notebook + | group + | hpaned + | vpaned + | properties)* + } +attlist.page &= attribute angle { text }? +attlist.page &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.page &= [ a:defaultValue = "4" ] attribute col { text }? +group = + element group { + attlist.group, + (label + | field + | image + | separator + | newline + | button + | notebook + | group + | hpaned + | vpaned + | properties)* + } +attlist.group &= attribute string { text }? +attlist.group &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.group &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.group &= [ a:defaultValue = "1" ] attribute fill { "0" | "1" }? +attlist.group &= [ a:defaultValue = "1" ] attribute rowspan { text }? +attlist.group &= [ a:defaultValue = "4" ] attribute col { text }? + +hpaned = element hpaned { attlist.hpaned, child1?, child2? } +attlist.hpaned &= [ a:defaultValue = "4" ] attribute colspan { text }? +attlist.hpaned &= attribute position { text }? + +vpaned = element vpaned { attlist.vpaned, child1?, child2? } +attlist.vpaned &= [ a:defaultValue = "4" ] attribute colspan { text }? +attlist.vpaned &= attribute position { text }? + +child1 = + element child1 { + attlist.child1, + (label + | field + | image + | separator + | newline + | button + | notebook + | group + | hpaned + | vpaned + | properties)* + } +attlist.child1 &= empty + +child2 = + element child2 { + attlist.child2, + (label + | field + | image + | separator + | newline + | button + | notebook + | group + | hpaned + | vpaned + | properties)* + } +attlist.child2 &= empty + +properties = element properties { attlist.properties, empty } +attlist.properties &= empty + +data = element data { attlist.data, xpath+ } +attlist.data &= empty + +xpath = element xpath { attlist.xpath, any } +attlist.xpath &= attribute expr { text } +attlist.xpath &= + [ a:defaultValue = "inside" ] + attribute position { "inside" | "replace" | "after" | "before" }? + +any = + (element * { + attribute * { text }*, + any + } + | text)* +start = data | form diff --git a/trytond/ir/ui/form.rng b/trytond/ir/ui/form.rng new file mode 100644 index 0000000000..439c6ca690 --- /dev/null +++ b/trytond/ir/ui/form.rng @@ -0,0 +1,841 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + top + bottom + + + + + + + + + + + + + + + + + + + + + + + + + + vbar + hbar + line + pie + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + date + char + many2one + date + one2many + selection + float + numeric + float_time + interger + datetime + boolean + text + url + email + callto + sip + sha + reference + binary + many2many + image + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + workflow + object + action + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + up + down + left + right + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inside + replace + after + before + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trytond/ir/ui/graph.dtd b/trytond/ir/ui/graph.dtd deleted file mode 100644 index 396512c75d..0000000000 --- a/trytond/ir/ui/graph.dtd +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/trytond/ir/ui/graph.rnc b/trytond/ir/ui/graph.rnc new file mode 100644 index 0000000000..4b299e786e --- /dev/null +++ b/trytond/ir/ui/graph.rnc @@ -0,0 +1,40 @@ +namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0" + +graph = element graph { attlist.graph, x, y } +attlist.graph &= + [ a:defaultValue = "vbar" ] + attribute type { "vbar" | "hbar" | "line" | "pie" }? +attlist.graph &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.graph &= + [ a:defaultValue = "#f5f5f5" ] attribute background { text }? +attlist.graph &= [ a:defaultValue = "blue" ] attribute color { text }? +attlist.graph &= + [ a:defaultValue = "1" ] attribute legend { "0" | "1" }? +x = element x { attlist.x, field } +attlist.x &= empty +y = element y { attlist.y, field+ } +attlist.y &= empty +field = element field { attlist.field, empty } +attlist.field &= attribute name { text } +attlist.field &= attribute string { text }? +attlist.field &= attribute key { text }? +attlist.field &= attribute domain { text }? +attlist.field &= attribute fill { "0" | "1" }? +attlist.field &= attribute empty { "0" | "1" }? +attlist.field &= attribute color { text }? +attlist.field &= attribute widget { "float_time" }? +data = element data { attlist.data, xpath+ } +attlist.data &= empty +xpath = element xpath { attlist.xpath, any } +attlist.xpath &= attribute expr { text } +attlist.xpath &= + [ a:defaultValue = "inside" ] + attribute position { "inside" | "replace" | "after" | "before" }? +start = data | graph +any = + (element * { + attribute * { text }*, + any + } + | text)* diff --git a/trytond/ir/ui/graph.rng b/trytond/ir/ui/graph.rng new file mode 100644 index 0000000000..22efa7454b --- /dev/null +++ b/trytond/ir/ui/graph.rng @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + vbar + hbar + line + pie + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + float_time + + + + + + + + + + + + + + + + + + + + + + + + + + + + inside + replace + after + before + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trytond/ir/ui/tree.dtd b/trytond/ir/ui/tree.dtd deleted file mode 100644 index 81a82650f3..0000000000 --- a/trytond/ir/ui/tree.dtd +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/trytond/ir/ui/tree.rnc b/trytond/ir/ui/tree.rnc new file mode 100644 index 0000000000..c54f8615c1 --- /dev/null +++ b/trytond/ir/ui/tree.rnc @@ -0,0 +1,55 @@ +namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0" + +tree = element tree { attlist.tree, field+ } +attlist.tree &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +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 toolbar { "0" | "1" }? +field = element field { attlist.field, empty } +attlist.field &= attribute name { text } +attlist.field &= attribute readonly { text }? +attlist.field &= attribute required { text }? +attlist.field &= + attribute widget { + "char" + | "many2one" + | "date" + | "one2many" + | "selection" + | "float" + | "numeric" + | "float_time" + | "interger" + | "datetime" + | "boolean" + | "text" + | "url" + | "email" + | "callto" + | "sip" + }? +attlist.field &= + [ a:defaultValue = "0" ] attribute select { "0" | "1" | "2" }? +attlist.field &= + [ a:defaultValue = "0" ] attribute tree_invisible { "0" | "1" }? +attlist.field &= attribute icon { text }? +attlist.field &= attribute sum { text }? +attlist.field &= attribute width { text }? +data = element data { attlist.data, xpath+ } +attlist.data &= empty +xpath = element xpath { attlist.xpath, any } +attlist.xpath &= attribute expr { text } +attlist.xpath &= + [ a:defaultValue = "inside" ] + attribute position { "inside" | "replace" | "after" | "before" }? +start = tree | data +any = + (element * { + attribute * { text }*, + any + } + | text)* diff --git a/trytond/ir/ui/tree.rng b/trytond/ir/ui/tree.rng new file mode 100644 index 0000000000..3e240937e7 --- /dev/null +++ b/trytond/ir/ui/tree.rng @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + top + bottom + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + char + many2one + date + one2many + selection + float + numeric + float_time + interger + datetime + boolean + text + url + email + callto + sip + + + + + + + + + 0 + 1 + 2 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inside + replace + after + before + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trytond/ir/ui/view.py b/trytond/ir/ui/view.py index 9c54dbb18a..445eeaea4e 100644 --- a/trytond/ir/ui/view.py +++ b/trytond/ir/ui/view.py @@ -56,17 +56,20 @@ class View(OSV): trans_views[trans['name']][trans['src']] = trans for view in views: xml = view.arch.strip() - dtd_name = os.path.join(os.path.dirname(__file__), - (view.inherit and view.inherit.type or view.type) + '.dtd') - dtd = etree.DTD(file(dtd_name)) tree = etree.fromstring(xml) - if not dtd.validate(tree): - logger = Logger() - error_log = reduce(lambda x, y: str(x) + '\n' + str(y), - dtd.error_log.filter_from_errors()) - logger.notify_channel('ir', LOG_ERROR, - 'Invalid xml view:\n%s' % (error_log + '\n' + xml)) - return False + + # validate the tree using RelaxNG + rng_name = os.path.join(os.path.dirname(__file__), + (view.inherit and view.inherit.type or view.type) + '.rng') + if hasattr(etree, 'RelaxNG'): + validator = etree.RelaxNG(file=rng_name) + if not validator.validate(tree): + logger = Logger() + error_log = reduce(lambda x, y: str(x) + '\n' + str(y), + validator.error_log.filter_from_errors()) + logger.notify_channel('ir', LOG_ERROR, + 'Invalid xml view:\n%s' % (error_log + '\n' + xml)) + return False root_element = tree.getroottree().getroot() strings = self._translate_view(root_element) view_ids = self.search(cursor, 0, [ diff --git a/trytond/osv/orm.py b/trytond/osv/orm.py index ac21107139..c1a5cca64c 100644 --- a/trytond/osv/orm.py +++ b/trytond/osv/orm.py @@ -1128,7 +1128,7 @@ class ORM(object): ' FROM ' + table_query + '\"' + self._table +'\" ' \ 'WHERE id IN ' \ '(' + ','.join([str(x) for x in sub_ids]) + ')'\ - ' AND ' + domain1 + ' ORDER BY ' + \ + ' AND (' + domain1 + ') ORDER BY ' + \ ','.join([self._table + '.' + x[0] + ' ' + x[1] \ for x in self._order])), table_args + domain2) @@ -1365,7 +1365,7 @@ class ORM(object): domain1, domain2 = self.pool.get('ir.rule').domain_get(cursor, user, self._name) if domain1: - domain1 = ' AND ' + domain1 + domain1 = ' AND (' + domain1 + ') ' for i in range((len(ids) / ID_MAX) + \ ((len(ids) % ID_MAX) and 1 or 0)): sub_ids = ids[ID_MAX * i:ID_MAX * (i + 1)] @@ -1491,7 +1491,7 @@ class ORM(object): domain1, domain2 = self.pool.get('ir.rule').domain_get(cursor, user, self._name) if domain1: - domain1 = ' and ' + domain1 + domain1 = ' AND (' + domain1 + ') ' for i in range((len(ids) / ID_MAX) + \ ((len(ids) % ID_MAX) and 1 or 0)): sub_ids = ids[ID_MAX * i:ID_MAX * (i + 1)] @@ -1964,7 +1964,7 @@ class ORM(object): if next is not None: for child in element2: index = parent.index(next) - parent.insert(index - 1, child) + parent.insert(index, child) else: parent.extend(element2.getchildren()) elif pos == 'before': diff --git a/trytond/report/report.py b/trytond/report/report.py index 8af3ad0c61..394e7e86ff 100644 --- a/trytond/report/report.py +++ b/trytond/report/report.py @@ -18,6 +18,12 @@ import time import os import datetime +if not hasattr(locale, 'nl_langinfo'): + locale.nl_langinfo = lambda *a: '%x' + +if not hasattr(locale, 'D_FMT'): + locale.D_FMT = None + MODULE_LIST = [] MODULE_CLASS_LIST = {} CLASS_POOL = {} @@ -537,17 +543,25 @@ class Report(object): (self._name, localcontext.get('language', False) or 'en_US')) if date: - # length of date like 2001-01-01 is ten: - if len(str(value)) == 10: - locale_format = locale.D_FMT - string_pattern = '%Y-%m-%d' + if isinstance(value, time.struct_time): + locale_format = locale.nl_langinfo(locale.D_FMT)\ + .replace('%y', '%Y') + date = value else: - if len(str(value)) > 19: + # assume string, parse it + if len(str(value)) == 10: + # length of date like 2001-01-01 is ten + # assume format '%Y-%m-%d' + locale_format = locale.nl_langinfo(locale.D_FMT)\ + .replace('%y', '%Y') + string_pattern = '%Y-%m-%d' + else: + # assume format '%Y-%m-%d %H:%M:%S' value = str(value)[:19] - locale_format = locale.D_T_FMT - string_pattern = '%Y-%m-%d %H:%M:%S' - date = time.strptime(str(value), string_pattern) - return time.strftime(locale.nl_langinfo(locale_format).\ - replace('%y', '%Y'), date) + locale_format = locale.nl_langinfo(locale.D_FMT)\ + .replace('%y', '%Y') + ' %H:%M:%S' + string_pattern = '%Y-%m-%d %H:%M:%S' + date = time.strptime(str(value), string_pattern) + return time.strftime(locale_format, date) return locale.format('%.' + str(digits) + 'f', value, True) diff --git a/trytond/tryton.dtd b/trytond/tryton.dtd deleted file mode 100644 index 4134bdfd1e..0000000000 --- a/trytond/tryton.dtd +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/trytond/tryton.rnc b/trytond/tryton.rnc new file mode 100644 index 0000000000..d8e3b9955b --- /dev/null +++ b/trytond/tryton.rnc @@ -0,0 +1,28 @@ +namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0" + +tryton = element tryton { attlist.tryton, data* } +attlist.tryton &= empty +data = element data { attlist.data, (record | menuitem)* } +attlist.data &= + [ a:defaultValue = "0" ] attribute noupdate { "0" | "1" }? +record = element record { attlist.record, field* } +attlist.record &= attribute model { text } +attlist.record &= attribute id { text } +attlist.record &= + [ a:defaultValue = "0" ] attribute update { "0" | "1" }? +field = element field { attlist.field, text } +attlist.field &= attribute name { text } +attlist.field &= attribute search { text }? +attlist.field &= attribute model { text }? +attlist.field &= attribute ref { text }? +attlist.field &= attribute eval { text }? +attlist.field &= attribute type { "xml" }? +menuitem = element menuitem { attlist.menuitem, empty } +attlist.menuitem &= attribute id { text } +attlist.menuitem &= attribute name { text }? +attlist.menuitem &= attribute icon { text }? +attlist.menuitem &= attribute sequence { text }? +attlist.menuitem &= attribute parent { text }? +attlist.menuitem &= attribute action { text }? +attlist.menuitem &= attribute groups { text }? +start = tryton diff --git a/trytond/web_service/db.py b/trytond/web_service/db.py index 64fa47cf45..513e904e9a 100644 --- a/trytond/web_service/db.py +++ b/trytond/web_service/db.py @@ -21,6 +21,7 @@ class DB(Service): self.export_method(self.restore) self.export_method(self.list) self.export_method(self.list_lang) + self.export_method(self.db_exist) self.export_method(self.change_admin_password) def create(self, password, db_name, lang):