diff --git a/.bzrignore b/.bzrignore index 8531ad42bbb..1e0564801ab 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1,19 +1,14 @@ -.*.swp -.bzrignore -.idea -.project -.pydevproject -.ropeproject -.settings -.DS_Store -openerp/addons/* -openerp/filestore* -.Python -*.pyc -*.pyo -bin/* +.* +*.egg-info +*.orig +*.vim build/ -include/ -lib/ -share/ -doc/_build/* +RE:^bin/ +RE:^dist/ +RE:^include/ + +RE:^share/ +RE:^man/ +RE:^lib/ + +RE:^addons/\w+/doc/_build/ diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py index 11b94353695..d83636de0f9 100644 --- a/addons/web/__openerp__.py +++ b/addons/web/__openerp__.py @@ -1,6 +1,7 @@ { 'name': 'Web', 'category': 'Hidden', + 'version': '7.0.1.0', 'description': """ OpenERP Web core module. @@ -40,6 +41,7 @@ This module provides the core of the OpenERP Web Client. "static/lib/cleditor/jquery.cleditor.js", "static/lib/py.js/lib/py.js", "static/src/js/boot.js", + "static/src/js/testing.js", "static/src/js/corelib.js", "static/src/js/coresetup.js", "static/src/js/dates.js", @@ -67,5 +69,21 @@ This module provides the core of the OpenERP Web Client. 'qweb' : [ "static/src/xml/*.xml", ], + 'test': [ + "static/test/testing.js", + "static/test/class.js", + "static/test/registry.js", + "static/test/form.js", + "static/test/list-utils.js", + "static/test/formats.js", + "static/test/rpc.js", + "static/test/evals.js", + "static/test/search.js", + "static/test/Widget.js", + "static/test/list.js", + "static/test/list-editable.js", + "static/test/mutex.js" + ], 'bootstrap': True, + 'twitter': False, } diff --git a/addons/web/controllers/__init__.py b/addons/web/controllers/__init__.py index 12a7e529b67..74c27518ece 100644 --- a/addons/web/controllers/__init__.py +++ b/addons/web/controllers/__init__.py @@ -1 +1,2 @@ from . import main +from . import testing diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 9eb672caa3b..fb7b45a4056 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -258,10 +258,20 @@ def concat_files(file_list, reader=None, intersperse=""): files_concat = intersperse.join(files_content) return files_concat, checksum.hexdigest() +concat_js_cache = {} + def concat_js(file_list): content, checksum = concat_files(file_list, intersperse=';') - content = rjsmin(content) - return content, checksum + if checksum in concat_js_cache: + content = concat_js_cache[checksum] + else: + content = rjsmin(content) + concat_js_cache[checksum] = content + return content, checksum + +def fs2web(path): + """convert FS path into web path""" + return '/'.join(path.split(os.path.sep)) def manifest_glob(req, addons, key): if addons is None: @@ -278,7 +288,7 @@ def manifest_glob(req, addons, key): globlist = manifest.get(key, []) for pattern in globlist: for path in glob.glob(os.path.normpath(os.path.join(addons_path, addon, pattern))): - r.append((path, path[len(addons_path):])) + r.append((path, fs2web(path[len(addons_path):]))) return r def manifest_list(req, mods, extension): @@ -637,8 +647,7 @@ class WebClient(openerpweb.Controller): data = fp.read().decode('utf-8') path = file_map[f] - # convert FS path into web path - web_dir = '/'.join(os.path.dirname(path).split(os.path.sep)) + web_dir = os.path.dirname(path) data = re.sub( rx_import, @@ -691,12 +700,10 @@ class WebClient(openerpweb.Controller): until we have established a valid session. This is meant only for translating the login page and db management chrome, using the browser's language. """ - lang = req.httprequest.accept_languages.best or 'en' # For performance reasons we only load a single translation, so for # sub-languages (that should only be partially translated) we load the # main language PO instead - that should be enough for the login screen. - if '-' in lang: # RFC2616 uses '-' separators for sublanguages - lang = lang.split('-')[0] + lang = req.lang.split('_')[0] translations_per_module = {} for addon_name in mods: @@ -770,15 +777,31 @@ class Database(openerpweb.Controller): @openerpweb.jsonrequest def create(self, req, fields): params = dict(map(operator.itemgetter('name', 'value'), fields)) - create_attrs = ( + return req.session.proxy("db").create_database( params['super_admin_pwd'], params['db_name'], bool(params.get('demo_data')), params['db_lang'], - params['create_admin_pwd'] + params['create_admin_pwd']) + + @openerpweb.jsonrequest + def duplicate(self, req, fields): + params = dict(map(operator.itemgetter('name', 'value'), fields)) + return req.session.proxy("db").duplicate_database( + params['super_admin_pwd'], + params['db_original_name'], + params['db_name']) + + @openerpweb.jsonrequest + def duplicate(self, req, fields): + params = dict(map(operator.itemgetter('name', 'value'), fields)) + duplicate_attrs = ( + params['super_admin_pwd'], + params['db_original_name'], + params['db_name'], ) - return req.session.proxy("db").create_database(*create_attrs) + return req.session.proxy("db").duplicate_database(*duplicate_attrs) @openerpweb.jsonrequest def drop(self, req, fields): @@ -886,10 +909,7 @@ class Session(openerpweb.Controller): @openerpweb.jsonrequest def get_lang_list(self, req): try: - return { - 'lang_list': (req.session.proxy("db").list_lang() or []), - 'error': "" - } + return req.session.proxy("db").list_lang() or [] except Exception, e: return {"error": e, "title": "Languages"} @@ -1455,11 +1475,24 @@ class Binary(openerpweb.Controller): try: if not id: res = Model.default_get([field], context).get(field) - image_data = base64.b64decode(res) + image_base64 = res else: res = Model.read([id], [last_update, field], context)[0] retag = hashlib.md5(res.get(last_update)).hexdigest() - image_data = base64.b64decode(res.get(field)) + image_base64 = res.get(field) + + if kw.get('resize'): + resize = kw.get('resize').split(','); + if len(resize) == 2 and int(resize[0]) and int(resize[1]): + width = int(resize[0]) + height = int(resize[1]) + # resize maximum 500*500 + if width > 500: width = 500 + if height > 500: height = 500 + image_base64 = openerp.tools.image_resize_image(base64_source=image_base64, size=(width, height), encoding='base64', filetype='PNG') + + image_data = base64.b64decode(image_base64) + except (TypeError, xmlrpclib.Fault): image_data = self.placeholder(req) headers.append(('ETag', retag)) @@ -1949,112 +1982,4 @@ class Reports(View): ('Content-Length', len(report))], cookies={'fileToken': int(token)}) -class Import(View): - _cp_path = "/web/import" - - def fields_get(self, req, model): - Model = req.session.model(model) - fields = Model.fields_get(False, req.session.eval_context(req.context)) - return fields - - @openerpweb.httprequest - def detect_data(self, req, csvfile, csvsep=',', csvdel='"', csvcode='utf-8', jsonp='callback'): - try: - data = list(csv.reader( - csvfile, quotechar=str(csvdel), delimiter=str(csvsep))) - except csv.Error, e: - csvfile.seek(0) - return '' % ( - jsonp, simplejson.dumps({'error': { - 'message': 'Error parsing CSV file: %s' % e, - # decodes each byte to a unicode character, which may or - # may not be printable, but decoding will succeed. - # Otherwise simplejson will try to decode the `str` using - # utf-8, which is very likely to blow up on characters out - # of the ascii range (in range [128, 256)) - 'preview': csvfile.read(200).decode('iso-8859-1')}})) - - try: - return '' % ( - jsonp, simplejson.dumps( - {'records': data[:10]}, encoding=csvcode)) - except UnicodeDecodeError: - return '' % ( - jsonp, simplejson.dumps({ - 'message': u"Failed to decode CSV file using encoding %s, " - u"try switching to a different encoding" % csvcode - })) - - @openerpweb.httprequest - def import_data(self, req, model, csvfile, csvsep, csvdel, csvcode, jsonp, - meta): - modle_obj = req.session.model(model) - skip, indices, fields = operator.itemgetter('skip', 'indices', 'fields')( - simplejson.loads(meta)) - - error = None - if not (csvdel and len(csvdel) == 1): - error = u"The CSV delimiter must be a single character" - - if not indices and fields: - error = u"You must select at least one field to import" - - if error: - return '' % ( - jsonp, simplejson.dumps({'error': {'message': error}})) - - # skip ignored records (@skip parameter) - # then skip empty lines (not valid csv) - # nb: should these operations be reverted? - rows_to_import = itertools.ifilter( - None, - itertools.islice( - csv.reader(csvfile, quotechar=str(csvdel), delimiter=str(csvsep)), - skip, None)) - - # if only one index, itemgetter will return an atom rather than a tuple - if len(indices) == 1: mapper = lambda row: [row[indices[0]]] - else: mapper = operator.itemgetter(*indices) - - data = None - error = None - try: - # decode each data row - data = [ - [record.decode(csvcode) for record in row] - for row in itertools.imap(mapper, rows_to_import) - # don't insert completely empty rows (can happen due to fields - # filtering in case of e.g. o2m content rows) - if any(row) - ] - except UnicodeDecodeError: - error = u"Failed to decode CSV file using encoding %s" % csvcode - except csv.Error, e: - error = u"Could not process CSV file: %s" % e - - # If the file contains nothing, - if not data: - error = u"File to import is empty" - if error: - return '' % ( - jsonp, simplejson.dumps({'error': {'message': error}})) - - try: - (code, record, message, _nope) = modle_obj.import_data( - fields, data, 'init', '', False, - req.session.eval_context(req.context)) - except xmlrpclib.Fault, e: - error = {"message": u"%s, %s" % (e.faultCode, e.faultString)} - return '' % ( - jsonp, simplejson.dumps({'error':error})) - - if code != -1: - return '' % ( - jsonp, simplejson.dumps({'success':True})) - - msg = u"Error during import: %s\n\nTrying to import record %r" % ( - message, record) - return '' % ( - jsonp, simplejson.dumps({'error': {'message':msg}})) - # vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/web/controllers/testing.py b/addons/web/controllers/testing.py new file mode 100644 index 00000000000..3c7c4899b6c --- /dev/null +++ b/addons/web/controllers/testing.py @@ -0,0 +1,162 @@ +# coding=utf-8 +# -*- encoding: utf-8 -*- + +import glob +import itertools +import json +import operator +import os + +from mako.template import Template +from openerp.modules import module + +from .main import module_topological_sort +from ..http import Controller, httprequest + +NOMODULE_TEMPLATE = Template(u""" + + + + + OpenERP Testing + + +
+ + +
+ + +""") +NOTFOUND = Template(u""" +

Unable to find the module [${module}], please check that the module + name is correct and the module is on OpenERP's path.

+<< Back to tests +""") +TESTING = Template(u""" + +<%def name="to_path(module, p)">/${module}/${p} + + + + OpenERP Web Tests + + + + + + + + +
+
+ +% for module, jss, tests, templates in files: + % for js in jss: + + % endfor + % if tests or templates: + + % endif + % if tests: + % for test in tests: + + % endfor + % endif +% endfor + +""") + +class TestRunnerController(Controller): + _cp_path = '/web/tests' + + @httprequest + def index(self, req, mod=None, **kwargs): + ms = module.get_modules() + manifests = dict( + (name, desc) + for name, desc in zip(ms, map(self.load_manifest, ms)) + if desc # remove not-actually-openerp-modules + ) + + if not mod: + return NOMODULE_TEMPLATE.render(modules=( + (manifest['name'], name) + for name, manifest in manifests.iteritems() + if any(testfile.endswith('.js') + for testfile in manifest['test']) + )) + sorted_mods = module_topological_sort(dict( + (name, manifest.get('depends', [])) + for name, manifest in manifests.iteritems() + )) + # to_load and to_test should be zippable lists of the same length. + # A falsy value in to_test indicate nothing to test at that index (just + # load the corresponding part of to_load) + to_test = sorted_mods + if mod != '*': + if mod not in manifests: + return req.not_found(NOTFOUND.render(module=mod)) + idx = sorted_mods.index(mod) + to_test = [None] * len(sorted_mods) + to_test[idx] = mod + + tests_candicates = [ + filter(lambda path: path.endswith('.js'), + manifests[mod]['test'] if mod else []) + for mod in to_test] + # remove trailing test-less modules + tests = reversed(list( + itertools.dropwhile( + operator.not_, + reversed(tests_candicates)))) + + files = [ + (mod, manifests[mod]['js'], tests, manifests[mod]['qweb']) + for mod, tests in itertools.izip(sorted_mods, tests) + ] + + # if all three db_info parameters are present, send them to the page + db_info = dict((k, v) for k, v in kwargs.iteritems() + if k in ['source', 'supadmin', 'password']) + if len(db_info) != 3: + db_info = None + + return TESTING.render(files=files, dependencies=json.dumps( + [name for name in sorted_mods + if module.get_module_resource(name, 'static') + if manifests[name]['js']]), db_info=json.dumps(db_info)) + + def load_manifest(self, name): + manifest = module.load_information_from_description_file(name) + if manifest: + path = module.get_module_path(name) + manifest['js'] = list( + self.expand_patterns(path, manifest.get('js', []))) + manifest['test'] = list( + self.expand_patterns(path, manifest.get('test', []))) + manifest['qweb'] = list( + self.expand_patterns(path, manifest.get('qweb', []))) + return manifest + + def expand_patterns(self, root, patterns): + for pattern in patterns: + normalized_pattern = os.path.normpath(os.path.join(root, pattern)) + for path in glob.glob(normalized_pattern): + # replace OS path separators (from join & normpath) by URI ones + yield path[len(root):].replace(os.path.sep, '/') diff --git a/addons/web/doc/async.rst b/addons/web/doc/async.rst index d597df0ddb0..6782fdac029 100644 --- a/addons/web/doc/async.rst +++ b/addons/web/doc/async.rst @@ -1,9 +1,6 @@ Asynchronous Operations ======================= -This documentation is outdated as then() is now pipe. Please never copy api -from other libraries just link to it. - 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 @@ -46,8 +43,8 @@ directly to asynchronous methods is the ability to :ref:`compose them Using deferreds ~~~~~~~~~~~~~~~ -deferreds have only one method of importance: :js:func:`Deferred.then`. This -method is used to attach new callbacks to the deferred object. +Deferreds's most important method is :js:func:`Deferred.then`. It 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 @@ -179,9 +176,9 @@ 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: +of both: with the tools described so far, handling e.g. OpenERP's +search/read sequence with this would require something along the lines +of: .. code-block:: javascript @@ -196,21 +193,14 @@ require something along the lines of: 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, +But :js:func:`~Deferred.then` also allows handling this kind of +chains: 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) + :js:func:`~Deferred.then`'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 @@ -218,7 +208,7 @@ callback is called, .. code-block:: javascript - promise.pipe(function () { + promise.then(function () { console.log('called'); }); @@ -235,7 +225,7 @@ callback is called, .. code-block:: javascript - return Model.search(condition).pipe(function (ids) { + return Model.search(condition).then(function (ids) { return Model.read(ids, fields); }); @@ -244,12 +234,109 @@ callback is called, will be resolved with ``read``'s resolution values if the chain executes correctly. -:js:func:`~Deferred.pipe` is also useful to adapt third-party +:js:func:`~Deferred.then` 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). +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). + + Returns a new deferred which resolves to the result of the + corresponding callback, if a callback returns a deferred + itself that new deferred will be used as the resolution of the + chain. + + :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 `_. 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. + +.. [#] 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 diff --git a/addons/web/doc/changelog-7.0.rst b/addons/web/doc/changelog-7.0.rst index 96ed1ae18a2..b801c11b945 100644 --- a/addons/web/doc/changelog-7.0.rst +++ b/addons/web/doc/changelog-7.0.rst @@ -15,7 +15,7 @@ DataSet -> Model ---------------- The 6.1 ``DataSet`` API has been deprecated in favor of the smaller -and more orthogonal :doc:`Model ` API, which more closely +and more orthogonal :doc:`Model ` API, which more closely matches the API in OpenERP Web's Python side and in OpenObject addons and removes most stateful behavior of DataSet. diff --git a/addons/web/doc/dev_client_action.rst b/addons/web/doc/client_action.rst similarity index 100% rename from addons/web/doc/dev_client_action.rst rename to addons/web/doc/client_action.rst diff --git a/addons/web/doc/conf.py b/addons/web/doc/conf.py index ac5b8907e0e..54434190707 100644 --- a/addons/web/doc/conf.py +++ b/addons/web/doc/conf.py @@ -16,10 +16,9 @@ import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) sys.path.append(os.path.abspath('_themes')) -sys.path.append(os.path.abspath('..')) -sys.path.append(os.path.abspath('../openerp')) +sys.path.insert(0, os.path.abspath('../addons')) +sys.path.insert(0, os.path.abspath('..')) # -- General configuration ----------------------------------------------------- @@ -43,7 +42,7 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'OpenERP Server Developers Documentation' +project = u'OpenERP Web Developers Documentation' copyright = u'2012, OpenERP s.a.' # The version info for the project you're documenting, acts as replacement for @@ -53,7 +52,7 @@ copyright = u'2012, OpenERP s.a.' # The short X.Y version. version = '7.0' # The full version, including alpha/beta/rc tags. -release = '7.0b' +release = '7.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -171,7 +170,7 @@ html_sidebars = { #html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'openerp-server-doc' +htmlhelp_basename = 'openerp-web-doc' # -- Options for LaTeX output -------------------------------------------------- @@ -190,7 +189,7 @@ latex_elements = { # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'openerp-server-doc.tex', u'OpenERP Server Developers Documentation', + ('index', 'openerp-web-doc.tex', u'OpenERP Web Developers Documentation', u'OpenERP s.a.', 'manual'), ] @@ -220,7 +219,7 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'openerp-server-doc', u'OpenERP Server Developers Documentation', + ('index', 'openerp-web-doc', u'OpenERP Web Developers Documentation', [u'OpenERP s.a.'], 1) ] @@ -234,8 +233,8 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'OpenERPServerDocumentation', u'OpenERP Server Developers Documentation', - u'OpenERP s.a.', 'OpenERPServerDocumentation', 'Developers documentation for the openobject-server project.', + ('index', 'OpenERPWebDocumentation', u'OpenERP Web Developers Documentation', + u'OpenERP s.a.', 'OpenERPWebDocumentation', 'Developers documentation for the openerp-web project.', 'Miscellaneous'), ] @@ -248,10 +247,12 @@ texinfo_documents = [ # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' +todo_include_todos = True # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { 'python': ('http://docs.python.org/', None), - 'openerpweb': ('http://doc.openerp.com/trunk/developers/web', None), + 'openerpserver': ('http://doc.openerp.com/trunk/developers/server', None), 'openerpdev': ('http://doc.openerp.com/trunk/developers', None), + 'openerpcommand': ('http://doc.openerp.com/trunk/developers/command', None), } diff --git a/addons/web/doc/internal_form.rst b/addons/web/doc/form_view.rst similarity index 100% rename from addons/web/doc/internal_form.rst rename to addons/web/doc/form_view.rst diff --git a/addons/web/doc/images/db-query.png b/addons/web/doc/images/db-query.png new file mode 100644 index 00000000000..e063b724001 Binary files /dev/null and b/addons/web/doc/images/db-query.png differ diff --git a/addons/web/doc/images/runner.png b/addons/web/doc/images/runner.png new file mode 100644 index 00000000000..bd48e9d2922 Binary files /dev/null and b/addons/web/doc/images/runner.png differ diff --git a/addons/web/doc/images/runner2.png b/addons/web/doc/images/runner2.png new file mode 100644 index 00000000000..38ea2949cfc Binary files /dev/null and b/addons/web/doc/images/runner2.png differ diff --git a/addons/web/doc/images/tests.png b/addons/web/doc/images/tests.png new file mode 100644 index 00000000000..84083d9e5ed Binary files /dev/null and b/addons/web/doc/images/tests.png differ diff --git a/addons/web/doc/images/tests2.png b/addons/web/doc/images/tests2.png new file mode 100644 index 00000000000..c8a6f8ae9ee Binary files /dev/null and b/addons/web/doc/images/tests2.png differ diff --git a/addons/web/doc/images/tests3.png b/addons/web/doc/images/tests3.png new file mode 100644 index 00000000000..247f70716af Binary files /dev/null and b/addons/web/doc/images/tests3.png differ diff --git a/addons/web/doc/index.rst b/addons/web/doc/index.rst index b79762431fa..06534c50903 100644 --- a/addons/web/doc/index.rst +++ b/addons/web/doc/index.rst @@ -14,18 +14,18 @@ Contents: presentation async - dev_rpc - dev_widget - dev_qweb - dev_client_action + testing - internal_form - internal_list - internal_search + widget + qweb + rpc + client_action + form_view + search_view + list_view changelog-7.0 - Indices and tables ================== diff --git a/addons/web/doc/internal_list.rst b/addons/web/doc/list_view.rst similarity index 99% rename from addons/web/doc/internal_list.rst rename to addons/web/doc/list_view.rst index c1ed4dcde89..51188d95f7b 100644 --- a/addons/web/doc/internal_list.rst +++ b/addons/web/doc/list_view.rst @@ -451,7 +451,7 @@ formview, delegating instead to its created. The result should be a valid form view, see :doc:`Form Notes - ` for various peculiarities of the form view + ` for various peculiarities of the form view format. :param editor: editor object asking for the view diff --git a/addons/web/doc/dev_qweb.rst b/addons/web/doc/qweb.rst similarity index 100% rename from addons/web/doc/dev_qweb.rst rename to addons/web/doc/qweb.rst diff --git a/addons/web/doc/dev_rpc.rst b/addons/web/doc/rpc.rst similarity index 100% rename from addons/web/doc/dev_rpc.rst rename to addons/web/doc/rpc.rst diff --git a/addons/web/doc/internal_search.rst b/addons/web/doc/search_view.rst similarity index 100% rename from addons/web/doc/internal_search.rst rename to addons/web/doc/search_view.rst diff --git a/addons/web/doc/test-report.txt b/addons/web/doc/test-report.txt new file mode 100644 index 00000000000..ce52618fe20 --- /dev/null +++ b/addons/web/doc/test-report.txt @@ -0,0 +1,25 @@ +test_empty_find (openerp.addons.web.tests.test_dataset.TestDataSetController) ... ok +test_ids_shortcut (openerp.addons.web.tests.test_dataset.TestDataSetController) ... ok +test_regular_find (openerp.addons.web.tests.test_dataset.TestDataSetController) ... ok +web.testing.stack: direct, value, success ... ok +web.testing.stack: direct, deferred, success ... ok +web.testing.stack: direct, value, error ... ok +web.testing.stack: direct, deferred, failure ... ok +web.testing.stack: successful setup ... ok +web.testing.stack: successful teardown ... ok +web.testing.stack: successful setup and teardown ... ok + +[snip ~150 lines] + +test_convert_complex_context (openerp.addons.web.tests.test_view.DomainsAndContextsTest) ... ok +test_convert_complex_domain (openerp.addons.web.tests.test_view.DomainsAndContextsTest) ... ok +test_convert_literal_context (openerp.addons.web.tests.test_view.DomainsAndContextsTest) ... ok +test_convert_literal_domain (openerp.addons.web.tests.test_view.DomainsAndContextsTest) ... ok +test_retrieve_nonliteral_context (openerp.addons.web.tests.test_view.DomainsAndContextsTest) ... ok +test_retrieve_nonliteral_domain (openerp.addons.web.tests.test_view.DomainsAndContextsTest) ... ok + +---------------------------------------------------------------------- +Ran 181 tests in 15.706s + +OK + diff --git a/addons/web/doc/testing.rst b/addons/web/doc/testing.rst new file mode 100644 index 00000000000..600d379aa02 --- /dev/null +++ b/addons/web/doc/testing.rst @@ -0,0 +1,693 @@ +.. highlight:: javascript + +Testing in OpenERP Web +====================== + +Javascript Unit Testing +----------------------- + +OpenERP Web 7.0 includes means to unit-test both the core code of +OpenERP Web and your own javascript modules. On the javascript side, +unit-testing is based on QUnit_ with a number of helpers and +extensions for better integration with OpenERP. + +To see what the runner looks like, find (or start) an OpenERP server +with the web client enabled, and navigate to ``/web/tests`` e.g. `on +OpenERP's CI `_. This will +show the runner selector, which lists all modules with javascript unit +tests, and allows starting any of them (or all javascript tests in all +modules at once). + +.. image:: ./images/runner.png + :align: center + +Clicking any runner button will launch the corresponding tests in the +bundled QUnit_ runner: + +.. image:: ./images/tests.png + :align: center + +Writing a test case +------------------- + +The first step is to list the test file(s). This is done through the +``test`` key of the openerp manifest, by adding javascript files to it +(next to the usual YAML files, if any): + +.. code-block:: python + + { + 'name': "Demonstration of web/javascript tests", + 'category': 'Hidden', + 'depends': ['web'], + 'test': ['static/test/demo.js'], + } + +and to create the corresponding test file(s) + +.. note:: + + Test files which do not exist will be ignored, if all test files + of a module are ignored (can not be found), the test runner will + consider that the module has no javascript tests. + +After that, refreshing the runner selector will display the new module +and allow running all of its (0 so far) tests: + +.. image:: ./images/runner2.png + :align: center + +The next step is to create a test case:: + + openerp.testing.section('basic section', function (test) { + test('my first test', function () { + ok(false, "this test has run"); + }); + }); + +All testing helpers and structures live in the ``openerp.testing`` +module. OpenERP tests live in a :js:func:`~openerp.testing.section`, +which is itself part of a module. The first argument to a section is +the name of the section, the second one is the section body. + +:js:func:`test `, provided by the +:js:func:`~openerp.testing.section` to the callback, is used to +register a given test case which will be run whenever the test runner +actually does its job. OpenERP Web test case use standard `QUnit +assertions`_ within them. + +Launching the test runner at this point will run the test and display +the corresponding assertion message, with red colors indicating the +test failed: + +.. image:: ./images/tests2.png + :align: center + +Fixing the test (by replacing ``false`` to ``true`` in the assertion) +will make it pass: + +.. image:: ./images/tests3.png + :align: center + +Assertions +---------- + +As noted above, OpenERP Web's tests use `qunit assertions`_. They are +available globally (so they can just be called without references to +anything). The following list is available: + +.. js:function:: ok(state[, message]) + + checks that ``state`` is truthy (in the javascript sense) + +.. js:function:: strictEqual(actual, expected[, message]) + + checks that the actual (produced by a method being tested) and + expected values are identical (roughly equivalent to ``ok(actual + === expected, message)``) + +.. js:function:: notStrictEqual(actual, expected[, message]) + + checks that the actual and expected values are *not* identical + (roughly equivalent to ``ok(actual !== expected, message)``) + +.. js:function:: deepEqual(actual, expected[, message]) + + deep comparison between actual and expected: recurse into + containers (objects and arrays) to ensure that they have the same + keys/number of elements, and the values match. + +.. js:function:: notDeepEqual(actual, expected[, message]) + + inverse operation to :js:func:`deepEqual` + +.. js:function:: throws(block[, expected][, message]) + + checks that, when called, the ``block`` throws an + error. Optionally validates that error against ``expected``. + + :param Function block: + :param expected: if a regexp, checks that the thrown error's + message matches the regular expression. If an + error type, checks that the thrown error is of + that type. + :type expected: Error | RegExp + +.. js:function:: equal(actual, expected[, message]) + + checks that ``actual`` and ``expected`` are loosely equal, using + the ``==`` operator and its coercion rules. + +.. js:function:: notEqual(actual, expected[, message]) + + inverse operation to :js:func:`equal` + +Getting an OpenERP instance +--------------------------- + +The OpenERP instance is the base through which most OpenERP Web +modules behaviors (functions, objects, …) are accessed. As a result, +the test framework automatically builds one, and loads the module +being tested and all of its dependencies inside it. This new instance +is provided as the first positional parameter to your test +cases. Let's observe by adding javascript code (not test code) to the +test module: + +.. code-block:: python + + { + 'name': "Demonstration of web/javascript tests", + 'category': 'Hidden', + 'depends': ['web'], + 'js': ['static/src/js/demo.js'], + 'test': ['static/test/demo.js'], + } + +:: + + // src/js/demo.js + openerp.web_tests_demo = function (instance) { + instance.web_tests_demo = { + value_true: true, + SomeType: instance.web.Class.extend({ + init: function (value) { + this.value = value; + } + }) + }; + }; + +and then adding a new test case, which simply checks that the +``instance`` contains all the expected stuff we created in the +module:: + + // test/demo.js + test('module content', function (instance) { + ok(instance.web_tests_demo.value_true, "should have a true value"); + var type_instance = new instance.web_tests_demo.SomeType(42); + strictEqual(type_instance.value, 42, "should have provided value"); + }); + +DOM Scratchpad +-------------- + +As in the wider client, arbitrarily accessing document content is +strongly discouraged during tests. But DOM access is still needed to +e.g. fully initialize :js:class:`widgets <~openerp.web.Widget>` before +testing them. + +Thus, a test case gets a DOM scratchpad as its second positional +parameter, in a jQuery instance. That scratchpad is fully cleaned up +before each test, and as long as it doesn't do anything outside the +scratchpad your code can do whatever it wants:: + + // test/demo.js + test('DOM content', function (instance, $scratchpad) { + $scratchpad.html('
ok
'); + ok($scratchpad.find('span').hasClass('foo'), + "should have provided class"); + }); + test('clean scratchpad', function (instance, $scratchpad) { + ok(!$scratchpad.children().length, "should have no content"); + ok(!$scratchpad.text(), "should have no text"); + }); + +.. note:: + + The top-level element of the scratchpad is not cleaned up, test + cases can add text or DOM children but shoud not alter + ``$scratchpad`` itself. + +Loading templates +----------------- + +To avoid the corresponding processing costs, by default templates are +not loaded into QWeb. If you need to render e.g. widgets making use of +QWeb templates, you can request their loading through the +:js:attr:`~TestOptions.templates` option to the :js:func:`test case +function `. + +This will automatically load all relevant templates in the instance's +qweb before running the test case: + +.. code-block:: python + + { + 'name': "Demonstration of web/javascript tests", + 'category': 'Hidden', + 'depends': ['web'], + 'js': ['static/src/js/demo.js'], + 'test': ['static/test/demo.js'], + 'qweb': ['static/src/xml/demo.xml'], + } + +.. code-block:: xml + + + + + +

+
+
+
+ +:: + + // test/demo.js + test('templates', {templates: true}, function (instance) { + var s = instance.web.qweb.render('DemoTemplate'); + var texts = $(s).find('p').map(function () { + return $(this).text(); + }).get(); + + deepEqual(texts, ['0', '1', '2', '3', '4']); + }); + +Asynchronous cases +------------------ + +The test case examples so far are all synchronous, they execute from +the first to the last line and once the last line has executed the +test is done. But the web client is full of :doc:`asynchronous code +`, and thus test cases need to be async-aware. + +This is done by returning a :js:class:`deferred ` from the +case callback:: + + // test/demo.js + test('asynchronous', { + asserts: 1 + }, function () { + var d = $.Deferred(); + setTimeout(function () { + ok(true); + d.resolve(); + }, 100); + return d; + }); + +This example also uses the :js:class:`options parameter ` +to specify the number of assertions the case should expect, if less or +more assertions are specified the case will count as failed. + +Asynchronous test cases *must* specify the number of assertions they +will run. This allows more easily catching situations where e.g. the +test architecture was not warned about asynchronous operations. + +.. note:: + + Asynchronous test cases also have a 2 seconds timeout: if the test + does not finish within 2 seconds, it will be considered + failed. This pretty much always means the test will not + resolve. This timeout *only* applies to the test itself, not to + the setup and teardown processes. + +.. note:: + + If the returned deferred is rejected, the test will be failed + unless :js:attr:`~TestOptions.fail_on_rejection` is set to + ``false``. + +RPC +--- + +An important subset of asynchronous test cases is test cases which +need to perform (and chain, to an extent) RPC calls. + +.. note:: + + Because they are a subset of asynchronous cases, RPC cases must + also provide a valid :js:attr:`assertions count + `. + +By default, test cases will fail when trying to perform an RPC +call. The ability to perform RPC calls must be explicitly requested by +a test case (or its containing test suite) through +:js:attr:`~TestOptions.rpc`, and can be one of two modes: ``mock`` or +``rpc``. + +Mock RPC +++++++++ + +The preferred (and fastest from a setup and execution time point of +view) way to do RPC during tests is to mock the RPC calls: while +setting up the test case, provide what the RPC responses "should" be, +and only test the code between the "user" (the test itself) and the +RPC call, before the call is effectively done. + +To do this, set the :js:attr:`rpc option ` to +``mock``. This will add a third parameter to the test case callback: + +.. js:function:: mock(rpc_spec, handler) + + Can be used in two different ways depending on the shape of the + first parameter: + + * If it matches the pattern ``model:method`` (if it contains a + colon, essentially) the call will set up the mocking of an RPC + call straight to the OpenERP server (through XMLRPC) as + performed via e.g. :js:func:`openerp.web.Model.call`. + + In that case, ``handler`` should be a function taking two + arguments ``args`` and ``kwargs``, matching the corresponding + arguments on the server side and should simply return the value + as if it were returned by the Python XMLRPC handler:: + + test('XML-RPC', {rpc: 'mock', asserts: 3}, function (instance, $s, mock) { + // set up mocking + mock('people.famous:name_search', function (args, kwargs) { + strictEqual(kwargs.name, 'bob'); + return [ + [1, "Microsoft Bob"], + [2, "Bob the Builder"], + [3, "Silent Bob"] + ]; + }); + + // actual test code + return new instance.web.Model('people.famous') + .call('name_search', {name: 'bob'}).then(function (result) { + strictEqual(result.length, 3, "shoud return 3 people"); + strictEqual(result[0][1], "Microsoft Bob", + "the most famous bob should be Microsoft Bob"); + }); + }); + + * Otherwise, if it matches an absolute path (e.g. ``/a/b/c``) it + will mock a JSON-RPC call to a web client controller, such as + ``/web/webclient/translations``. In that case, the handler takes + a single ``params`` argument holding all of the parameters + provided over JSON-RPC. + + As previously, the handler should simply return the result value + as if returned by the original JSON-RPC handler:: + + test('JSON-RPC', {rpc: 'mock', asserts: 3, templates: true}, function (instance, $s, mock) { + var fetched_dbs = false, fetched_langs = false; + mock('/web/database/get_list', function () { + fetched_dbs = true; + return ['foo', 'bar', 'baz']; + }); + mock('/web/session/get_lang_list', function () { + fetched_langs = true; + return [['vo_IS', 'Hopelandic / Vonlenska']]; + }); + + // widget needs that or it blows up + instance.webclient = {toggle_bars: openerp.testing.noop}; + var dbm = new instance.web.DatabaseManager({}); + return dbm.appendTo($s).then(function () { + ok(fetched_dbs, "should have fetched databases"); + ok(fetched_langs, "should have fetched languages"); + deepEqual(dbm.db_list, ['foo', 'bar', 'baz']); + }); + }); + +.. note:: + + Mock handlers can contain assertions, these assertions should be + part of the assertions count (and if multiple calls are made to a + handler containing assertions, it multiplies the effective number + of assertions). + +.. _testing-rpc-rpc: + +Actual RPC +++++++++++ + +A more realistic (but significantly slower and more expensive) way to +perform RPC calls is to perform actual calls to an actually running +OpenERP server. To do this, set the :js:attr:`rpc option +<~TestOptions.rpc>` to ``rpc``, it will not provide any new parameter +but will enable actual RPC, and the automatic creation and destruction +of databases (from a specified source) around tests. + +First, create a basic model we can test stuff with: + +.. code-block:: javascript + + from openerp.osv import orm, fields + + class TestObject(orm.Model): + _name = 'web_tests_demo.model' + + _columns = { + 'name': fields.char("Name", required=True), + 'thing': fields.char("Thing"), + 'other': fields.char("Other", required=True) + } + _defaults = { + 'other': "bob" + } + +then the actual test:: + + test('actual RPC', {rpc: 'rpc', asserts: 4}, function (instance) { + var Model = new instance.web.Model('web_tests_demo.model'); + return Model.call('create', [{name: "Bob"}]) + .then(function (id) { + return Model.call('read', [[id]]); + }).then(function (records) { + strictEqual(records.length, 1); + var record = records[0]; + strictEqual(record.name, "Bob"); + strictEqual(record.thing, false); + // default value + strictEqual(record.other, 'bob'); + }); + }); + +This test looks like a "mock" RPC test but for the lack of mock +response (and the different ``rpc`` type), however it has further +ranging consequences in that it will copy an existing database to a +new one, run the test in full on that temporary database and destroy +the database, to simulate an isolated and transactional context and +avoid affecting other tests. One of the consequences is that it takes +a *long* time to run (5~10s, most of that time being spent waiting for +a database duplication). + +Furthermore, as the test needs to clone a database, it also has to ask +which database to clone, the database/super-admin password and the +password of the ``admin`` user (in order to authenticate as said +user). As a result, the first time the test runner encounters an +``rpc: "rpc"`` test configuration it will produce the following +prompt: + +.. image:: ./images/db-query.png + :align: center + +and stop the testing process until the necessary information has been +provided. + +The prompt will only appear once per test run, all tests will use the +same "source" database. + +.. note:: + + The handling of that information is currently rather brittle and + unchecked, incorrect values will likely crash the runner. + +.. note:: + + The runner does not currently store this information (for any + longer than a test run that is), the prompt will have to be filled + every time. + +Testing API +----------- + +.. js:function:: openerp.testing.section(name[, options], body) + + A test section, serves as shared namespace for related tests (for + constants or values to only set up once). The ``body`` function + should contain the tests themselves. + + Note that the order in which tests are run is essentially + undefined, do *not* rely on it. + + :param String name: + :param TestOptions options: + :param body: + :type body: Function<:js:func:`~openerp.testing.case`, void> + +.. js:function:: openerp.testing.case(name[, options], callback) + + Registers a test case callback in the test runner, the callback + will only be run once the runner is started (or maybe not at all, + if the test is filtered out). + + :param String name: + :param TestOptions options: + :param callback: + :type callback: Function> + +.. js:class:: TestOptions + + the various options which can be passed to + :js:func:`~openerp.testing.section` or + :js:func:`~openerp.testing.case`. Except for + :js:attr:`~TestOptions.setup` and + :js:attr:`~TestOptions.teardown`, an option on + :js:func:`~openerp.testing.case` will overwrite the corresponding + option on :js:func:`~openerp.testing.section` so + e.g. :js:attr:`~TestOptions.rpc` can be set for a + :js:func:`~openerp.testing.section` and then differently set for + some :js:func:`~openerp.testing.case` of that + :js:func:`~openerp.testing.section` + + .. js:attribute:: TestOptions.asserts + + An integer, the number of assertions which should run during a + normal execution of the test. Mandatory for asynchronous tests. + + .. js:attribute:: TestOptions.setup + + Test case setup, run right before each test case. A section's + :js:func:`~TestOptions.setup` is run before the case's own, if + both are specified. + + .. js:attribute:: TestOptions.teardown + + Test case teardown, a case's :js:func:`~TestOptions.teardown` + is run before the corresponding section if both are present. + + .. js:attribute:: TestOptions.fail_on_rejection + + If the test is asynchronous and its resulting promise is + rejected, fail the test. Defaults to ``true``, set to + ``false`` to not fail the test in case of rejection:: + + // test/demo.js + test('unfail rejection', { + asserts: 1, + fail_on_rejection: false + }, function () { + var d = $.Deferred(); + setTimeout(function () { + ok(true); + d.reject(); + }, 100); + return d; + }); + + .. js:attribute:: TestOptions.rpc + + RPC method to use during tests, one of ``"mock"`` or + ``"rpc"``. Any other value will disable RPC for the test (if + they were enabled by the suite for instance). + + .. js:attribute:: TestOptions.templates + + Whether the current module (and its dependencies)'s templates + should be loaded into QWeb before starting the test. A + boolean, ``false`` by default. + +The test runner can also use two global configuration values set +directly on the ``window`` object: + +* ``oe_all_dependencies`` is an ``Array`` of all modules with a web + component, ordered by dependency (for a module ``A`` with + dependencies ``A'``, any module of ``A'`` must come before ``A`` in + the array) + +* ``oe_db_info`` is an object with 3 keys ``source``, ``supadmin`` and + ``password``. It is used to pre-configure :ref:`actual RPC + ` tests, to avoid a prompt being displayed + (especially for headless situations). + +Running through Python +---------------------- + +The web client includes the means to run these tests on the +command-line (or in a CI system), but while actually running it is +pretty simple the setup of the pre-requisite parts has some +complexities. + +1. Install unittest2_ and QUnitSuite_ in your Python environment. Both + can trivially be installed via `pip `_ or + `easy_install + `_. + + The former is the unit-testing framework used by OpenERP, the + latter is an adapter module to run qunit_ test suites and convert + their result into something unittest2_ can understand and report. + +2. Install PhantomJS_. It is a headless + browser which allows automating running and testing web + pages. QUnitSuite_ uses it to actually run the qunit_ test suite. + + The PhantomJS_ website provides pre-built binaries for some + platforms, and your OS's package management probably provides it as + well. + + If you're building PhantomJS_ from source, I recommend preparing + for some knitting time as it's not exactly fast (it needs to + compile both `Qt `_ and `Webkit + `_, both being pretty big projects). + + .. note:: + + Because PhantomJS_ is webkit-based, it will not be able to test + if Firefox, Opera or Internet Explorer can correctly run the + test suite (and it is only an approximation for Safari and + Chrome). It is therefore recommended to *also* run the test + suites in actual browsers once in a while. + + .. note:: + + The version of PhantomJS_ this was build through is 1.7, + previous versions *should* work but are not actually supported + (and tend to just segfault when something goes wrong in + PhantomJS_ itself so they're a pain to debug). + +3. Set up :ref:`OpenERP Command `, + which will be used to actually run the tests: running the qunit_ + test suite requires a running server, so at this point OpenERP + Server isn't able to do it on its own during the building/testing + process. + +4. Install a new database with all relevant modules (all modules with + a web component at least), then restart the server + + .. note:: + + For some tests, a source database needs to be duplicated. This + operation requires that there be no connection to the database + being duplicated, but OpenERP doesn't currently break + existing/outstanding connections, so restarting the server is + the simplest way to ensure everything is in the right state. + +5. Launch ``oe run-tests -d $DATABASE -mweb`` with the correct + addons-path specified (and replacing ``$DATABASE`` by the source + database you created above) + + .. note:: + + If you leave out ``-mweb``, the runner will attempt to run all + the tests in all the modules, which may or may not work. + +If everything went correctly, you should now see a list of tests with +(hopefully) ``ok`` next to their names, closing with a report of the +number of tests run and the time it took: + +.. literalinclude:: test-report.txt + :language: text + +Congratulation, you have just performed a successful "offline" run of +the OpenERP Web test suite. + +.. note:: + + Note that this runs all the Python tests for the ``web`` module, + but all the web tests for all of OpenERP. This can be surprising. + +.. _qunit: http://qunitjs.com/ + +.. _qunit assertions: http://api.qunitjs.com/category/assert/ + +.. _unittest2: http://pypi.python.org/pypi/unittest2 + +.. _QUnitSuite: http://pypi.python.org/pypi/QUnitSuite/ + +.. _PhantomJS: http://phantomjs.org/ diff --git a/addons/web/doc/dev_widget.rst b/addons/web/doc/widget.rst similarity index 100% rename from addons/web/doc/dev_widget.rst rename to addons/web/doc/widget.rst diff --git a/addons/web/http.py b/addons/web/http.py index 1a636971fb5..fc80cb03864 100644 --- a/addons/web/http.py +++ b/addons/web/http.py @@ -11,6 +11,7 @@ import logging import mimetypes import os import pprint +import random import sys import tempfile import threading @@ -21,6 +22,7 @@ import urlparse import uuid import xmlrpclib +import babel.core import simplejson import werkzeug.contrib.sessions import werkzeug.datastructures @@ -91,9 +93,25 @@ class WebRequest(object): self.session_id = self.params.pop("session_id", None) or uuid.uuid4().hex self.session = self.httpsession.get(self.session_id) if not self.session: - self.httpsession[self.session_id] = self.session = session.OpenERPSession() + self.session = session.OpenERPSession() + self.httpsession[self.session_id] = self.session self.context = self.params.pop('context', None) - self.debug = self.params.pop('debug', False) != False + self.debug = self.params.pop('debug', False) is not False + # Determine self.lang + lang = self.params.get('lang', None) + if lang is None: + lang = self.session.eval_context(self.context).get('lang') + if lang is None: + lang = self.httprequest.cookies.get('lang') + if lang is None: + lang = self.httprequest.accept_languages.best + if lang is None: + lang = 'en_US' + # tranform 2 letters lang like 'en' into 5 letters like 'en_US' + lang = babel.core.LOCALE_ALIASES.get(lang, lang) + # we use _ as seprator where RFC2616 uses '-' + self.lang = lang.replace('-', '_') + class JsonRequest(WebRequest): """ JSON-RPC2 over HTTP. @@ -210,6 +228,10 @@ class JsonRequest(WebRequest): _logger.debug("<--\n%s", pprint.pformat(response)) if jsonp: + # If we use jsonp, that's mean we are called from another host + # Some browser (IE and Safari) do no allow third party cookies + # We need then to manage http sessions manually. + response['httpsessionid'] = self.httpsession.sid mime = 'application/javascript' body = "%s(%s);" % (jsonp, simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder),) else: @@ -336,23 +358,13 @@ class Controller(object): #---------------------------------------------------------- # Session context manager #---------------------------------------------------------- -STORES = {} - @contextlib.contextmanager -def session_context(request, storage_path, session_cookie='httpsessionid'): - session_store, session_lock = STORES.get(storage_path, (None, None)) - if not session_store: - session_store = werkzeug.contrib.sessions.FilesystemSessionStore( storage_path) - session_lock = threading.Lock() - STORES[storage_path] = session_store, session_lock - - sid = request.cookies.get(session_cookie) +def session_context(request, session_store, session_lock, sid): with session_lock: if sid: request.session = session_store.get(sid) else: request.session = session_store.new() - try: yield request.session finally: @@ -404,6 +416,18 @@ def session_context(request, storage_path, session_cookie='httpsessionid'): session_store.save(request.session) +def session_gc(session_store): + if random.random() < 0.001: + # we keep session one week + last_week = time.time() - 60*60*24*7 + for fname in os.listdir(session_store.path): + path = os.path.join(session_store.path, fname) + try: + if os.path.getmtime(path) < last_week: + os.unlink(path) + except OSError: + pass + #---------------------------------------------------------- # WSGI Application #---------------------------------------------------------- @@ -434,26 +458,31 @@ class DisableCacheMiddleware(object): start_response(status, new_headers) return self.app(environ, start_wrapped) +def session_path(): + try: + username = getpass.getuser() + except Exception: + username = "unknown" + path = os.path.join(tempfile.gettempdir(), "oe-sessions-" + username) + if not os.path.exists(path): + os.mkdir(path, 0700) + return path + class Root(object): """Root WSGI application for the OpenERP Web Client. """ def __init__(self): - self.httpsession_cookie = 'httpsessionid' self.addons = {} static_dirs = self._load_addons() app = werkzeug.wsgi.SharedDataMiddleware( self.dispatch, static_dirs) self.dispatch = DisableCacheMiddleware(app) - try: - username = getpass.getuser() - except Exception: - username = "unknown" - self.session_storage = os.path.join(tempfile.gettempdir(), "oe-sessions-" + username) - - if not os.path.exists(self.session_storage): - os.mkdir(self.session_storage, 0700) - _logger.debug('HTTP sessions stored in: %s', self.session_storage) + # Setup http sessions + path = session_path() + self.session_store = werkzeug.contrib.sessions.FilesystemSessionStore(path) + self.session_lock = threading.Lock() + _logger.debug('HTTP sessions stored in: %s', path) def __call__(self, environ, start_response): """ Handle a WSGI request @@ -476,8 +505,14 @@ class Root(object): if not handler: response = werkzeug.exceptions.NotFound() else: - with session_context(request, self.session_storage, self.httpsession_cookie) as session: - result = handler( request) + sid = request.cookies.get('sid') + if not sid: + sid = request.args.get('sid') + + session_gc(self.session_store) + + with session_context(request, self.session_store, self.session_lock, sid) as session: + result = handler(request) if isinstance(result, basestring): headers=[('Content-Type', 'text/html; charset=utf-8'), ('Content-Length', len(result))] @@ -486,7 +521,7 @@ class Root(object): response = result if hasattr(response, 'set_cookie'): - response.set_cookie(self.httpsession_cookie, session.sid) + response.set_cookie('sid', session.sid) return response(environ, start_response) @@ -530,7 +565,7 @@ class Root(object): :rtype: ``Controller | None`` """ if l: - ps = '/' + '/'.join(l) + ps = '/' + '/'.join(filter(None, l)) method_name = 'index' while ps: c = controllers_path.get(ps) diff --git a/addons/web/i18n/ar.po b/addons/web/i18n/ar.po index e5d92071388..933e81f8772 100644 --- a/addons/web/i18n/ar.po +++ b/addons/web/i18n/ar.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:07+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/bg.po b/addons/web/i18n/bg.po index cb1ffd2c5ab..3cc1bb77ec8 100644 --- a/addons/web/i18n/bg.po +++ b/addons/web/i18n/bg.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:07+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/bn.po b/addons/web/i18n/bn.po index a1934f5346e..78d247805a3 100644 --- a/addons/web/i18n/bn.po +++ b/addons/web/i18n/bn.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:07+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/bs.po b/addons/web/i18n/bs.po index 525a46053bd..4ca035262f7 100644 --- a/addons/web/i18n/bs.po +++ b/addons/web/i18n/bs.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:07+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/ca.po b/addons/web/i18n/ca.po index 8082c37717d..88fc0e32653 100644 --- a/addons/web/i18n/ca.po +++ b/addons/web/i18n/ca.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/cs.po b/addons/web/i18n/cs.po index a12beb474b9..ceb1015a763 100644 --- a/addons/web/i18n/cs.po +++ b/addons/web/i18n/cs.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" "X-Poedit-Language: Czech\n" #. openerp-web diff --git a/addons/web/i18n/da.po b/addons/web/i18n/da.po index 2f8d5ef4e36..a35bac7c918 100644 --- a/addons/web/i18n/da.po +++ b/addons/web/i18n/da.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/de.po b/addons/web/i18n/de.po index 078004291a0..552f1e30f1b 100644 --- a/addons/web/i18n/de.po +++ b/addons/web/i18n/de.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/en_AU.po b/addons/web/i18n/en_AU.po index bdcedadd13d..268be13bd10 100644 --- a/addons/web/i18n/en_AU.po +++ b/addons/web/i18n/en_AU.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/en_GB.po b/addons/web/i18n/en_GB.po index 59a4e42c925..48d5af11c8a 100644 --- a/addons/web/i18n/en_GB.po +++ b/addons/web/i18n/en_GB.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/es.po b/addons/web/i18n/es.po index 8a086ec3654..745ba60db93 100644 --- a/addons/web/i18n/es.po +++ b/addons/web/i18n/es.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/es_CL.po b/addons/web/i18n/es_CL.po index f52e92abcee..9c0839670f2 100644 --- a/addons/web/i18n/es_CL.po +++ b/addons/web/i18n/es_CL.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/es_CR.po b/addons/web/i18n/es_CR.po index c09f10df847..29b09fa3d6c 100644 --- a/addons/web/i18n/es_CR.po +++ b/addons/web/i18n/es_CR.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" "Language: es\n" #. openerp-web diff --git a/addons/web/i18n/es_EC.po b/addons/web/i18n/es_EC.po index 28de64fb3c2..2f834527232 100644 --- a/addons/web/i18n/es_EC.po +++ b/addons/web/i18n/es_EC.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/et.po b/addons/web/i18n/et.po index bc1e88e7cf9..fc4fd35beac 100644 --- a/addons/web/i18n/et.po +++ b/addons/web/i18n/et.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/eu.po b/addons/web/i18n/eu.po index 2f724a53987..1e4526e67cc 100644 --- a/addons/web/i18n/eu.po +++ b/addons/web/i18n/eu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:07+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/fi.po b/addons/web/i18n/fi.po index 9301615a6f5..ce97bef4c44 100644 --- a/addons/web/i18n/fi.po +++ b/addons/web/i18n/fi.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/fr.po b/addons/web/i18n/fr.po index bdcecc565d0..fdc3c87a399 100644 --- a/addons/web/i18n/fr.po +++ b/addons/web/i18n/fr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/fr_CA.po b/addons/web/i18n/fr_CA.po index 104237fcc96..63c777fed9c 100644 --- a/addons/web/i18n/fr_CA.po +++ b/addons/web/i18n/fr_CA.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/gl.po b/addons/web/i18n/gl.po index 82804e9a00b..e6a8a84970d 100644 --- a/addons/web/i18n/gl.po +++ b/addons/web/i18n/gl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/gu.po b/addons/web/i18n/gu.po index 0e9bb980006..eed6596d47d 100644 --- a/addons/web/i18n/gu.po +++ b/addons/web/i18n/gu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/hi.po b/addons/web/i18n/hi.po index 4ded6cef521..c3fec02900b 100644 --- a/addons/web/i18n/hi.po +++ b/addons/web/i18n/hi.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/hr.po b/addons/web/i18n/hr.po index 6ce16f5bda3..774b006975c 100644 --- a/addons/web/i18n/hr.po +++ b/addons/web/i18n/hr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/hu.po b/addons/web/i18n/hu.po index cea5493c029..9587dbd3081 100644 --- a/addons/web/i18n/hu.po +++ b/addons/web/i18n/hu.po @@ -9,13 +9,13 @@ msgstr "" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-07-02 09:06+0200\n" "PO-Revision-Date: 2012-10-26 12:17+0000\n" -"Last-Translator: Herczeg Péter \n" +"Last-Translator: Herczeg Péter \n" "Language-Team: Hungarian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-27 05:15+0000\n" -"X-Generator: Launchpad (build 16194)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/id.po b/addons/web/i18n/id.po index b681859b55a..12509847ba3 100644 --- a/addons/web/i18n/id.po +++ b/addons/web/i18n/id.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/it.po b/addons/web/i18n/it.po index 7df8f4c27bb..6f0f9025e18 100644 --- a/addons/web/i18n/it.po +++ b/addons/web/i18n/it.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-23 05:05+0000\n" -"X-Generator: Launchpad (build 16179)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/ja.po b/addons/web/i18n/ja.po index 3da4bb12ac5..ae6f58716ba 100644 --- a/addons/web/i18n/ja.po +++ b/addons/web/i18n/ja.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/ka.po b/addons/web/i18n/ka.po index 1abd1880405..7c64ddb5ec9 100644 --- a/addons/web/i18n/ka.po +++ b/addons/web/i18n/ka.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/lt.po b/addons/web/i18n/lt.po index 195c0f3c82c..ecbe6ec4085 100644 --- a/addons/web/i18n/lt.po +++ b/addons/web/i18n/lt.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-22 04:46+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 @@ -66,7 +66,7 @@ msgstr "" #. openerp-web #: addons/web/static/src/js/chrome.js:499 msgid "Restored" -msgstr "" +msgstr "Atkurta" #. openerp-web #: addons/web/static/src/js/chrome.js:499 @@ -253,7 +253,7 @@ msgstr "" #: addons/web/static/src/js/formats.js:139 #, python-format msgid "(%d records)" -msgstr "" +msgstr "(%d įrašai(-ų))" #. openerp-web #: addons/web/static/src/js/formats.js:325 @@ -265,7 +265,7 @@ msgstr "Atsisiųsti" #: addons/web/static/src/js/formats.js:330 #, python-format msgid "Download \"%s\"" -msgstr "" +msgstr "Parsisiųsti \"%s\"" #. openerp-web #: addons/web/static/src/js/search.js:437 @@ -527,12 +527,12 @@ msgstr "Forma" #: addons/web/static/src/xml/base.xml:763 #: addons/web/static/src/xml/base.xml:1714 msgid "Delete" -msgstr "" +msgstr "Ištrinti" #. openerp-web #: addons/web/static/src/xml/base.xml:762 msgid "Duplicate" -msgstr "" +msgstr "Sukurti kopiją" #. openerp-web #: addons/web/static/src/js/view_form.js:133 @@ -589,12 +589,12 @@ msgstr "" #: addons/web/static/src/js/view_form.js:2238 #, python-format msgid "   Create \"%s\"" -msgstr "" +msgstr "   Sukurti \"%s\"" #. openerp-web #: addons/web/static/src/js/view_form.js:2244 msgid "   Create and Edit..." -msgstr "" +msgstr "   Sukurti ir redaguoti..." #. openerp-web #: addons/web/static/src/js/view_form.js:2277 @@ -606,7 +606,7 @@ msgstr "Paieška: " #: addons/web/static/src/js/view_form.js:2277 #: addons/web/static/src/js/view_form.js:2765 msgid "Create: " -msgstr "" +msgstr "Sukurti " #. openerp-web #: addons/web/static/src/js/view_form.js:2062 @@ -668,7 +668,7 @@ msgstr "Grupė" #. openerp-web #: addons/web/static/src/js/view_list.js:549 msgid "Do you really want to remove these records?" -msgstr "" +msgstr "Ar tikrai norite ištrinti šiuos įrašus?" #. openerp-web #: addons/web/static/src/js/views.js:925 @@ -813,25 +813,25 @@ msgstr "" #. openerp-web #: addons/web/static/src/xml/base.xml:297 msgid "Invalid username or password" -msgstr "" +msgstr "Neteisingas naudotojo vardas arba slaptažodis" #. openerp-web #: addons/web/static/src/xml/base.xml:116 #: addons/web/static/src/xml/base.xml:150 #: addons/web/static/src/xml/base.xml:301 msgid "Database:" -msgstr "" +msgstr "Duomenų bazė:" #. openerp-web #: addons/web/static/src/xml/base.xml:306 msgid "Username" -msgstr "" +msgstr "Naudotojas" #. openerp-web #: addons/web/static/src/xml/base.xml:308 #: addons/web/static/src/xml/base.xml:331 msgid "Password" -msgstr "" +msgstr "Slaptažodis" #. openerp-web #: addons/web/static/src/xml/base.xml:310 @@ -870,17 +870,17 @@ msgstr "" #: addons/web/static/src/xml/base.xml:195 #: addons/web/static/src/xml/base.xml:330 msgid "Restore" -msgstr "" +msgstr "Atkurti" #. openerp-web #: addons/web/static/src/xml/base.xml:332 msgid "Back to Login" -msgstr "" +msgstr "Grįžti į prisijungimo langą" #. openerp-web #: addons/web/static/src/xml/base.xml:61 msgid "CREATE DATABASE" -msgstr "" +msgstr "SUKURTI DUOMENŲ BAZĘ" #. openerp-web #: addons/web/static/src/xml/base.xml:68 addons/web/static/src/xml/base.xml:211 @@ -922,7 +922,7 @@ msgstr "" #: addons/web/static/src/xml/base.xml:162 #: addons/web/static/src/xml/base.xml:187 msgid "Master Password:" -msgstr "" +msgstr "Pagrindinis slaptažodis" #. openerp-web #: addons/web/static/src/xml/base.xml:143 @@ -932,7 +932,7 @@ msgstr "" #. openerp-web #: addons/web/static/src/xml/base.xml:175 msgid "RESTORE DATABASE" -msgstr "" +msgstr "ATKURTI DUOMENŲ BAZĘ" #. openerp-web #: addons/web/static/src/xml/base.xml:182 @@ -1012,17 +1012,17 @@ msgstr "OpenERP.com" #. openerp-web #: addons/web/static/src/xml/base.xml:1720 msgid "Old Password:" -msgstr "" +msgstr "Esamas slaptažodis:" #. openerp-web #: addons/web/static/src/xml/base.xml:1725 msgid "New Password:" -msgstr "" +msgstr "Naujas slaptažodis:" #. openerp-web #: addons/web/static/src/xml/base.xml:1730 msgid "Confirm Password:" -msgstr "" +msgstr "Patvirtinti slaptažodį:" #. openerp-web #: addons/web/static/src/xml/base.xml:390 @@ -1254,7 +1254,7 @@ msgstr "" #: addons/web/static/src/xml/base.xml:1222 #: addons/web/static/src/xml/base.xml:1279 msgid "Clear" -msgstr "" +msgstr "Išvalyti" #. openerp-web #: addons/web/static/src/xml/base.xml:1179 @@ -1408,12 +1408,12 @@ msgstr "" #. openerp-web #: addons/web/static/src/xml/base.xml:1509 msgid "Save & New" -msgstr "" +msgstr "Išsaugoti ir sukurti naują" #. openerp-web #: addons/web/static/src/xml/base.xml:1510 msgid "Save & Close" -msgstr "" +msgstr "Išsaugoti ir uždaryti" #. openerp-web #: addons/web/static/src/xml/base.xml:1617 @@ -1572,9 +1572,6 @@ msgstr "" #~ msgid "Advanced Filters" #~ msgstr "Išplėstiniai filtrai" -#~ msgid "Other Options" -#~ msgstr "Kiti nustatymai" - #~ msgid "OK" #~ msgstr "Gerai" @@ -1602,3 +1599,22 @@ msgstr "" #~ msgid "Reports" #~ msgstr "Ataskaitos" + +#~ msgid "Other Options" +#~ msgstr "Kitos parinktys" + +#~ msgid "LOGOUT" +#~ msgstr "ATSIJUNGTI" + +#~ msgid "Create..." +#~ msgstr "Sukurti..." + +#~ msgid "Search" +#~ msgstr "Ieškoti" + +#~ msgid "Search..." +#~ msgstr "Ieškoti..." + +#, python-format +#~ msgid "[%(first_record)d to %(last_record)d] of %(records_count)d" +#~ msgstr "[%(first_record)d iki %(last_record)d] iš %(records_count)d" diff --git a/addons/web/i18n/mk.po b/addons/web/i18n/mk.po index 62bef3d0015..30db39b4dfc 100644 --- a/addons/web/i18n/mk.po +++ b/addons/web/i18n/mk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/mn.po b/addons/web/i18n/mn.po index a862954b815..3ee9a552022 100644 --- a/addons/web/i18n/mn.po +++ b/addons/web/i18n/mn.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/nb.po b/addons/web/i18n/nb.po index f47de43b3cf..0b44af2712d 100644 --- a/addons/web/i18n/nb.po +++ b/addons/web/i18n/nb.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/nl.po b/addons/web/i18n/nl.po index 49631585157..eb80e4586ba 100644 --- a/addons/web/i18n/nl.po +++ b/addons/web/i18n/nl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/nl_BE.po b/addons/web/i18n/nl_BE.po index b3be018903b..04e45611f2d 100644 --- a/addons/web/i18n/nl_BE.po +++ b/addons/web/i18n/nl_BE.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/pl.po b/addons/web/i18n/pl.po index d5d854768d0..25cf2862611 100644 --- a/addons/web/i18n/pl.po +++ b/addons/web/i18n/pl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 @@ -243,17 +243,19 @@ msgid "" "Destination fields should only be selected once, some fields are selected " "more than once:" msgstr "" +"Pola docelowe muszą być wybierane tylko raz. niektóre inne pola mogą być " +"wybierane więcej niż raz:" #. openerp-web #: addons/web/static/src/js/data_import.js:386 msgid "*Required Fields are not selected :" -msgstr "" +msgstr "*Wymagane pola nie zostały wybrane :" #. openerp-web #: addons/web/static/src/js/formats.js:139 #, python-format msgid "(%d records)" -msgstr "" +msgstr "(%d rekordów)" #. openerp-web #: addons/web/static/src/js/formats.js:325 diff --git a/addons/web/i18n/pt.po b/addons/web/i18n/pt.po index 3bf3fa6062d..95f3c546400 100644 --- a/addons/web/i18n/pt.po +++ b/addons/web/i18n/pt.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/pt_BR.po b/addons/web/i18n/pt_BR.po index d950e97938c..6f14bf1f547 100644 --- a/addons/web/i18n/pt_BR.po +++ b/addons/web/i18n/pt_BR.po @@ -15,8 +15,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/ro.po b/addons/web/i18n/ro.po index 934e2e77f63..6a77472b1e4 100644 --- a/addons/web/i18n/ro.po +++ b/addons/web/i18n/ro.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/ru.po b/addons/web/i18n/ru.po index ed5735602d0..341f683e953 100644 --- a/addons/web/i18n/ru.po +++ b/addons/web/i18n/ru.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-11-02 05:20+0000\n" -"X-Generator: Launchpad (build 16218)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/sk.po b/addons/web/i18n/sk.po index 39bdd647453..12b5d5a1c56 100644 --- a/addons/web/i18n/sk.po +++ b/addons/web/i18n/sk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/sl.po b/addons/web/i18n/sl.po index 687742a1775..0c745f42d41 100644 --- a/addons/web/i18n/sl.po +++ b/addons/web/i18n/sl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-11-02 05:20+0000\n" -"X-Generator: Launchpad (build 16218)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/sq.po b/addons/web/i18n/sq.po index df11fea07c0..357e83e2bcf 100644 --- a/addons/web/i18n/sq.po +++ b/addons/web/i18n/sq.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:02+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:07+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/sr@latin.po b/addons/web/i18n/sr@latin.po index f52bea117d6..9fc0e685c54 100644 --- a/addons/web/i18n/sr@latin.po +++ b/addons/web/i18n/sr@latin.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/sv.po b/addons/web/i18n/sv.po index 64fc3c7e767..db6d9f7ae88 100644 --- a/addons/web/i18n/sv.po +++ b/addons/web/i18n/sv.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/tr.po b/addons/web/i18n/tr.po index 2467938d84d..9c5554bc028 100644 --- a/addons/web/i18n/tr.po +++ b/addons/web/i18n/tr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/uk.po b/addons/web/i18n/uk.po index 2b981ebf178..553beb5d123 100644 --- a/addons/web/i18n/uk.po +++ b/addons/web/i18n/uk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/zh_CN.po b/addons/web/i18n/zh_CN.po index 09a7d041b88..e66a5742745 100644 --- a/addons/web/i18n/zh_CN.po +++ b/addons/web/i18n/zh_CN.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-11-07 04:55+0000\n" -"X-Generator: Launchpad (build 16232)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/i18n/zh_TW.po b/addons/web/i18n/zh_TW.po index b803a5c04c3..b07bc75ae31 100644 --- a/addons/web/i18n/zh_TW.po +++ b/addons/web/i18n/zh_TW.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web/static/src/js/chrome.js:176 diff --git a/addons/web/static/lib/jquery.tipsy/jquery.tipsy.js b/addons/web/static/lib/jquery.tipsy/jquery.tipsy.js index 5929d591261..e978042f21b 100644 --- a/addons/web/static/lib/jquery.tipsy/jquery.tipsy.js +++ b/addons/web/static/lib/jquery.tipsy/jquery.tipsy.js @@ -27,7 +27,8 @@ var $tip = this.tip(); $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title); - $tip[0].className = 'tipsy openerp oe_tooltip '; // reset classname in case of dynamic gravity + $tip[0].className = 'tipsy '; // reset classname in case of dynamic gravity + $tip.openerpClass('oe_tooltip'); $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body); var pos = $.extend({}, this.$element.offset(), { diff --git a/addons/web/static/lib/jquery.ui.bootstrap/css/custom-theme/jquery-ui-1.9.0.custom.css b/addons/web/static/lib/jquery.ui.bootstrap/css/custom-theme/jquery-ui-1.9.0.custom.css index a06e9447afc..f19c56caed1 100644 --- a/addons/web/static/lib/jquery.ui.bootstrap/css/custom-theme/jquery-ui-1.9.0.custom.css +++ b/addons/web/static/lib/jquery.ui.bootstrap/css/custom-theme/jquery-ui-1.9.0.custom.css @@ -1115,7 +1115,7 @@ body .ui-tooltip { border-width:2px; } /*** Input field styling from Bootstrap **/ - input, textarea { +/* input, textarea { -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; -moz-transition: border linear 0.2s, box-shadow linear 0.2s; -ms-transition: border linear 0.2s, box-shadow linear 0.2s; @@ -1137,12 +1137,12 @@ input[type=file]:focus, input[type=checkbox]:focus, select:focus { -moz-box-shadow: none; box-shadow: none; outline: 1px dotted #666; -} +}*/ -input[type="text"], -input[type="password"], +/*input[type="text"], +input[type="password"],*/ .ui-autocomplete-input, -textarea, +/*textarea,*/ .uneditable-input { display: inline-block; padding: 4px; diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 94d02758ad0..ab7b74f85fe 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -20,20 +20,6 @@ font-style: normal; } -@media print { - .oe_topbar, .oe_leftbar, .oe_loading { - display: none !important; - } -} -.openerp.openerp_webclient_container { - height: 100%; -} - -.text-tag .text-button { - height: auto !important; - min-height: 16px; -} - .openerp { padding: 0; margin: 0; @@ -46,6 +32,9 @@ * http://stackoverflow.com/questions/2855589/replace-input-type-file-by-an-image */ } +.openerp.openerp_webclient_container { + height: 100%; +} .openerp :-moz-placeholder { color: #afafb6 !important; font-style: italic !important; @@ -197,6 +186,10 @@ .openerp .oe_bounce_container { display: inline-block; } +.openerp .text-tag .text-button { + height: auto !important; + min-height: 16px; +} .openerp .ui-tabs { position: static; } @@ -1136,6 +1129,7 @@ height: 40px; width: 157px; margin: 14px 0; + border: 0; } .openerp .oe_footer { position: fixed; @@ -2306,16 +2300,16 @@ text-align: justify; } .openerp .oe_form_editable .oe_form .oe_form_field_integer input { - width: 6em !important; + width: 6em; } .openerp .oe_form_editable .oe_form .oe_form_field_float input { - width: 7em !important; + width: 7em; } .openerp .oe_form_editable .oe_form .oe_form_field_date input { - width: 7.5em !important; + width: 7.5em; } .openerp .oe_form_editable .oe_form .oe_form_field_datetime input { - width: 11.5em !important; + width: 11.5em; } .openerp .oe_hidden_input_file { position: relative; @@ -2361,6 +2355,77 @@ .openerp .oe_form .oe_form_field_image:hover .oe_form_field_image_controls { display: block; } +.openerp .oe_fileupload { + display: inline-block; + clear: both; + width: 100%; +} +.openerp .oe_fileupload .oe_add { + float: left; + position: relative; + width: 100%; + left: 2px; + top: 7px; +} +.openerp .oe_fileupload .oe_add button { + display: inline; + height: 24px; + font-size: 12px; + line-height: 12px; + vertical-align: middle; +} +.openerp .oe_fileupload .oe_add button.oe_attach { + width: 24px; + overflow: hidden; + width: 24px; + overflow: hidden; + background: transparent; + color: #7c7bad; + box-shadow: none; + border: none; + text-shadow: none; +} +.openerp .oe_fileupload .oe_add button.oe_attach .oe_e { + position: relative; + top: -1px; + left: -9px; +} +.openerp .oe_fileupload .oe_add input.oe_form_binary_file { + display: inline-block; + margin-left: -5px; + height: 28px; + width: 52px; + margin-top: -26px; +} +.openerp .oe_fileupload .oe_add .oe_attach_label { + color: #7c7bad; + margin-left: -3px; +} +.openerp .oe_fileupload .oe_attachments { + margin-bottom: 4px; + margin-right: 0px; + font-size: 12px; + border-radius: 2px; + border: solid 1px rgba(124, 123, 173, 0.14); +} +.openerp .oe_fileupload .oe_attachments .oe_attachment { + padding: 2px; + padding-left: 4px; + padding-right: 4px; +} +.openerp .oe_fileupload .oe_attachments .oe_attachment .oe_e { + font-size: 23px; + margin-top: -5px; +} +.openerp .oe_fileupload .oe_attachments .oe_attachment .oe_e:hover { + text-decoration: none; +} +.openerp .oe_fileupload .oe_attachments .oe_attachment:nth-child(odd) { + background: white; +} +.openerp .oe_fileupload .oe_attachments .oe_attachment:nth-child(even) { + background: #f4f5fa; +} .openerp .oe_form_field_many2one td:first-child { position: relative; } @@ -2374,6 +2439,9 @@ float: right; padding-left: 2px; } +.openerp .oe_form_field_many2one input { + padding-right: 13px; +} .openerp.ui-autocomplete li.oe_m2o_dropdown_option a { font-style: italic; padding-left: 2em; @@ -2578,32 +2646,33 @@ top: 5px; } .openerp .oe_list.oe_list_editable.oe_editing .oe_m2o_cm_button { - display: none; + line-height: 19px; +} +.openerp .oe_list.oe_list_editable.oe_editing .oe_input_icon { + margin-top: 5px; +} +.openerp .oe_list.oe_list_editable.oe_editing .oe_form_field { + min-width: 0; + max-width: none; } .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field input, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field textarea { height: 27px; -} -.openerp .oe_list.oe_list_editable.oe_editing .oe_form_field input, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field textarea { -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; border: 1px solid #aaaaff; margin: 0; } +.openerp .oe_list.oe_list_editable.oe_editing .oe_form_field input, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field textarea, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field select { + min-width: 0; +} .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field.oe_form_field_float input, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field.oe_form_view_integer input { text-align: right; width: 100% !important; } -.openerp .oe_list.oe_list_editable.oe_editing .oe_form_field.oe_form_field_datetime > span, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field.oe_form_field_date > span { - width: 100% !important; -} .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field.oe_form_field_datetime input.oe_datepicker_master, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field.oe_form_field_date input.oe_datepicker_master { width: 100% !important; } -.openerp .oe_list.oe_list_editable.oe_editing .oe_form_field .oe_form_field_float, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field .oe_form_view_integer, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field.oe_form_field_datetime, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field.oe_form_field_date { - min-width: 0 !important; - max-width: none !important; -} .openerp .oe_list_group_name { white-space: nowrap; } @@ -2668,6 +2737,9 @@ text-align: right !important; max-width: 100px; } +.openerp .oe_list_content td.oe_list_field_date, .openerp .oe_list_content th.oe_list_header_date { + min-width: 6em; +} .openerp .oe_list_content > thead { border-bottom: 2px solid #cacaca; background: #eeeeee; @@ -2735,6 +2807,10 @@ .openerp .oe_list_content > tbody > tr > td.oe_list_checkbox:first-child:after, .openerp .oe_list_content > tbody > tr th.oe_list_checkbox:first-child:after { border-width: 0; } +.openerp .oe_list_content > tbody > tr > td.oe_list_field_boolean input { + filter: alpha(opacity=50); + opacity: 0.5; +} .openerp .oe_list_content > tbody > tr:nth-child(odd) { background-color: #f0f0fa; background-color: #f0f0fa; @@ -2882,78 +2958,6 @@ color: #333333; } -.openerp .oe_fileupload { - display: inline-block; - clear: both; - width: 100%; -} -.openerp .oe_fileupload .oe_add { - float: left; - position: relative; - width: 100%; - left: 2px; - top: 7px; -} -.openerp .oe_fileupload .oe_add button { - display: inline; - height: 24px; - font-size: 12px; - line-height: 12px; - vertical-align: middle; -} -.openerp .oe_fileupload .oe_add button.oe_attach { - width: 24px; - overflow: hidden; - width: 24px; - overflow: hidden; - background: transparent; - color: #7c7bad; - box-shadow: none; - border: none; - text-shadow: none; -} -.openerp .oe_fileupload .oe_add button.oe_attach .oe_e { - position: relative; - top: -1px; - left: -9px; -} -.openerp .oe_fileupload .oe_add input.oe_form_binary_file { - display: inline-block; - margin-left: -5px; - height: 28px; - width: 52px; - margin-top: -26px; -} -.openerp .oe_fileupload .oe_add .oe_attach_label { - color: #7c7bad; - margin-left: -3px; -} -.openerp .oe_fileupload .oe_attachments { - margin-bottom: 4px; - margin-right: 0px; - font-size: 12px; - border-radius: 2px; - border: solid 1px rgba(124, 123, 173, 0.14); -} -.openerp .oe_fileupload .oe_attachments .oe_attachment { - padding: 2px; - padding-left: 4px; - padding-right: 4px; -} -.openerp .oe_fileupload .oe_attachments .oe_attachment .oe_e { - font-size: 23px; - margin-top: -5px; -} -.openerp .oe_fileupload .oe_attachments .oe_attachment .oe_e:hover { - text-decoration: none; -} -.openerp .oe_fileupload .oe_attachments .oe_attachment:nth-child(odd) { - background: white; -} -.openerp .oe_fileupload .oe_attachments .oe_attachment:nth-child(even) { - background: #f4f5fa; -} - .kitten-mode-activated { background-image: url(http://placekitten.com/g/1365/769); background-size: cover; @@ -3012,8 +3016,8 @@ div.ui-widget-overlay { .openerp { text-shadow: none; } - .openerp .oe_header_row, .openerp ul.oe_header, .openerp div.oe_mail_thread_action, .openerp .oe_mail_recthread_actions, .openerp .oe_button_box, .openerp .oe_form button, .openerp button.oe_invite, .openerp .oe_form header, .openerp .openerp .oe_notebook > li.ui-state-default { - display: none; + .openerp .oe_header_row, .openerp ul.oe_header, .openerp div.oe_mail_thread_action, .openerp .oe_mail_recthread_actions, .openerp .oe_button_box, .openerp .oe_form button, .openerp button.oe_invite, .openerp .oe_form header, .openerp .openerp .oe_notebook > li.ui-state-default, .openerp .oe_topbar, .openerp .oe_leftbar, .openerp .oe_loading { + display: none !important; } .openerp .oe_list_content button, .openerp .oe_list_content input[type=checkbox] { visibility: hidden; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index f911929e159..c5fcb8008a5 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -140,18 +140,6 @@ $sheet-padding: 16px // }}} -@media print - .oe_topbar, .oe_leftbar, .oe_loading - display: none !important - -.openerp.openerp_webclient_container - height: 100% - -// jQueryUI css bug fixing -.text-tag .text-button - height: auto !important - min-height: 16px - .openerp // Global style {{{ padding: 0 @@ -161,6 +149,8 @@ $sheet-padding: 16px font-size: 13px background: white text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5) + &.openerp_webclient_container + height: 100% // }}} //Placeholder style{{{ \:-moz-placeholder @@ -254,6 +244,11 @@ $sheet-padding: 16px .oe_bounce_container display: inline-block + // Bug lp:1051746 + .text-tag .text-button + height: auto !important + min-height: 16px + // bug noted in jquery ui CSS doesn't seem to occur in IE9, // so remove position:relative .ui-tabs @@ -928,6 +923,7 @@ $sheet-padding: 16px height: 40px width: 157px margin: 14px 0 + border: 0 .oe_footer position: fixed bottom: 0 @@ -1837,13 +1833,13 @@ $sheet-padding: 16px .oe_form_editable .oe_form .oe_form_field_integer input - width: 6em !important + width: 6em .oe_form_field_float input - width: 7em !important + width: 7em .oe_form_field_date input - width: 7.5em !important + width: 7.5em .oe_form_field_datetime input - width: 11.5em !important + width: 11.5em // }}} // FormView.fields_binary {{{ /* http://www.quirksmode.org/dom/inputfile.html @@ -1886,6 +1882,64 @@ $sheet-padding: 16px @include box-sizing(border) &:hover .oe_form_field_image_controls display: block + .oe_fileupload + display: inline-block + clear: both + width: 100% + .oe_add + float: left + position: relative + width: 100% + left: +2px + top: +7px + button + display: inline + height: 24px + font-size: 12px + line-height: 12px + vertical-align: middle + button.oe_attach + width: 24px + overflow: hidden + width: 24px + overflow: hidden + background: transparent + color: #7C7BAD + box-shadow: none + border: none + text-shadow: none + .oe_e + position: relative + top: -1px + left: -9px + input.oe_form_binary_file + display: inline-block + margin-left: -5px + height: 28px + width: 52px + margin-top: -26px + .oe_attach_label + color: #7C7BAD + margin-left: -3px + .oe_attachments + margin-bottom: 4px + margin-right: 0px + font-size: 12px + border-radius: 2px + border: solid 1px rgba(124,123,173,0.14) + .oe_attachment + padding: 2px + padding-left: 4px + padding-right: 4px + .oe_e + font-size: 23px + margin-top: -5px + .oe_e:hover + text-decoration: none + .oe_attachment:nth-child(odd) + background: white + .oe_attachment:nth-child(even) + background: #F4F5FA // }}} // FormView.many2one {{{ .oe_form_field_many2one @@ -1899,6 +1953,8 @@ $sheet-padding: 16px line-height: 14px float: right padding-left: 2px + input + padding-right: 13px &.ui-autocomplete li.oe_m2o_dropdown_option a font-style: italic @@ -2041,26 +2097,26 @@ $sheet-padding: 16px .oe_m2o_drop_down_button top: 5px .oe_m2o_cm_button - display: none + line-height: 19px + .oe_input_icon + margin-top: 5px .oe_form_field + min-width: 0 + max-width: none input, textarea height: $row-height - input, textarea @include radius(0) border: 1px solid #aaf margin: 0 + input, textarea, select + min-width: 0 &.oe_form_field_float,&.oe_form_view_integer input text-align: right width: 100% !important &.oe_form_field_datetime,&.oe_form_field_date - > span - width: 100% !important input.oe_datepicker_master width: 100% !important - .oe_form_field_float,.oe_form_view_integer,&.oe_form_field_datetime,&.oe_form_field_date - min-width: 0 !important - max-width: none !important .oe_list_group_name white-space: nowrap // }}} @@ -2119,6 +2175,8 @@ $sheet-padding: 16px td.oe_number text-align: right !important max-width: 100px + td.oe_list_field_date, th.oe_list_header_date + min-width: 6em > thead border-bottom: 2px solid #cacaca background: #eee @@ -2168,6 +2226,8 @@ $sheet-padding: 16px width: 17px &:after border-width: 0 + > td.oe_list_field_boolean input + @include opacity() > tr:nth-child(odd) background-color: #f0f0fa @include vertical-gradient(#f0f0fa, #eeeef6) @@ -2282,67 +2342,6 @@ $sheet-padding: 16px float: right color: #333 // }}} - -.openerp - .oe_fileupload - display: inline-block - clear: both - width: 100% - .oe_add - float: left - position: relative - width: 100% - left: +2px - top: +7px - button - display: inline - height: 24px - font-size: 12px - line-height: 12px - vertical-align: middle - button.oe_attach - width: 24px - overflow: hidden - width: 24px - overflow: hidden - background: transparent - color: #7C7BAD - box-shadow: none - border: none - text-shadow: none - .oe_e - position: relative - top: -1px - left: -9px - input.oe_form_binary_file - display: inline-block - margin-left: -5px - height: 28px - width: 52px - margin-top: -26px - .oe_attach_label - color: #7C7BAD - margin-left: -3px - .oe_attachments - margin-bottom: 4px - margin-right: 0px - font-size: 12px - border-radius: 2px - border: solid 1px rgba(124,123,173,0.14) - .oe_attachment - padding: 2px - padding-left: 4px - padding-right: 4px - .oe_e - font-size: 23px - margin-top: -5px - .oe_e:hover - text-decoration: none - .oe_attachment:nth-child(odd) - background: white - .oe_attachment:nth-child(even) - background: #F4F5FA - // Kitten Mode {{{ .kitten-mode-activated background-image: url(http://placekitten.com/g/1365/769) @@ -2352,11 +2351,13 @@ $sheet-padding: 16px opacity: 0.70 // }}} +// jQueryUI top level {{{ // The jQuery-ui overlay and Autocomplete are outside the .openerp div, please don't add indentation !!! div.ui-widget-overlay background: black @include opacity(0.3) - +// TODO: I think only the overlay is problematic, the other top level widgets should use $.fn.openerpClass() +// eg: $el.autocomplete().openerpClass(); .ui-widget font-family: "Lucida Grande", Helvetica, Verdana, Arial, sans-serif color: #4c4c4c @@ -2383,11 +2384,14 @@ div.ui-widget-overlay .ui-corner-all @include radius(3px) +// }}} +// @media print {{{ @media print .openerp - .oe_header_row, ul.oe_header, div.oe_mail_thread_action, .oe_mail_recthread_actions, .oe_button_box, .oe_form button, button.oe_invite, .oe_form header, .openerp .oe_notebook > li.ui-state-default - display: none + .oe_header_row, ul.oe_header, div.oe_mail_thread_action, .oe_mail_recthread_actions, .oe_button_box, .oe_form button, button.oe_invite, .oe_form header, .openerp .oe_notebook > li.ui-state-default, .oe_topbar, .oe_leftbar, .oe_loading + // We use !important here because jQuery adds @style = display: block on elements when using $.fn.show() + display: none !important .oe_list_content button, input[type=checkbox] visibility: hidden @@ -2413,5 +2417,7 @@ div.ui-widget-overlay background: none .openerp div.oe_mail_wall overflow: hidden !important +// }}} + // au BufWritePost,FileWritePost *.sass :!sass --style expanded --line-numbers > "%:p:r.css" // vim:tabstop=4:shiftwidth=4:softtabstop=4:fdm=marker: diff --git a/addons/web/static/src/js/boot.js b/addons/web/static/src/js/boot.js index 05ce709e80a..631a7f8c6f5 100644 --- a/addons/web/static/src/js/boot.js +++ b/addons/web/static/src/js/boot.js @@ -19,12 +19,14 @@ /** * OpenERP instance constructor * - * @param {Array} modules list of modules to initialize + * @param {Array|String} modules list of modules to initialize */ init: function(modules) { - // By default only web will be loaded, the rest will be by loaded - // by openerp.web.Session on the first session_authenticate - modules = _.union(['web'], modules || []); + if (modules === "fuck your shit, don't load anything you cunt") { + modules = []; + } else { + modules = _.union(['web'], modules || []); + } var new_instance = { // links to the global openerp _openerp: openerp, diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 69dafa08c02..b95550c74a0 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -48,7 +48,7 @@ instance.web.Notification = instance.web.Widget.extend({ */ instance.web.dialog = function(element) { var result = element.dialog.apply(element, _.rest(_.toArray(arguments))); - result.dialog("widget").addClass("openerp"); + result.dialog("widget").openerpClass(); return result; }; @@ -190,7 +190,14 @@ instance.web.Dialog = instance.web.Widget.extend({ }); instance.web.CrashManager = instance.web.Class.extend({ + init: function() { + this.active = true; + }, + rpc_error: function(error) { + if (!this.active) { + return; + } if (error.data.fault_code) { var split = ("" + error.data.fault_code).split('\n')[0].split(' -- '); if (split.length > 1) { @@ -205,6 +212,9 @@ instance.web.CrashManager = instance.web.Class.extend({ } }, show_warning: function(error) { + if (!this.active) { + return; + } instance.web.dialog($('
' + QWeb.render('CrashManager.warning', {error: error}) + '
'), { title: "OpenERP " + _.str.capitalize(error.type), buttons: [ @@ -213,7 +223,9 @@ instance.web.CrashManager = instance.web.Class.extend({ }); }, show_error: function(error) { - var self = this; + if (!this.active) { + return; + } var buttons = {}; buttons[_t("Ok")] = function() { $(this).dialog("close"); @@ -310,7 +322,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ self.db_list = null; }); var fetch_langs = this.rpc("/web/session/get_lang_list", {}).done(function(result) { - self.lang_list = result.lang_list; + self.lang_list = result; }); return $.when(fetch_db, fetch_langs).done(self.do_render); }, @@ -333,6 +345,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ self.$el.find("tr td:first-child").addClass("oe_form_group_cell_label"); self.$el.find("label").addClass("oe_form_label"); self.$el.find("form[name=create_db_form]").validate({ submitHandler: self.do_create }); + self.$el.find("form[name=duplicate_db_form]").validate({ submitHandler: self.do_duplicate }); self.$el.find("form[name=drop_db_form]").validate({ submitHandler: self.do_drop }); self.$el.find("form[name=backup_db_form]").validate({ submitHandler: self.do_backup }); self.$el.find("form[name=restore_db_form]").validate({ submitHandler: self.do_restore }); @@ -418,6 +431,18 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ self.do_action(client_action); }); }, + do_duplicate: function(form) { + var self = this; + var fields = $(form).serializeArray(); + self.rpc("/web/database/duplicate", {'fields': fields}).then(function(result) { + if (result.error) { + self.display_error(result); + return; + } + self.do_notify("Duplicating database", "The database has been duplicated."); + self.start(); + }); + }, do_drop: function(form) { var self = this; var $form = $(form), @@ -518,6 +543,9 @@ instance.web.Login = instance.web.Widget.extend({ this.selected_db = null; this.selected_login = null; this.params = action.params || {}; + if (_.isEmpty(this.params)) { + this.params = $.bbq.getState(true); + } if (this.params.login_successful) { this.on('login_successful', this, this.params.login_successful); @@ -619,9 +647,35 @@ instance.web.Login = instance.web.Widget.extend({ }); instance.web.client_actions.add("login", "instance.web.Login"); +/** + * Redirect to url by replacing window.location + * If wait is true, sleep 1s and wait for the server i.e. after a restart. + */ +instance.web.redirect = function(url, wait) { + // Dont display a dialog if some xmlhttprequest are in progress + if (instance.client && instance.client.crashmanager) { + instance.client.crashmanager.active = false; + } + + var wait_server = function() { + instance.session.rpc("/web/webclient/version_info", {}).done(function() { + window.location = url; + }).fail(function() { + setTimeout(wait_server, 250); + }); + }; + + if (wait) { + setTimeout(wait_server, 1000); + } else { + window.location = url; + } +}; + /** * Client action to reload the whole interface. - * If params has an entry 'menu_id', it opens the given menu entry. + * If params.menu_id, it opens the given menu entry. + * If params.wait, reload will wait the openerp server to be reachable before reloading */ instance.web.Reload = function(parent, action) { var params = action.params || {}; @@ -637,8 +691,8 @@ instance.web.Reload = function(parent, action) { hash = "#menu_id=" + menu_id; } var url = l.protocol + "//" + l.host + l.pathname + search + hash; - window.onerror = function() {}; - window.location = url; + + instance.web.redirect(url, params.wait); }; instance.web.client_actions.add("reload", "instance.web.Reload"); @@ -648,7 +702,7 @@ instance.web.client_actions.add("reload", "instance.web.Reload"); */ instance.web.HistoryBack = function(parent) { if (!parent.history_back()) { - window.location = '/' + (window.location.search || ''); + instance.web.Home(parent); } }; instance.web.client_actions.add("history_back", "instance.web.HistoryBack"); @@ -656,11 +710,10 @@ instance.web.client_actions.add("history_back", "instance.web.HistoryBack"); /** * Client action to go back home. */ -instance.web.Home = instance.web.Widget.extend({ - init: function(parent) { - window.location = '/' + (window.location.search || ''); - } -}); +instance.web.Home = function(parent, action) { + var url = '/' + (window.location.search || ''); + instance.web.redirect(url, action.params && action.params.wait); +}; instance.web.client_actions.add("home", "instance.web.Home"); instance.web.ChangePassword = instance.web.Widget.extend({ @@ -887,7 +940,7 @@ instance.web.UserMenu = instance.web.Widget.extend({ if(res.company_id[0] > 1) topbar_name = _.str.sprintf("%s (%s)", topbar_name, res.company_id[1]); self.$el.find('.oe_topbar_name').text(topbar_name); - var avatar_src = _.str.sprintf('%s/web/binary/image?session_id=%s&model=res.users&field=image_small&id=%s', self.session.prefix, self.session.session_id, self.session.uid); + var avatar_src = self.session.url('/web/binary/image', {model:'res.users', field: 'image_small', id: self.session.uid}); $avatar.attr('src', avatar_src); }); }; @@ -899,7 +952,7 @@ instance.web.UserMenu = instance.web.Widget.extend({ on_menu_settings: function() { var self = this; if (!this.getParent().has_uncommitted_changes()) { - self.rpc("/web/action/load", { action_id: "base.action_res_users_my" }, function(result) { + self.rpc("/web/action/load", { action_id: "base.action_res_users_my" }).done(function(result) { result.res_id = instance.session.uid; self.getParent().action_manager.do_action(result); }); @@ -930,6 +983,7 @@ instance.web.Client = instance.web.Widget.extend({ return instance.session.session_bind(this.origin).then(function() { var $e = $(QWeb.render(self._template, {})); self.replaceElement($e); + $e.openerpClass(); self.bind_events(); return self.show_common(); }); @@ -1106,10 +1160,10 @@ instance.web.WebClient = instance.web.Client.extend({ var self = this; var state = event.getState(true); if (!_.isEqual(this._current_state, state)) { - if(state.action_id === undefined && state.menu_id) { + if(!state.action && state.menu_id) { self.menu.has_been_loaded.done(function() { self.menu.do_reload().done(function() { - self.menu.menu_click(state.menu_id) + self.menu.menu_click(state.menu_id); }); }); } else { diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js index 4012be526e6..06b3940f1e1 100644 --- a/addons/web/static/src/js/corelib.js +++ b/addons/web/static/src/js/corelib.js @@ -774,10 +774,10 @@ instance.web.Widget = instance.web.Class.extend(instance.web.PropertiesMixin, { } return false; }, - rpc: function(url, data, success, error) { - var def = $.Deferred().done(success).fail(error); + rpc: function(url, data, options) { + var def = $.Deferred(); var self = this; - instance.session.rpc(url, data).done(function() { + instance.session.rpc(url, data, options).done(function() { if (!self.isDestroyed()) def.resolve.apply(def, arguments); }).fail(function() { @@ -1231,12 +1231,14 @@ instance.web.JsonRPC = instance.web.Class.extend(instance.web.PropertiesMixin, { * * @param {String} url RPC endpoint * @param {Object} params call parameters + * @param {Object} options additional options for rpc call * @param {Function} success_callback function to execute on RPC call success * @param {Function} error_callback function to execute on RPC call failure * @returns {jQuery.Deferred} jquery-provided ajax deferred */ - rpc: function(url, params) { + rpc: function(url, params, options) { var self = this; + options = options || {}; // url can be an $.ajax option object if (_.isString(url)) { url = { url: url }; @@ -1251,10 +1253,12 @@ instance.web.JsonRPC = instance.web.Class.extend(instance.web.PropertiesMixin, { id: _.uniqueId('r') }; var deferred = $.Deferred(); - this.trigger('request', url, payload); + if (! options.shadow) + this.trigger('request', url, payload); var request = this.rpc_function(url, payload).done( function (response, textStatus, jqXHR) { - self.trigger('response', response); + if (! options.shadow) + self.trigger('response', response); if (!response.error) { if (url.url === '/web/session/eval_domain_and_context') { self.test_eval(params, response.result); @@ -1268,7 +1272,8 @@ instance.web.JsonRPC = instance.web.Class.extend(instance.web.PropertiesMixin, { } ).fail( function(jqXHR, textStatus, errorThrown) { - self.trigger('response_failed', jqXHR); + if (! options.shadow) + self.trigger('response_failed', jqXHR); var error = { code: -32098, message: "XmlHttpRequestError " + errorThrown, @@ -1276,7 +1281,7 @@ instance.web.JsonRPC = instance.web.Class.extend(instance.web.PropertiesMixin, { }; deferred.reject(error, $.Event()); }); - // Allow deferred user to disable on_rpc_error in fail + // Allow deferred user to disable rpc_error call in fail deferred.fail(function() { deferred.fail(function(error, event) { if (!event.isDefaultPrevented()) { @@ -1309,9 +1314,18 @@ instance.web.JsonRPC = instance.web.Class.extend(instance.web.PropertiesMixin, { // extracted from payload to set on the url var data = { session_id: this.session_id, - id: payload.id + id: payload.id, + sid: this.httpsessionid, }; - url.url = this.get_url(url.url); + + var set_sid = function (response, textStatus, jqXHR) { + // If response give us the http session id, we store it for next requests... + if (response.httpsessionid) { + self.httpsessionid = response.httpsessionid; + } + }; + + url.url = this.url(url.url, null); var ajax = _.extend({ type: "GET", dataType: 'jsonp', @@ -1326,7 +1340,7 @@ instance.web.JsonRPC = instance.web.Class.extend(instance.web.PropertiesMixin, { if(payload_url.length < 2000) { // Direct jsonp request ajax.data.r = payload_str; - return $.ajax(ajax); + return $.ajax(ajax).done(set_sid); } else { // Indirect jsonp request var ifid = _.uniqueId('oe_rpc_iframe'); @@ -1364,11 +1378,20 @@ instance.web.JsonRPC = instance.web.Class.extend(instance.web.PropertiesMixin, { }); // append the iframe to the DOM (will trigger the first load) $form.after($iframe); - return deferred; + return deferred.done(set_sid); } }, - get_url: function (file) { - return this.prefix + file; + + url: function(path, params) { + var qs = ''; + if (!_.isNull(params)) { + params = _.extend(params || {}, {session_id: this.session_id}); + if (this.httpsessionid) { + params.sid = this.httpsessionid; + } + qs = '?' + $.param(params); + } + return this.prefix + path + qs; }, }); diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js index 5ff47aa32fa..7ddefa301f2 100644 --- a/addons/web/static/src/js/coresetup.js +++ b/addons/web/static/src/js/coresetup.js @@ -3,10 +3,13 @@ *--------------------------------------------------------*/ var console; if (!console) { - console = {log: function () {}}; -} -if (!console.debug) { - console.debug = console.log; + // Even IE9 only exposes console object if debug window opened + console = {}; + ('log error debug info warn assert clear dir dirxml trace group' + + ' groupCollapsed groupEnd time timeEnd profile profileEnd count' + + ' exception').split(/\s+/).forEach(function(property) { + console[property] = _.identity; + }); } openerp.web.coresetup = function(instance) { @@ -19,9 +22,9 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess this.name = instance._session_id; this.qweb_mutex = new $.Mutex(); }, - rpc: function(url, params) { + rpc: function(url, params, options) { params.session_id = this.session_id; - return this._super(url, params); + return this._super(url, params, options); }, /** * Setup a sessionm @@ -198,7 +201,7 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess var self = this; _.each(files, function (file) { $('head').append($('', { - 'href': self.get_url(file), + 'href': self.url(file, null), 'rel': 'stylesheet', 'type': 'text/css' })); @@ -207,11 +210,11 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess load_js: function(files) { var self = this; var d = $.Deferred(); - if(files.length != 0) { + if(files.length !== 0) { var file = files.shift(); var tag = document.createElement('script'); tag.type = 'text/javascript'; - tag.src = self.get_url(file); + tag.src = self.url(file, null); tag.onload = tag.onreadystatechange = function() { if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done ) return; @@ -457,6 +460,16 @@ $.fn.getAttributes = function() { } return o; } +$.fn.openerpClass = function(additionalClass) { + // This plugin should be applied on top level elements + additionalClass = additionalClass || ''; + if (!!$.browser.msie) { + additionalClass += ' openerp_ie'; + } + return this.each(function() { + $(this).addClass('openerp ' + additionalClass); + }); +}; /** Jquery extentions */ $.Mutex = (function() { diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index dcdeb749672..524a88bdc48 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -278,9 +278,10 @@ instance.web.Model = instance.web.Class.extend({ * @param {String} method name of the method to call * @param {Array} [args] positional arguments * @param {Object} [kwargs] keyword arguments + * @param {Object} [options] additional options for the rpc() method * @returns {jQuery.Deferred<>} call result */ - call: function (method, args, kwargs) { + call: function (method, args, kwargs, options) { args = args || []; kwargs = kwargs || {}; if (!_.isArray(args)) { @@ -294,7 +295,7 @@ instance.web.Model = instance.web.Class.extend({ method: method, args: args, kwargs: kwargs - }); + }, options); }, /** * Fetches a Query instance bound to this model, for searching @@ -721,10 +722,10 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({ this.last_default_get = {}; }, default_get: function(fields, options) { - return this._super(fields, options).done(this.on_default_get); - }, - on_default_get: function(res) { - this.last_default_get = res; + var self = this; + return this._super(fields, options).done(function(res) { + self.last_default_get = res; + }); }, create: function(data) { var cached = {id:_.uniqueId(this.virtual_id_prefix), values: data, diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index 03b2c5b775d..e586b94db6b 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -83,6 +83,42 @@ instance.web.strip_raw_chars = function (value) { var normalize_format = function (format) { return Date.normalizeFormat(instance.web.strip_raw_chars(format)); }; + +/** + * Check with a scary heuristic if the value is a bin_size or not. + * If not, compute an approximate size out of the base64 encoded string. + * + * @param {String} value original format + */ +instance.web.binary_to_binsize = function (value) { + if (!value) { + return instance.web.human_size(0); + } + if (value.substr(0, 10).indexOf(' ') == -1) { + // Computing approximate size out of base64 encoded string + // http://en.wikipedia.org/wiki/Base64#MIME + return instance.web.human_size(value.length / 1.37); + } else { + // already bin_size + return value; + } +}; + +/** + * Returns a human readable size + * + * @param {Number} numner of bytes + */ +instance.web.human_size = function(size) { + var units = _t("Bytes,Kb,Mb,Gb,Tb,Pb,Eb,Zb,Yb").split(','); + var i = 0; + while (size >= 1024) { + size /= 1024; + ++i; + } + return size.toFixed(2) + ' ' + units[i]; +}; + /** * Formats a single atomic value based on a field descriptor * diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index e84ea66ff9a..0f25b2484c3 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -349,7 +349,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea $.when(load_view) .then(function(r) { self.search_view_loaded(r) - }).fail(function () { + }, function () { self.ready.reject.apply(null, arguments); }); } @@ -459,7 +459,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea complete_global_search: function (req, resp) { $.when.apply(null, _(this.inputs).chain() .invoke('complete', req.term) - .value()).done(function () { + .value()).then(function () { resp(_(_(arguments).compact()).flatten(true)); }); }, @@ -527,7 +527,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea childView.on('blurred', self, self.proxy('childBlurred')); }); - $.when.apply(null, started).done(function () { + $.when.apply(null, started).then(function () { var input_to_focus; // options.at: facet inserted at given index, focus next input // otherwise just focus last input @@ -608,7 +608,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea // add Filters to this.inputs, need view.controls filled (new instance.web.search.Filters(this)); // add custom filters to this.inputs - (new instance.web.search.CustomFilters(this)); + this.custom_filters = new instance.web.search.CustomFilters(this); // add Advanced to this.inputs (new instance.web.search.Advanced(this)); }, @@ -635,16 +635,41 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea // load defaults var defaults_fetched = $.when.apply(null, _(this.inputs).invoke( - 'facet_for_defaults', this.defaults)).done(function () { - self.query.reset(_(arguments).compact(), {preventSearch: true}); - }); - + 'facet_for_defaults', this.defaults)) + .then(this.proxy('setup_default_query')); + return $.when(drawer_started, defaults_fetched) .done(function () { self.trigger("search_view_loaded", data); self.ready.resolve(); }); }, + setup_default_query: function () { + // Hacky implementation of CustomFilters#facet_for_defaults ensure + // CustomFilters will be ready (and CustomFilters#filters will be + // correctly filled) by the time this method executes. + var custom_filters = this.custom_filters.filters; + if (!_(custom_filters).isEmpty()) { + // Check for any is_default custom filter + var personal_filter = _(custom_filters).find(function (filter) { + return filter.user_id && filter.is_default; + }); + if (personal_filter) { + this.custom_filters.enable_filter(personal_filter, true); + return; + } + + var global_filter = _(custom_filters).find(function (filter) { + return !filter.user_id && filter.is_default; + }); + if (global_filter) { + this.custom_filters.enable_filter(global_filter, true); + return; + } + } + // No custom filter, or no is_default custom filter, apply view defaults + this.query.reset(_(arguments).compact(), {preventSearch: true}); + }, /** * Extract search data from the view's facets. * @@ -1460,10 +1485,15 @@ instance.web.search.ManyToOneField = instance.web.search.CharField.extend({ instance.web.search.CustomFilters = instance.web.search.Input.extend({ template: 'SearchView.CustomFilters', _in_drawer: true, + init: function () { + this.is_ready = $.Deferred(); + this._super.apply(this, arguments); + }, start: function () { var self = this; this.model = new instance.web.Model('ir.filters'); this.filters = {}; + this.$filters = {}; this.view.query .on('remove', function (facet) { if (!facet.get('is_custom_filter')) { @@ -1479,24 +1509,78 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({ // FIXME: local eval of domain and context to get rid of special endpoint return this.rpc('/web/searchview/get_filters', { model: this.view.model - }).then(this.proxy('set_filters')); + }) + .then(this.proxy('set_filters')) + .then(function () { + self.is_ready.resolve(null); + }, function () { + self.is_ready.reject(); + }); + }, + /** + * Special implementation delaying defaults until CustomFilters is loaded + */ + facet_for_defaults: function () { + return this.is_ready; + }, + /** + * Generates a mapping key (in the filters and $filter mappings) for the + * filter descriptor object provided (as returned by ``get_filters``). + * + * The mapping key is guaranteed to be unique for a given (user_id, name) + * pair. + * + * @param {Object} filter + * @param {String} filter.name + * @param {Number|Pair} [filter.user_id] + * @return {String} mapping key corresponding to the filter + */ + key_for: function (filter) { + var user_id = filter.user_id; + var uid = (user_id instanceof Array) ? user_id[0] : user_id; + return _.str.sprintf('(%s)%s', uid, filter.name); + }, + /** + * Generates a :js:class:`~instance.web.search.Facet` descriptor from a + * filter descriptor + * + * @param {Object} filter + * @param {String} filter.name + * @param {Object} [filter.context] + * @param {Array} [filter.domain] + * @return {Object} + */ + facet_for: function (filter) { + return { + category: _t("Custom Filter"), + icon: 'M', + field: { + get_context: function () { return filter.context; }, + get_groupby: function () { return [filter.context]; }, + get_domain: function () { return filter.domain; } + }, + is_custom_filter: true, + values: [{label: filter.name, value: null}] + }; }, clear_selection: function () { this.$('li.oe_selected').removeClass('oe_selected'); }, append_filter: function (filter) { var self = this; - var key = _.str.sprintf('(%s)%s', filter.user_id, filter.name); + var key = this.key_for(filter); var $filter; - if (key in this.filters) { - $filter = this.filters[key]; + if (key in this.$filters) { + $filter = this.$filters[key]; } else { var id = filter.id; - $filter = this.filters[key] = $('
  • ') + this.filters[key] = filter; + $filter = this.$filters[key] = $('
  • ') .appendTo(this.$('.oe_searchview_custom_list')) .addClass(filter.user_id ? 'oe_searchview_custom_private' : 'oe_searchview_custom_public') + .toggleClass('oe_searchview_custom_default', filter.is_default) .text(filter.name); $('x') @@ -1504,33 +1588,30 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({ e.stopPropagation(); self.model.call('unlink', [id]).done(function () { $filter.remove(); + delete self.$filters[key]; + delete self.filters[key]; }); }) .appendTo($filter); } $filter.unbind('click').click(function () { - self.view.query.reset([{ - category: _t("Custom Filter"), - icon: 'M', - field: { - get_context: function () { return filter.context; }, - get_groupby: function () { return [filter.context]; }, - get_domain: function () { return filter.domain; } - }, - is_custom_filter: true, - values: [{label: filter.name, value: null}] - }]); - $filter.addClass('oe_selected'); + self.enable_filter(filter); }); }, + enable_filter: function (filter, preventSearch) { + this.view.query.reset([this.facet_for(filter)], { + preventSearch: preventSearch || false}); + this.$filters[this.key_for(filter)].addClass('oe_selected'); + }, set_filters: function (filters) { _(filters).map(_.bind(this.append_filter, this)); }, save_current: function () { var self = this; var $name = this.$('input:first'); - var private_filter = !this.$('input:last').prop('checked'); + var private_filter = !this.$('#oe_searchview_custom_public').prop('checked'); + var set_as_default = this.$('#oe_searchview_custom_default').prop('checked'); var search = this.view.build_search_data(); this.rpc('/web/session/eval_domain_and_context', { @@ -1546,7 +1627,8 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({ user_id: private_filter ? instance.session.uid : false, model_id: self.view.model, context: results.context, - domain: results.domain + domain: results.domain, + is_default: set_as_default }; // FIXME: current context? return self.model.call('create_or_replace', [filter]).done(function (id) { diff --git a/addons/web/static/src/js/testing.js b/addons/web/static/src/js/testing.js new file mode 100644 index 00000000000..bf39f543734 --- /dev/null +++ b/addons/web/static/src/js/testing.js @@ -0,0 +1,393 @@ +// Test support structures and methods for OpenERP +openerp.testing = {}; +(function (testing) { + var dependencies = { + corelib: [], + coresetup: ['corelib'], + data: ['corelib', 'coresetup'], + dates: [], + formats: ['coresetup', 'dates'], + chrome: ['corelib', 'coresetup'], + views: ['corelib', 'coresetup', 'data', 'chrome'], + search: ['data', 'coresetup', 'formats'], + list: ['views', 'data'], + form: ['data', 'views', 'list', 'formats'], + list_editable: ['list', 'form', 'data'], + }; + + testing.dependencies = window['oe_all_dependencies'] || []; + testing.current_module = null; + testing.templates = { }; + testing.add_template = function (name) { + var xhr = QWeb2.Engine.prototype.get_xhr(); + xhr.open('GET', name, false); + xhr.send(null); + (testing.templates[testing.current_module] = + testing.templates[testing.current_module] || []) + .push(xhr.responseXML); + }; + /** + * Function which does not do anything + */ + testing.noop = function () { }; + /** + * Alter provided instance's ``session`` attribute to make response + * mockable: + * + * * The ``responses`` parameter can be used to provide a map of (RPC) + * paths (e.g. ``/web/view/load``) to a function returning a response + * to the query. + * * ``instance.session`` grows a ``responses`` attribute which is + * a map of the same (and is in fact initialized to the ``responses`` + * parameter if one is provided) + * + * Note that RPC requests to un-mocked URLs will be rejected with an + * error message: only explicitly specified urls will get a response. + * + * Mocked sessions will *never* perform an actual RPC connection. + * + * @param instance openerp instance being initialized + * @param {Object} [responses] + */ + testing.mockifyRPC = function (instance, responses) { + var session = instance.session; + session.responses = responses || {}; + session.rpc_function = function (url, payload) { + var fn, params; + var needle = payload.params.model + ':' + payload.params.method; + if (url.url === '/web/dataset/call_kw' + && needle in this.responses) { + fn = this.responses[needle]; + params = [ + payload.params.args || [], + payload.params.kwargs || {} + ]; + } else { + fn = this.responses[url.url]; + params = [payload]; + } + + if (!fn) { + return $.Deferred().reject({}, 'failed', + _.str.sprintf("Url %s not found in mock responses, with arguments %s", + url.url, JSON.stringify(payload.params)) + ).promise(); + } + try { + return $.when(fn.apply(null, params)).then(function (result) { + // Wrap for RPC layer unwrapper thingy + return {result: result}; + }); + } catch (e) { + // not sure why this looks like that + return $.Deferred().reject({}, 'failed', String(e)); + } + }; + }; + + var StackProto = { + execute: function (fn) { + var args = [].slice.call(arguments, 1); + // Warning: here be dragons + var i = 0, setups = this.setups, teardowns = this.teardowns; + var d = $.Deferred(); + + var succeeded, failed; + var success = function () { + succeeded = _.toArray(arguments); + return teardown(); + }; + var failure = function () { + // save first failure + if (!failed) { + failed = _.toArray(arguments); + } + // chain onto next teardown + return teardown(); + }; + + var setup = function () { + // if setup to execute + if (i < setups.length) { + var f = setups[i] || testing.noop; + $.when(f.apply(null, args)).then(function () { + ++i; + setup(); + }, failure); + } else { + $.when(fn.apply(null, args)).then(success, failure); + } + }; + var teardown = function () { + // if teardown to execute + if (i > 0) { + var f = teardowns[--i] || testing.noop; + $.when(f.apply(null, args)).then(teardown, failure); + } else { + if (failed) { + d.reject.apply(d, failed); + } else if (succeeded) { + d.resolve.apply(d, succeeded); + } else { + throw new Error("Didn't succeed or fail?"); + } + } + }; + setup(); + + return d; + }, + push: function (setup, teardown) { + return _.extend(Object.create(StackProto), { + setups: this.setups.concat([setup]), + teardowns: this.teardowns.concat([teardown]) + }); + }, + unshift: function (setup, teardown) { + return _.extend(Object.create(StackProto), { + setups: [setup].concat(this.setups), + teardowns: [teardown].concat(this.teardowns) + }); + } + }; + /** + * + * @param {Function} [setup] + * @param {Function} [teardown] + * @return {*} + */ + testing.Stack = function (setup, teardown) { + return _.extend(Object.create(StackProto), { + setups: setup ? [setup] : [], + teardowns: teardown ? [teardown] : [] + }); + }; + + var db = window['oe_db_info']; + testing.section = function (name, options, body) { + if (_.isFunction(options)) { + body = options; + options = {}; + } + _.defaults(options, { + setup: testing.noop, + teardown: testing.noop + }); + + QUnit.module(testing.current_module + '.' + name, {_oe: options}); + body(testing.case); + }; + testing.case = function (name, options, callback) { + if (_.isFunction(options)) { + callback = options; + options = {}; + } + + var module = testing.current_module; + var module_index = _.indexOf(testing.dependencies, module); + var module_deps = testing.dependencies.slice( + // If module not in deps (because only tests, no JS) -> indexOf + // returns -1 -> index becomes 0 -> replace with ``undefined`` so + // Array#slice returns a full copy + 0, module_index + 1 || undefined); + + // Serialize options for this precise test case + // WARNING: typo is from jquery, do not fix! + var env = QUnit.config.currentModuleTestEnviroment; + // section setup + // case setup + // test + // case teardown + // section teardown + var case_stack = testing.Stack() + .push(env._oe.setup, env._oe.teardown) + .push(options.setup, options.teardown); + var opts = _.defaults({}, options, env._oe); + // FIXME: if this test is ignored, will still query + if (opts.rpc === 'rpc' && !db) { + QUnit.config.autostart = false; + db = { + source: null, + supadmin: null, + password: null + }; + var $msg = $('
    ') + .append('

    A test needs to clone a database

    ') + .append('

    Please provide the source clone information

    ') + .append(' Source DB: ').append('').append('
    ') + .append(' DB Password: ').append('').append('
    ') + .append('Admin Password: ').append('').append('
    ') + .append('') + .submit(function (e) { + e.preventDefault(); + e.stopPropagation(); + db.source = $msg.find('input[name=source]').val(); + db.supadmin = $msg.find('input[name=supadmin]').val(); + db.password = $msg.find('input[name=password]').val(); + QUnit.start(); + $.unblockUI(); + }); + $.blockUI({ + message: $msg, + css: { + fontFamily: 'monospace', + textAlign: 'left', + whiteSpace: 'pre-wrap', + cursor: 'default' + } + }); + } + + QUnit.test(name, function () { + var instance; + if (!opts.dependencies) { + instance = openerp.init(module_deps); + } else { + // empty-but-specified dependencies actually allow running + // without loading any module into the instance + + // TODO: clean up this mess + var d = opts.dependencies.slice(); + // dependencies list should be in deps order, reverse to make + // loading order from last + d.reverse(); + var di = 0; + while (di < d.length) { + var m = /^web\.(\w+)$/.exec(d[di]); + if (m) { + d[di] = m[1]; + } + d.splice.apply(d, [di+1, 0].concat( + _(dependencies[d[di]]).reverse())); + ++di; + } + + instance = openerp.init("fuck your shit, don't load anything you cunt"); + _(d).chain() + .reverse() + .uniq() + .each(function (module) { + openerp.web[module](instance); + }); + } + if (_.isNumber(opts.asserts)) { + expect(opts.asserts); + } + + if (opts.templates) { + for(var i=0; i got xml as string + // -> parse to xml and manipulate domains and contexts + // -> convert to json + // client: + // -> got view as json + // -> convert back to xml as string + // -> parse it as xml doc (manipulate button@type for IE) + // -> convert back to string + // -> parse it as dom element with jquery + // -> for each widget, convert node to json + // + // Wow !!! + var xml = instance.web.json_node_to_xml(arch); + + var doc = $.parseXML('
    ' + xml + '
    '); + $('button', doc).each(function() { + $(this).attr('data-button-type', $(this).attr('type')); + }); + xml = instance.web.xml_to_str(doc); + return $(xml); + }, render_to: function($target) { var self = this; this.$target = $target; - // TODO: I know this will save the world and all the kitten for a moment, - // but one day, we will have to get rid of xml2json - var xml = instance.web.json_node_to_xml(this.fvg.arch); - this.$form = $('
    ' + xml + '
    '); + this.$form = this.view_arch_to_dom_node(this.fvg.arch); this.process_version(); @@ -1863,6 +1893,7 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({ template: 'WidgetButton', init: function(field_manager, node) { + node.attrs.type = node.attrs['data-button-type']; this._super(field_manager, node); this.force_disabled = false; this.string = (this.node.attrs.string || '').replace(/_/g, ''); @@ -2152,17 +2183,10 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w }, set_dimensions: function (height, width) { - // remove width css property - this.$el.css('width', ''); - // extract style (without width) - var old_style = this.$el.attr('style'); - // jQuery doesn't understand/use !important - var style = 'width:' + width + 'px !important;'; - if (old_style) { - style += old_style - } - this.$el.attr('style', style); - this.$el.css('minHeight', height); + this.$el.css({ + width: width, + minHeight: height + }); }, commit_value: function() { return $.when(); @@ -2386,7 +2410,7 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ self.$input.focus(); return; } - self.picker('setDate', self.value ? instance.web.auto_str_to_date(self.value) : new Date()); + self.picker('setDate', self.get('value') ? instance.web.auto_str_to_date(self.get('value')) : new Date()); self.$input_picker.show(); self.picker('show'); self.$input_picker.hide(); @@ -3102,7 +3126,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc minLength: 0, delay: 0 }); - this.$input.autocomplete("widget").addClass("openerp"); + this.$input.autocomplete("widget").openerpClass(); // used to correct a bug when selecting an element by pushing 'enter' in an editable list this.$input.keyup(function(e) { if (e.which === 13) { // ENTER @@ -3813,26 +3837,13 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ this._super.apply(this, arguments); }, do_delete: function (ids) { - var self = this; - var next = $.when(); - var _super = this._super; - // handle deletion of an item which does not exist - // TODO: better handle that in the editable list? - var false_id_index = _(ids).indexOf(false); - if (false_id_index !== -1) { - ids.splice(false_id_index, 1); - next = this.cancel_edition(true); + var confirm = window.confirm; + window.confirm = function () { return true; }; + try { + return this._super(ids); + } finally { + window.confirm = confirm; } - return next.then(function () { - // wheeee - var confirm = window.confirm; - window.confirm = function () { return true; }; - try { - return _super.call(self, ids); - } finally { - window.confirm = confirm; - } - }); } }); instance.web.form.One2ManyGroups = instance.web.ListView.Groups.extend({ @@ -3995,13 +4006,18 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in self._drop_shown = true; }); self.tags = self.$text.textext()[0].tags(); - self.$text.focusout(function() { - self.$text.trigger("setInputData", ""); - }).keydown(function(e) { - if (e.which === $.ui.keyCode.TAB && self._drop_shown) { - self.$text.textext()[0].autocomplete().selectFromDropdown(); - } - }); + self.$text + .focusin(function () { + self.trigger('focused'); + }) + .focusout(function() { + self.$text.trigger("setInputData", ""); + self.trigger('blurred'); + }).keydown(function(e) { + if (e.which === $.ui.keyCode.TAB && self._drop_shown) { + self.$text.textext()[0].autocomplete().selectFromDropdown(); + } + }); }, set_value: function(value_) { value_ = value_ || []; @@ -4790,15 +4806,6 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance. this.$el.find('button.oe_form_binary_file_save').click(this.on_save_as); this.$el.find('.oe_form_binary_file_clear').click(this.on_clear); }, - human_filesize : function(size) { - var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - var i = 0; - while (size >= 1024) { - size /= 1024; - ++i; - } - return size.toFixed(2) + ' ' + units[i]; - }, on_file_change: function(e) { var self = this; var file_node = e.target; @@ -4846,6 +4853,7 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance. link.href = "data:application/octet-stream;base64," + value; } else { instance.web.blockUI(); + var c = instance.webclient.crashmanager; this.session.get_file({ url: '/web/binary/saveas_ajax', data: {data: JSON.stringify({ @@ -4856,7 +4864,7 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance. context: this.view.dataset.get_context() })}, complete: instance.web.unblockUI, - error: instance.webclient.crashmanager.on_rpc_error + error: c.rpc_error.bind(c) }); ev.stopPropagation(); return false; @@ -4915,7 +4923,7 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({ on_file_uploaded_and_valid: function(size, name, content_type, file_base64) { this.binary_value = true; this.internal_set_value(file_base64); - var show_value = name + " (" + this.human_filesize(size) + ")"; + var show_value = name + " (" + instance.web.human_size(size) + ")"; this.$el.find('input').eq(0).val(show_value); this.set_filename(name); }, @@ -4935,12 +4943,16 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({ if (this.get('value') && ! /^\d+(\.\d*)? \w+$/.test(this.get('value'))) { url = 'data:image/png;base64,' + this.get('value'); } else if (this.get('value')) { - var id = escape(JSON.stringify(this.view.datarecord.id || null)); + var id = JSON.stringify(this.view.datarecord.id || null); var field = this.name; if (this.options.preview_image) field = this.options.preview_image; - url = '/web/binary/image?session_id=' + this.session.session_id + '&model=' + - this.view.dataset.model +'&id=' + id + '&field=' + field + '&t=' + (new Date().getTime()); + url = this.session.url('/web/binary/image', { + model: this.view.dataset.model, + id: id, + field: field, + t: (new Date().getTime()), + }); } else { url = this.placeholder; } @@ -4979,14 +4991,14 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({ * Options on attribute ; "blockui" {Boolean} block the UI or not * during the file is uploading */ -instance.web.form.FieldOne2ManyBinaryMultiFiles = instance.web.form.AbstractField.extend({ +instance.web.form.FieldMany2ManyBinaryMultiFiles = instance.web.form.AbstractField.extend({ template: "FieldBinaryFileUploader", init: function(field_manager, node) { this._super(field_manager, node); this.field_manager = field_manager; this.node = node; - if(this.field.type != "one2many" || this.field.relation != 'ir.attachment') { - throw "The type of the field '"+this.field.string+"' must be a one2many field with a relation to 'ir.attachment' model."; + if(this.field.type != "many2many" || this.field.relation != 'ir.attachment') { + throw "The type of the field '"+this.field.string+"' must be a many2many field with a relation to 'ir.attachment' model."; } this.ds_file = new instance.web.DataSetSearch(this, 'ir.attachment'); this.fileupload_id = _.uniqueId('oe_fileupload_temp'); @@ -4996,21 +5008,85 @@ instance.web.form.FieldOne2ManyBinaryMultiFiles = instance.web.form.AbstractFiel this._super(this); this.$el.on('change', 'input.oe_form_binary_file', this.on_file_change ); }, + set_value: function(value_) { + var value_ = value_ || []; + var self = this; + var ids = []; + _.each(value_, function(command) { + if (isNaN(command) && command.id == undefined) { + switch (command[0]) { + case commands.CREATE: + ids = ids.concat(command[2]); + return; + case commands.REPLACE_WITH: + ids = ids.concat(command[2]); + return; + case commands.UPDATE: + ids = ids.concat(command[2]); + return; + case commands.LINK_TO: + ids = ids.concat(command[1]); + return; + case commands.DELETE: + ids = _.filter(ids, function (id) { return id != command[1];}); + return; + case commands.DELETE_ALL: + ids = []; + return; + } + } else { + ids.push(command); + } + }); + this._super( ids ); + }, get_value: function() { return _.map(this.get('value'), function (value) { return commands.link_to( value.id ); }); }, get_file_url: function (attachment) { - return instance.origin + '/web/binary/saveas?session_id=' + this.session.session_id + '&model=ir.attachment&field=datas&filename_field=datas_fname&id=' + attachment['id']; + return this.session.url('/web/binary/saveas', {model: 'ir.attachment', field: 'datas', filename_field: 'datas_fname', id: attachment['id']}); + }, + read_name_values : function () { + var self = this; + // select the list of id for a get_name + var values = []; + _.each(this.get('value'), function (val) { + if (typeof val != 'object') { + values.push(val); + } + }); + // send request for get_name + if (values.length) { + return this.ds_file.call('read', [values, ['id', 'name', 'datas_fname']]).done(function (datas) { + _.each(datas, function (data) { + data.no_unlink = true; + data.url = self.session.url('/web/binary/saveas', {model: 'ir.attachment', field: 'datas', filename_field: 'datas_fname', id: data.id}); + + _.each(self.get('value'), function (val, key) { + if(val == data.id) { + self.get('value')[key] = data; + } + }); + }); + }); + } else { + return $.when(this.get('value')); + } }, render_value: function () { - var render = $(instance.web.qweb.render('FieldBinaryFileUploader.files', {'widget': this})); - render.on('click', '.oe_delete', _.bind(this.on_file_delete, this)); - this.$('.oe_placeholder_files, .oe_attachments').replaceWith( render ); + var self = this; + this.read_name_values().then(function (datas) { - // reinit input type file - var $input = this.$('input.oe_form_binary_file'); - $input.after($input.clone(true)).remove(); - this.$(".oe_fileupload").show(); + var render = $(instance.web.qweb.render('FieldBinaryFileUploader.files', {'widget': self})); + render.on('click', '.oe_delete', _.bind(self.on_file_delete, self)); + self.$('.oe_placeholder_files, .oe_attachments').replaceWith( render ); + + // reinit input type file + var $input = self.$('input.oe_form_binary_file'); + $input.after($input.clone(true)).remove(); + self.$(".oe_fileupload").show(); + + }); }, on_file_change: function (event) { event.stopPropagation(); @@ -5026,7 +5102,7 @@ instance.web.form.FieldOne2ManyBinaryMultiFiles = instance.web.form.AbstractFiel } // block UI or not - if(this.node.attrs.blockui) { + if(this.node.attrs.blockui>0) { instance.web.blockUI(); } @@ -5060,7 +5136,7 @@ instance.web.form.FieldOne2ManyBinaryMultiFiles = instance.web.form.AbstractFiel }, on_file_loaded: function (event, result) { // unblock UI - if(this.node.attrs.blockui) { + if(this.node.attrs.blockui>0) { instance.web.unblockUI(); } @@ -5090,7 +5166,7 @@ instance.web.form.FieldOne2ManyBinaryMultiFiles = instance.web.form.AbstractFiel if(file_id != this.get('value')[i].id){ files.push(this.get('value')[i]); } - else { + else if(!this.get('value')[i].no_unlink) { this.ds_file.unlink([file_id]); } } @@ -5252,7 +5328,7 @@ instance.web.form.widgets = new instance.web.Registry({ 'progressbar': 'instance.web.form.FieldProgressBar', 'image': 'instance.web.form.FieldBinaryImage', 'binary': 'instance.web.form.FieldBinaryFile', - 'one2many_binary': 'instance.web.form.FieldOne2ManyBinaryMultiFiles', + 'many2many_binary': 'instance.web.form.FieldMany2ManyBinaryMultiFiles', 'statusbar': 'instance.web.form.FieldStatus', 'monetary': 'instance.web.form.FieldMonetary', }); diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 97efb983235..df74674a343 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -1,6 +1,6 @@ openerp.web.list = function (instance) { var _t = instance.web._t, - _lt = instance.web._lt; + _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# */ { @@ -503,12 +503,17 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi return this.reload_content(); }, reload_record: function (record) { + var self = this; return this.dataset.read_ids( [record.get('id')], _.pluck(_(this.columns).filter(function (r) { return r.tag === 'field'; }), 'name') ).done(function (records) { + if (!records[0]) { + self.records.remove(record); + return; + } _(records[0]).each(function (value, key) { record.set(key, value, {silent: true}); }); @@ -2151,7 +2156,7 @@ instance.web.list.Boolean = instance.web.list.Column.extend({ * @private */ _format: function (row_data, options) { - return _.str.sprintf('', + return _.str.sprintf('', row_data[this.id].value ? 'checked="checked"' : ''); } }); @@ -2163,20 +2168,24 @@ instance.web.list.Binary = instance.web.list.Column.extend({ */ _format: function (row_data, options) { var text = _t("Download"); - var download_url = _.str.sprintf( - '/web/binary/saveas?session_id=%s&model=%s&field=%s&id=%d', - instance.session.session_id, options.model, this.id, options.id); - if (this.filename) { - download_url += '&filename_field=' + this.filename; - if (row_data[this.filename]) { - text = _.str.sprintf(_t("Download \"%s\""), instance.web.format_value( - row_data[this.filename].value, {type: 'char'})); + var value = row_data[this.id].value; + var download_url; + if (value && value.substr(0, 10).indexOf(' ') == -1) { + download_url = "data:application/octet-stream;base64," + value; + } else { + download_url = this.session.url('/web/binary/saveas', {model: options.model, field: this.id, id: options.id}); + if (this.filename) { + download_url += '&filename_field=' + this.filename; } } - return _.template('<%-text%> (%<-size%>)', { + if (this.filename && row_data[this.filename]) { + text = _.str.sprintf(_t("Download \"%s\""), instance.web.format_value( + row_data[this.filename].value, {type: 'char'})); + } + return _.template('<%-text%> (<%-size%>)', { text: text, href: download_url, - size: row_data[this.id].value + size: instance.web.binary_to_binsize(value), }); } }); diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js index 37ce8c4f8b4..1abe3caab39 100644 --- a/addons/web/static/src/js/view_list_editable.js +++ b/addons/web/static/src/js/view_list_editable.js @@ -77,6 +77,15 @@ openerp.web.list_editable = function (instance) { do_edit: function (index, id, dataset) { _.extend(this.dataset, dataset); }, + do_delete: function (ids) { + var _super = this._super.bind(this); + var next = this.editor.is_editing() + ? this.cancel_edition(true) + : $.when(); + return next.then(function () { + return _super(ids); + }); + }, editable: function () { return this.fields_view.arch.attrs.editable || this._context_editable @@ -117,13 +126,6 @@ openerp.web.list_editable = function (instance) { e.preventDefault(); self.cancel_edition(); }); - this.$el - .off('click', 'tbody td:not(.oe_list_field_cell)') - .on('click', 'tbody td:not(.oe_list_field_cell)', function () { - if (!self.editor.is_editing()) { - self.start_edition(); - } - }); this.editor.destroy(); // Editor is not restartable due to formview not being // restartable @@ -164,13 +166,23 @@ openerp.web.list_editable = function (instance) { * @returns {$.Deferred} */ ensure_saved: function () { - var self = this; - return this.saving_mutex.exec(function() { - if (!self.editor.is_editing()) { - return $.when(); - } - return self.save_edition(); - }); + return this.save_edition(); + }, + /** + * Builds a record with the provided id (``false`` for a creation), + * setting all columns with ``false`` value so code which relies on + * having an actual value behaves correctly + * + * @param {*} id + * @return {instance.web.list.Record} + */ + make_empty_record: function (id) { + var attrs = {id: id}; + _(this.columns).chain() + .filter(function (x) { return x.tag === 'field'}) + .pluck('name') + .each(function (field) { attrs[field] = false; }); + return new instance.web.list.Record(attrs); }, /** * Set up the edition of a record of the list view "inline" @@ -186,12 +198,7 @@ openerp.web.list_editable = function (instance) { if (record) { item = record.attributes; } else { - var attrs = {id: false}; - _(this.columns).chain() - .filter(function (x) { return x.tag === 'field'}) - .pluck('name') - .each(function (field) { attrs[field] = false; }); - record = new instance.web.list.Record(attrs); + record = this.make_empty_record(false); this.records.add(record, { at: this.prepends_on_create() ? 0 : null}); } @@ -269,29 +276,34 @@ openerp.web.list_editable = function (instance) { */ save_edition: function () { var self = this; - return this.with_event('save', { - editor: this.editor, - form: this.editor.form, - cancel: false - }, function () { - return this.editor.save().then(function (attrs) { - var created = false; - var record = self.records.get(attrs.id); - if (!record) { - // new record - created = true; - record = self.records.find(function (r) { - return !r.get('id'); - }).set('id', attrs.id); - } - // onwrite callback could be altering & reloading the - // record which has *just* been saved, so first perform all - // onwrites then do a final reload of the record - return self.handle_onwrite(record) - .then(function () { - return self.reload_record(record); }) - .then(function () { - return { created: created, record: record }; }); + return self.saving_mutex.exec(function() { + if (!self.editor.is_editing()) { + return $.when(); + } + return self.with_event('save', { + editor: self.editor, + form: self.editor.form, + cancel: false + }, function () { + return self.editor.save().then(function (attrs) { + var created = false; + var record = self.records.get(attrs.id); + if (!record) { + // new record + created = true; + record = self.records.find(function (r) { + return !r.get('id'); + }).set('id', attrs.id); + } + // onwrite callback could be altering & reloading the + // record which has *just* been saved, so first perform all + // onwrites then do a final reload of the record + return self.handle_onwrite(record) + .then(function () { + return self.reload_record(record); }) + .then(function () { + return { created: created, record: record }; }); + }); }); }); }, @@ -391,7 +403,7 @@ openerp.web.list_editable = function (instance) { if (!record) { // insert after the source record var index = this.records.indexOf(source_record) + 1; - record = new instance.web.list.Record({id: id}); + record = this.make_empty_record(id); this.records.add(record, {at: index}); this.dataset.ids.splice(index, 0, id); } diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 53132e454d1..641821152b2 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -213,8 +213,12 @@ instance.web.ActionManager = instance.web.Widget.extend({ if (run_action) { this.null_action(); action_loaded = this.do_action(state.action); - instance.webclient.menu.has_been_loaded.done(function() { - instance.webclient.menu.open_action(state.action); + $.when(action_loaded || null).done(function() { + instance.webclient.menu.has_been_loaded.done(function() { + if (self.inner_action && self.inner_action.id) { + instance.webclient.menu.open_action(self.inner_action.id); + } + }); }); } } @@ -306,15 +310,15 @@ instance.web.ActionManager = instance.web.Widget.extend({ } var widget = executor.widget(); if (executor.action.target === 'new') { - if (this.dialog_widget && ! this.dialog_widget.isDestroyed()) + if (this.dialog_widget && !this.dialog_widget.isDestroyed()) { this.dialog_widget.destroy(); - if (this.dialog === null || this.dialog.isDestroyed()) { - this.dialog = new instance.web.Dialog(this, { - dialogClass: executor.klass, - }); - this.dialog.on("closing", null, options.on_close); - this.dialog.init_dialog(); } + this.dialog_stop(); + this.dialog = new instance.web.Dialog(this, { + dialogClass: executor.klass, + }); + this.dialog.on("closing", null, options.on_close); + this.dialog.init_dialog(); this.dialog.dialog_title = executor.action.name; if (widget instanceof instance.web.ViewManager) { _.extend(widget.flags, { @@ -397,6 +401,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ }).done(function(res) { action = _.clone(action); action.context = res.context; + var c = instance.webclient.crashmanager; self.session.get_file({ url: '/web/report', data: {action: JSON.stringify(action)}, @@ -407,7 +412,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ } self.dialog_stop(); }, - error: instance.webclient.crashmanager.on_rpc_error + error: c.rpc_error.bind(c) }) }); }, @@ -504,7 +509,7 @@ instance.web.ViewManager = instance.web.Widget.extend({ .find('.oe_view_manager_switch a').filter('[data-view-type="' + view_type + '"]') .parent().addClass('active'); - r = $.when(view_promise).done(function () { + return $.when(view_promise).done(function () { _.each(_.keys(self.views), function(view_name) { var controller = self.views[view_name].controller; if (controller) { @@ -520,7 +525,6 @@ instance.web.ViewManager = instance.web.Widget.extend({ }); self.trigger('switch_mode', view_type, no_store, view_options); }); - return r; }, do_create_view: function(view_type) { // Lazy loading of views @@ -785,8 +789,8 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({ name: "JS Tests", target: 'new', type : 'ir.actions.act_url', - url: '/web/static/test/test.html' - }) + url: '/web/tests?mod=*' + }); break; case 'perm_read': var ids = current_view.get_selected_ids(); @@ -1098,11 +1102,11 @@ instance.web.Sidebar = instance.web.Widget.extend({ on_attachments_loaded: function(attachments) { var self = this; var items = []; - var prefix = this.session.origin + '/web/binary/saveas?session_id=' + self.session.session_id + '&model=ir.attachment&field=datas&filename_field=name&id='; + var prefix = this.session.url('/web/binary/saveas', {model: 'ir.attachment', field: 'datas', filename_field: 'name'}); _.each(attachments,function(a) { a.label = a.name; if(a.type === "binary") { - a.url = prefix + a.id + '&t=' + (new Date().getTime()); + a.url = prefix + '&id=' + a.id + '&t=' + (new Date().getTime()); } }); self.items['files'] = attachments; @@ -1235,11 +1239,12 @@ instance.web.View = instance.web.Widget.extend({ }); }, null); } else { + self.do_action({"type":"ir.actions.act_window_close"}); return result_handler(); } }; - if (action_data.special) { + if (action_data.special === 'cancel') { return handler({"type":"ir.actions.act_window_close"}); } else if (action_data.type=="object") { var args = [[record_id]], additional_args = []; @@ -1277,6 +1282,27 @@ instance.web.View = instance.web.Widget.extend({ do_hide: function () { this.$el.hide(); }, + is_active: function () { + var manager = this.getParent(); + return !manager || !manager.active_view + || manager.views[manager.active_view].controller === this; + }, /** + * Wraps fn to only call it if the current view is the active one. If the + * current view is not active, doesn't call fn. + * + * fn can not return anything, as a non-call to fn can't return anything + * either + * + * @param {Function} fn function to wrap in the active guard + */ + guard_active: function (fn) { + var self = this; + return function () { + if (self.is_active()) { + fn.apply(self, arguments); + } + } + }, do_push_state: function(state) { if (this.getParent() && this.getParent().do_push_state) { this.getParent().do_push_state(state); @@ -1384,14 +1410,16 @@ instance.web.json_node_to_xml = function(node, human_readable, indent) { } else { return r + '/>'; } -} +}; instance.web.xml_to_str = function(node) { - if (window.ActiveXObject) { + if (window.XMLSerializer) { + return (new XMLSerializer()).serializeToString(node); + } else if (window.ActiveXObject) { return node.xml; } else { - return (new XMLSerializer()).serializeToString(node); + throw new Error("Could not serialize XML"); } -} +}; instance.web.str_to_xml = function(s) { if (window.DOMParser) { var dp = new DOMParser(); diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 215374cb6fb..1b7a5cea53a 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -152,6 +152,32 @@ +
    diff --git a/addons/web/static/test/Widget.js b/addons/web/static/test/Widget.js index 3e6cc262565..44b7cfe0dfa 100644 --- a/addons/web/static/test/Widget.js +++ b/addons/web/static/test/Widget.js @@ -1,32 +1,7 @@ -$(document).ready(function () { - var $fix = $('#qunit-fixture'); - var mod = { - setup: function () { - instance = window.openerp.init([]); - window.openerp.web.corelib(instance); - - instance.web.qweb = new QWeb2.Engine(); - instance.web.qweb.add_template( - '' + - '' + - '
      ' + - '
    1. ' + - '' + - '' + - '
    2. ' + - '
    ' + - '
    ' + - '' + - '

    ' + - '
    ' + - '
    '); - } - }; - var instance; - - module('Widget.proxy', mod); - test('(String)', function () { +openerp.testing.section('Widget.proxy', { + dependencies: ['web.corelib'] +}, function (test) { + test('(String)', function (instance) { var W = instance.web.Widget.extend({ exec: function () { this.executed = true; @@ -37,7 +12,7 @@ $(document).ready(function () { fn(); ok(w.executed, 'should execute the named method in the right context'); }); - test('(String)(*args)', function () { + test('(String)(*args)', function (instance) { var W = instance.web.Widget.extend({ exec: function (arg) { this.executed = arg; @@ -49,7 +24,7 @@ $(document).ready(function () { ok(w.executed, "should execute the named method in the right context"); equal(w.executed, 42, "should be passed the proxy's arguments"); }); - test('(String), include', function () { + test('(String), include', function (instance) { // the proxy function should handle methods being changed on the class // and should always proxy "by name", to the most recent one var W = instance.web.Widget.extend({ @@ -67,23 +42,43 @@ $(document).ready(function () { equal(w.executed, 2, "should be lazily resolved"); }); - test('(Function)', function () { + test('(Function)', function (instance) { var w = new (instance.web.Widget.extend({ })); var fn = w.proxy(function () { this.executed = true; }); fn(); ok(w.executed, "should set the function's context (like Function#bind)"); }); - test('(Function)(*args)', function () { + test('(Function)(*args)', function (instance) { var w = new (instance.web.Widget.extend({ })); var fn = w.proxy(function (arg) { this.executed = arg; }); fn(42); equal(w.executed, 42, "should be passed the proxy's arguments"); }); - - module('Widget.renderElement', mod); - test('no template, default', function () { +}); +openerp.testing.section('Widget.renderElement', { + dependencies: ['web.corelib'], + setup: function (instance) { + instance.web.qweb = new QWeb2.Engine(); + instance.web.qweb.add_template( + '' + + '' + + '
      ' + + '
    1. ' + + '' + + '' + + '
    2. ' + + '
    ' + + '
    ' + + '' + + '

    ' + + '
    ' + + '
    '); + } +}, function (test) { + test('no template, default', function (instance) { var w = new (instance.web.Widget.extend({ })); var $original = w.$el; @@ -98,7 +93,7 @@ $(document).ready(function () { equal(w.el.attributes.length, 0, "should not have generated any attribute"); ok(_.isEmpty(w.$el.html(), "should not have generated any content")); }); - test('no template, custom tag', function () { + test('no template, custom tag', function (instance) { var w = new (instance.web.Widget.extend({ tagName: 'ul' })); @@ -106,7 +101,7 @@ $(document).ready(function () { equal(w.el.nodeName, 'UL', "should have generated the custom element tag"); }); - test('no template, @id', function () { + test('no template, @id', function (instance) { var w = new (instance.web.Widget.extend({ id: 'foo' })); @@ -116,7 +111,7 @@ $(document).ready(function () { equal(w.$el.attr('id'), 'foo', "should have generated the id attribute"); equal(w.el.id, 'foo', "should also be available via property"); }); - test('no template, @className', function () { + test('no template, @className', function (instance) { var w = new (instance.web.Widget.extend({ className: 'oe_some_class' })); @@ -125,7 +120,7 @@ $(document).ready(function () { equal(w.el.className, 'oe_some_class', "should have the right property"); equal(w.$el.attr('class'), 'oe_some_class', "should have the right attribute"); }); - test('no template, bunch of attributes', function () { + test('no template, bunch of attributes', function (instance) { var w = new (instance.web.Widget.extend({ attributes: { 'id': 'some_id', @@ -152,7 +147,7 @@ $(document).ready(function () { equal(w.$el.attr('spoiler'), 'snape kills dumbledore'); }); - test('template', function () { + test('template', function (instance) { var w = new (instance.web.Widget.extend({ template: 'test.widget.template' })); @@ -162,9 +157,41 @@ $(document).ready(function () { equal(w.$el.children().length, 5); equal(w.el.textContent, '01234'); }); - - module('Widget.$', mod); - test('basic-alias', function () { + test('repeated', { asserts: 4 }, function (instance, $fix) { + var w = new (instance.web.Widget.extend({ + template: 'test.widget.template-value' + })); + w.value = 42; + return w.appendTo($fix) + .done(function () { + equal($fix.find('p').text(), '42', "DOM fixture should contain initial value"); + equal(w.$el.text(), '42', "should set initial value"); + w.value = 36; + w.renderElement(); + equal($fix.find('p').text(), '36', "DOM fixture should use new value"); + equal(w.$el.text(), '36', "should set new value"); + }); + }); +}); +openerp.testing.section('Widget.$', { + dependencies: ['web.corelib'], + setup: function (instance) { + instance.web.qweb = new QWeb2.Engine(); + instance.web.qweb.add_template( + '' + + '' + + '
      ' + + '
    1. ' + + '' + + '' + + '
    2. ' + + '
    ' + + '
    ' + + '
    '); + } +}, function (test) { + test('basic-alias', function (instance) { var w = new (instance.web.Widget.extend({ template: 'test.widget.template' })); @@ -173,9 +200,26 @@ $(document).ready(function () { ok(w.$('li:eq(3)').is(w.$el.find('li:eq(3)')), "should do the same thing as calling find on the widget root"); }); - - module('Widget.events', mod); - test('delegate', function () { +}); +openerp.testing.section('Widget.events', { + dependencies: ['web.corelib'], + setup: function (instance) { + instance.web.qweb = new QWeb2.Engine(); + instance.web.qweb.add_template( + '' + + '' + + '
      ' + + '
    1. ' + + '' + + '' + + '
    2. ' + + '
    ' + + '
    ' + + '
    '); + } +}, function (test) { + test('delegate', function (instance) { var a = []; var w = new (instance.web.Widget.extend({ template: 'test.widget.template', @@ -199,7 +243,7 @@ $(document).ready(function () { ok(a[i], "should pass test " + i); } }); - test('undelegate', function () { + test('undelegate', function (instance) { var clicked = false, newclicked = false; var w = new (instance.web.Widget.extend({ template: 'test.widget.template', @@ -218,22 +262,4 @@ $(document).ready(function () { ok(!clicked, "undelegate should unbind events delegated"); ok(newclicked, "undelegate should only unbind events it created"); }); - - module('Widget.renderElement', mod); - asyncTest('repeated', 4, function () { - var w = new (instance.web.Widget.extend({ - template: 'test.widget.template-value' - })); - w.value = 42; - w.appendTo($fix) - .always(start) - .done(function () { - equal($fix.find('p').text(), '42', "DOM fixture should contain initial value"); - equal(w.$el.text(), '42', "should set initial value"); - w.value = 36; - w.renderElement(); - equal($fix.find('p').text(), '36', "DOM fixture should use new value"); - equal(w.$el.text(), '36', "should set new value"); - }); - }); }); diff --git a/addons/web/static/test/class.js b/addons/web/static/test/class.js index faad4421e31..bb3fb7e12b9 100644 --- a/addons/web/static/test/class.js +++ b/addons/web/static/test/class.js @@ -1,30 +1,25 @@ -$(document).ready(function () { - var openerp; - module('web-class', { - setup: function () { - openerp = window.openerp.init([]); - window.openerp.web.corelib(openerp); - } - }); - test('Basic class creation', function () { - var C = openerp.web.Class.extend({ +openerp.testing.section('class', { + dependencies: ['web.corelib'] +}, function (test) { + test('Basic class creation', function (instance) { + var C = instance.web.Class.extend({ foo: function () { return this.somevar; } }); - var instance = new C(); - instance.somevar = 3; + var i = new C(); + i.somevar = 3; - ok(instance instanceof C); - strictEqual(instance.foo(), 3); + ok(i instanceof C); + strictEqual(i.foo(), 3); }); - test('Class initialization', function () { - var C1 = openerp.web.Class.extend({ + test('Class initialization', function (instance) { + var C1 = instance.web.Class.extend({ init: function () { this.foo = 3; } }); - var C2 = openerp.web.Class.extend({ + var C2 = instance.web.Class.extend({ init: function (arg) { this.foo = arg; } @@ -36,8 +31,8 @@ $(document).ready(function () { strictEqual(i1.foo, 3); strictEqual(i2.foo, 42); }); - test('Inheritance', function () { - var C0 = openerp.web.Class.extend({ + test('Inheritance', function (instance) { + var C0 = instance.web.Class.extend({ foo: function () { return 1; } @@ -57,8 +52,8 @@ $(document).ready(function () { strictEqual(new C1().foo(), 2); strictEqual(new C2().foo(), 3); }); - test('In-place extension', function () { - var C0 = openerp.web.Class.extend({ + test('In-place extension', function (instance) { + var C0 = instance.web.Class.extend({ foo: function () { return 3; }, @@ -83,8 +78,8 @@ $(document).ready(function () { strictEqual(new C0().foo(), 5); strictEqual(new C0().qux(), 5); }); - test('In-place extension and inheritance', function () { - var C0 = openerp.web.Class.extend({ + test('In-place extension and inheritance', function (instance) { + var C0 = instance.web.Class.extend({ foo: function () { return 1; }, bar: function () { return 1; } }); @@ -101,24 +96,24 @@ $(document).ready(function () { strictEqual(new C1().foo(), 4); strictEqual(new C1().bar(), 2); }); - test('In-place extensions alter existing instances', function () { - var C0 = openerp.web.Class.extend({ + test('In-place extensions alter existing instances', function (instance) { + var C0 = instance.web.Class.extend({ foo: function () { return 1; }, bar: function () { return 1; } }); - var instance = new C0(); - strictEqual(instance.foo(), 1); - strictEqual(instance.bar(), 1); + var i = new C0(); + strictEqual(i.foo(), 1); + strictEqual(i.bar(), 1); C0.include({ foo: function () { return 2; }, bar: function () { return 2 + this._super(); } }); - strictEqual(instance.foo(), 2); - strictEqual(instance.bar(), 3); + strictEqual(i.foo(), 2); + strictEqual(i.bar(), 3); }); - test('In-place extension of subclassed types', function () { - var C0 = openerp.web.Class.extend({ + test('In-place extension of subclassed types', function (instance) { + var C0 = instance.web.Class.extend({ foo: function () { return 1; }, bar: function () { return 1; } }); @@ -126,13 +121,13 @@ $(document).ready(function () { foo: function () { return 1 + this._super(); }, bar: function () { return 1 + this._super(); } }); - var instance = new C1(); - strictEqual(instance.foo(), 2); + var i = new C1(); + strictEqual(i.foo(), 2); C0.include({ foo: function () { return 2; }, bar: function () { return 2 + this._super(); } }); - strictEqual(instance.foo(), 3); - strictEqual(instance.bar(), 4); + strictEqual(i.foo(), 3); + strictEqual(i.bar(), 4); }); }); diff --git a/addons/web/static/test/evals.js b/addons/web/static/test/evals.js index 757d98c5bcc..6eec615b199 100644 --- a/addons/web/static/test/evals.js +++ b/addons/web/static/test/evals.js @@ -1,18 +1,11 @@ -$(document).ready(function () { - var openerp; - - module("eval.contexts", { - setup: function () { - openerp = window.openerp.init([]); - window.openerp.web.corelib(openerp); - window.openerp.web.coresetup(openerp); - } - }); - test('context_sequences', function () { +openerp.testing.section('eval.contexts', { + dependencies: ['web.coresetup'] +}, function (test) { + test('context_sequences', function (instance) { // Context n should have base evaluation context + all of contexts // 0..n-1 in its own evaluation context var active_id = 4; - var result = openerp.session.test_eval_contexts([ + var result = instance.session.test_eval_contexts([ { "__contexts": [ { @@ -55,8 +48,8 @@ $(document).ready(function () { record_id: active_id }); }); - test('non-literal_eval_contexts', function () { - var result = openerp.session.test_eval_contexts([{ + test('non-literal_eval_contexts', function (instance) { + var result = instance.session.test_eval_contexts([{ "__ref": "compound_context", "__contexts": [ {"__ref": "context", "__debug": "{'type':parent.type}", @@ -133,17 +126,15 @@ $(document).ready(function () { }]); deepEqual(result, {type: 'out_invoice'}); }); - module('eval.domains', { - setup: function () { - openerp = window.openerp.testing.instanceFor('coresetup'); - window.openerp.web.dates(openerp); - } - }); - test('current_date', function () { - var current_date = openerp.web.date_to_str(new Date()); - var result = openerp.session.test_eval_domains( +}); +openerp.testing.section('eval.contexts', { + dependencies: ['web.coresetup', 'web.dates'] +}, function (test) { + test('current_date', function (instance) { + var current_date = instance.web.date_to_str(new Date()); + var result = instance.session.test_eval_domains( [[],{"__ref":"domain","__debug":"[('name','>=',current_date),('name','<=',current_date)]","__id":"5dedcfc96648"}], - openerp.session.test_eval_get_context()); + instance.session.test_eval_get_context()); deepEqual(result, [ ['name', '>=', current_date], ['name', '<=', current_date] diff --git a/addons/web/static/test/form.js b/addons/web/static/test/form.js index aace926a96a..0c8107ce9bc 100644 --- a/addons/web/static/test/form.js +++ b/addons/web/static/test/form.js @@ -1,33 +1,21 @@ -$(document).ready(function () { - var openerp; - module("form.widget", { - setup: function () { - 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); - window.openerp.web.form(openerp); - } - }); - test("compute_domain", function () { +openerp.testing.section('compute_domain', { + dependencies: ['web.form'] +}, function (test) { + test("basic", function (instance) { var fields = { 'a': {value: 3}, 'group_method': {value: 'line'}, 'select1': {value: 'day'}, 'rrule_type': {value: 'monthly'} }; - ok(openerp.web.form.compute_domain( + ok(instance.web.form.compute_domain( [['a', '=', 3]], fields)); - ok(openerp.web.form.compute_domain( + ok(instance.web.form.compute_domain( [['group_method','!=','count']], fields)); - ok(openerp.web.form.compute_domain( + ok(instance.web.form.compute_domain( [['select1','=','day'], ['rrule_type','=','monthly']], fields)); }); - test("compute_domain or", function () { + test("or", function (instance) { var web = { 'section_id': {value: null}, 'user_id': {value: null}, @@ -38,22 +26,22 @@ $(document).ready(function () { '|', ['user_id','=',3], ['member_ids', 'in', [3]]]; - ok(openerp.web.form.compute_domain(domain, _.extend( + ok(instance.web.form.compute_domain(domain, _.extend( {}, web, {'section_id': {value: 42}}))); - ok(openerp.web.form.compute_domain(domain, _.extend( + ok(instance.web.form.compute_domain(domain, _.extend( {}, web, {'user_id': {value: 3}}))); - ok(openerp.web.form.compute_domain(domain, _.extend( + ok(instance.web.form.compute_domain(domain, _.extend( {}, web, {'member_ids': {value: 3}}))); }); - test("compute_domain not", function () { + test("not", function (instance) { var fields = { 'a': {value: 5}, 'group_method': {value: 'line'} }; - ok(openerp.web.form.compute_domain( + ok(instance.web.form.compute_domain( ['!', ['a', '=', 3]], fields)); - ok(openerp.web.form.compute_domain( + ok(instance.web.form.compute_domain( ['!', ['group_method','=','count']], fields)); }); }); diff --git a/addons/web/static/test/formats.js b/addons/web/static/test/formats.js index 4fe07ff0a9c..4536501d71d 100644 --- a/addons/web/static/test/formats.js +++ b/addons/web/static/test/formats.js @@ -1,16 +1,8 @@ -$(document).ready(function () { - var openerp; - - module('server-formats', { - setup: function () { - openerp = window.openerp.init([]); - window.openerp.web.corelib(openerp); - window.openerp.web.coresetup(openerp); - window.openerp.web.dates(openerp); - } - }); - test('Parse server datetime', function () { - var date = openerp.web.str_to_datetime("2009-05-04 12:34:23"); +openerp.testing.section('server-formats', { + dependencies: ['web.coresetup', 'web.dates'] +}, function (test) { + test('Parse server datetime', function (instance) { + var date = instance.web.str_to_datetime("2009-05-04 12:34:23"); deepEqual( [date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()], @@ -20,92 +12,86 @@ $(document).ready(function () { date.getHours(), date.getMinutes(), date.getSeconds()], [2009, 5 - 1, 4, 12 - (date.getTimezoneOffset() / 60), 34, 23]); - var date2 = openerp.web.str_to_datetime('2011-12-10 00:00:00'); + var date2 = instance.web.str_to_datetime('2011-12-10 00:00:00'); deepEqual( [date2.getUTCFullYear(), date2.getUTCMonth(), date2.getUTCDate(), date2.getUTCHours(), date2.getUTCMinutes(), date2.getUTCSeconds()], [2011, 12 - 1, 10, 0, 0, 0]); }); - test('Parse server date', function () { - var date = openerp.web.str_to_date("2009-05-04"); + test('Parse server date', function (instance) { + var date = instance.web.str_to_date("2009-05-04"); deepEqual( [date.getFullYear(), date.getMonth(), date.getDate()], [2009, 5 - 1, 4]); }); - test('Parse server time', function () { - var date = openerp.web.str_to_time("12:34:23"); + test('Parse server time', function (instance) { + var date = instance.web.str_to_time("12:34:23"); deepEqual( [date.getHours(), date.getMinutes(), date.getSeconds()], [12, 34, 23]); }); - - module('web-formats', { - setup: function () { - openerp = window.openerp.init([]); - window.openerp.web.corelib(openerp); - window.openerp.web.coresetup(openerp); - window.openerp.web.dates(openerp); - window.openerp.web.formats(openerp); - } - }); - test("format_datetime", function () { - var date = openerp.web.str_to_datetime("2009-05-04 12:34:23"); - var str = openerp.web.format_value(date, {type:"datetime"}); +}); +openerp.testing.section('web-formats', { + dependencies: ['web.formats'] +}, function (test) { + test("format_datetime", function (instance) { + var date = instance.web.str_to_datetime("2009-05-04 12:34:23"); + var str = instance.web.format_value(date, {type:"datetime"}); equal(str, date.toString("MM/dd/yyyy HH:mm:ss")); }); - test("format_date", function () { - var date = openerp.web.str_to_datetime("2009-05-04 12:34:23"); - var str = openerp.web.format_value(date, {type:"date"}); + test("format_date", function (instance) { + var date = instance.web.str_to_datetime("2009-05-04 12:34:23"); + var str = instance.web.format_value(date, {type:"date"}); equal(str, date.toString("MM/dd/yyyy")); }); - test("format_time", function () { - var date = openerp.web.str_to_datetime("2009-05-04 12:34:23"); - var str = openerp.web.format_value(date, {type:"time"}); + test("format_time", function (instance) { + var date = instance.web.str_to_datetime("2009-05-04 12:34:23"); + var str = instance.web.format_value(date, {type:"time"}); equal(str, date.toString("HH:mm:ss")); }); - test("format_float_time", function () { + test("format_float_time", function (instance) { strictEqual( - openerp.web.format_value(1.0, {type:'float', widget:'float_time'}), + instance.web.format_value(1.0, {type:'float', widget:'float_time'}), '01:00'); strictEqual( - openerp.web.format_value(0.9853, {type:'float', widget:'float_time'}), + instance.web.format_value(0.9853, {type:'float', widget:'float_time'}), '00:59'); strictEqual( - openerp.web.format_value(0.0085, {type:'float', widget:'float_time'}), + instance.web.format_value(0.0085, {type:'float', widget:'float_time'}), '00:01'); strictEqual( - openerp.web.format_value(-1.0, {type:'float', widget:'float_time'}), + instance.web.format_value(-1.0, {type:'float', widget:'float_time'}), '-01:00'); strictEqual( - openerp.web.format_value(-0.9853, {type:'float', widget:'float_time'}), + instance.web.format_value(-0.9853, {type:'float', widget:'float_time'}), '-00:59'); strictEqual( - openerp.web.format_value(-0.0085, {type:'float', widget:'float_time'}), + instance.web.format_value(-0.0085, {type:'float', widget:'float_time'}), '-00:01'); }); - test("format_float", function () { + test("format_float", function (instance) { var fl = 12.1234; - var str = openerp.web.format_value(fl, {type:"float"}); + var str = instance.web.format_value(fl, {type:"float"}); equal(str, "12.12"); - equal(openerp.web.format_value(12.02, {type: 'float'}), + equal(instance.web.format_value(12.02, {type: 'float'}), '12.02'); - equal(openerp.web.format_value(0.0002, {type: 'float', digits: [1, 3]}), + equal(instance.web.format_value(0.0002, {type: 'float', digits: [1, 3]}), '0.000'); - equal(openerp.web.format_value(0.0002, {type: 'float', digits: [1, 4]}), + equal(instance.web.format_value(0.0002, {type: 'float', digits: [1, 4]}), '0.0002'); - equal(openerp.web.format_value(0.0002, {type: 'float', digits: [1, 6]}), + equal(instance.web.format_value(0.0002, {type: 'float', digits: [1, 6]}), '0.000200'); - equal(openerp.web.format_value(1, {type: 'float', digits: [1, 6]}), + equal(instance.web.format_value(1, {type: 'float', digits: [1, 6]}), '1.000000'); - equal(openerp.web.format_value(1, {type: 'float'}), + equal(instance.web.format_value(1, {type: 'float'}), '1.00'); - equal(openerp.web.format_value(-11.25, {type: 'float'}), + equal(instance.web.format_value(-11.25, {type: 'float'}), "-11.25"); - openerp.web._t.database.parameters.grouping = [1, 2, -1]; - equal(openerp.web.format_value(1111111.25, {type: 'float'}), + instance.web._t.database.parameters.grouping = [1, 2, -1]; + equal(instance.web.format_value(1111111.25, {type: 'float'}), "1111,11,1.25"); - openerp.web._t.database.parameters.grouping = [1, 0]; - equal(openerp.web.format_value(-11.25, {type: 'float'}), + instance.web._t.database.parameters.grouping = [1, 0]; + equal(instance.web.format_value(-11.25, {type: 'float'}), "-1,1.25"); }); // test("parse_datetime", function () { @@ -123,29 +109,29 @@ $(document).ready(function () { // var res = openerp.web.parse_value(val.toString("HH:mm:ss"), {type:"time"}); // equal(val.toString("HH:mm:ss"), res.toString("HH:mm:ss")); // }); - test('parse_integer', function () { - var val = openerp.web.parse_value('123,456', {type: 'integer'}); + test('parse_integer', function (instance) { + var val = instance.web.parse_value('123,456', {type: 'integer'}); equal(val, 123456); - openerp.web._t.database.parameters.thousands_sep = '|'; - var val2 = openerp.web.parse_value('123|456', {type: 'integer'}); + instance.web._t.database.parameters.thousands_sep = '|'; + var val2 = instance.web.parse_value('123|456', {type: 'integer'}); equal(val2, 123456); }); - test("parse_float", function () { + test("parse_float", function (instance) { var str = "134,112.1234"; - var val = openerp.web.parse_value(str, {type:"float"}); + var val = instance.web.parse_value(str, {type:"float"}); equal(val, 134112.1234); var str = "-134,112.1234"; - var val = openerp.web.parse_value(str, {type:"float"}); + var val = instance.web.parse_value(str, {type:"float"}); equal(val, -134112.1234); - _.extend(openerp.web._t.database.parameters, { + _.extend(instance.web._t.database.parameters, { decimal_point: ',', thousands_sep: '.' }); - var val3 = openerp.web.parse_value('123.456,789', {type: 'float'}); + var val3 = instance.web.parse_value('123.456,789', {type: 'float'}); equal(val3, 123456.789); }); - test('intersperse', function () { - var g = openerp.web.intersperse; + test('intersperse', function (instance) { + var g = instance.web.intersperse; equal(g("", []), ""); equal(g("0", []), "0"); equal(g("012", []), "012"); @@ -176,60 +162,61 @@ $(document).ready(function () { equal(g("12345678", [3,3,3,3], '.'), '12.345.678'); equal(g("12345678", [3,0], '.'), '12.345.678'); }); - test('format_integer', function () { - openerp.web._t.database.parameters.grouping = [3, 3, 3, 3]; - equal(openerp.web.format_value(1000000, {type: 'integer'}), + test('format_integer', function (instance) { + instance.web._t.database.parameters.grouping = [3, 3, 3, 3]; + equal(instance.web.format_value(1000000, {type: 'integer'}), '1,000,000'); - openerp.web._t.database.parameters.grouping = [3, 2, -1]; - equal(openerp.web.format_value(106500, {type: 'integer'}), + instance.web._t.database.parameters.grouping = [3, 2, -1]; + equal(instance.web.format_value(106500, {type: 'integer'}), '1,06,500'); - openerp.web._t.database.parameters.grouping = [1, 2, -1]; - equal(openerp.web.format_value(106500, {type: 'integer'}), + instance.web._t.database.parameters.grouping = [1, 2, -1]; + equal(instance.web.format_value(106500, {type: 'integer'}), '106,50,0'); }); - test('format_float', function () { - openerp.web._t.database.parameters.grouping = [3, 3, 3, 3]; - equal(openerp.web.format_value(1000000, {type: 'float'}), + test('format_float', function (instance) { + instance.web._t.database.parameters.grouping = [3, 3, 3, 3]; + equal(instance.web.format_value(1000000, {type: 'float'}), '1,000,000.00'); - openerp.web._t.database.parameters.grouping = [3, 2, -1]; - equal(openerp.web.format_value(106500, {type: 'float'}), + instance.web._t.database.parameters.grouping = [3, 2, -1]; + equal(instance.web.format_value(106500, {type: 'float'}), '1,06,500.00'); - openerp.web._t.database.parameters.grouping = [1, 2, -1]; - equal(openerp.web.format_value(106500, {type: 'float'}), + instance.web._t.database.parameters.grouping = [1, 2, -1]; + equal(instance.web.format_value(106500, {type: 'float'}), '106,50,0.00'); - _.extend(openerp.web._t.database.parameters, { + _.extend(instance.web._t.database.parameters, { grouping: [3, 0], decimal_point: ',', thousands_sep: '.' }); - equal(openerp.web.format_value(6000, {type: 'float'}), + equal(instance.web.format_value(6000, {type: 'float'}), '6.000,00'); }); - module('custom-date-formats', { - setup: function () { - openerp = window.openerp.init([]); - window.openerp.web.corelib(openerp); - window.openerp.web.coresetup(openerp); - window.openerp.web.dates(openerp); - window.openerp.web.formats(openerp); - } +}); +openerp.testing.section('web-formats', { + dependencies: ['web.formats'] +}, function (test) { + test('format stripper', function (instance) { + strictEqual(instance.web.strip_raw_chars('%a, %Y %b %d'), + '%a, %Y %b %d'); + strictEqual(instance.web.strip_raw_chars('%a, %Y.eko %bren %da'), + '%a, %Y. %b %d'); }); - test('format stripper', function () { - strictEqual(openerp.web.strip_raw_chars('%a, %Y %b %d'), '%a, %Y %b %d'); - strictEqual(openerp.web.strip_raw_chars('%a, %Y.eko %bren %da'), '%a, %Y. %b %d'); + test('ES date format', function (instance) { + instance.web._t.database.parameters.date_format = '%a, %Y %b %d'; + var date = instance.web.str_to_date("2009-05-04"); + strictEqual(instance.web.format_value(date, {type:"date"}), + 'Mon, 2009 May 04'); + strictEqual(instance.web.parse_value('Mon, 2009 May 04', {type: 'date'}), + '2009-05-04'); }); - test('ES date format', function () { - openerp.web._t.database.parameters.date_format = '%a, %Y %b %d'; - var date = openerp.web.str_to_date("2009-05-04"); - strictEqual(openerp.web.format_value(date, {type:"date"}), 'Mon, 2009 May 04'); - strictEqual(openerp.web.parse_value('Mon, 2009 May 04', {type: 'date'}), '2009-05-04'); - }); - test('extended ES date format', function () { - openerp.web._t.database.parameters.date_format = '%a, %Y.eko %bren %da'; - var date = openerp.web.str_to_date("2009-05-04"); - strictEqual(openerp.web.format_value(date, {type:"date"}), 'Mon, 2009. May 04'); - strictEqual(openerp.web.parse_value('Mon, 2009. May 04', {type: 'date'}), '2009-05-04'); + test('extended ES date format', function (instance) { + instance.web._t.database.parameters.date_format = '%a, %Y.eko %bren %da'; + var date = instance.web.str_to_date("2009-05-04"); + strictEqual(instance.web.format_value(date, {type:"date"}), + 'Mon, 2009. May 04'); + strictEqual(instance.web.parse_value('Mon, 2009. May 04', {type: 'date'}), + '2009-05-04'); }); }); diff --git a/addons/web/static/test/list-editable.js b/addons/web/static/test/list-editable.js index 459a6df397a..b02e8abed96 100644 --- a/addons/web/static/test/list-editable.js +++ b/addons/web/static/test/list-editable.js @@ -1,16 +1,13 @@ -$(document).ready(function () { - var $fix = $('#qunit-fixture'); - - var instance; - var baseSetup = function () { - instance = openerp.testing.instanceFor('list_editable'); - - openerp.testing.loadTemplate(instance); - - openerp.testing.mockifyRPC(instance); - }; - - +openerp.testing.section('editor', { + dependencies: ['web.list_editable'], + rpc: 'mock', + templates: true, + setup: function (instance, $s, mock) { + mock('test.model:create', function () { + return 42; + }); + } +}, function (test) { /** * * @param {String} name @@ -30,7 +27,7 @@ $(document).ready(function () { } /** - * @param {Array} fields + * @param {Array} [fields] * @return {Object} */ function makeFormView(fields) { @@ -67,46 +64,37 @@ $(document).ready(function () { }; } - module('editor', { - setup: baseSetup - }); - asyncTest('base-state', 2, function () { + test('base-state', {asserts: 2}, function (instance, $fix) { var e = new instance.web.list.Editor({ dataset: {ids: []}, edition_view: function () { return makeFormView(); } }); - e.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error && error.message); }) + return e.appendTo($fix) .done(function () { ok(!e.is_editing(), "should not be editing"); ok(e.form instanceof instance.web.FormView, "should use default form type"); }); }); - asyncTest('toggle-edition-save', 4, function () { - instance.session.responses['/web/dataset/call_kw:create'] = function () { - return { result: 42 }; - }; - instance.session.responses['/web/dataset/call_kw:read'] = function () { - return { result: [{ - id: 42, - a: false, - b: false, - c: false - }]}; - }; + test('toggle-edition-save', { + asserts: 4, + setup: function (instance, $s, mock) { + mock('test.model:read', function () { + return [{id: 42, a: false, b: false, c: false}]; + }); + } + }, function (instance, $fix) { var e = new instance.web.list.Editor({ - dataset: new instance.web.DataSetSearch(), + dataset: new instance.web.DataSetSearch(null, 'test.model'), prepends_on_create: function () { return false; }, edition_view: function () { return makeFormView([ field('a'), field('b'), field('c') ]); } }); var counter = 0; - e.appendTo($fix) + return e.appendTo($fix) .then(function () { return e.edit({}, function () { ++counter; @@ -117,26 +105,21 @@ $(document).ready(function () { equal(counter, 3, "should have configured all fields"); return e.save(); }) - .always(start) - .fail(function (error) { ok(false, error && error.message); }) .done(function (record) { ok(!e.is_editing(), "should have stopped editing"); equal(record.id, 42, "should have newly created id"); }) }); - asyncTest('toggle-edition-cancel', 2, function () { - instance.session.responses['/web/dataset/call_kw:create'] = function () { - return { result: 42 }; - }; + test('toggle-edition-cancel', { asserts: 2 }, function (instance, $fix) { var e = new instance.web.list.Editor({ - dataset: new instance.web.DataSetSearch(), + dataset: new instance.web.DataSetSearch(null, 'test.model'), prepends_on_create: function () { return false; }, edition_view: function () { return makeFormView([ field('a'), field('b'), field('c') ]); } }); var counter = 0; - e.appendTo($fix) + return e.appendTo($fix) .then(function () { return e.edit({}, function () { ++counter; @@ -145,22 +128,20 @@ $(document).ready(function () { .then(function (form) { return e.cancel(); }) - .always(start) - .fail(function (error) { ok(false, error && error.message); }) .done(function (record) { ok(!e.is_editing(), "should have stopped editing"); ok(!record.id, "should have no id"); }) }); - asyncTest('toggle-save-required', 2, function () { - instance.session.responses['/web/dataset/call_kw:create'] = function () { - return { result: 42 }; - }; + test('toggle-save-required', { + asserts: 2, + fail_on_rejection: false + }, function (instance, $fix) { var e = new instance.web.list.Editor({ do_warn: function () { warnings++; }, - dataset: new instance.web.DataSetSearch(), + dataset: new instance.web.DataSetSearch(null, 'test.model'), prepends_on_create: function () { return false; }, edition_view: function () { return makeFormView([ @@ -169,7 +150,7 @@ $(document).ready(function () { }); var counter = 0; var warnings = 0; - e.appendTo($fix) + return e.appendTo($fix) .then(function () { return e.edit({}, function () { ++counter; @@ -178,78 +159,73 @@ $(document).ready(function () { .then(function (form) { return e.save(); }) - .always(start) .done(function () { ok(false, "cancel should not succeed"); }) .fail(function () { equal(warnings, 1, "should have been warned"); ok(e.is_editing(), "should have kept editing"); - }) + }); }); - - module('list-edition', { - setup: function () { - baseSetup(); - - var records = {}; - _.extend(instance.session.responses, { - '/web/view/load': function () { - return {result: { - type: 'tree', - fields: { - a: {type: 'char', string: "A"}, - b: {type: 'char', string: "B"}, - c: {type: 'char', string: "C"} - }, - arch: { - tag: 'tree', - attrs: {}, - children: [ - {tag: 'field', attrs: {name: 'a'}}, - {tag: 'field', attrs: {name: 'b'}}, - {tag: 'field', attrs: {name: 'c'}} - ] - } - }}; +}); +openerp.testing.section('list.edition', { + dependencies: ['web.list_editable'], + rpc: 'mock', + templates: true, + setup: function (instance, $s, mock) { + var records = {}; + mock('demo:create', function (args) { + records[42] = _.extend({}, args[0]); + return 42; + }); + mock('demo:read', function (args) { + var id = args[0][0]; + if (id in records) { + return [records[id]]; + } + return []; + }); + mock('/web/view/load', function () { + return { + type: 'tree', + fields: { + a: {type: 'char', string: "A"}, + b: {type: 'char', string: "B"}, + c: {type: 'char', string: "C"} }, - '/web/dataset/call_kw:create': function (params) { - records[42] = _.extend({}, params.params.args[0]); - return {result: 42}; - }, - '/web/dataset/call_kw:read': function (params) { - var id = params.params.args[0][0]; - if (id in records) { - return {result: [records[id]]}; - } - return {result: []}; + arch: { + tag: 'tree', + attrs: {}, + children: [ + {tag: 'field', attrs: {name: 'a'}}, + {tag: 'field', attrs: {name: 'b'}}, + {tag: 'field', attrs: {name: 'c'}} + ] } - }) - } - }); - asyncTest('newrecord', 6, function () { + }; + }); + } +}, function (test) { + test('newrecord', {asserts: 6}, function (instance, $fix, mock) { var got_defaults = false; - instance.session.responses['/web/dataset/call_kw:default_get'] = function (params) { - var fields = params.params.args[0]; + mock('demo:default_get', function (args) { + var fields = args[0]; deepEqual( fields, ['a', 'b', 'c'], "should ask defaults for all fields"); got_defaults = true; - return {result: { - a: "qux", - b: "quux" - }}; - }; + return { a: "qux", b: "quux" }; + }); var ds = new instance.web.DataSetStatic(null, 'demo', null, [1]); var l = new instance.web.ListView({}, ds, false, {editable: 'top'}); - l.appendTo($fix) + return l.appendTo($fix) .then(l.proxy('reload_content')) .then(function () { return l.start_edition(); }) - .always(start) .then(function () { ok(got_defaults, "should have fetched default values for form"); + return l.save_edition(); }) .then(function (result) { @@ -260,45 +236,39 @@ $(document).ready(function () { "should have used default values"); ok(!result.record.get('c'), "should have no value if there was no default"); - }) - .fail(function (e) { ok(false, e && e.message || e); }); - }); - - module('list-edition-events', { - setup: function () { - baseSetup(); - _.extend(instance.session.responses, { - '/web/view/load': function () { - return {result: { - type: 'tree', - fields: { - a: {type: 'char', string: "A"}, - b: {type: 'char', string: "B"}, - c: {type: 'char', string: "C"} - }, - arch: { - tag: 'tree', - attrs: {}, - children: [ - {tag: 'field', attrs: {name: 'a'}}, - {tag: 'field', attrs: {name: 'b'}}, - {tag: 'field', attrs: {name: 'c'}} - ] - } - }}; - }, - '/web/dataset/call_kw:read': function (params) { - return {result: [{ - id: 1, - a: 'foo', - b: 'bar', - c: 'baz' - }]}; - } }); - } }); - asyncTest('edition events', 4, function () { +}); +openerp.testing.section('list.edition.events', { + dependencies: ['web.list_editable'], + rpc: 'mock', + templates: true, + setup: function (instance, $s, mock) { + mock('demo:read', function () { + return [{ id: 1, a: 'foo', b: 'bar', c: 'baz' }]; + }); + mock('/web/view/load', function () { + return { + type: 'tree', + fields: { + a: {type: 'char', string: "A"}, + b: {type: 'char', string: "B"}, + c: {type: 'char', string: "C"} + }, + arch: { + tag: 'tree', + attrs: {}, + children: [ + {tag: 'field', attrs: {name: 'a'}}, + {tag: 'field', attrs: {name: 'b'}}, + {tag: 'field', attrs: {name: 'c'}} + ] + } + }; + }); + } +}, function (test) { + test('edition events', {asserts: 4}, function (instance, $fix) { var ds = new instance.web.DataSetStatic(null, 'demo', null, [1]); var o = { counter: 0, @@ -306,9 +276,8 @@ $(document).ready(function () { }; var l = new instance.web.ListView({}, ds, false, {editable: 'top'}); l.on('edit:before edit:after', o, o.onEvent); - l.appendTo($fix) + return l.appendTo($fix) .then(l.proxy('reload_content')) - .always(start) .then(function () { ok(l.options.editable, "should be editable"); equal(o.counter, 0, "should have seen no event yet"); @@ -317,11 +286,10 @@ $(document).ready(function () { .then(function () { ok(l.editor.is_editing(), "should be editing"); equal(o.counter, 2, "should have seen two edition events"); - }) - .fail(function (e) { ok(false, e && e.message); }); + }); }); - asyncTest('edition events: cancelling', 3, function () { + test('edition events: cancelling', {asserts: 3}, function (instance, $fix) { var edit_after = false; var ds = new instance.web.DataSetStatic(null, 'demo', null, [1]); var l = new instance.web.ListView({}, ds, false, {editable: 'top'}); @@ -331,9 +299,8 @@ $(document).ready(function () { l.on('edit:after', {}, function () { edit_after = true; }); - l.appendTo($fix) + return l.appendTo($fix) .then(l.proxy('reload_content')) - .always(start) .then(function () { ok(l.options.editable, "should be editable"); return l.start_edition(); @@ -343,7 +310,71 @@ $(document).ready(function () { ok(!l.editor.is_editing(), "should not be editing"); ok(!edit_after, "should not have fired the edit:after event"); return $.when(); - }) - .fail(function (e) { ok(false, e && e.message || e); }); + }); + }); +}); + +openerp.testing.section('list.edition.onwrite', { + dependencies: ['web.list_editable'], + rpc: 'mock', + templates: true, +}, function (test) { + test('record-to-read', {asserts: 4}, function (instance, $fix, mock) { + mock('/web/view/load', function () { + return { + type: 'tree', + fields: { + a: {type: 'char', string: "A"} + }, + arch: { + tag: 'tree', + attrs: { on_write: 'on_write', colors: 'red:a == "foo"' }, + children: [ + {tag: 'field', attrs: {name: 'a'}} + ] + } + }; + }); + mock('demo:read', function (args, kwargs) { + if (_.isEmpty(args[0])) { + return []; + } else if (_.isEqual(args[0], [1])) { + return [ + {id: 1, a: 'some value'} + ]; + } else if (_.isEqual(args[0], [42])) { + return [ {id: 42, a: 'foo'} ]; + } + throw new Error(JSON.stringify(_.toArray(arguments))); + }); + mock('demo:default_get', function () { return {}; }); + mock('demo:create', function () { return 1; }); + mock('demo:on_write', function () { return [42]; }); + + var ds = new instance.web.DataSetStatic(null, 'demo', null, []); + var l = new instance.web.ListView({}, ds, false, {editable: 'top'}); + return l.appendTo($fix) + .then(l.proxy('reload_content')) + .then(function () { + return l.start_edition(); + }) + .then(function () { + $fix.find('.oe_form_field input').val("some value").change(); + }) + .then(function () { + return l.save_edition(); + }) + .then(function () { + strictEqual(ds.ids.length, 2, + 'should have id of created + on_write'); + strictEqual(l.records.length, 2, + 'should have record of created + on_write'); + strictEqual( + $fix.find('tbody tr:eq(1)').css('color'), 'rgb(255, 0, 0)', + 'shoud have color applied'); + strictEqual( + $fix.find('tbody tr:eq(2)').css('color'), 'rgb(0, 0, 0)', + 'should have default color applied'); + }); }); }); diff --git a/addons/web/static/test/list-utils.js b/addons/web/static/test/list-utils.js index 6200ba788ce..84661138315 100644 --- a/addons/web/static/test/list-utils.js +++ b/addons/web/static/test/list-utils.js @@ -1,45 +1,34 @@ -$(document).ready(function () { - var openerp, - create = function (o) { - if (typeof Object.create === 'function') { - return Object.create(o); - } - function Cls() {} - Cls.prototype = o; - return new Cls; - }; - module('list-events', { - setup: function () { - 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); +openerp.testing.section('list.events', { + dependencies: ['web.list'] +}, function (test) { + var create = function (o) { + if (typeof Object.create === 'function') { + return Object.create(o); } - }); - test('Simple event triggering', function () { - var e = create(openerp.web.list.Events), passed = false; + function Cls() {} + Cls.prototype = o; + return new Cls; + }; + test('Simple event triggering', function (instance) { + var e = create(instance.web.list.Events), passed = false; e.bind('foo', function () { passed = true; }); e.trigger('foo'); ok(passed); }); - test('Bind all', function () { - var e = create(openerp.web.list.Events), event = null; + test('Bind all', function (instance) { + var e = create(instance.web.list.Events), event = null; e.bind(null, function (ev) { event = ev; }); e.trigger('foo'); strictEqual(event, 'foo'); }); - test('Propagate trigger params', function () { - var e = create(openerp.web.list.Events), p = false; + test('Propagate trigger params', function (instance) { + var e = create(instance.web.list.Events), p = false; e.bind(null, function (_, param) { p = param }); e.trigger('foo', true); strictEqual(p, true) }); - test('Bind multiple callbacks', function () { - var e = create(openerp.web.list.Events), count; + test('Bind multiple callbacks', function (instance) { + var e = create(instance.web.list.Events), count; e.bind('foo', function () { count++; }) .bind('bar', function () { count++; }) .bind(null, function () { count++; }) @@ -59,20 +48,20 @@ $(document).ready(function () { e.trigger('baz'); strictEqual(count, 3); }); - test('Mixin events', function () { - var cls = openerp.web.Class.extend({ + test('Mixin events', function (instance) { + var cls = instance.web.Class.extend({ method: function () { this.trigger('e'); } }); - cls.include(openerp.web.list.Events); - var instance = new cls, triggered = false; + cls.include(instance.web.list.Events); + var i = new cls, triggered = false; - instance.bind('e', function () { triggered = true; }); - instance.method(); + i.bind('e', function () { triggered = true; }); + i.method(); ok(triggered); }); - test('Unbind all handlers', function () { - var e = create(openerp.web.list.Events), passed = 0; + test('Unbind all handlers', function (instance) { + var e = create(instance.web.list.Events), passed = 0; e.bind('foo', function () { passed++; }); e.trigger('foo'); strictEqual(passed, 1); @@ -80,8 +69,8 @@ $(document).ready(function () { e.trigger('foo'); strictEqual(passed, 1); }); - test('Unbind one handler', function () { - var e = create(openerp.web.list.Events), p1 = 0, p2 = 0, + test('Unbind one handler', function (instance) { + var e = create(instance.web.list.Events), p1 = 0, p2 = 0, h1 = function () { p1++; }, h2 = function () { p2++; }; e.bind('foo', h1); e.bind('foo', h2); @@ -93,29 +82,20 @@ $(document).ready(function () { strictEqual(p1, 1); strictEqual(p2, 2); }); - - module('list-records', { - setup: function () { - 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); - } - }); - test('Basic record initialization', function () { - var r = new openerp.web.list.Record({qux: 3}); +}); +openerp.testing.section('list.records', { + dependencies: ['web.list'] +}, function (test) { + test('Basic record initialization', function (instance) { + var r = new instance.web.list.Record({qux: 3}); r.set('foo', 1); r.set('bar', 2); strictEqual(r.get('foo'), 1); strictEqual(r.get('bar'), 2); strictEqual(r.get('qux'), 3); }); - test('Change all the things', function () { - var r = new openerp.web.list.Record(), changed = false, field; + test('Change all the things', function (instance) { + var r = new instance.web.list.Record(), changed = false, field; r.bind('change', function () { changed = true; }); r.bind(null, function (e) { field = field || e.split(':')[1]}); r.set('foo', 1); @@ -123,8 +103,8 @@ $(document).ready(function () { ok(changed); strictEqual(field, 'foo'); }); - test('Change single field', function () { - var r = new openerp.web.list.Record(), changed = 0; + test('Change single field', function (instance) { + var r = new instance.web.list.Record(), changed = 0; r.bind('change:foo', function () { changed++; }); r.set('foo', 1); r.set('bar', 1); @@ -132,21 +112,12 @@ $(document).ready(function () { strictEqual(r.get('bar'), 1); strictEqual(changed, 1); }); - - module('list-collections', { - setup: function () { - 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); - } - }); - test('degenerate-fetch', function () { - var c = new openerp.web.list.Collection(); +}); +openerp.testing.section('list.collections', { + dependencies: ['web.list'] +}, function (test) { + test('degenerate-fetch', function (instance) { + var c = new instance.web.list.Collection(); strictEqual(c.length, 0); c.add({id: 1, value: 2}); c.add({id: 2, value: 3}); @@ -155,16 +126,16 @@ $(document).ready(function () { strictEqual(c.length, 4); var r = c.at(2), r2 = c.get(1); - ok(r instanceof openerp.web.list.Record); + ok(r instanceof instance.web.list.Record); strictEqual(r.get('id'), 3); strictEqual(r.get('value'), 5); - ok(r2 instanceof openerp.web.list.Record); + ok(r2 instanceof instance.web.list.Record); strictEqual(r2.get('id'), 1); strictEqual(r2.get('value'), 2); }); - test('degenerate-indexed-add', function () { - var c = new openerp.web.list.Collection([ + test('degenerate-indexed-add', function (instance) { + var c = new instance.web.list.Collection([ {id: 1, value: 5}, {id: 2, value: 10}, {id: 3, value: 20} @@ -175,8 +146,8 @@ $(document).ready(function () { strictEqual(c.at(1).get('value'), 55); strictEqual(c.at(3).get('value'), 20); }); - test('degenerate-remove', function () { - var c = new openerp.web.list.Collection([ + test('degenerate-remove', function (instance) { + var c = new instance.web.list.Collection([ {id: 1, value: 5}, {id: 2, value: 10}, {id: 3, value: 20} @@ -188,9 +159,9 @@ $(document).ready(function () { equal(c.get(2), undefined); strictEqual(c.at(1).get('value'), 20); }); - test('degenerate-remove-bound', function () { + test('degenerate-remove-bound', function (instance) { var changed = false, - c = new openerp.web.list.Collection([ {id: 1, value: 5} ]); + c = new instance.web.list.Collection([ {id: 1, value: 5} ]); c.bind('change', function () { changed = true; }); var record = c.get(1); c.remove(record); @@ -198,8 +169,8 @@ $(document).ready(function () { ok(!changed, 'removed records should not trigger events in their ' + 'parent collection'); }); - test('degenerate-reset', function () { - var event, obj, c = new openerp.web.list.Collection([ + test('degenerate-reset', function (instance) { + var event, obj, c = new instance.web.list.Collection([ {id: 1, value: 5}, {id: 2, value: 10}, {id: 3, value: 20} @@ -218,9 +189,9 @@ $(document).ready(function () { strictEqual(c.length, 1); strictEqual(c.get(42).get('value'), 55); }); - test('degenerate-reset-bound', function () { + test('degenerate-reset-bound', function (instance) { var changed = false, - c = new openerp.web.list.Collection([ {id: 1, value: 5} ]); + c = new instance.web.list.Collection([ {id: 1, value: 5} ]); c.bind('change', function () { changed = true; }); var record = c.get(1); c.reset(); @@ -229,9 +200,9 @@ $(document).ready(function () { 'parent collection'); }); - test('degenerate-propagations', function () { + test('degenerate-propagations', function (instance) { var values = []; - var c = new openerp.web.list.Collection([ + var c = new instance.web.list.Collection([ {id: 1, value: 5}, {id: 2, value: 10}, {id: 3, value: 20} @@ -244,8 +215,8 @@ $(document).ready(function () { c.get(3).set('value', 21); deepEqual(values, [6, 11, 21]); }); - test('BTree', function () { - var root = new openerp.web.list.Collection(), + test('BTree', function (instance) { + var root = new instance.web.list.Collection(), c = root.proxy('admin'), total = 0; c.add({id: 1, name: "Administrator", login: 'admin'}); @@ -260,8 +231,8 @@ $(document).ready(function () { c.at(1).set('wealth', 5); strictEqual(total, 47); }); - test('degenerate-successor', function () { - var root = new openerp.web.list.Collection([ + test('degenerate-successor', function (instance) { + var root = new instance.web.list.Collection([ {id: 1, value: 1}, {id: 2, value: 2}, {id: 3, value: 3}, @@ -282,8 +253,8 @@ $(document).ready(function () { root.at(3).attributes, "wraparound should have no effect if not succ(last_record)"); }); - test('successor', function () { - var root = new openerp.web.list.Collection(); + test('successor', function (instance) { + var root = new instance.web.list.Collection(); root.proxy('first').add([{id: 1, value: 1}, {id: 2, value: 2}]); root.proxy('second').add([{id: 3, value: 3}, {id: 4, value: 5}]); root.proxy('third').add([{id: 5, value: 8}, {id: 6, value: 13}]); @@ -298,8 +269,8 @@ $(document).ready(function () { root.get(3).attributes, "should wraparound within a collection"); }); - test('degenerate-predecessor', function () { - var root = new openerp.web.list.Collection([ + test('degenerate-predecessor', function (instance) { + var root = new instance.web.list.Collection([ {id: 1, value: 1}, {id: 2, value: 2}, {id: 3, value: 3}, @@ -320,8 +291,8 @@ $(document).ready(function () { root.at(0).attributes, "wraparound should have no effect if not pred(first_record)"); }); - test('predecessor', function () { - var root = new openerp.web.list.Collection(); + test('predecessor', function (instance) { + var root = new instance.web.list.Collection(); root.proxy('first').add([{id: 1, value: 1}, {id: 2, value: 2}]); root.proxy('second').add([{id: 3, value: 3}, {id: 4, value: 5}]); root.proxy('third').add([{id: 5, value: 8}, {id: 6, value: 13}]); @@ -336,21 +307,12 @@ $(document).ready(function () { root.get(4).attributes, "should wraparound within a collection"); }); - - module('list-hofs', { - setup: function () { - 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); - } - }); - test('each, degenerate', function () { - var c = new openerp.web.list.Collection([ +}); +openerp.testing.section('list.collections.hom', { + dependencies: ['web.list'] +}, function (test) { + test('each, degenerate', function (instance) { + var c = new instance.web.list.Collection([ {id: 1, value: 5}, {id: 2, value: 10}, {id: 3, value: 20} @@ -362,8 +324,8 @@ $(document).ready(function () { ids, [1, 2, 3], 'degenerate collections should be iterated in record order'); }); - test('each, deep', function () { - var root = new openerp.web.list.Collection(), + test('each, deep', function (instance) { + var root = new instance.web.list.Collection(), ids = []; root.proxy('foo').add([ {id: 1, value: 5}, @@ -382,8 +344,8 @@ $(document).ready(function () { ids, [1, 2, 3, 10, 20, 30], 'tree collections should be deeply iterated'); }); - test('map, degenerate', function () { - var c = new openerp.web.list.Collection([ + test('map, degenerate', function (instance) { + var c = new instance.web.list.Collection([ {id: 1, value: 5}, {id: 2, value: 10}, {id: 3, value: 20} @@ -395,8 +357,8 @@ $(document).ready(function () { ids, [1, 2, 3], 'degenerate collections should be iterated in record order'); }); - test('map, deep', function () { - var root = new openerp.web.list.Collection(); + test('map, deep', function (instance) { + var root = new instance.web.list.Collection(); root.proxy('foo').add([ {id: 1, value: 5}, {id: 2, value: 10}, @@ -414,29 +376,20 @@ $(document).ready(function () { ids, [1, 2, 3, 10, 20, 30], 'tree collections should be deeply iterated'); }); - - module("list-weirds", { - setup: function () { - 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); - } - }); - test('set-from-noid', function () { - var root = new openerp.web.list.Collection(); +}); +openerp.testing.section('list.collection.weirdoes', { + dependencies: ['web.list'] +}, function (test) { + test('set-from-noid', function (instance) { + var root = new instance.web.list.Collection(); root.add({v: 3}); root.at(0).set('id', 42); var record = root.get(42); equal(root.length, 1); equal(record.get('v'), 3, "should have fetched the original record"); }); - test('set-from-previd', function () { - var root = new openerp.web.list.Collection(); + test('set-from-previd', function (instance) { + var root = new instance.web.list.Collection(); root.add({id: 1, v: 2}); root.get(1).set('id', 42); var record = root.get(42); diff --git a/addons/web/static/test/list.js b/addons/web/static/test/list.js new file mode 100644 index 00000000000..22c33ef104a --- /dev/null +++ b/addons/web/static/test/list.js @@ -0,0 +1,56 @@ +openerp.testing.section('list.buttons', { + dependencies: ['web.list', 'web.form'], + rpc: 'mock', + templates: true +}, function (test) { + test('record-deletion', {asserts: 2}, function (instance, $fix, mock) { + mock('/web/view/load', function () { + return { + type: 'tree', + fields: { + a: {type: 'char', string: "A"} + }, + arch: { + tag: 'tree', + attrs: { }, + children: [ + {tag: 'field', attrs: {name: 'a'}}, + {tag: 'button', attrs: {type: 'object', name: 'foo'}} + ] + } + }; + }); + mock('demo:read', function (args, kwargs) { + if (_.isEqual(args[0], [1, 2, 3])) { + return [ + {id: 1, a: 'foo'}, {id: 2, a: 'bar'}, {id: 3, a: 'baz'} + ]; + } else if (_.isEqual(args[0], [2])) { + // button action virtually removed record + return []; + } + throw new Error(JSON.stringify(_.toArray(arguments))); + }); + mock('/web/dataset/call_button', function () { return false; }); + var ds = new instance.web.DataSetStatic(null, 'demo', null, [1, 2, 3]); + var l = new instance.web.ListView({ + do_action: openerp.testing.noop + }, ds, false, {editable: 'top'}); + return l.appendTo($fix) + .then(l.proxy('reload_content')) + .then(function () { + var d = $.Deferred(); + l.records.bind('remove', function () { + d.resolve(); + }); + $fix.find('table tbody tr:eq(1) button').click(); + return d.promise(); + }) + .then(function () { + strictEqual(l.records.length, 2, + "should have 2 records left"); + strictEqual($fix.find('table tbody tr[data-id]').length, 2, + "should have 2 rows left"); + }); + }); +}); diff --git a/addons/web/static/test/mutex.js b/addons/web/static/test/mutex.js new file mode 100644 index 00000000000..e88911b5b45 --- /dev/null +++ b/addons/web/static/test/mutex.js @@ -0,0 +1,60 @@ +openerp.testing.section('mutex', { + dependencies: ['web.coresetup'], + setup: function (instance) { + } +}, function (test) { + test('simpleScheduling', function (instance) { + var m = new $.Mutex(); + var def1 = $.Deferred(); + var def2 = $.Deferred(); + var p1 = m.exec(function() { return def1; }); + var p2 = m.exec(function() { return def2; }); + equal(p1.state(), "pending"); + equal(p2.state(), "pending"); + def1.resolve(); + equal(p1.state(), "resolved"); + equal(p2.state(), "pending"); + def2.resolve(); + equal(p1.state(), "resolved"); + equal(p2.state(), "resolved"); + }); + test('simpleScheduling2', function (instance) { + var m = new $.Mutex(); + var def1 = $.Deferred(); + var def2 = $.Deferred(); + var p1 = m.exec(function() { return def1; }); + var p2 = m.exec(function() { return def2; }); + equal(p1.state(), "pending"); + equal(p2.state(), "pending"); + def2.resolve(); + equal(p1.state(), "pending"); + equal(p2.state(), "pending"); + def1.resolve(); + equal(p1.state(), "resolved"); + equal(p2.state(), "resolved"); + }); + test('reject', function (instance) { + var m = new $.Mutex(); + var def1 = $.Deferred(); + var def2 = $.Deferred(); + var def3 = $.Deferred(); + var p1 = m.exec(function() {return def1;}); + var p2 = m.exec(function() {return def2;}); + var p3 = m.exec(function() {return def3;}); + equal(p1.state(), "pending"); + equal(p2.state(), "pending"); + equal(p3.state(), "pending"); + def1.resolve(); + equal(p1.state(), "resolved"); + equal(p2.state(), "pending"); + equal(p3.state(), "pending"); + def2.reject(); + equal(p1.state(), "resolved"); + equal(p2.state(), "rejected"); + equal(p3.state(), "pending"); + def3.resolve(); + equal(p1.state(), "resolved"); + equal(p2.state(), "rejected"); + equal(p3.state(), "resolved"); + }); +}); diff --git a/addons/web/static/test/registry.js b/addons/web/static/test/registry.js index ca689a351e0..2ad69a541bc 100644 --- a/addons/web/static/test/registry.js +++ b/addons/web/static/test/registry.js @@ -1,58 +1,55 @@ -$(document).ready(function () { - var openerp; - module('Registry', { - setup: function () { - openerp = window.openerp.init([]); - window.openerp.web.corelib(openerp); - openerp.web.Foo = {}; - openerp.web.Bar = {}; - openerp.web.Foo2 = {}; - } - }); - test('key set', function () { - var reg = new openerp.web.Registry(); +openerp.testing.section('registry', { + dependencies: ['web.corelib'], + setup: function (instance) { + instance.web.Foo = {}; + instance.web.Bar = {}; + instance.web.Foo2 = {}; + } +}, function (test) { + test('key set', function (instance) { + var reg = new instance.web.Registry(); - reg.add('foo', 'openerp.web.Foo') - .add('bar', 'openerp.web.Bar'); - strictEqual(reg.get_object('bar'), openerp.web.Bar); + reg.add('foo', 'instance.web.Foo') + .add('bar', 'instance.web.Bar'); + strictEqual(reg.get_object('bar'), instance.web.Bar); }); - test('extension', function () { - var reg = new openerp.web.Registry({ - foo: 'openerp.web.Foo', - bar: 'openerp.web.Bar' + test('extension', function (instance) { + var reg = new instance.web.Registry({ + foo: 'instance.web.Foo', + bar: 'instance.web.Bar' }); - var reg2 = reg.extend({ 'foo': 'openerp.web.Foo2' }); - strictEqual(reg.get_object('foo'), openerp.web.Foo); - strictEqual(reg2.get_object('foo'), openerp.web.Foo2); + var reg2 = reg.extend({ 'foo': 'instance.web.Foo2' }); + strictEqual(reg.get_object('foo'), instance.web.Foo); + strictEqual(reg2.get_object('foo'), instance.web.Foo2); }); - test('remain-linked', function () { - var reg = new openerp.web.Registry({ - foo: 'openerp.web.Foo', - bar: 'openerp.web.Bar' + test('remain-linked', function (instance) { + var reg = new instance.web.Registry({ + foo: 'instance.web.Foo', + bar: 'instance.web.Bar' }); var reg2 = reg.extend(); - reg.add('foo2', 'openerp.web.Foo2'); - strictEqual(reg.get_object('foo2'), openerp.web.Foo2); - strictEqual(reg2.get_object('foo2'), openerp.web.Foo2); + reg.add('foo2', 'instance.web.Foo2'); + strictEqual(reg.get_object('foo2'), instance.web.Foo2); + strictEqual(reg2.get_object('foo2'), instance.web.Foo2); }); - test('multiget', function () { - var reg = new openerp.web.Registry({ - foo: 'openerp.web.Foo', - bar: 'openerp.web.Bar' + test('multiget', function (instance) { + var reg = new instance.web.Registry({ + foo: 'instance.web.Foo', + bar: 'instance.web.Bar' }); strictEqual(reg.get_any(['qux', 'grault', 'bar', 'foo']), - openerp.web.Bar); + instance.web.Bar); }); - test('extended-multiget', function () { - var reg = new openerp.web.Registry({ - foo: 'openerp.web.Foo', - bar: 'openerp.web.Bar' + test('extended-multiget', function (instance) { + var reg = new instance.web.Registry({ + foo: 'instance.web.Foo', + bar: 'instance.web.Bar' }); var reg2 = reg.extend(); strictEqual(reg2.get_any(['qux', 'grault', 'bar', 'foo']), - openerp.web.Bar); + instance.web.Bar); }); }); diff --git a/addons/web/static/test/rpc.js b/addons/web/static/test/rpc.js index be7cbce9f41..85f562ef225 100644 --- a/addons/web/static/test/rpc.js +++ b/addons/web/static/test/rpc.js @@ -1,16 +1,8 @@ -$(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; +openerp.testing.section('misordered resolution managemeng', { + dependencies: ['web.data'] +}, function (test) { + test('Resolve all correctly ordered, sync', function (instance) { + var dm = new instance.web.DropMisordered(), flag = false; var d1 = $.Deferred(), d2 = $.Deferred(), r1 = dm.add(d1), r2 = dm.add(d2); @@ -23,8 +15,8 @@ $(document).ready(function () { ok(flag); }); - test("Don't resolve mis-ordered, sync", function () { - var dm = new openerp.web.DropMisordered(), + test("Don't resolve mis-ordered, sync", function (instance) { + var dm = new instance.web.DropMisordered(), done1 = false, done2 = false, fail1 = false, fail2 = false; @@ -44,8 +36,8 @@ $(document).ready(function () { ok(done2); ok(!fail2); }); - test('Fail mis-ordered flag, sync', function () { - var dm = new openerp.web.DropMisordered(true), + test('Fail mis-ordered flag, sync', function (instance) { + var dm = new instance.web.DropMisordered(true), done1 = false, done2 = false, fail1 = false, fail2 = false; @@ -66,8 +58,8 @@ $(document).ready(function () { ok(!fail2); }); - asyncTest('Resolve all correctly ordered, async', 1, function () { - var dm = new openerp.web.DropMisordered(); + test('Resolve all correctly ordered, async', {asserts: 1}, function (instance) { + var dm = new instance.web.DropMisordered(); var d1 = $.Deferred(), d2 = $.Deferred(), r1 = dm.add(d1), r2 = dm.add(d2); @@ -75,13 +67,12 @@ $(document).ready(function () { setTimeout(function () { d1.resolve(); }, 100); setTimeout(function () { d2.resolve(); }, 200); - $.when(r1, r2).done(function () { - start(); + return $.when(r1, r2).done(function () { ok(true); }); }); - asyncTest("Don't resolve mis-ordered, async", 4, function () { - var dm = new openerp.web.DropMisordered(), + test("Don't resolve mis-ordered, async", {asserts: 4}, function (instance) { + var dm = new instance.web.DropMisordered(), done1 = false, done2 = false, fail1 = false, fail2 = false; @@ -94,18 +85,20 @@ $(document).ready(function () { setTimeout(function () { d1.resolve(); }, 200); setTimeout(function () { d2.resolve(); }, 100); + var done = $.Deferred(); setTimeout(function () { - start(); // d1 is in limbo ok(!done1); ok(!fail1); // d2 is resolved ok(done2); ok(!fail2); + done.resolve(); }, 400); + return $.when(d1, d2, done); }); - asyncTest('Fail mis-ordered flag, async', 4, function () { - var dm = new openerp.web.DropMisordered(true), + test('Fail mis-ordered flag, async', {asserts: 4}, function (instance) { + var dm = new instance.web.DropMisordered(true), done1 = false, done2 = false, fail1 = false, fail2 = false; @@ -118,6 +111,7 @@ $(document).ready(function () { setTimeout(function () { d1.resolve(); }, 200); setTimeout(function () { d2.resolve(); }, 100); + var done = $.Deferred(); setTimeout(function () { start(); // d1 is failed @@ -126,6 +120,8 @@ $(document).ready(function () { // d2 is resolved ok(done2); ok(!fail2); + done.resolve(); }, 400); + return $.when(d1, d2, done) }); }); diff --git a/addons/web/static/test/search.js b/addons/web/static/test/search.js index 3ef4d6840e2..20534eff76a 100644 --- a/addons/web/static/test/search.js +++ b/addons/web/static/test/search.js @@ -1,11 +1,7 @@ -$(document).ready(function () { - var instance; - module('query', { - setup: function () { - instance = openerp.testing.instanceFor('search'); - } - }); - test('Adding a facet to the query creates a facet and a value', function () { +openerp.testing.section('query', { + dependencies: ['web.search'] +}, function (test) { + test('Adding a facet to the query creates a facet and a value', function (instance) { var query = new instance.web.search.SearchQuery; var field = {}; query.add({ @@ -19,7 +15,7 @@ $(document).ready(function () { equal(facet.get('field'), field); deepEqual(facet.get('values'), [{label: 'Value', value: 3}]); }); - test('Adding two facets', function () { + test('Adding two facets', function (instance) { var query = new instance.web.search.SearchQuery; query.add([ { category: 'Foo', field: {}, values: [{label: 'Value', value: 3}] }, @@ -30,7 +26,7 @@ $(document).ready(function () { equal(query.at(0).values.length, 1); equal(query.at(1).values.length, 1); }); - test('If a facet already exists, add values to it', function () { + test('If a facet already exists, add values to it', function (instance) { var query = new instance.web.search.SearchQuery; var field = {}; query.add({category: 'A', field: field, values: [{label: 'V1', value: 0}]}); @@ -43,7 +39,7 @@ $(document).ready(function () { {label: 'V2', value: 1} ]); }); - test('Facet being implicitly changed should trigger change, not add', function () { + test('Facet being implicitly changed should trigger change, not add', function (instance) { var query = new instance.web.search.SearchQuery; var field = {}, added = false, changed = false; query.add({category: 'A', field: field, values: [{label: 'V1', value: 0}]}); @@ -54,7 +50,7 @@ $(document).ready(function () { ok(!added, "query.add adding values to a facet should not trigger an add"); ok(changed, "query.add adding values to a facet should not trigger a change"); }); - test('Toggling a facet, value which does not exist should add it', function () { + test('Toggling a facet, value which does not exist should add it', function (instance) { var query = new instance.web.search.SearchQuery; var field = {}; query.toggle({category: 'A', field: field, values: [{label: 'V1', value: 0}]}); @@ -65,7 +61,7 @@ $(document).ready(function () { deepEqual(facet.get('values'), [{label: 'V1', value: 0}], "Facet's value should match input"); }); - test('Toggling a facet which exists with a value which does not should add the value to the facet', function () { + test('Toggling a facet which exists with a value which does not should add the value to the facet', function (instance) { var field = {}; var query = new instance.web.search.SearchQuery; query.add({category: 'A', field: field, values: [{label: 'V1', value: 0}]}); @@ -79,7 +75,7 @@ $(document).ready(function () { {label: 'V2', value: 1} ]); }); - test('Toggling a facet which exists with a value which does as well should remove the value from the facet', function () { + test('Toggling a facet which exists with a value which does as well should remove the value from the facet', function (instance) { var field = {}; var query = new instance.web.search.SearchQuery; query.add({category: 'A', field: field, values: [{label: 'V1', value: 0}]}); @@ -94,7 +90,7 @@ $(document).ready(function () { {label: 'V1', value: 0} ]); }); - test('Toggling off the last value of a facet should remove the facet', function () { + test('Toggling off the last value of a facet should remove the facet', function (instance) { var field = {}; var query = new instance.web.search.SearchQuery; query.add({category: 'A', field: field, values: [{label: 'V1', value: 0}]}); @@ -103,7 +99,7 @@ $(document).ready(function () { equal(query.length, 0, 'Should have removed the facet'); }); - test('Intermediate emptiness should not remove the facet', function () { + test('Intermediate emptiness should not remove the facet', function (instance) { var field = {}; var query = new instance.web.search.SearchQuery; query.add({category: 'A', field: field, values: [{label: 'V1', value: 0}]}); @@ -121,7 +117,7 @@ $(document).ready(function () { ]); }); - test('Reseting with multiple facets should still work to load defaults', function () { + test('Reseting with multiple facets should still work to load defaults', function (instance) { var query = new instance.web.search.SearchQuery; var field = {}; query.reset([ @@ -135,78 +131,75 @@ $(document).ready(function () { {label: 'V2', value: 1} ]) }); +}); - module('defaults', { - setup: function () { - instance = openerp.testing.instanceFor('search'); - - openerp.testing.loadTemplate(instance); - - openerp.testing.mockifyRPC(instance); - } - }); - - /** - * Builds a basic search view with a single "dummy" field. The dummy - * extends `instance.web.search.Field`, it does not add any (class) - * attributes beyond what is provided through ``dummy_widget_attributes``. - * - * The view is returned un-started, it is the caller's role to start it - * (or use DOM-insertion methods to start it indirectly). - * - * @param [dummy_widget_attributes={}] - * @param [defaults={}] - * @return {instance.web.SearchView} - */ - function makeSearchView(dummy_widget_attributes, defaults) { - instance.web.search.fields.add( - 'dummy', 'instance.dummy.DummyWidget'); - instance.dummy = {}; - instance.dummy.DummyWidget = instance.web.search.Field.extend( - dummy_widget_attributes || {}); - if (!('/web/searchview/load' in instance.session.responses)) { - instance.session.responses['/web/searchview/load'] = function () { - return {result: {fields_view: { - type: 'search', - fields: { - dummy: {type: 'char', string: "Dummy"} - }, - arch: { - tag: 'search', - attrs: {}, - children: [{ - tag: 'field', - attrs: { - name: 'dummy', - widget: 'dummy' - }, - children: [] - }] - } - }}}; - }; - } - instance.session.responses['/web/searchview/get_filters'] = function () { - return {result: []}; +/** + * Builds a basic search view with a single "dummy" field. The dummy + * extends `instance.web.search.Field`, it does not add any (class) + * attributes beyond what is provided through ``dummy_widget_attributes``. + * + * The view is returned un-started, it is the caller's role to start it + * (or use DOM-insertion methods to start it indirectly). + * + * @param instance + * @param [dummy_widget_attributes={}] + * @param [defaults={}] + * @return {instance.web.SearchView} + */ +var makeSearchView = function (instance, dummy_widget_attributes, defaults) { + instance.web.search.fields.add( + 'dummy', 'instance.dummy.DummyWidget'); + instance.dummy = {}; + instance.dummy.DummyWidget = instance.web.search.Field.extend( + dummy_widget_attributes || {}); + if (!('/web/searchview/load' in instance.session.responses)) { + instance.session.responses['/web/searchview/load'] = function () { + return {fields_view: { + type: 'search', + fields: { + dummy: {type: 'char', string: "Dummy"} + }, + arch: { + tag: 'search', + attrs: {}, + children: [{ + tag: 'field', + attrs: { + name: 'dummy', + widget: 'dummy' + }, + children: [] + }] + } + }}; }; - instance.session.responses['/web/searchview/fields_get'] = function () { - return {result: {fields: { - dummy: {type: 'char', string: 'Dummy'} - }}}; - }; - - var dataset = {model: 'dummy.model', get_context: function () { return {}; }}; - var view = new instance.web.SearchView(null, dataset, false, defaults); - var self = this; - view.on('invalid_search', self, function () { - ok(false, JSON.stringify([].slice(arguments))); - }); - return view; } - asyncTest('calling', 2, function () { + instance.session.responses['/web/searchview/get_filters'] = function () { + return []; + }; + instance.session.responses['/web/searchview/fields_get'] = function () { + return {fields: { + dummy: {type: 'char', string: 'Dummy'} + }}; + }; + + var dataset = {model: 'dummy.model', get_context: function () { return {}; }}; + var view = new instance.web.SearchView(null, dataset, false, defaults); + var self = this; + view.on('invalid_search', self, function () { + ok(false, JSON.stringify([].slice(arguments))); + }); + return view; +}; +openerp.testing.section('defaults', { + dependencies: ['web.search'], + rpc: 'mock', + templates: true, +}, function (test) { + test('calling', {asserts: 2}, function (instance, $s) { var defaults_called = false; - var view = makeSearchView({ + var view = makeSearchView(instance, { facet_for_defaults: function (defaults) { defaults_called = true; return $.when({ @@ -216,9 +209,7 @@ $(document).ready(function () { }); } }, {dummy: 42}); - view.appendTo($('#qunit-fixture')) - .always(start) - .fail(function (error) { ok(false, error.message); }) + return view.appendTo($s) .done(function () { ok(defaults_called, "should have called defaults"); deepEqual( @@ -227,7 +218,7 @@ $(document).ready(function () { "should have generated a facet with the default value"); }); }); - asyncTest('FilterGroup', 3, function () { + test('FilterGroup', {asserts: 3}, function (instance) { var view = {inputs: [], query: {on: function () {}}}; var filter_a = new instance.web.search.Filter( {attrs: {name: 'a'}}, view); @@ -235,9 +226,7 @@ $(document).ready(function () { {attrs: {name: 'b'}}, view); var group = new instance.web.search.FilterGroup( [filter_a, filter_b], view); - group.facet_for_defaults({a: true, b: true}) - .always(start) - .fail(function (error) { ok(false, error && error.message); }) + return group.facet_for_defaults({a: true, b: true}) .done(function (facet) { var model = facet; if (!(model instanceof instance.web.search.Facet)) { @@ -249,13 +238,11 @@ $(document).ready(function () { strictEqual(values.at(1).get('value'), filter_b); }); }); - asyncTest('Field', 4, function () { + test('Field', {asserts: 4}, function (instance) { var view = {inputs: []}; var f = new instance.web.search.Field( {attrs: {string: 'Dummy', name: 'dummy'}}, {}, view); - f.facet_for_defaults({dummy: 42}) - .always(start) - .fail(function (error) { ok(false, error && error.message); }) + return f.facet_for_defaults({dummy: 42}) .done(function (facet) { var model = facet; if (!(model instanceof instance.web.search.Facet)) { @@ -275,15 +262,13 @@ $(document).ready(function () { "facet value should match provided default"); }); }); - asyncTest('Selection: valid value', 4, function () { + test('Selection: valid value', {asserts: 4}, function (instance) { var view = {inputs: []}; var f = new instance.web.search.SelectionField( {attrs: {name: 'dummy', string: 'Dummy'}}, {selection: [[1, "Foo"], [2, "Bar"], [3, "Baz"], [4, "Qux"]]}, view); - f.facet_for_defaults({dummy: 3}) - .always(start) - .fail(function (error) { ok(false, error && error.message); }) + return f.facet_for_defaults({dummy: 3}) .done(function (facet) { var model = facet; if (!(model instanceof instance.web.search.Facet)) { @@ -303,36 +288,28 @@ $(document).ready(function () { "facet value should match provided default's selection"); }); }); - asyncTest('Selection: invalid value', 1, function () { + test('Selection: invalid value', {asserts: 1}, function (instance) { var view = {inputs: []}; var f = new instance.web.search.SelectionField( {attrs: {name: 'dummy', string: 'Dummy'}}, {selection: [[1, "Foo"], [2, "Bar"], [3, "Baz"], [4, "Qux"]]}, view); - f.facet_for_defaults({dummy: 42}) - .always(start) - .fail(function (error) { ok(false, error && error.message); }) + return f.facet_for_defaults({dummy: 42}) .done(function (facet) { ok(!facet, "an invalid value should result in a not-facet"); }); }); - asyncTest("M2O default: value", 7, function () { + test("M2O default: value", {asserts: 5}, function (instance, $s, mock) { var view = {inputs: []}, id = 4; var f = new instance.web.search.ManyToOneField( {attrs: {name: 'dummy', string: 'Dummy'}}, {relation: 'dummy.model.name'}, view); - instance.session.responses['/web/dataset/call_kw'] = function (req) { - equal(req.params.method, 'name_get', - "m2o should resolve default id"); - equal(req.params.model, f.attrs.relation, - "query model should match m2o relation"); - equal(req.params.args[0], id); - return {result: [[id, "DumDumDum"]]}; - }; - f.facet_for_defaults({dummy: id}) - .always(start) - .fail(function (error) { ok(false, error && error.message); }) + mock('dummy.model.name:name_get', function (args) { + equal(args[0], id); + return [[id, "DumDumDum"]]; + }); + return f.facet_for_defaults({dummy: id}) .done(function (facet) { var model = facet; if (!(model instanceof instance.web.search.Facet)) { @@ -352,34 +329,26 @@ $(document).ready(function () { "facet value should match provided default's selection"); }); }); - asyncTest("M2O default: value", 1, function () { + test("M2O default: value", {asserts: 1}, function (instance, $s, mock) { var view = {inputs: []}, id = 4; var f = new instance.web.search.ManyToOneField( {attrs: {name: 'dummy', string: 'Dummy'}}, {relation: 'dummy.model.name'}, view); - instance.session.responses['/web/dataset/call_kw'] = function (req) { - return {result: []}; - }; - f.facet_for_defaults({dummy: id}) - .always(start) - .fail(function (error) { ok(false, error && error.message); }) + mock('dummy.model.name:name_get', function () { return [] }); + return f.facet_for_defaults({dummy: id}) .done(function (facet) { ok(!facet, "an invalid m2o default should yield a non-facet"); }); }); - - module('completions', { - setup: function () { - instance = openerp.testing.instanceFor('search'); - - openerp.testing.loadTemplate(instance); - - openerp.testing.mockifyRPC(instance); - } - }); - asyncTest('calling', 4, function () { - var view = makeSearchView({ +}); +openerp.testing.section('completions', { + dependencies: ['web.search'], + rpc: 'mock', + templates: true +}, function (test) { + test('calling', {asserts: 4}, function (instance, $s) { + var view = makeSearchView(instance, { complete: function () { return $.when({ label: "Dummy", @@ -391,10 +360,11 @@ $(document).ready(function () { }); } }); - view.appendTo($('#qunit-fixture')) - .done(function () { + var done = $.Deferred(); + view.appendTo($s) + .then(function () { view.complete_global_search({term: "dum"}, function (completions) { - start(); + done.resolve(); equal(completions.length, 1, "should have a single completion"); var completion = completions[0]; equal(completion.label, "Dummy", @@ -405,9 +375,10 @@ $(document).ready(function () { [{label: 'dummy', value: 42}], "should have provided values"); }); - }); + }).fail(function () { done.reject.apply(done, arguments); }); + return done; }); - asyncTest('facet selection', 2, function () { + test('facet selection', {asserts: 2}, function (instance, $s) { var completion = { label: "Dummy", facet: { @@ -421,10 +392,8 @@ $(document).ready(function () { } }; - var view = makeSearchView({}); - view.appendTo($('#qunit-fixture')) - .always(start) - .fail(function (error) { ok(false, error.message); }) + var view = makeSearchView(instance); + return view.appendTo($s) .done(function () { view.select_completion( {preventDefault: function () {}}, @@ -436,7 +405,7 @@ $(document).ready(function () { "should have the right facet in the query"); }); }); - asyncTest('facet selection: new value existing facet', 3, function () { + test('facet selection: new value existing facet', {asserts: 3}, function (instance, $s) { var field = { get_domain: openerp.testing.noop, get_context: openerp.testing.noop, @@ -451,10 +420,8 @@ $(document).ready(function () { } }; - var view = makeSearchView({}); - view.appendTo($('#qunit-fixture')) - .always(start) - .fail(function (error) { ok(false, error.message); }) + var view = makeSearchView(instance); + return view.appendTo($s) .done(function () { view.query.add({field: field, category: 'Dummy', values: [{label: 'previous', value: 41}]}); @@ -470,23 +437,19 @@ $(document).ready(function () { "should have added selected value to old one"); }); }); - asyncTest('Field', 1, function () { + test('Field', {asserts: 1}, function (instance) { var view = {inputs: []}; var f = new instance.web.search.Field({attrs: {}}, {}, view); - f.complete('foo') - .always(start) - .fail(function (error) { ok(false, error.message); }) + return f.complete('foo') .done(function (completions) { ok(_(completions).isEmpty(), "field should not provide any completion"); }); }); - asyncTest('CharField', 6, function () { + test('CharField', {asserts: 6}, function (instance) { var view = {inputs: []}; var f = new instance.web.search.CharField( {attrs: {string: "Dummy"}}, {}, view); - f.complete('foo<') - .always(start) - .fail(function (error) { ok(false, error.message); }) + return f.complete('foo<') .done(function (completions) { equal(completions.length, 1, "should provide a single completion"); var c = completions[0]; @@ -503,15 +466,13 @@ $(document).ready(function () { "facet should have single value using completion item"); }); }); - asyncTest('Selection: match found', 14, function () { + test('Selection: match found', {asserts: 14}, function (instance) { var view = {inputs: []}; var f = new instance.web.search.SelectionField( {attrs: {string: "Dummy"}}, {selection: [[1, "Foo"], [2, "Bar"], [3, "Baz"], [4, "Bazador"]]}, view); - f.complete("ba") - .always(start) - .fail(function (error) { ok(false, error.message); }) + return f.complete("ba") .done(function (completions) { equal(completions.length, 4, "should provide two completions and a section title"); @@ -536,20 +497,18 @@ $(document).ready(function () { deepEqual(c3.facet.values, [{label: "Bazador", value: 4}]); }); }); - asyncTest('Selection: no match', 1, function () { + test('Selection: no match', {asserts: 1}, function (instance) { var view = {inputs: []}; var f = new instance.web.search.SelectionField( {attrs: {string: "Dummy"}}, {selection: [[1, "Foo"], [2, "Bar"], [3, "Baz"], [4, "Bazador"]]}, view); - f.complete("qux") - .always(start) - .fail(function (error) { ok(false, error.message); }) + return f.complete("qux") .done(function (completions) { ok(!completions, "if no value matches the needle, no completion shall be provided"); }); }); - asyncTest('Date', 6, function () { + test('Date', {asserts: 6}, function (instance) { instance.web._t.database.parameters = { date_format: '%Y-%m-%d', time_format: '%H:%M:%S' @@ -557,9 +516,7 @@ $(document).ready(function () { var view = {inputs: []}; var f = new instance.web.search.DateField( {attrs: {string: "Dummy"}}, {type: 'datetime'}, view); - f.complete('2012-05-21T21:21:21') - .always(start) - .fail(function (error) { ok(false, error.message); }) + return f.complete('2012-05-21T21:21:21') .done(function (completions) { equal(completions.length, 1, "should provide a single completion"); var c = completions[0]; @@ -573,21 +530,17 @@ $(document).ready(function () { new Date(2012, 4, 21, 21, 21, 21).getTime()); }); }); - asyncTest("M2O", 15, function () { - instance.session.responses['/web/dataset/call_kw'] = function (req) { - equal(req.params.method, "name_search"); - equal(req.params.model, "dummy.model"); - deepEqual(req.params.args, []); - deepEqual(req.params.kwargs.name, 'bob'); - return {result: [[42, "choice 1"], [43, "choice @"]]} - }; + test("M2O", {asserts: 13}, function (instance, $s, mock) { + mock('dummy.model:name_search', function (args, kwargs) { + deepEqual(args, []); + strictEqual(kwargs.name, 'bob'); + return [[42, "choice 1"], [43, "choice @"]]; + }); var view = {inputs: []}; var f = new instance.web.search.ManyToOneField( {attrs: {string: 'Dummy'}}, {relation: 'dummy.model'}, view); - f.complete("bob") - .always(start) - .fail(function (error) { ok(false, error.message); }) + return f.complete("bob") .done(function (c) { equal(c.length, 3, "should return results + title"); var title = c[0]; @@ -607,38 +560,29 @@ $(document).ready(function () { deepEqual(f2.values.toJSON(), [{label: 'choice @', value: 43}]); }); }); - asyncTest("M2O no match", 5, function () { - instance.session.responses['/web/dataset/call_kw'] = function (req) { - equal(req.params.method, "name_search"); - equal(req.params.model, "dummy.model"); - deepEqual(req.params.args, []); - deepEqual(req.params.kwargs.name, 'bob'); - return {result: []} - }; + test("M2O no match", {asserts: 3}, function (instance, $s, mock) { + mock('dummy.model:name_search', function (args, kwargs) { + deepEqual(args, []); + strictEqual(kwargs.name, 'bob'); + return []; + }); var view = {inputs: []}; var f = new instance.web.search.ManyToOneField( {attrs: {string: 'Dummy'}}, {relation: 'dummy.model'}, view); - f.complete("bob") - .always(start) - .fail(function (error) { ok(false, error.message); }) + return f.complete("bob") .done(function (c) { ok(!c, "no match should yield no completion"); }); }); - - module('search-serialization', { - setup: function () { - instance = openerp.testing.instanceFor('search'); - - openerp.testing.loadTemplate(instance); - - openerp.testing.mockifyRPC(instance); - } - }); - asyncTest('No facet, no call', 6, function () { +}); +openerp.testing.section('search-serialization', { + dependencies: ['web.search'], + rpc: 'mock', + templates: true +}, function (test) { + test('No facet, no call', {asserts: 6}, function (instance, $s) { var got_domain = false, got_context = false, got_groupby = false; - var $fix = $('#qunit-fixture'); - var view = makeSearchView({ + var view = makeSearchView(instance, { get_domain: function () { got_domain = true; return null; @@ -654,11 +598,9 @@ $(document).ready(function () { }); var ds, cs, gs; view.on('search_data', this, function (d, c, g) { - ds = d, cs = c, gs = g; + ds = d; cs = c; gs = g; }); - view.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error.message); }) + return view.appendTo($s) .done(function () { view.do_search(); ok(!got_domain, "no facet, should not have fetched domain"); @@ -671,10 +613,9 @@ $(document).ready(function () { ok(_(gs).isEmpty(), "groupby list should be empty"); }) }); - asyncTest('London, calling', 8, function () { + test('London, calling', {asserts: 8}, function (instance, $fix) { var got_domain = false, got_context = false, got_groupby = false; - var $fix = $('#qunit-fixture'); - var view = makeSearchView({ + var view = makeSearchView(instance, { get_domain: function (facet) { equal(facet.get('category'), "Dummy"); deepEqual(facet.values.toJSON(), [{label: "42", value: 42}]); @@ -692,11 +633,9 @@ $(document).ready(function () { }, {dummy: 42}); var ds, cs, gs; view.on('search_data', this, function (d, c, g) { - ds = d, cs = c, gs = g; + ds = d; cs = c; gs = g; }); - view.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error.message); }) + return view.appendTo($fix) .done(function () { view.do_search(); ok(got_domain, "should have fetched domain"); @@ -709,9 +648,8 @@ $(document).ready(function () { ok(_(gs).isEmpty(), "groupby list should be empty"); }) }); - asyncTest('Generate domains', 1, function () { - var $fix = $('#qunit-fixture'); - var view = makeSearchView({ + test('Generate domains', {asserts: 1}, function (instance, $fix) { + var view = makeSearchView(instance, { get_domain: function (facet) { return facet.values.map(function (value) { return ['win', '4', value.get('value')]; @@ -720,9 +658,7 @@ $(document).ready(function () { }, {dummy: 42}); var ds; view.on('search_data', this, function (d) { ds = d; }); - view.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error.message); }) + return view.appendTo($fix) .done(function () { view.do_search(); deepEqual(ds, [[['win', '4', 42]]], @@ -730,7 +666,9 @@ $(document).ready(function () { }); }); - test('Field single value, default domain & context', function () { + test('Field single value, default domain & context', { + rpc: false + }, function (instance) { var f = new instance.web.search.Field({}, {name: 'foo'}, {inputs: []}); var facet = new instance.web.search.Facet({ field: f, @@ -742,7 +680,9 @@ $(document).ready(function () { equal(f.get_context(facet), null, "default field context is null"); }); - test('Field multiple values, default domain & context', function () { + test('Field multiple values, default domain & context', { + rpc: false + }, function (instance) { var f = new instance.web.search.Field({}, {name: 'foo'}, {inputs: []}); var facet = new instance.web.search.Facet({ field: f, @@ -763,7 +703,9 @@ $(document).ready(function () { equal(f.get_context(facet), null, "default field context is null"); }); - test('Field single value, custom domain & context', function () { + test('Field single value, custom domain & context', { + rpc: false + }, function (instance) { var f = new instance.web.search.Field({attrs:{ context: "{'bob': self}", filter_domain: "[['edmund', 'is', self]]" @@ -793,7 +735,9 @@ $(document).ready(function () { self: "great" }, "evaluation context should hold facet value as self"); }); - test("M2O default", function () { + test("M2O default", { + rpc: false + }, function (instance) { var f = new instance.web.search.ManyToOneField( {}, {name: 'foo'}, {inputs: []}); var facet = new instance.web.search.Facet({ @@ -806,7 +750,9 @@ $(document).ready(function () { deepEqual(f.get_context(facet), {default_foo: 42}, "m2o should use value as context default"); }); - test("M2O default multiple values", function () { + test("M2O default multiple values", { + rpc: false + }, function (instance) { var f = new instance.web.search.ManyToOneField( {}, {name: 'foo'}, {inputs: []}); var facet = new instance.web.search.Facet({ @@ -823,7 +769,9 @@ $(document).ready(function () { equal(f.get_context(facet), null, "m2o should not have default context in case of multiple values"); }); - test("M2O custom operator", function () { + test("M2O custom operator", { + rpc: false + }, function (instance) { var f = new instance.web.search.ManyToOneField( {attrs: {operator: 'boos'}}, {name: 'foo'}, {inputs: []}); var facet = new instance.web.search.Facet({ @@ -836,7 +784,9 @@ $(document).ready(function () { deepEqual(f.get_context(facet), {default_foo: 42}, "m2o should use value as context default"); }); - test("M2O custom domain & context", function () { + test("M2O custom domain & context", { + rpc: false + }, function (instance) { var f = new instance.web.search.ManyToOneField({attrs: { context: "{'whee': self}", filter_domain: "[['filter', 'is', self]]" @@ -862,7 +812,7 @@ $(document).ready(function () { }, "custom context's self should be label"); }); - asyncTest('FilterGroup', 6, function () { + test('FilterGroup', {asserts: 6}, function (instance) { var view = {inputs: [], query: {on: function () {}}}; var filter_a = new instance.web.search.Filter( {attrs: {name: 'a', context: 'c1', domain: 'd1'}}, view); @@ -872,9 +822,7 @@ $(document).ready(function () { {attrs: {name: 'c', context: 'c3', domain: 'd3'}}, view); var group = new instance.web.search.FilterGroup( [filter_a, filter_b, filter_c], view); - group.facet_for_defaults({a: true, c: true}) - .always(start) - .fail(function (error) { ok(false, error && error.message); }) + return group.facet_for_defaults({a: true, c: true}) .done(function (facet) { var model = facet; if (!(model instanceof instance.web.search.Facet)) { @@ -897,19 +845,14 @@ $(document).ready(function () { ok(!context.get_eval_context(), "context should have no evaluation context"); }); }); - - module('removal', { - setup: function () { - instance = openerp.testing.instanceFor('search'); - - openerp.testing.loadTemplate(instance); - - openerp.testing.mockifyRPC(instance); - } - }); - asyncTest('clear button', function () { - var $fix = $('#qunit-fixture'); - var view = makeSearchView({ +}); +openerp.testing.section('removal', { + dependencies: ['web.search'], + rpc: 'mock', + templates: true +}, function (test) { + test('clear button', {asserts: 2}, function (instance, $fix) { + var view = makeSearchView(instance, { facet_for_defaults: function (defaults) { return $.when({ field: this, @@ -918,31 +861,22 @@ $(document).ready(function () { }); } }, {dummy: 42}); - view.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error.message); }) + return view.appendTo($fix) .done(function () { equal(view.query.length, 1, "view should have default facet"); $fix.find('.oe_searchview_clear').click(); equal(view.query.length, 0, "cleared view should not have any facet"); }); }); - - module('drawer', { - setup: function () { - instance = openerp.testing.instanceFor('search'); - - openerp.testing.loadTemplate(instance); - - openerp.testing.mockifyRPC(instance); - } - }); - asyncTest('is-drawn', 2, function () { - var view = makeSearchView(); - var $fix = $('#qunit-fixture'); - view.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error.message); }) +}); +openerp.testing.section('drawer', { + dependencies: ['web.search'], + rpc: 'mock', + templates: true +}, function (test) { + test('is-drawn', {asserts: 2}, function (instance, $fix) { + var view = makeSearchView(instance); + return view.appendTo($fix) .done(function () { ok($fix.find('.oe_searchview_filters').length, "filters drawer control has been drawn"); @@ -950,50 +884,44 @@ $(document).ready(function () { "filters advanced search has been drawn"); }); }); - - module('filters', { - setup: function () { - instance = openerp.testing.instanceFor('search'); - - openerp.testing.loadTemplate(instance); - - openerp.testing.mockifyRPC(instance, { - '/web/searchview/load': function () { - // view with a single group of filters - return {result: {fields_view: { - type: 'search', - fields: {}, - arch: { - tag: 'search', - attrs: {}, - children: [{ - tag: 'filter', - attrs: { string: "Foo1", domain: [ ['foo', '=', '1'] ] }, - children: [] - }, { - tag: 'filter', - attrs: { - name: 'foo2', - string: "Foo2", - domain: [ ['foo', '=', '2'] ] }, - children: [] - }, { - tag: 'filter', - attrs: { string: "Foo3", domain: [ ['foo', '=', '3'] ] }, - children: [] - }] - } - }}}; +}); +openerp.testing.section('filters', { + dependencies: ['web.search'], + rpc: 'mock', + templates: true, + setup: function (instance, $s, mock) { + mock('/web/searchview/load', function () { + // view with a single group of filters + return {fields_view: { + type: 'search', + fields: {}, + arch: { + tag: 'search', + attrs: {}, + children: [{ + tag: 'filter', + attrs: { string: "Foo1", domain: [ ['foo', '=', '1'] ] }, + children: [] + }, { + tag: 'filter', + attrs: { + name: 'foo2', + string: "Foo2", + domain: [ ['foo', '=', '2'] ] }, + children: [] + }, { + tag: 'filter', + attrs: { string: "Foo3", domain: [ ['foo', '=', '3'] ] }, + children: [] + }] } - }); - } - }); - asyncTest('drawn', 3, function () { - var view = makeSearchView(); - var $fix = $('#qunit-fixture'); - view.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error.message); }) + }}; + }); + } +}, function (test) { + test('drawn', {asserts: 3}, function (instance, $fix) { + var view = makeSearchView(instance); + return view.appendTo($fix) .done(function () { var $fs = $fix.find('.oe_searchview_filters ul'); // 3 filters, 1 filtergroup, 1 custom filters widget, @@ -1006,12 +934,9 @@ $(document).ready(function () { "Text content of first filter option should match filter string"); }); }); - asyncTest('click adding from empty query', 4, function () { - var view = makeSearchView(); - var $fix = $('#qunit-fixture'); - view.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error.message); }) + test('click adding from empty query', {asserts: 4}, function (instance, $fix) { + var view = makeSearchView(instance); + return view.appendTo($fix) .done(function () { var $fs = $fix.find('.oe_searchview_filters ul'); $fs.children(':eq(2)').trigger('click'); @@ -1025,12 +950,9 @@ $(document).ready(function () { "value should be third filter"); }); }); - asyncTest('click adding from existing query', 4, function () { - var view = makeSearchView({}, {foo2: true}); - var $fix = $('#qunit-fixture'); - view.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error.message); }) + test('click adding from existing query', {asserts: 4}, function (instance, $fix) { + var view = makeSearchView(instance, {}, {foo2: true}); + return view.appendTo($fix) .done(function () { var $fs = $fix.find('.oe_searchview_filters ul'); $fs.children(':eq(2)').trigger('click'); @@ -1045,16 +967,13 @@ $(document).ready(function () { "second value should be clicked filter"); }); }); - asyncTest('click removing from query', 4, function () { + test('click removing from query', {asserts: 4}, function (instance, $fix) { var calls = 0; - var view = makeSearchView({}, {foo2: true}); + var view = makeSearchView(instance, {}, {foo2: true}); view.on('search_data', null, function () { ++calls; }); - var $fix = $('#qunit-fixture'); - view.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error.message); }) + return view.appendTo($fix) .done(function () { var $fs = $fix.find('.oe_searchview_filters ul'); // sanity check @@ -1065,29 +984,19 @@ $(document).ready(function () { strictEqual(calls, 1, "one search should have been triggered"); }); }); +}); +openerp.testing.section('saved_filters', { + dependencies: ['web.search'], + rpc: 'mock', + templates: true +}, function (test) { + test('checkboxing', {asserts: 6}, function (instance, $fix, mock) { + var view = makeSearchView(instance); + mock('/web/searchview/get_filters', function () { + return [{ name: "filter name", user_id: 42 }]; + }); - module('saved_filters', { - setup: function () { - instance = openerp.testing.instanceFor('search'); - - openerp.testing.loadTemplate(instance); - - openerp.testing.mockifyRPC(instance); - } - }); - asyncTest('checkboxing', 6, function () { - var view = makeSearchView(); - instance.session.responses['/web/searchview/get_filters'] = function () { - return {result: [{ - name: "filter name", - user_id: 42 - }]}; - }; - var $fix = $('#qunit-fixture'); - - view.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error.message); }) + return view.appendTo($fix) .done(function () { var $row = $fix.find('.oe_searchview_custom li:first').click(); @@ -1104,44 +1013,31 @@ $(document).ready(function () { "should have no value set"); }) }); - asyncTest('removal', 1, function () { - var view = makeSearchView(); - instance.session.responses['/web/searchview/get_filters'] = function () { - return {result: [{ - name: "filter name", - user_id: 42 - }]}; - }; - var $fix = $('#qunit-fixture'); + test('removal', {asserts: 1}, function (instance, $fix, mock) { + var view = makeSearchView(instance); + mock('/web/searchview/get_filters', function () { + return [{ name: "filter name", user_id: 42 }]; + }); - view.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error.message); }) + return view.appendTo($fix) .done(function () { var $row = $fix.find('.oe_searchview_custom li:first').click(); view.query.remove(view.query.at(0)); ok(!$row.hasClass('oe_selected'), "should not be checked anymore"); - }) + }); }); +}); +openerp.testing.section('advanced', { + dependencies: ['web.search'], + rpc: 'mock', + templates: true +}, function (test) { + test('single-advanced', {asserts: 6}, function (instance, $fix) { + var view = makeSearchView(instance); - module('advanced', { - setup: function () { - instance = openerp.testing.instanceFor('search'); - - openerp.testing.loadTemplate(instance); - - openerp.testing.mockifyRPC(instance); - } - }); - asyncTest('single-advanced', 6, function () { - var view = makeSearchView(); - var $fix = $('#qunit-fixture'); - - view.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error.message); }) + return view.appendTo($fix) .done(function () { var $advanced = $fix.find('.oe_searchview_advanced'); // open advanced search (not actually useful) @@ -1174,13 +1070,10 @@ $(document).ready(function () { "advanced search facet should return proposed domain"); }); }); - asyncTest('multiple-advanced', 3, function () { - var view = makeSearchView(); - var $fix = $('#qunit-fixture'); + test('multiple-advanced', {asserts: 3}, function (instance, $fix) { + var view = makeSearchView(instance); - view.appendTo($fix) - .always(start) - .fail(function (error) { ok(false, error.message); }) + return view.appendTo($fix) .done(function () { var $advanced = $fix.find('.oe_searchview_advanced'); // open advanced search (not actually useful) diff --git a/addons/web/static/test/test.html b/addons/web/static/test/test.html deleted file mode 100644 index 185125659cc..00000000000 --- a/addons/web/static/test/test.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - OpenERP Web Test Suite - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - - - - - - - - - - - - diff --git a/addons/web/static/test/testing.js b/addons/web/static/test/testing.js index 1be8e94e74b..5bd008ad7ec 100644 --- a/addons/web/static/test/testing.js +++ b/addons/web/static/test/testing.js @@ -1,97 +1,244 @@ -// Test support structures and methods for OpenERP -openerp.testing = (function () { - var xhr = QWeb2.Engine.prototype.get_xhr(); - xhr.open('GET', '/web/static/src/xml/base.xml', false); - xhr.send(null); - var doc = xhr.responseXML; - - var dependencies = { - corelib: [], - coresetup: ['corelib'], - data: ['corelib', 'coresetup'], - dates: [], - formats: ['coresetup', 'dates'], - chrome: ['corelib', 'coresetup'], - views: ['corelib', 'coresetup', 'data', 'chrome'], - search: ['data', 'coresetup', 'formats'], - list: ['views', 'data'], - form: ['data', 'views', 'list', 'formats'], - list_editable: ['list', 'form', 'data'], +openerp.testing.section('testing.stack', function (test) { + // I heard you like tests, so I put tests in your testing infrastructure, + // so you can test what you test + var reject = function () { + // utility function, rejects a success + var args = _.toArray(arguments); + return $.Deferred(function (d) { + d.reject.apply(d, ["unexpected success"].concat(args)); + }); }; + test('direct, value, success', {asserts: 1}, function () { + var s = openerp.testing.Stack(); + return s.execute(function () { + return 42; + }).then(function (val) { + strictEqual(val, 42, "should return the handler value"); + }); + }); + test('direct, deferred, success', {asserts: 1}, function () { + var s = openerp.testing.Stack(); + return s.execute(function () { + return $.when(42); + }).then(function (val) { + strictEqual(val, 42, "should return the handler value") + }); + }); + test('direct, deferred, failure', {asserts: 1}, function () { + var s = openerp.testing.Stack(); + return s.execute(function () { + return $.Deferred(function (d) { + d.reject("failed"); + }); + }).then(reject, function (f) { + strictEqual(f, "failed", "should propagate failure"); + return $.when(); + }); + }); - return { - /** - * Function which does not do anything - */ - noop: function () { }, - /** - * Loads 'base.xml' template file into qweb for the provided instance - * - * @param instance openerp instance being initialized, to load the template file in - */ - loadTemplate: function (instance) { - instance.web.qweb.add_template(doc); - }, - /** - * Alter provided instance's ``session`` attribute to make response - * mockable: - * - * * The ``responses`` parameter can be used to provide a map of (RPC) - * paths (e.g. ``/web/view/load``) to a function returning a response - * to the query. - * * ``instance.session`` grows a ``responses`` attribute which is - * a map of the same (and is in fact initialized to the ``responses`` - * parameter if one is provided) - * - * Note that RPC requests to un-mocked URLs will be rejected with an - * error message: only explicitly specified urls will get a response. - * - * Mocked sessions will *never* perform an actual RPC connection. - * - * @param instance openerp instance being initialized - * @param {Object} [responses] - */ - mockifyRPC: function (instance, responses) { - var session = instance.session; - session.responses = responses || {}; - session.rpc_function = function (url, payload) { - var fn = this.responses[url.url + ':' + payload.params.method] - || this.responses[url.url]; + test('successful setup', {asserts: 2}, function () { + var setup_done = false; + var s = openerp.testing.Stack(); + return s.push(function () { + return $.Deferred(function (d) { + setTimeout(function () { + setup_done = true; + d.resolve(2); + }, 50); + }); + }).execute(function () { + return 42; + }).then(function (val) { + ok(setup_done, "should have executed setup"); + strictEqual(val, 42, "should return executed function value (not setup)"); + }); + }); + test('successful teardown', {asserts: 2}, function () { + var teardown = false; + var s = openerp.testing.Stack(); + return s.push(null, function () { + return $.Deferred(function (d) { + setTimeout(function () { + teardown = true; + d.resolve(2); + }, 50); + }); + }).execute(function () { + return 42; + }).then(function (val) { + ok(teardown, "should have executed teardown"); + strictEqual(val, 42, "should return executed function value (not setup)"); + }); + }); + test('successful setup and teardown', {asserts: 3}, function () { + var setup = false, teardown = false; + var s = openerp.testing.Stack(); + return s.push(function () { + return $.Deferred(function (d) { + setTimeout(function () { + setup = true; + d.resolve(2); + }, 50); + }); + }, function () { + return $.Deferred(function (d) { + setTimeout(function () { + teardown = true; + d.resolve(2); + }, 50); + }); + }).execute(function () { + return 42; + }).then(function (val) { + ok(setup, "should have executed setup"); + ok(teardown, "should have executed teardown"); + strictEqual(val, 42, "should return executed function value (not setup)"); + }); + }); - if (!fn) { - return $.Deferred().reject({}, 'failed', - _.str.sprintf("Url %s not found in mock responses, with arguments %s", - url.url, JSON.stringify(payload.params)) - ).promise(); - } - return $.when(fn(payload)); - }; - }, - /** - * Creates an openerp web instance loading the specified module after - * all of its dependencies. - * - * @param {String} module - * @returns OpenERP Web instance - */ - instanceFor: function (module) { - var instance = openerp.init([]); - this._load(instance, module); - return instance; - }, - _load: function (instance, module, loaded) { - if (!loaded) { loaded = []; } + test('multiple setups', {asserts: 2}, function () { + var setups = 0; + var s = openerp.testing.Stack(); + return s.push(function () { + setups++; + }).push(function () { + setups++; + }).push(function () { + setups++; + }).push(function () { + setups++; + }).execute(function () { + return 42; + }).then(function (val) { + strictEqual(setups, 4, "should have executed all setups of stack"); + strictEqual(val, 42); + }); + }); + test('multiple teardowns', {asserts: 2}, function () { + var teardowns = 0; + var s = openerp.testing.Stack(); + return s.push(null, function () { + teardowns++; + }).push(null, function () { + teardowns++; + }).push(null, function () { + teardowns++; + }).push(null, function () { + teardowns++; + }).execute(function () { + return 42; + }).then(function (val) { + strictEqual(teardowns, 4, "should have executed all teardowns of stack"); + strictEqual(val, 42); + }); + }); + test('holes in setups', {asserts: 2}, function () { + var setups = []; + var s = openerp.testing.Stack(); + return s.push(function () { + setups.push(0); + }).push().push().push(function () { + setups.push(3); + }).push(function () { + setups.push(4); + }).push().push(function () { + setups.push(6); + }).execute(function () { + return 42; + }).then(function (val) { + deepEqual(setups, [0, 3, 4, 6], + "should have executed setups in correct order"); + strictEqual(val, 42); + }); + }); + test('holes in teardowns', {asserts: 2}, function () { + var teardowns = []; + var s = openerp.testing.Stack(); + return s.push(null, function () { + teardowns.push(0); + }).push().push().push(null, function () { + teardowns.push(3); + }).push(null, function () { + teardowns.push(4); + }).push().push(null, function () { + teardowns.push(6); + }).execute(function () { + return 42; + }).then(function (val) { + deepEqual(teardowns, [6, 4, 3, 0], + "should have executed teardowns in correct order"); + strictEqual(val, 42); + }); - var deps = dependencies[module]; - if (!deps) { throw new Error("Unknown dependencies for " + module); } + }); - var to_load = _.difference(deps, loaded); - while (!_.isEmpty(to_load)) { - this._load(instance, to_load[0], loaded); - to_load = _.difference(deps, loaded); - } - openerp.web[module](instance); - loaded.push(module); - } - } -})(); + test('failed setup', {asserts: 5}, function () { + var setup, teardown, teardown2, code; + return openerp.testing.Stack().push(function () { + setup = true; + }, function () { + teardown = true; + }).push(function () { + return $.Deferred().reject("Fail!"); + }, function () { + teardown2 = true; + }).execute(function () { + code = true; + return 42; + }).then(reject, function (m) { + ok(setup, "should have executed first setup function"); + ok(teardown, "should have executed first teardown function"); + ok(!teardown2, "should not have executed second teardown function"); + strictEqual(m, "Fail!", "should return setup failure message"); + ok(!code, "should not have executed callback"); + return $.when(); + }); + }); + test('failed teardown', {asserts: 2}, function () { + var teardowns = 0; + return openerp.testing.Stack().push(null, function () { + teardowns++; + return $.Deferred().reject('Fail 1'); + }).push(null, function () { + teardowns++; + }).push(null, function () { + teardowns++; + return $.Deferred().reject('Fail 3'); + }).execute(function () { + return 42; + }).then(reject, function (m) { + strictEqual(teardowns, 3, + "should have tried executing all teardowns"); + strictEqual(m, "Fail 3", "should return first failure message"); + return $.when(); + }); + }); + test('failed call + teardown', {asserts: 2}, function () { + var teardowns = 0; + return openerp.testing.Stack().push(null, function () { + teardowns++; + }).push(null, function () { + teardowns++; + return $.Deferred().reject('Fail 2'); + }).execute(function () { + return $.Deferred().reject("code"); + }).then(reject, function (m) { + strictEqual(teardowns, 2, + "should have tried executing all teardowns"); + strictEqual(m, "code", "should return first failure message"); + return $.when(); + }); + }); + + test('arguments passing', {asserts: 9}, function () { + var asserter = function (a, b, c) { + strictEqual(a, 1); + strictEqual(b, "foo"); + deepEqual(c, {bar: "baz", qux: 42}); + }; + + return openerp.testing.Stack() + .push(asserter, asserter) + .execute(asserter, 1, "foo", {bar: 'baz', qux: 42}); + }); +}); diff --git a/addons/web/test_support/__init__.py b/addons/web/test_support/__init__.py deleted file mode 100644 index 59f6cc67ca2..00000000000 --- a/addons/web/test_support/__init__.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- 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 - }, '') diff --git a/addons/web/test_support/controllers.py b/addons/web/test_support/controllers.py deleted file mode 100644 index f1013fbaaf8..00000000000 --- a/addons/web/test_support/controllers.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- 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, - } diff --git a/addons/web/tests/__init__.py b/addons/web/tests/__init__.py index fb1a593bc78..8cb2118e0b6 100644 --- a/addons/web/tests/__init__.py +++ b/addons/web/tests/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from . import test_dataset, test_menu, test_serving_base, test_view +from . import test_dataset, test_menu, test_serving_base, test_view, test_js fast_suite = [] checks = [ diff --git a/addons/web/tests/test_js.py b/addons/web/tests/test_js.py new file mode 100644 index 00000000000..a126ce4b2f3 --- /dev/null +++ b/addons/web/tests/test_js.py @@ -0,0 +1,25 @@ +import urlparse +from openerp import sql_db, tools +from qunitsuite.suite import QUnitSuite + +class WebSuite(QUnitSuite): + def __init__(self): + url = urlparse.urlunsplit([ + 'http', + 'localhost:{port}'.format(port=tools.config['xmlrpc_port']), + '/web/tests', + 'mod=*&source={db}&supadmin={supadmin}&password={password}'.format( + db=tools.config['db_name'], + supadmin=tools.config['db_password'] or 'admin', + password=tools.config['admin_passwd'] or 'admin'), + '' + ]) + super(WebSuite, self).__init__(url, 50000) + def run(self, result): + if sql_db._Pool is not None: + sql_db._Pool.close_all(sql_db.dsn(tools.config['db_name'])) + return super(WebSuite, self).run(result) + +def load_tests(loader, standard_tests, _): + standard_tests.addTest(WebSuite()) + return standard_tests diff --git a/addons/web_calendar/i18n/ar.po b/addons/web_calendar/i18n/ar.po index ab2b44e8c0f..f9241ca23d3 100644 --- a/addons/web_calendar/i18n/ar.po +++ b/addons/web_calendar/i18n/ar.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/bg.po b/addons/web_calendar/i18n/bg.po index 1efca8799a5..3fb494c8f3f 100644 --- a/addons/web_calendar/i18n/bg.po +++ b/addons/web_calendar/i18n/bg.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/bn.po b/addons/web_calendar/i18n/bn.po index cf1540dcfc8..a520f497700 100644 --- a/addons/web_calendar/i18n/bn.po +++ b/addons/web_calendar/i18n/bn.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/bs.po b/addons/web_calendar/i18n/bs.po index 86271e95cf3..5c36cf3c0cc 100644 --- a/addons/web_calendar/i18n/bs.po +++ b/addons/web_calendar/i18n/bs.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/ca.po b/addons/web_calendar/i18n/ca.po index 72d9ef16031..af2d7ea63a4 100644 --- a/addons/web_calendar/i18n/ca.po +++ b/addons/web_calendar/i18n/ca.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/cs.po b/addons/web_calendar/i18n/cs.po index 66bc1beb88c..5ac3d5d34b3 100644 --- a/addons/web_calendar/i18n/cs.po +++ b/addons/web_calendar/i18n/cs.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" "X-Poedit-Language: Czech\n" #. openerp-web diff --git a/addons/web_calendar/i18n/da.po b/addons/web_calendar/i18n/da.po index 3e4b334c4c8..aefa989ec61 100644 --- a/addons/web_calendar/i18n/da.po +++ b/addons/web_calendar/i18n/da.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/de.po b/addons/web_calendar/i18n/de.po index df4a364ff1a..384635c1f49 100644 --- a/addons/web_calendar/i18n/de.po +++ b/addons/web_calendar/i18n/de.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/en_AU.po b/addons/web_calendar/i18n/en_AU.po index b4e653989a7..a06c829d2a8 100644 --- a/addons/web_calendar/i18n/en_AU.po +++ b/addons/web_calendar/i18n/en_AU.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/en_GB.po b/addons/web_calendar/i18n/en_GB.po index 1c4d71479d2..220c92d2e4c 100644 --- a/addons/web_calendar/i18n/en_GB.po +++ b/addons/web_calendar/i18n/en_GB.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/es.po b/addons/web_calendar/i18n/es.po index c475d7c85ab..5c8764d16e9 100644 --- a/addons/web_calendar/i18n/es.po +++ b/addons/web_calendar/i18n/es.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/es_CL.po b/addons/web_calendar/i18n/es_CL.po index ddc28ac04e8..ed465fa1f9f 100644 --- a/addons/web_calendar/i18n/es_CL.po +++ b/addons/web_calendar/i18n/es_CL.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/es_CR.po b/addons/web_calendar/i18n/es_CR.po index 22123fbf838..aa3315ad9ab 100644 --- a/addons/web_calendar/i18n/es_CR.po +++ b/addons/web_calendar/i18n/es_CR.po @@ -15,8 +15,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" "Language: es\n" #. openerp-web diff --git a/addons/web_calendar/i18n/es_EC.po b/addons/web_calendar/i18n/es_EC.po index 0333a6ac721..120e1181970 100644 --- a/addons/web_calendar/i18n/es_EC.po +++ b/addons/web_calendar/i18n/es_EC.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/et.po b/addons/web_calendar/i18n/et.po index b51b759e47b..a6aa0042572 100644 --- a/addons/web_calendar/i18n/et.po +++ b/addons/web_calendar/i18n/et.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/eu.po b/addons/web_calendar/i18n/eu.po index fb4ed997f5d..dbce60de184 100644 --- a/addons/web_calendar/i18n/eu.po +++ b/addons/web_calendar/i18n/eu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/fa.po b/addons/web_calendar/i18n/fa.po index b0120f3ef10..d7c0d87a872 100644 --- a/addons/web_calendar/i18n/fa.po +++ b/addons/web_calendar/i18n/fa.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/fi.po b/addons/web_calendar/i18n/fi.po index 01732824cb6..7f9a8163010 100644 --- a/addons/web_calendar/i18n/fi.po +++ b/addons/web_calendar/i18n/fi.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/fr.po b/addons/web_calendar/i18n/fr.po index de9875e1eb1..1c11cfc675a 100644 --- a/addons/web_calendar/i18n/fr.po +++ b/addons/web_calendar/i18n/fr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/fr_CA.po b/addons/web_calendar/i18n/fr_CA.po index 97f3f6cba13..4397816f032 100644 --- a/addons/web_calendar/i18n/fr_CA.po +++ b/addons/web_calendar/i18n/fr_CA.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/gl.po b/addons/web_calendar/i18n/gl.po index f6990a15bcd..1bbf185bdc2 100644 --- a/addons/web_calendar/i18n/gl.po +++ b/addons/web_calendar/i18n/gl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/gu.po b/addons/web_calendar/i18n/gu.po new file mode 100644 index 00000000000..65e20902cf5 --- /dev/null +++ b/addons/web_calendar/i18n/gu.po @@ -0,0 +1,141 @@ +# Gujarati 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 , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-07-02 09:06+0200\n" +"PO-Revision-Date: 2012-11-17 12:42+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Gujarati \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2012-11-18 04:47+0000\n" +"X-Generator: Launchpad (build 16278)\n" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:11 +msgid "Calendar" +msgstr "કૅલેન્ડર" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:70 +msgid "Filter" +msgstr "" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:144 +msgid "Today" +msgstr "આજે" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:145 +msgid "Day" +msgstr "દિવસ" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:146 +msgid "Week" +msgstr "" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:147 +msgid "Month" +msgstr "" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:148 +msgid "New event" +msgstr "" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:149 +msgid "Save" +msgstr "સંગ્રહો" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:150 +msgid "Cancel" +msgstr "રદ કરો" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:151 +msgid "Details" +msgstr "વિગતો" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:152 +msgid "Edit" +msgstr "ફેરફાર કરો" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:153 +msgid "Delete" +msgstr "કાઢી નાંખો" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:155 +msgid "Event will be deleted permanently, are you sure?" +msgstr "" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:156 +#: addons/web_calendar/static/src/js/calendar.js:169 +msgid "Description" +msgstr "વર્ણન" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:157 +msgid "Time period" +msgstr "" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:158 +msgid "Full day" +msgstr "" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:161 +msgid "Do you want to edit the whole set of repeated events?" +msgstr "" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:162 +msgid "Repeat event" +msgstr "" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:163 +msgid "Disabled" +msgstr "" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:164 +msgid "Enabled" +msgstr "" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:167 +#: addons/web_calendar/static/src/js/calendar.js:175 +msgid "Agenda" +msgstr "" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:168 +msgid "Date" +msgstr "તારીખ" + +#. openerp-web +#: addons/web_calendar/static/src/js/calendar.js:172 +msgid "Year" +msgstr "વર્ષ" + +#. openerp-web +#: addons/web_calendar/static/src/xml/web_calendar.xml:5 +#: addons/web_calendar/static/src/xml/web_calendar.xml:6 +msgid " " +msgstr " " diff --git a/addons/web_calendar/i18n/hr.po b/addons/web_calendar/i18n/hr.po index 3c50d92c7d6..420a7eb1c33 100644 --- a/addons/web_calendar/i18n/hr.po +++ b/addons/web_calendar/i18n/hr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/hu.po b/addons/web_calendar/i18n/hu.po index 97ff16d5b51..a7711c4020a 100644 --- a/addons/web_calendar/i18n/hu.po +++ b/addons/web_calendar/i18n/hu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/id.po b/addons/web_calendar/i18n/id.po index d1525772a40..e6de231635a 100644 --- a/addons/web_calendar/i18n/id.po +++ b/addons/web_calendar/i18n/id.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/it.po b/addons/web_calendar/i18n/it.po index 28758fc6086..a857dee48f8 100644 --- a/addons/web_calendar/i18n/it.po +++ b/addons/web_calendar/i18n/it.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/ja.po b/addons/web_calendar/i18n/ja.po index b13351a6d0e..65e1890e1c7 100644 --- a/addons/web_calendar/i18n/ja.po +++ b/addons/web_calendar/i18n/ja.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/ka.po b/addons/web_calendar/i18n/ka.po index 71f560182fc..c6639155ad4 100644 --- a/addons/web_calendar/i18n/ka.po +++ b/addons/web_calendar/i18n/ka.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/lt.po b/addons/web_calendar/i18n/lt.po index b506033dd29..de38e7437c7 100644 --- a/addons/web_calendar/i18n/lt.po +++ b/addons/web_calendar/i18n/lt.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-22 04:46+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/mk.po b/addons/web_calendar/i18n/mk.po index f6121903251..83616520f79 100644 --- a/addons/web_calendar/i18n/mk.po +++ b/addons/web_calendar/i18n/mk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/mn.po b/addons/web_calendar/i18n/mn.po index 5dbfd1146c5..f12b785fee7 100644 --- a/addons/web_calendar/i18n/mn.po +++ b/addons/web_calendar/i18n/mn.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/nb.po b/addons/web_calendar/i18n/nb.po index 1bfd031fdca..151abb46415 100644 --- a/addons/web_calendar/i18n/nb.po +++ b/addons/web_calendar/i18n/nb.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/nl.po b/addons/web_calendar/i18n/nl.po index f85a54d90a8..855f44d7ec8 100644 --- a/addons/web_calendar/i18n/nl.po +++ b/addons/web_calendar/i18n/nl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/nl_BE.po b/addons/web_calendar/i18n/nl_BE.po index 25fc24a3121..6420eb49047 100644 --- a/addons/web_calendar/i18n/nl_BE.po +++ b/addons/web_calendar/i18n/nl_BE.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/pl.po b/addons/web_calendar/i18n/pl.po index 75d984ec95a..53066f91e89 100644 --- a/addons/web_calendar/i18n/pl.po +++ b/addons/web_calendar/i18n/pl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/pt.po b/addons/web_calendar/i18n/pt.po index 316e2886ebf..8c5762714de 100644 --- a/addons/web_calendar/i18n/pt.po +++ b/addons/web_calendar/i18n/pt.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/pt_BR.po b/addons/web_calendar/i18n/pt_BR.po index fd1c6800f69..075f9c3cc52 100644 --- a/addons/web_calendar/i18n/pt_BR.po +++ b/addons/web_calendar/i18n/pt_BR.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/ro.po b/addons/web_calendar/i18n/ro.po index f2be8570780..0b1be890e7e 100644 --- a/addons/web_calendar/i18n/ro.po +++ b/addons/web_calendar/i18n/ro.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/ru.po b/addons/web_calendar/i18n/ru.po index c286c58bf1a..3f9cccf8b21 100644 --- a/addons/web_calendar/i18n/ru.po +++ b/addons/web_calendar/i18n/ru.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-24 05:20+0000\n" -"X-Generator: Launchpad (build 16179)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/sk.po b/addons/web_calendar/i18n/sk.po index 10eaa327715..ccc7f62c3a3 100644 --- a/addons/web_calendar/i18n/sk.po +++ b/addons/web_calendar/i18n/sk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/sl.po b/addons/web_calendar/i18n/sl.po index 550fafc22d4..0dce08c77f4 100644 --- a/addons/web_calendar/i18n/sl.po +++ b/addons/web_calendar/i18n/sl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-11-02 05:20+0000\n" -"X-Generator: Launchpad (build 16218)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/sq.po b/addons/web_calendar/i18n/sq.po index 6dc15299697..a53cf945075 100644 --- a/addons/web_calendar/i18n/sq.po +++ b/addons/web_calendar/i18n/sq.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:08+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/sr@latin.po b/addons/web_calendar/i18n/sr@latin.po index d798c8d29c0..d5229958f93 100644 --- a/addons/web_calendar/i18n/sr@latin.po +++ b/addons/web_calendar/i18n/sr@latin.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/sv.po b/addons/web_calendar/i18n/sv.po index e6e72691141..fee033889cc 100644 --- a/addons/web_calendar/i18n/sv.po +++ b/addons/web_calendar/i18n/sv.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/tr.po b/addons/web_calendar/i18n/tr.po index d429fbde854..0b06085aed8 100644 --- a/addons/web_calendar/i18n/tr.po +++ b/addons/web_calendar/i18n/tr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/uk.po b/addons/web_calendar/i18n/uk.po index 8ae70eb2f77..4f8c91ed43f 100644 --- a/addons/web_calendar/i18n/uk.po +++ b/addons/web_calendar/i18n/uk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/i18n/zh_CN.po b/addons/web_calendar/i18n/zh_CN.po index 134091e9d64..eda04768775 100644 --- a/addons/web_calendar/i18n/zh_CN.po +++ b/addons/web_calendar/i18n/zh_CN.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_calendar/static/src/js/calendar.js:11 diff --git a/addons/web_calendar/static/src/js/calendar.js b/addons/web_calendar/static/src/js/calendar.js index 51bce57f7cd..30b14c32749 100644 --- a/addons/web_calendar/static/src/js/calendar.js +++ b/addons/web_calendar/static/src/js/calendar.js @@ -2,6 +2,22 @@ * OpenERP web_calendar *---------------------------------------------------------*/ +(function() { + // Monkey patch dhtml scheduler in order to fix a bug. + // It manually implements some kind of dbl click event + // bubbling but fails to do it properly. + if (this.scheduler) { + var old_scheduler_dblclick = scheduler._on_dbl_click; + scheduler._on_dbl_click = function(e, src) { + if (src && !src.className) { + return; + } else { + old_scheduler_dblclick.apply(this, arguments); + } + }; + } +}()); + openerp.web_calendar = function(instance) { var _t = instance.web._t, _lt = instance.web._lt; @@ -219,7 +235,6 @@ instance.web_calendar.CalendarView = instance.web.View.extend({ if (!date.between(this.range_start, this.range_stop)) { this.update_range_dates(date); this.ranged_search(); - this.$el.find(".dhx_cal_navline div").removeAttr('style'); } this.ready.resolve(); }, diff --git a/addons/web_diagram/i18n/ar.po b/addons/web_diagram/i18n/ar.po index b2854ec93c6..4830e2a9572 100644 --- a/addons/web_diagram/i18n/ar.po +++ b/addons/web_diagram/i18n/ar.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/bg.po b/addons/web_diagram/i18n/bg.po index cd73e4d4628..bbe9d04d00f 100644 --- a/addons/web_diagram/i18n/bg.po +++ b/addons/web_diagram/i18n/bg.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/bn.po b/addons/web_diagram/i18n/bn.po index cb8d8b712c4..7af98d96e18 100644 --- a/addons/web_diagram/i18n/bn.po +++ b/addons/web_diagram/i18n/bn.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/bs.po b/addons/web_diagram/i18n/bs.po index 78b776e129d..b2173f2d278 100644 --- a/addons/web_diagram/i18n/bs.po +++ b/addons/web_diagram/i18n/bs.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/ca.po b/addons/web_diagram/i18n/ca.po index f835a46149c..980bb73c187 100644 --- a/addons/web_diagram/i18n/ca.po +++ b/addons/web_diagram/i18n/ca.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/cs.po b/addons/web_diagram/i18n/cs.po index 59b05ca204c..e2beae2bc3e 100644 --- a/addons/web_diagram/i18n/cs.po +++ b/addons/web_diagram/i18n/cs.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" "X-Poedit-Language: Czech\n" #. openerp-web diff --git a/addons/web_diagram/i18n/da.po b/addons/web_diagram/i18n/da.po index 38cc3c33f5a..99d6694387e 100644 --- a/addons/web_diagram/i18n/da.po +++ b/addons/web_diagram/i18n/da.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/de.po b/addons/web_diagram/i18n/de.po index 0572c893571..02f01c0a298 100644 --- a/addons/web_diagram/i18n/de.po +++ b/addons/web_diagram/i18n/de.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/en_GB.po b/addons/web_diagram/i18n/en_GB.po index 9a1de1ff09a..f45a36ebfec 100644 --- a/addons/web_diagram/i18n/en_GB.po +++ b/addons/web_diagram/i18n/en_GB.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/es.po b/addons/web_diagram/i18n/es.po index 57bee045a52..1127f66ac32 100644 --- a/addons/web_diagram/i18n/es.po +++ b/addons/web_diagram/i18n/es.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/es_CL.po b/addons/web_diagram/i18n/es_CL.po index ca18b98d811..0cd2218ad58 100644 --- a/addons/web_diagram/i18n/es_CL.po +++ b/addons/web_diagram/i18n/es_CL.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/es_CR.po b/addons/web_diagram/i18n/es_CR.po index cb952c8d76d..853ed64e10c 100644 --- a/addons/web_diagram/i18n/es_CR.po +++ b/addons/web_diagram/i18n/es_CR.po @@ -15,8 +15,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" "Language: es\n" #. openerp-web diff --git a/addons/web_diagram/i18n/es_EC.po b/addons/web_diagram/i18n/es_EC.po index 64122e572d9..9d12b54ad84 100644 --- a/addons/web_diagram/i18n/es_EC.po +++ b/addons/web_diagram/i18n/es_EC.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/et.po b/addons/web_diagram/i18n/et.po index 3b16af5630b..a91455e4f4c 100644 --- a/addons/web_diagram/i18n/et.po +++ b/addons/web_diagram/i18n/et.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/fa.po b/addons/web_diagram/i18n/fa.po index cf23a8270ef..5e11f131796 100644 --- a/addons/web_diagram/i18n/fa.po +++ b/addons/web_diagram/i18n/fa.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/fi.po b/addons/web_diagram/i18n/fi.po index 43dd28e6408..313dc4df75a 100644 --- a/addons/web_diagram/i18n/fi.po +++ b/addons/web_diagram/i18n/fi.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/fr.po b/addons/web_diagram/i18n/fr.po index 775b01c4c79..28555736c81 100644 --- a/addons/web_diagram/i18n/fr.po +++ b/addons/web_diagram/i18n/fr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/gl.po b/addons/web_diagram/i18n/gl.po index c4db0075c79..c09f8dcf150 100644 --- a/addons/web_diagram/i18n/gl.po +++ b/addons/web_diagram/i18n/gl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/gu.po b/addons/web_diagram/i18n/gu.po new file mode 100644 index 00000000000..dac8f061956 --- /dev/null +++ b/addons/web_diagram/i18n/gu.po @@ -0,0 +1,74 @@ +# Gujarati 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 , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-07-02 09:06+0200\n" +"PO-Revision-Date: 2012-11-17 11:58+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Gujarati \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2012-11-18 04:47+0000\n" +"X-Generator: Launchpad (build 16278)\n" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:11 +msgid "Diagram" +msgstr "" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:165 +msgid "Are you sure?" +msgstr "" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:195 +msgid "" +"Deleting this node cannot be undone.\n" +"It will also delete all connected transitions.\n" +"\n" +"Are you sure ?" +msgstr "" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:213 +msgid "" +"Deleting this transition cannot be undone.\n" +"\n" +"Are you sure ?" +msgstr "" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:224 +#: addons/web_diagram/static/src/js/diagram.js:257 +msgid "Activity" +msgstr "પ્રવૃત્તિ" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:232 +#: addons/web_diagram/static/src/js/diagram.js:296 +msgid "Open: " +msgstr "" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:262 +#: addons/web_diagram/static/src/js/diagram.js:314 +msgid "Create:" +msgstr "" + +#. openerp-web +#: addons/web_diagram/static/src/js/diagram.js:289 +#: addons/web_diagram/static/src/js/diagram.js:308 +msgid "Transition" +msgstr "" + +#. openerp-web +#: addons/web_diagram/static/src/xml/base_diagram.xml:6 +msgid "New Node" +msgstr "" diff --git a/addons/web_diagram/i18n/hr.po b/addons/web_diagram/i18n/hr.po index 416c3465db6..b2ecdefe05c 100644 --- a/addons/web_diagram/i18n/hr.po +++ b/addons/web_diagram/i18n/hr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/id.po b/addons/web_diagram/i18n/id.po index 2754693c6ac..ad64db2b7dc 100644 --- a/addons/web_diagram/i18n/id.po +++ b/addons/web_diagram/i18n/id.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/it.po b/addons/web_diagram/i18n/it.po index 6d0de20c705..d61a1bed790 100644 --- a/addons/web_diagram/i18n/it.po +++ b/addons/web_diagram/i18n/it.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/ja.po b/addons/web_diagram/i18n/ja.po index ec31f0d22a0..df4aa38e9b4 100644 --- a/addons/web_diagram/i18n/ja.po +++ b/addons/web_diagram/i18n/ja.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/ka.po b/addons/web_diagram/i18n/ka.po index fd549ad47b6..23fe83c5ede 100644 --- a/addons/web_diagram/i18n/ka.po +++ b/addons/web_diagram/i18n/ka.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/lt.po b/addons/web_diagram/i18n/lt.po index 0d7eb1b2f38..69e24c3d916 100644 --- a/addons/web_diagram/i18n/lt.po +++ b/addons/web_diagram/i18n/lt.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-22 04:46+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/mn.po b/addons/web_diagram/i18n/mn.po index 538bd4086ad..5f8eae9ae47 100644 --- a/addons/web_diagram/i18n/mn.po +++ b/addons/web_diagram/i18n/mn.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/nl.po b/addons/web_diagram/i18n/nl.po index f04fa3d2ad7..601d2bde471 100644 --- a/addons/web_diagram/i18n/nl.po +++ b/addons/web_diagram/i18n/nl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/nl_BE.po b/addons/web_diagram/i18n/nl_BE.po index e612f2989b1..4b46f5eb164 100644 --- a/addons/web_diagram/i18n/nl_BE.po +++ b/addons/web_diagram/i18n/nl_BE.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/pl.po b/addons/web_diagram/i18n/pl.po index 1050e73f775..0c6a4a21b1e 100644 --- a/addons/web_diagram/i18n/pl.po +++ b/addons/web_diagram/i18n/pl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/pt.po b/addons/web_diagram/i18n/pt.po index e666dd56ae0..838ac158e93 100644 --- a/addons/web_diagram/i18n/pt.po +++ b/addons/web_diagram/i18n/pt.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/pt_BR.po b/addons/web_diagram/i18n/pt_BR.po index c3d2bf290bb..1cd50b59da6 100644 --- a/addons/web_diagram/i18n/pt_BR.po +++ b/addons/web_diagram/i18n/pt_BR.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/ro.po b/addons/web_diagram/i18n/ro.po index 8c5dc473e43..e191e16675a 100644 --- a/addons/web_diagram/i18n/ro.po +++ b/addons/web_diagram/i18n/ro.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/ru.po b/addons/web_diagram/i18n/ru.po index 14062840b2f..274a99a3eb6 100644 --- a/addons/web_diagram/i18n/ru.po +++ b/addons/web_diagram/i18n/ru.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-26 05:19+0000\n" -"X-Generator: Launchpad (build 16194)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/sl.po b/addons/web_diagram/i18n/sl.po index 37b554a2754..eafb11b74eb 100644 --- a/addons/web_diagram/i18n/sl.po +++ b/addons/web_diagram/i18n/sl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/sq.po b/addons/web_diagram/i18n/sq.po index d8191d79db2..c6e8dd1536e 100644 --- a/addons/web_diagram/i18n/sq.po +++ b/addons/web_diagram/i18n/sq.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/sr@latin.po b/addons/web_diagram/i18n/sr@latin.po index 06bf0eccafb..7ff90bf1a58 100644 --- a/addons/web_diagram/i18n/sr@latin.po +++ b/addons/web_diagram/i18n/sr@latin.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/sv.po b/addons/web_diagram/i18n/sv.po index 97fba58992f..de325566358 100644 --- a/addons/web_diagram/i18n/sv.po +++ b/addons/web_diagram/i18n/sv.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/tr.po b/addons/web_diagram/i18n/tr.po index a3c2b3f1ccb..ae6e8c92859 100644 --- a/addons/web_diagram/i18n/tr.po +++ b/addons/web_diagram/i18n/tr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_diagram/i18n/zh_CN.po b/addons/web_diagram/i18n/zh_CN.po index a30f45d11c2..355d6bb98d9 100644 --- a/addons/web_diagram/i18n/zh_CN.po +++ b/addons/web_diagram/i18n/zh_CN.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_diagram/static/src/js/diagram.js:11 diff --git a/addons/web_gantt/i18n/ar.po b/addons/web_gantt/i18n/ar.po index e9ad745a76e..efc1fe00bec 100644 --- a/addons/web_gantt/i18n/ar.po +++ b/addons/web_gantt/i18n/ar.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/bg.po b/addons/web_gantt/i18n/bg.po index 23976f96791..21aab3a1f0c 100644 --- a/addons/web_gantt/i18n/bg.po +++ b/addons/web_gantt/i18n/bg.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/bn.po b/addons/web_gantt/i18n/bn.po index c2f60c8d625..c6bb1af2553 100644 --- a/addons/web_gantt/i18n/bn.po +++ b/addons/web_gantt/i18n/bn.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/bs.po b/addons/web_gantt/i18n/bs.po index 175bc84cf5c..e6434dc0b2e 100644 --- a/addons/web_gantt/i18n/bs.po +++ b/addons/web_gantt/i18n/bs.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/ca.po b/addons/web_gantt/i18n/ca.po index dd4c08c9b50..b7a907a44ad 100644 --- a/addons/web_gantt/i18n/ca.po +++ b/addons/web_gantt/i18n/ca.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/cs.po b/addons/web_gantt/i18n/cs.po index 6e57eebe539..1d1bca8db86 100644 --- a/addons/web_gantt/i18n/cs.po +++ b/addons/web_gantt/i18n/cs.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" "X-Poedit-Language: Czech\n" #. openerp-web diff --git a/addons/web_gantt/i18n/da.po b/addons/web_gantt/i18n/da.po index 92d9e8f6bb3..6096374d6ac 100644 --- a/addons/web_gantt/i18n/da.po +++ b/addons/web_gantt/i18n/da.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/de.po b/addons/web_gantt/i18n/de.po index f8f5b69470a..29e8ae0b15f 100644 --- a/addons/web_gantt/i18n/de.po +++ b/addons/web_gantt/i18n/de.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/en_AU.po b/addons/web_gantt/i18n/en_AU.po index 595d3fc734b..9b50d740fe2 100644 --- a/addons/web_gantt/i18n/en_AU.po +++ b/addons/web_gantt/i18n/en_AU.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/en_GB.po b/addons/web_gantt/i18n/en_GB.po index 9c1d2cc5ec7..c211b69f7d3 100644 --- a/addons/web_gantt/i18n/en_GB.po +++ b/addons/web_gantt/i18n/en_GB.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/es.po b/addons/web_gantt/i18n/es.po index fb6ed0101a1..0082b7c5548 100644 --- a/addons/web_gantt/i18n/es.po +++ b/addons/web_gantt/i18n/es.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/es_CL.po b/addons/web_gantt/i18n/es_CL.po index a472a7a1485..532c5c7e70a 100644 --- a/addons/web_gantt/i18n/es_CL.po +++ b/addons/web_gantt/i18n/es_CL.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/es_CR.po b/addons/web_gantt/i18n/es_CR.po index fe29c2995f5..668df147118 100644 --- a/addons/web_gantt/i18n/es_CR.po +++ b/addons/web_gantt/i18n/es_CR.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/es_EC.po b/addons/web_gantt/i18n/es_EC.po index c1735a3dd8b..239f4aaabdf 100644 --- a/addons/web_gantt/i18n/es_EC.po +++ b/addons/web_gantt/i18n/es_EC.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/fa.po b/addons/web_gantt/i18n/fa.po index 86a25319f47..e34e1f663a1 100644 --- a/addons/web_gantt/i18n/fa.po +++ b/addons/web_gantt/i18n/fa.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/fi.po b/addons/web_gantt/i18n/fi.po index 268f133941d..1f9c20703e4 100644 --- a/addons/web_gantt/i18n/fi.po +++ b/addons/web_gantt/i18n/fi.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/fr.po b/addons/web_gantt/i18n/fr.po index 5b0fadbf06a..2c3ef92e2db 100644 --- a/addons/web_gantt/i18n/fr.po +++ b/addons/web_gantt/i18n/fr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/gl.po b/addons/web_gantt/i18n/gl.po index 8624ee7a069..4ab201938cd 100644 --- a/addons/web_gantt/i18n/gl.po +++ b/addons/web_gantt/i18n/gl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/gu.po b/addons/web_gantt/i18n/gu.po new file mode 100644 index 00000000000..2c31432f767 --- /dev/null +++ b/addons/web_gantt/i18n/gu.po @@ -0,0 +1,28 @@ +# Gujarati 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 , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-07-02 09:06+0200\n" +"PO-Revision-Date: 2012-11-17 10:36+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Gujarati \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2012-11-18 04:47+0000\n" +"X-Generator: Launchpad (build 16278)\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 "બનાવો" diff --git a/addons/web_gantt/i18n/hr.po b/addons/web_gantt/i18n/hr.po index 5d9863412ca..e9694fdb382 100644 --- a/addons/web_gantt/i18n/hr.po +++ b/addons/web_gantt/i18n/hr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/hu.po b/addons/web_gantt/i18n/hu.po index 04343f07b7c..fd289446d7f 100644 --- a/addons/web_gantt/i18n/hu.po +++ b/addons/web_gantt/i18n/hu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/it.po b/addons/web_gantt/i18n/it.po index 44392f14b66..17f5759ecfd 100644 --- a/addons/web_gantt/i18n/it.po +++ b/addons/web_gantt/i18n/it.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/ja.po b/addons/web_gantt/i18n/ja.po index 251322ebf3d..9a02f165279 100644 --- a/addons/web_gantt/i18n/ja.po +++ b/addons/web_gantt/i18n/ja.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/ka.po b/addons/web_gantt/i18n/ka.po index 5e8bb8a4a5f..9d2f65285cd 100644 --- a/addons/web_gantt/i18n/ka.po +++ b/addons/web_gantt/i18n/ka.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/lt.po b/addons/web_gantt/i18n/lt.po index 6310962c04e..99905322c04 100644 --- a/addons/web_gantt/i18n/lt.po +++ b/addons/web_gantt/i18n/lt.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-22 04:46+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/mk.po b/addons/web_gantt/i18n/mk.po index 2e7cb554db6..018a2a3b16c 100644 --- a/addons/web_gantt/i18n/mk.po +++ b/addons/web_gantt/i18n/mk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/mn.po b/addons/web_gantt/i18n/mn.po index 6f42fb9e495..d2c8da8e22f 100644 --- a/addons/web_gantt/i18n/mn.po +++ b/addons/web_gantt/i18n/mn.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/nb.po b/addons/web_gantt/i18n/nb.po index b9f50c24a7c..501581bcb04 100644 --- a/addons/web_gantt/i18n/nb.po +++ b/addons/web_gantt/i18n/nb.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/nl.po b/addons/web_gantt/i18n/nl.po index 1f22a510595..795da258259 100644 --- a/addons/web_gantt/i18n/nl.po +++ b/addons/web_gantt/i18n/nl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/nl_BE.po b/addons/web_gantt/i18n/nl_BE.po index ad943f78869..29639d63418 100644 --- a/addons/web_gantt/i18n/nl_BE.po +++ b/addons/web_gantt/i18n/nl_BE.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/pl.po b/addons/web_gantt/i18n/pl.po index e92010a58c3..8861a13adfd 100644 --- a/addons/web_gantt/i18n/pl.po +++ b/addons/web_gantt/i18n/pl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/pt.po b/addons/web_gantt/i18n/pt.po index 308b740582d..580380da267 100644 --- a/addons/web_gantt/i18n/pt.po +++ b/addons/web_gantt/i18n/pt.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/pt_BR.po b/addons/web_gantt/i18n/pt_BR.po index 361fab71df7..72b9f5724ee 100644 --- a/addons/web_gantt/i18n/pt_BR.po +++ b/addons/web_gantt/i18n/pt_BR.po @@ -15,8 +15,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/ro.po b/addons/web_gantt/i18n/ro.po index 262084e175b..1fe6e2d2c72 100644 --- a/addons/web_gantt/i18n/ro.po +++ b/addons/web_gantt/i18n/ro.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/ru.po b/addons/web_gantt/i18n/ru.po index 43c6170f691..32d3b90e36b 100644 --- a/addons/web_gantt/i18n/ru.po +++ b/addons/web_gantt/i18n/ru.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/sl.po b/addons/web_gantt/i18n/sl.po index 007ef01e8ca..f26f72b7b43 100644 --- a/addons/web_gantt/i18n/sl.po +++ b/addons/web_gantt/i18n/sl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/sq.po b/addons/web_gantt/i18n/sq.po index d9998290592..f514a0c2728 100644 --- a/addons/web_gantt/i18n/sq.po +++ b/addons/web_gantt/i18n/sq.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/sr@latin.po b/addons/web_gantt/i18n/sr@latin.po index c7049eb9c9f..12eae1b5924 100644 --- a/addons/web_gantt/i18n/sr@latin.po +++ b/addons/web_gantt/i18n/sr@latin.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/sv.po b/addons/web_gantt/i18n/sv.po index 547c50ac571..1dd0aa4086e 100644 --- a/addons/web_gantt/i18n/sv.po +++ b/addons/web_gantt/i18n/sv.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/tr.po b/addons/web_gantt/i18n/tr.po index ce2779e23ae..70dea5797c2 100644 --- a/addons/web_gantt/i18n/tr.po +++ b/addons/web_gantt/i18n/tr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_gantt/i18n/zh_CN.po b/addons/web_gantt/i18n/zh_CN.po index e8739bf81ac..7e0a75f9387 100644 --- a/addons/web_gantt/i18n/zh_CN.po +++ b/addons/web_gantt/i18n/zh_CN.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_gantt/static/src/js/gantt.js:11 diff --git a/addons/web_graph/i18n/ar.po b/addons/web_graph/i18n/ar.po index 3150b37d553..f4673c7eb0d 100644 --- a/addons/web_graph/i18n/ar.po +++ b/addons/web_graph/i18n/ar.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/bg.po b/addons/web_graph/i18n/bg.po index 6aab3ad70b7..f53d8f2e766 100644 --- a/addons/web_graph/i18n/bg.po +++ b/addons/web_graph/i18n/bg.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/bn.po b/addons/web_graph/i18n/bn.po index b19bfaf8fff..7ae977e2463 100644 --- a/addons/web_graph/i18n/bn.po +++ b/addons/web_graph/i18n/bn.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/bs.po b/addons/web_graph/i18n/bs.po index d5bf94fc711..0ad1e813651 100644 --- a/addons/web_graph/i18n/bs.po +++ b/addons/web_graph/i18n/bs.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/ca.po b/addons/web_graph/i18n/ca.po index 370b3190749..6e3328d6fa6 100644 --- a/addons/web_graph/i18n/ca.po +++ b/addons/web_graph/i18n/ca.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/cs.po b/addons/web_graph/i18n/cs.po index 9f216542bc0..e2a375305c9 100644 --- a/addons/web_graph/i18n/cs.po +++ b/addons/web_graph/i18n/cs.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/da.po b/addons/web_graph/i18n/da.po index 6c1a477a417..bce5117670f 100644 --- a/addons/web_graph/i18n/da.po +++ b/addons/web_graph/i18n/da.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/de.po b/addons/web_graph/i18n/de.po index ec6a4d249e3..004eaad2c94 100644 --- a/addons/web_graph/i18n/de.po +++ b/addons/web_graph/i18n/de.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/en_AU.po b/addons/web_graph/i18n/en_AU.po index f89a24e1332..23da37b7f15 100644 --- a/addons/web_graph/i18n/en_AU.po +++ b/addons/web_graph/i18n/en_AU.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/en_GB.po b/addons/web_graph/i18n/en_GB.po index 70e0a38837f..6ce1fd26bef 100644 --- a/addons/web_graph/i18n/en_GB.po +++ b/addons/web_graph/i18n/en_GB.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/es.po b/addons/web_graph/i18n/es.po index 0b23d1a7052..8ad576a49ea 100644 --- a/addons/web_graph/i18n/es.po +++ b/addons/web_graph/i18n/es.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/es_CL.po b/addons/web_graph/i18n/es_CL.po index 5588bd39e9b..f3235627451 100644 --- a/addons/web_graph/i18n/es_CL.po +++ b/addons/web_graph/i18n/es_CL.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/es_CR.po b/addons/web_graph/i18n/es_CR.po index 28cd92a1bdf..e26959c1b36 100644 --- a/addons/web_graph/i18n/es_CR.po +++ b/addons/web_graph/i18n/es_CR.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/es_EC.po b/addons/web_graph/i18n/es_EC.po index e4b016a8a3d..9a137d32e74 100644 --- a/addons/web_graph/i18n/es_EC.po +++ b/addons/web_graph/i18n/es_EC.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/fa.po b/addons/web_graph/i18n/fa.po index 1d9ba33c635..70e66f3bed7 100644 --- a/addons/web_graph/i18n/fa.po +++ b/addons/web_graph/i18n/fa.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/fi.po b/addons/web_graph/i18n/fi.po index 1588337b41c..ef55e2f3353 100644 --- a/addons/web_graph/i18n/fi.po +++ b/addons/web_graph/i18n/fi.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/fr.po b/addons/web_graph/i18n/fr.po index 9e07304a87d..6d4cf6f63a1 100644 --- a/addons/web_graph/i18n/fr.po +++ b/addons/web_graph/i18n/fr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/gl.po b/addons/web_graph/i18n/gl.po index 5d89c5e7a7a..b83edaa0003 100644 --- a/addons/web_graph/i18n/gl.po +++ b/addons/web_graph/i18n/gl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/gu.po b/addons/web_graph/i18n/gu.po new file mode 100644 index 00000000000..25b35828984 --- /dev/null +++ b/addons/web_graph/i18n/gu.po @@ -0,0 +1,98 @@ +# Gujarati 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 , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-07-02 09:06+0200\n" +"PO-Revision-Date: 2012-11-17 10:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Gujarati \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2012-11-18 04:47+0000\n" +"X-Generator: Launchpad (build 16278)\n" + +#. openerp-web +#: addons/web_graph/static/src/js/graph.js:19 +msgid "Graph" +msgstr "આલેખ" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:5 +msgid "Graph Options" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:7 +msgid "Graph Mode" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:11 +msgid "Pie" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:12 +msgid "Bars" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:14 +msgid "Lines" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:15 +msgid "Areas" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:18 +msgid "Radar" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:20 +msgid "Legend" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:24 +msgid "Hidden" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:25 +msgid "Inside" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:26 +msgid "Top" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:28 +msgid "Actions" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:32 +msgid "Switch Axis" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:33 +msgid "Show Data" +msgstr "" + +#. openerp-web +#: addons/web_graph/static/src/xml/web_graph.xml:34 +msgid "Download as PNG" +msgstr "" diff --git a/addons/web_graph/i18n/hr.po b/addons/web_graph/i18n/hr.po index f42d955f760..13c509d2824 100644 --- a/addons/web_graph/i18n/hr.po +++ b/addons/web_graph/i18n/hr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/hu.po b/addons/web_graph/i18n/hu.po index 7c401a38d11..b6ae8e819ea 100644 --- a/addons/web_graph/i18n/hu.po +++ b/addons/web_graph/i18n/hu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/it.po b/addons/web_graph/i18n/it.po index 3c297f69fea..c93b1893e9c 100644 --- a/addons/web_graph/i18n/it.po +++ b/addons/web_graph/i18n/it.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/ja.po b/addons/web_graph/i18n/ja.po index e2328b4107a..d79e3780ed2 100644 --- a/addons/web_graph/i18n/ja.po +++ b/addons/web_graph/i18n/ja.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/ka.po b/addons/web_graph/i18n/ka.po index f01c0ae5f99..2ba2b591c5f 100644 --- a/addons/web_graph/i18n/ka.po +++ b/addons/web_graph/i18n/ka.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/lt.po b/addons/web_graph/i18n/lt.po index ad566156e26..3cb8e482d6e 100644 --- a/addons/web_graph/i18n/lt.po +++ b/addons/web_graph/i18n/lt.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-22 04:46+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/mk.po b/addons/web_graph/i18n/mk.po index 502b1ccf3ff..279cfc26e1c 100644 --- a/addons/web_graph/i18n/mk.po +++ b/addons/web_graph/i18n/mk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/mn.po b/addons/web_graph/i18n/mn.po index 6f1a85b3526..c454eb74a17 100644 --- a/addons/web_graph/i18n/mn.po +++ b/addons/web_graph/i18n/mn.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/nl.po b/addons/web_graph/i18n/nl.po index 66526cb0d63..19360ad4092 100644 --- a/addons/web_graph/i18n/nl.po +++ b/addons/web_graph/i18n/nl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/nl_BE.po b/addons/web_graph/i18n/nl_BE.po index 59a936a06b2..b8adf273d37 100644 --- a/addons/web_graph/i18n/nl_BE.po +++ b/addons/web_graph/i18n/nl_BE.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/pl.po b/addons/web_graph/i18n/pl.po index 06cee6ac833..cb77a0c8f84 100644 --- a/addons/web_graph/i18n/pl.po +++ b/addons/web_graph/i18n/pl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/pt.po b/addons/web_graph/i18n/pt.po index 3f8edebbf9b..eb00e9406fa 100644 --- a/addons/web_graph/i18n/pt.po +++ b/addons/web_graph/i18n/pt.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/pt_BR.po b/addons/web_graph/i18n/pt_BR.po index a99a4819e09..96fd7730fcf 100644 --- a/addons/web_graph/i18n/pt_BR.po +++ b/addons/web_graph/i18n/pt_BR.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/ro.po b/addons/web_graph/i18n/ro.po index 395789af612..efcbc0afe63 100644 --- a/addons/web_graph/i18n/ro.po +++ b/addons/web_graph/i18n/ro.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/ru.po b/addons/web_graph/i18n/ru.po index fcb97444257..5006d7c124f 100644 --- a/addons/web_graph/i18n/ru.po +++ b/addons/web_graph/i18n/ru.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-24 05:20+0000\n" -"X-Generator: Launchpad (build 16179)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/sl.po b/addons/web_graph/i18n/sl.po index 159b01142da..d8275c1dd29 100644 --- a/addons/web_graph/i18n/sl.po +++ b/addons/web_graph/i18n/sl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/sq.po b/addons/web_graph/i18n/sq.po index 5a9b63f8c35..dafb35d6d04 100644 --- a/addons/web_graph/i18n/sq.po +++ b/addons/web_graph/i18n/sq.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/sr@latin.po b/addons/web_graph/i18n/sr@latin.po index 54fd7987d5e..8c41f4579da 100644 --- a/addons/web_graph/i18n/sr@latin.po +++ b/addons/web_graph/i18n/sr@latin.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/sv.po b/addons/web_graph/i18n/sv.po index e1a5d2f9032..3ff11c4d03d 100644 --- a/addons/web_graph/i18n/sv.po +++ b/addons/web_graph/i18n/sv.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/tr.po b/addons/web_graph/i18n/tr.po index 720a4039a7b..2eb5c4651f7 100644 --- a/addons/web_graph/i18n/tr.po +++ b/addons/web_graph/i18n/tr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/i18n/zh_CN.po b/addons/web_graph/i18n/zh_CN.po index a2bc90c1827..db352a3e5d9 100644 --- a/addons/web_graph/i18n/zh_CN.po +++ b/addons/web_graph/i18n/zh_CN.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_graph/static/src/js/graph.js:19 diff --git a/addons/web_graph/static/lib/flotr2/lib/bean.js b/addons/web_graph/static/lib/flotr2/lib/bean.js index 6e6e3ef4eb5..1a854771006 100644 --- a/addons/web_graph/static/lib/flotr2/lib/bean.js +++ b/addons/web_graph/static/lib/flotr2/lib/bean.js @@ -9,9 +9,7 @@ */ /*global module:true, define:true*/ !function (name, context, definition) { - if (typeof module !== 'undefined') module.exports = definition(name, context); - else if (typeof define === 'function' && typeof define.amd === 'object') define(definition); - else context[name] = definition(name, context); + context[name] = definition(name, context); }('bean', this, function (name, context) { var win = window , old = context[name] diff --git a/addons/web_hello/i18n/ar.po b/addons/web_hello/i18n/ar.po index 067507856fe..933b9f8bd9f 100644 --- a/addons/web_hello/i18n/ar.po +++ b/addons/web_hello/i18n/ar.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" diff --git a/addons/web_hello/i18n/es_CR.po b/addons/web_hello/i18n/es_CR.po index cc1a06469ec..4c93888641a 100644 --- a/addons/web_hello/i18n/es_CR.po +++ b/addons/web_hello/i18n/es_CR.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" diff --git a/addons/web_hello/i18n/fr.po b/addons/web_hello/i18n/fr.po index 029ada82c70..1db28fcd669 100644 --- a/addons/web_hello/i18n/fr.po +++ b/addons/web_hello/i18n/fr.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" diff --git a/addons/web_hello/i18n/pt_BR.po b/addons/web_hello/i18n/pt_BR.po index d374091e09e..76a3d76ef42 100644 --- a/addons/web_hello/i18n/pt_BR.po +++ b/addons/web_hello/i18n/pt_BR.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" diff --git a/addons/web_kanban/i18n/ar.po b/addons/web_kanban/i18n/ar.po index ba734cf3f82..2b41c88af20 100644 --- a/addons/web_kanban/i18n/ar.po +++ b/addons/web_kanban/i18n/ar.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/bg.po b/addons/web_kanban/i18n/bg.po index 000818fb9c7..060707f8971 100644 --- a/addons/web_kanban/i18n/bg.po +++ b/addons/web_kanban/i18n/bg.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/bn.po b/addons/web_kanban/i18n/bn.po index 2473660d416..545f20352c9 100644 --- a/addons/web_kanban/i18n/bn.po +++ b/addons/web_kanban/i18n/bn.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/bs.po b/addons/web_kanban/i18n/bs.po index 0d208a70b37..e7078c96433 100644 --- a/addons/web_kanban/i18n/bs.po +++ b/addons/web_kanban/i18n/bs.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/ca.po b/addons/web_kanban/i18n/ca.po index 93862e3d292..177a7d00799 100644 --- a/addons/web_kanban/i18n/ca.po +++ b/addons/web_kanban/i18n/ca.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/cs.po b/addons/web_kanban/i18n/cs.po index 9012c6f4560..f5d9f774a21 100644 --- a/addons/web_kanban/i18n/cs.po +++ b/addons/web_kanban/i18n/cs.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" "X-Poedit-Language: Czech\n" #. openerp-web diff --git a/addons/web_kanban/i18n/da.po b/addons/web_kanban/i18n/da.po index a14b5544337..48cc86e2236 100644 --- a/addons/web_kanban/i18n/da.po +++ b/addons/web_kanban/i18n/da.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/de.po b/addons/web_kanban/i18n/de.po index 794169a3e0e..a88a66d3a77 100644 --- a/addons/web_kanban/i18n/de.po +++ b/addons/web_kanban/i18n/de.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/en_GB.po b/addons/web_kanban/i18n/en_GB.po index e2a72bc19ca..38c82e62c7f 100644 --- a/addons/web_kanban/i18n/en_GB.po +++ b/addons/web_kanban/i18n/en_GB.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/es.po b/addons/web_kanban/i18n/es.po index d562b6bf82e..c065470b00e 100644 --- a/addons/web_kanban/i18n/es.po +++ b/addons/web_kanban/i18n/es.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/es_CL.po b/addons/web_kanban/i18n/es_CL.po index 55e598d7017..8a467e05508 100644 --- a/addons/web_kanban/i18n/es_CL.po +++ b/addons/web_kanban/i18n/es_CL.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/es_CR.po b/addons/web_kanban/i18n/es_CR.po index b7b851f14c7..1d434969d8f 100644 --- a/addons/web_kanban/i18n/es_CR.po +++ b/addons/web_kanban/i18n/es_CR.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/es_EC.po b/addons/web_kanban/i18n/es_EC.po index afe3b25aeaf..ffdfc0083f8 100644 --- a/addons/web_kanban/i18n/es_EC.po +++ b/addons/web_kanban/i18n/es_EC.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/fa.po b/addons/web_kanban/i18n/fa.po index e24902448a1..8d97b5cd087 100644 --- a/addons/web_kanban/i18n/fa.po +++ b/addons/web_kanban/i18n/fa.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/fi.po b/addons/web_kanban/i18n/fi.po index fdfeea871ad..ca1b51564e9 100644 --- a/addons/web_kanban/i18n/fi.po +++ b/addons/web_kanban/i18n/fi.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/fr.po b/addons/web_kanban/i18n/fr.po index d31357bad62..a4e8b026287 100644 --- a/addons/web_kanban/i18n/fr.po +++ b/addons/web_kanban/i18n/fr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/gl.po b/addons/web_kanban/i18n/gl.po index 9ccd66c71eb..e03983179f6 100644 --- a/addons/web_kanban/i18n/gl.po +++ b/addons/web_kanban/i18n/gl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/gu.po b/addons/web_kanban/i18n/gu.po new file mode 100644 index 00000000000..0e82f736171 --- /dev/null +++ b/addons/web_kanban/i18n/gu.po @@ -0,0 +1,66 @@ +# Gujarati 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 , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-07-02 09:06+0200\n" +"PO-Revision-Date: 2012-11-17 11:38+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Gujarati \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2012-11-18 04:47+0000\n" +"X-Generator: Launchpad (build 16278)\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:293 +msgid "Undefined" +msgstr "" + +#. openerp-web +#: addons/web_kanban/static/src/js/kanban.js:471 +msgid "Are you sure you want to delete this record ?" +msgstr "" + +#. openerp-web +#: addons/web_kanban/static/src/js/kanban.js:839 +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:71 +msgid "Add" +msgstr "" + +#. openerp-web +#: addons/web_kanban/static/src/xml/web_kanban.xml:71 +msgid "or" +msgstr "" + +#. openerp-web +#: addons/web_kanban/static/src/xml/web_kanban.xml:72 +msgid "Cancel" +msgstr "" + +#~ msgid "Create" +#~ msgstr "બનાવો" diff --git a/addons/web_kanban/i18n/hr.po b/addons/web_kanban/i18n/hr.po index bfb80508047..4475b0596b9 100644 --- a/addons/web_kanban/i18n/hr.po +++ b/addons/web_kanban/i18n/hr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/hu.po b/addons/web_kanban/i18n/hu.po index 6392fa227fd..febf19037aa 100644 --- a/addons/web_kanban/i18n/hu.po +++ b/addons/web_kanban/i18n/hu.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/it.po b/addons/web_kanban/i18n/it.po index 71da09eac6a..4aad60e6cf4 100644 --- a/addons/web_kanban/i18n/it.po +++ b/addons/web_kanban/i18n/it.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/ja.po b/addons/web_kanban/i18n/ja.po index 61a6473fdb4..f054f40115f 100644 --- a/addons/web_kanban/i18n/ja.po +++ b/addons/web_kanban/i18n/ja.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/ka.po b/addons/web_kanban/i18n/ka.po index 4196dba39cb..d3ebdf522db 100644 --- a/addons/web_kanban/i18n/ka.po +++ b/addons/web_kanban/i18n/ka.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/lt.po b/addons/web_kanban/i18n/lt.po index 04f788195ac..e0f087dd442 100644 --- a/addons/web_kanban/i18n/lt.po +++ b/addons/web_kanban/i18n/lt.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-22 04:46+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/mn.po b/addons/web_kanban/i18n/mn.po index 9afb4e45d93..573f278dd84 100644 --- a/addons/web_kanban/i18n/mn.po +++ b/addons/web_kanban/i18n/mn.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/nl.po b/addons/web_kanban/i18n/nl.po index ff3b7094b2b..3cb8c91034e 100644 --- a/addons/web_kanban/i18n/nl.po +++ b/addons/web_kanban/i18n/nl.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/nl_BE.po b/addons/web_kanban/i18n/nl_BE.po index b4b8fae14c9..347beeb76af 100644 --- a/addons/web_kanban/i18n/nl_BE.po +++ b/addons/web_kanban/i18n/nl_BE.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/pl.po b/addons/web_kanban/i18n/pl.po index 6c42bc5571b..c040e1c7ba0 100644 --- a/addons/web_kanban/i18n/pl.po +++ b/addons/web_kanban/i18n/pl.po @@ -14,13 +14,13 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 msgid "Kanban" -msgstr "" +msgstr "Kanban" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:293 @@ -64,3 +64,6 @@ msgstr "" #~ msgid "Create" #~ msgstr "Utwórz" + +#~ msgid "" +#~ msgstr "" diff --git a/addons/web_kanban/i18n/pt.po b/addons/web_kanban/i18n/pt.po index c8e0196d7ba..4747266805c 100644 --- a/addons/web_kanban/i18n/pt.po +++ b/addons/web_kanban/i18n/pt.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/pt_BR.po b/addons/web_kanban/i18n/pt_BR.po index 1047c7e7725..c0b67986f3d 100644 --- a/addons/web_kanban/i18n/pt_BR.po +++ b/addons/web_kanban/i18n/pt_BR.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/ro.po b/addons/web_kanban/i18n/ro.po index 27326621b10..acd190514b7 100644 --- a/addons/web_kanban/i18n/ro.po +++ b/addons/web_kanban/i18n/ro.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/ru.po b/addons/web_kanban/i18n/ru.po index a30f7c53997..03b3e9a9dfe 100644 --- a/addons/web_kanban/i18n/ru.po +++ b/addons/web_kanban/i18n/ru.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-27 05:15+0000\n" -"X-Generator: Launchpad (build 16194)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/sr@latin.po b/addons/web_kanban/i18n/sr@latin.po index 4ba839580e8..63c0887990b 100644 --- a/addons/web_kanban/i18n/sr@latin.po +++ b/addons/web_kanban/i18n/sr@latin.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/sv.po b/addons/web_kanban/i18n/sv.po index aff6a057656..77dd0d06cb2 100644 --- a/addons/web_kanban/i18n/sv.po +++ b/addons/web_kanban/i18n/sv.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/tr.po b/addons/web_kanban/i18n/tr.po index 4df30e4ee5e..80cb052e407 100644 --- a/addons/web_kanban/i18n/tr.po +++ b/addons/web_kanban/i18n/tr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/i18n/zh_CN.po b/addons/web_kanban/i18n/zh_CN.po index 07c905699ad..1d543e0d06c 100644 --- a/addons/web_kanban/i18n/zh_CN.po +++ b/addons/web_kanban/i18n/zh_CN.po @@ -9,13 +9,13 @@ msgstr "" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-07-02 09:06+0200\n" "PO-Revision-Date: 2012-02-10 08:25+0000\n" -"Last-Translator: Jeff Wang \n" +"Last-Translator: 开阖软件 Jeff Wang \n" "Language-Team: Chinese (Simplified) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" #. openerp-web #: addons/web_kanban/static/src/js/kanban.js:10 diff --git a/addons/web_kanban/static/src/css/kanban.css b/addons/web_kanban/static/src/css/kanban.css index 105e074df1f..9b74462ee13 100644 --- a/addons/web_kanban/static/src/css/kanban.css +++ b/addons/web_kanban/static/src/css/kanban.css @@ -277,7 +277,7 @@ width: 100%; } .openerp .oe_kanban_view.oe_kanban_ungrouped .oe_kanban_column .oe_kanban_record { - float: left; + display: inline-block; padding: 2px; box-sizing: border-box; -moz-box-sizing: border-box; diff --git a/addons/web_kanban/static/src/css/kanban.sass b/addons/web_kanban/static/src/css/kanban.sass index fbc9e3d8568..b993b648691 100644 --- a/addons/web_kanban/static/src/css/kanban.sass +++ b/addons/web_kanban/static/src/css/kanban.sass @@ -264,7 +264,7 @@ width: 100% &.oe_kanban_ungrouped .oe_kanban_column .oe_kanban_record - float: left + display: inline-block padding: 2px box-sizing: border-box -moz-box-sizing: border-box diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index 0e739f2c080..98dba6df611 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -27,6 +27,7 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ this.group_by = null; this.group_by_field = {}; this.grouped_by_m2o = false; + this.many2manys = []; this.state = { groups : {}, records : {} @@ -130,12 +131,11 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ } switch (node.tag) { case 'field': - if(this.fields_view.fields[ node.attrs['name'] ].type == 'many2many'){ - node.tag = 'div'; - node.attrs['class'] = 'oe_form_field oe_tags'; - node.attrs['model'] = this.fields_view.fields[node.attrs['name']].relation; - node.attrs['t-att-data'] = 'record.' + node.attrs['name'] + '.raw_value'; - }else { + if (this.fields_view.fields[node.attrs.name].type === 'many2many') { + this.many2manys.push(node.attrs.name); + node.tag = 'div'; + node.attrs['class'] = (node.attrs['class'] || '') + ' oe_form_field oe_tags'; + } else { node.tag = QWeb.prefix; node.attrs[QWeb.prefix + '-esc'] = 'record.' + node.attrs['name'] + '.value'; } @@ -388,7 +388,7 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ } else { this.$el.find('.oe_kanban_draghandle').removeClass('oe_kanban_draghandle'); } - instance.web_kanban.KanbanView.postprocessing_widget_many2many_tags(self); + this.postprocess_m2m_tags(); }, on_record_moved : function(record, old_group, old_index, new_group, new_index) { var self = this; @@ -470,44 +470,48 @@ instance.web_kanban.KanbanView = instance.web.View.extend({ this.$el.find('.oe_view_nocontent').click(function() { create_nocontent.effect('bounce', {distance: 18, times: 5}, 150); }); + }, + + /* + * postprocessing of fields type many2many + * make the rpc request for all ids/model and insert value inside .oe_tags fields + */ + postprocess_m2m_tags: function() { + var self = this; + if (!this.many2manys.length) { + return; + } + var relations = {}; + this.groups.forEach(function(group) { + group.records.forEach(function(record) { + self.many2manys.forEach(function(name) { + var field = record.record[name]; + var $el = record.$('.oe_form_field.oe_tags[name=' + name + ']'); + if (!relations[field.relation]) { + relations[field.relation] = { ids: [], elements: {}}; + } + var rel = relations[field.relation]; + field.raw_value.forEach(function(id) { + rel.ids.push(id); + if (!rel.elements[id]) { + rel.elements[id] = []; + } + rel.elements[id].push($el[0]); + }); + }); + }); + }); + _.each(relations, function(rel, rel_name) { + var dataset = new instance.web.DataSetSearch(self, rel_name, self.dataset.get_context()); + dataset.name_get(_.uniq(rel.ids)).done(function(result) { + result.forEach(function(nameget) { + $(rel.elements[nameget[0]]).append('' + _.str.escapeHTML(nameget[1]) + ''); + }); + }); + }); } }); -/* -* widget for list of tags/categories -* make the rpc request for all ids/model and insert value inside .oe_tags fields -*/ -instance.web_kanban.KanbanView.postprocessing_widget_many2many_tags = function(self){ - var model_list_id={}; - - // select all widget for the kanban view or the widget inside the record - self.$el.find(".oe_form_field.oe_tags").each(function(){ - var model = $(this).attr("model"); - if(model.length){ - var data = $(this).attr("data"); - var list = data.split(","); - - //select all id (per model) - if(!model_list_id[model]) model_list_id[model]=[]; - for(var t=0;t0){ - var block = self.$el.find(".oe_form_field.oe_tags[model='" + model + "']"); - var dataset = new instance.web.DataSetSearch(self, model, self.session.context); - dataset.name_get(_.uniq( model_list_id[model] )).done( - function(result) { - for(var t=0;t'+result[t][1]+''); - } - } - ); - } - } -} function get_class(name) { return new instance.web.Registry({'tmp' : name}).get_object("tmp"); @@ -946,7 +950,7 @@ instance.web_kanban.KanbanRecord = instance.web.Widget.extend({ self.$el.data('widget', self); self.bind_events(); self.group.compute_cards_auto_height(); - instance.web_kanban.KanbanView.postprocessing_widget_many2many_tags(self); + self.view.postprocess_m2m_tags(); } else { self.destroy(); } @@ -988,10 +992,10 @@ instance.web_kanban.KanbanRecord = instance.web.Widget.extend({ } else if (this.record[field] && ! this.record[field].value) { url = "/web/static/src/img/placeholder.png"; } else { - id = escape(JSON.stringify(id)); + id = JSON.stringify(id); if (options.preview_image) field = options.preview_image; - url = instance.session.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id; + url = this.session.url('/web/binary/image', {model: model, field: field, id: id}); if (cache !== undefined) { // Set the cache duration in seconds. url += '&cache=' + parseInt(cache, 10); diff --git a/addons/web_tests/i18n/es_CR.po b/addons/web_tests/i18n/es_CR.po index 8d2bfb39fe0..03a3decee15 100644 --- a/addons/web_tests/i18n/es_CR.po +++ b/addons/web_tests/i18n/es_CR.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" diff --git a/addons/web_tests/i18n/fr_CA.po b/addons/web_tests/i18n/fr_CA.po index 41dc4167edd..e5e6713348f 100644 --- a/addons/web_tests/i18n/fr_CA.po +++ b/addons/web_tests/i18n/fr_CA.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-10-21 05:03+0000\n" -"X-Generator: Launchpad (build 16165)\n" +"X-Launchpad-Export-Date: 2012-11-15 05:09+0000\n" +"X-Generator: Launchpad (build 16265)\n" diff --git a/addons/web_tests_demo/__init__.py b/addons/web_tests_demo/__init__.py new file mode 100644 index 00000000000..137d472ec74 --- /dev/null +++ b/addons/web_tests_demo/__init__.py @@ -0,0 +1,14 @@ +from openerp.osv import orm, fields + +class TestObject(orm.Model): + _name = 'web_tests_demo.model' + + _columns = { + 'name': fields.char("Name", required=True), + 'thing': fields.char("Thing"), + 'other': fields.char("Other", required=True) + } + _defaults = { + 'other': "bob" + } + diff --git a/addons/web_tests_demo/__openerp__.py b/addons/web_tests_demo/__openerp__.py new file mode 100644 index 00000000000..7404ef6b4fc --- /dev/null +++ b/addons/web_tests_demo/__openerp__.py @@ -0,0 +1,8 @@ +{ + 'name': "Demonstration of web/javascript tests", + 'category': 'Hidden', + 'depends': ['web'], + 'js': ['static/src/js/demo.js'], + 'test': ['static/test/demo.js'], + 'qweb': ['static/src/xml/demo.xml'], +} diff --git a/addons/web_tests_demo/static/src/js/demo.js b/addons/web_tests_demo/static/src/js/demo.js new file mode 100644 index 00000000000..b35b44b80f8 --- /dev/null +++ b/addons/web_tests_demo/static/src/js/demo.js @@ -0,0 +1,11 @@ +// static/src/js/demo.js +openerp.web_tests_demo = function (instance) { + instance.web_tests_demo = { + value_true: true, + SomeType: instance.web.Class.extend({ + init: function (value) { + this.value = value; + } + }) + }; +}; diff --git a/addons/web_tests_demo/static/src/xml/demo.xml b/addons/web_tests_demo/static/src/xml/demo.xml new file mode 100644 index 00000000000..1bd3862d70e --- /dev/null +++ b/addons/web_tests_demo/static/src/xml/demo.xml @@ -0,0 +1,7 @@ + +
    + +

    +
    +
    +
    diff --git a/addons/web_tests_demo/static/test/demo.js b/addons/web_tests_demo/static/test/demo.js new file mode 100644 index 00000000000..b2d54c83d68 --- /dev/null +++ b/addons/web_tests_demo/static/test/demo.js @@ -0,0 +1,102 @@ +openerp.testing.section('basic section', function (test) { + test('my first test', function () { + ok(true, "this test has run"); + }); + test('module content', function (instance) { + ok(instance.web_tests_demo.value_true, "should have a true value"); + var type_instance = new instance.web_tests_demo.SomeType(42); + strictEqual(type_instance.value, 42, "should have provided value"); + }); + test('DOM content', function (instance, $scratchpad) { + $scratchpad.html('
    ok
    '); + ok($scratchpad.find('span').hasClass('foo'), + "should have provided class"); + }); + test('clean scratchpad', function (instance, $scratchpad) { + ok(!$scratchpad.children().length, "should have no content"); + ok(!$scratchpad.text(), "should have no text"); + }); + + test('templates', {templates: true}, function (instance) { + var s = instance.web.qweb.render('DemoTemplate'); + var texts = $(s).find('p').map(function () { + return $(this).text(); + }).get(); + + deepEqual(texts, ['0', '1', '2', '3', '4']); + }); + + test('asynchronous', { + asserts: 1 + }, function () { + var d = $.Deferred(); + setTimeout(function () { + ok(true); + d.resolve(); + }, 100); + return d; + }); + test('unfail rejection', { + asserts: 1, + fail_on_rejection: false + }, function () { + var d = $.Deferred(); + setTimeout(function () { + ok(true); + d.reject(); + }, 100); + return d; + }); + + test('XML-RPC', {rpc: 'mock', asserts: 3}, function (instance, $s, mock) { + mock('people.famous:name_search', function (args, kwargs) { + strictEqual(kwargs.name, 'bob'); + return [ + [1, "Microsoft Bob"], + [2, "Bob the Builder"], + [3, "Silent Bob"] + ]; + }); + return new instance.web.Model('people.famous') + .call('name_search', {name: 'bob'}).then(function (result) { + strictEqual(result.length, 3, "shoud return 3 people"); + strictEqual(result[0][1], "Microsoft Bob", + "the most famous bob should be Microsoft Bob"); + }); + }); + test('JSON-RPC', {rpc: 'mock', asserts: 3, templates: true}, function (instance, $s, mock) { + var fetched_dbs = false, fetched_langs = false; + mock('/web/database/get_list', function () { + fetched_dbs = true; + return ['foo', 'bar', 'baz']; + }); + mock('/web/session/get_lang_list', function () { + fetched_langs = true; + return [['vo_IS', 'Hopelandic / Vonlenska']]; + }); + + // widget needs that or it blows up + instance.webclient = {toggle_bars: openerp.testing.noop}; + var dbm = new instance.web.DatabaseManager({}); + return dbm.appendTo($s).then(function () { + ok(fetched_dbs, "should have fetched databases"); + ok(fetched_langs, "should have fetched languages"); + deepEqual(dbm.db_list, ['foo', 'bar', 'baz']); + }); + }); + + test('actual RPC', {rpc: 'rpc', asserts: 4}, function (instance) { + var Model = new instance.web.Model('web_tests_demo.model'); + return Model.call('create', [{name: "Bob"}]) + .then(function (id) { + return Model.call('read', [[id]]); + }).then(function (records) { + strictEqual(records.length, 1); + var record = records[0]; + strictEqual(record.name, "Bob"); + strictEqual(record.thing, false); + // default value + strictEqual(record.other, 'bob'); + }); + }); +});