diff options
| author | sma (Tiny) <sma@tinyerp.com> | 2011-08-31 16:09:21 +0530 |
|---|---|---|
| committer | sma (Tiny) <sma@tinyerp.com> | 2011-08-31 16:09:21 +0530 |
| commit | fde5d6a1486ea9843d54b72ae2f31cd2bea18a59 (patch) | |
| tree | 15958b2d1f7f7c04a88077c23d305aaa214c1831 /addons/base/static/src | |
| parent | e629395daa3bd050f075a6012619d7c61ce0d801 (diff) | |
| parent | 5b8ad8068bac7f124071249899e91822f11f194f (diff) | |
[MERGE]
bzr revid: sma@tinyerp.com-20110831103921-fdpmikied597o2kk
Diffstat (limited to 'addons/base/static/src')
| -rw-r--r-- | addons/base/static/src/css/base.css | 20 | ||||
| -rw-r--r-- | addons/base/static/src/js/boot.js | 4 | ||||
| -rw-r--r-- | addons/base/static/src/js/chrome.js | 49 | ||||
| -rw-r--r-- | addons/base/static/src/js/core.js | 4 | ||||
| -rw-r--r-- | addons/base/static/src/js/data.js | 15 | ||||
| -rw-r--r-- | addons/base/static/src/js/form.js | 227 | ||||
| -rw-r--r-- | addons/base/static/src/js/formats.js | 30 | ||||
| -rw-r--r-- | addons/base/static/src/js/list.js | 59 | ||||
| -rw-r--r-- | addons/base/static/src/js/search.js | 2 | ||||
| -rw-r--r-- | addons/base/static/src/js/views.js | 123 | ||||
| -rw-r--r-- | addons/base/static/src/xml/base.xml | 43 |
11 files changed, 348 insertions, 228 deletions
diff --git a/addons/base/static/src/css/base.css b/addons/base/static/src/css/base.css index cd420ea8c0d..4133a9c8623 100644 --- a/addons/base/static/src/css/base.css +++ b/addons/base/static/src/css/base.css @@ -597,13 +597,13 @@ label.error { background-color: #ccc; } .openerp .searchview_group.folded .searchview_group_string { - background: url("../img/ui/group-folded.png") no-repeat scroll 0 50%; + background: url("/base/static/src/img/ui/group-folded.png") no-repeat scroll 0 50%; } .openerp .searchview_group.folded .searchview_group_content { display: none; } .openerp .searchview_group.expanded .searchview_group_string { - background: url("../img/ui/group-expanded.png") no-repeat scroll 0 50%; + background: url("/base/static/src/img/ui/group-expanded.png") no-repeat scroll 0 50%; } .openerp .searchview_group.expanded .searchview_group_content { display: block; @@ -635,13 +635,13 @@ label.error { } .openerp .oe_search-view-custom-filter-btn span { - background: url(../img/icons/gtk-add.png) repeat-y; + background: url(/base/static/src/img/icons/gtk-add.png) repeat-y; padding-left: 18px; } .openerp .searchview_extended_add_proposition span { font-size: 0.9em; - background: url(../img/icons/gtk-add.png) repeat-y; + background: url(/base/static/src/img/icons/gtk-add.png) repeat-y; padding-left: 18px; } @@ -657,7 +657,7 @@ label.error { .openerp .searchview_extended_delete_group span, .openerp .searchview_extended_delete_prop span { font-size: 0.9em; - background: url(../img/icons/gtk-close.png) repeat-y; + background: url(/base/static/src/img/icons/gtk-close.png) repeat-y; padding-left: 18px; } /* List */ @@ -870,6 +870,9 @@ label.error { .openerp .oe_forms input[type="text"], .openerp .oe_forms input[type="password"], .openerp .oe_forms select, .openerp .oe_forms .button { height: 22px; } +.openerp .oe_forms input.field_datetime { + min-width: 11em; +} .openerp .oe_forms .button { color: #4c4c4c; white-space: nowrap; @@ -892,6 +895,9 @@ label.error { position: relative; top: 4px; } +.openerp .oe_trad_field.touched { + border: 1px solid green !important; +} /* http://www.quirksmode.org/dom/inputfile.html * http://stackoverflow.com/questions/2855589/replace-input-type-file-by-an-image @@ -1085,7 +1091,7 @@ label.error { cursor: pointer; border: 1px solid #D2CFCF; display: block; - background: url(../img/toggle-a-bg.png); + background: url(/base/static/src/img/toggle-a-bg.png); width: 21px; height: 21px; z-index: 10; @@ -1100,7 +1106,7 @@ label.error { } .openerp li.oe_sidebar_print { padding-left: 20px; - background: 1px 3px url(../img/icons/gtk-print.png) no-repeat; + background: 1px 3px url(/base/static/src/img/icons/gtk-print.png) no-repeat; } .openerp.kitten-mode-activated .main_table { diff --git a/addons/base/static/src/js/boot.js b/addons/base/static/src/js/boot.js index 0dd8dcdc980..8fe62d2e5a4 100644 --- a/addons/base/static/src/js/boot.js +++ b/addons/base/static/src/js/boot.js @@ -50,7 +50,9 @@ openerp.base = function(instance) { openerp.base.core(instance); - openerp.base.dates(instance); + if (openerp.base.dates) { + openerp.base.dates(instance); + } openerp.base.formats(instance); openerp.base.chrome(instance); openerp.base.data(instance); diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index 954e2024965..720bc38d54a 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -479,8 +479,6 @@ openerp.base.Login = openerp.base.Widget.extend({ this.selected_login = localStorage.getItem('last_login_login_success'); } if (jQuery.deparam(jQuery.param.querystring()).debug != undefined) { - this.selected_db = this.selected_db || "trunk"; - this.selected_login = this.selected_login || "admin"; this.selected_password = this.selected_password || "a"; } }, @@ -564,22 +562,25 @@ openerp.base.Login = openerp.base.Widget.extend({ }); openerp.base.Header = openerp.base.Widget.extend({ - init: function(parent, element_id) { - this._super(parent, element_id); - if (jQuery.deparam(jQuery.param.querystring()).debug !== undefined) { - this.qs = '?debug' - } else { - this.qs = '' - } + template: "Header", + identifier_prefix: 'oe-app-header-', + init: function(parent) { + this._super(parent); + this.qs = "?" + jQuery.param.querystring(); + this.$content = $(); }, start: function() { - return this.do_update(); + this._super(); }, do_update: function () { - this.$element.html(QWeb.render("Header", this)); + this.$content = $(QWeb.render("Header-content", {widget: this})); + this.$content.appendTo(this.$element); this.$element.find(".logout").click(this.on_logout); return this.shortcut_load(); }, + do_reset: function() { + this.$content.remove(); + }, shortcut_load :function(){ var self = this, sc = self.session.shortcuts, @@ -590,22 +591,27 @@ openerp.base.Header = openerp.base.Widget.extend({ sc.binding = {}; $(sc.binding).bind({ 'add': function (e, attrs) { - var $shortcut = $('<li>', { + shortcuts_ds.create(attrs, function (out) { + $('<li>', { + 'data-shortcut-id':out.result, 'data-id': attrs.res_id }).text(attrs.name) - .appendTo(self.$element.find('.oe-shortcuts ul')); - shortcuts_ds.create(attrs, function (out) { - $shortcut.data('shortcut-id', out.result); + .appendTo(self.$element.find('.oe-shortcuts ul')); + attrs.id = out.result; + sc.push(attrs); }); }, 'remove-current': function () { var menu_id = self.session.active_id; var $shortcut = self.$element - .find('.oe-shortcuts li[data-id=' + menu_id + ']'); + .find('.oe-shortcuts li[data-id=' + menu_id + ']'); var shortcut_id = $shortcut.data('shortcut-id'); $shortcut.remove(); shortcuts_ds.unlink([shortcut_id]); - } + var sc_new = _.reject(sc, function(shortcut){ return shortcut_id === shortcut.id}); + sc.splice(0, sc.length); + sc.push.apply(sc, sc_new); + } }); } return this.rpc('/base/session/sc_list', {}, function(shortcuts) { @@ -615,6 +621,7 @@ openerp.base.Header = openerp.base.Widget.extend({ self.$element.find('.oe-shortcuts') .html(QWeb.render('Shortcuts', {'shortcuts': shortcuts})) .undelegate('li', 'click') + .delegate('li', 'click', function(e) { e.stopPropagation(); var id = $(this).data('id'); @@ -743,21 +750,23 @@ openerp.base.WebClient = openerp.base.Widget.extend({ // Do you autorize this ? will be replaced by notify() in controller openerp.base.Widget.prototype.notification = new openerp.base.Notification(this, "oe_notification"); - this.header = new openerp.base.Header(this, "oe_header"); + + this.header = new openerp.base.Header(this); this.login = new openerp.base.Login(this, "oe_login"); this.header.on_logout.add(this.login.on_logout); + this.header.on_action.add(this.on_menu_action); this.session.on_session_invalid.add(this.login.do_ask_login); this.session.on_session_valid.add_last(this.header.do_update); + this.session.on_session_invalid.add_last(this.header.do_reset); this.session.on_session_valid.add_last(this.on_logged); this.menu = new openerp.base.Menu(this, "oe_menu", "oe_secondary_menu"); this.menu.on_action.add(this.on_menu_action); - this.header.on_action.add(this.on_menu_action); }, start: function() { + this.header.appendTo($("#oe_header")); this.session.start(); - this.header.start(); this.login.start(); this.menu.start(); this.notification.notify("OpenERP Client", "The openerp client has been initialized."); diff --git a/addons/base/static/src/js/core.js b/addons/base/static/src/js/core.js index e872ced1f0d..4cd46504a69 100644 --- a/addons/base/static/src/js/core.js +++ b/addons/base/static/src/js/core.js @@ -567,8 +567,8 @@ openerp.base.Session = openerp.base.CallbackEnabled.extend( /** @lends openerp.b self.do_load_js(file_list.concat(files)); }); } else { - self.do_load_css(file_list.concat(["/base/webclient/css?mods="+modules])); - self.do_load_js(["/base/webclient/js?mods="+modules]); + self.do_load_css(["/base/webclient/css?mods="+modules]); + self.do_load_js(file_list.concat(["/base/webclient/js?mods="+modules])); } openerp._modules_loaded = true; }); diff --git a/addons/base/static/src/js/data.js b/addons/base/static/src/js/data.js index 04c23224806..e95adaf8870 100644 --- a/addons/base/static/src/js/data.js +++ b/addons/base/static/src/js/data.js @@ -355,12 +355,13 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data * @param {Function} error_callback function called in case of write error * @returns {$.Deferred} */ - write: function (id, data, callback, error_callback) { + write: function (id, data, options, callback, error_callback) { + var options = options || {}; return this.rpc('/base/dataset/save', { model: this.model, id: id, data: data, - context: this.get_context() + context: this.get_context(options.context) }, callback, error_callback); }, /** @@ -396,18 +397,18 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data * * @param {String} method * @param {Array} [args] - * @param {Number} [domain_id] index of a domain to evaluate in the args array - * @param {Number} [context_id] index of a context to evaluate in the args array + * @param {Number} [domain_index] index of a domain to evaluate in the args array + * @param {Number} [context_index] index of a context to evaluate in the args array * @param {Function} callback * @param {Function }error_callback * @returns {$.Deferred} */ - call_and_eval: function (method, args, domain_id, context_id, callback, error_callback) { + call_and_eval: function (method, args, domain_index, context_index, callback, error_callback) { return this.rpc('/base/dataset/call', { model: this.model, method: method, - domain_id: domain_id || null, - context_id: context_id || null, + domain_id: domain_index || null, + context_id: context_index || null, args: args || [] }, callback, error_callback); }, diff --git a/addons/base/static/src/js/form.js b/addons/base/static/src/js/form.js index 7a4d3c92d89..e2a99e9b8c5 100644 --- a/addons/base/static/src/js/form.js +++ b/addons/base/static/src/js/form.js @@ -157,6 +157,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormVi this.do_update_pager(record.id == null); if (this.sidebar) { this.sidebar.attachments.do_update(); + this.sidebar.$element.find('.oe_sidebar_translate').toggleClass('oe_hide', !record.id); } if (this.default_focus_field && !this.embedded_view) { this.default_focus_field.focus(); @@ -342,7 +343,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormVi self.on_created(r, success, prepend_on_create); }); } else { - return this.dataset.write(this.datarecord.id, values, function(r) { + return this.dataset.write(this.datarecord.id, values, {}, function(r) { self.on_saved(r, success); }); } @@ -441,6 +442,10 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormVi values[key] = val; }); return values; + }, + get_selected_ids: function() { + var id = this.dataset.ids[this.dataset.index]; + return id ? [id] : []; } }); @@ -875,6 +880,9 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({ }, update_dom: function() { this._super.apply(this, arguments); + if (this.field.translate) { + this.$element.find('.oe_field_translate').toggle(!!this.view.datarecord.id); + } if (!this.disable_utility_classes) { this.$element.toggleClass('disabled', this.readonly); this.$element.toggleClass('required', this.required); @@ -949,7 +957,7 @@ openerp.base.form.FieldChar = openerp.base.form.Field.extend({ }, set_value: function(value) { this._super.apply(this, arguments); - var show_value = (value != null && value !== false) ? value : ''; + var show_value = openerp.base.format_value(value, this, ''); this.$element.find('input').val(show_value); }, update_dom: function() { @@ -957,16 +965,16 @@ openerp.base.form.FieldChar = openerp.base.form.Field.extend({ this.$element.find('input').attr('disabled', this.readonly); }, set_value_from_ui: function() { - this.value = this.$element.find('input').val(); + this.value = openerp.base.parse_value(this.$element.find('input').val(), this); this._super(); }, validate: function() { this.invalid = false; - var value = this.$element.find('input').val(); - if (value === "") { - this.invalid = this.required; - } else if (this.validation_regex) { - this.invalid = !this.validation_regex.test(value); + try { + var value = openerp.base.parse_value(this.$element.find('input').val(), this, ''); + this.invalid = this.required && value === ''; + } catch(e) { + this.invalid = true; } }, focus: function() { @@ -978,7 +986,6 @@ openerp.base.form.FieldEmail = openerp.base.form.FieldChar.extend({ init: function(view, node) { this._super(view, node); this.template = "FieldEmail"; - this.validation_regex = /@/; }, start: function() { this._super.apply(this, arguments); @@ -993,8 +1000,7 @@ openerp.base.form.FieldEmail = openerp.base.form.FieldChar.extend({ }, set_value: function(value) { this._super.apply(this, arguments); - var show_value = (value != null && value !== false) ? value : ''; - this.$element.find('a').attr('href', 'mailto:' + show_value); + this.$element.find('a').attr('href', 'mailto:' + this.$element.find('input').val()); } }); @@ -1017,44 +1023,13 @@ openerp.base.form.FieldUrl = openerp.base.form.FieldChar.extend({ }); openerp.base.form.FieldFloat = openerp.base.form.FieldChar.extend({ - init: function(view, node) { - this._super(view, node); - this.validation_regex = /^-?\d+(\.\d+)?$/; - }, set_value: function(value) { - this._super.apply(this, [value]); if (value === false || value === undefined) { // As in GTK client, floats default to 0 value = 0; this.dirty = true; } - var show_value = value.toFixed(2); - this.$element.find('input').val(show_value); - }, - set_value_from_ui: function() { - this.value = Number(this.$element.find('input').val().replace(/,/g, '.')); - this._super(); - } -}); - -openerp.base.form.FieldInteger = openerp.base.form.FieldFloat.extend({ - init: function(view, node) { - this._super(view, node); - this.validation_regex = /^-?\d+$/; - }, - set_value: function(value) { this._super.apply(this, [value]); - if (value === false || value === undefined) { - // TODO fme: check if GTK client default integers to 0 (like it does with floats) - value = 0; - this.dirty = true; - } - var show_value = parseInt(value, 10); - this.$element.find('input').val(show_value); - }, - set_value_from_ui: function() { - this.value = Number(this.$element.find('input').val()); - this._super(); } }); @@ -1063,7 +1038,6 @@ openerp.base.form.FieldDatetime = openerp.base.form.Field.extend({ this._super(view, node); this.template = "FieldDate"; this.jqueryui_object = 'datetimepicker'; - this.validation_regex = /^\d+-\d+-\d+( \d+:\d+(:\d+)?)?$/; }, start: function() { this._super.apply(this, arguments); @@ -1103,8 +1077,6 @@ openerp.base.form.FieldDatetime = openerp.base.form.Field.extend({ var value = this.$element.find('input').val(); if (value === "") { this.invalid = this.required; - } else if (this.validation_regex) { - this.invalid = !this.validation_regex.test(value); } else { this.invalid = !this.$element.find('input')[this.jqueryui_object]('getDate'); } @@ -1120,39 +1092,15 @@ openerp.base.form.FieldDate = openerp.base.form.FieldDatetime.extend({ init: function(view, node) { this._super(view, node); this.jqueryui_object = 'datepicker'; - this.validation_regex = /^\d+-\d+-\d+$/; }, parse: openerp.base.str_to_date, format: openerp.base.date_to_str }); -openerp.base.form.FieldFloatTime = openerp.base.form.FieldChar.extend({ - init: function(view, node) { - this._super(view, node); - this.validation_regex = /^\d+:\d+$/; - }, - set_value: function(value) { - this._super.apply(this, [value]); - if (value === false || value === undefined) { - // As in GTK client, floats default to 0 - value = 0; - this.dirty = true; - } - var show_value = _.sprintf("%02d:%02d", Math.floor(value), Math.round((value % 1) * 60)); - this.$element.find('input').val(show_value); - }, - set_value_from_ui: function() { - var time = this.$element.find('input').val().split(':'); - this.set_value(parseInt(time[0], 10) + parseInt(time[1], 10) / 60); - this._super(); - } -}); - openerp.base.form.FieldText = openerp.base.form.Field.extend({ init: function(view, node) { this._super(view, node); this.template = "FieldText"; - this.validation_regex = null; }, start: function() { this._super.apply(this, arguments); @@ -1160,7 +1108,7 @@ openerp.base.form.FieldText = openerp.base.form.Field.extend({ }, set_value: function(value) { this._super.apply(this, arguments); - var show_value = (value != null && value !== false) ? value : ''; + var show_value = openerp.base.format_value(value, this, ''); this.$element.find('textarea').val(show_value); }, update_dom: function() { @@ -1168,16 +1116,16 @@ openerp.base.form.FieldText = openerp.base.form.Field.extend({ this.$element.find('textarea').attr('disabled', this.readonly); }, set_value_from_ui: function() { - this.value = this.$element.find('textarea').val(); + this.value = openerp.base.parse_value(this.$element.find('textarea').val(), this); this._super(); }, validate: function() { this.invalid = false; - var value = this.$element.find('textarea').val(); - if (value === "") { - this.invalid = this.required; - } else if (this.validation_regex) { - this.invalid = !this.validation_regex.test(value); + try { + var value = openerp.base.parse_value(this.$element.find('textarea').val(), this, ''); + this.invalid = this.required && value === ''; + } catch(e) { + this.invalid = true; } }, focus: function() { @@ -1366,36 +1314,56 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({ this.$input = this.$element.find("input"); this.$drop_down = this.$element.find(".oe-m2o-drop-down-button"); this.$menu_btn = this.$element.find(".oe-m2o-cm-button"); - + // context menu - var bindings = {}; - bindings[this.cm_id + "_search"] = function() { - self._search_create_popup("search"); - }; - bindings[this.cm_id + "_create"] = function() { - self._search_create_popup("form"); - }; - bindings[this.cm_id + "_open"] = function() { - if (!self.value) { - return; - } - var pop = new openerp.base.form.FormOpenPopup(self.view); - pop.show_element(self.field.relation, self.value[0],self.build_context(), {}); - pop.on_write_completed.add_last(function() { - self.set_value(self.value[0]); + var init_context_menu_def = $.Deferred().then(function(e) { + var rdataset = new openerp.base.DataSetStatic(self, "ir.values", self.build_context()); + rdataset.call("get", ['action', 'client_action_relate', + [[self.field.relation, false]], false, rdataset.get_context()], false, 0) + .then(function(result) { + self.related_entries = result; + + var $cmenu = $("#" + self.cm_id); + $cmenu.append(QWeb.render("FieldMany2One.context_menu", {widget: self})); + var bindings = {}; + bindings[self.cm_id + "_search"] = function() { + self._search_create_popup("search"); + }; + bindings[self.cm_id + "_create"] = function() { + self._search_create_popup("form"); + }; + bindings[self.cm_id + "_open"] = function() { + if (!self.value) { + return; + } + var pop = new openerp.base.form.FormOpenPopup(self.view); + pop.show_element(self.field.relation, self.value[0],self.build_context(), {}); + pop.on_write_completed.add_last(function() { + self.set_value(self.value[0]); + }); + }; + _.each(_.range(self.related_entries.length), function(i) { + bindings[self.cm_id + "_related_" + i] = function() { + self.open_related(self.related_entries[i]); + }; + }); + var cmenu = self.$menu_btn.contextMenu(self.cm_id, {'leftClickToo': true, + bindings: bindings, itemStyle: {"color": ""}, + onContextMenu: function() { + if(self.value) { + $("#" + self.cm_id + " .oe_m2o_menu_item_mandatory").removeClass("oe-m2o-disabled-cm"); + } else { + $("#" + self.cm_id + " .oe_m2o_menu_item_mandatory").addClass("oe-m2o-disabled-cm"); + } + return true; + }, menuStyle: {width: "200px"} + }); + setTimeout(function() {self.$menu_btn.trigger(e);}, 0); }); - }; - var cmenu = this.$menu_btn.contextMenu(this.cm_id, {'leftClickToo': true, - bindings: bindings, itemStyle: {"color": ""}, - onContextMenu: function() { - if(self.value) { - $("#" + self.cm_id + "_open").removeClass("oe-m2o-disabled-cm"); - } else { - $("#" + self.cm_id + "_open").addClass("oe-m2o-disabled-cm"); - } - return true; - } }); + var ctx_callback = function(e) {init_context_menu_def.resolve(e); e.preventDefault()}; + this.$menu_btn.bind('contextmenu', ctx_callback); + this.$menu_btn.click(ctx_callback); // some behavior for input this.$input.keyup(function() { @@ -1555,12 +1523,14 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({ }, set_value: function(value) { value = value || null; + this.invalid = false; var self = this; - var _super = this._super; this.tmp_value = value; + self.update_dom(); + self.on_value_changed(); var real_set_value = function(rval) { self.tmp_value = undefined; - _super.apply(self, rval); + self.value = rval; self.original_value = undefined; self._change_int_ext_value(rval); }; @@ -1586,9 +1556,27 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({ }, validate: function() { this.invalid = false; - if (this.value === null) { + var val = this.tmp_value !== undefined ? this.tmp_value : this.value; + if (val === null) { this.invalid = this.required; } + }, + open_related: function(related) { + var self = this; + if (!self.value) + return; + var additional_context = { + active_id: self.value[0], + active_ids: [self.value[0]], + active_model: self.field.relation + }; + self.rpc("/base/action/load", { + action_id: related[2].id, + context: additional_context + }, function(result) { + result.result.context = _.extend(result.result.context || {}, additional_context); + self.do_action(result.result); + }); } }); @@ -1884,10 +1872,13 @@ openerp.base.form.One2ManyListView = openerp.base.ListView.extend({ pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(),{ auto_write: false, alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined, - parent_view: self.o2m.view + parent_view: self.o2m.view, + read_function: function() { + return self.o2m.dataset.read_ids.apply(self.o2m.dataset, arguments); + } }); pop.on_write.add(function(id, data) { - self.o2m.dataset.write(id, data, function(r) { + self.o2m.dataset.write(id, data, {}, function(r) { self.o2m.reload_current_view(); }); }); @@ -2156,6 +2147,7 @@ openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({ * options: * - alternative_form_view * - auto_write (default true) + * - read_function * - parent_view */ show_element: function(model, row_id, context, options) { @@ -2171,7 +2163,8 @@ openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({ }, start: function() { this._super(); - this.dataset = new openerp.base.ReadOnlyDataSetSearch(this, this.model, this.context); + this.dataset = new openerp.base.form.FormOpenDataset(this, this.model, this.context); + this.dataset.fop = this; this.dataset.ids = [this.row_id]; this.dataset.index = 0; this.dataset.parent_view = this.options.parent_view; @@ -2184,7 +2177,7 @@ openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({ var self = this; var wdataset = new openerp.base.DataSetSearch(this, this.model, this.context, this.domain); wdataset.parent_view = this.options.parent_view; - wdataset.write(id, data, function(r) { + wdataset.write(id, data, {}, function(r) { self.on_write_completed(); }); }, @@ -2213,6 +2206,16 @@ openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({ } }); +openerp.base.form.FormOpenDataset = openerp.base.ReadOnlyDataSetSearch.extend({ + read_ids: function() { + if (this.fop.options.read_function) { + return this.fop.options.read_function.apply(null, arguments); + } else { + return this._super.apply(this, arguments); + } + } +}); + openerp.base.form.FieldReference = openerp.base.form.Field.extend({ init: function(view, node) { this._super(view, node); @@ -2440,9 +2443,9 @@ openerp.base.form.widgets = new openerp.base.Registry({ 'reference' : 'openerp.base.form.FieldReference', 'boolean' : 'openerp.base.form.FieldBoolean', 'float' : 'openerp.base.form.FieldFloat', - 'integer': 'openerp.base.form.FieldInteger', + 'integer': 'openerp.base.form.FieldFloat', + 'float_time': 'openerp.base.form.FieldFloat', 'progressbar': 'openerp.base.form.FieldProgressBar', - 'float_time': 'openerp.base.form.FieldFloatTime', 'image': 'openerp.base.form.FieldBinaryImage', 'binary': 'openerp.base.form.FieldBinaryFile' }); diff --git a/addons/base/static/src/js/formats.js b/addons/base/static/src/js/formats.js index c141aad908c..bf54290bf45 100644 --- a/addons/base/static/src/js/formats.js +++ b/addons/base/static/src/js/formats.js @@ -28,8 +28,10 @@ openerp.base.format_value = function (value, descriptor, value_if_empty) { case 'float': var precision = descriptor.digits ? descriptor.digits[1] : 2; var int_part = Math.floor(value); - var dec_part = Math.floor((value % 1) * Math.pow(10, precision)); - return _.sprintf('%d' + openerp.base._t.database.parameters.decimal_point + '%d', int_part, dec_part); + var dec_part = Math.abs(Math.floor((value % 1) * Math.pow(10, precision))); + return _.sprintf('%d%s%d', + int_part, + openerp.base._t.database.parameters.decimal_point, dec_part); case 'float_time': return _.sprintf("%02d:%02d", Math.floor(value), @@ -45,8 +47,8 @@ openerp.base.format_value = function (value, descriptor, value_if_empty) { if (typeof(value) == "string") value = openerp.base.str_to_datetime(value); try { - return value.format(_.sprintf("%s %s", openerp.base._t.database.parameters.date_format, - openerp.base._t.database.parameters.time_format)); + return value.toString(_.sprintf("%s %s", Date.CultureInfo.formatPatterns.shortDate, + Date.CultureInfo.formatPatterns.longTime)); } catch (e) { return value.format("%m/%d/%Y %H:%M:%S"); } @@ -55,7 +57,7 @@ openerp.base.format_value = function (value, descriptor, value_if_empty) { if (typeof(value) == "string") value = openerp.base.str_to_date(value); try { - return value.format(openerp.base._t.database.parameters.date_format); + return value.toString(Date.CultureInfo.formatPatterns.shortDate); } catch (e) { return value.format("%m/%d/%Y"); } @@ -63,7 +65,7 @@ openerp.base.format_value = function (value, descriptor, value_if_empty) { if (typeof(value) == "string") value = openerp.base.str_to_time(value); try { - return value.format(openerp.base._t.database.parameters.time_format); + return value.toString(Date.CultureInfo.formatPatterns.longTime); } catch (e) { return value.format("%H:%M:%S"); } @@ -108,17 +110,27 @@ openerp.base.parse_value = function (value, descriptor, value_if_empty) { case 'progressbar': return openerp.base.parse_value(value, {type: "float"}); case 'datetime': - var tmp = Date.parse(value); + var tmp = Date.parseExact(value, _.sprintf("%s %s", Date.CultureInfo.formatPatterns.shortDate, + Date.CultureInfo.formatPatterns.longTime)); + if (tmp !== null) + return tmp; + tmp = Date.parse(value); if (tmp !== null) return tmp; throw value + " is not a valid datetime"; case 'date': - var tmp = Date.parse(value); + var tmp = Date.parseExact(value, Date.CultureInfo.formatPatterns.shortDate); + if (tmp !== null) + return tmp; + tmp = Date.parse(value); if (tmp !== null) return tmp; throw value + " is not a valid date"; case 'time': - var tmp = Date.parse(value); + var tmp = Date.parseExact(value, Date.CultureInfo.formatPatterns.longTime); + if (tmp !== null) + return tmp; + tmp = Date.parse(value); if (tmp !== null) return tmp; throw value + " is not a valid time"; diff --git a/addons/base/static/src/js/list.js b/addons/base/static/src/js/list.js index 9797b5dff99..786c8cb2068 100644 --- a/addons/base/static/src/js/list.js +++ b/addons/base/static/src/js/list.js @@ -365,7 +365,6 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi reload_view: function (grouped, context, initial) { var self = this; var callback = function (field_view_get) { - console.log('loaded', initial ? 'initial' : 'subsequent'); self.on_loaded(field_view_get, grouped); }; if (this.embedded_view) { @@ -383,10 +382,19 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi * re-renders the content of the list view */ reload_content: function () { + var self = this; this.records.reset(); this.$element.find('.oe-listview-content').append( - this.groups.render( - $.proxy(this, 'compute_aggregates'))); + this.groups.render(function () { + if (self.dataset.index == null) { + var has_one = false; + self.records.each(function () { has_one = true; }); + if (has_one) { + self.dataset.index = 0; + } + } + self.compute_aggregates(); + })); }, /** * Event handler for a search, asks for the computation/folding of domains @@ -399,8 +407,8 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi */ do_search: function (domains, contexts, groupbys) { return this.rpc('/base/session/eval_domain_and_context', { - domains: domains, - contexts: contexts, + domains: [this.dataset.get_domain()].concat(domains), + contexts: [this.dataset.get_context()].concat(contexts), group_by_seq: groupbys }, $.proxy(this, 'do_actual_search')); }, @@ -589,8 +597,11 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi $footer_cells.filter(_.sprintf('[data-field=%s]', column.id)) .html(openerp.base.format_cell(aggregation, column)); }); + }, + get_selected_ids: function() { + var ids = this.groups.get_selection().ids; + return ids; } - // TODO: implement reorder (drag and drop rows) }); openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.ListView.List# */{ /** @@ -1040,25 +1051,25 @@ openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.bas var fields = _.pluck(_.select(this.columns, function(x) {return x.tag == "field"}), 'name'); var options = { offset: page * limit, limit: limit }; dataset.read_slice(fields, options , function (records) { - if (!self.datagroup.openable) { - view.configure_pager(dataset); - } else { - var pages = Math.ceil(dataset.ids.length / limit); - self.$row - .find('.oe-pager-state') - .text(_.sprintf('%d/%d', page + 1, pages)) - .end() - .find('button[data-pager-action=previous]') - .attr('disabled', page === 0) - .end() - .find('button[data-pager-action=next]') - .attr('disabled', page === pages - 1); - } + if (!self.datagroup.openable) { + view.configure_pager(dataset); + } else { + var pages = Math.ceil(dataset.ids.length / limit); + self.$row + .find('.oe-pager-state') + .text(_.sprintf('%d/%d', page + 1, pages)) + .end() + .find('button[data-pager-action=previous]') + .attr('disabled', page === 0) + .end() + .find('button[data-pager-action=next]') + .attr('disabled', page === pages - 1); + } - self.records.add(records, {silent: true}); - list.render(); - d.resolve(list); - }); + self.records.add(records, {silent: true}); + list.render(); + d.resolve(list); + }); return d.promise(); }, setup_resequence_rows: function (list, dataset) { diff --git a/addons/base/static/src/js/search.js b/addons/base/static/src/js/search.js index 99f07784160..e3d51e2b439 100644 --- a/addons/base/static/src/js/search.js +++ b/addons/base/static/src/js/search.js @@ -801,6 +801,8 @@ openerp.base.search.ManyToOneField = openerp.base.search.CharField.extend({ render: function (defaults) { if (defaults[this.attrs.name]) { this.id = defaults[this.attrs.name]; + if (this.id instanceof Array) + this.id = this.id[0]; // TODO: maybe this should not be completely removed delete defaults[this.attrs.name]; this.dataset.name_get([this.id], $.proxy(this, 'on_name_get')); diff --git a/addons/base/static/src/js/views.js b/addons/base/static/src/js/views.js index 7320d09d251..11b45cbfeb0 100644 --- a/addons/base/static/src/js/views.js +++ b/addons/base/static/src/js/views.js @@ -123,6 +123,14 @@ openerp.base.ActionManager = openerp.base.Widget.extend({ this.content_stop(); var ClientWidget = openerp.base.client_actions.get_object(action.tag); (this.client_widget = new ClientWidget(this, action.params)).appendTo(this); + }, + ir_actions_report_xml: function(action) { + this.rpc('/base/report/get_report', { + action: action, + context: {} + }).then(function(result) { + debugger; + }); } }); @@ -350,20 +358,22 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({ shortcut_add_remove: function() { var self = this; var $shortcut_toggle = this.$element.find('.oe-shortcut-toggle'); - $shortcut_toggle.click(function() { - if ($shortcut_toggle.hasClass("oe-shortcut-remove")) { - $(self.session.shortcuts.binding).trigger('remove-current'); - $shortcut_toggle.removeClass("oe-shortcut-remove"); - } else { - $(self.session.shortcuts.binding).trigger('add', { - 'user_id': self.session.uid, - 'res_id': self.session.active_id, - 'resource': 'ir.ui.menu', - 'name': self.action.name - }); - $shortcut_toggle.addClass("oe-shortcut-remove"); - } - }); + $shortcut_toggle + .unbind("click") + .click(function() { + if ($shortcut_toggle.hasClass("oe-shortcut-remove")) { + $(self.session.shortcuts.binding).trigger('remove-current'); + $shortcut_toggle.removeClass("oe-shortcut-remove"); + } else { + $(self.session.shortcuts.binding).trigger('add', { + 'user_id': self.session.uid, + 'res_id': self.session.active_id, + 'resource': 'ir.ui.menu', + 'name': self.action.name + }); + $shortcut_toggle.addClass("oe-shortcut-remove"); + } + }); } }); @@ -374,8 +384,8 @@ openerp.base.Sidebar = openerp.base.Widget.extend({ this.sections = {}; }, start: function() { + this._super(this); var self = this; - this._super(this, arguments); this.$element.html(QWeb.render('Sidebar')); this.$element.find(".toggle-sidebar").click(function(e) { self.do_toggle(); @@ -431,9 +441,26 @@ openerp.base.Sidebar = openerp.base.Widget.extend({ item.callback(); } if (item.action) { - item.action.flags = item.action.flags || {}; - item.action.flags.new_window = true; - self.do_action(item.action); + var ids = self.widget_parent.get_selected_ids(); + if (ids.length == 0) { + //TODO niv: maybe show a warning? + return false; + } + var additional_context = { + active_id: ids[0], + active_ids: ids, + active_model: self.widget_parent.dataset.model + }; + self.rpc("/base/action/load", { + action_id: item.action.id, + context: additional_context + }, function(result) { + result.result.context = _.extend(result.result.context || {}, + additional_context); + result.result.flags = result.result.flags || {}; + result.result.flags.new_window = true; + self.do_action(result.result); + }); } return false; }); @@ -456,6 +483,9 @@ openerp.base.Sidebar = openerp.base.Widget.extend({ openerp.base.TranslateDialog = openerp.base.Dialog.extend({ dialog_title: _t("Translations"), init: function(view) { + // TODO fme: should add the language to fields_view_get because between the fields view get + // and the moment the user opens the translation dialog, the user language could have been changed + this.view_language = view.session.user_context.lang; this['on_button' + _t("Save")] = this.on_button_Save; this['on_button' + _t("Close")] = this.on_button_Close; this._super(view, { @@ -484,6 +514,9 @@ openerp.base.TranslateDialog = openerp.base.Dialog.extend({ self.select_tab('view'); } self.$fields_form = self.$element.find('.oe_translation_form'); + self.$fields_form.find('.oe_trad_field').change(function() { + $(this).toggleClass('touched', ($(this).val() != $(this).attr('data-value'))); + }); }); return this; }, @@ -498,19 +531,27 @@ openerp.base.TranslateDialog = openerp.base.Dialog.extend({ _.each(self.languages, function(lg) { var deff = $.Deferred(); deffered.push(deff); - self.rpc('/base/dataset/get', { - model: self.view.dataset.model, - ids: [self.view.datarecord.id], - fields: self.translatable_fields_keys, - context: self.view.dataset.get_context({ - 'lang': lg.code - }) - }, function(values) { + var callback = function(values) { _.each(self.translatable_fields_keys, function(f) { - self.$fields_form.find('.oe_trad_field[name="' + lg.code + '-' + f + '"]').val(values[0][f] || ''); + self.$fields_form.find('.oe_trad_field[name="' + lg.code + '-' + f + '"]').val(values[0][f] || '').attr('data-value', values[0][f] || ''); }); deff.resolve(); - }); + } + if (lg.code === self.view_language) { + var values = {}; + _.each(self.translatable_fields_keys, function(field) { + values[field] = self.view.fields[field].get_value(); + }); + callback([values]); + } else { + self.rpc('/base/dataset/get', { + model: self.view.dataset.model, + ids: [self.view.datarecord.id], + fields: self.translatable_fields_keys, + context: self.view.dataset.get_context({ + 'lang': lg.code + })}, callback); + } }); $.when.apply(null, deffered).then(callback); }, @@ -531,21 +572,39 @@ openerp.base.TranslateDialog = openerp.base.Dialog.extend({ }, open: function(field) { var self = this, - super = this._super; + sup = this._super; $.when(this.languages_loaded).then(function() { if (self.view.translatable_fields && self.view.translatable_fields.length) { self.do_load_fields_values(function() { - super.call(self); + sup.call(self); if (field) { // TODO: focus and scroll to field } }); } else { - super.call(self); + sup.call(self); } }); }, on_button_Save: function() { + var trads = {}, + self = this; + self.$fields_form.find('.oe_trad_field.touched').each(function() { + var field = $(this).attr('name').split('-'); + if (!trads[field[0]]) { + trads[field[0]] = {}; + } + trads[field[0]][field[1]] = $(this).val(); + }); + _.each(trads, function(data, code) { + if (code === self.view_language) { + _.each(data, function(value, field) { + self.view.fields[field].set_value(value); + }); + } else { + self.view.dataset.write(self.view.datarecord.id, data, { 'lang': code }); + } + }); this.close(); }, on_button_Close: function() { @@ -651,7 +710,7 @@ openerp.base.View = openerp.base.Widget.extend({ }, { label: "Translate", callback: this.on_sidebar_translate, - classname: 'oe_sidebar_translate' + classname: 'oe_sidebar_translate oe_hide' }, { label: "View Log", callback: this.on_sidebar_view_log, diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml index 69aac831386..c6bd9a1ee19 100644 --- a/addons/base/static/src/xml/base.xml +++ b/addons/base/static/src/xml/base.xml @@ -326,15 +326,19 @@ </div> </t> <t t-name="Header"> - <a t-att-href="'/' + qs" class="company_logo_link"> - <div class="company_logo" /> - </a> - <h1 class="header_title" t-if="session.session_is_valid()"> - <span class="database"><t t-esc="session.db"/></span> - <t t-esc="session.login"/> <br/> - <small class="username">rpc_session_id: <t t-esc="session.session_id"/></small> + <div> + <a t-att-href="'/' + widget.qs" class="company_logo_link"> + <div class="company_logo" /> + </a> + </div> +</t> +<t t-name="Header-content"> + <h1 class="header_title"> + <span class="database"><t t-esc="widget.session.db"/></span> - <t t-esc="widget.session.login"/> <br/> + <small class="username">rpc_session_id: <t t-esc="widget.session.session_id"/></small> </h1> <div class="header_corner"> - <ul class="block" t-if="session.session_is_valid()"> + <ul class="block"> <li> <a href="#home" title="Home" class="home"><img src="/base/static/src/img/header-home.png" width="16" height="16" border="0"/></a> </li> @@ -474,8 +478,8 @@ <label class="oe_form_label"><t t-esc="field.string"/>:</label> </td> <td t-foreach="widget.languages" t-as="lg" class="oe_form_frame_cell"> - <input t-if="field.type == 'char'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" class="oe_trad_field" style="width: 100%"/> - <textarea t-if="field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" class="oe_trad_field" style="width: 100%"></textarea> + <input t-if="field.type == 'char'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field" style="width: 100%"/> + <textarea t-if="field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" style="width: 100%"></textarea> </td> </tr> </table> @@ -805,13 +809,24 @@ <img src="/base/static/src/img/down-arrow.png" /></span> <span class="oe-m2o-cm-button" t-att-id="widget.name + '_open'"> <img src="/base/static/src/img/icons/gtk-index.png"/></span> - <div t-att-id="widget.cm_id" class="contextMenu" style="display:none"><ul> - <li t-att-id="widget.cm_id + '_open'" style="color:grey">Open...</li> - <li t-att-id="widget.cm_id + '_create'">Create...</li> - <li t-att-id="widget.cm_id + '_search'">Search...</li> - </ul></div> + <div t-att-id="widget.cm_id" class="contextMenu" style="display:none"> + </div> </div> </t> +<t t-name="FieldMany2One.context_menu"> + <ul> + <li t-att-id="widget.cm_id + '_open'" style="color:grey">Open...</li> + <li t-att-id="widget.cm_id + '_create'">Create...</li> + <li t-att-id="widget.cm_id + '_search'" class="oe_m2o_menu_item_mandatory">Search...</li> + <t t-set="i" t-value="0"/> + <t t-foreach="widget.related_entries" t-as="entry"> + <li t-att-id="widget.cm_id + '_related_' + i" style="color:grey" class="oe_m2o_menu_item_mandatory"> + ... <t t-esc="(entry[2] || {})['name'] || ''"/> + </li> + <t t-set="i" t-value="i+1"/> + </t> + </ul> +</t> <t t-name="FieldOne2Many"> <div t-att-id="widget.element_id"> </div> |
