diff options
| author | ced <> | 2007-11-26 15:46:03 +0000 |
|---|---|---|
| committer | ced <> | 2007-11-26 15:46:03 +0000 |
| commit | 0caeaf1d9bba3d58d652e86f4fab31ed589bd3c4 (patch) | |
| tree | dd0e50d325fd0187f67dfbbc182c223bcbe65d44 /bin | |
| parent | 80a9af32dbd8dd2f14a18cd37a5c5424e1a9afbe (diff) | |
Allow to translate en_US language (custom)
- en_US is translatable also
- fix cache on translation
- add view to language
- fix client translation windows
bzr revid: ced-b6ab18eba46eb8e1e8a97ed5afa6797078cec659
Diffstat (limited to 'bin')
| -rw-r--r-- | bin/addons/base/__terp__.py | 1 | ||||
| -rw-r--r-- | bin/addons/base/ir/ir_translation.py | 78 | ||||
| -rw-r--r-- | bin/addons/base/res/__init__.py | 1 | ||||
| -rw-r--r-- | bin/addons/base/res/res_lang.py | 47 | ||||
| -rw-r--r-- | bin/addons/base/res/res_lang_view.xml | 26 | ||||
| -rw-r--r-- | bin/addons/base/res/res_user.py | 16 | ||||
| -rw-r--r-- | bin/osv/orm.py | 60 | ||||
| -rw-r--r-- | bin/osv/osv.py | 26 | ||||
| -rw-r--r-- | bin/report/report_sxw.py | 2 |
9 files changed, 182 insertions, 75 deletions
diff --git a/bin/addons/base/__terp__.py b/bin/addons/base/__terp__.py index a200188e453..96c6723bc37 100644 --- a/bin/addons/base/__terp__.py +++ b/bin/addons/base/__terp__.py @@ -25,6 +25,7 @@ "module/module_report.xml", # "module/move_module_wizard.xml", "res/res_request_view.xml", + "res/res_lang_view.xml", "res/partner/partner_report.xml", "res/partner/partner_view.xml", "res/partner/partner_wizard.xml", diff --git a/bin/addons/base/ir/ir_translation.py b/bin/addons/base/ir/ir_translation.py index dedd34a3a28..5c4aa6b3c7c 100644 --- a/bin/addons/base/ir/ir_translation.py +++ b/bin/addons/base/ir/ir_translation.py @@ -47,8 +47,16 @@ class ir_translation(osv.osv, Cacheable): _name = "ir.translation" _log_access = False - def _get_language(sel, cr, uid, context): - return tools.scan_languages() + def _get_language(self, cr, uid, context): + lang_obj = self.pool.get('res.lang') + lang_ids = lang_obj.search(cr, uid, [('translatable', '=', True)], + context=context) + langs = lang_obj.browse(cr, uid, lang_ids, context=context) + res = [(lang.code, lang.name) for lang in langs] + for lang_dict in tools.scan_languages(): + if lang_dict not in res: + res.append(lang_dict) + return res _columns = { 'name': fields.char('Field Name', size=128, required=True), @@ -67,35 +75,67 @@ class ir_translation(osv.osv, Cacheable): translations, to_fetch = {}, [] for id in ids: trans = self.get((lang, name, id)) - if trans: + if trans is not None: translations[id] = trans else: to_fetch.append(id) if to_fetch: - cr.execute('select res_id,value from ir_translation where lang=%s and type=%s and name=%s and res_id in ('+','.join(map(str, to_fetch))+')', (lang,tt,name)) + cr.execute('select res_id,value ' \ + 'from ir_translation ' \ + 'where lang=%s ' \ + 'and type=%s ' \ + 'and name=%s ' \ + 'and res_id in ('+','.join(map(str, to_fetch))+')', + (lang,tt,name)) for res_id, value in cr.fetchall(): self.add((lang, tt, name, res_id), value) translations[res_id] = value + for res_id in ids: + if res_id not in translations: + self.add((lang, tt, name, res_id), False) + translations[res_id] = False return translations def _set_ids(self, cr, uid, name, tt, lang, ids, value): - cr.execute('delete from ir_translation where lang=%s and type=%s and name=%s and res_id in ('+','.join(map(str,ids))+')', (lang,tt,name)) + cr.execute('delete from ir_translation ' \ + 'where lang=%s ' \ + 'and type=%s ' \ + 'and name=%s ' \ + 'and res_id in ('+','.join(map(str,ids))+')', + (lang,tt,name)) for id in ids: - self.create(cr, uid, {'lang':lang, 'type':tt, 'name':name, 'res_id':id, 'value':value}) + self.create(cr, uid, { + 'lang':lang, + 'type':tt, + 'name':name, + 'res_id':id, + 'value':value, + }) return len(ids) def _get_source(self, cr, uid, name, tt, lang, source=None): trans = self.get((lang, tt, name, source)) - if trans: + if trans is not None: return trans - + if source: source = source.strip().replace('\n',' ') if isinstance(source, unicode): - source = source.encode('utf8') - cr.execute('select value from ir_translation where lang=%s and type=%s and name=%s and src=%s', (lang, tt, str(name), source)) + source = source.encode('utf8') + cr.execute('select value ' \ + 'from ir_translation ' \ + 'where lang=%s ' \ + 'and type=%s ' \ + 'and name=%s ' \ + 'and src=%s', + (lang, tt, str(name), source)) else: - cr.execute('select value from ir_translation where lang=%s and type=%s and name=%s', (lang, tt, str(name))) + cr.execute('select value ' \ + 'from ir_translation ' \ + 'where lang=%s ' \ + 'and type=%s ' \ + 'and name=%s', + (lang, tt, str(name))) res = cr.fetchone() if res: self.add((lang, tt, name, source), res[0]) @@ -103,4 +143,20 @@ class ir_translation(osv.osv, Cacheable): else: self.add((lang, tt, name, source), False) return False + + def unlink(self, cursor, user, ids, context=None): + self.clear() + return super(ir_translation, self).unlink(cusor, user, ids, + context=context) + + def create(self, cursor, user, vals, context=None): + self.clear() + return super(ir_translation, self).create(cursor, user, ids, + context=context) + + def write(self, cursor, user, ids, vals, context=None): + self.clear() + return super(ir_translation, self).write(cursor, user, ids, + context=context) + ir_translation() diff --git a/bin/addons/base/res/__init__.py b/bin/addons/base/res/__init__.py index bff90b8e1d5..14cf9bd5bd0 100644 --- a/bin/addons/base/res/__init__.py +++ b/bin/addons/base/res/__init__.py @@ -34,6 +34,7 @@ import partner import res_currency import res_company import res_user +import res_lang import res_request diff --git a/bin/addons/base/res/res_lang.py b/bin/addons/base/res/res_lang.py new file mode 100644 index 00000000000..fc53eba631d --- /dev/null +++ b/bin/addons/base/res/res_lang.py @@ -0,0 +1,47 @@ +############################################################################## +# +# Copyright (c) 2007 TINY SPRL. (http://tiny.be) All Rights Reserved. +# Fabien Pinckaers <fp@tiny.Be> +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsability of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# garantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## + +from osv import fields, osv + +class lang(osv.osv): + _name = "res.lang" + _columns = { + 'name': fields.char('Name', size=64, required=True), + 'code': fields.char('Code', size=5, required=True), + 'translatable': fields.boolean('Translatable'), + 'active': fields.boolean('Active'), + 'direction': fields.selection([('ltr', 'Left-to-right'), ('rtl', 'Right-to-left')], 'Direction',resuired=True), + } + _defaults = { + 'active': lambda *a: 1, + 'translatable': lambda *a: 0, + 'direction': lambda *a: 'ltr', + } + +lang() + diff --git a/bin/addons/base/res/res_lang_view.xml b/bin/addons/base/res/res_lang_view.xml new file mode 100644 index 00000000000..06b6a223319 --- /dev/null +++ b/bin/addons/base/res/res_lang_view.xml @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<terp> + <data> + <record model="ir.ui.view" id="res_lang_tree"> + <field name="name">res.lang.tree</field> + <field name="model">res.lang</field> + <field name="type">tree</field> + <field name="arch" type="xml"> + <tree string="Languages" editable="bottom"> + <field name="name"/> + <field name="code"/> + <field name="direction"/> + <field name="translatable"/> + <field name="active"/> + </tree> + </field> + </record> + <record model="ir.actions.act_window" id="res_lang_act_window"> + <field name="res_model">res.lang</field> + <field name="view_type">form</field> + <field name="context">{'active_test': False}</field> + </record> + <menuitem name="Administration/Translations/Languages" + action="res_lang_act_window" id="menu_res_lang_act_window"/> + </data> +</terp> diff --git a/bin/addons/base/res/res_user.py b/bin/addons/base/res/res_user.py index d04c9f9097b..d41022e47b7 100644 --- a/bin/addons/base/res/res_user.py +++ b/bin/addons/base/res/res_user.py @@ -81,22 +81,6 @@ class roles(osv.osv): return False roles() -class lang(osv.osv): - _name = "res.lang" - _columns = { - 'name': fields.char('Name', size=64, required=True), - 'code': fields.char('Code', size=5, required=True), - 'translatable': fields.boolean('Translatable'), - 'active': fields.boolean('Active'), - 'direction': fields.selection([('ltr', 'Left-to-right'), ('rtl', 'Right-to-left')], 'Direction',resuired=True), - } - _defaults = { - 'active': lambda *a: 1, - 'translatable': lambda *a: 0, - 'direction': lambda *a: 'ltr', - } -lang() - class users(osv.osv): _name = "res.users" _log_access = False diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 959330c36ec..7de301cce00 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -824,13 +824,12 @@ class orm(object): else: res = map(lambda x: {'id':x}, ids) - if context.get('lang', False) and context['lang'] != 'en_US': - for f in fields_pre: - if self._columns[f].translate: - ids = map(lambda x: x['id'], res) - res_trans = self.pool.get('ir.translation')._get_ids(cr, user, self._name+','+f, 'model', context['lang'], ids) - for r in res: - r[f] = res_trans.get(r['id'], r[f]) + for f in fields_pre: + if self._columns[f].translate: + ids = map(lambda x: x['id'], res) + res_trans = self.pool.get('ir.translation')._get_ids(cr, user, self._name+','+f, 'model', context.get('lang', False) or 'en_US', ids) + for r in res: + r[f] = res_trans.get(r['id'], False) or r[f] for table in self._inherits: col = self._inherits[table] @@ -1284,29 +1283,26 @@ class orm(object): res[f][arg] = getattr(self._columns[f], arg) # translate the field label - if context.get('lang', False) and context['lang'] != 'en_US': - res_trans = translation_obj._get_source(cr, user, - self._name + ',' + f, 'field', context['lang']) - if res_trans: - res[f]['string'] = res_trans - help_trans = translation_obj._get_source(cr, user, - self._name + ',' + f, 'help', context['lang']) - if help_trans: - res[f]['help'] = help_trans + res_trans = translation_obj._get_source(cr, user, + self._name + ',' + f, 'field', context.get('lang', False) or 'en_US') + if res_trans: + res[f]['string'] = res_trans + help_trans = translation_obj._get_source(cr, user, + self._name + ',' + f, 'help', context.get('lang', False) or 'en_US') + if help_trans: + res[f]['help'] = help_trans if hasattr(self._columns[f], 'selection'): if isinstance(self._columns[f].selection, (tuple, list)): sel = self._columns[f].selection - # translate each selection option - if context.get('lang', False) and context['lang'] != 'en_US': - sel2 = [] - for (key,val) in sel: - val2 = translation_obj._get_source(cr, user, - self._name + ',' + f, 'selection', - context['lang'], val) - sel2.append((key, val2 or val)) - sel = sel2 + sel2 = [] + for (key,val) in sel: + val2 = translation_obj._get_source(cr, user, + self._name + ',' + f, 'selection', + context.get('lang', False) or 'en_US', val) + sel2.append((key, val2 or val)) + sel = sel2 res[f]['selection'] = sel else: # call the 'dynamic selection' function @@ -1705,12 +1701,20 @@ class orm(object): args[i] += (table,) i+=1 else: - if field.translate and context.get('lang', False) and context['lang'] != 'en_US': + if field.translate: if args[i][1] in ('like', 'ilike'): args[i] = (args[i][0], args[i][1], '%%%s%%' % args[i][2]) - cr.execute('select res_id from ir_translation where name = %s and lang = %s and type = %s and value '+args[i][1]+' %s', (table._name+','+args[i][0], context['lang'], 'model', args[i][2])) + cr.execute('select res_id from ir_translation ' \ + 'where name = %s and lang = %s ' \ + 'and type = %s ' \ + 'and value ' + args[i][1] + ' %s', + (table._name+','+args[i][0], + context.get('lang', False) or 'en_US', 'model', + args[i][2])) ids = map(lambda x: x[0], cr.fetchall()) - cr.execute('select id from "'+table._table+'" where "'+args[i][0]+'" '+args[i][1]+' %s', (args[i][2],)) + cr.execute('select id from "' + table._table + '" ' \ + 'where "' + args[i][0]+'" '+args[i][1]+' %s', + (args[i][2],)) ids += map(lambda x: x[0], cr.fetchall()) args[i] = ('id', 'in', ids, table) else: diff --git a/bin/osv/osv.py b/bin/osv/osv.py index 4cc9cf39757..8a62b5d385e 100644 --- a/bin/osv/osv.py +++ b/bin/osv/osv.py @@ -38,6 +38,7 @@ import sys import psycopg from netsvc import Logger, LOG_ERROR +from tools.misc import UpdateableDict module_list = [] module_class_list = {} @@ -262,34 +263,21 @@ class osv(orm.orm): class Cacheable(object): - _cache = {} - count = 0 - - def __delete_key(self, key): - odico = self._cache - for key_item in key[:-1]: - odico = odico[key_item] - del odico[key[-1]] - - def __add_key(self, key, value): - odico = self._cache - for key_item in key[:-1]: - odico = odico.setdefault(key_item, {}) - odico[key[-1]] = value + _cache = UpdateableDict() def add(self, key, value): - self.__add_key(key, value) - + self._cache[key] = value + def invalidate(self, key): - self.__delete_key(key) - + del self._cache[key] + def get(self, key): try: w = self._cache[key] return w except KeyError: return None - + def clear(self): self._cache.clear() self._items = [] diff --git a/bin/report/report_sxw.py b/bin/report/report_sxw.py index fc0b72073df..9fc71044967 100644 --- a/bin/report/report_sxw.py +++ b/bin/report/report_sxw.py @@ -209,7 +209,7 @@ class rml_parse(object): # translate the RML file if 'lang' in self.localcontext: lang = self.localcontext['lang'] - if lang not in (False, 'en_US') and text and not text.isspace(): + if lang and text and not text.isspace(): transl_obj = self.pool.get('ir.translation') piece_list = self._transl_regex.split(text) for pn in range(len(piece_list)): |
