diff --git a/addons/base/static/src/css/base.css b/addons/base/static/src/css/base.css
index 242167480f3..cd420ea8c0d 100644
--- a/addons/base/static/src/css/base.css
+++ b/addons/base/static/src/css/base.css
@@ -878,13 +878,20 @@ label.error {
position: relative;
vertical-align: top;
}
-.openerp img.ui-datepicker-trigger, .openerp img.ui-datepicker-trigger {
+.openerp img.ui-datepicker-trigger {
margin-left: -20px;
vertical-align: middle;
cursor: pointer;
position: relative;
top: -1px;
}
+.openerp img.oe_field_translate {
+ margin-left: -21px;
+ vertical-align: top;
+ cursor: pointer;
+ position: relative;
+ top: 4px;
+}
/* http://www.quirksmode.org/dom/inputfile.html
* http://stackoverflow.com/questions/2855589/replace-input-type-file-by-an-image
diff --git a/addons/base/static/src/js/form.js b/addons/base/static/src/js/form.js
index 5da048a17b9..7a4d3c92d89 100644
--- a/addons/base/static/src/js/form.js
+++ b/addons/base/static/src/js/form.js
@@ -38,6 +38,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormVi
this.registry = openerp.base.form.widgets;
this.has_been_loaded = $.Deferred();
this.$form_header = null;
+ this.translatable_fields = [];
_.defaults(this.options, {"always_show_new_button": true});
},
start: function() {
@@ -461,7 +462,7 @@ openerp.base.form.SidebarAttachments = openerp.base.Widget.extend({
['res_model', '=', this.view.dataset.model],
['res_id', '=', this.view.datarecord.id],
['type', 'in', ['binary', 'url']]
- ])).read_slice(['name', 'url', 'type'], this.on_attachments_loaded);
+ ])).read_slice(['name', 'url', 'type'], {}, this.on_attachments_loaded);
}
},
on_attachments_loaded: function(attachments) {
@@ -839,6 +840,13 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
this.invalid = false;
this.dirty = false;
},
+ start: function() {
+ this._super.apply(this, arguments);
+ if (this.field.translate) {
+ this.view.translatable_fields.push(this);
+ this.$element.find('.oe_field_translate').click(this.on_translate);
+ }
+ },
set_value: function(value) {
this.value = value;
this.invalid = false;
@@ -850,6 +858,9 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
},
on_value_changed: function() {
},
+ on_translate: function() {
+ this.view.open_translate_dialog(this);
+ },
get_value: function() {
return this.value;
},
diff --git a/addons/base/static/src/js/views.js b/addons/base/static/src/js/views.js
index cb9b7d364cf..c6782150297 100644
--- a/addons/base/static/src/js/views.js
+++ b/addons/base/static/src/js/views.js
@@ -4,6 +4,8 @@
openerp.base.views = function(openerp) {
+var _t = openerp.base._t;
+
/**
* Registry for all the client actions key: tag value: widget
*/
@@ -450,6 +452,106 @@ openerp.base.Sidebar = openerp.base.Widget.extend({
}
});
+openerp.base.TranslateDialog = openerp.base.Dialog.extend({
+ dialog_title: _t("Translations"),
+ init: function(view) {
+ this['on_button' + _t("Save")] = this.on_button_Save;
+ this['on_button' + _t("Close")] = this.on_button_Close;
+ this._super(view, {
+ width: '80%',
+ height: '80%'
+ });
+ this.view = view;
+ this.view_type = view.fields_view.type || '';
+ this.$fields_form = null;
+ 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.base.DataSetSearch(this, 'res.lang', this.view.dataset.get_context(),
+ [['translatable', '=', '1']])).read_slice(['code', 'name'], { sort: 'id' }, this.on_languages_loaded);
+ },
+ start: function() {
+ var self = this;
+ this._super();
+ $.when(this.languages_loaded).then(function() {
+ self.$element.html(QWeb.render('TranslateDialog', { widget: self }));
+ self.$element.tabs();
+ if (!(self.view.translatable_fields && self.view.translatable_fields.length)) {
+ self.hide_tabs('fields');
+ self.select_tab('view');
+ }
+ self.$fields_form = self.$element.find('.oe_translation_form');
+ });
+ return this;
+ },
+ on_languages_loaded: function(langs) {
+ this.languages = langs;
+ this.languages_loaded.resolve();
+ },
+ do_load_fields_values: function(callback) {
+ var self = this,
+ deffered = [];
+ this.$fields_form.find('.oe_trad_field').val('').removeClass('touched');
+ _.each(self.languages, function(lg) {
+ var deff = $.Deferred();
+ deffered.push(deff);
+ self.rpc('/base/dataset/get', {
+ model: self.view.dataset.model,
+ ids: [self.view.datarecord.id],
+ fields: self.translatable_fields_keys,
+ context: self.view.dataset.get_context({
+ 'lang': lg.code
+ })
+ }, function(values) {
+ _.each(self.translatable_fields_keys, function(f) {
+ self.$fields_form.find('.oe_trad_field[name="' + lg.code + '-' + f + '"]').val(values[0][f] || '');
+ });
+ deff.resolve();
+ });
+ });
+ $.when.apply(null, deffered).then(callback);
+ },
+ show_tabs: function() {
+ for (var i = 0; i < arguments.length; i++) {
+ this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().show();
+ }
+ },
+ hide_tabs: function() {
+ for (var i = 0; i < arguments.length; i++) {
+ this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().hide();
+ }
+ },
+ select_tab: function(name) {
+ this.show_tabs(name);
+ var index = this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().index() - 1;
+ this.$element.tabs('select', index);
+ },
+ open: function(field) {
+ var self = this,
+ super = this._super;
+ $.when(this.languages_loaded).then(function() {
+ if (self.view.translatable_fields && self.view.translatable_fields.length) {
+ self.do_load_fields_values(function() {
+ super.call(self);
+ if (field) {
+ // TODO: focus and scroll to field
+ }
+ });
+ } else {
+ super.call(self);
+ }
+ });
+ },
+ on_button_Save: function() {
+ this.close();
+ },
+ on_button_Close: function() {
+ this.close();
+ }
+});
+
openerp.base.View = openerp.base.Widget.extend({
set_default_options: function(options) {
this.options = options || {};
@@ -461,6 +563,12 @@ openerp.base.View = openerp.base.Widget.extend({
action_views_ids: {}
});
},
+ open_translate_dialog: function(field) {
+ if (!this.translate_dialog) {
+ this.translate_dialog = new openerp.base.TranslateDialog(this).start();
+ }
+ this.translate_dialog.open(field);
+ },
/**
* Fetches and executes the action identified by ``action_data``.
*
@@ -542,7 +650,7 @@ openerp.base.View = openerp.base.Widget.extend({
}, {
label: "Translate",
callback: this.on_sidebar_translate,
- classname: 'oe_hide oe_sidebar_translate'
+ classname: 'oe_sidebar_translate'
}, {
label: "View Log",
callback: this.on_sidebar_view_log,
@@ -570,6 +678,7 @@ openerp.base.View = openerp.base.Widget.extend({
export_view.start();
},
on_sidebar_translate: function() {
+ this.open_translate_dialog();
},
on_sidebar_view_log: function() {
}
diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml
index 879d98d15a6..69aac831386 100644
--- a/addons/base/static/src/xml/base.xml
+++ b/addons/base/static/src/xml/base.xml
@@ -453,6 +453,40 @@
+
+
+
+
+ Translate view
+
+
+ Translate sidebar
+
+
-
+