diff --git a/addons/base/static/src/css/base.css b/addons/base/static/src/css/base.css index bbf8cba0fe7..b173386e234 100644 --- a/addons/base/static/src/css/base.css +++ b/addons/base/static/src/css/base.css @@ -30,6 +30,9 @@ body.openerp { .openerp .oe-number { text-align: right !important; } +.openerp .oe_hide { + display: none !important; +} /* STATES */ .openerp .on_logged { diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index 996642385ef..41a17d37d94 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -137,7 +137,7 @@ openerp.base.Registry = openerp.base.Class.extend( /** @lends openerp.base.Regis }); -openerp.base.Session = openerp.base.Controller.extend( /** @lends openerp.base.Session# */{ +openerp.base.Session = openerp.base.Widget.extend( /** @lends openerp.base.Session# */{ /** * @constructs * @param element_id to use for exception reporting @@ -405,7 +405,7 @@ openerp.base.Session = openerp.base.Controller.extend( /** @lends openerp.base.S } }); -openerp.base.Notification = openerp.base.Controller.extend({ +openerp.base.Notification = openerp.base.Widget.extend({ init: function(parent, element_id) { this._super(parent, element_id); this.$element.notify({ @@ -427,7 +427,7 @@ openerp.base.Notification = openerp.base.Controller.extend({ } }); -openerp.base.Dialog = openerp.base.BaseWidget.extend({ +openerp.base.Dialog = openerp.base.OldWidget.extend({ dialog_title: "", identifier_prefix: 'dialog', init: function (parent, options) { @@ -557,7 +557,7 @@ openerp.base.CrashManager = openerp.base.Dialog.extend({ } }); -openerp.base.Loading = openerp.base.Controller.extend({ +openerp.base.Loading = openerp.base.Widget.extend({ init: function(parent, element_id) { this._super(parent, element_id); this.count = 0; @@ -576,10 +576,10 @@ openerp.base.Loading = openerp.base.Controller.extend({ } }); -openerp.base.Database = openerp.base.Controller.extend({ +openerp.base.Database = openerp.base.Widget.extend({ }); -openerp.base.Login = openerp.base.Controller.extend({ +openerp.base.Login = openerp.base.Widget.extend({ remember_creditentials: true, init: function(parent, element_id) { this._super(parent, element_id); @@ -657,7 +657,7 @@ openerp.base.Login = openerp.base.Controller.extend({ } }); -openerp.base.Header = openerp.base.Controller.extend({ +openerp.base.Header = openerp.base.Widget.extend({ init: function(parent, element_id) { this._super(parent, element_id); }, @@ -671,7 +671,7 @@ openerp.base.Header = openerp.base.Controller.extend({ on_logout: function() {} }); -openerp.base.Menu = openerp.base.Controller.extend({ +openerp.base.Menu = openerp.base.Widget.extend({ init: function(parent, element_id, secondary_menu_id) { this._super(parent, element_id); this.secondary_menu_id = secondary_menu_id; @@ -752,16 +752,16 @@ openerp.base.Menu = openerp.base.Controller.extend({ } }); -openerp.base.Homepage = openerp.base.Controller.extend({ +openerp.base.Homepage = openerp.base.Widget.extend({ }); -openerp.base.Preferences = openerp.base.Controller.extend({ +openerp.base.Preferences = openerp.base.Widget.extend({ }); -openerp.base.ImportExport = openerp.base.Controller.extend({ +openerp.base.ImportExport = openerp.base.Widget.extend({ }); -openerp.base.WebClient = openerp.base.Controller.extend({ +openerp.base.WebClient = openerp.base.Widget.extend({ init: function(element_id) { this._super(null, element_id); @@ -778,7 +778,7 @@ openerp.base.WebClient = openerp.base.Controller.extend({ this.crashmanager.start(false); // Do you autorize this ? will be replaced by notify() in controller - openerp.base.Controller.prototype.notification = new openerp.base.Notification(this, "oe_notification"); + openerp.base.Widget.prototype.notification = new openerp.base.Notification(this, "oe_notification"); this.header = new openerp.base.Header(this, "oe_header"); this.login = new openerp.base.Login(this, "oe_login"); diff --git a/addons/base/static/src/js/controller.js b/addons/base/static/src/js/controller.js index 1a13ab18607..2ed00f29ff9 100644 --- a/addons/base/static/src/js/controller.js +++ b/addons/base/static/src/js/controller.js @@ -140,7 +140,7 @@ instance.base.generate_null_object_class = function(claz, add) { copy_proto(prototype.prototype); }; copy_proto(claz.prototype); - newer.init = instance.base.Controller.prototype.init; + newer.init = instance.base.Widget.prototype.init; var tmpclass = claz.extend(newer); return tmpclass.extend(add || {}); }; @@ -148,44 +148,118 @@ instance.base.generate_null_object_class = function(claz, add) { // -------------------------------------------------------- // OLD // -------------------------------------------------------- - /** - * OpenERP Controller - * TODO merge BaseWidget with Controller + * Class for OpenERP session aware classes to extend. Also provides callback mechanism and logging + * facility. */ -instance.base.Controller = instance.base.Class.extend( /** @lends instance.base.Controller# */{ +instance.base.SessionAware = instance.base.Class.extend({ + init: function(session) { + this.session = session; + + // Transform on_* method into openerp.base.callbacks + for (var name in this) { + if(typeof(this[name]) == "function") { + this[name].debug_name = name; + // bind ALL function to this not only on_and _do ? + if((/^on_|^do_/).test(name)) { + this[name] = instance.base.callback(this, this[name]); + } + } + } + }, + /** + * Performs a JSON-RPC call + * + * @param {String} url endpoint url + * @param {Object} data RPC parameters + * @param {Function} success RPC call success callback + * @param {Function} error RPC call error callback + * @returns {jQuery.Deferred} deferred object for the RPC call + */ + rpc: function(url, data, success, error) { + return this.session.rpc(url, data, success, error); + }, + log: function() { + var args = Array.prototype.slice.call(arguments); + var caller = arguments.callee.caller; + // TODO add support for line number using + // https://github.com/emwendelin/javascript-stacktrace/blob/master/stacktrace.js + // args.unshift("" + caller.debug_name); + this.on_log.apply(this,args); + }, + on_log: function() { + if(window.openerp.debug || (window.location.search.indexOf('?debug') !== -1)) { + var notify = false; + var body = false; + if(window.console) { + console.log(arguments); + } else { + body = true; + } + var a = Array.prototype.slice.call(arguments, 0); + for(var i = 0; i < a.length; i++) { + var v = a[i]==null ? "null" : a[i].toString(); + if(i==0) { + notify = v.match(/^not/); + body = v.match(/^bod/); + } + if(body) { + $('
').text(v).appendTo($('body'));
+                }
+                if(notify && this.notification) {
+                    this.notification.notify("Logging:",v);
+                }
+            }
+        }
+    }
+});
+
+instance.base.Widget = instance.base.SessionAware.extend({
+    /**
+     * The name of the QWeb template that will be used for rendering. Must be
+     * redefined in subclasses or the default render() method can not be used.
+     * 
+     * @type string
+     */
+    template: null,
+    /**
+     * The prefix used to generate an id automatically. Should be redefined in
+     * subclasses. If it is not defined, a generic identifier will be used.
+     * 
+     * @type string
+     */
+    identifier_prefix: 'generic-identifier',
     /**
      * @constructs
      * rpc operations, event binding and callback calling should be done in
      * start() instead of init so that events can be hooked in between.
      */
     init: function(parent, element_id) {
+        this._super((parent || {}).session);
+        //TODO niv: get away the possibility to specify an id
         this.element_id = element_id;
+        this.element_id = this.element_id || _.uniqueId(this.identifier_prefix);
+        
         this.$element = $('#' + element_id);
         if (element_id) {
             instance.screen[element_id] = this;
         }
         // save the parent children relationship
-        this.controller_parent = parent;
-        this.controller_children = [];
-        if(parent && parent.controller_children) {
-            parent.controller_children.push(this);
-        }
-        // backward compatibility
-        this.parent = this.controller_parent;
-        this.children = this.controller_children;
-
-        // Transform on_* method into openerp.base.callbacks
-        for (var name in this) {
-            if(typeof(this[name]) == "function") {
-                this[name].debug_name = name;
-                // bind ALL function to this not only on_and _do ?
-                if((/^on_|^do_/).test(name)) {
-                    this[name] = instance.base.callback(this, this[name]);
-                }
-            }
+        this.widget_parent = parent;
+        this.widget_children = [];
+        if(parent && parent.widget_children) {
+            parent.widget_children.push(this);
         }
     },
+    /**
+     * Render the widget. This.template must be defined.
+     * The content of the current object is passed as context to the template.
+     * 
+     * @param {object} additional Additional context arguments to pass to the template.
+     */
+    render: function (additional) {
+        return QWeb.render(this.template, _.extend({widget: this}, additional || {}));
+    },
     /**
      * Event binding, rpc and callback calling required to initialize the
      * object should happen here
@@ -196,354 +270,36 @@ instance.base.Controller = instance.base.Class.extend( /** @lends instance.base.
      * @returns {jQuery.Deferred}
      */
     start: function() {
-        // returns an already fulfilled promise. Maybe we could return nothing?
-        // $.when can take non-deferred and in that case it simply considers
-        // them all as fulfilled promises.
-        // But in thise case we *have* to ensure callers use $.when and don't
-        // try to call deferred methods on this return value.
+        var tmp = document.getElementById(this.element_id);
+        this.$element = tmp ? $(tmp) : null;
         return $.Deferred().done().promise();
     },
     stop: function() {
-        if (this.parent && this.parent.children) {
-            this.parent.children = _.without(this.parent.children, this);
-            this.parent.controller_children = this.parent.children;
-        }
-        this.parent = null;
-        this.controller_parent = null;
-    },
-    log: function() {
-        var args = Array.prototype.slice.call(arguments);
-        var caller = arguments.callee.caller;
-        // TODO add support for line number using
-        // https://github.com/emwendelin/javascript-stacktrace/blob/master/stacktrace.js
-        // args.unshift("" + caller.debug_name);
-        this.on_log.apply(this,args);
-    },
-    on_log: function() {
-        if(window.openerp.debug || (window.location.search.indexOf('?debug') !== -1)) {
-            var notify = false;
-            var body = false;
-            if(window.console) {
-                console.log(arguments);
-            } else {
-                body = true;
-            }
-            var a = Array.prototype.slice.call(arguments, 0);
-            for(var i = 0; i < a.length; i++) {
-                var v = a[i]==null ? "null" : a[i].toString();
-                if(i==0) {
-                    notify = v.match(/^not/);
-                    body = v.match(/^bod/);
-                }
-                if(body) {
-                    $('
').text(v).appendTo($('body'));
-                }
-                if(notify && this.notification) {
-                    this.notification.notify("Logging:",v);
-                }
-            }
-        }
-
-    }
-});
-
-/**
- * OpenERP session aware controller
- * a controller takes an already existing dom element and manage it
- */
-instance.base.Controller = instance.base.Controller.extend( /** @lends openerp.base.Controller# */{
-    init: function(parent, element_id) {
-        this._super(parent, element_id);
-        if(this.controller_parent && this.controller_parent.session) {
-            this.session = this.controller_parent.session;
-        }
-    },
-    /**
-     * Performs a JSON-RPC call
-     *
-     * @param {String} url endpoint url
-     * @param {Object} data RPC parameters
-     * @param {Function} success RPC call success callback
-     * @param {Function} error RPC call error callback
-     * @returns {jQuery.Deferred} deferred object for the RPC call
-     */
-    rpc: function(url, data, success, error) {
-        return this.session.rpc(url, data, success, error);
-    },
-    do_action: function(action, on_finished) {
-        return this.parent.do_action(action, on_finished);
-    }
-});
-
-/**
- * OpenERP session aware widget
- * A widget is a controller that doesnt take an element_id
- * it render its own html render() that you should insert into the dom
- * and bind it at start()
- */
-instance.base.BaseWidget = instance.base.Controller.extend({
-    /**
-     * 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 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.
-     * Also initialize the identifier.
-     *
-     * @constructs
-     * @params {openerp.base.search.BaseWidget} parent The parent widget.
-     */
-    init: function (parent) {
-        this._super(parent);
-        this.make_id(this.identifier_prefix);
-    },
-    /**
-     * Sets and returns a globally unique identifier for the widget.
-     *
-     * If a prefix is appended, the identifier will be appended to it.
-     *
-     * @params sections prefix sections, empty/falsy sections will be removed
-     */
-    make_id: function () {
-        this.element_id = _.uniqueId(_.toArray(arguments).join('_'));
-        return this.element_id;
-    },
-    /**
-     * Render the widget. This.template must be defined.
-     * The content of the current object is passed as context to the template.
-     * 
-     * @param {object} additional Additional context arguments to pass to the template.
-     */
-    render: function (additional) {
-        return QWeb.render(this.template, _.extend({}, this, additional != null ? additional : {}));
-    },
-    /**
-     * "Starts" the widgets. Called at the end of the rendering, this allows
-     * to get a jQuery object referring to the DOM ($element attribute).
-     */
-    start: function () {
-        this._super();
-        var tmp = document.getElementById(this.element_id);
-        this.$element = tmp ? $(tmp) : null;
-    },
-    /**
-     * "Stops" the widgets. Called when the view destroys itself, this
-     * lets the widgets clean up after themselves.
-     */
-    stop: function () {
+        _.each(_.clone(this.widget_children), function(el) {
+            el.stop();
+        });
         if(this.$element != null) {
             this.$element.remove();
         }
-        this._super();
-    }
-});
-
-// --------------------------------------------------------
-// N-style aka New-Style or Niv-Style
-// --------------------------------------------------------
-
-instance.base.NivController = instance.base.Class.extend({
-    init: function(parent) {
-        this.controller_parent = parent;
-        // Take the session of the parent if defined
-        if(this.controller_parent && this.controller_parent.session) {
-            this.session = this.controller_parent.session;
+        if (this.widget_parent && this.widget_parent.widget_children) {
+            this.widget_parent.widget_children = _.without(this.widget_parent.widget_children, this);
         }
-        // Transform on_* method into openerp.base.callbacks
-        for (var name in this) {
-            if(typeof(this[name]) == "function") {
-                this[name].debug_name = name;
-                // bind ALL function to this not only on_and _do ?
-                if((/^on_|^do_/).test(name)) {
-                    this[name] = instance.base.callback(this, this[name]);
-                }
-            }
-        }
-    },
-    /**
-     * Event binding, rpc and callback calling required to initialize the
-     * object should happen here
-     *
-     * Returns a promise object letting callers (subclasses and direct callers)
-     * know when this component is done starting
-     *
-     * @returns {jQuery.Deferred}
-     */
-    start: function() {
-        // returns an already fulfilled promise. Maybe we could return nothing?
-        // $.when can take non-deferred and in that case it simply considers
-        // them all as fulfilled promises.
-        // But in thise case we *have* to ensure callers use $.when and don't
-        // try to call deferred methods on this return value.
-        return $.Deferred().done().promise();
-    },
-    stop: function() {
-    },
-    log: function() {
-        var args = Array.prototype.slice.call(arguments);
-        var caller = arguments.callee.caller;
-        // TODO add support for line number using
-        // https://github.com/emwendelin/javascript-stacktrace/blob/master/stacktrace.js
-        // args.unshift("" + caller.debug_name);
-        this.on_log.apply(this,args);
-    },
-    on_log: function() {
-        if(window.openerp.debug || (window.location.search.indexOf('?debug') !== -1)) {
-            var notify = false;
-            var body = false;
-            if(window.console) {
-                console.log(arguments);
-            } else {
-                body = true;
-            }
-            var a = Array.prototype.slice.call(arguments, 0);
-            for(var i = 0; i < a.length; i++) {
-                var v = a[i]==null ? "null" : a[i].toString();
-                if(i==0) {
-                    notify = v.match(/^not/);
-                    body = v.match(/^bod/);
-                }
-                if(body) {
-                    $('
').text(v).appendTo($('body'));
-                }
-                if(notify && this.notification) {
-                    this.notification.notify("Logging:",v);
-                }
-            }
-        }
-
-    },
-    /**
-     * Performs a JSON-RPC call
-     *
-     * @param {String} url endpoint url
-     * @param {Object} data RPC parameters
-     * @param {Function} success RPC call success callback
-     * @param {Function} error RPC call error callback
-     * @returns {jQuery.Deferred} deferred object for the RPC call
-     */
-    rpc: function(url, data, success, error) {
-        return this.session.rpc(url, data, success, error);
+        this.widget_parent = null;
     },
     do_action: function(action, on_finished) {
-        return this.controller_parent.do_action(action, on_finished);
+        return this.widget_parent.do_action(action, on_finished);
     }
 });
 
-instance.base.NivWidget = instance.base.Controller.extend({
-    /**
-     * 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 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.
-     * Also initialize the identifier.
-     *
-     * @constructs
-     * @params {openerp.base.search.BaseWidget} parent The parent widget.
-     */
-    init: function(parent, element_id) {
-        this._super(parent);
-        this.make_id(this.identifier_prefix);
-        // this.element_id = element_id;
-        // this.$element = $('#' + element_id);
-        // if (element_id) {
-        //     instance.screen[element_id] = this;
-        // }
-        // save the parent children relationship
-        this.controller_children = [];
-        if(parent && parent.controller_children) {
-            parent.controller_children.push(this);
-        }
-        // backward compatibility
-        this.parent = this.controller_parent;
-        this.children = this.controller_children;
-
-    },
-    /**
-     * Event binding, rpc and callback calling required to initialize the
-     * object should happen here
-     *
-     * Returns a promise object letting callers (subclasses and direct callers)
-     * know when this component is done starting
-     *
-     * @returns {jQuery.Deferred}
-     */
-    /**
-     * "Starts" the widgets. Called at the end of the rendering, this allows
-     * to get a jQuery object referring to the DOM ($element attribute).
-     */
-    start: function () {
-        this._super();
-        var tmp = document.getElementById(this.element_id);
-        this.$element = tmp ? $(tmp) : null;
-    },
-    stop: function() {
-        if(this.$element != null) {
-            this.$element.remove();
-        }
-        if (this.parent && this.parent.children) {
-            this.parent.children = _.without(this.parent.children, this);
-            this.parent.controller_children = this.parent.children;
-        }
-        this.parent = null;
-        this.controller_parent = null;
-    },
-    /**
-     * Sets and returns a globally unique identifier for the widget.
-     *
-     * If a prefix is appended, the identifier will be appended to it.
-     *
-     * @params sections prefix sections, empty/falsy sections will be removed
-     */
-    make_id: function () {
-        this.element_id = _.uniqueId(_.toArray(arguments).join('_'));
-        return this.element_id;
-    },
-    /**
-     * Render the widget. This.template must be defined.
-     * The content of the current object is passed as context to the template.
-     * 
-     * @param {object} additional Additional context arguments to pass to the template.
-     */
+/*
+ * For retro compatibility only, the only difference with is that render takes
+ * directly this instead of 
+ */
+instance.base.OldWidget = instance.base.Widget.extend({
     render: function (additional) {
-        return QWeb.render(this.template, _.extend({}, this, additional != null ? additional : {}));
-    },
-    widget_add: function(element, addfunc) {
-    },
-    widget_append: function(element) {
-    },
-    widget_prepend: function(element) {
-    },
-    widget_append2: function(element) {
-    },
-    widget_prepend2: function(element) {
-    },
+        return QWeb.render(this.template, _.extend(_.extend({}, this), additional || {}));
+    }
 });
 
-
-};
-
+}
 // vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
diff --git a/addons/base/static/src/js/data.js b/addons/base/static/src/js/data.js
index 9eb08cf0fde..5545e32df17 100644
--- a/addons/base/static/src/js/data.js
+++ b/addons/base/static/src/js/data.js
@@ -18,7 +18,7 @@ openerp.base.serialize_sort = function (criterion) {
         }).join(', ');
 };
 
-openerp.base.DataGroup =  openerp.base.Controller.extend( /** @lends openerp.base.DataGroup# */{
+openerp.base.DataGroup =  openerp.base.Widget.extend( /** @lends openerp.base.DataGroup# */{
     /**
      * Management interface between views and grouped collections of OpenERP
      * records.
@@ -30,7 +30,7 @@ openerp.base.DataGroup =  openerp.base.Controller.extend( /** @lends openerp.bas
      * content of the current grouping level.
      *
      * @constructs
-     * @extends openerp.base.Controller
+     * @extends openerp.base.Widget
      *
      * @param {openerp.base.Session} session Current OpenERP session
      * @param {String} model name of the model managed by this DataGroup
@@ -232,13 +232,13 @@ openerp.base.StaticDataGroup = openerp.base.GrouplessDataGroup.extend( /** @lend
     }
 });
 
-openerp.base.DataSet =  openerp.base.Controller.extend( /** @lends openerp.base.DataSet# */{
+openerp.base.DataSet =  openerp.base.Widget.extend( /** @lends openerp.base.DataSet# */{
     /**
      * DateaManagement interface between views and the collection of selected
      * OpenERP records (represents the view's state?)
      *
      * @constructs
-     * @extends openerp.base.Controller
+     * @extends openerp.base.Widget
      *
      * @param {String} model the OpenERP model this dataset will manage
      */
diff --git a/addons/base/static/src/js/form.js b/addons/base/static/src/js/form.js
index 80ef7efe96d..f8e2e91667d 100644
--- a/addons/base/static/src/js/form.js
+++ b/addons/base/static/src/js/form.js
@@ -88,9 +88,10 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormVi
         if (this.options.sidebar && this.options.sidebar_id) {
             this.sidebar = new openerp.base.Sidebar(this, this.options.sidebar_id);
             this.sidebar.start();
-            this.sidebar.attachments = new openerp.base.form.SidebarAttachments(this.sidebar, this.sidebar.add_section("Attachments"), this);
-            this.sidebar.add_toolbar(data.fields_view.toolbar);
             this.sidebar.do_unfold();
+            this.sidebar.attachments = new openerp.base.form.SidebarAttachments(this.sidebar, this.sidebar.add_section('attachments', "Attachments"), this);
+            this.sidebar.add_toolbar(data.fields_view.toolbar);
+            this.set_common_sidebar_sections(this.sidebar);
         }
         this.has_been_loaded.resolve();
     },
@@ -441,7 +442,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormVi
 /** @namespace */
 openerp.base.form = {};
 
-openerp.base.form.SidebarAttachments = openerp.base.Controller.extend({
+openerp.base.form.SidebarAttachments = openerp.base.Widget.extend({
     init: function(parent, element_id, form_view) {
         this._super(parent, element_id);
         this.view = form_view;
@@ -548,7 +549,7 @@ openerp.base.form.compute_domain = function(expr, fields) {
     return _.all(stack);
 };
 
-openerp.base.form.Widget = openerp.base.Controller.extend({
+openerp.base.form.Widget = openerp.base.Widget.extend({
     template: 'Widget',
     init: function(view, node) {
         this.view = view;
@@ -1934,7 +1935,7 @@ openerp.base.form.Many2ManyListView = openerp.base.ListView.extend({
     }
 });
 
-openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
+openerp.base.form.SelectCreatePopup = openerp.base.OldWidget.extend({
     identifier_prefix: "selectcreatepopup",
     template: "SelectCreatePopup",
     /**
@@ -2074,7 +2075,7 @@ openerp.base.form.SelectCreateListView = openerp.base.ListView.extend({
     }
 });
 
-openerp.base.form.FormOpenPopup = openerp.base.BaseWidget.extend({
+openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({
     identifier_prefix: "formopenpopup",
     template: "FormOpenPopup",
     /**
diff --git a/addons/base/static/src/js/list.js b/addons/base/static/src/js/list.js
index 0c595bed22d..d64d83329c0 100644
--- a/addons/base/static/src/js/list.js
+++ b/addons/base/static/src/js/list.js
@@ -271,6 +271,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
             this.sidebar = new openerp.base.Sidebar(this, this.options.sidebar_id);
             this.sidebar.start();
             this.sidebar.add_toolbar(data.fields_view.toolbar);
+            this.set_common_sidebar_sections(this.sidebar);
         }
     },
     /**
diff --git a/addons/base/static/src/js/search.js b/addons/base/static/src/js/search.js
index 8a51abe1335..a63ba79355c 100644
--- a/addons/base/static/src/js/search.js
+++ b/addons/base/static/src/js/search.js
@@ -1,6 +1,6 @@
 openerp.base.search = function(openerp) {
 
-openerp.base.SearchView = openerp.base.Controller.extend({
+openerp.base.SearchView = openerp.base.Widget.extend({
     init: function(parent, element_id, dataset, view_id, defaults) {
         this._super(parent, element_id);
         this.view_manager = parent || new openerp.base.NullViewManager();
@@ -386,13 +386,13 @@ openerp.base.search.Invalid = openerp.base.Class.extend( /** @lends openerp.base
                 ': [' + this.value + '] is ' + this.message);
     }
 });
-openerp.base.search.Widget = openerp.base.Controller.extend( /** @lends openerp.base.search.Widget# */{
+openerp.base.search.Widget = openerp.base.Widget.extend( /** @lends openerp.base.search.Widget# */{
     template: null,
     /**
      * Root class of all search widgets
      *
      * @constructs
-     * @extends openerp.base.Controller
+     * @extends openerp.base.Widget
      *
      * @param view the ancestor view of this widget
      */
@@ -851,7 +851,7 @@ openerp.base.search.ManyToManyField = openerp.base.search.CharField.extend({
     // TODO: .related_columns (Array), .context, .domain
 });
 
-openerp.base.search.ExtendedSearch = openerp.base.BaseWidget.extend({
+openerp.base.search.ExtendedSearch = openerp.base.OldWidget.extend({
     template: 'SearchView.extended_search',
     identifier_prefix: 'extended-search',
     init: function (parent, model) {
@@ -891,7 +891,7 @@ openerp.base.search.ExtendedSearch = openerp.base.BaseWidget.extend({
         if(this.$element.closest("table.oe-searchview-render-line").css("display") == "none") {
             return null;
         }
-        return _.reduce(this.children,
+        return _.reduce(this.widget_children,
             function(mem, x) { return mem.concat(x.get_domain());}, []);
     },
     on_activate: function() {
@@ -910,14 +910,14 @@ openerp.base.search.ExtendedSearch = openerp.base.BaseWidget.extend({
         }
     },
     check_last_element: function() {
-        _.each(this.children, function(x) {x.set_last_group(false);});
-        if (this.children.length >= 1) {
-            this.children[this.children.length - 1].set_last_group(true);
+        _.each(this.widget_children, function(x) {x.set_last_group(false);});
+        if (this.widget_children.length >= 1) {
+            this.widget_children[this.widget_children.length - 1].set_last_group(true);
         }
     }
 });
 
-openerp.base.search.ExtendedSearchGroup = openerp.base.BaseWidget.extend({
+openerp.base.search.ExtendedSearchGroup = openerp.base.OldWidget.extend({
     template: 'SearchView.extended_search.group',
     identifier_prefix: 'extended-search-group',
     init: function (parent, fields) {
@@ -926,7 +926,7 @@ openerp.base.search.ExtendedSearchGroup = openerp.base.BaseWidget.extend({
     },
     add_prop: function() {
         var prop = new openerp.base.search.ExtendedSearchProposition(this, this.fields);
-        var render = prop.render({'index': this.children.length - 1});
+        var render = prop.render({'index': this.widget_children.length - 1});
         this.$element.find('.searchview_extended_propositions_list').append(render);
         prop.start();
     },
@@ -943,7 +943,7 @@ openerp.base.search.ExtendedSearchGroup = openerp.base.BaseWidget.extend({
         });
     },
     get_domain: function() {
-        var props = _(this.children).chain().map(function(x) {
+        var props = _(this.widget_children).chain().map(function(x) {
             return x.get_proposition();
         }).compact().value();
         var choice = this.$element.find(".searchview_extended_group_choice").val();
@@ -953,9 +953,9 @@ openerp.base.search.ExtendedSearchGroup = openerp.base.BaseWidget.extend({
             props);
     },
     stop: function() {
-        var parent = this.parent;
-        if (this.parent.children.length == 1)
-            this.parent.hide();
+        var parent = this.widget_parent;
+        if (this.widget_parent.widget_children.length == 1)
+            this.widget_parent.hide();
         this._super();
         parent.check_last_element();
     },
@@ -967,7 +967,7 @@ openerp.base.search.ExtendedSearchGroup = openerp.base.BaseWidget.extend({
     }
 });
 
-openerp.base.search.ExtendedSearchProposition = openerp.base.BaseWidget.extend({
+openerp.base.search.ExtendedSearchProposition = openerp.base.OldWidget.extend({
     template: 'SearchView.extended_search.proposition',
     identifier_prefix: 'extended-search-proposition',
     init: function (parent, fields) {
@@ -992,9 +992,12 @@ openerp.base.search.ExtendedSearchProposition = openerp.base.BaseWidget.extend({
         });
     },
     stop: function() {
-        if (this.parent.children.length == 1)
-            this.parent.stop();
+        var parent;
+        if (this.widget_parent.widget_children.length == 1)
+            parent = this.widget_parent;
         this._super();
+        if (parent)
+            parent.stop();
     },
     changed: function() {
         var nval = this.$element.find(".searchview_extended_prop_field").val();
@@ -1054,7 +1057,7 @@ openerp.base.search.ExtendedSearchProposition = openerp.base.BaseWidget.extend({
     }
 });
 
-openerp.base.search.ExtendedSearchProposition.Char = openerp.base.BaseWidget.extend({
+openerp.base.search.ExtendedSearchProposition.Char = openerp.base.OldWidget.extend({
     template: 'SearchView.extended_search.proposition.char',
     identifier_prefix: 'extended-search-proposition-char',
     operators: [
@@ -1071,7 +1074,7 @@ openerp.base.search.ExtendedSearchProposition.Char = openerp.base.BaseWidget.ext
         return this.$element.val();
     }
 });
-openerp.base.search.ExtendedSearchProposition.DateTime = openerp.base.BaseWidget.extend({
+openerp.base.search.ExtendedSearchProposition.DateTime = openerp.base.OldWidget.extend({
     template: 'SearchView.extended_search.proposition.datetime',
     identifier_prefix: 'extended-search-proposition-datetime',
     operators: [
@@ -1093,7 +1096,7 @@ openerp.base.search.ExtendedSearchProposition.DateTime = openerp.base.BaseWidget
         });
     }
 });
-openerp.base.search.ExtendedSearchProposition.Date = openerp.base.BaseWidget.extend({
+openerp.base.search.ExtendedSearchProposition.Date = openerp.base.OldWidget.extend({
     template: 'SearchView.extended_search.proposition.date',
     identifier_prefix: 'extended-search-proposition-date',
     operators: [
@@ -1115,7 +1118,7 @@ openerp.base.search.ExtendedSearchProposition.Date = openerp.base.BaseWidget.ext
         });
     }
 });
-openerp.base.search.ExtendedSearchProposition.Integer = openerp.base.BaseWidget.extend({
+openerp.base.search.ExtendedSearchProposition.Integer = openerp.base.OldWidget.extend({
     template: 'SearchView.extended_search.proposition.integer',
     identifier_prefix: 'extended-search-proposition-integer',
     operators: [
@@ -1134,7 +1137,7 @@ openerp.base.search.ExtendedSearchProposition.Integer = openerp.base.BaseWidget.
         return Math.round(value);
     }
 });
-openerp.base.search.ExtendedSearchProposition.Float = openerp.base.BaseWidget.extend({
+openerp.base.search.ExtendedSearchProposition.Float = openerp.base.OldWidget.extend({
     template: 'SearchView.extended_search.proposition.float',
     identifier_prefix: 'extended-search-proposition-float',
     operators: [
@@ -1153,7 +1156,7 @@ openerp.base.search.ExtendedSearchProposition.Float = openerp.base.BaseWidget.ex
         return value;
     }
 });
-openerp.base.search.ExtendedSearchProposition.Selection = openerp.base.BaseWidget.extend({
+openerp.base.search.ExtendedSearchProposition.Selection = openerp.base.OldWidget.extend({
     template: 'SearchView.extended_search.proposition.selection',
     identifier_prefix: 'extended-search-proposition-selection',
     operators: [
@@ -1167,7 +1170,7 @@ openerp.base.search.ExtendedSearchProposition.Selection = openerp.base.BaseWidge
         return this.$element.val();
     }
 });
-openerp.base.search.ExtendedSearchProposition.Boolean = openerp.base.BaseWidget.extend({
+openerp.base.search.ExtendedSearchProposition.Boolean = openerp.base.OldWidget.extend({
     template: 'SearchView.extended_search.proposition.boolean',
     identifier_prefix: 'extended-search-proposition-boolean',
     operators: [
diff --git a/addons/base/static/src/js/view_help.js b/addons/base/static/src/js/view_help.js
index 704c982eb3a..aa98f59c3ab 100644
--- a/addons/base/static/src/js/view_help.js
+++ b/addons/base/static/src/js/view_help.js
@@ -4,10 +4,10 @@
 
 openerp.base.view_help = function(openerp) {
 
-openerp.base.ProcessView = openerp.base.Controller.extend({
+openerp.base.ProcessView = openerp.base.Widget.extend({
 });
 
-openerp.base.HelpView = openerp.base.Controller.extend({
+openerp.base.HelpView = openerp.base.Widget.extend({
 });
 
 };
diff --git a/addons/base/static/src/js/view_tree.js b/addons/base/static/src/js/view_tree.js
index ceb5478a4a7..90972f84973 100644
--- a/addons/base/static/src/js/view_tree.js
+++ b/addons/base/static/src/js/view_tree.js
@@ -5,7 +5,7 @@
 openerp.base.view_tree = function(openerp) {
 
 openerp.base.views.add('tree', 'openerp.base.TreeView');
-openerp.base.TreeView = openerp.base.Controller.extend({
+openerp.base.TreeView = openerp.base.Widget.extend({
 /**
  * Genuine tree view (the one displayed as a tree, not the list)
  */
diff --git a/addons/base/static/src/js/views.js b/addons/base/static/src/js/views.js
index 36fce76d40c..00182874c8c 100644
--- a/addons/base/static/src/js/views.js
+++ b/addons/base/static/src/js/views.js
@@ -4,7 +4,7 @@
 
 openerp.base.views = function(openerp) {
 
-openerp.base.ActionManager = openerp.base.Controller.extend({
+openerp.base.ActionManager = openerp.base.Widget.extend({
 // process all kind of actions
     init: function(parent, element_id) {
         this._super(parent, element_id);
@@ -112,7 +112,7 @@ openerp.base.ActionDialog = openerp.base.Dialog.extend({
     }
 });
 
-openerp.base.ViewManager =  openerp.base.Controller.extend({
+openerp.base.ViewManager =  openerp.base.Widget.extend({
     init: function(parent, element_id, dataset, views) {
         this._super(parent, element_id);
         this.model = dataset.model;
@@ -346,7 +346,7 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
         }
     },
     stop: function() {
-        // should be replaced by automatic destruction implemented in BaseWidget
+        // should be replaced by automatic destruction implemented in Widget
         this._super();
     },
     /**
@@ -373,10 +373,11 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
     }
 });
 
-openerp.base.Sidebar = openerp.base.Controller.extend({
+openerp.base.Sidebar = openerp.base.Widget.extend({
     init: function(parent, element_id) {
         this._super(parent, element_id);
         this.items = {};
+        this.sections = {};
     },
     start: function() {
         var self = this;
@@ -398,11 +399,11 @@ openerp.base.Sidebar = openerp.base.Controller.extend({
                         classname: 'oe_sidebar_' + type[0]
                     }
                 }
-                self.add_section(type[1], items);
+                self.add_section(type[0], type[1], items);
             }
         });
     },
-    add_section: function(name, items) {
+    add_section: function(code, name, items) {
         // For each section, we pass a name/label and optionally an array of items.
         // If no items are passed, then the section will be created as a custom section
         // returning back an element_id to be used by a custom controller.
@@ -411,11 +412,12 @@ openerp.base.Sidebar = openerp.base.Controller.extend({
         //    label: label to be displayed for the link,
         //    action: action to be launch when the link is clicked,
         //    callback: a function to be executed when the link is clicked,
-        //    classname: optionnal dom class name for the line,
+        //    classname: optional dom class name for the line,
+        //    title: optional title for the link
         // }
         // Note: The item should have one action or/and a callback
         var self = this,
-            section_id = _.uniqueId(this.element_id + '_section_');
+            section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
         if (items) {
             for (var i = 0; i < items.length; i++) {
                 items[i].element_id = _.uniqueId(section_id + '_item_');
@@ -425,6 +427,7 @@ openerp.base.Sidebar = openerp.base.Controller.extend({
         var $section = $(QWeb.render("Sidebar.section", {
             section_id: section_id,
             name: name,
+            classname: 'oe_sidebar_' + code,
             items: items
         }));
         if (items) {
@@ -442,6 +445,7 @@ openerp.base.Sidebar = openerp.base.Controller.extend({
             });
         }
         $section.appendTo(this.$element.find('div.sidebar-actions'));
+        this.sections[code] = $section;
         return section_id;
     },
     do_fold: function() {
@@ -455,7 +459,7 @@ openerp.base.Sidebar = openerp.base.Controller.extend({
     }
 });
 
-openerp.base.View = openerp.base.Controller.extend({
+openerp.base.View = openerp.base.Widget.extend({
     set_default_options: function(options) {
         this.options = options || {};
         _.defaults(this.options, {
@@ -524,6 +528,34 @@ openerp.base.View = openerp.base.Controller.extend({
      */
     set_embedded_view: function(embedded_view) {
         this.embedded_view = embedded_view;
+    },
+    set_common_sidebar_sections: function(sidebar) {
+        var items = [];
+        sidebar.add_section('customize', "Customize", [
+            {
+                label: "Manage Views",
+                callback: this.on_sidebar_manage_view,
+                title: "Manage views of the current object"
+            }, {
+                label: "Edit Workflow",
+                callback: this.on_sidebar_edit_workflow,
+                title: "Manage views of the current object",
+                classname: 'oe_hide oe_sidebar_edit_workflow'
+            }, {
+                label: "Customize Object",
+                callback: this.on_sidebar_customize_object,
+                title: "Manage views of the current object"
+            }
+        ]);
+    },
+    on_sidebar_manage_view: function() {
+        console.log('Todo');
+    },
+    on_sidebar_edit_workflow: function() {
+        console.log('Todo');
+    },
+    on_sidebar_customize_object: function() {
+        console.log('Todo');
     }
 });
 
diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml
index 1c35ce9a06d..c51284ad63a 100644
--- a/addons/base/static/src/xml/base.xml
+++ b/addons/base/static/src/xml/base.xml
@@ -248,10 +248,10 @@
 
 
     

-
+
  • - +
  • diff --git a/addons/base_diagram/static/src/js/diagram.js b/addons/base_diagram/static/src/js/diagram.js index af56c256ee7..b992b5cbf42 100644 --- a/addons/base_diagram/static/src/js/diagram.js +++ b/addons/base_diagram/static/src/js/diagram.js @@ -5,7 +5,7 @@ openerp.base.diagram = function (openerp) { openerp.base.views.add('diagram', 'openerp.base.DiagramView'); -openerp.base.DiagramView = openerp.base.Controller.extend({ +openerp.base.DiagramView = openerp.base.Widget.extend({ init: function(view_manager, session, element_id, dataset, view_id){ this._super(session, element_id); this.view_manager = view_manager; diff --git a/addons/base_gantt/static/src/js/gantt.js b/addons/base_gantt/static/src/js/gantt.js index cf0ce449d60..09174e25ab7 100644 --- a/addons/base_gantt/static/src/js/gantt.js +++ b/addons/base_gantt/static/src/js/gantt.js @@ -5,7 +5,7 @@ openerp.base_gantt = function (openerp) { QWeb.add_template('/base_gantt/static/src/xml/base_gantt.xml'); openerp.base.views.add('gantt', 'openerp.base_gantt.GanttView'); -openerp.base_gantt.GanttView = openerp.base.Controller.extend({ +openerp.base_gantt.GanttView = openerp.base.Widget.extend({ init: function(view_manager, session, element_id, dataset, view_id) { diff --git a/addons/web_mobile/static/src/js/chrome_mobile.js b/addons/web_mobile/static/src/js/chrome_mobile.js index 138d37136a9..785cf98b6aa 100644 --- a/addons/web_mobile/static/src/js/chrome_mobile.js +++ b/addons/web_mobile/static/src/js/chrome_mobile.js @@ -1,5 +1,5 @@ openerp.web_mobile.chrome_mobile = function(openerp) { -openerp.web_mobile.Shortcuts = openerp.base.Controller.extend({ +openerp.web_mobile.Shortcuts = openerp.base.Widget.extend({ init: function(session, element_id) { this._super(session, element_id); }, @@ -19,7 +19,7 @@ openerp.web_mobile.Shortcuts = openerp.base.Controller.extend({ this.listview.start(); } }); -openerp.web_mobile.Header = openerp.base.Controller.extend({ +openerp.web_mobile.Header = openerp.base.Widget.extend({ init: function(session, element_id) { this._super(session, element_id); }, @@ -36,7 +36,7 @@ openerp.web_mobile.Header = openerp.base.Controller.extend({ } } }); -openerp.web_mobile.Secondary = openerp.base.Controller.extend({ +openerp.web_mobile.Secondary = openerp.base.Widget.extend({ init: function(session, element_id, secondary_menu_id) { this._super(session, element_id); this.data = secondary_menu_id; @@ -74,7 +74,7 @@ openerp.web_mobile.Secondary = openerp.base.Controller.extend({ } }); -openerp.web_mobile.Menu = openerp.base.Controller.extend({ +openerp.web_mobile.Menu = openerp.base.Widget.extend({ init: function(session, element_id, secondary_menu_id) { this._super(session, element_id); this.secondary_menu_id = secondary_menu_id; @@ -106,7 +106,7 @@ openerp.web_mobile.Menu = openerp.base.Controller.extend({ this.secondary.start(); } }); -openerp.web_mobile.Options = openerp.base.Controller.extend({ +openerp.web_mobile.Options = openerp.base.Widget.extend({ init: function(session, element_id) { this._super(session, element_id); }, @@ -121,7 +121,7 @@ openerp.web_mobile.Options = openerp.base.Controller.extend({ this.login.start(); } }); -openerp.web_mobile.Login = openerp.base.Controller.extend({ +openerp.web_mobile.Login = openerp.base.Widget.extend({ init: function(session, element_id) { this._super(session, element_id); }, @@ -190,7 +190,7 @@ openerp.web_mobile.Login = openerp.base.Controller.extend({ }); } }); -openerp.web_mobile.MobileWebClient = openerp.base.Controller.extend({ +openerp.web_mobile.MobileWebClient = openerp.base.Widget.extend({ init: function(element_id) { var self = this; this._super(null, element_id); diff --git a/addons/web_mobile/static/src/js/form_mobile.js b/addons/web_mobile/static/src/js/form_mobile.js index 9fa219ee86e..51bfd719c7f 100644 --- a/addons/web_mobile/static/src/js/form_mobile.js +++ b/addons/web_mobile/static/src/js/form_mobile.js @@ -1,5 +1,5 @@ openerp.web_mobile.form_mobile = function (openerp) { -openerp.web_mobile.FormView = openerp.base.Controller.extend({ +openerp.web_mobile.FormView = openerp.base.Widget.extend({ init: function(session, element_id, list_id, action) { this._super(session, element_id); this.list_id = list_id; diff --git a/addons/web_mobile/static/src/js/list_mobile.js b/addons/web_mobile/static/src/js/list_mobile.js index f7a88019e3d..809797bfe0f 100644 --- a/addons/web_mobile/static/src/js/list_mobile.js +++ b/addons/web_mobile/static/src/js/list_mobile.js @@ -1,5 +1,5 @@ openerp.web_mobile.list_mobile = function (openerp) { -openerp.web_mobile.ListView = openerp.base.Controller.extend({ +openerp.web_mobile.ListView = openerp.base.Widget.extend({ init: function(session, element_id, list_id) { this._super(session, element_id); this.list_id = list_id;