[MERGE] from trunk

bzr revid: xmo@openerp.com-20120423125009-ndyll5onu37j4kaf
This commit is contained in:
Xavier Morel 2012-04-23 14:50:09 +02:00
commit 2ccb3e793f
87 changed files with 10016 additions and 2313 deletions

View File

@ -405,14 +405,14 @@ def session_context(request, storage_path, session_cookie='sessionid'):
#----------------------------------------------------------
addons_module = {}
addons_manifest = {}
controllers_class = {}
controllers_class = []
controllers_object = {}
controllers_path = {}
class ControllerType(type):
def __init__(cls, name, bases, attrs):
super(ControllerType, cls).__init__(name, bases, attrs)
controllers_class["%s.%s" % (cls.__module__, cls.__name__)] = cls
controllers_class.append(("%s.%s" % (cls.__module__, cls.__name__), cls))
class Controller(object):
__metaclass__ = ControllerType
@ -440,12 +440,12 @@ class Root(object):
self.root = '/web/webclient/home'
self.config = options
if self.config.backend == 'local':
conn = LocalConnector()
else:
conn = openerplib.get_connector(hostname=self.config.server_host,
port=self.config.server_port)
self.config.connector = conn
if not hasattr(self.config, 'connector'):
if self.config.backend == 'local':
self.config.connector = LocalConnector()
else:
self.config.connector = openerplib.get_connector(
hostname=self.config.server_host, port=self.config.server_port)
self.session_cookie = 'sessionid'
self.addons = {}
@ -526,7 +526,7 @@ class Root(object):
addons_module[module] = m
addons_manifest[module] = manifest
statics['/%s/static' % module] = path_static
for k, v in controllers_class.items():
for k, v in controllers_class:
if k not in controllers_object:
o = v()
controllers_object[k] = o

View File

@ -909,11 +909,6 @@ class Menu(openerpweb.Controller):
class DataSet(openerpweb.Controller):
_cp_path = "/web/dataset"
@openerpweb.jsonrequest
def fields(self, req, model):
return {'fields': req.session.model(model).fields_get(False,
req.session.eval_context(req.context))}
@openerpweb.jsonrequest
def search_read(self, req, model, fields=False, offset=0, limit=False, domain=None, sort=None):
return self.do_search_read(req, model, fields, offset, limit, domain, sort)
@ -949,7 +944,6 @@ class DataSet(openerpweb.Controller):
if fields and fields == ['id']:
# shortcut read if we only want the ids
return {
'ids': ids,
'length': length,
'records': [{'id': id} for id in ids]
}
@ -957,46 +951,10 @@ class DataSet(openerpweb.Controller):
records = Model.read(ids, fields or False, context)
records.sort(key=lambda obj: ids.index(obj['id']))
return {
'ids': ids,
'length': length,
'records': records
}
@openerpweb.jsonrequest
def read(self, req, model, ids, fields=False):
return self.do_search_read(req, model, ids, fields)
@openerpweb.jsonrequest
def get(self, req, model, ids, fields=False):
return self.do_get(req, model, ids, fields)
def do_get(self, req, model, ids, fields=False):
""" Fetches and returns the records of the model ``model`` whose ids
are in ``ids``.
The results are in the same order as the inputs, but elements may be
missing (if there is no record left for the id)
:param req: the JSON-RPC2 request object
:type req: openerpweb.JsonRequest
:param model: the model to read from
:type model: str
:param ids: a list of identifiers
:type ids: list
:param fields: a list of fields to fetch, ``False`` or empty to fetch
all fields in the model
:type fields: list | False
:returns: a list of records, in the same order as the list of ids
:rtype: list
"""
Model = req.session.model(model)
records = Model.read(ids, fields, req.session.eval_context(req.context))
record_map = dict((record['id'], record) for record in records)
return [record_map[id] for id in ids if record_map.get(id)]
@openerpweb.jsonrequest
def load(self, req, model, id, fields):
m = req.session.model(model)
@ -1006,23 +964,6 @@ class DataSet(openerpweb.Controller):
value = r[0]
return {'value': value}
@openerpweb.jsonrequest
def create(self, req, model, data):
m = req.session.model(model)
r = m.create(data, req.session.eval_context(req.context))
return {'result': r}
@openerpweb.jsonrequest
def save(self, req, model, id, data):
m = req.session.model(model)
r = m.write([id], data, req.session.eval_context(req.context))
return {'result': r}
@openerpweb.jsonrequest
def unlink(self, req, model, ids=()):
Model = req.session.model(model)
return Model.unlink(ids, req.session.eval_context(req.context))
def call_common(self, req, model, method, args, domain_id=None, context_id=None):
has_domain = domain_id is not None and domain_id < len(args)
has_context = context_id is not None and context_id < len(args)
@ -1098,19 +1039,7 @@ class DataSet(openerpweb.Controller):
@openerpweb.jsonrequest
def exec_workflow(self, req, model, id, signal):
r = req.session.exec_workflow(model, id, signal)
return {'result': r}
@openerpweb.jsonrequest
def default_get(self, req, model, fields):
Model = req.session.model(model)
return Model.default_get(fields, req.session.eval_context(req.context))
@openerpweb.jsonrequest
def name_search(self, req, model, search_str, domain=[], context={}):
m = req.session.model(model)
r = m.name_search(search_str+'%', domain, '=ilike', context)
return {'result': r}
return req.session.exec_workflow(model, id, signal)
class DataGroup(openerpweb.Controller):
_cp_path = "/web/group"

1544
addons/web/i18n/bs.po Normal file

File diff suppressed because it is too large Load Diff

1547
addons/web/i18n/es_CL.po Normal file

File diff suppressed because it is too large Load Diff

1544
addons/web/i18n/gu.po Normal file

File diff suppressed because it is too large Load Diff

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-14 15:27+0100\n"
"PO-Revision-Date: 2012-04-02 13:15+0000\n"
"PO-Revision-Date: 2012-04-16 12:21+0000\n"
"Last-Translator: Erwin <Unknown>\n"
"Language-Team: Dutch <nl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-03 05:16+0000\n"
"X-Generator: Launchpad (build 15052)\n"
"X-Launchpad-Export-Date: 2012-04-17 05:23+0000\n"
"X-Generator: Launchpad (build 15099)\n"
#. openerp-web
#: addons/web/static/src/js/chrome.js:172
@ -53,7 +53,7 @@ msgstr "Ongeldige database naam"
#. openerp-web
#: addons/web/static/src/js/chrome.js:483
msgid "Backed"
msgstr ""
msgstr "Back-up gereed"
#. openerp-web
#: addons/web/static/src/js/chrome.js:484

10
addons/web/static/lib/qunit/qunit.css Executable file → Normal file
View File

@ -1,9 +1,9 @@
/**
* QUnit v1.2.0 - A JavaScript Unit Testing Framework
* QUnit v1.4.0pre - A JavaScript Unit Testing Framework
*
* http://docs.jquery.com/QUnit
*
* Copyright (c) 2011 John Resig, Jörn Zaefferer
* Copyright (c) 2012 John Resig, Jörn Zaefferer
* Dual licensed under the MIT (MIT-LICENSE.txt)
* or GPL (GPL-LICENSE.txt) licenses.
*/
@ -54,6 +54,10 @@
color: #fff;
}
#qunit-header label {
display: inline-block;
}
#qunit-banner {
height: 5px;
}
@ -223,4 +227,6 @@
position: absolute;
top: -10000px;
left: -10000px;
width: 1000px;
height: 1000px;
}

119
addons/web/static/lib/qunit/qunit.js Executable file → Normal file
View File

@ -1,9 +1,9 @@
/**
* QUnit v1.2.0 - A JavaScript Unit Testing Framework
* QUnit v1.4.0pre - A JavaScript Unit Testing Framework
*
* http://docs.jquery.com/QUnit
*
* Copyright (c) 2011 John Resig, Jörn Zaefferer
* Copyright (c) 2012 John Resig, Jörn Zaefferer
* Dual licensed under the MIT (MIT-LICENSE.txt)
* or GPL (GPL-LICENSE.txt) licenses.
*/
@ -13,8 +13,11 @@
var defined = {
setTimeout: typeof window.setTimeout !== "undefined",
sessionStorage: (function() {
var x = "qunit-test-string";
try {
return !!sessionStorage.getItem;
sessionStorage.setItem(x, x);
sessionStorage.removeItem(x);
return true;
} catch(e) {
return false;
}
@ -25,11 +28,10 @@ var testId = 0,
toString = Object.prototype.toString,
hasOwn = Object.prototype.hasOwnProperty;
var Test = function(name, testName, expected, testEnvironmentArg, async, callback) {
var Test = function(name, testName, expected, async, callback) {
this.name = name;
this.testName = testName;
this.expected = expected;
this.testEnvironmentArg = testEnvironmentArg;
this.async = async;
this.callback = callback;
this.assertions = [];
@ -62,6 +64,10 @@ Test.prototype = {
runLoggingCallbacks( 'moduleStart', QUnit, {
name: this.module
} );
} else if (config.autorun) {
runLoggingCallbacks( 'moduleStart', QUnit, {
name: this.module
} );
}
config.current = this;
@ -69,9 +75,6 @@ Test.prototype = {
setup: function() {},
teardown: function() {}
}, this.moduleTestEnvironment);
if (this.testEnvironmentArg) {
extend(this.testEnvironment, this.testEnvironmentArg);
}
runLoggingCallbacks( 'testStart', QUnit, {
name: this.testName,
@ -274,17 +277,12 @@ var QUnit = {
},
test: function(testName, expected, callback, async) {
var name = '<span class="test-name">' + testName + '</span>', testEnvironmentArg;
var name = '<span class="test-name">' + escapeInnerText(testName) + '</span>';
if ( arguments.length === 2 ) {
callback = expected;
expected = null;
}
// is 2nd argument a testEnvironment?
if ( expected && typeof expected === 'object') {
testEnvironmentArg = expected;
expected = null;
}
if ( config.currentModule ) {
name = '<span class="module-name">' + config.currentModule + "</span>: " + name;
@ -294,7 +292,7 @@ var QUnit = {
return;
}
var test = new Test(name, testName, expected, testEnvironmentArg, async, callback);
var test = new Test(name, testName, expected, async, callback);
test.module = config.currentModule;
test.moduleTestEnvironment = config.currentModuleTestEnviroment;
test.queue();
@ -312,6 +310,9 @@ var QUnit = {
* @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
*/
ok: function(a, msg) {
if (!config.current) {
throw new Error("ok() assertion outside test context, was " + sourceFromStacktrace(2));
}
a = !!a;
var details = {
result: a,
@ -447,9 +448,14 @@ var QUnit = {
QUnit.constructor = F;
})();
// Backwards compatibility, deprecated
QUnit.equals = QUnit.equal;
QUnit.same = QUnit.deepEqual;
// deprecated; still export them to window to provide clear error messages
// next step: remove entirely
QUnit.equals = function() {
throw new Error("QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead");
};
QUnit.same = function() {
throw new Error("QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead");
};
// Maintain internal state
var config = {
@ -513,8 +519,7 @@ if ( typeof exports === "undefined" || typeof require === "undefined" ) {
extend(window, QUnit);
window.QUnit = QUnit;
} else {
extend(exports, QUnit);
exports.QUnit = QUnit;
module.exports = QUnit;
}
// define these after exposing globals to keep them in these QUnit namespace only
@ -536,6 +541,16 @@ extend(QUnit, {
semaphore: 0
});
var qunit = id( "qunit" );
if ( qunit ) {
qunit.innerHTML =
'<h1 id="qunit-header">' + escapeInnerText( document.title ) + '</h1>' +
'<h2 id="qunit-banner"></h2>' +
'<div id="qunit-testrunner-toolbar"></div>' +
'<h2 id="qunit-userAgent"></h2>' +
'<ol id="qunit-tests"></ol>';
}
var tests = id( "qunit-tests" ),
banner = id( "qunit-banner" ),
result = id( "qunit-testresult" );
@ -564,15 +579,15 @@ extend(QUnit, {
/**
* Resets the test setup. Useful for tests that modify the DOM.
*
* If jQuery is available, uses jQuery's html(), otherwise just innerHTML.
* If jQuery is available, uses jQuery's replaceWith(), otherwise use replaceChild
*/
reset: function() {
if ( window.jQuery ) {
jQuery( "#qunit-fixture" ).html( config.fixture );
} else {
var main = id( 'qunit-fixture' );
if ( main ) {
main.innerHTML = config.fixture;
var main = id( 'qunit-fixture' );
if ( main ) {
if ( window.jQuery ) {
jQuery( main ).replaceWith( config.fixture.cloneNode(true) );
} else {
main.parentNode.replaceChild(config.fixture.cloneNode(true), main);
}
}
},
@ -636,6 +651,9 @@ extend(QUnit, {
},
push: function(result, actual, expected, message) {
if (!config.current) {
throw new Error("assertion outside test context, was " + sourceFromStacktrace());
}
var details = {
result: result,
message: message,
@ -645,21 +663,22 @@ extend(QUnit, {
message = escapeInnerText(message) || (result ? "okay" : "failed");
message = '<span class="test-message">' + message + "</span>";
expected = escapeInnerText(QUnit.jsDump.parse(expected));
actual = escapeInnerText(QUnit.jsDump.parse(actual));
var output = message + '<table><tr class="test-expected"><th>Expected: </th><td><pre>' + expected + '</pre></td></tr>';
if (actual != expected) {
output += '<tr class="test-actual"><th>Result: </th><td><pre>' + actual + '</pre></td></tr>';
output += '<tr class="test-diff"><th>Diff: </th><td><pre>' + QUnit.diff(expected, actual) +'</pre></td></tr>';
}
var output = message;
if (!result) {
expected = escapeInnerText(QUnit.jsDump.parse(expected));
actual = escapeInnerText(QUnit.jsDump.parse(actual));
output += '<table><tr class="test-expected"><th>Expected: </th><td><pre>' + expected + '</pre></td></tr>';
if (actual != expected) {
output += '<tr class="test-actual"><th>Result: </th><td><pre>' + actual + '</pre></td></tr>';
output += '<tr class="test-diff"><th>Diff: </th><td><pre>' + QUnit.diff(expected, actual) +'</pre></td></tr>';
}
var source = sourceFromStacktrace();
if (source) {
details.source = source;
output += '<tr class="test-source"><th>Source: </th><td><pre>' + escapeInnerText(source) + '</pre></td></tr>';
}
output += "</table>";
}
output += "</table>";
runLoggingCallbacks( 'log', QUnit, details );
@ -779,7 +798,7 @@ QUnit.load = function() {
var main = id('qunit-fixture');
if ( main ) {
config.fixture = main.innerHTML;
config.fixture = main.cloneNode(true);
}
if (config.autostart) {
@ -847,6 +866,15 @@ function done() {
].join(" ");
}
// clear own sessionStorage items if all tests passed
if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
for (var key in sessionStorage) {
if (sessionStorage.hasOwnProperty(key) && key.indexOf("qunit-") === 0 ) {
sessionStorage.removeItem(key);
}
}
}
runLoggingCallbacks( 'done', QUnit, {
failed: config.stats.bad,
passed: passed,
@ -881,16 +909,21 @@ function validTest( name ) {
// so far supports only Firefox, Chrome and Opera (buggy)
// could be extended in the future to use something like https://github.com/csnover/TraceKit
function sourceFromStacktrace() {
function sourceFromStacktrace(offset) {
offset = offset || 3;
try {
throw new Error();
} catch ( e ) {
if (e.stacktrace) {
// Opera
return e.stacktrace.split("\n")[6];
return e.stacktrace.split("\n")[offset + 3];
} else if (e.stack) {
// Firefox, Chrome
return e.stack.split("\n")[4];
var stack = e.stack.split("\n");
if (/^error$/i.test(stack[0])) {
stack.shift();
}
return stack[offset];
} else if (e.sourceURL) {
// Safari, PhantomJS
// TODO sourceURL points at the 'throw new Error' line above, useless
@ -989,6 +1022,7 @@ function fail(message, exception, callback) {
if ( typeof console !== "undefined" && console.error && console.warn ) {
console.error(message);
console.error(exception);
console.error(exception.stack);
console.warn(callback.toString());
} else if ( window.opera && opera.postError ) {
@ -1368,9 +1402,9 @@ QUnit.jsDump = (function() {
var ret = [ ];
QUnit.jsDump.up();
for ( var key in map ) {
var val = map[key];
var val = map[key];
ret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(val, undefined, stack));
}
}
QUnit.jsDump.down();
return join( '{', ret, '}' );
},
@ -1594,4 +1628,5 @@ QUnit.diff = (function() {
};
})();
})(this);
// get at whatever the global object is, like window in browsers
})( (function() {return this}).call() );

View File

@ -21,16 +21,13 @@
color: #4c4c4c;
font-size: 13px;
background: white;
}
.openerp a {
text-decoration: none;
}
.openerp {
/* http://www.quirksmode.org/dom/inputfile.html
* http://stackoverflow.com/questions/2855589/replace-input-type-file-by-an-image
*/
}
.openerp a {
text-decoration: none;
}
.openerp table {
padding: 0;
font-size: 13px;
@ -904,6 +901,9 @@
color: white;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}
.openerp .oe_view_manager_header2 .oe_view_manager_buttons {
white-space: nowrap;
}
.openerp .oe_view_manager_body h4 {
margin: 8px 0;
}
@ -1042,6 +1042,9 @@
-webkit-box-shadow: none;
-box-shadow: none;
}
.openerp .oe_sidebar {
white-space: nowrap;
}
.openerp .oe_searchview {
position: relative;
float: right;
@ -1614,6 +1617,15 @@
height: auto;
line-height: 16px;
}
.openerp .oe_listview_nocontent > img {
float: left;
margin-right: 1.5em;
}
.openerp .oe_listview_nocontent > div {
overflow: hidden;
padding: 6px;
font-size: 125%;
}
.openerp .oe-listview-content {
width: 100%;
}
@ -1771,23 +1783,13 @@
font-weight: bold;
}
.openerp .oe_layout_debugging .oe_form_group {
border: 2px dashed red;
outline: 2px dashed green;
}
.openerp .oe_layout_debugging .oe_form_group_cell {
border: 1px solid blue;
padding-bottom: 1em;
outline: 1px solid blue;
}
.openerp .oe_layout_debugging .oe_layout_debug_cell {
color: white;
background: #669966;
font-size: 80%;
text-align: center;
}
.openerp .oe_layout_debugging .oe_layout_debug_cell {
display: block;
}
.openerp .oe_layout_debug_cell {
display: none;
.openerp .oe_layout_debugging .oe_form_group:hover, .openerp .oe_layout_debugging .oe_form_group_cell:hover {
outline-color: red;
}
.openerp .oe_debug_view {
float: left;

View File

@ -78,12 +78,10 @@ $colour4: #8a89ba
color: #4c4c4c
font-size: 13px
background: white
// }}}
// Tag reset {{{
a
text-decoration: none
// }}}
.openerp
// Tag reset {{{
table
padding: 0
font-size: 13px
@ -705,6 +703,8 @@ $colour4: #8a89ba
a
color: #fff
text-shadow: 0 1px 2px rgba(0,0,0,0.4)
.oe_view_manager_buttons
white-space: nowrap
// }}}
// ViewManager.body {{{
.oe_view_manager_body
@ -814,7 +814,8 @@ $colour4: #8a89ba
text-decoration: none
@include vertical-gradient(#f0f0fa, #eeeef6)
@include box-shadow(none)
.oe_sidebar
white-space: nowrap
// }}}
// SearchView xmo {{{
.oe_searchview
@ -1363,6 +1364,15 @@ $colour4: #8a89ba
// }}}
// ListView {{{
.oe_listview_nocontent
> img
float: left
margin-right: 1.5em
> div
// don't encroach on my arrow
overflow: hidden
padding: 6px
font-size: 125%
.oe-listview-content
width: 100%
thead, tfoot
@ -1477,23 +1487,14 @@ $colour4: #8a89ba
.oe_tooltip_technical_title
font-weight: bold
// }}}
// Debugging stuff {{{
.oe_layout_debugging
.oe_form_group
border: 2px dashed red
outline: 2px dashed green
.oe_form_group_cell
border: 1px solid blue
padding-bottom: 1em
.oe_layout_debug_cell
color: white
background: #696
font-size: 80%
text-align: center
.oe_layout_debug_cell
display: block
.oe_layout_debug_cell
display: none
outline: 1px solid blue
.oe_form_group:hover, .oe_form_group_cell:hover
outline-color: red
.oe_debug_view
float: left
@ -1526,4 +1527,3 @@ $colour4: #8a89ba
// au BufWritePost,FileWritePost *.sass :!sass --style expanded --line-numbers <afile> > "%:p:r.css"
// vim:tabstop=4:shiftwidth=4:softtabstop=4:fdm=marker:

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 846 B

After

Width:  |  Height:  |  Size: 846 B

View File

@ -1,16 +1,16 @@
/*---------------------------------------------------------
* OpenERP Web chrome
*---------------------------------------------------------*/
openerp.web.chrome = function(openerp) {
var QWeb = openerp.web.qweb,
_t = openerp.web._t;
openerp.web.chrome = function(instance) {
var QWeb = instance.web.qweb,
_t = instance.web._t;
openerp.web.Notification = openerp.web.Widget.extend({
instance.web.Notification = instance.web.Widget.extend({
template: 'Notification',
init: function() {
this._super.apply(this, arguments);
// move to openerp.web.notification
openerp.notification = this;
// move to instance.web.notification
instance.notification = this;
},
start: function() {
this._super.apply(this, arguments);
@ -43,13 +43,13 @@ openerp.web.Notification = openerp.web.Widget.extend({
}
});
openerp.web.dialog = function(element) {
instance.web.dialog = function(element) {
var result = element.dialog.apply(element, _.rest(_.toArray(arguments)));
result.dialog("widget").addClass("openerp");
return result;
}
openerp.web.Dialog = openerp.web.Widget.extend({
instance.web.Dialog = instance.web.Widget.extend({
dialog_title: "",
init: function (parent, options, content) {
var self = this;
@ -83,7 +83,7 @@ openerp.web.Dialog = openerp.web.Widget.extend({
if (this.dialog_options.autoOpen) {
this.open();
} else {
openerp.web.dialog(this.$element, this.get_options());
instance.web.dialog(this.$element, this.get_options());
}
},
get_options: function(options) {
@ -122,7 +122,7 @@ openerp.web.Dialog = openerp.web.Widget.extend({
this.$element.html(this.renderElement());
}
var o = this.get_options(options);
openerp.web.dialog(this.$element, o).dialog('open');
instance.web.dialog(this.$element, o).dialog('open');
if (o.height === 'auto' && o.max_height) {
this.$element.css({ 'max-height': o.max_height, 'overflow-y': 'auto' });
}
@ -146,7 +146,7 @@ openerp.web.Dialog = openerp.web.Widget.extend({
}
});
openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
instance.web.CrashManager = instance.web.CallbackEnabled.extend({
on_rpc_error: function(error) {
if (error.data.fault_code) {
var split = ("" + error.data.fault_code).split('\n')[0].split(' -- ');
@ -162,7 +162,7 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
}
},
on_managed_error: function(error) {
openerp.web.dialog($('<div>' + QWeb.render('CrashManager.warning', {error: error}) + '</div>'), {
instance.web.dialog($('<div>' + QWeb.render('CrashManager.warning', {error: error}) + '</div>'), {
title: "OpenERP " + _.str.capitalize(error.type),
buttons: [
{text: _t("Ok"), click: function() { $(this).dialog("close"); }}
@ -172,14 +172,14 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
on_traceback: function(error) {
var self = this;
var buttons = {};
if (openerp.connection.openerp_entreprise) {
if (instance.connection.openerp_entreprise) {
buttons[_t("Send OpenERP Enterprise Report")] = function() {
var $this = $(this);
var issuename = $('#issuename').val();
var explanation = $('#explanation').val();
var remark = $('#remark').val();
// Call the send method from server to send mail with details
new openerp.web.DataSet(self, 'publisher_warranty.contract').call_and_eval('send', [error.data,explanation,remark,issuename]).then(function(result){
new instance.web.DataSet(self, 'publisher_warranty.contract').call_and_eval('send', [error.data,explanation,remark,issuename]).then(function(result){
if (result === false) {
alert('There was a communication error.')
} else {
@ -195,7 +195,7 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
$(this).dialog("close");
};
}
var dialog = new openerp.web.Dialog(this, {
var dialog = new instance.web.Dialog(this, {
title: "OpenERP " + _.str.capitalize(error.type),
width: '80%',
height: '50%',
@ -203,11 +203,11 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
min_height: '600px',
buttons: buttons
}).open();
dialog.$element.html(QWeb.render('CrashManager.error', {session: openerp.connection, error: error}));
dialog.$element.html(QWeb.render('CrashManager.error', {session: instance.connection, error: error}));
}
});
openerp.web.Loading = openerp.web.Widget.extend({
instance.web.Loading = instance.web.Widget.extend({
template: 'Loading',
init: function(parent) {
this._super(parent);
@ -258,7 +258,7 @@ openerp.web.Loading = openerp.web.Widget.extend({
}
});
openerp.web.DatabaseManager = openerp.web.Widget.extend({
instance.web.DatabaseManager = instance.web.Widget.extend({
init: function(parent) {
this._super(parent);
this.unblockUIFunction = $.unblockUI;
@ -344,7 +344,7 @@ openerp.web.DatabaseManager = openerp.web.Widget.extend({
* @param {String} error.error message of the error dialog
*/
display_error: function (error) {
return openerp.web.dialog($('<div>'), {
return instance.web.dialog($('<div>'), {
modal: true,
title: error.title,
buttons: [
@ -388,7 +388,7 @@ openerp.web.DatabaseManager = openerp.web.Widget.extend({
success: function () {
self.do_notify(_t("Backed"), _t("Database backed up successfully"));
},
error: openerp.webclient.crashmanager.on_rpc_error,
error: instance.webclient.crashmanager.on_rpc_error,
complete: function() {
self.unblockUI();
}
@ -439,7 +439,7 @@ openerp.web.DatabaseManager = openerp.web.Widget.extend({
}
});
openerp.web.Login = openerp.web.Widget.extend({
instance.web.Login = instance.web.Widget.extend({
template: "Login",
remember_credentials: true,
init: function(parent) {
@ -464,7 +464,7 @@ openerp.web.Login = openerp.web.Widget.extend({
self.$element.find('.oe_login_manage_db').click(function() {
self.$element.find('.oe_login_bottom').hide();
self.$element.find('.oe_login_pane').hide();
self.databasemanager = new openerp.web.DatabaseManager(self);
self.databasemanager = new instance.web.DatabaseManager(self);
self.databasemanager.appendTo(self.$element);
self.databasemanager.do_exit.add_last(function() {
self.databasemanager.destroy();
@ -486,7 +486,7 @@ openerp.web.Login = openerp.web.Widget.extend({
});
},
set_db_list: function (list) {
this.$element.find("[name=db]").replaceWith(openerp.web.qweb.render('Login.dblist', { db_list: list, selected_db: this.selected_db}))
this.$element.find("[name=db]").replaceWith(instance.web.qweb.render('Login.dblist', { db_list: list, selected_db: this.selected_db}))
},
on_submit: function(ev) {
if(ev) {
@ -538,7 +538,7 @@ openerp.web.Login = openerp.web.Widget.extend({
}
});
openerp.web.Menu = openerp.web.Widget.extend({
instance.web.Menu = instance.web.Widget.extend({
template: 'Menu',
init: function() {
this._super.apply(this, arguments);
@ -638,6 +638,7 @@ openerp.web.Menu = openerp.web.Widget.extend({
}
},
on_menu_click: function(ev, id) {
// TODO If first level menu doesnt have action trigger first leaf
this.do_hide_more();
id = id || 0;
var $clicked_menu, manual = false;
@ -682,7 +683,7 @@ openerp.web.Menu = openerp.web.Widget.extend({
}
});
openerp.web.UserMenu = openerp.web.Widget.extend({
instance.web.UserMenu = instance.web.Widget.extend({
template: "UserMenu",
init: function(parent) {
this._super(parent);
@ -707,7 +708,7 @@ openerp.web.UserMenu = openerp.web.Widget.extend({
},
change_password :function() {
var self = this;
this.dialog = new openerp.web.Dialog(this, {
this.dialog = new instance.web.Dialog(this, {
title: _t("Change Password"),
width : 'auto'
}).open();
@ -721,14 +722,14 @@ openerp.web.UserMenu = openerp.web.Widget.extend({
self.display_error(result);
return;
} else {
openerp.webclient.on_logout();
instance.webclient.on_logout();
}
});
}
});
},
display_error: function (error) {
return openerp.web.dialog($('<div>'), {
return instance.web.dialog($('<div>'), {
modal: true,
title: error.title,
buttons: [
@ -743,10 +744,10 @@ openerp.web.UserMenu = openerp.web.Widget.extend({
$avatar.attr('src', $avatar.data('default-src'));
if (!self.session.uid)
return;
var func = new openerp.web.Model("res.users").get_func("read");
var func = new instance.web.Model("res.users").get_func("read");
return func(self.session.uid, ["name", "company_id"]).pipe(function(res) {
// TODO: Show company if multicompany is in use
var topbar_name = _.str.sprintf("%s (%s)", res.name, openerp.connection.db, res.company_id[1]);
var topbar_name = _.str.sprintf("%s (%s)", res.name, instance.connection.db, res.company_id[1]);
self.$element.find('.oe_topbar_name').text(topbar_name);
var avatar_src = _.str.sprintf('%s/web/binary/image?session_id=%s&model=res.users&field=avatar&id=%s', self.session.prefix, self.session.session_id, self.session.uid);
$avatar.attr('src', avatar_src);
@ -760,7 +761,7 @@ openerp.web.UserMenu = openerp.web.Widget.extend({
shortcut_load :function(){
var self = this,
sc = self.session.shortcuts,
shortcuts_ds = new openerp.web.DataSet(this, 'ir.ui.view_sc');
shortcuts_ds = new instance.web.DataSet(this, 'ir.ui.view_sc');
self.$element.find('.oe_dropdown_options a[data-menu=shortcut]').each(function() {
$(this).parent().remove();
});
@ -807,8 +808,8 @@ openerp.web.UserMenu = openerp.web.Widget.extend({
},
on_menu_settings: function() {
var self = this;
var action_manager = new openerp.web.ActionManager(this);
var dataset = new openerp.web.DataSet (this,'res.users',this.context);
var action_manager = new instance.web.ActionManager(this);
var dataset = new instance.web.DataSet (this,'res.users',this.context);
dataset.call ('action_get','',function (result){
self.rpc('/web/action/load', {action_id:result}, function(result){
action_manager.do_action(_.extend(result['result'], {
@ -825,7 +826,7 @@ openerp.web.UserMenu = openerp.web.Widget.extend({
}));
});
});
this.dialog = new openerp.web.Dialog(this,{
this.dialog = new instance.web.Dialog(this,{
title: _t("Preferences"),
width: '700px',
buttons: [
@ -855,7 +856,7 @@ openerp.web.UserMenu = openerp.web.Widget.extend({
window.location = $.param.querystring(
window.location.href, 'debug');
});
openerp.web.dialog($help, {autoOpen: true,
instance.web.dialog($help, {autoOpen: true,
modal: true, width: 960, title: _t("About")});
});
},
@ -871,11 +872,11 @@ openerp.web.UserMenu = openerp.web.Widget.extend({
}
});
openerp.web.WebClient = openerp.web.Widget.extend({
instance.web.WebClient = instance.web.Widget.extend({
init: function(parent) {
var self = this;
this._super(parent);
openerp.webclient = this;
instance.webclient = this;
this.querystring = '?' + jQuery.param.querystring();
this._current_state = null;
},
@ -900,7 +901,7 @@ openerp.web.WebClient = openerp.web.Widget.extend({
self.menu.do_reload();
if(self.action_manager)
self.action_manager.destroy();
self.action_manager = new openerp.web.ActionManager(self);
self.action_manager = new instance.web.ActionManager(self);
self.action_manager.appendTo(self.$element.find('.oe_application'));
self.bind_hashchange();
var version_label = _t("OpenERP - Unsupported/Community Version");
@ -917,7 +918,7 @@ openerp.web.WebClient = openerp.web.Widget.extend({
var self = this;
this.destroy_content();
this.show_common();
self.login = new openerp.web.Login(self);
self.login = new instance.web.Login(self);
self.login.appendTo(self.$element);
},
show_application: function() {
@ -926,10 +927,10 @@ openerp.web.WebClient = openerp.web.Widget.extend({
this.show_common();
self.$table = $(QWeb.render("WebClient", {}));
self.$element.append(self.$table);
self.menu = new openerp.web.Menu(self);
self.menu = new instance.web.Menu(self);
self.menu.replace(this.$element.find('.oe_menu_placeholder'));
self.menu.on_action.add(this.proxy('on_menu_action'));
self.user_menu = new openerp.web.UserMenu(self);
self.user_menu = new instance.web.UserMenu(self);
self.user_menu.replace(this.$element.find('.oe_user_menu_placeholder'));
self.user_menu.on_menu_logout.add(this.proxy('on_logout'));
self.user_menu.on_action.add(this.proxy('on_menu_action'));
@ -937,8 +938,8 @@ openerp.web.WebClient = openerp.web.Widget.extend({
show_common: function() {
var self = this;
if (!this.crashmanager) {
this.crashmanager = new openerp.web.CrashManager();
openerp.connection.on_rpc_error.add(this.crashmanager.on_rpc_error);
this.crashmanager = new instance.web.CrashManager();
instance.connection.on_rpc_error.add(this.crashmanager.on_rpc_error);
window.onerror = function (message, file, line) {
self.crashmanager.on_traceback({
type: _t("Client Error"),
@ -947,9 +948,9 @@ openerp.web.WebClient = openerp.web.Widget.extend({
});
}
}
this.notification = new openerp.web.Notification(this);
this.notification = new instance.web.Notification(this);
this.notification.appendTo(this.$element);
this.loading = new openerp.web.Loading(this);
this.loading = new instance.web.Loading(this);
this.loading.appendTo(this.$element);
},
destroy_content: function() {
@ -961,7 +962,7 @@ openerp.web.WebClient = openerp.web.Widget.extend({
do_reload: function() {
var self = this;
return this.session.session_reload().pipe(function () {
openerp.connection.load_modules(true).pipe(
instance.connection.load_modules(true).pipe(
self.menu.proxy('do_reload')); });
},
@ -984,13 +985,18 @@ openerp.web.WebClient = openerp.web.Widget.extend({
});
},
bind_hashchange: function() {
var self = this;
$(window).bind('hashchange', this.on_hashchange);
var state = $.bbq.getState(true);
if (! _.isEmpty(state)) {
$(window).trigger('hashchange');
} else {
this.action_manager.do_action({type: 'ir.actions.client', tag: 'default_home'});
self.menu.has_been_loaded.then(function() {
var first_menu_id = self.menu.$element.find("a:first").data("menu");
if(first_menu_id)
self.menu.on_menu_click(null,first_menu_id);
});
}
},
on_hashchange: function(event) {
@ -1025,14 +1031,14 @@ openerp.web.WebClient = openerp.web.Widget.extend({
}
});
openerp.web.EmbeddedClient = openerp.web.Widget.extend({
instance.web.EmbeddedClient = instance.web.Widget.extend({
template: 'EmptyComponent',
init: function(parent, action_id, options) {
this._super(parent);
// TODO take the xmlid of a action instead of its id
this.action_id = action_id;
this.options = options || {};
this.am = new openerp.web.ActionManager(this);
this.am = new instance.web.ActionManager(this);
},
start: function() {
var self = this;
@ -1052,7 +1058,7 @@ openerp.web.EmbeddedClient = openerp.web.Widget.extend({
}
});
openerp.web.embed = function (origin, dbname, login, key, action, options) {
instance.web.embed = function (origin, dbname, login, key, action, options) {
$('head').append($('<link>', {
'rel': 'stylesheet',
'type': 'text/css',
@ -1063,9 +1069,9 @@ openerp.web.embed = function (origin, dbname, login, key, action, options) {
var sc = document.getElementsByTagName('script');
currentScript = sc[sc.length-1];
}
openerp.connection.session_bind(origin).then(function () {
openerp.connection.session_authenticate(dbname, login, key, true).then(function () {
var client = new openerp.web.EmbeddedClient(null, action, options);
instance.connection.session_bind(origin).then(function () {
instance.connection.session_authenticate(dbname, login, key, true).then(function () {
var client = new instance.web.EmbeddedClient(null, action, options);
client.insertAfter(currentScript);
});
});

View File

@ -23,7 +23,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
openerp.web.corelib = function(openerp) {
openerp.web.corelib = function(instance) {
/**
* Improved John Resig's inheritance, based on:
@ -39,7 +39,7 @@ openerp.web.corelib = function(openerp) {
*
* Example:
*
* var Person = openerp.web.Class.extend({
* var Person = instance.web.Class.extend({
* init: function(isDancing){
* this.dancing = isDancing;
* },
@ -75,14 +75,14 @@ openerp.web.corelib = function(openerp) {
var initializing = false,
fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
// The web Class implementation (does nothing)
openerp.web.Class = function(){};
instance.web.Class = function(){};
/**
* Subclass an existing class
*
* @param {Object} prop class-level properties (class attributes and instance methods) to set on the new class
*/
openerp.web.Class.extend = function() {
instance.web.Class.extend = function() {
var _super = this.prototype;
// Support mixins arguments
var args = _.toArray(arguments);
@ -180,7 +180,7 @@ openerp.web.corelib = function(openerp) {
* When an object is destroyed, all its children are destroyed too releasing
* any resource they could have reserved before.
*/
openerp.web.ParentedMixin = {
instance.web.ParentedMixin = {
__parentedMixin : true,
init: function() {
this.__parentedDestroyed = false;
@ -239,9 +239,7 @@ openerp.web.ParentedMixin = {
};
/**
* TODO al: move into the the mixin
*
* Backbone's events
* Backbone's events. Do not ever use it directly, use EventDispatcherMixin instead.
*
* (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
* Backbone may be freely distributed under the MIT license.
@ -253,8 +251,7 @@ openerp.web.ParentedMixin = {
* events is done in EventDispatcherMixin.
*
*/
openerp.web.Events = openerp.web.Class.extend({
var Events = instance.web.Class.extend({
on : function(events, callback, context) {
var ev;
events = events.split(/\s+/);
@ -323,12 +320,13 @@ openerp.web.Events = openerp.web.Class.extend({
return this;
}
});
// end of Jeremy Ashkenas' code
openerp.web.EventDispatcherMixin = _.extend({}, openerp.web.ParentedMixin, {
instance.web.EventDispatcherMixin = _.extend({}, instance.web.ParentedMixin, {
__eventDispatcherMixin: true,
init: function() {
openerp.web.ParentedMixin.init.call(this);
this.__edispatcherEvents = new openerp.web.Events();
instance.web.ParentedMixin.init.call(this);
this.__edispatcherEvents = new Events();
this.__edispatcherRegisteredEvents = [];
},
on: function(events, dest, func) {
@ -369,13 +367,13 @@ openerp.web.EventDispatcherMixin = _.extend({}, openerp.web.ParentedMixin, {
debugger;
}
this.__edispatcherEvents.off();
openerp.web.ParentedMixin.destroy.call(this);
instance.web.ParentedMixin.destroy.call(this);
}
});
openerp.web.GetterSetterMixin = _.extend({}, openerp.web.EventDispatcherMixin, {
instance.web.PropertiesMixin = _.extend({}, instance.web.EventDispatcherMixin, {
init: function() {
openerp.web.EventDispatcherMixin.init.call(this);
instance.web.EventDispatcherMixin.init.call(this);
this.__getterSetterInternalMap = {};
},
set: function(map) {
@ -400,9 +398,9 @@ openerp.web.GetterSetterMixin = _.extend({}, openerp.web.EventDispatcherMixin, {
}
});
openerp.web.CallbackEnabledMixin = _.extend({}, openerp.web.GetterSetterMixin, {
instance.web.CallbackEnabledMixin = _.extend({}, instance.web.PropertiesMixin, {
init: function() {
openerp.web.GetterSetterMixin.init.call(this);
instance.web.PropertiesMixin.init.call(this);
var self = this;
var callback_maker = function(obj, name, method) {
var callback = function() {
@ -421,7 +419,7 @@ openerp.web.CallbackEnabledMixin = _.extend({}, openerp.web.GetterSetterMixin, {
r = result;
}
// TODO special value to stop the chain
// openerp.web.callback_stop
// instance.web.callback_stop
}
return r;
};
@ -500,7 +498,7 @@ openerp.web.CallbackEnabledMixin = _.extend({}, openerp.web.GetterSetterMixin, {
}
});
openerp.web.WidgetMixin = _.extend({},openerp.web.CallbackEnabledMixin, {
instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, {
/**
* Tag name when creating a default $element.
* @type string
@ -509,10 +507,10 @@ openerp.web.WidgetMixin = _.extend({},openerp.web.CallbackEnabledMixin, {
/**
* Constructs the widget and sets its parent if a parent is given.
*
* @constructs openerp.web.Widget
* @extends openerp.web.CallbackEnabled
* @constructs instance.web.Widget
* @extends instance.web.CallbackEnabled
*
* @param {openerp.web.Widget} parent Binds the current instance to the given Widget instance.
* @param {instance.web.Widget} parent Binds the current instance to the given Widget instance.
* When that widget is destroyed by calling destroy(), the current instance will be
* destroyed too. Can be null.
* @param {String} element_id Deprecated. Sets the element_id. Only useful when you want
@ -521,7 +519,7 @@ openerp.web.WidgetMixin = _.extend({},openerp.web.CallbackEnabledMixin, {
* for new components this argument should not be provided any more.
*/
init: function(parent) {
openerp.web.CallbackEnabledMixin.init.call(this);
instance.web.CallbackEnabledMixin.init.call(this);
this.$element = $(document.createElement(this.tagName));
this.setParent(parent);
},
@ -535,7 +533,7 @@ openerp.web.WidgetMixin = _.extend({},openerp.web.CallbackEnabledMixin, {
if(this.$element != null) {
this.$element.remove();
}
openerp.web.GetterSetterMixin.destroy.call(this);
instance.web.PropertiesMixin.destroy.call(this);
},
/**
* Renders the current widget and appends it to the given jQuery object or Widget.
@ -616,9 +614,9 @@ openerp.web.WidgetMixin = _.extend({},openerp.web.CallbackEnabledMixin, {
// Classes
openerp.web.CallbackEnabled = openerp.web.Class.extend(openerp.web.CallbackEnabledMixin, {
instance.web.CallbackEnabled = instance.web.Class.extend(instance.web.CallbackEnabledMixin, {
init: function() {
openerp.web.CallbackEnabledMixin.init.call(this);
instance.web.CallbackEnabledMixin.init.call(this);
}
});
@ -637,7 +635,7 @@ openerp.web.CallbackEnabled = openerp.web.Class.extend(openerp.web.CallbackEnabl
*
* Here is a sample child class:
*
* MyWidget = openerp.base.Widget.extend({
* MyWidget = instance.base.Widget.extend({
* // the name of the QWeb template to use for rendering
* template: "MyQWebTemplate",
*
@ -670,7 +668,7 @@ openerp.web.CallbackEnabled = openerp.web.Class.extend(openerp.web.CallbackEnabl
*
* That will kill the widget in a clean way and erase its content from the dom.
*/
openerp.web.Widget = openerp.web.Class.extend(openerp.web.WidgetMixin, {
instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, {
/**
* The name of the QWeb template that will be used for rendering. Must be
* redefined in subclasses or the default render() method can not be used.
@ -681,10 +679,10 @@ openerp.web.Widget = openerp.web.Class.extend(openerp.web.WidgetMixin, {
/**
* Constructs the widget and sets its parent if a parent is given.
*
* @constructs openerp.web.Widget
* @extends openerp.web.CallbackEnabled
* @constructs instance.web.Widget
* @extends instance.web.CallbackEnabled
*
* @param {openerp.web.Widget} parent Binds the current instance to the given Widget instance.
* @param {instance.web.Widget} parent Binds the current instance to the given Widget instance.
* When that widget is destroyed by calling destroy(), the current instance will be
* destroyed too. Can be null.
* @param {String} element_id Deprecated. Sets the element_id. Only useful when you want
@ -693,8 +691,8 @@ openerp.web.Widget = openerp.web.Class.extend(openerp.web.WidgetMixin, {
* for new components this argument should not be provided any more.
*/
init: function(parent) {
openerp.web.WidgetMixin.init.call(this,parent);
this.session = openerp.connection;
instance.web.WidgetMixin.init.call(this,parent);
this.session = instance.connection;
},
/**
* Renders the element. The default implementation renders the widget using QWeb,
@ -704,7 +702,7 @@ openerp.web.Widget = openerp.web.Class.extend(openerp.web.WidgetMixin, {
renderElement: function() {
var rendered = null;
if (this.template)
rendered = openerp.web.qweb.render(this.template, {widget: this});
rendered = instance.web.qweb.render(this.template, {widget: this});
if (_.str.trim(rendered)) {
var elem = $(rendered);
this.$element.replaceWith(elem);
@ -737,7 +735,7 @@ openerp.web.Widget = openerp.web.Class.extend(openerp.web.WidgetMixin, {
rpc: function(url, data, success, error) {
var def = $.Deferred().then(success, error);
var self = this;
openerp.connection.rpc(url, data). then(function() {
instance.connection.rpc(url, data). then(function() {
if (!self.isDestroyed())
def.resolve.apply(def, arguments);
}, function() {
@ -748,7 +746,7 @@ openerp.web.Widget = openerp.web.Class.extend(openerp.web.WidgetMixin, {
}
});
openerp.web.Registry = openerp.web.Class.extend({
instance.web.Registry = instance.web.Class.extend({
/**
* Stores a mapping of arbitrary key (strings) to object paths (as strings
* as well).
@ -757,11 +755,11 @@ openerp.web.Registry = openerp.web.Class.extend({
* object, even if those objects have been overloaded/replaced after the
* registry was created.
*
* An object path is simply a dotted name from the openerp root to the
* object pointed to (e.g. ``"openerp.web.Connection"`` for an OpenERP
* An object path is simply a dotted name from the instance root to the
* object pointed to (e.g. ``"instance.web.Connection"`` for an OpenERP
* connection object).
*
* @constructs openerp.web.Registry
* @constructs instance.web.Registry
* @param {Object} mapping a mapping of keys to object-paths
*/
init: function (mapping) {
@ -785,7 +783,7 @@ openerp.web.Registry = openerp.web.Class.extend({
return null;
}
var object_match = openerp;
var object_match = instance;
var path = path_string.split('.');
// ignore first section
for(var i=1; i<path.length; ++i) {
@ -838,7 +836,7 @@ openerp.web.Registry = openerp.web.Class.extend({
*
* @param {String} key
* @param {String} object_path fully qualified dotted object path
* @returns {openerp.web.Registry} itself
* @returns {instance.web.Registry} itself
*/
add: function (key, object_path) {
this.map[key] = object_path;
@ -854,7 +852,7 @@ openerp.web.Registry = openerp.web.Class.extend({
* @param {Object} [mapping={}] a mapping of keys to object-paths
*/
extend: function (mapping) {
var child = new openerp.web.Registry(mapping);
var child = new instance.web.Registry(mapping);
child.parent = this;
return child;
},
@ -867,10 +865,10 @@ openerp.web.Registry = openerp.web.Class.extend({
}
});
openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.web.Connection# */{
instance.web.Connection = instance.web.CallbackEnabled.extend( /** @lends instance.web.Connection# */{
/**
* @constructs openerp.web.Connection
* @extends openerp.web.CallbackEnabled
* @constructs instance.web.Connection
* @extends instance.web.CallbackEnabled
*
* @param {String} [server] JSON-RPC endpoint hostname
* @param {String} [port] JSON-RPC endpoint port
@ -880,7 +878,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
this.server = null;
this.debug = ($.deparam($.param.querystring()).debug != undefined);
// TODO: session store in cookie should be optional
this.name = openerp._session_id;
this.name = instance._session_id;
this.qweb_mutex = new $.Mutex();
},
session_bind: function(origin) {
@ -888,7 +886,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
this.origin = origin ? _.str.rtrim(origin,'/') : window_origin;
this.prefix = this.origin;
this.server = this.origin; // keep chs happy
openerp.web.qweb.default_dict['_s'] = this.origin;
instance.web.qweb.default_dict['_s'] = this.origin;
this.rpc_function = (this.origin == window_origin) ? this.rpc_json : this.rpc_jsonp;
this.session_id = false;
this.uid = false;
@ -896,7 +894,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
this.user_context= {};
this.db = false;
this.openerp_entreprise = false;
this.module_list = openerp._modules.slice();
this.module_list = instance._modules.slice();
this.module_loaded = {};
_(this.module_list).each(function (mod) {
self.module_loaded[mod] = true;
@ -1069,7 +1067,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
try {
var ctx = this.test_eval_contexts(source.contexts);
if (!_.isEqual(ctx, expected.context)) {
openerp.webclient.notification.warn('Context mismatch, report to xmo',
instance.webclient.notification.warn('Context mismatch, report to xmo',
_.str.sprintf(match_template, {
source: JSON.stringify(source.contexts),
local: JSON.stringify(ctx),
@ -1077,7 +1075,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
}), true);
}
} catch (e) {
openerp.webclient.notification.warn('Context fail, report to xmo',
instance.webclient.notification.warn('Context fail, report to xmo',
_.str.sprintf(fail_template, {
error: e.message,
source: JSON.stringify(source.contexts)
@ -1087,7 +1085,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
try {
var dom = this.test_eval_domains(source.domains, this.test_eval_get_context());
if (!_.isEqual(dom, expected.domain)) {
openerp.webclient.notification.warn('Domains mismatch, report to xmo',
instance.webclient.notification.warn('Domains mismatch, report to xmo',
_.str.sprintf(match_template, {
source: JSON.stringify(source.domains),
local: JSON.stringify(dom),
@ -1095,7 +1093,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
}), true);
}
} catch (e) {
openerp.webclient.notification.warn('Domain fail, report to xmo',
instance.webclient.notification.warn('Domain fail, report to xmo',
_.str.sprintf(fail_template, {
error: e.message,
source: JSON.stringify(source.domains)
@ -1105,7 +1103,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
try {
var groups = this.test_eval_groupby(source.group_by_seq);
if (!_.isEqual(groups, expected.group_by)) {
openerp.webclient.notification.warn('GroupBy mismatch, report to xmo',
instance.webclient.notification.warn('GroupBy mismatch, report to xmo',
_.str.sprintf(match_template, {
source: JSON.stringify(source.group_by_seq),
local: JSON.stringify(groups),
@ -1113,7 +1111,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
}), true);
}
} catch (e) {
openerp.webclient.notification.warn('GroupBy fail, report to xmo',
instance.webclient.notification.warn('GroupBy fail, report to xmo',
_.str.sprintf(fail_template, {
error: e.message,
source: JSON.stringify(source.group_by_seq)
@ -1369,7 +1367,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
// TODO: session store in cookie should be optional
this.session_id = this.get_cookie('session_id');
return this.session_reload().pipe(function(result) {
var modules = openerp._modules.join(',');
var modules = instance._modules.join(',');
var deferred = self.rpc('/web/webclient/qweblist', {mods: modules}).pipe(self.do_load_qweb);
if(self.session_is_valid()) {
return deferred.pipe(function() { return self.load_modules(); });
@ -1390,6 +1388,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
// an invalid session or no session at all), refresh session data
// (should not change, but just in case...)
_.extend(self, {
session_id: result.session_id,
db: result.db,
username: result.login,
uid: result.uid,
@ -1491,7 +1490,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
self.rpc('/web/webclient/csslist', {mods: to_load}, self.do_load_css),
self.rpc('/web/webclient/qweblist', {mods: to_load}).pipe(self.do_load_qweb),
self.rpc('/web/webclient/translations', params).pipe(function(trans) {
openerp.web._t.database.set_bundle(trans);
instance.web._t.database.set_bundle(trans);
var file_list = ["/web/static/lib/datejs/globalization/" + lang.replace("_", "-") + ".js"];
return self.rpc('/web/webclient/jslist', {mods: to_load}).pipe(function(files) {
return self.do_load_js(file_list.concat(files));
@ -1553,7 +1552,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
self.qweb_mutex.exec(function() {
return self.rpc('/web/proxy/load', {path: file}).pipe(function(xml) {
if (!xml) { return; }
openerp.web.qweb.add_template(_.str.trim(xml));
instance.web.qweb.add_template(_.str.trim(xml));
});
});
});
@ -1564,10 +1563,10 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
var mod = this.module_list[j];
if(this.module_loaded[mod])
continue;
openerp[mod] = {};
instance[mod] = {};
// init module mod
if(openerp._openerp[mod] != undefined) {
openerp._openerp[mod](openerp);
if(instance._openerp[mod] != undefined) {
instance._openerp[mod](instance);
this.module_loaded[mod] = true;
}
}
@ -1687,10 +1686,10 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
}
});
openerp.web.TranslationDataBase = openerp.web.Class.extend(/** @lends openerp.web.TranslationDataBase# */{
instance.web.TranslationDataBase = instance.web.Class.extend(/** @lends instance.web.TranslationDataBase# */{
/**
* @constructs openerp.web.TranslationDataBase
* @extends openerp.web.Class
* @constructs instance.web.TranslationDataBase
* @extends instance.web.Class
*/
init: function() {
this.db = {};
@ -1741,9 +1740,9 @@ openerp.web.TranslationDataBase = openerp.web.Class.extend(/** @lends openerp.we
});
/**
* @deprecated use :class:`openerp.web.Widget`
* @deprecated use :class:`instance.web.Widget`
*/
openerp.web.OldWidget = openerp.web.Widget.extend({
instance.web.OldWidget = instance.web.Widget.extend({
init: function(parent, element_id) {
this._super(parent);
this.element_id = element_id;
@ -1762,7 +1761,7 @@ openerp.web.OldWidget = openerp.web.Widget.extend({
},
render: function (additional) {
if (this.template)
return openerp.web.qweb.render(this.template, _.extend({widget: this}, additional || {}));
return instance.web.qweb.render(this.template, _.extend({widget: this}, additional || {}));
return null;
}
});

View File

@ -9,10 +9,10 @@ if (!console.debug) {
console.debug = console.log;
}
openerp.web.coresetup = function(openerp) {
openerp.web.coresetup = function(instance) {
/** Configure default qweb */
openerp.web._t = new openerp.web.TranslationDataBase().build_translation_function();
instance.web._t = new instance.web.TranslationDataBase().build_translation_function();
/**
* Lazy translation function, only performs the translation when actually
* printed (e.g. inserted into a template)
@ -24,16 +24,16 @@ openerp.web._t = new openerp.web.TranslationDataBase().build_translation_functio
* @param {String} s string to translate
* @returns {Object} lazy translation object
*/
openerp.web._lt = function (s) {
return {toString: function () { return openerp.web._t(s); }}
instance.web._lt = function (s) {
return {toString: function () { return instance.web._t(s); }}
};
openerp.web.qweb = new QWeb2.Engine();
openerp.web.qweb.debug = ($.deparam($.param.querystring()).debug != undefined);
openerp.web.qweb.default_dict = {
instance.web.qweb = new QWeb2.Engine();
instance.web.qweb.debug = ($.deparam($.param.querystring()).debug != undefined);
instance.web.qweb.default_dict = {
'_' : _,
'_t' : openerp.web._t
'_t' : instance.web._t
};
openerp.web.qweb.preprocess_node = function() {
instance.web.qweb.preprocess_node = function() {
// Note that 'this' is the Qweb Node
switch (this.node.nodeType) {
case 3:
@ -47,7 +47,7 @@ openerp.web.qweb.preprocess_node = function() {
if (ts.length === 0) {
return;
}
var tr = openerp.web._t(ts);
var tr = instance.web._t(ts);
if (tr !== ts) {
this.node.data = tr;
}
@ -57,7 +57,7 @@ openerp.web.qweb.preprocess_node = function() {
var attr, attrs = ['label', 'title', 'alt'];
while (attr = attrs.pop()) {
if (this.attributes[attr]) {
this.attributes[attr] = openerp.web._t(this.attributes[attr]);
this.attributes[attr] = instance.web._t(this.attributes[attr]);
}
}
}
@ -99,8 +99,8 @@ $.Mutex = (function() {
})();
/** Setup default connection */
openerp.connection = new openerp.web.Connection();
openerp.web.qweb.default_dict['__debug__'] = openerp.connection.debug;
instance.connection = new instance.web.Connection();
instance.web.qweb.default_dict['__debug__'] = instance.connection.debug;
$.async_when = function() {
var async = false;
@ -131,7 +131,7 @@ $.async_when = function() {
// special tweak for the web client
var old_async_when = $.async_when;
$.async_when = function() {
if (openerp.connection.synch)
if (instance.connection.synch)
return $.when.apply(this, arguments);
else
return old_async_when.apply(this, arguments);

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
openerp.web.data_export = function(openerp) {
var QWeb = openerp.web.qweb,
_t = openerp.web._t;
openerp.web.DataExport = openerp.web.Dialog.extend({
openerp.web.data_export = function(instance) {
var QWeb = instance.web.qweb,
_t = instance.web._t;
instance.web.DataExport = instance.web.Dialog.extend({
template: 'ExportTreeView',
dialog_title: {toString: function () { return _t("Export Data"); }},
init: function(parent, dataset) {
this._super(parent);
this.records = {};
this.dataset = dataset;
this.exports = new openerp.web.DataSetSearch(
this.exports = new instance.web.DataSetSearch(
this, 'ir.exports', this.dataset.get_context());
},
start: function() {

View File

@ -1,6 +1,6 @@
openerp.web.data_import = function(openerp) {
var QWeb = openerp.web.qweb,
_t = openerp.web._t;
openerp.web.data_import = function(instance) {
var QWeb = instance.web.qweb,
_t = instance.web._t;
/**
* Safari does not deal well at all with raw JSON data being returned. As a
* result, we're going to cheat by using a pseudo-jsonp: instead of getting
@ -29,7 +29,7 @@ function jsonp(form, attributes, callback) {
$(form).ajaxSubmit(attributes);
}
openerp.web.DataImport = openerp.web.Dialog.extend({
instance.web.DataImport = instance.web.Dialog.extend({
template: 'ImportDataView',
dialog_title: {toString: function () { return _t("Import Data"); }},
init: function(parent, dataset){
@ -79,10 +79,10 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
this.$element.delegate('fieldset legend', 'click', function() {
$(this).parent().toggleClass('oe-closed');
});
this.ready.push(new openerp.web.DataSet(this, this.model).call(
this.ready.push(new instance.web.DataSet(this, this.model).call(
'fields_get', [], function (fields) {
self.graft_fields(fields);
self.ready.push(new openerp.web.DataSet(self, self.model)
self.ready.push(new instance.web.DataSet(self, self.model)
.default_get(_.pluck(self.fields, 'id')).then(function (fields) {
_.each(fields, function(val, key) {
if (val) {
@ -140,7 +140,7 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
f.fields = [];
// only fetch sub-fields to a depth of 2 levels
if (level < 2) {
self.ready.push(new openerp.web.DataSet(self, field.relation).call(
self.ready.push(new instance.web.DataSet(self, field.relation).call(
'fields_get', [], function (fields) {
self.graft_fields(fields, f, level+1);
}));
@ -151,7 +151,7 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
});
},
toggle_import_button: function (newstate) {
openerp.web.dialog(this.$element, 'widget')
instance.web.dialog(this.$element, 'widget')
.find('.oe-dialog-import-button')
.button('option', 'disabled', !newstate);
},

View File

@ -1,5 +1,5 @@
openerp.web.dates = function(openerp) {
openerp.web.dates = function(instance) {
/**
* Converts a string to a Date javascript object using OpenERP's
@ -11,7 +11,7 @@ openerp.web.dates = function(openerp) {
* @param {String} str A string representing a datetime.
* @returns {Date}
*/
openerp.web.str_to_datetime = function(str) {
instance.web.str_to_datetime = function(str) {
if(!str) {
return str;
}
@ -38,7 +38,7 @@ openerp.web.str_to_datetime = function(str) {
* @param {String} str A string representing a date.
* @returns {Date}
*/
openerp.web.str_to_date = function(str) {
instance.web.str_to_date = function(str) {
if(!str) {
return str;
}
@ -65,7 +65,7 @@ openerp.web.str_to_date = function(str) {
* @param {String} str A string representing a time.
* @returns {Date}
*/
openerp.web.str_to_time = function(str) {
instance.web.str_to_time = function(str) {
if(!str) {
return str;
}
@ -104,7 +104,7 @@ var zpad = function(str, size) {
* @param {Date} obj
* @returns {String} A string representing a datetime.
*/
openerp.web.datetime_to_str = function(obj) {
instance.web.datetime_to_str = function(obj) {
if (!obj) {
return false;
}
@ -124,7 +124,7 @@ openerp.web.datetime_to_str = function(obj) {
* @param {Date} obj
* @returns {String} A string representing a date.
*/
openerp.web.date_to_str = function(obj) {
instance.web.date_to_str = function(obj) {
if (!obj) {
return false;
}
@ -143,7 +143,7 @@ openerp.web.date_to_str = function(obj) {
* @param {Date} obj
* @returns {String} A string representing a time.
*/
openerp.web.time_to_str = function(obj) {
instance.web.time_to_str = function(obj) {
if (!obj) {
return false;
}

View File

@ -1,6 +1,6 @@
openerp.web.formats = function(openerp) {
var _t = openerp.web._t;
openerp.web.formats = function(instance) {
var _t = instance.web._t;
/**
* Intersperses ``separator`` in ``str`` at the positions indicated by
@ -23,7 +23,7 @@ var _t = openerp.web._t;
* @param {String} separator
* @returns {String}
*/
openerp.web.intersperse = function (str, indices, separator) {
instance.web.intersperse = function (str, indices, separator) {
separator = separator || '';
var result = [], last = str.length;
@ -55,10 +55,10 @@ openerp.web.intersperse = function (str, indices, separator) {
* @param {String} num
* @returns {String}
*/
openerp.web.insert_thousand_seps = function (num) {
instance.web.insert_thousand_seps = function (num) {
var negative = num[0] === '-';
num = (negative ? num.slice(1) : num);
return (negative ? '-' : '') + openerp.web.intersperse(
return (negative ? '-' : '') + instance.web.intersperse(
num, _t.database.parameters.grouping, _t.database.parameters.thousands_sep);
};
@ -69,7 +69,7 @@ openerp.web.insert_thousand_seps = function (num) {
*
* @param {String} value original format
*/
openerp.web.strip_raw_chars = function (value) {
instance.web.strip_raw_chars = function (value) {
var isletter = /[a-zA-Z]/, output = [];
for(var index=0; index < value.length; ++index) {
var character = value[index];
@ -81,7 +81,7 @@ openerp.web.strip_raw_chars = function (value) {
return output.join('');
};
var normalize_format = function (format) {
return Date.normalizeFormat(openerp.web.strip_raw_chars(format));
return Date.normalizeFormat(instance.web.strip_raw_chars(format));
};
/**
* Formats a single atomic value based on a field descriptor
@ -93,7 +93,7 @@ var normalize_format = function (format) {
* @param {Object} [descriptor.digits] used for the formatting of floats
* @param {String} [value_if_empty=''] returned if the ``value`` argument is considered empty
*/
openerp.web.format_value = function (value, descriptor, value_if_empty) {
instance.web.format_value = function (value, descriptor, value_if_empty) {
// If NaN value, display as with a `false` (empty cell)
if (typeof value === 'number' && isNaN(value)) {
value = false;
@ -111,16 +111,16 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
return value_if_empty === undefined ? '' : value_if_empty;
}
var l10n = _t.database.parameters;
switch (descriptor.widget || descriptor.type) {
switch (descriptor.type || (descriptor.field && descriptor.field.type)) {
case 'id':
return value.toString();
case 'integer':
return openerp.web.insert_thousand_seps(
return instance.web.insert_thousand_seps(
_.str.sprintf('%d', value));
case 'float':
var precision = descriptor.digits ? descriptor.digits[1] : 2;
var formatted = _.str.sprintf('%.' + precision + 'f', value).split('.');
formatted[0] = openerp.web.insert_thousand_seps(formatted[0]);
formatted[0] = instance.web.insert_thousand_seps(formatted[0]);
return formatted.join(l10n.decimal_point);
case 'float_time':
var pattern = '%02d:%02d';
@ -136,17 +136,17 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
return value[1];
case 'datetime':
if (typeof(value) == "string")
value = openerp.web.auto_str_to_date(value);
value = instance.web.auto_str_to_date(value);
return value.toString(normalize_format(l10n.date_format)
+ ' ' + normalize_format(l10n.time_format));
case 'date':
if (typeof(value) == "string")
value = openerp.web.auto_str_to_date(value);
value = instance.web.auto_str_to_date(value);
return value.toString(normalize_format(l10n.date_format));
case 'time':
if (typeof(value) == "string")
value = openerp.web.auto_str_to_date(value);
value = instance.web.auto_str_to_date(value);
return value.toString(normalize_format(l10n.time_format));
case 'selection': case 'statusbar':
// Each choice is [value, label]
@ -163,7 +163,7 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
}
};
openerp.web.parse_value = function (value, descriptor, value_if_empty) {
instance.web.parse_value = function (value, descriptor, value_if_empty) {
var date_pattern = normalize_format(_t.database.parameters.date_format),
time_pattern = normalize_format(_t.database.parameters.time_format);
switch (value) {
@ -171,12 +171,12 @@ openerp.web.parse_value = function (value, descriptor, value_if_empty) {
case "":
return value_if_empty === undefined ? false : value_if_empty;
}
switch (descriptor.widget || descriptor.type) {
switch (descriptor.type || (descriptor.field && descriptor.field.type)) {
case 'integer':
var tmp;
do {
tmp = value;
value = value.replace(openerp.web._t.database.parameters.thousands_sep, "");
value = value.replace(instance.web._t.database.parameters.thousands_sep, "");
} while(tmp !== value);
tmp = Number(value);
if (isNaN(tmp))
@ -190,9 +190,9 @@ openerp.web.parse_value = function (value, descriptor, value_if_empty) {
var tmp2 = value;
do {
tmp = tmp2;
tmp2 = tmp.replace(openerp.web._t.database.parameters.thousands_sep, "");
tmp2 = tmp.replace(instance.web._t.database.parameters.thousands_sep, "");
} while(tmp !== tmp2);
var reformatted_value = tmp.replace(openerp.web._t.database.parameters.decimal_point, ".");
var reformatted_value = tmp.replace(instance.web._t.database.parameters.decimal_point, ".");
var parsed = Number(reformatted_value);
if (isNaN(parsed))
throw new Error(value + " is not a correct float");
@ -205,62 +205,62 @@ openerp.web.parse_value = function (value, descriptor, value_if_empty) {
}
var float_time_pair = value.split(":");
if (float_time_pair.length != 2)
return factor * openerp.web.parse_value(value, {type: "float"});
var hours = openerp.web.parse_value(float_time_pair[0], {type: "integer"});
var minutes = openerp.web.parse_value(float_time_pair[1], {type: "integer"});
return factor * instance.web.parse_value(value, {type: "float"});
var hours = instance.web.parse_value(float_time_pair[0], {type: "integer"});
var minutes = instance.web.parse_value(float_time_pair[1], {type: "integer"});
return factor * (hours + (minutes / 60));
case 'progressbar':
return openerp.web.parse_value(value, {type: "float"});
return instance.web.parse_value(value, {type: "float"});
case 'datetime':
var datetime = Date.parseExact(
value, (date_pattern + ' ' + time_pattern));
if (datetime !== null)
return openerp.web.datetime_to_str(datetime);
return instance.web.datetime_to_str(datetime);
datetime = Date.parse(value);
if (datetime !== null)
return openerp.web.datetime_to_str(datetime);
return instance.web.datetime_to_str(datetime);
throw new Error(value + " is not a valid datetime");
case 'date':
var date = Date.parseExact(value, date_pattern);
if (date !== null)
return openerp.web.date_to_str(date);
return instance.web.date_to_str(date);
date = Date.parse(value);
if (date !== null)
return openerp.web.date_to_str(date);
return instance.web.date_to_str(date);
throw new Error(value + " is not a valid date");
case 'time':
var time = Date.parseExact(value, time_pattern);
if (time !== null)
return openerp.web.time_to_str(time);
return instance.web.time_to_str(time);
time = Date.parse(value);
if (time !== null)
return openerp.web.time_to_str(time);
return instance.web.time_to_str(time);
throw new Error(value + " is not a valid time");
}
return value;
};
openerp.web.auto_str_to_date = function(value, type) {
instance.web.auto_str_to_date = function(value, type) {
try {
return openerp.web.str_to_datetime(value);
return instance.web.str_to_datetime(value);
} catch(e) {}
try {
return openerp.web.str_to_date(value);
return instance.web.str_to_date(value);
} catch(e) {}
try {
return openerp.web.str_to_time(value);
return instance.web.str_to_time(value);
} catch(e) {}
throw new Error("'" + value + "' is not a valid date, datetime nor time");
};
openerp.web.auto_date_to_str = function(value, type) {
instance.web.auto_date_to_str = function(value, type) {
switch(type) {
case 'datetime':
return openerp.web.datetime_to_str(value);
return instance.web.datetime_to_str(value);
case 'date':
return openerp.web.date_to_str(value);
return instance.web.date_to_str(value);
case 'time':
return openerp.web.time_to_str(value);
return instance.web.time_to_str(value);
default:
throw new Error(type + " is not convertible to date, datetime nor time");
}
@ -290,7 +290,7 @@ openerp.web.auto_date_to_str = function(value, type) {
* @param {Number} [options.id] current record's id
*
*/
openerp.web.format_cell = function (row_data, column, options) {
instance.web.format_cell = function (row_data, column, options) {
options = options || {};
var attrs = {};
if (options.process_modifiers !== false) {
@ -303,9 +303,9 @@ openerp.web.format_cell = function (row_data, column, options) {
'<img src="<%-prefix%>/web/static/src/img/icons/<%-icon%>.png" alt="<%-alt%>"/>' +
'</button>', {
title: column.string || '',
additional_attributes: isNaN(row_data["id"].value) && openerp.web.BufferedDataSet.virtual_id_regex.test(row_data["id"].value) ?
additional_attributes: isNaN(row_data["id"].value) && instance.web.BufferedDataSet.virtual_id_regex.test(row_data["id"].value) ?
'disabled="disabled" class="oe-listview-button-disabled"' : '',
prefix: openerp.connection.prefix,
prefix: instance.connection.prefix,
icon: column.icon,
alt: column.string || ''
});
@ -320,11 +320,11 @@ openerp.web.format_cell = function (row_data, column, options) {
row_data[column.id].value ? 'checked="checked"' : '');
case "binary":
var text = _t("Download"),
download_url = _.str.sprintf('/web/binary/saveas?session_id=%s&model=%s&field=%s&id=%d', openerp.connection.session_id, options.model, column.id, options.id);
download_url = _.str.sprintf('/web/binary/saveas?session_id=%s&model=%s&field=%s&id=%d', instance.connection.session_id, options.model, column.id, options.id);
if (column.filename) {
download_url += '&filename_field=' + column.filename;
if (row_data[column.filename]) {
text = _.str.sprintf(_t("Download \"%s\""), openerp.web.format_value(
text = _.str.sprintf(_t("Download \"%s\""), instance.web.format_value(
row_data[column.filename].value, {type: 'char'}));
}
}
@ -340,7 +340,7 @@ openerp.web.format_cell = function (row_data, column, options) {
});
}
return _.escape(openerp.web.format_value(
return _.escape(instance.web.format_value(
row_data[column.id].value, column, options.value_if_empty));
}

View File

@ -1,7 +1,7 @@
openerp.web.search = function(openerp) {
var QWeb = openerp.web.qweb,
_t = openerp.web._t,
_lt = openerp.web._lt;
openerp.web.search = function(instance) {
var QWeb = instance.web.qweb,
_t = instance.web._t,
_lt = instance.web._lt;
_.mixin({
sum: function (obj) { return _.reduce(obj, function (a, b) { return a + b; }, 0); }
});
@ -70,11 +70,11 @@ _.extend(VS.model.SearchFacet.prototype, {
}
});
openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.SearchView# */{
instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.SearchView# */{
template: "SearchView",
/**
* @constructs openerp.web.SearchView
* @extends openerp.web.OldWidget
* @constructs instance.web.SearchView
* @extends instance.web.OldWidget
*
* @param parent
* @param element_id
@ -178,7 +178,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
var running_count = 0;
// get total filters count
var is_group = function (i) { return i instanceof openerp.web.search.FilterGroup; };
var is_group = function (i) { return i instanceof instance.web.search.FilterGroup; };
var filters_count = _(this.controls).chain()
.flatten()
.filter(is_group)
@ -212,12 +212,12 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
name: _t("Custom Filters"),
filters: _.map(this.custom_filters, function (filter) {
// FIXME: handling of ``disabled`` being set
var f = new openerp.web.search.Filter({attrs: {
var f = new instance.web.search.Filter({attrs: {
string: filter.name,
context: filter.context,
domain: filter.domain
}}, self);
return new openerp.web.search.FilterGroup([f], self);
return new instance.web.search.FilterGroup([f], self);
}),
length: 3
});
@ -225,7 +225,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
return $.when(
this.render_column(col1, $('<div>').appendTo($filters)),
this.render_column(col2, $('<div>').appendTo($filters)),
(new openerp.web.search.Advanced(this).appendTo($drawer)));
(new instance.web.search.Advanced(this).appendTo($drawer)));
},
render_column: function (column, $el) {
return $.when.apply(null, _(column).map(function (group) {
@ -314,10 +314,10 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
* @param {VS.model.SearchFacet} options.model facet object to render
*/
make_visualsearch_facet: function (options) {
return new openerp.web.search.FilterGroupFacet(options);
return new instance.web.search.FilterGroupFacet(options);
// if (options.model.get('field') instanceof openerp.web.search.FilterGroup) {
// return new openerp.web.search.FilterGroupFacet(options);
// if (options.model.get('field') instanceof instance.web.search.FilterGroup) {
// return new instance.web.search.FilterGroupFacet(options);
// }
// return new VS.ui.SearchFacet(options);
},
@ -363,7 +363,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
var filters = [];
_.each(items, function (item) {
if (filters.length && item.tag !== 'filter') {
group.push(new openerp.web.search.FilterGroup(filters, this));
group.push(new instance.web.search.FilterGroup(filters, this));
filters = [];
}
@ -371,7 +371,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
case 'separator': case 'newline':
break;
case 'filter':
filters.push(new openerp.web.search.Filter(item, this));
filters.push(new instance.web.search.Filter(item, this));
break;
case 'group':
self.make_widgets(item.children, fields, item.attrs.string);
@ -385,7 +385,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
}, this);
if (filters.length) {
group.push(new openerp.web.search.FilterGroup(filters, this));
group.push(new instance.web.search.FilterGroup(filters, this));
}
},
/**
@ -394,10 +394,10 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
*
* @param {Object} item fields_view_get node for the field
* @param {Object} field fields_get result for the field
* @returns openerp.web.search.Field
* @returns instance.web.search.Field
*/
make_field: function (item, field) {
var obj = openerp.web.search.fields.get_any( [item.attrs.widget, field.type]);
var obj = instance.web.search.fields.get_any( [item.attrs.widget, field.type]);
if(obj) {
return new (obj) (item, field, this);
} else {
@ -460,11 +460,11 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
break;
case 'save_filter':
var data = this.build_search_data();
var context = new openerp.web.CompoundContext();
var context = new instance.web.CompoundContext();
_.each(data.contexts, function(x) {
context.add(x);
});
var domain = new openerp.web.CompoundDomain();
var domain = new instance.web.CompoundDomain();
_.each(data.domains, function(x) {
domain.add(x);
});
@ -472,7 +472,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
context.add({"group_by": groupbys});
var dial_html = QWeb.render("SearchView.managed-filters.add");
var $dial = $(dial_html);
openerp.web.dialog($dial, {
instance.web.dialog($dial, {
modal: true,
title: _t("Filter Entry"),
buttons: [
@ -525,13 +525,13 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
on_add_to_dashboard: function() {
this.$element.find(".oe_search-view-filters-management")[0].selectedIndex = 0;
var self = this,
menu = openerp.webclient.menu,
menu = instance.webclient.menu,
$dialog = $(QWeb.render("SearchView.add_to_dashboard", {
dashboards : menu.data.data.children,
selected_menu_id : menu.$element.find('a.active').data('menu')
}));
$dialog.find('input').val(this.fields_view.name);
openerp.web.dialog($dialog, {
instance.web.dialog($dialog, {
modal: true,
title: _t("Add to Dashboard"),
buttons: [
@ -543,8 +543,8 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
var menu_id = $(this).find("select").val(),
title = $(this).find("input").val(),
data = self.build_search_data(),
context = new openerp.web.CompoundContext(),
domain = new openerp.web.CompoundDomain();
context = new instance.web.CompoundContext(),
domain = new instance.web.CompoundDomain();
_.each(data.contexts, function(x) {
context.add(x);
});
@ -573,10 +573,10 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
* Performs the search view collection of widget data.
*
* If the collection went well (all fields are valid), then triggers
* :js:func:`openerp.web.SearchView.on_search`.
* :js:func:`instance.web.SearchView.on_search`.
*
* If at least one field failed its validation, triggers
* :js:func:`openerp.web.SearchView.on_invalid` instead.
* :js:func:`instance.web.SearchView.on_invalid` instead.
*
* @param e jQuery event object coming from the "Search" button
*/
@ -599,7 +599,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
groupbys.push.apply(groupbys, group_by);
}
} catch (e) {
if (e instanceof openerp.web.search.Invalid) {
if (e instanceof instance.web.search.Invalid) {
errors.push(e);
} else {
throw e;
@ -648,9 +648,9 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
});
/** @namespace */
openerp.web.search = {};
instance.web.search = {};
openerp.web.search.FilterGroupFacet = VS.ui.SearchFacet.extend({
instance.web.search.FilterGroupFacet = VS.ui.SearchFacet.extend({
events: _.extend({
'click': 'selectFacet'
}, VS.ui.SearchFacet.prototype.events),
@ -682,30 +682,30 @@ openerp.web.search.FilterGroupFacet = VS.ui.SearchFacet.extend({
}
});
/**
* Registry of search fields, called by :js:class:`openerp.web.SearchView` to
* Registry of search fields, called by :js:class:`instance.web.SearchView` to
* find and instantiate its field widgets.
*/
openerp.web.search.fields = new openerp.web.Registry({
'char': 'openerp.web.search.CharField',
'text': 'openerp.web.search.CharField',
'boolean': 'openerp.web.search.BooleanField',
'integer': 'openerp.web.search.IntegerField',
'id': 'openerp.web.search.IntegerField',
'float': 'openerp.web.search.FloatField',
'selection': 'openerp.web.search.SelectionField',
'datetime': 'openerp.web.search.DateTimeField',
'date': 'openerp.web.search.DateField',
'many2one': 'openerp.web.search.ManyToOneField',
'many2many': 'openerp.web.search.CharField',
'one2many': 'openerp.web.search.CharField'
instance.web.search.fields = new instance.web.Registry({
'char': 'instance.web.search.CharField',
'text': 'instance.web.search.CharField',
'boolean': 'instance.web.search.BooleanField',
'integer': 'instance.web.search.IntegerField',
'id': 'instance.web.search.IntegerField',
'float': 'instance.web.search.FloatField',
'selection': 'instance.web.search.SelectionField',
'datetime': 'instance.web.search.DateTimeField',
'date': 'instance.web.search.DateField',
'many2one': 'instance.web.search.ManyToOneField',
'many2many': 'instance.web.search.CharField',
'one2many': 'instance.web.search.CharField'
});
openerp.web.search.Invalid = openerp.web.Class.extend( /** @lends openerp.web.search.Invalid# */{
instance.web.search.Invalid = instance.web.Class.extend( /** @lends instance.web.search.Invalid# */{
/**
* Exception thrown by search widgets when they hold invalid values,
* which they can not return when asked.
*
* @constructs openerp.web.search.Invalid
* @extends openerp.web.Class
* @constructs instance.web.search.Invalid
* @extends instance.web.Class
*
* @param field the name of the field holding an invalid value
* @param value the invalid value
@ -723,13 +723,13 @@ openerp.web.search.Invalid = openerp.web.Class.extend( /** @lends openerp.web.se
);
}
});
openerp.web.search.Widget = openerp.web.OldWidget.extend( /** @lends openerp.web.search.Widget# */{
instance.web.search.Widget = instance.web.OldWidget.extend( /** @lends instance.web.search.Widget# */{
template: null,
/**
* Root class of all search widgets
*
* @constructs openerp.web.search.Widget
* @extends openerp.web.OldWidget
* @constructs instance.web.search.Widget
* @extends instance.web.OldWidget
*
* @param view the ancestor view of this widget
*/
@ -738,14 +738,14 @@ openerp.web.search.Widget = openerp.web.OldWidget.extend( /** @lends openerp.web
this.view = view;
}
});
openerp.web.search.add_expand_listener = function($root) {
instance.web.search.add_expand_listener = function($root) {
$root.find('a.searchview_group_string').click(function (e) {
$root.toggleClass('folded expanded');
e.stopPropagation();
e.preventDefault();
});
};
openerp.web.search.Group = openerp.web.search.Widget.extend({
instance.web.search.Group = instance.web.search.Widget.extend({
template: 'SearchView.group',
init: function (view_section, view, fields) {
this._super(view);
@ -755,10 +755,10 @@ openerp.web.search.Group = openerp.web.search.Widget.extend({
}
});
openerp.web.search.Input = openerp.web.search.Widget.extend( /** @lends openerp.web.search.Input# */{
instance.web.search.Input = instance.web.search.Widget.extend( /** @lends instance.web.search.Input# */{
/**
* @constructs openerp.web.search.Input
* @extends openerp.web.search.Widget
* @constructs instance.web.search.Input
* @extends instance.web.search.Widget
*
* @param view
*/
@ -784,7 +784,7 @@ openerp.web.search.Input = openerp.web.search.Widget.extend( /** @lends openerp.
* they apply to this widget, or null if they don't.
*
* This default implementation will try calling
* :js:func:`openerp.web.search.Input#facet_for` if the widget's name
* :js:func:`instance.web.search.Input#facet_for` if the widget's name
* matches the input key
*
* @param {Object} defaults
@ -820,17 +820,17 @@ openerp.web.search.Input = openerp.web.search.Widget.extend( /** @lends openerp.
this.attrs = attrs;
}
});
openerp.web.search.FilterGroup = openerp.web.search.Input.extend(/** @lends openerp.web.search.FilterGroup# */{
instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends instance.web.search.FilterGroup# */{
template: 'SearchView.filters',
/**
* Inclusive group of filters, creates a continuous "button" with clickable
* sections (the normal display for filters is to be a self-contained button)
*
* @constructs openerp.web.search.FilterGroup
* @extends openerp.web.search.Input
* @constructs instance.web.search.FilterGroup
* @extends instance.web.search.Input
*
* @param {Array<openerp.web.search.Filter>} filters elements of the group
* @param {openerp.web.SearchView} view view in which the filters are contained
* @param {Array<instance.web.search.Filter>} filters elements of the group
* @param {instance.web.SearchView} view view in which the filters are contained
*/
init: function (filters, view) {
this._super(view);
@ -868,7 +868,7 @@ openerp.web.search.FilterGroup = openerp.web.search.Input.extend(/** @lends open
if (!contexts.length) { return; }
if (contexts.length === 1) { return contexts[0]; }
return _.extend(new openerp.web.CompoundContext, {
return _.extend(new instance.web.CompoundContext, {
__contexts: contexts
});
},
@ -901,7 +901,7 @@ openerp.web.search.FilterGroup = openerp.web.search.Input.extend(/** @lends open
for (var i=domains.length; --i;) {
domains.unshift(['|']);
}
return _.extend(new openerp.web.CompoundDomain(), {
return _.extend(new instance.web.CompoundDomain(), {
__domains: domains
});
},
@ -945,7 +945,7 @@ openerp.web.search.FilterGroup = openerp.web.search.Input.extend(/** @lends open
});
}
});
openerp.web.search.Filter = openerp.web.search.Input.extend(/** @lends openerp.web.search.Filter# */{
instance.web.search.Filter = instance.web.search.Input.extend(/** @lends instance.web.search.Filter# */{
template: 'SearchView.filter',
/**
* Implementation of the OpenERP filters (button with a context and/or
@ -955,8 +955,8 @@ openerp.web.search.Filter = openerp.web.search.Input.extend(/** @lends openerp.w
* domains and contexts, converting between facets and filters) is
* performed by the filter group.
*
* @constructs openerp.web.search.Filter
* @extends openerp.web.search.Input
* @constructs instance.web.search.Filter
* @extends instance.web.search.Input
*
* @param node
* @param view
@ -969,12 +969,12 @@ openerp.web.search.Filter = openerp.web.search.Input.extend(/** @lends openerp.w
get_context: function () { },
get_domain: function () { },
});
openerp.web.search.Field = openerp.web.search.Input.extend( /** @lends openerp.web.search.Field# */ {
instance.web.search.Field = instance.web.search.Input.extend( /** @lends instance.web.search.Field# */ {
template: 'SearchView.field',
default_operator: '=',
/**
* @constructs openerp.web.search.Field
* @extends openerp.web.search.Input
* @constructs instance.web.search.Field
* @extends instance.web.search.Input
*
* @param view_section
* @param field
@ -1005,7 +1005,7 @@ openerp.web.search.Field = openerp.web.search.Input.extend( /** @lends openerp.w
if (!(has_value && context)) {
return;
}
return new openerp.web.CompoundContext(context)
return new instance.web.CompoundContext(context)
.set_eval_context({self: val});
},
get_groupby: function () { },
@ -1036,7 +1036,7 @@ openerp.web.search.Field = openerp.web.search.Input.extend( /** @lends openerp.w
this.attrs.operator || this.default_operator,
facet);
}
return new openerp.web.CompoundDomain(domain)
return new instance.web.CompoundDomain(domain)
.set_eval_context({self: val});
}
});
@ -1048,9 +1048,9 @@ openerp.web.search.Field = openerp.web.search.Input.extend( /** @lends openerp.w
* * The Javascript and the HTML values are identical (strings)
*
* @class
* @extends openerp.web.search.Field
* @extends instance.web.search.Field
*/
openerp.web.search.CharField = openerp.web.search.Field.extend( /** @lends openerp.web.search.CharField# */ {
instance.web.search.CharField = instance.web.search.Field.extend( /** @lends instance.web.search.CharField# */ {
default_operator: 'ilike',
complete: function (value) {
if (_.isEmpty(value)) { return $.when(null); }
@ -1066,7 +1066,7 @@ openerp.web.search.CharField = openerp.web.search.Field.extend( /** @lends opene
}]);
}
});
openerp.web.search.NumberField = openerp.web.search.Field.extend(/** @lends openerp.web.search.NumberField# */{
instance.web.search.NumberField = instance.web.search.Field.extend(/** @lends instance.web.search.NumberField# */{
get_value: function () {
if (!this.$element.val()) {
return null;
@ -1075,7 +1075,7 @@ openerp.web.search.NumberField = openerp.web.search.Field.extend(/** @lends open
check = Number(this.$element.val());
if (isNaN(val) || val !== check) {
this.$element.addClass('error');
throw new openerp.web.search.Invalid(
throw new instance.web.search.Invalid(
this.attrs.name, this.$element.val(), this.error_message);
}
this.$element.removeClass('error');
@ -1084,13 +1084,13 @@ openerp.web.search.NumberField = openerp.web.search.Field.extend(/** @lends open
});
/**
* @class
* @extends openerp.web.search.NumberField
* @extends instance.web.search.NumberField
*/
openerp.web.search.IntegerField = openerp.web.search.NumberField.extend(/** @lends openerp.web.search.IntegerField# */{
instance.web.search.IntegerField = instance.web.search.NumberField.extend(/** @lends instance.web.search.IntegerField# */{
error_message: _t("not a valid integer"),
parse: function (value) {
try {
return openerp.web.parse_value(value, {'widget': 'integer'});
return instance.web.parse_value(value, {'widget': 'integer'});
} catch (e) {
return NaN;
}
@ -1098,13 +1098,13 @@ openerp.web.search.IntegerField = openerp.web.search.NumberField.extend(/** @len
});
/**
* @class
* @extends openerp.web.search.NumberField
* @extends instance.web.search.NumberField
*/
openerp.web.search.FloatField = openerp.web.search.NumberField.extend(/** @lends openerp.web.search.FloatField# */{
instance.web.search.FloatField = instance.web.search.NumberField.extend(/** @lends instance.web.search.FloatField# */{
error_message: _t("not a valid number"),
parse: function (value) {
try {
return openerp.web.parse_value(value, {'widget': 'float'});
return instance.web.parse_value(value, {'widget': 'float'});
} catch (e) {
return NaN;
}
@ -1112,9 +1112,9 @@ openerp.web.search.FloatField = openerp.web.search.NumberField.extend(/** @lends
});
/**
* @class
* @extends openerp.web.search.Field
* @extends instance.web.search.Field
*/
openerp.web.search.SelectionField = openerp.web.search.Field.extend(/** @lends openerp.web.search.SelectionField# */{
instance.web.search.SelectionField = instance.web.search.Field.extend(/** @lends instance.web.search.SelectionField# */{
// This implementation is a basic <select> field, but it may have to be
// altered to be more in line with the GTK client, which uses a combo box
// (~ jquery.autocomplete):
@ -1171,10 +1171,10 @@ openerp.web.search.SelectionField = openerp.web.search.Field.extend(/** @lends o
return facet.get('json');
}
});
openerp.web.search.BooleanField = openerp.web.search.SelectionField.extend(/** @lends openerp.web.search.BooleanField# */{
instance.web.search.BooleanField = instance.web.search.SelectionField.extend(/** @lends instance.web.search.BooleanField# */{
/**
* @constructs openerp.web.search.BooleanField
* @extends openerp.web.search.BooleanField
* @constructs instance.web.search.BooleanField
* @extends instance.web.search.BooleanField
*/
init: function () {
this._super.apply(this, arguments);
@ -1193,16 +1193,16 @@ openerp.web.search.BooleanField = openerp.web.search.SelectionField.extend(/** @
});
/**
* @class
* @extends openerp.web.search.DateField
* @extends instance.web.search.DateField
*/
openerp.web.search.DateField = openerp.web.search.Field.extend(/** @lends openerp.web.search.DateField# */{
instance.web.search.DateField = instance.web.search.Field.extend(/** @lends instance.web.search.DateField# */{
get_value: function (facet) {
return openerp.web.date_to_str(facet.get('json'));
return instance.web.date_to_str(facet.get('json'));
},
complete: function (needle) {
var d = Date.parse(needle);
if (!d) { return $.when(null); }
var value = openerp.web.format_value(d, this.attrs);
var value = instance.web.format_value(d, this.attrs);
var label = _.str.sprintf(_.str.escapeHTML(
_t("Search %(field)s at: %(value)s")), {
field: '<em>' + this.attrs.string + '</em>',
@ -1225,17 +1225,17 @@ openerp.web.search.DateField = openerp.web.search.Field.extend(/** @lends opener
* spanning the whole day selected by the date widget
*
* @class
* @extends openerp.web.DateField
* @extends instance.web.DateField
*/
openerp.web.search.DateTimeField = openerp.web.search.DateField.extend(/** @lends openerp.web.search.DateTimeField# */{
instance.web.search.DateTimeField = instance.web.search.DateField.extend(/** @lends instance.web.search.DateTimeField# */{
get_value: function (facet) {
return openerp.web.datetime_to_str(facet.get('json'));
return instance.web.datetime_to_str(facet.get('json'));
}
});
openerp.web.search.ManyToOneField = openerp.web.search.CharField.extend({
instance.web.search.ManyToOneField = instance.web.search.CharField.extend({
init: function (view_section, field, view) {
this._super(view_section, field, view);
this.model = new openerp.web.Model(this.attrs.relation);
this.model = new instance.web.Model(this.attrs.relation);
},
complete: function (needle) {
var self = this;
@ -1289,7 +1289,7 @@ openerp.web.search.ManyToOneField = openerp.web.search.CharField.extend({
}
});
openerp.web.search.Advanced = openerp.web.search.Input.extend({
instance.web.search.Advanced = instance.web.search.Input.extend({
template: 'SearchView.advanced',
start: function () {
var self = this;
@ -1314,7 +1314,7 @@ openerp.web.search.Advanced = openerp.web.search.Input.extend({
});
},
append_proposition: function () {
return (new openerp.web.search.ExtendedSearchProposition(this, this.fields))
return (new instance.web.search.ExtendedSearchProposition(this, this.fields))
.appendTo(this.$element.find('ul'));
},
commit_search: function () {
@ -1323,14 +1323,14 @@ openerp.web.search.Advanced = openerp.web.search.Input.extend({
var children = this.getChildren(),
domain = _.invoke(children, 'get_proposition');
var filters = _(domain).map(function (section) {
return new openerp.web.search.Filter({attrs: {
return new instance.web.search.Filter({attrs: {
string: _.str.sprintf('%s(%s)%s',
section[0], section[1], section[2]),
domain: [section]
}}, self.view);
});
// Create Filter (& FilterGroup around it) with that domain
var f = new openerp.web.search.FilterGroup(filters, this.view);
var f = new instance.web.search.FilterGroup(filters, this.view);
// add group to query
this.view.vs.searchQuery.add({
category: _t("Advanced"),
@ -1349,11 +1349,11 @@ openerp.web.search.Advanced = openerp.web.search.Input.extend({
}
});
openerp.web.search.ExtendedSearchProposition = openerp.web.OldWidget.extend(/** @lends openerp.web.search.ExtendedSearchProposition# */{
instance.web.search.ExtendedSearchProposition = instance.web.OldWidget.extend(/** @lends instance.web.search.ExtendedSearchProposition# */{
template: 'SearchView.extended_search.proposition',
/**
* @constructs openerp.web.search.ExtendedSearchProposition
* @extends openerp.web.OldWidget
* @constructs instance.web.search.ExtendedSearchProposition
* @extends instance.web.OldWidget
*
* @param parent
* @param fields
@ -1401,10 +1401,9 @@ openerp.web.search.ExtendedSearchProposition = openerp.web.OldWidget.extend(/**
}
var type = field.type;
var obj = openerp.web.search.custom_filters.get_object(type);
var obj = instance.web.search.custom_filters.get_object(type);
if(obj === null) {
console.log('Unknow field type ' + e.key);
obj = openerp.web.search.custom_filters.get_object("char");
obj = instance.web.search.custom_filters.get_object("char");
}
this.value = new (obj) (this);
if(this.value.set_field) {
@ -1430,12 +1429,12 @@ openerp.web.search.ExtendedSearchProposition = openerp.web.OldWidget.extend(/**
}
});
openerp.web.search.ExtendedSearchProposition.Field = openerp.web.OldWidget.extend({
instance.web.search.ExtendedSearchProposition.Field = instance.web.OldWidget.extend({
start: function () {
this.$element = $("#" + this.element_id);
}
});
openerp.web.search.ExtendedSearchProposition.Char = openerp.web.search.ExtendedSearchProposition.Field.extend({
instance.web.search.ExtendedSearchProposition.Char = instance.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.char',
operators: [
{value: "ilike", text: _lt("contains")},
@ -1447,7 +1446,7 @@ openerp.web.search.ExtendedSearchProposition.Char = openerp.web.search.ExtendedS
return this.$element.val();
}
});
openerp.web.search.ExtendedSearchProposition.DateTime = openerp.web.search.ExtendedSearchProposition.Field.extend({
instance.web.search.ExtendedSearchProposition.DateTime = instance.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.empty',
operators: [
{value: "=", text: _lt("is equal to")},
@ -1462,11 +1461,11 @@ openerp.web.search.ExtendedSearchProposition.DateTime = openerp.web.search.Exten
},
start: function() {
this._super();
this.datewidget = new openerp.web.DateTimeWidget(this);
this.datewidget = new instance.web.DateTimeWidget(this);
this.datewidget.prependTo(this.$element);
}
});
openerp.web.search.ExtendedSearchProposition.Date = openerp.web.search.ExtendedSearchProposition.Field.extend({
instance.web.search.ExtendedSearchProposition.Date = instance.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.empty',
operators: [
{value: "=", text: _lt("is equal to")},
@ -1481,11 +1480,11 @@ openerp.web.search.ExtendedSearchProposition.Date = openerp.web.search.ExtendedS
},
start: function() {
this._super();
this.datewidget = new openerp.web.DateWidget(this);
this.datewidget = new instance.web.DateWidget(this);
this.datewidget.prependTo(this.$element);
}
});
openerp.web.search.ExtendedSearchProposition.Integer = openerp.web.search.ExtendedSearchProposition.Field.extend({
instance.web.search.ExtendedSearchProposition.Integer = instance.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.integer',
operators: [
{value: "=", text: _lt("is equal to")},
@ -1497,16 +1496,16 @@ openerp.web.search.ExtendedSearchProposition.Integer = openerp.web.search.Extend
],
get_value: function() {
try {
return openerp.web.parse_value(this.$element.val(), {'widget': 'integer'});
return instance.web.parse_value(this.$element.val(), {'widget': 'integer'});
} catch (e) {
return "";
}
}
});
openerp.web.search.ExtendedSearchProposition.Id = openerp.web.search.ExtendedSearchProposition.Integer.extend({
instance.web.search.ExtendedSearchProposition.Id = instance.web.search.ExtendedSearchProposition.Integer.extend({
operators: [{value: "=", text: _lt("is")}]
});
openerp.web.search.ExtendedSearchProposition.Float = openerp.web.search.ExtendedSearchProposition.Field.extend({
instance.web.search.ExtendedSearchProposition.Float = instance.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.float',
operators: [
{value: "=", text: _lt("is equal to")},
@ -1518,13 +1517,13 @@ openerp.web.search.ExtendedSearchProposition.Float = openerp.web.search.Extended
],
get_value: function() {
try {
return openerp.web.parse_value(this.$element.val(), {'widget': 'float'});
return instance.web.parse_value(this.$element.val(), {'widget': 'float'});
} catch (e) {
return "";
}
}
});
openerp.web.search.ExtendedSearchProposition.Selection = openerp.web.search.ExtendedSearchProposition.Field.extend({
instance.web.search.ExtendedSearchProposition.Selection = instance.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.selection',
operators: [
{value: "=", text: _lt("is")},
@ -1537,7 +1536,7 @@ openerp.web.search.ExtendedSearchProposition.Selection = openerp.web.search.Exte
return this.$element.val();
}
});
openerp.web.search.ExtendedSearchProposition.Boolean = openerp.web.search.ExtendedSearchProposition.Field.extend({
instance.web.search.ExtendedSearchProposition.Boolean = instance.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.boolean',
operators: [
{value: "=", text: _lt("is true")},
@ -1548,21 +1547,21 @@ openerp.web.search.ExtendedSearchProposition.Boolean = openerp.web.search.Extend
}
});
openerp.web.search.custom_filters = new openerp.web.Registry({
'char': 'openerp.web.search.ExtendedSearchProposition.Char',
'text': 'openerp.web.search.ExtendedSearchProposition.Char',
'one2many': 'openerp.web.search.ExtendedSearchProposition.Char',
'many2one': 'openerp.web.search.ExtendedSearchProposition.Char',
'many2many': 'openerp.web.search.ExtendedSearchProposition.Char',
instance.web.search.custom_filters = new instance.web.Registry({
'char': 'instance.web.search.ExtendedSearchProposition.Char',
'text': 'instance.web.search.ExtendedSearchProposition.Char',
'one2many': 'instance.web.search.ExtendedSearchProposition.Char',
'many2one': 'instance.web.search.ExtendedSearchProposition.Char',
'many2many': 'instance.web.search.ExtendedSearchProposition.Char',
'datetime': 'openerp.web.search.ExtendedSearchProposition.DateTime',
'date': 'openerp.web.search.ExtendedSearchProposition.Date',
'integer': 'openerp.web.search.ExtendedSearchProposition.Integer',
'float': 'openerp.web.search.ExtendedSearchProposition.Float',
'boolean': 'openerp.web.search.ExtendedSearchProposition.Boolean',
'selection': 'openerp.web.search.ExtendedSearchProposition.Selection',
'datetime': 'instance.web.search.ExtendedSearchProposition.DateTime',
'date': 'instance.web.search.ExtendedSearchProposition.Date',
'integer': 'instance.web.search.ExtendedSearchProposition.Integer',
'float': 'instance.web.search.ExtendedSearchProposition.Float',
'boolean': 'instance.web.search.ExtendedSearchProposition.Boolean',
'selection': 'instance.web.search.ExtendedSearchProposition.Selection',
'id': 'openerp.web.search.ExtendedSearchProposition.Id'
'id': 'instance.web.search.ExtendedSearchProposition.Id'
});
};

View File

@ -0,0 +1,79 @@
openerp.test_support = {
setup_connection: function (connection) {
var origin = location.protocol+"//"+location.host;
_.extend(connection, {
origin: origin,
prefix: origin,
server: origin, // keep chs happy
//openerp.web.qweb.default_dict['_s'] = this.origin;
rpc_function: connection.rpc_json,
session_id: false,
uid: false,
username: false,
user_context: {},
db: false,
openerp_entreprise: false,
// this.module_list = openerp._modules.slice();
// this.module_loaded = {};
// _(this.module_list).each(function (mod) {
// self.module_loaded[mod] = true;
// });
context: {},
shortcuts: [],
active_id: null
});
return connection.session_reload();
},
module: function (title, tested_core, nonliterals) {
var conf = QUnit.config.openerp = {};
QUnit.module(title, {
setup: function () {
QUnit.stop();
var oe = conf.openerp = window.openerp.init();
window.openerp.web[tested_core](oe);
var done = openerp.test_support.setup_connection(oe.connection);
if (nonliterals) {
done = done.pipe(function () {
return oe.connection.rpc('/tests/add_nonliterals', {
domains: nonliterals.domains || [],
contexts: nonliterals.contexts || []
}).then(function (r) {
oe.domains = r.domains;
oe.contexts = r.contexts;
});
});
}
done.always(QUnit.start)
.then(function () {
conf.openerp = oe;
}, function (e) {
QUnit.test(title, function () {
console.error(e);
QUnit.ok(false, 'Could not obtain a session:' + e.debug);
});
});
}
});
},
test: function (title, fn) {
var conf = QUnit.config.openerp;
QUnit.test(title, function () {
QUnit.stop();
fn(conf.openerp);
});
},
expect: function (promise, fn) {
promise.always(QUnit.start)
.done(function () { QUnit.ok(false, 'RPC requests should not succeed'); })
.fail(function (e) {
if (e.code !== 200) {
QUnit.equal(e.code, 200, 'Testing connector should raise RPC faults');
if (typeof console !== 'undefined' && console.error) {
console.error(e.data.debug);
}
return;
}
fn(e.data.fault_code);
})
}
};

View File

@ -1,15 +1,15 @@
openerp.web.view_editor = function(openerp) {
var _t = openerp.web._t;
var QWeb = openerp.web.qweb;
openerp.web.ViewEditor = openerp.web.OldWidget.extend({
openerp.web.view_editor = function(instance) {
var _t = instance.web._t;
var QWeb = instance.web.qweb;
instance.web.ViewEditor = instance.web.OldWidget.extend({
init: function(parent, element_id, dataset, view, options) {
this._super(parent);
this.element_id = element_id;
this.parent = parent;
this.dataset = new openerp.web.DataSetSearch(this, 'ir.ui.view', null, null),
this.dataset = new instance.web.DataSetSearch(this, 'ir.ui.view', null, null),
this.model = dataset.model;
this.xml_element_id = 0;
this.property = openerp.web.ViewEditor.property_widget;
this.property = instance.web.ViewEditor.property_widget;
this.one_object = false;
},
start: function() {
@ -39,7 +39,7 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
select_view_id: self.parent.fields_view.view_id
}
};
this.view_edit_dialog = new openerp.web.Dialog(this, {
this.view_edit_dialog = new instance.web.Dialog(this, {
title: action_title,
width: 850,
buttons: [
@ -51,7 +51,7 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
}).open();
this.view_edit_dialog.on_close.add_last(function(){window.location.reload();});
this.main_view_id = this.parent.fields_view.view_id;
this.action_manager = new openerp.web.ActionManager(this);
this.action_manager = new instance.web.ActionManager(this);
this.action_manager.appendTo(this.view_edit_dialog);
$.when(this.action_manager.do_action(action)).then(function() {
var viewmanager = self.action_manager.inner_viewmanager,
@ -67,7 +67,7 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
},
on_create_view: function() {
var self = this;
this.create_view_dialog = new openerp.web.Dialog(this, {
this.create_view_dialog = new instance.web.Dialog(this, {
title: _.str.sprintf(_t("Create a view (%s)"), self.model),
buttons: [
{text: _t("Save"), click: function () {
@ -115,8 +115,8 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
},
do_save_view: function(values) {
def = $.Deferred();
var field_dataset = new openerp.web.DataSetSearch(this, this.model, null, null);
var model_dataset = new openerp.web.DataSetSearch(this, 'ir.model', null, null);
var field_dataset = new instance.web.DataSetSearch(this, this.model, null, null);
var model_dataset = new instance.web.DataSetSearch(this, 'ir.model', null, null);
var view_string = "", field_name = false, self = this;
field_dataset.call( 'fields_get', [], function(fields) {
_.each(['name', 'x_name'], function(value) {
@ -360,7 +360,7 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
edit_view: function(one_object) {
var self = this;
this.one_object = one_object;
this.edit_xml_dialog = new openerp.web.Dialog(this, {
this.edit_xml_dialog = new instance.web.Dialog(this, {
title: _.str.sprintf(_t("View Editor %d - %s"), self.main_view_id, self.model),
height: '90%',
buttons: [
@ -392,7 +392,7 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
action_buttons: false
}
};
var action_manager = new openerp.web.ActionManager(self);
var action_manager = new instance.web.ActionManager(self);
action_manager.do_action(action);
}},
{text: _t("Close"), click: function(){
@ -517,7 +517,7 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
var self = this;
var tr = self.get_object_by_id(this.one_object.clicked_tr_id, this.one_object['main_object'], [])[0].att_list[0];
var parent_tr = ($(side).prevAll("tr[level=" + String(this.one_object.clicked_tr_level - 1) + "]"))[0];
var field_dataset = new openerp.web.DataSetSearch(this, this.model, null, null);
var field_dataset = new instance.web.DataSetSearch(this, this.model, null, null);
parent_tr = $(parent_tr).find('a').text();
field_dataset.call( 'fields_get', [], function(result) {
var fields = _.keys(result);
@ -811,7 +811,7 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
},
on_edit_node: function(properties){
var self = this;
this.edit_node_dialog = new openerp.web.Dialog(this,{
this.edit_node_dialog = new instance.web.Dialog(this,{
title: _t("Properties"),
width: 450,
buttons: [
@ -873,14 +873,15 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
'widget' : {'name':'widget', 'string': 'widget', 'type': 'selection'},
'colors' : {'name':'colors', 'string': 'Colors', 'type': 'char'},
'editable' : {'name':'editable', 'string': 'Editable', 'type': 'selection', 'selection': [["",""],["top","Top"],["bottom", "Bottom"]]},
'groups' : {'name':'groups', 'string': 'Groups', 'type': 'selection_multi'}
'groups' : {'name':'groups', 'string': 'Groups', 'type': 'selection_multi'},
'fonts' : {'name':'fonts', 'string': 'fonts', 'type': 'char'},
};
var arch_val = self.get_object_by_id(this.one_object.clicked_tr_id,this.one_object['main_object'], []);
this.edit_node_dialog.$element.append('<table id="rec_table" style="width:400px" class="oe_forms"></table>');
this.edit_widget = [];
self.ready = $.when(self.on_groups(properties)).then(function () {
_PROPERTIES_ATTRIBUTES['groups']['selection'] = self.groups;
var values = _.keys( openerp.web.form.widgets.map);
var values = _.keys( instance.web.form.widgets.map);
values.push('');
values.sort();
_PROPERTIES_ATTRIBUTES['widget']['selection'] = values;
@ -908,8 +909,8 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
def.resolve();
}
var group_ids = [], group_names = {}, groups = [];
var res_groups = new openerp.web.DataSetSearch(this,'res.groups', null, null),
model_data = new openerp.web.DataSetSearch(self,'ir.model.data', null, null);
var res_groups = new instance.web.DataSetSearch(this,'res.groups', null, null),
model_data = new instance.web.DataSetSearch(self,'ir.model.data', null, null);
res_groups.read_slice([], {}).done(function (res_grp) {
_.each(res_grp, function (res) {
var key = res.id;
@ -935,7 +936,7 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
{'name': 'field_value','selection': fields, 'value': false, 'string': '','type': 'selection'},
{'name': 'position','selection': ['After','Before','Inside'], 'value': false, 'string': 'Position','type': 'selection'}];
this.add_widget = [];
this.add_node_dialog = new openerp.web.Dialog(this,{
this.add_node_dialog = new instance.web.Dialog(this,{
title: _t("Properties"),
width: 450,
buttons: [
@ -980,7 +981,7 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
});
table_selector.find("td[id^=]").attr("width","100px");
self.add_node_dialog.$element.find('#new_field').click(function() {
model_data = new openerp.web.DataSetSearch(self,'ir.model', null, null);
model_data = new instance.web.DataSetSearch(self,'ir.model', null, null);
model_data.read_slice([], {domain: [['model','=', self.model]]}).then(function(result) {
self.render_new_field(result[0].id);
});
@ -998,7 +999,7 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
action_buttons: true
}
};
var action_manager = new openerp.web.ActionManager(self);
var action_manager = new instance.web.ActionManager(self);
$.when(action_manager.do_action(action)).then(function() {
var controller = action_manager.dialog_viewmanager.views['form'].controller;
controller.on_button_cancel.add_last(function(){
@ -1015,7 +1016,7 @@ openerp.web.ViewEditor = openerp.web.OldWidget.extend({
});
}
});
openerp.web.ViewEditor.Field = openerp.web.Class.extend({
instance.web.ViewEditor.Field = instance.web.Class.extend({
init: function(view, widget) {
this.$element = view.$element;
this.dirty = false;
@ -1041,7 +1042,7 @@ openerp.web.ViewEditor.Field = openerp.web.Class.extend({
validate: function() {
this.is_invalid = false;
try {
var value = openerp.web.parse_value(this.get_value(), this, '');
var value = instance.web.parse_value(this.get_value(), this, '');
this.is_invalid = this.required && value === '';
} catch(e) {
this.is_invalid = true;
@ -1051,7 +1052,7 @@ openerp.web.ViewEditor.Field = openerp.web.Class.extend({
return _.str.sprintf("<td id = %s>%s</td>", this.name, QWeb.render(this.template, {widget: this}))
}
});
openerp.web.ViewEditor.FieldBoolean = openerp.web.ViewEditor.Field.extend({
instance.web.ViewEditor.FieldBoolean = instance.web.ViewEditor.Field.extend({
template : "vieweditor_boolean",
start: function() {
var self = this;
@ -1069,7 +1070,7 @@ openerp.web.ViewEditor.FieldBoolean = openerp.web.ViewEditor.Field.extend({
return this.$element.find("input[id=" + this.name + "]").is(':checked')? "1" : null;
}
});
openerp.web.ViewEditor.FieldChar = openerp.web.ViewEditor.Field.extend({
instance.web.ViewEditor.FieldChar = instance.web.ViewEditor.Field.extend({
template : "vieweditor_char",
start: function () {
var self = this;
@ -1085,7 +1086,7 @@ openerp.web.ViewEditor.FieldChar = openerp.web.ViewEditor.Field.extend({
return this.$element.find("input[id=" + this.name + "]").val();
}
});
openerp.web.ViewEditor.FieldSelect = openerp.web.ViewEditor.Field.extend({
instance.web.ViewEditor.FieldSelect = instance.web.ViewEditor.Field.extend({
template : "vieweditor_selection",
start: function () {
var self = this;
@ -1115,7 +1116,7 @@ openerp.web.ViewEditor.FieldSelect = openerp.web.ViewEditor.Field.extend({
return this.$element.find("select[id=" + this.name + "]").val();
}
});
openerp.web.ViewEditor.FieldSelectMulti = openerp.web.ViewEditor.FieldSelect.extend({
instance.web.ViewEditor.FieldSelectMulti = instance.web.ViewEditor.FieldSelect.extend({
start: function () {
this._super();
this.$element.find("select[id=" + this.name + "]").css('height', '100px').attr("multiple", true);
@ -1131,7 +1132,7 @@ openerp.web.ViewEditor.FieldSelectMulti = openerp.web.ViewEditor.FieldSelect.ext
});
}
});
openerp.web.ViewEditor.FieldFloat = openerp.web.ViewEditor.FieldChar.extend({
instance.web.ViewEditor.FieldFloat = instance.web.ViewEditor.FieldChar.extend({
});
var _PROPERTIES = {
@ -1149,7 +1150,7 @@ var _PROPERTIES = {
'board': ['style'],
'column' : [],
'action' : ['name', 'string', 'colspan', 'groups'],
'tree' : ['string', 'colors', 'editable', 'link', 'limit', 'min_rows'],
'tree' : ['string', 'colors', 'editable', 'link', 'limit', 'min_rows', 'fonts'],
'graph' : ['string', 'type'],
'calendar' : ['string', 'date_start', 'date_stop', 'date_delay', 'day_length', 'color', 'mode']
};
@ -1196,11 +1197,11 @@ var _ICONS = ['','STOCK_ABOUT', 'STOCK_ADD', 'STOCK_APPLY', 'STOCK_BOLD',
'terp-sale', 'terp-tools', 'terp-administration', 'terp-hr', 'terp-partner',
'terp-project', 'terp-report', 'terp-stock', 'terp-calendar', 'terp-graph'
];
openerp.web.ViewEditor.property_widget = new openerp.web.Registry({
'boolean' : 'openerp.web.ViewEditor.FieldBoolean',
'selection_multi' : 'openerp.web.ViewEditor.FieldSelectMulti',
'selection' : 'openerp.web.ViewEditor.FieldSelect',
'char' : 'openerp.web.ViewEditor.FieldChar',
'float' : 'openerp.web.ViewEditor.FieldFloat'
instance.web.ViewEditor.property_widget = new instance.web.Registry({
'boolean' : 'instance.web.ViewEditor.FieldBoolean',
'selection_multi' : 'instance.web.ViewEditor.FieldSelectMulti',
'selection' : 'instance.web.ViewEditor.FieldSelect',
'char' : 'instance.web.ViewEditor.FieldChar',
'float' : 'instance.web.ViewEditor.FieldFloat'
});
};

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
openerp.web.list = function (openerp) {
var _t = openerp.web._t,
_lt = openerp.web._lt;
var QWeb = openerp.web.qweb;
openerp.web.views.add('list', 'openerp.web.ListView');
openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView# */ {
openerp.web.list = function (instance) {
var _t = instance.web._t,
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
instance.web.views.add('list', 'instance.web.ListView');
instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListView# */ {
_template: 'ListView',
display_name: _lt('List'),
defaults: {
@ -33,11 +33,11 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
* See constructor parameters and method documentations for information on
* the default behaviors and possible options for the list view.
*
* @constructs openerp.web.ListView
* @extends openerp.web.View
* @constructs instance.web.ListView
* @extends instance.web.View
*
* @param parent parent object
* @param {openerp.web.DataSet} dataset the dataset the view should work with
* @param {instance.web.DataSet} dataset the dataset the view should work with
* @param {String} view_id the listview's identifier, if any
* @param {Object} options A set of options used to configure the view
* @param {Boolean} [options.selectable=true] determines whether view rows are selectable (e.g. via a checkbox)
@ -56,17 +56,18 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
this.view_id = view_id;
this.previous_colspan = null;
this.colors = null;
this.fonts = null;
this.columns = [];
this.records = new Collection();
this.set_groups(new openerp.web.ListView.Groups(this));
this.set_groups(new instance.web.ListView.Groups(this));
if (this.dataset instanceof openerp.web.DataSetStatic) {
this.groups.datagroup = new openerp.web.StaticDataGroup(this.dataset);
if (this.dataset instanceof instance.web.DataSetStatic) {
this.groups.datagroup = new instance.web.StaticDataGroup(this.dataset);
} else {
this.groups.datagroup = new openerp.web.DataGroup(
this.groups.datagroup = new instance.web.DataGroup(
this, this.model,
dataset.get_domain(),
dataset.get_context(),
@ -104,7 +105,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
/**
* Set a custom Group construct as the root of the List View.
*
* @param {openerp.web.ListView.Groups} groups
* @param {instance.web.ListView.Groups} groups
*/
set_groups: function (groups) {
var self = this;
@ -140,29 +141,53 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
return this.reload_view(null, null, true);
},
/**
* Returns the color for the provided record in the current view (from the
* ``@colors`` attribute)
* Returns the style for the provided record in the current view (from the
* ``@colors`` and ``@fonts`` attributes)
*
* @param {Record} record record for the current row
* @returns {String} CSS color declaration
* @returns {String} CSS style declaration
*/
color_for: function (record) {
if (!this.colors) { return ''; }
style_for: function (record) {
var style= '';
var context = _.extend({}, record.attributes, {
uid: this.session.uid,
current_date: new Date().toString('yyyy-MM-dd')
// TODO: time, datetime, relativedelta
});
if (this.fonts) {
for(var i=0, len=this.fonts.length; i<len; ++i) {
var pair = this.fonts[i],
font = pair[0],
expression = pair[1];
if (py.evaluate(expression, context).toJSON()) {
switch(font) {
case 'bold':
style += 'font-weight: bold;';
break;
case 'italic':
style += 'font-style: italic;';
break;
case 'underline':
style += 'text-decoration: underline;';
break;
}
}
}
}
if (!this.colors) { return style; }
for(var i=0, len=this.colors.length; i<len; ++i) {
var pair = this.colors[i],
color = pair[0],
expression = pair[1];
if (py.evaluate(expression, context).toJSON()) {
return 'color: ' + color + ';';
return style += 'color: ' + color + ';';
}
// TODO: handle evaluation errors
}
return '';
return style;
},
/**
* Called after loading the list view's description, sets up such things
@ -203,6 +228,16 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
}).value();
}
if (this.fields_view.arch.attrs.fonts) {
this.fonts = _(this.fields_view.arch.attrs.fonts.split(';')).chain().compact()
.map(function(font_pair) {
var pair = font_pair.split(':'),
font = pair[0],
expr = pair[1];
return [font, py.parse(py.tokenize(expr)), expr];
}).value();
}
this.setup_columns(this.fields_view.fields, grouped);
this.$element.html(QWeb.render(this._template, this));
@ -301,8 +336,8 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
}
// Sidebar
if (!this.sidebar && this.options.sidebar && this.options.$sidebar) {
this.sidebar = new openerp.web.Sidebar(this);
if (!this.sidebar && this.options.$sidebar) {
this.sidebar = new instance.web.Sidebar(this);
this.sidebar.appendTo(this.options.$sidebar);
this.sidebar.add_toolbar(this.fields_view.toolbar);
}
@ -312,7 +347,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
*
* Horrifying side-effect: sets the dataset's data on this.dataset?
*
* @param {openerp.web.DataSet} dataset
* @param {instance.web.DataSet} dataset
*/
configure_pager: function (dataset) {
this.dataset.ids = dataset.ids;
@ -336,7 +371,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
* @param {Boolean} [grouped] Should the grouping columns (group and count) be displayed
*/
setup_columns: function (fields, grouped) {
var domain_computer = openerp.web.form.compute_domain;
var domain_computer = instance.web.form.compute_domain;
var noop = function () { return {}; };
var field_to_column = function (field) {
@ -405,7 +440,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
*
* The default implementation asks the list view's view manager to switch
* to a different view (by calling
* :js:func:`~openerp.web.ViewManager.on_mode_switch`), using the
* :js:func:`~instance.web.ViewManager.on_mode_switch`), using the
* provided record index (within the current list view's dataset).
*
* If the index is null, ``switch_to_record`` asks for the creation of a
@ -464,7 +499,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
view_id: this.view_id,
view_type: "tree",
context: this.dataset.get_context(context),
toolbar: this.options.sidebar
toolbar: !!this.options.$sidebar
}, callback);
}
},
@ -526,7 +561,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
*/
do_search: function (domain, context, group_by) {
this.page = 0;
this.groups.datagroup = new openerp.web.DataGroup(
this.groups.datagroup = new instance.web.DataGroup(
this, this.model, domain, context, group_by);
this.groups.datagroup.sort = this.dataset._sort;
@ -598,7 +633,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
return;
}
var c = new openerp.web.CompoundContext();
var c = new instance.web.CompoundContext();
c.set_eval_context(_.extend({
active_id: id,
active_ids: [id],
@ -615,7 +650,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
*
* @param {Number} index index of the record in the dataset
* @param {Object} id identifier of the activated record
* @param {openerp.web.DataSet} dataset dataset in which the record is available (may not be the listview's dataset in case of nested groups)
* @param {instance.web.DataSet} dataset dataset in which the record is available (may not be the listview's dataset in case of nested groups)
*/
do_activate_record: function (index, id, dataset, view) {
this.dataset.ids = dataset.ids;
@ -639,11 +674,11 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
/**
* Computes the aggregates for the current list view, either on the
* records provided or on the records of the internal
* :js:class:`~openerp.web.ListView.Group`, by calling
* :js:func:`~openerp.web.ListView.group.get_records`.
* :js:class:`~instance.web.ListView.Group`, by calling
* :js:func:`~instance.web.ListView.group.get_records`.
*
* Then displays the aggregates in the table through
* :js:method:`~openerp.web.ListView.display_aggregates`.
* :js:method:`~instance.web.ListView.display_aggregates`.
*
* @param {Array} [records]
*/
@ -719,7 +754,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
}
$footer_cells.filter(_.str.sprintf('[data-field=%s]', column.id))
.html(openerp.web.format_cell(aggregation, column, {
.html(instance.web.format_cell(aggregation, column, {
process_modifiers: false
}));
});
@ -770,9 +805,20 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
.attr('colspan', this.previous_colspan);
this.previous_colspan = null;
}
},
no_result: function () {
if (this.groups.group_by
|| !this.options.action
|| !this.options.action.help) {
return;
}
this.$element.children('table').replaceWith(
$('<div class="oe_listview_nocontent">')
.append($('<img>', { src: '/web/static/src/img/list_empty_arrow.png' }))
.append($('<div>').html(this.options.action.help)));
}
});
openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.ListView.List# */{
instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web.ListView.List# */{
/**
* List display for the ListView, handles basic DOM events and transforms
* them in the relevant higher-level events, to which the list view (or
@ -797,10 +843,10 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
* Triggered when a row of the table is clicked, provides the index (in
* the rows array) and id of the selected record to the handle function.
*
* @constructs openerp.web.ListView.List
* @extends openerp.web.Class
* @constructs instance.web.ListView.List
* @extends instance.web.Class
*
* @param {Object} opts display options, identical to those of :js:class:`openerp.web.ListView`
* @param {Object} opts display options, identical to those of :js:class:`instance.web.ListView`
*/
init: function (group, opts) {
var self = this;
@ -915,7 +961,7 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
// to get a correctly displayable value in the field
var model = ref_match[1],
id = parseInt(ref_match[2], 10);
new openerp.web.DataSet(this.view, model).name_get([id], function(names) {
new instance.web.DataSet(this.view, model).name_get([id], function(names) {
if (!names.length) { return; }
record.set(column.id, names[0][1]);
});
@ -930,14 +976,14 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
// fetch the name, set it on the record (in the right field)
// and let the various registered events handle refreshing the
// row
new openerp.web.DataSet(this.view, column.relation)
new instance.web.DataSet(this.view, column.relation)
.name_get([value], function (names) {
if (!names.length) { return; }
record.set(column.id, names[0]);
});
}
}
return openerp.web.format_cell(record.toForm().data, column, {
return instance.web.format_cell(record.toForm().data, column, {
model: this.dataset.model,
id: record.get('id')
});
@ -1091,19 +1137,19 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
});
}
});
openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.ListView.Groups# */{
instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.web.ListView.Groups# */{
passtrough_events: 'action deleted row_link',
/**
* Grouped display for the ListView. Handles basic DOM events and interacts
* with the :js:class:`~openerp.web.DataGroup` bound to it.
* with the :js:class:`~instance.web.DataGroup` bound to it.
*
* Provides events similar to those of
* :js:class:`~openerp.web.ListView.List`
* :js:class:`~instance.web.ListView.List`
*
* @constructs openerp.web.ListView.Groups
* @extends openerp.web.Class
* @constructs instance.web.ListView.Groups
* @extends instance.web.Class
*
* @param {openerp.web.ListView} view
* @param {instance.web.ListView} view
* @param {Object} [options]
* @param {Collection} [options.records]
* @param {Object} [options.options]
@ -1214,7 +1260,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
self.records.proxy(group.value).reset();
delete self.children[group.value];
}
var child = self.children[group.value] = new openerp.web.ListView.Groups(self.view, {
var child = self.children[group.value] = new instance.web.ListView.Groups(self.view, {
records: self.records.proxy(group.value),
options: self.options,
columns: self.columns
@ -1250,7 +1296,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
var group_column = _(self.columns).detect(function (column) {
return column.id === group.grouped_on; });
try {
$group_column.html(openerp.web.format_cell(
$group_column.html(instance.web.format_cell(
row_data, group_column, {
value_if_empty: _t("Undefined"),
process_modifiers: false
@ -1287,7 +1333,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
var r = {};
r[column.id] = {value: group.aggregates[column.id]};
$('<td class="oe-number">')
.html(openerp.web.format_cell(
.html(instance.web.format_cell(
r, column, {process_modifiers: false}))
.appendTo($row);
} else {
@ -1320,7 +1366,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
},
render_dataset: function (dataset) {
var self = this,
list = new openerp.web.ListView.List(this, {
list = new instance.web.ListView.List(this, {
options: this.options,
columns: this.columns,
dataset: dataset,
@ -1367,6 +1413,9 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
self.records.add(records, {silent: true});
list.render();
d.resolve(list);
if (_.isEmpty(records)) {
view.no_result();
}
});});
return d.promise();
},
@ -1533,10 +1582,10 @@ var Events = /** @lends Events# */{
return this;
}
};
var Record = openerp.web.Class.extend(/** @lends Record# */{
var Record = instance.web.Class.extend(/** @lends Record# */{
/**
* @constructs Record
* @extends openerp.web.Class
* @extends instance.web.Class
*
* @mixes Events
* @param {Object} [data]
@ -1614,7 +1663,7 @@ var Record = openerp.web.Class.extend(/** @lends Record# */{
}
});
Record.include(Events);
var Collection = openerp.web.Class.extend(/** @lends Collection# */{
var Collection = instance.web.Class.extend(/** @lends Collection# */{
/**
* Smarter collections, with events, very strongly inspired by Backbone's.
*
@ -1622,7 +1671,7 @@ var Collection = openerp.web.Class.extend(/** @lends Collection# */{
* various serious
*
* @constructs Collection
* @extends openerp.web.Class
* @extends instance.web.Class
*
* @mixes Events
* @param {Array} [records] records to initialize the collection with
@ -1654,19 +1703,19 @@ var Collection = openerp.web.Class.extend(/** @lends Collection# */{
var records = record instanceof Array ? record : [record];
for(var i=0, length=records.length; i<length; ++i) {
var instance = (records[i] instanceof Record) ? records[i] : new Record(records[i]);
instance.bind(null, this._onRecordEvent);
this._byId[instance.get('id')] = instance;
var instance_ = (records[i] instanceof Record) ? records[i] : new Record(records[i]);
instance_.bind(null, this._onRecordEvent);
this._byId[instance_.get('id')] = instance_;
if (options.at == undefined) {
this.records.push(instance);
this.records.push(instance_);
if (!options.silent) {
this.trigger('add', this, instance, this.records.length-1);
this.trigger('add', this, instance_, this.records.length-1);
}
} else {
var insertion_index = options.at + i;
this.records.splice(insertion_index, 0, instance);
this.records.splice(insertion_index, 0, instance_);
if (!options.silent) {
this.trigger('add', this, instance, insertion_index);
this.trigger('add', this, instance_, insertion_index);
}
}
this.length++;
@ -1797,7 +1846,7 @@ var Collection = openerp.web.Class.extend(/** @lends Collection# */{
}
});
Collection.include(Events);
openerp.web.list = {
instance.web.list = {
Events: Events,
Record: Record,
Collection: Collection

View File

@ -2,16 +2,16 @@
* handles editability case for lists, because it depends on form and forms already depends on lists it had to be split out
* @namespace
*/
openerp.web.list_editable = function (openerp) {
openerp.web.list_editable = function (instance) {
var KEY_RETURN = 13,
KEY_ESCAPE = 27;
var QWeb = openerp.web.qweb;
var QWeb = instance.web.qweb;
// editability status of list rows
openerp.web.ListView.prototype.defaults.editable = null;
instance.web.ListView.prototype.defaults.editable = null;
// TODO: not sure second @lends on existing item is correct, to check
openerp.web.ListView.include(/** @lends openerp.web.ListView# */{
instance.web.ListView.include(/** @lends instance.web.ListView# */{
init: function () {
var self = this;
this._super.apply(this, arguments);
@ -37,7 +37,7 @@ openerp.web.list_editable = function (openerp) {
*
* @param {Number} index index of the record in the dataset
* @param {Object} id identifier of the record being edited
* @param {openerp.web.DataSet} dataset dataset in which the record is available
* @param {instance.web.DataSet} dataset dataset in which the record is available
*/
do_edit: function (index, id, dataset) {
_.extend(this.dataset, dataset);
@ -93,8 +93,8 @@ openerp.web.list_editable = function (openerp) {
}
});
openerp.web.ListView.Groups.include(/** @lends openerp.web.ListView.Groups# */{
passtrough_events: openerp.web.ListView.Groups.prototype.passtrough_events + " edit saved",
instance.web.ListView.Groups.include(/** @lends instance.web.ListView.Groups# */{
passtrough_events: instance.web.ListView.Groups.prototype.passtrough_events + " edit saved",
new_record: function () {
// TODO: handle multiple children
this.children[null].new_record();
@ -113,7 +113,7 @@ openerp.web.list_editable = function (openerp) {
}
});
openerp.web.ListView.List.include(/** @lends openerp.web.ListView.List# */{
instance.web.ListView.List.include(/** @lends instance.web.ListView.List# */{
row_clicked: function (event) {
if (!this.options.editable) {
return this._super.apply(this, arguments);
@ -236,7 +236,7 @@ openerp.web.list_editable = function (openerp) {
self.edition = true;
self.edition_id = record_id;
$new_row.addClass("oe_form_container");
self.edition_form = new openerp.web.ListEditableFormView(self.view, self.dataset, false);
self.edition_form = new instance.web.ListEditableFormView(self.view, self.dataset, false);
self.edition_form.$element = $new_row;
self.edition_form.editable_list = self;
// HO HO
@ -274,7 +274,7 @@ openerp.web.list_editable = function (openerp) {
// insert after the source record
var index = self.records.indexOf(
self.records.get(source_record_id)) + 1;
record = new openerp.web.list.Record({id: id});
record = new instance.web.list.Record({id: id});
self.records.add(record, {at: index});
self.dataset.ids.splice(index, 0, id);
}
@ -368,15 +368,16 @@ openerp.web.list_editable = function (openerp) {
}
});
openerp.web.ListEditableFormView = openerp.web.FormView.extend({
instance.web.ListEditableFormView = instance.web.FormView.extend({
init: function() {
this._super.apply(this, arguments);
this.rendering_engine = new openerp.web.ListEditableRenderingEngine(this);
this.rendering_engine = new instance.web.ListEditableRenderingEngine(this);
this.options.initial_mode = "edit";
},
renderElement: function() {}
});
openerp.web.ListEditableRenderingEngine = openerp.web.Class.extend({
instance.web.ListEditableRenderingEngine = instance.web.Class.extend({
init: function(view) {
this.view = view;
},
@ -392,7 +393,7 @@ openerp.web.list_editable = function (openerp) {
render_to: function($element) {
var self = this;
var xml = openerp.web.json_node_to_xml(this.fvg.arch);
var xml = instance.web.json_node_to_xml(this.fvg.arch);
var $xml = $(xml);
if (this.view.editable_list.options.selectable)
@ -406,17 +407,21 @@ openerp.web.list_editable = function (openerp) {
if (modifiers.tree_invisible === true)
$td.hide();
var tag_name = el.tagName.toLowerCase();
var key = tag_name;
var w;
if (tag_name === "field") {
var name = $(el).attr("name");
key = $(el).attr('widget') || self.fvg.fields[name].type;
var key = $(el).attr('widget') || self.fvg.fields[name].type;
var obj = self.view.fields_registry.get_object(key);
w = new (obj)(self.view, instance.web.xml_to_json(el));
self.view.register_field(w, $(el).attr("name"));
} else {
var obj = self.tags_registry.get_object(tag_name);
w = new (obj)(self.view, instance.web.xml_to_json(el));
}
var obj = self.view.fields_registry.get_object(key);
var w = new (obj)(self.view, openerp.web.xml_to_json(el));
w.appendTo($td);
$td.appendTo($element);
});
$("<td><button class='oe-edit-row-save' type='button'></button></td>").appendTo($element);
$("<td><button class='oe-edit-row-save' type='button'>Save</button></td>").appendTo($element);
},
});
};

View File

@ -2,12 +2,12 @@
* OpenERP web library
*---------------------------------------------------------*/
openerp.web.view_tree = function(openerp) {
var QWeb = openerp.web.qweb,
_lt = openerp.web._lt;
openerp.web.view_tree = function(instance) {
var QWeb = instance.web.qweb,
_lt = instance.web._lt;
openerp.web.views.add('tree', 'openerp.web.TreeView');
openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView# */{
instance.web.views.add('tree', 'instance.web.TreeView');
instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeView# */{
display_name: _lt('Tree'),
/**
* Indicates that this view is not searchable, and thus that no search
@ -17,8 +17,8 @@ openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView#
/**
* Genuine tree view (the one displayed as a tree, not the list)
*
* @constructs openerp.web.TreeView
* @extends openerp.web.View
* @constructs instance.web.TreeView
* @extends instance.web.View
*
* @param parent
* @param dataset
@ -203,7 +203,7 @@ openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView#
'fields_view': self.fields_view.arch.children,
'fields': self.fields,
'level': $curr_node.data('level') || 0,
'render': openerp.web.format_value,
'render': instance.web.format_value,
'color_for': self.color_for
});
@ -226,12 +226,12 @@ openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView#
return this.rpc('/web/treeview/action', {
id: id,
model: this.dataset.model,
context: new openerp.web.CompoundContext(
context: new instance.web.CompoundContext(
this.dataset.get_context(), local_context)
}).pipe(function (actions) {
if (!actions.length) { return; }
var action = actions[0][2];
var c = new openerp.web.CompoundContext(local_context);
var c = new instance.web.CompoundContext(local_context);
if (action.context) {
c.add(action.context);
}

View File

@ -2,11 +2,11 @@
* OpenERP web library
*---------------------------------------------------------*/
openerp.web.views = function(session) {
var QWeb = session.web.qweb,
_t = session.web._t;
openerp.web.views = function(instance) {
var QWeb = instance.web.qweb,
_t = instance.web._t;
session.web.ActionManager = session.web.Widget.extend({
instance.web.ActionManager = instance.web.Widget.extend({
init: function(parent) {
this._super(parent);
this.inner_action = null;
@ -52,8 +52,8 @@ session.web.ActionManager = session.web.Widget.extend({
if (run_action) {
this.null_action();
action_loaded = this.do_action(state.action_id);
session.webclient.menu.has_been_loaded.then(function() {
session.webclient.menu.open_action(state.action_id);
instance.webclient.menu.has_been_loaded.then(function() {
instance.webclient.menu.open_action(state.action_id);
});
}
} else if (state.model && state.id) {
@ -124,31 +124,31 @@ session.web.ActionManager = session.web.Widget.extend({
.contains(action.res_model)) {
var old_close = on_close;
on_close = function () {
session.webclient.do_reload().then(old_close);
instance.webclient.do_reload().then(old_close);
};
}
if (action.target === 'new') {
if (this.dialog == null) {
this.dialog = new session.web.Dialog(this, { width: '80%' });
this.dialog = new instance.web.Dialog(this, { width: '80%' });
if(on_close)
this.dialog.on_close.add(on_close);
} else {
this.dialog_viewmanager.destroy();
}
this.dialog.dialog_title = action.name;
this.dialog_viewmanager = new session.web.ViewManagerAction(this, action);
this.dialog_viewmanager = new instance.web.ViewManagerAction(this, action);
this.dialog_viewmanager.appendTo(this.dialog.$element);
this.dialog.open();
} else {
if(action.menu_id) {
return this.getParent().do_action(action, function () {
session.webclient.menu.open_menu(action.menu_id);
instance.webclient.menu.open_menu(action.menu_id);
});
}
this.dialog_stop();
this.content_stop();
this.inner_action = action;
this.inner_viewmanager = new session.web.ViewManagerAction(this, action);
this.inner_viewmanager = new instance.web.ViewManagerAction(this, action);
this.inner_viewmanager.appendTo(this.$element);
}
},
@ -170,7 +170,7 @@ session.web.ActionManager = session.web.Widget.extend({
ir_actions_client: function (action) {
this.content_stop();
this.dialog_stop();
var ClientWidget = session.web.client_actions.get_object(action.tag);
var ClientWidget = instance.web.client_actions.get_object(action.tag);
(this.client_widget = new ClientWidget(this, action.params)).appendTo(this.$element);
},
ir_actions_report_xml: function(action, on_closed) {
@ -192,7 +192,7 @@ session.web.ActionManager = session.web.Widget.extend({
}
self.dialog_stop();
},
error: session.webclient.crashmanager.on_rpc_error
error: instance.webclient.crashmanager.on_rpc_error
})
});
},
@ -204,7 +204,7 @@ session.web.ActionManager = session.web.Widget.extend({
}
});
session.web.ViewManager = session.web.Widget.extend({
instance.web.ViewManager = instance.web.Widget.extend({
template: "ViewManager",
init: function(parent, dataset, views, flags) {
this._super(parent);
@ -214,7 +214,7 @@ session.web.ViewManager = session.web.Widget.extend({
this.active_view = null;
this.views_src = _.map(views, function(x) {
if (x instanceof Array) {
var View = session.web.views.get_object(x[1], true);
var View = instance.web.views.get_object(x[1], true);
return {
view_id: x[0],
view_type: x[1],
@ -226,7 +226,7 @@ session.web.ViewManager = session.web.Widget.extend({
});
this.views = {};
this.flags = flags || {};
this.registry = session.web.views;
this.registry = instance.web.views;
this.views_history = [];
},
/**
@ -245,7 +245,7 @@ session.web.ViewManager = session.web.Widget.extend({
controller : null,
options : _.extend({
$buttons : self.$element.find('.oe_view_manager_buttons'),
$sidebar : self.$element.find('.oe_view_manager_sidebar'),
$sidebar : self.flags.sidebar ? self.$element.find('.oe_view_manager_sidebar') : undefined,
$pager : self.$element.find('.oe_view_manager_pager'),
action : self.action,
action_views_ids : views_ids
@ -283,7 +283,7 @@ session.web.ViewManager = session.web.Widget.extend({
// Lazy loading of views
var controllerclass = this.registry.get_object(view_type);
var options = _.clone(view.options);
if (view_type === "form") {
if (view_type === "form" && this.action) {
switch (this.action.target) {
case 'new':
case 'inline':
@ -353,6 +353,7 @@ session.web.ViewManager = session.web.Widget.extend({
* @returns {$.Deferred} switching end signal
*/
on_prev_view: function (options) {
options = options || {};
var current_view = this.views_history.pop();
var previous_view = this.views_history[this.views_history.length - 1] || options['default'];
if (options.created && current_view === 'form' && previous_view === 'list') {
@ -376,7 +377,7 @@ session.web.ViewManager = session.web.Widget.extend({
if (this.searchview) {
this.searchview.destroy();
}
this.searchview = new session.web.SearchView(this, this.dataset, view_id, search_defaults, this.flags.search_view === false);
this.searchview = new instance.web.SearchView(this, this.dataset, view_id, search_defaults, this.flags.search_view === false);
this.searchview.on_search.add(this.do_searchview_search);
return this.searchview.appendTo(this.$element.find(".oe_view_manager_view_search"));
@ -390,8 +391,8 @@ session.web.ViewManager = session.web.Widget.extend({
contexts: [action_context].concat(contexts || []),
group_by_seq: groupbys || []
}, function (results) {
self.dataset.context = results.context;
self.dataset.domain = results.domain;
self.dataset._model = new instance.web.Model(
self.dataset.model, results.context, results.domain);
var groupby = results.group_by.length
? results.group_by
: action_context.group_by;
@ -435,13 +436,13 @@ session.web.ViewManager = session.web.Widget.extend({
}
});
session.web.ViewManagerAction = session.web.ViewManager.extend({
instance.web.ViewManagerAction = instance.web.ViewManager.extend({
template:"ViewManagerAction",
/**
* @constructs session.web.ViewManagerAction
* @extends session.web.ViewManager
* @constructs instance.web.ViewManagerAction
* @extends instance.web.ViewManager
*
* @param {session.web.ActionManager} parent parent object/widget
* @param {instance.web.ActionManager} parent parent object/widget
* @param {Object} action descriptor for the action this viewmanager needs to manage its views.
*/
init: function(parent, action) {
@ -466,7 +467,7 @@ session.web.ViewManagerAction = session.web.ViewManager.extend({
this._super(parent, null, action.views, flags);
this.session = parent.session;
this.action = action;
var dataset = new session.web.DataSetSearch(this, action.res_model, action.context, action.domain);
var dataset = new instance.web.DataSetSearch(this, action.res_model, action.context, action.domain);
if (action.res_id) {
dataset.ids.push(action.res_id);
dataset.index = 0;
@ -507,7 +508,7 @@ session.web.ViewManagerAction = session.web.ViewManager.extend({
this.$element.find('.oe_debug_view').change(this.on_debug_changed);
if (this.action.help && !this.flags.low_profile) {
var Users = new session.web.DataSet(self, 'res.users'),
var Users = new instance.web.DataSet(self, 'res.users'),
$tips = this.$element.find('.oe_view_manager_menu_tips');
$tips.delegate('blockquote button', 'click', function() {
var $this = $(this);
@ -541,19 +542,19 @@ session.web.ViewManagerAction = session.web.ViewManager.extend({
current_view = this.views[this.active_view].controller;
switch (val) {
case 'fvg':
var dialog = new session.web.Dialog(this, { title: _t("Fields View Get"), width: '95%' }).open();
$('<pre>').text(session.web.json_node_to_xml(current_view.fields_view.arch, true)).appendTo(dialog.$element);
var dialog = new instance.web.Dialog(this, { title: _t("Fields View Get"), width: '95%' }).open();
$('<pre>').text(instance.web.json_node_to_xml(current_view.fields_view.arch, true)).appendTo(dialog.$element);
break;
case 'perm_read':
var ids = current_view.get_selected_ids();
if (ids.length === 1) {
this.dataset.call('perm_read', [ids]).then(function(result) {
var dialog = new session.web.Dialog(this, {
var dialog = new instance.web.Dialog(this, {
title: _.str.sprintf(_t("View Log (%s)"), self.dataset.model),
width: 400
}, QWeb.render('ViewManagerDebugViewLog', {
perm : result[0],
format : session.web.format_value
format : instance.web.format_value
})).open();
});
}
@ -578,7 +579,7 @@ session.web.ViewManagerAction = session.web.ViewManager.extend({
.append($('<dd style="white-space: pre-wrap;">').text(def));
});
});
new session.web.Dialog(self, {
new instance.web.Dialog(self, {
title: _.str.sprintf(_t("Model %s fields"),
self.dataset.model),
width: '95%'}, $root).open();
@ -586,7 +587,7 @@ session.web.ViewManagerAction = session.web.ViewManager.extend({
break;
case 'manage_views':
if (current_view.fields_view && current_view.fields_view.arch) {
var view_editor = new session.web.ViewEditor(current_view, current_view.$element, this.dataset, current_view.fields_view.arch);
var view_editor = new instance.web.ViewEditor(current_view, current_view.$element, this.dataset, current_view.fields_view.arch);
view_editor.start();
} else {
this.do_warn(_t("Manage Views"),
@ -723,12 +724,10 @@ session.web.ViewManagerAction = session.web.ViewManager.extend({
}
});
session.web.Sidebar = session.web.Widget.extend({
instance.web.Sidebar = instance.web.Widget.extend({
init: function(parent) {
this._super(parent);
var view = this.getParent();
var view_manager = view.getParent();
var action = view_manager.action;
this.sections = [
{ 'name' : 'print', 'label' : _t('Print'), },
{ 'name' : 'files', 'label' : _t('Attachement'), },
@ -759,25 +758,25 @@ session.web.Sidebar = session.web.Widget.extend({
var section = $(this).data('section');
var index = $(this).data('index');
$(this).closest('ul').hide();
console.log('click item',section,index);
var item = self.items[section][index];
if (item.callback) {
item.callback.apply(self, [item]);
}
if (item.action) {
} else if (item.action) {
self.on_item_action_clicked(item);
} else if (item.url) {
return true;
}
return false;
});
//this.$div.html(QWeb.render('FormView.sidebar.attachments', this));
//this.$element.find('.oe-binary-file').change(this.on_attachment_changed);
//this.$element.find('.oe-sidebar-attachment-delete').click(this.on_attachment_delete);
},
redraw: function() {
var self = this;
self.$element.html(QWeb.render('Sidebar', {widget: self}));
this.$element.find('ul').hide();
},
add_default_sections: function() {
var self = this;
},
add_section: function() {
var self = this;
},
@ -834,7 +833,7 @@ session.web.Sidebar = session.web.Widget.extend({
self.getParent().sidebar_context().then(function (context) {
var ids = self.getParent().get_selected_ids();
if (ids.length == 0) {
session.web.dialog($("<div />").text(_t("You must choose at least one record.")), { title: _t("Warning"), modal: true });
instance.web.dialog($("<div />").text(_t("You must choose at least one record.")), { title: _t("Warning"), modal: true });
return false;
}
var additional_context = _.extend({
@ -857,9 +856,60 @@ session.web.Sidebar = session.web.Widget.extend({
});
});
},
do_attachement_update: function(dataset, model_id) {
if (!model_id) {
this.on_attachments_loaded([]);
} else {
var dom = [ ['res_model', '=', dataset.model], ['res_id', '=', model_id], ['type', 'in', ['binary', 'url']] ];
var ds = new instance.web.DataSetSearch(this, 'ir.attachment', dataset.get_context(), dom);
ds.read_slice(['name', 'url', 'type'], {}).then(this.on_attachments_loaded);
}
},
on_attachments_loaded: function(attachments) {
var self = this;
var items = [];
// TODO: preprend: _s +
var prefix = '/web/binary/saveas?session_id=' + self.session.session_id + '&model=ir.attachment&field=datas&filename_field=name&id=';
_.each(attachments,function(a) {
a.label = a.name;
if(a.type === "binary") {
a.url = prefix + a.id + '&t=' + (new Date().getTime());
}
});
attachments.push( { label: _t("Add..."), callback: self.on_attachment_add } );
self.items['files'] = attachments;
self.redraw();
},
on_attachment_add: function(e) {
this.$element.find('.oe_sidebar_add').show();
},
on_attachment_changed: function(e) {
return;
window[this.element_id + '_iframe'] = this.do_update;
var $e = $(e.target);
if ($e.val() != '') {
this.$element.find('form.oe-binary-form').submit();
$e.parent().find('input[type=file]').prop('disabled', true);
$e.parent().find('button').prop('disabled', true).find('img, span').toggle();
}
},
on_attachment_delete: function(e) {
return;
var self = this, $e = $(e.currentTarget);
var name = _.str.trim($e.parent().find('a.oe-sidebar-attachments-link').text());
if (confirm(_.str.sprintf(_t("Do you really want to delete the attachment %s?"), name))) {
this.rpc('/web/dataset/unlink', {
model: 'ir.attachment',
ids: [parseInt($e.attr('data-id'))]
}, function(r) {
$e.parent().remove();
self.do_notify("Delete an attachment", "The attachment '" + name + "' has been deleted");
});
}
}
});
session.web.TranslateDialog = session.web.Dialog.extend({
instance.web.TranslateDialog = instance.web.Dialog.extend({
dialog_title: {toString: function () { return _t("Translations"); }},
init: function(view) {
// TODO fme: should add the language to fields_view_get because between the fields view get
@ -879,14 +929,14 @@ session.web.TranslateDialog = session.web.Dialog.extend({
this.translatable_fields_keys = _.map(this.view.translatable_fields || [], function(i) { return i.name });
this.languages = null;
this.languages_loaded = $.Deferred();
(new session.web.DataSetSearch(this, 'res.lang', this.view.dataset.get_context(),
(new instance.web.DataSetSearch(this, 'res.lang', this.view.dataset.get_context(),
[['translatable', '=', '1']])).read_slice(['code', 'name'], { sort: 'id' }).then(this.on_languages_loaded);
},
start: function() {
var self = this;
this._super();
$.when(this.languages_loaded).then(function() {
self.$element.html(session.web.qweb.render('TranslateDialog', { widget: self }));
self.$element.html(instance.web.qweb.render('TranslateDialog', { widget: self }));
self.$fields_form = self.$element.find('.oe_translation_form');
self.$fields_form.find('.oe_trad_field').change(function() {
$(this).toggleClass('touched', ($(this).val() != $(this).attr('data-value')));
@ -975,7 +1025,7 @@ session.web.TranslateDialog = session.web.Dialog.extend({
}
});
session.web.View = session.web.Widget.extend({
instance.web.View = instance.web.Widget.extend({
template: "EmptyComponent",
// name displayed in view switchers
display_name: '',
@ -999,14 +1049,14 @@ session.web.View = session.web.Widget.extend({
$.async_when().then(function() {def.resolve(self.embedded_view);});
return def.pipe(this.on_loaded);
} else {
var context = new session.web.CompoundContext(this.dataset.get_context());
var context = new instance.web.CompoundContext(this.dataset.get_context());
if (! this.view_type)
console.warn("view_type is not defined", this);
return this.rpc("/web/view/load", {
"model": this.dataset.model,
"view_id": this.view_id,
"view_type": this.view_type,
toolbar: this.options.sidebar,
toolbar: !!this.options.$sidebar,
context: context
}).pipe(this.on_loaded);
}
@ -1023,14 +1073,13 @@ session.web.View = session.web.Widget.extend({
// All possible views options should be defaulted here
$sidebar: null,
sidebar_id: null,
sidebar: true,
action: null,
action_views_ids: {}
});
},
open_translate_dialog: function(field) {
if (!this.translate_dialog) {
this.translate_dialog = new session.web.TranslateDialog(this).start();
this.translate_dialog = new instance.web.TranslateDialog(this).start();
}
this.translate_dialog.open(field);
},
@ -1042,7 +1091,7 @@ session.web.View = session.web.Widget.extend({
* @param {String} [action_data.special=null] special action handlers (currently: only ``'cancel'``)
* @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 {session.web.DataSet} dataset a dataset object used to communicate with the server
* @param {instance.web.DataSet} dataset a dataset object used to communicate with the server
* @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)
*/
@ -1054,12 +1103,12 @@ session.web.View = session.web.Widget.extend({
return self.getParent().on_action_executed.apply(null, arguments);
}
};
var context = new session.web.CompoundContext(dataset.get_context(), action_data.context || {});
var context = new instance.web.CompoundContext(dataset.get_context(), action_data.context || {});
var handler = function (r) {
var action = r.result;
if (action && action.constructor == Object) {
var ncontext = new session.web.CompoundContext(context);
var ncontext = new instance.web.CompoundContext(context);
if (record_id) {
ncontext.add({
active_id: record_id,
@ -1108,13 +1157,12 @@ session.web.View = session.web.Widget.extend({
/**
* Directly set a view to use instead of calling fields_view_get. This method must
* be called before start(). When an embedded view is set, underlying implementations
* of session.web.View must use the provided view instead of any other one.
* of instance.web.View must use the provided view instead of any other one.
*
* @param embedded_view A view.
*/
set_embedded_view: function(embedded_view) {
this.embedded_view = embedded_view;
this.options.sidebar = false;
},
do_show: function () {
this.$element.show();
@ -1147,15 +1195,12 @@ session.web.View = session.web.Widget.extend({
},
do_search: function(view) {
},
set_common_sidebar_sections: function(sidebar) {
sidebar.add_default_sections();
},
on_sidebar_import: function() {
var import_view = new session.web.DataImport(this, this.dataset);
var import_view = new instance.web.DataImport(this, this.dataset);
import_view.start();
},
on_sidebar_export: function() {
var export_view = new session.web.DataExport(this, this.dataset);
var export_view = new instance.web.DataExport(this, this.dataset);
export_view.start();
},
on_sidebar_translate: function() {
@ -1180,7 +1225,7 @@ session.web.View = session.web.Widget.extend({
}
});
session.web.xml_to_json = function(node) {
instance.web.xml_to_json = function(node) {
switch (node.nodeType) {
case 3:
case 4:
@ -1198,11 +1243,11 @@ session.web.xml_to_json = function(node) {
return {
tag: node.tagName.toLowerCase(),
attrs: attrs,
children: _.map(node.childNodes, session.web.xml_to_json)
children: _.map(node.childNodes, instance.web.xml_to_json)
}
}
}
session.web.json_node_to_xml = function(node, human_readable, indent) {
instance.web.json_node_to_xml = function(node, human_readable, indent) {
// For debugging purpose, this function will convert a json node back to xml
// Maybe useful for xml view editor
indent = indent || 0;
@ -1231,7 +1276,7 @@ session.web.json_node_to_xml = function(node, human_readable, indent) {
r += '>' + cr;
var childs = [];
for (var i = 0, ii = node.children.length; i < ii; i++) {
childs.push(session.web.json_node_to_xml(node.children[i], human_readable, indent + 1));
childs.push(instance.web.json_node_to_xml(node.children[i], human_readable, indent + 1));
}
r += childs.join(cr);
r += cr + sindent + '</' + node.tag + '>';
@ -1240,23 +1285,43 @@ session.web.json_node_to_xml = function(node, human_readable, indent) {
return r + '/>';
}
}
session.web.xml_to_str = function(node) {
instance.web.xml_to_str = function(node) {
if (window.ActiveXObject) {
return node.xml;
} else {
return (new XMLSerializer()).serializeToString(node);
}
}
instance.web.str_to_xml = function(s) {
if (window.DOMParser) {
var dp = new DOMParser();
var r = dp.parseFromString(s, "text/xml");
if (r.body && r.body.firstChild && r.body.firstChild.nodeName == 'parsererror') {
throw new Error("Could not parse string to xml");
}
return r;
}
var xDoc;
try {
xDoc = new ActiveXObject("MSXML2.DOMDocument");
} catch (e) {
throw new Error("Could not find a DOM Parser: " + e.message);
}
xDoc.async = false;
xDoc.preserveWhiteSpace = true;
xDoc.loadXML(s);
return xDoc;
}
/**
* Registry for all the client actions key: tag value: widget
*/
session.web.client_actions = new session.web.Registry();
instance.web.client_actions = new instance.web.Registry();
/**
* Registry for all the main views
*/
session.web.views = new session.web.Registry();
instance.web.views = new instance.web.Registry();
};

View File

@ -275,7 +275,10 @@
</tr>
<tr>
<td class="oe_leftbar" valign="top">
<a href="#" class="oe_logo"><img t-att-src='_s + "/web/static/src/img/logo.png"'/></a>
<t t-js="d">
d.url = '/' + (window.location.search || '');
</t>
<a t-att-href="url" class="oe_logo"><img t-att-src='_s + "/web/static/src/img/logo.png"'/></a>
<div class="oe_secondary_menus_container"/>
<div class="oe_footer">
Powered by <a href="http://www.openerp.com"><span>Open</span>ERP</a>
@ -324,7 +327,7 @@
</ul>
</t>
<t t-name="Menu.secondary.link">
<a href="#"
<a t-attf-href="#menu_id=#{menu.id}&amp;action_id=#{menu.action ? menu.action.split(',')[1] : ''}"
t-att-class="menu.children.length ? 'oe_menu_toggler' : 'oe_menu_leaf'"
t-att-data-menu="menu.id"
t-att-data-action-model="menu.action ? menu.action.split(',')[0] : ''"
@ -342,7 +345,7 @@
<ul class="oe_user_menu oe_topbar_item">
<li class="oe_dropdown">
<a href="#" class="oe_dropdown_toggle">
<img class="oe_topbar_avatar" t-att-data-default-src="_s + '/web/static/src/img/topbar-avatar.png'"/>
<img class="oe_topbar_avatar" t-att-data-default-src="_s + '/web/static/src/img/user_menu_avatar.png'"/>
<span class="oe_topbar_name"/>
</a>
<ul class="oe_dropdown_options">
@ -515,15 +518,52 @@
<button class="oe_dropdown_toggle"><t t-esc="section.label"/></button>
<ul class="oe_dropdown_menu">
<li t-foreach="widget.items[section.name]" t-as="item" t-att-class="item.classname">
<a class="oe_sidebar_action_a" t-att-title="item.title" href="#" t-att-data-section="section.name" t-att-data-index="item_index">
<a class="oe_sidebar_action_a" t-att-title="item.title" t-att-data-section="section.name" t-att-data-index="item_index" t-att-href="item.url" target="_blank">
<t t-raw="item.label"/>
</a>
</li>
<li t-if="section.name == 'files'" class="oe_sidebar_add" style="display:none;">
Input type file stuff
</li>
</ul>
</div>
</t>
</div>
</t>
<t t-name="Sidebar.attachments">
<div class="oe-sidebar-attachments-toolbar">
<div class="oe-binary-file-set" style="float: right">
<form class="oe-binary-form" t-attf-target="#{element_id}_iframe"
method="post" enctype="multipart/form-data" action="/web/binary/upload_attachment">
<input type="hidden" name="session_id" t-att-value="session.session_id"/>
<input type="hidden" name="callback" t-attf-value="#{element_id}_iframe"/>
<input type="hidden" name="model" t-att-value="view.dataset.model"/>
<input type="hidden" name="id" t-att-value="view.datarecord.id"/>
<button class="oe_button" type="button">
<img t-att-src='_s + "/web/static/src/img/throbber.gif"' width="16" height="16" style="display: none"/>
<span>Add</span>
</button>
<input type="file" class="oe-binary-file" name="ufile" title="Add attachment"
t-att-onclick="view.datarecord.id ? null : 'alert(\'No record selected ! You can only attach to existing record.\'); return false;'"/>
</form>
<iframe t-attf-id="#{element_id}_iframe" t-attf-name="#{element_id}_iframe" style="display: none"/>
</div>
</div>
<br style="clear: both"/>
<ul class="oe-sidebar-attachments-items">
<li t-foreach="attachments" t-as="attachment">
<t t-if="attachment.type == 'binary'" t-set="attachment.url" t-value="_s + '/web/binary/saveas?session_id='
+ session.session_id + '&amp;model=ir.attachment&amp;id=' + attachment.id
+ '&amp;field=datas&amp;filename_field=name&amp;t=' + (new Date().getTime())"/>
<a class="oe-sidebar-attachments-link" t-att-href="attachment.url" target="_blank">
<t t-esc="attachment.name"/>
</a>
<a href="#" class="oe-sidebar-attachment-delete" t-att-data-id="attachment.id" t-attf-title="Delete the attachment #{attachment.name}">
<img t-att-src='_s + "/web/static/src/img/attachments-close.png"' width="15" height="15" border="0"/>
</a>
</li>
</ul>
</t>
<t t-name="TreeView">
<select t-if="toolbar" style="width: 30%">
@ -633,7 +673,7 @@
</t>
<tr t-name="ListView.row" t-att-class="row_parity"
t-att-data-id="record.get('id')"
t-att-style="view.color_for(record)">
t-att-style="view.style_for(record)">
<t t-foreach="columns" t-as="column">
<td t-if="column.meta">
@ -678,8 +718,8 @@
<button type="button" class="oe_button oe_form_button_delete">Delete</button>
</span>
<span class="oe_form_buttons_edit">
<button type="button" class="oe_button oe_form_button_save">Save</button>
<button type="button" class="oe_button oe_form_button_cancel">Cancel</button>
<button type="button" class="oe_button oe_form_button_save">Save</button> or
<a href="#" class="oe_form_button_cancel">Discard</a>
</span>
</t>
</div>
@ -690,40 +730,6 @@
</t>
</div>
</t>
<t t-name="FormView.sidebar.attachments">
<div class="oe-sidebar-attachments-toolbar">
<div class="oe-binary-file-set" style="float: right">
<form class="oe-binary-form" t-attf-target="#{element_id}_iframe"
method="post" enctype="multipart/form-data" action="/web/binary/upload_attachment">
<input type="hidden" name="session_id" t-att-value="session.session_id"/>
<input type="hidden" name="callback" t-attf-value="#{element_id}_iframe"/>
<input type="hidden" name="model" t-att-value="view.dataset.model"/>
<input type="hidden" name="id" t-att-value="view.datarecord.id"/>
<button class="oe_button" type="button">
<img t-att-src='_s + "/web/static/src/img/throbber.gif"' width="16" height="16" style="display: none"/>
<span>Add</span>
</button>
<input type="file" class="oe-binary-file" name="ufile" title="Add attachment"
t-att-onclick="view.datarecord.id ? null : 'alert(\'No record selected ! You can only attach to existing record.\'); return false;'"/>
</form>
<iframe t-attf-id="#{element_id}_iframe" t-attf-name="#{element_id}_iframe" style="display: none"/>
</div>
</div>
<br style="clear: both"/>
<ul class="oe-sidebar-attachments-items">
<li t-foreach="attachments" t-as="attachment">
<t t-if="attachment.type == 'binary'" t-set="attachment.url" t-value="_s + '/web/binary/saveas?session_id='
+ session.session_id + '&amp;model=ir.attachment&amp;id=' + attachment.id
+ '&amp;field=datas&amp;filename_field=name&amp;t=' + (new Date().getTime())"/>
<a class="oe-sidebar-attachments-link" t-att-href="attachment.url" target="_blank">
<t t-esc="attachment.name"/>
</a>
<a href="#" class="oe-sidebar-attachment-delete" t-att-data-id="attachment.id" t-attf-title="Delete the attachment #{attachment.name}">
<img t-att-src='_s + "/web/static/src/img/attachments-close.png"' width="15" height="15" border="0"/>
</a>
</li>
</ul>
</t>
<form t-name="FormView.set_default" class="oe_forms oe_frame">
<t t-set="args" t-value="widget.dialog_options.args"/>
<table style="width: 100%">
@ -808,7 +814,7 @@
<t t-name="FormRenderingNotebook">
<div>
<ul t-attf-class="oe_form_notebook #{classnames}">
<li t-foreach="pages" t-as="page">
<li t-foreach="pages" t-as="page" t-att-modifiers="page.modifiers">
<a t-attf-href="##{page.id}">
<t t-esc="page.string"/>
</a>
@ -969,16 +975,16 @@
</t>
</t>
<t t-name="FieldText">
<t t-if="!widget.get('effective_readonly')">
<div class="oe_form_field_text">
<textarea rows="6"
t-att-name="widget.name"
class="field_text"
t-att-tabindex="widget.node.attrs.tabindex"
t-att-autofocus="widget.node.attrs.autofocus"
></textarea><img class="oe_field_translate oe_input_icon" t-if="widget.field.translate" t-att-src='_s + "/web/static/src/img/icons/terp-translate.png"' width="16" height="16" border="0"/>
</div>
</t>
<div class="oe_form_field_text">
<textarea rows="6"
t-att-name="widget.name"
class="field_text"
t-att-tabindex="widget.node.attrs.tabindex"
t-att-autofocus="widget.node.attrs.autofocus"
></textarea>
<img class="oe_field_translate oe_input_icon" t-if="widget.field.translate"
t-att-src='_s + "/web/static/src/img/icons/terp-translate.png"' width="16" height="16" border="0"/>
</div>
</t>
<t t-name="web.datetimepicker">
<div class="oe_datepicker_root oe_form_field_datetime">
@ -1037,19 +1043,14 @@
</t>
</t>
<t t-name="FieldReference">
<t t-if="!widget.get('effective_readonly')">
<table class="oe_form_field_reference oe_frame oe_forms" border="0" cellpadding="0" cellspacing="0">
<tr>
<td t-attf-class="oe_form_frame_cell oe_form_selection oe_form_view_reference_selection">
</td>
<td t-attf-class="oe_form_frame_cell oe_form_many2one oe_form_view_reference_m2o" nowrap="true" style="display: none">
</td>
</tr>
</table>
</t>
<t t-if="widget.get('effective_readonly')">
<a href="#" class="oe_form_uri"/>
</t>
<table class="oe_form_field_reference oe_frame oe_forms" border="0" cellpadding="0" cellspacing="0">
<tr>
<td t-attf-class="oe_form_frame_cell oe_form_selection oe_form_view_reference_selection">
</td>
<td t-attf-class="oe_form_frame_cell oe_form_many2one oe_form_view_reference_m2o" nowrap="true" style="display: none">
</td>
</tr>
</table>
</t>
<t t-name="FieldBoolean">
<span class="oe_form_field_boolean">

View File

@ -2,8 +2,8 @@ $(document).ready(function () {
var openerp;
module('web-class', {
setup: function () {
openerp = window.openerp.init();
window.openerp.web.core(openerp);
openerp = window.openerp.init([]);
window.openerp.web.corelib(openerp);
}
});
test('Basic class creation', function () {

View File

@ -1,143 +0,0 @@
module("Class");
test("base", function() {
ok(!!nova.Class, "Class does exist");
ok(!!nova.Class.extend, "extend does exist");
var Claz = nova.Class.extend({
test: function() {
return "ok";
}
});
equal(new Claz().test(), "ok");
var Claz2 = Claz.extend({
test: function() {
return this._super() + "2";
}
});
equal(new Claz2().test(), "ok2");
});
module("DestroyableMixin");
test("base", function() {
var Claz = nova.Class.extend(_.extend({}, nova.DestroyableMixin, {}));
var x = new Claz();
equal(!!x.isDestroyed(), false);
x.destroy();
equal(x.isDestroyed(), true);
});
module("ParentedMixin");
test("base", function() {
var Claz = nova.Class.extend(_.extend({}, nova.ParentedMixin, {}));
var x = new Claz();
var y = new Claz();
y.setParent(x);
equal(y.getParent(), x);
equal(x.getChildren()[0], y);
x.destroy();
equal(y.isDestroyed(), true);
});
module("Events");
test("base", function() {
var x = new nova.internal.Events();
var tmp = 0;
var fct = function() {tmp = 1;};
x.on("test", fct);
equal(tmp, 0);
x.trigger("test");
equal(tmp, 1);
tmp = 0;
x.off("test", fct);
x.trigger("test");
equal(tmp, 0);
});
module("EventDispatcherMixin");
test("base", function() {
var Claz = nova.Class.extend(_.extend({}, nova.EventDispatcherMixin, {}));
var x = new Claz();
var y = new Claz();
var tmp = 0;
var fct = function() {tmp = 1;};
x.on("test", y, fct);
equal(tmp, 0);
x.trigger("test");
equal(tmp, 1);
tmp = 0;
x.off("test", y, fct);
x.trigger("test");
equal(tmp, 0);
tmp = 0;
x.on("test", y, fct);
y.destroy();
x.trigger("test");
equal(tmp, 0);
});
module("GetterSetterMixin");
test("base", function() {
var Claz = nova.Class.extend(_.extend({}, nova.GetterSetterMixin, {}));
var x = new Claz();
var y = new Claz();
x.set({test: 1});
equal(x.get("test"), 1);
var tmp = 0;
x.on("change:test", y, function(model, options) {
tmp = 1;
equal(options.oldValue, 1);
equal(options.newValue, 2);
equal(x.get("test"), 2);
equal(model, x);
});
x.set({test: 2});
equal(tmp, 1);
});
test("change event only when changed", function() {
var Claz = nova.Class.extend(_.extend({}, nova.GetterSetterMixin, {}));
var x = new Claz();
var exec1 = false;
var exec2 = false;
x.on("change:test", null, function() {exec1 = true;});
x.on("change", null, function() {exec2 = true;});
x.set({"test": 3});
equal(exec1, true);
equal(exec2, true);
exec1 = false;
exec2 = false;
x.set({"test": 3});
equal(exec1, false);
equal(exec2, false);
});
module("Widget");
test("base", function() {
var Claz = nova.Widget.extend({
renderElement: function() {
this.$element.attr("id", "testdiv");
this.$element.html("test");
}
});
var x = new Claz();
x.appendTo($("body"));
var $el = $("#testdiv");
equal($el.length, 1);
equal($el.parents()[0], $("body")[0]);
equal($el.html(), "test");
var y = new Claz(x);
equal(y.getParent(), x);
x.destroy();
$el = $("#testdiv");
equal($el.length, 0);
});

View File

@ -3,8 +3,9 @@ $(document).ready(function () {
module("eval.contexts", {
setup: function () {
openerp = window.openerp.init();
window.openerp.web.core(openerp);
openerp = window.openerp.init([]);
window.openerp.web.corelib(openerp);
window.openerp.web.coresetup(openerp);
}
});
test('context_sequences', function () {

View File

@ -2,8 +2,9 @@ $(document).ready(function () {
var openerp;
module("form.widget", {
setup: function () {
openerp = window.openerp.init(true);
window.openerp.web.core(openerp);
openerp = window.openerp.init([]);
window.openerp.web.corelib(openerp);
window.openerp.web.coresetup(openerp);
window.openerp.web.chrome(openerp);
// views loader stuff
window.openerp.web.data(openerp);

View File

@ -3,8 +3,9 @@ $(document).ready(function () {
module('server-formats', {
setup: function () {
openerp = window.openerp.init();
window.openerp.web.core(openerp);
openerp = window.openerp.init([]);
window.openerp.web.corelib(openerp);
window.openerp.web.coresetup(openerp);
window.openerp.web.dates(openerp);
}
});
@ -40,8 +41,9 @@ $(document).ready(function () {
module('web-formats', {
setup: function () {
openerp = window.openerp.init();
window.openerp.web.core(openerp);
openerp = window.openerp.init([]);
window.openerp.web.corelib(openerp);
window.openerp.web.coresetup(openerp);
window.openerp.web.dates(openerp);
window.openerp.web.formats(openerp);
}
@ -206,8 +208,9 @@ $(document).ready(function () {
});
module('custom-date-formats', {
setup: function () {
openerp = window.openerp.init();
window.openerp.web.core(openerp);
openerp = window.openerp.init([]);
window.openerp.web.corelib(openerp);
window.openerp.web.coresetup(openerp);
window.openerp.web.dates(openerp);
window.openerp.web.formats(openerp);
}

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html style="height: 100%">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>OpenERP</title>
<link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" href="/web/static/lib/qunit/qunit.css">
<script src="/web/static/lib/qunit/qunit.js" type="text/javascript"></script>
<script src="/web/static/lib/underscore/underscore.js" type="text/javascript"></script>
<script src="/web/static/lib/underscore/underscore.string.js" type="text/javascript"></script>
<!-- jquery -->
<script src="/web/static/lib/jquery/jquery-1.6.4.js"></script>
<script src="/web/static/lib/jquery.ui/js/jquery-ui-1.8.17.custom.min.js"></script>
<script src="/web/static/lib/jquery.ba-bbq/jquery.ba-bbq.js"></script>
<script src="/web/static/lib/datejs/globalization/en-US.js"></script>
<script src="/web/static/lib/datejs/core.js"></script>
<script src="/web/static/lib/datejs/parser.js"></script>
<script src="/web/static/lib/datejs/sugarpak.js"></script>
<script src="/web/static/lib/datejs/extras.js"></script>
<script src="/web/static/lib/qweb/qweb2.js"></script>
<script src="/web/static/lib/py.js/lib/py.js"></script>
<script src="/web/static/src/js/boot.js"></script>
<script src="/web/static/src/js/corelib.js"></script>
<script src="/web/static/src/js/coresetup.js"></script>
<script src="/web/static/src/js/dates.js"></script>
<script src="/web/static/src/js/formats.js"></script>
<script src="/web/static/src/js/chrome.js"></script>
<script src="/web/static/src/js/data.js"></script>
<script src="/web/static/src/js/test_support.js"></script>
</head>
<body id="oe" class="openerp">
<h1 id="qunit-header">
OpenERP Web Test Suite: javascript to XML-RPC (excluded)
</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture"></div>
<script type="text/javascript" src="/web/static/test/fulltest/dataset.js"></script>
</body>
</html>

View File

@ -0,0 +1,241 @@
$(document).ready(function () {
var t = window.openerp.test_support;
function context_(c) {
return _.extend({ lang: 'en_US', tz: 'UTC', uid: 87539319 }, c);
}
t.module('Dataset shortcuts', 'data');
t.test('read_index', function (openerp) {
var ds = new openerp.web.DataSet(
{session: openerp.connection}, 'some.model');
ds.ids = [10, 20, 30, 40, 50];
ds.index = 2;
t.expect(ds.read_index(['a', 'b', 'c']), function (result) {
strictEqual(result.method, 'read');
strictEqual(result.model, 'some.model');
strictEqual(result.args.length, 2);
deepEqual(result.args[0], [30]);
deepEqual(result.kwargs, {
context: context_()
});
});
});
t.test('default_get', function (openerp) {
var ds = new openerp.web.DataSet(
{session: openerp.connection}, 'some.model', {foo: 'bar'});
t.expect(ds.default_get(['a', 'b', 'c']), function (result) {
strictEqual(result.method, 'default_get');
strictEqual(result.model, 'some.model');
strictEqual(result.args.length, 1);
deepEqual(result.args[0], ['a', 'b', 'c']);
deepEqual(result.kwargs, {
context: context_({foo: 'bar'})
});
});
});
t.test('create', function (openerp) {
var ds = new openerp.web.DataSet({session: openerp.connection}, 'some.model');
t.expect(ds.create({foo: 1, bar: 2}), function (r) {
strictEqual(r.method, 'create');
strictEqual(r.args.length, 1);
deepEqual(r.args[0], {foo: 1, bar: 2});
deepEqual(r.kwargs, {
context: context_()
});
});
});
t.test('write', function (openerp) {
var ds = new openerp.web.DataSet({session: openerp.connection}, 'mod');
t.expect(ds.write(42, {foo: 1}), function (r) {
strictEqual(r.method, 'write');
strictEqual(r.args.length, 2);
deepEqual(r.args[0], [42]);
deepEqual(r.args[1], {foo: 1});
deepEqual(r.kwargs, {
context: context_()
});
});
// FIXME: can't run multiple sessions in the same test(), fucks everything up
// t.expect(ds.write(42, {foo: 1}, { context: {lang: 'bob'} }), function (r) {
// strictEqual(r.args.length, 3);
// strictEqual(r.args[2].lang, 'bob');
// });
});
t.test('unlink', function (openerp) {
var ds = new openerp.web.DataSet({session: openerp.connection}, 'mod');
t.expect(ds.unlink([42]), function (r) {
strictEqual(r.method, 'unlink');
strictEqual(r.args.length, 1);
deepEqual(r.args[0], [42]);
deepEqual(r.kwargs, {
context: context_()
});
});
});
t.test('call', function (openerp) {
var ds = new openerp.web.DataSet({session: openerp.connection}, 'mod');
t.expect(ds.call('frob', ['a', 'b', 42]), function (r) {
strictEqual(r.method, 'frob');
strictEqual(r.args.length, 3);
deepEqual(r.args, ['a', 'b', 42]);
ok(_.isEmpty(r.kwargs));
});
});
t.test('name_get', function (openerp) {
var ds = new openerp.web.DataSet({session: openerp.connection}, 'mod');
t.expect(ds.name_get([1, 2], null), function (r) {
strictEqual(r.method, 'name_get');
strictEqual(r.args.length, 1);
deepEqual(r.args[0], [1, 2]);
deepEqual(r.kwargs, {
context: context_()
});
});
});
t.test('name_search, name', function (openerp) {
var ds = new openerp.web.DataSet({session: openerp.connection}, 'mod');
t.expect(ds.name_search('bob'), function (r) {
strictEqual(r.method, 'name_search');
strictEqual(r.args.length, 0);
deepEqual(r.kwargs, {
name: 'bob',
args: false,
operator: 'ilike',
context: context_(),
limit: 0
});
});
});
t.test('name_search, domain & operator', function (openerp) {
var ds = new openerp.web.DataSet({session: openerp.connection}, 'mod');
t.expect(ds.name_search(0, [['foo', '=', 3]], 'someop'), function (r) {
strictEqual(r.method, 'name_search');
strictEqual(r.args.length, 0);
deepEqual(r.kwargs, {
name: '',
args: [['foo', '=', 3]],
operator: 'someop',
context: context_(),
limit: 0
});
});
});
t.test('exec_workflow', function (openerp) {
var ds = new openerp.web.DataSet({session: openerp.connection}, 'mod');
t.expect(ds.exec_workflow(42, 'foo'), function (r) {
strictEqual(r['service'], 'object');
strictEqual(r.method, 'exec_workflow');
// db, id, password, model, method, id
strictEqual(r.args.length, 6);
strictEqual(r.args[4], 'foo');
strictEqual(r.args[5], 42);
});
});
t.test('DataSetSearch#read_slice', function (openerp) {
var ds = new openerp.web.DataSetSearch({session: openerp.connection}, 'mod');
t.expect(ds.read_slice(['foo', 'bar'], {
domain: [['foo', '>', 42], ['qux', '=', 'grault']],
context: {peewee: 'herman'},
offset: 160,
limit: 80
}), function (r) {
strictEqual(r.method, 'search');
strictEqual(r.args.length, 5);
deepEqual(r.args[0], [['foo', '>', 42], ['qux', '=', 'grault']]);
strictEqual(r.args[1], 160);
strictEqual(r.args[2], 80);
strictEqual(r.args[3], false);
strictEqual(r.args[4].peewee, 'herman');
ok(_.isEmpty(r.kwargs));
});
});
t.test('DataSetSearch#read_slice sorted', function (openerp) {
var ds = new openerp.web.DataSetSearch({session: openerp.connection}, 'mod');
ds.sort('foo');
ds.sort('foo');
ds.sort('bar');
t.expect(ds.read_slice(['foo', 'bar'], { }), function (r) {
strictEqual(r.method, 'search');
strictEqual(r.args.length, 5);
deepEqual(r.args[0], []);
strictEqual(r.args[1], 0);
strictEqual(r.args[2], false);
strictEqual(r.args[3], 'bar ASC, foo DESC');
deepEqual(r.args[4], context_());
ok(_.isEmpty(r.kwargs));
});
});
t.module('Nonliterals', 'data', {
domains: [
"[('model_id', '=', parent.model)]",
"[('product_id','=',product_id)]"
],
contexts: ['{a: b > c}']
});
t.test('Dataset', function (openerp) {
var ds = new openerp.web.DataSetSearch(
{session: openerp.connection}, 'mod');
var c = new openerp.web.CompoundContext(
{a: 'foo', b: 3, c: 5}, openerp.contexts[0]);
t.expect(ds.read_slice(['foo', 'bar'], {
context: c
}), function (r) {
strictEqual(r.method, 'search');
deepEqual(r.args[4], context_({
foo: false,
a: 'foo',
b: 3,
c: 5
}));
ok(_.isEmpty(r.kwargs));
});
});
t.test('name_search', function (openerp) {
var eval_context = {
active_id: 42,
active_ids: [42],
active_model: 'mod',
parent: {model: 'qux'}
};
var ds = new openerp.web.DataSet(
{session: openerp.connection}, 'mod',
new openerp.web.CompoundContext({})
.set_eval_context(eval_context));
var domain = new openerp.web.CompoundDomain(openerp.domains[0])
.set_eval_context(eval_context);
t.expect(ds.name_search('foo', domain, 'ilike', 0), function (r) {
strictEqual(r.method, 'name_search');
strictEqual(r.args.length, 0);
deepEqual(r.kwargs, {
name: 'foo',
args: [['model_id', '=', 'qux']],
operator: 'ilike',
context: context_(),
limit: 0
});
});
});
});

View File

@ -10,7 +10,13 @@ $(document).ready(function () {
};
module('list-events', {
setup: function () {
openerp = window.openerp.init();
openerp = window.openerp.init([]);
window.openerp.web.corelib(openerp);
window.openerp.web.coresetup(openerp);
window.openerp.web.chrome(openerp);
// views loader stuff
window.openerp.web.data(openerp);
window.openerp.web.views(openerp);
window.openerp.web.list(openerp);
}
});
@ -90,7 +96,13 @@ $(document).ready(function () {
module('list-records', {
setup: function () {
openerp = window.openerp.init();
openerp = window.openerp.init([]);
window.openerp.web.corelib(openerp);
window.openerp.web.coresetup(openerp);
window.openerp.web.chrome(openerp);
// views loader stuff
window.openerp.web.data(openerp);
window.openerp.web.views(openerp);
window.openerp.web.list(openerp);
}
});
@ -123,7 +135,13 @@ $(document).ready(function () {
module('list-collections-degenerate', {
setup: function () {
openerp = window.openerp.init();
openerp = window.openerp.init([]);
window.openerp.web.corelib(openerp);
window.openerp.web.coresetup(openerp);
window.openerp.web.chrome(openerp);
// views loader stuff
window.openerp.web.data(openerp);
window.openerp.web.views(openerp);
window.openerp.web.list(openerp);
}
});
@ -245,7 +263,13 @@ $(document).ready(function () {
module('list-hofs', {
setup: function () {
openerp = window.openerp.init();
openerp = window.openerp.init([]);
window.openerp.web.corelib(openerp);
window.openerp.web.coresetup(openerp);
window.openerp.web.chrome(openerp);
// views loader stuff
window.openerp.web.data(openerp);
window.openerp.web.views(openerp);
window.openerp.web.list(openerp);
}
});

View File

@ -1,74 +0,0 @@
$(document).ready(function () {
var openerp,
make_form = function (default_values) {
var fields = {};
_(default_values).each(function (value, name) {
fields[name] = value instanceof Function ? value : {
get_on_change_value: function () { return value; }
};
});
return _.extend(new openerp.web.FormView(null, {}),
{fields: fields});
};
module("form.onchange", {
setup: function () {
openerp = window.openerp.init(true);
window.openerp.web.core(openerp);
window.openerp.web.chrome(openerp);
// views loader stuff
window.openerp.web.data(openerp);
window.openerp.web.views(openerp);
window.openerp.web.list(openerp);
window.openerp.web.form(openerp);
}
});
test('Parse args-less onchange', function () {
var f = new openerp.web.FormView(null, {});
var result = f.parse_on_change('on_change_foo()', {});
equal(result.method, 'on_change_foo');
deepEqual(result.args, []);
});
test('Parse 1-arg onchange', function () {
var f = make_form({foo: 3});
var result = f.parse_on_change('on_change_foo(foo)', {});
equal(result.method, 'on_change_foo');
deepEqual(result.args, [3]);
});
test('Parse 2-args onchange', function () {
var f = make_form({foo: 3, bar: 'qux'});
var result = f.parse_on_change('on_change_foo(bar, foo)', {});
equal(result.method, 'on_change_foo');
deepEqual(result.args, ['qux', 3]);
});
test('Literal null', function () {
var f = make_form();
var result = f.parse_on_change('on_null(None)', {});
deepEqual(result.args, [null]);
});
test('Literal true', function () {
var f = make_form();
var result = f.parse_on_change('on_null(True)', {});
deepEqual(result.args, [true]);
});
test('Literal false', function () {
var f = make_form();
var result = f.parse_on_change('on_null(False)', {});
deepEqual(result.args, [false]);
});
test('Literal string', function () {
var f = make_form();
var result = f.parse_on_change('on_str("foo")', {});
deepEqual(result.args, ['foo']);
var result2 = f.parse_on_change("on_str('foo')", {});
deepEqual(result2.args, ['foo']);
});
test('Literal number', function () {
var f = make_form();
var result = f.parse_on_change('on_str(42)', {});
deepEqual(result.args, [42]);
var result2 = f.parse_on_change("on_str(-25)", {});
deepEqual(result2.args, [-25]);
var result3 = f.parse_on_change("on_str(25.02)", {});
deepEqual(result3.args, [25.02]);
});
});

View File

@ -2,8 +2,8 @@ $(document).ready(function () {
var openerp;
module('Registry', {
setup: function () {
openerp = window.openerp.init(true);
window.openerp.web.core(openerp);
openerp = window.openerp.init([]);
window.openerp.web.corelib(openerp);
openerp.web.Foo = {};
openerp.web.Bar = {};
openerp.web.Foo2 = {};

View File

@ -0,0 +1,131 @@
$(document).ready(function () {
var openerp;
module('Misordered resolution management', {
setup: function () {
openerp = window.openerp.init([]);
window.openerp.web.corelib(openerp);
window.openerp.web.coresetup(openerp);
window.openerp.web.data(openerp);
}
});
test('Resolve all correctly ordered, sync', function () {
var dm = new openerp.web.DropMisordered(), flag = false;
var d1 = $.Deferred(), d2 = $.Deferred(),
r1 = dm.add(d1), r2 = dm.add(d2);
$.when(r1, r2).done(function () {
flag = true;
});
d1.resolve();
d2.resolve();
ok(flag);
});
test("Don't resolve mis-ordered, sync", function () {
var dm = new openerp.web.DropMisordered(),
done1 = false, done2 = false,
fail1 = false, fail2 = false;
var d1 = $.Deferred(), d2 = $.Deferred();
dm.add(d1).then(function () { done1 = true; },
function () { fail1 = true; });
dm.add(d2).then(function () { done2 = true; },
function () { fail2 = true; });
d2.resolve();
d1.resolve();
// d1 is in limbo
ok(!done1);
ok(!fail1);
// d2 is resolved
ok(done2);
ok(!fail2);
});
test('Fail mis-ordered flag, sync', function () {
var dm = new openerp.web.DropMisordered(true),
done1 = false, done2 = false,
fail1 = false, fail2 = false;
var d1 = $.Deferred(), d2 = $.Deferred();
dm.add(d1).then(function () { done1 = true; },
function () { fail1 = true; });
dm.add(d2).then(function () { done2 = true; },
function () { fail2 = true; });
d2.resolve();
d1.resolve();
// d1 is failed
ok(!done1);
ok(fail1);
// d2 is resolved
ok(done2);
ok(!fail2);
});
asyncTest('Resolve all correctly ordered, sync', 1, function () {
var dm = new openerp.web.DropMisordered();
var d1 = $.Deferred(), d2 = $.Deferred(),
r1 = dm.add(d1), r2 = dm.add(d2);
setTimeout(function () { d1.resolve(); }, 100);
setTimeout(function () { d2.resolve(); }, 200);
$.when(r1, r2).done(function () {
start();
ok(true);
});
});
asyncTest("Don't resolve mis-ordered, sync", 4, function () {
var dm = new openerp.web.DropMisordered(),
done1 = false, done2 = false,
fail1 = false, fail2 = false;
var d1 = $.Deferred(), d2 = $.Deferred();
dm.add(d1).then(function () { done1 = true; },
function () { fail1 = true; });
dm.add(d2).then(function () { done2 = true; },
function () { fail2 = true; });
setTimeout(function () { d1.resolve(); }, 200);
setTimeout(function () { d2.resolve(); }, 100);
setTimeout(function () {
start();
// d1 is in limbo
ok(!done1);
ok(!fail1);
// d2 is resolved
ok(done2);
ok(!fail2);
}, 400);
});
asyncTest('Fail mis-ordered flag, sync', 4, function () {
var dm = new openerp.web.DropMisordered(true),
done1 = false, done2 = false,
fail1 = false, fail2 = false;
var d1 = $.Deferred(), d2 = $.Deferred();
dm.add(d1).then(function () { done1 = true; },
function () { fail1 = true; });
dm.add(d2).then(function () { done2 = true; },
function () { fail2 = true; });
setTimeout(function () { d1.resolve(); }, 200);
setTimeout(function () { d2.resolve(); }, 100);
setTimeout(function () {
start();
// d1 is failed
ok(!done1);
ok(fail1);
// d2 is resolved
ok(done2);
ok(!fail2);
}, 400);
});
});

View File

@ -26,10 +26,9 @@
<script src="/web/static/lib/py.js/lib/py.js"></script>
<script src="/web/static/lib/novajs/src/nova.js"></script>
<script src="/web/static/src/js/boot.js"></script>
<script src="/web/static/src/js/core.js"></script>
<script src="/web/static/src/js/corelib.js"></script>
<script src="/web/static/src/js/coresetup.js"></script>
<script src="/web/static/src/js/dates.js"></script>
<script src="/web/static/src/js/formats.js"></script>
<script src="/web/static/src/js/chrome.js"></script>
@ -52,6 +51,6 @@
<script type="text/javascript" src="/web/static/test/form.js"></script>
<script type="text/javascript" src="/web/static/test/list-utils.js"></script>
<script type="text/javascript" src="/web/static/test/formats.js"></script>
<script type="text/javascript" src="/web/static/test/onchange.js"></script>
<script type="text/javascript" src="/web/static/test/rpc.js"></script>
<script type="text/javascript" src="/web/static/test/evals.js"></script>
</html>

View File

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
import xmlrpclib
from ..common.openerplib.main import Connector
execute_map = {}
class TestConnector(Connector):
def db_list_lang(self):
return [('en_US', u'Test Language')]
def common_authenticate(self, db, login, password, environment):
return 87539319
def common_login(self, db, login, password):
return self.common_authenticate(db, login, password, {})
def object_execute_kw(self, db, uid, password, model, method, args, kwargs):
if model in execute_map and hasattr(execute_map[model], method):
return getattr(execute_map[model], method)(*args, **kwargs)
raise xmlrpclib.Fault({
'model': model,
'method': method,
'args': args,
'kwargs': kwargs
}, '')
def send(self, service_name, method, *args):
method_name = '%s_%s' % (service_name, method)
if hasattr(self, method_name):
return getattr(self, method_name)(*args)
raise xmlrpclib.Fault({
'service': service_name,
'method': method,
'args': args
}, '')

View File

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
from ..common import http, nonliterals
from ..controllers.main import Session
UID = 87539319
DB = 'test_db'
LOGIN = 'test_login'
PASSWORD = 'test_password'
CONTEXT = {'lang': 'en_US', 'tz': 'UTC', 'uid': UID}
def bind(session):
session.bind(DB, UID, LOGIN, PASSWORD)
session.context = CONTEXT
session.build_connection().set_login_info(DB, LOGIN, PASSWORD, UID)
class TestController(http.Controller):
_cp_path = '/tests'
@http.jsonrequest
def add_nonliterals(self, req, domains, contexts):
return {
'domains': [nonliterals.Domain(req.session, domain)
for domain in domains],
'contexts': [nonliterals.Context(req.session, context)
for context in contexts]
}
class TestSession(Session):
_cp_path = '/web/session'
def session_info(self, req):
if not req.session._uid:
bind(req.session)
return {
"session_id": req.session_id,
"uid": req.session._uid,
"context": CONTEXT,
"db": req.session._db,
"login": req.session._login,
"openerp_entreprise": False,
}

View File

@ -0,0 +1,41 @@
# Bosnian translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-06 17:33+0100\n"
"PO-Revision-Date: 2012-04-15 00:09+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bosnian <bs@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-16 04:50+0000\n"
"X-Generator: Launchpad (build 15099)\n"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:11
msgid "Calendar"
msgstr "Kalendar"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:466
#: addons/web_calendar/static/src/js/calendar.js:467
msgid "Responsible"
msgstr "Odgovoran"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:504
#: addons/web_calendar/static/src/js/calendar.js:505
msgid "Navigator"
msgstr "Navigator"
#. openerp-web
#: addons/web_calendar/static/src/xml/web_calendar.xml:5
#: addons/web_calendar/static/src/xml/web_calendar.xml:6
msgid "&nbsp;"
msgstr "&nbsp;"

View File

@ -0,0 +1,41 @@
# Spanish (Chile) translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-06 17:33+0100\n"
"PO-Revision-Date: 2012-04-14 15:13+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish (Chile) <es_CL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-15 04:48+0000\n"
"X-Generator: Launchpad (build 15070)\n"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:11
msgid "Calendar"
msgstr "Calendario"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:466
#: addons/web_calendar/static/src/js/calendar.js:467
msgid "Responsible"
msgstr "Responsable"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:504
#: addons/web_calendar/static/src/js/calendar.js:505
msgid "Navigator"
msgstr "Navegador"
#. openerp-web
#: addons/web_calendar/static/src/xml/web_calendar.xml:5
#: addons/web_calendar/static/src/xml/web_calendar.xml:6
msgid "&nbsp;"
msgstr "&nbsp;"

View File

@ -2,12 +2,12 @@
* OpenERP web_calendar
*---------------------------------------------------------*/
openerp.web_calendar = function(openerp) {
var _t = openerp.web._t,
_lt = openerp.web._lt;
var QWeb = openerp.web.qweb;
openerp.web.views.add('calendar', 'openerp.web_calendar.CalendarView');
openerp.web_calendar.CalendarView = openerp.web.View.extend({
openerp.web_calendar = function(instance) {
var _t = instance.web._t,
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
instance.web.views.add('calendar', 'instance.web_calendar.CalendarView');
instance.web_calendar.CalendarView = instance.web.View.extend({
display_name: _lt('Calendar'),
// Dhtmlx scheduler ?
init: function(parent, dataset, view_id, options) {
@ -22,7 +22,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
this.has_been_loaded = $.Deferred();
this.creating_event_id = null;
this.dataset_events = [];
this.form_dialog = new openerp.web_calendar.CalendarFormDialog(this, {
this.form_dialog = new instance.web_calendar.CalendarFormDialog(this, {
destroy_on_close: false,
width: '80%',
min_width: 850
@ -102,9 +102,9 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
this.init_scheduler();
if (this.options.sidebar) {
this.sidebar = new openerp.web_calendar.Sidebar(this);
this.has_been_loaded.pipe(this.sidebar.appendTo(this.$element));
if (! this.sidebar && this.options.$sidebar) {
this.sidebar = new instance.web_calendar.Sidebar(this);
this.has_been_loaded.pipe(this.sidebar.appendTo(this.options.$sidebar));
}
return this.has_been_loaded.resolve();
@ -158,7 +158,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
scheduler.setCurrentView(scheduler._date);
},
refresh_minical: function() {
if (this.options.sidebar) {
if (this.sidebar) {
scheduler.updateCalendar(this.sidebar.mini_calendar);
}
},
@ -207,23 +207,23 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
}
if (this.fields[this.date_start]['type'] == 'date') {
evt[this.date_start] = openerp.web.auto_str_to_date(evt[this.date_start]).set({hour: 9}).toString('yyyy-MM-dd HH:mm:ss');
evt[this.date_start] = instance.web.auto_str_to_date(evt[this.date_start]).set({hour: 9}).toString('yyyy-MM-dd HH:mm:ss');
}
if (this.date_stop && evt[this.date_stop] && this.fields[this.date_stop]['type'] == 'date') {
evt[this.date_stop] = openerp.web.auto_str_to_date(evt[this.date_stop]).set({hour: 17}).toString('yyyy-MM-dd HH:mm:ss');
evt[this.date_stop] = instance.web.auto_str_to_date(evt[this.date_stop]).set({hour: 17}).toString('yyyy-MM-dd HH:mm:ss');
}
res_events.push(this.convert_event(evt));
}
scheduler.parse(res_events, 'json');
this.refresh_scheduler();
this.refresh_minical();
if (!no_filter_reload && this.options.sidebar) {
if (!no_filter_reload && this.sidebar) {
this.sidebar.filter.on_events_loaded(sidebar_items);
}
},
convert_event: function(evt) {
var date_start = openerp.web.str_to_datetime(evt[this.date_start]),
date_stop = this.date_stop ? openerp.web.str_to_datetime(evt[this.date_stop]) : null,
var date_start = instance.web.str_to_datetime(evt[this.date_start]),
date_stop = this.date_stop ? instance.web.str_to_datetime(evt[this.date_stop]) : null,
date_delay = evt[this.date_delay] || 1.0,
res_text = '',
res_description = [];
@ -289,10 +289,9 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
var field_name = self[field];
if (field_name && form.fields[field_name]) {
var ffield = form.fields[field_name];
ffield.reset();
ffield._dirty_flag = false;
$.when(ffield.set_value(data[field_name])).then(function() {
ffield.validate();
ffield.dirty = true;
ffield._dirty_flag = true;
form.do_onchange(ffield);
});
}
@ -354,9 +353,9 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
var data = {
name: event_obj.text
};
data[this.date_start] = openerp.web.datetime_to_str(event_obj.start_date);
data[this.date_start] = instance.web.datetime_to_str(event_obj.start_date);
if (this.date_stop) {
data[this.date_stop] = openerp.web.datetime_to_str(event_obj.end_date);
data[this.date_stop] = instance.web.datetime_to_str(event_obj.end_date);
}
if (this.date_delay) {
var diff_seconds = Math.round((event_obj.end_date.getTime() - event_obj.start_date.getTime()) / 1000);
@ -383,7 +382,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
});
},
get_range_domain: function() {
var format = openerp.web.date_to_str,
var format = instance.web.date_to_str,
domain = this.last_search[0].slice(0);
domain.unshift([this.date_start, '>=', format(this.range_start.clone().addDays(-6))]);
domain.unshift([this.date_start, '<=', format(this.range_stop.clone().addDays(6))]);
@ -402,7 +401,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
}
});
openerp.web_calendar.CalendarFormDialog = openerp.web.Dialog.extend({
instance.web_calendar.CalendarFormDialog = instance.web.Dialog.extend({
init: function(view, options, view_id, dataset) {
this._super(view, options);
this.dataset = dataset;
@ -412,8 +411,7 @@ openerp.web_calendar.CalendarFormDialog = openerp.web.Dialog.extend({
start: function() {
var self = this;
this._super();
this.form = new openerp.web.FormView(this, this.dataset, this.view_id, {
sidebar: false,
this.form = new instance.web.FormView(this, this.dataset, this.view_id, {
pager: false
});
this.form.appendTo(this.$element);
@ -440,7 +438,7 @@ openerp.web_calendar.CalendarFormDialog = openerp.web.Dialog.extend({
}
});
openerp.web_calendar.Sidebar = openerp.web.Widget.extend({
instance.web_calendar.Sidebar = instance.web.Widget.extend({
template: 'CalendarView.sidebar',
start: function() {
this._super();
@ -452,11 +450,11 @@ openerp.web_calendar.Sidebar = openerp.web.Widget.extend({
scheduler.setCurrentView(date, 'day');
}
});
this.filter = new openerp.web_calendar.SidebarFilter(this, this.getParent());
this.filter = new instance.web_calendar.SidebarFilter(this, this.getParent());
this.filter.appendTo(this.$element.find('.oe_calendar_filter'));
}
});
openerp.web_calendar.SidebarFilter = openerp.web.Widget.extend({
instance.web_calendar.SidebarFilter = instance.web.Widget.extend({
init: function(parent, view) {
this._super(parent);
this.view = view;

View File

@ -0,0 +1,111 @@
# Bosnian translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-14 15:27+0100\n"
"PO-Revision-Date: 2012-04-15 00:11+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bosnian <bs@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-16 04:50+0000\n"
"X-Generator: Launchpad (build 15099)\n"
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:63
msgid "Edit Layout"
msgstr ""
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:109
msgid "Are you sure you want to remove this item ?"
msgstr "Jeste li sigurni da želite ukloniti predmet?"
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:316
msgid "Uncategorized"
msgstr "Nekategorisano"
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:324
#, python-format
msgid "Execute task \"%s\""
msgstr "Izvrši zadatak \"%s\""
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:325
msgid "Mark this task as done"
msgstr "Označi zadatak kao izvršen"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:4
msgid "Reset Layout.."
msgstr ""
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:6
msgid "Reset"
msgstr "Resetuj"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:8
msgid "Change Layout.."
msgstr ""
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:10
msgid "Change Layout"
msgstr "Izmijeni izgled"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:27
msgid "&nbsp;"
msgstr "&nbsp;"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:28
msgid "Create"
msgstr "Napravi"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:39
msgid "Choose dashboard layout"
msgstr ""
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:62
msgid "progress:"
msgstr "Napredak:"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:67
msgid ""
"Click on the functionalites listed below to launch them and configure your "
"system"
msgstr ""
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:110
msgid "Welcome to OpenERP"
msgstr "Dobro došli na OpenERP"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:118
msgid "Remember to bookmark"
msgstr ""
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:119
msgid "This url"
msgstr "Ovaj url"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:121
msgid "Your login:"
msgstr "Vaš login:"

View File

@ -0,0 +1,113 @@
# Spanish (Chile) translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-14 15:27+0100\n"
"PO-Revision-Date: 2012-04-14 15:21+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish (Chile) <es_CL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-15 04:48+0000\n"
"X-Generator: Launchpad (build 15070)\n"
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:63
msgid "Edit Layout"
msgstr "Modificar diseño"
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:109
msgid "Are you sure you want to remove this item ?"
msgstr "¿Esta seguro que quiere eliminar este item?"
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:316
msgid "Uncategorized"
msgstr "Sin categoría"
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:324
#, python-format
msgid "Execute task \"%s\""
msgstr "Ejecutar tarea \"%s\""
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:325
msgid "Mark this task as done"
msgstr "Marcar esta tarea como terminada"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:4
msgid "Reset Layout.."
msgstr "Reiniciar disposición"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:6
msgid "Reset"
msgstr "Reiniciar"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:8
msgid "Change Layout.."
msgstr "Cambiar Disposición.."
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:10
msgid "Change Layout"
msgstr "Cambiar disposición"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:27
msgid "&nbsp;"
msgstr "&nbsp;"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:28
msgid "Create"
msgstr "Crear"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:39
msgid "Choose dashboard layout"
msgstr "Elegir disposición del tablero"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:62
msgid "progress:"
msgstr "progreso:"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:67
msgid ""
"Click on the functionalites listed below to launch them and configure your "
"system"
msgstr ""
"Haga click en las funcionalidades listadas debajo para lanzarlas y "
"configurar su sistema"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:110
msgid "Welcome to OpenERP"
msgstr "Bienvenido a OpenERP"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:118
msgid "Remember to bookmark"
msgstr "Recordar en marcadores"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:119
msgid "This url"
msgstr "Esta url"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:121
msgid "Your login:"
msgstr "Su inicio de sesión:"

View File

@ -0,0 +1,112 @@
# Swedish translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-14 15:27+0100\n"
"PO-Revision-Date: 2012-04-17 09:21+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-18 04:57+0000\n"
"X-Generator: Launchpad (build 15108)\n"
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:63
msgid "Edit Layout"
msgstr "Ändra layout"
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:109
msgid "Are you sure you want to remove this item ?"
msgstr "Är du säker på att du vill radera?"
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:316
msgid "Uncategorized"
msgstr "Okategoriserad"
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:324
#, python-format
msgid "Execute task \"%s\""
msgstr "Utför åtgärd \"%s\""
#. openerp-web
#: addons/web_dashboard/static/src/js/dashboard.js:325
msgid "Mark this task as done"
msgstr "Markera denna uppgift som färdig"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:4
msgid "Reset Layout.."
msgstr "Återställ layouten"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:6
msgid "Reset"
msgstr "Nollställ"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:8
msgid "Change Layout.."
msgstr "Ändra layout..."
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:10
msgid "Change Layout"
msgstr "Ändra layout"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:27
msgid "&nbsp;"
msgstr ""
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:28
msgid "Create"
msgstr "Skapa"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:39
msgid "Choose dashboard layout"
msgstr "Välj infopanellayout"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:62
msgid "progress:"
msgstr "framsteg:"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:67
msgid ""
"Click on the functionalites listed below to launch them and configure your "
"system"
msgstr ""
"Välj bland funktionerna nedan för att starta och konfigurera ditt system"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:110
msgid "Welcome to OpenERP"
msgstr "Välkommen till OpenERP"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:118
msgid "Remember to bookmark"
msgstr "Kom ihåg att spara ett bokmärke till"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:119
msgid "This url"
msgstr "denna url"
#. openerp-web
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:121
msgid "Your login:"
msgstr "Din inloggning:"

View File

@ -1,13 +1,13 @@
openerp.web_dashboard = function(openerp) {
var QWeb = openerp.web.qweb,
_t = openerp.web._t;
openerp.web_dashboard = function(instance) {
var QWeb = instance.web.qweb,
_t = instance.web._t;
if (!openerp.web_dashboard) {
if (!instance.web_dashboard) {
/** @namespace */
openerp.web_dashboard = {};
instance.web_dashboard = {};
}
openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
instance.web.form.DashBoard = instance.web.form.Widget.extend({
init: function(view, node) {
this._super(view, node);
this.form_template = 'DashBoard';
@ -56,7 +56,7 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
var qdict = {
current_layout : this.$element.find('.oe-dashboard').attr('data-layout')
};
var $dialog = openerp.web.dialog($('<div>'), {
var $dialog = instance.web.dialog($('<div>'), {
modal: true,
title: _t("Edit Layout"),
width: 'auto',
@ -188,7 +188,7 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
selectable: false
}
};
var am = new openerp.web.ActionManager(this),
var am = new instance.web.ActionManager(this),
// FIXME: ideally the dashboard view shall be refactored like kanban.
$action = $('#' + this.view.element_id + '_action_' + index);
$action.parent().data('action_attrs', action_attrs);
@ -249,7 +249,7 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
action_manager.do_action(view_manager.action);
}
});
openerp.web.form.DashBoardLegacy = openerp.web.form.DashBoard.extend({
instance.web.form.DashBoardLegacy = instance.web.form.DashBoard.extend({
renderElement: function() {
if (this.node.tag == 'hpaned') {
this.node.attrs.style = '2-1';
@ -273,105 +273,24 @@ openerp.web.form.DashBoardLegacy = openerp.web.form.DashBoard.extend({
}
});
openerp.web.form.tags.add('hpaned', 'openerp.web.form.DashBoardLegacy');
openerp.web.form.tags.add('vpaned', 'openerp.web.form.DashBoardLegacy');
openerp.web.form.tags.add('board', 'openerp.web.form.DashBoard');
/*
* ConfigOverview
* This client action designed to be used as a dashboard widget display
* ir.actions.todo in a fancy way
*/
openerp.web.client_actions.add( 'board.config.overview', 'openerp.web_dashboard.ConfigOverview');
openerp.web_dashboard.ConfigOverview = openerp.web.View.extend({
template: 'ConfigOverview',
init: function (parent) {
this._super(parent);
this.user = _.extend(new openerp.web.DataSet(this, 'res.users'), {
index: 0,
ids: [this.session.uid]
});
this.dataset = new openerp.web.DataSetSearch(this, 'ir.actions.todo');
},
start: function () {
var self = this;
return this.user.read_index(['groups_id']).pipe(function(record) {
var todos_filter = [
['type', '!=', 'automatic'],
'|', ['groups_id', '=', false],
['groups_id', 'in', record['groups_id']]];
return $.when(
self.dataset.read_slice(
['state', 'action_id', 'category_id'],
{ domain: todos_filter }
),
self.dataset.call('progress').pipe(
function (arg) { return arg; }, null))
}, null).then(this.on_records_loaded);
},
on_records_loaded: function (records, progress) {
var grouped_todos = _(records).chain()
.map(function (record) {
return {
id: record.id,
name: record.action_id[1],
done: record.state !== 'open',
to_do: record.state === 'open',
category: record['category_id'][1] || _t("Uncategorized")
}
})
.groupBy(function (record) {return record.category})
.value();
this.$element.html(QWeb.render('ConfigOverview.content', {
completion: 100 * progress.done / progress.total,
groups: grouped_todos,
task_title: _t("Execute task \"%s\""),
checkbox_title: _t("Mark this task as done"),
_: _
}));
var $progress = this.$element.find('div.oe-config-progress-bar');
$progress.progressbar({value: $progress.data('completion')});
var self = this;
this.$element.find('dl')
.delegate('input', 'click', function (e) {
// switch todo status
e.stopImmediatePropagation();
var new_state = this.checked ? 'done' : 'open',
todo_id = parseInt($(this).val(), 10);
self.dataset.write(todo_id, {state: new_state}, {}, function () {
self.start();
});
})
.delegate('li:not(.oe-done)', 'click', function () {
self.getParent().getParent().getParent().do_execute_action({
type: 'object',
name: 'action_launch'
}, self.dataset,
$(this).data('id'), function () {
// after action popup closed, refresh configuration
// thingie
self.start();
});
});
}
});
instance.web.form.tags.add('hpaned', 'instance.web.form.DashBoardLegacy');
instance.web.form.tags.add('vpaned', 'instance.web.form.DashBoardLegacy');
instance.web.form.tags.add('board', 'instance.web.form.DashBoard');
/*
* Widgets
* This client action designed to be used as a dashboard widget display
* the html content of a res_widget given as argument
*/
openerp.web.client_actions.add( 'board.home.widgets', 'openerp.web_dashboard.Widget');
openerp.web_dashboard.Widget = openerp.web.View.extend(/** @lends openerp.web_dashboard.Widgets# */{
instance.web.client_actions.add( 'board.home.widgets', 'instance.web_dashboard.Widget');
instance.web_dashboard.Widget = instance.web.View.extend(/** @lends instance.web_dashboard.Widgets# */{
template: 'HomeWidget',
/**
* Initializes a "HomeWidget" client widget: handles the display of a given
* res.widget objects in an OpenERP view (mainly a dashboard).
*
* @constructs openerp.web_dashboard.Widget
* @extends openerp.web.View
* @constructs instance.web_dashboard.Widget
* @extends instance.web.View
*
* @param {Object} parent
* @param {Object} options
@ -382,7 +301,7 @@ openerp.web_dashboard.Widget = openerp.web.View.extend(/** @lends openerp.web_da
this.widget_id = options.widget_id;
},
start: function () {
var ds = new openerp.web.DataSet(this, 'res.widget');
var ds = new instance.web.DataSet(this, 'res.widget');
return ds.read_ids([this.widget_id], ['title']).then(this.on_widget_loaded);
},
on_widget_loaded: function (widgets) {
@ -397,79 +316,5 @@ openerp.web_dashboard.Widget = openerp.web.View.extend(/** @lends openerp.web_da
}
});
/*
* HomeTiles this client action display either the list of application to
* install (if none is installed yet) or a list of root menu items
*/
openerp.web.client_actions.add('default_home', 'session.web_dashboard.ApplicationTiles');
openerp.web_dashboard.ApplicationTiles = openerp.web.OldWidget.extend({
template: 'web_dashboard.ApplicationTiles',
init: function(parent) {
this._super(parent);
},
start: function() {
var self = this;
var domain = [['application','=',true], ['state','=','installed'], ['name', '!=', 'base']];
var ds = new openerp.web.DataSetSearch(this, 'ir.module.module',{},domain);
ds.read_slice(['id']).then(function(result) {
if(result.length) {
self.on_installed_database();
} else {
self.on_uninstalled_database();
}
});
},
on_uninstalled_database: function() {
installer = new openerp.web_dashboard.ApplicationInstaller(this);
installer.appendTo(this.$element);
},
on_installed_database: function() {
var self = this;
self.rpc('/web/menu/get_user_roots', {}).then(function (menu_ids) {
var menuds = new openerp.web.DataSet(this, 'ir.ui.menu',{})
.read_ids(menu_ids, ['name', 'web_icon_data', 'web_icon_hover_data', 'module']).then(function (applications) {
var tiles = QWeb.render('ApplicationTiles.content', {applications: applications});
$(tiles).appendTo(self.$element).find('.oe_install-module-link').click(function () {
openerp.webclient.menu.on_menu_click(null, $(this).data('menu'))
});
});
});
}
});
/**
* ApplicationInstaller
* This client action display a list of applications to install.
*/
openerp.web.client_actions.add( 'board.application.installer', 'openerp.web_dashboard.ApplicationInstaller');
openerp.web_dashboard.ApplicationInstaller = openerp.web.OldWidget.extend({
template: 'web_dashboard.ApplicationInstaller',
start: function () {
// TODO menu hide
var r = this._super();
this.action_manager = new openerp.web.ActionManager(this);
this.action_manager.appendTo(this.$element.find('.oe_installer'));
this.action_manager.do_action({
type: 'ir.actions.act_window',
res_model: 'ir.module.module',
domain: [['application','=',true]],
views: [[false, 'kanban']],
flags: {
display_title:false,
search_view: false,
views_switcher: false,
action_buttons: false,
sidebar: false,
pager: false
}
});
return r;
},
destroy: function() {
this.action_manager.destroy();
return this._super();
}
});
};

View File

@ -56,71 +56,9 @@
</board>
</form>
</t>
<div t-name="ConfigOverview" class="oe-dashboard-config-overview"/>
<t t-name="ConfigOverview.content">
<div class="oe-config-progress">
<h6 class="oe-config-progress-title">
progress: <t t-esc="Math.round(completion)"/>%
</h6>
<div class="oe-config-progress-bar" t-att-data-completion="completion"/>
</div>
<p class="oe-config-tip">Click on the functionalites listed below to launch them and configure your system</p>
<dl>
<t t-foreach="groups" t-as="category">
<dt><t t-esc="category"/></dt>
<dd><ul>
<li t-foreach="category_value" t-as="todo"
t-att-class="todo.done ? 'oe-done' : undefined"
t-att-data-id="todo.id"
t-att-title="!todo.done ? _.str.sprintf(task_title, todo.name) : undefined">
<span style="text-decoration: underline;"><t t-esc="todo.name"/></span>
<input type="checkbox" t-att-value="todo.id"
t-att-title="!todo.done ? checkbox_title : undefined"
t-att-checked="todo.done ? 'checked' : undefined"/>
</li>
</ul></dd>
</t>
</dl>
</t>
<div t-name="HomeWidget" class="oe-dashboard-home-widget"/>
<t t-name="HomeWidget.content">
<h3><t t-esc="widget.title"/></h3>
<iframe width="100%" frameborder="0" t-att-src="url"/>
</t>
<t t-name="ApplicationTiles.content">
<ul class="oe_app_tiles">
<t t-foreach="applications" t-as="application" >
<li>
<a href="#" class="oe_install-module-link" t-att-data-module="application.module" t-att-data-menu="application.id" >
<img t-if="application.web_icon_data" t-att-src="'data:image/png;base64,' + application.web_icon_data"
/><img t-if="application.web_icon_hover_data" class="hover" t-att-src="'data:image/png;base64,' + application.web_icon_hover_data"/>
<span><t t-esc="application.name"/></span>
</a>
</li>
</t>
</ul>
</t>
<t t-name="web_dashboard.ApplicationTiles">
<div>
<div class="oe_applications_tiles">
<h1 class="oe_welcome_message">Welcome to OpenERP</h1>
</div>
</div>
</t>
<div t-name="web_dashboard.ApplicationInstaller">
<div class="oe_initial_welcome_message">
<ul>
<li>Remember to bookmark
<a class="oe_welcome_url" t-att-href="widget.session.origin">This url</a>
</li>
<li>Your login: <t t-esc="widget.session.username"/></li>
</ul>
</div>
<div class="oe_installer" />
</div>
</template>

View File

@ -0,0 +1,57 @@
# Bosnian translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-06 17:33+0100\n"
"PO-Revision-Date: 2012-04-16 15:36+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bosnian <bs@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-17 05:24+0000\n"
"X-Generator: Launchpad (build 15099)\n"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:11
msgid "Diagram"
msgstr "Dijagram"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:208
#: addons/web_diagram/static/src/js/diagram.js:224
#: addons/web_diagram/static/src/js/diagram.js:257
msgid "Activity"
msgstr "Aktivnost"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:208
#: addons/web_diagram/static/src/js/diagram.js:289
#: addons/web_diagram/static/src/js/diagram.js:308
msgid "Transition"
msgstr "Prijelaz"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:214
#: addons/web_diagram/static/src/js/diagram.js:262
#: addons/web_diagram/static/src/js/diagram.js:314
msgid "Create:"
msgstr "Kreiraj"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:231
#: addons/web_diagram/static/src/js/diagram.js:232
#: addons/web_diagram/static/src/js/diagram.js:296
msgid "Open: "
msgstr "Otvori: "
#. openerp-web
#: addons/web_diagram/static/src/xml/base_diagram.xml:5
#: addons/web_diagram/static/src/xml/base_diagram.xml:6
msgid "New Node"
msgstr "Novi čvor"

View File

@ -0,0 +1,57 @@
# Spanish (Chile) translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-06 17:33+0100\n"
"PO-Revision-Date: 2012-04-14 15:15+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish (Chile) <es_CL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-15 04:48+0000\n"
"X-Generator: Launchpad (build 15070)\n"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:11
msgid "Diagram"
msgstr "Gráfico"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:208
#: addons/web_diagram/static/src/js/diagram.js:224
#: addons/web_diagram/static/src/js/diagram.js:257
msgid "Activity"
msgstr "Actividad"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:208
#: addons/web_diagram/static/src/js/diagram.js:289
#: addons/web_diagram/static/src/js/diagram.js:308
msgid "Transition"
msgstr "Transición"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:214
#: addons/web_diagram/static/src/js/diagram.js:262
#: addons/web_diagram/static/src/js/diagram.js:314
msgid "Create:"
msgstr "Crear:"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:231
#: addons/web_diagram/static/src/js/diagram.js:232
#: addons/web_diagram/static/src/js/diagram.js:296
msgid "Open: "
msgstr "Abrir: "
#. openerp-web
#: addons/web_diagram/static/src/xml/base_diagram.xml:5
#: addons/web_diagram/static/src/xml/base_diagram.xml:6
msgid "New Node"
msgstr "Nuevo nodo"

View File

@ -0,0 +1,57 @@
# Swedish translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-06 17:33+0100\n"
"PO-Revision-Date: 2012-04-17 13:23+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-18 04:57+0000\n"
"X-Generator: Launchpad (build 15108)\n"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:11
msgid "Diagram"
msgstr "Diagram"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:208
#: addons/web_diagram/static/src/js/diagram.js:224
#: addons/web_diagram/static/src/js/diagram.js:257
msgid "Activity"
msgstr "Aktivitet"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:208
#: addons/web_diagram/static/src/js/diagram.js:289
#: addons/web_diagram/static/src/js/diagram.js:308
msgid "Transition"
msgstr "Övergång"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:214
#: addons/web_diagram/static/src/js/diagram.js:262
#: addons/web_diagram/static/src/js/diagram.js:314
msgid "Create:"
msgstr "Skapa:"
#. openerp-web
#: addons/web_diagram/static/src/js/diagram.js:231
#: addons/web_diagram/static/src/js/diagram.js:232
#: addons/web_diagram/static/src/js/diagram.js:296
msgid "Open: "
msgstr "Öppna: "
#. openerp-web
#: addons/web_diagram/static/src/xml/base_diagram.xml:5
#: addons/web_diagram/static/src/xml/base_diagram.xml:6
msgid "New Node"
msgstr "Ny nod"

View File

@ -2,12 +2,12 @@
* OpenERP diagram library
*---------------------------------------------------------*/
openerp.web_diagram = function (openerp) {
var QWeb = openerp.web.qweb,
_t = openerp.web._t,
_lt = openerp.web._lt;
openerp.web.views.add('diagram', 'openerp.web.DiagramView');
openerp.web.DiagramView = openerp.web.View.extend({
openerp.web_diagram = function (instance) {
var QWeb = instance.web.qweb,
_t = instance.web._t,
_lt = instance.web._lt;
instance.web.views.add('diagram', 'instance.web.DiagramView');
instance.web.DiagramView = instance.web.View.extend({
display_name: _lt('Diagram'),
searchable: false,
init: function(parent, dataset, view_id, options) {
@ -194,7 +194,7 @@ openerp.web.DiagramView = openerp.web.View.extend({
if(!confirm(_t("Deleting this node cannot be undone.\nIt will also delete all connected transitions.\n\nAre you sure ?"))){
return $.Deferred().reject().promise();
}
return new openerp.web.DataSet(self,self.node).unlink([cutenode.id]);
return new instance.web.DataSet(self,self.node).unlink([cutenode.id]);
};
CuteEdge.double_click_callback = function(cuteedge){
self.edit_connector(cuteedge.id);
@ -212,7 +212,7 @@ openerp.web.DiagramView = openerp.web.View.extend({
if(!confirm(_t("Deleting this transition cannot be undone.\n\nAre you sure ?"))){
return $.Deferred().reject().promise();
}
return new openerp.web.DataSet(self,self.connector).unlink([cuteedge.id]);
return new instance.web.DataSet(self,self.connector).unlink([cuteedge.id]);
};
},
@ -221,7 +221,7 @@ openerp.web.DiagramView = openerp.web.View.extend({
edit_node: function(node_id){
var self = this;
var title = _t('Activity');
var pop = new openerp.web.form.FormOpenPopup(self);
var pop = new instance.web.form.FormOpenPopup(self);
pop.show_element(
self.node,
@ -254,7 +254,7 @@ openerp.web.DiagramView = openerp.web.View.extend({
add_node: function(){
var self = this;
var title = _t('Activity');
var pop = new openerp.web.form.SelectCreatePopup(self);
var pop = new instance.web.form.SelectCreatePopup(self);
pop.select_element(
self.node,
{
@ -286,7 +286,7 @@ openerp.web.DiagramView = openerp.web.View.extend({
edit_connector: function(connector_id){
var self = this;
var title = _t('Transition');
var pop = new openerp.web.form.FormOpenPopup(self);
var pop = new instance.web.form.FormOpenPopup(self);
pop.show_element(
self.connector,
parseInt(connector_id,10), //FIXME Isn't connector_id supposed to be an int ?
@ -305,7 +305,7 @@ openerp.web.DiagramView = openerp.web.View.extend({
add_connector: function(node_source_id, node_dest_id, dummy_cuteedge){
var self = this;
var title = _t('Transition');
var pop = new openerp.web.form.SelectCreatePopup(self);
var pop = new instance.web.form.SelectCreatePopup(self);
pop.select_element(
self.connector,

View File

@ -0,0 +1,28 @@
# Bengali translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-06 17:33+0100\n"
"PO-Revision-Date: 2012-04-12 14:53+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bengali <bn@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-13 05:38+0000\n"
"X-Generator: Launchpad (build 15070)\n"
#. openerp-web
#: addons/web_gantt/static/src/js/gantt.js:11
msgid "Gantt"
msgstr "জ্ঞান্ট"
#. openerp-web
#: addons/web_gantt/static/src/xml/web_gantt.xml:10
msgid "Create"
msgstr "তৈরি করুন"

View File

@ -0,0 +1,28 @@
# Bosnian translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-06 17:33+0100\n"
"PO-Revision-Date: 2012-04-16 15:37+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bosnian <bs@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-17 05:24+0000\n"
"X-Generator: Launchpad (build 15099)\n"
#. openerp-web
#: addons/web_gantt/static/src/js/gantt.js:11
msgid "Gantt"
msgstr "Gant"
#. openerp-web
#: addons/web_gantt/static/src/xml/web_gantt.xml:10
msgid "Create"
msgstr "Kreiraj"

View File

@ -0,0 +1,28 @@
# Spanish (Chile) translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-06 17:33+0100\n"
"PO-Revision-Date: 2012-04-14 15:15+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish (Chile) <es_CL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-15 04:48+0000\n"
"X-Generator: Launchpad (build 15070)\n"
#. openerp-web
#: addons/web_gantt/static/src/js/gantt.js:11
msgid "Gantt"
msgstr "Gantt"
#. openerp-web
#: addons/web_gantt/static/src/xml/web_gantt.xml:10
msgid "Create"
msgstr "Crear"

View File

@ -1,13 +1,13 @@
/*---------------------------------------------------------
* OpenERP web_gantt
*---------------------------------------------------------*/
openerp.web_gantt = function (openerp) {
var _t = openerp.web._t,
_lt = openerp.web._lt;
var QWeb = openerp.web.qweb;
openerp.web.views.add('gantt', 'openerp.web_gantt.GanttView');
openerp.web_gantt = function (instance) {
var _t = instance.web._t,
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
instance.web.views.add('gantt', 'instance.web_gantt.GanttView');
openerp.web_gantt.GanttView = openerp.web.View.extend({
instance.web_gantt.GanttView = instance.web.View.extend({
display_name: _lt('Gantt'),
template: "GanttView",
view_type: "gantt",
@ -122,7 +122,7 @@ openerp.web_gantt.GanttView = openerp.web.View.extend({
return memo === undefined || date > memo ? date : memo;
}, undefined);
var duration = (task_stop.getTime() - task_start.getTime()) / (1000 * 60 * 60);
var group_name = openerp.web.format_value(task.name, self.fields[group_bys[level]]);
var group_name = instance.web.format_value(task.name, self.fields[group_bys[level]]);
if (level == 0) {
var group = new GanttProjectInfo(_.uniqueId("gantt_project_"), group_name, task_start);
_.each(task_infos, function(el) {
@ -138,16 +138,16 @@ openerp.web_gantt.GanttView = openerp.web.View.extend({
}
} else {
var task_name = task.__name;
var task_start = openerp.web.auto_str_to_date(task[self.fields_view.arch.attrs.date_start]);
var task_start = instance.web.auto_str_to_date(task[self.fields_view.arch.attrs.date_start]);
if (!task_start)
return;
var task_stop;
if (self.fields_view.arch.attrs.date_stop) {
task_stop = openerp.web.auto_str_to_date(task[self.fields_view.arch.attrs.date_stop]);
task_stop = instance.web.auto_str_to_date(task[self.fields_view.arch.attrs.date_stop]);
if (!task_stop)
return;
} else { // we assume date_duration is defined
var tmp = openerp.web.format_value(task[self.fields_view.arch.attrs.date_delay],
var tmp = instance.web.format_value(task[self.fields_view.arch.attrs.date_delay],
self.fields[self.fields_view.arch.attrs.date_delay]);
if (!tmp)
return;
@ -197,10 +197,10 @@ openerp.web_gantt.GanttView = openerp.web.View.extend({
var end = start.clone().addMilliseconds(duration * 60 * 60 * 1000);
var data = {};
data[self.fields_view.arch.attrs.date_start] =
openerp.web.auto_date_to_str(start, self.fields[self.fields_view.arch.attrs.date_start].type);
instance.web.auto_date_to_str(start, self.fields[self.fields_view.arch.attrs.date_start].type);
if (self.fields_view.arch.attrs.date_stop) {
data[self.fields_view.arch.attrs.date_stop] =
openerp.web.auto_date_to_str(end, self.fields[self.fields_view.arch.attrs.date_stop].type);
instance.web.auto_date_to_str(end, self.fields[self.fields_view.arch.attrs.date_stop].type);
} else { // we assume date_duration is defined
data[self.fields_view.arch.attrs.date_delay] = duration;
}
@ -210,7 +210,7 @@ openerp.web_gantt.GanttView = openerp.web.View.extend({
},
on_task_display: function(task) {
var self = this;
var pop = new openerp.web.form.FormOpenPopup(self);
var pop = new instance.web.form.FormOpenPopup(self);
pop.on_write_completed.add_last(function() {
self.reload();
});
@ -223,7 +223,7 @@ openerp.web_gantt.GanttView = openerp.web.View.extend({
},
on_task_create: function() {
var self = this;
var pop = new openerp.web.form.SelectCreatePopup(this);
var pop = new instance.web.form.SelectCreatePopup(this);
pop.on_select_elements.add_last(function() {
self.reload();
});

View File

@ -0,0 +1,23 @@
# Bengali translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-06 17:33+0100\n"
"PO-Revision-Date: 2012-04-12 14:54+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bengali <bn@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-13 05:38+0000\n"
"X-Generator: Launchpad (build 15070)\n"
#. openerp-web
#: addons/web_graph/static/src/js/graph.js:19
msgid "Graph"
msgstr "লেখচিত্র"

View File

@ -0,0 +1,23 @@
# Bosnian translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-06 17:33+0100\n"
"PO-Revision-Date: 2012-04-16 15:37+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bosnian <bs@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-17 05:24+0000\n"
"X-Generator: Launchpad (build 15099)\n"
#. openerp-web
#: addons/web_graph/static/src/js/graph.js:19
msgid "Graph"
msgstr "Graf"

View File

@ -0,0 +1,23 @@
# Spanish (Chile) translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-06 17:33+0100\n"
"PO-Revision-Date: 2012-04-14 15:16+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish (Chile) <es_CL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-15 04:48+0000\n"
"X-Generator: Launchpad (build 15070)\n"
#. openerp-web
#: addons/web_graph/static/src/js/graph.js:19
msgid "Graph"
msgstr "Gráfico"

View File

@ -0,0 +1,23 @@
# Swedish translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-06 17:33+0100\n"
"PO-Revision-Date: 2012-04-17 13:21+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-18 04:57+0000\n"
"X-Generator: Launchpad (build 15108)\n"
#. openerp-web
#: addons/web_graph/static/src/js/graph.js:19
msgid "Graph"
msgstr "Diagram"

View File

@ -2,7 +2,7 @@
* OpenERP web_graph
*---------------------------------------------------------*/
openerp.web_graph = function (openerp) {
openerp.web_graph = function (instance) {
var COLOR_PALETTE = [
'#cc99ff', '#ccccff', '#48D1CC', '#CFD784', '#8B7B8B', '#75507b',
'#b0008c', '#ff0000', '#ff8e00', '#9000ff', '#0078ff', '#00ff00',
@ -12,10 +12,10 @@ var COLOR_PALETTE = [
'#ad7fa8', '#729fcf', '#8ae234', '#e9b96e', '#fce94f', '#f57900',
'#cc0000', '#d400a8'];
var QWeb = openerp.web.qweb,
_lt = openerp.web._lt;
openerp.web.views.add('graph', 'openerp.web_graph.GraphView');
openerp.web_graph.GraphView = openerp.web.View.extend({
var QWeb = instance.web.qweb,
_lt = instance.web._lt;
instance.web.views.add('graph', 'instance.web_graph.GraphView');
instance.web_graph.GraphView = instance.web.View.extend({
display_name: _lt('Graph'),
view_type: "graph",

View File

@ -2,9 +2,9 @@
* OpenERP base_hello (Example module)
*---------------------------------------------------------*/
openerp.web_hello = function(openerp) {
openerp.web_hello = function(instance) {
openerp.web.SearchView = openerp.web.SearchView.extend({
instance.web.SearchView = instance.web.SearchView.extend({
init:function() {
this._super.apply(this,arguments);
this.on_search.add(function(){console.log('hello');});
@ -13,7 +13,7 @@ openerp.web.SearchView = openerp.web.SearchView.extend({
// here you may tweak globals object, if any, and play with on_* or do_* callbacks on them
openerp.web.Login = openerp.web.Login.extend({
instance.web.Login = instance.web.Login.extend({
start: function() {
console.log('Hello there');
this._super.apply(this,arguments);

View File

@ -0,0 +1,55 @@
# Bengali translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-14 15:27+0100\n"
"PO-Revision-Date: 2012-04-12 15:08+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bengali <bn@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-13 05:38+0000\n"
"X-Generator: Launchpad (build 15070)\n"
#. openerp-web
#: addons/web_kanban/static/src/js/kanban.js:10
msgid "Kanban"
msgstr "কানবান"
#. openerp-web
#: addons/web_kanban/static/src/js/kanban.js:294
#: addons/web_kanban/static/src/js/kanban.js:295
msgid "Undefined"
msgstr "অনির্ণীত"
#. openerp-web
#: addons/web_kanban/static/src/js/kanban.js:469
#: addons/web_kanban/static/src/js/kanban.js:470
msgid "Are you sure you want to delete this record ?"
msgstr "আপনি কি নিশ্চিত যে আপনি এই তথ্য মুছে ফেলতে চান?"
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:5
msgid "Create"
msgstr "তৈরি করুন"
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:41
msgid "Show more... ("
msgstr "আরও দেখান...("
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:41
msgid "remaining)"
msgstr "অবশিষ্ট)"
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:59
msgid "</tr><tr>"
msgstr "</tr><tr>"

View File

@ -0,0 +1,55 @@
# Bosnian translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-14 15:27+0100\n"
"PO-Revision-Date: 2012-04-16 15:39+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bosnian <bs@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-17 05:24+0000\n"
"X-Generator: Launchpad (build 15099)\n"
#. openerp-web
#: addons/web_kanban/static/src/js/kanban.js:10
msgid "Kanban"
msgstr ""
#. openerp-web
#: addons/web_kanban/static/src/js/kanban.js:294
#: addons/web_kanban/static/src/js/kanban.js:295
msgid "Undefined"
msgstr "Nedefinisano"
#. openerp-web
#: addons/web_kanban/static/src/js/kanban.js:469
#: addons/web_kanban/static/src/js/kanban.js:470
msgid "Are you sure you want to delete this record ?"
msgstr "Jeste li sigurni da želite izbrisati zapis?"
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:5
msgid "Create"
msgstr "Kreiraj"
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:41
msgid "Show more... ("
msgstr "Prikaži više"
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:41
msgid "remaining)"
msgstr "Preostalo"
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:59
msgid "</tr><tr>"
msgstr "</tr><tr>"

View File

@ -0,0 +1,55 @@
# Spanish (Chile) translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-14 15:27+0100\n"
"PO-Revision-Date: 2012-04-14 15:16+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish (Chile) <es_CL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-15 04:48+0000\n"
"X-Generator: Launchpad (build 15070)\n"
#. openerp-web
#: addons/web_kanban/static/src/js/kanban.js:10
msgid "Kanban"
msgstr "Kanban"
#. openerp-web
#: addons/web_kanban/static/src/js/kanban.js:294
#: addons/web_kanban/static/src/js/kanban.js:295
msgid "Undefined"
msgstr "Sin definir"
#. openerp-web
#: addons/web_kanban/static/src/js/kanban.js:469
#: addons/web_kanban/static/src/js/kanban.js:470
msgid "Are you sure you want to delete this record ?"
msgstr "¿Está seguro que quiere eliminar este registro?"
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:5
msgid "Create"
msgstr "Crear"
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:41
msgid "Show more... ("
msgstr "Mostrar más... ("
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:41
msgid "remaining)"
msgstr "restante)"
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:59
msgid "</tr><tr>"
msgstr "</tr><tr>"

View File

@ -0,0 +1,55 @@
# Swedish translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-14 15:27+0100\n"
"PO-Revision-Date: 2012-04-17 12:50+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-18 04:57+0000\n"
"X-Generator: Launchpad (build 15108)\n"
#. openerp-web
#: addons/web_kanban/static/src/js/kanban.js:10
msgid "Kanban"
msgstr "Kanban"
#. openerp-web
#: addons/web_kanban/static/src/js/kanban.js:294
#: addons/web_kanban/static/src/js/kanban.js:295
msgid "Undefined"
msgstr "Odefinierad"
#. openerp-web
#: addons/web_kanban/static/src/js/kanban.js:469
#: addons/web_kanban/static/src/js/kanban.js:470
msgid "Are you sure you want to delete this record ?"
msgstr "Är du säker på att du vill radera denna post?"
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:5
msgid "Create"
msgstr "Skapa"
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:41
msgid "Show more... ("
msgstr "Visa mer... ("
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:41
msgid "remaining)"
msgstr "återstående)"
#. openerp-web
#: addons/web_kanban/static/src/xml/web_kanban.xml:59
msgid "</tr><tr>"
msgstr "</tr><tr>"

View File

@ -1,11 +1,11 @@
openerp.web_kanban = function (openerp) {
openerp.web_kanban = function (instance) {
var _t = openerp.web._t,
_lt = openerp.web._lt;
var QWeb = openerp.web.qweb;
openerp.web.views.add('kanban', 'openerp.web_kanban.KanbanView');
var _t = instance.web._t,
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
instance.web.views.add('kanban', 'instance.web_kanban.KanbanView');
openerp.web_kanban.KanbanView = openerp.web.View.extend({
instance.web_kanban.KanbanView = instance.web.View.extend({
template: "KanbanView",
display_name: _lt('Kanban'),
default_nr_columns: 3,
@ -23,12 +23,12 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
records : {}
};
this.groups = [];
this.form_dialog = new openerp.web.form.FormDialog(this, {}, this.options.action_views_ids.form, dataset).start();
this.form_dialog = new instance.web.form.FormDialog(this, {}, this.options.action_views_ids.form, dataset).start();
this.form_dialog.on_form_dialog_saved.add_last(this.do_reload);
this.aggregates = {};
this.group_operators = ['avg', 'max', 'min', 'sum', 'count'];
this.qweb = new QWeb2.Engine();
this.qweb.debug = openerp.connection.debug;
this.qweb.debug = instance.connection.debug;
this.qweb.default_dict = _.clone(QWeb.default_dict);
this.has_been_loaded = $.Deferred();
this.search_domain = this.search_context = this.search_group_by = null;
@ -57,7 +57,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
var child = this.fields_view.arch.children[i];
if (child.tag === "templates") {
this.transform_qweb_template(child);
this.qweb.add_template(openerp.web.json_node_to_xml(child));
this.qweb.add_template(instance.web.json_node_to_xml(child));
break;
} else if (child.tag === 'field') {
this.extract_aggregates(child);
@ -109,7 +109,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
node.children = [{
tag: 'img',
attrs: {
src: openerp.connection.prefix + '/web/static/src/img/icons/' + node.attrs['data-icon'] + '.png',
src: instance.connection.prefix + '/web/static/src/img/icons/' + node.attrs['data-icon'] + '.png',
width: '16',
height: '16'
}
@ -141,7 +141,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
this.search_group_by = group_by;
$.when(this.has_been_loaded).then(function() {
self.group_by = group_by.length ? group_by[0] : self.fields_view.arch.attrs.default_group_by;
self.datagroup = new openerp.web.DataGroup(self, self.dataset.model, domain, context, self.group_by ? [self.group_by] : []);
self.datagroup = new instance.web.DataGroup(self, self.dataset.model, domain, context, self.group_by ? [self.group_by] : []);
self.datagroup.list(self.fields_keys, self.do_process_groups, self.do_process_dataset);
});
},
@ -154,10 +154,10 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
var remaining = groups.length - 1,
groups_array = [];
_.each(groups, function (group, index) {
var dataset = new openerp.web.DataSetSearch(self, self.dataset.model, group.context, group.domain);
var dataset = new instance.web.DataSetSearch(self, self.dataset.model, group.context, group.domain);
dataset.read_slice(self.fields_keys.concat(['__last_update']), { 'limit': self.limit }).then(function(records) {
self.dataset.ids.push.apply(self.dataset.ids, dataset.ids);
groups_array[index] = new openerp.web_kanban.KanbanGroup(self, records, group, dataset);
groups_array[index] = new instance.web_kanban.KanbanGroup(self, records, group, dataset);
if (!remaining--) {
self.dataset.index = self.dataset.size() ? 0 : null;
def.pipe(self.do_add_groups(groups_array));
@ -175,7 +175,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
var def = $.Deferred();
self.do_clear_groups();
self.dataset.read_slice(self.fields_keys.concat(['__last_update']), { 'limit': self.limit }).then(function(records) {
var kgroup = new openerp.web_kanban.KanbanGroup(self, records, null, self.dataset);
var kgroup = new instance.web_kanban.KanbanGroup(self, records, null, self.dataset);
self.do_add_groups([kgroup]).then(function() {
def.resolve();
});
@ -293,7 +293,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
},
});
openerp.web_kanban.KanbanGroup = openerp.web.OldWidget.extend({
instance.web_kanban.KanbanGroup = instance.web.OldWidget.extend({
template: 'KanbanView.group_header',
init: function (parent, records, group, dataset) {
var self = this;
@ -315,7 +315,7 @@ openerp.web_kanban.KanbanGroup = openerp.web.OldWidget.extend({
var field = this.view.fields_view.fields[this.view.group_by];
if (field) {
try {
this.title = openerp.web.format_value(group.value, field, false);
this.title = instance.web.format_value(group.value, field, false);
} catch(e) {}
}
_.each(this.view.aggregates, function(value, key) {
@ -376,7 +376,7 @@ openerp.web_kanban.KanbanGroup = openerp.web.OldWidget.extend({
do_add_records: function(records) {
var self = this;
_.each(records, function(record) {
var rec = new openerp.web_kanban.KanbanRecord(self, record);
var rec = new instance.web_kanban.KanbanRecord(self, record);
rec.insertBefore(self.$records.find('.oe_kanban_show_more'));
self.records.push(rec);
});
@ -404,7 +404,7 @@ openerp.web_kanban.KanbanGroup = openerp.web.OldWidget.extend({
}
});
openerp.web_kanban.KanbanRecord = openerp.web.OldWidget.extend({
instance.web_kanban.KanbanRecord = instance.web.OldWidget.extend({
template: 'KanbanView.record',
init: function (parent, record) {
this._super(parent);
@ -434,11 +434,11 @@ openerp.web_kanban.KanbanRecord = openerp.web.OldWidget.extend({
_.each(record, function(value, name) {
var r = _.clone(self.view.fields_view.fields[name] || {});
if ((r.type === 'date' || r.type === 'datetime') && value) {
r.raw_value = openerp.web.auto_str_to_date(value);
r.raw_value = instance.web.auto_str_to_date(value);
} else {
r.raw_value = value;
}
r.value = openerp.web.format_value(value, r);
r.value = instance.web.format_value(value, r);
new_record[name] = r;
});
return new_record;
@ -584,9 +584,9 @@ openerp.web_kanban.KanbanRecord = openerp.web.OldWidget.extend({
},
kanban_image: function(model, field, id) {
id = id || '';
var url = openerp.connection.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id;
var url = instance.connection.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id;
if (this.record.__last_update && this.record.__last_update.raw_value) {
var time = openerp.web.str_to_datetime(this.record.__last_update.raw_value).getTime();
var time = instance.web.str_to_datetime(this.record.__last_update.raw_value).getTime();
url += '&t=' + time;
}
return url;

View File

@ -8,59 +8,59 @@ msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-07 10:13+0100\n"
"PO-Revision-Date: 2011-11-24 12:56+0000\n"
"Last-Translator: nasir khan saikat <nasir8891@gmail.com>\n"
"PO-Revision-Date: 2012-04-14 22:49+0000\n"
"Last-Translator: Kazi Shahnoor Ashraf <kazidxb@gmail.com>\n"
"Language-Team: Bengali <bn@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-02-08 06:39+0000\n"
"X-Generator: Launchpad (build 14747)\n"
"X-Launchpad-Export-Date: 2012-04-16 04:50+0000\n"
"X-Generator: Launchpad (build 15099)\n"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:17
msgid "OpenERP"
msgstr ""
msgstr "ওপেন-ই-আর-পি"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:22
msgid "Database:"
msgstr "ডেটাবেস:"
msgstr "উপাত্তুৎস"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:30
msgid "Login:"
msgstr "লগইন:"
msgstr "প্রবেশ করুন:"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:32
msgid "Password:"
msgstr "পাসওয়ার্ড:"
msgstr "শব্দচাবি:"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:34
msgid "Login"
msgstr "লগইন"
msgstr "প্রবেশ করুন"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:36
msgid "Bad username or password"
msgstr ""
msgstr "ব্যবহারকারীর নাম অথবা পাসওয়ার্ড এ ভূল আছে"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:42
msgid "Powered by openerp.com"
msgstr ""
msgstr "openerp.com এর কর্তৃত্বে"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:49
msgid "Home"
msgstr ""
msgstr "ঘর"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:57
msgid "Favourite"
msgstr ""
msgstr "প্রিয়"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:58
@ -75,32 +75,32 @@ msgstr "লগআউট"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:132
msgid "There are no records to show."
msgstr ""
msgstr "তথ্য প্রদর্শনের জন্য কিছু নাই"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:183
msgid "Open this resource"
msgstr ""
msgstr "এই তথ্যসম্পদ খুলুন"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:223
#: addons/web_mobile/static/src/xml/web_mobile.xml:226
msgid "Percent of tasks closed according to total of tasks to do..."
msgstr ""
msgstr "সর্বমোট করনীয় কাজের শতাংশ কাজ বন্ধ হয়েছে"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:264
#: addons/web_mobile/static/src/xml/web_mobile.xml:268
msgid "On"
msgstr ""
msgstr "চালু"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:265
#: addons/web_mobile/static/src/xml/web_mobile.xml:269
msgid "Off"
msgstr ""
msgstr "বন্ধ"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:294
msgid "Form View"
msgstr ""
msgstr "গাঠনিক দৃশ্য"

View File

@ -0,0 +1,108 @@
# Spanish (Chile) translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-07 10:13+0100\n"
"PO-Revision-Date: 2012-04-14 15:07+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish (Chile) <es_CL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-15 04:48+0000\n"
"X-Generator: Launchpad (build 15070)\n"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:17
msgid "OpenERP"
msgstr "OpenERP"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:22
msgid "Database:"
msgstr "Base de datos:"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:30
msgid "Login:"
msgstr "Inicio de Sesión:"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:32
msgid "Password:"
msgstr "Contraseña:"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:34
msgid "Login"
msgstr "Inicio de sesión"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:36
msgid "Bad username or password"
msgstr "Nombre de usuario o contraseña incorrectos"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:42
msgid "Powered by openerp.com"
msgstr "Desarrollado por openerp.com"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:49
msgid "Home"
msgstr "Inicio"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:57
msgid "Favourite"
msgstr "Favorito"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:58
msgid "Preference"
msgstr "Preferencias"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:123
msgid "Logout"
msgstr "Cerrar sesión"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:132
msgid "There are no records to show."
msgstr "No hay registros para mostrar."
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:183
msgid "Open this resource"
msgstr "Abrir este recurso"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:223
#: addons/web_mobile/static/src/xml/web_mobile.xml:226
msgid "Percent of tasks closed according to total of tasks to do..."
msgstr ""
"Porcentaje de la tarea realizado de acuerdo al total de la tarea a "
"realizar..."
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:264
#: addons/web_mobile/static/src/xml/web_mobile.xml:268
msgid "On"
msgstr "Activo"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:265
#: addons/web_mobile/static/src/xml/web_mobile.xml:269
msgid "Off"
msgstr "Apagar"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:294
msgid "Form View"
msgstr "Vista formulario"

View File

@ -0,0 +1,106 @@
# Swedish translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-07 10:13+0100\n"
"PO-Revision-Date: 2012-04-17 12:46+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-18 04:57+0000\n"
"X-Generator: Launchpad (build 15108)\n"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:17
msgid "OpenERP"
msgstr "OpenERP"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:22
msgid "Database:"
msgstr "Databas:"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:30
msgid "Login:"
msgstr "Användarnamn:"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:32
msgid "Password:"
msgstr "Lösenord:"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:34
msgid "Login"
msgstr "Logga in"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:36
msgid "Bad username or password"
msgstr "Fel användanamn eller lösenord"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:42
msgid "Powered by openerp.com"
msgstr "Baserad på openerp.com"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:49
msgid "Home"
msgstr "Hem"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:57
msgid "Favourite"
msgstr "Favorit"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:58
msgid "Preference"
msgstr "Inställning"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:123
msgid "Logout"
msgstr "Logga ut"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:132
msgid "There are no records to show."
msgstr "Det finns inte några poster att visa."
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:183
msgid "Open this resource"
msgstr "Öppna denna resurs"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:223
#: addons/web_mobile/static/src/xml/web_mobile.xml:226
msgid "Percent of tasks closed according to total of tasks to do..."
msgstr "Andel avslutade uppgifter i jämförelse med alla..."
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:264
#: addons/web_mobile/static/src/xml/web_mobile.xml:268
msgid "On"
msgstr "På"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:265
#: addons/web_mobile/static/src/xml/web_mobile.xml:269
msgid "Off"
msgstr "Av"
#. openerp-web
#: addons/web_mobile/static/src/xml/web_mobile.xml:294
msgid "Form View"
msgstr "Formulär"

View File

@ -2,36 +2,36 @@
* OpenERP Web Mobile chrome
*---------------------------------------------------------*/
openerp.web_mobile.chrome_mobile = function(openerp) {
openerp.web_mobile.chrome_mobile = function(instance) {
openerp.web_mobile.mobilewebclient = function(element_id) {
// TODO Helper to start mobile webclient rename it openerp.web.webclient
var client = new openerp.web_mobile.MobileWebClient(element_id);
instance.web_mobile.mobilewebclient = function(element_id) {
// TODO Helper to start mobile webclient rename it instance.web.webclient
var client = new instance.web_mobile.MobileWebClient(element_id);
client.start();
return client;
};
openerp.web_mobile.MobileWebClient = openerp.web.OldWidget.extend({
instance.web_mobile.MobileWebClient = instance.web.OldWidget.extend({
template: "WebClient",
init: function(element_id) {
this._super(null, element_id);
this.crashmanager = new openerp.web.CrashManager(this);
this.login = new openerp.web_mobile.Login(this, "oe_login");
this.crashmanager = new instance.web.CrashManager(this);
this.login = new instance.web_mobile.Login(this, "oe_login");
},
start: function() {
this._super.apply(this, arguments);
var self = this;
this.session.bind_session().then(function() {
openerp.web.qweb.add_template("xml/web_mobile.xml");
instance.web.qweb.add_template("xml/web_mobile.xml");
self.$element.html(self.render());
self.login.start();
});
}
});
openerp.web_mobile.Login = openerp.web.OldWidget.extend({
instance.web_mobile.Login = instance.web.OldWidget.extend({
template: "Login",
@ -103,7 +103,7 @@ openerp.web_mobile.Login = openerp.web.OldWidget.extend({
.addClass("login_valid");
//.hide();
if(!$('#oe_menu').html().length){
this.menu = new openerp.web_mobile.Menu(this, "oe_menu", "oe_secondary_menu");
this.menu = new instance.web_mobile.Menu(this, "oe_menu", "oe_secondary_menu");
this.menu.start();
}else{
$.mobile.changePage("#oe_menu", "slide", false, true);
@ -119,7 +119,7 @@ openerp.web_mobile.Login = openerp.web.OldWidget.extend({
}
});
openerp.web_mobile.Header = openerp.web.OldWidget.extend({
instance.web_mobile.Header = instance.web.OldWidget.extend({
template: "Header",
@ -131,7 +131,7 @@ openerp.web_mobile.Header = openerp.web.OldWidget.extend({
}
});
openerp.web_mobile.Footer = openerp.web.OldWidget.extend({
instance.web_mobile.Footer = instance.web.OldWidget.extend({
template: "Footer",
@ -143,7 +143,7 @@ openerp.web_mobile.Footer = openerp.web.OldWidget.extend({
}
});
openerp.web_mobile.Shortcuts = openerp.web.OldWidget.extend({
instance.web_mobile.Shortcuts = instance.web.OldWidget.extend({
template: "Shortcuts",
@ -171,7 +171,7 @@ openerp.web_mobile.Shortcuts = openerp.web.OldWidget.extend({
res_id = $shortcut.data('res');
if(!$('[id^="oe_list_'+res_id+'"]').html()){
$('<div id="oe_list_'+res_id+'" data-role="page" data-url="oe_list_'+res_id+'"> </div>').appendTo('#moe');
this.listview = new openerp.web_mobile.ListView(self, "oe_list_"+res_id, res_id);
this.listview = new instance.web_mobile.ListView(self, "oe_list_"+res_id, res_id);
this.listview.start();
}else{
$.mobile.changePage('#oe_list_'+res_id, "slide", false, true);
@ -182,7 +182,7 @@ openerp.web_mobile.Shortcuts = openerp.web.OldWidget.extend({
}
});
openerp.web_mobile.Menu = openerp.web.OldWidget.extend({
instance.web_mobile.Menu = instance.web.OldWidget.extend({
template: "Menu",
@ -199,16 +199,16 @@ openerp.web_mobile.Menu = openerp.web.OldWidget.extend({
on_loaded: function(data) {
var self = this;
this.data = data;
this.header = new openerp.web_mobile.Header(this, "oe_header");
this.header = new instance.web_mobile.Header(this, "oe_header");
this.header.start();
this.footer = new openerp.web_mobile.Footer(this, "oe_footer");
this.footer = new instance.web_mobile.Footer(this, "oe_footer");
this.footer.start();
this.$element.html(this.render(this.data));
this.$element.find("[data-role=header]").find('h1').html('Applications');
this.$element.find("[data-role=header]").find('#home').hide();
this.$element.find("[data-role=footer]").find('#shrotcuts').click(function(){
if(!$('#oe_shortcuts').html().length){
this.shortcuts = new openerp.web_mobile.Shortcuts(self, "oe_shortcuts");
this.shortcuts = new instance.web_mobile.Shortcuts(self, "oe_shortcuts");
this.shortcuts.start();
}else{
$.mobile.changePage($("#oe_shortcuts"), "slide", false, true);
@ -216,7 +216,7 @@ openerp.web_mobile.Menu = openerp.web.OldWidget.extend({
});
this.$element.find("[data-role=footer]").find('#preference').click(function(){
if(!$('#oe_options').html().length){
this.options = new openerp.web_mobile.Options(self, "oe_options");
this.options = new instance.web_mobile.Options(self, "oe_options");
this.options.start();
}else{
$.mobile.changePage("#oe_options", "slide", false, true);
@ -240,7 +240,7 @@ openerp.web_mobile.Menu = openerp.web.OldWidget.extend({
.addClass("secondary_menu");
if(!$('[id^="oe_sec_menu_'+id+'"]').html()){
$('<div id="oe_sec_menu_'+id+'" data-role="page" data-url="oe_sec_menu_'+id+'"> </div>').appendTo('#moe');
this.secondary = new openerp.web_mobile.Secondary(this, "oe_sec_menu_"+id, this.children);
this.secondary = new instance.web_mobile.Secondary(this, "oe_sec_menu_"+id, this.children);
this.secondary.start();
}else{
$.mobile.changePage('#oe_sec_menu_'+id, "slide", false, true);
@ -248,7 +248,7 @@ openerp.web_mobile.Menu = openerp.web.OldWidget.extend({
}
});
openerp.web_mobile.Secondary = openerp.web.OldWidget.extend({
instance.web_mobile.Secondary = instance.web.OldWidget.extend({
template: "Menu.secondary",
@ -287,7 +287,7 @@ openerp.web_mobile.Secondary = openerp.web.OldWidget.extend({
.addClass("secondary_menu");
if(!$('[id^="oe_sec_menu_'+id+'"]').html()){
$('<div id="oe_sec_menu_'+id+'" data-role="page" data-url="oe_sec_menu_'+id+'"> </div>').appendTo('#moe');
this.secondary = new openerp.web_mobile.Secondary(this, "oe_sec_menu_"+id, this.children);
this.secondary = new instance.web_mobile.Secondary(this, "oe_sec_menu_"+id, this.children);
this.secondary.start();
}else{
$.mobile.changePage('#oe_sec_menu_'+id, "slide", false, true);
@ -295,7 +295,7 @@ openerp.web_mobile.Secondary = openerp.web.OldWidget.extend({
}else {
if(!$('[id^="oe_list_'+id+'"]').html()){
$('<div id="oe_list_'+id+'" data-role="page" data-url="oe_list_'+id+'"> </div>').appendTo('#moe');
this.listview = new openerp.web_mobile.ListView(this, "oe_list_"+id, id);
this.listview = new instance.web_mobile.ListView(this, "oe_list_"+id, id);
this.listview.start();
}else{
$.mobile.changePage('#oe_list_'+id, "slide", false, true);
@ -305,7 +305,7 @@ openerp.web_mobile.Secondary = openerp.web.OldWidget.extend({
}
});
openerp.web_mobile.Options = openerp.web.OldWidget.extend({
instance.web_mobile.Options = instance.web.OldWidget.extend({
template: "Options",

View File

@ -2,9 +2,9 @@
* OpenERP Web Mobile Form View
*---------------------------------------------------------*/
openerp.web_mobile.form_mobile = function (openerp) {
openerp.web_mobile.form_mobile = function (instance) {
openerp.web_mobile.FormView = openerp.web.OldWidget.extend({
instance.web_mobile.FormView = instance.web.OldWidget.extend({
template: 'FormView',
@ -25,8 +25,8 @@ openerp.web_mobile.FormView = openerp.web.OldWidget.extend({
}else{
var view_id = this.viewid;
}
this.dataset = new openerp.web.DataSetSearch(this, model, null, null);
var context = new openerp.web.CompoundContext(this.dataset.get_context());
this.dataset = new instance.web.DataSetSearch(this, model, null, null);
var context = new instance.web.CompoundContext(this.dataset.get_context());
this.dataset.read_slice([]).then(function (result) {
for (var i = 0; i < result.length; i++) {
if (result[i].id == id) {
@ -71,14 +71,14 @@ openerp.web_mobile.FormView = openerp.web.OldWidget.extend({
var head = rel_field.string;
if (rel_ids) {
var list_ids = [];
var datasearch = new openerp.web.DataSetSearch(self, rel_field.relation, rel_field.context);
var datasearch = new instance.web.DataSetSearch(self, rel_field.relation, rel_field.context);
datasearch.domain=[['id', 'in', rel_ids]];
datasearch.read_slice(['name'], {context:rel_field.context, domain: datasearch.domain, limit:80}).then(function(listrec){
_.each(listrec, function(i) {
list_ids.push(i.id);
});
_.extend(rel_field.context,{"html_name_get" : true});
var dataset = new openerp.web.DataSet(self, rel_field.relation,rel_field.context);
var dataset = new instance.web.DataSet(self, rel_field.relation,rel_field.context);
dataset.name_get(list_ids,function(res){
var additional = "";
if(res['html_name_get']){
@ -86,7 +86,7 @@ openerp.web_mobile.FormView = openerp.web.OldWidget.extend({
}
if(!$('[id^="oe_list_'+relational+'_'+self.element_id+'"]').html()){
$('<div id="oe_list_'+relational+'_'+self.element_id+'" data-role="page" data-url="oe_list_'+relational+'_'+self.element_id+'"> </div>').appendTo('#moe');
$('[id^="oe_list_'+relational+'_'+self.element_id+'"]').html(openerp.web.qweb.render("ListView", {'records' : res,'data': additional}));
$('[id^="oe_list_'+relational+'_'+self.element_id+'"]').html(instance.web.qweb.render("ListView", {'records' : res,'data': additional}));
$('[id^="oe_list_'+relational+'_'+self.element_id+'"]').find("[data-role=header]").find('h1').html(head);
$('[id^="oe_list_'+relational+'_'+self.element_id+'"]').find("[data-role=header]").find('#home').click(function(){
$.mobile.changePage("#oe_menu", "slide", false, true);
@ -98,7 +98,7 @@ openerp.web_mobile.FormView = openerp.web.OldWidget.extend({
var listid = $(ev.currentTarget).data('id');
if(!$('[id^="oe_form_'+listid+rel_field.relation+'"]').html()){
$('<div id="oe_form_'+listid+rel_field.relation+'" data-role="page" data-url="oe_form_'+listid+rel_field.relation+'"> </div>').appendTo('#moe');
this.formview = new openerp.web_mobile.FormView(self, "oe_form_"+listid+rel_field.relation, listid, '', head, rel_field.relation, false);
this.formview = new instance.web_mobile.FormView(self, "oe_form_"+listid+rel_field.relation, listid, '', head, rel_field.relation, false);
this.formview.start();
}else{
$.mobile.changePage('#oe_form_'+listid+rel_field.relation, "slide", false, true);
@ -126,7 +126,7 @@ openerp.web_mobile.FormView = openerp.web.OldWidget.extend({
if(selected_id){
if(!$('[id^="oe_form_'+selected_id+select_model+'"]').html()){
$('<div id="oe_form_'+selected_id+select_model+'" data-role="page" data-url="oe_form_'+selected_id+select_model+'"> </div>').appendTo('#moe');
this.formview = new openerp.web_mobile.FormView(self, "oe_form_"+selected_id+select_model, selected_id, '', head, select_model, false);
this.formview = new instance.web_mobile.FormView(self, "oe_form_"+selected_id+select_model, selected_id, '', head, select_model, false);
this.formview.start();
}else{
$.mobile.changePage('#oe_form_'+selected_id+select_model, "slide", false, true);
@ -168,7 +168,7 @@ openerp.web_mobile.FormView = openerp.web.OldWidget.extend({
// Temp: Set as disabled
$("#"+getfields[i].attrs.name).attr('disabled', 'true');
if(result.fields[getfields[i].attrs.name]){
var dateresult = openerp.web.format_value(data[getfields[i].attrs.name], {"widget": result.fields[getfields[i].attrs.name].type});
var dateresult = instance.web.format_value(data[getfields[i].attrs.name], {"widget": result.fields[getfields[i].attrs.name].type});
$(this).val(dateresult);
}
}

View File

@ -2,9 +2,9 @@
* OpenERP Web Mobile List View
*---------------------------------------------------------*/
openerp.web_mobile.list_mobile = function (openerp) {
openerp.web_mobile.list_mobile = function (instance) {
openerp.web_mobile.ListView = openerp.web.OldWidget.extend({
instance.web_mobile.ListView = instance.web.OldWidget.extend({
template: 'ListView',
@ -31,14 +31,14 @@ openerp.web_mobile.ListView = openerp.web.OldWidget.extend({
on_search_data: function(ev){
var self = this;
var list_ids = [];
var datasearch = new openerp.web.DataSetSearch(self, self.action.res_model,self.action.context);
var datasearch = new instance.web.DataSetSearch(self, self.action.res_model,self.action.context);
datasearch.domain = self.action.domain;
datasearch.read_slice(['name'], {context:datasearch.context, domain: datasearch.domain, limit:80}).then(function(listresult){
_.each(listresult, function(i) {
list_ids.push(i.id);
});
_.extend(self.action.context,{"html_name_get" : true});
var dataset = new openerp.web.DataSet(self, datasearch.model,datasearch.context);
var dataset = new instance.web.DataSet(self, datasearch.model,datasearch.context);
dataset.name_get(list_ids,function(res){
var additional = "";
if(res['html_name_get']){
@ -64,7 +64,7 @@ openerp.web_mobile.ListView = openerp.web.OldWidget.extend({
head_title = $.trim($record.text());
if(!$('[id^="oe_form_'+id+this.action.res_model+'"]').html()){
$('<div id="oe_form_'+id+this.action.res_model+'" data-role="page" data-url="oe_form_'+id+this.action.res_model+'"> </div>').appendTo('#moe');
this.formview = new openerp.web_mobile.FormView(this, "oe_form_"+id+this.action.res_model, id, this.action, head_title, '' ,'');
this.formview = new instance.web_mobile.FormView(this, "oe_form_"+id+this.action.res_model, id, this.action, head_title, '' ,'');
this.formview.start();
}else{
$.mobile.changePage('#oe_form_'+id+this.action.res_model, "slide", false, true);

View File

@ -0,0 +1,118 @@
# Bengali translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-07 19:19+0100\n"
"PO-Revision-Date: 2012-04-12 22:04+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bengali <bn@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-13 05:38+0000\n"
"X-Generator: Launchpad (build 15070)\n"
#. openerp-web
#: addons/web_process/static/src/js/process.js:261
msgid "Cancel"
msgstr "বাতিল করুন"
#. openerp-web
#: addons/web_process/static/src/js/process.js:262
msgid "Save"
msgstr "সংরক্ষণ করুন"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:6
msgid "Process View"
msgstr "প্রক্রিয়াদর্শন"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:19
msgid "Documentation"
msgstr "নথিকরন"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:19
msgid "Read Documentation Online"
msgstr "অনলাইনে নথিপত্র পরুন"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:25
msgid "Forum"
msgstr "মুক্ত আলোচনাস্থল"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:25
msgid "Community Discussion"
msgstr "সাম্প্রদায়িক আলোচনা"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:31
msgid "Books"
msgstr "বইগুলি"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:31
msgid "Get the books"
msgstr "বইগুলি নাও"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:37
msgid "OpenERP Enterprise"
msgstr "ওপেন-ই-আর-পি শিল্পোদ্যোগ"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:37
msgid "Purchase OpenERP Enterprise"
msgstr "ওপেন-ই-আর-পি শিল্পোদ্যোগ কিনুন"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:52
msgid "Process"
msgstr "প্রক্রিয়া"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:56
msgid "Notes:"
msgstr "টীকাগুলি"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:59
msgid "Last modified by:"
msgstr "সর্বশেষ পরিবর্তন"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:59
msgid "N/A"
msgstr "প্রযোজ্য নয়"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:62
msgid "Subflows:"
msgstr "উপপ্রবাহগুলি:"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:75
msgid "Related:"
msgstr "সম্পর্কিত:"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:88
msgid "Select Process"
msgstr "প্রক্রিয়া নির্বাচন করুন"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:98
msgid "Select"
msgstr "নির্বাচন করুন"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:109
msgid "Edit Process"
msgstr "প্রক্রিয়া সম্পাদনা করুন"

View File

@ -0,0 +1,118 @@
# Bosnian translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-07 19:19+0100\n"
"PO-Revision-Date: 2012-04-17 17:00+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bosnian <bs@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-18 04:57+0000\n"
"X-Generator: Launchpad (build 15108)\n"
#. openerp-web
#: addons/web_process/static/src/js/process.js:261
msgid "Cancel"
msgstr "Otkaži"
#. openerp-web
#: addons/web_process/static/src/js/process.js:262
msgid "Save"
msgstr "Spasi"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:6
msgid "Process View"
msgstr "Pregled Procesa"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:19
msgid "Documentation"
msgstr "Dokumentacija"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:19
msgid "Read Documentation Online"
msgstr "Čitaj Dokumentaciju Online"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:25
msgid "Forum"
msgstr "Forum"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:25
msgid "Community Discussion"
msgstr "Zajednička Diskusija"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:31
msgid "Books"
msgstr "Knjige"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:31
msgid "Get the books"
msgstr "Nabavite knjige"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:37
msgid "OpenERP Enterprise"
msgstr "Pokreni OpenERP"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:37
msgid "Purchase OpenERP Enterprise"
msgstr "Kupi OpenERP Enterprise"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:52
msgid "Process"
msgstr "Proces"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:56
msgid "Notes:"
msgstr "Bilješke:"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:59
msgid "Last modified by:"
msgstr "Posljednje modifikovano od:"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:59
msgid "N/A"
msgstr "N/A"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:62
msgid "Subflows:"
msgstr ""
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:75
msgid "Related:"
msgstr "Srodnost:"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:88
msgid "Select Process"
msgstr "Odabrani Proces"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:98
msgid "Select"
msgstr "Izaberi"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:109
msgid "Edit Process"
msgstr "Edituj proces"

View File

@ -0,0 +1,118 @@
# Spanish (Chile) translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-07 19:19+0100\n"
"PO-Revision-Date: 2012-04-14 15:22+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Spanish (Chile) <es_CL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-15 04:48+0000\n"
"X-Generator: Launchpad (build 15070)\n"
#. openerp-web
#: addons/web_process/static/src/js/process.js:261
msgid "Cancel"
msgstr "Cancelar"
#. openerp-web
#: addons/web_process/static/src/js/process.js:262
msgid "Save"
msgstr "Guardar"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:6
msgid "Process View"
msgstr "Vista del proceso"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:19
msgid "Documentation"
msgstr "Documentación"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:19
msgid "Read Documentation Online"
msgstr "Leer documentación online"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:25
msgid "Forum"
msgstr "Foro"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:25
msgid "Community Discussion"
msgstr "Debate de la comunidad"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:31
msgid "Books"
msgstr "Libros"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:31
msgid "Get the books"
msgstr "Obtener los libros"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:37
msgid "OpenERP Enterprise"
msgstr "OpenERP Enterprise"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:37
msgid "Purchase OpenERP Enterprise"
msgstr "Comprar OpenERP Enterprise"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:52
msgid "Process"
msgstr "Proceso"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:56
msgid "Notes:"
msgstr "Observaciones:"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:59
msgid "Last modified by:"
msgstr "Última modificación por:"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:59
msgid "N/A"
msgstr "N/D"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:62
msgid "Subflows:"
msgstr "Subflujos:"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:75
msgid "Related:"
msgstr "Relacionado:"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:88
msgid "Select Process"
msgstr "Seleccionar proceso"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:98
msgid "Select"
msgstr "Seleccionar"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:109
msgid "Edit Process"
msgstr "Editar Proceso"

View File

@ -0,0 +1,118 @@
# Swedish translation for openerp-web
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-02-07 19:19+0100\n"
"PO-Revision-Date: 2012-04-17 12:42+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-04-18 04:57+0000\n"
"X-Generator: Launchpad (build 15108)\n"
#. openerp-web
#: addons/web_process/static/src/js/process.js:261
msgid "Cancel"
msgstr "Avbryt"
#. openerp-web
#: addons/web_process/static/src/js/process.js:262
msgid "Save"
msgstr "Spara"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:6
msgid "Process View"
msgstr "Processvy"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:19
msgid "Documentation"
msgstr "Dokumentation"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:19
msgid "Read Documentation Online"
msgstr "Läs online-dokumentationen"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:25
msgid "Forum"
msgstr "Forum"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:25
msgid "Community Discussion"
msgstr "Diskussion i användarföreningen"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:31
msgid "Books"
msgstr "Böcker"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:31
msgid "Get the books"
msgstr "Komma över böckerna"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:37
msgid "OpenERP Enterprise"
msgstr "OpenERP Enterprise"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:37
msgid "Purchase OpenERP Enterprise"
msgstr "Köp OpenERP Enterprise"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:52
msgid "Process"
msgstr "Process"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:56
msgid "Notes:"
msgstr "Anteckningar:"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:59
msgid "Last modified by:"
msgstr "Senast ändrad av:"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:59
msgid "N/A"
msgstr "Ej tillgänglig"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:62
msgid "Subflows:"
msgstr "Underflöde"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:75
msgid "Related:"
msgstr "Relaterad:"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:88
msgid "Select Process"
msgstr "Välj process"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:98
msgid "Select"
msgstr "Välj"
#. openerp-web
#: addons/web_process/static/src/xml/web_process.xml:109
msgid "Edit Process"
msgstr "Ändra processen"

View File

@ -1,7 +1,7 @@
openerp.web_process = function (openerp) {
var QWeb = openerp.web.qweb,
_t = openerp.web._t;
openerp.web.ViewManager.include({
openerp.web_process = function (instance) {
var QWeb = instance.web.qweb,
_t = instance.web._t;
instance.web.ViewManager.include({
start: function() {
this._super();
this.process_check();
@ -15,7 +15,7 @@ openerp.web_process = function (openerp) {
grandparent = this.getParent() && this.getParent().getParent(),
view = this.views[this.views_src[0].view_type],
$process_view = this.$element.find('.oe-process-view');
if (!(grandparent instanceof openerp.web.WebClient) ||
if (!(grandparent instanceof instance.web.WebClient) ||
!(view.view_type === this.views_src[0].view_type
&& view.view_id === this.views_src[0].view_id)) {
$process_view.hide();
@ -86,7 +86,7 @@ openerp.web_process = function (openerp) {
if(!this.subflow_model) {
def.resolve(this.action ? (this.action.help!=false ? this.action.help : 'Help: Not Defined') : 'Help: Not Defined');
} else {
var dataset = new openerp.web.DataSetSearch(this, "ir.actions.act_window", this.session.context, []);
var dataset = new instance.web.DataSetSearch(this, "ir.actions.act_window", this.session.context, []);
dataset
.read_slice(['help'],
{
@ -107,7 +107,7 @@ openerp.web_process = function (openerp) {
if(this.process_id)
return def.resolve().promise();
this.process_dataset = new openerp.web.DataSetStatic(this, "process.process", this.session.context);
this.process_dataset = new instance.web.DataSet(this, "process.process", this.session.context);
this.process_dataset
.call("search_by_model", [self.process_model,self.session.context])
.done(function(res) {
@ -237,7 +237,7 @@ openerp.web_process = function (openerp) {
},
jump_to_view: function(model, id) {
var self = this;
var dataset = new openerp.web.DataSetStatic(this, 'ir.values', this.session.context);
var dataset = new instance.web.DataSet(this, 'ir.values', this.session.context);
dataset.call('get',
['action', 'tree_but_open',[['ir.ui.menu', id]], dataset.context],
function(res) {
@ -246,7 +246,7 @@ openerp.web_process = function (openerp) {
action_id: action.id,
context: dataset.context
}, function(result) {
var action_manager = new openerp.web.ActionManager(self);
var action_manager = new instance.web.ActionManager(self);
action_manager.replace(self.$element);
action_manager.do_action(result.result);
});
@ -254,8 +254,8 @@ openerp.web_process = function (openerp) {
},
edit_process_view: function() {
var self = this;
var action_manager = new openerp.web.ActionManager(this);
var dialog = new openerp.web.Dialog(this, {
var action_manager = new instance.web.ActionManager(this);
var dialog = new instance.web.Dialog(this, {
width: 800,
buttons : [
{text: _t("Cancel"), click: function() { $(this).dialog('destroy'); }},

View File

@ -1,16 +1,16 @@
openerp.web_tests = function (db) {
db.web.client_actions.add(
openerp.web_tests = function (instance) {
instance.web.client_actions.add(
'buncha-forms', 'instance.web_tests.BunchaForms');
db.web_tests = {};
db.web_tests.BunchaForms = db.web.OldWidget.extend({
instance.web_tests = {};
instance.web_tests.BunchaForms = instance.web.OldWidget.extend({
init: function (parent) {
this._super(parent);
this.dataset = new db.web.DataSetSearch(this, 'test.listview.relations');
this.form = new db.web.FormView(this, this.dataset, false, {
this.dataset = new instance.web.DataSetSearch(this, 'test.listview.relations');
this.form = new instance.web.FormView(this, this.dataset, false, {
action_buttons: false,
pager: false
});
this.form.registry = db.web.form.readonly;
this.form.registry = instance.web.form.readonly;
},
render: function () {
return '<div class="oe-bunchaforms"></div>';

353
doc/async.rst Normal file
View File

@ -0,0 +1,353 @@
Don't stop the world now: asynchronous development and Javascript
=================================================================
As a language (and runtime), javascript is fundamentally
single-threaded. This means any blocking request or computation will
blocks the whole page (and, in older browsers, the software itself
even preventing users from switching to an other tab): a javascript
environment can be seen as an event-based runloop where application
developers have no control over the runloop itself.
As a result, performing long-running synchronous network requests or
other types of complex and expensive accesses is frowned upon and
asynchronous APIs are used instead.
Asynchronous code rarely comes naturally, especially for developers
used to synchronous server-side code (in Python, Java or C#) where the
code will just block until the deed is gone. This is increased further
when asynchronous programming is not a first-class concept and is
instead implemented on top of callbacks-based programming, which is
the case in javascript.
The goal of this guide is to provide some tools to deal with
asynchronous systems, and warn against systematic issues or dangers.
Deferreds
---------
Deferreds are a form of `promises`_. OpenERP Web currently uses
`jQuery's deferred`_, but any `CommonJS Promises/A`_ implementation
should work.
The core idea of deferreds is that potentially asynchronous methods
will return a :js:class:`Deferred` object instead of an arbitrary
value or (most commonly) nothing.
This object can then be used to track the end of the asynchronous
operation by adding callbacks onto it, either success callbacks or
error callbacks.
A great advantage of deferreds over simply passing callback functions
directly to asynchronous methods is the ability to :ref:`compose them
<deferred-composition>`.
Using deferreds
~~~~~~~~~~~~~~~
`CommonJS Promises/A`_ deferreds have only one method of importance:
:js:func:`Deferred.then`. This method is used to attach new callbacks
to the deferred object.
* the first parameter attaches a success callback, called when the
deferred object is successfully resolved and provided with the
resolved value(s) for the asynchronous operation.
* the second parameter attaches a failure callback, called when the
deferred object is rejected and provided with rejection values
(often some sort of error message).
Callbacks attached to deferreds are never "lost": if a callback is
attached to an already resolved or rejected deferred, the callback
will be called (or ignored) immediately. A deferred is also only ever
resolved or rejected once, and is either resolved or rejected: a given
deferred can not call a single success callback twice, or call both a
success and a failure callbacks.
:js:func:`~Deferred.then` should be the method you'll use most often
when interacting with deferred objects (and thus asynchronous APIs).
Building deferreds
~~~~~~~~~~~~~~~~~~
After using asynchronous APIs may come the time to build them: for
`mocks`_, to compose deferreds from multiple source in a complex
manner, in order to let the current operations repaint the screen or
give other events the time to unfold, ...
This is easy using jQuery's deferred objects.
.. note:: this section is an implementation detail of jQuery Deferred
objects, the creation of promises is not part of any
standard (even tentative) that I know of. If you are using
deferred objects which are not jQuery's, their API may (and
often will) be completely different.
Deferreds are created by invoking their constructor [#]_ without any
argument. This creates a :js:class:`Deferred` instance object with the
following methods:
:js:func:`Deferred.resolve`
As its name indicates, this method moves the deferred to the
"Resolved" state. It can be provided as many arguments as
necessary, these arguments will be provided to any pending success
callback.
:js:func:`Deferred.reject`
Similar to :js:func:`~Deferred.resolve`, but moves the deferred to
the "Rejected" state and calls pending failure handlers.
:js:func:`Deferred.promise`
Creates a readonly view of the deferred object. It is generally a
good idea to return a promise view of the deferred to prevent
callers from resolving or rejecting the deferred in your stead.
:js:func:`~Deferred.reject` and :js:func:`~Deferred.resolve` are used
to inform callers that the asynchronous operation has failed (or
succeeded). These methods should simply be called when the
asynchronous operation has ended, to notify anybody interested in its
result(s).
.. _deferred-composition:
Composing deferreds
~~~~~~~~~~~~~~~~~~~
What we've seen so far is pretty nice, but mostly doable by passing
functions to other functions (well adding functions post-facto would
probably be a chore... still, doable).
Deferreds truly shine when code needs to compose asynchronous
operations in some way or other, as they can be used as a basis for
such composition.
There are two main forms of compositions over deferred: multiplexing
and piping/cascading.
Deferred multiplexing
`````````````````````
The most common reason for multiplexing deferred is simply performing
2+ asynchronous operations and wanting to wait until all of them are
done before moving on (and executing more stuff).
The jQuery multiplexing function for promises is :js:func:`when`.
.. note:: the multiplexing behavior of jQuery's :js:func:`when` is an
(incompatible, mostly) extension of the behavior defined in
`CommonJS Promises/B`_.
This function can take any number of promises [#]_ and will return a
promise.
This returned promise will be resolved when *all* multiplexed promises
are resolved, and will be rejected as soon as one of the multiplexed
promises is rejected (it behaves like Python's ``all()``, but with
promise objects instead of boolean-ish).
The resolved values of the various promises multiplexed via
:js:func:`when` are mapped to the arguments of :js:func:`when`'s
success callback, if they are needed. The resolved values of a promise
are at the same index in the callback's arguments as the promise in
the :js:func:`when` call so you will have:
.. code-block:: javascript
$.when(p0, p1, p2, p3).then(
function (results0, results1, results2, results3) {
// code
});
.. warning::
in a normal mapping, each parameter to the callback would be an
array: each promise is conceptually resolved with an array of 0..n
values and these values are passed to :js:func:`when`'s
callback. But jQuery treats deferreds resolving a single value
specially, and "unwraps" that value.
For instance, in the code block above if the index of each promise
is the number of values it resolves (0 to 3), ``results0`` is an
empty array, ``results2`` is an array of 2 elements (a pair) but
``results1`` is the actual value resolved by ``p1``, not an array.
Deferred chaining
`````````````````
A second useful composition is starting an asynchronous operation as
the result of an other asynchronous operation, and wanting the result
of both: :js:func:`Deferred.then` returns the deferred on which it was
called, so handle e.g. OpenERP's search/read sequence with this would
require something along the lines of:
.. code-block:: javascript
var result = $.Deferred();
Model.search(condition).then(function (ids) {
Model.read(ids, fields).then(function (records) {
result.resolve(records);
});
});
return result.promise();
While it doesn't look too bad for trivial code, this quickly gets
unwieldy.
Instead, jQuery provides a tool to handle this kind of chains:
:js:func:`Deferred.pipe`.
:js:func:`~Deferred.pipe` has the same signature as
:js:func:`~Deferred.then` and could be used in the same manner
provided its return value was not used.
It differs from :js:func:`~Deferred.then` in two ways: it returns a
new promise object, not the one it was called with, and the return
values of the callbacks is actually important to it: whichever
callback is called,
* If the callback is not set (not provided or left to null), the
resolution or rejection value(s) is simply forwarded to
:js:func:`~Deferred.pipe`'s promise (it's essentially a noop)
* If the callback is set and does not return an observable object (a
deferred or a promise), the value it returns (``undefined`` if it
does not return anything) will replace the value it was given, e.g.
.. code-block:: javascript
promise.pipe(function () {
console.log('called');
});
will resolve with the sole value ``undefined``.
* If the callback is set and returns an observable object, that object
will be the actual resolution (and result) of the pipe. This means a
resolved promise from the failure callback will resolve the pipe,
and a failure promise from the success callback will reject the
pipe.
This provides an easy way to chain operation successes, and the
previous piece of code can now be rewritten:
.. code-block:: javascript
return Model.search(condition).pipe(function (ids) {
return Model.read(ids, fields);
});
the result of the whole expression will encode failure if either
``search`` or ``read`` fails (with the right rejection values), and
will be resolved with ``read``'s resolution values if the chain
executes correctly.
:js:func:`~Deferred.pipe` is also useful to adapt third-party
promise-based APIs, in order to filter their resolution value counts
for instance (to take advantage of :js:func:`when` 's special treatment
of single-value promises).
jQuery.Deferred API
~~~~~~~~~~~~~~~~~~~
.. js:function:: when(deferreds…)
:param deferreds: deferred objects to multiplex
:returns: a multiplexed deferred
:rtype: :js:class:`Deferred`
.. js:class:: Deferred
.. js:function:: Deferred.then(doneCallback[, failCallback])
Attaches new callbacks to the resolution or rejection of the
deferred object. Callbacks are executed in the order they are
attached to the deferred.
To provide only a failure callback, pass ``null`` as the
``doneCallback``, to provide only a success callback the
second argument can just be ignored (and not passed at all).
:param doneCallback: function called when the deferred is resolved
:type doneCallback: Function
:param failCallback: function called when the deferred is rejected
:type failCallback: Function
:returns: the deferred object on which it was called
:rtype: :js:class:`Deferred`
.. js:function:: Deferred.done(doneCallback)
Attaches a new success callback to the deferred, shortcut for
``deferred.then(doneCallback)``.
This is a jQuery extension to `CommonJS Promises/A`_ providing
little value over calling :js:func:`~Deferred.then` directly,
it should be avoided.
:param doneCallback: function called when the deferred is resolved
:type doneCallback: Function
:returns: the deferred object on which it was called
:rtype: :js:class:`Deferred`
.. js:function:: Deferred.fail(failCallback)
Attaches a new failure callback to the deferred, shortcut for
``deferred.then(null, failCallback)``.
A second jQuery extension to `Promises/A <CommonJS
Promises/A>`_. Although it provides more value than
:js:func:`~Deferred.done`, it still is not much and should be
avoided as well.
:param failCallback: function called when the deferred is rejected
:type failCallback: Function
:returns: the deferred object on which it was called
:rtype: :js:class:`Deferred`
.. js:function:: Deferred.promise()
Returns a read-only view of the deferred object, with all
mutators (resolve and reject) methods removed.
.. js:function:: Deferred.resolve(value…)
Called to resolve a deferred, any value provided will be
passed onto the success handlers of the deferred object.
Resolving a deferred which has already been resolved or
rejected has no effect.
.. js:function:: Deferred.reject(value…)
Called to reject (fail) a deferred, any value provided will be
passed onto the failure handler of the deferred object.
Rejecting a deferred which has already been resolved or
rejected has no effect.
.. js:function:: Deferred.pipe(doneFilter[, failFilter])
Filters the result of a deferred, able to transform a success
into failure and a failure into success, or to delay
resolution further.
.. [#] or simply calling :js:class:`Deferred` as a function, the
result is the same
.. [#] or not-promises, the `CommonJS Promises/B`_ role of
:js:func:`when` is to be able to treat values and promises
uniformly: :js:func:`when` will pass promises through directly,
but non-promise values and objects will be transformed into a
resolved promise (resolving themselves with the value itself).
jQuery's :js:func:`when` keeps this behavior making deferreds
easy to build from "static" values, or allowing defensive code
where expected promises are wrapped in :js:func:`when` just in
case.
.. _promises: http://en.wikipedia.org/wiki/Promise_(programming)
.. _jQuery's deferred: http://api.jquery.com/category/deferred-object/
.. _CommonJS Promises/A: http://wiki.commonjs.org/wiki/Promises/A
.. _CommonJS Promises/B: http://wiki.commonjs.org/wiki/Promises/B
.. _mocks: http://en.wikipedia.org/wiki/Mock_object

108
doc/changelog-6.2.rst Normal file
View File

@ -0,0 +1,108 @@
API changes from OpenERP Web 6.1 to 6.2
=======================================
DataSet -> Model
----------------
The 6.1 ``DataSet`` API has been deprecated in favor of the smaller
and more orthogonal :doc:`Model </rpc>` API, which more closely
matches the API in OpenERP Web's Python side and in OpenObject addons
and removes most stateful behavior of DataSet.
Migration guide
~~~~~~~~~~~~~~~
* Actual arbitrary RPC calls can just be remapped on a
:js:class:`~openerp.web.Model` instance:
.. code-block:: javascript
dataset.call(method, args)
or
.. code-block:: javascript
dataset.call_and_eval(method, args)
can be replaced by calls to :js:func:`openerp.web.Model.call`:
.. code-block:: javascript
model.call(method, args)
If callbacks are passed directly to the older methods, they need to
be added to the new one via ``.then()``.
.. note::
The ``context_index`` and ``domain_index`` features were not
ported, context and domain now need to be passed in "in full",
they won't be automatically filled with the user's current
context.
* Shorcut methods (``name_get``, ``name_search``, ``unlink``,
``write``, ...) should be ported to
:js:func:`openerp.web.Model.call`, using the server's original
signature. On the other hand, the non-shortcut equivalents can now
use keyword arguments (see :js:func:`~openerp.web.Model.call`'s
signature for details)
* ``read_slice``, which allowed a single round-trip to perform a
search and a read, should be reimplemented via
:js:class:`~openerp.web.Query` objects (see:
:js:func:`~openerp.web.Model.query`) for clearer and simpler
code. ``read_index`` should be replaced by a
:js:class:`~openerp.web.Query` as well, combining
:js:func:`~openerp.web.Query.offset` and
:js:func:`~openerp.web.Query.first`.
Rationale
~~~~~~~~~
Renaming
The name *DataSet* exists in the CS community consciousness, and
(as its name implies) it's a set of data (often fetched from a
database, maybe lazily). OpenERP Web's dataset behaves very
differently as it does not store (much) data (only a bunch of ids
and just enough state to break things). The name "Model" matches
the one used on the Python side for the task of building an RPC
proxy to OpenERP objects.
API simplification
``DataSet`` has a number of methods which serve as little more
than shortcuts, or are there due to domain and context evaluation
issues in 6.1.
The shortcuts really add little value, and OpenERP Web 6.2 embeds
a restricted Python evaluator (in javascript) meaning most of the
context and domain parsing & evaluation can be moved to the
javascript code and does not require cooperative RPC bridging.
DataGroup -> also Model
-----------------------
Alongside the deprecation of ``DataSet`` for
:js:class:`~openerp.web.Model`, OpenERP Web 6.2 also deprecates
``DataGroup`` and its subtypes in favor of a single method on
:js:class:`~openerp.web.Query`:
:js:func:`~openerp.web.Query.group_by`.
Migration guide
~~~~~~~~~~~~~~~
Rationale
~~~~~~~~~
While the ``DataGroup`` API worked (mostly), it is quite odd and
alien-looking, a bit too Smalltalk-inspired (behaves like a
self-contained flow-control structure for reasons which may or may not
have been good).
Because it is heavily related to ``DataSet`` (as it *yields*
``DataSet`` objects), deprecating ``DataSet`` automatically deprecates
``DataGroup`` (if we want to stay consistent), which is a good time to
make the API more imperative and look more like what most developers
are used to.

View File

@ -8,6 +8,17 @@ Welcome to OpenERP Web's documentation!
Contents:
.. toctree::
:maxdepth: 1
changelog-6.2
async
rpc
Older stuff
-----------
.. toctree::
:maxdepth: 2

345
doc/rpc.rst Normal file
View File

@ -0,0 +1,345 @@
Outside the box: network interactions
=====================================
Building static displays is all nice and good and allows for neat
effects (and sometimes you're given data to display from third parties
so you don't have to make any effort), but a point generally comes
where you'll want to talk to the world and make some network requests.
OpenERP Web provides two primary APIs to handle this, a low-level
JSON-RPC based API communicating with the Python section of OpenERP
Web (and of your addon, if you have a Python part) and a high-level
API above that allowing your code to talk directly to the OpenERP
server, using familiar-looking calls.
All networking APIs are :doc:`asynchronous </async>`. As a result, all
of them will return :js:class:`Deferred` objects (whether they resolve
those with values or not). Understanding how those work before before
moving on is probably necessary.
High-level API: calling into OpenERP models
-------------------------------------------
Access to OpenERP object methods (made available through XML-RPC from
the server) is done via the :js:class:`openerp.web.Model` class. This
class maps onto the OpenERP server objects via two primary methods,
:js:func:`~openerp.web.Model.call` and
:js:func:`~openerp.web.Model.query`.
:js:func:`~openerp.web.Model.call` is a direct mapping to the
corresponding method of the OpenERP server object. Its usage is
similar to that of the OpenERP Model API, with three differences:
* The interface is :doc:`asynchronous </async>`, so instead of
returning results directly RPC method calls will return
:js:class:`Deferred` instances, which will themselves resolve to the
result of the matching RPC call.
* Because ECMAScript 3/Javascript 1.5 doesnt feature any equivalent to
``__getattr__`` or ``method_missing``, there needs to be an explicit
method to dispatch RPC methods.
* No notion of pooler, the model proxy is instantiated where needed,
not fetched from an other (somewhat global) object
.. code-block:: javascript
var Users = new Model('res.users');
Users.call('change_password', ['oldpassword', 'newpassword'],
{context: some_context}).then(function (result) {
// do something with change_password result
});
:js:func:`~openerp.web.Model.query` is a shortcut for a builder-style
interface to searches (``search`` + ``read`` in OpenERP RPC terms). It
returns a :js:class:`~openerp.web.Query` object which is immutable but
allows building new :js:class:`~openerp.web.Query` instances from the
first one, adding new properties or modifiying the parent object's:
.. code-block:: javascript
Users.query(['name', 'login', 'user_email', 'signature'])
.filter([['active', '=', true], ['company_id', '=', main_company]])
.limit(15)
.all().then(function (users) {
// do work with users records
});
The query is only actually performed when calling one of the query
serialization methods, :js:func:`~openerp.web.Query.all` and
:js:func:`~openerp.web.Query.first`. These methods will perform a new
RPC call every time they are called.
For that reason, it's actually possible to keep "intermediate" queries
around and use them differently/add new specifications on them.
.. js:class:: openerp.web.Model(name)
.. js:attribute:: openerp.web.Model.name
name of the OpenERP model this object is bound to
.. js:function:: openerp.web.Model.call(method[, args][, kwargs])
Calls the ``method`` method of the current model, with the
provided positional and keyword arguments.
:param String method: method to call over rpc on the
:js:attr:`~openerp.web.Model.name`
:param Array<> args: positional arguments to pass to the
method, optional
:param Object<> kwargs: keyword arguments to pass to the
method, optional
:rtype: Deferred<>
.. js:function:: openerp.web.Model.query(fields)
:param Array<String> fields: list of fields to fetch during
the search
:returns: a :js:class:`~openerp.web.Query` object
representing the search to perform
.. js:class:: openerp.web.Query(fields)
The first set of methods is the "fetching" methods. They perform
RPC queries using the internal data of the object they're called
on.
.. js:function:: openerp.web.Query.all()
Fetches the result of the current
:js:class:`~openerp.web.Query` object's search.
:rtype: Deferred<Array<>>
.. js:function:: openerp.web.Query.first()
Fetches the **first** result of the current
:js:class:`~openerp.web.Query`, or ``null`` if the current
:js:class:`~openerp.web.Query` does have any result.
:rtype: Deferred<Object | null>
.. js:function:: openerp.web.Query.count()
Fetches the number of records the current
:js:class:`~openerp.web.Query` would retrieve.
:rtype: Deferred<Number>
.. js:function:: openerp.web.Query.group_by(grouping...)
Fetches the groups for the query, using the first specified
grouping parameter
:param Array<String> grouping: Lists the levels of grouping
asked of the server. Grouping
can actually be an array or
varargs.
:rtype: Deferred<Array<openerp.web.Group>> | null
The second set of methods is the "mutator" methods, they create a
**new** :js:class:`~openerp.web.Query` object with the relevant
(internal) attribute either augmented or replaced.
.. js:function:: openerp.web.Query.context(ctx)
Adds the provided ``ctx`` to the query, on top of any existing
context
.. js:function:: openerp.web.Query.filter(domain)
Adds the provided domain to the query, this domain is
``AND``-ed to the existing query domain.
.. js:function:: opeenrp.web.Query.offset(offset)
Sets the provided offset on the query. The new offset
*replaces* the old one.
.. js:function:: openerp.web.Query.limit(limit)
Sets the provided limit on the query. The new limit *replaces*
the old one.
.. js:function:: openerp.web.Query.order_by(fields…)
Overrides the model's natural order with the provided field
specifications. Behaves much like Django's `QuerySet.order_by
<https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by>`_:
* Takes 1..n field names, in order of most to least importance
(the first field is the first sorting key). Fields are
provided as strings.
* A field specifies an ascending order, unless it is prefixed
with the minus sign "``-``" in which case the field is used
in the descending order
Divergences from Django's sorting include a lack of random sort
(``?`` field) and the inability to "drill down" into relations
for sorting.
Aggregation (grouping)
~~~~~~~~~~~~~~~~~~~~~~
OpenERP has powerful grouping capacities, but they are kind-of strange
in that they're recursive, and level n+1 relies on data provided
directly by the grouping at level n. As a result, while ``read_group``
works it's not a very intuitive API.
OpenERP Web 6.2 eschews direct calls to ``read_group`` in favor of
calling a method of :js:class:`~openerp.web.Query`, `much in the way
it is one in SQLAlchemy
<http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.group_by>`_ [#]_:
.. code-block:: javascript
some_query.group_by(['field1', 'field2']).then(function (groups) {
// do things with the fetched groups
});
This method is asynchronous when provided with 1..n fields (to group
on) as argument, but it can also be called without any field (empty
fields collection or nothing at all). In this case, instead of
returning a Deferred object it will return ``null``.
When grouping criterion come from a third-party and may or may not
list fields (e.g. could be an empty list), this provides two ways to
test the presence of actual subgroups (versus the need to perform a
regular query for records):
* A check on ``group_by``'s result and two completely separate code
paths
.. code-block:: javascript
var groups;
if (groups = some_query.group_by(gby)) {
groups.then(function (gs) {
// groups
});
}
// no groups
* Or a more coherent code path using :js:func:`when`'s ability to
coerce values into deferreds:
.. code-block:: javascript
$.when(some_query.group_by(gby)).then(function (groups) {
if (!groups) {
// No grouping
} else {
// grouping, even if there are no groups (groups
// itself could be an empty array)
}
});
The result of a (successful) :js:func:`~openerp.web.Query.group_by` is
an array of :js:class:`~openerp.web.data.Group`.
Synchronizing views (provisional)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. note:: this API may not be final, and may not even remain
While the high-level RPC API is mostly stateless, some objects in
OpenERP Web need to share state information. One of those is OpenERP
views, especially between "collection-based" views (lists, graphs) and
"record-based" views (forms, diagrams), which gets its very own API
for traversing collections of records, the aptly-named
:js:class:`~openerp.web.Traverser`.
A :js:class:`~openerp.web.Traverser` is linked to a
:js:class:`~openerp.web.Model` and is used to iterate over it
asynchronously (and using indexes).
.. js:class:: openerp.web.Traverser(model)
.. js:function:: openerp.web.Traverser.model()
:returns: the :js:class:`~openerp.web.Model` this traverser
instance is bound to
.. js:function:: openerp.web.Traverser.index([idx])
If provided with an index parameter, sets that as the new
index for the traverser.
:param Number idx: the new index for the traverser
:returns: the current index for the traverser
.. js:function:: openerp.web.Traverser.current([fields])
Fetches the traverser's "current" record (that is, the record
at the current index of the traverser)
:param Array<String> fields: fields to return in the record
:rtype: Deferred<>
.. js:function:: openerp.web.Traverser.next([fields])
Increases the traverser's internal index by one, the fetches
the corresponding record. Roughly equivalent to:
.. code-block:: javascript
var idx = traverser.index();
traverser.index(idx+1);
traverser.current();
:param Array<String> fields: fields to return in the record
:rtype: Deferred<>
.. js:function:: openerp.web.Traverser.previous([fields])
Similar to :js:func:`~openerp.web.Traverser.next` but iterates
the traverser backwards rather than forward.
:param Array<String> fields: fields to return in the record
:rtype: Deferred<>
.. js:function:: openerp.web.Traverser.size()
Shortcut to checking the size of the backing model, calling
``traverser.size()`` is equivalent to calling
``traverser.model().query([]).count()``
:rtype: Deferred<Number>
Low-level API: RPC calls to Python side
---------------------------------------
While the previous section is great for calling core OpenERP code
(models code), it does not work if you want to call the Python side of
OpenERP Web.
For this, a lower-level API exists on on
:js:class:`~openerp.web.Connection` objects (usually available through
``openerp.connection``): the ``rpc`` method.
This method simply takes an absolute path (which is the combination of
the Python controller's ``_cp_path`` attribute and the name of the
method you want to call) and a mapping of attributes to values (applied
as keyword arguments on the Python method [#]_). This function fetches
the return value of the Python methods, converted to JSON.
For instance, to call the ``eval_domain_and_context`` of the
:class:`~web.controllers.main.Session` controller:
.. code-block:: javascript
openerp.connection.rpc('/web/session/eval_domain_and_context', {
domains: ds,
contexts: cs
}).then(function (result) {
// handle result
});
.. [#] with a small twist: SQLAlchemy's ``orm.query.Query.group_by``
is not terminal, it returns a query which can still be altered.
.. [#] except for ``context``, which is extracted and stored in the
request object itself.

View File

@ -50,6 +50,19 @@ logging_opts.add_option("--log-config", dest="log_config", default=os.path.join(
help="Logging configuration file", metavar="FILE")
optparser.add_option_group(logging_opts)
testing_opts = optparse.OptionGroup(optparser, "Testing")
testing_opts.add_option('--test-mode', dest='test_mode',
action='store_true', default=False,
help="Starts test mode, which provides a few"
" (utterly unsafe) APIs for testing purposes and"
" sets up a special connector which always raises"
" errors on tentative server access. These errors"
" serialize RPC query information (service,"
" method, arguments list) in the fault_code"
" attribute of the error object returned to the"
" client. This lets javascript code assert the" \
" XMLRPC consequences of its queries.")
optparser.add_option_group(testing_opts)
if __name__ == "__main__":
(options, args) = optparser.parse_args(sys.argv[1:])
@ -78,6 +91,12 @@ if __name__ == "__main__":
options.backend = 'xmlrpc'
os.environ["TZ"] = "UTC"
if options.test_mode:
import web.test_support
import web.test_support.controllers
options.connector = web.test_support.TestConnector()
logging.getLogger('werkzeug').setLevel(logging.WARNING)
if sys.version_info >= (2, 7) and os.path.exists(options.log_config):
with open(options.log_config) as file:
dct = json.load(file)