[MERGE] Merge with trunk upto revision no 790.
bzr revid: ysa@tinyerp.com-20110811094854-m93w506cch3hihgj
This commit is contained in:
+6
-7
@@ -1,12 +1,11 @@
|
||||
RE:lib/(?!populate.sh).*
|
||||
.*
|
||||
*.egg-info
|
||||
*.orig
|
||||
bin/
|
||||
build/
|
||||
dist/
|
||||
include/
|
||||
RE:^bin/
|
||||
RE:^dist/
|
||||
RE:^include/
|
||||
|
||||
share/
|
||||
man/
|
||||
lib/
|
||||
RE:^share/
|
||||
RE:^man/
|
||||
RE:^lib/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//---------------------------------------------------------
|
||||
// OpenERP Web Boostrap
|
||||
//---------------------------------------------------------
|
||||
/*---------------------------------------------------------
|
||||
* OpenERP Web Boostrap Code
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @name openerp
|
||||
@@ -14,13 +14,8 @@
|
||||
|
||||
/** @lends openerp */
|
||||
var openerp = this.openerp = {
|
||||
/**
|
||||
* Debug flag turns on logging
|
||||
*/
|
||||
// debug flag
|
||||
debug: true,
|
||||
// element_ids registry linked to all controllers on the page
|
||||
// TODO rename to elements, or keep gtk naming?
|
||||
screen: {},
|
||||
// Per session namespace
|
||||
// openerp.<module> will map to
|
||||
// openerp.sessions.sessionname.<module> using a closure
|
||||
@@ -40,8 +35,6 @@
|
||||
// this unique id will be replaced by hostname_databasename by
|
||||
// openerp.base.Connection on the first connection
|
||||
_session_id: "session" + session_counter++,
|
||||
screen: openerp.screen,
|
||||
sessions: openerp.sessions,
|
||||
base: {},
|
||||
web_mobile: {}
|
||||
};
|
||||
@@ -51,12 +44,13 @@
|
||||
}
|
||||
return new_instance;
|
||||
}
|
||||
// TODO add initrpc to init core only for RPC
|
||||
};
|
||||
})();
|
||||
|
||||
//---------------------------------------------------------
|
||||
// OpenERP base module split
|
||||
//---------------------------------------------------------
|
||||
/*---------------------------------------------------------
|
||||
* OpenERP Web base module split
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
openerp.base = function(instance) {
|
||||
openerp.base.core(instance);
|
||||
|
||||
@@ -1,285 +1,9 @@
|
||||
/*---------------------------------------------------------
|
||||
* OpenERP base library
|
||||
* OpenERP Web chrome
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
openerp.base.chrome = function(openerp) {
|
||||
|
||||
openerp.base.Session = openerp.base.Widget.extend( /** @lends openerp.base.Session# */{
|
||||
/**
|
||||
* @constructs
|
||||
* @param element_id to use for exception reporting
|
||||
* @param server
|
||||
* @param port
|
||||
*/
|
||||
init: function(parent, element_id, server, port) {
|
||||
this._super(parent, element_id);
|
||||
this.server = (server == undefined) ? location.hostname : server;
|
||||
this.port = (port == undefined) ? location.port : port;
|
||||
this.rpc_mode = (server == location.hostname) ? "ajax" : "jsonp";
|
||||
this.debug = true;
|
||||
this.db = "";
|
||||
this.login = "";
|
||||
this.password = "";
|
||||
this.uid = false;
|
||||
this.session_id = false;
|
||||
this.module_list = [];
|
||||
this.module_loaded = {"base": true};
|
||||
this.context = {};
|
||||
},
|
||||
start: function() {
|
||||
this.session_restore();
|
||||
},
|
||||
/**
|
||||
* Executes an RPC call, registering the provided callbacks.
|
||||
*
|
||||
* Registers a default error callback if none is provided, and handles
|
||||
* setting the correct session id and session context in the parameter
|
||||
* objects
|
||||
*
|
||||
* @param {String} url RPC endpoint
|
||||
* @param {Object} params call parameters
|
||||
* @param {Function} success_callback function to execute on RPC call success
|
||||
* @param {Function} error_callback function to execute on RPC call failure
|
||||
* @returns {jQuery.Deferred} jquery-provided ajax deferred
|
||||
*/
|
||||
rpc: function(url, params, success_callback, error_callback) {
|
||||
var self = this;
|
||||
// Construct a JSON-RPC2 request, method is currently unused
|
||||
params.session_id = this.session_id;
|
||||
|
||||
// Call using the rpc_mode
|
||||
var deferred = $.Deferred();
|
||||
this.rpc_ajax(url, {
|
||||
jsonrpc: "2.0",
|
||||
method: "call",
|
||||
params: params,
|
||||
id:null
|
||||
}).then(function () {deferred.resolve.apply(deferred, arguments);},
|
||||
function(error) {deferred.reject(error, $.Event());});
|
||||
return deferred.fail(function() {
|
||||
deferred.fail(function(error, event) {
|
||||
if (!event.isDefaultPrevented()) {
|
||||
self.on_rpc_error(error, event);
|
||||
}
|
||||
});
|
||||
}).then(success_callback, error_callback).promise();
|
||||
},
|
||||
/**
|
||||
* Raw JSON-RPC call
|
||||
*
|
||||
* @returns {jQuery.Deferred} ajax-based deferred object
|
||||
*/
|
||||
rpc_ajax: function(url, payload) {
|
||||
var self = this;
|
||||
this.on_rpc_request();
|
||||
// url can be an $.ajax option object
|
||||
if (_.isString(url)) {
|
||||
url = {
|
||||
url: url
|
||||
}
|
||||
}
|
||||
var ajax = _.extend({
|
||||
type: "POST",
|
||||
url: url,
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(payload),
|
||||
processData: false
|
||||
}, url);
|
||||
var deferred = $.Deferred();
|
||||
$.ajax(ajax).done(function(response, textStatus, jqXHR) {
|
||||
self.on_rpc_response();
|
||||
if (!response.error) {
|
||||
deferred.resolve(response["result"], textStatus, jqXHR);
|
||||
return;
|
||||
}
|
||||
if (response.error.data.type !== "session_invalid") {
|
||||
deferred.reject(response.error);
|
||||
return;
|
||||
}
|
||||
self.uid = false;
|
||||
self.on_session_invalid(function() {
|
||||
self.rpc(url, payload.params,
|
||||
function() {
|
||||
deferred.resolve.apply(deferred, arguments);
|
||||
},
|
||||
function(error, event) {
|
||||
event.preventDefault();
|
||||
deferred.reject.apply(deferred, arguments);
|
||||
});
|
||||
});
|
||||
}).fail(function(jqXHR, textStatus, errorThrown) {
|
||||
self.on_rpc_response();
|
||||
var error = {
|
||||
code: -32098,
|
||||
message: "XmlHttpRequestError " + errorThrown,
|
||||
data: {type: "xhr"+textStatus, debug: jqXHR.responseText, objects: [jqXHR, errorThrown] }
|
||||
};
|
||||
deferred.reject(error);
|
||||
});
|
||||
return deferred.promise();
|
||||
},
|
||||
on_rpc_request: function() {
|
||||
},
|
||||
on_rpc_response: function() {
|
||||
},
|
||||
on_rpc_error: function(error) {
|
||||
},
|
||||
/**
|
||||
* The session is validated either by login or by restoration of a previous session
|
||||
*/
|
||||
on_session_valid: function() {
|
||||
if(!openerp._modules_loaded)
|
||||
this.load_modules();
|
||||
},
|
||||
on_session_invalid: function(contination) {
|
||||
},
|
||||
session_is_valid: function() {
|
||||
return this.uid;
|
||||
},
|
||||
session_login: function(db, login, password, success_callback) {
|
||||
var self = this;
|
||||
this.db = db;
|
||||
this.login = login;
|
||||
this.password = password;
|
||||
var params = { db: this.db, login: this.login, password: this.password };
|
||||
this.rpc("/base/session/login", params, function(result) {
|
||||
self.session_id = result.session_id;
|
||||
self.uid = result.uid;
|
||||
self.session_save();
|
||||
self.on_session_valid();
|
||||
if (success_callback)
|
||||
success_callback();
|
||||
});
|
||||
},
|
||||
session_logout: function() {
|
||||
this.uid = false;
|
||||
},
|
||||
/**
|
||||
* Reloads uid and session_id from local storage, if they exist
|
||||
*/
|
||||
session_restore: function () {
|
||||
this.uid = this.get_cookie('uid');
|
||||
this.session_id = this.get_cookie('session_id');
|
||||
this.db = this.get_cookie('db');
|
||||
this.login = this.get_cookie('login');
|
||||
// we should do an rpc to confirm that this session_id is valid and if it is retrieve the information about db and login
|
||||
// then call on_session_valid
|
||||
this.on_session_valid();
|
||||
},
|
||||
/**
|
||||
* Saves the session id and uid locally
|
||||
*/
|
||||
session_save: function () {
|
||||
this.set_cookie('uid', this.uid);
|
||||
this.set_cookie('session_id', this.session_id);
|
||||
this.set_cookie('db', this.db);
|
||||
this.set_cookie('login', this.login);
|
||||
},
|
||||
logout: function() {
|
||||
delete this.uid;
|
||||
delete this.session_id;
|
||||
delete this.db;
|
||||
delete this.login;
|
||||
this.set_cookie('uid', '');
|
||||
this.set_cookie('session_id', '');
|
||||
this.set_cookie('db', '');
|
||||
this.set_cookie('login', '');
|
||||
this.on_session_invalid(function() {});
|
||||
},
|
||||
/**
|
||||
* Fetches a cookie stored by an openerp session
|
||||
*
|
||||
* @private
|
||||
* @param name the cookie's name
|
||||
*/
|
||||
get_cookie: function (name) {
|
||||
var nameEQ = this.element_id + '|' + name + '=';
|
||||
var cookies = document.cookie.split(';');
|
||||
for(var i=0; i<cookies.length; ++i) {
|
||||
var cookie = cookies[i].replace(/^\s*/, '');
|
||||
if(cookie.indexOf(nameEQ) === 0) {
|
||||
return JSON.parse(decodeURIComponent(cookie.substring(nameEQ.length)));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
/**
|
||||
* Create a new cookie with the provided name and value
|
||||
*
|
||||
* @private
|
||||
* @param name the cookie's name
|
||||
* @param value the cookie's value
|
||||
* @param ttl the cookie's time to live, 1 year by default, set to -1 to delete
|
||||
*/
|
||||
set_cookie: function (name, value, ttl) {
|
||||
ttl = ttl || 24*60*60*365;
|
||||
document.cookie = [
|
||||
this.element_id + '|' + name + '=' + encodeURIComponent(JSON.stringify(value)),
|
||||
'max-age=' + ttl,
|
||||
'expires=' + new Date(new Date().getTime() + ttl*1000).toGMTString()
|
||||
].join(';');
|
||||
},
|
||||
/**
|
||||
* Load additional web addons of that instance and init them
|
||||
*/
|
||||
load_modules: function() {
|
||||
var self = this;
|
||||
this.rpc('/base/session/modules', {}, function(result) {
|
||||
self.module_list = result;
|
||||
var modules = self.module_list.join(',');
|
||||
if(self.debug || true) {
|
||||
self.rpc('/base/webclient/csslist', {"mods": modules}, self.do_load_css);
|
||||
self.rpc('/base/webclient/jslist', {"mods": modules}, self.do_load_js);
|
||||
} else {
|
||||
self.do_load_css(["/base/webclient/css?mods="+modules]);
|
||||
self.do_load_js(["/base/webclient/js?mods="+modules]);
|
||||
}
|
||||
openerp._modules_loaded = true;
|
||||
});
|
||||
},
|
||||
do_load_css: function (files) {
|
||||
_.each(files, function (file) {
|
||||
$('head').append($('<link>', {
|
||||
'href': file,
|
||||
'rel': 'stylesheet',
|
||||
'type': 'text/css'
|
||||
}));
|
||||
});
|
||||
},
|
||||
do_load_js: function(files) {
|
||||
var self = this;
|
||||
if(files.length != 0) {
|
||||
var file = files.shift();
|
||||
var tag = document.createElement('script');
|
||||
tag.type = 'text/javascript';
|
||||
tag.src = file;
|
||||
tag.onload = tag.onreadystatechange = function() {
|
||||
if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done )
|
||||
return;
|
||||
tag.onload_done = true;
|
||||
self.do_load_js(files);
|
||||
};
|
||||
document.head.appendChild(tag);
|
||||
} else {
|
||||
this.on_modules_loaded();
|
||||
}
|
||||
},
|
||||
on_modules_loaded: function() {
|
||||
for(var j=0; j<this.module_list.length; j++) {
|
||||
var mod = this.module_list[j];
|
||||
if(this.module_loaded[mod])
|
||||
continue;
|
||||
openerp[mod] = {};
|
||||
// init module mod
|
||||
if(openerp._openerp[mod] != undefined) {
|
||||
openerp._openerp[mod](openerp);
|
||||
this.module_loaded[mod] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.Notification = openerp.base.Widget.extend({
|
||||
init: function(parent, element_id) {
|
||||
this._super(parent, element_id);
|
||||
@@ -318,9 +42,7 @@ openerp.base.Dialog = openerp.base.OldWidget.extend({
|
||||
max_height: '100%',
|
||||
autoOpen: false,
|
||||
buttons: {},
|
||||
beforeClose: function () {
|
||||
self.on_close();
|
||||
}
|
||||
beforeClose: function () { self.on_close(); }
|
||||
};
|
||||
for (var f in this) {
|
||||
if (f.substr(0, 10) == 'on_button_') {
|
||||
@@ -368,12 +90,10 @@ openerp.base.Dialog = openerp.base.OldWidget.extend({
|
||||
return parseInt(val, 10);
|
||||
}
|
||||
},
|
||||
start: function (auto_open) {
|
||||
start: function () {
|
||||
this.$dialog = $('<div id="' + this.element_id + '"></div>').dialog(this.dialog_options);
|
||||
if (auto_open !== false) {
|
||||
this.open();
|
||||
}
|
||||
this._super();
|
||||
return this;
|
||||
},
|
||||
open: function(dialog_options) {
|
||||
// TODO fme: bind window on resize
|
||||
@@ -952,6 +672,7 @@ openerp.base.Preferences = openerp.base.Widget.extend({
|
||||
openerp.base.WebClient = openerp.base.Widget.extend({
|
||||
init: function(element_id) {
|
||||
this._super(null, element_id);
|
||||
openerp.webclient = this;
|
||||
|
||||
QWeb.add_template("/base/static/src/xml/base.xml");
|
||||
var params = {};
|
||||
@@ -963,7 +684,7 @@ openerp.base.WebClient = openerp.base.Widget.extend({
|
||||
this.session = new openerp.base.Session(this,"oe_errors");
|
||||
this.loading = new openerp.base.Loading(this,"oe_loading");
|
||||
this.crashmanager = new openerp.base.CrashManager(this);
|
||||
this.crashmanager.start(false);
|
||||
this.crashmanager.start();
|
||||
|
||||
// Do you autorize this ? will be replaced by notify() in controller
|
||||
openerp.base.Widget.prototype.notification = new openerp.base.Notification(this, "oe_notification");
|
||||
@@ -988,6 +709,8 @@ openerp.base.WebClient = openerp.base.Widget.extend({
|
||||
this.notification.notify("OpenERP Client", "The openerp client has been initialized.");
|
||||
},
|
||||
on_logged: function() {
|
||||
if(this.action_manager)
|
||||
this.action_manager.stop();
|
||||
this.action_manager = new openerp.base.ActionManager(this);
|
||||
this.action_manager.appendTo($("#oe_app"));
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*---------------------------------------------------------
|
||||
* OpenERP controller framework
|
||||
* OpenERP Web core
|
||||
*--------------------------------------------------------*/
|
||||
|
||||
openerp.base.core = function(openerp) {
|
||||
@@ -574,6 +574,18 @@ openerp.base.Widget = openerp.base.SessionAware.extend({
|
||||
}
|
||||
return false;
|
||||
},
|
||||
do_notify: function() {
|
||||
if (this.widget_parent) {
|
||||
return this.widget_parent.do_notify.apply(this,arguments);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
do_warn: function() {
|
||||
if (this.widget_parent) {
|
||||
return this.widget_parent.do_warn.apply(this,arguments);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
rpc: function(url, data, success, error) {
|
||||
var def = $.Deferred().then(success, error);
|
||||
var self = this;
|
||||
@@ -599,5 +611,282 @@ openerp.base.OldWidget = openerp.base.Widget.extend({
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.Session = openerp.base.Widget.extend( /** @lends openerp.base.Session# */{
|
||||
/**
|
||||
* @constructs
|
||||
* @param element_id to use for exception reporting
|
||||
* @param server
|
||||
* @param port
|
||||
*/
|
||||
init: function(parent, element_id, server, port) {
|
||||
this._super(parent, element_id);
|
||||
this.server = (server == undefined) ? location.hostname : server;
|
||||
this.port = (port == undefined) ? location.port : port;
|
||||
this.rpc_mode = (server == location.hostname) ? "ajax" : "jsonp";
|
||||
this.debug = true;
|
||||
this.db = "";
|
||||
this.login = "";
|
||||
this.password = "";
|
||||
this.uid = false;
|
||||
this.session_id = false;
|
||||
this.module_list = [];
|
||||
this.module_loaded = {"base": true};
|
||||
this.context = {};
|
||||
},
|
||||
start: function() {
|
||||
this.session_restore();
|
||||
},
|
||||
/**
|
||||
* Executes an RPC call, registering the provided callbacks.
|
||||
*
|
||||
* Registers a default error callback if none is provided, and handles
|
||||
* setting the correct session id and session context in the parameter
|
||||
* objects
|
||||
*
|
||||
* @param {String} url RPC endpoint
|
||||
* @param {Object} params call parameters
|
||||
* @param {Function} success_callback function to execute on RPC call success
|
||||
* @param {Function} error_callback function to execute on RPC call failure
|
||||
* @returns {jQuery.Deferred} jquery-provided ajax deferred
|
||||
*/
|
||||
rpc: function(url, params, success_callback, error_callback) {
|
||||
var self = this;
|
||||
// Construct a JSON-RPC2 request, method is currently unused
|
||||
params.session_id = this.session_id;
|
||||
|
||||
// Call using the rpc_mode
|
||||
var deferred = $.Deferred();
|
||||
this.rpc_ajax(url, {
|
||||
jsonrpc: "2.0",
|
||||
method: "call",
|
||||
params: params,
|
||||
id:null
|
||||
}).then(function () {deferred.resolve.apply(deferred, arguments);},
|
||||
function(error) {deferred.reject(error, $.Event());});
|
||||
return deferred.fail(function() {
|
||||
deferred.fail(function(error, event) {
|
||||
if (!event.isDefaultPrevented()) {
|
||||
self.on_rpc_error(error, event);
|
||||
}
|
||||
});
|
||||
}).then(success_callback, error_callback).promise();
|
||||
},
|
||||
/**
|
||||
* Raw JSON-RPC call
|
||||
*
|
||||
* @returns {jQuery.Deferred} ajax-based deferred object
|
||||
*/
|
||||
rpc_ajax: function(url, payload) {
|
||||
var self = this;
|
||||
this.on_rpc_request();
|
||||
// url can be an $.ajax option object
|
||||
if (_.isString(url)) {
|
||||
url = {
|
||||
url: url
|
||||
}
|
||||
}
|
||||
var ajax = _.extend({
|
||||
type: "POST",
|
||||
url: url,
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(payload),
|
||||
processData: false
|
||||
}, url);
|
||||
var deferred = $.Deferred();
|
||||
$.ajax(ajax).done(function(response, textStatus, jqXHR) {
|
||||
self.on_rpc_response();
|
||||
if (!response.error) {
|
||||
deferred.resolve(response["result"], textStatus, jqXHR);
|
||||
return;
|
||||
}
|
||||
if (response.error.data.type !== "session_invalid") {
|
||||
deferred.reject(response.error);
|
||||
return;
|
||||
}
|
||||
self.uid = false;
|
||||
self.on_session_invalid(function() {
|
||||
self.rpc(url, payload.params,
|
||||
function() {
|
||||
deferred.resolve.apply(deferred, arguments);
|
||||
},
|
||||
function(error, event) {
|
||||
event.preventDefault();
|
||||
deferred.reject.apply(deferred, arguments);
|
||||
});
|
||||
});
|
||||
}).fail(function(jqXHR, textStatus, errorThrown) {
|
||||
self.on_rpc_response();
|
||||
var error = {
|
||||
code: -32098,
|
||||
message: "XmlHttpRequestError " + errorThrown,
|
||||
data: {type: "xhr"+textStatus, debug: jqXHR.responseText, objects: [jqXHR, errorThrown] }
|
||||
};
|
||||
deferred.reject(error);
|
||||
});
|
||||
return deferred.promise();
|
||||
},
|
||||
on_rpc_request: function() {
|
||||
},
|
||||
on_rpc_response: function() {
|
||||
},
|
||||
on_rpc_error: function(error) {
|
||||
},
|
||||
/**
|
||||
* The session is validated either by login or by restoration of a previous session
|
||||
*/
|
||||
on_session_valid: function() {
|
||||
if(!openerp._modules_loaded)
|
||||
this.load_modules();
|
||||
},
|
||||
on_session_invalid: function(contination) {
|
||||
},
|
||||
session_is_valid: function() {
|
||||
return this.uid;
|
||||
},
|
||||
session_login: function(db, login, password, success_callback) {
|
||||
var self = this;
|
||||
this.db = db;
|
||||
this.login = login;
|
||||
this.password = password;
|
||||
var params = { db: this.db, login: this.login, password: this.password };
|
||||
this.rpc("/base/session/login", params, function(result) {
|
||||
self.session_id = result.session_id;
|
||||
self.uid = result.uid;
|
||||
self.session_save();
|
||||
self.on_session_valid();
|
||||
if (success_callback)
|
||||
success_callback();
|
||||
});
|
||||
},
|
||||
session_logout: function() {
|
||||
this.uid = false;
|
||||
},
|
||||
/**
|
||||
* Reloads uid and session_id from local storage, if they exist
|
||||
*/
|
||||
session_restore: function () {
|
||||
this.uid = this.get_cookie('uid');
|
||||
this.session_id = this.get_cookie('session_id');
|
||||
this.db = this.get_cookie('db');
|
||||
this.login = this.get_cookie('login');
|
||||
// we should do an rpc to confirm that this session_id is valid and if it is retrieve the information about db and login
|
||||
// then call on_session_valid
|
||||
this.on_session_valid();
|
||||
},
|
||||
/**
|
||||
* Saves the session id and uid locally
|
||||
*/
|
||||
session_save: function () {
|
||||
this.set_cookie('uid', this.uid);
|
||||
this.set_cookie('session_id', this.session_id);
|
||||
this.set_cookie('db', this.db);
|
||||
this.set_cookie('login', this.login);
|
||||
},
|
||||
logout: function() {
|
||||
delete this.uid;
|
||||
delete this.session_id;
|
||||
delete this.db;
|
||||
delete this.login;
|
||||
this.set_cookie('uid', '');
|
||||
this.set_cookie('session_id', '');
|
||||
this.set_cookie('db', '');
|
||||
this.set_cookie('login', '');
|
||||
this.on_session_invalid(function() {});
|
||||
},
|
||||
/**
|
||||
* Fetches a cookie stored by an openerp session
|
||||
*
|
||||
* @private
|
||||
* @param name the cookie's name
|
||||
*/
|
||||
get_cookie: function (name) {
|
||||
var nameEQ = this.element_id + '|' + name + '=';
|
||||
var cookies = document.cookie.split(';');
|
||||
for(var i=0; i<cookies.length; ++i) {
|
||||
var cookie = cookies[i].replace(/^\s*/, '');
|
||||
if(cookie.indexOf(nameEQ) === 0) {
|
||||
return JSON.parse(decodeURIComponent(cookie.substring(nameEQ.length)));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
/**
|
||||
* Create a new cookie with the provided name and value
|
||||
*
|
||||
* @private
|
||||
* @param name the cookie's name
|
||||
* @param value the cookie's value
|
||||
* @param ttl the cookie's time to live, 1 year by default, set to -1 to delete
|
||||
*/
|
||||
set_cookie: function (name, value, ttl) {
|
||||
ttl = ttl || 24*60*60*365;
|
||||
document.cookie = [
|
||||
this.element_id + '|' + name + '=' + encodeURIComponent(JSON.stringify(value)),
|
||||
'max-age=' + ttl,
|
||||
'expires=' + new Date(new Date().getTime() + ttl*1000).toGMTString()
|
||||
].join(';');
|
||||
},
|
||||
/**
|
||||
* Load additional web addons of that instance and init them
|
||||
*/
|
||||
load_modules: function() {
|
||||
var self = this;
|
||||
this.rpc('/base/session/modules', {}, function(result) {
|
||||
self.module_list = result;
|
||||
var modules = self.module_list.join(',');
|
||||
if(self.debug || true) {
|
||||
self.rpc('/base/webclient/csslist', {"mods": modules}, self.do_load_css);
|
||||
self.rpc('/base/webclient/jslist', {"mods": modules}, self.do_load_js);
|
||||
} else {
|
||||
self.do_load_css(["/base/webclient/css?mods="+modules]);
|
||||
self.do_load_js(["/base/webclient/js?mods="+modules]);
|
||||
}
|
||||
openerp._modules_loaded = true;
|
||||
});
|
||||
},
|
||||
do_load_css: function (files) {
|
||||
_.each(files, function (file) {
|
||||
$('head').append($('<link>', {
|
||||
'href': file,
|
||||
'rel': 'stylesheet',
|
||||
'type': 'text/css'
|
||||
}));
|
||||
});
|
||||
},
|
||||
do_load_js: function(files) {
|
||||
var self = this;
|
||||
if(files.length != 0) {
|
||||
var file = files.shift();
|
||||
var tag = document.createElement('script');
|
||||
tag.type = 'text/javascript';
|
||||
tag.src = file;
|
||||
tag.onload = tag.onreadystatechange = function() {
|
||||
if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done )
|
||||
return;
|
||||
tag.onload_done = true;
|
||||
self.do_load_js(files);
|
||||
};
|
||||
document.head.appendChild(tag);
|
||||
} else {
|
||||
this.on_modules_loaded();
|
||||
}
|
||||
},
|
||||
on_modules_loaded: function() {
|
||||
for(var j=0; j<this.module_list.length; j++) {
|
||||
var mod = this.module_list[j];
|
||||
if(this.module_loaded[mod])
|
||||
continue;
|
||||
openerp[mod] = {};
|
||||
// init module mod
|
||||
if(openerp._openerp[mod] != undefined) {
|
||||
openerp._openerp[mod](openerp);
|
||||
this.module_loaded[mod] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
|
||||
|
||||
@@ -268,9 +268,13 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data
|
||||
},
|
||||
/**
|
||||
* Read records.
|
||||
*
|
||||
* @param {Array} ids identifiers of the records to read
|
||||
* @param {Array} fields fields to read and return, by default all fields are returned
|
||||
* @param {Function} callback function called with read result
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
read_ids: function (ids, fields, callback) {
|
||||
var self = this;
|
||||
return this.rpc('/base/dataset/get', {
|
||||
model: this.model,
|
||||
ids: ids,
|
||||
@@ -282,13 +286,20 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data
|
||||
* Read a slice of the records represented by this DataSet, based on its
|
||||
* domain and context.
|
||||
*
|
||||
* @param {Number} [offset=0] The index from which selected records should be returned
|
||||
* @param {Number} [limit=null] The maximum number of records to return
|
||||
* @params {Object} options
|
||||
* @param {Array} [options.fields] fields to read and return, by default all fields are returned
|
||||
* @param {Number} [options.offset=0] The index from which selected records should be returned
|
||||
* @param {Number} [options.limit=null] The maximum number of records to return
|
||||
* @param {Function} callback function called with read_slice result
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
read_slice: function (fields, offset, limit, callback) {
|
||||
},
|
||||
read_slice: function (options, callback) { return null; },
|
||||
/**
|
||||
* Read the indexed record.
|
||||
* Reads the current dataset record (from its index)
|
||||
*
|
||||
* @params {Array} [fields] fields to read and return, by default all fields are returned
|
||||
* @params {Function} callback function called with read_index result
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
read_index: function (fields, callback) {
|
||||
var def = $.Deferred().then(callback);
|
||||
@@ -304,6 +315,13 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data
|
||||
}
|
||||
return def.promise();
|
||||
},
|
||||
/**
|
||||
* Reads default values for the current model
|
||||
*
|
||||
* @param {Array} [fields] fields to get default values for, by default all defaults are read
|
||||
* @param {Function} callback function called with default_get result
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
default_get: function(fields, callback) {
|
||||
return this.rpc('/base/dataset/default_get', {
|
||||
model: this.model,
|
||||
@@ -311,6 +329,14 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data
|
||||
context: this.get_context()
|
||||
}, callback);
|
||||
},
|
||||
/**
|
||||
* Creates a new record in db
|
||||
*
|
||||
* @param {Object} data field values to set on the new record
|
||||
* @param {Function} callback function called with operation result
|
||||
* @param {Function} error_callback function called in case of creation error
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
create: function(data, callback, error_callback) {
|
||||
return this.rpc('/base/dataset/create', {
|
||||
model: this.model,
|
||||
@@ -318,6 +344,15 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data
|
||||
context: this.get_context()
|
||||
}, callback, error_callback);
|
||||
},
|
||||
/**
|
||||
* Saves the provided data in an existing db record
|
||||
*
|
||||
* @param {Number|String} id identifier for the record to alter
|
||||
* @param {Object} data field values to write into the record
|
||||
* @param {Function} callback function called with operation result
|
||||
* @param {Function} error_callback function called in case of write error
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
write: function (id, data, callback, error_callback) {
|
||||
return this.rpc('/base/dataset/save', {
|
||||
model: this.model,
|
||||
@@ -326,11 +361,27 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data
|
||||
context: this.get_context()
|
||||
}, callback, error_callback);
|
||||
},
|
||||
/**
|
||||
* Deletes an existing record from the database
|
||||
*
|
||||
* @param {Number|String} ids identifier of the record to delete
|
||||
* @param {Function} callback function called with operation result
|
||||
* @param {Function} error_callback function called in case of deletion error
|
||||
*/
|
||||
unlink: function(ids, callback, error_callback) {
|
||||
var self = this;
|
||||
return this.call_and_eval("unlink", [ids, this.get_context()], null, 1,
|
||||
callback, error_callback);
|
||||
},
|
||||
/**
|
||||
* Calls an arbitrary RPC method
|
||||
*
|
||||
* @param {String} method name of the method (on the current model) to call
|
||||
* @param {Array} [args] arguments to pass to the method
|
||||
* @param {Function} callback
|
||||
* @param {Function} error_callback
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
call: function (method, args, callback, error_callback) {
|
||||
return this.rpc('/base/dataset/call', {
|
||||
model: this.model,
|
||||
@@ -338,6 +389,17 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data
|
||||
args: args || []
|
||||
}, callback, error_callback);
|
||||
},
|
||||
/**
|
||||
* Calls an arbitrary method, with more crazy
|
||||
*
|
||||
* @param {String} method
|
||||
* @param {Array} [args]
|
||||
* @param {Number} [domain_id] index of a domain to evaluate in the args array
|
||||
* @param {Number} [context_id] index of a context to evaluate in the args array
|
||||
* @param {Function} callback
|
||||
* @param {Function }error_callback
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
call_and_eval: function (method, args, domain_id, context_id, callback, error_callback) {
|
||||
return this.rpc('/base/dataset/call', {
|
||||
model: this.model,
|
||||
@@ -347,6 +409,15 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data
|
||||
args: args || []
|
||||
}, callback, error_callback);
|
||||
},
|
||||
/**
|
||||
* Calls a button method, usually returning some sort of action
|
||||
*
|
||||
* @param {String} method
|
||||
* @param {Array} [args]
|
||||
* @param {Function} callback
|
||||
* @param {Function} error_callback
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
call_button: function (method, args, callback, error_callback) {
|
||||
return this.rpc('/base/dataset/call_button', {
|
||||
model: this.model,
|
||||
@@ -356,17 +427,34 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data
|
||||
args: args || []
|
||||
}, callback, error_callback);
|
||||
},
|
||||
/**
|
||||
* Fetches the "readable name" for records, based on intrinsic rules
|
||||
*
|
||||
* @param {Array} ids
|
||||
* @param {Function} callback
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
name_get: function(ids, callback) {
|
||||
return this.call_and_eval('name_get', [ids, this.get_context()], null, 1, callback);
|
||||
},
|
||||
/*
|
||||
* args = domain
|
||||
/**
|
||||
*
|
||||
* @param {String} name name to perform a search for/on
|
||||
* @param {Array} [domain=[]] filters for the objects returned, OpenERP domain
|
||||
* @param {String} [operator='ilike'] matching operator to use with the provided name value
|
||||
* @param {Number} [limit=100] maximum number of matches to return
|
||||
* @param {Function} callback function to call with name_search result
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
name_search: function (name, args, operator, limit, callback) {
|
||||
name_search: function (name, domain, operator, limit, callback) {
|
||||
return this.call_and_eval('name_search',
|
||||
[name || '', args || false, operator || 'ilike', this.get_context(), limit || 100],
|
||||
[name || '', domain || false, operator || 'ilike', this.get_context(), limit || 100],
|
||||
1, 3, callback);
|
||||
},
|
||||
/**
|
||||
* @param name
|
||||
* @param callback
|
||||
*/
|
||||
name_create: function(name, callback) {
|
||||
return this.call_and_eval('name_create', [name, this.get_context()], null, 1, callback);
|
||||
},
|
||||
@@ -377,7 +465,10 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data
|
||||
signal: signal
|
||||
}, callback);
|
||||
},
|
||||
get_context: function() {
|
||||
get_context: function(request_context) {
|
||||
if (request_context) {
|
||||
return new openerp.base.CompoundContext(this.context, request_context);
|
||||
}
|
||||
return this.context;
|
||||
}
|
||||
});
|
||||
@@ -387,9 +478,11 @@ openerp.base.DataSetStatic = openerp.base.DataSet.extend({
|
||||
// all local records
|
||||
this.ids = ids || [];
|
||||
},
|
||||
read_slice: function (fields, offset, limit, callback) {
|
||||
var self = this;
|
||||
offset = offset || 0;
|
||||
read_slice: function (options, callback) {
|
||||
var self = this,
|
||||
offset = options.offset || 0,
|
||||
limit = options.limit || false,
|
||||
fields = options.fields || false;
|
||||
var end_pos = limit && limit !== -1 ? offset + limit : undefined;
|
||||
return this.read_ids(this.ids.slice(offset, end_pos), fields, callback);
|
||||
},
|
||||
@@ -426,25 +519,30 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
|
||||
// is it necessary ?
|
||||
this.ids = [];
|
||||
},
|
||||
read_slice: function (fields, offset, limit, callback) {
|
||||
/**
|
||||
* Read a slice of the records represented by this DataSet, based on its
|
||||
* domain and context.
|
||||
*
|
||||
* @params {Object} options
|
||||
* @param {Array} [options.fields] fields to read and return, by default all fields are returned
|
||||
* @param {Object} [options.context] context data to add to the request payload, on top of the DataSet's own context
|
||||
* @param {Array} [options.domain] domain data to add to the request payload, ANDed with the dataset's domain
|
||||
* @param {Number} [options.offset=0] The index from which selected records should be returned
|
||||
* @param {Number} [options.limit=null] The maximum number of records to return
|
||||
* @param {Function} callback function called with read_slice result
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
read_slice: function (options, callback) {
|
||||
var self = this;
|
||||
offset = offset || 0;
|
||||
// cached search, not sure it's a good idea
|
||||
if(this.offset <= offset) {
|
||||
var start = offset - this.offset;
|
||||
if(this.ids.length - start >= limit) {
|
||||
// TODO: check if this could work do only read if possible
|
||||
// return read_ids(ids.slice(start,start+limit),fields,callback)
|
||||
}
|
||||
}
|
||||
var offset = options.offset || 0;
|
||||
return this.rpc('/base/dataset/search_read', {
|
||||
model: this.model,
|
||||
fields: fields,
|
||||
domain: this.domain,
|
||||
context: this.get_context(),
|
||||
fields: options.fields || false,
|
||||
domain: this.get_domain(options.domain),
|
||||
context: this.get_context(options.context),
|
||||
sort: this.sort(),
|
||||
offset: offset,
|
||||
limit: limit
|
||||
limit: options.limit || false
|
||||
}, function (result) {
|
||||
self.ids = result.ids;
|
||||
self.offset = offset;
|
||||
@@ -453,6 +551,12 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
|
||||
}
|
||||
});
|
||||
},
|
||||
get_domain: function (other_domain) {
|
||||
if (other_domain) {
|
||||
return new openerp.base.CompoundDomain(this.domain, other_domain);
|
||||
}
|
||||
return this.domain;
|
||||
},
|
||||
/**
|
||||
* Reads or changes sort criteria on the dataset.
|
||||
*
|
||||
@@ -628,48 +732,51 @@ openerp.base.ReadOnlyDataSetSearch = openerp.base.DataSetSearch.extend({
|
||||
on_unlink: function(ids) {}
|
||||
});
|
||||
|
||||
openerp.base.CompoundContext = function() {
|
||||
this.__ref = "compound_context";
|
||||
this.__contexts = [];
|
||||
this.__eval_context = null;
|
||||
var self = this;
|
||||
_.each(arguments, function(x) {
|
||||
self.add(x);
|
||||
});
|
||||
};
|
||||
openerp.base.CompoundContext.prototype.add = function(context) {
|
||||
this.__contexts.push(context);
|
||||
return this;
|
||||
};
|
||||
openerp.base.CompoundContext.prototype.set_eval_context = function(eval_context) {
|
||||
this.__eval_context = eval_context;
|
||||
return this;
|
||||
};
|
||||
openerp.base.CompoundContext.prototype.get_eval_context = function() {
|
||||
return this.__eval_context;
|
||||
};
|
||||
|
||||
openerp.base.CompoundDomain = function() {
|
||||
this.__ref = "compound_domain";
|
||||
this.__domains = [];
|
||||
this.__eval_context = null;
|
||||
var self = this;
|
||||
_.each(arguments, function(x) {
|
||||
self.add(x);
|
||||
});
|
||||
};
|
||||
openerp.base.CompoundDomain.prototype.add = function(domain) {
|
||||
this.__domains.push(domain);
|
||||
return this;
|
||||
};
|
||||
openerp.base.CompoundDomain.prototype.set_eval_context = function(eval_context) {
|
||||
this.__eval_context = eval_context;
|
||||
return this;
|
||||
};
|
||||
openerp.base.CompoundDomain.prototype.get_eval_context = function() {
|
||||
return this.__eval_context;
|
||||
};
|
||||
openerp.base.CompoundContext = openerp.base.Class.extend({
|
||||
init: function () {
|
||||
this.__ref = "compound_context";
|
||||
this.__contexts = [];
|
||||
this.__eval_context = null;
|
||||
var self = this;
|
||||
_.each(arguments, function(x) {
|
||||
self.add(x);
|
||||
});
|
||||
},
|
||||
add: function (context) {
|
||||
this.__contexts.push(context);
|
||||
return this;
|
||||
},
|
||||
set_eval_context: function (eval_context) {
|
||||
this.__eval_context = eval_context;
|
||||
return this;
|
||||
},
|
||||
get_eval_context: function () {
|
||||
return this.__eval_context;
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.CompoundDomain = openerp.base.Class.extend({
|
||||
init: function () {
|
||||
this.__ref = "compound_domain";
|
||||
this.__domains = [];
|
||||
this.__eval_context = null;
|
||||
var self = this;
|
||||
_.each(arguments, function(x) {
|
||||
self.add(x);
|
||||
});
|
||||
},
|
||||
add: function(domain) {
|
||||
this.__domains.push(domain);
|
||||
return this;
|
||||
},
|
||||
set_eval_context: function(eval_context) {
|
||||
this.__eval_context = eval_context;
|
||||
return this;
|
||||
},
|
||||
get_eval_context: function() {
|
||||
return this.__eval_context;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
|
||||
|
||||
@@ -451,12 +451,14 @@ openerp.base.form.SidebarAttachments = openerp.base.Widget.extend({
|
||||
this.on_attachments_loaded([]);
|
||||
} else {
|
||||
(new openerp.base.DataSetSearch(
|
||||
this, 'ir.attachment', this.view.dataset.get_context(),
|
||||
[['res_model', '=', this.view.dataset.model],
|
||||
['res_id', '=', this.view.datarecord.id],
|
||||
['type', 'in', ['binary', 'url']]])).read_slice(
|
||||
['name', 'url', 'type'], false, false,
|
||||
this.on_attachments_loaded);
|
||||
this, 'ir.attachment', this.view.dataset.get_context(),
|
||||
[
|
||||
['res_model', '=', this.view.dataset.model],
|
||||
['res_id', '=', this.view.datarecord.id],
|
||||
['type', 'in', ['binary', 'url']]
|
||||
])).read_slice(
|
||||
{fields: ['name', 'url', 'type']},
|
||||
this.on_attachments_loaded);
|
||||
}
|
||||
},
|
||||
on_attachments_loaded: function(attachments) {
|
||||
@@ -510,36 +512,40 @@ openerp.base.form.compute_domain = function(expr, fields) {
|
||||
}
|
||||
}
|
||||
|
||||
var field = fields[ex[0]].get_value ? fields[ex[0]].get_value() : fields[ex[0]].value;
|
||||
var field = fields[ex[0]];
|
||||
if (!field) {
|
||||
throw new Error("Domain references unknown field : " + ex[0]);
|
||||
}
|
||||
var field_value = field.get_value ? fields[ex[0]].get_value() : fields[ex[0]].value;
|
||||
var op = ex[1];
|
||||
var val = ex[2];
|
||||
|
||||
switch (op.toLowerCase()) {
|
||||
case '=':
|
||||
case '==':
|
||||
stack.push(field == val);
|
||||
stack.push(field_value == val);
|
||||
break;
|
||||
case '!=':
|
||||
case '<>':
|
||||
stack.push(field != val);
|
||||
stack.push(field_value != val);
|
||||
break;
|
||||
case '<':
|
||||
stack.push(field < val);
|
||||
stack.push(field_value < val);
|
||||
break;
|
||||
case '>':
|
||||
stack.push(field > val);
|
||||
stack.push(field_value > val);
|
||||
break;
|
||||
case '<=':
|
||||
stack.push(field <= val);
|
||||
stack.push(field_value <= val);
|
||||
break;
|
||||
case '>=':
|
||||
stack.push(field >= val);
|
||||
stack.push(field_value >= val);
|
||||
break;
|
||||
case 'in':
|
||||
stack.push(_(val).contains(field));
|
||||
stack.push(_(val).contains(field_value));
|
||||
break;
|
||||
case 'not in':
|
||||
stack.push(!_(val).contains(field));
|
||||
stack.push(!_(val).contains(field_value));
|
||||
break;
|
||||
default:
|
||||
this.log("Unsupported operator in modifiers :", op);
|
||||
@@ -767,8 +773,7 @@ openerp.base.form.WidgetButton = openerp.base.form.Widget.extend({
|
||||
var self = this;
|
||||
|
||||
this.view.execute_action(
|
||||
this.node.attrs, this.view.dataset, this.session.action_manager,
|
||||
this.view.datarecord.id, function () {
|
||||
this.node.attrs, this.view.dataset, this.view.datarecord.id, function () {
|
||||
self.view.reload();
|
||||
});
|
||||
}
|
||||
@@ -803,7 +808,7 @@ openerp.base.form.WidgetLabel = openerp.base.form.Widget.extend({
|
||||
var self = this;
|
||||
this.$element.find("label").dblclick(function() {
|
||||
var widget = self['for'] || self;
|
||||
console.log(widget.element_id , widget);
|
||||
self.log(widget.element_id , widget);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1885,7 +1890,7 @@ openerp.base.form.FieldMany2Many = openerp.base.form.Field.extend({
|
||||
self.on_ui_change();
|
||||
});
|
||||
|
||||
this.list_view = new openerp.base.form.Many2ManyListView(new openerp.base.NullViewManager(this), this.list_id, this.dataset, false, {
|
||||
this.list_view = new openerp.base.form.Many2ManyListView(this, this.list_id, this.dataset, false, {
|
||||
'addable': 'Add',
|
||||
'selectable': self.multi_selection
|
||||
});
|
||||
@@ -2210,8 +2215,8 @@ openerp.base.form.FieldBinary = openerp.base.form.Field.extend({
|
||||
delete(window[this.iframe]);
|
||||
if (size === false) {
|
||||
this.notification.warn("File Upload", "There was a problem while uploading your file");
|
||||
// TODO: use openerp web exception handler
|
||||
console.log("Error while uploading file : ", name);
|
||||
// TODO: use openerp web crashmanager
|
||||
this.log("Error while uploading file : ", name);
|
||||
} else {
|
||||
this.on_file_uploaded_and_valid.apply(this, arguments);
|
||||
this.on_ui_change();
|
||||
@@ -2320,10 +2325,8 @@ openerp.base.form.widgets = new openerp.base.Registry({
|
||||
'url' : 'openerp.base.form.FieldUrl',
|
||||
'text' : 'openerp.base.form.FieldText',
|
||||
'text_wiki' : 'openerp.base.form.FieldText',
|
||||
// 'date' : 'openerp.base.form.FieldDate',
|
||||
// 'datetime' : 'openerp.base.form.FieldDatetime',
|
||||
'date' : 'openerp.base.form.FieldChar',
|
||||
'datetime' : 'openerp.base.form.FieldChar',
|
||||
'date' : 'openerp.base.form.FieldDate',
|
||||
'datetime' : 'openerp.base.form.FieldDatetime',
|
||||
'selection' : 'openerp.base.form.FieldSelection',
|
||||
'many2one' : 'openerp.base.form.FieldMany2One',
|
||||
'many2many' : 'openerp.base.form.FieldMany2Many',
|
||||
|
||||
@@ -74,15 +74,16 @@ openerp.base.parse_time = function(str) {
|
||||
};
|
||||
|
||||
/*
|
||||
* Just a simple function to add some '0' if an integer it too small.
|
||||
* Left-pad provided arg 1 with zeroes until reaching size provided by second
|
||||
* argument.
|
||||
*
|
||||
* @param {Number|String} str value to pad
|
||||
* @param {Number} size size to reach on the final padded value
|
||||
* @returns {String} padded string
|
||||
*/
|
||||
var fts = function(str, size) {
|
||||
var zpad = function(str, size) {
|
||||
str = "" + str;
|
||||
var to_add = "";
|
||||
_.each(_.range(size - str.length), function() {
|
||||
to_add = to_add + "0";
|
||||
});
|
||||
return to_add + str;
|
||||
return new Array(size - str.length).join('0') + str;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -99,9 +100,9 @@ openerp.base.format_datetime = function(obj) {
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
return fts(obj.getUTCFullYear(),4) + "-" + fts(obj.getUTCMonth() + 1,2) + "-"
|
||||
+ fts(obj.getUTCDate(),2) + " " + fts(obj.getUTCHours(),2) + ":"
|
||||
+ fts(obj.getUTCMinutes(),2) + ":" + fts(obj.getUTCSeconds(),2);
|
||||
return zpad(obj.getUTCFullYear(),4) + "-" + zpad(obj.getUTCMonth() + 1,2) + "-"
|
||||
+ zpad(obj.getUTCDate(),2) + " " + zpad(obj.getUTCHours(),2) + ":"
|
||||
+ zpad(obj.getUTCMinutes(),2) + ":" + zpad(obj.getUTCSeconds(),2);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -115,8 +116,8 @@ openerp.base.format_date = function(obj) {
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
return fts(obj.getFullYear(),4) + "-" + fts(obj.getMonth() + 1,2) + "-"
|
||||
+ fts(obj.getDate(),2);
|
||||
return zpad(obj.getFullYear(),4) + "-" + zpad(obj.getMonth() + 1,2) + "-"
|
||||
+ zpad(obj.getDate(),2);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -130,8 +131,8 @@ openerp.base.format_time = function(obj) {
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
return fts(obj.getHours(),2) + ":" + fts(obj.getMinutes(),2) + ":"
|
||||
+ fts(obj.getSeconds(),2);
|
||||
return zpad(obj.getHours(),2) + ":" + zpad(obj.getMinutes(),2) + ":"
|
||||
+ zpad(obj.getSeconds(),2);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,7 +61,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
||||
/**
|
||||
* Retrieves the view's number of records per page (|| section)
|
||||
*
|
||||
* options > defaults > indefinite
|
||||
* options > defaults > parent.action.limit > indefinite
|
||||
*
|
||||
* @returns {Number|null}
|
||||
*/
|
||||
@@ -69,6 +69,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
||||
if (this._limit === undefined) {
|
||||
this._limit = (this.options.limit
|
||||
|| this.defaults.limit
|
||||
|| (this.widget_parent.action || {}).limit
|
||||
|| null);
|
||||
}
|
||||
return this._limit;
|
||||
@@ -94,7 +95,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
||||
self.do_delete(ids);
|
||||
},
|
||||
'action': function (e, action_name, id, callback) {
|
||||
self.do_action(action_name, id, callback);
|
||||
self.do_button_action(action_name, id, callback);
|
||||
},
|
||||
'row_link': function (e, id, dataset) {
|
||||
self.do_activate_record(dataset.index, id, dataset);
|
||||
@@ -399,11 +400,10 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
||||
* @param {Object} results results of evaluating domain and process for a search
|
||||
*/
|
||||
do_actual_search: function (results) {
|
||||
this.dataset.context = results.context;
|
||||
this.dataset.domain = results.domain;
|
||||
this.groups.datagroup = new openerp.base.DataGroup(
|
||||
this, this.model,
|
||||
results.domain, results.context,
|
||||
this.dataset.get_domain(results.domain),
|
||||
this.dataset.get_context(results.context),
|
||||
results.group_by);
|
||||
this.groups.datagroup.sort = this.dataset._sort;
|
||||
|
||||
@@ -454,17 +454,16 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
||||
* @param {Object} id id of the record the action should be called on
|
||||
* @param {Function} callback should be called after the action is executed, if non-null
|
||||
*/
|
||||
do_action: function (name, id, callback) {
|
||||
do_button_action: function (name, id, callback) {
|
||||
var self = this,
|
||||
action = _.detect(this.columns, function (field) {
|
||||
return field.name === name;
|
||||
});
|
||||
if (!action) { return; }
|
||||
this.execute_action(
|
||||
action, this.dataset, this.session.action_manager, id, function () {
|
||||
$.when(callback.apply(this, arguments).then(function () {
|
||||
self.compute_aggregates();
|
||||
}));
|
||||
this.execute_action(action, this.dataset, id, function () {
|
||||
$.when(callback.apply(this, arguments).then(function () {
|
||||
self.compute_aggregates();
|
||||
}));
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -476,11 +475,11 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
||||
*/
|
||||
do_activate_record: function (index, id, dataset) {
|
||||
var self = this;
|
||||
_.extend(this.dataset, {
|
||||
domain: dataset.domain,
|
||||
context: dataset.get_context()
|
||||
}).read_slice([], 0, false, function () {
|
||||
self.select_record(index);
|
||||
this.dataset.read_slice({
|
||||
context: dataset.get_context(),
|
||||
domain: dataset.get_domain()
|
||||
}, function () {
|
||||
self.select_record(index);
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -1034,10 +1033,11 @@ openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.bas
|
||||
d = new $.Deferred(),
|
||||
page = this.datagroup.openable ? this.page : view.page;
|
||||
|
||||
dataset.read_slice(
|
||||
_.filter(_.pluck(_.select(this.columns, function(x) {return x.tag == "field";}), 'name'), _.identity),
|
||||
page * limit, limit,
|
||||
function (records) {
|
||||
dataset.read_slice({
|
||||
fields: _.filter(_.pluck(_.select(this.columns, function(x) {return x.tag == "field";}), 'name'), _.identity),
|
||||
offset: page * limit,
|
||||
limit: limit
|
||||
}, function (records) {
|
||||
if (!self.datagroup.openable) {
|
||||
view.configure_pager(dataset);
|
||||
} else {
|
||||
|
||||
@@ -3,7 +3,6 @@ openerp.base.search = function(openerp) {
|
||||
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();
|
||||
this.dataset = dataset;
|
||||
this.model = dataset.model;
|
||||
this.view_id = view_id;
|
||||
@@ -624,39 +623,6 @@ openerp.base.search.CharField = openerp.base.search.Field.extend( /** @lends ope
|
||||
return this.$element.val();
|
||||
}
|
||||
});
|
||||
openerp.base.search.BooleanField = openerp.base.search.Field.extend({
|
||||
template: 'SearchView.field.selection',
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.attrs.selection = [
|
||||
['true', 'Yes'],
|
||||
['false', 'No']
|
||||
];
|
||||
},
|
||||
/**
|
||||
* Search defaults likely to be boolean values (for a boolean field).
|
||||
*
|
||||
* In the HTML, we only get strings, and our strings here are
|
||||
* <code>'true'</code> and <code>'false'</code>, so ensure we get only
|
||||
* those by truth-testing the default value.
|
||||
*
|
||||
* @param {Object} defaults default values for this search view
|
||||
*/
|
||||
render: function (defaults) {
|
||||
var name = this.attrs.name;
|
||||
if (name in defaults) {
|
||||
defaults[name] = defaults[name] ? "true" : "false";
|
||||
}
|
||||
return this._super(defaults);
|
||||
},
|
||||
get_value: function () {
|
||||
switch (this.$element.val()) {
|
||||
case 'false': return false;
|
||||
case 'true': return true;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
openerp.base.search.NumberField = openerp.base.search.Field.extend(/** @lends openerp.base.search.NumberField# */{
|
||||
get_value: function () {
|
||||
if (!this.$element.val()) {
|
||||
@@ -693,90 +659,73 @@ openerp.base.search.FloatField = openerp.base.search.NumberField.extend(/** @len
|
||||
return parseFloat(value);
|
||||
}
|
||||
});
|
||||
openerp.base.search.SelectionField = openerp.base.search.Field.extend({
|
||||
/**
|
||||
* @class
|
||||
* @extends openerp.base.search.Field
|
||||
*/
|
||||
openerp.base.search.SelectionField = openerp.base.search.Field.extend(/** @lends openerp.base.search.SelectionField# */{
|
||||
template: 'SearchView.field.selection',
|
||||
get_value: function () {
|
||||
return this.$element.val();
|
||||
}
|
||||
});
|
||||
openerp.base.search.BooleanField = openerp.base.search.SelectionField.extend(/** @lends openerp.base.search.BooleanField# */{
|
||||
/**
|
||||
* @constructs
|
||||
* @extends openerp.base.search.BooleanField
|
||||
*/
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.attrs.selection = [
|
||||
['true', 'Yes'],
|
||||
['false', 'No']
|
||||
];
|
||||
},
|
||||
/**
|
||||
* Search defaults likely to be boolean values (for a boolean field).
|
||||
*
|
||||
* In the HTML, we only want/get strings, and our strings here are ``true``
|
||||
* and ``false``, so ensure we use precisely those by truth-testing the
|
||||
* default value (iif there is one in the view's defaults).
|
||||
*
|
||||
* @param {Object} defaults default values for this search view
|
||||
* @returns {String} rendered boolean field
|
||||
*/
|
||||
render: function (defaults) {
|
||||
var name = this.attrs.name;
|
||||
if (name in defaults) {
|
||||
defaults[name] = defaults[name] ? "true" : "false";
|
||||
}
|
||||
return this._super(defaults);
|
||||
},
|
||||
get_value: function () {
|
||||
switch (this.$element.val()) {
|
||||
case 'false': return false;
|
||||
case 'true': return true;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
openerp.base.search.DateField = openerp.base.search.Field.extend( /** @lends openerp.base.search.DateField# */{
|
||||
template: 'SearchView.fields.date',
|
||||
/**
|
||||
* enables date picker on the HTML widgets
|
||||
*/
|
||||
start: function () {
|
||||
this._super();
|
||||
this.$element.find('input').datepicker({
|
||||
this.$element.addClass('field_date').datepicker({
|
||||
dateFormat: 'yy-mm-dd'
|
||||
});
|
||||
},
|
||||
stop: function () {
|
||||
this.$element.find('input').datepicker('destroy');
|
||||
this.$element.datepicker('destroy');
|
||||
},
|
||||
/**
|
||||
* Returns an object with two optional keys ``from`` and ``to`` providing
|
||||
* the values for resp. the from and to sections of the date widget.
|
||||
*
|
||||
* If a key is absent, then the corresponding field was not filled.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
get_values: function () {
|
||||
var values_array = this.$element.find('input').serializeArray();
|
||||
|
||||
if (!values_array || !values_array[0]) {
|
||||
throw new openerp.base.search.Invalid(
|
||||
this.attrs.name, null, "widget not ready");
|
||||
}
|
||||
var from = values_array[0].value,
|
||||
to = values_array[1].value;
|
||||
|
||||
var field_values = {};
|
||||
if (from) {
|
||||
field_values.from = from;
|
||||
}
|
||||
if (to) {
|
||||
field_values.to = to;
|
||||
}
|
||||
return field_values;
|
||||
},
|
||||
get_context: function () {
|
||||
var values = this.get_values();
|
||||
if (!this.attrs.context || _.isEmpty(values)) {
|
||||
return null;
|
||||
}
|
||||
return _.extend(
|
||||
{}, this.attrs.context,
|
||||
{own_values: {self: values}});
|
||||
},
|
||||
get_domain: function () {
|
||||
var values = this.get_values();
|
||||
if (_.isEmpty(values)) {
|
||||
return null;
|
||||
}
|
||||
var domain = this.attrs['filter_domain'];
|
||||
if (!domain) {
|
||||
domain = [];
|
||||
if (values.from) {
|
||||
domain.push([this.attrs.name, '>=', values.from]);
|
||||
}
|
||||
if (values.to) {
|
||||
domain.push([this.attrs.name, '<=', values.to]);
|
||||
}
|
||||
return domain;
|
||||
}
|
||||
|
||||
return _.extend(
|
||||
{}, domain,
|
||||
{own_values: {self: values}});
|
||||
get_value: function () {
|
||||
return this.$element.val();
|
||||
}
|
||||
});
|
||||
openerp.base.search.DateTimeField = openerp.base.search.DateField.extend({
|
||||
// TODO: time?
|
||||
});
|
||||
openerp.base.search.OneToManyField = openerp.base.search.CharField.extend({
|
||||
// TODO: .relation, .context, .domain
|
||||
});
|
||||
openerp.base.search.ManyToOneField = openerp.base.search.CharField.extend({
|
||||
// TODO: @widget
|
||||
// TODO: .selection, .context, .domain
|
||||
@@ -847,9 +796,6 @@ openerp.base.search.ManyToOneField = openerp.base.search.CharField.extend({
|
||||
return this._super();
|
||||
}
|
||||
});
|
||||
openerp.base.search.ManyToManyField = openerp.base.search.CharField.extend({
|
||||
// TODO: .related_columns (Array), .context, .domain
|
||||
});
|
||||
|
||||
openerp.base.search.ExtendedSearch = openerp.base.OldWidget.extend({
|
||||
template: 'SearchView.extended_search',
|
||||
|
||||
@@ -72,7 +72,7 @@ openerp.base.TreeView = openerp.base.View.extend({
|
||||
'toolbar': has_toolbar
|
||||
}));
|
||||
|
||||
this.dataset.read_slice(this.fields_list(), 0, false, function (records) {
|
||||
this.dataset.read_slice({fields: this.fields_list()}, function (records) {
|
||||
if (!has_toolbar) {
|
||||
// WARNING: will do a second read on the same ids, but only on
|
||||
// first load so not very important
|
||||
@@ -177,7 +177,7 @@ openerp.base.TreeView = openerp.base.View.extend({
|
||||
if (!actions.length) { return; }
|
||||
var action = actions[0][2];
|
||||
action.flags.new_window = true;
|
||||
self.session.action_manager.do_action(action);
|
||||
self.do_action(action);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -9,27 +9,6 @@ openerp.base.views = function(openerp) {
|
||||
*/
|
||||
openerp.base.client_actions = new openerp.base.Registry();
|
||||
|
||||
/**
|
||||
* Registry for all the main views
|
||||
*/
|
||||
openerp.base.views = new openerp.base.Registry();
|
||||
|
||||
openerp.base.ActionDialog = openerp.base.Dialog.extend({
|
||||
identifier_prefix: 'action_dialog',
|
||||
on_close: function() {
|
||||
this._super(this, arguments);
|
||||
if (this.close_callback) {
|
||||
this.close_callback();
|
||||
}
|
||||
},
|
||||
stop: function() {
|
||||
this._super(this, arguments);
|
||||
if (this.viewmanager) {
|
||||
this.viewmanager.stop();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.ActionManager = openerp.base.Widget.extend({
|
||||
identifier_prefix: "actionmanager",
|
||||
init: function(parent) {
|
||||
@@ -68,25 +47,24 @@ openerp.base.ActionManager = openerp.base.Widget.extend({
|
||||
pager : !popup
|
||||
}, action.flags || {});
|
||||
if (!(type in this)) {
|
||||
console.log("Action manager can't handle action of type " + action.type, action);
|
||||
this.log("Action manager can't handle action of type " + action.type, action);
|
||||
return;
|
||||
}
|
||||
this[type](action, on_closed);
|
||||
this[type](action, on_close);
|
||||
},
|
||||
ir_actions_act_window: function (action, on_closed) {
|
||||
ir_actions_act_window: function (action, on_close) {
|
||||
if (action.flags.popup) {
|
||||
if (this.dialog == null) {
|
||||
this.dialog = new openerp.base.ActionDialog(this, { title: action.name, width: '80%' });
|
||||
this.dialog.close_callback = on_closed;
|
||||
this.dialog.start(false);
|
||||
this.dialog_viewmanager = new openerp.base.ViewManagerAction(this, action);
|
||||
this.dialog_viewmanager.appendTo(this.dialog.$element);
|
||||
this.dialog.open();
|
||||
this.dialog = new openerp.base.Dialog(this, { title: action.name, width: '80%' });
|
||||
if(on_close)
|
||||
this.dialog.on_close.add(on_close);
|
||||
this.dialog.start();
|
||||
} else {
|
||||
this.dialog_viewmanager.stop();
|
||||
this.dialog_viewmanager = new openerp.base.ViewManagerAction(this, action);
|
||||
this.dialog_viewmanager.appendTo(this.dialog.$element);
|
||||
}
|
||||
this.dialog_viewmanager = new openerp.base.ViewManagerAction(this, action);
|
||||
this.dialog_viewmanager.appendTo(this.dialog.$element);
|
||||
this.dialog.open();
|
||||
} else {
|
||||
this.dialog_stop();
|
||||
this.inner_stop();
|
||||
@@ -101,7 +79,7 @@ openerp.base.ActionManager = openerp.base.Widget.extend({
|
||||
*/
|
||||
},
|
||||
ir_actions_act_window_close: function (action, on_closed) {
|
||||
this.close_dialog();
|
||||
this.dialog_stop();
|
||||
},
|
||||
ir_actions_server: function (action, on_closed) {
|
||||
var self = this;
|
||||
@@ -253,9 +231,8 @@ openerp.base.ViewManager = openerp.base.Widget.extend({
|
||||
this.searchview.hide();
|
||||
}
|
||||
this.searchview.on_search.add(function(domains, contexts, groupbys) {
|
||||
self.views[self.active_view].controller.do_search.call(
|
||||
self, domains.concat(self.domains()),
|
||||
contexts.concat(self.contexts()), groupbys);
|
||||
var controller = self.views[self.active_view].controller;
|
||||
controller.do_search.call(controller, domains, contexts, groupbys);
|
||||
});
|
||||
return this.searchview.start();
|
||||
},
|
||||
@@ -269,49 +246,19 @@ openerp.base.ViewManager = openerp.base.Widget.extend({
|
||||
on_remove: function() {
|
||||
},
|
||||
on_edit: function() {
|
||||
},
|
||||
/**
|
||||
* Domains added on searches by the view manager, to override in subsequent
|
||||
* view manager in order to add new pieces of domains to searches
|
||||
*
|
||||
* @returns an empty list
|
||||
*/
|
||||
domains: function () {
|
||||
return [];
|
||||
},
|
||||
/**
|
||||
* Contexts added on searches by the view manager.
|
||||
*
|
||||
* @returns an empty list
|
||||
*/
|
||||
contexts: function () {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.NullViewManager = openerp.base.generate_null_object_class(openerp.base.ViewManager, {
|
||||
init: function(parent) {
|
||||
this._super(parent);
|
||||
if(parent)
|
||||
this.session = parent.session;
|
||||
this.action = {flags: {}};
|
||||
}
|
||||
});
|
||||
|
||||
// Move parts or everything to ActionManager
|
||||
openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
|
||||
init: function(parent, action) {
|
||||
this.session = parent.session;
|
||||
var dataset;
|
||||
if (!action.res_id) {
|
||||
dataset = new openerp.base.DataSetSearch(this, action.res_model, action.context || null, action.domain || null);
|
||||
dataset = new openerp.base.DataSetSearch(this, action.res_model, action.context, action.domain);
|
||||
} else {
|
||||
dataset = new openerp.base.DataSetStatic(this, action.res_model, {}, [action.res_id]);
|
||||
if (action.context) {
|
||||
// TODO fme: should normalize all DataSets constructors to (session, model, context, domain, ...)
|
||||
dataset.context = action.context;
|
||||
}
|
||||
dataset = new openerp.base.DataSetStatic(this, action.res_model, action.context, [action.res_id]);
|
||||
}
|
||||
this.action = action;
|
||||
this._super(parent, dataset, action.views);
|
||||
this.action = action;
|
||||
this.flags = this.action.flags || {};
|
||||
@@ -344,28 +291,6 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
|
||||
.then(this.searchview.do_search);
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* adds action domain to the search domains
|
||||
*
|
||||
* @returns the action's domain
|
||||
*/
|
||||
domains: function () {
|
||||
if (!this.action.domain) {
|
||||
return [];
|
||||
}
|
||||
return [this.action.domain];
|
||||
},
|
||||
/**
|
||||
* adds action context to the search contexts
|
||||
*
|
||||
* @returns the action's context
|
||||
*/
|
||||
contexts: function () {
|
||||
if (!this.action.context) {
|
||||
return [];
|
||||
}
|
||||
return [this.action.context];
|
||||
}
|
||||
});
|
||||
|
||||
@@ -475,11 +400,10 @@ openerp.base.View = openerp.base.Widget.extend({
|
||||
* @param {String} [action_data.type='workflow'] the action type, if present, one of ``'object'``, ``'action'`` or ``'workflow'``
|
||||
* @param {Object} [action_data.context=null] additional action context, to add to the current context
|
||||
* @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_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_closed) {
|
||||
execute_action: function (action_data, dataset, record_id, on_closed) {
|
||||
var self = this;
|
||||
var handler = function (r) {
|
||||
var action = r.result;
|
||||
@@ -497,8 +421,9 @@ openerp.base.View = openerp.base.Widget.extend({
|
||||
};
|
||||
|
||||
var context = new openerp.base.CompoundContext(dataset.get_context(), action_data.context || {});
|
||||
|
||||
if (action_data.special) {
|
||||
// dunno
|
||||
handler({result: {"type":"ir.actions.act_window_close"}});
|
||||
} else if (action_data.type=="object") {
|
||||
return dataset.call_button(action_data.name, [[record_id], context], handler);
|
||||
} else if (action_data.type=="action") {
|
||||
@@ -563,16 +488,16 @@ openerp.base.View = openerp.base.Widget.extend({
|
||||
}
|
||||
},
|
||||
on_sidebar_edit_workflow: function() {
|
||||
console.log('Todo');
|
||||
this.log('Todo');
|
||||
},
|
||||
on_sidebar_customize_object: function() {
|
||||
console.log('Todo');
|
||||
this.log('Todo');
|
||||
},
|
||||
on_sidebar_import: function() {
|
||||
},
|
||||
on_sidebar_export: function() {
|
||||
var export_view = new openerp.base.DataExport(this, this.dataset);
|
||||
export_view.start(false);
|
||||
export_view.start();
|
||||
},
|
||||
on_sidebar_translate: function() {
|
||||
},
|
||||
@@ -580,6 +505,11 @@ openerp.base.View = openerp.base.Widget.extend({
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Registry for all the main views
|
||||
*/
|
||||
openerp.base.views = new openerp.base.Registry();
|
||||
|
||||
openerp.base.json_node_to_xml = function(node, single_quote, indent) {
|
||||
// For debugging purpose, this function will convert a json node back to xml
|
||||
// Maybe usefull for xml view editor
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
</table>
|
||||
<table align="center" class="db_option_table">
|
||||
<tr>
|
||||
<td><label for="super_admin_pwd">Super admin password:</label></td>
|
||||
<td><label for="super_admin_pwd">Master password:</label></td>
|
||||
<td><input type="password" name="super_admin_pwd"
|
||||
class="required" autofocus="autofocus"/></td>
|
||||
</tr>
|
||||
@@ -103,7 +103,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="create_admin_pwd">Super admin password:</label></td>
|
||||
<td><label for="create_admin_pwd">Admin password:</label></td>
|
||||
<td><input type="password" name="create_admin_pwd" class="required"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -138,7 +138,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="drop_password">Password:</label></td>
|
||||
<td><label for="drop_password">Master Password:</label></td>
|
||||
<td><input type="password" name="drop_pwd" class="required"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -170,7 +170,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="backup_pwd">Password:</label></td>
|
||||
<td><label for="backup_pwd">Master Password:</label></td>
|
||||
<td><input type="password" name="backup_pwd" class="required"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -195,7 +195,7 @@
|
||||
autofocus="autofocus"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="restore_pwd">Password:</label></td>
|
||||
<td><label for="restore_pwd">Master Password:</label></td>
|
||||
<td><input type="password" name="restore_pwd" class="required"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -213,23 +213,23 @@
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td class="option_string">
|
||||
CHANGE DATABASE PASSWORD
|
||||
CHANGE MASTER PASSWORD
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table align="center" class="db_option_table">
|
||||
<tr>
|
||||
<td><label for="old_pwd">Old password:</label></td>
|
||||
<td><label for="old_pwd">Master password:</label></td>
|
||||
<td><input type="password" name="old_pwd" class="required"
|
||||
minlength="1" autofocus="autofocus"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="new_pwd">New password:</label></td>
|
||||
<td><label for="new_pwd">New master password:</label></td>
|
||||
<td><input type="password" name="new_pwd" class="required"
|
||||
minlength="1"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="confirm_pwd">Confirm password:</label></td>
|
||||
<td><label for="confirm_pwd">Confirm new master password:</label></td>
|
||||
<td><input type="password" name="confirm_pwd" class="required"
|
||||
equalTo="input[name=new_pwd]" minlength="1"/></td>
|
||||
</tr>
|
||||
@@ -547,14 +547,9 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
<t t-name="ListView.rows" t-foreach="rows" t-as="row">
|
||||
<t t-call="ListView.row">
|
||||
<t t-set="style" t-value="null"/>
|
||||
<t-if test="row.color">
|
||||
<t t-set="style" t-value="'color: ' + row.color"/>
|
||||
</t-if>
|
||||
</t>
|
||||
<t t-call="ListView.row"/>
|
||||
</t>
|
||||
<tr t-name="ListView.row" t-att-style="style" t-att-class="row_parity"
|
||||
<tr t-name="ListView.row" t-att-class="row_parity"
|
||||
t-att-data-index="row_index">
|
||||
<t t-foreach="columns" t-as="column">
|
||||
<td t-if="column.meta">
|
||||
@@ -968,22 +963,6 @@
|
||||
<t t-if="filters.length" t-raw="filters.render(defaults)"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="SearchView.fields.date">
|
||||
<label style="display: block" t-att-title="attrs.help"
|
||||
t-att-for="element_id">
|
||||
<t t-esc="attrs.string || attrs.name"/>
|
||||
<span t-if="attrs.help">(?)</span>
|
||||
</label>
|
||||
<div style="white-space: nowrap;" t-att-id="element_id">
|
||||
<input t-att-name="attrs.name" type="text" class="field_date"
|
||||
t-att-value="defaults[attrs.name] || ''"
|
||||
t-att-autofocus="attrs.default_focus === '1' ? 'autofocus' : undefined"/>
|
||||
to
|
||||
<input t-att-name="attrs.name" type="text" class="field_date"
|
||||
t-att-value="defaults[attrs.name] || ''"/>
|
||||
<t t-if="filters.length" t-raw="filters.render(defaults)"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="SearchView.field.selection">
|
||||
<label style="display: block" t-att-title="attrs.help"
|
||||
t-att-for="element_id">
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
$(document).ready(function () {
|
||||
var openerp;
|
||||
function get_widget(attrs) {
|
||||
var widget = new openerp.base.search.DateField(
|
||||
{attrs: attrs}, {name: 'foo'}, {inputs: []});
|
||||
$('#qunit-fixture').html(widget.render({}));
|
||||
widget.start();
|
||||
return widget;
|
||||
}
|
||||
|
||||
module('search-date', {
|
||||
setup: function () {
|
||||
openerp = window.openerp.init(true);
|
||||
window.openerp.base.core(openerp);
|
||||
window.openerp.base.chrome(openerp);
|
||||
window.openerp.base.views(openerp);
|
||||
window.openerp.base.search(openerp);
|
||||
}
|
||||
});
|
||||
test('no values', function () {
|
||||
var widget = get_widget();
|
||||
deepEqual(widget.get_values(), {});
|
||||
strictEqual(widget.get_context(), null);
|
||||
strictEqual(widget.get_domain(), null);
|
||||
});
|
||||
test('filled from', function () {
|
||||
var widget = get_widget();
|
||||
widget.$element.find('input:eq(0)').val('1912-06-23');
|
||||
|
||||
deepEqual(widget.get_values(), {from: '1912-06-23'});
|
||||
strictEqual(widget.get_context(), null);
|
||||
deepEqual(widget.get_domain(), [['foo', '>=', '1912-06-23']]);
|
||||
});
|
||||
test('filled to', function () {
|
||||
var widget = get_widget();
|
||||
widget.$element.find('input:eq(1)').val('1954-06-07');
|
||||
|
||||
deepEqual(widget.get_values(), {to: '1954-06-07'});
|
||||
strictEqual(widget.get_context(), null);
|
||||
deepEqual(widget.get_domain(), [['foo', '<=', '1954-06-07']]);
|
||||
});
|
||||
test('filled both', function () {
|
||||
var widget = get_widget();
|
||||
widget.$element.find('input:eq(0)').val('1912-06-23');
|
||||
widget.$element.find('input:eq(1)').val('1954-06-07');
|
||||
|
||||
deepEqual(widget.get_values(), {from: '1912-06-23', to: '1954-06-07'});
|
||||
strictEqual(widget.get_context(), null);
|
||||
deepEqual(widget.get_domain(),
|
||||
[['foo', '>=', '1912-06-23'], ['foo', '<=', '1954-06-07']]);
|
||||
});
|
||||
test('custom context', function () {
|
||||
var widget = get_widget({context: {__id: -1}});
|
||||
widget.$element.find('input:eq(0)').val('1912-06-23');
|
||||
widget.$element.find('input:eq(1)').val('1954-06-07');
|
||||
|
||||
deepEqual(
|
||||
widget.get_context(),
|
||||
{__id: -1,
|
||||
own_values: {
|
||||
self: {from: '1912-06-23', to: '1954-06-07'}}});
|
||||
});
|
||||
test('custom filter_domain', function () {
|
||||
var widget = get_widget({filter_domain: {__id: -42}});
|
||||
widget.$element.find('input:eq(0)').val('1912-06-23');
|
||||
widget.$element.find('input:eq(1)').val('1954-06-07');
|
||||
|
||||
deepEqual(
|
||||
widget.get_domain(),
|
||||
{__id: -42,
|
||||
own_values: {
|
||||
self: {from: '1912-06-23', to: '1954-06-07'}}});
|
||||
});
|
||||
});
|
||||
@@ -39,6 +39,5 @@
|
||||
</body>
|
||||
<script type="text/javascript" src="/base/static/test/class.js"></script>
|
||||
<script type="text/javascript" src="/base/static/test/registry.js"></script>
|
||||
<script type="text/javascript" src="/base/static/test/search-date.js"></script>
|
||||
<script type="text/javascript" src="/base/static/test/form.js"></script>
|
||||
</html>
|
||||
|
||||
@@ -48,14 +48,19 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({
|
||||
this.fields = this.fields_view.fields;
|
||||
|
||||
//* Calendar Fields *
|
||||
this.calendar_fields['date_start'] = {'name': this.date_start, 'kind': this.fields[this.date_start]['type']};
|
||||
this.calendar_fields.date_start = {'name': this.date_start, 'kind': this.fields[this.date_start].type};
|
||||
|
||||
if (this.date_delay) {
|
||||
this.calendar_fields['date_delay'] = {'name': this.date_delay, 'kind': this.fields[this.date_delay]['type']};
|
||||
if (this.fields[this.date_delay].type != 'float') {
|
||||
throw new Error("Calendar view has a 'date_delay' type != float");
|
||||
}
|
||||
this.calendar_fields.date_delay = {'name': this.date_delay, 'kind': this.fields[this.date_delay].type};
|
||||
}
|
||||
|
||||
if (this.date_stop) {
|
||||
this.calendar_fields['date_stop'] = {'name': this.date_stop, 'kind': this.fields[this.date_stop]['type']};
|
||||
this.calendar_fields.date_stop = {'name': this.date_stop, 'kind': this.fields[this.date_stop].type};
|
||||
}
|
||||
if (!this.date_delay && !this.date_stop) {
|
||||
throw new Error("Calendar view has none of the following attributes : 'date_stop', 'date_delay'");
|
||||
}
|
||||
|
||||
for (var fld = 0; fld < this.fields_view.arch.children.length; fld++) {
|
||||
@@ -126,7 +131,7 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({
|
||||
},
|
||||
load_scheduler: function() {
|
||||
var self = this;
|
||||
this.dataset.read_slice([], 0, false, function(events) {
|
||||
this.dataset.read_slice({}, function(events) {
|
||||
if (self.session.locale_code) {
|
||||
// TODO: replace $LAB
|
||||
$LAB.setOptions({AlwaysPreserveOrder: true}).script([
|
||||
@@ -307,10 +312,9 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({
|
||||
var data = {
|
||||
name: event_obj.text
|
||||
};
|
||||
var date_format = this.calendar_fields.date_start.kind == 'time' ? 'HH:mm:ss' : 'yyyy-MM-dd HH:mm:ss';
|
||||
data[this.date_start] = event_obj.start_date.toString(date_format);
|
||||
data[this.date_start] = openerp.base.format_datetime(event_obj.start_date);
|
||||
if (this.date_stop) {
|
||||
data[this.date_stop] = event_obj.end_date.toString(date_format);
|
||||
data[this.date_stop] = openerp.base.format_datetime(event_obj.end_date);
|
||||
}
|
||||
if (this.date_delay) {
|
||||
var tds = (event_obj.start_date.getOrdinalNumber() / 1e3 >> 0) - (event_obj.start_date.getOrdinalNumber() < 0);
|
||||
@@ -327,15 +331,21 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({
|
||||
},
|
||||
do_search: function(domains, contexts, groupbys) {
|
||||
var self = this;
|
||||
this.rpc('/base/session/eval_domain_and_context', {
|
||||
domains: domains,
|
||||
contexts: contexts,
|
||||
group_by_seq: groupbys
|
||||
}, function (results) {
|
||||
// TODO: handle non-empty results.group_by with read_group
|
||||
self.dataset.context = self.context = results.context;
|
||||
self.dataset.domain = self.domain = results.domain;
|
||||
self.dataset.read_slice(_.keys(self.fields), 0, self.limit, self.on_events_loaded);
|
||||
$.when(this.has_been_loaded).then(function() {
|
||||
self.rpc('/base/session/eval_domain_and_context', {
|
||||
domains: domains,
|
||||
contexts: contexts,
|
||||
group_by_seq: groupbys
|
||||
}, function (results) {
|
||||
// TODO: handle non-empty results.group_by with read_group
|
||||
self.dataset.context = self.context = results.context;
|
||||
self.dataset.domain = self.domain = results.domain;
|
||||
self.dataset.read_slice({
|
||||
fields: _.keys(self.fields),
|
||||
offset:0,
|
||||
limit: self.limit
|
||||
}, self.on_events_loaded);
|
||||
});
|
||||
});
|
||||
},
|
||||
do_show: function () {
|
||||
@@ -411,7 +421,7 @@ openerp.base_calendar.CalendarFormDialog = openerp.base.Dialog.extend({
|
||||
this.view = view;
|
||||
},
|
||||
start: function() {
|
||||
this._super(false);
|
||||
this._super();
|
||||
this.form = new openerp.base.FormView(this, this.element_id, this.dataset, this.view_id, {
|
||||
sidebar: false,
|
||||
pager: false
|
||||
|
||||
@@ -290,7 +290,7 @@ openerp.base_dashboard.ConfigOverview = openerp.base.View.extend({
|
||||
this.dataset.domain = [['type', '=', 'manual']];
|
||||
},
|
||||
start: function () {
|
||||
$.when(this.dataset.read_slice(['state', 'action_id', 'category_id']),
|
||||
$.when(this.dataset.read_slice({fields: ['state', 'action_id', 'category_id']}),
|
||||
this.dataset.call('progress'))
|
||||
.then(this.on_records_loaded);
|
||||
},
|
||||
@@ -333,7 +333,6 @@ openerp.base_dashboard.ConfigOverview = openerp.base.View.extend({
|
||||
type: 'object',
|
||||
name: 'action_launch'
|
||||
}, self.dataset,
|
||||
self.session.action_manager,
|
||||
$(this).data('id'), function () {
|
||||
// after action popup closed, refresh configuration
|
||||
// thingie
|
||||
@@ -354,8 +353,8 @@ openerp.base_dashboard.ApplicationTiles = openerp.base.View.extend({
|
||||
start: function () {
|
||||
var self = this;
|
||||
this.dataset.read_slice(
|
||||
['name', 'web_icon_data', 'web_icon_hover_data'],
|
||||
null, null, function (applications) {
|
||||
{fields: ['name', 'web_icon_data', 'web_icon_hover_data']},
|
||||
function (applications) {
|
||||
// Create a matrix of 3*x applications
|
||||
var rows = [];
|
||||
while (applications.length) {
|
||||
@@ -385,7 +384,8 @@ openerp.base_dashboard.Widgets = openerp.base.View.extend({
|
||||
this.widgets = new openerp.base.DataSetSearch(this, 'res.widget');
|
||||
},
|
||||
start: function () {
|
||||
this.user_widgets.read_slice(['widget_id', 'user_id'], null, null,
|
||||
this.user_widgets.read_slice(
|
||||
{fields: ['widget_id', 'user_id']},
|
||||
this.on_widgets_list_loaded);
|
||||
},
|
||||
on_widgets_list_loaded: function (user_widgets) {
|
||||
|
||||
@@ -86,7 +86,7 @@ openerp.base_default_home = function (openerp) {
|
||||
$.blockUI({
|
||||
message: '<img src="/base_default_home/static/src/img/throbber.gif">'
|
||||
});
|
||||
Modules.read_slice(['id'], null, null, function (records) {
|
||||
Modules.read_slice({fields: ['id']}, function (records) {
|
||||
if (!(records.length === 1)) { return; }
|
||||
Modules.call('state_update',
|
||||
[_.pluck(records, 'id'), 'to install', ['uninstalled']],
|
||||
|
||||
@@ -81,7 +81,7 @@ init: function(view_manager, session, element_id, dataset, view_id) {
|
||||
get_events: function() {
|
||||
|
||||
var self = this;
|
||||
this.dataset.read_slice(false, false, false, function(result) {
|
||||
this.dataset.read_slice({}, function(result) {
|
||||
self.load_event(result);
|
||||
});
|
||||
|
||||
@@ -460,7 +460,7 @@ init: function(view_manager, session, element_id, dataset, view_id) {
|
||||
|
||||
reload_gantt: function() {
|
||||
var self = this;
|
||||
this.dataset.read_slice(false, false, false, function(response) {
|
||||
this.dataset.read_slice({}, function(response) {
|
||||
ganttChartControl.clearAll();
|
||||
jQuery("#GanttDiv").children().remove();
|
||||
self.load_event(response);
|
||||
|
||||
@@ -89,7 +89,7 @@ openerp.base_graph.GraphView = openerp.base.View.extend({
|
||||
}
|
||||
this.dataset.domain = domain;
|
||||
this.dataset.context = this.view_manager.dataset.context;
|
||||
this.dataset.read_slice(_(this.fields).keys(), 0, false, function(res) {
|
||||
this.dataset.read_slice({fields: _(this.fields).keys()}, function(res) {
|
||||
self.schedule_chart(res);
|
||||
});
|
||||
}
|
||||
@@ -442,7 +442,7 @@ openerp.base_graph.GraphView = openerp.base.View.extend({
|
||||
}
|
||||
views.push(view);
|
||||
});
|
||||
this.session.action_manager.do_action({
|
||||
this.do_action({
|
||||
"res_model" : this.dataset.model,
|
||||
"domain" : this.dataset.domain,
|
||||
"views" : views,
|
||||
@@ -468,9 +468,7 @@ openerp.base_graph.GraphView = openerp.base.View.extend({
|
||||
}
|
||||
self.dataset.context = results.context;
|
||||
self.dataset.domain = results.domain;
|
||||
self.dataset.read_slice([], 0, false,function(response){
|
||||
self.load_chart(response);
|
||||
});
|
||||
self.dataset.read_slice({}, $.proxy(self, 'load_chart'));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ openerp.web_mobile.FormView = openerp.base.Widget.extend({
|
||||
view_id = this.action.views[1][0];
|
||||
|
||||
this.dataset = new openerp.base.DataSetSearch(this.session, this.action.res_model, null, null);
|
||||
this.dataset.read_slice(false, false, false, function (result) {
|
||||
this.dataset.read_slice({}, function (result) {
|
||||
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
if (result[i].id == id) {
|
||||
@@ -101,4 +101,4 @@ openerp.web_mobile.FormView = openerp.base.Widget.extend({
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user