mirror of https://github.com/OCA/web.git
[CHG] restored the translate dialog, still needs UI tweaks
parent
59cb3403d8
commit
6854196cfd
|
@ -19,5 +19,4 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import orm
|
||||
|
||||
from . import orm
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
.oe_field_translate {
|
||||
visibility: hidden;
|
||||
/* visibility: hidden; */
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
instance.web.View.include({
|
||||
open_translate_dialog: function() {
|
||||
new instance.web_translate_dialog_page.TranslateDialogPage(this).open();
|
||||
}
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
// 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();
|
||||
},
|
||||
open: function() {
|
||||
var self = this,
|
||||
sup = this._super;
|
||||
// the template needs the languages
|
||||
$.when(this.languages_loaded).then(function() {
|
||||
// if (self.view.translatable_fields && self.view.translatable_fields.length) {
|
||||
return sup.call(self);
|
||||
});
|
||||
},
|
||||
start: function() {
|
||||
var self = this;
|
||||
this._super();
|
||||
$.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() {
|
||||
self.$el.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'});
|
||||
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();
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
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] || '');
|
||||
});
|
||||
$.when.apply(null, deffered).then(callback);
|
||||
deff.resolve();
|
||||
});
|
||||
});
|
||||
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();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -15,18 +15,23 @@
|
|||
<label class="oe_label"><t t-esc="field.string"/>:</label>
|
||||
</td>
|
||||
<td t-foreach="widget.languages" t-as="lg" class="oe_form_frame_cell">
|
||||
<input t-if="field.type == 'char' || field.type == 'url'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field" style="width: 100%"/>
|
||||
<textarea t-if="field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" style="width: 100%"></textarea>
|
||||
<input t-if="field.field.type == 'char' || field.field.type == 'url'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field" style="width: 100%"/>
|
||||
<textarea t-if="field.field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" style="width: 100%"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<t t-extend="PageView">
|
||||
<t t-jquery=".oe_button.oe_form_button_edit" t-operation="after">
|
||||
<t t-name="TranslateDialogPage.buttons">
|
||||
<button class="oe_form_translate_dialog_save_button oe_button oe_highlight">Save</button>
|
||||
<button class="oe_form_translate_dialog_cancel_button oe_button">Cancel</button>
|
||||
</t>
|
||||
|
||||
<div t-extend="FormView.buttons">
|
||||
<t t-jquery="span.oe_form_buttons_view" t-operation="append">
|
||||
<button type="button" class="oe_button oe_form_button_translate">Translate</button>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
</templates>
|
||||
|
||||
|
|
Loading…
Reference in New Issue