diff --git a/CHANGELOG b/CHANGELOG index 7a735c4f52..9a52f9320f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Manage symbol widget * Fallback to model name as title * Set treeview footer sticky on bottom * Add get, in_ and contains methods to PYSON diff --git a/COPYRIGHT b/COPYRIGHT index 9cba55f27a..bdffefcb22 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -4,6 +4,8 @@ Copyright (C) 2012-2014 Bertrand Chenal. Copyright (C) 2012-2020 B2CK SPRL. Copyright (C) 2019 Jitbit. Copyright (C) 2013 Thomas Park +Copyright (C) 2020 Maxime Richez +Copyright (C) 2020 SALUC SA This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/model.js b/src/model.js index e631153415..8366a76c46 100644 --- a/src/model.js +++ b/src/model.js @@ -1832,6 +1832,27 @@ var shift = Math.round(Math.log(Math.abs(factor)) / Math.LN10); return [digits[0] + shift, digits[1] - shift]; }, + get_symbol: function(record, symbol) { + if (record && (symbol in record.model.fields)) { + var value = this.get(record) || 0; + var sign = 1; + if (value < 0) { + sign = -1; + } else if (value === 0) { + sign = 0; + } + var symbol_field = record.model.fields[symbol]; + var symbol_name = symbol_field.description.relation; + var symbol_id = symbol_field.get(record); + if (symbol_name && (symbol_id !== null) && (symbol_id >= 0)) { + return Sao.rpc({ + 'method': 'model.' + symbol_name + '.get_symbol', + 'params': [symbol_id, sign, record.get_context()], + }, record.model.session, false) || ['', 1]; + } + } + return ['', 1]; + }, check_required: function(record) { var state_attrs = this.get_state_attrs(record); if (state_attrs.required == 1) { diff --git a/src/screen.js b/src/screen.js index 14bc1ca8dc..d7e3b2cf8b 100644 --- a/src/screen.js +++ b/src/screen.js @@ -1671,6 +1671,10 @@ } }); } + var symbol = node.getAttribute('symbol'); + if (symbol && !(symbol in dom_fields)) { + dom_fields[symbol] = fields[symbol]; + } } }); fields = dom_fields; diff --git a/src/view/form.js b/src/view/form.js index 6d93c108ec..b2418241d8 100644 --- a/src/view/form.js +++ b/src/view/form.js @@ -1784,6 +1784,14 @@ function eval_pyson(value){ init: function(view, attributes) { Sao.View.Form.Integer._super.init.call(this, view, attributes); this.input_text = this.labelled = integer_input(this.input); + if (this.attributes.symbol) { + this.symbol_start = jQuery('', { + 'class': 'input-group-addon symbol symbol-start' + }).prependTo(this.group); + this.symbol_end = jQuery('', { + 'class': 'input-group-addon symbol symbol-end' + }).appendTo(this.group); + } this.group.css('width', ''); this.factor = Number(attributes.factor || 1); }, @@ -1825,12 +1833,34 @@ function eval_pyson(value){ return 8; }, display: function() { + var set_symbol = function(el, text) { + if (text) { + el.text(text); + el.show(); + } else { + el.text(''); + el.hide(); + } + }; Sao.View.Form.Integer._super.display.call(this); - var field = this.field; + var field = this.field, + record = this.record; var value = ''; this.el.css('width', this.width + 'ch'); if (field) { - value = field.get_client(this.record, this.factor); + value = field.get_client(record, this.factor); + } + if (field && this.attributes.symbol) { + var result = field.get_symbol(record, this.attributes.symbol); + var symbol = result[0], + position = result[1]; + if (position < 0.5) { + set_symbol(this.symbol_start, symbol); + set_symbol(this.symbol_end, ''); + } else { + set_symbol(this.symbol_start, ''); + set_symbol(this.symbol_end, symbol); + } } this.input_text.val(value); this.input_text.attr('maxlength', this.input.attr('maxlength')); diff --git a/src/view/tree.js b/src/view/tree.js index 2283473eaf..d319d9dd96 100644 --- a/src/view/tree.js +++ b/src/view/tree.js @@ -77,6 +77,12 @@ if ('icon' in attributes) { column.prefixes.push(new Sao.View.Tree.Affix(attributes)); } + if ('symbol' in attributes) { + column.prefixes.push( + new Sao.View.Tree.Symbol(attributes, 0)); + column.suffixes.push( + new Sao.View.Tree.Symbol(attributes, 1)); + } var affix, affix_attributes; var affixes = node.childNodes; for (var i = 0; i < affixes.length; i++) { @@ -702,6 +708,9 @@ 'boolean': 3, 'binary': 20, }[column.attributes.widget] || 10; + if (column.attributes.symbol) { + width += 2; + } var factor = 1; if (column.attributes.expand) { factor += parseInt(column.attributes.expand, 10); @@ -1999,6 +2008,51 @@ } }); + Sao.View.Tree.Symbol = Sao.class_(Object, { + class_: 'column-symbol', + init: function(attributes, position) { + this.attributes = attributes; + this.position = position; + }, + get_cell: function() { + var cell = jQuery('', { + 'class': this.class_, + 'tabindex': 0 + }); + return cell; + }, + render: function(record, cell) { + if (!cell) { + cell = this.get_cell(); + } + var render = function() { + var field = record.model.fields[this.attributes.name]; + var invisible = field.get_state_attrs(record).invisible; + if (invisible) { + cell.text(''); + cell.hide(); + return; + } + var result = field.get_symbol(record, this.attributes.symbol); + var symbol = result[0], + position = result[1]; + if (Math.round(position) === this.position) { + cell.text(symbol); + cell.show(); + } else { + cell.text(''); + cell.hide(); + } + }.bind(this); + if (!record.is_loaded(this.attributes.name)) { + record.load(this.attributes.name).done(render); + } else { + render(); + } + return cell; + }, + }); + Sao.View.Tree.CharColumn = Sao.class_(Object, { class_: 'column-char', init: function(model, attributes) {