← Back to team overview

openerp-community-reviewer team mailing list archive

[Merge] lp:~camptocamp/web-addons/7.0-web_translate_dialog_page into lp:web-addons

 

Guewen Baconnier @ Camptocamp has proposed merging lp:~camptocamp/web-addons/7.0-web_translate_dialog_page into lp:web-addons.

Commit message:
[ADD] web_translate_dialog: replace the translation view by a translation dialog like in OpenERP 6.1

Requested reviews:
  Web-Addons Core Editors (webaddons-core-editors)

For more details, see:
https://code.launchpad.net/~camptocamp/web-addons/7.0-web_translate_dialog_page/+merge/198063

Hello,

Here is a replacement for the translations, restoring a dialog more or less like the 6.1 one.
It also support the HTML fields.
-- 
https://code.launchpad.net/~camptocamp/web-addons/7.0-web_translate_dialog_page/+merge/198063
Your team Web-Addons Core Editors is requested to review the proposed merge of lp:~camptocamp/web-addons/7.0-web_translate_dialog_page into lp:web-addons.
=== added directory 'web_translate_dialog'
=== added file 'web_translate_dialog/__init__.py'
--- web_translate_dialog/__init__.py	1970-01-01 00:00:00 +0000
+++ web_translate_dialog/__init__.py	2013-12-06 14:09:34 +0000
@@ -0,0 +1,1 @@
+# -*- coding: utf-8 -*-

=== added file 'web_translate_dialog/__openerp__.py'
--- web_translate_dialog/__openerp__.py	1970-01-01 00:00:00 +0000
+++ web_translate_dialog/__openerp__.py	2013-12-06 14:09:34 +0000
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Author: Guewen Baconnier
+#    Copyright 2012 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
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+{"name": "Web Translate Dialog",
+ "category": "Hidden",
+ "description": """
+Replace the standard translation view by an alternative one:
+
+ * Add a "Translate" button item in the "More" menu
+ * The translations are displayed in a dialog (much like the OpenERP
+   6.1's one)
+ * Support HTML fields
+ * Autosize the textareas to the size of the content
+
+""",
+ "version": "1.0",
+ "depends": ['web',
+             ],
+ 'js': ['static/src/js/web_translate_dialog.js',
+        ],
+ 'css': ['static/src/css/base.css',
+         ],
+ 'qweb': ["static/src/xml/base.xml",
+          ],
+ 'auto_install': False,
+ }

=== added directory 'web_translate_dialog/static'
=== added directory 'web_translate_dialog/static/src'
=== added directory 'web_translate_dialog/static/src/css'
=== added file 'web_translate_dialog/static/src/css/base.css'
--- web_translate_dialog/static/src/css/base.css	1970-01-01 00:00:00 +0000
+++ web_translate_dialog/static/src/css/base.css	2013-12-06 14:09:34 +0000
@@ -0,0 +1,6 @@
+.openerp .oe_trad_field {
+  width: 95%;
+}
+.openerp .oe_trad_field.touched {
+  border: 1px solid green !important;
+}

=== added directory 'web_translate_dialog/static/src/js'
=== added file 'web_translate_dialog/static/src/js/web_translate_dialog.js'
--- web_translate_dialog/static/src/js/web_translate_dialog.js	1970-01-01 00:00:00 +0000
+++ web_translate_dialog/static/src/js/web_translate_dialog.js	2013-12-06 14:09:34 +0000
@@ -0,0 +1,211 @@
+openerp.web_translate_dialog = function (instance) {
+
+    "use strict";
+
+    var QWeb = instance.web.qweb,
+        _t  = instance.web._t,
+        _lt = instance.web._lt;
+
+    instance.web.FormView.include({
+        load_form: function(data) {
+            var self = this;
+            this._super(data);
+            if (this.sidebar) {
+                this.sidebar.add_items('other', _.compact([
+                    self.is_action_enabled('edit') && { label: _t('Translate'), callback: self.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.TranslateDialog(this).open();
+        }
+    });
+
+    instance.web_translate_dialog.TranslateDialog = instance.web.Dialog.extend({
+        template: "TranslateDialog",
+        dialog_title: {toString: function () { return _t("Translations"); }},
+        init: function(parent, options, content) {
+            this._super(parent,
+                        {width: '90%',
+                         height: '80%'},
+                        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 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() {
+                return sup.call(self);
+            });
+        },
+        start: function() {
+            var self = this;
+            this.$el.find('.oe_trad_field').change(function() {
+                $(this).toggleClass('touched', ($(this).val() != $(this).attr('data-value')));
+            });
+            this.$buttons.html(QWeb.render("TranslateDialog.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();
+            });
+            this.initialize_html_fields();
+
+            this.do_load_fields_values();
+        },
+        initialize_html_fields: function() {
+            this.$el.find('.oe_form_field_html textarea').each(function() {
+                var $textarea = $(this);
+                var width = 100;  // forced to fixed size on initialization
+                                  // will be changed to percentage right after
+                                  // the creation
+                var height = 250;
+                $textarea.cleditor({
+                    width:      width, // width not including margins, borders or padding
+                    height:     height, // height not including margins, borders or padding
+                    controls:   // controls to add to the toolbar
+                                "bold italic underline strikethrough " +
+                                "| removeformat | bullets numbering | outdent " +
+                                "indent | link unlink | source",
+                    bodyStyle:  // style to assign to document body contained within the editor
+                                "margin:4px; color:#4c4c4c; font-size:13px; font-family:'Lucida Grande',Helvetica,Verdana,Arial,sans-serif; cursor:text"
+                });
+
+                var $cleditor = $textarea.cleditor()[0];
+                // Down to -- end, this is a workaround for the bug
+                // https://bugs.launchpad.net/openerp-web/+bug/1258463
+                // The editor is initially created with a fixed size so
+                // the buggy event is not bound to $(window), then we restore
+                // a percentage width and bind the "normal" event without the
+                // CHM's buggy change.
+                $cleditor.$main.width('95%');
+                $cleditor.options.width = '95%';
+                $(window).resize(function() {
+                    //Forcefully blurred iframe contentWindow, chrome, IE, safari doesn't trigger blur on window resize and due to which text disappears
+                    var contentWindow = $cleditor.$frame[0].contentWindow;
+                    if(!$.browser.mozilla && contentWindow){
+                        $(contentWindow).trigger('blur');
+                    }
+                });
+                $cleditor.refresh();
+                // -- end
+
+                $cleditor.change(function() {
+                    this.updateTextArea();
+                    this.$area.toggleClass('touched',
+                                        (this.$area.val() != this.$area.attr('data-value')));
+                });
+            });
+        },
+        // 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,
+                deferred = [];
+
+            this.$el.find('.oe_trad_field').val('').removeClass('touched');
+            _.each(self.languages, function(lg) {
+                var deff = $.Deferred();
+                deferred.push(deff);
+                var callback = function(values) {
+                };
+                self.view.dataset.call(
+                    'read',
+                    [[self.view.datarecord.id],
+                     self.translatable_fields_keys,
+                     self.view.dataset.get_context({
+                        'lang': lg.code
+                     })]).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] || '');
+
+                            var $tarea = self.$el.find('.oe_form_field_html .oe_trad_field[name="' + lg.code + '-' + f + '"]');
+                            if ($tarea.length) {
+                                $tarea.cleditor()[0].updateFrame();
+                            }
+                        });
+                        var $textarea = self.$el.find('textarea.oe_trad_field');
+                        $textarea.css({minHeight:'100px'});
+                        $textarea.autosize();
+                        $(window).resize();  // triggers the autosize
+                        deff.resolve();
+                     });
+            });
+            return deferred;
+        },
+        on_button_save: function() {
+            var trads = {},
+                self = this,
+                trads_mutex = new $.Mutex();
+            self.$el.find('.oe_trad_field.touched').each(function() {
+                var field = $(this).attr('name').split('-');
+                if (!trads[field[0]]) {
+                    trads[field[0]] = {};
+                }
+                trads[field[0]][field[1]] = $(this).val();
+            });
+            _.each(trads, function(data, code) {
+                if (code === self.view_language) {
+                    _.each(data, function(value, field) {
+                        var view_field = self.view.fields[field];
+                        var is_dirty = view_field.view.$el.hasClass('oe_form_dirty');
+                        // update the field on the view
+                        view_field.set_value(value);
+                        if ( !is_dirty ) {
+                            // Avoid to set the view dirty when not necessary:
+                            // values have already been saved.
+                            view_field.view.$el.removeClass('oe_form_dirty');
+                        }
+                    });
+                }
+                trads_mutex.exec(function() {
+                    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_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();
+        },
+    });
+};

=== added directory 'web_translate_dialog/static/src/xml'
=== added file 'web_translate_dialog/static/src/xml/base.xml'
--- web_translate_dialog/static/src/xml/base.xml	1970-01-01 00:00:00 +0000
+++ web_translate_dialog/static/src/xml/base.xml	2013-12-06 14:09:34 +0000
@@ -0,0 +1,34 @@
+<templates>
+
+    <t t-name="TranslateDialog">
+        <table t-if="widget.view.translatable_fields" class="oe_frame oe_forms oe_translation_form" border="0" cellpadding="0" cellspacing="0" width="100%">
+        <tr>
+            <td class="oe_form_separator" width="1%" nowrap="nowrap">
+                <div class="separator horizontal">Field</div>
+            </td>
+            <th t-foreach="widget.languages" align="left">
+                <div class="separator horizontal"><t t-esc="name"/></div>
+            </th>
+        </tr>
+        <tr t-foreach="widget.view.translatable_fields" t-as="field" t-att-data-field="field.name">
+            <td class="oe_form_frame_cell" width="1%" nowrap="nowrap">
+                <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.field.type == 'char' || field.field.type == 'url'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field"/>
+                <textarea t-if="field.field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" ></textarea>
+                <div t-if="field.field.type == 'html'" class="oe_form_field_html">
+                    <textarea class="oe_trad_field oe_form_field" t-attf-name="#{lg.code}-#{field.name}" data-value=""/>
+                </div>
+            </td>
+        </tr>
+        </table>
+    </t>
+
+    <t t-name="TranslateDialog.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>
+
+</templates>
+


Follow ups