changeset 854012242629 in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset;node=854012242629
description:
Add language configuration wizard
issue9172
review267031002
diffstat:
CHANGELOG | 1 +
trytond/ir/__init__.py | 2 +
trytond/ir/lang.py | 82 ++++++++++++++++++++++++++++-
trytond/ir/lang.xml | 29 ++++++++++
trytond/ir/view/lang_config_start_form.xml | 9 +++
trytond/ir/view/lang_form.xml | 4 +
trytond/ir/view/lang_list.xml | 3 +-
trytond/modules/__init__.py | 37 +++++++-----
trytond/res/ir.xml | 4 +
9 files changed, 149 insertions(+), 22 deletions(-)
diffs (301 lines):
diff -r aeb7307bf72c -r 854012242629 CHANGELOG
--- a/CHANGELOG Mon Apr 13 17:25:02 2020 +0200
+++ b/CHANGELOG Mon Apr 13 20:47:17 2020 +0200
@@ -1,3 +1,4 @@
+* Add language configuration wizard
* Allow copying attachments and notes to created records
* Add link button on form
* Support explicit delete and remove for saving and on_change xxx2Many
diff -r aeb7307bf72c -r 854012242629 trytond/ir/__init__.py
--- a/trytond/ir/__init__.py Mon Apr 13 17:25:02 2020 +0200
+++ b/trytond/ir/__init__.py Mon Apr 13 20:47:17 2020 +0200
@@ -71,6 +71,7 @@
note.NoteRead,
cron.Cron,
lang.Lang,
+ lang.LangConfigStart,
export.Export,
export.ExportLine,
rule.RuleGroup,
@@ -105,6 +106,7 @@
module.ModuleConfigWizard,
module.ModuleActivateUpgrade,
module.ModuleConfig,
+ lang.LangConfig,
module='ir', type_='wizard')
Pool.register(
model.ModelGraph,
diff -r aeb7307bf72c -r 854012242629 trytond/ir/lang.py
--- a/trytond/ir/lang.py Mon Apr 13 17:25:02 2020 +0200
+++ b/trytond/ir/lang.py Mon Apr 13 20:47:17 2020 +0200
@@ -8,18 +8,17 @@
from sql import Table
from ..model import ModelView, ModelSQL, DeactivableMixin, fields, Check
+from ..modules import create_graph, load_translations
from ..cache import Cache
from ..transaction import Transaction
from ..pool import Pool
+from ..pyson import Eval
from ..exceptions import UserError
from ..i18n import gettext
+from ..wizard import Wizard, StateView, Button, StateTransition
Transaction.cache_keys.add('translate_name')
-__all__ = [
- 'Lang',
- ]
-
class GroupingError(UserError):
pass
@@ -43,7 +42,7 @@
name = fields.Char('Name', required=True, translate=True)
code = fields.Char('Code', required=True,
help="RFC 4646 tag: http://tools.ietf.org/html/rfc4646")
- translatable = fields.Boolean('Translatable')
+ translatable = fields.Boolean('Translatable', readonly=True)
parent = fields.Char("Parent Code", help="Code of the exceptional parent")
direction = fields.Selection([
('ltr', 'Left-to-right'),
@@ -87,6 +86,12 @@
Check(table, table.decimal_point != table.thousands_sep),
'decimal_point and thousands_sep must be different!'),
]
+ cls._buttons.update({
+ 'load_translations': {},
+ 'unload_translations': {
+ 'invisible': ~Eval('translatable', False),
+ },
+ })
@classmethod
def search_rec_name(cls, name, clause):
@@ -187,6 +192,37 @@
return False
@classmethod
+ @ModelView.button
+ def load_translations(cls, languages):
+ pool = Pool()
+ Module = pool.get('ir.module')
+ codes = set()
+ cls.write(languages, {'translatable': True})
+ for language in languages:
+ code = language.code
+ while code:
+ codes.add(code)
+ code = get_parent_language(code)
+ modules = Module.search([
+ ('state', '=', 'activated'),
+ ])
+ modules = [m.name for m in modules]
+ for node in create_graph(modules):
+ load_translations(pool, node, codes)
+
+ @classmethod
+ @ModelView.button
+ def unload_translations(cls, languages):
+ pool = Pool()
+ Translation = pool.get('ir.translation')
+ cls.write(languages, {'translatable': False})
+ languages = [l.code for l in languages]
+ Translation.delete(Translation.search([
+ ('lang', 'in', languages),
+ ('module', '!=', None),
+ ]))
+
+ @classmethod
def validate(cls, languages):
super(Lang, cls).validate(languages)
cls.check_grouping(languages)
@@ -503,6 +539,42 @@
return value.strftime(format)
+class LangConfigStart(ModelView):
+ 'Language Configuration Start'
+ __name__ = 'ir.lang.config.start'
+
+ languages = fields.Many2Many('ir.lang', None, None, "Languages")
+
+ @classmethod
+ def default_languages(cls):
+ pool = Pool()
+ Lang = pool.get('ir.lang')
+ return [x.id for x in Lang.search([('translatable', '=', True)])]
+
+
+class LangConfig(Wizard):
+ 'Configure languages'
+ __name__ = 'ir.lang.config'
+
+ start = StateView('ir.lang.config.start',
+ 'ir.lang_config_start_view_form', [
+ Button('Cancel', 'end', 'tryton-cancel'),
+ Button('Load', 'load', 'tryton-ok', default=True),
+ ])
+ load = StateTransition()
+
+ def transition_load(self):
+ pool = Pool()
+ Lang = pool.get('ir.lang')
+ Lang.load_translations(list(self.start.languages))
+ untranslated_languages = Lang.search([
+ ('id', 'not in', [l.id for l in self.start.languages]),
+ ('translatable', '=', True),
+ ])
+ Lang.unload_translations(untranslated_languages)
+ return 'end'
+
+
def get_parent_language(code):
if code not in _parents:
# Use SQL because it is used by load_module_graph
diff -r aeb7307bf72c -r 854012242629 trytond/ir/lang.xml
--- a/trytond/ir/lang.xml Mon Apr 13 17:25:02 2020 +0200
+++ b/trytond/ir/lang.xml Mon Apr 13 20:47:17 2020 +0200
@@ -495,5 +495,34 @@
</record>
<menuitem name="Languages" parent="ir.menu_localization"
action="act_lang_form" id="menu_lang_form"/>
+
+ <record model="ir.model.button" id="lang_load_translations_button">
+ <field name="name">load_translations</field>
+ <field name="string">Load translations</field>
+ <field name="model" search="[('model', '=', 'ir.lang')]"/>
+ <field name="confirm">Are you sure you want to load languages'
translations?</field>
+ </record>
+ <record model="ir.model.button" id="lang_unload_translations_button">
+ <field name="name">unload_translations</field>
+ <field name="string">Unload translations</field>
+ <field name="confirm">Are you sure you want to remove languages'
translations?</field>
+ <field name="model" search="[('model', '=', 'ir.lang')]"/>
+ </record>
+
+ <record model="ir.ui.view" id="lang_config_start_view_form">
+ <field name="model">ir.lang.config.start</field>
+ <field name="type">form</field>
+ <field name="name">lang_config_start_form</field>
+ </record>
+
+ <record model="ir.action.wizard" id="act_lang_config">
+ <field name="name">Configure Languages</field>
+ <field name="wiz_name">ir.lang.config</field>
+ <field name="window" eval="True"/>
+ </record>
+
+ <record model="ir.module.config_wizard.item"
id="config_wizard_item_lang">
+ <field name="action" ref="act_lang_config"/>
+ </record>
</data>
</tryton>
diff -r aeb7307bf72c -r 854012242629 trytond/ir/view/lang_config_start_form.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/trytond/ir/view/lang_config_start_form.xml Mon Apr 13 20:47:17
2020 +0200
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
+this repository contains the full copyright notices and license terms. -->
+<form col="2">
+ <image name="tryton-info" xexpand="0" xfill="0"/>
+ <label string="You can now load aditional translations to the system."
+ id="load" yalign="0.0" xalign="0.0" xexpand="1"/>
+ <field name="languages" colspan="2" widget="multiselection"/>
+</form>
diff -r aeb7307bf72c -r 854012242629 trytond/ir/view/lang_form.xml
--- a/trytond/ir/view/lang_form.xml Mon Apr 13 17:25:02 2020 +0200
+++ b/trytond/ir/view/lang_form.xml Mon Apr 13 20:47:17 2020 +0200
@@ -55,4 +55,8 @@
<field name="p_sep_by_space"/>
<label name="n_sep_by_space"/>
<field name="n_sep_by_space"/>
+ <group id="buttons" colspan="6" col="-1">
+ <button name="load_translations" icon="tryton-launch"/>
+ <button name="unload_translations" icon="tryton-launch"/>
+ </group>
</form>
diff -r aeb7307bf72c -r 854012242629 trytond/ir/view/lang_list.xml
--- a/trytond/ir/view/lang_list.xml Mon Apr 13 17:25:02 2020 +0200
+++ b/trytond/ir/view/lang_list.xml Mon Apr 13 20:47:17 2020 +0200
@@ -1,9 +1,10 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
-<tree editable="1">
+<tree>
<field name="name" expand="1"/>
<field name="code"/>
<field name="direction"/>
<field name="translatable"/>
+ <button name="load_translations"/>
</tree>
diff -r aeb7307bf72c -r 854012242629 trytond/modules/__init__.py
--- a/trytond/modules/__init__.py Mon Apr 13 17:25:02 2020 +0200
+++ b/trytond/modules/__init__.py Mon Apr 13 20:47:17 2020 +0200
@@ -166,6 +166,26 @@
return False
+def load_translations(pool, node, languages):
+ module = node.name
+ localedir = '%s/%s' % (node.info['directory'], 'locale')
+ lang2filenames = defaultdict(list)
+ for filename in itertools.chain(
+ iglob('%s/*.po' % localedir),
+ iglob('%s/override/*.po' % localedir)):
+ filename = filename.replace('/', os.sep)
+ lang = os.path.splitext(os.path.basename(filename))[0]
+ if lang not in languages:
+ continue
+ lang2filenames[lang].append(filename)
+ base_path_position = len(node.info['directory']) + 1
+ for language, files in lang2filenames.items():
+ filenames = [f[base_path_position:] for f in files]
+ logger.info('%s:loading %s', module, ','.join(filenames))
+ Translation = pool.get('ir.translation')
+ Translation.translation_import(language, module, files)
+
+
def load_module_graph(graph, pool, update=None, lang=None):
from trytond.ir.lang import get_parent_language
@@ -233,22 +253,7 @@
modules_todo.append((module, list(tryton_parser.to_delete)))
- localedir = '%s/%s' % (node.info['directory'], 'locale')
- lang2filenames = defaultdict(list)
- for filename in itertools.chain(
- iglob('%s/*.po' % localedir),
- iglob('%s/override/*.po' % localedir)):
- filename = filename.replace('/', os.sep)
- lang2 = os.path.splitext(os.path.basename(filename))[0]
- if lang2 not in lang:
- continue
- lang2filenames[lang2].append(filename)
- base_path_position = len(node.info['directory']) + 1
- for language, files in lang2filenames.items():
- filenames = [f[base_path_position:] for f in files]
- logger.info('%s:loading %s', module, ','.join(filenames))
- Translation = pool.get('ir.translation')
- Translation.translation_import(language, module, files)
+ load_translations(pool, node, lang)
if package_state == 'to remove':
continue
diff -r aeb7307bf72c -r 854012242629 trytond/res/ir.xml
--- a/trytond/res/ir.xml Mon Apr 13 17:25:02 2020 +0200
+++ b/trytond/res/ir.xml Mon Apr 13 20:47:17 2020 +0200
@@ -560,6 +560,10 @@
<field name="action" ref="ir.act_translation_export"/>
<field name="group" ref="group_admin"/>
</record>
+ <record model="ir.action-res.group" id="act_lang_config">
+ <field name="action" ref="ir.act_lang_config"/>
+ <field name="group" ref="group_admin"/>
+ </record>
<record model="ir.ui.menu-res.group"
id="menu_administration_group_admin">
<field name="menu" ref="ir.menu_administration"/>