diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py index 2855441bf6b..a4000856afe 100644 --- a/addons/web/__openerp__.py +++ b/addons/web/__openerp__.py @@ -14,83 +14,7 @@ This module provides the core of the OpenERP Web Client. 'data': [ 'views/webclient_templates.xml', ], - 'js': [ - "static/lib/es5-shim/es5-shim.min.js", - "static/lib/datejs/globalization/en-US.js", - "static/lib/datejs/core.js", - "static/lib/datejs/parser.js", - "static/lib/datejs/sugarpak.js", - "static/lib/datejs/extras.js", - "static/lib/jquery/jquery.js", - "static/lib/jquery.form/jquery.form.js", - "static/lib/jquery.validate/jquery.validate.js", - "static/lib/jquery.ba-bbq/jquery.ba-bbq.js", - "static/lib/spinjs/spin.js", - "static/lib/jquery.autosize/jquery.autosize.js", - "static/lib/jquery.blockUI/jquery.blockUI.js", - "static/lib/jquery.hotkeys/jquery.hotkeys.js", - "static/lib/jquery.placeholder/jquery.placeholder.js", - "static/lib/jquery.ui/js/jquery-ui-1.9.1.custom.js", - "static/lib/jquery.ui.timepicker/js/jquery-ui-timepicker-addon.js", - "static/lib/jquery.ui.notify/js/jquery.notify.js", - "static/lib/jquery.deferred-queue/jquery.deferred-queue.js", - "static/lib/jquery.scrollTo/jquery.scrollTo-min.js", - "static/lib/jquery.tipsy/jquery.tipsy.js", - "static/lib/jquery.textext/jquery.textext.js", - "static/lib/jquery.timeago/jquery.timeago.js", - "static/lib/bootstrap/js/bootstrap.js", - "static/lib/qweb/qweb2.js", - "static/lib/underscore/underscore.js", - "static/lib/underscore.string/lib/underscore.string.js", - "static/lib/backbone/backbone.js", - "static/lib/cleditor/jquery.cleditor.js", - "static/lib/py.js/lib/py.js", - "static/lib/select2/select2.js", - "static/src/js/openerpframework.js", - "static/src/js/boot.js", - "static/src/js/testing.js", - "static/src/js/pyeval.js", - "static/src/js/core.js", - "static/src/js/formats.js", - "static/src/js/chrome.js", - "static/src/js/views.js", - "static/src/js/data.js", - "static/src/js/data_export.js", - "static/src/js/search.js", - "static/src/js/view_list.js", - "static/src/js/view_form.js", - "static/src/js/view_list_editable.js", - "static/src/js/view_tree.js", - ], - 'css' : [ - "static/lib/jquery.ui.bootstrap/css/custom-theme/jquery-ui-1.9.0.custom.css", - "static/lib/jquery.ui.timepicker/css/jquery-ui-timepicker-addon.css", - "static/lib/jquery.ui.notify/css/ui.notify.css", - "static/lib/jquery.tipsy/tipsy.css", - "static/lib/jquery.textext/jquery.textext.css", - "static/lib/fontawesome/css/font-awesome.css", - "static/lib/bootstrap/css/bootstrap.css", - "static/lib/select2/select2.css", - "static/src/css/base.css", - "static/src/css/data_export.css", - "static/lib/cleditor/jquery.cleditor.css", - ], 'qweb' : [ "static/src/xml/*.xml", ], - 'test': [ - "static/test/testing.js", - "static/test/framework.js", - "static/test/registry.js", - "static/test/form.js", - "static/test/data.js", - "static/test/list-utils.js", - "static/test/formats.js", - "static/test/rpc-misordered.js", - "static/test/evals.js", - "static/test/search.js", - "static/test/list.js", - "static/test/list-editable.js", - "static/test/mutex.js" - ], } diff --git a/addons/web/controllers/__init__.py b/addons/web/controllers/__init__.py index 74c27518ece..12a7e529b67 100644 --- a/addons/web/controllers/__init__.py +++ b/addons/web/controllers/__init__.py @@ -1,2 +1 @@ from . import main -from . import testing diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index a6b5fa63918..5b2c7a5e91a 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -31,6 +31,7 @@ except ImportError: import openerp import openerp.modules.registry +from openerp.addons.base.ir.ir_qweb import AssetsBundle, QWebTemplateNotFound from openerp.tools.translate import _ from openerp import http @@ -52,50 +53,6 @@ env.filters["json"] = simplejson.dumps # OpenERP Web helpers #---------------------------------------------------------- -def rjsmin(script): - """ Minify js with a clever regex. - Taken from http://opensource.perlig.de/rjsmin - Apache License, Version 2.0 """ - def subber(match): - """ Substitution callback """ - groups = match.groups() - return ( - groups[0] or - groups[1] or - groups[2] or - groups[3] or - (groups[4] and '\n') or - (groups[5] and ' ') or - (groups[6] and ' ') or - (groups[7] and ' ') or - '' - ) - - result = re.sub( - r'([^\047"/\000-\040]+)|((?:(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]|\r?' - r'\n|\r)[^\047\\\r\n]*)*\047)|(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|' - r'\r)[^"\\\r\n]*)*"))[^\047"/\000-\040]*)|(?:(?<=[(,=:\[!&|?{};\r\n]' - r')(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/' - r'))*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*' - r'(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/)[^\047"/\000-\040]*' - r'))|(?:(?<=[\000-#%-,./:-@\[-^`{-~-]return)(?:[\000-\011\013\014\01' - r'6-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*((?:/(?![\r\n/*])[^/' - r'\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]' - r'*)*\]))[^/\\\[\r\n]*)*/)[^\047"/\000-\040]*))|(?<=[^\000-!#%&(*,./' - r':-@\[\\^`{|~])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/' - r'*][^*]*\*+)*/))*(?:((?:(?://[^\r\n]*)?[\r\n]))(?:[\000-\011\013\01' - r'4\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040"#' - r'%-\047)*,./:-@\\-^`|-~])|(?<=[^\000-#%-,./:-@\[-^`{-~-])((?:[\000-' - r'\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=[^' - r'\000-#%-,./:-@\[-^`{-~-])|(?<=\+)((?:[\000-\011\013\014\016-\040]|' - r'(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=\+)|(?<=-)((?:[\000-\011\0' - r'13\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=-)|(?:[\0' - r'00-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))+|(?:' - r'(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*' - r']*\*+(?:[^/*][^*]*\*+)*/))*)+', subber, '\n%s\n' % script - ).strip() - return result - db_list = http.db_list db_monodb = http.db_monodb @@ -309,45 +266,6 @@ def concat_xml(file_list): root.append(child) return ElementTree.tostring(root, 'utf-8'), checksum.hexdigest() -def concat_files(file_list, reader=None, intersperse=""): - """ Concatenates contents of all provided files - - :param list(str) file_list: list of files to check - :param function reader: reading procedure for each file - :param str intersperse: string to intersperse between file contents - :returns: (concatenation_result, checksum) - :rtype: (str, str) - """ - checksum = hashlib.new('sha1') - if not file_list: - return '', checksum.hexdigest() - - if reader is None: - def reader(f): - import codecs - with codecs.open(f, 'rb', "utf-8-sig") as fp: - return fp.read().encode("utf-8") - - files_content = [] - for fname in file_list: - contents = reader(fname) - checksum.update(contents) - files_content.append(contents) - - 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=';') - 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)) @@ -371,30 +289,17 @@ def manifest_glob(extension, addons=None, db=None, include_remotes=False): r.append((None, pattern)) else: for path in glob.glob(os.path.normpath(os.path.join(addons_path, addon, pattern))): - # Hack for IE, who limit 288Ko, 4095 rules, 31 sheets - # http://support.microsoft.com/kb/262161/en - if pattern == "static/lib/bootstrap/css/bootstrap.css": - if include_remotes: - r.insert(0, (None, fs2web(path[len(addons_path):]))) - else: - r.append((path, fs2web(path[len(addons_path):]))) + r.append((path, fs2web(path[len(addons_path):]))) return r -def manifest_list(extension, mods=None, db=None, debug=False): +def manifest_list(extension, mods=None, db=None, debug=None): """ list ressources to load specifying either: mods: a comma separated string listing modules db: a database name (return all installed modules in that database) """ + if debug is not None: + _logger.warning("openerp.addons.web.main.manifest_list(): debug parameter is deprecated") files = manifest_glob(extension, addons=mods, db=db, include_remotes=True) - if not debug: - path = '/web/webclient/' + extension - if mods is not None: - path += '?' + werkzeug.url_encode({'mods': mods}) - elif db: - path += '?' + werkzeug.url_encode({'db': db}) - - remotes = [wp for fp, wp in files if fp is None] - return [path] + remotes return [wp for _fp, wp in files] def get_last_modified(files): @@ -411,7 +316,7 @@ def get_last_modified(files): for f in files) return datetime.datetime(1970, 1, 1) -def make_conditional(response, last_modified=None, etag=None): +def make_conditional(response, last_modified=None, etag=None, max_age=0): """ Makes the provided response conditional based upon the request, and mandates revalidation from clients @@ -426,7 +331,7 @@ def make_conditional(response, last_modified=None, etag=None): :rtype: werkzeug.wrappers.Response """ response.cache_control.must_revalidate = True - response.cache_control.max_age = 0 + response.cache_control.max_age = max_age if last_modified: response.last_modified = last_modified if etag: @@ -592,59 +497,6 @@ def content_disposition(filename): #---------------------------------------------------------- # OpenERP Web web Controllers #---------------------------------------------------------- - -# TODO: to remove once the database manager has been migrated server side -# and `edi` + `pos` addons has been adapted to use render_bootstrap_template() -html_template = """ - - - - - OpenERP - - - %(css)s - %(js)s - - - - - - -""" - -def render_bootstrap_template(template, values=None, debug=False, db=None, **kw): - if not db: - db = request.db - if request.debug: - debug = True - if values is None: - values = {} - values['debug'] = debug - values['current_db'] = db - try: - values['databases'] = http.db_list() - except openerp.exceptions.AccessDenied: - values['databases'] = None - - for res in ['js', 'css']: - if res not in values: - values[res] = manifest_list(res, db=db, debug=debug) - - if 'modules' not in values: - values['modules'] = module_boot(db=db) - values['modules'] = simplejson.dumps(values['modules']) - - return request.render(template, values, **kw) - class Home(http.Controller): @http.route('/', type='http', auth="none") @@ -658,12 +510,7 @@ class Home(http.Controller): if request.session.uid: if kw.get('redirect'): return werkzeug.utils.redirect(kw.get('redirect'), 303) - - headers = { - 'Cache-Control': 'no-cache', - 'Content-Type': 'text/html; charset=utf-8', - } - return render_bootstrap_template("web.webclient_bootstrap", headers=headers) + return request.render('web.webclient_bootstrap') else: return login_redirect() @@ -681,17 +528,57 @@ class Home(http.Controller): if not redirect: redirect = '/web?' + request.httprequest.query_string values['redirect'] = redirect + + try: + values['databases'] = http.db_list() + except openerp.exceptions.AccessDenied: + values['databases'] = None + if request.httprequest.method == 'POST': + old_uid = request.uid uid = request.session.authenticate(request.session.db, request.params['login'], request.params['password']) if uid is not False: return http.redirect_with_hash(redirect) + request.uid = old_uid values['error'] = "Wrong login/password" - return render_bootstrap_template('web.login', values) + return request.render('web.login', values) @http.route('/login', type='http', auth="none") def login(self, db, login, key, redirect="/web", **kw): return login_and_redirect(db, login, key, redirect_url=redirect) + @http.route('/web/js/', type='http', auth="public") + def js_bundle(self, xmlid, **kw): + # manifest backward compatible mode, to be removed + values = {'manifest_list': manifest_list} + try: + assets_html = request.render(xmlid, lazy=False, qcontext=values) + except QWebTemplateNotFound: + return request.not_found() + bundle = AssetsBundle(xmlid, assets_html, debug=request.debug) + + response = request.make_response( + bundle.js(), [('Content-Type', 'application/javascript')]) + + # TODO: check that we don't do weird lazy overriding of __call__ which break body-removal + return make_conditional( + response, bundle.last_modified, bundle.checksum, max_age=60*60*24) + + @http.route('/web/css/', type='http', auth='public') + def css_bundle(self, xmlid, **kw): + values = {'manifest_list': manifest_list} # manifest backward compatible mode, to be removed + try: + assets_html = request.render(xmlid, lazy=False, qcontext=values) + except QWebTemplateNotFound: + return request.not_found() + bundle = AssetsBundle(xmlid, assets_html, debug=request.debug) + + response = request.make_response( + bundle.css(), [('Content-Type', 'text/css')]) + + return make_conditional( + response, bundle.last_modified, bundle.checksum, max_age=60*60*24) + class WebClient(http.Controller): @http.route('/web/webclient/csslist', type='json', auth="none") @@ -702,74 +589,6 @@ class WebClient(http.Controller): def jslist(self, mods=None): return manifest_list('js', mods=mods) - @http.route('/web/webclient/qweblist', type='json', auth="none") - def qweblist(self, mods=None): - return manifest_list('qweb', mods=mods) - - @http.route('/web/webclient/css', type='http', auth="none") - def css(self, mods=None, db=None): - files = list(manifest_glob('css', addons=mods, db=db)) - last_modified = get_last_modified(f[0] for f in files) - if request.httprequest.if_modified_since and request.httprequest.if_modified_since >= last_modified: - return werkzeug.wrappers.Response(status=304) - - file_map = dict(files) - - rx_import = re.compile(r"""@import\s+('|")(?!'|"|/|https?://)""", re.U) - rx_url = re.compile(r"""url\s*\(\s*('|"|)(?!'|"|/|https?://|data:)""", re.U) - - def reader(f): - """read the a css file and absolutify all relative uris""" - with open(f, 'rb') as fp: - data = fp.read().decode('utf-8') - - path = file_map[f] - web_dir = os.path.dirname(path) - - data = re.sub( - rx_import, - r"""@import \1%s/""" % (web_dir,), - data, - ) - - data = re.sub( - rx_url, - r"url(\1%s/" % (web_dir,), - data, - ) - return data.encode('utf-8') - - content, checksum = concat_files((f[0] for f in files), reader) - - # move up all @import and @charset rules to the top - matches = [] - def push(matchobj): - matches.append(matchobj.group(0)) - return '' - - content = re.sub(re.compile("(@charset.+;$)", re.M), push, content) - content = re.sub(re.compile("(@import.+;$)", re.M), push, content) - - matches.append(content) - content = '\n'.join(matches) - - return make_conditional( - request.make_response(content, [('Content-Type', 'text/css')]), - last_modified, checksum) - - @http.route('/web/webclient/js', type='http', auth="none") - def js(self, mods=None, db=None): - files = [f[0] for f in manifest_glob('js', addons=mods, db=db)] - last_modified = get_last_modified(files) - if request.httprequest.if_modified_since and request.httprequest.if_modified_since >= last_modified: - return werkzeug.wrappers.Response(status=304) - - content, checksum = concat_js(files) - - return make_conditional( - request.make_response(content, [('Content-Type', 'application/javascript')]), - last_modified, checksum) - @http.route('/web/webclient/qweb', type='http', auth="none") def qweb(self, mods=None, db=None): files = [f[0] for f in manifest_glob('qweb', addons=mods, db=db)] @@ -843,6 +662,10 @@ class WebClient(http.Controller): def version_info(self): return openerp.service.common.exp_version() + @http.route('/web/tests', type='http', auth="none") + def index(self, mod=None, **kwargs): + return request.render('web.qunit_suite') + class Proxy(http.Controller): @http.route('/web/proxy/load', type='json', auth="none") @@ -879,19 +702,9 @@ class Database(http.Controller): def manager(self, **kw): # TODO: migrate the webclient's database manager to server side views request.session.logout() - js = "\n ".join('' % i for i in manifest_list('js', debug=request.debug)) - css = "\n ".join('' % i for i in manifest_list('css', debug=request.debug)) - - r = html_template % { - 'js': js, - 'css': css, + return env.get_template("database_manager.html").render({ 'modules': simplejson.dumps(module_boot()), - 'init': """ - var wc = new s.web.WebClient(null, { action: 'database_manager' }); - wc.appendTo($(document.body)); - """ - } - return r + }) @http.route('/web/database/get_list', type='json', auth="none") def get_list(self): @@ -1088,16 +901,7 @@ class Menu(http.Controller): """ s = request.session Menus = s.model('ir.ui.menu') - # If a menu action is defined use its domain to get the root menu items - user_menu_id = s.model('res.users').read([s.uid], ['menu_id'], - request.context)[0]['menu_id'] - menu_domain = [('parent_id', '=', False)] - if user_menu_id: - domain_string = s.model('ir.actions.act_window').read( - [user_menu_id[0]], ['domain'],request.context)[0]['domain'] - if domain_string: - menu_domain = ast.literal_eval(domain_string) return Menus.search(menu_domain, 0, False, False, request.context) @@ -1225,7 +1029,7 @@ class DataSet(http.Controller): records = getattr(request.session.model(model), method)(*args, **kwargs) for record in records: record['display_name'] = \ - names.get(record['id']) or "%s#%d" % (model, (record['id'])) + names.get(record['id']) or "{0}#{1}".format(model, (record['id'])) return records if method.startswith('_'): diff --git a/addons/web/controllers/testing.py b/addons/web/controllers/testing.py deleted file mode 100644 index a51b619d49f..00000000000 --- a/addons/web/controllers/testing.py +++ /dev/null @@ -1,159 +0,0 @@ -# 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 openerp import http -from openerp.http import request - -from .main import module_topological_sort - -NOMODULE_TEMPLATE = Template(u""" - - - - - OpenERP Testing - - -
- -
    - % for name, module in modules: -
  • ${name}
  • - % endfor -
-
- - -""", default_filters=['h']) -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 -""", default_filters=['h']) -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: - % if not js.endswith('/apps.js'): - - % endif - % endfor - % if tests or templates: - - % endif - % if tests: - % for test in tests: - - % endfor - % endif -% endfor - -""", default_filters=['h']) - -class TestRunnerController(http.Controller): - - @http.route('/web/tests', type='http', auth="none") - def index(self, 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 request.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) - ] - - 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']])) - - 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/i18n/ar.po b/addons/web/i18n/ar.po index d847ecb2e1b..b1556bfc29e 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:31+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/bg.po b/addons/web/i18n/bg.po index 3200798afca..95343c77fc7 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/bn.po b/addons/web/i18n/bn.po index 5ad67dbc189..018ac00953b 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:31+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/bs.po b/addons/web/i18n/bs.po index d3ad8c5fcaa..020336a3459 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:31+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/ca.po b/addons/web/i18n/ca.po index a9a6f60fa22..03728f73ead 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/cs.po b/addons/web/i18n/cs.po index d572f8ce11f..d6187adba73 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" "X-Poedit-Language: Czech\n" #. module: web diff --git a/addons/web/i18n/da.po b/addons/web/i18n/da.po index 571dedcc5c4..9338fbc2c4a 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/de.po b/addons/web/i18n/de.po index a22df51ce71..7b9b24d8dcc 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/en_AU.po b/addons/web/i18n/en_AU.po index a1cdf449f9b..0611bba79b0 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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/en_GB.po b/addons/web/i18n/en_GB.po index 586c44543c3..f6c6b8f3ac7 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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/es.po b/addons/web/i18n/es.po index 2911e97a98b..0ebd39c1795 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/es_CL.po b/addons/web/i18n/es_CL.po index 8786cde4424..917c7f5234a 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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/es_CR.po b/addons/web/i18n/es_CR.po index 5aec19d8207..7a1c4f10c0c 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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" "Language: es\n" #. module: web diff --git a/addons/web/i18n/es_DO.po b/addons/web/i18n/es_DO.po index 23b88465fdd..90c5af3799b 100644 --- a/addons/web/i18n/es_DO.po +++ b/addons/web/i18n/es_DO.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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/es_EC.po b/addons/web/i18n/es_EC.po index 8fc6129e4ec..c1ce429932a 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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/es_MX.po b/addons/web/i18n/es_MX.po index a635938be37..12b9573056e 100644 --- a/addons/web/i18n/es_MX.po +++ b/addons/web/i18n/es_MX.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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/es_PE.po b/addons/web/i18n/es_PE.po index c79aedb7c54..73dcc465257 100644 --- a/addons/web/i18n/es_PE.po +++ b/addons/web/i18n/es_PE.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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/et.po b/addons/web/i18n/et.po index 31124e42155..1e1fcaaaca0 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/eu.po b/addons/web/i18n/eu.po index 3dbe990e9d4..da130c4e193 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:31+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/fa.po b/addons/web/i18n/fa.po index 73189acbf3b..231c0cba505 100644 --- a/addons/web/i18n/fa.po +++ b/addons/web/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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/fi.po b/addons/web/i18n/fi.po index 7964566fd42..9c8da1d5cb2 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/fr.po b/addons/web/i18n/fr.po index 3b8bb419f5b..e3030102707 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/fr_CA.po b/addons/web/i18n/fr_CA.po index f7bee061dd0..377e8508d1b 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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/gl.po b/addons/web/i18n/gl.po index 31e924db129..e822b968880 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/gu.po b/addons/web/i18n/gu.po index 0a0e108f59e..5d19d82e8c3 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/he.po b/addons/web/i18n/he.po index c2ca619ac10..0e3d86c08f8 100644 --- a/addons/web/i18n/he.po +++ b/addons/web/i18n/he.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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/hi.po b/addons/web/i18n/hi.po index fb858fb82f0..21b0dec3a96 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: 2014-04-10 05:56+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/hr.po b/addons/web/i18n/hr.po index 2bff56b362b..e82b7c4832d 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/hu.po b/addons/web/i18n/hu.po index 1074f41727a..c1cd65aaa6a 100644 --- a/addons/web/i18n/hu.po +++ b/addons/web/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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/id.po b/addons/web/i18n/id.po index 483ca79f8ab..feb30a5c409 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/it.po b/addons/web/i18n/it.po index 5d5e7e064b5..bdc14fa8443 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/ja.po b/addons/web/i18n/ja.po index d46eee695ea..aa8987dc830 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/ka.po b/addons/web/i18n/ka.po index 89d3011b25d..ad652a2259d 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/ko.po b/addons/web/i18n/ko.po index ce4c2b6b019..a74981e1926 100644 --- a/addons/web/i18n/ko.po +++ b/addons/web/i18n/ko.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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web @@ -68,14 +68,14 @@ msgstr "기존 암호를 입력해 주세요." #: code:addons/web/static/src/xml/base.xml:300 #, python-format msgid "Master password:" -msgstr "마스터 암호:" +msgstr "마스터 비밀번호" #. module: web #. openerp-web #: code:addons/web/static/src/xml/base.xml:292 #, python-format msgid "Change Master Password" -msgstr "마스터 암호 변경" +msgstr "마스터 비밀번호 변경하기" #. module: web #. openerp-web @@ -110,7 +110,7 @@ msgstr "업로드 오류" #: code:addons/web/static/src/js/coresetup.js:593 #, python-format msgid "about an hour ago" -msgstr "약 한 시간 전" +msgstr "약 1시간 전" #. module: web #. openerp-web @@ -161,14 +161,14 @@ msgstr "파일" #: code:addons/web/controllers/main.py:869 #, python-format msgid "You cannot leave any password empty." -msgstr "암호는 비워둘 수 없습니다." +msgstr "비밀번호는 비워둘 수 없습니다." #. module: web #. openerp-web #: code:addons/web/static/src/js/chrome.js:732 #, python-format msgid "Invalid username or password" -msgstr "유효하지 않은 사용자명 또는 암호" +msgstr "유효하지 않은 사용자명 또는 비밀번호" #. module: web #. openerp-web @@ -177,7 +177,7 @@ msgstr "유효하지 않은 사용자명 또는 암호" #: code:addons/web/static/src/xml/base.xml:278 #, python-format msgid "Master Password:" -msgstr "마스터 암호:" +msgstr "마스터 비밀번호" #. module: web #. openerp-web @@ -185,7 +185,7 @@ msgstr "마스터 암호:" #: code:addons/web/static/src/xml/base.xml:1402 #, python-format msgid "Select" -msgstr "선택" +msgstr "선택하기" #. module: web #. openerp-web @@ -235,7 +235,7 @@ msgstr "모든 사용자들과 공유" #: code:addons/web/static/src/js/view_form.js:320 #, python-format msgid "Form" -msgstr "양식" +msgstr "폼" #. module: web #. openerp-web @@ -263,7 +263,7 @@ msgstr "유효한 숫자가 아님" #: code:addons/web/static/src/xml/base.xml:343 #, python-format msgid "New Password:" -msgstr "새로운 비밀번호" +msgstr "새 비밀번호:" #. module: web #. openerp-web @@ -348,7 +348,7 @@ msgstr "중복 데이터베이스" #: code:addons/web/static/src/xml/base.xml:354 #, python-format msgid "Change Password" -msgstr "암호 변경" +msgstr "비밀번호 변경하기" #. module: web #. openerp-web @@ -1601,7 +1601,7 @@ msgstr "데이터 베이스 삭제" #: code:addons/web/static/src/xml/base.xml:467 #, python-format msgid "Powered by" -msgstr "" +msgstr "Powered by" #. module: web #. openerp-web @@ -1644,7 +1644,7 @@ msgstr "--- 가져오지 않기 ---" #: code:addons/web/static/src/xml/base.xml:1697 #, python-format msgid "Import-Compatible Export" -msgstr "" +msgstr "가져오기-호환 파일 내보내기" #. module: web #. openerp-web @@ -2364,7 +2364,7 @@ msgstr "o2m 기록은 액션을 사용하기 전에 저장되어야 합니다." #: code:addons/web/static/src/js/chrome.js:531 #, python-format msgid "Backed" -msgstr "" +msgstr "백업됨" #. module: web #. openerp-web @@ -2420,7 +2420,7 @@ msgstr "ID:" #: code:addons/web/static/src/xml/base.xml:892 #, python-format msgid "Only you" -msgstr "" +msgstr "Only you" #. module: web #. openerp-web diff --git a/addons/web/i18n/lo.po b/addons/web/i18n/lo.po index bb484d07f1d..1f96321abbd 100644 --- a/addons/web/i18n/lo.po +++ b/addons/web/i18n/lo.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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/lt.po b/addons/web/i18n/lt.po index 25efa7b8f5c..b9b53d05cd5 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/lv.po b/addons/web/i18n/lv.po index 9f685f70d31..84a27c25e45 100644 --- a/addons/web/i18n/lv.po +++ b/addons/web/i18n/lv.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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/mk.po b/addons/web/i18n/mk.po index 79a9cecaf20..674772a588f 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/mn.po b/addons/web/i18n/mn.po index d47989ab748..9cc662abcd6 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/nb.po b/addons/web/i18n/nb.po index 5db5fdb8333..6f96a005b45 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/nl.po b/addons/web/i18n/nl.po index ee2fcb2d04c..02d4e64676b 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:32+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/nl_BE.po b/addons/web/i18n/nl_BE.po index b04d024e96e..66e182a34f6 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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/pl.po b/addons/web/i18n/pl.po index 98b94458f0a..5cd63e311f8 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/pt.po b/addons/web/i18n/pt.po index 22abc7689fb..d2a9e1f6204 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/pt_BR.po b/addons/web/i18n/pt_BR.po index 1417acfdf5b..b5e079373aa 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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/ro.po b/addons/web/i18n/ro.po index cea4b12cd8a..2f99d49f061 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/ru.po b/addons/web/i18n/ru.po index e6ccd923125..f9d40793a93 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/sk.po b/addons/web/i18n/sk.po index d191a3f7470..b4e1267e9a0 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/sl.po b/addons/web/i18n/sl.po index cc7c4633a12..af7387e5437 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:33+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/sq.po b/addons/web/i18n/sq.po index dd2ce5edd1b..86a3d8fac4c 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: 2014-04-09 06:38+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:31+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/sr@latin.po b/addons/web/i18n/sr@latin.po index a0178bd5140..691c54c92ed 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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:35+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/sv.po b/addons/web/i18n/sv.po index c785e60777e..7d882638fab 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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/th.po b/addons/web/i18n/th.po index 5cff3bb8f8d..fbcf5d550f6 100644 --- a/addons/web/i18n/th.po +++ b/addons/web/i18n/th.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: 2014-04-09 06:39+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web @@ -2593,7 +2593,7 @@ msgstr "สร้างฐานข้อมูล" #: code:addons/web/static/src/xml/base.xml:442 #, python-format msgid "GNU Affero General Public License" -msgstr "" +msgstr "GNU Affero General Public License" #. module: web #. openerp-web diff --git a/addons/web/i18n/tr.po b/addons/web/i18n/tr.po index 8a65bd712d4..47a114c7d14 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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/uk.po b/addons/web/i18n/uk.po index 31d499f1180..fd1213415a5 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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/vi.po b/addons/web/i18n/vi.po index 9c6de31b9bc..bbd5960c37a 100644 --- a/addons/web/i18n/vi.po +++ b/addons/web/i18n/vi.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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/zh_CN.po b/addons/web/i18n/zh_CN.po index ceaf734876d..34b233cd1c9 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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/i18n/zh_TW.po b/addons/web/i18n/zh_TW.po index a3d58934af4..19816a75fd8 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: 2014-04-09 06:40+0000\n" -"X-Generator: Launchpad (build 16976)\n" +"X-Launchpad-Export-Date: 2014-05-06 06:34+0000\n" +"X-Generator: Launchpad (build 16996)\n" #. module: web #. openerp-web diff --git a/addons/web/static/lib/fontawesome/css/font-awesome.css b/addons/web/static/lib/fontawesome/css/font-awesome.css index 7fa0e6f467b..35da66e7484 100644 --- a/addons/web/static/lib/fontawesome/css/font-awesome.css +++ b/addons/web/static/lib/fontawesome/css/font-awesome.css @@ -207,6 +207,9 @@ .fa-star:before { content: "\f005"; } +. fa-tasks:before { + content: "\f0ae"; +} .fa-star-o:before { content: "\f006"; } @@ -237,6 +240,12 @@ .fa-search-minus:before { content: "\f010"; } +.fa-adn:before { + content: "\f170"; +} +. fa-times:before { + content: "\f00d"; +} .fa-power-off:before { content: "\f011"; } @@ -308,6 +317,9 @@ .fa-qrcode:before { content: "\f029"; } +.fa-calendar:before { + content: "\f073"; +} .fa-barcode:before { content: "\f02a"; } @@ -759,6 +771,9 @@ .fa-pinterest:before { content: "\f0d2"; } +.fa-pencil-square-o:before { + content: "\f044"; +} .fa-pinterest-square:before { content: "\f0d3"; } diff --git a/addons/web/static/lib/jquery.tipsy/jquery.tipsy.js b/addons/web/static/lib/jquery.tipsy/jquery.tipsy.js deleted file mode 100644 index e978042f21b..00000000000 --- a/addons/web/static/lib/jquery.tipsy/jquery.tipsy.js +++ /dev/null @@ -1,250 +0,0 @@ -// tipsy, facebook style tooltips for jquery -// version 1.0.0a -// (c) 2008-2010 jason frame [jason@onehackoranother.com] -// released under the MIT license - -(function($) { - - function maybeCall(thing, ctx) { - return (typeof thing == 'function') ? (thing.call(ctx)) : thing; - }; - - function Tipsy(element, options) { - this.$element = $(element); - this.options = options; - this.enabled = true; - this.fixTitle(); - }; - - Tipsy.prototype = { - show: function() { - $.fn.tipsy.clear(); - if (!this.$element.parent().length) { - return; - } - var title = this.getTitle(); - if (title && this.enabled) { - var $tip = this.tip(); - - $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title); - $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(), { - width: this.$element[0].offsetWidth, - height: this.$element[0].offsetHeight - }); - - var actualWidth = $tip[0].offsetWidth, - actualHeight = $tip[0].offsetHeight, - gravity = maybeCall(this.options.gravity, this.$element[0]); - - var tp; - switch (gravity.charAt(0)) { - case 'n': - tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; - break; - case 's': - tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; - break; - case 'e': - tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset}; - break; - case 'w': - tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset}; - break; - } - - if (gravity.length == 2) { - if (gravity.charAt(1) == 'w') { - tp.left = pos.left + pos.width / 2 - 15; - } else { - tp.left = pos.left + pos.width / 2 - actualWidth + 15; - } - } - - $tip.css(tp).addClass('tipsy-' + gravity); - $tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0); - if (this.options.className) { - $tip.addClass(maybeCall(this.options.className, this.$element[0])); - } - - if (this.options.fade) { - $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity}); - } else { - $tip.css({visibility: 'visible', opacity: this.options.opacity}); - } - } - }, - - hide: function() { - if (this.options.fade) { - this.tip().stop().fadeOut(function() { $(this).remove(); }); - } else { - this.tip().remove(); - } - }, - - fixTitle: function() { - var $e = this.$element; - if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') { - $e.attr('original-title', $e.attr('title') || '').removeAttr('title'); - } - }, - - getTitle: function() { - var title, $e = this.$element, o = this.options; - this.fixTitle(); - var title, o = this.options; - if (typeof o.title == 'string') { - title = $e.attr(o.title == 'title' ? 'original-title' : o.title); - } else if (typeof o.title == 'function') { - title = o.title.call($e[0]); - } - title = ('' + title).replace(/(^\s*|\s*$)/, ""); - return title || o.fallback; - }, - - tip: function() { - if (!this.$tip) { - this.$tip = $('
').html('
'); - } - return this.$tip; - }, - - validate: function() { - if (!this.$element[0].parentNode) { - this.hide(); - this.$element = null; - this.options = null; - } - }, - - enable: function() { this.enabled = true; }, - disable: function() { this.enabled = false; }, - toggleEnabled: function() { this.enabled = !this.enabled; } - }; - - $.fn.tipsy = function(options) { - - if (options === true) { - return this.data('tipsy'); - } else if (typeof options == 'string') { - var tipsy = this.data('tipsy'); - if (tipsy) tipsy[options](); - return this; - } - - options = $.extend({}, $.fn.tipsy.defaults, options); - - function get(ele) { - var tipsy = $.data(ele, 'tipsy'); - if (!tipsy) { - tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options)); - $.data(ele, 'tipsy', tipsy); - } - return tipsy; - } - - function enter() { - var tipsy = get(this); - tipsy.hoverState = 'in'; - if (options.delayIn == 0) { - tipsy.show(); - } else { - tipsy.fixTitle(); - setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn); - } - }; - - function leave() { - var tipsy = get(this); - tipsy.hoverState = 'out'; - if (options.delayOut == 0) { - tipsy.hide(); - } else { - setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut); - } - }; - - if (!options.live) this.each(function() { get(this); }); - - if (options.trigger != 'manual') { - var binder = options.live ? 'live' : 'bind', - eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus', - eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur'; - this[binder](eventIn, enter)[binder](eventOut, leave); - } - - return this; - - }; - - $.fn.tipsy.clear = function() { - $('div.tipsy').stop().remove(); - } - - $.fn.tipsy.defaults = { - className: null, - delayIn: 0, - delayOut: 0, - fade: false, - fallback: '', - gravity: 'n', - html: false, - live: false, - offset: 0, - opacity: 0.8, - title: 'title', - trigger: 'hover' - }; - - // Overwrite this method to provide options on a per-element basis. - // For example, you could store the gravity in a 'tipsy-gravity' attribute: - // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' }); - // (remember - do not modify 'options' in place!) - $.fn.tipsy.elementOptions = function(ele, options) { - return $.metadata ? $.extend({}, options, $(ele).metadata()) : options; - }; - - $.fn.tipsy.autoNS = function() { - return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n'; - }; - - $.fn.tipsy.autoWE = function() { - return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w'; - }; - - /** - * yields a closure of the supplied parameters, producing a function that takes - * no arguments and is suitable for use as an autogravity function like so: - * - * @param margin (int) - distance from the viewable region edge that an - * element should be before setting its tooltip's gravity to be away - * from that edge. - * @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer - * if there are no viewable region edges effecting the tooltip's - * gravity. It will try to vary from this minimally, for example, - * if 'sw' is preferred and an element is near the right viewable - * region edge, but not the top edge, it will set the gravity for - * that element's tooltip to be 'se', preserving the southern - * component. - */ - $.fn.tipsy.autoBounds = function(margin, prefer) { - return function() { - var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)}, - boundTop = $(document).scrollTop() + margin, - boundLeft = $(document).scrollLeft() + margin, - $this = $(this); - - if ($this.offset().top < boundTop) dir.ns = 'n'; - if ($this.offset().left < boundLeft) dir.ew = 'w'; - if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e'; - if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's'; - - return dir.ns + (dir.ew ? dir.ew : ''); - } - }; - -})(jQuery); diff --git a/addons/web/static/lib/jquery.tipsy/tipsy.css b/addons/web/static/lib/jquery.tipsy/tipsy.css deleted file mode 100644 index 59d0fb97b9e..00000000000 --- a/addons/web/static/lib/jquery.tipsy/tipsy.css +++ /dev/null @@ -1,25 +0,0 @@ -.tipsy { font-size: 90%; position: absolute; padding: 5px; z-index: 100000; overflow: hidden;} - .tipsy-inner { background-color: #000; color: #FFF; max-width: 500px; padding: 5px 8px 4px 8px; } - - /* Rounded corners */ - .tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; } - - /* Uncomment for shadow */ - .tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; } - - .tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; } - - /* Rules to colour arrows */ - .tipsy-arrow-n { border-bottom-color: #000; } - .tipsy-arrow-s { border-top-color: #000; } - .tipsy-arrow-e { border-left-color: #000; } - .tipsy-arrow-w { border-right-color: #000; } - - .tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} - .tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} - .tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } - .tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 7fae47dc059..49c9573afde 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -79,7 +79,7 @@ vertical-align: top; } .openerp .oe_title { - width: 50%; + width: 38%; float: left; } .openerp .oe_title:after { @@ -314,47 +314,57 @@ .openerp .oe_form_dirty button.oe_highlight_on_dirty:hover { background: #ed6f6a; } -.openerp .oe_button_box { - width: 400px; - text-align: left; -} -.openerp .oe_button_box .oe_stat_button:hover { - background: #7c7bad; - color: white; -} -.openerp .oe_button_box .oe_stat_button:hover .fa { - color: white; -} -.openerp .oe_button_box .oe_stat_button { +.openerp .oe_stat_button { font-weight: normal; - display: inline-table; - width: 33% !important; - height: 42px; + width: 132px !important; + height: 40px; + color: #666666; margin: 0px -1px -1px 0px; padding: 0; - color: #666666; border: 1px solid #dddddd; border-radius: 0; box-shadow: none; background: white; } -.openerp .oe_button_box .oe_stat_button > div { +.openerp .oe_stat_button > div { display: table-cell; vertical-align: middle; text-align: left; padding: 0; line-height: 120%; } -.openerp .oe_button_box .oe_stat_button .stat_button_icon { +.openerp .oe_stat_button .stat_button_icon { color: #7c7bad; font-size: 24px; padding: 0px 3px; width: 37px; text-align: center; } -.openerp .oe_button_box .oe_stat_button svg { +.openerp .oe_stat_button .oe_form_field_percent_pie { + width: 42px; +} +.openerp .oe_stat_button .oe_form_field_bar_chart { + width: 42px; +} +.openerp .oe_stat_button svg { width: 38px; height: 38px; + display: inline; + vertical-align: middle; +} +.openerp .oe_stat_button:hover { + background: #7c7bad; + color: white; +} +.openerp .oe_stat_button:hover .fa { + color: white; +} +.openerp .oe_button_box { + width: 400px; + text-align: right; +} +.openerp .oe_button_box .oe_stat_button { + display: inline-table; } .openerp .oe_avatar > img { max-height: 90px; @@ -470,7 +480,7 @@ display: inline-block; height: 12px; width: 12px; - vertical-align: bottom; + vertical-align: top; border-radius: 10px; margin: 1px 0; } @@ -496,40 +506,6 @@ font-style: italic; text-decoration: none; } -.openerp.oe_tooltip { - font-size: 12px; -} -.openerp.oe_tooltip .oe_tooltip_string { - color: #ffdd55; - font-weight: bold; - font-size: 13px; -} -.openerp.oe_tooltip .oe_tooltip_help { - white-space: pre-wrap; -} -.openerp.oe_tooltip .oe_tooltip_technical { - padding: 0 0 4px 0; - margin: 5px 0 0 15px; -} -.openerp.oe_tooltip .oe_tooltip_technical li { - list-style: circle; -} -.openerp.oe_tooltip .oe_tooltip_technical_title { - font-weight: bold; -} -.openerp.oe_tooltip .oe_tooltip_close { - margin: -5px 0 0 2px; - cursor: default; - float: right; - color: white; -} -.openerp.oe_tooltip .oe_tooltip_close:hover { - color: #999999; - cursor: pointer; -} -.openerp.oe_tooltip .oe_tooltip_message { - max-width: 310px; -} .openerp .oe_notebook { margin: 8px 0; padding: 0 16px; @@ -746,7 +722,7 @@ border-bottom-left-radius: 8px; } .openerp .oe_notification { - z-index: 1050; + z-index: 1500; } .openerp .oe_webclient_timezone_notification a { color: white; @@ -1916,7 +1892,7 @@ .openerp .oe_form > :not(.oe_form_nosheet) header { padding-left: 2px; } -.openerp .oe_form > :not(.oe_form_nosheet) header ul { +.openerp .oe_form > :not(.oe_form_nosheet) header ul:not(.oe_tooltip_technical):not(.oe_dropdown_menu) { display: inline-block; float: right; } @@ -2772,9 +2748,11 @@ border: none; background: transparent; padding: 0; - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; +} +.openerp .oe_list_content > tbody > tr > td > button.btn_txt, .openerp .oe_list_content > tbody > tr > th > button.btn_txt { + border: 1px solid rgba(0, 0, 0, 0.4); + background: #e3e3e3; + padding: 3px 12px; } .openerp .oe_list_content > tbody > tr > td.oe_list_checkbox:first-child, .openerp .oe_list_content > tbody > tr th.oe_list_checkbox:first-child { width: 17px; @@ -3319,6 +3297,88 @@ body.oe_single_form .oe_single_form_container { overflow: hidden !important; } } +.tooltip { + padding: 0; + margin: 0; + font-family: "Lucida Grande", Helvetica, Verdana, Arial, sans-serif; + color: #4c4c4c; + font-size: 12px; + background: white; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5); + background-color: transparent; +} +.tooltip .tooltip-inner { + text-align: left !important; + max-width: 350px; +} +.tooltip .tooltip-inner .oe_tooltip_string { + color: #ffdd55; + font-weight: bold; + font-size: 13px; +} + +.tooltip .tooltip-inner .oe_tooltip_help { + white-space: pre-wrap; +} +.tooltip .tooltip-inner .oe_tooltip_technical { + padding: 0 0 4px 0; + margin: 5px 0 0 15px; +} +.tooltip .tooltip-inner .oe_tooltip_technical li { + list-style: circle; +} +.tooltip .tooltip-inner .oe_tooltip_technical_title { + font-weight: bold; +} +.tooltip .tooltip-inner .oe_tooltip_close { + margin: -5px 0 0 2px; + cursor: default; + float: right; + color: white; +} +.tooltip .tooltip-inner .oe_tooltip_close:hover { + color: #999999; + cursor: pointer; +} +.tooltip .tooltip-inner .oe_tooltip_message { + max-width: 310px; +} + +.ui-icon { + width: 18px; + height: 18px; +} + +.modal .modal-header button.close { + border: none; + background: none; + padding: 1px; + height: 18px; + font-size: 20px; +} +.modal .modal-footer { + text-align: left; +} +.modal .oe_button { + margin: 0 4px 0 0; +} +.modal .oe_act_window.modal-body { + padding: 0; +} + +.ui-datepicker { + z-index: 1500 !important; +} + +input[type="radio"], input[type="checkbox"] { + margin-right: 4px; + margin-left: 4px; +} + +.blockUI.blockOverlay { + background-color: black; + opacity: 0.6; +} .openerp .dropdown-menu.state { background: white; background: white !important; @@ -3330,7 +3390,6 @@ body.oe_single_form .oe_single_form_container { color: #333333; padding-left: 5px; padding-right: 0px; - font-size: 13px; } .openerp .btn-group.state { padding-top: 3px; @@ -3379,30 +3438,3 @@ body.oe_single_form .oe_single_form_container { float: left; margin-right: 8px; } - -.ui-icon { - width: 18px; - height: 18px; -} -.modal .modal-header button.close { - border: none; - background: none; - padding: 1px; - height: 18px; - font-size: 20px; -} -.modal .modal-footer { - text-align: left; -} -.modal .oe_act_window.modal-body{ - padding: 0; -} -input[type="radio"], input[type="checkbox"] { - margin-right: 4px; - margin-left: 4px; -} - -.blockUI.blockOverlay { - background-color: black; - opacity: 0.6; -} diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index 92fb4c0c289..a73bf027f59 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -190,7 +190,7 @@ $sheet-padding: 16px td vertical-align: top .oe_title - width: 50% + width: 38% float: left .oe_title:after content: "." @@ -330,41 +330,48 @@ $sheet-padding: 16px @include box-shadow(none) &:hover background: #ED6F6A + .oe_stat_button + font-weight: normal + width: 132px !important + height: 40px + color: #666 + margin: 0px -1px -1px 0px + padding: 0 + border: 1px solid #dddddd + border-radius: 0 + box-shadow: none + background: white + > div + display: table-cell + vertical-align: middle + text-align: left + padding: 0 + line-height: 120% + .stat_button_icon + color: #7C7BAD + font-size: 24px + padding: 0px 3px + width: 37px + text-align: center + .oe_form_field_percent_pie + width: 42px + .oe_form_field_bar_chart + width: 42px + svg + width: 38px + height: 38px + display: inline + vertical-align: middle + .oe_stat_button:hover + background: #7c7bad + color: white + .fa + color: white .oe_button_box width: 400px - text-align: left - .oe_stat_button:hover - background: #7c7bad - color: white - .fa - color: white + text-align: right .oe_stat_button - font-weight: normal display: inline-table - width: 33% !important - height: 42px - margin: 0px -1px -1px 0px - padding: 0 - color: #666 - border: 1px solid #dddddd - border-radius: 0 - box-shadow: none - background: white - > div - display: table-cell - vertical-align: middle - text-align: left - padding: 0 - line-height: 120% - .stat_button_icon - color: #7C7BAD - font-size: 24px - padding: 0px 3px - width: 37px - text-align: center - svg - width: 38px - height: 38px .oe_avatar > img max-height: 90px @@ -446,7 +453,7 @@ $sheet-padding: 16px display: inline-block height: 12px width: 12px - vertical-align: bottom + vertical-align: top border-radius: 10px margin: 1px 0 &.oe_form_invalid @@ -466,33 +473,6 @@ $sheet-padding: 16px text-decoration: none margin-bottom: 1px // }}} - // Tooltips {{{ - &.oe_tooltip - font-size: 12px - .oe_tooltip_string - color: #FD5 - font-weight: bold - font-size: 13px - .oe_tooltip_help - white-space: pre-wrap - .oe_tooltip_technical - padding: 0 0 4px 0 - margin: 5px 0 0 15px - li - list-style: circle - .oe_tooltip_technical_title - font-weight: bold - .oe_tooltip_close - margin: -5px 0 0 2px - cursor: default - float: right - color: white - &:hover - color: #999 - cursor: pointer - .oe_tooltip_message - max-width: 310px - // }}} // Notebook {{{ .oe_notebook margin: 8px 0 @@ -660,7 +640,8 @@ $sheet-padding: 16px // }}} // Notifications {{{ .oe_notification - z-index: 1050 + z-index: 1500 + .oe_webclient_timezone_notification a color: white @@ -1571,7 +1552,7 @@ $sheet-padding: 16px // FormView.header {{{ .oe_form > :not(.oe_form_nosheet) header padding-left: 2px - ul + ul:not(.oe_tooltip_technical):not(.oe_dropdown_menu) display: inline-block float: right .oe_button @@ -2245,7 +2226,10 @@ $sheet-padding: 16px border: none background: transparent padding: 0 - @include box-shadow(none) + > button.btn_txt + border: 1px solid rgba(0,0,0,0.4) + background: #e3e3e3 + padding: 3px 12px > td.oe_list_checkbox:first-child, th.oe_list_checkbox:first-child width: 17px &:after @@ -2697,6 +2681,76 @@ body.oe_single_form overflow: hidden !important // }}} +// End of customize + +// Customize bootstrap3 for tooltip +.tooltip + padding: 0 + margin: 0 + font-family: "Lucida Grande", Helvetica, Verdana, Arial, sans-serif + color: #4c4c4c + font-size: 12px + background: white + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5) + background-color: transparent + .tooltip-inner + text-align: left !important + max-width: 350px + .oe_tooltip_string + color: #FD5 + font-weight: bold + font-size: 13px + .oe_tooltip_help + white-space: pre-wrap + .oe_tooltip_technical + padding: 0 0 4px 0 + margin: 5px 0 0 15px + li + list-style: circle + .oe_tooltip_technical_title + font-weight: bold + .oe_tooltip_close + margin: -5px 0 0 2px + cursor: default + float: right + color: white + &:hover + color: #999 + cursor: pointer + .oe_tooltip_message + max-width: 310px + +// Hack for ui icon {{{ +.ui-icon + width: 18px + height: 18px +// End hack}}} + +// Customized modal according bootstrap3 +.modal + .modal-header button.close + border: none + background: none + padding: 1px + height: 18px + font-size: 20px + .modal-footer + text-align: left + .oe_button + margin: 0 4px 0 0 + .oe_act_window.modal-body + padding: 0 + +.ui-datepicker + z-index: 1500 !important + +input[type="radio"], input[type="checkbox"] + margin-right: 4px + margin-left: 4px + +.blockUI.blockOverlay + background-color: black + opacity: 0.6000000238418579 .openerp .dropdown-menu.state background: white @@ -2751,34 +2805,5 @@ body.oe_single_form .oe_star_left float: left margin-right: 8px -// End hack }}} - -// Hack for ui icon {{{ -.ui-icon - width: 18px - height: 18px -// End hack}}} - -// Customized modal according bootstrap3 -.modal - .modal-header button.close - border: none - background: none - padding: 1px - height: 18px - font-size: 20px - .modal-footer - text-align: left - .oe_act_window.modal-body - padding: 0 - -input[type="radio"], input[type="checkbox"] - margin-right: 4px - margin-left: 4px - -.blockUI.blockOverlay - background-color: black - opacity: 0.6000000238418579 - // 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/chrome.js b/addons/web/static/src/js/chrome.js index b3fbb35134b..4f12a915a7c 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -166,7 +166,7 @@ instance.web.Dialog = instance.web.Widget.extend({ $dialog_content.openerpClass(); this.$dialog_box.on('hidden.bs.modal', this, function(){ - self.trigger("closing"); + self.close(); }); this.$dialog_box.modal('show'); @@ -178,8 +178,11 @@ instance.web.Dialog = instance.web.Widget.extend({ Closes the popup, if destroy_on_close was passed to the constructor, it is also destroyed. */ close: function(reason) { - if (this.dialog_inited && this.$el.is(":data(bs.modal)")) { - this.$el.parents('.modal').modal('hide'); + if (this.dialog_inited) { + this.trigger("closing", reason); + if (this.$el.is(":data(bs.modal)")) { // may have been destroyed by closing signal + this.$el.parents('.modal').modal('hide'); + } } }, _closing: function() { @@ -209,8 +212,9 @@ instance.web.Dialog = instance.web.Widget.extend({ //we need this to put the instruction to remove modal from DOM at the end //of the queue, otherwise it might already have been removed before the modal-backdrop //is removed when pressing escape key + var $parent = this.$el.parents('.modal'); setTimeout(function () { - self.$el.parents('.modal').remove(); + $parent.remove(); },0); } this._super(); @@ -1074,8 +1078,8 @@ instance.web.Client = instance.web.Widget.extend({ }, bind_events: function() { var self = this; - this.$el.on('mouseenter', '.oe_systray > div:not([data-tipsy=true])', function() { - $(this).attr('data-tipsy', 'true').tipsy().trigger('mouseenter'); + this.$el.on('mouseenter', '.oe_systray > div:not([data-toggle=tooltip])', function() { + $(this).attr('data-toggle', 'tooltip').tooltip().trigger('mouseenter'); }); this.$el.on('click', '.oe_dropdown_toggle', function(ev) { ev.preventDefault(); @@ -1099,7 +1103,7 @@ instance.web.Client = instance.web.Widget.extend({ }, 0); }); instance.web.bus.on('click', this, function(ev) { - $.fn.tipsy.clear(); + $.fn.tooltip('destroy'); if (!$(ev.target).is('input[type=file]')) { self.$el.find('.oe_dropdown_menu.oe_opened, .oe_dropdown_toggle.oe_opened').removeClass('oe_opened'); } @@ -1453,7 +1457,7 @@ instance.web.embed = function (origin, dbname, login, key, action, options) { $('head').append($('', { 'rel': 'stylesheet', 'type': 'text/css', - 'href': origin +'/web/webclient/css' + 'href': origin +'/web/css/web.assets_webclient' })); var currentScript = document.currentScript; if (!currentScript) { diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 90c84ba9cda..29f6c3e4d9e 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -232,7 +232,7 @@ instance.web.Session.include( /** @lends instance.web.Session# */{ var self = this; return this.session_reload().then(function(result) { var modules = instance._modules.join(','); - var deferred = self.rpc('/web/webclient/qweblist', {mods: modules}).then(self.load_qweb.bind(self)); + var deferred = self.load_qweb(modules); if(self.session_is_valid()) { return deferred.then(function() { return self.load_modules(); }); } @@ -318,7 +318,7 @@ instance.web.Session.include( /** @lends instance.web.Session# */{ loaded = $.when( loaded, self.rpc('/web/webclient/csslist', {mods: to_load}).done(self.load_css.bind(self)), - self.rpc('/web/webclient/qweblist', {mods: to_load}).then(self.load_qweb.bind(self)), + self.load_qweb(to_load), self.rpc('/web/webclient/jslist', {mods: to_load}).done(function(files) { file_list = file_list.concat(files); }) @@ -345,44 +345,27 @@ instance.web.Session.include( /** @lends instance.web.Session# */{ load_css: function (files) { var self = this; _.each(files, function (file) { - $('head').append($('', { - 'href': self.url(file, null), - 'rel': 'stylesheet', - 'type': 'text/css' - })); + openerp.loadCSS(self.url(file, null)); }); }, 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.url(file, null); - tag.onload = tag.onreadystatechange = function() { - if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done ) - return; - tag.onload_done = true; - self.load_js(files).done(function () { - d.resolve(); - }); - }; - var head = document.head || document.getElementsByTagName('head')[0]; - head.appendChild(tag); + var url = self.url(file, null); + openerp.loadJS(url).done(d.resolve); } else { d.resolve(); } return d; }, - load_qweb: function(files) { + load_qweb: function(mods) { var self = this; - _.each(files, function(file) { - self.qweb_mutex.exec(function() { - return self.rpc('/web/proxy/load', {path: file}).then(function(xml) { - if (!xml) { return; } - instance.web.qweb.add_template(_.str.trim(xml)); - }); + self.qweb_mutex.exec(function() { + return self.rpc('/web/proxy/load', {path: '/web/webclient/qweb?mods=' + mods}).then(function(xml) { + if (!xml) { return; } + instance.web.qweb.add_template(_.str.trim(xml)); }); }); return self.qweb_mutex.def; @@ -460,14 +443,11 @@ instance.web.Session.include( /** @lends instance.web.Session# */{ .appendTo(document.body) .load(function () { try { - if (options.error) { - if (!this.contentDocument.body.childNodes[1]) { - options.error(this.contentDocument.body.childNodes); - } - else { - options.error(JSON.parse(this.contentDocument.body.childNodes[1].textContent)); - } - } + if (options.error) { + var body = this.contentDocument.body; + var node = body.childNodes[1] || body.childNodes[0]; + options.error(JSON.parse(node.textContent)); + } } finally { complete(); } @@ -788,6 +768,22 @@ instance.web.unblockUI = function() { return $.unblockUI.apply($, arguments); }; + +/* Bootstrap defaults overwrite */ +$.fn.tooltip.Constructor.DEFAULTS.placement = 'auto top'; +$.fn.tooltip.Constructor.DEFAULTS.html = true; +$.fn.tooltip.Constructor.DEFAULTS.container = 'body'; +//overwrite bootstrap tooltip method to fix bug when using placement +//auto and the parent element does not exist anymore resulting in +//an error. This should be remove once bootstrap fix the bug +var bootstrap_show_function = $.fn.tooltip.Constructor.prototype.show; +$.fn.tooltip.Constructor.prototype.show = function (e) { + if (this.$element.parent().length === 0){ + return; + } + return bootstrap_show_function.call(this, e); +}; + /** * Registry for all the client actions key: tag value: widget */ diff --git a/addons/web/static/src/js/data_export.js b/addons/web/static/src/js/data_export.js index 2de933f45e8..2f7ff81d089 100644 --- a/addons/web/static/src/js/data_export.js +++ b/addons/web/static/src/js/data_export.js @@ -32,7 +32,7 @@ instance.web.DataExport = instance.web.Dialog.extend({ var self = this; var options = { buttons: [ - {text: _t("Close"), click: function () { self.close(); }}, + {text: _t("Close"), click: function () { self.$el.parents('.modal').modal('hide'); }}, {text: _t("Export To File"), click: function () { self.on_click_export_data(); }} ], close: function () { self.close();} diff --git a/addons/web/static/src/js/openerpframework.js b/addons/web/static/src/js/openerpframework.js index 5dcc2197944..f190fefeba3 100644 --- a/addons/web/static/src/js/openerpframework.js +++ b/addons/web/static/src/js/openerpframework.js @@ -933,6 +933,46 @@ openerp.jsonpRpc = function(url, fct_name, params, settings) { }); }; +openerp.loadCSS = function (url) { + if (!$('link[href="' + url + '"]').length) { + $('head').append($('', { + 'href': url, + 'rel': 'stylesheet', + 'type': 'text/css' + })); + } +}; +openerp.loadJS = function (url) { + var def = $.Deferred(); + if ($('script[src="' + url + '"]').length) { + def.resolve(); + } else { + var script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = url; + script.onload = script.onreadystatechange = function() { + if ((script.readyState && script.readyState != "loaded" && script.readyState != "complete") || script.onload_done) { + return; + } + script.onload_done = true; + def.resolve(url); + }; + script.onerror = function () { + console.error("Error loading file", script.src); + def.reject(url); + }; + var head = document.head || document.getElementsByTagName('head')[0]; + head.appendChild(script); + } + return def; +}; +openerp.loadBundle = function (name) { + return $.when( + openerp.loadCSS('/web/css/' + name), + openerp.loadJS('/web/js/' + name) + ); +}; + var realSetTimeout = function(fct, millis) { var finished = new Date().getTime() + millis; var wait = function() { diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 04bb1a61d99..832faa4ca62 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -29,8 +29,8 @@ my.Facet = B.Model.extend({ B.Model.prototype.initialize.apply(this, arguments); this.values = new my.FacetValues(values || []); - this.values.on('add remove change reset', function () { - this.trigger('change', this); + this.values.on('add remove change reset', function (_, options) { + this.trigger('change', this, options); }, this); }, get: function (key) { @@ -399,7 +399,8 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea this.setup_global_completion(); this.query = new my.SearchQuery() .on('add change reset remove', this.proxy('do_search')) - .on('add change reset remove', this.proxy('renderFacets')); + .on('change', this.proxy('renderChangedFacets')) + .on('add reset remove', this.proxy('renderFacets')); if (this.options.hidden) { this.$el.hide(); @@ -578,14 +579,20 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea .trigger('blur'); }, /** - * - * @param {openerp.web.search.SearchQuery | openerp.web.search.Facet} _1 - * @param {openerp.web.search.Facet} [_2] + * Call the renderFacets method with the correct arguments. + * This is due to the fact that change events are called with two arguments + * (model, options) while add, reset and remove events are called with + * (collection, model, options) as arguments + */ + renderChangedFacets: function (model, options) { + this.renderFacets(undefined, model, options); + }, + /** + * @param {openerp.web.search.SearchQuery | undefined} Undefined if event is change + * @param {openerp.web.search.Facet} * @param {Object} [options] */ - renderFacets: function (_1, _2, options) { - // _1: model if event=change, otherwise collection - // _2: undefined if event=change, otherwise model + renderFacets: function (collection, model, options) { var self = this; var started = []; var $e = this.$('div.oe_searchview_facets'); @@ -610,6 +617,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea }); $.when.apply(null, started).then(function () { + if (options && options.focus_input === false) return; var input_to_focus; // options.at: facet inserted at given index, focus next input // otherwise just focus last input @@ -618,7 +626,6 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea } else { input_to_focus = self.input_subviews[(options.at + 1) * 2]; } - input_to_focus.$el.focus(); }); }, @@ -1602,8 +1609,11 @@ instance.web.search.ManyToOneField = instance.web.search.CharField.extend({ return facetValue.get('label'); }, make_domain: function (name, operator, facetValue) { - if (operator === this.default_operator) { + switch(operator){ + case this.default_operator: return [[name, '=', facetValue.get('value')]]; + case 'child_of': + return [[name, 'child_of', facetValue.get('value')]]; } return this._super(name, operator, facetValue); }, diff --git a/addons/web/static/src/js/testing.js b/addons/web/static/src/js/testing.js index 1f1c718ad5f..5e9483addc1 100644 --- a/addons/web/static/src/js/testing.js +++ b/addons/web/static/src/js/testing.js @@ -48,15 +48,6 @@ openerp.testing = {}; 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 */ @@ -206,7 +197,7 @@ openerp.testing = {}; teardown: testing.noop }); - QUnit.module(testing.current_module + '.' + name, {_oe: options}); + QUnit.module(name, {_oe: options}); body(testing['case']); }; testing['case'] = function (name, options, callback) { @@ -244,18 +235,6 @@ openerp.testing = {}; expect(opts.asserts); } - if (opts.templates) { - for(var i=0; i 0){ + container = $(trigger).parents('.oe_view_manager_view_form'); + } + else { + if (window.$('.modal.in').length>0){ + container = window.$('.modal.in:last()'); + } + } options = _.extend({ - delayIn: 500, - delayOut: 0, - fade: true, + delay: { show: 500, hide: 0 }, + trigger: 'hover', + container: container, title: function() { var template = widget.template + '.tooltip'; if (!QWeb.has_template(template)) { @@ -1877,12 +1898,12 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi widget: widget }); }, - gravity: $.fn.tipsy.autoBounds(50, 'nw'), - html: true, - opacity: 0.85, - trigger: 'hover' }, options || {}); - $(trigger).tipsy(options); + //only show tooltip if we are in debug or if we have a help to show, otherwise it will display + //as empty + if (instance.session.debug || widget.node.attrs.help || (widget.field && widget.field.help)){ + $(trigger).tooltip(options); + } }, /** * Builds a new context usable for operations related to fields by merging @@ -1919,7 +1940,7 @@ instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({ init: function(field_manager, node) { node.attrs.type = node.attrs['data-button-type']; this.is_stat_button = /\boe_stat_button\b/.test(node.attrs['class']); - this.icon = node.attrs.icon && ""; + this.icon_class = node.attrs.icon && "stat_button_icon fa " + node.attrs.icon + " fa-fw"; this._super(field_manager, node); this.force_disabled = false; this.string = (this.node.attrs.string || '').replace(/_/g, ''); @@ -1955,7 +1976,7 @@ instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({ var exec_action = function() { if (self.node.attrs.confirm) { var def = $.Deferred(); - var dialog = instance.web.Dialog(this, { + var dialog = new instance.web.Dialog(this, { title: _t('Confirm'), buttons: [ {text: _t("Cancel"), click: function() { @@ -2119,8 +2140,8 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w this.$el.find('.oe_field_translate').click(this.on_translate); } this.$label = this.view ? this.view.$el.find('label[for=' + this.id_for_label + ']') : $(); + this.do_attach_tooltip(this, this.$label[0] || this.$el); if (instance.session.debug) { - this.do_attach_tooltip(this, this.$label[0] || this.$el); this.$label.off('dblclick').on('dblclick', function() { console.log("Field '%s' of type '%s' in View: %o", self.name, (self.node.attrs.widget || self.field.type), self.view); window.w = self; @@ -2535,6 +2556,76 @@ instance.web.form.FieldFloat = instance.web.form.FieldChar.extend({ } }); +instance.web.form.FieldCharDomain = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, { + init: function(field_manager, node) { + this._super.apply(this, arguments); + }, + start: function() { + var self = this; + this._super.apply(this, arguments); + this.on("change:effective_readonly", this, function () { + this.display_field(); + this.render_value(); + }); + this.display_field(); + return this._super(); + }, + render_value: function() { + this.$('button.select_records').css('visibility', this.get('effective_readonly') ? 'hidden': ''); + }, + set_value: function(value_) { + var self = this; + this.set('value', value_ || false); + this.display_field(); + }, + display_field: function() { + var self = this; + this.$el.html(instance.web.qweb.render("FieldCharDomain", {widget: this})); + if (this.get('value')) { + var model = this.options.model || this.field_manager.get_field_value(this.options.model_field); + var domain = instance.web.pyeval.eval('domain', this.get('value')); + var ds = new instance.web.DataSetStatic(self, model, self.build_context()); + ds.call('search_count', [domain]).then(function (results) { + $('.oe_domain_count', self.$el).text(results + ' records selected'); + $('button span', self.$el).text(' Change selection'); + }); + } else { + $('.oe_domain_count', this.$el).text('0 record selected'); + $('button span', this.$el).text(' Select records'); + }; + this.$('.select_records').on('click', self.on_click); + }, + on_click: function(ev) { + var self = this; + var model = this.options.model || this.field_manager.get_field_value(this.options.model_field); + this.pop = new instance.web.form.SelectCreatePopup(this); + this.pop.select_element( + model, {title: 'Select records...'}, + [], this.build_context()); + this.pop.on("elements_selected", self, function(element_ids) { + if (this.pop.$('input.oe_list_record_selector').prop('checked')) { + var search_data = this.pop.searchview.build_search_data(); + var domain_done = instance.web.pyeval.eval_domains_and_contexts({ + domains: search_data.domains, + contexts: search_data.contexts, + group_by_seq: search_data.groupbys || [] + }).then(function (results) { + return results.domain; + }); + } + else { + var domain = ["id", "in", element_ids]; + var domain_done = $.Deferred().resolve(domain); + } + $.when(domain_done).then(function (domain) { + var domain = self.pop.dataset.domain.concat(domain || []); + self.set_value(JSON.stringify(domain)) + }); + }); + event.preventDefault(); + }, +}); + instance.web.DateTimeWidget = instance.web.Widget.extend({ template: "web.datepicker", jqueryui_object: 'datetimepicker', @@ -2930,10 +3021,10 @@ instance.web.form.FieldPercentPie = instance.web.form.AbstractField.extend({ svg.innerHTML = ""; nv.addGraph(function() { - var size=43; + var width = 42, height = 42; var chart = nv.models.pieChart() - .width(size) - .height(size) + .width(width) + .height(height) .margin({top: 0, right: 0, bottom: 0, left: 0}) .donut(true) .showLegend(false) @@ -2946,11 +3037,11 @@ instance.web.form.FieldPercentPie = instance.web.form.AbstractField.extend({ .datum([{'x': 'value', 'y': value}, {'x': 'complement', 'y': 100 - value}]) .transition() .call(chart) - .attr({width:size, height:size}); + .attr('style', 'width: ' + width + 'px; height:' + height + 'px;'); d3.select(svg) .append("text") - .attr({x: size/2, y: size/2 + 3, 'text-anchor': 'middle'}) + .attr({x: width/2, y: height/2 + 3, 'text-anchor': 'middle'}) .style({"font-size": "10px", "font-weight": "bold"}) .text(formatted_value); @@ -2960,6 +3051,43 @@ instance.web.form.FieldPercentPie = instance.web.form.AbstractField.extend({ } }); +/** + The FieldBarChart expectsa list of values (indeed) +*/ +instance.web.form.FieldBarChart = instance.web.form.AbstractField.extend({ + template: 'FieldBarChart', + + render_value: function() { + var value = JSON.parse(this.get('value')); + var svg = this.$('svg')[0]; + svg.innerHTML = ""; + nv.addGraph(function() { + var width = 34, height = 34; + var chart = nv.models.discreteBarChart() + .x(function (d) { return d.tooltip }) + .y(function (d) { return d.value }) + .width(width) + .height(height) + .margin({top: 0, right: 0, bottom: 0, left: 0}) + .tooltips(false) + .showValues(false) + .transitionDuration(350) + .showXAxis(false) + .showYAxis(false); + + d3.select(svg) + .datum([{key: 'values', values: value}]) + .transition() + .call(chart) + .attr('style', 'width: ' + (width + 4) + 'px; height: ' + (height + 8) + 'px;'); + + nv.utils.windowResize(chart.update); + + return chart; + }); + + } +}); instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, { @@ -3328,13 +3456,16 @@ instance.web.form.CompletionFieldMixin = { instance.web.form.M2ODialog = instance.web.Dialog.extend({ template: "M2ODialog", init: function(parent) { + this.name = parent.string; this._super(parent, { - title: _.str.sprintf(_t("Add %s"), parent.string), + title: _.str.sprintf(_t("Create a %s"), parent.string), size: 'medium', }); }, start: function() { var self = this; + var text = _.str.sprintf(_t("You are creating a new %s, are you sure it does not exist yet?"), self.name); + this.$("p").text( text ); this.$buttons.html(QWeb.render("M2ODialog.buttons")); this.$("input").val(this.getParent().last_query); this.$buttons.find(".oe_form_m2o_qc_button").click(function(){ @@ -3441,20 +3572,25 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc return; } var pop = new instance.web.form.FormOpenPopup(self); - pop.show_element( - self.field.relation, - self.get("value"), - self.build_context(), - { - title: _t("Open: ") + self.string - } - ); - pop.on('write_completed', self, function(){ - self.display_value = {}; - self.display_value_backup = {}; - self.render_value(); - self.focus(); - self.view.do_onchange(self); + var context = self.build_context().eval(); + var model_obj = new instance.web.Model(self.field.relation); + model_obj.call('get_formview_id', [self.get("value"), context]).then(function(view_id){ + pop.show_element( + self.field.relation, + self.get("value"), + self.build_context(), + { + title: _t("Open: ") + self.string, + view_id: view_id + } + ); + pop.on('write_completed', self, function(){ + self.display_value = {}; + self.display_value_backup = {}; + self.render_value(); + self.focus(); + self.trigger('changed_value'); + }); }); }); @@ -3516,7 +3652,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc } self.floating = false; } - if (used && self.get("value") === false && ! self.no_ed) { + if (used && self.get("value") === false && ! self.no_ed && (self.options.no_create === false || self.options.no_create === undefined)) { self.ed_def.reject(); self.uned_def.reject(); self.ed_def = $.Deferred(); @@ -3588,6 +3724,8 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc minLength: 0, delay: 250 }); + // set position for list of suggestions box + this.$input.autocomplete( "option", "position", { my : "left top", at: "left bottom" } ); 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) { @@ -3650,13 +3788,10 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc .html(link); if (! this.options.no_open) $link.click(function () { - self.do_action({ - type: 'ir.actions.act_window', - res_model: self.field.relation, - res_id: self.get("value"), - views: [[false, 'form']], - target: 'current', - context: self.build_context().eval(), + var context = self.build_context().eval(); + var model_obj = new instance.web.Model(self.field.relation); + model_obj.call('get_formview_action', [self.get("value"), context]).then(function(action){ + self.do_action(action); }); return false; }); @@ -6016,20 +6151,30 @@ instance.web.form.X2ManyCounter = instance.web.form.AbstractField.extend(instanc display a simple string "