diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index 1abfaa7c323..a1fcc51818c 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- -import base64 -import glob, os +import base64, glob, os, re from xml.etree import ElementTree from cStringIO import StringIO @@ -55,6 +54,20 @@ class Xml2Json: # OpenERP Web base Controllers #---------------------------------------------------------- +class Database(openerpweb.Controller): + _cp_path = "/base/database" + + @openerpweb.jsonrequest + def get_databases_list(self, req): + proxy = req.session.proxy("db") + dbs = proxy.list() + h = req.httprequest.headers['Host'].split(':')[0] + d = h.split('.')[0] + r = cherrypy.config['openerp.dbfilter'].replace('%h',h).replace('%d',d) + print "h,d",h,d,r + dbs = [i for i in dbs if re.match(r,i)] + return {"db_list": dbs} + class Session(openerpweb.Controller): _cp_path = "/base/session" @@ -103,13 +116,6 @@ class Session(openerpweb.Controller): return req.session.model('ir.ui.view_sc').get_sc(req.session._uid, "ir.ui.menu", req.session.eval_context(req.context)) - @openerpweb.jsonrequest - def get_databases_list(self, req): - proxy = req.session.proxy("db") - dbs = proxy.list() - - return {"db_list": dbs} - @openerpweb.jsonrequest def modules(self, req): return {"modules": [name @@ -230,14 +236,14 @@ class Session(openerpweb.Controller): if not saved_actions: return None return saved_actions["actions"].get(key) - + def eval_context_and_domain(session, context, domain=None): e_context = session.eval_context(context) # should we give the evaluated context as an evaluation context to the domain? e_domain = session.eval_domain(domain or []) return e_context, e_domain - + 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) @@ -301,7 +307,6 @@ def generate_views(action): return action['views'] = [(view_id, view_modes[0])] - 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): @@ -545,7 +550,7 @@ class View(openerpweb.Controller): # todo fme?: check that we should pass the evaluated context here self.process_view(request.session, fvg, context, transform) return fvg - + def process_view(self, session, fvg, context, transform): # depending on how it feels, xmlrpclib.ServerProxy can translate # XML-RPC strings to ``str`` or ``unicode``. ElementTree does not @@ -809,3 +814,5 @@ class Action(openerpweb.Controller): 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) + +# diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index 20f952798e4..84f2747166c 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -930,7 +930,7 @@ openerp.base.Login = openerp.base.Controller.extend({ }, start: function() { var self = this; - this.rpc("/base/session/get_databases_list", {}, function(result) { + this.rpc("/base/database/get_databases_list", {}, function(result) { self.db_list = result.db_list; self.display(); }, function() { diff --git a/addons/base/static/src/js/data.js b/addons/base/static/src/js/data.js index 534fd356f06..a49e6cf901f 100644 --- a/addons/base/static/src/js/data.js +++ b/addons/base/static/src/js/data.js @@ -584,12 +584,12 @@ openerp.base.ReadOnlyDataSetSearch = openerp.base.DataSetSearch.extend({ }, on_create: function(data) {}, write: function (id, data, callback) { - this.on_write(id); + this.on_write(id, data); var to_return = $.Deferred().then(callback); setTimeout(function () {to_return.resolve({"result": true});}, 0); return to_return.promise(); }, - on_write: function(id) {}, + on_write: function(id, data) {}, unlink: function(ids, callback, error_callback) { this.on_unlink(ids); var to_return = $.Deferred().then(callback); diff --git a/addons/base/static/src/js/form.js b/addons/base/static/src/js/form.js index 7faa942c6b0..60511c49c17 100644 --- a/addons/base/static/src/js/form.js +++ b/addons/base/static/src/js/form.js @@ -41,7 +41,10 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV start: function() { //this.log('Starting FormView '+this.model+this.view_id) if (this.embedded_view) { - return $.Deferred().then(this.on_loaded).resolve({fields_view: this.embedded_view}); + var def = $.Deferred().then(this.on_loaded); + var self = this; + setTimeout(function() {def.resolve({fields_view: self.embedded_view});}, 0); + return def.promise(); } else { var context = new openerp.base.CompoundContext(this.dataset.get_context()); if (this.view_manager.action && this.view_manager.action.context) { @@ -611,14 +614,15 @@ openerp.base.form.WidgetFrame = openerp.base.form.Widget.extend({ if (node.attrs.nolabel != '1') { var label = new (this.view.registry.get_object('label')) (this.view, node); label["for"] = widget; - this.add_widget(label); + this.add_widget(label, widget.colspan + 1); } } this.add_widget(widget); }, - add_widget: function(widget) { + add_widget: function(widget, colspan) { + colspan = colspan || widget.colspan; var current_row = this.table[this.table.length - 1]; - if (current_row.length && (this.x + widget.colspan) > this.columns) { + if (current_row.length && (this.x + colspan) > this.columns) { current_row = this.add_row(); } current_row.push(widget); @@ -719,10 +723,7 @@ openerp.base.form.WidgetButton = openerp.base.form.Widget.extend({ this.view.execute_action( this.node.attrs, this.view.dataset, this.session.action_manager, - this.view.datarecord.id, function (result) { - self.log("Button returned", result); - self.view.reload(); - }, function() { + this.view.datarecord.id, function () { self.view.reload(); }); } @@ -1267,13 +1268,10 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({ if (!self.value) { return; } - self.session.action_manager.do_action({ - "res_model": self.field.relation, - "views":[[false,"form"]], - "res_id": self.value[0], - "type":"ir.actions.act_window", - "target":"new", - "context": self.build_context() + var pop = new openerp.base.form.FormOpenPopup(null, self.view.session); + 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 cmenu = this.$menu_btn.contextMenu(this.cm_id, {'leftClickToo': true, @@ -1703,6 +1701,20 @@ openerp.base.form.One2ManyListView = openerp.base.ListView.extend({ }); }); } + }, + do_activate_record: function(index, id) { + var self = this; + var pop = new openerp.base.form.FormOpenPopup(null, self.o2m.view.session); + pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(),{ + auto_write: false, + alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined, + parent_view: self.o2m.view + }); + pop.on_write.add(function(id, data) { + self.o2m.dataset.write(id, data, function(r) { + self.o2m.reload_current_view(); + }); + }); } }); @@ -1788,15 +1800,11 @@ openerp.base.form.Many2ManyListView = openerp.base.ListView.extend({ }); }, do_activate_record: function(index, id) { - this.m2m_field.view.session.action_manager.do_action({ - "res_model": this.dataset.model, - "views": [[false,"form"]], - "res_id": id, - "type": "ir.actions.act_window", - "view_type": "form", - "view_mode": "form", - "target": "new", - "context": this.m2m_field.build_context() + var self = this; + var pop = new openerp.base.form.FormOpenPopup(null, this.m2m_field.view.session); + pop.show_element(this.dataset.model, id, this.m2m_field.build_context(), {}); + pop.on_write_completed.add_last(function() { + self.reload_content(); }); } }); @@ -1885,7 +1893,7 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({ return; var self = this; var wdataset = new openerp.base.DataSetSearch(this.session, this.model, this.context, this.domain); - wdataset = this.options.parent_view; + wdataset.parent_view = this.options.parent_view; wdataset.create(data, function(r) { self.on_select_elements([r.result]); }); @@ -1945,6 +1953,72 @@ openerp.base.form.SelectCreateListView = openerp.base.ListView.extend({ } }); +openerp.base.form.FormOpenPopup = openerp.base.BaseWidget.extend({ + identifier_prefix: "formopenpopup", + template: "FormOpenPopup", + /** + * options: + * - alternative_form_view + * - auto_write (default true) + * - parent_view + */ + show_element: function(model, row_id, context, options) { + this.model = model; + this.row_id = row_id; + this.context = context || {}; + this.options = _.defaults(options || {}, {"auto_write": true}); + jQuery(this.render()).dialog({title: '', + modal: true, + width: 960, + height: 600}); + this.start(); + }, + start: function() { + this._super(); + this.dataset = new openerp.base.ReadOnlyDataSetSearch(this.session, this.model, + this.context); + this.dataset.ids = [this.row_id]; + this.dataset.index = 0; + this.dataset.parent_view = this.options.parent_view; + this.setup_form_view(); + }, + on_write: function(id, data) { + this.stop(); + if (!this.options.auto_write) + return; + var self = this; + var wdataset = new openerp.base.DataSetSearch(this.session, this.model, this.context, this.domain); + wdataset.parent_view = this.options.parent_view; + wdataset.write(id, data, function(r) { + self.on_write_completed(); + }); + }, + on_write_completed: function() {}, + setup_form_view: function() { + var self = this; + this.view_form = new openerp.base.FormView(null, this.session, + this.element_id + "_view_form", this.dataset, false); + if (this.options.alternative_form_view) { + this.view_form.set_embedded_view(this.options.alternative_form_view); + } + this.view_form.start(); + this.view_form.on_loaded.add_last(function() { + var $buttons = self.view_form.$element.find(".oe_form_buttons"); + $buttons.html(QWeb.render("FormOpenPopup.form.buttons")); + var $nbutton = $buttons.find(".oe_formopenpopup-form-save"); + $nbutton.click(function() { + self.view_form.do_save(); + }); + var $cbutton = $buttons.find(".oe_formopenpopup-form-close"); + $cbutton.click(function() { + self.stop(); + }); + self.view_form.do_show(); + }); + this.dataset.on_write.add(this.on_write); + } +}); + openerp.base.form.FieldReference = openerp.base.form.Field.extend({ init: function(view, node) { this._super(view, node); diff --git a/addons/base/static/src/js/list.js b/addons/base/static/src/js/list.js index c1df8857f08..7922f690784 100644 --- a/addons/base/static/src/js/list.js +++ b/addons/base/static/src/js/list.js @@ -453,13 +453,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi return field.name === name; }); if (!action) { return; } - this.execute_action( - action, this.dataset, this.session.action_manager, - id, function () { - if (callback) { - callback(); - } - }); + this.execute_action(action, this.dataset, this.session.action_manager, id, callback); }, /** * Handles the activation of a record (clicking on it) diff --git a/addons/base/static/src/js/views.js b/addons/base/static/src/js/views.js index 7f80046e645..5efe27c7e21 100644 --- a/addons/base/static/src/js/views.js +++ b/addons/base/static/src/js/views.js @@ -29,17 +29,6 @@ openerp.base.ActionManager = openerp.base.Controller.extend({ pager : action.target != 'new' }, action.flags || {}); // instantiate the right controllers by understanding the action - if (this.current_dialog) { - this.current_dialog.stop(); - this.current_dialog = null; - } - if (this.current_dialog) { - this.current_dialog.stop(); - this.current_dialog = null; - } else if (this.view_manager && this.view_manager.current_dialog) { - this.view_manager.current_dialog.stop(); - this.view_manager.current_dialog = null; - } switch (action.type) { case 'ir.actions.act_window': if (!action.target && this.current_dialog) { @@ -51,14 +40,11 @@ openerp.base.ActionManager = openerp.base.Controller.extend({ width: '50%' }); if (on_closed) { - dialog.on_closed.add_first(on_closed); + dialog.close_callback = on_closed; } dialog.start(false); - var viewmanager = new openerp.base.ViewManagerAction(this.session, dialog.element_id, action); + var viewmanager = dialog.viewmanager = new openerp.base.ViewManagerAction(this.session, dialog.element_id, action); viewmanager.start(); - // TODO: merge ActionManager & ViewManager in order to get rid of this circular reference - viewmanager.current_dialog = dialog; - dialog.viewmanager = viewmanager; dialog.open(); } else if (action.flags.new_window) { action.flags.new_window = false; @@ -76,6 +62,7 @@ openerp.base.ActionManager = openerp.base.Controller.extend({ } break; case 'ir.actions.act_window_close': + this.close_dialog(); break; case 'ir.actions.server': this.rpc('/base/action/run', { @@ -88,6 +75,12 @@ openerp.base.ActionManager = openerp.base.Controller.extend({ default: console.log("Action manager can't handle action of type " + action.type, action); } + }, + close_dialog: function() { + if (this.current_dialog) { + this.current_dialog.stop(); + this.current_dialog = null; + } } }); @@ -354,14 +347,11 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({ openerp.base.ActionDialog = openerp.base.Dialog.extend({ identifier_prefix: 'action_dialog', - close: function() { - this._super(this, arguments); - this.on_closed(); - }, - on_closed: function() { - }, stop: function() { this._super(this, arguments); + if (this.close_callback) { + this.close_callback(); + } if (this.viewmanager) { this.viewmanager.stop(); } @@ -456,11 +446,15 @@ openerp.base.View = openerp.base.Controller.extend({ * @param {openerp.base.DataSet} dataset a dataset object used to communicate with the server * @param {openerp.base.ActionManager} action_manager object able to actually execute the action, if any is fetched * @param {Object} [record_id] the identifier of the object on which the action is to be applied - * @param {Function} on_no_action callback to execute if the action does not generate any result (no new action) + * @param {Function} on_closed callback to execute when dialog is closed or when the action does not generate any result (no new action) */ - execute_action: function (action_data, dataset, action_manager, record_id, on_no_action, on_closed) { + execute_action: function (action_data, dataset, action_manager, record_id, on_closed) { var self = this; + if (action_manager.current_dialog) { + on_closed = action_manager.current_dialog.close_callback; + } var handler = function (r) { + action_manager.close_dialog(); var action = r.result; if (action && action.constructor == Object) { action.context = action.context || {}; @@ -473,20 +467,12 @@ openerp.base.View = openerp.base.Controller.extend({ new_window: true }; action_manager.do_action(action, on_closed); - } else { - on_no_action(action); + } else if (on_closed) { + on_closed(action); } }; - if (action_data.special) { - if (action_manager.current_dialog) { - action_manager.current_dialog.stop(); - action_manager.current_dialog = null; - } else if (this.view_manager.current_dialog) { - this.view_manager.current_dialog.stop(); - this.view_manager.current_dialog = null; - } - } else { + if (!action_data.special) { var context = new openerp.base.CompoundContext(dataset.get_context(), action_data.context || {}); switch(action_data.type) { case 'object': @@ -496,6 +482,8 @@ openerp.base.View = openerp.base.Controller.extend({ default: return dataset.exec_workflow(record_id, action_data.name, handler); } + } else { + action_manager.close_dialog(); } }, /** diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml index 6d075e6972a..603c75cdb74 100644 --- a/addons/base/static/src/xml/base.xml +++ b/addons/base/static/src/xml/base.xml @@ -908,7 +908,15 @@ - + +
+
+
+
+ + + + $(document.createElement('t')) diff --git a/addons/base_dashboard/static/src/js/dashboard.js b/addons/base_dashboard/static/src/js/dashboard.js index fe52f1affd9..1c30b1541ed 100644 --- a/addons/base_dashboard/static/src/js/dashboard.js +++ b/addons/base_dashboard/static/src/js/dashboard.js @@ -71,7 +71,6 @@ openerp.base.form.DashBoard = openerp.base.form.Widget.extend({ // TODO: create a Dialog controller which optionally takes an action // Should set width & height automatically and take buttons & views callback var dialog_id = _.uniqueId('act_window_dialog'); - var action_manager = new openerp.base.ActionManager(this.session, dialog_id); var $dialog = $('
').dialog({ modal : true, title : 'Actions', @@ -87,8 +86,7 @@ openerp.base.form.DashBoard = openerp.base.form.Widget.extend({ } } }); - action_manager.start(); - action_manager.do_action(action); + new openerp.base.ViewManagerAction(this.session, dialog_id, action).start(); // TODO: should bind ListView#select_record in order to catch record clicking }, do_add_widget : function(action_manager) { @@ -226,9 +224,8 @@ openerp.base.form.DashBoard = openerp.base.form.Widget.extend({ action_buttons : false, pager: false }; - new openerp.base.ActionManager( - this.session, this.view.element_id + '_action_' + action.id) - .do_action(action); + new openerp.base.ViewManagerAction(this.session, + this.view.element_id + '_action_' + action.id, action).start(); }, render: function() { // We should start with three columns available diff --git a/addons/base_graph/static/src/js/graph.js b/addons/base_graph/static/src/js/graph.js index 6f1e3a89253..fdf3585449c 100644 --- a/addons/base_graph/static/src/js/graph.js +++ b/addons/base_graph/static/src/js/graph.js @@ -434,9 +434,7 @@ openerp.base_graph.GraphView = openerp.base.View.extend({ } views.push(view); }); - this.actionmanager = new openerp.base.ActionManager(this.session, "oe_app"); - this.actionmanager.start(); - this.actionmanager.do_action({ + this.session.action_manager.do_action({ "res_model" : this.dataset.model, "domain" : this.dataset.domain, "views" : views, diff --git a/openerpweb/openerpweb.py b/openerpweb/openerpweb.py index f567cf1b812..ee75ac0b1f9 100644 --- a/openerpweb/openerpweb.py +++ b/openerpweb/openerpweb.py @@ -270,6 +270,9 @@ class JsonRequest(object): self.request = request self.params = request.get("params", {}) self.applicationsession = applicationsession + self.httprequest = cherrypy.request + self.httpresponse = cherrypy.response + self.httpsession = cherrypy.session self.httpsession_id = "cookieid" self.httpsession = cherrypy.session self.session_id = self.params.pop("session_id", None) or uuid.uuid4().hex @@ -454,22 +457,19 @@ def main(argv): os.environ["TZ"] = "UTC" DEFAULT_CONFIG = { - 'openerp.server.host': '127.0.0.1', - 'openerp.server.port': 8069, - 'server.socket_port': 8002, 'server.socket_host': '0.0.0.0', 'tools.sessions.on': True, 'tools.sessions.storage_type': 'file', - 'tools.sessions.storage_path': os.path.join(tempfile.gettempdir(), "cpsessions"), 'tools.sessions.timeout': 60 } # Parse config op = optparse.OptionParser() - op.add_option("-p", "--port", dest="server.socket_port", help="listening port", type="int", metavar="NUMBER") - op.add_option("-s", "--session-path", dest="tools.sessions.storage_path", help="directory used for session storage", metavar="DIR") - op.add_option("--server-host", dest="openerp.server.host", help="OpenERP server hostname", metavar="HOST") - op.add_option("--server-port", dest="openerp.server.port", help="OpenERP server port", type="int", metavar="NUMBER") + op.add_option("-p", "--port", dest="server.socket_port", default=8002, help="listening port", type="int", metavar="NUMBER") + op.add_option("-s", "--session-path", dest="tools.sessions.storage_path", default=os.path.join(tempfile.gettempdir(), "cpsessions"), help="directory used for session storage", metavar="DIR") + op.add_option("--server-host", dest="openerp.server.host", default='127.0.0.1', help="OpenERP server hostname", metavar="HOST") + op.add_option("--server-port", dest="openerp.server.port", default=8069, help="OpenERP server port", type="int", metavar="NUMBER") + op.add_option("--db-filter", dest="openerp.dbfilter", default='.*', help="Filter listed database", metavar="REGEXP") (o, args) = op.parse_args(argv[1:]) o = vars(o) for k in o.keys(): @@ -480,8 +480,8 @@ def main(argv): cherrypy.tree.mount(Root()) cherrypy.config.update(config=DEFAULT_CONFIG) - if os.path.exists(os.path.join(os.path.dirname( os.path.dirname(__file__)),'openerp-web.cfg')): - cherrypy.config.update(os.path.join(os.path.dirname( os.path.dirname(__file__)),'openerp-web.cfg')) + if os.path.exists(os.path.join(path_root,'openerp-web.cfg')): + cherrypy.config.update(os.path.join(path_root,'openerp-web.cfg')) if os.path.exists(os.path.expanduser('~/.openerp_webrc')): cherrypy.config.update(os.path.expanduser('~/.openerp_webrc')) cherrypy.config.update(o)