diff --git a/.bzrignore b/.bzrignore index b83a43bf1d4..7ae985ce4df 100644 --- a/.bzrignore +++ b/.bzrignore @@ -9,3 +9,4 @@ RE:^include/ RE:^share/ RE:^man/ RE:^lib/ +logging.cfg diff --git a/addons/web/__init__.py b/addons/web/__init__.py index bcb8f6db28c..2478edb81b7 100644 --- a/addons/web/__init__.py +++ b/addons/web/__init__.py @@ -5,8 +5,7 @@ import logging _logger = logging.getLogger(__name__) - -try: +def wsgi_postload(): import openerp.wsgi import os import tempfile @@ -24,9 +23,6 @@ try: #import openerp.wsgi openerp.wsgi.register_wsgi_handler(app) -except ImportError: - _logger.info("standalone mode") - # TODO # if we detect that we are imported from the openerp server register common.Root() as a wsgi entry point diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py index 9a1fd119fb9..74633fa4969 100644 --- a/addons/web/__openerp__.py +++ b/addons/web/__openerp__.py @@ -45,5 +45,5 @@ "static/src/css/base.css", "static/src/css/data_export.css", ], - 'wsgi' : 'app', + 'post_load' : 'wsgi_postload', } diff --git a/addons/web/common/session.py b/addons/web/common/session.py index 3691f88e3f5..d1997a3f903 100644 --- a/addons/web/common/session.py +++ b/addons/web/common/session.py @@ -43,30 +43,30 @@ class OpenERPSession(object): def build_connection(self): return openerplib.get_connection(hostname=self._server, port=self._port, - database=self._db, + database=self._db, login=self._login, user_id=self._uid, password=self._password) def proxy(self, service): return self.build_connection().get_service(service) - def bind(self, db, uid, password): + def bind(self, db, uid, login, password): self._db = db self._uid = uid + self._login = login self._password = password def login(self, db, login, password): uid = self.proxy('common').login(db, login, password) - self.bind(db, uid, password) - self._login = login + self.bind(db, uid, login, password) if uid: self.get_context() return uid - def assert_valid(self): + def assert_valid(self, force=False): """ Ensures this session is valid (logged into the openerp server) """ - self.build_connection().check_login(False) + self.build_connection().check_login(force) def execute(self, model, func, *l, **d): self.assert_valid() diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 6ce4bd612f2..d0c8950f9e1 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -301,6 +301,7 @@ class Session(openerpweb.Controller): } @openerpweb.jsonrequest def get_session_info(self, req): + req.session.assert_valid(force=True) return { "uid": req.session._uid, "context": req.session.get_context() if req.session._uid else False, diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 6462529d0c9..a33fca458d0 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -501,6 +501,8 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web self.on_session_valid(); else self.on_session_invalid(); + }, function() { + self.on_session_invalid(); }); }, /** @@ -741,6 +743,59 @@ openerp.web.SessionAware = openerp.web.CallbackEnabled.extend(/** @lends openerp } }); +/** + * Base class for all visual components. Provides a lot of functionalities helpful + * for the management of a part of the DOM. + * + * Widget handles: + * - Rendering with QWeb. + * - Life-cycle management and parenting (when a parent is destroyed, all its children are + * destroyed too). + * - Insertion in DOM. + * + * Widget also extends SessionAware for ease of use. + * + * Guide to create implementations of the Widget class: + * ============================================== + * + * Here is a sample child class: + * + * MyWidget = openerp.base.Widget.extend({ + * // the name of the QWeb template to use for rendering + * template: "MyQWebTemplate", + * // identifier prefix, it is useful to put an obvious one for debugging + * identifier_prefix: 'my-id-prefix-', + * + * init: function(parent) { + * this._super(parent); + * // stuff that you want to init before the rendering + * }, + * start: function() { + * this._super(); + * // stuff you want to make after the rendering, `this.$element` holds a correct value + * this.$element.find(".my_button").click(/* an example of event binding * /); + * + * // if you have some asynchronous operations, it's a good idea to return + * // a promise in start() + * var promise = this.rpc(...); + * return promise; + * } + * }); + * + * Now this class can simply be used with the following syntax: + * + * var my_widget = new MyWidget(this); + * my_widget.appendTo($(".some-div")); + * + * With these two lines, the MyWidget instance was inited, rendered, it was inserted into the + * DOM inside the ".some-div" div and its events were binded. + * + * And of course, when you don't need that widget anymore, just do: + * + * my_widget.stop(); + * + * That will kill the widget in a clean way and erase its content from the dom. + */ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widget# */{ /** * The name of the QWeb template that will be used for rendering. Must be diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index fdaff535fb8..82bfa817ef1 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -26,7 +26,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# this.set_default_options(options); this.dataset = dataset; this.model = dataset.model; - this.view_id = view_id; + this.view_id = view_id || false; this.fields_view = {}; this.widgets = {}; this.widgets_counter = 0; @@ -315,9 +315,15 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# var def = $.Deferred(); $.when(this.has_been_loaded).then(function() { if (self.can_be_discarded()) { - self.dataset.default_get(_.keys(self.fields_view.fields)).then(self.on_record_loaded).then(function() { + var keys = _.keys(self.fields_view.fields); + if (keys.length) { + self.dataset.default_get(keys).then(self.on_record_loaded).then(function() { + def.resolve(); + }); + } else { + self.on_record_loaded({}); def.resolve(); - }); + } } }); return def.promise(); @@ -373,7 +379,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# first_invalid_field.focus(); this.on_invalid(); return false; - } else if (form_dirty) { + } else { console.log("About to save", values); if (!this.datarecord.id) { return this.dataset.create(values, function(r) { @@ -384,11 +390,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# self.on_saved(r, success); }); } - } else { - setTimeout(function() { - self.on_saved({ result: true }, success); - }); - return true; } }, do_save_edit: function() { @@ -413,7 +414,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# if (!r.result) { // should not happen in the server, but may happen for internal purpose } else { - console.debug(_.sprintf("The record #%s has been saved.", this.datarecord.id)); if (success) { success(r); } @@ -986,7 +986,7 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f return !this.invalid; }, is_dirty: function() { - return this.dirty; + return this.dirty && !this.readonly; }, get_on_change_value: function() { return this.get_value(); @@ -2551,7 +2551,7 @@ openerp.web.form.FieldBinaryImage = openerp.web.form.FieldBinary.extend({ }); openerp.web.form.FieldStatus = openerp.web.form.Field.extend({ - template: "FieldStatus", + template: "EmptyComponent", start: function() { this._super(); this.selected_value = null; diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index ad2e2131884..88db848118f 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -133,11 +133,19 @@ db.web.ActionManager = db.web.Widget.extend({ (this.client_widget = new ClientWidget(this, action.params)).appendTo(this); }, ir_actions_report_xml: function(action) { + var self = this; $.blockUI(); - this.session.get_file({ - url: '/web/report', - data: {action: JSON.stringify(action)}, - complete: $.unblockUI + self.rpc("/web/session/eval_domain_and_context", { + contexts: [action.context], + domains: [] + }).then(function(res) { + action = _.clone(action); + action.context = res.context; + self.session.get_file({ + url: '/web/report', + data: {action: JSON.stringify(action)}, + complete: $.unblockUI + }); }); } }); diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 73ef6ba7cf3..45b2800ea97 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -342,22 +342,12 @@
  • -
  • - +
  • - +
  • -
    LOGOUT @@ -1428,9 +1418,6 @@

    - -
    -