diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py
index a1fcc51818c..701bb0f1723 100644
--- a/addons/base/controllers/main.py
+++ b/addons/base/controllers/main.py
@@ -508,7 +508,7 @@ class DataSet(openerpweb.Controller):
@openerpweb.jsonrequest
def call(self, req, model, method, args, domain_id=None, context_id=None):
- return {'result': self.call_common(req, model, method, args, domain_id, context_id)}
+ return self.call_common(req, model, method, args, domain_id, context_id)
@openerpweb.jsonrequest
def call_button(self, req, model, method, args, domain_id=None, context_id=None):
@@ -524,20 +524,19 @@ class DataSet(openerpweb.Controller):
@openerpweb.jsonrequest
def default_get(self, req, model, fields):
- m = req.session.model(model)
- r = m.default_get(fields, req.session.eval_context(req.context))
- return {'result': r}
+ Model = req.session.model(model)
+ return Model.default_get(fields, req.session.eval_context(req.context))
class DataGroup(openerpweb.Controller):
_cp_path = "/base/group"
@openerpweb.jsonrequest
- def read(self, request, model, fields, group_by_fields, domain=None):
+ def read(self, request, model, fields, group_by_fields, domain=None, sort=None):
Model = request.session.model(model)
context, domain = eval_context_and_domain(request.session, request.context, domain)
return Model.read_group(
domain or [], fields, group_by_fields, 0, False,
- dict(context, group_by=group_by_fields))
+ dict(context, group_by=group_by_fields), sort or False)
class View(openerpweb.Controller):
_cp_path = "/base/view"
@@ -570,10 +569,15 @@ class View(openerpweb.Controller):
else:
xml = ElementTree.fromstring(arch)
fvg['arch'] = Xml2Json.convert_element(xml)
- for field in fvg['fields'].values():
- if field.has_key('views') and field['views']:
- for view in field["views"].values():
+
+ for field in fvg['fields'].itervalues():
+ if field.get('views'):
+ for view in field["views"].itervalues():
self.process_view(session, view, None, transform)
+ if field.get('domain'):
+ field["domain"] = self.parse_domain(field["domain"], session)
+ if field.get('context'):
+ field["context"] = self.parse_context(field["context"], session)
@openerpweb.jsonrequest
def add_custom(self, request, view_id, arch):
@@ -611,27 +615,38 @@ class View(openerpweb.Controller):
self.parse_domains_and_contexts(elem, session)
return root
- def parse_domain(self, elem, attr_name, session):
- """ Parses an attribute of the provided name as a domain, transforms it
+ def parse_domain(self, domain, session):
+ """ Parses an arbitrary string containing a domain, transforms it
to either a literal domain or a :class:`openerpweb.nonliterals.Domain`
- :param elem: the node being parsed
- :type param: xml.etree.ElementTree.Element
- :param str attr_name: the name of the attribute which should be parsed
+ :param domain: the domain to parse, if the domain is not a string it is assumed to
+ be a literal domain and is returned as-is
:param session: Current OpenERP session
:type session: openerpweb.openerpweb.OpenERPSession
"""
- domain = elem.get(attr_name, '').strip()
- if domain:
- try:
- elem.set(
- attr_name,
- openerpweb.ast.literal_eval(
- domain))
- except ValueError:
- # not a literal
- elem.set(attr_name,
- openerpweb.nonliterals.Domain(session, domain))
+ if not isinstance(domain, (str, unicode)):
+ return domain
+ try:
+ return openerpweb.ast.literal_eval(domain)
+ except ValueError:
+ # not a literal
+ return openerpweb.nonliterals.Domain(session, domain)
+
+ def parse_context(self, context, session):
+ """ Parses an arbitrary string containing a context, transforms it
+ to either a literal context or a :class:`openerpweb.nonliterals.Context`
+
+ :param context: the context to parse, if the context is not a string it is assumed to
+ be a literal domain and is returned as-is
+ :param session: Current OpenERP session
+ :type session: openerpweb.openerpweb.OpenERPSession
+ """
+ if not isinstance(context, (str, unicode)):
+ return context
+ try:
+ return openerpweb.ast.literal_eval(context)
+ except ValueError:
+ return openerpweb.nonliterals.Context(session, context)
def parse_domains_and_contexts(self, elem, session):
""" Converts domains and contexts from the view into Python objects,
@@ -644,18 +659,14 @@ class View(openerpweb.Controller):
non-literal objects
:type session: openerpweb.openerpweb.OpenERPSession
"""
- self.parse_domain(elem, 'domain', session)
- self.parse_domain(elem, 'filter_domain', session)
+ for el in ['domain', 'filter_domain']:
+ domain = elem.get(el, '').strip()
+ if domain:
+ elem.set(el, self.parse_domain(domain, session))
for el in ['context', 'default_get']:
context_string = elem.get(el, '').strip()
if context_string:
- try:
- elem.set(el,
- openerpweb.ast.literal_eval(context_string))
- except ValueError:
- elem.set(el,
- openerpweb.nonliterals.Context(
- session, context_string))
+ elem.set(el, self.parse_context(context_string, session))
class FormView(View):
_cp_path = "/base/formview"
diff --git a/addons/base/static/src/css/base.css b/addons/base/static/src/css/base.css
index e91bbd922ec..d220c8b406b 100644
--- a/addons/base/static/src/css/base.css
+++ b/addons/base/static/src/css/base.css
@@ -577,6 +577,10 @@ background: linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,
display: none;
}
+.openerp .searchview_extended_delete_prop {
+ text-decoration: none;
+}
+
.openerp .searchview_extended_delete_group span,
.openerp .searchview_extended_delete_prop span {
font-size: 0.9em;
@@ -609,10 +613,14 @@ background: linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,
.openerp .oe-listview td.oe-record-delete {
text-align: right;
}
-.openerp .oe-listview th.oe-sortable,
-.openerp .oe-listview th.oe-sortable .ui-icon {
+.openerp .oe-listview th.oe-sortable {
cursor: pointer;
}
+.openerp .oe-listview th.oe-sortable .ui-icon {
+ height: 1em;
+ display: inline;
+ display: inline-block;
+}
.openerp .oe-listview .oe-field-cell {
cursor: pointer;
diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js
index 84f2747166c..c6bf0adada4 100644
--- a/addons/base/static/src/js/chrome.js
+++ b/addons/base/static/src/js/chrome.js
@@ -365,7 +365,7 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b
params: params,
id:null
}).then(function () {deferred.resolve.apply(deferred, arguments);},
- function(error) {deferred.reject(error, $.Event());});
+ function(error) {deferred.reject(error, $.Event());});
return deferred.fail(function() {
deferred.fail(function(error, event) {
if (!event.isDefaultPrevented()) {
@@ -398,31 +398,35 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b
}, url);
var deferred = $.Deferred();
$.ajax(ajax).done(function(response, textStatus, jqXHR) {
- self.on_rpc_response();
- if (response.error) {
- if (response.error.data.type == "session_invalid") {
- self.uid = false;
- self.on_session_invalid(function() {
- self.rpc(url, payload.params,
- function() {deferred.resolve.apply(deferred, arguments);},
- function(error, event) {event.preventDefault();
- deferred.reject.apply(deferred, arguments);});
- });
- } else {
- deferred.reject(response.error);
- }
- } else {
- deferred.resolve(response["result"], textStatus, jqXHR);
- }
- }).fail(function(jqXHR, textStatus, errorThrown) {
- self.on_rpc_response();
- var error = {
- code: -32098,
- message: "XmlHttpRequestError " + errorThrown,
- data: {type: "xhr"+textStatus, debug: jqXHR.responseText, objects: [jqXHR, errorThrown] }
- };
- deferred.reject(error);
+ self.on_rpc_response();
+ if (!response.error) {
+ deferred.resolve(response["result"], textStatus, jqXHR);
+ return;
+ }
+ if (response.error.data.type !== "session_invalid") {
+ deferred.reject(response.error);
+ return;
+ }
+ self.uid = false;
+ self.on_session_invalid(function() {
+ self.rpc(url, payload.params,
+ function() {
+ deferred.resolve.apply(deferred, arguments);
+ },
+ function(error, event) {
+ event.preventDefault();
+ deferred.reject.apply(deferred, arguments);
+ });
});
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ self.on_rpc_response();
+ var error = {
+ code: -32098,
+ message: "XmlHttpRequestError " + errorThrown,
+ data: {type: "xhr"+textStatus, debug: jqXHR.responseText, objects: [jqXHR, errorThrown] }
+ };
+ deferred.reject(error);
+ });
return deferred.promise();
},
on_rpc_request: function() {
diff --git a/addons/base/static/src/js/data.js b/addons/base/static/src/js/data.js
index a49e6cf901f..c1b64b93307 100644
--- a/addons/base/static/src/js/data.js
+++ b/addons/base/static/src/js/data.js
@@ -1,6 +1,23 @@
openerp.base.data = function(openerp) {
+/**
+ * Serializes the sort criterion array of a dataset into a form which can be
+ * consumed by OpenERP's RPC APIs.
+ *
+ * @param {Array} criterion array of fields, from first to last criteria, prefixed with '-' for reverse sorting
+ * @returns {String} SQL-like sorting string (``ORDER BY``) clause
+ */
+openerp.base.serialize_sort = function (criterion) {
+ return _.map(criterion,
+ function (criteria) {
+ if (criteria[0] === '-') {
+ return criteria.slice(1) + ' DESC';
+ }
+ return criteria + ' ASC';
+ }).join(', ');
+};
+
openerp.base.DataGroup = openerp.base.Controller.extend( /** @lends openerp.base.DataGroup# */{
/**
* Management interface between views and grouped collections of OpenERP
@@ -130,7 +147,8 @@ openerp.base.ContainerDataGroup = openerp.base.DataGroup.extend(
context: this.context,
domain: this.domain,
fields: _.uniq(this.group_by.concat(fields)),
- group_by_fields: this.group_by
+ group_by_fields: this.group_by,
+ sort: openerp.base.serialize_sort(this.sort)
}, function () { }).then(function (response) {
var data_groups = _(response).map(
_.bind(self.transform_group, self));
@@ -174,7 +192,7 @@ openerp.base.ContainerDataGroup = openerp.base.DataGroup.extend(
self.session, self.model, group.__domain,
child_context, child_context.group_by,
self.level + 1),
- group);
+ group, {sort: self.sort});
}));
});
}
@@ -197,8 +215,8 @@ openerp.base.GrouplessDataGroup = openerp.base.DataGroup.extend(
},
list: function (fields, ifGroups, ifRecords) {
ifRecords(_.extend(
- new openerp.base.DataSetSearch(this.session, this.model),
- {domain: this.domain, context: this.context}));
+ new openerp.base.DataSetSearch(this.session, this.model),
+ {domain: this.domain, context: this.context, _sort: this.sort}));
}
});
@@ -378,7 +396,7 @@ openerp.base.DataSetStatic = openerp.base.DataSet.extend({
var self = this;
offset = offset || 0;
var end_pos = limit && limit !== -1 ? offset + limit : undefined;
- this.read_ids(this.ids.slice(offset, end_pos), fields, callback);
+ return this.read_ids(this.ids.slice(offset, end_pos), fields, callback);
},
set_ids: function (ids) {
this.ids = ids;
@@ -415,7 +433,7 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
// return read_ids(ids.slice(start,start+limit),fields,callback)
}
}
- this.rpc('/base/dataset/search_read', {
+ return this.rpc('/base/dataset/search_read', {
model: this.model,
fields: fields,
domain: this.domain,
@@ -426,7 +444,9 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
}, function (result) {
self.ids = result.ids;
self.offset = offset;
- callback(result.records);
+ if (callback) {
+ callback(result.records);
+ }
});
},
/**
@@ -444,16 +464,12 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
*/
sort: function (field, force_reverse) {
if (!field) {
- return _.map(this._sort, function (criteria) {
- if (criteria[0] === '-') {
- return criteria.slice(1) + ' DESC';
- }
- return criteria + ' ASC';
- }).join(', ');
+ return openerp.base.serialize_sort(this._sort);
}
-
var reverse = force_reverse || (this._sort[0] === field);
- this._sort = _.without(this._sort, field, '-' + field);
+ this._sort.splice.apply(
+ this._sort, [0, this._sort.length].concat(
+ _.without(this._sort, field, '-' + field)));
this._sort.unshift((reverse ? '-' : '') + field);
return undefined;
diff --git a/addons/base/static/src/js/form.js b/addons/base/static/src/js/form.js
index 60511c49c17..523f47e5f33 100644
--- a/addons/base/static/src/js/form.js
+++ b/addons/base/static/src/js/form.js
@@ -79,6 +79,10 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
this.$form_header.find('button.oe_form_button_cancel').click(this.do_cancel);
this.$form_header.find('button.oe_form_button_new').click(this.on_button_new);
+ this.$form_header.find('button.oe_get_xml_view').click(function() {
+ $('
' + openerp.base.json_node_to_xml(self.fields_view.arch, true) + '').dialog({ width: '95%', height: 600});
+ });
+
this.view_manager.sidebar.set_toolbar(data.fields_view.toolbar);
this.has_been_loaded.resolve();
},
@@ -235,6 +239,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
if (result.value) {
for (var f in result.value) {
var field = this.fields[f];
+ // If field is not defined in the view, just ignore it
if (field) {
var value = result.value[f];
processed.push(field.name);
@@ -245,8 +250,6 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
this.do_onchange(field, processed);
}
}
- } else {
- // this is a common case, the normal behavior should be to ignore it
}
}
this.on_form_changed();
@@ -262,16 +265,15 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
});
}
if (result.domain) {
- // Will be removed ?
+ // TODO:
}
this.ready = true;
},
on_button_new: function() {
var self = this;
$.when(this.has_been_loaded).then(function() {
- self.dataset.default_get(_.keys(self.fields_view.fields), function(result) {
- self.on_record_loaded(result.result);
- });
+ self.dataset.default_get(
+ _.keys(self.fields_view.fields), self.on_record_loaded);
});
},
/**
@@ -826,8 +828,10 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
* the fields'context with the action's context.
*/
build_context: function() {
- var a_context = this.view.dataset.get_context() || {};
- var f_context = this.field.context || {};
+ // I previously belevied contexts should be herrited, but now I doubt it
+ //var a_context = this.view.dataset.get_context() || {};
+ var f_context = this.field.context || null;
+ // maybe the default_get should only be used when we do a default_get?
var v_context1 = this.node.attrs.default_get || {};
var v_context2 = this.node.attrs.context || {};
var v_context = new openerp.base.CompoundContext(v_context1, v_context2);
@@ -835,17 +839,19 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
var fields_values = this._build_view_fields_values();
v_context.set_eval_context(fields_values);
}
- var ctx = new openerp.base.CompoundContext(a_context, f_context, v_context);
+ // if there is a context on the node, overrides the model's context
+ var ctx = f_context || v_context;
return ctx;
},
build_domain: function() {
- var f_domain = this.field.domain || [];
+ var f_domain = this.field.domain || null;
var v_domain = this.node.attrs.domain || [];
if (!(v_domain instanceof Array) || true) { //TODO niv: remove || true
var fields_values = this._build_view_fields_values();
v_domain = new openerp.base.CompoundDomain(v_domain).set_eval_context(fields_values);
}
- return new openerp.base.CompoundDomain(f_domain, v_domain);
+ // if there is a domain on the node, overrides the model's domain
+ return f_domain || v_domain;
}
});
@@ -1239,6 +1245,21 @@ openerp.base.form.FieldSelection = openerp.base.form.Field.extend({
});
})();
+openerp.base.form.dialog = function(content, options) {
+ options = _.extend({
+ autoOpen: true,
+ width: '90%',
+ height: '90%',
+ min_width: '800px',
+ min_height: '600px'
+ }, options || {});
+ options.autoOpen = true;
+ var dialog = new openerp.base.Dialog(null, options);
+ dialog.$dialog = $(content).dialog(dialog.options);
+ console.log(dialog.options)
+ return dialog.$dialog;
+}
+
openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
init: function(view, node) {
this._super(view, node);
@@ -1827,10 +1848,7 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
this.context = context || {};
this.options = _.defaults(options || {}, {"initial_view": "search", "auto_create": true});
this.initial_ids = this.options.initial_ids;
- jQuery(this.render()).dialog({title: '',
- modal: true,
- width: 960,
- height: 600});
+ openerp.base.form.dialog(this.render());
this.start();
},
start: function() {
@@ -2019,10 +2037,10 @@ openerp.base.form.FormOpenPopup = openerp.base.BaseWidget.extend({
}
});
-openerp.base.form.FieldReference = openerp.base.form.Field.extend({
+openerp.base.form.FieldReference = openerp.base.form.FieldChar.extend({
init: function(view, node) {
this._super(view, node);
- this.template = "FieldReference";
+ //this.template = "FieldReference";
}
});
@@ -2040,6 +2058,10 @@ openerp.base.form.FieldBinary = openerp.base.form.Field.extend({
},
set_value_from_ui: function() {
},
+ update_dom: function() {
+ this._super.apply(this, arguments);
+ this.$element.find('.oe-binary').toggle(!this.readonly);
+ },
human_filesize : function(size) {
var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
var i = 0;
@@ -2137,6 +2159,13 @@ openerp.base.form.FieldBinaryImage = openerp.base.form.FieldBinary.extend({
this._super.apply(this, arguments);
this.$image = this.$element.find('img.oe-binary-image');
},
+ set_value: function(value) {
+ this._super.apply(this, arguments);
+ this.set_image_maxwidth();
+ var url = '/base/binary/image?session_id=' + this.session.session_id + '&model=' +
+ this.view.dataset.model +'&id=' + (this.view.datarecord.id || '') + '&field=' + this.name + '&t=' + (new Date().getTime())
+ this.$image.attr('src', url);
+ },
set_image_maxwidth: function() {
this.$image.css('max-width', this.$element.width());
},
@@ -2152,13 +2181,6 @@ openerp.base.form.FieldBinaryImage = openerp.base.form.FieldBinary.extend({
on_clear: function() {
this._super.apply(this, arguments);
this.$image.attr('src', '/base/static/src/img/placeholder.png');
- },
- set_value: function(value) {
- this._super.apply(this, arguments);
- this.set_image_maxwidth();
- var url = '/base/binary/image?session_id=' + this.session.session_id + '&model=' +
- this.view.dataset.model +'&id=' + (this.view.datarecord.id || '') + '&field=' + this.name + '&t=' + (new Date().getTime())
- this.$image.attr('src', url);
}
});
diff --git a/addons/base/static/src/js/list-editable.js b/addons/base/static/src/js/list-editable.js
index a460dfcff41..4aa06cc8152 100644
--- a/addons/base/static/src/js/list-editable.js
+++ b/addons/base/static/src/js/list-editable.js
@@ -247,7 +247,12 @@ openerp.base.list.editable = function (openerp) {
this.render_row_as_form();
}
});
- openerp.base.list = {form: {}};
+ if (!openerp.base.list) {
+ openerp.base.list = {};
+ }
+ if (!openerp.base.list.form) {
+ openerp.base.list.form = {};
+ }
openerp.base.list.form.WidgetFrame = openerp.base.form.WidgetFrame.extend({
template: 'ListView.row.frame'
});
diff --git a/addons/base/static/src/js/list.js b/addons/base/static/src/js/list.js
index 7922f690784..49cd10c10b6 100644
--- a/addons/base/static/src/js/list.js
+++ b/addons/base/static/src/js/list.js
@@ -1,5 +1,50 @@
openerp.base.list = function (openerp) {
openerp.base.views.add('list', 'openerp.base.ListView');
+openerp.base.list = {
+ /**
+ * Formats the rendring of a given value based on its field type
+ *
+ * @param {Object} row_data record whose values should be displayed in the cell
+ * @param {Object} column column descriptor
+ * @param {"button"|"field"} column.tag base control type
+ * @param {String} column.type widget type for a field control
+ * @param {String} [column.string] button label
+ * @param {String} [column.icon] button icon
+ * @param {String} [value_if_empty=''] what to display if the field's value is ``false``
+ */
+ render_cell: function (row_data, column, value_if_empty) {
+ var attrs = column.modifiers_for(row_data);
+ if (attrs.invisible) { return ''; }
+ if (column.tag === 'button') {
+ return [
+ ''
+ ].join('')
+ }
+
+ var record = row_data[column.id];
+ if (record.value === false) {
+ return value_if_empty === undefined ? '' : value_if_empty;
+ }
+ switch (column.widget || column.type) {
+ case 'many2one':
+ // name_get value format
+ return record.value[1];
+ case 'float_time':
+ return _.sprintf("%02d:%02d",
+ Math.floor(record.value),
+ Math.round((record.value % 1) * 60));
+ case 'progressbar':
+ return _.sprintf(
+ '',
+ record.value, record.value);
+ default:
+ return record.value;
+ }
+ }
+};
openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListView# */ {
defaults: {
// records can be selected one by one
@@ -147,8 +192,6 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
this.setup_columns(this.fields_view.fields, grouped);
- if (!this.fields_view.sorted) { this.fields_view.sorted = {}; }
-
this.$element.html(QWeb.render("ListView", this));
// Head hook
@@ -158,13 +201,20 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
this.$element.find('.oe-list-delete')
.attr('disabled', true)
.click(this.do_delete_selected);
- this.$element.find('thead').delegate('th[data-id]', 'click', function (e) {
+ this.$element.find('thead').delegate('th.oe-sortable[data-id]', 'click', function (e) {
e.stopPropagation();
- self.dataset.sort($(this).data('id'));
+ var $this = $(this);
+ self.dataset.sort($this.data('id'));
+ if ($this.find('span').length) {
+ $this.find('span').toggleClass(
+ 'ui-icon-triangle-1-s ui-icon-triangle-1-n');
+ } else {
+ $this.append('')
+ .siblings('.oe-sortable').find('span').remove();
+ }
- // TODO: should only reload content (and set the right column to a sorted display state)
- self.reload_view();
+ self.reload_content();
});
this.$element.find('.oe-list-pager')
@@ -263,6 +313,9 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
'invisible': domain_computer(modifiers.invisible, fields)
};
};
+ if (modifiers['tree_invisible']) {
+ column.invisible = '1';
+ }
} else {
column.modifiers_for = noop;
}
@@ -401,6 +454,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
this.session, this.model,
results.domain, results.context,
results.group_by);
+ this.groups.datagroup.sort = this.dataset._sort;
if (_.isEmpty(results.group_by) && !results.context['group_by_no_leaf']) {
results.group_by = null;
@@ -634,7 +688,7 @@ openerp.base.ListView.List = Class.extend( /** @lends openerp.base.ListView.List
this.$current = this.$_element.clone(true);
this.$current.empty().append(
QWeb.render('ListView.rows', _.extend({
- render_cell: this.render_cell}, this)));
+ render_cell: openerp.base.list.render_cell}, this)));
},
/**
* Gets the ids of all currently selected records, if any
@@ -765,49 +819,9 @@ openerp.base.ListView.List = Class.extend( /** @lends openerp.base.ListView.List
row: this.rows[record_index],
row_parity: (record_index % 2 === 0) ? 'even' : 'odd',
row_index: record_index,
- render_cell: this.render_cell
+ render_cell: openerp.base.list.render_cell
});
},
- /**
- * Formats the rendring of a given value based on its field type
- *
- * @param {Object} row_data record whose values should be displayed in the cell
- * @param {Object} column column descriptor
- * @param {"button"|"field"} column.tag base control type
- * @param {String} column.type widget type for a field control
- * @param {String} [column.string] button label
- * @param {String} [column.icon] button icon
- */
- render_cell: function (row_data, column) {
- var attrs = column.modifiers_for(row_data);
- if (attrs.invisible) { return ''; }
- if (column.tag === 'button') {
- return [
- ''
- ].join('')
- }
-
- var record = row_data[column.id];
- if (record.value === false) { return ''; }
- switch (column.widget || column.type) {
- case 'many2one':
- // name_get value format
- return record.value[1];
- case 'float_time':
- return _.sprintf("%02d:%02d",
- Math.floor(record.value),
- Math.round((record.value % 1) * 60));
- case 'progressbar':
- return _.sprintf(
- '',
- record.value, record.value);
- default:
- return record.value;
- }
- },
/**
* Stops displaying the records matching the provided ids.
*
@@ -959,10 +973,15 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
placeholder.appendChild($row[0]);
var $group_column = $('
').appendTo($row);
+ // Don't fill this if group_by_no_leaf but no group_by
if (group.grouped_on) {
- // Don't fill this if group_by_no_leaf but no group_by
- $group_column
- .text((group.value instanceof Array ? group.value[1] : group.value));
+ var row_data = {};
+ row_data[group.grouped_on] = group;
+ var group_column = _(self.columns).detect(function (column) {
+ return column.id === group.grouped_on; });
+ $group_column.text(openerp.base.list.render_cell(
+ row_data, group_column, "Undefined"
+ ));
if (group.openable) {
// Make openable if not terminal group & group_by_no_leaf
$group_column
diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml
index 603c75cdb74..8f9d063ffba 100644
--- a/addons/base/static/src/xml/base.xml
+++ b/addons/base/static/src/xml/base.xml
@@ -283,10 +283,8 @@