diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py
index 92987ffa639..96782c1cec4 100644
--- a/addons/base/controllers/main.py
+++ b/addons/base/controllers/main.py
@@ -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"
diff --git a/addons/base/static/src/base.html b/addons/base/static/src/base.html
index f8c700946f3..3c8f76a6e23 100644
--- a/addons/base/static/src/base.html
+++ b/addons/base/static/src/base.html
@@ -3,7 +3,7 @@
OpenERP
-
+
diff --git a/addons/base/static/src/js/data.js b/addons/base/static/src/js/data.js
index 1e96dde23fc..8f5d6168e75 100644
--- a/addons/base/static/src/js/data.js
+++ b/addons/base/static/src/js/data.js
@@ -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# */{
diff --git a/addons/base/static/src/js/form.js b/addons/base/static/src/js/form.js
index ff04f55314b..bf42fc4fd7f 100644
--- a/addons/base/static/src/js/form.js
+++ b/addons/base/static/src/js/form.js
@@ -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({
diff --git a/addons/base/static/src/js/list.js b/addons/base/static/src/js/list.js
index 533ff0d9deb..4b1eeaaf993 100644
--- a/addons/base/static/src/js/list.js
+++ b/addons/base/static/src/js/list.js
@@ -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,
diff --git a/addons/base/static/src/js/views.js b/addons/base/static/src/js/views.js
index 6adc0fc3d38..747a35dedbc 100644
--- a/addons/base/static/src/js/views.js
+++ b/addons/base/static/src/js/views.js
@@ -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 = $('');
+ 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 () {
diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml
index f93a38c96fc..caf463cf4e0 100644
--- a/addons/base/static/src/xml/base.xml
+++ b/addons/base/static/src/xml/base.xml
@@ -533,8 +533,8 @@
diff --git a/openerpweb/openerpweb.py b/openerpweb/openerpweb.py
index 69ae2f43108..6a4d4146280 100644
--- a/openerpweb/openerpweb.py
+++ b/openerpweb/openerpweb.py
@@ -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()
+