[MERGE] Removed fields_view_get from web controller. Replaced by instance.web.fields_view_get

bzr revid: fme@openerp.com-20121206161749-0cx1xychzqe96fb2
This commit is contained in:
Fabien Meghazi 2012-12-06 17:17:49 +01:00
commit 3dbed3b90d
11 changed files with 81 additions and 191 deletions

View File

@ -1121,41 +1121,6 @@ class DataSet(openerpweb.Controller):
class View(openerpweb.Controller):
_cp_path = "/web/view"
def fields_view_get(self, req, model, view_id, view_type,
transform=True, toolbar=False, submenu=False):
Model = req.session.model(model)
fvg = Model.fields_view_get(view_id, view_type, req.context, toolbar, submenu)
# todo fme?: check that we should pass the evaluated context here
self.process_view(req.session, fvg, req.context, transform, (view_type == 'kanban'))
return fvg
def process_view(self, session, fvg, context, transform, preserve_whitespaces=False):
# depending on how it feels, xmlrpclib.ServerProxy can translate
# XML-RPC strings to ``str`` or ``unicode``. ElementTree does not
# enjoy unicode strings which can not be trivially converted to
# strings, and it blows up during parsing.
# So ensure we fix this retardation by converting view xml back to
# bit strings.
if isinstance(fvg['arch'], unicode):
arch = fvg['arch'].encode('utf-8')
else:
arch = fvg['arch']
fvg['arch_string'] = arch
fvg['arch'] = xml2json_from_elementtree(
ElementTree.fromstring(arch), preserve_whitespaces)
if 'id' in fvg['fields']:
# Special case for id's
id_field = fvg['fields']['id']
id_field['original_type'] = id_field['type']
id_field['type'] = 'id'
for field in fvg['fields'].itervalues():
for view in field.get("views", {}).itervalues():
self.process_view(session, view, None, transform)
@openerpweb.jsonrequest
def add_custom(self, req, view_id, arch):
CustomView = req.session.model('ir.ui.view.custom')
@ -1179,10 +1144,6 @@ class View(openerpweb.Controller):
return {'result': True}
return {'result': False}
@openerpweb.jsonrequest
def load(self, req, model, view_id, view_type, toolbar=False):
return self.fields_view_get(req, model, view_id, view_type, toolbar=toolbar)
class TreeView(View):
_cp_path = "/web/treeview"

View File

@ -341,12 +341,10 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
if (this.headless) {
this.ready.resolve();
} else {
var load_view = this.rpc("/web/view/load", {
model: this.model,
var load_view = instance.web.fields_view_get({
model: this.dataset._model,
view_id: this.view_id,
view_type: 'search',
context: instance.web.pyeval.eval(
'context', this.dataset.get_context())
});
$.when(load_view).then(function (r) {

View File

@ -10,7 +10,7 @@ openerp.testing = {};
formats: ['coresetup', 'dates'],
chrome: ['corelib', 'coresetup'],
views: ['corelib', 'coresetup', 'data', 'chrome'],
search: ['data', 'coresetup', 'formats'],
search: ['views', 'formats'],
list: ['views', 'data'],
form: ['data', 'views', 'list', 'formats'],
list_editable: ['list', 'form', 'data'],

View File

@ -1189,36 +1189,19 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
});
}
},
view_arch_to_dom_node: function(arch) {
// Historic mess for views arch
//
// server:
// -> got xml as string
// -> parse to xml and manipulate domains and contexts
// -> convert to json
// client:
// -> got view as json
// -> convert back to xml as string
// -> parse it as xml doc (manipulate button@type for IE)
// -> convert back to string
// -> parse it as dom element with jquery
// -> for each widget, convert node to json
//
// Wow !!!
var xml = instance.web.json_node_to_xml(arch);
var doc = $.parseXML('<div class="oe_form">' + xml + '</div>');
get_arch_fragment: function() {
var doc = $.parseXML(instance.web.json_node_to_xml(this.fvg.arch)).documentElement;
// IE won't allow custom button@type and will revert it to spec default : 'submit'
$('button', doc).each(function() {
$(this).attr('data-button-type', $(this).attr('type')).attr('type', 'button');
});
xml = instance.web.xml_to_str(doc);
return $(xml);
return $('<div class="oe_form"/>').append(instance.web.xml_to_str(doc));
},
render_to: function($target) {
var self = this;
this.$target = $target;
this.$form = this.view_arch_to_dom_node(this.fvg.arch);
this.$form = this.get_arch_fragment();
this.process_version();

View File

@ -9,6 +9,7 @@ var QWeb = instance.web.qweb,
instance.web.views.add('tree', 'instance.web.TreeView');
instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeView# */{
display_name: _lt('Tree'),
view_type: 'tree',
/**
* Indicates that this view is not searchable, and thus that no search
* view should be displayed (if there is one active).
@ -36,18 +37,9 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie
this.options = _.extend({}, this.defaults, options || {});
_.bindAll(this, 'color_for');
this.on('view_loaded', this, this.load_tree);
},
start: function () {
return this.rpc("/web/treeview/load", {
model: this.model,
view_id: this.view_id,
view_type: "tree",
toolbar: this.view_manager ? !!this.view_manager.sidebar : false,
context: instance.web.pyeval.eval(
'context', this.dataset.get_context())
}).done(this.on_loaded);
},
/**
* Returns the list of fields needed to correctly read objects.
*
@ -64,7 +56,7 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie
}
return fields;
},
on_loaded: function (fields_view) {
load_tree: function (fields_view) {
var self = this;
var has_toolbar = !!fields_view.arch.attrs.toolbar;
// field name in OpenERP is kinda stupid: this is the name of the field

View File

@ -1198,13 +1198,11 @@ instance.web.View = instance.web.Widget.extend({
} else {
if (! this.view_type)
console.warn("view_type is not defined", this);
view_loaded = this.rpc("/web/view/load", {
"model": this.dataset.model,
view_loaded = instance.web.fields_view_get({
"model": this.dataset._model,
"view_id": this.view_id,
"view_type": this.view_type,
toolbar: !!this.options.$sidebar,
context: instance.web.pyeval.eval(
'context', this.dataset.get_context(context))
"toolbar": !!this.options.$sidebar,
});
}
return view_loaded.then(function(r) {
@ -1379,12 +1377,53 @@ instance.web.View = instance.web.Widget.extend({
}
});
instance.web.xml_to_json = function(node) {
/**
* Performs a fields_view_get and apply postprocessing.
* return a {$.Deferred} resolved with the fvg
*
* @param {Object} [args]
* @param {String|Object} args.model instance.web.Model instance or string repr of the model
* @param {null|Object} args.context context if args.model is a string
* @param {null|Number} args.view_id id of the view to be loaded, default view if null
* @param {null|String} args.view_type type of view to be loaded if view_id is null
* @param {Boolean} [args.toolbar=false] get the toolbar definition
*/
instance.web.fields_view_get = function(args) {
function postprocess(fvg) {
var doc = $.parseXML(fvg.arch).documentElement;
fvg.arch = instance.web.xml_to_json(doc, (doc.nodeName.toLowerCase() !== 'kanban'));
if ('id' in fvg.fields) {
// Special case for id's
var id_field = fvg.fields['id'];
id_field.original_type = id_field.type;
id_field.type = 'id';
}
_.each(fvg.fields, function(field) {
_.each(field.views || {}, function(view) {
postprocess(view);
});
});
return fvg;
}
args = _.defaults(args, {
toolbar: false,
});
var model = args.model;
if (typeof model === 'string') {
model = new instance.web.Model(args.model, args.context);
}
return args.model.call('fields_view_get', [args.view_id, args.view_type, model.context(), args.toolbar]).then(function(fvg) {
return postprocess(fvg);
});
};
instance.web.xml_to_json = function(node, strip_whitespace) {
switch (node.nodeType) {
case 9:
return instance.web.xml_to_json(node.documentElement, strip_whitespace);
case 3:
case 4:
return node.data;
break;
return (strip_whitespace && node.data.trim() === '') ? undefined : node.data;
case 1:
var attrs = $(node).getAttributes();
_.each(['domain', 'filter_domain', 'context', 'default_get'], function(key) {
@ -1397,7 +1436,9 @@ instance.web.xml_to_json = function(node) {
return {
tag: node.tagName.toLowerCase(),
attrs: attrs,
children: _.map(node.childNodes, instance.web.xml_to_json)
children: _.compact(_.map(node.childNodes, function(node) {
return instance.web.xml_to_json(node, strip_whitespace);
})),
}
}
}
@ -1449,26 +1490,6 @@ instance.web.xml_to_str = function(node) {
throw new Error(_t("Could not serialize XML"));
}
};
instance.web.str_to_xml = function(s) {
if (window.DOMParser) {
var dp = new DOMParser();
var r = dp.parseFromString(s, "text/xml");
if (r.body && r.body.firstChild && r.body.firstChild.nodeName == 'parsererror') {
throw new Error(_t("Could not parse string to xml"));
}
return r;
}
var xDoc;
try {
xDoc = new ActiveXObject("MSXML2.DOMDocument");
} catch (e) {
throw new Error(_.str.sprintf( _t("Could not find a DOM Parser: %s"), e.message));
}
xDoc.async = false;
xDoc.preserveWhiteSpace = true;
xDoc.loadXML(s);
return xDoc;
}
/**
* Registry for all the main views

View File

@ -183,7 +183,7 @@ openerp.testing.section('list.edition', {
}
return [];
});
mock('/web/view/load', function () {
mock('demo:fields_view_get', function () {
return {
type: 'tree',
fields: {
@ -191,15 +191,7 @@ openerp.testing.section('list.edition', {
b: {type: 'char', string: "B"},
c: {type: 'char', string: "C"}
},
arch: {
tag: 'tree',
attrs: {},
children: [
{tag: 'field', attrs: {name: 'a'}},
{tag: 'field', attrs: {name: 'b'}},
{tag: 'field', attrs: {name: 'c'}}
]
}
arch: '<tree><field name="a"/><field name="b"/><field name="c"/></tree>',
};
});
}
@ -247,7 +239,7 @@ openerp.testing.section('list.edition.events', {
mock('demo:read', function () {
return [{ id: 1, a: 'foo', b: 'bar', c: 'baz' }];
});
mock('/web/view/load', function () {
mock('demo:fields_view_get', function () {
return {
type: 'tree',
fields: {
@ -255,15 +247,7 @@ openerp.testing.section('list.edition.events', {
b: {type: 'char', string: "B"},
c: {type: 'char', string: "C"}
},
arch: {
tag: 'tree',
attrs: {},
children: [
{tag: 'field', attrs: {name: 'a'}},
{tag: 'field', attrs: {name: 'b'}},
{tag: 'field', attrs: {name: 'c'}}
]
}
arch: '<tree><field name="a"/><field name="b"/><field name="c"/></tree>',
};
});
}
@ -320,19 +304,13 @@ openerp.testing.section('list.edition.onwrite', {
templates: true,
}, function (test) {
test('record-to-read', {asserts: 4}, function (instance, $fix, mock) {
mock('/web/view/load', function () {
mock('demo:fields_view_get', function () {
return {
type: 'tree',
fields: {
a: {type: 'char', string: "A"}
},
arch: {
tag: 'tree',
attrs: { on_write: 'on_write', colors: 'red:a == "foo"' },
children: [
{tag: 'field', attrs: {name: 'a'}}
]
}
arch: '<tree on_write="on_write" colors="red:a == \'foo\'"><field name="a"/></tree>',
};
});
mock('demo:read', function (args, kwargs) {

View File

@ -4,20 +4,13 @@ openerp.testing.section('list.buttons', {
templates: true
}, function (test) {
test('record-deletion', {asserts: 2}, function (instance, $fix, mock) {
mock('/web/view/load', function () {
mock('demo:fields_view_get', function () {
return {
type: 'tree',
fields: {
a: {type: 'char', string: "A"}
},
arch: {
tag: 'tree',
attrs: { },
children: [
{tag: 'field', attrs: {name: 'a'}},
{tag: 'button', attrs: {type: 'object', name: 'foo'}}
]
}
arch: '<tree><field name="a"/><button type="object" name="foo"/></tree>',
};
});
mock('demo:read', function (args, kwargs) {

View File

@ -152,25 +152,14 @@ var makeSearchView = function (instance, dummy_widget_attributes, defaults) {
instance.dummy = {};
instance.dummy.DummyWidget = instance.web.search.Field.extend(
dummy_widget_attributes || {});
if (!('/web/view/load' in instance.session.responses)) {
instance.session.responses['/web/view/load'] = function () {
if (!('dummy.model:fields_view_get' in instance.session.responses)) {
instance.session.responses['dummy.model:fields_view_get'] = function () {
return {
type: 'search',
fields: {
dummy: {type: 'char', string: "Dummy"}
},
arch: {
tag: 'search',
attrs: {},
children: [{
tag: 'field',
attrs: {
name: 'dummy',
widget: 'dummy'
},
children: []
}]
}
arch: '<search><field name="dummy" widget="dummy"/></search>'
};
};
}
@ -183,7 +172,7 @@ var makeSearchView = function (instance, dummy_widget_attributes, defaults) {
};
};
var dataset = {model: 'dummy.model', get_context: function () { return {}; }};
var dataset = new instance.web.DataSet(null, 'dummy.model');
var view = new instance.web.SearchView(null, dataset, false, defaults);
var self = this;
view.on('invalid_search', self, function () {
@ -926,31 +915,16 @@ openerp.testing.section('filters', {
rpc: 'mock',
templates: true,
setup: function (instance, $s, mock) {
mock('/web/view/load', function () {
mock('dummy.model:fields_view_get', function () {
// view with a single group of filters
return {
type: 'search',
fields: {},
arch: {
tag: 'search',
attrs: {},
children: [{
tag: 'filter',
attrs: { string: "Foo1", domain: [ ['foo', '=', '1'] ] },
children: []
}, {
tag: 'filter',
attrs: {
name: 'foo2',
string: "Foo2",
domain: [ ['foo', '=', '2'] ] },
children: []
}, {
tag: 'filter',
attrs: { string: "Foo3", domain: [ ['foo', '=', '3'] ] },
children: []
}]
}
arch: '<search>' +
'<filter string="Foo1" domain="[ [\'foo\', \'=\', \'1\'] ]"/>' +
'<filter name="foo2" string="Foo2" domain="[ [\'foo\', \'=\', \'2\'] ]"/>' +
'<filter string="Foo3" domain="[ [\'foo\', \'=\', \'3\'] ]"/>' +
'</search>',
};
});
}

View File

@ -3,11 +3,6 @@ import openerp
class DiagramView(openerp.addons.web.controllers.main.View):
_cp_path = "/web_diagram/diagram"
@openerp.addons.web.http.jsonrequest
def load(self, req, model, view_id):
fields_view = self.fields_view_get(req, model, view_id, 'diagram')
return {'fields_view': fields_view}
@openerp.addons.web.http.jsonrequest
def get_diagram_info(self, req, id, model, node, connector,
src_node, des_node, label, **kw):

View File

@ -9,6 +9,7 @@ var QWeb = instance.web.qweb,
instance.web.views.add('diagram', 'instance.web.DiagramView');
instance.web.DiagramView = instance.web.View.extend({
display_name: _lt('Diagram'),
view_type: 'diagram',
searchable: false,
init: function(parent, dataset, view_id, options) {
var self = this;
@ -24,12 +25,6 @@ instance.web.DiagramView = instance.web.View.extend({
this.on('view_loaded', self, self.load_diagram);
this.on('pager_action_executed', self, self.pager_action_trigger);
},
start: function() {
var self = this;
return this.rpc("/web_diagram/diagram/load", {"model": this.model, "view_id": this.view_id}).done(function(r) {
self.load_diagram(r);
});
},
toTitleCase: function(str) {
return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
@ -41,7 +36,7 @@ instance.web.DiagramView = instance.web.View.extend({
this.id = this.ids[self.dataset.index || 0];
}
this.fields_view = result.fields_view,
this.fields_view = result,
this.view_id = this.fields_view.view_id,
this.fields = this.fields_view.fields,
this.nodes = this.fields_view.arch.children[0],