From aa412d99ec8dcbd5f49a45c051adcd483da83e2c Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Thu, 13 Mar 2014 15:22:58 +0100 Subject: [PATCH 01/29] [FIX] website tour: create a stub for bootstrap tour in automatic/test mode bzr revid: chm@openerp.com-20140313142258-wblpqpwp9oubboc9 --- addons/website/static/src/js/website.tour.js | 16 ++++++++++++++++ addons/website_sale/tests/test_ui.py | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index a17115d2184..61b8f851339 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -3,9 +3,22 @@ var website = openerp.website; +// don't need template to use bootstrap Tour in automatic mode if (typeof QWeb2 !== "undefined") website.add_template_file('/website/static/src/xml/website.tour.xml'); +// don't need to use bootstrap Tour to launch an automatic tour +function bootstrap_tour_stub () { + if (typeof Tour === "undefined") { + window.Tour = function Tour() {}; + Tour.prototype.addSteps = function () {}; + Tour.prototype.end = function () {}; + Tour.prototype.goto = function () {}; + } +} + + + if (website.EditorBar) website.EditorBar.include({ tours: [], @@ -175,6 +188,9 @@ website.Tour = openerp.Class.extend({ }, registerTour: function () { + if (this.automatic) { + bootstrap_tour_stub(); + } this.tour = new Tour({ name: this.id, storage: this.tourStorage, diff --git a/addons/website_sale/tests/test_ui.py b/addons/website_sale/tests/test_ui.py index b024e405a1c..fcb84773036 100644 --- a/addons/website_sale/tests/test_ui.py +++ b/addons/website_sale/tests/test_ui.py @@ -14,7 +14,7 @@ class TestUi(openerp.tests.HttpCase): self.phantom_js("/", "openerp.website.Tour.run_test('shop')", "openerp.website.Tour.Shop", login="admin") def test_02_admin_checkout(self): - self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour", login="admin") + self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour", login="admin", inject=inject) def test_03_demo_checkout(self): self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="demo", inject=inject) From 51a0bb001bc496718c30e34701c82964ccb0cdc8 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Fri, 14 Mar 2014 12:35:10 +0100 Subject: [PATCH 02/29] [IMP] website snippet: add onfocus, onblur, onclone and onremove on snippet options; fix banner id bzr revid: chm@openerp.com-20140314113510-dqj70i85z41q5j0k --- .../static/src/js/website.snippets.editor.js | 76 +++++++++++++++---- 1 file changed, 61 insertions(+), 15 deletions(-) diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index 8ff89466368..1fddc7b869b 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -419,7 +419,7 @@ $target.data("overlay").remove(); $target.removeData("overlay"); } - $target.find("[data-snippet-id]").each(function () { + $target.find(website.snippet.globalSelector).each(function () { var $snippet = $(this); $snippet.removeData("snippet-editor"); if ($snippet.data("overlay")) { @@ -676,6 +676,30 @@ // start is call just after the init start: function () { }, + /* onFocus + * This method is called when the user click inside the snippet in the dom + */ + onFocus : function () { + }, + + /* onFocus + * This method is called when the user click outside the snippet in the dom, after a focus + */ + onBlur : function () { + }, + + /* on_clone + * This method is called when the snippet is cloned ($clone is allready inserted) + */ + on_clone: function ($clone) { + }, + + /* on_remove + * This method is called when the snippet is removed (dom is removing after this call) + */ + on_remove: function () { + }, + /* * drop_and_build_snippet * This method is called just after that a thumbnail is drag and dropped into a drop zone @@ -806,23 +830,36 @@ }); website.snippet.options.slider = website.snippet.Option.extend({ + unique_id: function () { + var id = 0; + $(".carousel").each(function () { + var cid = 1 + parseInt($(this).attr("id").replace(/[^0123456789]/g, ''),10); + if (id < cid) id = cid; + }); + return "myCarousel" + id; + }, drop_and_build_snippet: function() { - var id = $(".carousel").length; - this.id = "myCarousel" + id; + this.id = this.unique_id(); this.$target.attr("id", this.id); - this.$target.find(".carousel-control").attr("href", "#myCarousel" + id); - this.$target.find("[data-target]").attr("data-target", "#myCarousel" + id); + this.$target.find("[data-slide]").attr("href", "#" + this.id); + this.$target.find("[data-slide-to]").attr("data-target", "#" + this.id); this.rebind_event(); }, + on_clone: function ($clone) { + var id = this.unique_id(); + $clone.attr("id", id); + $clone.find("[data-slide]").attr("href", "#" + id); + $clone.find("[data-slide-to]").attr("data-target", "#" + id); + }, // rebind event to active carousel on edit mode rebind_event: function () { var self = this; - this.$target.find('.carousel-indicators [data-target]').off('click').on('click', function () { + this.$target.find('.carousel-indicators [data-slide-to]').off('click').on('click', function () { self.$target.carousel(+$(this).data('slide-to')); }); this.$target.attr('contentEditable', 'false'); - this.$target.find('.oe_structure, .content>.row').attr('contentEditable', 'true'); + this.$target.find('.oe_structure, .content>.row, [data-slide]').attr('contentEditable', 'true'); }, clean_for_save: function () { this._super(); @@ -1187,25 +1224,22 @@ this._super(); }, hide_remove_button: function() { - this.$overlay.find('.oe_snippet_remove').toggleClass("hidden", - !this.$target.siblings().length && this.$target.parents("[data-snippet-id]:first").find("[data-snippet-id='colmd']").length > 1); + this.$overlay.find('.oe_snippet_remove').toggleClass("hidden", !this.$target.siblings().length); }, onFocus : function () { this._super(); this.hide_remove_button(); }, - on_clone: function () { - var $clone = this.$target.clone(false); + on_clone: function ($clone) { var _class = $clone.attr("class").replace(/\s*(col-lg-offset-|col-md-offset-)([0-9-]+)/g, ''); $clone.attr("class", _class); - this.$target.after($clone); this.hide_remove_button(); return false; }, on_remove: function () { if (!this.$target.siblings().length) { - var $parent = this.$target.parents("[data-snippet-id]:first"); - if($parent.find("[data-snippet-id='colmd']").length > 1) { + var $parent = this.$target.parents(".row:first"); + if($parent.find("[class*='col-md']").length > 1) { return false; } else { if (!$parent.data("snippet-editor")) { @@ -1455,7 +1489,7 @@ get_parent_block: function () { var self = this; var $button = this.$overlay.find('.oe_snippet_parent'); - var $parent = this.$target.parents("[data-snippet-id]:first"); + var $parent = this.$target.parents(website.snippet.globalSelector).first(); if ($parent.length) { $button.removeClass("hidden"); $button.off("click").on('click', function (event) { @@ -1483,12 +1517,18 @@ on_clone: function () { var $clone = this.$target.clone(false); this.$target.after($clone); + for (var i in this.styles){ + this.styles[i].on_clone($clone); + } return false; }, on_remove: function () { this.onBlur(); var index = _.indexOf(this.BuildingBlock.snippets, this.$target.get(0)); + for (var i in this.styles){ + this.styles[i].on_remove(); + } delete this.BuildingBlock.snippets[index]; this.$target.remove(); this.$overlay.remove(); @@ -1511,12 +1551,18 @@ */ onFocus : function () { this.$overlay.addClass('oe_active'); + for (var i in this.styles){ + this.styles[i].onFocus(); + } }, /* onFocus * This method is called when the user click outside the snippet in the dom, after a focus */ onBlur : function () { + for (var i in this.styles){ + this.styles[i].onBlur(); + } this.$overlay.removeClass('oe_active'); }, From c93b466d32fc40973827ee89363087f81b4af9c3 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Mar 2014 17:54:42 +0100 Subject: [PATCH 03/29] [FIX] website tour, prepare for manual injection - reorder website.js in a choerent way - remove injectable website.tour.test.js We will do injection manually using website.inject_tour, in the mean time only non injection test are supported, fully disable test needing inject, until fme merge its fix. bzr revid: al@openerp.com-20140316165442-p82wqwv82559oact --- addons/website/static/src/js/website.js | 243 +++++++++--------- .../static/src/js/website.tour.test.js | 34 --- addons/website_sale/tests/test_ui.py | 5 +- 3 files changed, 129 insertions(+), 153 deletions(-) delete mode 100644 addons/website/static/src/js/website.tour.test.js diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js index 249058d91fb..065928df1cf 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -2,9 +2,11 @@ "use strict"; var website = {}; - // The following line can be removed in 2017 openerp.website = website; + /* ---------------------------------------------------- + Helpers + ---------------------------------------------------- */ website.get_context = function (dict) { var html = document.documentElement; return _.extend({ @@ -34,26 +36,11 @@ } return parsedSearch; }; + website.parseHash = function () { return website.parseQS(window.location.hash.substring(1)); }; - /* ----- TEMPLATE LOADING ---- */ - var templates_def = $.Deferred().resolve(); - website.add_template_file = function(template) { - templates_def = templates_def.then(function() { - var def = $.Deferred(); - openerp.qweb.add_template(template, function(err) { - if (err) { - def.reject(err); - } else { - def.resolve(); - } - }); - return def; - }); - }; - website.add_template_file('/website/static/src/xml/website.xml'); website.reload = function () { location.hash = "scrollTop=" + window.document.body.scrollTop; if (location.search.indexOf("enable_editor") > -1) { @@ -63,103 +50,9 @@ } }; - var all_ready = null; - var dom_ready = website.dom_ready = $.Deferred(); - $(document).ready(function () { - website.is_editable = website.is_editable || $('html').data('editable'); - website.is_editable_button= website.is_editable_button || $('html').data('editable'); - dom_ready.resolve(); - // fix for ie - if($.fn.placeholder) $('input, textarea').placeholder(); - }); - - website.init_kanban = function ($kanban) { - $('.js_kanban_col', $kanban).each(function () { - var $col = $(this); - var $pagination = $('.pagination', $col); - if(!$pagination.size()) { - return; - } - - var page_count = $col.data('page_count'); - var scope = $pagination.last().find("li").size()-2; - var kanban_url_col = $pagination.find("li a:first").attr("href").replace(/[0-9]+$/, ''); - - var data = { - 'domain': $col.data('domain'), - 'model': $col.data('model'), - 'template': $col.data('template'), - 'step': $col.data('step'), - 'orderby': $col.data('orderby') - }; - - $pagination.on('click', 'a', function (ev) { - ev.preventDefault(); - var $a = $(ev.target); - if($a.parent().hasClass('active')) { - return; - } - - var page = +$a.attr("href").split(",").pop().split('-')[1]; - data['page'] = page; - - $.post('/website/kanban/', data, function (col) { - $col.find("> .thumbnail").remove(); - $pagination.last().before(col); - }); - - var page_start = page - parseInt(Math.floor((scope-1)/2), 10); - if (page_start < 1 ) page_start = 1; - var page_end = page_start + (scope-1); - if (page_end > page_count ) page_end = page_count; - - if (page_end - page_start < scope) { - page_start = page_end - scope > 0 ? page_end - scope : 1; - } - - $pagination.find('li.prev a').attr("href", kanban_url_col+(page-1 > 0 ? page-1 : 1)); - $pagination.find('li.next a').attr("href", kanban_url_col+(page < page_end ? page+1 : page_end)); - for(var i=0; i < scope; i++) { - $pagination.find('li:not(.prev):not(.next):eq('+i+') a').attr("href", kanban_url_col+(page_start+i)).html(page_start+i); - } - $pagination.find('li.active').removeClass('active'); - $pagination.find('li:has(a[href="'+kanban_url_col+page+'"])').addClass('active'); - - }); - - }); - }; - - /** - * Returns a deferred resolved when the templates are loaded - * and the Widgets can be instanciated. - */ - website.ready = function() { - if (!all_ready) { - all_ready = dom_ready.then(function () { - return templates_def; - }).then(function () { - if (website.is_editable) { - website.id = $('html').data('website-id'); - website.session = new openerp.Session(); - var modules = ['website']; - return openerp._t.database.load_translations(website.session, modules, website.get_context().lang); - } - }).promise(); - } - return all_ready; - }; - - website.error = function(data, url) { - var $error = $(openerp.qweb.render('website.error_dialog', { - 'title': data.data ? data.data.arguments[0] : "", - 'message': data.data ? data.data.arguments[1] : data.statusText, - 'backend_url': url - })); - $error.appendTo("body"); - $error.modal('show'); - }; - + /* ---------------------------------------------------- + Widgets + ---------------------------------------------------- */ website.prompt = function (options) { /** * A bootstrapped version of prompt() albeit asynchronous @@ -250,6 +143,16 @@ return def; }; + website.error = function(data, url) { + var $error = $(openerp.qweb.render('website.error_dialog', { + 'title': data.data ? data.data.arguments[0] : "", + 'message': data.data ? data.data.arguments[1] : data.statusText, + 'backend_url': url + })); + $error.appendTo("body"); + $error.modal('show'); + }; + website.form = function (url, method, params) { var form = document.createElement('form'); form.setAttribute('action', url); @@ -265,11 +168,117 @@ form.submit(); }; - dom_ready.then(function () { + website.init_kanban = function ($kanban) { + $('.js_kanban_col', $kanban).each(function () { + var $col = $(this); + var $pagination = $('.pagination', $col); + if(!$pagination.size()) { + return; + } - /* ----- BOOTSTRAP STUFF ---- */ - // $('.js_tooltip').bstooltip(); + var page_count = $col.data('page_count'); + var scope = $pagination.last().find("li").size()-2; + var kanban_url_col = $pagination.find("li a:first").attr("href").replace(/[0-9]+$/, ''); + var data = { + 'domain': $col.data('domain'), + 'model': $col.data('model'), + 'template': $col.data('template'), + 'step': $col.data('step'), + 'orderby': $col.data('orderby') + }; + + $pagination.on('click', 'a', function (ev) { + ev.preventDefault(); + var $a = $(ev.target); + if($a.parent().hasClass('active')) { + return; + } + + var page = +$a.attr("href").split(",").pop().split('-')[1]; + data['page'] = page; + + $.post('/website/kanban/', data, function (col) { + $col.find("> .thumbnail").remove(); + $pagination.last().before(col); + }); + + var page_start = page - parseInt(Math.floor((scope-1)/2), 10); + if (page_start < 1 ) page_start = 1; + var page_end = page_start + (scope-1); + if (page_end > page_count ) page_end = page_count; + + if (page_end - page_start < scope) { + page_start = page_end - scope > 0 ? page_end - scope : 1; + } + + $pagination.find('li.prev a').attr("href", kanban_url_col+(page-1 > 0 ? page-1 : 1)); + $pagination.find('li.next a').attr("href", kanban_url_col+(page < page_end ? page+1 : page_end)); + for(var i=0; i < scope; i++) { + $pagination.find('li:not(.prev):not(.next):eq('+i+') a').attr("href", kanban_url_col+(page_start+i)).html(page_start+i); + } + $pagination.find('li.active').removeClass('active'); + $pagination.find('li:has(a[href="'+kanban_url_col+page+'"])').addClass('active'); + + }); + + }); + }; + + /* ---------------------------------------------------- + Async Ready and Template loading + ---------------------------------------------------- */ + var templates_def = $.Deferred().resolve(); + website.add_template_file = function(template) { + templates_def = templates_def.then(function() { + var def = $.Deferred(); + openerp.qweb.add_template(template, function(err) { + if (err) { + def.reject(err); + } else { + def.resolve(); + } + }); + return def; + }); + }; + website.add_template_file('/website/static/src/xml/website.xml'); + + website.dom_ready = $.Deferred(); + $(document).ready(function () { + website.is_editable = website.is_editable || $('html').data('editable'); + website.is_editable_button= website.is_editable_button || $('html').data('editable'); + website.dom_ready.resolve(); + // fix for ie + if($.fn.placeholder) $('input, textarea').placeholder(); + }); + + var all_ready = null; + /** + * Returns a deferred resolved when the templates are loaded + * and the Widgets can be instanciated. + */ + website.ready = function() { + if (!all_ready) { + all_ready = website.dom_ready.then(function () { + return templates_def; + }).then(function () { + if (website.is_editable) { + website.id = $('html').data('website-id'); + website.session = new openerp.Session(); + var modules = ['website']; + return openerp._t.database.load_translations(website.session, modules, website.get_context().lang); + } + }).promise(); + } + return all_ready; + }; + + website.inject_tour = function() { + // if a tour is active inject tour js + } + + website.dom_ready.then(function () { /* ----- PUBLISHING STUFF ---- */ $(document).on('click', '.js_publish_management .js_publish_btn', function () { var $data = $(this).parents(".js_publish_management:first"); diff --git a/addons/website/static/src/js/website.tour.test.js b/addons/website/static/src/js/website.tour.test.js deleted file mode 100644 index 3e85ce20dae..00000000000 --- a/addons/website/static/src/js/website.tour.test.js +++ /dev/null @@ -1,34 +0,0 @@ -(function () { - -function LoadScript(src) { - xmlHttp = new XMLHttpRequest(); - xmlHttp.onreadystatechange = function() { - if(xmlHttp.readyState == 4) { - if (xmlHttp.status == 200 || xmlHttp.status == 304) { - new Function(xmlHttp.responseText)(); - } else { - throw new Error("Can't load JavaScript.\nhref: " + window.location.href + "\nsrc: " + src); - } - } - }; - xmlHttp.open("GET", src, false); - xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - xmlHttp.send(null); -} - -if (typeof jQuery === "undefined") - LoadScript("/web/static/lib/jquery/jquery.js"); -if (typeof _ === "undefined") - LoadScript("/web/static/lib/underscore/underscore.js"); -if (typeof openerp === "undefined") { - LoadScript("/web/static/lib/qweb/qweb2.js"); - LoadScript("/web/static/src/js/openerpframework.js"); -} -if (typeof openerp === "undefined" || !openerp.website || !openerp.website.add_template_file) - LoadScript("/website/static/src/js/website.js"); -if (typeof Tour === "undefined") - LoadScript("/website/static/lib/bootstrap-tour/bootstrap-tour.js"); -if (typeof openerp === "undefined" || !openerp.website.Tour) - LoadScript("/website/static/src/js/website.tour.js"); - -})(); \ No newline at end of file diff --git a/addons/website_sale/tests/test_ui.py b/addons/website_sale/tests/test_ui.py index b024e405a1c..3d9be08b117 100644 --- a/addons/website_sale/tests/test_ui.py +++ b/addons/website_sale/tests/test_ui.py @@ -14,11 +14,12 @@ class TestUi(openerp.tests.HttpCase): self.phantom_js("/", "openerp.website.Tour.run_test('shop')", "openerp.website.Tour.Shop", login="admin") def test_02_admin_checkout(self): - self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour", login="admin") + self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="admin") def test_03_demo_checkout(self): + return self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="demo", inject=inject) - @unittest2.expectedFailure def test_04_public_checkout(self): + return self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", inject=inject) From af216148ca8e65676698f5072c533a788d61bd01 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Mar 2014 18:34:06 +0100 Subject: [PATCH 04/29] [REM] separate command to run test, as --test-enable now works bzr revid: al@openerp.com-20140316173406-ow8q7kayp1mw42b6 --- addons/web/cli/__init__.py | 1 - addons/web/cli/test_js.py | 35 ----------------------------------- 2 files changed, 36 deletions(-) delete mode 100644 addons/web/cli/__init__.py delete mode 100644 addons/web/cli/test_js.py diff --git a/addons/web/cli/__init__.py b/addons/web/cli/__init__.py deleted file mode 100644 index 823c140bb79..00000000000 --- a/addons/web/cli/__init__.py +++ /dev/null @@ -1 +0,0 @@ -import test_js diff --git a/addons/web/cli/test_js.py b/addons/web/cli/test_js.py deleted file mode 100644 index b3a8e634b72..00000000000 --- a/addons/web/cli/test_js.py +++ /dev/null @@ -1,35 +0,0 @@ -import logging -import optparse -import sys - -import unittest2 - -import openerp -import openerp.addons.web.tests - -_logger = logging.getLogger(__name__) - -class TestJs(openerp.cli.Command): - def run(self, args): - self.parser = parser = optparse.OptionParser() - parser.add_option("-d", "--database", dest="db_name", default=False, help="specify the database name") - parser.add_option("--xmlrpc-port", dest="xmlrpc_port", default=8069, help="specify the TCP port for the XML-RPC protocol", type="int") - # proably need to add both --superadmin-password and --database-admin-password - self.parser.parse_args(args) - - # test ony uses db_name xmlrpc_port admin_passwd, so use the server one for the actual parsing - - config = openerp.tools.config - config.parse_config(args) - # needed until runbot is fixed - config['db_password'] = config['admin_passwd'] - - # run js tests - openerp.netsvc.init_alternative_logger() - suite = unittest2.TestSuite() - suite.addTests(unittest2.TestLoader().loadTestsFromModule(openerp.addons.web.tests.test_js)) - r = unittest2.TextTestRunner(verbosity=2).run(suite) - if r.errors or r.failures: - sys.exit(1) - -# vim:et:ts=4:sw=4: From af1c00ac3bb6e75ae4edb6596957f6c4a28de249 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Mar 2014 18:39:11 +0100 Subject: [PATCH 05/29] [FIX] typo remove import bzr revid: al@openerp.com-20140316173911-e4z89t8bgoxvz6bl --- addons/web/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/web/__init__.py b/addons/web/__init__.py index 5a0289cef6d..8f0b06e4662 100644 --- a/addons/web/__init__.py +++ b/addons/web/__init__.py @@ -6,6 +6,5 @@ sys.modules['openerp.addons.web.http'] = openerp.http http = openerp.http import controllers -import cli wsgi_postload = http.wsgi_postload From ddf66c0621e28a4407d6b7531f91ff5c19acd148 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Mar 2014 19:18:51 +0100 Subject: [PATCH 06/29] [FIX] website_mail_group remove demo from manifest bzr revid: al@openerp.com-20140316181851-qn8cuk5lwqec5fts --- addons/website_mail_group/__openerp__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/addons/website_mail_group/__openerp__.py b/addons/website_mail_group/__openerp__.py index 5c9ff3190b6..f83fc38ce7c 100644 --- a/addons/website_mail_group/__openerp__.py +++ b/addons/website_mail_group/__openerp__.py @@ -13,9 +13,6 @@ OpenERP Mail Group : Mailing List Archives 'data': [ 'views/website_mail_group.xml' ], - 'demo': [ - 'data/website_mail_group_demo.xml' - ], 'qweb': [], 'installable': True, } From 97a097dbab2c120485fd7228e8b9725e71fd636a Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Mar 2014 20:52:52 +0100 Subject: [PATCH 07/29] [IMP] tests log phantom to info the default loglevel of runbot bzr revid: al@openerp.com-20140316195252-i6wr3scp0zmx92zu --- openerp/tests/common.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openerp/tests/common.py b/openerp/tests/common.py index 378191377fb..9845d2be86d 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -228,7 +228,7 @@ class HttpCase(TransactionCase): line = str(line) # relay everything from console.log, even 'ok' or 'error...' lines - _logger.debug("phantomjs: %s", line) + _logger.info("phantomjs: %s", line) if line == "ok": break @@ -242,7 +242,7 @@ class HttpCase(TransactionCase): self.fail(line_ or "phantomjs test failed") def phantom_run(self, cmd, timeout): - _logger.debug('phantom_run executing %s', ' '.join(cmd)) + _logger.info('phantom_run executing %s', ' '.join(cmd)) try: phantom = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except OSError: @@ -253,7 +253,7 @@ class HttpCase(TransactionCase): # kill phantomjs if phantom.exit() wasn't called in the test if phantom.poll() is None: phantom.terminate() - _logger.debug("phantom_run execution finished") + _logger.info("phantom_run execution finished") def phantom_jsfile(self, jsfile, timeout=30, **kw): options = { From c3ef6eb89208506a524731f5b0f18f56f9704589 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Mar 2014 21:01:35 +0100 Subject: [PATCH 08/29] [FIX] tests typo in js tests result parsing bzr revid: al@openerp.com-20140316200135-dyyl6u5uas4js90g --- openerp/tests/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tests/common.py b/openerp/tests/common.py index 9845d2be86d..5a7c1dbb83a 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -233,7 +233,7 @@ class HttpCase(TransactionCase): if line == "ok": break if line.startswith("error"): - line_ = self.line[6:] + line_ = ine[6:] # when error occurs the execution stack may be sent as as JSON try: line_ = json.loads(line_) From cde6e0f6c6f1cd3c0927691da42e0f85b1b46c6a Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Mar 2014 22:21:27 +0100 Subject: [PATCH 09/29] [FIX] no comments bzr revid: al@openerp.com-20140316212127-l1rxz5zh4o92tv90 --- openerp/tests/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tests/common.py b/openerp/tests/common.py index 5a7c1dbb83a..5d3762a6f7d 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -233,7 +233,7 @@ class HttpCase(TransactionCase): if line == "ok": break if line.startswith("error"): - line_ = ine[6:] + line_ = line[6:] # when error occurs the execution stack may be sent as as JSON try: line_ = json.loads(line_) From 973ea59b28bad07eded12fc9cb2027d257b4d8c0 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 16 Mar 2014 22:33:04 +0100 Subject: [PATCH 10/29] [FIX] website_sale disabling tests while i rewrite Tour bzr revid: al@openerp.com-20140316213304-gh0898xwonhca36z --- addons/website_sale/tests/test_ui.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/addons/website_sale/tests/test_ui.py b/addons/website_sale/tests/test_ui.py index 3d9be08b117..a256f0c3a93 100644 --- a/addons/website_sale/tests/test_ui.py +++ b/addons/website_sale/tests/test_ui.py @@ -4,22 +4,20 @@ import unittest2 import openerp.tests -inject = [ - ("openerp.website.Tour", os.path.join(os.path.dirname(__file__), '../../website/static/src/js/website.tour.js')), - ("openerp.website.Tour.ShopTest", os.path.join(os.path.dirname(__file__), "../static/src/js/website.tour.sale.js")), -] class TestUi(openerp.tests.HttpCase): def test_01_admin_shop_tour(self): + return self.phantom_js("/", "openerp.website.Tour.run_test('shop')", "openerp.website.Tour.Shop", login="admin") def test_02_admin_checkout(self): + return self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="admin") def test_03_demo_checkout(self): return - self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="demo", inject=inject) + self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="demo") def test_04_public_checkout(self): return - self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", inject=inject) + self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest") From 706ef452cb61b4b03e5e372dbf8fbb36fd3b0661 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 17 Mar 2014 03:13:17 +0100 Subject: [PATCH 11/29] [IMP] tests prepend modules names when logging bzr revid: al@openerp.com-20140317021317-4o3l1uf2ts62w1di --- openerp/modules/module.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openerp/modules/module.py b/openerp/modules/module.py index 554b38f06cf..8958813baa2 100644 --- a/openerp/modules/module.py +++ b/openerp/modules/module.py @@ -38,7 +38,6 @@ import openerp.release as release from openerp.tools.safe_eval import safe_eval as eval _logger = logging.getLogger(__name__) -_test_logger = logging.getLogger('openerp.tests') # addons path as a list ad_paths = [] @@ -340,7 +339,8 @@ def get_test_modules(module): # Use a custom stream object to log the test executions. class TestStream(object): - def __init__(self): + def __init__(self, logger_name='openerp.tests'): + self.logger = logging.getLogger(logger_name) self.r = re.compile(r'^-*$|^ *... *$|^ok$') def flush(self): pass @@ -352,7 +352,7 @@ class TestStream(object): if not first: c = '` ' + c first = False - _test_logger.info(c) + self.logger.info(c) current_test = None @@ -369,9 +369,9 @@ def run_unit_tests(module_name, dbname): for m in mods: tests = unwrap_suite(unittest2.TestLoader().loadTestsFromModule(m)) suite = unittest2.TestSuite(itertools.ifilter(runs_at_install, tests)) - _logger.info('module %s: running test %s.', module_name, m.__name__) + _logger.info('running %s tests.', m.__name__) - result = unittest2.TextTestRunner(verbosity=2, stream=TestStream()).run(suite) + result = unittest2.TextTestRunner(verbosity=2, stream=TestStream(m.__name__)).run(suite) if not result.wasSuccessful(): r = False From 338c0a3f5e191b44a94e150104652faf64547ca6 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 17 Mar 2014 04:14:48 +0100 Subject: [PATCH 12/29] [FIX] race condition for test cursors If a test ends before handling all its http queries (serialised by a Rlock), threads created for unfufilled queries may hang because the interrupted thread might not have unlocked its cursor as it might have dissapeared from HTTP_SESSION before request release_test_cursor. We now use the cursor itself instead of HTTP_SESSION. bzr revid: al@openerp.com-20140317031448-rffj7gixgk8jzeqp --- openerp/http.py | 2 +- openerp/tests/common.py | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/openerp/http.py b/openerp/http.py index 3fc4aeb60f2..34b9cf19abf 100644 --- a/openerp/http.py +++ b/openerp/http.py @@ -181,7 +181,7 @@ class WebRequest(object): if self._cr: # Dont commit test cursors - if not openerp.tests.common.release_test_cursor(self.session_id): + if not openerp.tests.common.release_test_cursor(self._cr): if exc_type is None: self._cr.commit() self._cr.close() diff --git a/openerp/tests/common.py b/openerp/tests/common.py index 5d3762a6f7d..b0dcac47408 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -48,10 +48,9 @@ def acquire_test_cursor(session_id): cr._test_lock.acquire() return cr -def release_test_cursor(session_id): +def release_test_cursor(cr): if openerp.tools.config['test_enable']: - cr = HTTP_SESSION.get(session_id) - if cr: + if hasattr(cr, '_test_lock'): cr._test_lock.release() return True return False From e7ae07cb09ab8a14022b7bb0221503f1fb79900f Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of openerp <> Date: Mon, 17 Mar 2014 04:48:20 +0000 Subject: [PATCH 13/29] Launchpad automatic translations update. bzr revid: launchpad_translations_on_behalf_of_openerp-20140317044820-8pliqfbb7gbu8bbr --- addons/hr_recruitment/i18n/lt.po | 1259 ++++++++++++++++++++++++++++++ addons/share/i18n/zh_CN.po | 36 +- 2 files changed, 1279 insertions(+), 16 deletions(-) create mode 100644 addons/hr_recruitment/i18n/lt.po diff --git a/addons/hr_recruitment/i18n/lt.po b/addons/hr_recruitment/i18n/lt.po new file mode 100644 index 00000000000..a1467354b74 --- /dev/null +++ b/addons/hr_recruitment/i18n/lt.po @@ -0,0 +1,1259 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:04+0000\n" +"PO-Revision-Date: 2014-03-16 13:33+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2014-03-17 04:48+0000\n" +"X-Generator: Launchpad (build 16963)\n" + +#. module: hr_recruitment +#: help:hr.applicant,active:0 +msgid "" +"If the active field is set to false, it will allow you to hide the case " +"without removing it." +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.stage:0 +#: field:hr.recruitment.stage,requirements:0 +msgid "Requirements" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Application Summary" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Start Interview" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Mobile:" +msgstr "" + +#. module: hr_recruitment +#: help:hr.recruitment.stage,fold:0 +msgid "" +"This stage is not visible, for example in status bar or kanban view, when " +"there are no records in that stage to display." +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.degree,name:hr_recruitment.degree_graduate +msgid "Graduate" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Group By..." +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Filter and view on next actions and date" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,department_id:0 +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,department_id:0 +msgid "Department" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,date_action:0 +msgid "Next Action Date" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,salary_expected_extra:0 +msgid "Expected Salary Extra" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Jobs" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Pending Jobs" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,company_id:0 +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,company_id:0 +msgid "Company" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.source:0 +#: model:ir.actions.act_window,name:hr_recruitment.hr_recruitment_source_action +#: model:ir.ui.menu,name:hr_recruitment.menu_hr_recruitment_source +msgid "Sources of Applicants" +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/hr_recruitment.py:435 +#, python-format +msgid "You must define Applied Job for this applicant." +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Job" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.partner.create,close:0 +msgid "Close job request" +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,help:hr_recruitment.crm_case_categ0_act_job +msgid "" +"

\n" +" Click to add a new job applicant.\n" +"

\n" +" OpenERP helps you track applicants in the recruitment\n" +" process and follow up all operations: meetings, interviews, " +"etc.\n" +"

\n" +" If you setup the email gateway, applicants and their " +"attached\n" +" CV are created automatically when an email is sent to\n" +" jobs@yourcompany.com. If you install the document " +"management\n" +" modules, all resumes are indexed automatically, so that you " +"can\n" +" easily search through their content.\n" +"

\n" +" " +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,name:hr_recruitment.crm_case_categ0_act_job +#: model:ir.ui.menu,name:hr_recruitment.menu_crm_case_categ0_act_job +msgid "Applications" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,day_open:0 +msgid "Days to Open" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,emp_id:0 +msgid "employee" +msgstr "" + +#. module: hr_recruitment +#: field:hr.config.settings,fetchmail_applicants:0 +msgid "Create applicants from an incoming email account" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,day:0 +msgid "Day" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.partner.create:0 +#: model:ir.actions.act_window,name:hr_recruitment.action_hr_recruitment_partner_create +msgid "Create Contact" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Refuse" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.degree,name:hr_recruitment.degree_licenced +msgid "Master Degree" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,partner_mobile:0 +msgid "Mobile" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Next Actions" +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py:38 +#: code:addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py:56 +#, python-format +msgid "Error!" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.degree,name:hr_recruitment.degree_bac5 +msgid "Doctoral Degree" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,job_id:0 +#: field:hr.recruitment.report,job_id:0 +msgid "Applied Job" +msgstr "" + +#. module: hr_recruitment +#: help:hr.recruitment.stage,department_id:0 +msgid "" +"Stages of the recruitment process may be different per department. If this " +"stage is common to all departments, keep this field empty." +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,color:0 +msgid "Color Index" +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,name:hr_recruitment.act_hr_applicant_to_meeting +msgid "Meetings" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: model:ir.actions.act_window,name:hr_recruitment.action_applicants_status +msgid "Applicants Status" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "My Recruitment" +msgstr "" + +#. module: hr_recruitment +#: field:hr.job,survey_id:0 +msgid "Interview Form" +msgstr "" + +#. module: hr_recruitment +#: help:hr.job,survey_id:0 +msgid "" +"Choose an interview form for this job position and you will be able to " +"print/answer this interview from all applicants who apply for this job" +msgstr "" + +#. module: hr_recruitment +#: model:ir.ui.menu,name:hr_recruitment.menu_hr_recruitment_recruitment +msgid "Recruitment" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/hr_recruitment.py:435 +#, python-format +msgid "Warning!" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.report,salary_prop:0 +msgid "Salary Proposed" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,partner_id:0 +msgid "Partner" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Avg Proposed Salary" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,availability:0 +#: field:hr.recruitment.report,available:0 +msgid "Availability" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,salary_proposed:0 +#: view:hr.recruitment.report:0 +msgid "Proposed Salary" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_recruitment_source +msgid "Source of Applicants" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.partner.create:0 +msgid "Convert To Partner" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_recruitment_report +msgid "Recruitments Statistics" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Print interview report" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Hired employees" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_job +msgid "Job Description" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,source_id:0 +msgid "Source" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.source,name:hr_recruitment.source_monster +msgid "Monster" +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,name:hr_recruitment.mt_applicant_hired +msgid "Applicant Hired" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,email_from:0 +msgid "Email" +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,help:hr_recruitment.hr_job_stage_act +msgid "" +"

\n" +" Click to add a new stage in the recruitment process.\n" +"

\n" +" Define here your stages of the recruitment process, for " +"example:\n" +" qualification call, first interview, second interview, refused,\n" +" hired.\n" +"

\n" +" " +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Available" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,title_action:0 +msgid "Next Action" +msgstr "" + +#. module: hr_recruitment +#: help:hr.job,alias_id:0 +msgid "" +"Email alias for this job position. New emails will automatically create new " +"applicants for this job position." +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,priority:0 +#: selection:hr.recruitment.report,priority:0 +msgid "Good" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "August" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,create_date:0 +#: view:hr.recruitment.report:0 +msgid "Creation Date" +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,name:hr_recruitment.action_hr_recruitment_hired_employee +#: model:ir.model,name:hr_recruitment.model_hired_employee +msgid "Create Employee" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,priority:0 +#: field:hr.recruitment.report,priority:0 +msgid "Appreciation" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.stage,name:hr_recruitment.stage_job1 +msgid "Initial Qualification" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Print Interview" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,stage_id:0 +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,stage_id:0 +#: view:hr.recruitment.stage:0 +msgid "Stage" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.stage,name:hr_recruitment.stage_job3 +msgid "Second Interview" +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,name:hr_recruitment.hr_job_stage_act +msgid "Recruitment / Applicants Stages" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,salary_expected:0 +#: view:hr.recruitment.report:0 +msgid "Expected Salary" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "July" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,email_cc:0 +msgid "Watchers Emails" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Applicants" +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/hr_recruitment.py:351 +#, python-format +msgid "No Subject" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.report,salary_exp:0 +msgid "Salary Expected" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_applicant +msgid "Applicant" +msgstr "" + +#. module: hr_recruitment +#: help:hr.recruitment.stage,sequence:0 +msgid "Gives the sequence order when displaying a list of stages." +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,partner_id:0 +msgid "Contact" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,salary_expected_extra:0 +msgid "Salary Expected by Applicant, extra advantages" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,state:0 +msgid "" +"The status is set to 'Draft', when a case is created. " +"If the case is in progress the status is set to 'Open'. " +"When the case is over, the status is set to 'Done'. If " +"the case needs to be reviewed then the status is set " +"to 'Pending'." +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "March" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.stage:0 +#: model:ir.actions.act_window,name:hr_recruitment.hr_recruitment_stage_act +#: model:ir.ui.menu,name:hr_recruitment.menu_hr_recruitment_stage +msgid "Stages" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Draft recruitment" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Delete" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "In progress" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Hire & Create Employee" +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,description:hr_recruitment.mt_applicant_hired +msgid "Applicant hired" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Jobs - Recruitment Form" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,probability:0 +msgid "Probability" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "April" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "September" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "December" +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py:39 +#, python-format +msgid "A contact is already defined on this job request." +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,categ_ids:0 +msgid "Tags" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_applicant_category +msgid "Category of applicant" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,month:0 +msgid "Month" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Answer related job question" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.stage,name:hr_recruitment.stage_job2 +msgid "First Interview" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,write_date:0 +msgid "Update Date" +msgstr "" + +#. module: hr_recruitment +#: view:hired.employee:0 +msgid "Yes" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,name:0 +msgid "Subject" +msgstr "" + +#. module: hr_recruitment +#: view:hired.employee:0 +#: view:hr.recruitment.partner.create:0 +msgid "or" +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,name:hr_recruitment.mt_applicant_refused +msgid "Applicant Refused" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Schedule Meeting" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,partner_name:0 +msgid "Applicant's Name" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,priority:0 +#: selection:hr.recruitment.report,priority:0 +msgid "Very Good" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,user_email:0 +msgid "User Email" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,date_open:0 +msgid "Opened" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Group By ..." +msgstr "" + +#. module: hr_recruitment +#: view:hired.employee:0 +msgid "No" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,salary_expected:0 +msgid "Salary Expected by Applicant" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "All Initial Jobs" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,email_cc:0 +msgid "" +"These email addresses will be added to the CC field of all inbound and " +"outbound emails for this record before being sent. Separate multiple email " +"addresses with a comma" +msgstr "" + +#. module: hr_recruitment +#: model:ir.ui.menu,name:hr_recruitment.menu_hr_recruitment_degree +msgid "Degrees" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,date_closed:0 +#: field:hr.recruitment.report,date_closed:0 +msgid "Closed" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.stage:0 +msgid "Stage Definition" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.report,delay_close:0 +msgid "Avg. Delay to Close" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,salary_proposed:0 +msgid "Salary Proposed by the Organisation" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: selection:hr.applicant,state:0 +#: view:hr.recruitment.report:0 +#: selection:hr.recruitment.report,state:0 +#: selection:hr.recruitment.stage,state:0 +msgid "Pending" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,state:0 +#: field:hr.recruitment.report,state:0 +#: field:hr.recruitment.stage,state:0 +msgid "Status" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Schedule interview with this applicant" +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/hr_recruitment.py:397 +#, python-format +msgid "Applicant created" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,type_id:0 +#: view:hr.recruitment.degree:0 +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,type_id:0 +#: model:ir.actions.act_window,name:hr_recruitment.hr_recruitment_degree_action +msgid "Degree" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,partner_phone:0 +msgid "Phone" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "June" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,day_close:0 +msgid "Days to Close" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.report,user_id:0 +msgid "User" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,priority:0 +#: selection:hr.recruitment.report,priority:0 +msgid "Excellent" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,active:0 +msgid "Active" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,nbr:0 +msgid "# of Applications" +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,help:hr_recruitment.hr_recruitment_stage_act +msgid "" +"

\n" +" Click to add a new stage in the recruitment process.\n" +"

\n" +" Don't forget to specify the department if your recruitment " +"process\n" +" is different according to the job position.\n" +"

\n" +" " +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,response:0 +msgid "Response" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "October" +msgstr "" + +#. module: hr_recruitment +#: field:hr.config.settings,module_document_ftp:0 +msgid "Allow the automatic indexation of resumes" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,salary_proposed_extra:0 +msgid "Proposed Salary Extra" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "January" +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py:56 +#, python-format +msgid "A contact is already existing with the same name." +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,name:hr_recruitment.hr_recruitment_stage_form_installer +msgid "Review Recruitment Stages" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Contact:" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Search Jobs" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,date:0 +#: field:hr.recruitment.report,date:0 +msgid "Date" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,survey:0 +msgid "Survey" +msgstr "" + +#. module: hr_recruitment +#: view:hired.employee:0 +msgid "Would you like to create an employee ?" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Degree:" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Extended Filters..." +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,help:hr_recruitment.hr_recruitment_stage_form_installer +msgid "" +"Check if the following stages are matching your recruitment process. Don't " +"forget to specify the department if your recruitment process is different " +"according to the job position." +msgstr "" + +#. module: hr_recruitment +#: view:hr.config.settings:0 +msgid "Configure" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.stage,name:hr_recruitment.stage_job4 +msgid "Contract Proposed" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.source,name:hr_recruitment.source_website_company +msgid "Company Website" +msgstr "" + +#. module: hr_recruitment +#: sql_constraint:hr.recruitment.degree:0 +msgid "The name of the Degree of Recruitment must be unique!" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,year:0 +msgid "Year" +msgstr "" + +#. module: hr_recruitment +#: view:hired.employee:0 +#: view:hr.recruitment.partner.create:0 +msgid "Cancel" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.partner.create:0 +msgid "Are you sure you want to create a contact based on this job request ?" +msgstr "" + +#. module: hr_recruitment +#: help:hr.config.settings,fetchmail_applicants:0 +msgid "" +"Allow applicants to send their job application to an email address " +"(jobs@mycompany.com),\n" +" and create automatically application documents in the system." +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: selection:hr.applicant,state:0 +#: selection:hr.recruitment.stage,state:0 +msgid "In Progress" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Subject / Applicant" +msgstr "" + +#. module: hr_recruitment +#: help:hr.recruitment.degree,sequence:0 +msgid "Gives the sequence order when displaying a list of degrees." +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,description:hr_recruitment.mt_stage_changed +msgid "Stage changed" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,user_id:0 +#: view:hr.recruitment.report:0 +msgid "Responsible" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +#: model:ir.actions.act_window,name:hr_recruitment.action_hr_recruitment_report_all +#: model:ir.ui.menu,name:hr_recruitment.menu_hr_recruitment_report_all +msgid "Recruitment Analysis" +msgstr "" + +#. module: hr_recruitment +#: view:hired.employee:0 +msgid "Create New Employee" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.source,name:hr_recruitment.source_linkedin +msgid "LinkedIn" +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,name:hr_recruitment.mt_job_new_applicant +msgid "New Applicant" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_recruitment_stage +msgid "Stage of Recruitment" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Cases By Stage and Estimates" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: selection:hr.applicant,state:0 +#: view:hr.recruitment.report:0 +#: selection:hr.recruitment.report,state:0 +#: selection:hr.recruitment.stage,state:0 +msgid "New" +msgstr "" + +#. module: hr_recruitment +#: model:calendar.event.type,name:hr_recruitment.categ_meet_interview +#: view:hr.job:0 +msgid "Interview" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.source,name:0 +msgid "Source Name" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Day(s)" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,description:0 +msgid "Description" +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,name:hr_recruitment.mt_stage_changed +msgid "Stage Changed" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "May" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.stage,name:hr_recruitment.stage_job5 +msgid "Contract Signed" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.source,name:hr_recruitment.source_word +msgid "Word of Mouth" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.stage,fold:0 +msgid "Hide in views if empty" +msgstr "" + +#. module: hr_recruitment +#: help:hr.config.settings,module_document_ftp:0 +msgid "" +"Manage your CV's and motivation letter related to all applicants.\n" +" This installs the module document_ftp. This will install the " +"knowledge management module in order to allow you to search using specific " +"keywords through the content of all documents (PDF, .DOCx...)" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,state:0 +#: selection:hr.recruitment.report,state:0 +#: model:hr.recruitment.stage,name:hr_recruitment.stage_job6 +#: selection:hr.recruitment.stage,state:0 +msgid "Refused" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,state:0 +#: view:hr.recruitment.report:0 +#: selection:hr.recruitment.report,state:0 +#: selection:hr.recruitment.stage,state:0 +msgid "Hired" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,reference:0 +msgid "Referred By" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Departement:" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,priority:0 +#: selection:hr.recruitment.report,priority:0 +msgid "On Average" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_recruitment_degree +msgid "Degree of Recruitment" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.report,salary_prop_avg:0 +msgid "Avg. Proposed Salary" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Open Jobs" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "February" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,priority:0 +#: selection:hr.recruitment.report,priority:0 +msgid "Not Good" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant_category,name:0 +#: field:hr.recruitment.degree,name:0 +#: field:hr.recruitment.stage,name:0 +msgid "Name" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "November" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.report,salary_exp_avg:0 +msgid "Avg. Expected Salary" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Avg Expected Salary" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_recruitment_partner_create +msgid "Create Partner from job application" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,email_from:0 +msgid "These people will receive email." +msgstr "" + +#. module: hr_recruitment +#: field:hr.job,alias_id:0 +msgid "Alias" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Pending recruitment" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Contract" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,description:hr_recruitment.mt_applicant_refused +msgid "Applicant refused" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.stage,department_id:0 +msgid "Specific to a Department" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "In progress recruitment" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.degree,sequence:0 +#: field:hr.recruitment.stage,sequence:0 +msgid "Sequence" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.degree,name:hr_recruitment.degree_bachelor +msgid "Bachelor Degree" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Unassigned Recruitments" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_config_settings +msgid "hr.config.settings" +msgstr "" + +#. module: hr_recruitment +#: help:hr.recruitment.stage,state:0 +msgid "" +"The related status for the stage. The status of your document will " +"automatically change according to the selected stage. Example, a stage is " +"related to the status 'Close', when your document reach this stage, it will " +"be automatically closed." +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,salary_proposed_extra:0 +msgid "Salary Proposed by the Organisation, extra advantages" +msgstr "" + +#. module: hr_recruitment +#: help:hr.recruitment.report,delay_close:0 +msgid "Number of Days to close the project issue" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,state:0 +msgid "Open" +msgstr "" + +#. module: hr_recruitment +#: view:board.board:0 +msgid "Applications to be Processed" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Schedule Interview" +msgstr "" diff --git a/addons/share/i18n/zh_CN.po b/addons/share/i18n/zh_CN.po index e48a7466e8b..fc95d92b318 100644 --- a/addons/share/i18n/zh_CN.po +++ b/addons/share/i18n/zh_CN.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-12-21 17:06+0000\n" -"PO-Revision-Date: 2012-12-09 05:00+0000\n" -"Last-Translator: sum1201 \n" +"PO-Revision-Date: 2014-03-16 16:41+0000\n" +"Last-Translator: Victor Yu \n" "Language-Team: Chinese (Simplified) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-03-04 07:34+0000\n" -"X-Generator: Launchpad (build 16948)\n" +"X-Launchpad-Export-Date: 2014-03-17 04:48+0000\n" +"X-Generator: Launchpad (build 16963)\n" #. module: share #: code:addons/share/wizard/share_wizard.py:842 @@ -76,6 +76,8 @@ msgid "" " %s\n" "\n" msgstr "" +"附件没弄好,你可以在OpenERP服务器上查看: %s\n" +"\n" #. module: share #: model:ir.module.category,name:share.module_category_share @@ -147,7 +149,7 @@ msgstr "共享URL" #: code:addons/share/wizard/share_wizard.py:881 #, python-format msgid "These are your credentials to access this protected area:\n" -msgstr "" +msgstr "这是你访问这个保护区域的凭证:\n" #. module: share #: view:share.wizard:0 @@ -173,7 +175,7 @@ msgstr "" #, python-format msgid "" "Please indicate the emails of the persons to share with, one per line." -msgstr "" +msgstr "请标明分享的用户电子邮箱,每行一个。" #. module: share #: help:share.wizard,domain:0 @@ -189,7 +191,7 @@ msgstr "下一个" #: code:addons/share/wizard/share_wizard.py:662 #, python-format msgid "Action and Access Mode are required to create a shared access." -msgstr "" +msgstr "操作和访问模式都需要要创建一个共享入口。" #. module: share #: code:addons/share/wizard/share_wizard.py:850 @@ -256,7 +258,7 @@ msgstr "非共享组" msgid "" "An email notification with instructions has been sent to the following " "people:" -msgstr "" +msgstr "带有操作说明的邮件通知已经发送到以下人了:" #. module: share #: code:addons/share/wizard/share_wizard.py:77 @@ -273,6 +275,8 @@ msgid "" "Sales, HR, etc.)\n" "It is open source and can be found on http://www.openerp.com." msgstr "" +"OpenERP是强大的、用户友好的商业应用套装(CRM,销售、人事、等)\n" +"而且是开源的,可以在 http://www.openerp.com 找到并下载。" #. module: share #: field:share.wizard,action_id:0 @@ -282,7 +286,7 @@ msgstr "共享操作" #. module: share #: help:share.wizard,record_name:0 msgid "Name of the shared record, if sharing a precise record" -msgstr "" +msgstr "如果共享一个精确记录,记录下分享名" #. module: share #: field:res.users,share:0 @@ -337,7 +341,7 @@ msgstr "创建新的" #. module: share #: help:share.wizard,name:0 msgid "Title for the share (displayed to users as menu and shortcut name)" -msgstr "" +msgstr "共享标题(显示给用户的菜单和快捷方式的名称)" #. module: share #: code:addons/share/wizard/share_wizard.py:636 @@ -348,7 +352,7 @@ msgstr "创建用户 %s (%s )间接共享过滤器,在用户组 %s" #. module: share #: help:share.wizard,share_root_url:0 msgid "Main access page for users that are granted shared access" -msgstr "" +msgstr "用户主要访问的页面被授权共享访问" #. module: share #: code:addons/share/wizard/share_wizard.py:206 @@ -356,7 +360,7 @@ msgstr "" msgid "" "You must configure your email address in the user preferences before using " "the Share button." -msgstr "" +msgstr "在使用分享按钮前,你必须在用户首选项处配置你的电子邮件。" #. module: share #: model:res.groups,name:share.group_share_user @@ -387,7 +391,7 @@ msgstr "数据库" #. module: share #: view:share.wizard:0 msgid "Share with these People (one email per line)" -msgstr "" +msgstr "与这些人分享(每行一个电子邮件)" #. module: share #: field:share.wizard,domain:0 @@ -409,7 +413,7 @@ msgstr "简述" #: help:share.wizard,embed_code:0 msgid "" "Embed this code in your documents to provide a link to the shared document." -msgstr "" +msgstr "在你的文档中嵌入下列代码以提供到分享文档的连接。" #. module: share #: code:addons/share/wizard/share_wizard.py:513 @@ -431,7 +435,7 @@ msgstr "共享你的单据" #. module: share #: view:share.wizard:0 msgid "Or insert the following code where you want to embed your documents" -msgstr "" +msgstr "或者在你想要嵌入你的文档时,插入下列代码" #. module: share #: code:addons/share/wizard/share_wizard.py:886 @@ -439,7 +443,7 @@ msgstr "" msgid "" "The documents have been automatically added to your current OpenERP " "documents.\n" -msgstr "" +msgstr "一份文档已经被自动增加到你现在的OpenERP文档中了。\n" #. module: share #: model:ir.model,name:share.model_share_wizard_result_line From 8ffc4d0a5a6eddf3bbfd76699e40420830f7b868 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 17 Mar 2014 11:42:51 +0100 Subject: [PATCH 14/29] [ADD] support for presized fields in website/image also add presized field to attachments (automatically computed from datas) bzr revid: xmo@openerp.com-20140317104251-ddsa9cfpq1vkk2k1 --- addons/website/controllers/main.py | 46 ++++++++++++++++++++++-------- addons/website/models/website.py | 18 +++++++++++- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index eff28b61fcd..aee0997e4b4 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -314,6 +314,23 @@ class Website(openerp.addons.web.controllers.main.Home): '/website/image///' ], auth="public", website=True) def website_image(self, model, id, field, max_width=maxint, max_height=maxint): + """ Fetches the requested field and ensures it does not go above + (max_width, max_height), resizing it if necessary. + + Resizing is bypassed if the object provides a $field_big, which will + be interpreted as a pre-resized version of the base field. + + If the record is not found or does not have the requested field, + returns a placeholder image via :meth:`~.placeholder`. + + Sets and checks conditional response parameters: + * :mailheader:`ETag` is always set (and checked) + * :mailheader:`Last-Modified is set iif the record has a concurrency + field (``__last_update``) + + The requested field is assumed to be base64-encoded image data in + all cases. + """ Model = request.registry[model] response = werkzeug.wrappers.Response() @@ -322,15 +339,17 @@ class Website(openerp.addons.web.controllers.main.Home): ids = Model.search(request.cr, request.uid, [('id', '=', id)], context=request.context) \ - or Model.search(request.cr, openerp.SUPERUSER_ID, - [('id', '=', id), ('website_published', '=', True)], context=request.context) + or Model.search(request.cr, openerp.SUPERUSER_ID, + [('id', '=', id), ('website_published', '=', True)], context=request.context) if not ids: return self.placeholder(response) + presized = '%s_big' % field concurrency = '__last_update' [record] = Model.read(request.cr, openerp.SUPERUSER_ID, [id], - [concurrency, field], context=request.context) + [concurrency, field, presized], + context=request.context) if concurrency in record: server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT @@ -354,25 +373,28 @@ class Website(openerp.addons.web.controllers.main.Home): if response.status_code == 304: return response - data = record[field].decode('base64') - fit = int(max_width), int(max_height) + data = (record.get(presized) or record[field]).decode('base64') - buf = cStringIO.StringIO(data) - - image = Image.open(buf) - image.load() + image = Image.open(cStringIO.StringIO(data)) response.mimetype = Image.MIME[image.format] + # record provides a pre-resized version of the base field, use that + # directly + if record.get(presized): + response.set_data(data) + return response + + fit = int(max_width), int(max_height) w, h = image.size max_w, max_h = fit if w < max_w and h < max_h: - response.data = data + response.set_data(data) else: image.thumbnail(fit, Image.ANTIALIAS) image.save(response.stream, image.format) - # invalidate content-length computed by make_conditional as writing - # to response.stream does not do it (as of werkzeug 0.9.3) + # invalidate content-length computed by make_conditional as + # writing to response.stream does not do it (as of werkzeug 0.9.3) del response.headers['Content-Length'] return response diff --git a/addons/website/models/website.py b/addons/website/models/website.py index f48dbd06be5..1a541865987 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -580,10 +580,26 @@ class ir_attachment(osv.osv): return hashlib.new('sha1', attachment_dict['datas']).hexdigest() return None + def _datas_big(self, cr, uid, ids, name, arg, context=None): + result = dict.fromkeys(ids, False) + if context and context.get('bin_size'): + return result + + for record in self.browse(cr, uid, ids, context=context): + if not record.datas: continue + try: + result[record.id] = openerp.tools.image_resize_image_big(record.datas) + except IOError: # apparently the error PIL.Image.open raises + pass + + return result + _columns = { 'datas_checksum': fields.function(_datas_checksum, size=40, string="Datas checksum", type='char', store=True, select=True), - 'website_url': fields.function(_website_url_get, string="Attachment URL", type='char') + 'website_url': fields.function(_website_url_get, string="Attachment URL", type='char'), + 'datas_big': fields.function (_datas_big, type='binary', store=True, + string="Resized file content"), } def create(self, cr, uid, values, context=None): From a2ef044c477a049875a2077e4f2b4420bb35ef75 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 17 Mar 2014 12:09:04 +0100 Subject: [PATCH 15/29] [IMP] skip injection of data-oe-* attributes outside of editable mode bzr revid: xmo@openerp.com-20140317110904-k8bptgv7y2yhhh8s --- openerp/addons/base/ir/ir_qweb.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/openerp/addons/base/ir/ir_qweb.py b/openerp/addons/base/ir/ir_qweb.py index e9e0386b4e2..0b3bf91dc1f 100644 --- a/openerp/addons/base/ir/ir_qweb.py +++ b/openerp/addons/base/ir/ir_qweb.py @@ -488,7 +488,6 @@ class FieldConverter(osv.AbstractModel): A default configuration key is ``widget`` which can override the field's own ``_type``. """ - content = None try: content = self.record_to_html( cr, uid, field_name, record, @@ -503,12 +502,14 @@ class FieldConverter(osv.AbstractModel): field_name, record._model._name, exc_info=True) content = None - g_att += ''.join( - ' %s="%s"' % (name, werkzeug.utils.escape(value)) - for name, value in self.attributes( - cr, uid, field_name, record, options, - source_element, g_att, t_att, qweb_context) - ) + if context and context.get('inherit_branding'): + # add branding attributes + g_att += ''.join( + ' %s="%s"' % (name, werkzeug.utils.escape(value)) + for name, value in self.attributes( + cr, uid, field_name, record, options, + source_element, g_att, t_att, qweb_context) + ) return self.render_element(cr, uid, source_element, t_att, g_att, qweb_context, content) From 44bebab6825a067ef0ddf3494d49249ada8baaf0 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 17 Mar 2014 12:49:38 +0100 Subject: [PATCH 16/29] [FIX] website: typo: message let the user think that he can change the mobile view while he cannot bzr revid: chm@openerp.com-20140317114938-3ghhwm0km3u5wyu1 --- addons/website/static/src/js/website.tour.banner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website/static/src/js/website.tour.banner.js b/addons/website/static/src/js/website.tour.banner.js index ff3ed030f76..a92934df89d 100644 --- a/addons/website/static/src/js/website.tour.banner.js +++ b/addons/website/static/src/js/website.tour.banner.js @@ -101,7 +101,7 @@ element: '.modal:has(#mobile-viewport) button[data-dismiss=modal]', placement: 'right', title: _t("Check Mobile Preview"), - content: _t("Scroll in the mobile preview to test the rendering. Once it's ok, close this dialog."), + content: _t("Scroll to check rendering and then close the mobile preview."), popover: { next: _t("Continue") }, }, { From 19aacaaea8f809ec39dcbc3e4a2e997e85c22d20 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 17 Mar 2014 12:49:56 +0100 Subject: [PATCH 17/29] [FIX] website: readability block with container css bzr revid: chm@openerp.com-20140317114956-j5sqt6flie5fla31 --- addons/website/static/src/css/website.css | 2 +- addons/website/static/src/css/website.sass | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/website/static/src/css/website.css b/addons/website/static/src/css/website.css index a6e4c3eb916..1f0242d93d1 100644 --- a/addons/website/static/src/css/website.css +++ b/addons/website/static/src/css/website.css @@ -116,7 +116,7 @@ header a.navbar-brand img { } /* ----- BOOTSTRAP FIX ----- */ -.container .container { +.container .container, .readable .container { padding-left: 0; padding-right: 0; width: auto; diff --git a/addons/website/static/src/css/website.sass b/addons/website/static/src/css/website.sass index d6fbd0ac7bf..e08d5c1dbe3 100644 --- a/addons/website/static/src/css/website.sass +++ b/addons/website/static/src/css/website.sass @@ -85,7 +85,7 @@ header /* ----- BOOTSTRAP FIX ----- */ -.container +.container, .readable .container padding-left: 0 padding-right: 0 From d3c7750b96253e952f199abdbbb5eede67d3c873 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 17 Mar 2014 13:40:56 +0100 Subject: [PATCH 18/29] [FIX] inject WORD JOINER inside p so they don't seemingly disappear after saving bzr revid: xmo@openerp.com-20140317124056-kg2jngp2mg769v7m --- addons/website/static/src/css/website.css | 6 +++++- addons/website/static/src/css/website.sass | 9 ++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/addons/website/static/src/css/website.css b/addons/website/static/src/css/website.css index 1f0242d93d1..fd5492c9bc2 100644 --- a/addons/website/static/src/css/website.css +++ b/addons/website/static/src/css/website.css @@ -102,6 +102,10 @@ header a.navbar-brand img { max-height: 50px; } +div:before, p:before { + content: "\2060"; +} + /* ----- Snippets Styles ----- */ .readable { font-size: 120%; @@ -217,7 +221,6 @@ footer { /* -- Hack for removing double scrollbar from mobile preview -- */ div#mobile-preview.modal { overflow: hidden; - overflow-y: hidden; } ul.nav-stacked > li > a { @@ -284,6 +287,7 @@ ul.nav-stacked > li > a { section, .carousel, .parallax, .row, .hr, .blockquote { min-height: 30px; } + .carousel, .parallax, .blockquote { overflow: hidden; } diff --git a/addons/website/static/src/css/website.sass b/addons/website/static/src/css/website.sass index e08d5c1dbe3..44afd627214 100644 --- a/addons/website/static/src/css/website.sass +++ b/addons/website/static/src/css/website.sass @@ -68,6 +68,12 @@ header img max-height: 50px +// add {WORD JOINER} (equivalent to deprecated ZERO WIDTH NO-BREAK SPACE) at +// the beginning of paragraphs (and divs) so they don't "disappear" after +// saving when used solely for spacing. +div:before, p:before + content: '\2060' + /* ----- Snippets Styles ----- */ .readable @@ -78,11 +84,9 @@ header /* ----- EDITOR ----- */ - .css_non_editable_mode_hidden display: none - /* ----- BOOTSTRAP FIX ----- */ .container, .readable @@ -180,7 +184,6 @@ footer /* -- Hack for removing double scrollbar from mobile preview -- */ div#mobile-preview.modal overflow: hidden - overflow-y: hidden ul.nav-stacked > li > a padding: 2px 15px From 09deba48268bed7a77050d9b1d9776b485cb44e2 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 17 Mar 2014 13:43:43 +0100 Subject: [PATCH 19/29] [FIX] tests dont generate traceback on aborted test requests bzr revid: al@openerp.com-20140317124343-kgesa5c215z19vpn --- openerp/sql_db.py | 10 +++++----- openerp/tests/common.py | 5 ++++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/openerp/sql_db.py b/openerp/sql_db.py index 694ae02b3d9..59841656d8c 100644 --- a/openerp/sql_db.py +++ b/openerp/sql_db.py @@ -148,7 +148,7 @@ class Cursor(object): def check(f): @wraps(f) def wrapper(self, *args, **kwargs): - if self.__closed: + if self._closed: msg = 'Unable to use a closed cursor.' if self.__closer: msg += ' It was closed at %s, line %s' % self.__closer @@ -165,7 +165,7 @@ class Cursor(object): self.sql_log = _logger.isEnabledFor(logging.DEBUG) self.sql_log_count = 0 - self.__closed = True # avoid the call of close() (by __del__) if an exception + self._closed = True # avoid the call of close() (by __del__) if an exception # is raised by any of the following initialisations self._pool = pool self.dbname = dbname @@ -180,7 +180,7 @@ class Cursor(object): self.__caller = frame_codeinfo(currentframe(),2) else: self.__caller = False - self.__closed = False # real initialisation value + self._closed = False # real initialisation value self.autocommit(False) self.__closer = False @@ -189,7 +189,7 @@ class Cursor(object): self.cache = {} def __del__(self): - if not self.__closed and not self._cnx.closed: + if not self._closed and not self._cnx.closed: # Oops. 'self' has not been closed explicitly. # The cursor will be deleted by the garbage collector, # but the database connection is not put back into the connection @@ -302,7 +302,7 @@ class Cursor(object): # collected as fast as they should). The problem is probably due in # part because browse records keep a reference to the cursor. del self._obj - self.__closed = True + self._closed = True # Clean the underlying connection. self._cnx.rollback() diff --git a/openerp/tests/common.py b/openerp/tests/common.py index b0dcac47408..99f5919f2fc 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -15,9 +15,10 @@ import time import unittest2 import urllib2 import xmlrpclib - from datetime import datetime, timedelta +import werkzeug + import openerp _logger = logging.getLogger(__name__) @@ -46,6 +47,8 @@ def acquire_test_cursor(session_id): cr = HTTP_SESSION.get(session_id) if cr: cr._test_lock.acquire() + if cr._closed: + werkzeug.exceptions.abort(500) return cr def release_test_cursor(cr): From 25732de9cebc92fc4ccb231c8ad073a16b6035f6 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 17 Mar 2014 14:37:00 +0100 Subject: [PATCH 20/29] [FIX] website tour: typo for banner (from usertest feedback) bzr revid: chm@openerp.com-20140317133700-8xrneej6aytua4j4 --- addons/website/static/src/js/website.tour.banner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website/static/src/js/website.tour.banner.js b/addons/website/static/src/js/website.tour.banner.js index a92934df89d..304d4fe7ead 100644 --- a/addons/website/static/src/js/website.tour.banner.js +++ b/addons/website/static/src/js/website.tour.banner.js @@ -35,7 +35,7 @@ element: 'button[data-action=snippet]', placement: 'bottom', title: _t("Insert building blocks"), - content: _t("To add content in a page, you can insert building blocks."), + content: _t("Click here to insert blocks of centent in the page."), popover: { fixed: true }, }, { From cd4f83122ac61d44eeb45840aa6a2ec251ed9033 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 17 Mar 2014 14:51:44 +0100 Subject: [PATCH 21/29] [FIX] reduce span of paragraph spacer thing to not break layout bzr revid: xmo@openerp.com-20140317135144-hvuxshfp4cjudnbh --- addons/website/static/src/css/website.css | 2 +- addons/website/static/src/css/website.sass | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/website/static/src/css/website.css b/addons/website/static/src/css/website.css index fd5492c9bc2..dc0628ca3c5 100644 --- a/addons/website/static/src/css/website.css +++ b/addons/website/static/src/css/website.css @@ -102,7 +102,7 @@ header a.navbar-brand img { max-height: 50px; } -div:before, p:before { +#wrapwrap p:empty:after { content: "\2060"; } diff --git a/addons/website/static/src/css/website.sass b/addons/website/static/src/css/website.sass index 44afd627214..a15953e0f2b 100644 --- a/addons/website/static/src/css/website.sass +++ b/addons/website/static/src/css/website.sass @@ -69,9 +69,9 @@ header max-height: 50px // add {WORD JOINER} (equivalent to deprecated ZERO WIDTH NO-BREAK SPACE) at -// the beginning of paragraphs (and divs) so they don't "disappear" after -// saving when used solely for spacing. -div:before, p:before +// the beginning of paragraphs so they don't "disappear" after saving when +// used solely for spacing. +#wrapwrap p:empty:after content: '\2060' /* ----- Snippets Styles ----- */ From 627b5b671edd98303f3b8636d66ad11c4184c532 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 17 Mar 2014 14:52:39 +0100 Subject: [PATCH 22/29] [FIX] tests dont log traceback on aborted request while testing bzr revid: al@openerp.com-20140317135239-08aefkdxiil7bpcs --- openerp/http.py | 6 ++++-- openerp/tests/common.py | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openerp/http.py b/openerp/http.py index 34b9cf19abf..438c8ec1cc0 100644 --- a/openerp/http.py +++ b/openerp/http.py @@ -361,7 +361,7 @@ class JsonRequest(WebRequest): response['id'] = self.jsonrequest.get('id') response["result"] = self._call_function(**self.params) except AuthenticationError, e: - _logger.exception("Exception during JSON request handling.") + _logger.exception("JSON-RPC AuthenticationError in %s.", self.httprequest.path) se = serialize_exception(e) error = { 'code': 100, @@ -369,7 +369,9 @@ class JsonRequest(WebRequest): 'data': se } except Exception, e: - _logger.exception("Exception during JSON request handling.") + # Mute test cursor error for runbot + if not (openerp.tools.config['test_enable'] and isinstance(e, psycopg2.OperationalError)): + _logger.exception("JSON-RPC Exception in %s.", self.httprequest.path) se = serialize_exception(e) error = { 'code': 200, diff --git a/openerp/tests/common.py b/openerp/tests/common.py index 99f5919f2fc..a53a8d82240 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -47,8 +47,6 @@ def acquire_test_cursor(session_id): cr = HTTP_SESSION.get(session_id) if cr: cr._test_lock.acquire() - if cr._closed: - werkzeug.exceptions.abort(500) return cr def release_test_cursor(cr): From d3111df3aa5e8ca3d57e2e71c82267c7952a98ea Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 17 Mar 2014 15:13:24 +0100 Subject: [PATCH 23/29] [FIX] website: The user does not see the content menu because of the tutorial is hover bzr revid: chm@openerp.com-20140317141324-th65fhx512h2p1fa --- addons/website/static/src/js/website.tour.banner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website/static/src/js/website.tour.banner.js b/addons/website/static/src/js/website.tour.banner.js index 304d4fe7ead..9c8afcd61e5 100644 --- a/addons/website/static/src/js/website.tour.banner.js +++ b/addons/website/static/src/js/website.tour.banner.js @@ -107,7 +107,7 @@ { waitNot: '.modal', element: '#content-menu-button', - placement: 'bottom', + placement: 'left', title: _t("Add new pages and menus"), content: _t("The 'Content' menu allows you to add pages or add the top menu."), popover: { next: _t("Close Tutorial") }, From 363bbd00dbf40670303947dc290723c7beb74199 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 17 Mar 2014 15:17:49 +0100 Subject: [PATCH 24/29] [FIX] website_sale: display empty message for public user and allow admin to edit 'no product found' message bzr revid: chm@openerp.com-20140317141749-vmsx9x1kkmygnc61 --- addons/website_sale/views/website_sale.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml index a3576b90c2c..f0c14ee1573 100644 --- a/addons/website_sale/views/website_sale.xml +++ b/addons/website_sale/views/website_sale.xml @@ -200,8 +200,8 @@
-

No product defined.

- +

No product found.

+

Use the 'Content' top menu to create a new product.

From d87bc392ce05034bcb3ac839e5160e8e01afca5d Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 17 Mar 2014 15:42:54 +0100 Subject: [PATCH 25/29] [IMP] website snippet option: rename data-class into data-value bzr revid: chm@openerp.com-20140317144254-18cscu2yx5thmb89 --- .../static/src/js/website.snippets.editor.js | 51 ++++++++------- addons/website/views/snippets.xml | 62 +++++++++---------- 2 files changed, 58 insertions(+), 55 deletions(-) diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index 1fddc7b869b..b8533236e01 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -623,7 +623,7 @@ this.required = this.$el.data("required"); this.set_active(); - this.$el.find('li[data-class] a').on('mouseover mouseout click', _.bind(this._mouse, this)); + this.$el.find('li[data-value] a').on('mouseover mouseout click', _.bind(this._mouse, this)); this.$target.on('snippet-style-reset', _.bind(this.set_active, this)); this.start(); @@ -643,9 +643,9 @@ var $prev, $next; if (event.type === 'mouseout') { $prev = $(event.currentTarget).parent(); - $next = this.$el.find("li[data-class].active"); + $next = this.$el.find("li[data-value].active"); } else { - $prev = this.$el.find("li[data-class].active"); + $prev = this.$el.find("li[data-value].active"); $next = $(event.currentTarget).parent(); } if (!$prev.length) { @@ -709,6 +709,7 @@ }, /* select * called when a user select an item + * li must have data-value attribute * variables: np = {$next, $prev} * $next is false if they are no next item selected * $prev is false if they are no previous item selected @@ -717,10 +718,10 @@ var self = this; // add or remove html class if (np.$prev) { - this.$target.removeClass(np.$prev.data('class' || "")); + this.$target.removeClass(np.$prev.data('value' || "")); } if (np.$next) { - this.$target.addClass(np.$next.data('class') || ""); + this.$target.addClass(np.$next.data('value') || ""); } }, /* preview @@ -734,10 +735,10 @@ // add or remove html class if (np.$prev) { - this.$target.removeClass(np.$prev.data('class') || ""); + this.$target.removeClass(np.$prev.data('value') || ""); } if (np.$next) { - this.$target.addClass(np.$next.data('class') || ""); + this.$target.addClass(np.$next.data('value') || ""); } }, /* set_active @@ -747,14 +748,14 @@ set_active: function () { var self = this; this.$el.find('li').removeClass("active"); - var $active = this.$el.find('li[data-class]') + var $active = this.$el.find('li[data-value]') .filter(function () { var $li = $(this); - return ($li.data('class') && self.$target.hasClass($li.data('class'))); + return ($li.data('value') && self.$target.hasClass($li.data('value'))); }) .first() .addClass("active"); - this.$el.find('li:has(li[data-class].active)').addClass("active"); + this.$el.find('li:has(li[data-value].active)').addClass("active"); }, /* clean_for_save * function called just before save vue @@ -773,7 +774,7 @@ start: function () { this._super(); var src = this._get_bg(); - this.$el.find("li[data-class].active.oe_custom_bg").data("src", src); + this.$el.find("li[data-value].active.oe_custom_bg").data("src", src); }, select: function(event, np) { var self = this; @@ -789,7 +790,7 @@ }); editor.on('cancel', self, function () { if (!np.$prev || np.$prev.data("src") === "") { - self.$target.removeClass(np.$next.data("class")); + self.$target.removeClass(np.$next.data("value")); self.$target.trigger("snippet-style-change", [self, np]); } }); @@ -799,7 +800,7 @@ } } else { this._set_bg(false); - this.$target.removeClass(np.$prev.data("class")); + this.$target.removeClass(np.$prev.data("value")); } }, preview: function (event, np) { @@ -812,20 +813,20 @@ var self = this; var bg = self.$target.css("background-image"); this.$el.find('li').removeClass("active"); - var $active = this.$el.find('li[data-class]') + var $active = this.$el.find('li[data-value]') .filter(function () { var $li = $(this); return ($li.data('src') && bg.indexOf($li.data('src')) >= 0) || - (!$li.data('src') && self.$target.hasClass($li.data('class'))); + (!$li.data('src') && self.$target.hasClass($li.data('value'))); }) .first(); if (!$active.length) { $active = this.$target.css("background-image") !== 'none' ? - this.$el.find('li[data-class].oe_custom_bg') : - this.$el.find('li[data-class=""]'); + this.$el.find('li[data-value].oe_custom_bg') : + this.$el.find('li[data-value=""]'); } $active.addClass("active"); - this.$el.find('li:has(li[data-class].active)').addClass("active"); + this.$el.find('li:has(li[data-value].active)').addClass("active"); } }); @@ -942,7 +943,7 @@ }, load_style_options : function () { this._super(); - $(".snippet-style-size li[data-class='']").remove(); + $(".snippet-style-size li[data-value='']").remove(); }, start : function () { var self = this; @@ -960,11 +961,11 @@ $active.css("background-image", self.$target.css("background-image")); } if (np.$prev) { - $active.removeClass(np.$prev.data("class")); + $active.removeClass(np.$prev.data("value")); } if (np.$next) { - $active.addClass(np.$next.data("class")); - add_class(np.$next.data("class")); + $active.addClass(np.$next.data("value")); + add_class(np.$next.data("value")); } }); this.$target.on('slid', function () { // slide.bs.carousel @@ -986,11 +987,13 @@ var bg = this.$target.data("snippet-option-ids").background; if (!bg) return $clone; - var $styles = bg.$el.find("li[data-class]:not(.oe_custom_bg)"); + var $styles = bg.$el.find("li[data-value]:not(.oe_custom_bg)"); var styles_index = $styles.index($styles.filter(".active")[0]); + $styles.removeClass("active"); var $select = $($styles[styles_index >= $styles.length-1 ? 0 : styles_index+1]); + $select.addClass("active"); $clone.css("background-image", $select.data("src") ? "url('"+ $select.data("src") +"')" : ""); - $clone.addClass($select.data("class") || ""); + $clone.addClass($select.data("value") || ""); return $clone; }, diff --git a/addons/website/views/snippets.xml b/addons/website/views/snippets.xml index f91bd969c70..cdc4bd8f961 100644 --- a/addons/website/views/snippets.xml +++ b/addons/website/views/snippets.xml @@ -860,7 +860,7 @@ @@ -873,51 +873,51 @@ -
  • None
  • +
  • None
  • -
  • Choose an image...
  • +
  • Choose an image...
  • @@ -927,9 +927,9 @@ From 3d2452e8d4f150f193d769d8184ed2a805e02925 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 17 Mar 2014 16:18:10 +0100 Subject: [PATCH 26/29] [FIX] Force routing map to be rebuilt between each module test suite bzr revid: fme@openerp.com-20140317151810-tgsvv0ip4you1qko --- openerp/modules/loading.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openerp/modules/loading.py b/openerp/modules/loading.py index 7ca0a6785d6..681d8534c05 100644 --- a/openerp/modules/loading.py +++ b/openerp/modules/loading.py @@ -187,6 +187,10 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= # Yamel test report.record_result(load_test(module_name, idref, mode)) # Python tests + ir_http = registry['ir.http'] + if hasattr(ir_http, '_routing_map'): + # Force routing map to be rebuilt between each module test suite + del(ir_http._routing_map) report.record_result(openerp.modules.module.run_unit_tests(module_name, cr.dbname)) processed_modules.append(package.name) From 4988b40ef5255ec3e1dd3c769461de53f9865ff3 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 17 Mar 2014 16:24:24 +0100 Subject: [PATCH 27/29] [FIX] qweb tests re. inherit_branding enabling/disabling injection of data attributes bzr revid: xmo@openerp.com-20140317152424-bchnq81cn2e7fhjb --- openerp/addons/base/tests/test_qweb.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openerp/addons/base/tests/test_qweb.py b/openerp/addons/base/tests/test_qweb.py index 71beaab605a..ca1503a0c24 100644 --- a/openerp/addons/base/tests/test_qweb.py +++ b/openerp/addons/base/tests/test_qweb.py @@ -14,7 +14,8 @@ class TestQWebTField(common.TransactionCase): self.engine = self.registry('ir.qweb') def context(self, values): - return ir_qweb.QWebContext(self.cr, self.uid, values) + return ir_qweb.QWebContext( + self.cr, self.uid, values, context={'inherit_branding': True}) def test_trivial(self): field = document.createElement('span') From 5196cd6e8c577d35c5788df70c7c59d8e7176183 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 17 Mar 2014 16:25:02 +0100 Subject: [PATCH 28/29] [FIX] website: set inherit_branding in test contexts to trigger generation of relevant edition attributes bzr revid: xmo@openerp.com-20140317152502-6a2agi1xjooi516e --- addons/website/tests/test_converter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/website/tests/test_converter.py b/addons/website/tests/test_converter.py index d31df8e6956..ca72a361ac2 100644 --- a/addons/website/tests/test_converter.py +++ b/addons/website/tests/test_converter.py @@ -135,7 +135,7 @@ class TestConvertBack(common.TransactionCase): rendered = self.registry('website.qweb').render_tag_field( e, {'field': field_value}, '', ir_qweb.QWebContext(self.cr, self.uid, { 'record': record, - })) + }, context={'inherit_branding': True})) element = html.fromstring( rendered, parser=html.HTMLParser(encoding='utf-8')) @@ -216,7 +216,7 @@ class TestConvertBack(common.TransactionCase): rendered = self.registry('website.qweb').render_tag_field( e, {'field': field_value}, '', ir_qweb.QWebContext(self.cr, self.uid, { 'record': record, - })) + }, context={'inherit_branding': True})) element = html.fromstring(rendered, parser=html.HTMLParser(encoding='utf-8')) # emulate edition From 788708563133720c2833fdf0f67515940f6d4cd9 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 17 Mar 2014 18:07:06 +0100 Subject: [PATCH 29/29] [FIX] test_converter: force inherit_branding by passing the right context bzr revid: chs@openerp.com-20140317170706-dkig0e31xtnrsskj --- openerp/addons/test_converter/tests/test_html.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openerp/addons/test_converter/tests/test_html.py b/openerp/addons/test_converter/tests/test_html.py index 2f0896990ea..3ef6566e829 100644 --- a/openerp/addons/test_converter/tests/test_html.py +++ b/openerp/addons/test_converter/tests/test_html.py @@ -112,11 +112,14 @@ class TestCurrencyExport(TestExport): 'widget': 'monetary', 'display_currency': 'c2' } + context = dict(inherit_branding=True) converted = converter.to_html( self.cr, self.uid, 'value', obj, options, doc.createElement('span'), {'field': 'obj.value', 'field-options': json.dumps(options)}, - '', ir_qweb.QWebContext(self.cr, self.uid, {'obj': obj, 'c2': dest, })) + '', ir_qweb.QWebContext(self.cr, self.uid, {'obj': obj, 'c2': dest, }), + context=context, + ) return converted def test_currency_post(self):