diff options
| author | Minh Tran <mit@openerp.com> | 2012-01-11 12:08:03 +0100 |
|---|---|---|
| committer | Minh Tran <mit@openerp.com> | 2012-01-11 12:08:03 +0100 |
| commit | ce2202a823b1469c50412bbbe7b8bfda04b0718b (patch) | |
| tree | 163b7eaac8f7a596f015eec8098ac7d4d33862cb /addons/web/static/src | |
| parent | d63c20b73de27d5b272ce8b1442044cc8d5fbb93 (diff) | |
| parent | 2b736ee2cf2037734fd426bd968b6294a7a843e4 (diff) | |
Merge from trunk
bzr revid: mit@openerp.com-20120111110803-pcizwc2x9w51tsdx
Diffstat (limited to 'addons/web/static/src')
| -rw-r--r-- | addons/web/static/src/css/base.css | 21 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome.js | 67 | ||||
| -rw-r--r-- | addons/web/static/src/js/data.js | 5 | ||||
| -rw-r--r-- | addons/web/static/src/js/data_export.js | 8 | ||||
| -rw-r--r-- | addons/web/static/src/js/formats.js | 65 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_editor.js | 7 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_form.js | 79 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_list.js | 23 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_page.js | 7 | ||||
| -rw-r--r-- | addons/web/static/src/js/views.js | 169 | ||||
| -rw-r--r-- | addons/web/static/src/xml/base.xml | 15 |
11 files changed, 252 insertions, 214 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index df6d78e8aa5..6da9f1bbe8d 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -2033,6 +2033,7 @@ ul.oe-arrow-list li.oe-arrow-list-selected .oe-arrow-list-after { .openerp .oe_vm_switch_form, .openerp .oe_vm_switch_page, +.openerp .oe_vm_switch_tree, .openerp .oe_vm_switch_list, .openerp .oe_vm_switch_graph, .openerp .oe_vm_switch_gantt, @@ -2049,6 +2050,7 @@ ul.oe-arrow-list li.oe-arrow-list-selected .oe-arrow-list-after { .openerp .oe_vm_switch_form span, .openerp .oe_vm_switch_page span, +.openerp .oe_vm_switch_tree span, .openerp .oe_vm_switch_list span, .openerp .oe_vm_switch_graph span, .openerp .oe_vm_switch_gantt span, @@ -2068,6 +2070,16 @@ ul.oe-arrow-list li.oe-arrow-list-selected .oe-arrow-list-after { background-position: 0px -21px; } +.openerp .oe_vm_switch_tree { + background-position: 0px 0px; +} +.openerp .oe_vm_switch_tree:active, +.openerp .oe_vm_switch_tree:hover, +.openerp .oe_vm_switch_tree:focus, +.openerp .oe_vm_switch_tree[disabled="disabled"] { + background-position: 0px -21px; +} + .openerp .oe_vm_switch_form { background-position: -22px 0px; } @@ -2078,6 +2090,15 @@ ul.oe-arrow-list li.oe-arrow-list-selected .oe-arrow-list-after { background-position: -22px -21px; } +.openerp .oe_vm_switch_page { + background-position: -22px 0px; +} +.openerp .oe_vm_switch_page:active, +.openerp .oe_vm_switch_page:hover, +.openerp .oe_vm_switch_page:focus, +.openerp .oe_vm_switch_page[disabled="disabled"] { + background-position: -22px -21px; +} .openerp .oe_vm_switch_graph { background-position: -44px 0px; } diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 34b413526f0..520345e1e23 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -44,9 +44,9 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog# * @extends openerp.web.OldWidget * * @param parent - * @param dialog_options + * @param options */ - init: function (parent, dialog_options) { + init: function (parent, options) { var self = this; this._super(parent); this.dialog_options = { @@ -57,10 +57,9 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog# max_width: '95%', height: 'auto', min_height: 0, - max_height: '95%', + max_height: this.get_height('100%') - 140, autoOpen: false, position: [false, 50], - autoResize : 'auto', buttons: {}, beforeClose: function () { self.on_close(); }, resizeStop: this.on_resized @@ -70,31 +69,24 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog# this.dialog_options.buttons[f.substr(10)] = this[f]; } } - if (dialog_options) { - this.set_options(dialog_options); + if (options) { + _.extend(this.dialog_options, options); } }, - set_options: function(options) { - options = options || {}; - options.width = this.get_width(options.width || this.dialog_options.width); - options.min_width = this.get_width(options.min_width || this.dialog_options.min_width); - options.max_width = this.get_width(options.max_width || this.dialog_options.max_width); - options.height = this.get_height(options.height || this.dialog_options.height); - options.min_height = this.get_height(options.min_height || this.dialog_options.min_height); - options.max_height = this.get_height(options.max_height || this.dialog_options.max_height); - - if (options.width !== 'auto') { - if (options.width > options.max_width) options.width = options.max_width; - if (options.width < options.min_width) options.width = options.min_width; - } - if (options.height !== 'auto') { - if (options.height > options.max_height) options.height = options.max_height; - if (options.height < options.min_height) options.height = options.min_height; - } - if (!options.title && this.dialog_title) { - options.title = this.dialog_title; + get_options: function(options) { + var self = this, + o = _.extend({}, this.dialog_options, options || {}); + _.each(['width', 'height'], function(unit) { + o[unit] = self['get_' + unit](o[unit]); + o['min_' + unit] = self['get_' + unit](o['min_' + unit] || 0); + o['max_' + unit] = self['get_' + unit](o['max_' + unit] || 0); + if (o[unit] !== 'auto' && o['min_' + unit] && o[unit] < o['min_' + unit]) o[unit] = o['min_' + unit]; + if (o[unit] !== 'auto' && o['max_' + unit] && o[unit] > o['max_' + unit]) o[unit] = o['max_' + unit]; + }); + if (!o.title && this.dialog_title) { + o.title = this.dialog_title; } - _.extend(this.dialog_options, options); + return o; }, get_width: function(val) { return this.get_size(val.toString(), $(window.top).width()); @@ -116,13 +108,16 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog# this._super(); return this; }, - open: function(dialog_options) { + open: function(options) { // TODO fme: bind window on resize if (this.template) { this.$element.html(this.render()); } - this.set_options(dialog_options); - this.$element.dialog(this.dialog_options).dialog('open'); + var o = this.get_options(options); + this.$element.dialog(o).dialog('open'); + if (o.height === 'auto' && o.max_height) { + this.$element.css({ 'max-height': o.max_height, 'overflow-y': 'auto' }); + } return this; }, close: function() { @@ -134,9 +129,7 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog# } }, on_resized: function() { - if (openerp.connection.debug) { - console.log("Dialog resized to %d x %d", this.$element.width(), this.$element.height()); - } + openerp.log("Dialog resized to %d x %d", this.$element.width(), this.$element.height()); }, stop: function () { // Destroy widget @@ -481,7 +474,10 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database error: error[1] }); }, - complete: $.proxy(self, 'unblockUI') + complete: function() { + self.unblockUI(); + self.do_notify(_t("Backed"), _t("Database backed up successfully")); + } }); } }); @@ -517,7 +513,10 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database }) } }, - complete: $.proxy(self, 'unblockUI') + complete: function() { + self.unblockUI(); + self.do_notify(_t("Restored"), _t("Database restored successfully")); + } }); } }); diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index c24325a9327..3b444dffc78 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -322,16 +322,17 @@ openerp.web.DataSet = openerp.web.Widget.extend( /** @lends openerp.web.DataSet * Reads the current dataset record (from its index) * * @params {Array} [fields] fields to read and return, by default all fields are returned + * @param {Object} [options.context] context data to add to the request payload, on top of the DataSet's own context * @params {Function} callback function called with read_index result * @returns {$.Deferred} */ - read_index: function (fields, callback) { + read_index: function (fields, options, callback) { var def = $.Deferred().then(callback); if (_.isEmpty(this.ids)) { def.reject(); } else { fields = fields || false; - this.read_ids([this.ids[this.index]], fields).then(function(records) { + this.read_ids([this.ids[this.index]], fields, options).then(function(records) { def.resolve(records[0]); }, function() { def.reject.apply(def, arguments); diff --git a/addons/web/static/src/js/data_export.js b/addons/web/static/src/js/data_export.js index 78dc3bef1f9..c6fe96432ea 100644 --- a/addons/web/static/src/js/data_export.js +++ b/addons/web/static/src/js/data_export.js @@ -114,7 +114,7 @@ openerp.web.DataExport = openerp.web.Dialog.extend({ if (value) { self.do_save_export_list(value); } else { - alert("Pleae Enter Save Field List Name"); + alert(_t("Please enter save field list name")); } }); } else { @@ -349,24 +349,24 @@ openerp.web.DataExport = openerp.web.Dialog.extend({ export_field.push($(this).val()); }); if (!export_field.length) { - alert('Please select fields to save export list...'); + alert(_t("Please select fields to save export list...")); } return export_field; }, on_click_export_data: function() { - $.blockUI(this.$element); var exported_fields = [], self = this; this.$element.find("#fields_list option").each(function() { var fieldname = self.records[$(this).val()]; exported_fields.push({name: fieldname, label: $(this).text()}); }); if (_.isEmpty(exported_fields)) { - alert('Please select fields to export...'); + alert(_t("Please select fields to export...")); return; } exported_fields.unshift({name: 'id', label: 'External ID'}); var export_format = this.$element.find("#export_format").val(); + $.blockUI(); this.session.get_file({ url: '/web/export/' + export_format, data: {data: JSON.stringify({ diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index 37d1e4cf7b5..7f220d0aa54 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -102,10 +102,6 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) { return _.str.sprintf("%02d:%02d", Math.floor(value), Math.round((value % 1) * 60)); - case 'progressbar': - return _.str.sprintf( - '<progress value="%.2f" max="100.0">%.2f%%</progress>', - value, value); case 'many2one': // name_get value format return value[1]; @@ -237,7 +233,15 @@ openerp.web.auto_date_to_str = function(value, type) { }; /** - * Formats a provided cell based on its field type + * Formats a provided cell based on its field type. Most of the field types + * return a correctly formatted value, but some tags and fields are + * special-cased in their handling: + * + * * buttons will return an actual ``<button>`` tag with a bunch of error handling + * + * * boolean fields will return a checkbox input, potentially disabled + * + * * binary fields will return a link to download the binary data as a file * * @param {Object} row_data record whose values should be displayed in the cell * @param {Object} column column descriptor @@ -245,15 +249,21 @@ openerp.web.auto_date_to_str = function(value, 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`` - * @param {Boolean} [process_modifiers=true] should the modifiers be computed ? + * @param {Object} [options] + * @param {String} [options.value_if_empty=''] what to display if the field's value is ``false`` + * @param {Boolean} [options.process_modifiers=true] should the modifiers be computed ? + * @param {String} [options.model] current record's model + * @param {Number} [options.id] current record's id + * */ -openerp.web.format_cell = function (row_data, column, value_if_empty, process_modifiers) { +openerp.web.format_cell = function (row_data, column, options) { + options = options || {}; var attrs = {}; - if (process_modifiers !== false) { + if (options.process_modifiers !== false) { attrs = column.modifiers_for(row_data); } if (attrs.invisible) { return ''; } + if (column.tag === 'button') { return _.template('<button type="button" title="<%-title%>" <%=additional_attributes%> >' + '<img src="<%-prefix%>/web/static/src/img/icons/<%-icon%>.png" alt="<%-alt%>"/>' + @@ -263,14 +273,41 @@ openerp.web.format_cell = function (row_data, column, value_if_empty, process_mo 'disabled="disabled" class="oe-listview-button-disabled"' : '', prefix: openerp.connection.prefix, icon: column.icon, - alt: column.string || '', + alt: column.string || '' }); } if (!row_data[column.id]) { - return value_if_empty === undefined ? '' : value_if_empty; + return options.value_if_empty === undefined ? '' : options.value_if_empty; } - return openerp.web.format_value( - row_data[column.id].value, column, value_if_empty); + + switch (column.widget || column.type) { + case "boolean": + return _.str.sprintf('<input type="checkbox" %s disabled="disabled"/>', + row_data[column.id].value ? 'checked="checked"' : ''); + case "binary": + var text = _t("Download"), + download_url = _.str.sprintf('/web/binary/saveas?session_id=%s&model=%s&field=%s&id=%d', openerp.connection.session_id, options.model, column.id, options.id); + if (column.filename) { + download_url += '&filename_field=' + column.filename; + if (row_data[column.filename]) { + text = _.str.sprintf(_t("Download \"%s\""), openerp.web.format_value( + row_data[column.filename].value, {type: 'char'})); + } + } + return _.template('<a href="<%-href%>"><%-text%></a> (%<-size%>)', { + text: text, + href: download_url, + size: row_data[column.id].value + }); + case 'progressbar': + return _.template( + '<progress value="<%-value%>" max="100"><%-value%>%</progress>', { + value: row_data[column.id].value + }); + } + + return _.escape(openerp.web.format_value( + row_data[column.id].value, column, options.value_if_empty)); } - + }; diff --git a/addons/web/static/src/js/view_editor.js b/addons/web/static/src/js/view_editor.js index 649f324744d..3635b988318 100644 --- a/addons/web/static/src/js/view_editor.js +++ b/addons/web/static/src/js/view_editor.js @@ -16,9 +16,10 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({ this.init_view_editor(); }, init_view_editor: function() { - var self = this; + var self = this, + action_title = _.str.sprintf(_t("Manage Views (%s)"), this.model); var action = { - name: _.str.sprintf("Manage Views (%s)", this.model), + name: action_title, context: this.session.user_context, domain: [["model", "=", this.model]], res_model: 'ir.ui.view', @@ -38,7 +39,7 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({ } }; this.view_edit_dialog = new openerp.web.Dialog(this, { - title: _t("ViewEditor"), + title: action_title, width: 850, buttons: [ {text: _t("Create"), click: function() { self.on_create_view(); }}, diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index ec92cd2ac52..2d0cf214135 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -50,10 +50,10 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# _.defaults(this.options, { "not_interactible_on_create": false }); - this.mutating_lock = $.Deferred(); - this.initial_mutating_lock = this.mutating_lock; - this.on_change_lock = $.Deferred().resolve(); - this.reload_lock = $.Deferred().resolve(); + this.is_initialized = $.Deferred(); + this.mutating_mutex = new $.Mutex(); + this.on_change_mutex = new $.Mutex(); + this.reload_mutex = new $.Mutex(); }, start: function() { this._super(); @@ -136,6 +136,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# do_show: function () { var self = this; + this.$element.show().css('visibility', 'hidden'); return this.has_been_loaded.pipe(function() { var result; if (self.dataset.index === null) { @@ -144,7 +145,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# } else { result = self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_record_loaded); } - self.$element.show(); + result.pipe(function() { + self.$element.css('visibility', 'visible'); + }); if (self.sidebar) { self.sidebar.$element.show(); } @@ -186,7 +189,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# }); } self.on_form_changed(); - self.initial_mutating_lock.resolve(); + self.is_initialized.resolve(); self.show_invalid = true; self.do_update_pager(record.id == null); if (self.sidebar) { @@ -303,7 +306,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# }, do_onchange: function(widget, processed) { var self = this; - var act = function() { + return this.on_change_mutex.exec(function() { try { processed = processed || []; var on_change = widget.node.attrs.on_change; @@ -330,9 +333,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# console.error(e); return $.Deferred().reject(); } - }; - this.on_change_lock = this.on_change_lock.pipe(act, act); - return this.on_change_lock; + }); }, on_processed_onchange: function(response, processed) { try { @@ -414,10 +415,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# */ do_save: function(success, prepend_on_create) { var self = this; - var action = function() { + return this.mutating_mutex.exec(function() { return self.is_initialized.pipe(function() { try { - if (!self.initial_mutating_lock.isResolved() && !self.initial_mutating_lock.isRejected()) - return; var form_invalid = false, values = {}, first_invalid_field = null; @@ -462,9 +461,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# console.error(e); return $.Deferred().reject(); } - }; - this.mutating_lock = this.mutating_lock.pipe(action, action); - return this.mutating_lock; + });}); }, on_invalid: function() { var msg = "<ul>"; @@ -525,15 +522,13 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# }, reload: function() { var self = this; - var act = function() { + return this.reload_mutex.exec(function() { if (self.dataset.index == null || self.dataset.index < 0) { return $.when(self.on_button_new()); } else { return self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_record_loaded); } - }; - this.reload_lock = this.reload_lock.pipe(act, act); - return this.reload_lock; + }); }, get_fields_values: function(blacklist) { blacklist = blacklist || []; @@ -831,23 +826,17 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form. * the fields'context with the action's context. */ build_context: function(blacklist) { - var f_context = (this.field || {}).context || {}; - if (!!f_context.__ref || true) { //TODO: remove true - var fields_values = this._build_eval_context(blacklist); - f_context = new openerp.web.CompoundContext(f_context).set_eval_context(fields_values); - } - // maybe the default_get should only be used when we do a default_get? - var v_contexts = _.compact([this.node.attrs.default_get || null, - this.node.attrs.context || null]); - var v_context = new openerp.web.CompoundContext(); - _.each(v_contexts, function(x) {v_context.add(x);}); - if (_.detect(v_contexts, function(x) {return !!x.__ref;}) || true) { //TODO: remove true + // only use the model's context if there is not context on the node + var v_context = this.node.attrs.context; + if (! v_context) { + v_context = (this.field || {}).context || {}; + } + + if (v_context.__ref || true) { //TODO: remove true var fields_values = this._build_eval_context(blacklist); - v_context.set_eval_context(fields_values); + v_context = new openerp.web.CompoundContext(v_context).set_eval_context(fields_values); } - // if there is a context on the node, overrides the model's context - var ctx = v_contexts.length > 0 ? v_context : f_context; - return ctx; + return v_context; }, build_domain: function() { var f_domain = this.field.domain || []; @@ -1705,16 +1694,13 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({ openerp.web.form.dialog = function(content, options) { options = _.extend({ - autoOpen: true, width: '90%', - height: '90%', - min_width: '800px', - min_height: '600px' + height: 'auto', + min_width: '800px' }, options || {}); options.autoOpen = true; - var dialog = new openerp.web.Dialog(null, options); - dialog.$element = $(content).dialog(dialog.dialog_options); - return dialog.$element; + var dialog = new openerp.web.Dialog(null, options).open(); + return dialog.$element.html(content); }; openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({ @@ -2303,6 +2289,9 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({ this.viewmanager.views[this.viewmanager.active_view].controller) { var view = this.viewmanager.views[this.viewmanager.active_view].controller; if (this.viewmanager.active_view === "form") { + if (!view.is_initialized.isResolved()) { + return false; + } var res = $.when(view.do_save()); if (!res.isResolved() && !res.isRejected()) { console.warn("Asynchronous get_value() is not supported in form view."); @@ -2750,7 +2739,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope var $nbutton = $buttons.find(".oe_selectcreatepopup-form-save-new"); $nbutton.click(function() { $.when(self.view_form.do_save()).then(function() { - self.view_form.reload_lock.then(function() { + self.view_form.reload_mutex.exec(function() { self.view_form.on_button_new(); }); }); @@ -2758,7 +2747,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope var $nbutton = $buttons.find(".oe_selectcreatepopup-form-save"); $nbutton.click(function() { $.when(self.view_form.do_save()).then(function() { - self.view_form.reload_lock.then(function() { + self.view_form.reload_mutex.exec(function() { self.check_exit(); }); }); @@ -3020,7 +3009,7 @@ openerp.web.form.FieldBinary = openerp.web.form.Field.extend({ on_save_as: function() { var url = '/web/binary/saveas?session_id=' + this.session.session_id + '&model=' + this.view.dataset.model +'&id=' + (this.view.datarecord.id || '') + '&field=' + this.name + - '&fieldname=' + (this.node.attrs.filename || '') + '&t=' + (new Date().getTime()); + '&filename_field=' + (this.node.attrs.filename || '') + '&t=' + (new Date().getTime()); window.open(url); }, on_clear: function() { diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 2ab1152a0fa..2615ea297d0 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -685,6 +685,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView# this.display_aggregates(aggregates); }, display_aggregates: function (aggregation) { + var self = this; var $footer_cells = this.$element.find('.oe-list-footer'); _(this.aggregate_columns).each(function (column) { if (!column['function']) { @@ -692,7 +693,9 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView# } $footer_cells.filter(_.str.sprintf('[data-field=%s]', column.id)) - .html(openerp.web.format_cell(aggregation, column, undefined, false)); + .html(openerp.web.format_cell(aggregation, column, { + process_modifiers: false + })); }); }, get_selected_ids: function() { @@ -846,6 +849,9 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis return self.reload_record(self.records.get(record_id)); }]); }) + .delegate('a', 'click', function (e) { + e.stopPropagation(); + }) .delegate('tr', 'click', function (e) { e.stopPropagation(); var row_id = self.row_id(e.currentTarget); @@ -905,7 +911,10 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis }); } } - return openerp.web.format_cell(record.toForm().data, column); + return openerp.web.format_cell(record.toForm().data, column, { + model: this.dataset.model, + id: record.get('id') + }); }, render: function () { if (this.$current) { @@ -1211,7 +1220,10 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L return column.id === group.grouped_on; }); try { $group_column.html(openerp.web.format_cell( - row_data, group_column, _t("Undefined"), false)); + row_data, group_column, { + value_if_empty: _t("Undefined"), + process_modifiers: false + })); } catch (e) { $group_column.html(row_data[group_column.id].value); } @@ -1232,6 +1244,9 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L if (self.options.selectable) { $row.append('<td>'); } + if (self.options.isClarkGable) { + $row.append('<td>'); + } _(self.columns).chain() .filter(function (column) {return !column.invisible;}) .each(function (column) { @@ -1286,7 +1301,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L page = this.datagroup.openable ? this.page : view.page; var fields = _.pluck(_.select(this.columns, function(x) {return x.tag == "field"}), 'name'); - var options = { offset: page * limit, limit: limit }; + var options = { offset: page * limit, limit: limit, context: {bin_size: true} }; //TODO xmo: investigate why we need to put the setTimeout $.async_when().then(function() {dataset.read_slice(fields, options , function (records) { // FIXME: ignominious hacks, parents (aka form view) should not send two ListView#reload_content concurrently diff --git a/addons/web/static/src/js/view_page.js b/addons/web/static/src/js/view_page.js index 6ac5bc9f72b..d3ee79effca 100644 --- a/addons/web/static/src/js/view_page.js +++ b/addons/web/static/src/js/view_page.js @@ -208,6 +208,12 @@ openerp.web.page = function (openerp) { openerp.web.page.FieldOne2ManyReadonly = openerp.web.form.FieldOne2Many.extend({ force_readonly: true }); + openerp.web.page.FieldBinaryImageReaonly = openerp.web.form.FieldBinaryImage.extend({ + update_dom: function() { + this._super.apply(this, arguments); + this.$element.find('.oe-binary').hide(); + } + }); openerp.web.page.FieldBinaryFileReadonly = openerp.web.form.FieldBinary.extend({ template: 'FieldURI.readonly', start: function() { @@ -249,5 +255,6 @@ openerp.web.page = function (openerp) { 'integer': 'openerp.web.page.FieldCharReadonly', 'float_time': 'openerp.web.page.FieldCharReadonly', 'binary': 'openerp.web.page.FieldBinaryFileReadonly', + 'image': 'openerp.web.page.FieldBinaryImageReaonly' }); }; diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 6a70be5696f..18119650262 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -109,7 +109,8 @@ session.web.ActionManager = session.web.Widget.extend({ search_view : !popup, action_buttons : !popup, sidebar : !popup, - pager : !popup + pager : !popup, + display_title : !popup }, action.flags || {}); if (!(type in this)) { console.error("Action manager can't handle action of type " + action.type, action); @@ -133,13 +134,14 @@ session.web.ActionManager = session.web.Widget.extend({ } if (action.target === 'new') { if (this.dialog == null) { - this.dialog = new session.web.Dialog(this, { title: action.name, width: '80%' }); + this.dialog = new session.web.Dialog(this, { width: '80%' }); if(on_close) this.dialog.on_close.add(on_close); this.dialog.start(); } else { this.dialog_viewmanager.stop(); } + this.dialog.dialog_title = action.name; this.dialog_viewmanager = new session.web.ViewManagerAction(this, action); this.dialog_viewmanager.appendTo(this.dialog.$element); this.dialog.open(); @@ -355,9 +357,12 @@ session.web.ViewManager = session.web.Widget.extend(/** @lends session.web.View on_prev_view: function (created) { var current_view = this.views_history.pop(); var previous_view = this.views_history[this.views_history.length - 1]; - // APR special case: "If creation mode from list (and only from a list), - // after saving, go to page view (don't come back in list)" if (created && current_view === 'form' && previous_view === 'list') { + // APR special case: "If creation mode from list (and only from a list), + // after saving, go to page view (don't come back in list)" + return this.on_mode_switch('page'); + } else if (created && !previous_view && this.action && this.action.flags.default_view === 'form') { + // APR special case: "If creation from dashboard, we have no previous view return this.on_mode_switch('page'); } return this.on_mode_switch(previous_view, true); @@ -538,41 +543,45 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner return manager_ready; }, on_debug_changed: function (evt) { - var $sel = $(evt.currentTarget), + var self = this, + $sel = $(evt.currentTarget), $option = $sel.find('option:selected'), - val = $sel.val(); + val = $sel.val(), + current_view = this.views[this.active_view].controller; switch (val) { case 'fvg': - $('<pre>').text(session.web.json_node_to_xml( - this.views[this.active_view].controller.fields_view.arch, true) - ).dialog({ width: '95%'}); + var dialog = new session.web.Dialog(this, { title: "Fields View Get", width: '95%' }).open(); + $('<pre>').text(session.web.json_node_to_xml(current_view.fields_view.arch, true)).appendTo(dialog.$element); break; - case 'edit': - var model = $option.data('model'), - id = $option.data('id'), - domain = $option.data('domain'), - action = { - res_model : model, - type : 'ir.actions.act_window', - view_type : 'form', - view_mode : 'form', - target : 'new', - flags : { - action_buttons : true, - form : { - resize_textareas : true - } - } - }; - if (id) { - action.res_id = id, - action.views = [[false, 'form']]; - } else if (domain) { - action.views = [[false, 'list'], [false, 'form']]; - action.domain = domain; - action.flags.views_switcher = true; + case 'customize_object': + this.rpc('/web/dataset/search_read', { + model: 'ir.model', + fields: ['id'], + domain: [['model', '=', this.dataset.model]] + }, function (result) { + self.do_edit_resource('ir.model', result.ids[0], { name : "Customize Object" }); + }); + break; + case 'manage_views': + if (current_view.fields_view && current_view.fields_view.arch) { + var view_editor = new session.web.ViewEditor(current_view, current_view.$element, this.dataset, current_view.fields_view.arch); + view_editor.start(); + } else { + this.do_warn("Manage Views", "Could not find current view declaration"); } - this.do_action(action); + break; + case 'edit_workflow': + return this.do_action({ + res_model : 'workflow', + domain : [['osv', '=', this.dataset.model]], + views: [[false, 'list'], [false, 'form'], [false, 'diagram']], + type : 'ir.actions.act_window', + view_type : 'list', + view_mode : 'list' + }); + break; + case 'edit': + this.do_edit_resource($option.data('model'), $option.data('id'), { name : $option.text() }); break; default: if (val) { @@ -581,6 +590,24 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner } evt.currentTarget.selectedIndex = 0; }, + do_edit_resource: function(model, id, action) { + var action = _.extend({ + res_model : model, + res_id : id, + type : 'ir.actions.act_window', + view_type : 'form', + view_mode : 'form', + views : [[false, 'form']], + target : 'new', + flags : { + action_buttons : true, + form : { + resize_textareas : true + } + } + }, action || {}); + this.do_action(action); + }, on_mode_switch: function (view_type, no_store) { var self = this; @@ -728,26 +755,11 @@ session.web.Sidebar = session.web.Widget.extend({ action = view_manager.action; if (this.session.uid === 1) { this.add_section(_t('Customize'), 'customize'); - this.add_items('customize', [ - { - label: _t("Manage Views"), - callback: view.on_sidebar_manage_views, - title: _t("Manage views of the current object") - }, { - label: _t("Edit Workflow"), - callback: view.on_sidebar_edit_workflow, - title: _t("Manage views of the current object"), - classname: 'oe_sidebar_edit_workflow' - }, { - label: _t("Customize Object"), - callback: view.on_sidebar_customize_object, - title: _t("Manage views of the current object") - }, { - label: _t("Translate"), - callback: view.on_sidebar_translate, - title: _t("Technical translation") - } - ]); + this.add_items('customize', [{ + label: _t("Translate"), + callback: view.on_sidebar_translate, + title: _t("Technical translation") + }]); } this.add_section(_t('Other Options'), 'other'); @@ -1131,34 +1143,6 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{ set_common_sidebar_sections: function(sidebar) { sidebar.add_default_sections(); }, - on_sidebar_manage_views: function() { - if (this.fields_view && this.fields_view.arch) { - var view_editor = new session.web.ViewEditor(this, this.$element, this.dataset, this.fields_view.arch); - view_editor.start(); - } else { - this.do_warn("Manage Views", "Could not find current view declaration"); - } - }, - on_sidebar_edit_workflow: function() { - return this.do_action({ - res_model : 'workflow', - domain : [['osv', '=', this.dataset.model]], - views: [[false, 'list'], [false, 'form']], - type : 'ir.actions.act_window', - view_type : "list", - view_mode : "list" - }); - }, - on_sidebar_customize_object: function() { - var self = this; - this.rpc('/web/dataset/search_read', { - model: 'ir.model', - fields: ['id'], - domain: [['model', '=', self.dataset.model]] - }, function (result) { - self.on_sidebar_edit_resource('ir.model', result.ids[0]); - }); - }, on_sidebar_import: function() { var import_view = new session.web.DataImport(this, this.dataset); import_view.start(); @@ -1177,27 +1161,6 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{ view_mode : "list" }); }, - on_sidebar_edit_resource: function(model, id, domain) { - var action = { - res_model : model, - type : 'ir.actions.act_window', - view_type : 'form', - view_mode : 'form', - target : 'new', - flags : { - action_buttons : true - } - } - if (id) { - action.res_id = id, - action.views = [[false, 'form']]; - } else if (domain) { - action.views = [[false, 'list'], [false, 'form']]; - action.domain = domain; - action.flags.views_switcher = true; - } - this.do_action(action); - }, on_sidebar_view_log: function() { }, sidebar_context: function () { diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 7238124ef49..642f1f89709 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -470,10 +470,15 @@ </t> <t t-name="ViewManagerDebug"> <option value="">Debug View#<t t-esc="view.fields_view.view_id"/></option> - <option value="fvg"> - Fields View Get</option> - <option value="edit" data-model="ir.ui.view" t-att-data-id="view.fields_view.view_id"> - Edit <t t-esc="_.str.capitalize(view.fields_view.type)"/>View</option> - <option t-if="view_manager.searchview" value="edit" data-model="ir.ui.view" t-att-data-id="view_manager.searchview.view_id"> - Edit SearchView</option> - <option t-if="view_manager.action" value="edit" t-att-data-model="view_manager.action.type" t-att-data-id="view_manager.action.id"> - Edit Action</option> + <option value="fvg">Fields View Get</option> + <t t-if="view_manager.session.uid === 1"> + <option value="manage_views">Manage Views</option> + <option value="edit" data-model="ir.ui.view" t-att-data-id="view.fields_view.view_id">Edit <t t-esc="_.str.capitalize(view.fields_view.type)"/>View</option> + <option t-if="view_manager.searchview" value="edit" data-model="ir.ui.view" t-att-data-id="view_manager.searchview.view_id">Edit SearchView</option> + <option t-if="view_manager.action" value="edit" t-att-data-model="view_manager.action.type" t-att-data-id="view_manager.action.id">Edit Action</option> + <option value="customize_object">Customize Object</option> + <option value="edit_workflow">Edit Workflow</option> + </t> </t> <t t-extend="ViewManager" t-name="One2Many.viewmanager"> <t t-jquery="span.oe_view_title_text" t-operation="replace"/> @@ -743,7 +748,7 @@ <li t-foreach="attachments" t-as="attachment"> <t t-if="attachment.type == 'binary'" t-set="attachment.url" t-value="_s + '/web/binary/saveas?session_id=' + session.session_id + '&model=ir.attachment&id=' + attachment.id - + '&field=datas&fieldname=name&t=' + (new Date().getTime())"/> + + '&field=datas&filename_field=name&t=' + (new Date().getTime())"/> <a class="oe-sidebar-attachments-link" t-att-href="attachment.url" target="_blank"> <t t-esc="attachment.name"/> </a> |
