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 @@ - + + + +