[merge] many improvements for relateds
bzr revid: nicolas.vanhoren@openerp.com-20110825171642-lfmj3rrmfkt0lgex
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -805,13 +805,24 @@
|
||||
<img src="/base/static/src/img/down-arrow.png" /></span>
|
||||
<span class="oe-m2o-cm-button" t-att-id="widget.name + '_open'">
|
||||
<img src="/base/static/src/img/icons/gtk-index.png"/></span>
|
||||
<div t-att-id="widget.cm_id" class="contextMenu" style="display:none"><ul>
|
||||
<li t-att-id="widget.cm_id + '_open'" style="color:grey">Open...</li>
|
||||
<li t-att-id="widget.cm_id + '_create'">Create...</li>
|
||||
<li t-att-id="widget.cm_id + '_search'">Search...</li>
|
||||
</ul></div>
|
||||
<div t-att-id="widget.cm_id" class="contextMenu" style="display:none">
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="FieldMany2One.context_menu">
|
||||
<ul>
|
||||
<li t-att-id="widget.cm_id + '_open'" style="color:grey">Open...</li>
|
||||
<li t-att-id="widget.cm_id + '_create'">Create...</li>
|
||||
<li t-att-id="widget.cm_id + '_search'" class="oe_m2o_menu_item_mandatory">Search...</li>
|
||||
<t t-set="i" t-value="0"/>
|
||||
<t t-foreach="widget.related_entries" t-as="entry">
|
||||
<li t-att-id="widget.cm_id + '_related_' + i" style="color:grey" class="oe_m2o_menu_item_mandatory">
|
||||
... <t t-esc="(entry[2] || {})['name'] || ''"/>
|
||||
</li>
|
||||
<t t-set="i" t-value="i+1"/>
|
||||
</t>
|
||||
</ul>
|
||||
</t>
|
||||
<t t-name="FieldOne2Many">
|
||||
<div t-att-id="widget.element_id">
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user