diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py
index d5eaafaecee..1e6bd6b8500 100644
--- a/addons/base/controllers/main.py
+++ b/addons/base/controllers/main.py
@@ -423,25 +423,25 @@ def eval_context_and_domain(session, context, domain=None):
return e_context, e_domain
-def load_actions_from_ir_values(req, key, key2, models, meta, context):
+def load_actions_from_ir_values(req, key, key2, models, meta):
+ context = req.session.eval_context(req.context)
Values = req.session.model('ir.values')
actions = Values.get(key, key2, models, meta, context)
- return [(id, name, clean_action(action, req.session, context=context))
+ return [(id, name, clean_action(req, action))
for id, name, action in actions]
-def clean_action(action, session, context=None):
+def clean_action(req, action):
+ context = req.session.eval_context(req.context)
+ eval_ctx = req.session.evaluation_context(context)
action.setdefault('flags', {})
- if action['type'] != 'ir.actions.act_window':
- return action
+
# values come from the server, we can just eval them
if isinstance(action.get('context'), basestring):
- localvars = session.evaluation_context(context=context)
- action['context'] = eval( action['context'], localvars ) or {}
+ action['context'] = eval( action['context'], eval_ctx ) or {}
if isinstance(action.get('domain'), basestring):
- localvars = session.evaluation_context( action.get('context', {}))
- action['domain'] = eval( action['domain'], localvars ) or []
+ action['domain'] = eval( action['domain'], eval_ctx ) or []
return fix_view_modes(action)
@@ -559,8 +559,7 @@ class Menu(openerpweb.Controller):
@openerpweb.jsonrequest
def action(self, req, menu_id):
actions = load_actions_from_ir_values(req,'action', 'tree_but_open',
- [('ir.ui.menu', menu_id)], False,
- req.session.eval_context(req.context))
+ [('ir.ui.menu', menu_id)], False)
return {"action": actions}
class DataSet(openerpweb.Controller):
@@ -572,15 +571,15 @@ class DataSet(openerpweb.Controller):
req.session.eval_context(req.context))}
@openerpweb.jsonrequest
- def search_read(self, request, model, fields=False, offset=0, limit=False, domain=None, sort=None):
- return self.do_search_read(request, model, fields, offset, limit, domain, sort)
- def do_search_read(self, request, model, fields=False, offset=0, limit=False, domain=None
+ def search_read(self, req, model, fields=False, offset=0, limit=False, domain=None, sort=None):
+ return self.do_search_read(req, model, fields, offset, limit, domain, sort)
+ def do_search_read(self, req, model, fields=False, offset=0, limit=False, domain=None
, sort=None):
""" Performs a search() followed by a read() (if needed) using the
provided search criteria
- :param request: a JSON-RPC request object
- :type request: openerpweb.JsonRequest
+ :param req: a JSON-RPC request object
+ :type req: openerpweb.JsonRequest
:param str model: the name of the model to search on
:param fields: a list of the fields to return in the result records
:type fields: [str]
@@ -593,10 +592,10 @@ class DataSet(openerpweb.Controller):
matching fields selection set)
:rtype: list
"""
- Model = request.session.model(model)
+ Model = req.session.model(model)
context, domain = eval_context_and_domain(
- request.session, request.context, domain)
+ req.session, req.context, domain)
ids = Model.search(domain, 0, False, sort or False, context)
# need to fill the dataset with all ids for the (domain, context) pair,
@@ -618,22 +617,22 @@ class DataSet(openerpweb.Controller):
@openerpweb.jsonrequest
- def read(self, request, model, ids, fields=False):
- return self.do_search_read(request, model, ids, fields)
+ def read(self, req, model, ids, fields=False):
+ return self.do_search_read(req, model, ids, fields)
@openerpweb.jsonrequest
- def get(self, request, model, ids, fields=False):
- return self.do_get(request, model, ids, fields)
+ def get(self, req, model, ids, fields=False):
+ return self.do_get(req, model, ids, fields)
- def do_get(self, request, model, ids, fields=False):
+ def do_get(self, req, model, ids, fields=False):
""" Fetches and returns the records of the model ``model`` whose ids
are in ``ids``.
The results are in the same order as the inputs, but elements may be
missing (if there is no record left for the id)
- :param request: the JSON-RPC2 request object
- :type request: openerpweb.JsonRequest
+ :param req: the JSON-RPC2 request object
+ :type req: openerpweb.JsonRequest
:param model: the model to read from
:type model: str
:param ids: a list of identifiers
@@ -644,8 +643,8 @@ class DataSet(openerpweb.Controller):
:returns: a list of records, in the same order as the list of ids
:rtype: list
"""
- Model = request.session.model(model)
- records = Model.read(ids, fields, request.session.eval_context(request.context))
+ Model = req.session.model(model)
+ records = Model.read(ids, fields, req.session.eval_context(req.context))
record_map = dict((record['id'], record) for record in records)
@@ -673,9 +672,9 @@ class DataSet(openerpweb.Controller):
return {'result': r}
@openerpweb.jsonrequest
- def unlink(self, request, model, ids=()):
- Model = request.session.model(model)
- return Model.unlink(ids, request.session.eval_context(request.context))
+ def unlink(self, req, model, ids=()):
+ Model = req.session.model(model)
+ return Model.unlink(ids, req.session.eval_context(req.context))
def call_common(self, req, model, method, args, domain_id=None, context_id=None):
domain = args[domain_id] if domain_id and len(args) - 1 >= domain_id else []
@@ -696,7 +695,7 @@ class DataSet(openerpweb.Controller):
def call_button(self, req, model, method, args, domain_id=None, context_id=None):
action = self.call_common(req, model, method, args, domain_id, context_id)
if isinstance(action, dict) and action.get('type') != '':
- return {'result': clean_action(action, req.session)}
+ return {'result': clean_action(req, action)}
return {'result': False}
@openerpweb.jsonrequest
@@ -718,9 +717,9 @@ class DataSet(openerpweb.Controller):
class DataGroup(openerpweb.Controller):
_cp_path = "/base/group"
@openerpweb.jsonrequest
- def read(self, request, model, fields, group_by_fields, domain=None, sort=None):
- Model = request.session.model(model)
- context, domain = eval_context_and_domain(request.session, request.context, domain)
+ def read(self, req, model, fields, group_by_fields, domain=None, sort=None):
+ Model = req.session.model(model)
+ context, domain = eval_context_and_domain(req.session, req.context, domain)
return Model.read_group(
domain or [], fields, group_by_fields, 0, False,
@@ -729,13 +728,13 @@ class DataGroup(openerpweb.Controller):
class View(openerpweb.Controller):
_cp_path = "/base/view"
- def fields_view_get(self, request, model, view_id, view_type,
+ def fields_view_get(self, req, model, view_id, view_type,
transform=True, toolbar=False, submenu=False):
- Model = request.session.model(model)
- context = request.session.eval_context(request.context)
+ Model = req.session.model(model)
+ context = req.session.eval_context(req.context)
fvg = Model.fields_view_get(view_id, view_type, context, toolbar, submenu)
# todo fme?: check that we should pass the evaluated context here
- self.process_view(request.session, fvg, context, transform)
+ self.process_view(req.session, fvg, context, transform)
return fvg
def process_view(self, session, fvg, context, transform):
@@ -768,20 +767,20 @@ class View(openerpweb.Controller):
field["context"] = self.parse_context(field["context"], session)
@openerpweb.jsonrequest
- def add_custom(self, request, view_id, arch):
- CustomView = request.session.model('ir.ui.view.custom')
+ def add_custom(self, req, view_id, arch):
+ CustomView = req.session.model('ir.ui.view.custom')
CustomView.create({
- 'user_id': request.session._uid,
+ 'user_id': req.session._uid,
'ref_id': view_id,
'arch': arch
- }, request.session.eval_context(request.context))
+ }, req.session.eval_context(req.context))
return {'result': True}
@openerpweb.jsonrequest
- def undo_custom(self, request, view_id, reset=False):
- CustomView = request.session.model('ir.ui.view.custom')
- context = request.session.eval_context(request.context)
- vcustom = CustomView.search([('user_id', '=', request.session._uid), ('ref_id' ,'=', view_id)],
+ def undo_custom(self, req, view_id, reset=False):
+ CustomView = req.session.model('ir.ui.view.custom')
+ context = req.session.eval_context(req.context)
+ vcustom = CustomView.search([('user_id', '=', req.session._uid), ('ref_id' ,'=', view_id)],
0, False, False, context)
if vcustom:
if reset:
@@ -1040,13 +1039,13 @@ class Action(openerpweb.Controller):
action = req.session.model(action_type[0]['type']).read([action_id], False,
context)
if action:
- value = clean_action(action[0], req.session)
+ value = clean_action(req, action[0])
return {'result': value}
@openerpweb.jsonrequest
def run(self, req, action_id):
- return clean_action(req.session.model('ir.actions.server').run(
- [action_id], req.session.eval_context(req.context)), req.session)
+ return clean_action(req, req.session.model('ir.actions.server').run(
+ [action_id], req.session.eval_context(req.context)))
class TreeView(View):
_cp_path = "/base/treeview"
@@ -1059,7 +1058,7 @@ class TreeView(View):
def action(self, req, model, id):
return load_actions_from_ir_values(
req,'action', 'tree_but_open',[(model, id)],
- False, req.session.eval_context(req.context))
+ False)
def export_csv(fields, result):
fp = StringIO()
diff --git a/addons/base/static/src/js/data.js b/addons/base/static/src/js/data.js
index 04c23224806..668898dd66c 100644
--- a/addons/base/static/src/js/data.js
+++ b/addons/base/static/src/js/data.js
@@ -396,18 +396,18 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data
*
* @param {String} method
* @param {Array} [args]
- * @param {Number} [domain_id] index of a domain to evaluate in the args array
- * @param {Number} [context_id] index of a context to evaluate in the args array
+ * @param {Number} [domain_index] index of a domain to evaluate in the args array
+ * @param {Number} [context_index] index of a context to evaluate in the args array
* @param {Function} callback
* @param {Function }error_callback
* @returns {$.Deferred}
*/
- call_and_eval: function (method, args, domain_id, context_id, callback, error_callback) {
+ call_and_eval: function (method, args, domain_index, context_index, callback, error_callback) {
return this.rpc('/base/dataset/call', {
model: this.model,
method: method,
- domain_id: domain_id || null,
- context_id: context_id || null,
+ domain_id: domain_index || null,
+ context_id: context_index || null,
args: args || []
}, callback, error_callback);
},
diff --git a/addons/base/static/src/js/form.js b/addons/base/static/src/js/form.js
index 3280b7e0d81..4138f6d50b5 100644
--- a/addons/base/static/src/js/form.js
+++ b/addons/base/static/src/js/form.js
@@ -1306,36 +1306,56 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
this.$input = this.$element.find("input");
this.$drop_down = this.$element.find(".oe-m2o-drop-down-button");
this.$menu_btn = this.$element.find(".oe-m2o-cm-button");
-
+
// context menu
- var bindings = {};
- bindings[this.cm_id + "_search"] = function() {
- self._search_create_popup("search");
- };
- bindings[this.cm_id + "_create"] = function() {
- self._search_create_popup("form");
- };
- bindings[this.cm_id + "_open"] = function() {
- if (!self.value) {
- return;
- }
- var pop = new openerp.base.form.FormOpenPopup(self.view);
- pop.show_element(self.field.relation, self.value[0],self.build_context(), {});
- pop.on_write_completed.add_last(function() {
- self.set_value(self.value[0]);
+ var init_context_menu_def = $.Deferred().then(function(e) {
+ var rdataset = new openerp.base.DataSetStatic(self, "ir.values", self.build_context());
+ rdataset.call("get", ['action', 'client_action_relate',
+ [[self.field.relation, false]], false, rdataset.get_context()], false, 0)
+ .then(function(result) {
+ self.related_entries = result;
+
+ var $cmenu = $("#" + self.cm_id);
+ $cmenu.append(QWeb.render("FieldMany2One.context_menu", {widget: self}));
+ var bindings = {};
+ bindings[self.cm_id + "_search"] = function() {
+ self._search_create_popup("search");
+ };
+ bindings[self.cm_id + "_create"] = function() {
+ self._search_create_popup("form");
+ };
+ bindings[self.cm_id + "_open"] = function() {
+ if (!self.value) {
+ return;
+ }
+ var pop = new openerp.base.form.FormOpenPopup(self.view);
+ pop.show_element(self.field.relation, self.value[0],self.build_context(), {});
+ pop.on_write_completed.add_last(function() {
+ self.set_value(self.value[0]);
+ });
+ };
+ _.each(_.range(self.related_entries.length), function(i) {
+ bindings[self.cm_id + "_related_" + i] = function() {
+ self.open_related(self.related_entries[i]);
+ };
+ });
+ var cmenu = self.$menu_btn.contextMenu(self.cm_id, {'leftClickToo': true,
+ bindings: bindings, itemStyle: {"color": ""},
+ onContextMenu: function() {
+ if(self.value) {
+ $("#" + self.cm_id + " .oe_m2o_menu_item_mandatory").removeClass("oe-m2o-disabled-cm");
+ } else {
+ $("#" + self.cm_id + " .oe_m2o_menu_item_mandatory").addClass("oe-m2o-disabled-cm");
+ }
+ return true;
+ }, menuStyle: {width: "200px"}
+ });
+ setTimeout(function() {self.$menu_btn.trigger(e);}, 0);
});
- };
- var cmenu = this.$menu_btn.contextMenu(this.cm_id, {'leftClickToo': true,
- bindings: bindings, itemStyle: {"color": ""},
- onContextMenu: function() {
- if(self.value) {
- $("#" + self.cm_id + "_open").removeClass("oe-m2o-disabled-cm");
- } else {
- $("#" + self.cm_id + "_open").addClass("oe-m2o-disabled-cm");
- }
- return true;
- }
});
+ var ctx_callback = function(e) {init_context_menu_def.resolve(e); e.preventDefault()};
+ this.$menu_btn.bind('contextmenu', ctx_callback);
+ this.$menu_btn.click(ctx_callback);
// some behavior for input
this.$input.keyup(function() {
@@ -1529,6 +1549,22 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
if (this.value === null) {
this.invalid = this.required;
}
+ },
+ open_related: function(related) {
+ var self = this;
+ if (!self.value)
+ return;
+ self.rpc("/base/action/load", {
+ action_id: related[2].id,
+ context: {
+ active_id: self.value[0],
+ active_ids: self.value[1],
+ active_model: self.field.relation
+ }
+ }, function(result) {
+ //TODO niv
+ debugger;
+ });
}
});
diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml
index 69aac831386..0c17e70cfc7 100644
--- a/addons/base/static/src/xml/base.xml
+++ b/addons/base/static/src/xml/base.xml
@@ -805,13 +805,24 @@
-