From e6695c72d8c702c1d170ed9eb9b784949a59caa4 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Fri, 25 Jul 2014 12:26:32 +0200 Subject: [PATCH] [WIP] ir.ui.view's arch field fetches disk version if --dev mode is used --- openerp/addons/base/ir/ir_ui_view.py | 55 +++++++++++++++++++++++++++- openerp/tools/config.py | 3 +- openerp/tools/convert.py | 19 ++++++++-- 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py index 08fb4d4ef59..feabfe3023e 100644 --- a/openerp/addons/base/ir/ir_ui_view.py +++ b/openerp/addons/base/ir/ir_ui_view.py @@ -38,7 +38,8 @@ import openerp from openerp import tools, api from openerp.http import request from openerp.osv import fields, osv, orm -from openerp.tools import graph, SKIPPED_ELEMENT_TYPES +from openerp.tools import config, graph, SKIPPED_ELEMENT_TYPES +from openerp.tools.convert import _fix_multiple_roots from openerp.tools.parse_version import parse_version from openerp.tools.safe_eval import safe_eval as eval from openerp.tools.view_validation import valid_view @@ -105,6 +106,30 @@ def _hasclass(context, *cls): return node_classes.issuperset(cls) +def get_view_arch_from_file(filename, xmlid): + doc = etree.parse(filename) + node = None + for n in doc.xpath('//*[@id="%s"] | //*[@id="%s"]' % (xmlid, xmlid.split('.')[1])): + if n.tag in ('template', 'record'): + node = n + break + if node is not None: + if node.tag == 'record': + field = node.find('field[@name="arch"]') + _fix_multiple_roots(field) + inner = ''.join([etree.tostring(child) for child in field.iterchildren()]) + return field.text + inner + elif node.tag == 'template': + # The following dom operations has been copied from convert.py's _tag_template() + if not node.get('inherit_id'): + node.set('t-name', xmlid) + node.tag = 't' + else: + node.tag = 'data' + node.attrib.pop('id', None) + return etree.tostring(node) + raise ValueError("Could not find view arch definition in file '%s' for xmlid '%s'" % (filename, xmlid)) + xpath_utils = etree.FunctionNamespace(None) xpath_utils['hasclass'] = _hasclass @@ -123,6 +148,30 @@ class view(osv.osv): data_ids = IMD.search_read(cr, uid, [('id', 'in', ids), ('model', '=', 'ir.ui.view')], ['res_id'], context=context) return map(itemgetter('res_id'), data_ids) + def _arch_get(self, cr, uid, ids, name, arg, context=None): + result = {} + for view in self.browse(cr, uid, ids, context=context): + arch_fs = None + if config['dev_mode'] and view.arch_fs and view.xml_id: + arch_fs = get_view_arch_from_file(view.arch_fs, view.xml_id) + result[view.id] = arch_fs or view.arch_db + return result + + def _arch_set(self, cr, uid, ids, field_name, field_value, args, context=None): + if not isinstance(ids, list): + ids = [ids] + if field_value: + for view in self.browse(cr, uid, ids, context=context): + data = dict(arch_db=field_value) + key = 'install_mode_data' + if context and key in context: + imd = context[key] + if self._model._name == imd['model'] and (not view.xml_id or view.xml_id == imd['xml_id']): + data['arch_fs'] = imd['xml_file'] + self.write(cr, uid, ids, data, context=context) + + return True + _columns = { 'name': fields.char('View Name', required=True), 'model': fields.char('Object', select=True), @@ -137,7 +186,9 @@ class view(osv.osv): ('kanban', 'Kanban'), ('search','Search'), ('qweb', 'QWeb')], string='View Type'), - 'arch': fields.text('View Architecture', required=True), + 'arch': fields.function(_arch_get, fnct_inv=_arch_set, string='View Architecture', type="text", nodrop=True), + 'arch_db': fields.text('Arch Blob'), + 'arch_fs': fields.text('Arch Filename'), 'inherit_id': fields.many2one('ir.ui.view', 'Inherited View', ondelete='cascade', select=True), 'inherit_children_ids': fields.one2many('ir.ui.view','inherit_id', 'Inherit Views'), 'field_parent': fields.char('Child Field'), diff --git a/openerp/tools/config.py b/openerp/tools/config.py index e4205f0b5f5..94dfc8ea3cd 100644 --- a/openerp/tools/config.py +++ b/openerp/tools/config.py @@ -257,6 +257,7 @@ class configmanager(object): group = optparse.OptionGroup(parser, "Advanced options") if os.name == 'posix': group.add_option('--auto-reload', dest='auto_reload', action='store_true', my_default=False, help='enable auto reload') + group.add_option('--dev', dest='dev_mode', action='store_true', my_default=False, help='enable developper mode') group.add_option('--debug', dest='debug_mode', action='store_true', my_default=False, help='enable debug mode') group.add_option("--stop-after-init", action="store_true", dest="stop_after_init", my_default=False, help="stop the server after its initialization") @@ -407,7 +408,7 @@ class configmanager(object): # if defined but None take the configfile value keys = [ 'language', 'translate_out', 'translate_in', 'overwrite_existing_translations', - 'debug_mode', 'smtp_ssl', 'load_language', + 'dev_mode', 'debug_mode', 'smtp_ssl', 'load_language', 'stop_after_init', 'logrotate', 'without_demo', 'xmlrpc', 'syslog', 'list_db', 'xmlrpcs', 'proxy_mode', 'test_file', 'test_enable', 'test_commit', 'test_report_directory', diff --git a/openerp/tools/convert.py b/openerp/tools/convert.py index d55ba52eb71..9be6547ba63 100644 --- a/openerp/tools/convert.py +++ b/openerp/tools/convert.py @@ -774,9 +774,17 @@ form: module.record_id""" % (xml_id,) rec_model = rec.get("model").encode('ascii') model = self.pool[rec_model] rec_id = rec.get("id",'').encode('ascii') - rec_context = rec.get("context", None) + rec_context = rec.get("context", {}) if rec_context: rec_context = unsafe_eval(rec_context) + + if self.xml_filename and rec_id: + rec_context['install_mode_data'] = dict( + xml_file=self.xml_filename, + xml_id=rec_id, + model=rec_model, + ) + self._test_xml_id(rec_id) # in update mode, the record won't be updated if the data node explicitely # opt-out using @noupdate="1". A second check will be performed in @@ -941,7 +949,7 @@ form: module.record_id""" % (xml_id,) raise ParseError, (misc.ustr(e), etree.tostring(rec).rstrip(), rec.getroottree().docinfo.URL, rec.sourceline), exc_info[2] return True - def __init__(self, cr, module, idref, mode, report=None, noupdate=False): + def __init__(self, cr, module, idref, mode, report=None, noupdate=False, xml_filename=None): self.mode = mode self.module = module @@ -953,6 +961,7 @@ form: module.record_id""" % (xml_id,) report = assertion_report.assertion_report() self.assertion_report = report self.noupdate = noupdate + self.xml_filename = xml_filename self._tags = { 'menuitem': self._tag_menuitem, 'record': self._tag_record, @@ -1066,7 +1075,11 @@ def convert_xml_import(cr, module, xmlfile, idref=None, mode='init', noupdate=Fa if idref is None: idref={} - obj = xml_import(cr, module, idref, mode, report=report, noupdate=noupdate) + if isinstance(xmlfile, file): + xml_filename = xmlfile.name + else: + xml_filename = xmlfile + obj = xml_import(cr, module, idref, mode, report=report, noupdate=noupdate, xml_filename=xml_filename) obj.parse(doc.getroot()) return True