From f9ad472466645f8ab9dc4dbc66a049042d97b8f9 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Wed, 11 Jul 2012 12:40:54 +0530 Subject: [PATCH 01/67] [ADD] add new http service translation. bzr revid: tpa@tinyerp.com-20120711071054-rfreaxwys8b1fqbc --- openerp/service/web_services.py | 50 +++++++++++++++++++++++++++++++++ openerp/tools/translate.py | 17 +++++++++-- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 330bb86dcfc..6762426d8cd 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -777,6 +777,55 @@ class report_spool(netsvc.ExportService): else: raise Exception, 'ReportNotFound' +class translation(netsvc.ExportService): + + def __init__(self, name="translation"): + netsvc.ExportService.__init__(self, name) + + def exp_load(self, db, modules, langs, flag=None, context=None): + translated_data = [] + cr = pooler.get_db(db).cursor() + for module_name in modules: + modpath = openerp.modules.get_module_path(module_name) + if not modpath: + # unable to find the module. we skip + continue + for lang in langs: + iso_lang = tools.get_iso_codes(lang) + f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') + context2 = context and context.copy() or {} + if f and '_' in iso_lang: + iso_lang2 = iso_lang.split('_')[0] + f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') + if f2: + _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) + translated_data.append(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, context=context)) + context2['overwrite'] = True + # Implementation notice: we must first search for the full name of + # the language derivative, like "en_UK", and then the generic, + # like "en". + if (not f) and '_' in iso_lang: + iso_lang = iso_lang.split('_')[0] + f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') + if f: + _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) + translated_data.append(tools.trans_load(cr, f, lang, verbose=False, flag=flag, context=context2)) + elif iso_lang != 'en': + _logger.warning('module %s: no translation for language %s', module_name, iso_lang) + cr.commit() + cr.close() + return translated_data + + def dispatch(self, method, params): + if method in ['load']: + # No security check for these methods + pass + else: + raise KeyError("Method not found: %s" % method) + fn = getattr(self, 'exp_'+method) + return fn(*params) + +translation() def start_web_services(): db() @@ -784,6 +833,7 @@ def start_web_services(): objects_proxy() wizard() report_spool() + translation() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index eb5dbe24077..0d3802bd5c0 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -43,6 +43,7 @@ import misc from misc import UpdateableStr from misc import SKIPPED_ELEMENT_TYPES import osutil +import babel.messages.pofile _logger = logging.getLogger(__name__) @@ -842,12 +843,22 @@ def trans_generate(lang, modules, cr): return out -def trans_load(cr, filename, lang, verbose=True, context=None): +def trans_load(cr, filename, lang, verbose=True, flag=None, context=None): try: fileobj = misc.file_open(filename) + pool = pooler.get_pool(cr.dbname) + traslation_obj = pool.get('ir.translation') _logger.info("loading %s", filename) - fileformat = os.path.splitext(filename)[-1][1:].lower() - r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, context=context) + if flag == 'web': + transl = {"messages":[]} + po = babel.messages.pofile.read_po(fileobj) + for x in po: + if x.id and x.string and "openerp-web" in x.auto_comments: + transl["messages"].append({'id': x.id, 'string': x.string}) + return transl + else: + fileformat = os.path.splitext(filename)[-1][1:].lower() + r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, context=context) fileobj.close() return r except IOError: From 4ea3ad65b24ad8b89d1c06d36bffc40e3ea9a865 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 10:51:11 +0530 Subject: [PATCH 02/67] [ADD] added module field in ir.translation and improved code for that. bzr revid: tpa@tinyerp.com-20120712052111-5qq9noxd5vd9dlwv --- openerp/addons/base/ir/ir_translation.py | 20 ++++++++++---------- openerp/addons/base/module/module.py | 4 ++-- openerp/service/web_services.py | 4 ++-- openerp/tools/translate.py | 12 ++++++------ 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 61e40e807d4..2f8f87a0a2a 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -70,7 +70,6 @@ class ir_translation_import_cursor(object): cr.execute('''CREATE TEMP TABLE %s( imd_model VARCHAR(64), - imd_module VARCHAR(64), imd_name VARCHAR(128) ) INHERITS (%s) ''' % (self._table_name, self._parent_table)) @@ -80,10 +79,10 @@ class ir_translation_import_cursor(object): self._cr.execute("INSERT INTO " + self._table_name \ + """(name, lang, res_id, src, type, - imd_model, imd_module, imd_name, value) + imd_model, module, imd_name, value) VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s)""", (ddict['name'], ddict['lang'], ddict.get('res_id'), ddict['src'], ddict['type'], - ddict.get('imd_model'), ddict.get('imd_module'), ddict.get('imd_name'), + ddict.get('imd_model'), ddict.get('module'), ddict.get('imd_name'), ddict['value'])) def finish(self): @@ -101,18 +100,18 @@ class ir_translation_import_cursor(object): SET res_id = imd.res_id FROM ir_model_data AS imd WHERE ti.res_id IS NULL - AND ti.imd_module IS NOT NULL AND ti.imd_name IS NOT NULL + AND ti.module IS NOT NULL AND ti.imd_name IS NOT NULL - AND ti.imd_module = imd.module AND ti.imd_name = imd.name + AND ti.module = imd.module AND ti.imd_name = imd.name AND ti.imd_model = imd.model; """ % self._table_name) if self._debug: - cr.execute("SELECT imd_module, imd_model, imd_name FROM %s " \ - "WHERE res_id IS NULL AND imd_module IS NOT NULL" % self._table_name) + cr.execute("SELECT module, imd_model, imd_name FROM %s " \ + "WHERE res_id IS NULL AND module IS NOT NULL" % self._table_name) for row in cr.fetchall(): _logger.debug("ir.translation.cursor: missing res_id for %s. %s/%s ", *row) - cr.execute("DELETE FROM %s WHERE res_id IS NULL AND imd_module IS NOT NULL" % \ + cr.execute("DELETE FROM %s WHERE res_id IS NULL AND module IS NOT NULL" % \ self._table_name) # Records w/o res_id must _not_ be inserted into our db, because they are @@ -132,8 +131,8 @@ class ir_translation_import_cursor(object): # Step 3: insert new translations - cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value) - SELECT name, lang, res_id, src, type, value + cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value, module) + SELECT name, lang, res_id, src, type, value, module FROM %s AS ti WHERE NOT EXISTS(SELECT 1 FROM ONLY %s AS irt WHERE %s); """ % (self._parent_table, self._table_name, self._parent_table, find_expr)) @@ -167,6 +166,7 @@ class ir_translation(osv.osv): 'type': fields.selection(TRANSLATION_TYPE, string='Type', size=16, select=True), 'src': fields.text('Source'), 'value': fields.text('Translation Value'), + 'module': fields.char('Module Name', size=128), } _sql_constraints = [ ('lang_fkey_res_lang', 'FOREIGN KEY(lang) REFERENCES res_lang(code)', diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 392850f7b77..1a3b41513b4 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -620,7 +620,7 @@ class module(osv.osv): f2 = modules.get_module_resource(mod.name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', mod.name, iso_lang2, lang) - tools.trans_load(cr, f2, lang, verbose=False, context=context) + tools.trans_load(cr, f2, lang, verbose=False, module_name=mod.name, context=context) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -630,7 +630,7 @@ class module(osv.osv): f = modules.get_module_resource(mod.name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', mod.name, iso_lang, lang) - tools.trans_load(cr, f, lang, verbose=False, context=context2) + tools.trans_load(cr, f, lang, verbose=False, module_name=mod.name, context=context2) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', mod.name, iso_lang) diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 6762426d8cd..2dbaa67a425 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -799,7 +799,7 @@ class translation(netsvc.ExportService): f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - translated_data.append(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, context=context)) + translated_data.append(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -809,7 +809,7 @@ class translation(netsvc.ExportService): f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - translated_data.append(tools.trans_load(cr, f, lang, verbose=False, flag=flag, context=context2)) + translated_data.append(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', module_name, iso_lang) cr.commit() diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 0d3802bd5c0..83576d8d7b9 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -843,7 +843,7 @@ def trans_generate(lang, modules, cr): return out -def trans_load(cr, filename, lang, verbose=True, flag=None, context=None): +def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, context=None): try: fileobj = misc.file_open(filename) pool = pooler.get_pool(cr.dbname) @@ -858,7 +858,7 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, context=None): return transl else: fileformat = os.path.splitext(filename)[-1][1:].lower() - r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, context=context) + r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) fileobj.close() return r except IOError: @@ -866,7 +866,7 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, context=None): _logger.error("couldn't read translation file %s", filename) return None -def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, context=None): +def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, module_name=None, context=None): """Populates the ir_translation table.""" if verbose: _logger.info('loading translation file for language %s', lang) @@ -896,7 +896,7 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, break elif fileformat == 'po': reader = TinyPoFile(fileobj) - f = ['type', 'name', 'res_id', 'src', 'value'] + f = ['type', 'name', 'res_id', 'src', 'value', 'module'] else: _logger.error('Bad file format: %s', fileformat) raise Exception(_('Bad file format')) @@ -929,6 +929,7 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, if res_id and isinstance(res_id, (int, long)) \ or (isinstance(res_id, basestring) and res_id.isdigit()): dic['res_id'] = int(res_id) + dic['module'] = module_name else: try: tmodel = dic['name'].split(',')[0] @@ -938,9 +939,8 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, tmodule = dic_module tname = res_id dic['imd_model'] = tmodel - dic['imd_module'] = tmodule + dic['module'] = tmodule dic['imd_name'] = tname - dic['res_id'] = None except Exception: _logger.warning("Could not decode resource for %s, please fix the po file.", From d87adc497e11e3f5c22da7069720b6f9270d7ada Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 14:28:38 +0530 Subject: [PATCH 03/67] [IMP] improved code to get translation from database. bzr revid: tpa@tinyerp.com-20120712085838-pqzj86fptp96eag6 --- openerp/service/web_services.py | 10 +++++++--- openerp/tools/translate.py | 13 ++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 2dbaa67a425..7f6b201d9c3 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -783,7 +783,7 @@ class translation(netsvc.ExportService): netsvc.ExportService.__init__(self, name) def exp_load(self, db, modules, langs, flag=None, context=None): - translated_data = [] + translated_data = {'messages':[]} cr = pooler.get_db(db).cursor() for module_name in modules: modpath = openerp.modules.get_module_path(module_name) @@ -799,7 +799,9 @@ class translation(netsvc.ExportService): f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - translated_data.append(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) + trans = tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context) + if trans: + translated_data['messages'].extend(trans) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -809,7 +811,9 @@ class translation(netsvc.ExportService): f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - translated_data.append(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) + trans = tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2) + if trans: + translated_data['messages'].extend(trans) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', module_name, iso_lang) cr.commit() diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 83576d8d7b9..4067133e2a9 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -849,12 +849,11 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co pool = pooler.get_pool(cr.dbname) traslation_obj = pool.get('ir.translation') _logger.info("loading %s", filename) - if flag == 'web': - transl = {"messages":[]} - po = babel.messages.pofile.read_po(fileobj) - for x in po: - if x.id and x.string and "openerp-web" in x.auto_comments: - transl["messages"].append({'id': x.id, 'string': x.string}) + if flag == 'web' and module_name == 'web': + transl = [] + trans_ids = traslation_obj.search(cr, 1, [('module','=', module_name),('lang','=',lang)]) + for trans in traslation_obj.browse(cr, 1, trans_ids, context=context): + transl.append({'id': trans.src, 'string': trans.value}) return transl else: fileformat = os.path.splitext(filename)[-1][1:].lower() @@ -913,7 +912,7 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, # dictionary which holds values for this line of the csv file # {'lang': ..., 'type': ..., 'name': ..., 'res_id': ..., - # 'src': ..., 'value': ...} + # 'src': ..., 'value': ..., 'module':...} dic = {'lang': lang} dic_module = False for i in range(len(f)): From 20646e9104a1e36a2375f0b688dc5a5ed18665b1 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 15:01:30 +0530 Subject: [PATCH 04/67] [IMP] move load function to the ir_translation.py bzr revid: tpa@tinyerp.com-20120712093130-rcis1aamb7bbptdd --- openerp/addons/base/ir/ir_translation.py | 36 ++++++++++++++++++++++++ openerp/service/web_services.py | 35 ++--------------------- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 2f8f87a0a2a..404dfb842a3 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -22,6 +22,7 @@ from osv import fields, osv import tools import logging +import openerp.modules _logger = logging.getLogger(__name__) @@ -322,6 +323,41 @@ class ir_translation(osv.osv): """ Return a cursor-like object for fast inserting translations """ return ir_translation_import_cursor(cr, uid, self, context=context) + + def load(self, cr, modules, langs, flag, context=None): + translated_data = {'messages':[]} + for module_name in modules: + modpath = openerp.modules.get_module_path(module_name) + if not modpath: + # unable to find the module. we skip + continue + for lang in langs: + iso_lang = tools.get_iso_codes(lang) + f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') + context2 = context and context.copy() or {} + if f and '_' in iso_lang: + iso_lang2 = iso_lang.split('_')[0] + f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') + if f2: + _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) + trans = tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context) + if trans: + translated_data['messages'].extend(trans) + context2['overwrite'] = True + # Implementation notice: we must first search for the full name of + # the language derivative, like "en_UK", and then the generic, + # like "en". + if (not f) and '_' in iso_lang: + iso_lang = iso_lang.split('_')[0] + f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') + if f: + _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) + trans = tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2) + if trans: + translated_data['messages'].extend(trans) + elif iso_lang != 'en': + _logger.warning('module %s: no translation for language %s', module_name, iso_lang) + return translated_data ir_translation() diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 7f6b201d9c3..17935efda54 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -783,39 +783,10 @@ class translation(netsvc.ExportService): netsvc.ExportService.__init__(self, name) def exp_load(self, db, modules, langs, flag=None, context=None): - translated_data = {'messages':[]} cr = pooler.get_db(db).cursor() - for module_name in modules: - modpath = openerp.modules.get_module_path(module_name) - if not modpath: - # unable to find the module. we skip - continue - for lang in langs: - iso_lang = tools.get_iso_codes(lang) - f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') - context2 = context and context.copy() or {} - if f and '_' in iso_lang: - iso_lang2 = iso_lang.split('_')[0] - f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') - if f2: - _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - trans = tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context) - if trans: - translated_data['messages'].extend(trans) - context2['overwrite'] = True - # Implementation notice: we must first search for the full name of - # the language derivative, like "en_UK", and then the generic, - # like "en". - if (not f) and '_' in iso_lang: - iso_lang = iso_lang.split('_')[0] - f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') - if f: - _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - trans = tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2) - if trans: - translated_data['messages'].extend(trans) - elif iso_lang != 'en': - _logger.warning('module %s: no translation for language %s', module_name, iso_lang) + pool = pooler.get_pool(cr.dbname) + traslation_obj = pool.get('ir.translation') + translated_data = traslation_obj.load(cr, modules, langs, flag, context=context) cr.commit() cr.close() return translated_data From 976944bce2f4a39f0d1f0b22737a2b0603479b32 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 15:21:31 +0530 Subject: [PATCH 05/67] [IMP] improved code in module.py to load translation. bzr revid: tpa@tinyerp.com-20120712095131-3tt25snidvafflhb --- openerp/addons/base/ir/ir_translation.py | 2 +- openerp/addons/base/module/module.py | 30 +++--------------------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 404dfb842a3..ad7d7013127 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -324,7 +324,7 @@ class ir_translation(osv.osv): """ return ir_translation_import_cursor(cr, uid, self, context=context) - def load(self, cr, modules, langs, flag, context=None): + def load(self, cr, modules, langs, flag=None, context=None): translated_data = {'messages':[]} for module_name in modules: modpath = openerp.modules.get_module_path(module_name) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 1a3b41513b4..963fb292946 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -596,8 +596,8 @@ class module(osv.osv): def update_translations(self, cr, uid, ids, filter_lang=None, context=None): if context is None: context = {} + pool = pooler.get_pool(cr.dbname) if not filter_lang: - pool = pooler.get_pool(cr.dbname) lang_obj = pool.get('res.lang') lang_ids = lang_obj.search(cr, uid, [('translatable', '=', True)]) filter_lang = [lang.code for lang in lang_obj.browse(cr, uid, lang_ids)] @@ -607,32 +607,8 @@ class module(osv.osv): for mod in self.browse(cr, uid, ids): if mod.state != 'installed': continue - modpath = modules.get_module_path(mod.name) - if not modpath: - # unable to find the module. we skip - continue - for lang in filter_lang: - iso_lang = tools.get_iso_codes(lang) - f = modules.get_module_resource(mod.name, 'i18n', iso_lang + '.po') - context2 = context and context.copy() or {} - if f and '_' in iso_lang: - iso_lang2 = iso_lang.split('_')[0] - f2 = modules.get_module_resource(mod.name, 'i18n', iso_lang2 + '.po') - if f2: - _logger.info('module %s: loading base translation file %s for language %s', mod.name, iso_lang2, lang) - tools.trans_load(cr, f2, lang, verbose=False, module_name=mod.name, context=context) - context2['overwrite'] = True - # Implementation notice: we must first search for the full name of - # the language derivative, like "en_UK", and then the generic, - # like "en". - if (not f) and '_' in iso_lang: - iso_lang = iso_lang.split('_')[0] - f = modules.get_module_resource(mod.name, 'i18n', iso_lang + '.po') - if f: - _logger.info('module %s: loading translation file (%s) for language %s', mod.name, iso_lang, lang) - tools.trans_load(cr, f, lang, verbose=False, module_name=mod.name, context=context2) - elif iso_lang != 'en': - _logger.warning('module %s: no translation for language %s', mod.name, iso_lang) + traslation_obj = pool.get('ir.translation') + traslation_obj.load(cr, [mod.name], filter_lang, context=context) def check(self, cr, uid, ids, context=None): for mod in self.browse(cr, uid, ids, context=context): From bc76991e24edc42353fc637624fa7ff4bfa8a34f Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 18:53:08 +0530 Subject: [PATCH 06/67] [IMP] improved code. bzr revid: tpa@tinyerp.com-20120712132308-1qvurv572sxmsnqe --- openerp/addons/base/ir/ir_translation.py | 8 ++------ openerp/tools/translate.py | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index ad7d7013127..0a3124b36ce 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -340,9 +340,7 @@ class ir_translation(osv.osv): f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - trans = tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context) - if trans: - translated_data['messages'].extend(trans) + translated_data['messages'].extend(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -352,9 +350,7 @@ class ir_translation(osv.osv): f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - trans = tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2) - if trans: - translated_data['messages'].extend(trans) + translated_data['messages'].extend(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', module_name, iso_lang) return translated_data diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 4067133e2a9..517b39e6999 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -857,9 +857,9 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co return transl else: fileformat = os.path.splitext(filename)[-1][1:].lower() - r = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) + trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) fileobj.close() - return r + return [] except IOError: if verbose: _logger.error("couldn't read translation file %s", filename) From c17ea49de98e6cbe2ba2c760f3bc70323bfc9202 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Thu, 12 Jul 2012 18:57:00 +0530 Subject: [PATCH 07/67] [IMP] improved code bzr revid: tpa@tinyerp.com-20120712132700-zc4co6o4plhzoi60 --- openerp/tools/translate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 517b39e6999..e9b830302f7 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -849,7 +849,7 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co pool = pooler.get_pool(cr.dbname) traslation_obj = pool.get('ir.translation') _logger.info("loading %s", filename) - if flag == 'web' and module_name == 'web': + if flag == 'web': transl = [] trans_ids = traslation_obj.search(cr, 1, [('module','=', module_name),('lang','=',lang)]) for trans in traslation_obj.browse(cr, 1, trans_ids, context=context): From f05ee5dfdb3dc5ec3f2db9b7685e5ed9e8e8fc01 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 11:23:30 +0530 Subject: [PATCH 08/67] [IMP] improved code. bzr revid: tpa@tinyerp.com-20120713055330-avz6ebzuqvcpxdd5 --- openerp/addons/base/module/module.py | 5 ++--- openerp/service/web_services.py | 4 +--- openerp/tools/translate.py | 8 +++----- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 963fb292946..bbf3f3f5b64 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -594,9 +594,9 @@ class module(osv.osv): self.write(cr, uid, [mod_browse.id], {'category_id': p_id}) def update_translations(self, cr, uid, ids, filter_lang=None, context=None): + pool = pooler.get_pool(cr.dbname) if context is None: context = {} - pool = pooler.get_pool(cr.dbname) if not filter_lang: lang_obj = pool.get('res.lang') lang_ids = lang_obj.search(cr, uid, [('translatable', '=', True)]) @@ -607,8 +607,7 @@ class module(osv.osv): for mod in self.browse(cr, uid, ids): if mod.state != 'installed': continue - traslation_obj = pool.get('ir.translation') - traslation_obj.load(cr, [mod.name], filter_lang, context=context) + pool.get('ir.translation').load(cr, [mod.name], filter_lang, context=context) def check(self, cr, uid, ids, context=None): for mod in self.browse(cr, uid, ids, context=context): diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index 17935efda54..0cfcf468a2b 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -784,9 +784,7 @@ class translation(netsvc.ExportService): def exp_load(self, db, modules, langs, flag=None, context=None): cr = pooler.get_db(db).cursor() - pool = pooler.get_pool(cr.dbname) - traslation_obj = pool.get('ir.translation') - translated_data = traslation_obj.load(cr, modules, langs, flag, context=context) + translated_data = pooler.get_pool(db).get('ir.translation').load(cr, modules, langs, flag, context=context) cr.commit() cr.close() return translated_data diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index e9b830302f7..bbada8c2efc 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -846,20 +846,18 @@ def trans_generate(lang, modules, cr): def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, context=None): try: fileobj = misc.file_open(filename) - pool = pooler.get_pool(cr.dbname) - traslation_obj = pool.get('ir.translation') + traslation_obj = pooler.get_pool(cr.dbname).get('ir.translation') _logger.info("loading %s", filename) + transl = [] if flag == 'web': - transl = [] trans_ids = traslation_obj.search(cr, 1, [('module','=', module_name),('lang','=',lang)]) for trans in traslation_obj.browse(cr, 1, trans_ids, context=context): transl.append({'id': trans.src, 'string': trans.value}) - return transl else: fileformat = os.path.splitext(filename)[-1][1:].lower() trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) fileobj.close() - return [] + return transl except IOError: if verbose: _logger.error("couldn't read translation file %s", filename) From 402ba23000ed38f2d4c95d5b240d6327d70b3731 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 12:25:21 +0530 Subject: [PATCH 09/67] [IMP] improved code to retun traslation in proper format from server bzr revid: tpa@tinyerp.com-20120713065521-07a7qdfxfio673cq --- openerp/addons/base/ir/ir_translation.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 0a3124b36ce..cd6fa271852 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -325,8 +325,9 @@ class ir_translation(osv.osv): return ir_translation_import_cursor(cr, uid, self, context=context) def load(self, cr, modules, langs, flag=None, context=None): - translated_data = {'messages':[]} + translated_data = {} for module_name in modules: + translated_data[module_name] = {'messages':[]} modpath = openerp.modules.get_module_path(module_name) if not modpath: # unable to find the module. we skip @@ -340,7 +341,7 @@ class ir_translation(osv.osv): f2 = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang2 + '.po') if f2: _logger.info('module %s: loading base translation file %s for language %s', module_name, iso_lang2, lang) - translated_data['messages'].extend(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) + translated_data[module_name]['messages'].extend(tools.trans_load(cr, f2, lang, verbose=False, flag=flag, module_name=module_name, context=context)) context2['overwrite'] = True # Implementation notice: we must first search for the full name of # the language derivative, like "en_UK", and then the generic, @@ -350,7 +351,7 @@ class ir_translation(osv.osv): f = openerp.modules.get_module_resource(module_name, 'i18n', iso_lang + '.po') if f: _logger.info('module %s: loading translation file (%s) for language %s', module_name, iso_lang, lang) - translated_data['messages'].extend(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) + translated_data[module_name]['messages'].extend(tools.trans_load(cr, f, lang, verbose=False, flag=flag, module_name=module_name, context=context2)) elif iso_lang != 'en': _logger.warning('module %s: no translation for language %s', module_name, iso_lang) return translated_data From 8383d6a2459588b332ecdcb0a26c38f92c5ab317 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 14:58:38 +0530 Subject: [PATCH 10/67] [IMP] Fetch only traslated and distinct strings using sql. bzr revid: tpa@tinyerp.com-20120713092838-5th251msbdkgjdnb --- openerp/tools/translate.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index bbada8c2efc..11801326ba3 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -850,9 +850,9 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co _logger.info("loading %s", filename) transl = [] if flag == 'web': - trans_ids = traslation_obj.search(cr, 1, [('module','=', module_name),('lang','=',lang)]) - for trans in traslation_obj.browse(cr, 1, trans_ids, context=context): - transl.append({'id': trans.src, 'string': trans.value}) + cr.execute("select DISTINCT src,value from ir_translation where module='%s' AND value != ''"% (module_name)) + for src, value in cr.fetchall(): + transl.append({'id': src, 'string': value}) else: fileformat = os.path.splitext(filename)[-1][1:].lower() trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context) From 48a344c1e8d88b005eaf29128890196fd096b441 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 13 Jul 2012 15:24:48 +0530 Subject: [PATCH 11/67] [IMP] improved code. bzr revid: tpa@tinyerp.com-20120713095448-ghr750h2jk9ivsj2 --- openerp/tools/translate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 11801326ba3..25e80e260fa 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -850,7 +850,7 @@ def trans_load(cr, filename, lang, verbose=True, flag=None, module_name=None, co _logger.info("loading %s", filename) transl = [] if flag == 'web': - cr.execute("select DISTINCT src,value from ir_translation where module='%s' AND value != ''"% (module_name)) + cr.execute("select DISTINCT src,value from ir_translation where module='%s' AND lang='%s' AND value != ''"% (module_name,lang)) for src, value in cr.fetchall(): transl.append({'id': src, 'string': value}) else: From d931a099ac4551a4d24724a09ecc12d3951a82b6 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Mon, 16 Jul 2012 16:04:58 +0530 Subject: [PATCH 12/67] [ADD] added test case for translation load in tests_xmlrpc.py. bzr revid: tpa@tinyerp.com-20120716103458-p2l9p38g4ubl7d2i --- openerp/tests/common.py | 1 + openerp/tests/test_xmlrpc.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/openerp/tests/common.py b/openerp/tests/common.py index ef5b0586136..351645c41f2 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -72,6 +72,7 @@ class RpcCase(unittest2.TestCase): self.proxy.common_61 = xmlrpclib.ServerProxy(url_61 + 'common') self.proxy.db_61 = xmlrpclib.ServerProxy(url_61 + 'db') self.proxy.model_61 = xmlrpclib.ServerProxy(url_61 + 'model/' + DB) + self.proxy.translation_61 = xmlrpclib.ServerProxy(url_61 + 'translation') @classmethod def generate_database_name(cls): diff --git a/openerp/tests/test_xmlrpc.py b/openerp/tests/test_xmlrpc.py index 37655e72718..5f73325fe4c 100644 --- a/openerp/tests/test_xmlrpc.py +++ b/openerp/tests/test_xmlrpc.py @@ -71,6 +71,11 @@ class test_xmlrpc(common.RpcCase): """ assert self.proxy.db_60.drop(ADMIN_PASSWORD, DB) is True + def test_xmlrpc_61_translation_load(self): + """ Try a load translation service like web. """ + messages = self.proxy.translation_61.load(DB, ['base', 'web'], ['ru_RU'], 'web') + assert messages + if __name__ == '__main__': unittest2.main() From 74fd43b82c211d416fef8f9b1ff10bc43d5aaab8 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Mon, 16 Jul 2012 16:13:05 +0530 Subject: [PATCH 13/67] [IMP] change language. bzr revid: tpa@tinyerp.com-20120716104305-ws8igxbfx7m0bwy9 --- openerp/tests/test_xmlrpc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tests/test_xmlrpc.py b/openerp/tests/test_xmlrpc.py index 5f73325fe4c..70ac6b1f75f 100644 --- a/openerp/tests/test_xmlrpc.py +++ b/openerp/tests/test_xmlrpc.py @@ -73,7 +73,7 @@ class test_xmlrpc(common.RpcCase): def test_xmlrpc_61_translation_load(self): """ Try a load translation service like web. """ - messages = self.proxy.translation_61.load(DB, ['base', 'web'], ['ru_RU'], 'web') + messages = self.proxy.translation_61.load(DB, ['base', 'web'], ['en_US'], 'web') assert messages if __name__ == '__main__': From 09ba29883c06d1f1de06c40e89c864c85f53d5c7 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Tue, 11 Sep 2012 15:52:54 +0200 Subject: [PATCH 14/67] [FIX] ir.translation: typo in last sync with trunk bzr revid: odo@openerp.com-20120911135254-uqi1s4n8qh0e3d1y --- openerp/addons/base/ir/ir_translation.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 68b413344b2..c8f9cf8e6fe 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -68,7 +68,6 @@ class ir_translation_import_cursor(object): # Note that Postgres will NOT inherit the constraints or indexes # of ir_translation, so this copy will be much faster. - cr.execute('''CREATE TEMP TABLE %s( imd_model VARCHAR(64), imd_name VARCHAR(128) @@ -77,16 +76,14 @@ class ir_translation_import_cursor(object): def push(self, trans_dict): """Feed a translation, as a dictionary, into the cursor """ - params = dict(trans_dict, - state="translated" if trans_dict['value'] else "to_translate") + params = dict(trans_dict, state="translated" if trans_dict['value'] else "to_translate") self._cr.execute("""INSERT INTO %s (name, lang, res_id, src, type, imd_model, module, imd_name, value, state) - VALUES (%(name)s, %(lang)s, %(res_id)s, %(src)s, %(type)s, %(imd_model)s, %(module)s, %(imd_name)s, %(value)s, %(state)s)""", - params) + VALUES (%%(name)s, %%(lang)s, %%(res_id)s, %%(src)s, %%(type)s, %%(imd_model)s, %%(module)s, %%(imd_name)s, %%(value)s, %%(state)s)""" % self._table_name, + params) def finish(self): """ Transfer the data from the temp table to ir.translation """ - cr = self._cr if self._debug: cr.execute("SELECT count(*) FROM %s" % self._table_name) @@ -129,7 +126,6 @@ class ir_translation_import_cursor(object): """ % (self._parent_table, self._table_name, find_expr)) # Step 3: insert new translations - cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value, module, state) SELECT name, lang, res_id, src, type, value, module, state FROM %s AS ti From 550751b35825d60af0ed5985cd46b4ff4e2d3d01 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Thu, 13 Sep 2012 16:29:20 +0200 Subject: [PATCH 15/67] [IMP] translations: wip, remove unnecessary code, support loading PO comments and storing them, split ir.translation view data in separate XML file bzr revid: odo@openerp.com-20120913142920-ggpeqth4s2wwqwd2 --- openerp/addons/base/__openerp__.py | 1 + openerp/addons/base/ir/ir.xml | 69 ------------- openerp/addons/base/ir/ir_translation.py | 123 ++++++++++++----------- openerp/addons/base/ir/ir_ui_view.py | 5 +- openerp/addons/base/module/module.py | 16 +-- openerp/service/web_services.py | 24 ----- openerp/tests/common.py | 1 - openerp/tests/test_xmlrpc.py | 5 - openerp/tools/translate.py | 61 ++++++----- 9 files changed, 98 insertions(+), 207 deletions(-) diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py index 937c9cbd20b..082cf260373 100644 --- a/openerp/addons/base/__openerp__.py +++ b/openerp/addons/base/__openerp__.py @@ -44,6 +44,7 @@ The kernel of OpenERP, needed for all installation. 'data/res.country.state.csv', 'ir/wizard/wizard_menu_view.xml', 'ir/ir.xml', + 'ir/ir_translation_view.xml', 'ir/ir_filters.xml', 'ir/ir_config_parameter_view.xml', 'ir/workflow/workflow_view.xml', diff --git a/openerp/addons/base/ir/ir.xml b/openerp/addons/base/ir/ir.xml index 29bb681981a..515d9641001 100644 --- a/openerp/addons/base/ir/ir.xml +++ b/openerp/addons/base/ir/ir.xml @@ -1147,75 +1147,6 @@ - - - - Translations - ir.translation - - - - - - - - - - - - - Translations - ir.translation - -
-
- -
- - - - - - - - - - - - - - - - - - -
-
-
- - Translations - ir.translation - - - - - - - - - - - - - Translated Terms - ir.translation - form - - - - + + Translations + ir.translation + + + + + + + + + + + + + + Translations + ir.translation + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+
+
+ + Translations + ir.translation + + + + + + + + + + + + + Translated Terms + ir.translation + form + + + + + + + \ No newline at end of file From f76f9d00013a8cfaee042124d4e54b61bdb895b1 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Fri, 28 Sep 2012 14:07:03 +0200 Subject: [PATCH 18/67] [IMP] base.export.language: improve/cleanup wizard model and its form view bzr revid: odo@openerp.com-20120928120703-n87j8osun6bptehm --- .../module/wizard/base_export_language.py | 86 +++++++++---------- .../wizard/base_export_language_view.xml | 46 ++++++---- 2 files changed, 72 insertions(+), 60 deletions(-) diff --git a/openerp/addons/base/module/wizard/base_export_language.py b/openerp/addons/base/module/wizard/base_export_language.py index 5ff99501943..80cb2d70292 100644 --- a/openerp/addons/base/module/wizard/base_export_language.py +++ b/openerp/addons/base/module/wizard/base_export_language.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- ############################################################################## # -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). +# OpenERP, Open Source Business Applications +# Copyright (c) 2004-2012 OpenERP S.A. # # 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,68 +22,68 @@ import tools import base64 import cStringIO -import pooler from osv import fields,osv from tools.translate import _ from tools.misc import get_iso_codes +NEW_LANG_KEY = '__new__' + class base_language_export(osv.osv_memory): + _name = "base.language.export" def _get_languages(self, cr, uid, context): - lang_obj=pooler.get_pool(cr.dbname).get('res.lang') - ids=lang_obj.search(cr, uid, ['&', ('active', '=', True), ('translatable', '=', True),]) - langs=lang_obj.browse(cr, uid, ids) - return [(lang.code, lang.name) for lang in langs] - - def act_cancel(self, cr, uid, ids, context=None): - #self.unlink(cr, uid, ids, context) - return {'type':'ir.actions.act_window_close' } - - def act_destroy(self, *args): - return {'type':'ir.actions.act_window_close' } + lang_obj = self.pool.get('res.lang') + ids = lang_obj.search(cr, uid, [('translatable', '=', True)]) + langs = lang_obj.browse(cr, uid, ids) + return [(NEW_LANG_KEY, _('New Language (Empty translation template)'))] + [(lang.code, lang.name) for lang in langs] + + _columns = { + 'name': fields.char('File Name', readonly=True), + 'lang': fields.selection(_get_languages, 'Language', required=True), + 'format': fields.selection([('csv','CSV File'), + ('po','PO File'), + ('tgz', 'TGZ Archive')], 'File Format', required=True), + 'modules': fields.many2many('ir.module.module', 'rel_modules_langexport', 'wiz_id', 'module_id', 'Modules To Export', domain=[('state','=','installed')]), + 'data': fields.binary('File', readonly=True), + 'advice': fields.text('Note', readonly=True), + 'state': fields.selection([('choose', 'choose'), # choose language + ('get', 'get')]) # get the file + } + _defaults = { + 'state': 'choose', + 'name': 'lang.tar.gz', + 'lang': NEW_LANG_KEY, + 'format': 'csv', + } def act_getfile(self, cr, uid, ids, context=None): this = self.browse(cr, uid, ids)[0] + lang = this.lang if this.lang != NEW_LANG_KEY else False mods = map(lambda m: m.name, this.modules) or ['all'] mods.sort() - buf=cStringIO.StringIO() + buf = cStringIO.StringIO() tools.trans_export(this.lang, mods, buf, this.format, cr) if this.format == 'csv': - this.advice = _("Save this document to a .CSV file and open it with your favourite spreadsheet software. The file encoding is UTF-8. You have to translate the latest column before reimporting it.") + this.advice = _("Save this document as a .CSV file and open it with your favourite spreadsheet software. The file encoding is UTF-8. You have to translate the last column before reimporting it.") elif this.format == 'po': - if not this.lang: + if not lang: this.format = 'pot' - this.advice = _("Save this document to a %s file and edit it with a specific software or a text editor. The file encoding is UTF-8.") % ('.'+this.format,) + this.advice = _("Save this document as a %s file and edit it with a PO editor or a text editor. The file encoding is UTF-8.") % ('.'+this.format,) elif this.format == 'tgz': - ext = this.lang and '.po' or '.pot' - this.advice = _('Save this document to a .tgz file. This archive containt UTF-8 %s files and may be uploaded to launchpad.') % (ext,) + this.advice = _('Save this document as a .tgz file. This archive contains UTF-8 %s files and may be uploaded to launchpad.') filename = _('new') - if not this.lang and len(mods) == 1: - filename = mods[0] - if this.lang: + if lang: filename = get_iso_codes(this.lang) + elif len(mods) == 1: + filename = mods[0] this.name = "%s.%s" % (filename, this.format) - out=base64.encodestring(buf.getvalue()) + out = base64.encodestring(buf.getvalue()) buf.close() - return self.write(cr, uid, ids, {'state':'get', 'data':out, 'advice':this.advice, 'name':this.name}, context=context) + self.write(cr, uid, ids, {'state': 'get', + 'data': out, + 'advice': this.advice, + 'name':this.name}, context=context) + return True - _name = "base.language.export" - _inherit = "ir.wizard.screen" - _columns = { - 'name': fields.char('File Name', 16, readonly=True), - 'lang': fields.selection(_get_languages, 'Language', help='To export a new language, do not select a language.'), # not required: unset = new language - 'format': fields.selection( ( ('csv','CSV File'), ('po','PO File'), ('tgz', 'TGZ Archive')), 'File Format', required=True), - 'modules': fields.many2many('ir.module.module', 'rel_modules_langexport', 'wiz_id', 'module_id', 'Modules', domain=[('state','=','installed')]), - 'data': fields.binary('File', readonly=True), - 'advice': fields.text('Advice', readonly=True), - 'state': fields.selection( ( ('choose','choose'), # choose language - ('get','get'), # get the file - ) ), - } - _defaults = { - 'state': lambda *a: 'choose', - 'name': lambda *a: 'lang.tar.gz' - } -base_language_export() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/module/wizard/base_export_language_view.xml b/openerp/addons/base/module/wizard/base_export_language_view.xml index 88e411845c3..2e50b3bed8f 100644 --- a/openerp/addons/base/module/wizard/base_export_language_view.xml +++ b/openerp/addons/base/module/wizard/base_export_language_view.xml @@ -1,31 +1,43 @@ - - Export Translations + Translations Export base.language.export -
- - + + + + - - - - - - - - - + + +
+

Export Complete

+

Here is the exported translation file:

+

This file was generated using the universal Unicode/UTF-8 file encoding, please be sure to view and edit + using the same encoding.

+

The next step depends on the file format: +

    +
  • CSV format: you may edit it directly with your favorite spreadsheet software, + the rightmost column (value) contains the translations
  • +
  • PO(T) format: you should edit it with a PO editor such as + POEdit, or your preferred text editor
  • +
  • TGZ format: this is a compressed archive containing a PO file, directly suitable + for uploading to OpenERP's translation platform, + Launchpad
  • +
+

+

For more details about translating OpenERP in your language, please refer to the + documentation.

+
-
-
From d8c74879e8eedf5139f1e0b23c087c70b9017f81 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Fri, 28 Sep 2012 14:22:06 +0200 Subject: [PATCH 19/67] [REM] Remove unused ir.wizard.menu and ir.wizard.screen - internal wizards used for config, now gone ; some lint cleanup bzr revid: odo@openerp.com-20120928122206-iynu3ilsurzecwde --- openerp/addons/base/__openerp__.py | 1 - openerp/addons/base/ir/__init__.py | 1 - openerp/addons/base/ir/wizard/__init__.py | 24 ------- openerp/addons/base/ir/wizard/wizard_menu.py | 72 ------------------- .../base/ir/wizard/wizard_menu_view.xml | 23 ------ .../addons/base/ir/wizard/wizard_screen.py | 54 -------------- .../module/wizard/base_import_language.py | 3 - .../module/wizard/base_language_install.py | 3 - .../base/module/wizard/base_module_import.py | 4 -- .../base/module/wizard/base_module_update.py | 4 -- .../module/wizard/base_update_translations.py | 18 ++--- .../wizard/base_update_translations_view.xml | 2 +- openerp/addons/base/res/res_config.py | 1 - 13 files changed, 7 insertions(+), 203 deletions(-) delete mode 100644 openerp/addons/base/ir/wizard/__init__.py delete mode 100644 openerp/addons/base/ir/wizard/wizard_menu.py delete mode 100644 openerp/addons/base/ir/wizard/wizard_menu_view.xml delete mode 100644 openerp/addons/base/ir/wizard/wizard_screen.py diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py index 69552a61f72..173c6adcbc4 100644 --- a/openerp/addons/base/__openerp__.py +++ b/openerp/addons/base/__openerp__.py @@ -42,7 +42,6 @@ The kernel of OpenERP, needed for all installation. 'res/res_security.xml', 'res/res_config.xml', 'data/res.country.state.csv', - 'ir/wizard/wizard_menu_view.xml', 'ir/ir.xml', 'ir/ir_translation_view.xml', 'ir/ir_filters.xml', diff --git a/openerp/addons/base/ir/__init__.py b/openerp/addons/base/ir/__init__.py index bc4f3eecfbf..c296042e3b2 100644 --- a/openerp/addons/base/ir/__init__.py +++ b/openerp/addons/base/ir/__init__.py @@ -36,7 +36,6 @@ import ir_translation import ir_exports import workflow import ir_rule -import wizard import ir_config_parameter import osv_memory_autovacuum import ir_mail_server diff --git a/openerp/addons/base/ir/wizard/__init__.py b/openerp/addons/base/ir/wizard/__init__.py deleted file mode 100644 index 3f5495524f5..00000000000 --- a/openerp/addons/base/ir/wizard/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). -# -# 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 . -# -############################################################################## -import wizard_menu -import wizard_screen -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/openerp/addons/base/ir/wizard/wizard_menu.py b/openerp/addons/base/ir/wizard/wizard_menu.py deleted file mode 100644 index 3b4dc797c99..00000000000 --- a/openerp/addons/base/ir/wizard/wizard_menu.py +++ /dev/null @@ -1,72 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). -# -# 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 . -# -############################################################################## -from osv import fields,osv - -class wizard_model_menu(osv.osv_memory): - _name = 'wizard.ir.model.menu.create' - _columns = { - 'menu_id': fields.many2one('ir.ui.menu', 'Parent Menu', required=True), - 'name': fields.char('Menu Name', size=64, required=True), - } - - def menu_create(self, cr, uid, ids, context=None): - if not context: - context = {} - model_pool = self.pool.get('ir.model') - for menu in self.browse(cr, uid, ids, context): - model = model_pool.browse(cr, uid, context.get('model_id'), context=context) - val = { - 'name': menu.name, - 'res_model': model.model, - 'view_type': 'form', - 'view_mode': 'tree,form' - } - action_id = self.pool.get('ir.actions.act_window').create(cr, uid, val) - self.pool.get('ir.ui.menu').create(cr, uid, { - 'name': menu.name, - 'parent_id': menu.menu_id.id, - 'action': 'ir.actions.act_window,%d' % (action_id,), - 'icon': 'STOCK_INDENT' - }, context) - return {'type':'ir.actions.act_window_close'} -wizard_model_menu() - -class wizard_model_menu_line(osv.osv_memory): - _name = 'wizard.ir.model.menu.create.line' - _columns = { - 'wizard_id': fields.many2one('wizard.ir.model.menu.create','Wizard'), - 'sequence': fields.integer('Sequence'), - 'view_type': fields.selection([ - ('tree','Tree'), - ('form','Form'), - ('graph','Graph'), - ('calendar','Calendar'), - ('gantt','Gantt')],'View Type',required=True), - 'view_id': fields.many2one('ir.ui.view', 'View'), - } - _defaults = { - 'view_type': lambda self,cr,uid,ctx: 'tree' - } -wizard_model_menu_line() - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/openerp/addons/base/ir/wizard/wizard_menu_view.xml b/openerp/addons/base/ir/wizard/wizard_menu_view.xml deleted file mode 100644 index 7fd32b256e2..00000000000 --- a/openerp/addons/base/ir/wizard/wizard_menu_view.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - Create Menu - wizard.ir.model.menu.create - -
- - - - -
-
-
-
-
- -
-
diff --git a/openerp/addons/base/ir/wizard/wizard_screen.py b/openerp/addons/base/ir/wizard/wizard_screen.py deleted file mode 100644 index d413ce0474e..00000000000 --- a/openerp/addons/base/ir/wizard/wizard_screen.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Copyright (C) 2010 OpenERP s.a. (). -# -# 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 . -# -############################################################################## -import base64 -import os -import random - -import tools -from osv import fields,osv - -# Simple base class for wizards that wish to use random images on the left -# side of the form. -class wizard_screen(osv.osv_memory): - _name = 'ir.wizard.screen' - - def _get_image(self, cr, uid, context=None): - path = os.path.join('base','res','config_pixmaps','%d.png'%random.randrange(1,4)) - image_file = file_data = tools.file_open(path,'rb') - try: - file_data = image_file.read() - return base64.encodestring(file_data) - finally: - image_file.close() - - def _get_image_fn(self, cr, uid, ids, name, args, context=None): - image = self._get_image(cr, uid, context) - return dict.fromkeys(ids, image) # ok to use .fromkeys() as the image is same for all - - _columns = { - 'config_logo': fields.function(_get_image_fn, string='Image', type='binary'), - } - - _defaults = { - 'config_logo': _get_image - } -wizard_screen() - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/module/wizard/base_import_language.py b/openerp/addons/base/module/wizard/base_import_language.py index 94b9ae4db59..6f09dc43d90 100644 --- a/openerp/addons/base/module/wizard/base_import_language.py +++ b/openerp/addons/base/module/wizard/base_import_language.py @@ -29,8 +29,6 @@ class base_language_import(osv.osv_memory): _name = "base.language.import" _description = "Language Import" - _inherit = "ir.wizard.screen" - _columns = { 'name': fields.char('Language Name',size=64 , required=True), 'code': fields.char('Code (eg:en__US)',size=5 , required=True), @@ -66,6 +64,5 @@ class base_language_import(osv.osv_memory): fileobj.close() return {} -base_language_import() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/module/wizard/base_language_install.py b/openerp/addons/base/module/wizard/base_language_install.py index 1e40f84cc60..ab65159f0d4 100644 --- a/openerp/addons/base/module/wizard/base_language_install.py +++ b/openerp/addons/base/module/wizard/base_language_install.py @@ -27,9 +27,7 @@ class base_language_install(osv.osv_memory): """ Install Language""" _name = "base.language.install" - _inherit = "ir.wizard.screen" _description = "Install Language" - _columns = { 'lang': fields.selection(tools.scan_languages(),'Language', required=True), 'overwrite': fields.boolean('Overwrite Existing Terms', help="If you check this box, your customized translations will be overwritten and replaced by the official ones."), @@ -63,6 +61,5 @@ class base_language_install(osv.osv_memory): 'target': 'new', 'res_id': ids and ids[0] or False, } -base_language_install() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/module/wizard/base_module_import.py b/openerp/addons/base/module/wizard/base_module_import.py index 3ef9132af0e..34f22bf82f0 100644 --- a/openerp/addons/base/module/wizard/base_module_import.py +++ b/openerp/addons/base/module/wizard/base_module_import.py @@ -34,9 +34,7 @@ class base_module_import(osv.osv_memory): """ Import Module """ _name = "base.module.import" - _inherit = "ir.wizard.screen" _description = "Import Module" - _columns = { 'module_file': fields.binary('Module .ZIP file', required=True), 'state':fields.selection([('init','init'),('done','done')], @@ -88,7 +86,5 @@ class base_module_import(osv.osv_memory): 'type': 'ir.actions.act_window', } -base_module_import() - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/module/wizard/base_module_update.py b/openerp/addons/base/module/wizard/base_module_update.py index a0d21840d90..0893761cd28 100644 --- a/openerp/addons/base/module/wizard/base_module_update.py +++ b/openerp/addons/base/module/wizard/base_module_update.py @@ -25,7 +25,6 @@ class base_module_update(osv.osv_memory): _name = "base.module.update" _description = "Update Module" - _inherit = "ir.wizard.screen" _columns = { 'update': fields.integer('Number of modules updated', readonly=True), @@ -55,7 +54,4 @@ class base_module_update(osv.osv_memory): } return res - -base_module_update() - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/openerp/addons/base/module/wizard/base_update_translations.py b/openerp/addons/base/module/wizard/base_update_translations.py index d24851b1cd5..abfbc445316 100644 --- a/openerp/addons/base/module/wizard/base_update_translations.py +++ b/openerp/addons/base/module/wizard/base_update_translations.py @@ -21,31 +21,28 @@ from osv import osv, fields import tools -import pooler import cStringIO from tools.translate import _ class base_update_translations(osv.osv_memory): def _get_languages(self, cr, uid, context): - lang_obj=pooler.get_pool(cr.dbname).get('res.lang') - ids=lang_obj.search(cr, uid, ['&', ('active', '=', True), ('translatable', '=', True),]) - langs=lang_obj.browse(cr, uid, ids) + lang_obj = self.pool.get('res.lang') + ids = lang_obj.search(cr, uid, ['&', ('active', '=', True), ('translatable', '=', True),]) + langs = lang_obj.browse(cr, uid, ids) return [(lang.code, lang.name) for lang in langs] def _get_lang_name(self, cr, uid, lang_code): - lang_obj=pooler.get_pool(cr.dbname).get('res.lang') - ids=lang_obj.search(cr, uid, [('code', '=', lang_code)]) + lang_obj = self.pool.get('res.lang') + ids = lang_obj.search(cr, uid, [('code', '=', lang_code)]) if not ids: raise osv.except_osv(_('Error!'), _('No language with code "%s" exists') % lang_code) lang = lang_obj.browse(cr, uid, ids[0]) return lang.name - def act_cancel(self, cr, uid, ids, context=None): - return {'type': 'ir.actions.act_window_close'} def act_update(self, cr, uid, ids, context=None): this = self.browse(cr, uid, ids)[0] lang_name = self._get_lang_name(cr, uid, this.lang) - buf=cStringIO.StringIO() + buf = cStringIO.StringIO() tools.trans_export(this.lang, ['all'], buf, 'csv', cr) tools.trans_load_data(cr, buf, 'csv', this.lang, lang_name=lang_name) buf.close() @@ -66,11 +63,8 @@ class base_update_translations(osv.osv_memory): return res _name = 'base.update.translations' - _inherit = "ir.wizard.screen" _columns = { 'lang': fields.selection(_get_languages, 'Language', required=True), } -base_update_translations() - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/module/wizard/base_update_translations_view.xml b/openerp/addons/base/module/wizard/base_update_translations_view.xml index 4a20ef30bee..18fd30532bd 100644 --- a/openerp/addons/base/module/wizard/base_update_translations_view.xml +++ b/openerp/addons/base/module/wizard/base_update_translations_view.xml @@ -12,7 +12,7 @@
diff --git a/openerp/addons/base/res/res_config.py b/openerp/addons/base/res/res_config.py index d6b42e970bf..c24fc11a377 100644 --- a/openerp/addons/base/res/res_config.py +++ b/openerp/addons/base/res/res_config.py @@ -37,7 +37,6 @@ class res_config_configurable(osv.osv_memory): their view inherit from the related res_config_view_base view. ''' _name = 'res.config' - _inherit = 'ir.wizard.screen' def _next_action(self, cr, uid, context=None): Todos = self.pool['ir.actions.todo'] From af41ee194cc47ba15376486ee33bc43b71cad8bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 1 Oct 2012 14:39:13 +0200 Subject: [PATCH 20/67] [FIX] css: icons overlapping text in notes bzr revid: fva@openerp.com-20121001123913-nn50tybpc73o1byn --- addons/web_kanban/static/src/css/kanban.css | 9 +++------ addons/web_kanban/static/src/css/kanban.sass | 7 +++---- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/addons/web_kanban/static/src/css/kanban.css b/addons/web_kanban/static/src/css/kanban.css index d865213c8a6..6846171a82a 100644 --- a/addons/web_kanban/static/src/css/kanban.css +++ b/addons/web_kanban/static/src/css/kanban.css @@ -385,9 +385,6 @@ .openerp .oe_kanban_view .oe_kanban_card h3:hover, .openerp .oe_kanban_view .oe_kanban_quick_create h3:hover { text-decoration: none; } -.openerp .oe_kanban_view .oe_kanban_card .oe_dropdown_kanban, .openerp .oe_kanban_view .oe_kanban_quick_create .oe_dropdown_kanban { - margin-top: 4px; -} .openerp .oe_kanban_view .oe_kanban_card .oe_dropdown_kanban .oe_kanban_project_times li, .openerp .oe_kanban_view .oe_kanban_quick_create .oe_dropdown_kanban .oe_kanban_project_times li { float: left; } @@ -480,10 +477,10 @@ white-space: nowrap; } .openerp .oe_kanban_view .oe_dropdown_kanban { - position: absolute; - top: -8px; - right: 3px; + float: right; + clear: both; cursor: pointer; + margin-top: -6px; } .openerp .oe_kanban_view .oe_dropdown_kanban:hover { text-decoration: none; diff --git a/addons/web_kanban/static/src/css/kanban.sass b/addons/web_kanban/static/src/css/kanban.sass index 8063d9d2cb8..88b60134f24 100644 --- a/addons/web_kanban/static/src/css/kanban.sass +++ b/addons/web_kanban/static/src/css/kanban.sass @@ -341,7 +341,6 @@ h3:hover text-decoration: none .oe_dropdown_kanban - margin-top: 4px .oe_kanban_project_times li float: left @@ -404,10 +403,10 @@ // }}} // KanbanDropDown {{{ .oe_dropdown_kanban - position: absolute - top: -8px - right: 3px + float: right + clear: both cursor: pointer + margin-top: -6px &:hover text-decoration: none .oe_dropdown_menu From 6c8ed08bf3457838d06c49ef4bc40e786124aaee Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Mon, 1 Oct 2012 16:27:35 +0200 Subject: [PATCH 21/67] [IMP] yaml processing: fixed the creation of record through yaml files in order to use the views and on_change() functions that match the initial fields_view_get(). bzr revid: qdp-launchpad@openerp.com-20121001142735-bvqx48fbt9lyesjw --- openerp/tools/yaml_import.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/openerp/tools/yaml_import.py b/openerp/tools/yaml_import.py index 14b857cd658..f88f253c0f2 100644 --- a/openerp/tools/yaml_import.py +++ b/openerp/tools/yaml_import.py @@ -313,13 +313,14 @@ class YamlInterpreter(object): #context = self.get_context(record, self.eval_context) #TOFIX: record.context like {'withoutemployee':True} should pass from self.eval_context. example: test_project.yml in project module context = record.context + fields_view_get_result = False if view_id: varg = view_id if view_id is True: varg = False - view = model.fields_view_get(self.cr, SUPERUSER_ID, varg, 'form', context) - view_id = etree.fromstring(view['arch'].encode('utf-8')) + fields_view_get_result = model.fields_view_get(self.cr, SUPERUSER_ID, varg, 'form', context) + view_id = etree.fromstring(fields_view_get_result['arch'].encode('utf-8')) - record_dict = self._create_record(model, fields, view_id, default=default) + record_dict = self._create_record(model, fields, view_id, default=default, fields_view_get=fields_view_get_result) _logger.debug("RECORD_DICT %s" % record_dict) id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, record.model, \ self.module, record_dict, record.id, noupdate=self.isnoupdate(record), mode=self.mode, context=context) @@ -327,7 +328,7 @@ class YamlInterpreter(object): if config.get('import_partial'): self.cr.commit() - def _create_record(self, model, fields, view=False, parent={}, default=True): + def _create_record(self, model, fields, view=False, parent={}, default=True, fields_view_get=None): if view is not False: defaults = default and model._add_missing_default_values(self.cr, SUPERUSER_ID, {}, context=self.context) or {} fg = model.fields_get(self.cr, SUPERUSER_ID, context=self.context) @@ -359,12 +360,14 @@ class YamlInterpreter(object): view2 = None # if the form view is not inline, we call fields_view_get if (view is not False) and (fg[field_name]['type']=='one2many'): - view2 = view.find("field[@name='%s']/form"%(field_name,)) + tmp = fields_view_get['fields'][field_name]['views'] + if tmp.has_key('form'): + view2 = tmp.get('form') if not view2: view2 = self.pool.get(fg[field_name]['relation']).fields_view_get(self.cr, SUPERUSER_ID, False, 'form', self.context) - view2 = etree.fromstring(view2['arch'].encode('utf-8')) + view2 = etree.fromstring(view2['arch'].encode('utf-8')) - field_value = self._eval_field(model, field_name, fields[field_name], view2, parent=record_dict, default=default) + field_value = self._eval_field(model, field_name, fields[field_name], view2, parent=record_dict, default=default, fields_view_get=fields_view_get) record_dict[field_name] = field_value #if (field_name in defaults) and defaults[field_name] == field_value: # print '*** You can remove these lines:', field_name, field_value @@ -409,7 +412,7 @@ class YamlInterpreter(object): for field_name, expression in fields.items(): if field_name in record_dict: continue - field_value = self._eval_field(model, field_name, expression, default=False) + field_value = self._eval_field(model, field_name, expression, default=False, fields_view_get=fields_view_get) record_dict[field_name] = field_value return record_dict @@ -440,7 +443,7 @@ class YamlInterpreter(object): def process_eval(self, node): return eval(node.expression, self.eval_context) - def _eval_field(self, model, field_name, expression, view=False, parent={}, default=True): + def _eval_field(self, model, field_name, expression, view=False, parent={}, default=True, fields_view_get=None): # TODO this should be refactored as something like model.get_field() in bin/osv if field_name in model._columns: column = model._columns[field_name] @@ -461,7 +464,7 @@ class YamlInterpreter(object): value = self.get_id(expression) elif column._type == "one2many": other_model = self.get_model(column._obj) - value = [(0, 0, self._create_record(other_model, fields, view, parent, default=default)) for fields in expression] + value = [(0, 0, self._create_record(other_model, fields, view, parent, default=default, fields_view_get=fields_view_get)) for fields in expression] elif column._type == "many2many": ids = [self.get_id(xml_id) for xml_id in expression] value = [(6, 0, ids)] From 273904d103c3a13499521b71772d794e5e5d400b Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 1 Oct 2012 17:03:05 +0200 Subject: [PATCH 22/67] [IMP] orm: be more vebose when accessing an invalid field of browse_record objects bzr revid: chs@openerp.com-20121001150305-recozdvfc68wc766 --- openerp/osv/orm.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index f324ed67522..47afda39e5e 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -51,6 +51,7 @@ import pickle import re import simplejson import time +import traceback import types from lxml import etree @@ -373,6 +374,8 @@ class browse_record(object): else: error_msg = "Field '%s' does not exist in object '%s'" % (name, self) self.__logger.warning(error_msg) + if self.__logger.isEnabledFor(logging.DEBUG): + self.__logger.debug(''.join(traceback.format_stack())) raise KeyError(error_msg) # if the field is a classic one or a many2one, we'll fetch all classic and many2one fields From 5763e40506f9f155e09b2fccbc7ffa4247b02b9b Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 1 Oct 2012 17:14:21 +0200 Subject: [PATCH 23/67] [IMP] orm: remove trailing spaces bzr revid: chs@openerp.com-20121001151421-vdfkzuf864rz8q20 --- openerp/osv/orm.py | 60 +++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 47afda39e5e..8b78621db03 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -372,7 +372,7 @@ class browse_record(object): else: return attr else: - error_msg = "Field '%s' does not exist in object '%s'" % (name, self) + error_msg = "Field '%s' does not exist in object '%s'" % (name, self) self.__logger.warning(error_msg) if self.__logger.isEnabledFor(logging.DEBUG): self.__logger.debug(''.join(traceback.format_stack())) @@ -712,7 +712,7 @@ class BaseModel(object): def log(self, cr, uid, id, message, secondary=False, context=None): return _logger.warning("log() is deprecated. Please use OpenChatter notification system instead of the res.log mechanism.") - + def view_init(self, cr, uid, fields_list, context=None): """Override this method to do specific things when a view on the object is opened.""" pass @@ -902,7 +902,7 @@ class BaseModel(object): # If new class defines a constraint with # same function name, we let it override # the old one. - + new[c2] = c exist = True break @@ -1596,7 +1596,7 @@ class BaseModel(object): def user_has_groups(self, cr, uid, groups, context=None): """Return true if the user is at least member of one of the groups in groups_str. Typically used to resolve ``groups`` attribute - in view and model definitions. + in view and model definitions. :param str groups: comma-separated list of fully-qualified group external IDs, e.g.: ``base.group_user,base.group_system`` @@ -1639,7 +1639,7 @@ class BaseModel(object): the field should be completely removed from the view, as it is completely unavailable for non-members - :return: True if field should be included in the result of fields_view_get + :return: True if field should be included in the result of fields_view_get """ if node.tag == 'field' and node.get('name') in self._all_columns: column = self._all_columns[node.get('name')].column @@ -1914,7 +1914,7 @@ class BaseModel(object): def _get_default_calendar_view(self, cr, user, context=None): """ Generates a default calendar view by trying to infer calendar fields from a number of pre-set attribute names - + :param cr: database cursor :param int user: user id :param dict context: connection context @@ -1993,7 +1993,7 @@ class BaseModel(object): def raise_view_error(error_msg, child_view_id): view, child_view = self.pool.get('ir.ui.view').browse(cr, user, [view_id, child_view_id], context) - error_msg = error_msg % {'parent_xml_id': view.xml_id} + error_msg = error_msg % {'parent_xml_id': view.xml_id} raise AttributeError("View definition error for inherited view '%s' on model '%s': %s" % (child_view.xml_id, self._name, error_msg)) @@ -2029,7 +2029,7 @@ class BaseModel(object): if all(node.get(attr) == spec.get(attr) \ for attr in spec.attrib if attr not in ('position','version')): - # Version spec should match parent's root element's version + # Version spec should match parent's root element's version if spec.get('version') and spec.get('version') != source.get('version'): return None return node @@ -2103,7 +2103,7 @@ class BaseModel(object): raise_view_error("Mismatching view API version for element '%s': %r vs %r in parent view '%%(parent_xml_id)s'" % \ (tag, spec.get('version'), source.get('version')), inherit_id) raise_view_error("Element '%s' not found in parent view '%%(parent_xml_id)s'" % tag, inherit_id) - + return source def apply_view_inheritance(cr, user, source, inherit_id): @@ -2318,7 +2318,7 @@ class BaseModel(object): or ``'='``. :param int limit: optional max number of records to return :rtype: list - :return: list of pairs ``(id,text_repr)`` for all matching records. + :return: list of pairs ``(id,text_repr)`` for all matching records. """ return self._name_search(cr, user, name, args, operator, context, limit) @@ -2448,7 +2448,7 @@ class BaseModel(object): # This is useful to implement kanban views for instance, where all columns # should be displayed even if they don't contain any record. - # Grab the list of all groups that should be displayed, including all present groups + # Grab the list of all groups that should be displayed, including all present groups present_group_ids = [x[groupby][0] for x in read_group_result if x[groupby]] all_groups,folded = self._group_by_full[groupby](self, cr, uid, present_group_ids, domain, read_group_order=read_group_order, @@ -2824,28 +2824,28 @@ class BaseModel(object): def _m2o_fix_foreign_key(self, cr, source_table, source_field, dest_model, ondelete): # Find FK constraint(s) currently established for the m2o field, - # and see whether they are stale or not + # and see whether they are stale or not cr.execute("""SELECT confdeltype as ondelete_rule, conname as constraint_name, cl2.relname as foreign_table FROM pg_constraint as con, pg_class as cl1, pg_class as cl2, pg_attribute as att1, pg_attribute as att2 - WHERE con.conrelid = cl1.oid - AND cl1.relname = %s - AND con.confrelid = cl2.oid - AND array_lower(con.conkey, 1) = 1 - AND con.conkey[1] = att1.attnum - AND att1.attrelid = cl1.oid - AND att1.attname = %s - AND array_lower(con.confkey, 1) = 1 - AND con.confkey[1] = att2.attnum - AND att2.attrelid = cl2.oid - AND att2.attname = %s + WHERE con.conrelid = cl1.oid + AND cl1.relname = %s + AND con.confrelid = cl2.oid + AND array_lower(con.conkey, 1) = 1 + AND con.conkey[1] = att1.attnum + AND att1.attrelid = cl1.oid + AND att1.attname = %s + AND array_lower(con.confkey, 1) = 1 + AND con.confkey[1] = att2.attnum + AND att2.attrelid = cl2.oid + AND att2.attname = %s AND con.contype = 'f'""", (source_table, source_field, 'id')) constraints = cr.dictfetchall() if constraints: if len(constraints) == 1: # Is it the right constraint? - cons, = constraints + cons, = constraints if cons['ondelete_rule'] != POSTGRES_CONFDELTYPES.get((ondelete or 'set null').upper(), 'a')\ or cons['foreign_table'] != dest_model._table: _schema.debug("Table '%s': dropping obsolete FK constraint: '%s'", @@ -3218,7 +3218,7 @@ class BaseModel(object): def _o2m_raise_on_missing_reference(self, cr, f): # TODO this check should be a method on fields.one2many. - + other = self.pool.get(f._obj) if other: # TODO the condition could use fields_get_keys(). @@ -3735,7 +3735,7 @@ class BaseModel(object): the length of `ids`, and raise an appropriate exception if it does not. """ if cr.rowcount != len(ids): - # Attempt to distinguish record rule restriction vs deleted records, + # Attempt to distinguish record rule restriction vs deleted records, # to provide a more specific error message cr.execute('SELECT id FROM ' + self._table + ' WHERE id IN %s', (tuple(ids),)) if cr.rowcount != len(ids): @@ -3790,13 +3790,13 @@ class BaseModel(object): self._check_record_rules_result_count(cr, uid, sub_ids, operation, context=context) def _workflow_trigger(self, cr, uid, ids, trigger, context=None): - """Call given workflow trigger as a result of a CRUD operation""" + """Call given workflow trigger as a result of a CRUD operation""" wf_service = netsvc.LocalService("workflow") for res_id in ids: getattr(wf_service, trigger)(uid, self._name, res_id, cr) def _workflow_signal(self, cr, uid, ids, signal, context=None): - """Send given workflow signal""" + """Send given workflow signal""" wf_service = netsvc.LocalService("workflow") for res_id in ids: wf_service.trg_validate(uid, self._name, res_id, signal, cr) @@ -3827,7 +3827,7 @@ class BaseModel(object): self.check_access_rights(cr, uid, 'unlink') ir_property = self.pool.get('ir.property') - + # Check if the records are used as default properties. domain = [('res_id', '=', False), ('value_reference', 'in', ['%s,%s' % (self._name, i) for i in ids]), @@ -4955,7 +4955,7 @@ class BaseModel(object): :return: map of ids to their fully qualified XML ID, defaulting to an empty string when there's none - (to be usable as a function field), + (to be usable as a function field), e.g.:: { 'id': 'module.ext_id', From b7e5519b4c0b4c212ef1268a09dacdfb26b704d8 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 1 Oct 2012 17:37:53 +0200 Subject: [PATCH 24/67] [FIX] orm: handle fields.char() with not size correctly bzr revid: chs@openerp.com-20121001153753-um68vpz1caojm17r --- openerp/osv/orm.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 8b78621db03..ec995c6a8cc 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -2967,14 +2967,14 @@ class BaseModel(object): ('numeric', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]), ('float8', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]), ] - if f_pg_type == 'varchar' and f._type == 'char' and f_pg_size < f.size: + if f_pg_type == 'varchar' and f._type == 'char' and ((f.size is None and f_pg_size) or f_pg_size < f.size): cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO temp_change_size' % (self._table, k)) cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, pg_varchar(f.size))) cr.execute('UPDATE "%s" SET "%s"=temp_change_size::%s' % (self._table, k, pg_varchar(f.size))) cr.execute('ALTER TABLE "%s" DROP COLUMN temp_change_size CASCADE' % (self._table,)) cr.commit() _schema.debug("Table '%s': column '%s' (type varchar) changed size from %s to %s", - self._table, k, f_pg_size, f.size) + self._table, k, f_pg_size or 'unlimited', f.size or 'unlimited') for c in casts: if (f_pg_type==c[0]) and (f._type==c[1]): if f_pg_type != f_obj_type: @@ -3207,8 +3207,7 @@ class BaseModel(object): # attlen is the number of bytes necessary to represent the type when # the type has a fixed size. If the type has a varying size attlen is # -1 and atttypmod is the size limit + 4, or -1 if there is no limit. - # Thus the query can return a negative size for a unlimited varchar. - cr.execute("SELECT c.relname,a.attname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,t.typname,CASE WHEN a.attlen=-1 THEN a.atttypmod-4 ELSE a.attlen END as size " \ + cr.execute("SELECT c.relname,a.attname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,t.typname,CASE WHEN a.attlen=-1 THEN (CASE WHEN a.atttypmod=-1 THEN 0 ELSE a.atttypmod-4 END) ELSE a.attlen END as size " \ "FROM pg_class c,pg_attribute a,pg_type t " \ "WHERE c.relname=%s " \ "AND c.oid=a.attrelid " \ From 7812c73354d9ca924c109b3c6331bfbe1986f388 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Mon, 1 Oct 2012 17:38:06 +0200 Subject: [PATCH 25/67] [IMP] yaml processing: improved previous patch by replacing the old parameter view with the result of fields_view_get() directly, to avoid having an extra parameter a bit useless bzr revid: qdp-launchpad@openerp.com-20121001153806-k40ly5vdzh1v3hv3 --- openerp/tools/yaml_import.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/openerp/tools/yaml_import.py b/openerp/tools/yaml_import.py index f88f253c0f2..a5de5873908 100644 --- a/openerp/tools/yaml_import.py +++ b/openerp/tools/yaml_import.py @@ -313,14 +313,13 @@ class YamlInterpreter(object): #context = self.get_context(record, self.eval_context) #TOFIX: record.context like {'withoutemployee':True} should pass from self.eval_context. example: test_project.yml in project module context = record.context - fields_view_get_result = False + view_info = False if view_id: varg = view_id if view_id is True: varg = False - fields_view_get_result = model.fields_view_get(self.cr, SUPERUSER_ID, varg, 'form', context) - view_id = etree.fromstring(fields_view_get_result['arch'].encode('utf-8')) + view_info = model.fields_view_get(self.cr, SUPERUSER_ID, varg, 'form', context) - record_dict = self._create_record(model, fields, view_id, default=default, fields_view_get=fields_view_get_result) + record_dict = self._create_record(model, fields, view_info, default=default) _logger.debug("RECORD_DICT %s" % record_dict) id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, record.model, \ self.module, record_dict, record.id, noupdate=self.isnoupdate(record), mode=self.mode, context=context) @@ -328,7 +327,8 @@ class YamlInterpreter(object): if config.get('import_partial'): self.cr.commit() - def _create_record(self, model, fields, view=False, parent={}, default=True, fields_view_get=None): + def _create_record(self, model, fields, view_info=False, parent={}, default=True): + view = view_info and etree.fromstring(view_info['arch'].encode('utf-8')) or False if view is not False: defaults = default and model._add_missing_default_values(self.cr, SUPERUSER_ID, {}, context=self.context) or {} fg = model.fields_get(self.cr, SUPERUSER_ID, context=self.context) @@ -357,17 +357,15 @@ class YamlInterpreter(object): field_name = el.attrib['name'] assert field_name in fg, "The field '%s' is defined in the form view but not on the object '%s'!" % (field_name, model._name) if field_name in fields: - view2 = None + one2many_form_view = None # if the form view is not inline, we call fields_view_get if (view is not False) and (fg[field_name]['type']=='one2many'): - tmp = fields_view_get['fields'][field_name]['views'] - if tmp.has_key('form'): - view2 = tmp.get('form') - if not view2: - view2 = self.pool.get(fg[field_name]['relation']).fields_view_get(self.cr, SUPERUSER_ID, False, 'form', self.context) - view2 = etree.fromstring(view2['arch'].encode('utf-8')) + one2many_form_view = view_info['fields'][field_name]['views'].get('form') + if not one2many_form_view: + one2many_form_view = self.pool.get(fg[field_name]['relation']).fields_view_get(self.cr, SUPERUSER_ID, False, 'form', self.context) - field_value = self._eval_field(model, field_name, fields[field_name], view2, parent=record_dict, default=default, fields_view_get=fields_view_get) + view_info = one2many_form_view or view_info + field_value = self._eval_field(model, field_name, fields[field_name], view_info, parent=record_dict, default=default) record_dict[field_name] = field_value #if (field_name in defaults) and defaults[field_name] == field_value: # print '*** You can remove these lines:', field_name, field_value @@ -412,7 +410,7 @@ class YamlInterpreter(object): for field_name, expression in fields.items(): if field_name in record_dict: continue - field_value = self._eval_field(model, field_name, expression, default=False, fields_view_get=fields_view_get) + field_value = self._eval_field(model, field_name, expression, default=False) record_dict[field_name] = field_value return record_dict @@ -443,7 +441,7 @@ class YamlInterpreter(object): def process_eval(self, node): return eval(node.expression, self.eval_context) - def _eval_field(self, model, field_name, expression, view=False, parent={}, default=True, fields_view_get=None): + def _eval_field(self, model, field_name, expression, view_info=False, parent={}, default=True): # TODO this should be refactored as something like model.get_field() in bin/osv if field_name in model._columns: column = model._columns[field_name] @@ -464,7 +462,7 @@ class YamlInterpreter(object): value = self.get_id(expression) elif column._type == "one2many": other_model = self.get_model(column._obj) - value = [(0, 0, self._create_record(other_model, fields, view, parent, default=default, fields_view_get=fields_view_get)) for fields in expression] + value = [(0, 0, self._create_record(other_model, fields, view_info, parent, default=default)) for fields in expression] elif column._type == "many2many": ids = [self.get_id(xml_id) for xml_id in expression] value = [(6, 0, ids)] From 4d35720a57190f21edac89d1755d3d990c79fd83 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Mon, 1 Oct 2012 17:44:49 +0200 Subject: [PATCH 26/67] [IMP] translation import/export: more cleanup bzr revid: odo@openerp.com-20121001154449-146dte5i8ge1y1pj --- .../module/wizard/base_export_language.py | 16 ++------ .../wizard/base_export_language_view.xml | 4 +- .../module/wizard/base_import_language.py | 39 ++++++++----------- .../wizard/base_import_language_view.xml | 2 +- 4 files changed, 23 insertions(+), 38 deletions(-) diff --git a/openerp/addons/base/module/wizard/base_export_language.py b/openerp/addons/base/module/wizard/base_export_language.py index 80cb2d70292..95f1d85bf6c 100644 --- a/openerp/addons/base/module/wizard/base_export_language.py +++ b/openerp/addons/base/module/wizard/base_export_language.py @@ -45,7 +45,6 @@ class base_language_export(osv.osv_memory): ('tgz', 'TGZ Archive')], 'File Format', required=True), 'modules': fields.many2many('ir.module.module', 'rel_modules_langexport', 'wiz_id', 'module_id', 'Modules To Export', domain=[('state','=','installed')]), 'data': fields.binary('File', readonly=True), - 'advice': fields.text('Note', readonly=True), 'state': fields.selection([('choose', 'choose'), # choose language ('get', 'get')]) # get the file } @@ -62,18 +61,10 @@ class base_language_export(osv.osv_memory): mods = map(lambda m: m.name, this.modules) or ['all'] mods.sort() buf = cStringIO.StringIO() - tools.trans_export(this.lang, mods, buf, this.format, cr) - if this.format == 'csv': - this.advice = _("Save this document as a .CSV file and open it with your favourite spreadsheet software. The file encoding is UTF-8. You have to translate the last column before reimporting it.") - elif this.format == 'po': - if not lang: - this.format = 'pot' - this.advice = _("Save this document as a %s file and edit it with a PO editor or a text editor. The file encoding is UTF-8.") % ('.'+this.format,) - elif this.format == 'tgz': - this.advice = _('Save this document as a .tgz file. This archive contains UTF-8 %s files and may be uploaded to launchpad.') - filename = _('new') + tools.trans_export(lang, mods, buf, this.format, cr) + filename = 'new' if lang: - filename = get_iso_codes(this.lang) + filename = get_iso_codes(lang) elif len(mods) == 1: filename = mods[0] this.name = "%s.%s" % (filename, this.format) @@ -81,7 +72,6 @@ class base_language_export(osv.osv_memory): buf.close() self.write(cr, uid, ids, {'state': 'get', 'data': out, - 'advice': this.advice, 'name':this.name}, context=context) return True diff --git a/openerp/addons/base/module/wizard/base_export_language_view.xml b/openerp/addons/base/module/wizard/base_export_language_view.xml index 2e50b3bed8f..cbf7104f957 100644 --- a/openerp/addons/base/module/wizard/base_export_language_view.xml +++ b/openerp/addons/base/module/wizard/base_export_language_view.xml @@ -2,10 +2,10 @@ - Translations Export + Export Translations base.language.export -
+ diff --git a/openerp/addons/base/module/wizard/base_import_language.py b/openerp/addons/base/module/wizard/base_import_language.py index 6f09dc43d90..9c36c9d7c54 100644 --- a/openerp/addons/base/module/wizard/base_import_language.py +++ b/openerp/addons/base/module/wizard/base_import_language.py @@ -30,8 +30,8 @@ class base_language_import(osv.osv_memory): _name = "base.language.import" _description = "Language Import" _columns = { - 'name': fields.char('Language Name',size=64 , required=True), - 'code': fields.char('Code (eg:en__US)',size=5 , required=True), + 'name': fields.char('Language Name', size=64 , required=True), + 'code': fields.char('ISO Code', size=5, help="ISO Language and Country code, e.g. en_US", required=True), 'data': fields.binary('File', required=True), 'overwrite': fields.boolean('Overwrite Existing Terms', help="If you enable this option, existing translations (including custom ones) " @@ -39,30 +39,25 @@ class base_language_import(osv.osv_memory): } def import_lang(self, cr, uid, ids, context=None): - """ - Import Language - @param cr: the current row, from the database cursor. - @param uid: the current user’s ID for security checks. - @param ids: the ID or list of IDs - @param context: A standard dictionary - """ if context is None: context = {} - import_data = self.browse(cr, uid, ids)[0] - if import_data.overwrite: + this = self.browse(cr, uid, ids[0]) + if this.overwrite: context.update(overwrite=True) fileobj = TemporaryFile('w+') - fileobj.write(base64.decodestring(import_data.data)) - - # now we determine the file format - fileobj.seek(0) - first_line = fileobj.readline().strip().replace('"', '').replace(' ', '') - fileformat = first_line.endswith("type,name,res_id,src,value") and 'csv' or 'po' - fileobj.seek(0) - - tools.trans_load_data(cr, fileobj, fileformat, import_data.code, lang_name=import_data.name, context=context) - fileobj.close() - return {} + try: + fileobj.write(base64.decodestring(this.data)) + + # now we determine the file format + fileobj.seek(0) + first_line = fileobj.readline().strip().replace('"', '').replace(' ', '') + fileformat = first_line.endswith("type,name,res_id,src,value") and 'csv' or 'po' + fileobj.seek(0) + + tools.trans_load_data(cr, fileobj, fileformat, this.code, lang_name=this.name, context=context) + finally: + fileobj.close() + return True # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/module/wizard/base_import_language_view.xml b/openerp/addons/base/module/wizard/base_import_language_view.xml index 727de4e381b..5e2aada7766 100644 --- a/openerp/addons/base/module/wizard/base_import_language_view.xml +++ b/openerp/addons/base/module/wizard/base_import_language_view.xml @@ -8,7 +8,7 @@ - + From 7d46e337633ff4265642d8a7bf9a8a9157a80c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 1 Oct 2012 17:49:16 +0200 Subject: [PATCH 27/67] [IMP] css: animations for kanban notes bzr revid: fva@openerp.com-20121001154916-r5mq1z4icc54jmgz --- addons/web_kanban/static/src/css/kanban.css | 9 ++++++--- addons/web_kanban/static/src/css/kanban.sass | 14 ++++++++++++-- addons/web_kanban/static/src/js/kanban.js | 6 ++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/addons/web_kanban/static/src/css/kanban.css b/addons/web_kanban/static/src/css/kanban.css index 6846171a82a..60e8eefcf37 100644 --- a/addons/web_kanban/static/src/css/kanban.css +++ b/addons/web_kanban/static/src/css/kanban.css @@ -9,7 +9,6 @@ .openerp .oe_kanban_view .ui-sortable-placeholder { border: 1px solid rgba(0, 0, 0, 0.1); visibility: visible !important; - height: 60px !important; } .openerp .oe_kanban_view .ui-sortable-helper { -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.3); @@ -19,6 +18,9 @@ -webkit-transform: rotate(3deg); -o-transform: rotate(3deg); -ms-transform: rotate(3deg); + -webkit-transition: -webkit-transform 100ms linear; + -moz-transition: -moz-transform 100ms linear; + transition: transform 100ms linear; } .openerp .oe_kanban_view .oe_kanban_left { float: left; @@ -364,17 +366,18 @@ border-bottom-color: rgba(0, 0, 0, 0.3); padding: 8px; display: block; + -webkit-transition: -webkit-transform, -webkit-box-shadow, border 200ms linear; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } -.openerp .oe_kanban_view .oe_kanban_card:hover, .openerp .oe_kanban_view .oe_kanban_quick_create:hover { +.openerp .oe_kanban_view .oe_kanban_card:not(.ui-sortable-helper):hover, .openerp .oe_kanban_view .oe_kanban_quick_create:not(.ui-sortable-helper):hover { border: 1px solid #7c7bad; -moz-box-shadow: 0 0 4px #7c7bad; -webkit-box-shadow: 0 0 4px #7c7bad; -box-shadow: 0 0 4px #7c7bad; } -.openerp .oe_kanban_view .oe_kanban_card:hover .oe_dropdown_kanban > span, .openerp .oe_kanban_view .oe_kanban_quick_create:hover .oe_dropdown_kanban > span { +.openerp .oe_kanban_view .oe_kanban_card:not(.ui-sortable-helper):hover .oe_dropdown_kanban > span, .openerp .oe_kanban_view .oe_kanban_quick_create:not(.ui-sortable-helper):hover .oe_dropdown_kanban > span { visibility: visible; } .openerp .oe_kanban_view .oe_kanban_card h3, .openerp .oe_kanban_view .oe_kanban_quick_create h3 { diff --git a/addons/web_kanban/static/src/css/kanban.sass b/addons/web_kanban/static/src/css/kanban.sass index 88b60134f24..1210e9bf640 100644 --- a/addons/web_kanban/static/src/css/kanban.sass +++ b/addons/web_kanban/static/src/css/kanban.sass @@ -37,6 +37,13 @@ -webkit-transform: $transform -o-transform: $transform -ms-transform: $transform + +@mixin transition($transition: all 200ms linear) + -webkit-transition: $transition + -moz-transition: $transition + -ms-transition: $transition + -o-transition: $transition + transition: $transition // }}} .openerp .oe_kanban_view @@ -49,10 +56,12 @@ .ui-sortable-placeholder border: 1px solid rgba(0,0,0,0.1) visibility: visible !important - height: 60px !important .ui-sortable-helper @include box-shadow(0 1px 10px rgba(0, 0, 0, 0.3)) @include transform(rotate(3deg)) + -webkit-transition: -webkit-transform 100ms linear + -moz-transition: -moz-transform 100ms linear + transition: transform 100ms linear .oe_kanban_left float: left .oe_kanban_right @@ -328,8 +337,9 @@ border-bottom-color: rgba(0,0,0,0.3) padding: 8px display: block + -webkit-transition: -webkit-transform, -webkit-box-shadow, border 200ms linear @include radius(4px) - &:hover + &:not(.ui-sortable-helper):hover border: 1px solid #7C7BAD @include box-shadow(0 0 4px #7C7BAD) .oe_dropdown_kanban > span diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index bd36dcbf4ba..d8e93efa580 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -309,8 +309,14 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ ui.item.find('*').on('click.prevent', function(ev) { return false; }); + ui.placeholder.height(ui.item.height()); + }, + revert: 150, + beforeStop: function(event,ui){ + console.log('beforeStop:',ui); }, stop: function(event, ui) { + console.log('stop:',ui); var record = ui.item.data('widget'); var old_index = self.currently_dragging.index; var new_index = ui.item.index(); From feaa3bf3ab40c40dd64f32916de2194e4cb9d5d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 1 Oct 2012 19:12:26 +0200 Subject: [PATCH 28/67] [FIX] css: removed bold from active menu items, it made the menu wobble bzr revid: fva@openerp.com-20121001171226-xw275mzmhc43faeu --- addons/web/static/src/css/base.css | 3 +-- addons/web/static/src/css/base.sass | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 18db06c44a1..aadc73e3511 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -1081,9 +1081,8 @@ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4) inset; } .openerp .oe_menu > li > .oe_active { - background: rgba(0, 0, 0, 0.2); + background: rgba(0, 0, 0, 0.3); text-shadow: black 0px 0px 3px; - font-weight: bold; -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4) inset; -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4) inset; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4) inset; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index 851d0c3f9c9..818cd7dc450 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -875,9 +875,8 @@ $sheet-max-width: 860px color: white @include box-shadow(0 1px 2px rgba(0,0,0,0.4) inset) > .oe_active - background: rgba(0,0,0,0.2) + background: rgba(0,0,0,0.30) text-shadow: black 0px 0px 3px - font-weight: bold @include box-shadow(0 1px 2px rgba(0,0,0,0.4) inset) .oe_user_menu From 6664ca2653d47a2856272758a018bdb383668359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 1 Oct 2012 19:16:10 +0200 Subject: [PATCH 29/67] [FIX] css: disabled required inputs should not be highlighted bzr revid: fva@openerp.com-20121001171610-lyshewqacnl0me7s --- addons/web/static/src/css/base.css | 2 +- addons/web/static/src/css/base.sass | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index aadc73e3511..7cd189f8d4b 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -2240,7 +2240,7 @@ .openerp .oe_form .oe_datepicker_root { display: inline-block; } -.openerp .oe_form .oe_form_required input, .openerp .oe_form .oe_form_required select, .openerp .oe_form .oe_form_required textarea { +.openerp .oe_form .oe_form_required input:not([disabled]), .openerp .oe_form .oe_form_required select:not([disabled]), .openerp .oe_form .oe_form_required textarea:not([disabled]) { background-color: #d2d2ff !important; } .openerp .oe_form .oe_form_invalid input, .openerp .oe_form .oe_form_invalid select, .openerp .oe_form .oe_form_invalid textarea { diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index 818cd7dc450..06890b991dc 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -1772,8 +1772,8 @@ $sheet-max-width: 860px display: none .oe_datepicker_root display: inline-block - .oe_form_required - input, select, textarea + .oe_form_required + input:not([disabled]), select:not([disabled]), textarea:not([disabled]) background-color: #D2D2FF !important .oe_form_invalid input, select, textarea From fa852bab333fba81f8665a89ba15e55a2a801c48 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Tue, 2 Oct 2012 14:04:05 +0200 Subject: [PATCH 30/67] [FIX] yaml_import: don't erase the initial fields_view_get() result with the fields_view get of the first one2many fiel, other wise things get wrong -_- bzr revid: qdp-launchpad@openerp.com-20121002120405-hvy4ltgrjzesndox --- openerp/tools/yaml_import.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openerp/tools/yaml_import.py b/openerp/tools/yaml_import.py index a5de5873908..9ab034e55e6 100644 --- a/openerp/tools/yaml_import.py +++ b/openerp/tools/yaml_import.py @@ -364,8 +364,7 @@ class YamlInterpreter(object): if not one2many_form_view: one2many_form_view = self.pool.get(fg[field_name]['relation']).fields_view_get(self.cr, SUPERUSER_ID, False, 'form', self.context) - view_info = one2many_form_view or view_info - field_value = self._eval_field(model, field_name, fields[field_name], view_info, parent=record_dict, default=default) + field_value = self._eval_field(model, field_name, fields[field_name], one2many_form_view or view_info, parent=record_dict, default=default) record_dict[field_name] = field_value #if (field_name in defaults) and defaults[field_name] == field_value: # print '*** You can remove these lines:', field_name, field_value From a217a94f7fd222f0c8298c3c91a1c75bb9fdd77b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Tue, 2 Oct 2012 16:06:44 +0200 Subject: [PATCH 31/67] [IMP] css: display previously implicit 'or' operator in the advanced search bzr revid: fva@openerp.com-20121002140644-3qbx3w0fsgk3vd0v --- addons/web/static/src/css/base.css | 7 +++++++ addons/web/static/src/css/base.sass | 5 +++++ addons/web/static/src/xml/base.xml | 1 + 3 files changed, 13 insertions(+) diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 7cd189f8d4b..1220dee986d 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -1842,6 +1842,13 @@ margin: 0; white-space: nowrap; } +.openerp .oe_searchview .oe_searchview_drawer .oe_searchview_advanced li:first-child .searchview_extended_prop_or { + visibility: hidden; +} +.openerp .oe_searchview .oe_searchview_drawer .oe_searchview_advanced .searchview_extended_prop_or { + opacity: 0.5; + margin-left: -14px; +} .openerp .oe_searchview .oe_searchview_drawer .oe_opened h4:before { content: "▾ "; position: relative; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index 06890b991dc..680ed75abb8 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -1465,6 +1465,11 @@ $sheet-max-width: 860px list-style: none margin: 0 white-space: nowrap + &:first-child .searchview_extended_prop_or + visibility: hidden + .searchview_extended_prop_or + opacity: 0.5 + margin-left: -14px .oe_opened h4:before content: "▾ " diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index fdf39633186..a2fb99f2195 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -1485,6 +1485,7 @@
  • + or