diff --git a/web_translate_dialog_page/__init__.py b/web_translate_dialog_page/__init__.py index f1454453..06331652 100644 --- a/web_translate_dialog_page/__init__.py +++ b/web_translate_dialog_page/__init__.py @@ -19,5 +19,4 @@ # ############################################################################## -import orm - +from . import orm diff --git a/web_translate_dialog_page/__openerp__.py b/web_translate_dialog_page/__openerp__.py index 01fa58ee..121583a5 100644 --- a/web_translate_dialog_page/__openerp__.py +++ b/web_translate_dialog_page/__openerp__.py @@ -36,7 +36,6 @@ Replace the standard translation dialog by an alternative one: "version": "1.0", "depends": [ 'web', - 'web_textarea_autosize', ], 'js': [ 'static/src/js/web_translate_dialog_page.js', diff --git a/web_translate_dialog_page/orm.py b/web_translate_dialog_page/orm.py index 8ede8518..f8e395d3 100644 --- a/web_translate_dialog_page/orm.py +++ b/web_translate_dialog_page/orm.py @@ -2,7 +2,7 @@ ############################################################################## # # Author: Guewen Baconnier -# Copyright 2012 Camptocamp SA +# Copyright 2012-2013 Camptocamp SA # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -22,100 +22,8 @@ import openerp.osv.orm -# Check if we can remove the monkey-patching once the bug: -# https://bugs.launchpad.net/bugs/1053970 -# is resolved. -original_create = openerp.osv.orm.BaseModel.create -def create(self, cr, uid, vals, context=None): - """ - Monkey-patch the create of BaseModel in order to create translation lines - on translatable fields. - - Actually, the original behavior is quite strange. Here it is: - I'm logged in with en_US language. - I create a record, with a (translatable) title 'My title' - I check the source in database (table of the object), that's 'My title' - I check the translation lines for the en_US language, no line - I write on my record the title 'My title updated' - I check the source in database, that's 'My title updated' - I check the translation lines for the en_US language, no line - - I'm logged in with fr_FR language - I create a record, with a (translatable) title 'Mon titre' - I check the source in database (table of the object), that's 'Mon titre' - I check the translation lines for the fr_FR language, no line - I write on my record the title 'Mon titre mis à jour' - I check the source in database, that's 'Mon titre' (unchanged) - I check the translation lines for the fr_FR language, I have a line with 'Mon titre mis à jour' - - As you can see, the write method create translation lines for other - languages than en_US, that's correct. The create method does not, - and it has to do it. - - OpenERP seems to assume that the en_US should be the reference - language, so lets assume it completely, and generate the french - translation line directly when we enter the value. - - That's weird, because, if I create a record in french, the source - will be the french value (of course), but programmatically, I do not - have any means to know that someone entered a french translation. - - A simple scenario where the bug will occurs: - - User A is logged in with fr_FR - User A creates a product with a name 'Marteau' - User B is logged in with en_US - User B modifies the product 'Marteau' to be 'Hammer' - => The french translation is lost. - - It won't occurs in this slightly modified scenario: - - User A is logged in with fr_FR - User A creates a product with a name 'Martea' (typo) - User A modifies the product 'Martea' to be 'Marteau' - User B is logged in with en_US - User B modifies the product 'Marteau' to be 'Hammer' - => The french translation isn't lost, because the write has - correctly generated the french translation line - - - Bug reported : https://bugs.launchpad.net/bugs/1053970 - - """ - if context is None: - context = {} - - record_id = original_create(self, cr, uid, vals, context=context) - - if context.get('lang') and context['lang'] != 'en_US': - translate_fields = [field for field in vals if - field in self._columns and - self._columns[field].translate and - self._columns[field]._classic_write and - not hasattr(self._columns[field], '_fnct_inv')] - - for field in translate_fields: - src_trans = self.read(cr, uid, record_id, [field])[field] - if not src_trans: - src_trans = vals[field] - # Inserting value to DB - self.write(cr, uid, record_id, {field: vals[field]}) - self.pool.get('ir.translation')._set_ids( - cr, uid, - self._name + ',' + field, - 'model', - context['lang'], - [record_id], - vals[field], - src_trans) - - return record_id - -openerp.osv.orm.BaseModel.create = create - - # add the method in the orm so we can use it from the TranslateDialog of the -# webclient +# webclient instead of the normal read def read_translations(self, cr, user, ids, fields=None, context=None, load='_classic_read'): """ Read records with given ids with the given fields, if a field is not translated, its value will be False instead of the source language's value. @@ -131,9 +39,8 @@ def read_translations(self, cr, user, ids, fields=None, context=None, load='_cla if context is None: context = {} - self.check_read(cr, user) - if not fields: - fields = list(set(self._columns.keys() + self._inherit_fields.keys())) + self.check_access_rights(cr, user, 'read') + fields = self.check_field_access_rights(cr, user, 'read', fields) if isinstance(ids, (int, long)): select = [ids] else: @@ -143,9 +50,9 @@ def read_translations(self, cr, user, ids, fields=None, context=None, load='_cla if context.get('lang') and context['lang'] != 'en_US': fields_pre = [f for f in fields if - (f in self._columns and - getattr(self._columns[f], '_classic_write'))] + \ - self._inherits.values() + (f in self._columns and + getattr(self._columns[f], '_classic_write'))] + \ + self._inherits.values() for f in fields_pre: if self._columns[f].translate: @@ -170,4 +77,3 @@ def read_translations(self, cr, user, ids, fields=None, context=None, load='_cla return result openerp.osv.orm.BaseModel.read_translations = read_translations - diff --git a/web_translate_dialog_page/static/src/css/base.css b/web_translate_dialog_page/static/src/css/base.css index 8f0eaeca..29220ff9 100644 --- a/web_translate_dialog_page/static/src/css/base.css +++ b/web_translate_dialog_page/static/src/css/base.css @@ -1,4 +1,3 @@ .oe_field_translate { - visibility: hidden; + /* visibility: hidden; */ } - diff --git a/web_translate_dialog_page/static/src/js/web_translate_dialog_page.js b/web_translate_dialog_page/static/src/js/web_translate_dialog_page.js index d5e9b8c8..18144f27 100644 --- a/web_translate_dialog_page/static/src/js/web_translate_dialog_page.js +++ b/web_translate_dialog_page/static/src/js/web_translate_dialog_page.js @@ -1,90 +1,95 @@ -openerp.web_translate_dialog_page = function (openerp) { +openerp.web_translate_dialog_page = function (instance) { - var _t = openerp.web._t; - var QWeb = openerp.web.qweb; + "use strict"; - openerp.web.PageView.include({ - on_loaded: function(data) { + var QWeb = instance.web.qweb, + _t = instance.web._t, + _lt = instance.web._lt; + + instance.web.FormView.include({ + load_form: function(data) { this._super(data); - this.$form_header.find('button.oe_form_button_translate').click(this.on_button_translate); + this.$buttons.on('click', '.oe_form_button_translate', + this.guard_active(this.on_button_translate)); }, on_button_translate: function() { var self = this; $.when(this.has_been_loaded).then(function() { self.open_translate_dialog(this); }); - } + }, }); - openerp.web.View.include({ - // Replace the translation dialog by the new one - open_translate_dialog: function(field) { - if (!this.translate_dialog) { - this.translate_dialog = new openerp.web_translate_dialog_page.TranslateDialogPage(this).start(); - } - this.translate_dialog.open(field); + instance.web.View.include({ + open_translate_dialog: function() { + new instance.web_translate_dialog_page.TranslateDialogPage(this).open(); } }); - // completely redefine the translation dialog because we can - // not completely tie the standard one to our needs by sub-classing - openerp.web_translate_dialog_page.TranslateDialogPage = openerp.web.Dialog.extend({ + instance.web_translate_dialog_page.TranslateDialogPage = instance.web.Dialog.extend({ + template: "TranslateDialogPage", dialog_title: {toString: function () { return _t("Translations"); }}, - init: function(view) { - this.view_language = view.session.user_context.lang; - this['on_button_' + _t("Save")] = this.on_btn_save; - this['on_button_' + _t("Close")] = this.on_btn_close; - this._super(view, { - width: '80%', - height: '90%' - }); - this.view = view; - this.view_type = view.fields_view.type || ''; - this.$fields_form = null; + init: function(parent, options, content) { + this._super(parent, options, content); + this.view_language = this.session.user_context.lang; + this.view = parent; + this.view_type = parent.fields_view.type || ''; this.$view_form = null; this.$sidebar_form = null; this.translatable_fields_keys = _.map(this.view.translatable_fields || [], function(i) { return i.name;}); this.languages = null; this.languages_loaded = $.Deferred(); - (new openerp.web.DataSetSearch(this, 'res.lang', this.view.dataset.get_context(), - [['translatable', '=', '1']])).read_slice(['code', 'name'], { sort: 'id' }).then(this.on_languages_loaded); + (new instance.web.DataSetSearch(this, + 'res.lang', + this.view.dataset.get_context(), + [['translatable', '=', '1']])) + .read_slice(['code', 'name'], { sort: 'id' }) + .then(this.on_languages_loaded); }, on_languages_loaded: function(langs) { this.languages = langs; this.languages_loaded.resolve(); }, - start: function() { - var self = this; - this._super(); + open: function() { + var self = this, + sup = this._super; + // the template needs the languages $.when(this.languages_loaded).then(function() { - self.$element.html(QWeb.render('TranslateDialogPage', { widget: self })); - self.$fields_form = self.$element.find('.oe_translation_form'); - self.$fields_form.find('.oe_trad_field').change(function() { - $(this).toggleClass('touched', ($(this).val() != $(this).attr('data-value'))); - }); - var $textarea = self.$fields_form.find('textarea.oe_trad_field'); - $textarea.addClass('autosizeAnimated').autosize({append: "\n"}); - $textarea.css({minHeight:'100px'}); + // if (self.view.translatable_fields && self.view.translatable_fields.length) { + return sup.call(self); }); - return this; }, + start: function() { + var self = this; + self.$el.find('.oe_trad_field').change(function() { + $(this).toggleClass('touched', ($(this).val() != $(this).attr('data-value'))); + }); + this.$buttons.html(QWeb.render("TranslateDialogPage.buttons")); + this.$buttons.find(".oe_form_translate_dialog_save_button").click(function(){ + self.on_button_save(); + self.on_button_close(); + }); + this.$buttons.find(".oe_form_translate_dialog_cancel_button").click(function(){ + self.on_button_close(); + }); + self.do_load_fields_values(); + // var $textarea = self.$el.find('textarea.oe_trad_field'); + // $textarea.addClass('autosizeAnimated').autosize({append: "\n"}); + // $textarea.css({minHeight:'100px'}); + }, // use a `read_translations` method instead of a `read` // this latter leave the fields empty if there is no // translation for a field instead of taking the src field do_load_fields_values: function(callback) { var self = this, - deffered = []; + deferred = []; - this.$fields_form.find('.oe_trad_field').val('').removeClass('touched'); + this.$el.find('.oe_trad_field').val('').removeClass('touched'); _.each(self.languages, function(lg) { var deff = $.Deferred(); - deffered.push(deff); + deferred.push(deff); var callback = function(values) { - _.each(self.translatable_fields_keys, function(f) { - self.$fields_form.find('.oe_trad_field[name="' + lg.code + '-' + f + '"]').val(values[0][f] || '').attr('data-value', values[0][f] || ''); - }); - deff.resolve(); }; self.view.dataset.call( 'read_translations', @@ -92,29 +97,22 @@ openerp.web_translate_dialog_page = function (openerp) { self.translatable_fields_keys, self.view.dataset.get_context({ 'lang': lg.code - })], callback); + })]).done(function (values) { + _.each(self.translatable_fields_keys, function(f) { + self.$el.find('.oe_trad_field[name="' + lg.code + '-' + f + '"]') + .val(values[0][f] || '') + .attr('data-value', values[0][f] || ''); + }); + deff.resolve(); + }); }); - $.when.apply(null, deffered).then(callback); + return deferred; }, - open: function(field) { - var self = this, - sup = this._super; - $.when(this.languages_loaded).then(function() { - if (self.view.translatable_fields && self.view.translatable_fields.length) { - self.do_load_fields_values(function() { - sup.call(self); - $(window).resize(); - }); - } else { - sup.call(self); - } - }); - }, - on_btn_save: function() { + on_button_save: function() { var trads = {}, self = this, trads_mutex = new $.Mutex(); - self.$fields_form.find('.oe_trad_field.touched').each(function() { + self.$el.find('.oe_trad_field.touched').each(function() { var field = $(this).attr('name').split('-'); if (!trads[field[0]]) { trads[field[0]] = {}; @@ -128,15 +126,22 @@ openerp.web_translate_dialog_page = function (openerp) { }); } trads_mutex.exec(function() { - return new openerp.web.DataSet(self, self.view.dataset.model, self.view.dataset.get_context()).write(self.view.datarecord.id, data, { context : { 'lang': code }}); + return new instance.web.DataSet(self, self.view.dataset.model, self.view.dataset.get_context()).write(self.view.datarecord.id, data, { context : { 'lang': code }}); }); }); this.close(); }, - on_btn_close: function() { + on_button_close: function() { this.close(); } }); + + instance.web.form.AbstractField.include({ + on_translate: function() { + // the image next to the fields opens the translate dialog + this.view.open_translate_dialog(); + }, + }); }; diff --git a/web_translate_dialog_page/static/src/xml/base.xml b/web_translate_dialog_page/static/src/xml/base.xml index c834bd10..10dad07d 100644 --- a/web_translate_dialog_page/static/src/xml/base.xml +++ b/web_translate_dialog_page/static/src/xml/base.xml @@ -15,18 +15,23 @@ - - + + - - + + + + + +
+ - +