[MERGE] niv sidebar action
bzr revid: al@openerp.com-20110409201421-9dk19e0jbt25oh9b
This commit is contained in:
commit
39c554b192
|
@ -9,6 +9,8 @@ import openerpweb
|
|||
import openerpweb.ast
|
||||
import openerpweb.nonliterals
|
||||
|
||||
import cherrypy
|
||||
|
||||
# Should move to openerpweb.Xml2Json
|
||||
class Xml2Json:
|
||||
# xml2json-direct
|
||||
|
@ -168,26 +170,71 @@ class Session(openerpweb.Controller):
|
|||
'domain': domain,
|
||||
'group_by': group_by_sequence
|
||||
}
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def save_session_action(self, req, the_action):
|
||||
"""
|
||||
This method store an action object in the session object and returns an integer
|
||||
identifying that action. The method get_session_action() can be used to get
|
||||
back the action.
|
||||
|
||||
:param the_action: The action to save in the session.
|
||||
:type the_action: anything
|
||||
:return: A key identifying the saved action.
|
||||
:rtype: integer
|
||||
"""
|
||||
saved_actions = cherrypy.session.get('saved_actions')
|
||||
if not saved_actions:
|
||||
saved_actions = {"next":0, "actions":{}}
|
||||
cherrypy.session['saved_actions'] = saved_actions
|
||||
# we don't allow more than 10 stored actions
|
||||
if len(saved_actions["actions"]) >= 10:
|
||||
del saved_actions["actions"][min(saved_actions["actions"].keys())]
|
||||
key = saved_actions["next"]
|
||||
saved_actions["actions"][key] = the_action
|
||||
saved_actions["next"] = key + 1
|
||||
return key
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def get_session_action(self, req, key):
|
||||
"""
|
||||
Gets back a previously saved action. This method can return None if the action
|
||||
was saved since too much time (this case should be handled in a smart way).
|
||||
|
||||
:param key: The key given by save_session_action()
|
||||
:type key: integer
|
||||
:return: The saved action or None.
|
||||
:rtype: anything
|
||||
"""
|
||||
saved_actions = cherrypy.session.get('saved_actions')
|
||||
if not saved_actions:
|
||||
return None
|
||||
return saved_actions["actions"].get(key)
|
||||
|
||||
|
||||
def load_actions_from_ir_values(req, key, key2, models, meta, context):
|
||||
Values = req.session.model('ir.values')
|
||||
actions = Values.get(key, key2, models, meta, context)
|
||||
|
||||
for _, _, action in actions:
|
||||
# values come from the server, we can just eval them
|
||||
if isinstance(action['context'], basestring):
|
||||
action['context'] = eval(
|
||||
action['context'],
|
||||
req.session.evaluation_context()) or {}
|
||||
clean_action(action, req.session)
|
||||
|
||||
if isinstance(action['domain'], basestring):
|
||||
action['domain'] = eval(
|
||||
action['domain'],
|
||||
req.session.evaluation_context(
|
||||
action['context'])) or []
|
||||
fix_view_modes(action)
|
||||
return actions
|
||||
|
||||
def clean_action(action, session):
|
||||
# values come from the server, we can just eval them
|
||||
if isinstance(action['context'], basestring):
|
||||
action['context'] = eval(
|
||||
action['context'],
|
||||
session.evaluation_context()) or {}
|
||||
|
||||
if isinstance(action['domain'], basestring):
|
||||
action['domain'] = eval(
|
||||
action['domain'],
|
||||
session.evaluation_context(
|
||||
action['context'])) or []
|
||||
fix_view_modes(action)
|
||||
|
||||
def fix_view_modes(action):
|
||||
""" For historical reasons, OpenERP has weird dealings in relation to
|
||||
view_mode and the view_type attribute (on window actions):
|
||||
|
@ -354,9 +401,9 @@ class DataSet(openerpweb.Controller):
|
|||
return {'result': r}
|
||||
|
||||
class View(openerpweb.Controller):
|
||||
def fields_view_get(self, session, model, view_id, view_type, transform=True):
|
||||
def fields_view_get(self, session, model, view_id, view_type, transform=True, toolbar=False, submenu=False):
|
||||
Model = session.model(model)
|
||||
r = Model.fields_view_get(view_id, view_type)
|
||||
r = Model.fields_view_get(view_id, view_type, {}, toolbar, submenu)
|
||||
if transform:
|
||||
context = {} # TODO: dict(ctx_sesssion, **ctx_action)
|
||||
xml = self.transform_view(r['arch'], session, context)
|
||||
|
@ -460,16 +507,16 @@ class FormView(View):
|
|||
_cp_path = "/base/formview"
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def load(self, req, model, view_id):
|
||||
fields_view = self.fields_view_get(req.session, model, view_id, 'form')
|
||||
def load(self, req, model, view_id, toolbar=False):
|
||||
fields_view = self.fields_view_get(req.session, model, view_id, 'form', toolbar=toolbar)
|
||||
return {'fields_view': fields_view}
|
||||
|
||||
class ListView(View):
|
||||
_cp_path = "/base/listview"
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def load(self, req, model, view_id):
|
||||
fields_view = self.fields_view_get(req.session, model, view_id, 'tree')
|
||||
def load(self, req, model, view_id, toolbar=False):
|
||||
fields_view = self.fields_view_get(req.session, model, view_id, 'tree', toolbar=toolbar)
|
||||
return {'fields_view': fields_view}
|
||||
|
||||
class SearchView(View):
|
||||
|
@ -479,15 +526,6 @@ class SearchView(View):
|
|||
def load(self, req, model, view_id):
|
||||
fields_view = self.fields_view_get(req.session, model, view_id, 'search')
|
||||
return {'fields_view': fields_view}
|
||||
|
||||
class SideBar(View):
|
||||
_cp_path = "/base/sidebar"
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def get_actions(self, request, model, object_id=0):
|
||||
result = load_actions_from_ir_values(request, "action", "client_action_multi",
|
||||
[[model, object_id]], False, {})
|
||||
return result
|
||||
|
||||
class Action(openerpweb.Controller):
|
||||
_cp_path = "/base/action"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>OpenERP</title>
|
||||
<link rel="shortcut icon" href="/base/static/openerp/img/favicon.ico" type="image/x-icon"/>
|
||||
<link rel="shortcut icon" href="/base/static/src/img/favicon.ico" type="image/x-icon"/>
|
||||
|
||||
<script type="text/javascript" src="/base/static/lib/LABjs/LAB.js"></script>
|
||||
<script type="text/javascript" src="/base/static/lib/underscore/underscore.js"></script>
|
||||
|
|
|
@ -99,7 +99,7 @@ openerp.base.DataSet = openerp.base.Controller.extend( /** @lends openerp.base.
|
|||
context: this.context
|
||||
}, callback);
|
||||
},
|
||||
unlink: function() {
|
||||
unlink: function(ids) {
|
||||
this.notification['default']("Unlink", ids);
|
||||
},
|
||||
call: function (method, ids, args, callback) {
|
||||
|
@ -111,7 +111,7 @@ openerp.base.DataSet = openerp.base.Controller.extend( /** @lends openerp.base.
|
|||
ids: ids,
|
||||
args: args
|
||||
}, callback);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.DataSetStatic = openerp.base.DataSet.extend({
|
||||
|
@ -123,7 +123,7 @@ openerp.base.DataSetStatic = openerp.base.DataSet.extend({
|
|||
},
|
||||
read_slice: function (fields, offset, limit, callback) {
|
||||
this.read_ids(this.ids.slice(offset, offset + limit));
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.DataSetSearch = openerp.base.DataSet.extend({
|
||||
|
@ -163,7 +163,7 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
|
|||
}
|
||||
callback(records);
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.DataSetRelational = openerp.base.DataSet.extend( /** @lends openerp.base.DataSet# */{
|
||||
|
|
|
@ -30,7 +30,8 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
|
|||
},
|
||||
start: function() {
|
||||
//this.log('Starting FormView '+this.model+this.view_id)
|
||||
return this.rpc("/base/formview/load", {"model": this.model, "view_id": this.view_id}, this.on_loaded);
|
||||
return this.rpc("/base/formview/load", {"model": this.model, "view_id": this.view_id,
|
||||
toolbar:!!this.view_manager.sidebar}, this.on_loaded);
|
||||
},
|
||||
on_loaded: function(data) {
|
||||
var self = this;
|
||||
|
@ -54,7 +55,7 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
|
|||
|
||||
// sidebar stuff
|
||||
if (this.view_manager.sidebar) {
|
||||
this.view_manager.sidebar.load_multi_actions();
|
||||
this.view_manager.sidebar.set_toolbar(data.fields_view.toolbar);
|
||||
}
|
||||
},
|
||||
do_show: function () {
|
||||
|
@ -140,7 +141,7 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
|
|||
var ajax = {
|
||||
url: '/base/dataset/call',
|
||||
async: false
|
||||
}
|
||||
};
|
||||
return this.rpc(ajax, {
|
||||
model: this.dataset.model,
|
||||
method: method,
|
||||
|
@ -212,7 +213,7 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
|
|||
if (invalid) {
|
||||
this.on_invalid();
|
||||
} else {
|
||||
this.log("About to save", values)
|
||||
this.log("About to save", values);
|
||||
this.dataset.write(this.datarecord.id, values, this.on_saved);
|
||||
}
|
||||
},
|
||||
|
@ -244,8 +245,13 @@ openerp.base.FormView = openerp.base.Controller.extend( /** @lends openerp.base
|
|||
}
|
||||
},
|
||||
do_search: function (domains, contexts, groupbys) {
|
||||
this.notification['default']("Searching form");
|
||||
},
|
||||
on_action: function (action) {
|
||||
this.notification['default']('Executing action ' + action);
|
||||
},
|
||||
do_cancel: function () {
|
||||
this.notification['default']("Cancelling form");
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -698,7 +704,7 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
|
|||
},
|
||||
set_value: function(value) {
|
||||
this._super.apply(this, arguments);
|
||||
var show_value = ''
|
||||
var show_value = '';
|
||||
if (value != null && value !== false) {
|
||||
show_value = value[1];
|
||||
this.value = value[0];
|
||||
|
@ -713,17 +719,15 @@ openerp.base.form.FieldOne2ManyDatasSet = openerp.base.DataSetStatic.extend({
|
|||
write: function (id, data, callback) {
|
||||
this._super(id, data, callback);
|
||||
},
|
||||
write: function (id, data, callback) {
|
||||
this._super(id, data, callback);
|
||||
},
|
||||
unlink: function() {
|
||||
this.notification['default']('Unlinking o2m ' + this.ids);
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.form.FieldOne2ManyViewManager = openerp.base.ViewManager.extend({
|
||||
init: function(session, element_id, dataset, views) {
|
||||
this._super(session, element_id, dataset, views);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
|
||||
|
|
|
@ -36,7 +36,8 @@ openerp.base.ListView = openerp.base.Controller.extend(
|
|||
},
|
||||
start: function() {
|
||||
//this.log('Starting ListView '+this.model+this.view_id)
|
||||
return this.rpc("/base/listview/load", {"model": this.model, "view_id":this.view_id}, this.on_loaded);
|
||||
return this.rpc("/base/listview/load", {"model": this.model, "view_id":this.view_id,
|
||||
toolbar:!!this.view_manager.sidebar}, this.on_loaded);
|
||||
},
|
||||
on_loaded: function(data) {
|
||||
this.fields_view = data.fields_view;
|
||||
|
@ -73,8 +74,9 @@ openerp.base.ListView = openerp.base.Controller.extend(
|
|||
'tr', 'click', this.on_select_row);
|
||||
|
||||
// sidebar stuff
|
||||
if (this.view_manager.sidebar)
|
||||
this.view_manager.sidebar.load_multi_actions();
|
||||
if (this.view_manager.sidebar) {
|
||||
this.view_manager.sidebar.set_toolbar(data.fields_view.toolbar);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Fills the table with the provided records after emptying it
|
||||
|
@ -83,7 +85,6 @@ openerp.base.ListView = openerp.base.Controller.extend(
|
|||
* @returns {Promise} promise to the end of view rendering (list views are asynchronously filled for improved responsiveness)
|
||||
*/
|
||||
do_fill_table: function(records) {
|
||||
console.log("listview do_fill",records)
|
||||
this.rows = records;
|
||||
|
||||
var $table = this.$element.find('table');
|
||||
|
@ -148,7 +149,6 @@ openerp.base.ListView = openerp.base.Controller.extend(
|
|||
},
|
||||
do_search: function (domains, contexts, groupbys) {
|
||||
var self = this;
|
||||
console.log("listview do_search",domains)
|
||||
this.rpc('/base/session/eval_domain_and_context', {
|
||||
domains: domains,
|
||||
contexts: contexts,
|
||||
|
|
|
@ -20,7 +20,7 @@ openerp.base.ActionManager = openerp.base.Controller.extend({
|
|||
if (this.viewmanager) {
|
||||
this.viewmanager.stop();
|
||||
}
|
||||
this.viewmanager = new openerp.base.ViewManagerAction(this.session,this.element_id, action, false);
|
||||
this.viewmanager = new openerp.base.ViewManagerAction(this.session,this.element_id, action, true);
|
||||
this.viewmanager.start();
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +141,6 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
|
|||
this.sidebar = new openerp.base.Sidebar(null, this);
|
||||
},
|
||||
start: function() {
|
||||
var self = this;
|
||||
var inital_view_loaded = this._super();
|
||||
|
||||
// init sidebar
|
||||
|
@ -159,10 +158,13 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
|
|||
search_defaults[match[1]] = value;
|
||||
}
|
||||
});
|
||||
var searchview_loaded = this.setup_search_view(view_id,search_defaults);
|
||||
var searchview_loaded = null;
|
||||
if (view_id) {
|
||||
searchview_loaded = this.setup_search_view(view_id,search_defaults);
|
||||
}
|
||||
|
||||
// schedule auto_search
|
||||
if (this.action['auto_search']) {
|
||||
if (searchview_loaded != null && this.action['auto_search']) {
|
||||
$.when(searchview_loaded, inital_view_loaded)
|
||||
.then(this.searchview.do_search);
|
||||
}
|
||||
|
@ -173,29 +175,30 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
|
|||
this.sidebar.stop();
|
||||
}
|
||||
this._super();
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.BaseWidget = openerp.base.Controller.extend({
|
||||
/**
|
||||
* The name of the QWeb template that will be used for rendering. Must be redifined
|
||||
* in subclasses or the render() method can not be used.
|
||||
* The name of the QWeb template that will be used for rendering. Must be
|
||||
* redefined in subclasses or the render() method can not be used.
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
template: null,
|
||||
/**
|
||||
* The prefix used to generate an id automatically. Should be redifined in subclasses.
|
||||
* If it is not defined, a default identifier will be used.
|
||||
* The prefix used to generate an id automatically. Should be redefined in
|
||||
* subclasses. If it is not defined, a default identifier will be used.
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
identifier_prefix: 'generic-identifier',
|
||||
/**
|
||||
* Base class for widgets. Handle rendering (based on a QWeb template), identifier
|
||||
* generation, parenting and destruction of the widget.
|
||||
* Contructor. Also initialize the identifier.
|
||||
*
|
||||
* Base class for widgets. Handle rendering (based on a QWeb template),
|
||||
* identifier generation, parenting and destruction of the widget.
|
||||
* Also initialize the identifier.
|
||||
*
|
||||
* @constructs
|
||||
* @params {openerp.base.search.BaseWidget} parent The parent widget.
|
||||
*/
|
||||
init: function (parent, session) {
|
||||
|
@ -242,8 +245,8 @@ openerp.base.BaseWidget = openerp.base.Controller.extend({
|
|||
this._super();
|
||||
},
|
||||
/**
|
||||
* Set the parent of this component, also unregister the previous parent if there
|
||||
* was one.
|
||||
* Set the parent of this component, also un-register the previous parent
|
||||
* if there was one.
|
||||
*
|
||||
* @param {openerp.base.BaseWidget} parent The new parent.
|
||||
*/
|
||||
|
@ -274,27 +277,26 @@ openerp.base.Sidebar = openerp.base.BaseWidget.extend({
|
|||
this.view_manager = view_manager;
|
||||
this.sections = [];
|
||||
},
|
||||
load_multi_actions: function() {
|
||||
if (_.detect(this.sections, function(x) {return x.type=="multi_actions";}) != undefined)
|
||||
return;
|
||||
set_toolbar: function(toolbar) {
|
||||
this.sections = [];
|
||||
var self = this;
|
||||
this.rpc("/base/sidebar/get_actions",
|
||||
{"model": this.view_manager.dataset.model}, function(result) {
|
||||
self.sections.push({type: "multi_actions", elements:
|
||||
_.map(result, function(x) {return {text:x[2].name, action:x}; })});
|
||||
self.refresh();
|
||||
_.each(["print", "action", "relate"], function(type) {
|
||||
if (toolbar[type].length == 0)
|
||||
return;
|
||||
var section = {elements:toolbar[type]};
|
||||
self.sections.push(section);
|
||||
});
|
||||
this.refresh();
|
||||
},
|
||||
refresh: function() {
|
||||
this.$element.html(QWeb.render("ViewManager.sidebar.internal", _.extend({_:_}, this)));
|
||||
var self = this;
|
||||
this.$element.find("a").click(function(e) {
|
||||
$this = jQuery(this);
|
||||
var $this = jQuery(this);
|
||||
var i = $this.attr("data-i");
|
||||
var j = $this.attr("data-i");
|
||||
var j = $this.attr("data-j");
|
||||
var action = self.sections[i].elements[j];
|
||||
// I know this doesn't work, one day it will
|
||||
new openerp.base.ActionManager(this.view_manager, null).do_action(action);
|
||||
(new openerp.base.ExternalActionManager(self.view_manager.session, null)) .handle_action(action);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
@ -305,6 +307,30 @@ openerp.base.Sidebar = openerp.base.BaseWidget.extend({
|
|||
}
|
||||
});
|
||||
|
||||
openerp.base.ExternalActionManager = openerp.base.Controller.extend({
|
||||
handle_action: function(action) {
|
||||
if(action.type=="ir.actions.act_window") {
|
||||
if(action.target=="new") {
|
||||
var element_id = _.uniqueId("act_window_dialog");
|
||||
var dialog = $('<div id="'+element_id+'"></div>');
|
||||
dialog.dialog({
|
||||
title: action.name
|
||||
});
|
||||
var viewmanager = new openerp.base.ViewManagerAction(this.session ,element_id, action, false);
|
||||
viewmanager.start();
|
||||
} else if (action.target == "current") {
|
||||
this.rpc("/base/session/save_session_action", {the_action:action}, function(key) {
|
||||
var url = window.location.href;
|
||||
//window.open();
|
||||
});
|
||||
}
|
||||
}
|
||||
// TODO: show an error like "not implemented" here
|
||||
// since we don't currently have any way to handle errors do you have any better idea
|
||||
// than using todos?
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.views.add('calendar', 'openerp.base.CalendarView');
|
||||
openerp.base.CalendarView = openerp.base.Controller.extend({
|
||||
start: function () {
|
||||
|
|
|
@ -533,8 +533,8 @@
|
|||
<ul>
|
||||
<t t-set="j" t-value="0"/>
|
||||
<t t-foreach="section.elements" t-as="element">
|
||||
<li><a t-att-data-i="i" t-att-data-j="j" href="#"><t t-esc="element.text"/></a></li>
|
||||
<t t-set="j+1" t-value="0"/>
|
||||
<li><a t-att-data-i="i" t-att-data-j="j" href="#"><t t-esc="element.name"/></a></li>
|
||||
<t t-set="j" t-value="j+1"/>
|
||||
</t>
|
||||
</ul>
|
||||
</t>
|
||||
|
|
|
@ -18,6 +18,7 @@ import simplejson
|
|||
|
||||
import nonliterals
|
||||
import xmlrpctimeout
|
||||
import logging
|
||||
|
||||
#-----------------------------------------------------------
|
||||
# Globals
|
||||
|
@ -355,6 +356,8 @@ class JsonRequest(object):
|
|||
}
|
||||
}
|
||||
except Exception:
|
||||
cherrypy.log("An error occured while handling a json request",
|
||||
severity=logging.ERROR, traceback=True)
|
||||
error = {
|
||||
'code': 300,
|
||||
'message': "OpenERP WebClient Error",
|
||||
|
@ -495,3 +498,4 @@ def main(argv):
|
|||
cherrypy.server.subscribe()
|
||||
cherrypy.engine.start()
|
||||
cherrypy.engine.block()
|
||||
|
||||
|
|
Loading…
Reference in New Issue