diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py index d304825bd64..adf61f5facc 100644 --- a/addons/web/__openerp__.py +++ b/addons/web/__openerp__.py @@ -11,6 +11,7 @@ "static/lib/datejs/sugarpak.js", "static/lib/datejs/extras.js", "static/lib/jquery/jquery-1.6.2.js", + "static/lib/jquery.MD5/jquery.md5.js", "static/lib/jquery.form/jquery.form.js", "static/lib/jquery.validate/jquery.validate.js", "static/lib/jquery.ba-bbq/jquery.ba-bbq.js", diff --git a/addons/web/po/da.po b/addons/web/po/da.po index cefd844d49a..c0931065d1e 100644 --- a/addons/web/po/da.po +++ b/addons/web/po/da.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-10-12 04:44+0000\n" -"X-Generator: Launchpad (build 14124)\n" +"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n" +"X-Generator: Launchpad (build 14197)\n" #: addons/web/static/src/js/view_form.js:355 msgid "" diff --git a/addons/web/po/de.po b/addons/web/po/de.po index 027f34f9866..0a26630321f 100644 --- a/addons/web/po/de.po +++ b/addons/web/po/de.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n" -"X-Generator: Launchpad (build 14123)\n" +"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n" +"X-Generator: Launchpad (build 14197)\n" #: addons/web/static/src/js/view_form.js:355 msgid "" diff --git a/addons/web/po/es.po b/addons/web/po/es.po index 508b4e62245..9bd7071871b 100644 --- a/addons/web/po/es.po +++ b/addons/web/po/es.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n" -"X-Generator: Launchpad (build 14165)\n" +"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n" +"X-Generator: Launchpad (build 14197)\n" #: addons/web/static/src/js/view_form.js:355 msgid "" diff --git a/addons/web/po/es_EC.po b/addons/web/po/es_EC.po index eb2283f6fe5..588408ba979 100644 --- a/addons/web/po/es_EC.po +++ b/addons/web/po/es_EC.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-10-08 05:29+0000\n" -"X-Generator: Launchpad (build 14110)\n" +"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n" +"X-Generator: Launchpad (build 14197)\n" #: addons/web/static/src/js/view_form.js:355 msgid "" diff --git a/addons/web/po/et.po b/addons/web/po/et.po index 75269bf5cda..6b6da84f3a5 100644 --- a/addons/web/po/et.po +++ b/addons/web/po/et.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n" -"X-Generator: Launchpad (build 14123)\n" +"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n" +"X-Generator: Launchpad (build 14197)\n" #: addons/web/static/src/js/view_form.js:355 msgid "" diff --git a/addons/web/po/fr.po b/addons/web/po/fr.po index a4287a31030..df35344c558 100644 --- a/addons/web/po/fr.po +++ b/addons/web/po/fr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n" -"X-Generator: Launchpad (build 14185)\n" +"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n" +"X-Generator: Launchpad (build 14197)\n" #: addons/web/static/src/js/view_form.js:355 msgid "" diff --git a/addons/web/po/gl.po b/addons/web/po/gl.po index b43664b9bee..34b2d50085f 100644 --- a/addons/web/po/gl.po +++ b/addons/web/po/gl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n" -"X-Generator: Launchpad (build 14165)\n" +"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n" +"X-Generator: Launchpad (build 14197)\n" #: addons/web/static/src/js/view_form.js:355 msgid "" diff --git a/addons/web/po/it.po b/addons/web/po/it.po index fc53244533b..647030fd4ea 100644 --- a/addons/web/po/it.po +++ b/addons/web/po/it.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-10-09 05:22+0000\n" -"X-Generator: Launchpad (build 14110)\n" +"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n" +"X-Generator: Launchpad (build 14197)\n" #: addons/web/static/src/js/view_form.js:355 msgid "" diff --git a/addons/web/po/nl_BE.po b/addons/web/po/nl_BE.po index 2a2dccb1712..3d649b59b9d 100644 --- a/addons/web/po/nl_BE.po +++ b/addons/web/po/nl_BE.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-10-08 05:29+0000\n" -"X-Generator: Launchpad (build 14110)\n" +"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n" +"X-Generator: Launchpad (build 14197)\n" #: addons/web/static/src/js/view_form.js:355 msgid "" diff --git a/addons/web/po/sl.po b/addons/web/po/sl.po index bc63e7ff313..54349249817 100644 --- a/addons/web/po/sl.po +++ b/addons/web/po/sl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n" -"X-Generator: Launchpad (build 14165)\n" +"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n" +"X-Generator: Launchpad (build 14197)\n" #: addons/web/static/src/js/view_form.js:355 msgid "" diff --git a/addons/web/static/lib/jquery.MD5/README.md b/addons/web/static/lib/jquery.MD5/README.md new file mode 100644 index 00000000000..88778a7a3bf --- /dev/null +++ b/addons/web/static/lib/jquery.MD5/README.md @@ -0,0 +1,32 @@ +# jQuery MD5 Plugin + +## Usage +Create ([hex](http://en.wikipedia.org/wiki/Hexadecimal)-encoded) [MD5](http://en.wikipedia.org/wiki/MD5) hash of a given string value: + + var md5 = $.md5('value'); + +Create ([hex](http://en.wikipedia.org/wiki/Hexadecimal)-encoded) [HMAC](http://en.wikipedia.org/wiki/HMAC)-MD5 hash of a given string value and key: + + var md5 = $.md5('value', 'key'); + +Create raw [MD5](http://en.wikipedia.org/wiki/MD5) hash of a given string value: + + var md5 = $.md5('value', null, true); + +Create raw [HMAC](http://en.wikipedia.org/wiki/HMAC)-MD5 hash of a given string value and key: + + var md5 = $.md5('value', 'key', true); + +## Requirements +None. + +If [jQuery](http://jquery.com/) is not available, the md5 function will be added to the global object: + + var md5 = md5('value'); + +## License +Released under the [MIT license](http://creativecommons.org/licenses/MIT/). + +## Source Code & Download +* Browse and checkout the [source code](https://github.com/blueimp/jQuery-MD5). +* [Download](https://github.com/blueimp/jQuery-MD5/archives/master) the project to add the plugin to your website. diff --git a/addons/web/static/lib/jquery.MD5/README.txt b/addons/web/static/lib/jquery.MD5/README.txt new file mode 100644 index 00000000000..8a8cbf4db2a --- /dev/null +++ b/addons/web/static/lib/jquery.MD5/README.txt @@ -0,0 +1,32 @@ +jQuery MD5 Plugin +================= + +Usage +----- +Create (hex-encoded) MD5 hash of a given string value: + var md5 = $.md5('value'); + +Create (hex-encoded) HMAC-MD5 hash of a given string value and key: + var md5 = $.md5('value', 'key'); + +Create raw MD5 hash of a given string value: + var md5 = $.md5('value', null, true); + +Create raw HMAC-MD5 hash of a given string value and key: + var md5 = $.md5('value', 'key', true); + +Requirements +------------ +None. + +If jQuery is not available, the md5 function will be added to the global object: + var md5 = md5('value'); + +License +------- +Released under the MIT license: +http://creativecommons.org/licenses/MIT/ + +Source Code & Download +---------------------- +https://github.com/blueimp/jQuery-MD5 diff --git a/addons/web/static/lib/jquery.MD5/jquery.md5.js b/addons/web/static/lib/jquery.MD5/jquery.md5.js new file mode 100644 index 00000000000..bf9bbe97b55 --- /dev/null +++ b/addons/web/static/lib/jquery.MD5/jquery.md5.js @@ -0,0 +1,269 @@ +/* + * jQuery MD5 Plugin 1.2.1 + * https://github.com/blueimp/jQuery-MD5 + * + * Copyright 2010, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://creativecommons.org/licenses/MIT/ + * + * Based on + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +/*jslint bitwise: true */ +/*global unescape, jQuery */ + +(function ($) { + 'use strict'; + + /* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ + function safe_add(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF), + msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); + } + + /* + * Bitwise rotate a 32-bit number to the left. + */ + function bit_rol(num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)); + } + + /* + * These functions implement the four basic operations the algorithm uses. + */ + function md5_cmn(q, a, b, x, s, t) { + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); + } + function md5_ff(a, b, c, d, x, s, t) { + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); + } + function md5_gg(a, b, c, d, x, s, t) { + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); + } + function md5_hh(a, b, c, d, x, s, t) { + return md5_cmn(b ^ c ^ d, a, b, x, s, t); + } + function md5_ii(a, b, c, d, x, s, t) { + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); + } + + /* + * Calculate the MD5 of an array of little-endian words, and a bit length. + */ + function binl_md5(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var i, olda, oldb, oldc, oldd, + a = 1732584193, + b = -271733879, + c = -1732584194, + d = 271733878; + + for (i = 0; i < x.length; i += 16) { + olda = a; + oldb = b; + oldc = c; + oldd = d; + + a = md5_ff(a, b, c, d, x[i], 7, -680876936); + d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897); + d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); + d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i + 10], 17, -42063); + b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); + d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); + + a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510); + d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); + c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i], 20, -373897302); + a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691); + d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083); + c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438); + d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); + c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); + d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784); + c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); + + a = md5_hh(a, b, c, d, x[i + 5], 4, -378558); + d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); + d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174); + d = md5_hh(d, a, b, c, x[i], 11, -358537222); + c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487); + d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651); + + a = md5_ii(a, b, c, d, x[i], 6, -198630844); + d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); + d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); + d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070); + d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551); + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + return [a, b, c, d]; + } + + /* + * Convert an array of little-endian words to a string + */ + function binl2rstr(input) { + var i, + output = ''; + for (i = 0; i < input.length * 32; i += 8) { + output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF); + } + return output; + } + + /* + * Convert a raw string to an array of little-endian words + * Characters >255 have their high-byte silently ignored. + */ + function rstr2binl(input) { + var i, + output = []; + output[(input.length >> 2) - 1] = undefined; + for (i = 0; i < output.length; i += 1) { + output[i] = 0; + } + for (i = 0; i < input.length * 8; i += 8) { + output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32); + } + return output; + } + + /* + * Calculate the MD5 of a raw string + */ + function rstr_md5(s) { + return binl2rstr(binl_md5(rstr2binl(s), s.length * 8)); + } + + /* + * Calculate the HMAC-MD5, of a key and some data (raw strings) + */ + function rstr_hmac_md5(key, data) { + var i, + bkey = rstr2binl(key), + ipad = [], + opad = [], + hash; + ipad[15] = opad[15] = undefined; + if (bkey.length > 16) { + bkey = binl_md5(bkey, key.length * 8); + } + for (i = 0; i < 16; i += 1) { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); + return binl2rstr(binl_md5(opad.concat(hash), 512 + 128)); + } + + /* + * Convert a raw string to a hex string + */ + function rstr2hex(input) { + var hex_tab = '0123456789abcdef', + output = '', + x, + i; + for (i = 0; i < input.length; i += 1) { + x = input.charCodeAt(i); + output += hex_tab.charAt((x >>> 4) & 0x0F) + + hex_tab.charAt(x & 0x0F); + } + return output; + } + + /* + * Encode a string as utf-8 + */ + function str2rstr_utf8(input) { + return unescape(encodeURIComponent(input)); + } + + /* + * Take string arguments and return either raw or hex encoded strings + */ + function raw_md5(s) { + return rstr_md5(str2rstr_utf8(s)); + } + function hex_md5(s) { + return rstr2hex(raw_md5(s)); + } + function raw_hmac_md5(k, d) { + return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)); + } + function hex_hmac_md5(k, d) { + return rstr2hex(raw_hmac_md5(k, d)); + } + + $.md5 = function (string, key, raw) { + if (!key) { + if (!raw) { + return hex_md5(string); + } else { + return raw_md5(string); + } + } + if (!raw) { + return hex_hmac_md5(key, string); + } else { + return raw_hmac_md5(key, string); + } + }; + +}(typeof jQuery === 'function' ? jQuery : this)); \ No newline at end of file diff --git a/addons/web/static/lib/jquery.MD5/tests/index.html b/addons/web/static/lib/jquery.MD5/tests/index.html new file mode 100644 index 00000000000..27ba8d3607d --- /dev/null +++ b/addons/web/static/lib/jquery.MD5/tests/index.html @@ -0,0 +1,43 @@ + + + +
+ +
'});
+ $.blockUI();
self.rpc("/web/database/create", {'fields': fields}, function(result) {
if (result.error) {
$.unblockUI();
@@ -392,7 +408,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
.html(QWeb.render("BackupDB", self))
.find("form[name=backup_db_form]").validate({
submitHandler: function (form) {
- $.blockUI({message:'
'});
+ $.blockUI();
self.session.get_file({
form: form,
error: function (body) {
@@ -413,7 +429,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
self.$option_id.find("form[name=restore_db_form]").validate({
submitHandler: function (form) {
- $.blockUI({message:'
'});
+ $.blockUI();
$(form).ajaxSubmit({
url: '/web/database/restore',
type: 'POST',
diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js
index 39a1ba7ef64..9563abea49a 100644
--- a/addons/web/static/src/js/core.js
+++ b/addons/web/static/src/js/core.js
@@ -1043,9 +1043,16 @@ openerp.web.TranslationDataBase = openerp.web.Class.extend(/** @lends openerp.we
}
});
+if ($.blockUI) {
+ $.blockUI.defaults.baseZ = 1100;
+ $.blockUI.defaults.message = '
';
+}
openerp.web._t = new openerp.web.TranslationDataBase().build_translation_function();
openerp.web.qweb = new QWeb2.Engine();
openerp.web.qweb.debug = (window.location.search.indexOf('?debug') !== -1);
+openerp.web.qweb.default_dict = {
+ '_' : _
+}
openerp.web.qweb.format_text_node = function(s) {
// Note that 'this' is the Qweb Node of the text
var translation = this.node.parentNode.attributes['t-translation'];
diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js
index 3ab972f7a86..ca540844b7f 100644
--- a/addons/web/static/src/js/formats.js
+++ b/addons/web/static/src/js/formats.js
@@ -27,14 +27,8 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
return _.sprintf('%d', value);
case 'float':
var precision = descriptor.digits ? descriptor.digits[1] : 2;
- var int_part = Math.floor(value);
- var dec_part = _.sprintf(
- '%.' + precision + 'f',
- Math.abs(value) % 1).substring(2);
- return _.sprintf('%d%s%s',
- int_part,
- openerp.web._t.database.parameters.decimal_point,
- dec_part);
+ return _.sprintf('%.' + precision + 'f', value)
+ .replace('.', openerp.web._t.database.parameters.decimal_point);
case 'float_time':
return _.sprintf("%02d:%02d",
Math.floor(value),
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 1f1b5b8ef6f..237199d5472 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -89,7 +89,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.fields_view = data;
var frame = new (this.registry.get_object('frame'))(this, this.fields_view.arch);
- this.rendered = QWeb.render(this.form_template, { 'frame': frame, 'view': this });
+ this.rendered = QWeb.render(this.form_template, { 'frame': frame, 'widget': this });
}
this.$element.html(this.rendered);
_.each(this.widgets, function(w) {
@@ -105,17 +105,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
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_form_button_duplicate').click(this.on_button_duplicate);
- this.$form_header.find('button.oe_form_button_toggle').click(function () {
- self.translatable_fields = [];
- self.widgets = {};
- self.fields = {};
- self.$form_header.find('button').unbind('click');
- self.registry = self.registry === openerp.web.form.widgets
- ? openerp.web.form.readonly
- : openerp.web.form.widgets;
- self.on_loaded(self.fields_view);
- self.reload();
- });
+ this.$form_header.find('button.oe_form_button_toggle').click(this.on_toggle_readonly);
if (this.options.sidebar && this.options.sidebar_id) {
this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
@@ -127,6 +117,18 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
this.has_been_loaded.resolve();
},
+ on_toggle_readonly: function() {
+ var self = this;
+ self.translatable_fields = [];
+ self.widgets = {};
+ self.fields = {};
+ self.$form_header.find('button').unbind('click');
+ self.registry = self.registry === openerp.web.form.widgets
+ ? openerp.web.form.readonly
+ : openerp.web.form.widgets;
+ self.on_loaded(self.fields_view);
+ self.reload();
+ },
do_show: function () {
var promise;
if (this.dataset.index === null) {
@@ -715,6 +717,16 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.
this.invisible = this.modifiers['invisible'] === true;
this.classname = 'oe_form_' + this.type;
+ this.align = parseFloat(this.node.attrs.align);
+ if (isNaN(this.align) || this.align === 1) {
+ this.align = 'right';
+ } else if (this.align === 0) {
+ this.align = 'left';
+ } else {
+ this.align = 'center';
+ }
+
+
this.width = this.node.attrs.width;
},
start: function() {
@@ -1044,8 +1056,7 @@ openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({
this._super(view, node);
- // TODO fme: support for attrs.align
- if (this.node.tag == 'label' && (this.node.attrs.colspan || (this.string && this.string.length > 32))) {
+ if (this.node.tag == 'label' && (this.align === 'left' || this.node.attrs.colspan || (this.string && this.string.length > 32))) {
this.template = "WidgetParagraph";
this.colspan = parseInt(this.node.attrs.colspan || 1, 10);
} else {
@@ -1170,6 +1181,10 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
openerp.web.form.FieldChar = openerp.web.form.Field.extend({
template: 'FieldChar',
+ init: function (view, node) {
+ this._super(view, node);
+ this.password = this.node.attrs.password === 'True' || this.node.attrs.password === '1';
+ },
start: function() {
this._super.apply(this, arguments);
this.$element.find('input').change(this.on_ui_change);
@@ -1814,7 +1829,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
self.original_value = undefined;
self._change_int_ext_value(rval);
};
- if(typeof(value) === "number") {
+ if (value && !(value instanceof Array)) {
var dataset = new openerp.web.DataSetStatic(this, this.field.relation, self.build_context());
dataset.name_get([value], function(data) {
real_set_value(data[0]);
@@ -1917,7 +1932,8 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
multi_selection: false,
init: function(view, node) {
this._super(view, node);
- this.is_started = $.Deferred();
+ this.is_loaded = $.Deferred();
+ this.initial_is_loaded = this.is_loaded;
this.is_setted = $.Deferred();
this.form_last_update = $.Deferred();
this.init_form_last_update = this.form_last_update;
@@ -1935,8 +1951,18 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
self.on_ui_change();
});
+ this.is_setted.then(function() {
+ self.load_views();
+ });
+ },
+ is_readonly: function() {
+ return this.readonly || this.force_readonly;
+ },
+ load_views: function() {
+ var self = this;
+
var modes = this.node.attrs.mode;
- modes = !!modes ? modes.split(",") : ["tree", "form"];
+ modes = !!modes ? modes.split(",") : ["tree"];
var views = [];
_.each(modes, function(mode) {
var view = {
@@ -1949,25 +1975,38 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
}
if(view.view_type === "list") {
view.options.selectable = self.multi_selection;
+ if (self.is_readonly()) {
+ view.options.addable = null;
+ view.options.deletable = null;
+ }
} else if (view.view_type === "form") {
view.options.not_interactible_on_create = true;
}
views.push(view);
});
this.views = views;
-
+
this.viewmanager = new openerp.web.ViewManager(this, this.dataset, views);
this.viewmanager.registry = openerp.web.views.clone({
list: 'openerp.web.form.One2ManyListView',
- form: 'openerp.web.form.One2ManyFormView'
+ form: 'openerp.web.FormView'
});
var once = $.Deferred().then(function() {
self.init_form_last_update.resolve();
});
+ var def = $.Deferred().then(function() {
+ self.initial_is_loaded.resolve();
+ });
this.viewmanager.on_controller_inited.add_last(function(view_type, controller) {
if (view_type == "list") {
controller.o2m = self;
+ if (self.is_readonly())
+ controller.set_editable(false);
} else if (view_type == "form") {
+ if (self.is_readonly()) {
+ controller.on_toggle_readonly();
+ $(controller.$element.find(".oe_form_buttons")[0]).children().remove();
+ }
controller.on_record_loaded.add_last(function() {
once.resolve();
});
@@ -1978,33 +2017,40 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
} else if (view_type == "graph") {
self.reload_current_view()
}
- self.is_started.resolve();
+ def.resolve();
});
- this.viewmanager.on_mode_switch.add_first(function() {
- self.save_form_view();
+ this.viewmanager.on_mode_switch.add_first(function(n_mode, b, c, d, e) {
+ $.when(self.save_form_view()).then(function() {
+ if(n_mode === "list")
+ setTimeout(function() {self.reload_current_view();}, 0);
+ });
});
this.is_setted.then(function() {
setTimeout(function () {
self.viewmanager.appendTo(self.$element);
}, 0);
});
+ return def;
},
reload_current_view: function() {
var self = this;
- var view = self.viewmanager.views[self.viewmanager.active_view].controller;
- if(self.viewmanager.active_view === "list") {
- view.reload_content();
- } else if (self.viewmanager.active_view === "form") {
- if (this.dataset.index === null && this.dataset.ids.length >= 1) {
- this.dataset.index = 0;
+ self.is_loaded = self.is_loaded.pipe(function() {
+ var view = self.viewmanager.views[self.viewmanager.active_view].controller;
+ if(self.viewmanager.active_view === "list") {
+ return view.reload_content();
+ } else if (self.viewmanager.active_view === "form") {
+ if (self.dataset.index === null && self.dataset.ids.length >= 1) {
+ self.dataset.index = 0;
+ }
+ var act = function() {
+ return view.do_show();
+ }
+ self.form_last_update = self.form_last_update.pipe(act, act);
+ return self.form_last_update;
+ } else if (self.viewmanager.active_view === "graph") {
+ return view.do_search(self.build_domain(), self.dataset.get_context(), []);
}
- var act = function() {
- return view.do_show();
- }
- this.form_last_update = this.form_last_update.pipe(act, act);;
- } else if (self.viewmanager.active_view === "graph") {
- view.do_search(this.build_domain(), this.dataset.get_context(), []);
- }
+ });
},
set_value: function(value) {
value = value || [];
@@ -2061,9 +2107,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
if (this.dataset.index === null && this.dataset.ids.length > 0) {
this.dataset.index = 0;
}
- $.when(this.is_started).then(function() {
- self.reload_current_view();
- });
+ self.reload_current_view();
this.is_setted.resolve();
},
get_value: function() {
@@ -2127,7 +2171,18 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
},
update_dom: function() {
this._super.apply(this, arguments);
- this.$element.toggleClass('disabled', this.readonly);
+ var self = this;
+ if (this.previous_readonly !== this.readonly) {
+ this.previous_readonly = this.readonly;
+ if (this.viewmanager) {
+ this.is_loaded = this.is_loaded.pipe(function() {
+ self.viewmanager.stop();
+ return $.when(self.load_views()).then(function() {
+ self.reload_current_view();
+ });
+ });
+ }
+ }
}
});
@@ -2138,9 +2193,6 @@ openerp.web.form.One2ManyDataSet = openerp.web.BufferedDataSet.extend({
}
});
-openerp.web.form.One2ManyFormView = openerp.web.FormView.extend({
-});
-
openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
do_add_record: function () {
if (this.options.editable) {
@@ -2179,7 +2231,8 @@ openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
read_function: function() {
return self.o2m.dataset.read_ids.apply(self.o2m.dataset, arguments);
},
- form_view_options: {'not_interactible_on_create':true}
+ form_view_options: {'not_interactible_on_create':true},
+ readonly: self.o2m.is_readonly()
});
pop.on_write.add(function(id, data) {
self.o2m.dataset.write(id, data, {}, function(r) {
@@ -2195,7 +2248,9 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
init: function(view, node) {
this._super(view, node);
this.list_id = _.uniqueId("many2many");
- this.is_started = $.Deferred();
+ this.is_loaded = $.Deferred();
+ this.initial_is_loaded = this.is_loaded;
+ this.is_setted = $.Deferred();
},
start: function() {
this._super.apply(this, arguments);
@@ -2207,18 +2262,10 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
this.dataset.on_unlink.add_last(function(ids) {
self.on_ui_change();
});
-
- this.list_view = new openerp.web.form.Many2ManyListView(this, this.dataset, false, {
- 'addable': 'Add',
- 'selectable': self.multi_selection
- });
- this.list_view.m2m_field = this;
- this.list_view.on_loaded.add_last(function() {
- self.is_started.resolve();
+
+ this.is_setted.then(function() {
+ self.load_view();
});
- setTimeout(function () {
- self.list_view.appendTo($("#" + self.list_id));
- }, 0);
},
set_value: function(value) {
value = value || [];
@@ -2228,16 +2275,56 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
this._super(value);
this.dataset.set_ids(value);
var self = this;
- $.when(this.is_started).then(function() {
- self.list_view.reload_content();
- });
+ self.reload_content();
+ this.is_setted.resolve();
},
get_value: function() {
return [commands.replace_with(this.dataset.ids)];
},
validate: function() {
this.invalid = false;
- // TODO niv
+ },
+ is_readonly: function() {
+ return this.readonly || this.force_readonly;
+ },
+ load_view: function() {
+ var self = this;
+ this.list_view = new openerp.web.form.Many2ManyListView(this, this.dataset, false, {
+ 'addable': self.is_readonly() ? null : 'Add',
+ 'deletable': self.is_readonly() ? false : true,
+ 'selectable': self.multi_selection
+ });
+ this.list_view.m2m_field = this;
+ var loaded = $.Deferred();
+ this.list_view.on_loaded.add_last(function() {
+ self.initial_is_loaded.resolve();
+ loaded.resolve();
+ });
+ setTimeout(function () {
+ self.list_view.appendTo($("#" + self.list_id));
+ }, 0);
+ return loaded;
+ },
+ reload_content: function() {
+ var self = this;
+ this.is_loaded = this.is_loaded.pipe(function() {
+ return self.list_view.reload_content();
+ });
+ },
+ update_dom: function() {
+ this._super.apply(this, arguments);
+ var self = this;
+ if (this.previous_readonly !== this.readonly) {
+ this.previous_readonly = this.readonly;
+ if (this.list_view) {
+ this.is_loaded = this.is_loaded.pipe(function() {
+ self.list_view.stop();
+ return $.when(self.load_view()).then(function() {
+ self.reload_content();
+ });
+ });
+ }
+ }
}
});
@@ -2341,10 +2428,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
this.searchview.stop();
}
this.searchview = new openerp.web.SearchView(this,
- this.dataset, false, {
- "selectable": !this.options.disable_multiple_selection,
- "deletable": false
- });
+ this.dataset, false, {});
this.searchview.on_search.add(function(domains, contexts, groupbys) {
if (self.initial_ids) {
self.do_search(domains.concat([[["id", "in", self.initial_ids]], self.domain]),
@@ -2371,7 +2455,9 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
});
self.view_list = new openerp.web.form.SelectCreateListView(self,
self.dataset, false,
- _.extend({'deletable': false}, self.options.list_view_options || {}));
+ _.extend({'deletable': false,
+ 'selectable': !self.options.disable_multiple_selection
+ }, self.options.list_view_options || {}));
self.view_list.popup = self;
self.view_list.appendTo($("#" + self.element_id + "_view_list")).pipe(function() {
self.view_list.do_show();
@@ -2490,6 +2576,7 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
* - read_function
* - parent_view
* - form_view_options
+ * - readonly
*/
show_element: function(model, row_id, context, options) {
this.model = model;
@@ -2529,7 +2616,13 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
this.view_form.set_embedded_view(this.options.alternative_form_view);
}
this.view_form.appendTo(this.$element.find("#" + this.element_id + "_view_form"));
+ var once = $.Deferred().then(function() {
+ if (self.options.readonly) {
+ self.view_form.on_toggle_readonly();
+ }
+ });
this.view_form.on_loaded.add_last(function() {
+ once.resolve();
var $buttons = self.view_form.$element.find(".oe_form_buttons");
$buttons.html(QWeb.render("FormOpenPopup.form.buttons"));
var $nbutton = $buttons.find(".oe_formopenpopup-form-save");
@@ -2542,6 +2635,10 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
$cbutton.click(function() {
self.stop();
});
+ if (self.options.readonly) {
+ $nbutton.hide();
+ $cbutton.text(_t("Close"));
+ }
self.view_form.do_show();
});
this.dataset.on_write.add(this.on_write);
@@ -2829,9 +2926,16 @@ openerp.web.form.FieldReadonly = openerp.web.form.Field.extend({
});
openerp.web.form.FieldCharReadonly = openerp.web.form.FieldReadonly.extend({
template: 'FieldChar.readonly',
+ init: function(view, node) {
+ this._super(view, node);
+ this.password = this.node.attrs.password === 'True' || this.node.attrs.password === '1';
+ },
set_value: function (value) {
this._super.apply(this, arguments);
var show_value = openerp.web.format_value(value, this, '');
+ if (this.password) {
+ show_value = new Array(show_value.length + 1).join('*');
+ }
this.$element.find('div').text(show_value);
return show_value;
}
@@ -2894,9 +2998,17 @@ openerp.web.form.FieldMany2OneReadonly = openerp.web.form.FieldCharReadonly.exte
self.update_dom();
self.on_value_changed();
var real_set_value = function(rval) {
- self.$element.find('div').text(rval ? rval[1] : '');
+ self.value = rval;
+ var div = $(self.$element.find('div'));
+ div.html('');
+ var a = $(div.find("a"));
+ a.text(rval ? rval[1] : '');
+ a.click(function() {
+ var pop = new openerp.web.form.FormOpenPopup(self.view);
+ pop.show_element(self.field.relation, self.value[0],self.build_context(), {readonly:true});
+ });
};
- if(typeof(value) === "number") {
+ if (value && !(value instanceof Array)) {
var dataset = new openerp.web.DataSetStatic(
this, this.field.relation, self.build_context());
dataset.name_get([value], function(data) {
@@ -2941,6 +3053,13 @@ openerp.web.form.widgets = new openerp.web.Registry({
'binary': 'openerp.web.form.FieldBinaryFile',
'statusbar': 'openerp.web.form.FieldStatus'
});
+
+openerp.web.form.FieldMany2ManyReadonly = openerp.web.form.FieldMany2Many.extend({
+ force_readonly: true
+});
+openerp.web.form.FieldOne2ManyReadonly = openerp.web.form.FieldOne2Many.extend({
+ force_readonly: true
+});
openerp.web.form.readonly = openerp.web.form.widgets.clone({
'char': 'openerp.web.form.FieldCharReadonly',
'email': 'openerp.web.form.FieldEmailReadonly',
@@ -2951,6 +3070,9 @@ openerp.web.form.readonly = openerp.web.form.widgets.clone({
'datetime': 'openerp.web.form.FieldCharReadonly',
'selection' : 'openerp.web.form.FieldSelectionReadonly',
'many2one': 'openerp.web.form.FieldMany2OneReadonly',
+ 'many2many' : 'openerp.web.form.FieldMany2ManyReadonly',
+ 'one2many' : 'openerp.web.form.FieldOne2ManyReadonly',
+ 'one2many_list' : 'openerp.web.form.FieldOne2ManyReadonly',
'boolean': 'openerp.web.form.FieldBooleanReadonly',
'float': 'openerp.web.form.FieldCharReadonly',
'integer': 'openerp.web.form.FieldCharReadonly',
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index d09ec1d3035..e891a6c7db7 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -11,7 +11,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
// whether the column headers should be displayed
'header': true,
// display addition button, with that label
- 'addable': _t("New"),
+ 'addable': _t("Create"),
// whether the list view can be sorted, note that once a view has been
// sorted it can not be reordered anymore
'sortable': true,
@@ -201,8 +201,15 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
this.setup_columns(this.fields_view.fields, grouped);
this.$element.html(QWeb.render("ListView", this));
-
// Head hook
+ this.$element.find('.all-record-selector').click(function(){
+ self.$element.find('.oe-record-selector input').prop('checked',
+ self.$element.find('.all-record-selector').prop('checked') || false);
+ var selection = self.groups.get_selection();
+ $(self.groups).trigger(
+ 'selected', [selection.ids, selection.records]);
+ });
+
this.$element.find('.oe-list-add')
.click(this.do_add_record)
.attr('disabled', grouped && this.options.editable);
@@ -424,10 +431,13 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
},
/**
* re-renders the content of the list view
+ *
+ * @returns {$.Deferred} promise to content reloading
*/
reload_content: function () {
var self = this;
this.records.reset();
+ var reloaded = $.Deferred();
this.$element.find('.oe-listview-content').append(
this.groups.render(function () {
if (self.dataset.index == null) {
@@ -438,7 +448,9 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
}
}
self.compute_aggregates();
+ reloaded.resolve();
}));
+ return reloaded.promise();
},
/**
* Handler for the result of eval_domain_and_context, actually perform the
@@ -512,6 +524,17 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
return field.name === name;
});
if (!action) { return; }
+
+ var c = new openerp.web.CompoundContext();
+ c.set_eval_context(_.extend({
+ active_id: id,
+ active_ids: [id],
+ active_model: this.dataset.model
+ }, this.records.get(id).toContext()));
+ if (action.context) {
+ c.add(action.context);
+ }
+ action.context = c;
this.do_execute_action(action, this.dataset, id, callback);
},
/**
@@ -1201,6 +1224,10 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
var options = { offset: page * limit, limit: limit };
//TODO xmo: investigate why we need to put the setTimeout
setTimeout(function() {dataset.read_slice(fields, options , function (records) {
+ // FIXME: ignominious hacks, parents (aka form view) should not send two ListView#reload_content concurrently
+ if (self.records.length) {
+ self.records.reset(null, {silent: true});
+ }
if (!self.datagroup.openable) {
view.configure_pager(dataset);
} else {
@@ -1430,6 +1457,25 @@ var Record = openerp.web.Class.extend(/** @lends Record# */{
}
return {data: form_data};
+ },
+ /**
+ * Converts the current record to a format expected by context evaluations
+ * (identical to record.attributes, except m2o fields are their integer
+ * value rather than a pair)
+ */
+ toContext: function () {
+ var output = {}, attrs = this.attributes;
+ for(var k in attrs) {
+ var val = attrs[k];
+ if (typeof val !== 'object') {
+ output[k] = val;
+ } else if (val instanceof Array) {
+ output[k] = val[0];
+ } else {
+ throw new Error("Can't convert value " + val + " to context");
+ }
+ }
+ return output;
}
});
Record.include(Events);
@@ -1541,7 +1587,8 @@ var Collection = openerp.web.Class.extend(/** @lends Collection# */{
* @param {Array} [records]
* @returns this
*/
- reset: function (records) {
+ reset: function (records, options) {
+ options = options || {};
_(this._proxies).each(function (proxy) {
proxy.reset();
});
@@ -1552,7 +1599,9 @@ var Collection = openerp.web.Class.extend(/** @lends Collection# */{
if (records) {
this.add(records);
}
- this.trigger('reset', this);
+ if (!options.silent) {
+ this.trigger('reset', this);
+ }
return this;
},
/**
diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js
index 4cc081a6266..dba0a1abba4 100644
--- a/addons/web/static/src/js/view_list_editable.js
+++ b/addons/web/static/src/js/view_list_editable.js
@@ -78,6 +78,17 @@ openerp.web.list_editable = function (openerp) {
// tree/@editable takes priority on everything else if present.
this.options.editable = data.arch.attrs.editable || this.options.editable;
return this._super(data, grouped);
+ },
+ /**
+ * Ensures the editable list is saved (saves any pending edition if
+ * needed, or tries to)
+ *
+ * Returns a deferred to the end of the saving.
+ *
+ * @returns {$.Deferred}
+ */
+ ensure_saved: function () {
+ return this.groups.ensure_saved();
}
});
@@ -86,6 +97,18 @@ openerp.web.list_editable = function (openerp) {
new_record: function () {
// TODO: handle multiple children
this.children[null].new_record();
+ },
+ /**
+ * Ensures descendant editable List instances are all saved if they have
+ * pending editions.
+ *
+ * @returns {$.Deferred}
+ */
+ ensure_saved: function () {
+ return $.when.apply(null,
+ _.invoke(
+ _.values(this.children),
+ 'ensure_saved'));
}
});
@@ -254,9 +277,11 @@ openerp.web.list_editable = function (openerp) {
* sibling if asked.
*
* @param {Boolean} [edit_next=false] should the next row become editable
+ * @returns {$.Deferred}
*/
save_row: function (edit_next) {
- var self = this;
+ //noinspection JSPotentiallyInvalidConstructorUsage
+ var self = this, done = $.Deferred();
this.edition_form.do_save(function (result) {
if (result.created && !self.edition_id) {
self.records.add({id: result.result},
@@ -267,28 +292,44 @@ openerp.web.list_editable = function (openerp) {
next_record = self.records.at(
self.records.indexOf(edited_record) + 1);
- self.handle_onwrite(self.edition_id);
- self.cancel_pending_edition().then(function () {
- $(self).trigger('saved', [self.dataset]);
- if (!edit_next) {
- return;
- }
- if (result.created) {
- self.new_record();
- return;
- }
- var next_record_id;
- if (next_record) {
- next_record_id = next_record.get('id');
- self.dataset.index = _(self.dataset.ids)
- .indexOf(next_record_id);
- } else {
- self.dataset.index = 0;
- next_record_id = self.records.at(0).get('id');
- }
- self.edit_record(next_record_id);
- });
- }, this.options.editable === 'top');
+ $.when(
+ self.handle_onwrite(self.edition_id),
+ self.cancel_pending_edition().then(function () {
+ $(self).trigger('saved', [self.dataset]);
+ if (!edit_next) {
+ return;
+ }
+ if (result.created) {
+ self.new_record();
+ return;
+ }
+ var next_record_id;
+ if (next_record) {
+ next_record_id = next_record.get('id');
+ self.dataset.index = _(self.dataset.ids)
+ .indexOf(next_record_id);
+ } else {
+ self.dataset.index = 0;
+ next_record_id = self.records.at(0).get('id');
+ }
+ self.edit_record(next_record_id);
+ })).then(function () {
+ done.resolve();
+ });
+ }, this.options.editable === 'top').fail(function () {
+ done.reject();
+ });
+ return done.promise();
+ },
+ /**
+ * If the current list is being edited, ensures it's saved
+ */
+ ensure_saved: function () {
+ if (this.edition) {
+ return this.save_row();
+ }
+ //noinspection JSPotentiallyInvalidConstructorUsage
+ return $.Deferred().resolve().promise();
},
/**
* Cancels the edition of the row for the current dataset index
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index 10e53efa591..b6a37c82560 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -271,6 +271,10 @@ session.web.ViewManager = session.web.Widget.extend(/** @lends session.web.View
}
}
}
+ $.when(view_promise).then(function () {
+ self.$element.find('.oe_view_title:first').text(
+ self.display_title());
+ });
return view_promise;
},
/**
@@ -331,7 +335,15 @@ session.web.ViewManager = session.web.Widget.extend(/** @lends session.web.View
/**
* Called by children view after executing an action
*/
- on_action_executed: function () {}
+ on_action_executed: function () {},
+ display_title: function () {
+ var view = this.views[this.active_view];
+ if (view) {
+ // ick
+ return view.controller.fields_view.arch.attrs.string;
+ }
+ return '';
+ }
});
session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepnerp.web.ViewManagerAction# */{
@@ -444,6 +456,16 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
if (!self.action.name && fvg) {
self.$element.find('.oe_view_title').text(fvg.arch.attrs.string || fvg.name);
}
+
+ var $title = self.$element.find('.oe_view_title'),
+ $search_prefix = $title.find('span');
+ if (controller.searchable !== false) {
+ if (!$search_prefix.length) {
+ $title.prepend('' + _t("Search:") + '');
+ }
+ } else {
+ $search_prefix.remove();
+ }
});
},
shortcut_check : function(view) {
@@ -512,6 +534,9 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
return false;
});
});
+ },
+ display_title: function () {
+ return this.action.name;
}
});
@@ -544,7 +569,7 @@ session.web.Sidebar = session.web.Widget.extend({
{
label: _t("Manage Views"),
callback: this.call_default_on_sidebar,
- title: _t("Manage views of the current object"),
+ title: _t("Manage views of the current object")
}, {
label: _t("Edit Workflow"),
callback: this.call_default_on_sidebar,
@@ -553,7 +578,7 @@ session.web.Sidebar = session.web.Widget.extend({
}, {
label: _t("Customize Object"),
callback: this.call_default_on_sidebar,
- title: _t("Manage views of the current object"),
+ title: _t("Manage views of the current object")
}
]);
@@ -561,10 +586,10 @@ session.web.Sidebar = session.web.Widget.extend({
this.add_items('other', [
{
label: _t("Import"),
- callback: this.call_default_on_sidebar,
+ callback: this.call_default_on_sidebar
}, {
label: _t("Export"),
- callback: this.call_default_on_sidebar,
+ callback: this.call_default_on_sidebar
}, {
label: _t("Translate"),
callback: this.call_default_on_sidebar,
@@ -604,7 +629,7 @@ session.web.Sidebar = session.web.Widget.extend({
var $section = $(session.web.qweb.render("Sidebar.section", {
section_id: section_id,
name: name,
- classname: 'oe_sidebar_' + code,
+ classname: 'oe_sidebar_' + code
}));
$section.appendTo(this.$element.find('div.sidebar-actions'));
this.sections[code] = $section;
@@ -944,19 +969,19 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{
}
});
-session.web.json_node_to_xml = function(node, single_quote, indent) {
+session.web.json_node_to_xml = function(node, human_readable, indent) {
// For debugging purpose, this function will convert a json node back to xml
// Maybe usefull for xml view editor
+ indent = indent || 0;
+ var sindent = (human_readable ? (new Array(indent + 1).join('\t')) : ''),
+ r = sindent + '<' + node.tag,
+ cr = human_readable ? '\n' : '';
if (typeof(node) === 'string') {
- return node;
- }
- else if (typeof(node.tag) !== 'string' || !node.children instanceof Array || !node.attrs instanceof Object) {
+ return sindent + node;
+ } else if (typeof(node.tag) !== 'string' || !node.children instanceof Array || !node.attrs instanceof Object) {
throw("Node a json node");
}
- indent = indent || 0;
- var sindent = new Array(indent + 1).join('\t'),
- r = sindent + '<' + node.tag;
for (var attr in node.attrs) {
var vattr = node.attrs[attr];
if (typeof(vattr) !== 'string') {
@@ -964,19 +989,19 @@ session.web.json_node_to_xml = function(node, single_quote, indent) {
vattr = JSON.stringify(vattr);
}
vattr = vattr.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"');
- if (single_quote) {
+ if (human_readable) {
vattr = vattr.replace(/"/g, "'");
}
r += ' ' + attr + '="' + vattr + '"';
}
if (node.children && node.children.length) {
- r += '>\n';
+ r += '>' + cr;
var childs = [];
for (var i = 0, ii = node.children.length; i < ii; i++) {
- childs.push(session.web.json_node_to_xml(node.children[i], single_quote, indent + 1));
+ childs.push(session.web.json_node_to_xml(node.children[i], human_readable, indent + 1));
}
- r += childs.join('\n');
- r += '\n' + sindent + '' + node.tag + '>';
+ r += childs.join(cr);
+ r += cr + sindent + '' + node.tag + '>';
return r;
} else {
return r + '/>';
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 323854fa7a3..e8d0f14f2fe 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -415,6 +415,9 @@