[MERGE] Merge with trunk upto revision no 833.
bzr revid: ysa@tinyerp.com-20110819055354-jupt8bp7zaf4jn7k
This commit is contained in:
commit
cce6a3f6b9
|
@ -67,7 +67,6 @@ def manifest_glob(addons, key):
|
|||
files = []
|
||||
for addon in addons:
|
||||
globlist = openerpweb.addons_manifest.get(addon, {}).get(key, [])
|
||||
print globlist
|
||||
for pattern in globlist:
|
||||
for path in glob.glob(os.path.join(openerpweb.path_addons, addon, pattern)):
|
||||
files.append(path[len(openerpweb.path_addons):])
|
||||
|
@ -79,35 +78,36 @@ def concat_files(file_list):
|
|||
concat: concatenation of file content
|
||||
timestamp: max(os.path.getmtime of file_list)
|
||||
"""
|
||||
root = openerpweb.path_root
|
||||
files_content = []
|
||||
files_timestamp = 0
|
||||
for i in file_list:
|
||||
fname = os.path.join(root, i)
|
||||
fname = os.path.join(openerpweb.path_addons, i[1:])
|
||||
ftime = os.path.getmtime(fname)
|
||||
if ftime > files_timestamp:
|
||||
files_timestamp = ftime
|
||||
files_content = open(fname).read()
|
||||
files_content.append(open(fname).read())
|
||||
files_concat = "".join(files_content)
|
||||
return files_concat
|
||||
return (files_concat,files_timestamp)
|
||||
|
||||
home_template = textwrap.dedent("""<!DOCTYPE html>
|
||||
<html style="height: 100%%">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>OpenERP</title>
|
||||
%(javascript)s
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
QWeb = new QWeb2.Engine();
|
||||
openerp.init().base.webclient("oe");
|
||||
});
|
||||
</script>
|
||||
<link rel="shortcut icon" href="/base/static/src/img/favicon.ico" type="image/x-icon"/>
|
||||
%(css)s
|
||||
<!--[if lte IE 7]>
|
||||
<link rel="stylesheet" href="/base/static/src/css/base-ie7.css" type="text/css"/>
|
||||
<![endif]-->
|
||||
%(javascript)s
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
QWeb = new QWeb2.Engine();
|
||||
var c = new openerp.init();
|
||||
var wc = new c.base.WebClient("oe");
|
||||
wc.start();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body id="oe" class="openerp"></body>
|
||||
</html>
|
||||
|
@ -125,31 +125,31 @@ class WebClient(openerpweb.Controller):
|
|||
|
||||
@openerpweb.httprequest
|
||||
def css(self, req, mods='base'):
|
||||
cherrypy.response.headers['Content-Type'] = 'text/css'
|
||||
req.httpresponse.headers['Content-Type'] = 'text/css'
|
||||
files = manifest_glob(mods.split(','), 'css')
|
||||
concat = concat_files(files)[0]
|
||||
content,timestamp = concat_files(files)
|
||||
# TODO request set the Date of last modif and Etag
|
||||
return concat
|
||||
return content
|
||||
|
||||
@openerpweb.httprequest
|
||||
def js(self, req, mods='base'):
|
||||
cherrypy.response.headers['Content-Type'] = 'application/javascript'
|
||||
req.httpresponse.headers['Content-Type'] = 'application/javascript'
|
||||
files = manifest_glob(mods.split(','), 'js')
|
||||
concat = concat_files(files)[0]
|
||||
content,timestamp = concat_files(files)
|
||||
# TODO request set the Date of last modif and Etag
|
||||
return concat
|
||||
return content
|
||||
|
||||
@openerpweb.httprequest
|
||||
def home(self, req, s_action=None):
|
||||
# script tags
|
||||
jslist = ['/base/webclient/js']
|
||||
if 1: # debug == 1
|
||||
if req.debug:
|
||||
jslist = manifest_glob(['base'], 'js')
|
||||
js = "\n ".join(['<script type="text/javascript" src="%s"></script>'%i for i in jslist])
|
||||
|
||||
# css tags
|
||||
csslist = ['/base/webclient/css']
|
||||
if 1: # debug == 1
|
||||
if req.debug:
|
||||
csslist = manifest_glob(['base'], 'css')
|
||||
css = "\n ".join(['<link rel="stylesheet" href="%s">'%i for i in csslist])
|
||||
r = home_template % {
|
||||
|
@ -157,7 +157,7 @@ class WebClient(openerpweb.Controller):
|
|||
'css': css
|
||||
}
|
||||
return r
|
||||
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def translations(self, req, mods, lang):
|
||||
lang_model = req.session.model('res.lang')
|
||||
|
@ -193,7 +193,6 @@ class WebClient(openerpweb.Controller):
|
|||
transl["messages"].append({'id': x.id, 'string': x.string})
|
||||
return {"modules": transs,
|
||||
"lang_parameters": lang_obj}
|
||||
|
||||
|
||||
class Database(openerpweb.Controller):
|
||||
_cp_path = "/base/database"
|
||||
|
@ -249,16 +248,16 @@ class Database(openerpweb.Controller):
|
|||
try:
|
||||
db_dump = base64.decodestring(
|
||||
req.session.proxy("db").dump(backup_pwd, backup_db))
|
||||
cherrypy.response.headers['Content-Type'] = "application/octet-stream; charset=binary"
|
||||
cherrypy.response.headers['Content-Disposition'] = 'attachment; filename="' + backup_db + '.dump"'
|
||||
cherrypy.response.cookie['fileToken'] = token
|
||||
cherrypy.response.cookie['fileToken']['path'] = '/'
|
||||
req.httpresponse.headers['Content-Type'] = "application/octet-stream; charset=binary"
|
||||
req.httpresponse.headers['Content-Disposition'] = 'attachment; filename="' + backup_db + '.dump"'
|
||||
req.httpresponse.cookie['fileToken'] = token
|
||||
req.httpresponse.cookie['fileToken']['path'] = '/'
|
||||
return db_dump
|
||||
except xmlrpclib.Fault, e:
|
||||
if e.faultCode and e.faultCode.split(':')[0] == 'AccessDenied':
|
||||
return 'Backup Database|' + e.faultCode
|
||||
return 'Backup Database|Could not generate database backup'
|
||||
|
||||
|
||||
@openerpweb.httprequest
|
||||
def restore(self, req, db_file, restore_pwd, new_db):
|
||||
try:
|
||||
|
@ -267,9 +266,7 @@ class Database(openerpweb.Controller):
|
|||
return ''
|
||||
except xmlrpclib.Fault, e:
|
||||
if e.faultCode and e.faultCode.split(':')[0] == 'AccessDenied':
|
||||
raise cherrypy.HTTPError(403)
|
||||
|
||||
raise cherrypy.HTTPError()
|
||||
raise Exception("AccessDenied")
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def change_password(self, req, fields):
|
||||
|
@ -386,10 +383,10 @@ class Session(openerpweb.Controller):
|
|||
:return: A key identifying the saved action.
|
||||
:rtype: integer
|
||||
"""
|
||||
saved_actions = cherrypy.session.get('saved_actions')
|
||||
saved_actions = req.httpsession.get('saved_actions')
|
||||
if not saved_actions:
|
||||
saved_actions = {"next":0, "actions":{}}
|
||||
cherrypy.session['saved_actions'] = saved_actions
|
||||
req.httpsession['saved_actions'] = saved_actions
|
||||
# we don't allow more than 10 stored actions
|
||||
if len(saved_actions["actions"]) >= 10:
|
||||
del saved_actions["actions"][min(saved_actions["actions"].keys())]
|
||||
|
@ -409,7 +406,7 @@ class Session(openerpweb.Controller):
|
|||
:return: The saved action or None.
|
||||
:rtype: anything
|
||||
"""
|
||||
saved_actions = cherrypy.session.get('saved_actions')
|
||||
saved_actions = req.httpsession.get('saved_actions')
|
||||
if not saved_actions:
|
||||
return None
|
||||
return saved_actions["actions"].get(key)
|
||||
|
@ -439,18 +436,16 @@ def clean_action(action, session, context=None):
|
|||
return action
|
||||
# values come from the server, we can just eval them
|
||||
if isinstance(action.get('context'), basestring):
|
||||
action['context'] = eval(
|
||||
action['context'],
|
||||
session.evaluation_context(context=context)) or {}
|
||||
localvars = session.evaluation_context(context=context)
|
||||
action['context'] = eval( action['context'], localvars ) or {}
|
||||
|
||||
if isinstance(action.get('domain'), basestring):
|
||||
action['domain'] = eval(
|
||||
action['domain'],
|
||||
session.evaluation_context(
|
||||
action.get('context', {}))) or []
|
||||
localvars = session.evaluation_context( action.get('context', {}))
|
||||
action['domain'] = eval( action['domain'], localvars ) or []
|
||||
|
||||
return fix_view_modes(action)
|
||||
|
||||
# I think generate_views,fix_view_modes should go into js ActionManager
|
||||
def generate_views(action):
|
||||
"""
|
||||
While the server generates a sequence called "views" computing dependencies
|
||||
|
@ -947,10 +942,10 @@ class Binary(openerpweb.Controller):
|
|||
_cp_path = "/base/binary"
|
||||
|
||||
@openerpweb.httprequest
|
||||
def image(self, request, model, id, field, **kw):
|
||||
cherrypy.response.headers['Content-Type'] = 'image/png'
|
||||
Model = request.session.model(model)
|
||||
context = request.session.eval_context(request.context)
|
||||
def image(self, req, model, id, field, **kw):
|
||||
req.httpresponse.headers['Content-Type'] = 'image/png'
|
||||
Model = req.session.model(model)
|
||||
context = req.session.eval_context(req.context)
|
||||
try:
|
||||
if not id:
|
||||
res = Model.default_get([field], context).get(field, '')
|
||||
|
@ -963,26 +958,26 @@ class Binary(openerpweb.Controller):
|
|||
return open(os.path.join(openerpweb.path_addons, 'base', 'static', 'src', 'img', 'placeholder.png'), 'rb').read()
|
||||
|
||||
@openerpweb.httprequest
|
||||
def saveas(self, request, model, id, field, fieldname, **kw):
|
||||
Model = request.session.model(model)
|
||||
context = request.session.eval_context(request.context)
|
||||
def saveas(self, req, model, id, field, fieldname, **kw):
|
||||
Model = req.session.model(model)
|
||||
context = req.session.eval_context(req.context)
|
||||
res = Model.read([int(id)], [field, fieldname], context)[0]
|
||||
filecontent = res.get(field, '')
|
||||
if not filecontent:
|
||||
raise cherrypy.NotFound
|
||||
else:
|
||||
cherrypy.response.headers['Content-Type'] = 'application/octet-stream'
|
||||
req.httpresponse.headers['Content-Type'] = 'application/octet-stream'
|
||||
filename = '%s_%s' % (model.replace('.', '_'), id)
|
||||
if fieldname:
|
||||
filename = res.get(fieldname, '') or filename
|
||||
cherrypy.response.headers['Content-Disposition'] = 'attachment; filename=' + filename
|
||||
req.httpresponse.headers['Content-Disposition'] = 'attachment; filename=' + filename
|
||||
return base64.decodestring(filecontent)
|
||||
|
||||
@openerpweb.httprequest
|
||||
def upload(self, request, callback, ufile=None):
|
||||
def upload(self, req, callback, ufile=None):
|
||||
cherrypy.response.timeout = 500
|
||||
headers = {}
|
||||
for key, val in cherrypy.request.headers.iteritems():
|
||||
for key, val in req.httprequest.headers.iteritems():
|
||||
headers[key.lower()] = val
|
||||
size = int(headers.get('content-length', 0))
|
||||
# TODO: might be useful to have a configuration flag for max-length file uploads
|
||||
|
@ -1006,10 +1001,10 @@ class Binary(openerpweb.Controller):
|
|||
return out % (simplejson.dumps(callback), simplejson.dumps(args))
|
||||
|
||||
@openerpweb.httprequest
|
||||
def upload_attachment(self, request, callback, model, id, ufile=None):
|
||||
def upload_attachment(self, req, callback, model, id, ufile=None):
|
||||
cherrypy.response.timeout = 500
|
||||
context = request.session.eval_context(request.context)
|
||||
Model = request.session.model('ir.attachment')
|
||||
context = req.session.eval_context(req.context)
|
||||
Model = req.session.model('ir.attachment')
|
||||
try:
|
||||
out = """<script language="javascript" type="text/javascript">
|
||||
var win = window.top.window,
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
/* TODO: separate openerp web client page css from openerp views css */
|
||||
body {
|
||||
body.openerp {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
height: 100%;
|
||||
min-width: 1000px;
|
||||
overflow-y: scroll;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
body.openerp, .openerp textarea, .openerp input, .openerp select, .openerp option, .openerp button, .openerp .ui-widget {
|
||||
font-family: Ubuntu, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.oe_box {
|
||||
border: 1px solid #aaf;
|
||||
padding: 2px;
|
||||
|
@ -20,13 +26,6 @@ body {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
body.openerp {
|
||||
height: 100%;
|
||||
min-width: 1000px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.openerp .oe-number {
|
||||
text-align: right !important;
|
||||
}
|
||||
|
@ -120,7 +119,6 @@ body.openerp {
|
|||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
color: white;
|
||||
font-family: Ubuntu, Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
padding: 5px;
|
||||
|
@ -381,7 +379,7 @@ label.error {
|
|||
/* Header */
|
||||
.openerp .header {
|
||||
height: 65px;
|
||||
background: url("../img/header-background.png") repeat-x scroll left top transparent;
|
||||
background: url("/base/static/src/img/header-background.png") repeat-x scroll left top transparent;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: 0.5px;
|
||||
text-shadow: 0 1px 0 #333333;
|
||||
|
@ -497,7 +495,6 @@ label.error {
|
|||
color: #666666;
|
||||
font-weight: bold;
|
||||
font-size: 0.8em;
|
||||
font-family: Ubuntu, Helvetica, sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
.openerp div.oe_footer p.oe_footer_powered a {
|
||||
|
@ -515,7 +512,6 @@ label.error {
|
|||
.openerp h2.oe_view_title {
|
||||
font-size: 175%;
|
||||
font-weight: normal;
|
||||
font-family: Ubuntu, Helvetica, sans-serif;
|
||||
margin: 2px 0;
|
||||
color: #252424;
|
||||
text-shadow: white 0 1px 0;
|
||||
|
@ -859,7 +855,7 @@ label.error {
|
|||
-webkit-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 2px;
|
||||
padding: 0 2px 0 2px;
|
||||
border: 1px solid #999;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
|
@ -988,7 +984,6 @@ label.error {
|
|||
margin: 0;
|
||||
width: 180px;
|
||||
height: 100%;
|
||||
font-family: Ubuntu, Helvetica, sans-serif;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
|
@ -1046,7 +1041,6 @@ label.error {
|
|||
|
||||
.openerp .view-manager-main-sidebar h2 {
|
||||
margin:0;
|
||||
font-family: Ubuntu, Helvetica, sans-serif;
|
||||
font-size: 1.15em;
|
||||
color: #8E8E8E;
|
||||
text-shadow: white 0 1px 0;
|
||||
|
|
|
@ -12,10 +12,7 @@
|
|||
return;
|
||||
var session_counter = 0;
|
||||
|
||||
/** @lends openerp */
|
||||
var openerp = this.openerp = {
|
||||
// debug flag
|
||||
debug: true,
|
||||
// Per session namespace
|
||||
// openerp.<module> will map to
|
||||
// openerp.sessions.sessionname.<module> using a closure
|
||||
|
@ -44,7 +41,6 @@
|
|||
}
|
||||
return new_instance;
|
||||
}
|
||||
// TODO add initrpc to init core only for RPC
|
||||
};
|
||||
})();
|
||||
|
||||
|
@ -57,32 +53,11 @@ openerp.base = function(instance) {
|
|||
openerp.base.formats(instance);
|
||||
openerp.base.chrome(instance);
|
||||
openerp.base.data(instance);
|
||||
if (openerp.base.views) {
|
||||
openerp.base.views(instance);
|
||||
}
|
||||
if (openerp.base.search) {
|
||||
openerp.base.search(instance);
|
||||
}
|
||||
if (openerp.base.list) {
|
||||
openerp.base.list(instance);
|
||||
}
|
||||
if (openerp.base. m2o) {
|
||||
openerp.base.m2o(instance);
|
||||
}
|
||||
if (openerp.base.form) {
|
||||
openerp.base.form(instance);
|
||||
}
|
||||
if (openerp.base.list && openerp.base.list.editable) {
|
||||
openerp.base.list.editable(instance);
|
||||
}
|
||||
if (openerp.web_mobile) {
|
||||
openerp.web_mobile(instance);
|
||||
}
|
||||
if (openerp.base.view_tree) {
|
||||
openerp.base.view_tree(instance);
|
||||
}
|
||||
if (openerp.base.data_export) {
|
||||
openerp.base.data_export(instance);
|
||||
files = ["views","search","list","form","list_editable","web_mobile","view_tree","data_export"];
|
||||
for(i=0; i<files.length; i++) {
|
||||
if(openerp.base[files[i]]) {
|
||||
openerp.base[files[i]](instance);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -291,8 +291,7 @@ openerp.base.Database = openerp.base.Widget.extend({
|
|||
},
|
||||
do_create: function() {
|
||||
var self = this;
|
||||
self.$option_id.html(QWeb.render("CreateDB", self));
|
||||
|
||||
self.$option_id.html(QWeb.render("Database.CreateDB", self));
|
||||
self.$option_id.find("form[name=create_db_form]").validate({
|
||||
submitHandler: function (form) {
|
||||
var fields = $(form).serializeArray();
|
||||
|
@ -314,11 +313,9 @@ openerp.base.Database = openerp.base.Widget.extend({
|
|||
}
|
||||
});
|
||||
},
|
||||
|
||||
do_drop: function() {
|
||||
var self = this;
|
||||
self.$option_id.html(QWeb.render("DropDB", self));
|
||||
|
||||
self.$option_id.find("form[name=drop_db_form]").validate({
|
||||
submitHandler: function (form) {
|
||||
var $form = $(form),
|
||||
|
@ -341,7 +338,6 @@ openerp.base.Database = openerp.base.Widget.extend({
|
|||
}
|
||||
});
|
||||
},
|
||||
|
||||
wait_for_file: function (token, cleanup) {
|
||||
var self = this,
|
||||
cookie_name = 'fileToken',
|
||||
|
@ -362,7 +358,7 @@ openerp.base.Database = openerp.base.Widget.extend({
|
|||
|
||||
if (cleanup) { cleanup(); }
|
||||
}
|
||||
}, 100);
|
||||
}, 200);
|
||||
},
|
||||
do_backup: function() {
|
||||
var self = this;
|
||||
|
@ -402,7 +398,6 @@ openerp.base.Database = openerp.base.Widget.extend({
|
|||
}
|
||||
});
|
||||
},
|
||||
|
||||
do_restore: function() {
|
||||
var self = this;
|
||||
self.$option_id.html(QWeb.render("RestoreDB", self));
|
||||
|
@ -441,7 +436,6 @@ openerp.base.Database = openerp.base.Widget.extend({
|
|||
}
|
||||
});
|
||||
},
|
||||
|
||||
do_change_password: function() {
|
||||
var self = this;
|
||||
self.$option_id.html(QWeb.render("Change_DB_Pwd", self));
|
||||
|
@ -836,13 +830,6 @@ openerp.base.WebClient = openerp.base.Widget.extend({
|
|||
}
|
||||
});
|
||||
|
||||
openerp.base.webclient = function(element_id) {
|
||||
// TODO Helper to start webclient rename it openerp.base.webclient
|
||||
var client = new openerp.base.WebClient(element_id);
|
||||
client.start();
|
||||
return client;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
|
||||
|
|
|
@ -320,6 +320,293 @@ openerp.base.CallbackEnabled = openerp.base.Class.extend({
|
|||
}
|
||||
});
|
||||
|
||||
openerp.base.Session = openerp.base.CallbackEnabled.extend( /** @lends openerp.base.Session# */{
|
||||
/**
|
||||
* @constructs
|
||||
* @param server
|
||||
* @param port
|
||||
*/
|
||||
init: function(server, port) {
|
||||
this._super();
|
||||
this.server = (server == undefined) ? location.hostname : server;
|
||||
this.port = (port == undefined) ? location.port : port;
|
||||
this.rpc_mode = (server == location.hostname) ? "ajax" : "jsonp";
|
||||
this.debug = (window.location.search.indexOf('?debug') !== -1);
|
||||
this.db = "";
|
||||
this.login = "";
|
||||
this.password = "";
|
||||
this.user_context= {};
|
||||
this.uid = false;
|
||||
this.session_id = false;
|
||||
this.module_list = [];
|
||||
this.module_loaded = {"base": true};
|
||||
this.context = {};
|
||||
this.shortcuts = [];
|
||||
this.active_id = null;
|
||||
this.session = this;
|
||||
},
|
||||
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.user_context = result.context;
|
||||
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');
|
||||
this.user_context = this.get_cookie("user_context");
|
||||
// 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);
|
||||
this.set_cookie('user_context', this.user_context);
|
||||
},
|
||||
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 lang = self.user_context.lang;
|
||||
params = { mods: ["base"].concat(result), lang: lang};
|
||||
self.rpc('/base/webclient/translations',params).then(function(transs) {
|
||||
openerp.base._t.database.set_bundle(transs);
|
||||
var modules = self.module_list.join(',');
|
||||
if(self.debug) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Utility class that any class is allowed to extend to easy common manipulations.
|
||||
*
|
||||
|
@ -352,7 +639,7 @@ openerp.base.SessionAware = openerp.base.CallbackEnabled.extend({
|
|||
this.on_log.apply(this,args);
|
||||
},
|
||||
on_log: function() {
|
||||
if(window.openerp.debug || (window.location.search.indexOf('?debug') !== -1)) {
|
||||
if(this.session.debug) {
|
||||
var notify = false;
|
||||
var body = false;
|
||||
if(window.console) {
|
||||
|
@ -613,295 +900,6 @@ openerp.base.TranslationDataBase = openerp.base.Class.extend({
|
|||
|
||||
openerp.base._t = new openerp.base.TranslationDataBase().build_translation_function();
|
||||
|
||||
openerp.base.Session = openerp.base.CallbackEnabled.extend( /** @lends openerp.base.Session# */{
|
||||
/**
|
||||
* @constructs
|
||||
* @param element_id to use for exception reporting
|
||||
* @param server
|
||||
* @param port
|
||||
*/
|
||||
init: function(server, port) {
|
||||
this._super();
|
||||
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.user_context= {};
|
||||
this.uid = false;
|
||||
this.session_id = false;
|
||||
this.module_list = [];
|
||||
this.module_loaded = {"base": true};
|
||||
this.context = {};
|
||||
this.shortcuts = [];
|
||||
this.active_id = null;
|
||||
},
|
||||
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.user_context = result.context;
|
||||
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');
|
||||
this.user_context = this.get_cookie("user_context");
|
||||
// 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);
|
||||
this.set_cookie('user_context', this.user_context);
|
||||
},
|
||||
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 lang = self.user_context.lang;
|
||||
self.rpc('/base/webclient/translations',{
|
||||
mods: ["base"].concat(result),
|
||||
lang: lang})
|
||||
.then(function(transs) {
|
||||
openerp.base._t.database.set_bundle(transs);
|
||||
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:
|
||||
|
|
|
@ -286,14 +286,16 @@ 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 {Array} [fields] fields to read and return, by default all fields are returned
|
||||
* @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 (options, callback) { return null; },
|
||||
read_slice: function (fields, options, callback) {
|
||||
return null;
|
||||
},
|
||||
/**
|
||||
* Reads the current dataset record (from its index)
|
||||
*
|
||||
|
@ -478,11 +480,12 @@ openerp.base.DataSetStatic = openerp.base.DataSet.extend({
|
|||
// all local records
|
||||
this.ids = ids || [];
|
||||
},
|
||||
read_slice: function (options, callback) {
|
||||
read_slice: function (fields, options, callback) {
|
||||
// TODO remove fields from options
|
||||
var self = this,
|
||||
offset = options.offset || 0,
|
||||
limit = options.limit || false,
|
||||
fields = options.fields || false;
|
||||
fields = fields || false;
|
||||
var end_pos = limit && limit !== -1 ? offset + limit : undefined;
|
||||
return this.read_ids(this.ids.slice(offset, end_pos), fields, callback);
|
||||
},
|
||||
|
@ -532,12 +535,13 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
|
|||
* @param {Function} callback function called with read_slice result
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
read_slice: function (options, callback) {
|
||||
read_slice: function (fields, options, callback) {
|
||||
var self = this;
|
||||
var options = options || {};
|
||||
var offset = options.offset || 0;
|
||||
return this.rpc('/base/dataset/search_read', {
|
||||
model: this.model,
|
||||
fields: options.fields || false,
|
||||
fields: fields || false,
|
||||
domain: this.get_domain(options.domain),
|
||||
context: this.get_context(options.context),
|
||||
sort: this.sort(),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
openerp.base.form = function (openerp) {
|
||||
|
||||
|
||||
var _t = openerp.base._t;
|
||||
|
||||
openerp.base.views.add('form', 'openerp.base.FormView');
|
||||
|
@ -458,9 +458,7 @@ openerp.base.form.SidebarAttachments = openerp.base.Widget.extend({
|
|||
['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);
|
||||
])).read_slice(['name', 'url', 'type'], this.on_attachments_loaded);
|
||||
}
|
||||
},
|
||||
on_attachments_loaded: function(attachments) {
|
||||
|
@ -812,6 +810,7 @@ openerp.base.form.WidgetLabel = openerp.base.form.Widget.extend({
|
|||
this.$element.find("label").dblclick(function() {
|
||||
var widget = self['for'] || self;
|
||||
self.log(widget.element_id , widget);
|
||||
window.w = widget;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -842,9 +841,12 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
|
|||
this.value = value;
|
||||
this.invalid = false;
|
||||
this.update_dom();
|
||||
this.on_value_changed();
|
||||
},
|
||||
set_value_from_ui: function() {
|
||||
this.value = undefined;
|
||||
this.on_value_changed();
|
||||
},
|
||||
on_value_changed: function() {
|
||||
},
|
||||
get_value: function() {
|
||||
return this.value;
|
||||
|
@ -943,6 +945,7 @@ openerp.base.form.FieldChar = openerp.base.form.Field.extend({
|
|||
},
|
||||
set_value_from_ui: function() {
|
||||
this.value = this.$element.find('input').val();
|
||||
this._super();
|
||||
},
|
||||
validate: function() {
|
||||
this.invalid = false;
|
||||
|
@ -1017,6 +1020,7 @@ openerp.base.form.FieldFloat = openerp.base.form.FieldChar.extend({
|
|||
},
|
||||
set_value_from_ui: function() {
|
||||
this.value = Number(this.$element.find('input').val().replace(/,/g, '.'));
|
||||
this._super();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1037,6 +1041,7 @@ openerp.base.form.FieldInteger = openerp.base.form.FieldFloat.extend({
|
|||
},
|
||||
set_value_from_ui: function() {
|
||||
this.value = Number(this.$element.find('input').val());
|
||||
this._super();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1074,6 +1079,7 @@ openerp.base.form.FieldDatetime = openerp.base.form.Field.extend({
|
|||
if (this.value) {
|
||||
this.value = this.format(this.value);
|
||||
}
|
||||
this._super();
|
||||
},
|
||||
update_dom: function() {
|
||||
this._super.apply(this, arguments);
|
||||
|
@ -1125,6 +1131,7 @@ openerp.base.form.FieldFloatTime = openerp.base.form.FieldChar.extend({
|
|||
set_value_from_ui: function() {
|
||||
var time = this.$element.find('input').val().split(':');
|
||||
this.set_value(parseInt(time[0], 10) + parseInt(time[1], 10) / 60);
|
||||
this._super();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1149,6 +1156,7 @@ openerp.base.form.FieldText = openerp.base.form.Field.extend({
|
|||
},
|
||||
set_value_from_ui: function() {
|
||||
this.value = this.$element.find('textarea').val();
|
||||
this._super();
|
||||
},
|
||||
validate: function() {
|
||||
this.invalid = false;
|
||||
|
@ -1184,6 +1192,7 @@ openerp.base.form.FieldBoolean = openerp.base.form.Field.extend({
|
|||
},
|
||||
set_value_from_ui: function() {
|
||||
this.value = this.$element.find('input').is(':checked');
|
||||
this._super();
|
||||
},
|
||||
update_dom: function() {
|
||||
this._super.apply(this, arguments);
|
||||
|
@ -1266,6 +1275,7 @@ openerp.base.form.FieldSelection = openerp.base.form.Field.extend({
|
|||
var ikey = this.$element.find('select').val();
|
||||
var option = _.detect(this.field_index, function(x) {return x.ikey === ikey;});
|
||||
this.value = option === undefined ? false : option.ekey;
|
||||
this._super();
|
||||
},
|
||||
update_dom: function() {
|
||||
this._super.apply(this, arguments);
|
||||
|
@ -1530,7 +1540,6 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
|
|||
this.on_ui_change();
|
||||
}
|
||||
},
|
||||
set_value_from_ui: function() {},
|
||||
set_value: function(value) {
|
||||
value = value || null;
|
||||
var self = this;
|
||||
|
@ -1698,7 +1707,6 @@ openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
|
|||
});
|
||||
}
|
||||
},
|
||||
set_value_from_ui: function() {},
|
||||
set_value: function(value) {
|
||||
value = value || [];
|
||||
var self = this;
|
||||
|
@ -1919,7 +1927,6 @@ openerp.base.form.FieldMany2Many = openerp.base.form.Field.extend({
|
|||
get_value: function() {
|
||||
return [commands.replace_with(this.dataset.ids)];
|
||||
},
|
||||
set_value_from_ui: function() {},
|
||||
validate: function() {
|
||||
this.invalid = false;
|
||||
// TODO niv
|
||||
|
@ -2193,10 +2200,67 @@ openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({
|
|||
}
|
||||
});
|
||||
|
||||
openerp.base.form.FieldReference = openerp.base.form.FieldChar.extend({
|
||||
openerp.base.form.FieldReference = openerp.base.form.Field.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
//this.template = "FieldReference";
|
||||
this.template = "FieldReference";
|
||||
this.fields_view = {
|
||||
fields: {
|
||||
selection: {
|
||||
selection: view.fields_view.fields[this.name].selection
|
||||
},
|
||||
m2o: {
|
||||
relation: null
|
||||
}
|
||||
}
|
||||
}
|
||||
this.get_fields_values = view.get_fields_values;
|
||||
this.do_onchange = this.on_form_changed = this.on_nop;
|
||||
this.widgets = {};
|
||||
this.fields = {};
|
||||
this.selection = new openerp.base.form.FieldSelection(this, { attrs: {
|
||||
name: 'selection',
|
||||
widget: 'selection'
|
||||
}});
|
||||
this.selection.on_value_changed.add_last(this.on_selection_changed);
|
||||
this.m2o = new openerp.base.form.FieldMany2One(this, { attrs: {
|
||||
name: 'm2o',
|
||||
widget: 'many2one'
|
||||
}});
|
||||
},
|
||||
on_nop: function() {
|
||||
},
|
||||
on_selection_changed: function() {
|
||||
this.m2o.field.relation = this.selection.get_value();
|
||||
this.m2o.set_value(null);
|
||||
},
|
||||
start: function() {
|
||||
this._super();
|
||||
this.selection.start();
|
||||
this.m2o.start();
|
||||
},
|
||||
is_valid: function() {
|
||||
return this.required === false || typeof(this.get_value()) === 'string';
|
||||
},
|
||||
is_dirty: function() {
|
||||
return this.selection.is_dirty() || this.m2o.is_dirty();
|
||||
},
|
||||
set_value: function(value) {
|
||||
this._super(value);
|
||||
if (typeof(value) === 'string') {
|
||||
var vals = value.split(',');
|
||||
this.selection.set_value(vals[0]);
|
||||
this.m2o.set_value(parseInt(vals[1], 10));
|
||||
}
|
||||
},
|
||||
get_value: function() {
|
||||
var model = this.selection.get_value(),
|
||||
id = this.m2o.get_value();
|
||||
if (typeof(model) === 'string' && typeof(id) === 'number') {
|
||||
return model + ',' + id;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -2212,8 +2276,6 @@ openerp.base.form.FieldBinary = openerp.base.form.Field.extend({
|
|||
this.$element.find('button.oe-binary-file-save').click(this.on_save_as);
|
||||
this.$element.find('.oe-binary-file-clear').click(this.on_clear);
|
||||
},
|
||||
set_value_from_ui: function() {
|
||||
},
|
||||
update_dom: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.find('.oe-binary').toggle(!this.readonly);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @namespace handles editability case for lists, because it depends on form and forms already depends on lists it had to be split out
|
||||
*/
|
||||
openerp.base.list.editable = function (openerp) {
|
||||
openerp.base.list_editable = function (openerp) {
|
||||
var KEY_RETURN = 13,
|
||||
KEY_ESCAPE = 27;
|
||||
|
||||
|
|
|
@ -476,7 +476,8 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
|||
*/
|
||||
do_activate_record: function (index, id, dataset) {
|
||||
var self = this;
|
||||
this.dataset.read_slice({
|
||||
// TODO is it needed ?
|
||||
this.dataset.read_slice([],{
|
||||
context: dataset.get_context(),
|
||||
domain: dataset.get_domain()
|
||||
}, function () {
|
||||
|
@ -1034,11 +1035,9 @@ 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({
|
||||
fields: _.pluck(_.select(this.columns, function(x) {return x.tag == "field"}), 'name'),
|
||||
offset: page * limit,
|
||||
limit: limit
|
||||
}, function (records) {
|
||||
var fields = _.pluck(_.select(this.columns, function(x) {return x.tag == "field"}), 'name');
|
||||
var options = { offset: page * limit, limit: limit };
|
||||
dataset.read_slice(fields, options , function (records) {
|
||||
if (!self.datagroup.openable) {
|
||||
view.configure_pager(dataset);
|
||||
} else {
|
||||
|
|
|
@ -72,7 +72,7 @@ openerp.base.TreeView = openerp.base.View.extend({
|
|||
'toolbar': has_toolbar
|
||||
}));
|
||||
|
||||
this.dataset.read_slice({fields: this.fields_list()}, function (records) {
|
||||
this.dataset.read_slice(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
|
||||
|
|
|
@ -17,6 +17,7 @@ openerp.base.ActionManager = openerp.base.Widget.extend({
|
|||
this.dialog = null;
|
||||
this.dialog_viewmanager = null;
|
||||
this.client_widget = null;
|
||||
this.url = {}
|
||||
},
|
||||
render: function() {
|
||||
return "<div id='"+this.element_id+"'></div>";
|
||||
|
@ -35,7 +36,29 @@ openerp.base.ActionManager = openerp.base.Widget.extend({
|
|||
this.inner_viewmanager = null;
|
||||
}
|
||||
},
|
||||
do_action: function(action, on_closed) {
|
||||
url_update: function(action) {
|
||||
// this.url = {
|
||||
// "model": action.model,
|
||||
// "domain": action.domain,
|
||||
// };
|
||||
// action.res_model
|
||||
// action.domain
|
||||
// action.context
|
||||
// after
|
||||
// action.views
|
||||
// action.res_id
|
||||
// mode
|
||||
// menu
|
||||
},
|
||||
url_stringify: function(action) {
|
||||
},
|
||||
url_parse: function(action) {
|
||||
},
|
||||
on_url_update: function(url) {
|
||||
},
|
||||
do_url_action: function(url) {
|
||||
},
|
||||
do_action: function(action, on_close) {
|
||||
var type = action.type.replace(/\./g,'_');
|
||||
var popup = action.target === 'new';
|
||||
action.flags = _.extend({
|
||||
|
@ -49,7 +72,7 @@ openerp.base.ActionManager = openerp.base.Widget.extend({
|
|||
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_close) {
|
||||
if (action.target === 'new') {
|
||||
|
@ -69,6 +92,7 @@ openerp.base.ActionManager = openerp.base.Widget.extend({
|
|||
this.inner_stop();
|
||||
this.inner_viewmanager = new openerp.base.ViewManagerAction(this, action);
|
||||
this.inner_viewmanager.appendTo(this.$element);
|
||||
this.url_update(action);
|
||||
}
|
||||
/* new window code
|
||||
this.rpc("/base/session/save_session_action", { the_action : action}, function(key) {
|
||||
|
@ -285,7 +309,7 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
|
|||
|
||||
var searchview_loaded = this.setup_search_view(
|
||||
searchview_id || false, search_defaults);
|
||||
|
||||
|
||||
// schedule auto_search
|
||||
if (searchview_loaded != null && this.action['auto_search']) {
|
||||
$.when(searchview_loaded, inital_view_loaded)
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
<li id="back-to-login">Back to Login</li>
|
||||
</ul>
|
||||
</t>
|
||||
<t t-name="CreateDB">
|
||||
<t t-name="Database.CreateDB">
|
||||
<form name="create_db_form" class="oe_forms" method="POST">
|
||||
<table width="100%">
|
||||
<tr>
|
||||
|
@ -79,8 +79,7 @@
|
|||
<table align="center" class="db_option_table">
|
||||
<tr>
|
||||
<td><label for="super_admin_pwd">Master password:</label></td>
|
||||
<td><input type="password" name="super_admin_pwd"
|
||||
class="required" autofocus="autofocus"/></td>
|
||||
<td><input type="password" name="super_admin_pwd" class="required" value="admin"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="db_name">New database name:</label></td>
|
||||
|
@ -95,9 +94,7 @@
|
|||
<td>
|
||||
<select name="db_lang" t-if="lang_list">
|
||||
<t t-foreach="lang_list" t-as="lang">
|
||||
<option t-att-value="lang[0]"
|
||||
t-att-selected="lang[0] === 'en_US' ? 'selected' : undefined">
|
||||
<t t-esc="lang[1]"/></option>
|
||||
<option t-att-value="lang[0]" t-att-selected="lang[0] === 'en_US' ? 'selected' : undefined"><t t-esc="lang[1]"/></option>
|
||||
</t>
|
||||
</select>
|
||||
</td>
|
||||
|
@ -367,7 +364,6 @@
|
|||
t-att-data-shortcut-id="shortcut.id"
|
||||
><t t-esc="shortcut.name"/></li>
|
||||
</ul>
|
||||
|
||||
<t t-name="Menu">
|
||||
<table align="center">
|
||||
<tr>
|
||||
|
@ -784,7 +780,16 @@
|
|||
<div t-att-id="widget.list_id"></div>
|
||||
</t>
|
||||
<t t-name="FieldReference">
|
||||
<input type="text" t-att-name="widget.name" t-att-id="widget.element_id" t-att-class="'field_' + widget.type" style="width: 100%" placeholder="Widget Reference"/>
|
||||
<table border="0" width="100%" cellpadding="0" cellspacing="0" class="oe_frame oe_forms">
|
||||
<tr>
|
||||
<td t-att-id="widget.selection.element_id" class="oe_form_frame_cell oe_form_selection">
|
||||
<t t-raw="widget.selection.render()"/>
|
||||
</td>
|
||||
<td t-att-id="widget.m2o.element_id" class="oe_form_frame_cell oe_form_many2one" nowrap="true">
|
||||
<t t-raw="widget.m2o.render()"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</t>
|
||||
<t t-name="FieldBoolean">
|
||||
<input type="checkbox"
|
||||
|
@ -1166,7 +1171,6 @@
|
|||
<t t-name="ExportView">
|
||||
<a id="exportview" href="javascript: void(0)" style="text-decoration: none;color: #3D3D3D;">Export</a>
|
||||
</t>
|
||||
|
||||
<t t-name="ExportTreeView">
|
||||
<table class="view" style="background-color: #F3F3F3;">
|
||||
<tr>
|
||||
|
|
|
@ -26,6 +26,7 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({
|
|||
'#fcaf3e', '#ef2929', '#ff00c9', '#ad7fa8', '#729fcf', '#8ae234', '#e9b96e', '#fce94f',
|
||||
'#ff8e00', '#ff0000', '#b0008c', '#9000ff', '#0078ff', '#00ff00', '#e6ff00', '#ffff00',
|
||||
'#905000', '#9b0000', '#840067', '#510090', '#0000c9', '#009b00', '#9abe00', '#ffc900' ];
|
||||
this.color_map = {};
|
||||
},
|
||||
start: function() {
|
||||
this.rpc("/base_calendar/calendarview/load", {"model": this.model, "view_id": this.view_id, 'toolbar': true}, this.on_loaded);
|
||||
|
@ -136,17 +137,21 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({
|
|||
reload_event: function(id) {
|
||||
this.dataset.read_ids([id], _.keys(this.fields), this.on_events_loaded);
|
||||
},
|
||||
get_color: function(index) {
|
||||
index = index % this.COLOR_PALETTE.length;
|
||||
return this.COLOR_PALETTE[index];
|
||||
get_color: function(key) {
|
||||
if (this.color_map[key]) {
|
||||
return this.color_map[key];
|
||||
}
|
||||
var index = _.keys(this.color_map).length % this.COLOR_PALETTE.length;
|
||||
var color = this.COLOR_PALETTE[index];
|
||||
this.color_map[key] = color;
|
||||
return color;
|
||||
},
|
||||
on_events_loaded: function(events, fn_filter, no_filter_reload) {
|
||||
var self = this;
|
||||
|
||||
//To parse Events we have to convert date Format
|
||||
var res_events = [],
|
||||
sidebar_items = [],
|
||||
sidebar_ids = [];
|
||||
sidebar_items = {};
|
||||
for (var e = 0; e < events.length; e++) {
|
||||
var evt = events[e];
|
||||
if (!evt[this.date_start]) {
|
||||
|
@ -157,21 +162,19 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({
|
|||
if (this.color_field) {
|
||||
var filter = evt[this.color_field];
|
||||
if (filter) {
|
||||
var filter_item = {
|
||||
value: (typeof filter === 'object') ? filter[0] : filter,
|
||||
label: (typeof filter === 'object') ? filter[1] : filter
|
||||
}
|
||||
if (typeof(fn_filter) === 'function' && !fn_filter(filter_item.value)) {
|
||||
var filter_value = (typeof filter === 'object') ? filter[0] : filter;
|
||||
if (typeof(fn_filter) === 'function' && !fn_filter(filter_value)) {
|
||||
continue;
|
||||
}
|
||||
var filter_index = _.indexOf(sidebar_ids, filter_item.value);
|
||||
if (filter_index === -1) {
|
||||
evt.color = filter_item.color = this.get_color(sidebar_ids.length);
|
||||
sidebar_items.push(filter_item);
|
||||
sidebar_ids.push(filter_item.value);
|
||||
} else {
|
||||
evt.color = this.get_color(filter_index);
|
||||
var filter_item = {
|
||||
value: filter_value,
|
||||
label: (typeof filter === 'object') ? filter[1] : filter,
|
||||
color: this.get_color(filter_value)
|
||||
}
|
||||
if (!sidebar_items[filter_value]) {
|
||||
sidebar_items[filter_value] = filter_item;
|
||||
}
|
||||
evt.color = filter_item.color;
|
||||
evt.textColor = '#ffffff';
|
||||
}
|
||||
}
|
||||
|
@ -299,8 +302,7 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({
|
|||
// 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),
|
||||
self.dataset.read_slice(_.keys(self.fields), {
|
||||
offset:0,
|
||||
limit: self.limit
|
||||
}, function(events) {
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
</div>
|
||||
</t>
|
||||
<t t-name="CalendarView.sidebar.responsible">
|
||||
<div t-foreach="filters" t-as="filter" class="oe_calendar_responsible" t-attf-style="background: #{filter.color}">
|
||||
<input type="checkbox" name="selection" t-att-value="filter.value"/>
|
||||
<span><t t-esc="filter.label"/></span>
|
||||
<div t-foreach="filters" class="oe_calendar_responsible" t-attf-style="background: #{filters_value.color}">
|
||||
<input type="checkbox" name="selection" t-att-value="filters_value.value"/>
|
||||
<span><t t-esc="filters_value.label"/></span>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
|
|
@ -290,7 +290,7 @@ openerp.base_dashboard.ConfigOverview = openerp.base.View.extend({
|
|||
this.dataset.domain = [['type', '=', 'manual']];
|
||||
},
|
||||
start: function () {
|
||||
$.when(this.dataset.read_slice({fields: ['state', 'action_id', 'category_id']}),
|
||||
$.when(this.dataset.read_slice(['state', 'action_id', 'category_id']),
|
||||
this.dataset.call('progress'))
|
||||
.then(this.on_records_loaded);
|
||||
},
|
||||
|
@ -352,9 +352,7 @@ openerp.base_dashboard.ApplicationTiles = openerp.base.View.extend({
|
|||
},
|
||||
start: function () {
|
||||
var self = this;
|
||||
this.dataset.read_slice(
|
||||
{fields: ['name', 'web_icon_data', 'web_icon_hover_data']},
|
||||
function (applications) {
|
||||
this.dataset.read_slice( ['name', 'web_icon_data', 'web_icon_hover_data'], {}, function (applications) {
|
||||
// Create a matrix of 3*x applications
|
||||
var rows = [];
|
||||
while (applications.length) {
|
||||
|
@ -384,9 +382,7 @@ openerp.base_dashboard.Widgets = openerp.base.View.extend({
|
|||
this.widgets = new openerp.base.DataSetSearch(this, 'res.widget');
|
||||
},
|
||||
start: function () {
|
||||
this.user_widgets.read_slice(
|
||||
{fields: ['widget_id', 'user_id']},
|
||||
this.on_widgets_list_loaded);
|
||||
this.user_widgets.read_slice(['widget_id', 'user_id'], {}, this.on_widgets_list_loaded);
|
||||
},
|
||||
on_widgets_list_loaded: function (user_widgets) {
|
||||
var self = this;
|
||||
|
|
|
@ -1,24 +1,21 @@
|
|||
.oe-static-home {
|
||||
padding: 0.5em 0.5em;
|
||||
text-align: center;
|
||||
}
|
||||
.oe-static-home h1 {
|
||||
margin: 0 0 0.3em
|
||||
}
|
||||
.oe-static-home-banner {
|
||||
display: inline-block;
|
||||
margin: 0.5em 0;
|
||||
margin: auto 0;
|
||||
padding: 0.5em 5em;
|
||||
border: 1px inset #808080;
|
||||
background-color: #e6e3e3;
|
||||
-moz-border-radius: 2em;
|
||||
-webkit-border-radius: 2em;
|
||||
border-radius: 2em;
|
||||
text-align: left;
|
||||
}
|
||||
.oe-static-home-banner h1 {
|
||||
margin: 0 0 0.3em
|
||||
.oe-static-home-banner li {
|
||||
font-size: 150%;
|
||||
font-weight: bold;
|
||||
}
|
||||
.oe-static-home-banner p {
|
||||
|
||||
}
|
||||
.oe-static-home-banner address {
|
||||
.oe-static-home address {
|
||||
font-style: normal;
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
|
|
@ -78,15 +78,13 @@ openerp.base_default_home = function (openerp) {
|
|||
});
|
||||
},
|
||||
install_module: function (module_name) {
|
||||
var Modules = new openerp.base.DataSetSearch(
|
||||
this, 'ir.module.module', null,
|
||||
[['name', '=', module_name], ['state', '=', 'uninstalled']]),
|
||||
Upgrade = new openerp.base.DataSet(this, 'base.module.upgrade');
|
||||
var Modules = new openerp.base.DataSetSearch( this, 'ir.module.module', null, [['name', '=', module_name], ['state', '=', 'uninstalled']]);
|
||||
var Upgrade = new openerp.base.DataSet(this, 'base.module.upgrade');
|
||||
|
||||
$.blockUI({
|
||||
message: '<img src="/base_default_home/static/src/img/throbber.gif">'
|
||||
});
|
||||
Modules.read_slice({fields: ['id']}, function (records) {
|
||||
Modules.read_slice(['id'], {}, function (records) {
|
||||
if (!(records.length === 1)) { return; }
|
||||
Modules.call('state_update',
|
||||
[_.pluck(records, 'id'), 'to install', ['uninstalled']],
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
<template>
|
||||
<div t-name="StaticHome" class="oe-static-home">
|
||||
<h1>Welcome to your new OpenERP instance.</h1>
|
||||
<div class="oe-static-home-banner">
|
||||
<h1>Welcome to OpenERP</h1>
|
||||
<p>
|
||||
Don't forget to bookmark your application address to come back
|
||||
later:
|
||||
</p>
|
||||
<address>
|
||||
URL: <a t-att-href="url"><t t-esc="url"/></a><br/>
|
||||
login: <t t-esc="session.login"/>
|
||||
</address>
|
||||
<li>Bookmark this <a t-att-href="url">page</a></li>
|
||||
<li>Remember your login: <i><t t-esc="session.login"/></i></li>
|
||||
<li>Choose the first OpenERP Application you want to install..</li>
|
||||
</div>
|
||||
|
||||
<div class="oe-static-home-tiles">
|
||||
<table width="100%">
|
||||
<tr t-foreach="rows" t-as="row">
|
||||
|
@ -27,9 +21,7 @@
|
|||
<div class="oe-static-home-tile-text">
|
||||
<h2><t t-esc="application.name"/></h2>
|
||||
<p><t t-esc="application.help"/></p>
|
||||
<button type="button"
|
||||
t-att-value="application.module">
|
||||
Install</button>
|
||||
<button type="button" t-att-value="application.module"> Install</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -79,7 +79,7 @@ init: function(parent, element_id, dataset, view_id) {
|
|||
get_events: function() {
|
||||
|
||||
var self = this;
|
||||
this.dataset.read_slice({}, function(result) {
|
||||
this.dataset.read_slice([],{}, function(result) {
|
||||
self.load_event(result);
|
||||
});
|
||||
|
||||
|
@ -498,7 +498,7 @@ init: function(parent, element_id, dataset, view_id) {
|
|||
|
||||
reload_gantt: function() {
|
||||
var self = this;
|
||||
this.dataset.read_slice({}, 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({fields: _(this.fields).keys()}, function(res) {
|
||||
this.dataset.read_slice(_(this.fields).keys(),{}, function(res) {
|
||||
self.schedule_chart(res);
|
||||
});
|
||||
}
|
||||
|
@ -468,7 +468,7 @@ openerp.base_graph.GraphView = openerp.base.View.extend({
|
|||
}
|
||||
self.dataset.context = results.context;
|
||||
self.dataset.domain = results.domain;
|
||||
self.dataset.read_slice({}, $.proxy(self, 'load_chart'));
|
||||
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({}, function (result) {
|
||||
this.dataset.read_slice([],{}, function (result) {
|
||||
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
if (result[i].id == id) {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name" : "OpenERP Web base",
|
||||
"version" : "2.0",
|
||||
"depends" : [],
|
||||
'active': False,
|
||||
'js' : [
|
||||
"../base/static/lib/datejs/date-en-US.js",
|
||||
"../base/static/lib/jquery/jquery-1.6.2.js",
|
||||
"../base/static/lib/json/json2.js",
|
||||
"../base/static/lib/qweb/qweb2.js",
|
||||
"../base/static/lib/underscore/underscore.js",
|
||||
"../base/static/lib/underscore/underscore.string.js",
|
||||
"../base/static/src/js/boot.js",
|
||||
"../base/static/src/js/core.js",
|
||||
"../base/static/src/js/formats.js",
|
||||
"../base/static/src/js/chrome.js",
|
||||
"../base/static/src/js/data.js",
|
||||
],
|
||||
'css' : [
|
||||
],
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<!DOCTYPE html>
|
||||
<html style="height: 100%">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>OpenERP web_rpc example</title>
|
||||
<style type="text/css">
|
||||
pre.run {
|
||||
border: 1px solid black; margin:0;padding:4px;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript" src="/base/webclient/js?mods=web_rpc"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$("#ex1but").bind("click",function(){
|
||||
eval($("#ex1").text());
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>OpenERP web_rpc examples</h1>
|
||||
<h2>Example 1: Display a list of defined ir.model <button id="ex1but">Run it !</button> </h2>
|
||||
<h3>Code: </h3>
|
||||
<pre>
|
||||
<script type="text/javascript" src="/base/webclient/js?mods=web_rpc"></script>
|
||||
<script type="text/javascript">
|
||||
<pre id="ex1" class="run">
|
||||
var c = openerp.init(); // get a new webclient
|
||||
c._modules_loaded = true; // Hack to prevent loading of additional modules
|
||||
|
||||
var s = new c.base.Session(); // setup a Session
|
||||
s.session_login("web-trunk", "admin", "admin", function() {
|
||||
|
||||
var ds = new c.base.DataSetSearch(s, "ir.model"); // DataSetSearch used to search, read
|
||||
ds.read_slice(['name','model'], {}, function(users){
|
||||
for(var i in users) {
|
||||
$("#ex1res").append("<li>" + users[i].model + " (" + users[i].name + ") </li>")
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
</pre></script>
|
||||
</pre>
|
||||
<h3>Div for output:</h3>
|
||||
<div id="ex1res" style="border: 1px solid black;">
|
||||
|
||||
</div>
|
||||
<h2>Help me to complete this example page on <a href="http://bazaar.launchpad.net/~openerp/openerp-web/trunk/view/head:/addons/web_rpc/static/src/example.html">launchpad</a></h2>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -233,7 +233,27 @@ class OpenERPSession(object):
|
|||
#----------------------------------------------------------
|
||||
# OpenERP Web RequestHandler
|
||||
#----------------------------------------------------------
|
||||
class JsonRequest(object):
|
||||
class CherryPyRequest(object):
|
||||
""" CherryPy request handling
|
||||
"""
|
||||
def init(self,params):
|
||||
self.params = params
|
||||
# Move cherrypy thread local objects to attributes
|
||||
self.applicationsession = applicationsession
|
||||
self.httprequest = cherrypy.request
|
||||
self.httpresponse = cherrypy.response
|
||||
self.httpsession = cherrypy.session
|
||||
self.httpsession_id = "cookieid"
|
||||
# OpenERP session setup
|
||||
self.session_id = self.params.pop("session_id", None) or uuid.uuid4().hex
|
||||
host = cherrypy.config['openerp.server.host']
|
||||
port = cherrypy.config['openerp.server.port']
|
||||
self.session = self.httpsession.setdefault(self.session_id, OpenERPSession(host, port))
|
||||
# Request attributes
|
||||
self.context = self.params.pop('context', None)
|
||||
self.debug = self.params.pop('debug',False) != False
|
||||
|
||||
class JsonRequest(CherryPyRequest):
|
||||
""" JSON-RPC2 over HTTP.
|
||||
|
||||
Sucessful request::
|
||||
|
@ -267,48 +287,28 @@ class JsonRequest(object):
|
|||
|
||||
"""
|
||||
|
||||
def parse(self, request):
|
||||
self.request = request
|
||||
self.params = request.get("params", {})
|
||||
self.applicationsession = applicationsession
|
||||
self.httprequest = cherrypy.request
|
||||
self.httpresponse = cherrypy.response
|
||||
self.httpsession = cherrypy.session
|
||||
self.httpsession_id = "cookieid"
|
||||
self.httpsession = cherrypy.session
|
||||
self.session_id = self.params.pop("session_id", None) or uuid.uuid4().hex
|
||||
host = cherrypy.config['openerp.server.host']
|
||||
port = cherrypy.config['openerp.server.port']
|
||||
self.session = self.httpsession.setdefault(self.session_id, OpenERPSession(host, port))
|
||||
self.context = self.params.pop('context', None)
|
||||
return self.params
|
||||
|
||||
def dispatch(self, controller, method, requestf=None, request=None):
|
||||
""" Calls the method asked for by the JSON-RPC2 request
|
||||
|
||||
:param controller: the instance of the controller which received the request
|
||||
:type controller: type
|
||||
:param method: the method which received the request
|
||||
:type method: callable
|
||||
:param requestf: a file-like object containing an encoded JSON-RPC2 request
|
||||
:type requestf: <read() -> bytes>
|
||||
:param request: an encoded JSON-RPC2 request
|
||||
:type request: bytes
|
||||
:param request: a JSON-RPC2 request
|
||||
|
||||
:returns: a string-encoded JSON-RPC2 reply
|
||||
:rtype: bytes
|
||||
:returns: an utf8 encoded JSON-RPC2 reply
|
||||
"""
|
||||
# Read POST content or POST Form Data named "request"
|
||||
if requestf:
|
||||
request = simplejson.load(requestf, object_hook=nonliterals.non_literal_decoder)
|
||||
else:
|
||||
request = simplejson.loads(request, object_hook=nonliterals.non_literal_decoder)
|
||||
|
||||
response = {"jsonrpc": "2.0", "id": request.get('id')}
|
||||
response = {"jsonrpc": "2.0" }
|
||||
error = None
|
||||
try:
|
||||
print "--> %s.%s %s" % (controller.__class__.__name__, method.__name__, request)
|
||||
error = None
|
||||
self.parse(request)
|
||||
# Read POST content or POST Form Data named "request"
|
||||
if requestf:
|
||||
self.jsonrequest = simplejson.load(requestf, object_hook=nonliterals.non_literal_decoder)
|
||||
else:
|
||||
self.jsonrequest = simplejson.loads(request, object_hook=nonliterals.non_literal_decoder)
|
||||
self.init(self.jsonrequest.get("params", {}))
|
||||
if self.debug or 1:
|
||||
print "--> %s.%s %s" % (controller.__class__.__name__, method.__name__, self.jsonrequest)
|
||||
response['id'] = self.jsonrequest.get('id')
|
||||
response["result"] = method(controller, self, **self.params)
|
||||
except OpenERPUnboundException:
|
||||
error = {
|
||||
|
@ -344,8 +344,9 @@ class JsonRequest(object):
|
|||
if error:
|
||||
response["error"] = error
|
||||
|
||||
print "<--", response
|
||||
print
|
||||
if self.debug or 1:
|
||||
print "<--", response
|
||||
print
|
||||
|
||||
content = simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder)
|
||||
cherrypy.response.headers['Content-Type'] = 'application/json'
|
||||
|
@ -357,41 +358,32 @@ def jsonrequest(f):
|
|||
@functools.wraps(f)
|
||||
def json_handler(controller):
|
||||
return JsonRequest().dispatch(controller, f, requestf=cherrypy.request.body)
|
||||
|
||||
return json_handler
|
||||
|
||||
class HttpRequest(object):
|
||||
class HttpRequest(CherryPyRequest):
|
||||
""" Regular GET/POST request
|
||||
"""
|
||||
def dispatch(self, controller, f, request, **kw):
|
||||
self.request = request
|
||||
self.applicationsession = applicationsession
|
||||
self.httpsession_id = "cookieid"
|
||||
self.httpsession = cherrypy.session
|
||||
self.context = kw.get('context', {})
|
||||
host = cherrypy.config['openerp.server.host']
|
||||
port = cherrypy.config['openerp.server.port']
|
||||
self.session_id = kw.pop('session_id', None)
|
||||
self.session = self.httpsession.setdefault(self.session_id, OpenERPSession(host, port))
|
||||
self.result = ""
|
||||
if request.method == 'GET':
|
||||
print "GET --> %s.%s %s %r" % (controller.__class__.__name__, f.__name__, request, kw)
|
||||
else:
|
||||
akw = dict([(key, kw[key] if isinstance(kw[key], basestring) else type(kw[key])) for key in kw.keys()])
|
||||
print "POST --> %s.%s %s %r" % (controller.__class__.__name__, f.__name__, request, akw)
|
||||
r = f(controller, self, **kw)
|
||||
if isinstance(r, str):
|
||||
print "<--", len(r), 'bytes'
|
||||
else:
|
||||
print "<--", len(r), 'characters'
|
||||
print
|
||||
def dispatch(self, controller, method, **kw):
|
||||
self.init(kw)
|
||||
akw = {}
|
||||
for key in kw.keys():
|
||||
if isinstance(kw[key], basestring) and len(kw[key]) < 1024:
|
||||
akw[key] = kw[key]
|
||||
else:
|
||||
akw[key] = type(kw[key])
|
||||
if self.debug or 1:
|
||||
print "%s --> %s.%s %r" % (self.httprequest.method, controller.__class__.__name__, method.__name__, akw)
|
||||
r = method(controller, self, **kw)
|
||||
if self.debug or 1:
|
||||
print "<--", 'size:', len(r)
|
||||
print
|
||||
return r
|
||||
|
||||
def httprequest(f):
|
||||
# check cleaner wrapping:
|
||||
# functools.wraps(f)(lambda x: JsonRequest().dispatch(x, f))
|
||||
def http_handler(self,*l, **kw):
|
||||
return HttpRequest().dispatch(self, f, cherrypy.request, **kw)
|
||||
def http_handler(controller,*l, **kw):
|
||||
return HttpRequest().dispatch(controller, f, **kw)
|
||||
http_handler.exposed = 1
|
||||
return http_handler
|
||||
|
||||
|
|
Loading…
Reference in New Issue