[FIX] hide context menu. merge latest trunk.
bzr revid: vda@tinyerp.com-20111024101015-19l1vhvcvfiiwkkq
|
@ -9,4 +9,3 @@ RE:^include/
|
||||||
RE:^share/
|
RE:^share/
|
||||||
RE:^man/
|
RE:^man/
|
||||||
RE:^lib/
|
RE:^lib/
|
||||||
logging.cfg
|
|
||||||
|
|
|
@ -1,28 +1,26 @@
|
||||||
import common
|
import common
|
||||||
import controllers
|
import controllers
|
||||||
import common.dispatch
|
|
||||||
import logging
|
import logging
|
||||||
|
import optparse
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class Options(object):
|
||||||
|
pass
|
||||||
|
|
||||||
def wsgi_postload():
|
def wsgi_postload():
|
||||||
import openerp.wsgi
|
import openerp
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
_logger.info("embedded mode")
|
_logger.info("embedded mode")
|
||||||
class Options(object):
|
|
||||||
pass
|
|
||||||
o = Options()
|
o = Options()
|
||||||
o.dbfilter = '.*'
|
o.dbfilter = openerp.tools.config['dbfilter']
|
||||||
|
o.server_wide_modules = openerp.conf.server_wide_modules or ['web']
|
||||||
o.session_storage = os.path.join(tempfile.gettempdir(), "oe-sessions")
|
o.session_storage = os.path.join(tempfile.gettempdir(), "oe-sessions")
|
||||||
o.addons_path = os.path.dirname(os.path.dirname(__file__))
|
o.addons_path = openerp.modules.module.ad_paths
|
||||||
o.serve_static = True
|
o.serve_static = True
|
||||||
o.backend = 'local'
|
o.backend = 'local'
|
||||||
|
|
||||||
app = common.dispatch.Root(o)
|
app = common.http.Root(o)
|
||||||
#import openerp.wsgi
|
|
||||||
openerp.wsgi.register_wsgi_handler(app)
|
openerp.wsgi.register_wsgi_handler(app)
|
||||||
|
|
||||||
# TODO
|
|
||||||
# if we detect that we are imported from the openerp server register common.Root() as a wsgi entry point
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
{
|
{
|
||||||
"name" : "web",
|
"name" : "web",
|
||||||
|
"category" : "Hidden",
|
||||||
"depends" : [],
|
"depends" : [],
|
||||||
'active': True,
|
'active': True,
|
||||||
|
'post_load' : 'wsgi_postload',
|
||||||
'js' : [
|
'js' : [
|
||||||
"static/lib/datejs/globalization/en-US.js",
|
"static/lib/datejs/globalization/en-US.js",
|
||||||
"static/lib/datejs/core.js",
|
"static/lib/datejs/core.js",
|
||||||
|
@ -19,11 +21,13 @@
|
||||||
"static/lib/jquery.ui/js/jquery-ui-1.8.9.custom.min.js",
|
"static/lib/jquery.ui/js/jquery-ui-1.8.9.custom.min.js",
|
||||||
"static/lib/jquery.ui/js/jquery-ui-timepicker-addon.js",
|
"static/lib/jquery.ui/js/jquery-ui-timepicker-addon.js",
|
||||||
"static/lib/jquery.ui.notify/js/jquery.notify.js",
|
"static/lib/jquery.ui.notify/js/jquery.notify.js",
|
||||||
|
"static/lib/jquery.deferred-queue/jquery.deferred-queue.js",
|
||||||
"static/lib/json/json2.js",
|
"static/lib/json/json2.js",
|
||||||
"static/lib/qweb/qweb2.js",
|
"static/lib/qweb/qweb2.js",
|
||||||
"static/lib/underscore/underscore.js",
|
"static/lib/underscore/underscore.js",
|
||||||
"static/lib/underscore/underscore.string.js",
|
"static/lib/underscore/underscore.string.js",
|
||||||
"static/lib/labjs/LAB.src.js",
|
"static/lib/labjs/LAB.src.js",
|
||||||
|
"static/lib/py.parse/lib/py.js",
|
||||||
"static/src/js/boot.js",
|
"static/src/js/boot.js",
|
||||||
"static/src/js/core.js",
|
"static/src/js/core.js",
|
||||||
"static/src/js/dates.js",
|
"static/src/js/dates.js",
|
||||||
|
@ -32,6 +36,7 @@
|
||||||
"static/src/js/views.js",
|
"static/src/js/views.js",
|
||||||
"static/src/js/data.js",
|
"static/src/js/data.js",
|
||||||
"static/src/js/data_export.js",
|
"static/src/js/data_export.js",
|
||||||
|
"static/src/js/data_import.js",
|
||||||
"static/src/js/search.js",
|
"static/src/js/search.js",
|
||||||
"static/src/js/view_form.js",
|
"static/src/js/view_form.js",
|
||||||
"static/src/js/view_list.js",
|
"static/src/js/view_list.js",
|
||||||
|
@ -44,6 +49,6 @@
|
||||||
"static/lib/jquery.ui.notify/css/ui.notify.css",
|
"static/lib/jquery.ui.notify/css/ui.notify.css",
|
||||||
"static/src/css/base.css",
|
"static/src/css/base.css",
|
||||||
"static/src/css/data_export.css",
|
"static/src/css/data_export.css",
|
||||||
|
"static/src/css/data_import.css",
|
||||||
],
|
],
|
||||||
'post_load' : 'wsgi_postload',
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,6 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
from dispatch import *
|
import http
|
||||||
|
import nonliterals
|
||||||
|
import release
|
||||||
|
import session
|
||||||
|
import xml2json
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
""" Backport of Python 2.6's ast.py for Python 2.5
|
|
||||||
"""
|
|
||||||
__all__ = ['literal_eval']
|
|
||||||
try:
|
|
||||||
from ast import literal_eval
|
|
||||||
except ImportError:
|
|
||||||
from _ast import *
|
|
||||||
from _ast import __version__
|
|
||||||
|
|
||||||
|
|
||||||
def parse(expr, filename='<unknown>', mode='exec'):
|
|
||||||
"""
|
|
||||||
Parse an expression into an AST node.
|
|
||||||
Equivalent to compile(expr, filename, mode, PyCF_ONLY_AST).
|
|
||||||
"""
|
|
||||||
return compile(expr, filename, mode, PyCF_ONLY_AST)
|
|
||||||
|
|
||||||
|
|
||||||
def literal_eval(node_or_string):
|
|
||||||
"""
|
|
||||||
Safely evaluate an expression node or a string containing a Python
|
|
||||||
expression. The string or node provided may only consist of the
|
|
||||||
following Python literal structures: strings, numbers, tuples, lists,
|
|
||||||
dicts, booleans, and None.
|
|
||||||
"""
|
|
||||||
_safe_names = {'None': None, 'True': True, 'False': False}
|
|
||||||
if isinstance(node_or_string, basestring):
|
|
||||||
node_or_string = parse(node_or_string, mode='eval')
|
|
||||||
if isinstance(node_or_string, Expression):
|
|
||||||
node_or_string = node_or_string.body
|
|
||||||
def _convert(node):
|
|
||||||
if isinstance(node, Str):
|
|
||||||
return node.s
|
|
||||||
elif isinstance(node, Num):
|
|
||||||
return node.n
|
|
||||||
elif isinstance(node, Tuple):
|
|
||||||
return tuple(map(_convert, node.elts))
|
|
||||||
elif isinstance(node, List):
|
|
||||||
return list(map(_convert, node.elts))
|
|
||||||
elif isinstance(node, Dict):
|
|
||||||
return dict((_convert(k), _convert(v)) for k, v
|
|
||||||
in zip(node.keys, node.values))
|
|
||||||
elif isinstance(node, Name):
|
|
||||||
if node.id in _safe_names:
|
|
||||||
return _safe_names[node.id]
|
|
||||||
raise ValueError('malformed string')
|
|
||||||
return _convert(node_or_string)
|
|
|
@ -1,88 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# OpenERP, Open Source Management Solution
|
|
||||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
|
||||||
# Copyright (C) 2010 OpenERP s.a. (<http://openerp.com>).
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero General Public License as
|
|
||||||
# published by the Free Software Foundation, either version 3 of the
|
|
||||||
# License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU Affero General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
DEFAULT_SERVER_DATE_FORMAT = "%Y-%m-%d"
|
|
||||||
DEFAULT_SERVER_TIME_FORMAT = "%H:%M:%S"
|
|
||||||
DEFAULT_SERVER_DATETIME_FORMAT = "%s %s" % (
|
|
||||||
DEFAULT_SERVER_DATE_FORMAT,
|
|
||||||
DEFAULT_SERVER_TIME_FORMAT)
|
|
||||||
|
|
||||||
def str_to_datetime(str):
|
|
||||||
"""
|
|
||||||
Converts a string to a datetime object using OpenERP's
|
|
||||||
datetime string format (exemple: '2011-12-01 15:12:35').
|
|
||||||
|
|
||||||
No timezone information is added, the datetime is a naive instance, but
|
|
||||||
according to OpenERP 6.1 specification the timezone is always UTC.
|
|
||||||
"""
|
|
||||||
if not str:
|
|
||||||
return str
|
|
||||||
return datetime.datetime.strptime(str, DEFAULT_SERVER_DATETIME_FORMAT)
|
|
||||||
|
|
||||||
def str_to_date(str):
|
|
||||||
"""
|
|
||||||
Converts a string to a date object using OpenERP's
|
|
||||||
date string format (exemple: '2011-12-01').
|
|
||||||
"""
|
|
||||||
if not str:
|
|
||||||
return str
|
|
||||||
return datetime.datetime.strptime(str, DEFAULT_SERVER_DATE_FORMAT).date()
|
|
||||||
|
|
||||||
def str_to_time(str):
|
|
||||||
"""
|
|
||||||
Converts a string to a time object using OpenERP's
|
|
||||||
time string format (exemple: '15:12:35').
|
|
||||||
"""
|
|
||||||
if not str:
|
|
||||||
return str
|
|
||||||
return datetime.datetime.strptime(str, DEFAULT_SERVER_TIME_FORMAT).time()
|
|
||||||
|
|
||||||
def datetime_to_str(obj):
|
|
||||||
"""
|
|
||||||
Converts a datetime object to a string using OpenERP's
|
|
||||||
datetime string format (exemple: '2011-12-01 15:12:35').
|
|
||||||
|
|
||||||
The datetime instance should not have an attached timezone and be in UTC.
|
|
||||||
"""
|
|
||||||
if not obj:
|
|
||||||
return False
|
|
||||||
return obj.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
|
||||||
|
|
||||||
def date_to_str(obj):
|
|
||||||
"""
|
|
||||||
Converts a date object to a string using OpenERP's
|
|
||||||
date string format (exemple: '2011-12-01').
|
|
||||||
"""
|
|
||||||
if not obj:
|
|
||||||
return False
|
|
||||||
return obj.strftime(DEFAULT_SERVER_DATE_FORMAT)
|
|
||||||
|
|
||||||
def time_to_str(obj):
|
|
||||||
"""
|
|
||||||
Converts a time object to a string using OpenERP's
|
|
||||||
time string format (exemple: '15:12:35').
|
|
||||||
"""
|
|
||||||
if not obj:
|
|
||||||
return False
|
|
||||||
return obj.strftime(DEFAULT_SERVER_TIME_FORMAT)
|
|
|
@ -1,429 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
from __future__ import with_statement
|
|
||||||
|
|
||||||
import functools
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import pprint
|
|
||||||
import sys
|
|
||||||
import traceback
|
|
||||||
import uuid
|
|
||||||
import xmlrpclib
|
|
||||||
|
|
||||||
import simplejson
|
|
||||||
import werkzeug.datastructures
|
|
||||||
import werkzeug.exceptions
|
|
||||||
import werkzeug.urls
|
|
||||||
import werkzeug.utils
|
|
||||||
import werkzeug.wrappers
|
|
||||||
import werkzeug.wsgi
|
|
||||||
|
|
||||||
import ast
|
|
||||||
import nonliterals
|
|
||||||
import http
|
|
||||||
# import backendlocal as backend
|
|
||||||
import session as backend
|
|
||||||
import openerplib
|
|
||||||
|
|
||||||
__all__ = ['Root', 'jsonrequest', 'httprequest', 'Controller',
|
|
||||||
'WebRequest', 'JsonRequest', 'HttpRequest']
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
#-----------------------------------------------------------
|
|
||||||
# Globals (wont move into a pool)
|
|
||||||
#-----------------------------------------------------------
|
|
||||||
|
|
||||||
applicationsession = {}
|
|
||||||
addons_module = {}
|
|
||||||
addons_manifest = {}
|
|
||||||
controllers_class = {}
|
|
||||||
controllers_object = {}
|
|
||||||
controllers_path = {}
|
|
||||||
|
|
||||||
#----------------------------------------------------------
|
|
||||||
# OpenERP Web RequestHandler
|
|
||||||
#----------------------------------------------------------
|
|
||||||
class WebRequest(object):
|
|
||||||
""" Parent class for all OpenERP Web request types, mostly deals with
|
|
||||||
initialization and setup of the request object (the dispatching itself has
|
|
||||||
to be handled by the subclasses)
|
|
||||||
|
|
||||||
:param request: a wrapped werkzeug Request object
|
|
||||||
:type request: :class:`werkzeug.wrappers.BaseRequest`
|
|
||||||
:param config: configuration object
|
|
||||||
|
|
||||||
.. attribute:: applicationsession
|
|
||||||
|
|
||||||
an application-wide :class:`~collections.Mapping`
|
|
||||||
|
|
||||||
.. attribute:: httprequest
|
|
||||||
|
|
||||||
the original :class:`werkzeug.wrappers.Request` object provided to the
|
|
||||||
request
|
|
||||||
|
|
||||||
.. attribute:: httpsession
|
|
||||||
|
|
||||||
a :class:`~collections.Mapping` holding the HTTP session data for the
|
|
||||||
current http session
|
|
||||||
|
|
||||||
.. attribute:: config
|
|
||||||
|
|
||||||
config parameter provided to the request object
|
|
||||||
|
|
||||||
.. attribute:: params
|
|
||||||
|
|
||||||
:class:`~collections.Mapping` of request parameters, not generally
|
|
||||||
useful as they're provided directly to the handler method as keyword
|
|
||||||
arguments
|
|
||||||
|
|
||||||
.. attribute:: session_id
|
|
||||||
|
|
||||||
opaque identifier for the :class:`backend.OpenERPSession` instance of
|
|
||||||
the current request
|
|
||||||
|
|
||||||
.. attribute:: session
|
|
||||||
|
|
||||||
:class:`~backend.OpenERPSession` instance for the current request
|
|
||||||
|
|
||||||
.. attribute:: context
|
|
||||||
|
|
||||||
:class:`~collections.Mapping` of context values for the current request
|
|
||||||
|
|
||||||
.. attribute:: debug
|
|
||||||
|
|
||||||
``bool``, indicates whether the debug mode is active on the client
|
|
||||||
"""
|
|
||||||
def __init__(self, request, config):
|
|
||||||
self.applicationsession = applicationsession
|
|
||||||
self.httprequest = request
|
|
||||||
self.httpresponse = None
|
|
||||||
self.httpsession = request.session
|
|
||||||
self.config = config
|
|
||||||
def init(self, params):
|
|
||||||
self.params = dict(params)
|
|
||||||
# OpenERP session setup
|
|
||||||
self.session_id = self.params.pop("session_id", None) or uuid.uuid4().hex
|
|
||||||
self.session = self.httpsession.setdefault(
|
|
||||||
self.session_id, backend.OpenERPSession(
|
|
||||||
self.config.server_host, self.config.server_port))
|
|
||||||
self.context = self.params.pop('context', None)
|
|
||||||
self.debug = self.params.pop('debug', False) != False
|
|
||||||
|
|
||||||
class JsonRequest(WebRequest):
|
|
||||||
""" JSON-RPC2 over HTTP.
|
|
||||||
|
|
||||||
Sucessful request::
|
|
||||||
|
|
||||||
--> {"jsonrpc": "2.0",
|
|
||||||
"method": "call",
|
|
||||||
"params": {"session_id": "SID",
|
|
||||||
"context": {},
|
|
||||||
"arg1": "val1" },
|
|
||||||
"id": null}
|
|
||||||
|
|
||||||
<-- {"jsonrpc": "2.0",
|
|
||||||
"result": { "res1": "val1" },
|
|
||||||
"id": null}
|
|
||||||
|
|
||||||
Request producing a error::
|
|
||||||
|
|
||||||
--> {"jsonrpc": "2.0",
|
|
||||||
"method": "call",
|
|
||||||
"params": {"session_id": "SID",
|
|
||||||
"context": {},
|
|
||||||
"arg1": "val1" },
|
|
||||||
"id": null}
|
|
||||||
|
|
||||||
<-- {"jsonrpc": "2.0",
|
|
||||||
"error": {"code": 1,
|
|
||||||
"message": "End user error message.",
|
|
||||||
"data": {"code": "codestring",
|
|
||||||
"debug": "traceback" } },
|
|
||||||
"id": null}
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
def dispatch(self, controller, method, requestf=None, request=None):
|
|
||||||
""" Calls the method asked for by the JSON-RPC2 request
|
|
||||||
|
|
||||||
:param controller: the instance of the controller which received the request
|
|
||||||
:param method: the method which received the request
|
|
||||||
:param requestf: a file-like object containing an encoded JSON-RPC2 request
|
|
||||||
:param request: a JSON-RPC2 request
|
|
||||||
|
|
||||||
:returns: an utf8 encoded JSON-RPC2 reply
|
|
||||||
"""
|
|
||||||
response = {"jsonrpc": "2.0" }
|
|
||||||
error = None
|
|
||||||
try:
|
|
||||||
# Read POST content or POST Form Data named "request"
|
|
||||||
if requestf:
|
|
||||||
self.jsonrequest = simplejson.load(requestf, object_hook=nonliterals.non_literal_decoder)
|
|
||||||
else:
|
|
||||||
self.jsonrequest = simplejson.loads(request, object_hook=nonliterals.non_literal_decoder)
|
|
||||||
self.init(self.jsonrequest.get("params", {}))
|
|
||||||
if _logger.isEnabledFor(logging.DEBUG):
|
|
||||||
_logger.debug("--> %s.%s\n%s", controller.__class__.__name__, method.__name__, pprint.pformat(self.jsonrequest))
|
|
||||||
response['id'] = self.jsonrequest.get('id')
|
|
||||||
response["result"] = method(controller, self, **self.params)
|
|
||||||
except openerplib.AuthenticationError:
|
|
||||||
error = {
|
|
||||||
'code': 100,
|
|
||||||
'message': "OpenERP Session Invalid",
|
|
||||||
'data': {
|
|
||||||
'type': 'session_invalid',
|
|
||||||
'debug': traceback.format_exc()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
except xmlrpclib.Fault, e:
|
|
||||||
error = {
|
|
||||||
'code': 200,
|
|
||||||
'message': "OpenERP Server Error",
|
|
||||||
'data': {
|
|
||||||
'type': 'server_exception',
|
|
||||||
'fault_code': e.faultCode,
|
|
||||||
'debug': "Client %s\nServer %s" % (
|
|
||||||
"".join(traceback.format_exception("", None, sys.exc_traceback)), e.faultString)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
except Exception:
|
|
||||||
logging.getLogger(__name__ + '.JSONRequest.dispatch').exception\
|
|
||||||
("An error occured while handling a json request")
|
|
||||||
error = {
|
|
||||||
'code': 300,
|
|
||||||
'message': "OpenERP WebClient Error",
|
|
||||||
'data': {
|
|
||||||
'type': 'client_exception',
|
|
||||||
'debug': "Client %s" % traceback.format_exc()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if error:
|
|
||||||
response["error"] = error
|
|
||||||
|
|
||||||
if _logger.isEnabledFor(logging.DEBUG):
|
|
||||||
_logger.debug("<--\n%s", pprint.pformat(response))
|
|
||||||
content = simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder)
|
|
||||||
return werkzeug.wrappers.Response(
|
|
||||||
content, headers=[('Content-Type', 'application/json'),
|
|
||||||
('Content-Length', len(content))])
|
|
||||||
|
|
||||||
def jsonrequest(f):
|
|
||||||
""" Decorator marking the decorated method as being a handler for a
|
|
||||||
JSON-RPC request (the exact request path is specified via the
|
|
||||||
``$(Controller._cp_path)/$methodname`` combination.
|
|
||||||
|
|
||||||
If the method is called, it will be provided with a :class:`JsonRequest`
|
|
||||||
instance and all ``params`` sent during the JSON-RPC request, apart from
|
|
||||||
the ``session_id``, ``context`` and ``debug`` keys (which are stripped out
|
|
||||||
beforehand)
|
|
||||||
"""
|
|
||||||
@functools.wraps(f)
|
|
||||||
def json_handler(controller, request, config):
|
|
||||||
return JsonRequest(request, config).dispatch(
|
|
||||||
controller, f, requestf=request.stream)
|
|
||||||
json_handler.exposed = True
|
|
||||||
return json_handler
|
|
||||||
|
|
||||||
class HttpRequest(WebRequest):
|
|
||||||
""" Regular GET/POST request
|
|
||||||
"""
|
|
||||||
def dispatch(self, controller, method):
|
|
||||||
params = dict(self.httprequest.args)
|
|
||||||
params.update(self.httprequest.form)
|
|
||||||
params.update(self.httprequest.files)
|
|
||||||
self.init(params)
|
|
||||||
akw = {}
|
|
||||||
for key, value in self.httprequest.args.iteritems():
|
|
||||||
if isinstance(value, basestring) and len(value) < 1024:
|
|
||||||
akw[key] = value
|
|
||||||
else:
|
|
||||||
akw[key] = type(value)
|
|
||||||
_logger.debug("%s --> %s.%s %r", self.httprequest.method, controller.__class__.__name__, method.__name__, akw)
|
|
||||||
r = method(controller, self, **self.params)
|
|
||||||
if self.debug or 1:
|
|
||||||
if isinstance(r, werkzeug.wrappers.BaseResponse):
|
|
||||||
_logger.debug('<-- %s', r)
|
|
||||||
else:
|
|
||||||
_logger.debug("<-- size: %s", len(r))
|
|
||||||
return r
|
|
||||||
|
|
||||||
def make_response(self, data, headers=None, cookies=None):
|
|
||||||
""" Helper for non-HTML responses, or HTML responses with custom
|
|
||||||
response headers or cookies.
|
|
||||||
|
|
||||||
While handlers can just return the HTML markup of a page they want to
|
|
||||||
send as a string if non-HTML data is returned they need to create a
|
|
||||||
complete response object, or the returned data will not be correctly
|
|
||||||
interpreted by the clients.
|
|
||||||
|
|
||||||
:param basestring data: response body
|
|
||||||
:param headers: HTTP headers to set on the response
|
|
||||||
:type headers: ``[(name, value)]``
|
|
||||||
:param collections.Mapping cookies: cookies to set on the client
|
|
||||||
"""
|
|
||||||
response = werkzeug.wrappers.Response(data, headers=headers)
|
|
||||||
if cookies:
|
|
||||||
for k, v in cookies.iteritems():
|
|
||||||
response.set_cookie(k, v)
|
|
||||||
return response
|
|
||||||
|
|
||||||
def not_found(self, description=None):
|
|
||||||
""" Helper for 404 response, return its result from the method
|
|
||||||
"""
|
|
||||||
return werkzeug.exceptions.NotFound(description)
|
|
||||||
|
|
||||||
def httprequest(f):
|
|
||||||
""" Decorator marking the decorated method as being a handler for a
|
|
||||||
normal HTTP request (the exact request path is specified via the
|
|
||||||
``$(Controller._cp_path)/$methodname`` combination.
|
|
||||||
|
|
||||||
If the method is called, it will be provided with a :class:`HttpRequest`
|
|
||||||
instance and all ``params`` sent during the request (``GET`` and ``POST``
|
|
||||||
merged in the same dictionary), apart from the ``session_id``, ``context``
|
|
||||||
and ``debug`` keys (which are stripped out beforehand)
|
|
||||||
"""
|
|
||||||
@functools.wraps(f)
|
|
||||||
def http_handler(controller, request, config):
|
|
||||||
return HttpRequest(request, config).dispatch(controller, f)
|
|
||||||
http_handler.exposed = True
|
|
||||||
return http_handler
|
|
||||||
|
|
||||||
class ControllerType(type):
|
|
||||||
def __init__(cls, name, bases, attrs):
|
|
||||||
super(ControllerType, cls).__init__(name, bases, attrs)
|
|
||||||
controllers_class["%s.%s" % (cls.__module__, cls.__name__)] = cls
|
|
||||||
|
|
||||||
class Controller(object):
|
|
||||||
__metaclass__ = ControllerType
|
|
||||||
|
|
||||||
class Root(object):
|
|
||||||
"""Root WSGI application for the OpenERP Web Client.
|
|
||||||
|
|
||||||
:param options: mandatory initialization options object, must provide
|
|
||||||
the following attributes:
|
|
||||||
|
|
||||||
``server_host`` (``str``)
|
|
||||||
hostname of the OpenERP server to dispatch RPC to
|
|
||||||
``server_port`` (``int``)
|
|
||||||
RPC port of the OpenERP server
|
|
||||||
``serve_static`` (``bool | None``)
|
|
||||||
whether this application should serve the various
|
|
||||||
addons's static files
|
|
||||||
``storage_path`` (``str``)
|
|
||||||
filesystem path where HTTP session data will be stored
|
|
||||||
``dbfilter`` (``str``)
|
|
||||||
only used in case the list of databases is requested
|
|
||||||
by the server, will be filtered by this pattern
|
|
||||||
"""
|
|
||||||
def __init__(self, options):
|
|
||||||
self.root = werkzeug.urls.Href('/web/webclient/home')
|
|
||||||
self.config = options
|
|
||||||
|
|
||||||
self.session_cookie = 'sessionid'
|
|
||||||
self.addons = {}
|
|
||||||
|
|
||||||
static_dirs = self._load_addons()
|
|
||||||
if options.serve_static:
|
|
||||||
self.dispatch = werkzeug.wsgi.SharedDataMiddleware(
|
|
||||||
self.dispatch, static_dirs)
|
|
||||||
|
|
||||||
if options.session_storage:
|
|
||||||
if not os.path.exists(options.session_storage):
|
|
||||||
os.mkdir(options.session_storage, 0700)
|
|
||||||
self.session_storage = options.session_storage
|
|
||||||
|
|
||||||
def __call__(self, environ, start_response):
|
|
||||||
""" Handle a WSGI request
|
|
||||||
"""
|
|
||||||
return self.dispatch(environ, start_response)
|
|
||||||
|
|
||||||
def dispatch(self, environ, start_response):
|
|
||||||
"""
|
|
||||||
Performs the actual WSGI dispatching for the application, may be
|
|
||||||
wrapped during the initialization of the object.
|
|
||||||
|
|
||||||
Call the object directly.
|
|
||||||
"""
|
|
||||||
request = werkzeug.wrappers.Request(environ)
|
|
||||||
request.parameter_storage_class = werkzeug.datastructures.ImmutableDict
|
|
||||||
|
|
||||||
if request.path == '/':
|
|
||||||
return werkzeug.utils.redirect(
|
|
||||||
self.root(dict(request.args, debug='')), 301)(
|
|
||||||
environ, start_response)
|
|
||||||
elif request.path == '/mobile':
|
|
||||||
return werkzeug.utils.redirect(
|
|
||||||
'/web_mobile/static/src/web_mobile.html', 301)(
|
|
||||||
environ, start_response)
|
|
||||||
|
|
||||||
handler = self.find_handler(*(request.path.split('/')[1:]))
|
|
||||||
|
|
||||||
if not handler:
|
|
||||||
response = werkzeug.exceptions.NotFound()
|
|
||||||
else:
|
|
||||||
with http.session(request, self.session_storage, self.session_cookie) as session:
|
|
||||||
result = handler(
|
|
||||||
request, self.config)
|
|
||||||
|
|
||||||
if isinstance(result, basestring):
|
|
||||||
response = werkzeug.wrappers.Response(
|
|
||||||
result, headers=[('Content-Type', 'text/html; charset=utf-8'),
|
|
||||||
('Content-Length', len(result))])
|
|
||||||
else:
|
|
||||||
response = result
|
|
||||||
|
|
||||||
response.set_cookie(self.session_cookie, session.sid)
|
|
||||||
|
|
||||||
return response(environ, start_response)
|
|
||||||
|
|
||||||
def _load_addons(self):
|
|
||||||
"""
|
|
||||||
Loads all addons at the specified addons path, returns a mapping of
|
|
||||||
static URLs to the corresponding directories
|
|
||||||
"""
|
|
||||||
statics = {}
|
|
||||||
addons_path = self.config.addons_path
|
|
||||||
if addons_path not in sys.path:
|
|
||||||
sys.path.insert(0, addons_path)
|
|
||||||
for module in os.listdir(addons_path):
|
|
||||||
if module not in addons_module:
|
|
||||||
manifest_path = os.path.join(addons_path, module, '__openerp__.py')
|
|
||||||
if os.path.isfile(manifest_path):
|
|
||||||
manifest = ast.literal_eval(open(manifest_path).read())
|
|
||||||
_logger.info("Loading %s", module)
|
|
||||||
m = __import__(module)
|
|
||||||
addons_module[module] = m
|
|
||||||
addons_manifest[module] = manifest
|
|
||||||
|
|
||||||
statics['/%s/static' % module] = \
|
|
||||||
os.path.join(addons_path, module, 'static')
|
|
||||||
for k, v in controllers_class.items():
|
|
||||||
if k not in controllers_object:
|
|
||||||
o = v()
|
|
||||||
controllers_object[k] = o
|
|
||||||
if hasattr(o, '_cp_path'):
|
|
||||||
controllers_path[o._cp_path] = o
|
|
||||||
return statics
|
|
||||||
|
|
||||||
def find_handler(self, *l):
|
|
||||||
"""
|
|
||||||
Tries to discover the controller handling the request for the path
|
|
||||||
specified by the provided parameters
|
|
||||||
|
|
||||||
:param l: path sections to a controller or controller method
|
|
||||||
:returns: a callable matching the path sections, or ``None``
|
|
||||||
:rtype: ``Controller | None``
|
|
||||||
"""
|
|
||||||
if len(l) > 1:
|
|
||||||
for i in range(len(l), 1, -1):
|
|
||||||
ps = "/" + "/".join(l[0:i])
|
|
||||||
if ps in controllers_path:
|
|
||||||
c = controllers_path[ps]
|
|
||||||
rest = l[i:] or ['index']
|
|
||||||
meth = rest[0]
|
|
||||||
m = getattr(c, meth)
|
|
||||||
if getattr(m, 'exposed', False):
|
|
||||||
_logger.debug("Dispatching to %s %s %s", ps, c, meth)
|
|
||||||
return m
|
|
||||||
return None
|
|
|
@ -1,13 +1,286 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
#----------------------------------------------------------
|
||||||
|
# OpenERP Web HTTP layer
|
||||||
|
#----------------------------------------------------------
|
||||||
|
import ast
|
||||||
import contextlib
|
import contextlib
|
||||||
|
import functools
|
||||||
|
import logging
|
||||||
|
import urllib
|
||||||
|
import os
|
||||||
|
import pprint
|
||||||
|
import sys
|
||||||
|
import traceback
|
||||||
|
import uuid
|
||||||
|
import xmlrpclib
|
||||||
|
|
||||||
|
import simplejson
|
||||||
import werkzeug.contrib.sessions
|
import werkzeug.contrib.sessions
|
||||||
|
import werkzeug.datastructures
|
||||||
|
import werkzeug.exceptions
|
||||||
|
import werkzeug.utils
|
||||||
|
import werkzeug.wrappers
|
||||||
|
import werkzeug.wsgi
|
||||||
|
|
||||||
|
import nonliterals
|
||||||
|
import session
|
||||||
|
import openerplib
|
||||||
|
|
||||||
|
__all__ = ['Root', 'jsonrequest', 'httprequest', 'Controller',
|
||||||
|
'WebRequest', 'JsonRequest', 'HttpRequest']
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
# OpenERP Web RequestHandler
|
||||||
|
#----------------------------------------------------------
|
||||||
|
class WebRequest(object):
|
||||||
|
""" Parent class for all OpenERP Web request types, mostly deals with
|
||||||
|
initialization and setup of the request object (the dispatching itself has
|
||||||
|
to be handled by the subclasses)
|
||||||
|
|
||||||
|
:param request: a wrapped werkzeug Request object
|
||||||
|
:type request: :class:`werkzeug.wrappers.BaseRequest`
|
||||||
|
:param config: configuration object
|
||||||
|
|
||||||
|
.. attribute:: httprequest
|
||||||
|
|
||||||
|
the original :class:`werkzeug.wrappers.Request` object provided to the
|
||||||
|
request
|
||||||
|
|
||||||
|
.. attribute:: httpsession
|
||||||
|
|
||||||
|
a :class:`~collections.Mapping` holding the HTTP session data for the
|
||||||
|
current http session
|
||||||
|
|
||||||
|
.. attribute:: config
|
||||||
|
|
||||||
|
config parameter provided to the request object
|
||||||
|
|
||||||
|
.. attribute:: params
|
||||||
|
|
||||||
|
:class:`~collections.Mapping` of request parameters, not generally
|
||||||
|
useful as they're provided directly to the handler method as keyword
|
||||||
|
arguments
|
||||||
|
|
||||||
|
.. attribute:: session_id
|
||||||
|
|
||||||
|
opaque identifier for the :class:`session.OpenERPSession` instance of
|
||||||
|
the current request
|
||||||
|
|
||||||
|
.. attribute:: session
|
||||||
|
|
||||||
|
:class:`~session.OpenERPSession` instance for the current request
|
||||||
|
|
||||||
|
.. attribute:: context
|
||||||
|
|
||||||
|
:class:`~collections.Mapping` of context values for the current request
|
||||||
|
|
||||||
|
.. attribute:: debug
|
||||||
|
|
||||||
|
``bool``, indicates whether the debug mode is active on the client
|
||||||
|
"""
|
||||||
|
def __init__(self, request, config):
|
||||||
|
self.httprequest = request
|
||||||
|
self.httpresponse = None
|
||||||
|
self.httpsession = request.session
|
||||||
|
self.config = config
|
||||||
|
|
||||||
|
def init(self, params):
|
||||||
|
self.params = dict(params)
|
||||||
|
# OpenERP session setup
|
||||||
|
self.session_id = self.params.pop("session_id", None) or uuid.uuid4().hex
|
||||||
|
self.session = self.httpsession.setdefault(self.session_id, session.OpenERPSession())
|
||||||
|
self.session.config = self.config
|
||||||
|
self.context = self.params.pop('context', None)
|
||||||
|
self.debug = self.params.pop('debug', False) != False
|
||||||
|
|
||||||
|
class JsonRequest(WebRequest):
|
||||||
|
""" JSON-RPC2 over HTTP.
|
||||||
|
|
||||||
|
Sucessful request::
|
||||||
|
|
||||||
|
--> {"jsonrpc": "2.0",
|
||||||
|
"method": "call",
|
||||||
|
"params": {"session_id": "SID",
|
||||||
|
"context": {},
|
||||||
|
"arg1": "val1" },
|
||||||
|
"id": null}
|
||||||
|
|
||||||
|
<-- {"jsonrpc": "2.0",
|
||||||
|
"result": { "res1": "val1" },
|
||||||
|
"id": null}
|
||||||
|
|
||||||
|
Request producing a error::
|
||||||
|
|
||||||
|
--> {"jsonrpc": "2.0",
|
||||||
|
"method": "call",
|
||||||
|
"params": {"session_id": "SID",
|
||||||
|
"context": {},
|
||||||
|
"arg1": "val1" },
|
||||||
|
"id": null}
|
||||||
|
|
||||||
|
<-- {"jsonrpc": "2.0",
|
||||||
|
"error": {"code": 1,
|
||||||
|
"message": "End user error message.",
|
||||||
|
"data": {"code": "codestring",
|
||||||
|
"debug": "traceback" } },
|
||||||
|
"id": null}
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def dispatch(self, controller, method, requestf=None, request=None):
|
||||||
|
""" Calls the method asked for by the JSON-RPC2 request
|
||||||
|
|
||||||
|
:param controller: the instance of the controller which received the request
|
||||||
|
:param method: the method which received the request
|
||||||
|
:param requestf: a file-like object containing an encoded JSON-RPC2 request
|
||||||
|
:param request: a JSON-RPC2 request
|
||||||
|
|
||||||
|
:returns: an utf8 encoded JSON-RPC2 reply
|
||||||
|
"""
|
||||||
|
response = {"jsonrpc": "2.0" }
|
||||||
|
error = None
|
||||||
|
try:
|
||||||
|
# Read POST content or POST Form Data named "request"
|
||||||
|
if requestf:
|
||||||
|
self.jsonrequest = simplejson.load(requestf, object_hook=nonliterals.non_literal_decoder)
|
||||||
|
else:
|
||||||
|
self.jsonrequest = simplejson.loads(request, object_hook=nonliterals.non_literal_decoder)
|
||||||
|
self.init(self.jsonrequest.get("params", {}))
|
||||||
|
if _logger.isEnabledFor(logging.DEBUG):
|
||||||
|
_logger.debug("--> %s.%s\n%s", controller.__class__.__name__, method.__name__, pprint.pformat(self.jsonrequest))
|
||||||
|
response['id'] = self.jsonrequest.get('id')
|
||||||
|
response["result"] = method(controller, self, **self.params)
|
||||||
|
except openerplib.AuthenticationError:
|
||||||
|
error = {
|
||||||
|
'code': 100,
|
||||||
|
'message': "OpenERP Session Invalid",
|
||||||
|
'data': {
|
||||||
|
'type': 'session_invalid',
|
||||||
|
'debug': traceback.format_exc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
except xmlrpclib.Fault, e:
|
||||||
|
error = {
|
||||||
|
'code': 200,
|
||||||
|
'message': "OpenERP Server Error",
|
||||||
|
'data': {
|
||||||
|
'type': 'server_exception',
|
||||||
|
'fault_code': e.faultCode,
|
||||||
|
'debug': "Client %s\nServer %s" % (
|
||||||
|
"".join(traceback.format_exception("", None, sys.exc_traceback)), e.faultString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
logging.getLogger(__name__ + '.JSONRequest.dispatch').exception\
|
||||||
|
("An error occured while handling a json request")
|
||||||
|
error = {
|
||||||
|
'code': 300,
|
||||||
|
'message': "OpenERP WebClient Error",
|
||||||
|
'data': {
|
||||||
|
'type': 'client_exception',
|
||||||
|
'debug': "Client %s" % traceback.format_exc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if error:
|
||||||
|
response["error"] = error
|
||||||
|
|
||||||
|
if _logger.isEnabledFor(logging.DEBUG):
|
||||||
|
_logger.debug("<--\n%s", pprint.pformat(response))
|
||||||
|
content = simplejson.dumps(response, cls=nonliterals.NonLiteralEncoder)
|
||||||
|
return werkzeug.wrappers.Response(
|
||||||
|
content, headers=[('Content-Type', 'application/json'),
|
||||||
|
('Content-Length', len(content))])
|
||||||
|
|
||||||
|
def jsonrequest(f):
|
||||||
|
""" Decorator marking the decorated method as being a handler for a
|
||||||
|
JSON-RPC request (the exact request path is specified via the
|
||||||
|
``$(Controller._cp_path)/$methodname`` combination.
|
||||||
|
|
||||||
|
If the method is called, it will be provided with a :class:`JsonRequest`
|
||||||
|
instance and all ``params`` sent during the JSON-RPC request, apart from
|
||||||
|
the ``session_id``, ``context`` and ``debug`` keys (which are stripped out
|
||||||
|
beforehand)
|
||||||
|
"""
|
||||||
|
@functools.wraps(f)
|
||||||
|
def json_handler(controller, request, config):
|
||||||
|
return JsonRequest(request, config).dispatch(
|
||||||
|
controller, f, requestf=request.stream)
|
||||||
|
json_handler.exposed = True
|
||||||
|
return json_handler
|
||||||
|
|
||||||
|
class HttpRequest(WebRequest):
|
||||||
|
""" Regular GET/POST request
|
||||||
|
"""
|
||||||
|
def dispatch(self, controller, method):
|
||||||
|
params = dict(self.httprequest.args)
|
||||||
|
params.update(self.httprequest.form)
|
||||||
|
params.update(self.httprequest.files)
|
||||||
|
self.init(params)
|
||||||
|
akw = {}
|
||||||
|
for key, value in self.httprequest.args.iteritems():
|
||||||
|
if isinstance(value, basestring) and len(value) < 1024:
|
||||||
|
akw[key] = value
|
||||||
|
else:
|
||||||
|
akw[key] = type(value)
|
||||||
|
_logger.debug("%s --> %s.%s %r", self.httprequest.method, controller.__class__.__name__, method.__name__, akw)
|
||||||
|
r = method(controller, self, **self.params)
|
||||||
|
if self.debug or 1:
|
||||||
|
if isinstance(r, (werkzeug.wrappers.BaseResponse, werkzeug.exceptions.HTTPException)):
|
||||||
|
_logger.debug('<-- %s', r)
|
||||||
|
else:
|
||||||
|
_logger.debug("<-- size: %s", len(r))
|
||||||
|
return r
|
||||||
|
|
||||||
|
def make_response(self, data, headers=None, cookies=None):
|
||||||
|
""" Helper for non-HTML responses, or HTML responses with custom
|
||||||
|
response headers or cookies.
|
||||||
|
|
||||||
|
While handlers can just return the HTML markup of a page they want to
|
||||||
|
send as a string if non-HTML data is returned they need to create a
|
||||||
|
complete response object, or the returned data will not be correctly
|
||||||
|
interpreted by the clients.
|
||||||
|
|
||||||
|
:param basestring data: response body
|
||||||
|
:param headers: HTTP headers to set on the response
|
||||||
|
:type headers: ``[(name, value)]``
|
||||||
|
:param collections.Mapping cookies: cookies to set on the client
|
||||||
|
"""
|
||||||
|
response = werkzeug.wrappers.Response(data, headers=headers)
|
||||||
|
if cookies:
|
||||||
|
for k, v in cookies.iteritems():
|
||||||
|
response.set_cookie(k, v)
|
||||||
|
return response
|
||||||
|
|
||||||
|
def not_found(self, description=None):
|
||||||
|
""" Helper for 404 response, return its result from the method
|
||||||
|
"""
|
||||||
|
return werkzeug.exceptions.NotFound(description)
|
||||||
|
|
||||||
|
def httprequest(f):
|
||||||
|
""" Decorator marking the decorated method as being a handler for a
|
||||||
|
normal HTTP request (the exact request path is specified via the
|
||||||
|
``$(Controller._cp_path)/$methodname`` combination.
|
||||||
|
|
||||||
|
If the method is called, it will be provided with a :class:`HttpRequest`
|
||||||
|
instance and all ``params`` sent during the request (``GET`` and ``POST``
|
||||||
|
merged in the same dictionary), apart from the ``session_id``, ``context``
|
||||||
|
and ``debug`` keys (which are stripped out beforehand)
|
||||||
|
"""
|
||||||
|
@functools.wraps(f)
|
||||||
|
def http_handler(controller, request, config):
|
||||||
|
return HttpRequest(request, config).dispatch(controller, f)
|
||||||
|
http_handler.exposed = True
|
||||||
|
return http_handler
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
# OpenERP Web werkzeug Session Managment wraped using with
|
||||||
|
#----------------------------------------------------------
|
||||||
STORES = {}
|
STORES = {}
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def session(request, storage_path, session_cookie='sessionid'):
|
def session_context(request, storage_path, session_cookie='sessionid'):
|
||||||
session_store = STORES.get(storage_path)
|
session_store = STORES.get(storage_path)
|
||||||
if not session_store:
|
if not session_store:
|
||||||
session_store = werkzeug.contrib.sessions.FilesystemSessionStore(
|
session_store = werkzeug.contrib.sessions.FilesystemSessionStore(
|
||||||
|
@ -23,4 +296,188 @@ def session(request, storage_path, session_cookie='sessionid'):
|
||||||
try:
|
try:
|
||||||
yield request.session
|
yield request.session
|
||||||
finally:
|
finally:
|
||||||
|
# Remove all OpenERPSession instances with no uid, they're generated
|
||||||
|
# either by login process or by HTTP requests without an OpenERP
|
||||||
|
# session id, and are generally noise
|
||||||
|
for key, value in request.session.items():
|
||||||
|
if isinstance(value, session.OpenERPSession) and not value._uid:
|
||||||
|
del request.session[key]
|
||||||
|
|
||||||
|
# FIXME: remove this when non-literals disappear
|
||||||
|
if sid:
|
||||||
|
# Re-load sessions from storage and merge non-literal
|
||||||
|
# contexts and domains (they're indexed by hash of the
|
||||||
|
# content so conflicts should auto-resolve), otherwise if
|
||||||
|
# two requests alter those concurrently the last to finish
|
||||||
|
# will overwrite the previous one, leading to loss of data
|
||||||
|
# (a non-literal is lost even though it was sent to the
|
||||||
|
# client and client errors)
|
||||||
|
#
|
||||||
|
# note that domains_store and contexts_store are append-only (we
|
||||||
|
# only ever add items to them), so we can just update one with the
|
||||||
|
# other to get the right result, if we want to merge the
|
||||||
|
# ``context`` dict we'll need something smarter
|
||||||
|
in_store = session_store.get(sid)
|
||||||
|
for k, v in request.session.iteritems():
|
||||||
|
stored = in_store.get(k)
|
||||||
|
if stored and isinstance(v, session.OpenERPSession)\
|
||||||
|
and v != stored:
|
||||||
|
v.contexts_store.update(stored.contexts_store)
|
||||||
|
v.domains_store.update(stored.domains_store)
|
||||||
|
|
||||||
session_store.save(request.session)
|
session_store.save(request.session)
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
# OpenERP Web Module/Controller Loading and URL Routing
|
||||||
|
#----------------------------------------------------------
|
||||||
|
addons_module = {}
|
||||||
|
addons_manifest = {}
|
||||||
|
controllers_class = {}
|
||||||
|
controllers_object = {}
|
||||||
|
controllers_path = {}
|
||||||
|
|
||||||
|
class ControllerType(type):
|
||||||
|
def __init__(cls, name, bases, attrs):
|
||||||
|
super(ControllerType, cls).__init__(name, bases, attrs)
|
||||||
|
controllers_class["%s.%s" % (cls.__module__, cls.__name__)] = cls
|
||||||
|
|
||||||
|
class Controller(object):
|
||||||
|
__metaclass__ = ControllerType
|
||||||
|
|
||||||
|
class Root(object):
|
||||||
|
"""Root WSGI application for the OpenERP Web Client.
|
||||||
|
|
||||||
|
:param options: mandatory initialization options object, must provide
|
||||||
|
the following attributes:
|
||||||
|
|
||||||
|
``server_host`` (``str``)
|
||||||
|
hostname of the OpenERP server to dispatch RPC to
|
||||||
|
``server_port`` (``int``)
|
||||||
|
RPC port of the OpenERP server
|
||||||
|
``serve_static`` (``bool | None``)
|
||||||
|
whether this application should serve the various
|
||||||
|
addons's static files
|
||||||
|
``storage_path`` (``str``)
|
||||||
|
filesystem path where HTTP session data will be stored
|
||||||
|
``dbfilter`` (``str``)
|
||||||
|
only used in case the list of databases is requested
|
||||||
|
by the server, will be filtered by this pattern
|
||||||
|
"""
|
||||||
|
def __init__(self, options):
|
||||||
|
self.root = '/web/webclient/home'
|
||||||
|
self.config = options
|
||||||
|
|
||||||
|
if self.config.backend == 'local':
|
||||||
|
conn = openerplib.get_connector(protocol='local')
|
||||||
|
else:
|
||||||
|
conn = openerplib.get_connector(hostname=self.config.server_host,
|
||||||
|
port=self.config.server_port)
|
||||||
|
self.config.connector = conn
|
||||||
|
|
||||||
|
self.session_cookie = 'sessionid'
|
||||||
|
self.addons = {}
|
||||||
|
|
||||||
|
static_dirs = self._load_addons()
|
||||||
|
if options.serve_static:
|
||||||
|
self.dispatch = werkzeug.wsgi.SharedDataMiddleware(
|
||||||
|
self.dispatch, static_dirs)
|
||||||
|
|
||||||
|
if options.session_storage:
|
||||||
|
if not os.path.exists(options.session_storage):
|
||||||
|
os.mkdir(options.session_storage, 0700)
|
||||||
|
self.session_storage = options.session_storage
|
||||||
|
|
||||||
|
def __call__(self, environ, start_response):
|
||||||
|
""" Handle a WSGI request
|
||||||
|
"""
|
||||||
|
return self.dispatch(environ, start_response)
|
||||||
|
|
||||||
|
def dispatch(self, environ, start_response):
|
||||||
|
"""
|
||||||
|
Performs the actual WSGI dispatching for the application, may be
|
||||||
|
wrapped during the initialization of the object.
|
||||||
|
|
||||||
|
Call the object directly.
|
||||||
|
"""
|
||||||
|
request = werkzeug.wrappers.Request(environ)
|
||||||
|
request.parameter_storage_class = werkzeug.datastructures.ImmutableDict
|
||||||
|
|
||||||
|
if request.path == '/':
|
||||||
|
params = urllib.urlencode(dict(request.args, debug=''))
|
||||||
|
return werkzeug.utils.redirect(self.root + '?' + params, 301)(
|
||||||
|
environ, start_response)
|
||||||
|
elif request.path == '/mobile':
|
||||||
|
return werkzeug.utils.redirect(
|
||||||
|
'/web_mobile/static/src/web_mobile.html', 301)(environ, start_response)
|
||||||
|
|
||||||
|
handler = self.find_handler(*(request.path.split('/')[1:]))
|
||||||
|
|
||||||
|
if not handler:
|
||||||
|
response = werkzeug.exceptions.NotFound()
|
||||||
|
else:
|
||||||
|
with session_context(request, self.session_storage, self.session_cookie) as session:
|
||||||
|
result = handler( request, self.config)
|
||||||
|
|
||||||
|
if isinstance(result, basestring):
|
||||||
|
headers=[('Content-Type', 'text/html; charset=utf-8'), ('Content-Length', len(result))]
|
||||||
|
response = werkzeug.wrappers.Response(result, headers=headers)
|
||||||
|
else:
|
||||||
|
response = result
|
||||||
|
|
||||||
|
if hasattr(response, 'set_cookie'):
|
||||||
|
response.set_cookie(self.session_cookie, session.sid)
|
||||||
|
|
||||||
|
return response(environ, start_response)
|
||||||
|
|
||||||
|
def _load_addons(self):
|
||||||
|
"""
|
||||||
|
Loads all addons at the specified addons path, returns a mapping of
|
||||||
|
static URLs to the corresponding directories
|
||||||
|
"""
|
||||||
|
statics = {}
|
||||||
|
for addons_path in self.config.addons_path:
|
||||||
|
if addons_path not in sys.path:
|
||||||
|
sys.path.insert(0, addons_path)
|
||||||
|
for module in os.listdir(addons_path):
|
||||||
|
if module not in addons_module:
|
||||||
|
manifest_path = os.path.join(addons_path, module, '__openerp__.py')
|
||||||
|
path_static = os.path.join(addons_path, module, 'static')
|
||||||
|
if os.path.isfile(manifest_path) and os.path.isdir(path_static):
|
||||||
|
manifest = ast.literal_eval(open(manifest_path).read())
|
||||||
|
manifest['addons_path'] = addons_path
|
||||||
|
_logger.info("Loading %s", module)
|
||||||
|
m = __import__(module)
|
||||||
|
addons_module[module] = m
|
||||||
|
addons_manifest[module] = manifest
|
||||||
|
statics['/%s/static' % module] = path_static
|
||||||
|
for k, v in controllers_class.items():
|
||||||
|
if k not in controllers_object:
|
||||||
|
o = v()
|
||||||
|
controllers_object[k] = o
|
||||||
|
if hasattr(o, '_cp_path'):
|
||||||
|
controllers_path[o._cp_path] = o
|
||||||
|
return statics
|
||||||
|
|
||||||
|
def find_handler(self, *l):
|
||||||
|
"""
|
||||||
|
Tries to discover the controller handling the request for the path
|
||||||
|
specified by the provided parameters
|
||||||
|
|
||||||
|
:param l: path sections to a controller or controller method
|
||||||
|
:returns: a callable matching the path sections, or ``None``
|
||||||
|
:rtype: ``Controller | None``
|
||||||
|
"""
|
||||||
|
if len(l):
|
||||||
|
for i in range(len(l), 0, -1):
|
||||||
|
ps = "/" + "/".join(l[0:i])
|
||||||
|
if ps in controllers_path:
|
||||||
|
c = controllers_path[ps]
|
||||||
|
rest = l[i:] or ['index']
|
||||||
|
meth = rest[0]
|
||||||
|
m = getattr(c, meth)
|
||||||
|
if getattr(m, 'exposed', False):
|
||||||
|
_logger.debug("Dispatching to %s %s %s", ps, c, meth)
|
||||||
|
return m
|
||||||
|
return None
|
||||||
|
|
||||||
|
#
|
||||||
|
|
|
@ -21,12 +21,14 @@ class NonLiteralEncoder(simplejson.encoder.JSONEncoder):
|
||||||
if isinstance(object, Domain):
|
if isinstance(object, Domain):
|
||||||
return {
|
return {
|
||||||
'__ref': 'domain',
|
'__ref': 'domain',
|
||||||
'__id': object.key
|
'__id': object.key,
|
||||||
|
'__debug': object.get_domain_string()
|
||||||
}
|
}
|
||||||
elif isinstance(object, Context):
|
elif isinstance(object, Context):
|
||||||
return {
|
return {
|
||||||
'__ref': 'context',
|
'__ref': 'context',
|
||||||
'__id': object.key
|
'__id': object.key,
|
||||||
|
'__debug': object.get_context_string()
|
||||||
}
|
}
|
||||||
elif isinstance(object, CompoundDomain):
|
elif isinstance(object, CompoundDomain):
|
||||||
return {
|
return {
|
||||||
|
@ -41,6 +43,9 @@ class NonLiteralEncoder(simplejson.encoder.JSONEncoder):
|
||||||
'__eval_context': object.get_eval_context()
|
'__eval_context': object.get_eval_context()
|
||||||
}
|
}
|
||||||
raise TypeError('Could not encode unknown non-literal %s' % object)
|
raise TypeError('Could not encode unknown non-literal %s' % object)
|
||||||
|
|
||||||
|
_ALLOWED_KEYS = frozenset(['__ref', "__id", '__domains', '__debug',
|
||||||
|
'__contexts', '__eval_context', 'own_values'])
|
||||||
|
|
||||||
def non_literal_decoder(dct):
|
def non_literal_decoder(dct):
|
||||||
""" Decodes JSON dicts into :class:`Domain` and :class:`Context` based on
|
""" Decodes JSON dicts into :class:`Domain` and :class:`Context` based on
|
||||||
|
@ -50,6 +55,9 @@ def non_literal_decoder(dct):
|
||||||
``own_values`` dict key.
|
``own_values`` dict key.
|
||||||
"""
|
"""
|
||||||
if '__ref' in dct:
|
if '__ref' in dct:
|
||||||
|
for x in dct:
|
||||||
|
if x not in _ALLOWED_KEYS:
|
||||||
|
raise ValueError("'%s' key not allowed in non literal domain/context" % x)
|
||||||
if dct['__ref'] == 'domain':
|
if dct['__ref'] == 'domain':
|
||||||
domain = Domain(None, key=dct['__id'])
|
domain = Domain(None, key=dct['__id'])
|
||||||
if 'own_values' in dct:
|
if 'own_values' in dct:
|
||||||
|
@ -125,7 +133,10 @@ class Domain(BaseDomain):
|
||||||
ctx = self.session.evaluation_context(context)
|
ctx = self.session.evaluation_context(context)
|
||||||
if self.own:
|
if self.own:
|
||||||
ctx.update(self.own)
|
ctx.update(self.own)
|
||||||
return eval(self.get_domain_string(), SuperDict(ctx))
|
try:
|
||||||
|
return eval(self.get_domain_string(), SuperDict(ctx))
|
||||||
|
except NameError as e:
|
||||||
|
raise ValueError('Error during evaluation of this domain: "%s", message: "%s"' % (self.get_domain_string(), e.message))
|
||||||
|
|
||||||
class Context(BaseContext):
|
class Context(BaseContext):
|
||||||
def __init__(self, session, context_string=None, key=None):
|
def __init__(self, session, context_string=None, key=None):
|
||||||
|
@ -170,7 +181,10 @@ class Context(BaseContext):
|
||||||
ctx = self.session.evaluation_context(context)
|
ctx = self.session.evaluation_context(context)
|
||||||
if self.own:
|
if self.own:
|
||||||
ctx.update(self.own)
|
ctx.update(self.own)
|
||||||
return eval(self.get_context_string(), SuperDict(ctx))
|
try:
|
||||||
|
return eval(self.get_context_string(), SuperDict(ctx))
|
||||||
|
except NameError as e:
|
||||||
|
raise ValueError('Error during evaluation of this context: "%s", message: "%s"' % (self.get_context_string(), e.message))
|
||||||
|
|
||||||
class SuperDict(dict):
|
class SuperDict(dict):
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
|
@ -193,6 +207,11 @@ class CompoundDomain(BaseDomain):
|
||||||
self.add(domain)
|
self.add(domain)
|
||||||
|
|
||||||
def evaluate(self, context=None):
|
def evaluate(self, context=None):
|
||||||
|
ctx = dict(context or {})
|
||||||
|
eval_context = self.get_eval_context()
|
||||||
|
if eval_context:
|
||||||
|
eval_context = self.session.eval_context(eval_context)
|
||||||
|
ctx.update(eval_context)
|
||||||
final_domain = []
|
final_domain = []
|
||||||
for domain in self.domains:
|
for domain in self.domains:
|
||||||
if not isinstance(domain, (list, BaseDomain)):
|
if not isinstance(domain, (list, BaseDomain)):
|
||||||
|
@ -202,9 +221,6 @@ class CompoundDomain(BaseDomain):
|
||||||
if isinstance(domain, list):
|
if isinstance(domain, list):
|
||||||
final_domain.extend(domain)
|
final_domain.extend(domain)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
ctx = dict(context or {})
|
|
||||||
ctx.update(self.get_eval_context() or {})
|
|
||||||
|
|
||||||
domain.session = self.session
|
domain.session = self.session
|
||||||
final_domain.extend(domain.evaluate(ctx))
|
final_domain.extend(domain.evaluate(ctx))
|
||||||
|
@ -231,7 +247,10 @@ class CompoundContext(BaseContext):
|
||||||
|
|
||||||
def evaluate(self, context=None):
|
def evaluate(self, context=None):
|
||||||
ctx = dict(context or {})
|
ctx = dict(context or {})
|
||||||
ctx.update(self.get_eval_context() or {})
|
eval_context = self.get_eval_context()
|
||||||
|
if eval_context:
|
||||||
|
eval_context = self.session.eval_context(eval_context)
|
||||||
|
ctx.update(eval_context)
|
||||||
final_context = {}
|
final_context = {}
|
||||||
for context_to_eval in self.contexts:
|
for context_to_eval in self.contexts:
|
||||||
if not isinstance(context_to_eval, (dict, BaseContext)):
|
if not isinstance(context_to_eval, (dict, BaseContext)):
|
||||||
|
|
|
@ -38,6 +38,7 @@ Code repository: https://code.launchpad.net/~niv-openerp/openerp-client-lib/trun
|
||||||
import xmlrpclib
|
import xmlrpclib
|
||||||
import logging
|
import logging
|
||||||
import socket
|
import socket
|
||||||
|
import sys
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import cPickle as pickle
|
import cPickle as pickle
|
||||||
|
@ -54,6 +55,33 @@ _logger = logging.getLogger(__name__)
|
||||||
def _getChildLogger(logger, subname):
|
def _getChildLogger(logger, subname):
|
||||||
return logging.getLogger(logger.name + "." + subname)
|
return logging.getLogger(logger.name + "." + subname)
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
# Exceptions
|
||||||
|
# TODO openerplib should raise those instead of xmlrpc faults:
|
||||||
|
#----------------------------------------------------------
|
||||||
|
|
||||||
|
class LibException(Exception):
|
||||||
|
""" Base of all client lib exceptions """
|
||||||
|
def __init__(self,code=None,message=None):
|
||||||
|
self.code = code
|
||||||
|
self.message = message
|
||||||
|
|
||||||
|
class ApplicationError(LibException):
|
||||||
|
""" maps to code: 1, server side: Exception or openerp.exceptions.DeferredException"""
|
||||||
|
|
||||||
|
class Warning(LibException):
|
||||||
|
""" maps to code: 2, server side: openerp.exceptions.Warning"""
|
||||||
|
|
||||||
|
class AccessError(LibException):
|
||||||
|
""" maps to code: 3, server side: openerp.exceptions.AccessError"""
|
||||||
|
|
||||||
|
class AccessDenied(LibException):
|
||||||
|
""" maps to code: 4, server side: openerp.exceptions.AccessDenied"""
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
# Connectors
|
||||||
|
#----------------------------------------------------------
|
||||||
|
|
||||||
class Connector(object):
|
class Connector(object):
|
||||||
"""
|
"""
|
||||||
The base abstract class representing a connection to an OpenERP Server.
|
The base abstract class representing a connection to an OpenERP Server.
|
||||||
|
@ -70,6 +98,14 @@ class Connector(object):
|
||||||
self.hostname = hostname
|
self.hostname = hostname
|
||||||
self.port = port
|
self.port = port
|
||||||
|
|
||||||
|
def get_service(self, service_name):
|
||||||
|
"""
|
||||||
|
Returns a Service instance to allow easy manipulation of one of the services offered by the remote server.
|
||||||
|
|
||||||
|
:param service_name: The name of the service.
|
||||||
|
"""
|
||||||
|
return Service(self, service_name)
|
||||||
|
|
||||||
class XmlRPCConnector(Connector):
|
class XmlRPCConnector(Connector):
|
||||||
"""
|
"""
|
||||||
A type of connector that uses the XMLRPC protocol.
|
A type of connector that uses the XMLRPC protocol.
|
||||||
|
@ -90,6 +126,7 @@ class XmlRPCConnector(Connector):
|
||||||
def send(self, service_name, method, *args):
|
def send(self, service_name, method, *args):
|
||||||
url = '%s/%s' % (self.url, service_name)
|
url = '%s/%s' % (self.url, service_name)
|
||||||
service = xmlrpclib.ServerProxy(url)
|
service = xmlrpclib.ServerProxy(url)
|
||||||
|
# TODO should try except and wrap exception into LibException
|
||||||
return getattr(service, method)(*args)
|
return getattr(service, method)(*args)
|
||||||
|
|
||||||
class NetRPC_Exception(Exception):
|
class NetRPC_Exception(Exception):
|
||||||
|
@ -190,6 +227,47 @@ class NetRPCConnector(Connector):
|
||||||
socket.disconnect()
|
socket.disconnect()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
class LocalConnector(Connector):
|
||||||
|
"""
|
||||||
|
A type of connector that uses the XMLRPC protocol.
|
||||||
|
"""
|
||||||
|
PROTOCOL = 'local'
|
||||||
|
|
||||||
|
__logger = _getChildLogger(_logger, 'connector.local')
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def send(self, service_name, method, *args):
|
||||||
|
import openerp
|
||||||
|
import traceback
|
||||||
|
try:
|
||||||
|
result = openerp.netsvc.dispatch_rpc(service_name, method, args)
|
||||||
|
except Exception,e:
|
||||||
|
# TODO change the except to raise LibException instead of their emulated xmlrpc fault
|
||||||
|
if isinstance(e, openerp.osv.osv.except_osv):
|
||||||
|
fault = xmlrpclib.Fault('warning -- ' + e.name + '\n\n' + e.value, '')
|
||||||
|
elif isinstance(e, openerp.exceptions.Warning):
|
||||||
|
fault = xmlrpclib.Fault('warning -- Warning\n\n' + str(e), '')
|
||||||
|
elif isinstance(e, openerp.exceptions.AccessError):
|
||||||
|
fault = xmlrpclib.Fault('warning -- AccessError\n\n' + str(e), '')
|
||||||
|
elif isinstance(e, openerp.exceptions.AccessDenied):
|
||||||
|
fault = xmlrpclib.Fault('AccessDenied', str(e))
|
||||||
|
elif isinstance(e, openerp.exceptions.DeferredException):
|
||||||
|
info = e.traceback
|
||||||
|
formatted_info = "".join(traceback.format_exception(*info))
|
||||||
|
fault = xmlrpclib.Fault(openerp.tools.ustr(e.message), formatted_info)
|
||||||
|
else:
|
||||||
|
info = sys.exc_info()
|
||||||
|
formatted_info = "".join(traceback.format_exception(*info))
|
||||||
|
fault = xmlrpclib.Fault(openerp.tools.exception_to_unicode(e), formatted_info)
|
||||||
|
raise fault
|
||||||
|
return result
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
# Public api
|
||||||
|
#----------------------------------------------------------
|
||||||
|
|
||||||
class Service(object):
|
class Service(object):
|
||||||
"""
|
"""
|
||||||
A class to execute RPC calls on a specific service of the remote server.
|
A class to execute RPC calls on a specific service of the remote server.
|
||||||
|
@ -272,7 +350,7 @@ class Connection(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
if not self.database or not self.login or self.password is None:
|
if not self.database or not self.login or self.password is None:
|
||||||
raise AuthenticationError("Creditentials not provided")
|
raise AuthenticationError("Credentials not provided")
|
||||||
|
|
||||||
self.user_id = self.get_service("common").login(self.database, self.login, self.password)
|
self.user_id = self.get_service("common").login(self.database, self.login, self.password)
|
||||||
if not self.user_id:
|
if not self.user_id:
|
||||||
|
@ -295,7 +373,7 @@ class Connection(object):
|
||||||
|
|
||||||
:param service_name: The name of the service.
|
:param service_name: The name of the service.
|
||||||
"""
|
"""
|
||||||
return Service(self.connector, service_name)
|
return self.connector.get_service(service_name)
|
||||||
|
|
||||||
class AuthenticationError(Exception):
|
class AuthenticationError(Exception):
|
||||||
"""
|
"""
|
||||||
|
@ -342,7 +420,7 @@ class Model(object):
|
||||||
index = {}
|
index = {}
|
||||||
for r in result:
|
for r in result:
|
||||||
index[r['id']] = r
|
index[r['id']] = r
|
||||||
result = [index[x] for x in args[0]]
|
result = [index[x] for x in args[0] if x in index]
|
||||||
self.__logger.debug('result: %r', result)
|
self.__logger.debug('result: %r', result)
|
||||||
return result
|
return result
|
||||||
return proxy
|
return proxy
|
||||||
|
@ -363,7 +441,7 @@ class Model(object):
|
||||||
records = self.read(record_ids, fields or [], context or {})
|
records = self.read(record_ids, fields or [], context or {})
|
||||||
return records
|
return records
|
||||||
|
|
||||||
def get_connector(hostname, protocol="xmlrpc", port="auto"):
|
def get_connector(hostname=None, protocol="xmlrpc", port="auto"):
|
||||||
"""
|
"""
|
||||||
A shortcut method to easily create a connector to a remote server using XMLRPC or NetRPC.
|
A shortcut method to easily create a connector to a remote server using XMLRPC or NetRPC.
|
||||||
|
|
||||||
|
@ -377,10 +455,12 @@ def get_connector(hostname, protocol="xmlrpc", port="auto"):
|
||||||
return XmlRPCConnector(hostname, port)
|
return XmlRPCConnector(hostname, port)
|
||||||
elif protocol == "netrpc":
|
elif protocol == "netrpc":
|
||||||
return NetRPCConnector(hostname, port)
|
return NetRPCConnector(hostname, port)
|
||||||
|
elif protocol == "local":
|
||||||
|
return LocalConnector()
|
||||||
else:
|
else:
|
||||||
raise ValueError("You must choose xmlrpc or netrpc")
|
raise ValueError("You must choose xmlrpc or netrpc or local")
|
||||||
|
|
||||||
def get_connection(hostname, protocol="xmlrpc", port='auto', database=None,
|
def get_connection(hostname=None, protocol="xmlrpc", port='auto', database=None,
|
||||||
login=None, password=None, user_id=None):
|
login=None, password=None, user_id=None):
|
||||||
"""
|
"""
|
||||||
A shortcut method to easily create a connection to a remote OpenERP server.
|
A shortcut method to easily create a connection to a remote OpenERP server.
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
import datetime
|
import datetime
|
||||||
import dateutil.relativedelta
|
import dateutil.relativedelta
|
||||||
|
import logging
|
||||||
import time
|
import time
|
||||||
import openerplib
|
import openerplib
|
||||||
|
|
||||||
import nonliterals
|
import nonliterals
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
#----------------------------------------------------------
|
#----------------------------------------------------------
|
||||||
# OpenERPSession RPC openerp backend access
|
# OpenERPSession RPC openerp backend access
|
||||||
#----------------------------------------------------------
|
#----------------------------------------------------------
|
||||||
|
|
||||||
class OpenERPSession(object):
|
class OpenERPSession(object):
|
||||||
"""
|
"""
|
||||||
An OpenERP RPC session, a given user can own multiple such sessions
|
An OpenERP RPC session, a given user can own multiple such sessions
|
||||||
|
@ -26,25 +28,26 @@ class OpenERPSession(object):
|
||||||
Used to store references to non-literal domains which need to be
|
Used to store references to non-literal domains which need to be
|
||||||
round-tripped to the client browser.
|
round-tripped to the client browser.
|
||||||
"""
|
"""
|
||||||
def __init__(self, server='127.0.0.1', port=8069):
|
def __init__(self):
|
||||||
self._server = server
|
self.config = None
|
||||||
self._port = port
|
|
||||||
self._db = False
|
self._db = False
|
||||||
self._uid = False
|
self._uid = False
|
||||||
self._login = False
|
self._login = False
|
||||||
self._password = False
|
self._password = False
|
||||||
self._locale = 'en_US'
|
|
||||||
self.context = {}
|
self.context = {}
|
||||||
self.contexts_store = {}
|
self.contexts_store = {}
|
||||||
self.domains_store = {}
|
self.domains_store = {}
|
||||||
self._lang = {}
|
|
||||||
self.remote_timezone = 'utc'
|
|
||||||
self.client_timezone = False
|
|
||||||
|
|
||||||
|
def __getstate__(self):
|
||||||
|
state = dict(self.__dict__)
|
||||||
|
if "config" in state:
|
||||||
|
del state['config']
|
||||||
|
return state
|
||||||
|
|
||||||
def build_connection(self):
|
def build_connection(self):
|
||||||
return openerplib.get_connection(hostname=self._server, port=self._port,
|
conn = openerplib.Connection(self.config.connector, database=self._db, login=self._login,
|
||||||
database=self._db, login=self._login,
|
user_id=self._uid, password=self._password)
|
||||||
user_id=self._uid, password=self._password)
|
return conn
|
||||||
|
|
||||||
def proxy(self, service):
|
def proxy(self, service):
|
||||||
return self.build_connection().get_service(service)
|
return self.build_connection().get_service(service)
|
||||||
|
@ -99,15 +102,6 @@ class OpenERPSession(object):
|
||||||
self.context = self.model('res.users').context_get(self.context)
|
self.context = self.model('res.users').context_get(self.context)
|
||||||
self.context = self.context or {}
|
self.context = self.context or {}
|
||||||
|
|
||||||
self.client_timezone = self.context.get("tz", False)
|
|
||||||
# invalid code, anyway we decided the server will be in UTC
|
|
||||||
#if self.client_timezone:
|
|
||||||
# self.remote_timezone = self.execute('common', 'timezone_get')
|
|
||||||
|
|
||||||
self._locale = self.context.get('lang','en_US')
|
|
||||||
lang_ids = self.execute('res.lang','search', [('code', '=', self._locale)])
|
|
||||||
if lang_ids:
|
|
||||||
self._lang = self.execute('res.lang', 'read',lang_ids[0], [])
|
|
||||||
return self.context
|
return self.context
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
# xml2json-direct
|
||||||
|
# Simple and straightforward XML-to-JSON converter in Python
|
||||||
|
# New BSD Licensed
|
||||||
|
#
|
||||||
|
# URL: http://code.google.com/p/xml2json-direct/
|
||||||
|
|
||||||
|
class Xml2Json(object):
|
||||||
|
@staticmethod
|
||||||
|
def convert_to_json(s):
|
||||||
|
return simplejson.dumps(
|
||||||
|
Xml2Json.convert_to_structure(s), sort_keys=True, indent=4)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def convert_to_structure(s):
|
||||||
|
root = ElementTree.fromstring(s)
|
||||||
|
return Xml2Json.convert_element(root)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def convert_element(el, skip_whitespaces=True):
|
||||||
|
res = {}
|
||||||
|
if el.tag[0] == "{":
|
||||||
|
ns, name = el.tag.rsplit("}", 1)
|
||||||
|
res["tag"] = name
|
||||||
|
res["namespace"] = ns[1:]
|
||||||
|
else:
|
||||||
|
res["tag"] = el.tag
|
||||||
|
res["attrs"] = {}
|
||||||
|
for k, v in el.items():
|
||||||
|
res["attrs"][k] = v
|
||||||
|
kids = []
|
||||||
|
if el.text and (not skip_whitespaces or el.text.strip() != ''):
|
||||||
|
kids.append(el.text)
|
||||||
|
for kid in el:
|
||||||
|
kids.append(Xml2Json.convert_element(kid))
|
||||||
|
if kid.tail and (not skip_whitespaces or kid.tail.strip() != ''):
|
||||||
|
kids.append(kid.tail)
|
||||||
|
res["children"] = kids
|
||||||
|
return res
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import ast
|
||||||
import base64
|
import base64
|
||||||
import csv
|
import csv
|
||||||
import glob
|
import glob
|
||||||
|
@ -8,76 +9,22 @@ import operator
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import simplejson
|
import simplejson
|
||||||
import textwrap
|
|
||||||
import xmlrpclib
|
|
||||||
import time
|
import time
|
||||||
|
import xmlrpclib
|
||||||
import zlib
|
import zlib
|
||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
|
|
||||||
from babel.messages.pofile import read_po
|
import babel.messages.pofile
|
||||||
|
|
||||||
import web.common.dispatch as openerpweb
|
import web.common
|
||||||
import web.common.ast
|
openerpweb = web.common.http
|
||||||
import web.common.nonliterals
|
|
||||||
import web.common.release
|
|
||||||
openerpweb.ast = web.common.ast
|
|
||||||
openerpweb.nonliterals = web.common.nonliterals
|
|
||||||
|
|
||||||
|
|
||||||
# Should move to openerpweb.Xml2Json
|
|
||||||
class Xml2Json:
|
|
||||||
# xml2json-direct
|
|
||||||
# Simple and straightforward XML-to-JSON converter in Python
|
|
||||||
# New BSD Licensed
|
|
||||||
#
|
|
||||||
# URL: http://code.google.com/p/xml2json-direct/
|
|
||||||
@staticmethod
|
|
||||||
def convert_to_json(s):
|
|
||||||
return simplejson.dumps(
|
|
||||||
Xml2Json.convert_to_structure(s), sort_keys=True, indent=4)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def convert_to_structure(s):
|
|
||||||
root = ElementTree.fromstring(s)
|
|
||||||
return Xml2Json.convert_element(root)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def convert_element(el, skip_whitespaces=True):
|
|
||||||
res = {}
|
|
||||||
if el.tag[0] == "{":
|
|
||||||
ns, name = el.tag.rsplit("}", 1)
|
|
||||||
res["tag"] = name
|
|
||||||
res["namespace"] = ns[1:]
|
|
||||||
else:
|
|
||||||
res["tag"] = el.tag
|
|
||||||
res["attrs"] = {}
|
|
||||||
for k, v in el.items():
|
|
||||||
res["attrs"][k] = v
|
|
||||||
kids = []
|
|
||||||
if el.text and (not skip_whitespaces or el.text.strip() != ''):
|
|
||||||
kids.append(el.text)
|
|
||||||
for kid in el:
|
|
||||||
kids.append(Xml2Json.convert_element(kid))
|
|
||||||
if kid.tail and (not skip_whitespaces or kid.tail.strip() != ''):
|
|
||||||
kids.append(kid.tail)
|
|
||||||
res["children"] = kids
|
|
||||||
return res
|
|
||||||
|
|
||||||
#----------------------------------------------------------
|
#----------------------------------------------------------
|
||||||
# OpenERP Web web Controllers
|
# OpenERP Web web Controllers
|
||||||
#----------------------------------------------------------
|
#----------------------------------------------------------
|
||||||
|
|
||||||
def manifest_glob(addons_path, addons, key):
|
def concat_files(file_list):
|
||||||
files = []
|
|
||||||
for addon in addons:
|
|
||||||
globlist = openerpweb.addons_manifest.get(addon, {}).get(key, [])
|
|
||||||
for pattern in globlist:
|
|
||||||
for path in glob.glob(os.path.join(addons_path, addon, pattern)):
|
|
||||||
files.append(path[len(addons_path):])
|
|
||||||
return files
|
|
||||||
|
|
||||||
def concat_files(addons_path, file_list):
|
|
||||||
""" Concatenate file content
|
""" Concatenate file content
|
||||||
return (concat,timestamp)
|
return (concat,timestamp)
|
||||||
concat: concatenation of file content
|
concat: concatenation of file content
|
||||||
|
@ -85,8 +32,7 @@ def concat_files(addons_path, file_list):
|
||||||
"""
|
"""
|
||||||
files_content = []
|
files_content = []
|
||||||
files_timestamp = 0
|
files_timestamp = 0
|
||||||
for i in file_list:
|
for fname in file_list:
|
||||||
fname = os.path.join(addons_path, i[1:])
|
|
||||||
ftime = os.path.getmtime(fname)
|
ftime = os.path.getmtime(fname)
|
||||||
if ftime > files_timestamp:
|
if ftime > files_timestamp:
|
||||||
files_timestamp = ftime
|
files_timestamp = ftime
|
||||||
|
@ -94,66 +40,88 @@ def concat_files(addons_path, file_list):
|
||||||
files_concat = "".join(files_content)
|
files_concat = "".join(files_content)
|
||||||
return files_concat,files_timestamp
|
return files_concat,files_timestamp
|
||||||
|
|
||||||
home_template = textwrap.dedent("""<!DOCTYPE html>
|
html_template = """<!DOCTYPE html>
|
||||||
<html style="height: 100%%">
|
<html style="height: 100%%">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||||
<title>OpenERP</title>
|
<title>OpenERP</title>
|
||||||
<link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/>
|
<link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/>
|
||||||
%(css)s
|
%(css)s
|
||||||
%(javascript)s
|
%(js)s
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(function() {
|
$(function() {
|
||||||
var c = new openerp.init();
|
var s = new openerp.init(%(modules)s);
|
||||||
var wc = new c.web.WebClient("oe");
|
%(init)s
|
||||||
wc.start();
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body id="oe" class="openerp"></body>
|
<body id="oe" class="openerp"></body>
|
||||||
</html>
|
</html>
|
||||||
""")
|
"""
|
||||||
|
|
||||||
class WebClient(openerpweb.Controller):
|
class WebClient(openerpweb.Controller):
|
||||||
_cp_path = "/web/webclient"
|
_cp_path = "/web/webclient"
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
def server_wide_modules(self, req):
|
||||||
def csslist(self, req, mods='web'):
|
addons = [i for i in req.config.server_wide_modules if i in openerpweb.addons_manifest]
|
||||||
return manifest_glob(req.config.addons_path, mods.split(','), 'css')
|
return addons
|
||||||
|
|
||||||
|
def manifest_glob(self, req, addons, key):
|
||||||
|
if addons is None:
|
||||||
|
addons = self.server_wide_modules(req)
|
||||||
|
else:
|
||||||
|
addons = addons.split(',')
|
||||||
|
for addon in addons:
|
||||||
|
manifest = openerpweb.addons_manifest.get(addon, None)
|
||||||
|
if not manifest:
|
||||||
|
continue
|
||||||
|
# ensure does not ends with /
|
||||||
|
addons_path = os.path.join(manifest['addons_path'], '')[:-1]
|
||||||
|
globlist = manifest.get(key, [])
|
||||||
|
for pattern in globlist:
|
||||||
|
for path in glob.glob(os.path.normpath(os.path.join(addons_path, addon, pattern))):
|
||||||
|
yield path, path[len(addons_path):]
|
||||||
|
|
||||||
|
def manifest_list(self, req, mods, extension):
|
||||||
|
if not req.debug:
|
||||||
|
path = '/web/webclient/' + extension
|
||||||
|
if mods is not None:
|
||||||
|
path += '?mods=' + mods
|
||||||
|
return [path]
|
||||||
|
return ['%s?debug=%s' % (wp, os.path.getmtime(fp)) for fp, wp in self.manifest_glob(req, mods, extension)]
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
def jslist(self, req, mods='web'):
|
def csslist(self, req, mods=None):
|
||||||
return manifest_glob(req.config.addons_path, mods.split(','), 'js')
|
return self.manifest_list(req, mods, 'css')
|
||||||
|
|
||||||
|
@openerpweb.jsonrequest
|
||||||
|
def jslist(self, req, mods=None):
|
||||||
|
return self.manifest_list(req, mods, 'js')
|
||||||
|
|
||||||
@openerpweb.httprequest
|
@openerpweb.httprequest
|
||||||
def css(self, req, mods='web'):
|
def css(self, req, mods=None):
|
||||||
files = manifest_glob(req.config.addons_path, mods.split(','), 'css')
|
files = [f[0] for f in self.manifest_glob(req, mods, 'css')]
|
||||||
content,timestamp = concat_files(req.config.addons_path, files)
|
content,timestamp = concat_files(files)
|
||||||
# TODO request set the Date of last modif and Etag
|
# TODO use timestamp to set Last mofified date and E-tag
|
||||||
return req.make_response(content, [('Content-Type', 'text/css')])
|
return req.make_response(content, [('Content-Type', 'text/css')])
|
||||||
|
|
||||||
@openerpweb.httprequest
|
@openerpweb.httprequest
|
||||||
def js(self, req, mods='web'):
|
def js(self, req, mods=None):
|
||||||
files = manifest_glob(req.config.addons_path, mods.split(','), 'js')
|
files = [f[0] for f in self.manifest_glob(req, mods, 'js')]
|
||||||
content,timestamp = concat_files(req.config.addons_path, files)
|
content,timestamp = concat_files(files)
|
||||||
# TODO request set the Date of last modif and Etag
|
# TODO use timestamp to set Last mofified date and E-tag
|
||||||
return req.make_response(content, [('Content-Type', 'application/javascript')])
|
return req.make_response(content, [('Content-Type', 'application/javascript')])
|
||||||
|
|
||||||
@openerpweb.httprequest
|
@openerpweb.httprequest
|
||||||
def home(self, req, s_action=None, **kw):
|
def home(self, req, s_action=None, **kw):
|
||||||
# script tags
|
js = "\n ".join('<script type="text/javascript" src="%s"></script>'%i for i in self.manifest_list(req, None, 'js'))
|
||||||
jslist = ['/web/webclient/js']
|
css = "\n ".join('<link rel="stylesheet" href="%s">'%i for i in self.manifest_list(req, None, 'css'))
|
||||||
if req.debug:
|
|
||||||
jslist = [i + '?debug=' + str(time.time()) for i in manifest_glob(req.config.addons_path, ['web'], 'js')]
|
|
||||||
js = "\n ".join(['<script type="text/javascript" src="%s"></script>'%i for i in jslist])
|
|
||||||
|
|
||||||
# css tags
|
r = html_template % {
|
||||||
csslist = ['/web/webclient/css']
|
'js': js,
|
||||||
if req.debug:
|
'css': css,
|
||||||
csslist = [i + '?debug=' + str(time.time()) for i in manifest_glob(req.config.addons_path, ['web'], 'css')]
|
'modules': simplejson.dumps(self.server_wide_modules(req)),
|
||||||
css = "\n ".join(['<link rel="stylesheet" href="%s">'%i for i in csslist])
|
'init': 'new s.web.WebClient("oe").start();',
|
||||||
r = home_template % {
|
|
||||||
'javascript': js,
|
|
||||||
'css': css
|
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
@ -166,25 +134,26 @@ class WebClient(openerpweb.Controller):
|
||||||
"grouping", "decimal_point", "thousands_sep"])
|
"grouping", "decimal_point", "thousands_sep"])
|
||||||
else:
|
else:
|
||||||
lang_obj = None
|
lang_obj = None
|
||||||
|
|
||||||
if lang.count("_") > 0:
|
if lang.count("_") > 0:
|
||||||
separator = "_"
|
separator = "_"
|
||||||
else:
|
else:
|
||||||
separator = "@"
|
separator = "@"
|
||||||
langs = lang.split(separator)
|
langs = lang.split(separator)
|
||||||
langs = [separator.join(langs[:x]) for x in range(1, len(langs) + 1)]
|
langs = [separator.join(langs[:x]) for x in range(1, len(langs) + 1)]
|
||||||
|
|
||||||
transs = {}
|
transs = {}
|
||||||
for addon_name in mods:
|
for addon_name in mods:
|
||||||
transl = {"messages":[]}
|
transl = {"messages":[]}
|
||||||
transs[addon_name] = transl
|
transs[addon_name] = transl
|
||||||
for l in langs:
|
for l in langs:
|
||||||
f_name = os.path.join(req.config.addons_path, addon_name, "po", l + ".po")
|
addons_path = openerpweb.addons_manifest[addon_name]['addons_path']
|
||||||
|
f_name = os.path.join(addons_path, addon_name, "po", l + ".po")
|
||||||
if not os.path.exists(f_name):
|
if not os.path.exists(f_name):
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
with open(f_name) as t_file:
|
with open(f_name) as t_file:
|
||||||
po = read_po(t_file)
|
po = babel.messages.pofile.read_po(t_file)
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
for x in po:
|
for x in po:
|
||||||
|
@ -240,7 +209,7 @@ class Database(openerpweb.Controller):
|
||||||
password, db = operator.itemgetter(
|
password, db = operator.itemgetter(
|
||||||
'drop_pwd', 'drop_db')(
|
'drop_pwd', 'drop_db')(
|
||||||
dict(map(operator.itemgetter('name', 'value'), fields)))
|
dict(map(operator.itemgetter('name', 'value'), fields)))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return req.session.proxy("db").drop(password, db)
|
return req.session.proxy("db").drop(password, db)
|
||||||
except xmlrpclib.Fault, e:
|
except xmlrpclib.Fault, e:
|
||||||
|
@ -299,6 +268,7 @@ class Session(openerpweb.Controller):
|
||||||
"context": ctx,
|
"context": ctx,
|
||||||
"db": req.session._db
|
"db": req.session._db
|
||||||
}
|
}
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
def get_session_info(self, req):
|
def get_session_info(self, req):
|
||||||
req.session.assert_valid(force=True)
|
req.session.assert_valid(force=True)
|
||||||
|
@ -307,6 +277,7 @@ class Session(openerpweb.Controller):
|
||||||
"context": req.session.get_context() if req.session._uid else False,
|
"context": req.session.get_context() if req.session._uid else False,
|
||||||
"db": req.session._db
|
"db": req.session._db
|
||||||
}
|
}
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
def change_password (self,req,fields):
|
def change_password (self,req,fields):
|
||||||
old_password, new_password,confirm_password = operator.itemgetter('old_pwd', 'new_password','confirm_pwd')(
|
old_password, new_password,confirm_password = operator.itemgetter('old_pwd', 'new_password','confirm_pwd')(
|
||||||
|
@ -322,6 +293,7 @@ class Session(openerpweb.Controller):
|
||||||
except:
|
except:
|
||||||
return {'error': 'Original password incorrect, your password was not changed.', 'title': 'Change Password'}
|
return {'error': 'Original password incorrect, your password was not changed.', 'title': 'Change Password'}
|
||||||
return {'error': 'Error, password not changed !', 'title': 'Change Password'}
|
return {'error': 'Error, password not changed !', 'title': 'Change Password'}
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
def sc_list(self, req):
|
def sc_list(self, req):
|
||||||
return req.session.model('ir.ui.view_sc').get_sc(
|
return req.session.model('ir.ui.view_sc').get_sc(
|
||||||
|
@ -336,15 +308,25 @@ class Session(openerpweb.Controller):
|
||||||
}
|
}
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
return {"error": e, "title": "Languages"}
|
return {"error": e, "title": "Languages"}
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
def modules(self, req):
|
def modules(self, req):
|
||||||
# TODO query server for installed web modules
|
# Compute available candidates module
|
||||||
mods = []
|
loadable = openerpweb.addons_manifest.iterkeys()
|
||||||
for name, manifest in openerpweb.addons_manifest.items():
|
loaded = req.config.server_wide_modules
|
||||||
if name != 'web' and manifest.get('active', True):
|
candidates = [mod for mod in loadable if mod not in loaded]
|
||||||
mods.append(name)
|
|
||||||
return mods
|
# Compute active true modules that might be on the web side only
|
||||||
|
active = set(name for name in candidates
|
||||||
|
if openerpweb.addons_manifest[name].get('active'))
|
||||||
|
|
||||||
|
# Retrieve database installed modules
|
||||||
|
Modules = req.session.model('ir.module.module')
|
||||||
|
installed = set(module['name'] for module in Modules.search_read(
|
||||||
|
[('state','=','installed'), ('name','in', candidates)], ['name']))
|
||||||
|
|
||||||
|
# Merge both
|
||||||
|
return list(active | installed)
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
def eval_domain_and_context(self, req, contexts, domains,
|
def eval_domain_and_context(self, req, contexts, domains,
|
||||||
|
@ -379,8 +361,8 @@ class Session(openerpweb.Controller):
|
||||||
no group by should be performed)
|
no group by should be performed)
|
||||||
"""
|
"""
|
||||||
context, domain = eval_context_and_domain(req.session,
|
context, domain = eval_context_and_domain(req.session,
|
||||||
openerpweb.nonliterals.CompoundContext(*(contexts or [])),
|
web.common.nonliterals.CompoundContext(*(contexts or [])),
|
||||||
openerpweb.nonliterals.CompoundDomain(*(domains or [])))
|
web.common.nonliterals.CompoundDomain(*(domains or [])))
|
||||||
|
|
||||||
group_by_sequence = []
|
group_by_sequence = []
|
||||||
for candidate in (group_by_seq or []):
|
for candidate in (group_by_seq or []):
|
||||||
|
@ -459,18 +441,27 @@ def load_actions_from_ir_values(req, key, key2, models, meta):
|
||||||
return [(id, name, clean_action(req, action))
|
return [(id, name, clean_action(req, action))
|
||||||
for id, name, action in actions]
|
for id, name, action in actions]
|
||||||
|
|
||||||
def clean_action(req, action):
|
def clean_action(req, action, do_not_eval=False):
|
||||||
action.setdefault('flags', {})
|
action.setdefault('flags', {})
|
||||||
|
|
||||||
context = req.session.eval_context(req.context)
|
context = req.session.eval_context(req.context)
|
||||||
eval_ctx = req.session.evaluation_context(context)
|
eval_ctx = req.session.evaluation_context(context)
|
||||||
|
|
||||||
# values come from the server, we can just eval them
|
if not do_not_eval:
|
||||||
if isinstance(action.get('context'), basestring):
|
# values come from the server, we can just eval them
|
||||||
action['context'] = eval( action['context'], eval_ctx ) or {}
|
if isinstance(action.get('context'), basestring):
|
||||||
|
action['context'] = eval( action['context'], eval_ctx ) or {}
|
||||||
|
|
||||||
|
if isinstance(action.get('domain'), basestring):
|
||||||
|
action['domain'] = eval( action['domain'], eval_ctx ) or []
|
||||||
|
else:
|
||||||
|
if 'context' in action:
|
||||||
|
action['context'] = parse_context(action['context'], req.session)
|
||||||
|
if 'domain' in action:
|
||||||
|
action['domain'] = parse_domain(action['domain'], req.session)
|
||||||
|
|
||||||
if isinstance(action.get('domain'), basestring):
|
if 'type' not in action:
|
||||||
action['domain'] = eval( action['domain'], eval_ctx ) or []
|
action['type'] = 'ir.actions.act_window_close'
|
||||||
|
|
||||||
if action['type'] == 'ir.actions.act_window':
|
if action['type'] == 'ir.actions.act_window':
|
||||||
return fix_view_modes(action)
|
return fix_view_modes(action)
|
||||||
|
@ -535,7 +526,7 @@ def fix_view_modes(action):
|
||||||
if 'views' not in action:
|
if 'views' not in action:
|
||||||
generate_views(action)
|
generate_views(action)
|
||||||
|
|
||||||
if action.pop('view_type') != 'form':
|
if action.pop('view_type', 'form') != 'form':
|
||||||
return action
|
return action
|
||||||
|
|
||||||
action['views'] = [
|
action['views'] = [
|
||||||
|
@ -715,7 +706,7 @@ class DataSet(openerpweb.Controller):
|
||||||
args[domain_id] = d
|
args[domain_id] = d
|
||||||
if context_id and len(args) - 1 >= context_id:
|
if context_id and len(args) - 1 >= context_id:
|
||||||
args[context_id] = c
|
args[context_id] = c
|
||||||
|
|
||||||
for i in xrange(len(args)):
|
for i in xrange(len(args)):
|
||||||
if isinstance(args[i], web.common.nonliterals.BaseContext):
|
if isinstance(args[i], web.common.nonliterals.BaseContext):
|
||||||
args[i] = req.session.eval_context(args[i])
|
args[i] = req.session.eval_context(args[i])
|
||||||
|
@ -794,16 +785,16 @@ class View(openerpweb.Controller):
|
||||||
xml = self.transform_view(arch, session, evaluation_context)
|
xml = self.transform_view(arch, session, evaluation_context)
|
||||||
else:
|
else:
|
||||||
xml = ElementTree.fromstring(arch)
|
xml = ElementTree.fromstring(arch)
|
||||||
fvg['arch'] = Xml2Json.convert_element(xml)
|
fvg['arch'] = web.common.xml2json.Xml2Json.convert_element(xml)
|
||||||
|
|
||||||
for field in fvg['fields'].itervalues():
|
for field in fvg['fields'].itervalues():
|
||||||
if field.get('views'):
|
if field.get('views'):
|
||||||
for view in field["views"].itervalues():
|
for view in field["views"].itervalues():
|
||||||
self.process_view(session, view, None, transform)
|
self.process_view(session, view, None, transform)
|
||||||
if field.get('domain'):
|
if field.get('domain'):
|
||||||
field["domain"] = self.parse_domain(field["domain"], session)
|
field["domain"] = parse_domain(field["domain"], session)
|
||||||
if field.get('context'):
|
if field.get('context'):
|
||||||
field["context"] = self.parse_context(field["context"], session)
|
field["context"] = parse_context(field["context"], session)
|
||||||
|
|
||||||
def process_toolbar(self, req, toolbar):
|
def process_toolbar(self, req, toolbar):
|
||||||
"""
|
"""
|
||||||
|
@ -815,10 +806,10 @@ class View(openerpweb.Controller):
|
||||||
for actions in toolbar.itervalues():
|
for actions in toolbar.itervalues():
|
||||||
for action in actions:
|
for action in actions:
|
||||||
if 'context' in action:
|
if 'context' in action:
|
||||||
action['context'] = self.parse_context(
|
action['context'] = parse_context(
|
||||||
action['context'], req.session)
|
action['context'], req.session)
|
||||||
if 'domain' in action:
|
if 'domain' in action:
|
||||||
action['domain'] = self.parse_domain(
|
action['domain'] = parse_domain(
|
||||||
action['domain'], req.session)
|
action['domain'], req.session)
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
|
@ -857,39 +848,6 @@ class View(openerpweb.Controller):
|
||||||
self.parse_domains_and_contexts(elem, session)
|
self.parse_domains_and_contexts(elem, session)
|
||||||
return root
|
return root
|
||||||
|
|
||||||
def parse_domain(self, domain, session):
|
|
||||||
""" Parses an arbitrary string containing a domain, transforms it
|
|
||||||
to either a literal domain or a :class:`openerpweb.nonliterals.Domain`
|
|
||||||
|
|
||||||
:param domain: the domain to parse, if the domain is not a string it
|
|
||||||
is assumed to be a literal domain and is returned as-is
|
|
||||||
:param session: Current OpenERP session
|
|
||||||
:type session: openerpweb.openerpweb.OpenERPSession
|
|
||||||
"""
|
|
||||||
if not isinstance(domain, (str, unicode)):
|
|
||||||
return domain
|
|
||||||
try:
|
|
||||||
return openerpweb.ast.literal_eval(domain)
|
|
||||||
except ValueError:
|
|
||||||
# not a literal
|
|
||||||
return openerpweb.nonliterals.Domain(session, domain)
|
|
||||||
|
|
||||||
def parse_context(self, context, session):
|
|
||||||
""" Parses an arbitrary string containing a context, transforms it
|
|
||||||
to either a literal context or a :class:`openerpweb.nonliterals.Context`
|
|
||||||
|
|
||||||
:param context: the context to parse, if the context is not a string it
|
|
||||||
is assumed to be a literal domain and is returned as-is
|
|
||||||
:param session: Current OpenERP session
|
|
||||||
:type session: openerpweb.openerpweb.OpenERPSession
|
|
||||||
"""
|
|
||||||
if not isinstance(context, (str, unicode)):
|
|
||||||
return context
|
|
||||||
try:
|
|
||||||
return openerpweb.ast.literal_eval(context)
|
|
||||||
except ValueError:
|
|
||||||
return openerpweb.nonliterals.Context(session, context)
|
|
||||||
|
|
||||||
def parse_domains_and_contexts(self, elem, session):
|
def parse_domains_and_contexts(self, elem, session):
|
||||||
""" Converts domains and contexts from the view into Python objects,
|
""" Converts domains and contexts from the view into Python objects,
|
||||||
either literals if they can be parsed by literal_eval or a special
|
either literals if they can be parsed by literal_eval or a special
|
||||||
|
@ -904,16 +862,49 @@ class View(openerpweb.Controller):
|
||||||
for el in ['domain', 'filter_domain']:
|
for el in ['domain', 'filter_domain']:
|
||||||
domain = elem.get(el, '').strip()
|
domain = elem.get(el, '').strip()
|
||||||
if domain:
|
if domain:
|
||||||
elem.set(el, self.parse_domain(domain, session))
|
elem.set(el, parse_domain(domain, session))
|
||||||
for el in ['context', 'default_get']:
|
for el in ['context', 'default_get']:
|
||||||
context_string = elem.get(el, '').strip()
|
context_string = elem.get(el, '').strip()
|
||||||
if context_string:
|
if context_string:
|
||||||
elem.set(el, self.parse_context(context_string, session))
|
elem.set(el, parse_context(context_string, session))
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
def load(self, req, model, view_id, view_type, toolbar=False):
|
def load(self, req, model, view_id, view_type, toolbar=False):
|
||||||
return self.fields_view_get(req, model, view_id, view_type, toolbar=toolbar)
|
return self.fields_view_get(req, model, view_id, view_type, toolbar=toolbar)
|
||||||
|
|
||||||
|
def parse_domain(domain, session):
|
||||||
|
""" Parses an arbitrary string containing a domain, transforms it
|
||||||
|
to either a literal domain or a :class:`web.common.nonliterals.Domain`
|
||||||
|
|
||||||
|
:param domain: the domain to parse, if the domain is not a string it
|
||||||
|
is assumed to be a literal domain and is returned as-is
|
||||||
|
:param session: Current OpenERP session
|
||||||
|
:type session: openerpweb.openerpweb.OpenERPSession
|
||||||
|
"""
|
||||||
|
if not isinstance(domain, (str, unicode)):
|
||||||
|
return domain
|
||||||
|
try:
|
||||||
|
return ast.literal_eval(domain)
|
||||||
|
except ValueError:
|
||||||
|
# not a literal
|
||||||
|
return web.common.nonliterals.Domain(session, domain)
|
||||||
|
|
||||||
|
def parse_context(context, session):
|
||||||
|
""" Parses an arbitrary string containing a context, transforms it
|
||||||
|
to either a literal context or a :class:`web.common.nonliterals.Context`
|
||||||
|
|
||||||
|
:param context: the context to parse, if the context is not a string it
|
||||||
|
is assumed to be a literal domain and is returned as-is
|
||||||
|
:param session: Current OpenERP session
|
||||||
|
:type session: openerpweb.openerpweb.OpenERPSession
|
||||||
|
"""
|
||||||
|
if not isinstance(context, (str, unicode)):
|
||||||
|
return context
|
||||||
|
try:
|
||||||
|
return ast.literal_eval(context)
|
||||||
|
except ValueError:
|
||||||
|
return web.common.nonliterals.Context(session, context)
|
||||||
|
|
||||||
class ListView(View):
|
class ListView(View):
|
||||||
_cp_path = "/web/listview"
|
_cp_path = "/web/listview"
|
||||||
|
|
||||||
|
@ -959,27 +950,27 @@ class SearchView(View):
|
||||||
for field in fields.values():
|
for field in fields.values():
|
||||||
# shouldn't convert the views too?
|
# shouldn't convert the views too?
|
||||||
if field.get('domain'):
|
if field.get('domain'):
|
||||||
field["domain"] = self.parse_domain(field["domain"], req.session)
|
field["domain"] = parse_domain(field["domain"], req.session)
|
||||||
if field.get('context'):
|
if field.get('context'):
|
||||||
field["context"] = self.parse_domain(field["context"], req.session)
|
field["context"] = parse_context(field["context"], req.session)
|
||||||
return {'fields': fields}
|
return {'fields': fields}
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
def get_filters(self, req, model):
|
def get_filters(self, req, model):
|
||||||
Model = req.session.model("ir.filters")
|
Model = req.session.model("ir.filters")
|
||||||
filters = Model.get_filters(model)
|
filters = Model.get_filters(model)
|
||||||
for filter in filters:
|
for filter in filters:
|
||||||
filter["context"] = req.session.eval_context(self.parse_context(filter["context"], req.session))
|
filter["context"] = req.session.eval_context(parse_context(filter["context"], req.session))
|
||||||
filter["domain"] = req.session.eval_domain(self.parse_domain(filter["domain"], req.session))
|
filter["domain"] = req.session.eval_domain(parse_domain(filter["domain"], req.session))
|
||||||
return filters
|
return filters
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
def save_filter(self, req, model, name, context_to_save, domain):
|
def save_filter(self, req, model, name, context_to_save, domain):
|
||||||
Model = req.session.model("ir.filters")
|
Model = req.session.model("ir.filters")
|
||||||
ctx = openerpweb.nonliterals.CompoundContext(context_to_save)
|
ctx = web.common.nonliterals.CompoundContext(context_to_save)
|
||||||
ctx.session = req.session
|
ctx.session = req.session
|
||||||
ctx = ctx.evaluate()
|
ctx = ctx.evaluate()
|
||||||
domain = openerpweb.nonliterals.CompoundDomain(domain)
|
domain = web.common.nonliterals.CompoundDomain(domain)
|
||||||
domain.session = req.session
|
domain.session = req.session
|
||||||
domain = domain.evaluate()
|
domain = domain.evaluate()
|
||||||
uid = req.session._uid
|
uid = req.session._uid
|
||||||
|
@ -1002,23 +993,27 @@ class Binary(openerpweb.Controller):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not id:
|
if not id:
|
||||||
res = Model.default_get([field], context).get(field, '')
|
res = Model.default_get([field], context).get(field)
|
||||||
else:
|
else:
|
||||||
res = Model.read([int(id)], [field], context)[0].get(field, '')
|
res = Model.read([int(id)], [field], context)[0].get(field)
|
||||||
image_data = base64.b64decode(res)
|
image_data = base64.b64decode(res)
|
||||||
except (TypeError, xmlrpclib.Fault):
|
except (TypeError, xmlrpclib.Fault):
|
||||||
image_data = self.placeholder(req)
|
image_data = self.placeholder(req)
|
||||||
return req.make_response(image_data, [
|
return req.make_response(image_data, [
|
||||||
('Content-Type', 'image/png'), ('Content-Length', len(image_data))])
|
('Content-Type', 'image/png'), ('Content-Length', len(image_data))])
|
||||||
def placeholder(self, req):
|
def placeholder(self, req):
|
||||||
return open(os.path.join(req.addons_path, 'web', 'static', 'src', 'img', 'placeholder.png'), 'rb').read()
|
addons_path = openerpweb.addons_manifest['web']['addons_path']
|
||||||
|
return open(os.path.join(addons_path, 'web', 'static', 'src', 'img', 'placeholder.png'), 'rb').read()
|
||||||
|
|
||||||
@openerpweb.httprequest
|
@openerpweb.httprequest
|
||||||
def saveas(self, req, model, id, field, fieldname, **kw):
|
def saveas(self, req, model, id, field, fieldname, **kw):
|
||||||
Model = req.session.model(model)
|
Model = req.session.model(model)
|
||||||
context = req.session.eval_context(req.context)
|
context = req.session.eval_context(req.context)
|
||||||
res = Model.read([int(id)], [field, fieldname], context)[0]
|
if id:
|
||||||
filecontent = res.get(field, '')
|
res = Model.read([int(id)], [field, fieldname], context)[0]
|
||||||
|
else:
|
||||||
|
res = Model.default_get([field, fieldname], context)
|
||||||
|
filecontent = base64.b64decode(res.get(field, ''))
|
||||||
if not filecontent:
|
if not filecontent:
|
||||||
return req.not_found()
|
return req.not_found()
|
||||||
else:
|
else:
|
||||||
|
@ -1082,7 +1077,7 @@ class Action(openerpweb.Controller):
|
||||||
_cp_path = "/web/action"
|
_cp_path = "/web/action"
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
def load(self, req, action_id):
|
def load(self, req, action_id, do_not_eval=False):
|
||||||
Actions = req.session.model('ir.actions.actions')
|
Actions = req.session.model('ir.actions.actions')
|
||||||
value = False
|
value = False
|
||||||
context = req.session.eval_context(req.context)
|
context = req.session.eval_context(req.context)
|
||||||
|
@ -1094,7 +1089,7 @@ class Action(openerpweb.Controller):
|
||||||
ctx.update(context)
|
ctx.update(context)
|
||||||
action = req.session.model(action_type[0]['type']).read([action_id], False, ctx)
|
action = req.session.model(action_type[0]['type']).read([action_id], False, ctx)
|
||||||
if action:
|
if action:
|
||||||
value = clean_action(req, action[0])
|
value = clean_action(req, action[0], do_not_eval)
|
||||||
return {'result': value}
|
return {'result': value}
|
||||||
|
|
||||||
@openerpweb.jsonrequest
|
@openerpweb.jsonrequest
|
||||||
|
@ -1370,7 +1365,7 @@ class Reports(View):
|
||||||
|
|
||||||
report_srv = req.session.proxy("report")
|
report_srv = req.session.proxy("report")
|
||||||
context = req.session.eval_context(
|
context = req.session.eval_context(
|
||||||
openerpweb.nonliterals.CompoundContext(
|
web.common.nonliterals.CompoundContext(
|
||||||
req.context or {}, action[ "context"]))
|
req.context or {}, action[ "context"]))
|
||||||
|
|
||||||
report_data = {}
|
report_data = {}
|
||||||
|
@ -1378,11 +1373,10 @@ class Reports(View):
|
||||||
if 'report_type' in action:
|
if 'report_type' in action:
|
||||||
report_data['report_type'] = action['report_type']
|
report_data['report_type'] = action['report_type']
|
||||||
if 'datas' in action:
|
if 'datas' in action:
|
||||||
if 'form' in action['datas']:
|
|
||||||
report_data['form'] = action['datas']['form']
|
|
||||||
if 'ids' in action['datas']:
|
if 'ids' in action['datas']:
|
||||||
report_ids = action['datas']['ids']
|
report_ids = action['datas'].pop('ids')
|
||||||
|
report_data.update(action['datas'])
|
||||||
|
|
||||||
report_id = report_srv.report(
|
report_id = report_srv.report(
|
||||||
req.session._db, req.session._uid, req.session._password,
|
req.session._db, req.session._uid, req.session._password,
|
||||||
action["report_name"], report_ids,
|
action["report_name"], report_ids,
|
||||||
|
@ -1394,6 +1388,7 @@ class Reports(View):
|
||||||
req.session._db, req.session._uid, req.session._password, report_id)
|
req.session._db, req.session._uid, req.session._password, report_id)
|
||||||
if report_struct["state"]:
|
if report_struct["state"]:
|
||||||
break
|
break
|
||||||
|
|
||||||
time.sleep(self.POLLING_DELAY)
|
time.sleep(self.POLLING_DELAY)
|
||||||
|
|
||||||
report = base64.b64decode(report_struct['result'])
|
report = base64.b64decode(report_struct['result'])
|
||||||
|
@ -1407,3 +1402,107 @@ class Reports(View):
|
||||||
('Content-Type', report_mimetype),
|
('Content-Type', report_mimetype),
|
||||||
('Content-Length', len(report))],
|
('Content-Length', len(report))],
|
||||||
cookies={'fileToken': int(token)})
|
cookies={'fileToken': int(token)})
|
||||||
|
|
||||||
|
class Import(View):
|
||||||
|
_cp_path = "/web/import"
|
||||||
|
|
||||||
|
def fields_get(self, req, model):
|
||||||
|
Model = req.session.model(model)
|
||||||
|
fields = Model.fields_get(False, req.session.eval_context(req.context))
|
||||||
|
return fields
|
||||||
|
|
||||||
|
@openerpweb.httprequest
|
||||||
|
def detect_data(self, req, csvfile, csvsep, csvdel, csvcode, jsonp):
|
||||||
|
try:
|
||||||
|
data = list(csv.reader(
|
||||||
|
csvfile, quotechar=str(csvdel), delimiter=str(csvsep)))
|
||||||
|
except csv.Error, e:
|
||||||
|
csvfile.seek(0)
|
||||||
|
return '<script>window.top.%s(%s);</script>' % (
|
||||||
|
jsonp, simplejson.dumps({'error': {
|
||||||
|
'message': 'Error parsing CSV file: %s' % e,
|
||||||
|
# decodes each byte to a unicode character, which may or
|
||||||
|
# may not be printable, but decoding will succeed.
|
||||||
|
# Otherwise simplejson will try to decode the `str` using
|
||||||
|
# utf-8, which is very likely to blow up on characters out
|
||||||
|
# of the ascii range (in range [128, 256))
|
||||||
|
'preview': csvfile.read(200).decode('iso-8859-1')}}))
|
||||||
|
|
||||||
|
try:
|
||||||
|
return '<script>window.top.%s(%s);</script>' % (
|
||||||
|
jsonp, simplejson.dumps(
|
||||||
|
{'records': data[:10]}, encoding=csvcode))
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
return '<script>window.top.%s(%s);</script>' % (
|
||||||
|
jsonp, simplejson.dumps({
|
||||||
|
'message': u"Failed to decode CSV file using encoding %s, "
|
||||||
|
u"try switching to a different encoding" % csvcode
|
||||||
|
}))
|
||||||
|
|
||||||
|
@openerpweb.httprequest
|
||||||
|
def import_data(self, req, model, csvfile, csvsep, csvdel, csvcode, jsonp,
|
||||||
|
meta):
|
||||||
|
modle_obj = req.session.model(model)
|
||||||
|
skip, indices, fields = operator.itemgetter('skip', 'indices', 'fields')(
|
||||||
|
simplejson.loads(meta))
|
||||||
|
|
||||||
|
error = None
|
||||||
|
if not (csvdel and len(csvdel) == 1):
|
||||||
|
error = u"The CSV delimiter must be a single character"
|
||||||
|
|
||||||
|
if not indices and fields:
|
||||||
|
error = u"You must select at least one field to import"
|
||||||
|
|
||||||
|
if error:
|
||||||
|
return '<script>window.top.%s(%s);</script>' % (
|
||||||
|
jsonp, simplejson.dumps({'error': {'message': error}}))
|
||||||
|
|
||||||
|
# skip ignored records
|
||||||
|
data_record = itertools.islice(
|
||||||
|
csv.reader(csvfile, quotechar=str(csvdel), delimiter=str(csvsep)),
|
||||||
|
skip, None)
|
||||||
|
|
||||||
|
# if only one index, itemgetter will return an atom rather than a tuple
|
||||||
|
if len(indices) == 1: mapper = lambda row: [row[indices[0]]]
|
||||||
|
else: mapper = operator.itemgetter(*indices)
|
||||||
|
|
||||||
|
data = None
|
||||||
|
error = None
|
||||||
|
try:
|
||||||
|
# decode each data row
|
||||||
|
data = [
|
||||||
|
[record.decode(csvcode) for record in row]
|
||||||
|
for row in itertools.imap(mapper, data_record)
|
||||||
|
# don't insert completely empty rows (can happen due to fields
|
||||||
|
# filtering in case of e.g. o2m content rows)
|
||||||
|
if any(row)
|
||||||
|
]
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
error = u"Failed to decode CSV file using encoding %s" % csvcode
|
||||||
|
except csv.Error, e:
|
||||||
|
error = u"Could not process CSV file: %s" % e
|
||||||
|
|
||||||
|
# If the file contains nothing,
|
||||||
|
if not data:
|
||||||
|
error = u"File to import is empty"
|
||||||
|
if error:
|
||||||
|
return '<script>window.top.%s(%s);</script>' % (
|
||||||
|
jsonp, simplejson.dumps({'error': {'message': error}}))
|
||||||
|
|
||||||
|
try:
|
||||||
|
(code, record, message, _nope) = modle_obj.import_data(
|
||||||
|
fields, data, 'init', '', False,
|
||||||
|
req.session.eval_context(req.context))
|
||||||
|
except xmlrpclib.Fault, e:
|
||||||
|
error = {"message": u"%s, %s" % (e.faultCode, e.faultString)}
|
||||||
|
return '<script>window.top.%s(%s);</script>' % (
|
||||||
|
jsonp, simplejson.dumps({'error':error}))
|
||||||
|
|
||||||
|
if code != -1:
|
||||||
|
return '<script>window.top.%s(%s);</script>' % (
|
||||||
|
jsonp, simplejson.dumps({'success':True}))
|
||||||
|
|
||||||
|
msg = u"Error during import: %s\n\nTrying to import record %r" % (
|
||||||
|
message, record)
|
||||||
|
return '<script>window.top.%s(%s);</script>' % (
|
||||||
|
jsonp, simplejson.dumps({'error': {'message':msg}}))
|
||||||
|
|
|
@ -0,0 +1,707 @@
|
||||||
|
# Danish translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-11 14:21+0000\n"
|
||||||
|
"Last-Translator: Jonas Mortensen <Unknown>\n"
|
||||||
|
"Language-Team: Danish <da@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-12 04:44+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14124)\n"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:355
|
||||||
|
msgid ""
|
||||||
|
"Warning, the record has been modified, your changes will be discarded."
|
||||||
|
msgstr ""
|
||||||
|
"Advarsel, registreringen er blevet ændret, dine ændringer vil derfor blive "
|
||||||
|
"kasseret."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1659
|
||||||
|
msgid "<em> Search More...</em>"
|
||||||
|
msgstr "<em> Søg efter mere....</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1672
|
||||||
|
#, python-format
|
||||||
|
msgid "<em> Create \"<strong>%s</strong>\"</em>"
|
||||||
|
msgstr "<em> Create \"<strong>%s</strong>\"</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1678
|
||||||
|
msgid "<em> Create and Edit...</em>"
|
||||||
|
msgstr "<em> Opret og rediger...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:568
|
||||||
|
msgid "You must choose at least one record."
|
||||||
|
msgstr "Du skal vælge mindst en registrering."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:569
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Advarsel"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:609
|
||||||
|
msgid "Translations"
|
||||||
|
msgstr "Oversættelser"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save"
|
||||||
|
msgstr "Gem"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:615
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Luk"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "x"
|
||||||
|
msgstr "x"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{title}"
|
||||||
|
msgstr "#(titel)"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{text}"
|
||||||
|
msgstr "#(tekst)"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Powered by"
|
||||||
|
msgstr "Drevet af"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "openerp.com"
|
||||||
|
msgstr "openerp.com"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "."
|
||||||
|
msgstr ","
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Loading..."
|
||||||
|
msgstr "Indlæser..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create"
|
||||||
|
msgstr "Opret"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Drop"
|
||||||
|
msgstr "Drop"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Backup"
|
||||||
|
msgstr "Sikkerhedskopi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Restore"
|
||||||
|
msgstr "Gendan"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "Adgangskode"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Back to Login"
|
||||||
|
msgstr "Tilbage til log ind"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CREATE DATABASE"
|
||||||
|
msgstr "OPRET DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master password:"
|
||||||
|
msgstr "Hovedadgangskode"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New database name:"
|
||||||
|
msgstr "Nyt database navn:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Load Demonstration data:"
|
||||||
|
msgstr "Indlæs demonstrations data:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Default language:"
|
||||||
|
msgstr "Standardsprog:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Admin password:"
|
||||||
|
msgstr "Administrators adgangskode:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm password:"
|
||||||
|
msgstr "Bekræft adgangskode:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "DROP DATABASE"
|
||||||
|
msgstr "SLET DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database:"
|
||||||
|
msgstr "Database:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master Password:"
|
||||||
|
msgstr "Hovedadgangskode"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "BACKUP DATABASE"
|
||||||
|
msgstr "SIKKERHEDSKOPIER DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "RESTORE DATABASE"
|
||||||
|
msgstr "GENDAN DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "File:"
|
||||||
|
msgstr "Fil:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CHANGE MASTER PASSWORD"
|
||||||
|
msgstr "Skift hovedadgangskode"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New master password:"
|
||||||
|
msgstr "Ny hovedadgangskode"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm new master password:"
|
||||||
|
msgstr "Bekræft ny hovedadgangskode"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User:"
|
||||||
|
msgstr "Bruger:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr "Adgangskode:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database"
|
||||||
|
msgstr "Database"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Login"
|
||||||
|
msgstr "Log ind"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Bad username or password"
|
||||||
|
msgstr "Forkert brugernavn eller adgangskode"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"We think that daily job activities can be more intuitive, efficient, "
|
||||||
|
"automated, .. and even fun."
|
||||||
|
msgstr ""
|
||||||
|
"Vi tror at daglige arbejdsaktiviteter kan blive mere intuitive, effektive og "
|
||||||
|
"automatiserede, .. and even fun."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP's vision to be:"
|
||||||
|
msgstr "OpenERP´s vision at være:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Full featured"
|
||||||
|
msgstr "Fuldt udbygget"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Today's enterprise challenges are multiple. We provide one module for each "
|
||||||
|
"need."
|
||||||
|
msgstr ""
|
||||||
|
"Udfordringer det stilles til nutidens virksomheder er blevet store. Vi "
|
||||||
|
"leverer moduler til et hvert behov."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open Source"
|
||||||
|
msgstr "Open source"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"To Build a great product, we rely on the knowledge of thousands of "
|
||||||
|
"contributors."
|
||||||
|
msgstr ""
|
||||||
|
"For at bygge et godt produkt, stoler vi på viden fra tusindevis af "
|
||||||
|
"bidragydere."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User Friendly"
|
||||||
|
msgstr "Brugervenlig"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"In order to be productive, people need clean and easy to use interface."
|
||||||
|
msgstr "For at være produktiv kræves et nemt og brugervenligt interface."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "("
|
||||||
|
msgstr "("
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ")"
|
||||||
|
msgstr ")"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "LOGOUT"
|
||||||
|
msgstr "LOG UD"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "«"
|
||||||
|
msgstr "«"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "»"
|
||||||
|
msgstr "»"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_menu_item"
|
||||||
|
msgstr "oe_secondary_menu_item"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_submenu_item"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Hide this tip"
|
||||||
|
msgstr "Skjul dette tip"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Disable all tips"
|
||||||
|
msgstr "Deaktiver alle tips"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View#"
|
||||||
|
msgstr "View#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields"
|
||||||
|
msgstr "Felter"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View labels"
|
||||||
|
msgstr "Vis etiketter"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Sidebar Relates"
|
||||||
|
msgstr "Relaterede til Sidebare"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Field"
|
||||||
|
msgstr "Felt"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ":"
|
||||||
|
msgstr ":"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate view"
|
||||||
|
msgstr "Se oversættelse"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate sidebar"
|
||||||
|
msgstr "Oversæt sidebar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "Slet"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "First"
|
||||||
|
msgstr "Første"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<"
|
||||||
|
msgstr "<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">"
|
||||||
|
msgstr ">"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Last"
|
||||||
|
msgstr "Sidste"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "♻"
|
||||||
|
msgstr "♻"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Edit"
|
||||||
|
msgstr "Gem & Rediger"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create & Edit"
|
||||||
|
msgstr "Opret & Rediger"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New"
|
||||||
|
msgstr "Ny"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Duplicate"
|
||||||
|
msgstr "Duplikér"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Readonly/Editable"
|
||||||
|
msgstr "Skrivebeskyttet/redigerbar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<<"
|
||||||
|
msgstr "<<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "0"
|
||||||
|
msgstr "0"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "/"
|
||||||
|
msgstr "/"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">>"
|
||||||
|
msgstr ">>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "Tilføj"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Unhandled widget"
|
||||||
|
msgstr "Ubehandlet widget"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "?"
|
||||||
|
msgstr "?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#"
|
||||||
|
msgstr "#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Done"
|
||||||
|
msgstr "Udført"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open..."
|
||||||
|
msgstr "Åbn..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create..."
|
||||||
|
msgstr "Opret..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Search..."
|
||||||
|
msgstr "Søg..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "..."
|
||||||
|
msgstr "..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Uploading ..."
|
||||||
|
msgstr "Uploader ..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Select"
|
||||||
|
msgstr "Markér"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save As"
|
||||||
|
msgstr "Gem Som"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Clear"
|
||||||
|
msgstr "Ryd"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Advanced Filter"
|
||||||
|
msgstr "Avanceret filtrering"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Filters --"
|
||||||
|
msgstr "-- Filtreringer --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Actions --"
|
||||||
|
msgstr "-- Handlinger --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save Filter"
|
||||||
|
msgstr "Gem filter"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Manage Filters"
|
||||||
|
msgstr "Administrer Filtre"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Filter Name:"
|
||||||
|
msgstr "Filter Navn:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "(Any existing filter with the same name will be replaced)"
|
||||||
|
msgstr "(Et hvert filter med samme navn vil blive overskrevet)"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Any of the following conditions must match"
|
||||||
|
msgstr "Enhver af de følgende betingelser skal være opfyldt"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "All the following conditions must match"
|
||||||
|
msgstr "Alle de følgende betingelser skal være opfyldt"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "None of the following conditions must match"
|
||||||
|
msgstr "Ingen af de følgende betingelser skal være opfyldt"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add condition"
|
||||||
|
msgstr "Tilføj betingelse"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "and"
|
||||||
|
msgstr "og"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Annullér"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & New"
|
||||||
|
msgstr "Gem & Ny"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Close"
|
||||||
|
msgstr "Gem & Luk"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export"
|
||||||
|
msgstr "Eksportér"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"This wizard will export all data that matches the current search criteria to "
|
||||||
|
"a CSV file.\n"
|
||||||
|
" You can export all data or only the fields that can be "
|
||||||
|
"reimported after modification."
|
||||||
|
msgstr ""
|
||||||
|
"Denne guide vil eksportere alle de data der passe på de nuværende "
|
||||||
|
"søgekriterier til en CSV file.\n"
|
||||||
|
" Du kan eksportere alle data eller kun de felter der kan "
|
||||||
|
"genimporteres efter ændring."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Type:"
|
||||||
|
msgstr "Eksporteringstype:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Compatible Export"
|
||||||
|
msgstr "Importer Kompatibel Eksport"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export all Data"
|
||||||
|
msgstr "Eksporter alt Data"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Formats"
|
||||||
|
msgstr "Eksporter formater"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Available fields"
|
||||||
|
msgstr "Tilgængelige felter"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields to export"
|
||||||
|
msgstr "Felter der kan eksporteres"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save fields list"
|
||||||
|
msgstr "Gem listen med felter"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Fjern"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove All"
|
||||||
|
msgstr "Fjern alle"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Navn"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save as:"
|
||||||
|
msgstr "Gem som:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Ok"
|
||||||
|
msgstr "Ok"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Saved exports:"
|
||||||
|
msgstr "Gem eksporteringer"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Old Password:"
|
||||||
|
msgstr "Gammel adgangskode:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New Password:"
|
||||||
|
msgstr "Ny adgangskode:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm Password:"
|
||||||
|
msgstr "Bekræft adgangskode:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Importér"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "1. Import a .CSV file"
|
||||||
|
msgstr "1. Importér en .CSV fil"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Select a .CSV file to import. If you need a sample of file to import,\n"
|
||||||
|
" you should use the export tool with the \"Import Compatible\" option."
|
||||||
|
msgstr ""
|
||||||
|
"Vælg en .CSV fil som du vil importere. Hvis du har brug et udsnit af filen "
|
||||||
|
"som du importere,\n"
|
||||||
|
" skal du bruge eksporteringsværktøjet med valgmuligheden \"Import "
|
||||||
|
"kompatibilitet\"."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CSV File:"
|
||||||
|
msgstr "CSV Fil:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "2. Check your file format"
|
||||||
|
msgstr "2. Kontroller dit filformat"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Options"
|
||||||
|
msgstr "Importeringsindstillinger"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Does your file have titles?"
|
||||||
|
msgstr "Har din fil titler?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Separator:"
|
||||||
|
msgstr "Adskiller:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delimiter:"
|
||||||
|
msgstr "Begrænsning"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Encoding:"
|
||||||
|
msgstr "Kodning:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "UTF-8"
|
||||||
|
msgstr "UTF-8"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Latin 1"
|
||||||
|
msgstr "Latin 1"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Lines to skip"
|
||||||
|
msgstr "Linier, der springes over"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "The import failed due to:"
|
||||||
|
msgstr "Importeringen fejlede som følge af:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Here is a preview of the file we could not import:"
|
||||||
|
msgstr "Her er et preview of af filen som vi ikke kunne importere:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP Web"
|
||||||
|
msgstr "OpenERP Web"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Version"
|
||||||
|
msgstr "Udgave"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||||
|
msgstr "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP is a trademark of the"
|
||||||
|
msgstr "OpenERP er et varemærke af"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP SA Company"
|
||||||
|
msgstr "OpenERP SA Company"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Licenced under the terms of"
|
||||||
|
msgstr "Licenseret i henhold til"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "GNU Affero General Public License"
|
||||||
|
msgstr "GNU Affero General Public License"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "About OpenERP"
|
||||||
|
msgstr "Om OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP"
|
||||||
|
msgstr "OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"is a free enterprise-scale software system that is designed to boost\n"
|
||||||
|
" productivity and profit through data integration. It connects, "
|
||||||
|
"improves and\n"
|
||||||
|
" manages business processes in areas such as sales, finance, "
|
||||||
|
"supply chain,\n"
|
||||||
|
" project management, production, services, CRM, etc..."
|
||||||
|
msgstr ""
|
||||||
|
"er et gratis enterprise-scale software system, der er designet til at øge \n"
|
||||||
|
" produktivitet og profit via dataintegration. Systemet forbinder, "
|
||||||
|
"forbedrer og \n"
|
||||||
|
" håndterer forretningsprocesser inden for områder som salg, "
|
||||||
|
"økonomi, forsyningskæder, \n"
|
||||||
|
" projektledelse, produktion, service, CRM, etc..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"The system is platform-independent, and can be installed on Windows, Mac OS "
|
||||||
|
"X,\n"
|
||||||
|
" and various Linux and other Unix-based distributions. Its "
|
||||||
|
"architecture enables\n"
|
||||||
|
" new functionality to be rapidly created, modifications to be "
|
||||||
|
"made to a\n"
|
||||||
|
" production system and migration to a new version to be "
|
||||||
|
"straightforward."
|
||||||
|
msgstr ""
|
||||||
|
"Systemet er uafhængigt af bestemte platforme, og kan installeres på Windows, "
|
||||||
|
"Mac OS X,\n"
|
||||||
|
" og forskellige Linux og andre Unix-baserede distributioner. "
|
||||||
|
"Systemets arkitektur gør det\n"
|
||||||
|
" lige til at lave nye funktionaliteter,modifikationer til et\n"
|
||||||
|
" produktionssystem og migrere til nye vrsioner."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Depending on your needs, OpenERP is available through a web or application "
|
||||||
|
"client."
|
||||||
|
msgstr ""
|
||||||
|
"Afhængig af dine behov, er OpenERP tilgængelig igennem en web- eller "
|
||||||
|
"applikationsklient."
|
|
@ -0,0 +1,708 @@
|
||||||
|
# German translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-10 20:59+0000\n"
|
||||||
|
"Last-Translator: Felix Schubert <Unknown>\n"
|
||||||
|
"Language-Team: German <de@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14123)\n"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:355
|
||||||
|
msgid ""
|
||||||
|
"Warning, the record has been modified, your changes will be discarded."
|
||||||
|
msgstr ""
|
||||||
|
"Achtung der Datensatz wurde bearbeitet, alle Änderungen werden verworfen!"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1659
|
||||||
|
msgid "<em> Search More...</em>"
|
||||||
|
msgstr "<em> Suche mehr...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1672
|
||||||
|
#, python-format
|
||||||
|
msgid "<em> Create \"<strong>%s</strong>\"</em>"
|
||||||
|
msgstr "<em> Anlegen \"<strong>%s</strong>\"</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1678
|
||||||
|
msgid "<em> Create and Edit...</em>"
|
||||||
|
msgstr "<em> Anlegen und Bearbeiten...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:568
|
||||||
|
msgid "You must choose at least one record."
|
||||||
|
msgstr "Sie müssen mindestens einen Datensatz auswählen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:569
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Warnung!"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:609
|
||||||
|
msgid "Translations"
|
||||||
|
msgstr "Übersetzungen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save"
|
||||||
|
msgstr "Speichern"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:615
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Schließen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "x"
|
||||||
|
msgstr "x"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{title}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{text}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Powered by"
|
||||||
|
msgstr "unterstützt durch"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "openerp.com"
|
||||||
|
msgstr "openerp.com"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "."
|
||||||
|
msgstr "."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Loading..."
|
||||||
|
msgstr "Lade..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create"
|
||||||
|
msgstr "Erzeugen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Drop"
|
||||||
|
msgstr "Löschen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Backup"
|
||||||
|
msgstr "Sichern"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Restore"
|
||||||
|
msgstr "Wiederherstellen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "Passwort"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Back to Login"
|
||||||
|
msgstr "Zurück zur Anmeldung"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CREATE DATABASE"
|
||||||
|
msgstr "Datenbank anlegen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master password:"
|
||||||
|
msgstr "Master Passwort"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New database name:"
|
||||||
|
msgstr "Name der neuen Datenbank:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Load Demonstration data:"
|
||||||
|
msgstr "Beispieldaten laden:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Default language:"
|
||||||
|
msgstr "Standardsprache:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Admin password:"
|
||||||
|
msgstr "Admin Passwort"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm password:"
|
||||||
|
msgstr "Passwort wiederholen:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "DROP DATABASE"
|
||||||
|
msgstr "Datenbank löschen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database:"
|
||||||
|
msgstr "Datenbank:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master Password:"
|
||||||
|
msgstr "Master Passwort"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "BACKUP DATABASE"
|
||||||
|
msgstr "Datenbank sichern"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "RESTORE DATABASE"
|
||||||
|
msgstr "Datenbank wiederherstellen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "File:"
|
||||||
|
msgstr "Datei:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CHANGE MASTER PASSWORD"
|
||||||
|
msgstr "Master Passwort ändern"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New master password:"
|
||||||
|
msgstr "Neues Master Passwort:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm new master password:"
|
||||||
|
msgstr "Bestätigen Sie das neue Master Passwort:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User:"
|
||||||
|
msgstr "Benutzer:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr "Passwort:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database"
|
||||||
|
msgstr "Datenbank"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Login"
|
||||||
|
msgstr "Anmeldung"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Bad username or password"
|
||||||
|
msgstr "Falscher Benutzername oder Passwort"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"We think that daily job activities can be more intuitive, efficient, "
|
||||||
|
"automated, .. and even fun."
|
||||||
|
msgstr ""
|
||||||
|
"Wir sind der Überzeugung, das die tägliche Arbeit intuitiver, effizienter, "
|
||||||
|
"automatisierter und mit mehr Spaß verbunden sein kann."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP's vision to be:"
|
||||||
|
msgstr "OpenERP's Vision ist:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Full featured"
|
||||||
|
msgstr "vollständiges"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Today's enterprise challenges are multiple. We provide one module for each "
|
||||||
|
"need."
|
||||||
|
msgstr ""
|
||||||
|
"Die heutigen Unternehmensherausforderungen sind vielfältig. Wir bieten Ihnen "
|
||||||
|
"ein Modul für jede Anforderung."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open Source"
|
||||||
|
msgstr "Open Source"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"To Build a great product, we rely on the knowledge of thousands of "
|
||||||
|
"contributors."
|
||||||
|
msgstr ""
|
||||||
|
"Um ein grossartiges Produkt bereitzustellen, vertrauen wir auf das Wissen "
|
||||||
|
"von Tausenden von Unterstützern"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User Friendly"
|
||||||
|
msgstr "Benutzerfreundlich"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"In order to be productive, people need clean and easy to use interface."
|
||||||
|
msgstr ""
|
||||||
|
"Um produktiv arbeiten zu können, benötigen die Mitarbeiter eine einfache und "
|
||||||
|
"klar strukturierte Oberfläche."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "("
|
||||||
|
msgstr "("
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ")"
|
||||||
|
msgstr ")"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "LOGOUT"
|
||||||
|
msgstr "Abmeldung"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "«"
|
||||||
|
msgstr "«"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "»"
|
||||||
|
msgstr "»"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_menu_item"
|
||||||
|
msgstr "oe_secondary_menu_item"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_submenu_item"
|
||||||
|
msgstr "oe_secondary_submenu_item"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Hide this tip"
|
||||||
|
msgstr "Tip verbergen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Disable all tips"
|
||||||
|
msgstr "Deaktiviere alle Tipps"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View#"
|
||||||
|
msgstr "Ansicht#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields"
|
||||||
|
msgstr "Felder"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View labels"
|
||||||
|
msgstr "Feldbeschreibung anzeigen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Sidebar Relates"
|
||||||
|
msgstr "Seitenleiste bezieht sich auf"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Field"
|
||||||
|
msgstr "Feld"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ":"
|
||||||
|
msgstr ":"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate view"
|
||||||
|
msgstr "Übersetungsansicht"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate sidebar"
|
||||||
|
msgstr "Seitenleiste übersetzen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "Löschen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "First"
|
||||||
|
msgstr "Erste"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<"
|
||||||
|
msgstr "<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">"
|
||||||
|
msgstr ">"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Last"
|
||||||
|
msgstr "Ende"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "♻"
|
||||||
|
msgstr "♻"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Edit"
|
||||||
|
msgstr "Sichern & Bearbeiten"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create & Edit"
|
||||||
|
msgstr "Anlegen & Bearbeiten"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New"
|
||||||
|
msgstr "Neu"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Duplicate"
|
||||||
|
msgstr "Kopieren"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Readonly/Editable"
|
||||||
|
msgstr "Lesezugriff/Bearbeitbar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<<"
|
||||||
|
msgstr "<<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "0"
|
||||||
|
msgstr "0"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "/"
|
||||||
|
msgstr "/"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">>"
|
||||||
|
msgstr ">>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "Hinzufügen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Unhandled widget"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "?"
|
||||||
|
msgstr "?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#"
|
||||||
|
msgstr "Nr."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Done"
|
||||||
|
msgstr "Abgeschlossen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open..."
|
||||||
|
msgstr "Öffnen …"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create..."
|
||||||
|
msgstr "Erzeugen …"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Search..."
|
||||||
|
msgstr "Suchen ..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "..."
|
||||||
|
msgstr "…"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Uploading ..."
|
||||||
|
msgstr "Hochladen ..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Select"
|
||||||
|
msgstr "Auswählen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save As"
|
||||||
|
msgstr "Speichern unter"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Clear"
|
||||||
|
msgstr "Leeren"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Advanced Filter"
|
||||||
|
msgstr "Erweiterter Filter"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Filters --"
|
||||||
|
msgstr "-- Filter --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Actions --"
|
||||||
|
msgstr "-- Aktionen --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save Filter"
|
||||||
|
msgstr "Filter speichern"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Manage Filters"
|
||||||
|
msgstr "Filter verwalten"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Filter Name:"
|
||||||
|
msgstr "Filter Name:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "(Any existing filter with the same name will be replaced)"
|
||||||
|
msgstr "(Jeder existierende Filter mit dem selben Namen wird ersetzt)"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Any of the following conditions must match"
|
||||||
|
msgstr "Eine der folgenden Bedingungen muss zutreffen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "All the following conditions must match"
|
||||||
|
msgstr "Alle der folgenden Bedingungen müssen zutreffen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "None of the following conditions must match"
|
||||||
|
msgstr "Keine der folgenden Bedingungen müssen zutreffen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add condition"
|
||||||
|
msgstr "Bedingung hinzufügen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "and"
|
||||||
|
msgstr "und"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Abbrechen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & New"
|
||||||
|
msgstr "Speichern & Neu"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Close"
|
||||||
|
msgstr "Speichern & Beenden"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export"
|
||||||
|
msgstr "Export"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"This wizard will export all data that matches the current search criteria to "
|
||||||
|
"a CSV file.\n"
|
||||||
|
" You can export all data or only the fields that can be "
|
||||||
|
"reimported after modification."
|
||||||
|
msgstr ""
|
||||||
|
"Dieser Assistent wird alle Daten in eine CSV exportieren, die den aktuellen "
|
||||||
|
"Suchbedingungen entsprechen.\n"
|
||||||
|
" Sie können alle Daten oder nur die Felder exportieren, die nach einer "
|
||||||
|
"Bearbeitung wieder importiert werden können."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Type:"
|
||||||
|
msgstr "Export Typ:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Compatible Export"
|
||||||
|
msgstr "Importiere kompatible Exportfelder"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export all Data"
|
||||||
|
msgstr "Alle Daten exportieren"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Formats"
|
||||||
|
msgstr "Export Formate"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Available fields"
|
||||||
|
msgstr "Verfügbare Felder"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields to export"
|
||||||
|
msgstr "Zu exportierende Felder"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save fields list"
|
||||||
|
msgstr "Feldliste speichern"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Löschen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove All"
|
||||||
|
msgstr "Alle löschen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Name"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save as:"
|
||||||
|
msgstr "Speichern unter:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Ok"
|
||||||
|
msgstr "Ok"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Saved exports:"
|
||||||
|
msgstr "Gespeicherte Exporte:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Old Password:"
|
||||||
|
msgstr "Altes Passwort:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New Password:"
|
||||||
|
msgstr "Neues Passwort:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm Password:"
|
||||||
|
msgstr "Passwort bestätigen:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Import"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "1. Import a .CSV file"
|
||||||
|
msgstr "1. Importiere eine .CSV Datei"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Select a .CSV file to import. If you need a sample of file to import,\n"
|
||||||
|
" you should use the export tool with the \"Import Compatible\" option."
|
||||||
|
msgstr ""
|
||||||
|
"Wählen Sie eine CSV Datei aus, die Sie importieren möchten. Wenn Sie eine "
|
||||||
|
"Beispieldatei benötigen,\n"
|
||||||
|
" sollten Sie beim Export die Option \"Import-Kompatibel\" wählen."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CSV File:"
|
||||||
|
msgstr "CSV Datei:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "2. Check your file format"
|
||||||
|
msgstr "2. Überprüfen Sie das Dateiformat"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Options"
|
||||||
|
msgstr "Import-Einstellungen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Does your file have titles?"
|
||||||
|
msgstr "Enthält Ihre Datei eine Titel Zeile?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Separator:"
|
||||||
|
msgstr "Trennzeichen:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delimiter:"
|
||||||
|
msgstr "Feldtrenner:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Encoding:"
|
||||||
|
msgstr "Zeichenkodierung:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "UTF-8"
|
||||||
|
msgstr "UTF-8"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Latin 1"
|
||||||
|
msgstr "Latin 1"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Lines to skip"
|
||||||
|
msgstr "Zu überspringende Zeilen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "The import failed due to:"
|
||||||
|
msgstr "Der Import schlug fehl, da:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Here is a preview of the file we could not import:"
|
||||||
|
msgstr "Hier ist eine Vorschau der Datei die nicht importiert werden konnte"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP Web"
|
||||||
|
msgstr "OpenERP Web"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Version"
|
||||||
|
msgstr "Version"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||||
|
msgstr "Copyright © 2011 OpenERP SA. Alle Rechte vorbehalten."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP is a trademark of the"
|
||||||
|
msgstr "OpenERP ist eine Marke der"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP SA Company"
|
||||||
|
msgstr "OpenERP SA"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Licenced under the terms of"
|
||||||
|
msgstr "Lizensiert unter den Bedingungen der"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "GNU Affero General Public License"
|
||||||
|
msgstr "GNU Affero General Public License"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "About OpenERP"
|
||||||
|
msgstr "Über OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP"
|
||||||
|
msgstr "OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"is a free enterprise-scale software system that is designed to boost\n"
|
||||||
|
" productivity and profit through data integration. It connects, "
|
||||||
|
"improves and\n"
|
||||||
|
" manages business processes in areas such as sales, finance, "
|
||||||
|
"supply chain,\n"
|
||||||
|
" project management, production, services, CRM, etc..."
|
||||||
|
msgstr ""
|
||||||
|
"ist eine freie und skalierbare Unternehmenssoftware, die folgende "
|
||||||
|
"Unternehmensprozesse beschleunigt\n"
|
||||||
|
"Produktivität und Umsatz aufgrund der integrierten Datenhaltung. Sie "
|
||||||
|
"verbindet, verbessert und\n"
|
||||||
|
"verwaltet Geschäftsprozesse in den Geschäftsfeldern Vertrieb, Finanzen, "
|
||||||
|
"Lieferketten,\n"
|
||||||
|
"Projektmanagement, Produktion, Produktunterstützung, CRM, usw..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"The system is platform-independent, and can be installed on Windows, Mac OS "
|
||||||
|
"X,\n"
|
||||||
|
" and various Linux and other Unix-based distributions. Its "
|
||||||
|
"architecture enables\n"
|
||||||
|
" new functionality to be rapidly created, modifications to be "
|
||||||
|
"made to a\n"
|
||||||
|
" production system and migration to a new version to be "
|
||||||
|
"straightforward."
|
||||||
|
msgstr ""
|
||||||
|
"Das System ist plattform-unabhängig und kann unter Windows, Mac OS X,\n"
|
||||||
|
"vielen Linux-Derivaten und anderen Unix-basierten Betriebssystem betrieben "
|
||||||
|
"werden. Seine Architektur ermöglicht\n"
|
||||||
|
"neue Funktionen schnell zu entwickeln, Anpassungen an einem produktiven "
|
||||||
|
"System vorzunehmen\n"
|
||||||
|
"und Migrationen auf neue Releases schnell umzusetzen."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Depending on your needs, OpenERP is available through a web or application "
|
||||||
|
"client."
|
||||||
|
msgstr ""
|
||||||
|
"Abhängig von Ihren Systemanforderungen, steht OpenERP entweder als "
|
||||||
|
"eigenständiger Client oder als webbasierte Anwendung zur Verfügung."
|
|
@ -0,0 +1,710 @@
|
||||||
|
# Spanish translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-19 07:27+0000\n"
|
||||||
|
"Last-Translator: Amós Oviedo <Unknown>\n"
|
||||||
|
"Language-Team: Spanish <es@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14165)\n"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:355
|
||||||
|
msgid ""
|
||||||
|
"Warning, the record has been modified, your changes will be discarded."
|
||||||
|
msgstr ""
|
||||||
|
"Advertencia, el registro se ha modificado, los cambios serán descartados."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1659
|
||||||
|
msgid "<em> Search More...</em>"
|
||||||
|
msgstr "<em> Buscar más...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1672
|
||||||
|
#, python-format
|
||||||
|
msgid "<em> Create \"<strong>%s</strong>\"</em>"
|
||||||
|
msgstr "<em> Crear \"<strong>%s</strong>\"</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1678
|
||||||
|
msgid "<em> Create and Edit...</em>"
|
||||||
|
msgstr "<em> Crear y Editar...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:568
|
||||||
|
msgid "You must choose at least one record."
|
||||||
|
msgstr "Debe seleccionar al menos un registro."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:569
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Advertencia"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:609
|
||||||
|
msgid "Translations"
|
||||||
|
msgstr "Traducciones"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save"
|
||||||
|
msgstr "Guardar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:615
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Cerrar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "x"
|
||||||
|
msgstr "x"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{title}"
|
||||||
|
msgstr "#{title}"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{text}"
|
||||||
|
msgstr "#{text}"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Powered by"
|
||||||
|
msgstr "Desarrollado por"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "openerp.com"
|
||||||
|
msgstr "openerp.com"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "."
|
||||||
|
msgstr "."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Loading..."
|
||||||
|
msgstr "Cargando…"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create"
|
||||||
|
msgstr "Crear"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Drop"
|
||||||
|
msgstr "Eliminar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Backup"
|
||||||
|
msgstr "Copia de seguridad"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Restore"
|
||||||
|
msgstr "Restaurar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "Contraseña"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Back to Login"
|
||||||
|
msgstr "Volver al Inicio de sesión"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CREATE DATABASE"
|
||||||
|
msgstr "CREAR BASE DE DATOS"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master password:"
|
||||||
|
msgstr "Contraseña maestra"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New database name:"
|
||||||
|
msgstr "Nombre de la nueva base de datos:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Load Demonstration data:"
|
||||||
|
msgstr "Cargar datos de demostración:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Default language:"
|
||||||
|
msgstr "Idioma por defecto:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Admin password:"
|
||||||
|
msgstr "Contraseña de Admin:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm password:"
|
||||||
|
msgstr "Confirmar contraseña:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "DROP DATABASE"
|
||||||
|
msgstr "ELIMINAR BASE DE DATOS"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database:"
|
||||||
|
msgstr "Base de datos:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master Password:"
|
||||||
|
msgstr "Contraseña Maestra"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "BACKUP DATABASE"
|
||||||
|
msgstr "COPIA DE SEGURIDAD DE LA BASE DE DATOS"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "RESTORE DATABASE"
|
||||||
|
msgstr "RESTAURAR BASE DE DATOS"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "File:"
|
||||||
|
msgstr "Archivo:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CHANGE MASTER PASSWORD"
|
||||||
|
msgstr "CAMBIAR CONTRASEÑA MAESTRA"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New master password:"
|
||||||
|
msgstr "Nueva contraseña maestra:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm new master password:"
|
||||||
|
msgstr "Confirmar nueva contraseña maestra:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User:"
|
||||||
|
msgstr "Usuario:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr "Contraseña:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database"
|
||||||
|
msgstr "Database"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Login"
|
||||||
|
msgstr "Inicio de sesión"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Bad username or password"
|
||||||
|
msgstr "Nombre de usuario o contraseña incorrectos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"We think that daily job activities can be more intuitive, efficient, "
|
||||||
|
"automated, .. and even fun."
|
||||||
|
msgstr ""
|
||||||
|
"Creemos que las actividades diarias de trabajo pueden ser más intuitivas, "
|
||||||
|
"eficientes y automatizadas, .. e incluso divertidas."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP's vision to be:"
|
||||||
|
msgstr "Los objetivos de OpenERP son ser:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Full featured"
|
||||||
|
msgstr "Con todas las funciones"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Today's enterprise challenges are multiple. We provide one module for each "
|
||||||
|
"need."
|
||||||
|
msgstr ""
|
||||||
|
"Los retos actuales de la empresa son múltiples. Ofrecemos un módulo para "
|
||||||
|
"cada necesidad."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open Source"
|
||||||
|
msgstr "Código abierto"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"To Build a great product, we rely on the knowledge of thousands of "
|
||||||
|
"contributors."
|
||||||
|
msgstr ""
|
||||||
|
"Para construir un gran producto, contamos con los conocimientos de miles de "
|
||||||
|
"contribuyentes."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User Friendly"
|
||||||
|
msgstr "Fácil de usar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"In order to be productive, people need clean and easy to use interface."
|
||||||
|
msgstr ""
|
||||||
|
"Con el fin de ser productivo, la gente necesita una interfaz clara y fácil "
|
||||||
|
"de usar."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "("
|
||||||
|
msgstr "("
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ")"
|
||||||
|
msgstr ")"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "LOGOUT"
|
||||||
|
msgstr "CERRAR SESIÓN"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "«"
|
||||||
|
msgstr "«"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "»"
|
||||||
|
msgstr "»"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_menu_item"
|
||||||
|
msgstr "oe_secondary_menu_item"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_submenu_item"
|
||||||
|
msgstr "oe_secondary_submenu_item"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Hide this tip"
|
||||||
|
msgstr "Ocultar esta sugerencia"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Disable all tips"
|
||||||
|
msgstr "Desactivar todas las sugerencias"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View#"
|
||||||
|
msgstr "Vista#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields"
|
||||||
|
msgstr "Campos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View labels"
|
||||||
|
msgstr "Ver etiquetas"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Sidebar Relates"
|
||||||
|
msgstr "Se relaciona con la barra lateral"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Field"
|
||||||
|
msgstr "Campo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ":"
|
||||||
|
msgstr ":"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate view"
|
||||||
|
msgstr "Traducir vista"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate sidebar"
|
||||||
|
msgstr "Traducir barra lateral"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "Borrar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "First"
|
||||||
|
msgstr "Primero"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<"
|
||||||
|
msgstr "<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">"
|
||||||
|
msgstr ">"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Last"
|
||||||
|
msgstr "Último"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "♻"
|
||||||
|
msgstr "♻"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Edit"
|
||||||
|
msgstr "Guardar y Editar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create & Edit"
|
||||||
|
msgstr "Crear y Editar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New"
|
||||||
|
msgstr "Nuevo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Duplicate"
|
||||||
|
msgstr "Duplicar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Readonly/Editable"
|
||||||
|
msgstr "Sólo Lectura/Editable"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<<"
|
||||||
|
msgstr "<<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "0"
|
||||||
|
msgstr "0"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "/"
|
||||||
|
msgstr "/"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">>"
|
||||||
|
msgstr ">>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "Añadir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Unhandled widget"
|
||||||
|
msgstr "Widget no controlado"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "?"
|
||||||
|
msgstr "?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#"
|
||||||
|
msgstr "#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Done"
|
||||||
|
msgstr "Hecho"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open..."
|
||||||
|
msgstr "Abrir..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create..."
|
||||||
|
msgstr "Crear…"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Search..."
|
||||||
|
msgstr "Buscar..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "..."
|
||||||
|
msgstr "..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Uploading ..."
|
||||||
|
msgstr "Subiendo ..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Select"
|
||||||
|
msgstr "Seleccionar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save As"
|
||||||
|
msgstr "Guardar como"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Clear"
|
||||||
|
msgstr "Limpiar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Advanced Filter"
|
||||||
|
msgstr "Filtro Avanzado"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Filters --"
|
||||||
|
msgstr "-- Filtros --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Actions --"
|
||||||
|
msgstr "-- Acciones --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save Filter"
|
||||||
|
msgstr "Guardar Filtro"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Manage Filters"
|
||||||
|
msgstr "Gestionar Filtros"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Filter Name:"
|
||||||
|
msgstr "Nombre del Filtro"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "(Any existing filter with the same name will be replaced)"
|
||||||
|
msgstr "(Cualquier filtro existente con el mismo nombre será reemplazado)"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Any of the following conditions must match"
|
||||||
|
msgstr "Cualquiera de las condiciones siguientes deben coincidir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "All the following conditions must match"
|
||||||
|
msgstr "Todas las condiciones siguientes deben coincidir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "None of the following conditions must match"
|
||||||
|
msgstr "Ninguna de las siguientes condiciones deben coincidir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add condition"
|
||||||
|
msgstr "Añadir condición"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "and"
|
||||||
|
msgstr "y"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Cancelar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & New"
|
||||||
|
msgstr "Guardar y Nuevo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Close"
|
||||||
|
msgstr "Guardar y Cerrar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export"
|
||||||
|
msgstr "Exportar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"This wizard will export all data that matches the current search criteria to "
|
||||||
|
"a CSV file.\n"
|
||||||
|
" You can export all data or only the fields that can be "
|
||||||
|
"reimported after modification."
|
||||||
|
msgstr ""
|
||||||
|
"Este asistente le exportará todos los datos que coincidan con los criterios "
|
||||||
|
"de búsqueda actual a un archivo CSV.\n"
|
||||||
|
" Puede exportar todos los datos o sólo los campos que pueden "
|
||||||
|
"importarse de nuevo después de la modificación."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Type:"
|
||||||
|
msgstr "Tipo de Exportación:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Compatible Export"
|
||||||
|
msgstr "Exportación compatible con importación"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export all Data"
|
||||||
|
msgstr "Exportar todos los datos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Formats"
|
||||||
|
msgstr "Formatos de Exportación"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Available fields"
|
||||||
|
msgstr "Campos disponibles"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields to export"
|
||||||
|
msgstr "Campos a exportar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save fields list"
|
||||||
|
msgstr "Guardar lista de campos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Eliminar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove All"
|
||||||
|
msgstr "Eliminar Todo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Nombre"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save as:"
|
||||||
|
msgstr "Guardar como:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Ok"
|
||||||
|
msgstr "Ok"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Saved exports:"
|
||||||
|
msgstr "Exportaciones guardadas:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Old Password:"
|
||||||
|
msgstr "Contraseña anterior:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New Password:"
|
||||||
|
msgstr "Contraseña nueva:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm Password:"
|
||||||
|
msgstr "Confirmar la contraseña:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Importar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "1. Import a .CSV file"
|
||||||
|
msgstr "1. Importar un archivo .CSV"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Select a .CSV file to import. If you need a sample of file to import,\n"
|
||||||
|
" you should use the export tool with the \"Import Compatible\" option."
|
||||||
|
msgstr ""
|
||||||
|
"Seleccione un archivo .CSV para importar. Si necesita una muestra de archivo "
|
||||||
|
"para importar,\n"
|
||||||
|
" debería usar la herramienta de exportación con la opción de "
|
||||||
|
"\"Importación Compatible\"."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CSV File:"
|
||||||
|
msgstr "Archivo CSV:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "2. Check your file format"
|
||||||
|
msgstr "2. Compruebe el formato de archivo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Options"
|
||||||
|
msgstr "Opciones de importación"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Does your file have titles?"
|
||||||
|
msgstr "¿Tiene su archivo títulos?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Separator:"
|
||||||
|
msgstr "Separador:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delimiter:"
|
||||||
|
msgstr "Delimitador:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Encoding:"
|
||||||
|
msgstr "Codificación:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "UTF-8"
|
||||||
|
msgstr "UTF-8"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Latin 1"
|
||||||
|
msgstr "Latin 1"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Lines to skip"
|
||||||
|
msgstr "Líneas a omitir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "The import failed due to:"
|
||||||
|
msgstr "La importación falló debido a:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Here is a preview of the file we could not import:"
|
||||||
|
msgstr "Esta es una vista previa del archivo que no se pudo importar:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP Web"
|
||||||
|
msgstr "OpenERP Web"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Version"
|
||||||
|
msgstr "Versión"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||||
|
msgstr "Copyright © 2011-HOY OpenERP SA. Todos los Derechos Reservados."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP is a trademark of the"
|
||||||
|
msgstr "OpenERP es una marca registrada de la"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP SA Company"
|
||||||
|
msgstr "Compañía OpenERP SA"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Licenced under the terms of"
|
||||||
|
msgstr "Con licencia bajo los términos de"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "GNU Affero General Public License"
|
||||||
|
msgstr "GNU Affero General Public License"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "About OpenERP"
|
||||||
|
msgstr "Acerca de OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP"
|
||||||
|
msgstr "OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"is a free enterprise-scale software system that is designed to boost\n"
|
||||||
|
" productivity and profit through data integration. It connects, "
|
||||||
|
"improves and\n"
|
||||||
|
" manages business processes in areas such as sales, finance, "
|
||||||
|
"supply chain,\n"
|
||||||
|
" project management, production, services, CRM, etc..."
|
||||||
|
msgstr ""
|
||||||
|
"Es un sistema software empresarial-escalar libre diseñado para mejorar\n"
|
||||||
|
" la productividad y beneficios a través de la integración de "
|
||||||
|
"datos. Conecta, mejora y\n"
|
||||||
|
" gestiona los procesos de negocio en áreas como ventas, finanzas, "
|
||||||
|
"cadena de suministro,\n"
|
||||||
|
" gestión de proyectos, producción, servicios, CRM, etc..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"The system is platform-independent, and can be installed on Windows, Mac OS "
|
||||||
|
"X,\n"
|
||||||
|
" and various Linux and other Unix-based distributions. Its "
|
||||||
|
"architecture enables\n"
|
||||||
|
" new functionality to be rapidly created, modifications to be "
|
||||||
|
"made to a\n"
|
||||||
|
" production system and migration to a new version to be "
|
||||||
|
"straightforward."
|
||||||
|
msgstr ""
|
||||||
|
"El sistema es una plataforma-independiente, y puede ser instalada en "
|
||||||
|
"Windows, Mac OS X,\n"
|
||||||
|
" y varias distribuciones Linux y otra basadas en Unix. Su "
|
||||||
|
"arquitectura permite\n"
|
||||||
|
" crear nuevas funcionalidades rápidamente, las modificaciones a "
|
||||||
|
"hacer en un\n"
|
||||||
|
" sistema en producción y migración a una nueva versión son "
|
||||||
|
"sencillas."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Depending on your needs, OpenERP is available through a web or application "
|
||||||
|
"client."
|
||||||
|
msgstr ""
|
||||||
|
"Según sus necesidades, OpenERP está disponible mediante un cliente web o una "
|
||||||
|
"aplicación de escritorio."
|
|
@ -0,0 +1,710 @@
|
||||||
|
# Spanish (Ecuador) translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-07 18:16+0000\n"
|
||||||
|
"Last-Translator: Cristian Salamea (Gnuthink) <ovnicraft@gmail.com>\n"
|
||||||
|
"Language-Team: Spanish (Ecuador) <es_EC@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-08 05:29+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14110)\n"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:355
|
||||||
|
msgid ""
|
||||||
|
"Warning, the record has been modified, your changes will be discarded."
|
||||||
|
msgstr ""
|
||||||
|
"Aviso, el registro ha sido modificado, sus cambios serán descartados."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1659
|
||||||
|
msgid "<em> Search More...</em>"
|
||||||
|
msgstr "<em> Buscar Más...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1672
|
||||||
|
#, python-format
|
||||||
|
msgid "<em> Create \"<strong>%s</strong>\"</em>"
|
||||||
|
msgstr "<em> Crear \"<strong>%s</strong>\"</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1678
|
||||||
|
msgid "<em> Create and Edit...</em>"
|
||||||
|
msgstr "<em> Crear y Editar...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:568
|
||||||
|
msgid "You must choose at least one record."
|
||||||
|
msgstr "Debe seleccionar al menos un registro."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:569
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Advertencia"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:609
|
||||||
|
msgid "Translations"
|
||||||
|
msgstr "Traducciones"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save"
|
||||||
|
msgstr "Guardar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:615
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Cerrar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "x"
|
||||||
|
msgstr "x"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{title}"
|
||||||
|
msgstr "#{title}"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{text}"
|
||||||
|
msgstr "#{text}"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Powered by"
|
||||||
|
msgstr "Powered by"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "openerp.com"
|
||||||
|
msgstr "openerp.com"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "."
|
||||||
|
msgstr "."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Loading..."
|
||||||
|
msgstr "Cargando..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create"
|
||||||
|
msgstr "Crear"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Drop"
|
||||||
|
msgstr "Borrar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Backup"
|
||||||
|
msgstr "Respaldar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Restore"
|
||||||
|
msgstr "Restaurar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "Contraseña"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Back to Login"
|
||||||
|
msgstr "Regresar a inicio de sesión"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CREATE DATABASE"
|
||||||
|
msgstr "CREATE DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master password:"
|
||||||
|
msgstr "Master password:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New database name:"
|
||||||
|
msgstr "Nuevo nombre de la base de datos:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Load Demonstration data:"
|
||||||
|
msgstr "Cargar datos de demostración"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Default language:"
|
||||||
|
msgstr "Lenguaje por defecto:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Admin password:"
|
||||||
|
msgstr "Admin password:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm password:"
|
||||||
|
msgstr "Confirmar password:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "DROP DATABASE"
|
||||||
|
msgstr "DROP DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database:"
|
||||||
|
msgstr "Base de datos:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master Password:"
|
||||||
|
msgstr "Master Password:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "BACKUP DATABASE"
|
||||||
|
msgstr "BACKUP DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "RESTORE DATABASE"
|
||||||
|
msgstr "RESTORE DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "File:"
|
||||||
|
msgstr "Archivo:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CHANGE MASTER PASSWORD"
|
||||||
|
msgstr "CHANGE MASTER PASSWORD"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New master password:"
|
||||||
|
msgstr "New master password:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm new master password:"
|
||||||
|
msgstr "Confirmar nueva master password:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User:"
|
||||||
|
msgstr "Usuario:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr "Contraseña:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database"
|
||||||
|
msgstr "Bases de datos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Login"
|
||||||
|
msgstr "Iniciar sesión"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Bad username or password"
|
||||||
|
msgstr "Usuario o contraseña incorrectos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"We think that daily job activities can be more intuitive, efficient, "
|
||||||
|
"automated, .. and even fun."
|
||||||
|
msgstr ""
|
||||||
|
"Pensamos que el trabajo diario debe ser mas intuitivo, eficiente, "
|
||||||
|
"automatizado, ... e incluso divertido."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP's vision to be:"
|
||||||
|
msgstr "OpenERP's vision to be:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Full featured"
|
||||||
|
msgstr "Full featured"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Today's enterprise challenges are multiple. We provide one module for each "
|
||||||
|
"need."
|
||||||
|
msgstr ""
|
||||||
|
"Today's enterprise challenges are multiple. We provide one module for each "
|
||||||
|
"need."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open Source"
|
||||||
|
msgstr "Open Source"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"To Build a great product, we rely on the knowledge of thousands of "
|
||||||
|
"contributors."
|
||||||
|
msgstr ""
|
||||||
|
"To Build a great product, we rely on the knowledge of thousands of "
|
||||||
|
"contributors."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User Friendly"
|
||||||
|
msgstr "User Friendly"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"In order to be productive, people need clean and easy to use interface."
|
||||||
|
msgstr ""
|
||||||
|
"Para ser productivo, los usuarios necesitan una interfaz limpia y fácil de "
|
||||||
|
"usar."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "("
|
||||||
|
msgstr "("
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ")"
|
||||||
|
msgstr ")"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "LOGOUT"
|
||||||
|
msgstr "LOGOUT"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "«"
|
||||||
|
msgstr "«"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "»"
|
||||||
|
msgstr "»"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_menu_item"
|
||||||
|
msgstr "oe_secondary_menu_item"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_submenu_item"
|
||||||
|
msgstr "oe_secondary_submenu_item"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Hide this tip"
|
||||||
|
msgstr "Ocultar este tip"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Disable all tips"
|
||||||
|
msgstr "Desactivar todas las sugerencias"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View#"
|
||||||
|
msgstr "View#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields"
|
||||||
|
msgstr "Campos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View labels"
|
||||||
|
msgstr "Ver etiquetas"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Sidebar Relates"
|
||||||
|
msgstr "Columna lateral relacionada"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Field"
|
||||||
|
msgstr "Campo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ":"
|
||||||
|
msgstr ":"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate view"
|
||||||
|
msgstr "Traducir vista"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate sidebar"
|
||||||
|
msgstr "Traducir Barra lateral"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "Eliminar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "First"
|
||||||
|
msgstr "Primero"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<"
|
||||||
|
msgstr "<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">"
|
||||||
|
msgstr ">"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Last"
|
||||||
|
msgstr "Último"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "♻"
|
||||||
|
msgstr "♻"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Edit"
|
||||||
|
msgstr "Grabar & Editar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create & Edit"
|
||||||
|
msgstr "Crear & Editar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New"
|
||||||
|
msgstr "Nuevo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Duplicate"
|
||||||
|
msgstr "Duplicar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Readonly/Editable"
|
||||||
|
msgstr "Sólo Lectura/Editable"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<<"
|
||||||
|
msgstr "<<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "0"
|
||||||
|
msgstr "0"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "/"
|
||||||
|
msgstr "/"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">>"
|
||||||
|
msgstr ">>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "Agregar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Unhandled widget"
|
||||||
|
msgstr "Wdiget no controlado"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "?"
|
||||||
|
msgstr "?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#"
|
||||||
|
msgstr "#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Done"
|
||||||
|
msgstr "Realizado"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open..."
|
||||||
|
msgstr "Abrir…"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create..."
|
||||||
|
msgstr "Crear..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Search..."
|
||||||
|
msgstr "Buscar..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "..."
|
||||||
|
msgstr "..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Uploading ..."
|
||||||
|
msgstr "Subiendo..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Select"
|
||||||
|
msgstr "Seleccionar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save As"
|
||||||
|
msgstr "Guardar Como"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Clear"
|
||||||
|
msgstr "Limpiar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Advanced Filter"
|
||||||
|
msgstr "Filtro Avanzado"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Filters --"
|
||||||
|
msgstr "-- Filtros --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Actions --"
|
||||||
|
msgstr "-- Acciones --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save Filter"
|
||||||
|
msgstr "Guardar Filtro"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Manage Filters"
|
||||||
|
msgstr "Gestionar filtros"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Filter Name:"
|
||||||
|
msgstr "Nombre del Filtro:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "(Any existing filter with the same name will be replaced)"
|
||||||
|
msgstr "(Cualquier filtro existente con el mismo nombre será reemplazado)"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Any of the following conditions must match"
|
||||||
|
msgstr "Cualquiera de las siguientes condiciones debe coincidir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "All the following conditions must match"
|
||||||
|
msgstr "Todas las siguientes condiciones deben coincidir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "None of the following conditions must match"
|
||||||
|
msgstr "Ninguna de las siguientes condiciones debe coincidir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add condition"
|
||||||
|
msgstr "Agregar condición"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "and"
|
||||||
|
msgstr "y"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Cancelar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & New"
|
||||||
|
msgstr "Grabar & Nuevo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Close"
|
||||||
|
msgstr "Grabar & Cerrar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export"
|
||||||
|
msgstr "Exportar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"This wizard will export all data that matches the current search criteria to "
|
||||||
|
"a CSV file.\n"
|
||||||
|
" You can export all data or only the fields that can be "
|
||||||
|
"reimported after modification."
|
||||||
|
msgstr ""
|
||||||
|
"Este asistente exportará todos los datos que coincidan con el criterio de "
|
||||||
|
"búsqueda actual a un archivo CSV.\n"
|
||||||
|
" Tu puedes exportar todos los datos o solo los campos que serán "
|
||||||
|
"reimportados después de la modificación."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Type:"
|
||||||
|
msgstr "Tipo de Exportación"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Compatible Export"
|
||||||
|
msgstr "Import Compatible Export"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export all Data"
|
||||||
|
msgstr "Exportar todos los datos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Formats"
|
||||||
|
msgstr "Formato para exportar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Available fields"
|
||||||
|
msgstr "Campos disponibles"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields to export"
|
||||||
|
msgstr "Campos a exportar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save fields list"
|
||||||
|
msgstr "Guardar lista de campos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Eliminar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove All"
|
||||||
|
msgstr "Borrar todo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Nombre"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save as:"
|
||||||
|
msgstr "Guardar Como:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Ok"
|
||||||
|
msgstr "Ok"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Saved exports:"
|
||||||
|
msgstr "Exportaciones guardadas:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Old Password:"
|
||||||
|
msgstr "Password anterior:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New Password:"
|
||||||
|
msgstr "Nueva Password:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm Password:"
|
||||||
|
msgstr "Confirmar Password:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Importar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "1. Import a .CSV file"
|
||||||
|
msgstr "1. Importar a archivo .CSV"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Select a .CSV file to import. If you need a sample of file to import,\n"
|
||||||
|
" you should use the export tool with the \"Import Compatible\" option."
|
||||||
|
msgstr ""
|
||||||
|
"Seleccionar un .archivo CSV para importar. Si necesitas un ejemplo de un "
|
||||||
|
"archivo para importar,\n"
|
||||||
|
" you podrías usar la herramienta de exportar con la opción de "
|
||||||
|
"\"Compatible con Importación\"."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CSV File:"
|
||||||
|
msgstr "Archivo CSV:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "2. Check your file format"
|
||||||
|
msgstr "Revisa tu formato de archivo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Options"
|
||||||
|
msgstr "Opciones para importar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Does your file have titles?"
|
||||||
|
msgstr "Tiene tu archivo títulos ?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Separator:"
|
||||||
|
msgstr "Separador:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delimiter:"
|
||||||
|
msgstr "Delimitador:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Encoding:"
|
||||||
|
msgstr "Codificación:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "UTF-8"
|
||||||
|
msgstr "UTF-8"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Latin 1"
|
||||||
|
msgstr "Latin 1"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Lines to skip"
|
||||||
|
msgstr "Líneas a omitir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "The import failed due to:"
|
||||||
|
msgstr "La importación falló debido a:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Here is a preview of the file we could not import:"
|
||||||
|
msgstr "Aquí está una vista preliminar del archivo que no podemos importar:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP Web"
|
||||||
|
msgstr "OpenERP Web"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Version"
|
||||||
|
msgstr "Versión"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||||
|
msgstr "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP is a trademark of the"
|
||||||
|
msgstr "OpenERP es una marca registrada de"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP SA Company"
|
||||||
|
msgstr "OpenERP SA Company"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Licenced under the terms of"
|
||||||
|
msgstr "Licenciado bajo los términos de"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "GNU Affero General Public License"
|
||||||
|
msgstr "GNU Affero General Public License"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "About OpenERP"
|
||||||
|
msgstr "Acerca de OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP"
|
||||||
|
msgstr "OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"is a free enterprise-scale software system that is designed to boost\n"
|
||||||
|
" productivity and profit through data integration. It connects, "
|
||||||
|
"improves and\n"
|
||||||
|
" manages business processes in areas such as sales, finance, "
|
||||||
|
"supply chain,\n"
|
||||||
|
" project management, production, services, CRM, etc..."
|
||||||
|
msgstr ""
|
||||||
|
"is a free enterprise-scale software system that is designed to boost\n"
|
||||||
|
" productivity and profit through data integration. It connects, "
|
||||||
|
"improves and\n"
|
||||||
|
" manages business processes in areas such as sales, finance, "
|
||||||
|
"supply chain,\n"
|
||||||
|
" project management, production, services, CRM, etc..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"The system is platform-independent, and can be installed on Windows, Mac OS "
|
||||||
|
"X,\n"
|
||||||
|
" and various Linux and other Unix-based distributions. Its "
|
||||||
|
"architecture enables\n"
|
||||||
|
" new functionality to be rapidly created, modifications to be "
|
||||||
|
"made to a\n"
|
||||||
|
" production system and migration to a new version to be "
|
||||||
|
"straightforward."
|
||||||
|
msgstr ""
|
||||||
|
"The system is platform-independent, and can be installed on Windows, Mac OS "
|
||||||
|
"X,\n"
|
||||||
|
" and various Linux and other Unix-based distributions. Its "
|
||||||
|
"architecture enables\n"
|
||||||
|
" new functionality to be rapidly created, modifications to be "
|
||||||
|
"made to a\n"
|
||||||
|
" production system and migration to a new version to be "
|
||||||
|
"straightforward."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Depending on your needs, OpenERP is available through a web or application "
|
||||||
|
"client."
|
||||||
|
msgstr ""
|
||||||
|
"Dependiendo de tus necesidades, OpenERP está disponible através de un "
|
||||||
|
"cliente web o escritorio."
|
|
@ -0,0 +1,677 @@
|
||||||
|
# Estonian translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-10 18:30+0000\n"
|
||||||
|
"Last-Translator: Aare Vesi <Unknown>\n"
|
||||||
|
"Language-Team: Estonian <et@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14123)\n"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:355
|
||||||
|
msgid ""
|
||||||
|
"Warning, the record has been modified, your changes will be discarded."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1659
|
||||||
|
msgid "<em> Search More...</em>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1672
|
||||||
|
#, python-format
|
||||||
|
msgid "<em> Create \"<strong>%s</strong>\"</em>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1678
|
||||||
|
msgid "<em> Create and Edit...</em>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:568
|
||||||
|
msgid "You must choose at least one record."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:569
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Hoiatus"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:609
|
||||||
|
msgid "Translations"
|
||||||
|
msgstr "Tõlked"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save"
|
||||||
|
msgstr "Salvesta"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:615
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "x"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{title}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{text}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Powered by"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "openerp.com"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Loading..."
|
||||||
|
msgstr "Laadimine..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create"
|
||||||
|
msgstr "Loo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Drop"
|
||||||
|
msgstr "Hülga"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Backup"
|
||||||
|
msgstr "Varunda"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Restore"
|
||||||
|
msgstr "Taasta"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "Salasõna"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Back to Login"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CREATE DATABASE"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master password:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New database name:"
|
||||||
|
msgstr "Uue andmebaasi nimi:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Load Demonstration data:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Default language:"
|
||||||
|
msgstr "Vaikekeel:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Admin password:"
|
||||||
|
msgstr "Admin salasõna:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm password:"
|
||||||
|
msgstr "Salasõna uuesti:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "DROP DATABASE"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database:"
|
||||||
|
msgstr "Andmebaas:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master Password:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "BACKUP DATABASE"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "RESTORE DATABASE"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "File:"
|
||||||
|
msgstr "Fail:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CHANGE MASTER PASSWORD"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New master password:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm new master password:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User:"
|
||||||
|
msgstr "Kasutaja:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr "Salasõna:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database"
|
||||||
|
msgstr "Andmebaas"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Login"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Bad username or password"
|
||||||
|
msgstr "Vale kasutajanimi või salasõna"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"We think that daily job activities can be more intuitive, efficient, "
|
||||||
|
"automated, .. and even fun."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP's vision to be:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Full featured"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Today's enterprise challenges are multiple. We provide one module for each "
|
||||||
|
"need."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open Source"
|
||||||
|
msgstr "Avatud lähtekoodiga"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"To Build a great product, we rely on the knowledge of thousands of "
|
||||||
|
"contributors."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User Friendly"
|
||||||
|
msgstr "Kasutajasõbralik"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"In order to be productive, people need clean and easy to use interface."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "("
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ")"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "LOGOUT"
|
||||||
|
msgstr "VÄLJU"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "«"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "»"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_menu_item"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_submenu_item"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Hide this tip"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Disable all tips"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View#"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields"
|
||||||
|
msgstr "Väljad"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View labels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Sidebar Relates"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Field"
|
||||||
|
msgstr "Väli"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ":"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate view"
|
||||||
|
msgstr "Tõlke vaade"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate sidebar"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "Kustuta"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "First"
|
||||||
|
msgstr "Esimene"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Last"
|
||||||
|
msgstr "Viimane"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "♻"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Edit"
|
||||||
|
msgstr "Salvesta & Muuda"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create & Edit"
|
||||||
|
msgstr "Loo & Muuda"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New"
|
||||||
|
msgstr "Uus"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Duplicate"
|
||||||
|
msgstr "Tee koopia"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Readonly/Editable"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<<"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "0"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "/"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "Lisa"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Unhandled widget"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Done"
|
||||||
|
msgstr "Valmis"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open..."
|
||||||
|
msgstr "Ava..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create..."
|
||||||
|
msgstr "Loo..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Search..."
|
||||||
|
msgstr "Otsi..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Uploading ..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Select"
|
||||||
|
msgstr "Vali"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save As"
|
||||||
|
msgstr "Salvesta kui"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Clear"
|
||||||
|
msgstr "Tühjenda"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Advanced Filter"
|
||||||
|
msgstr "Täiustatud filter"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Filters --"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Actions --"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save Filter"
|
||||||
|
msgstr "Salvesta filter"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Manage Filters"
|
||||||
|
msgstr "Halda filtreid"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Filter Name:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "(Any existing filter with the same name will be replaced)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Any of the following conditions must match"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "All the following conditions must match"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "None of the following conditions must match"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add condition"
|
||||||
|
msgstr "Lisa tingimus"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "and"
|
||||||
|
msgstr "ja"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Tühista"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & New"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export"
|
||||||
|
msgstr "Eksport"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"This wizard will export all data that matches the current search criteria to "
|
||||||
|
"a CSV file.\n"
|
||||||
|
" You can export all data or only the fields that can be "
|
||||||
|
"reimported after modification."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Type:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Compatible Export"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export all Data"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Formats"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Available fields"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields to export"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save fields list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Eemalda"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove All"
|
||||||
|
msgstr "Eemalda kõik"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Nimi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save as:"
|
||||||
|
msgstr "Salvesta kui:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Ok"
|
||||||
|
msgstr "Ok"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Saved exports:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Old Password:"
|
||||||
|
msgstr "Vana salasõna:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New Password:"
|
||||||
|
msgstr "Uus salasõna:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm Password:"
|
||||||
|
msgstr "Kinnita salasõna:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Import"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "1. Import a .CSV file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Select a .CSV file to import. If you need a sample of file to import,\n"
|
||||||
|
" you should use the export tool with the \"Import Compatible\" option."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CSV File:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "2. Check your file format"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Options"
|
||||||
|
msgstr "Impordi valikud"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Does your file have titles?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Separator:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delimiter:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Encoding:"
|
||||||
|
msgstr "Kodeering:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "UTF-8"
|
||||||
|
msgstr "UTF-8"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Latin 1"
|
||||||
|
msgstr "Latin 1"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Lines to skip"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "The import failed due to:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Here is a preview of the file we could not import:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP Web"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Version"
|
||||||
|
msgstr "Versioon"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP is a trademark of the"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP SA Company"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Licenced under the terms of"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "GNU Affero General Public License"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "About OpenERP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP"
|
||||||
|
msgstr "OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"is a free enterprise-scale software system that is designed to boost\n"
|
||||||
|
" productivity and profit through data integration. It connects, "
|
||||||
|
"improves and\n"
|
||||||
|
" manages business processes in areas such as sales, finance, "
|
||||||
|
"supply chain,\n"
|
||||||
|
" project management, production, services, CRM, etc..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"The system is platform-independent, and can be installed on Windows, Mac OS "
|
||||||
|
"X,\n"
|
||||||
|
" and various Linux and other Unix-based distributions. Its "
|
||||||
|
"architecture enables\n"
|
||||||
|
" new functionality to be rapidly created, modifications to be "
|
||||||
|
"made to a\n"
|
||||||
|
" production system and migration to a new version to be "
|
||||||
|
"straightforward."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Depending on your needs, OpenERP is available through a web or application "
|
||||||
|
"client."
|
||||||
|
msgstr ""
|
|
@ -0,0 +1,678 @@
|
||||||
|
# French translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-23 12:20+0000\n"
|
||||||
|
"Last-Translator: Xavier (Open ERP) <Unknown>\n"
|
||||||
|
"Language-Team: French <fr@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14185)\n"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:355
|
||||||
|
msgid ""
|
||||||
|
"Warning, the record has been modified, your changes will be discarded."
|
||||||
|
msgstr ""
|
||||||
|
"Attention, l'enregistrement a été modifié, vos changements seront perdus."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1659
|
||||||
|
msgid "<em> Search More...</em>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1672
|
||||||
|
#, python-format
|
||||||
|
msgid "<em> Create \"<strong>%s</strong>\"</em>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1678
|
||||||
|
msgid "<em> Create and Edit...</em>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:568
|
||||||
|
msgid "You must choose at least one record."
|
||||||
|
msgstr "Vous devez choisir au moins un enregistrement"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:569
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Attention"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:609
|
||||||
|
msgid "Translations"
|
||||||
|
msgstr "Traductions"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save"
|
||||||
|
msgstr "Enregistrer"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:615
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Fermer"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "x"
|
||||||
|
msgstr "x"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{title}"
|
||||||
|
msgstr "#{title}"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{text}"
|
||||||
|
msgstr "#{text}"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Powered by"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "openerp.com"
|
||||||
|
msgstr "openerp.com"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "."
|
||||||
|
msgstr "."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Loading..."
|
||||||
|
msgstr "Chargement..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create"
|
||||||
|
msgstr "Créer"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Drop"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Backup"
|
||||||
|
msgstr "Archiver"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Restore"
|
||||||
|
msgstr "Restaurer"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "Mot de passe"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Back to Login"
|
||||||
|
msgstr "Retour à la page d'authentification"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CREATE DATABASE"
|
||||||
|
msgstr "CRÉER LA BASE DE DONNÉES"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master password:"
|
||||||
|
msgstr "Mot de passe principal:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New database name:"
|
||||||
|
msgstr "Nom de la nouvelle base de données :"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Load Demonstration data:"
|
||||||
|
msgstr "Charger les données de démonstration:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Default language:"
|
||||||
|
msgstr "Langue par défaut :"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Admin password:"
|
||||||
|
msgstr "Mot de passe administrateur:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm password:"
|
||||||
|
msgstr "Confirmer le mot de passe:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "DROP DATABASE"
|
||||||
|
msgstr "SUPPRIMER LA BASE DE DONNÉES"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database:"
|
||||||
|
msgstr "Base de données :"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master Password:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "BACKUP DATABASE"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "RESTORE DATABASE"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "File:"
|
||||||
|
msgstr "Fichier :"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CHANGE MASTER PASSWORD"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New master password:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm new master password:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User:"
|
||||||
|
msgstr "Utilisateur :"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr "Mot de passe :"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database"
|
||||||
|
msgstr "Base de données"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Login"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Bad username or password"
|
||||||
|
msgstr "Mauvais identfiant ou mot de passe"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"We think that daily job activities can be more intuitive, efficient, "
|
||||||
|
"automated, .. and even fun."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP's vision to be:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Full featured"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Today's enterprise challenges are multiple. We provide one module for each "
|
||||||
|
"need."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open Source"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"To Build a great product, we rely on the knowledge of thousands of "
|
||||||
|
"contributors."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User Friendly"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"In order to be productive, people need clean and easy to use interface."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "("
|
||||||
|
msgstr "("
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ")"
|
||||||
|
msgstr ")"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "LOGOUT"
|
||||||
|
msgstr "DÉCONNEXION"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "«"
|
||||||
|
msgstr "«"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "»"
|
||||||
|
msgstr "»"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_menu_item"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_submenu_item"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Hide this tip"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Disable all tips"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View#"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View labels"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Sidebar Relates"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Field"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ":"
|
||||||
|
msgstr ":"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate view"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate sidebar"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "Supprimer"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "First"
|
||||||
|
msgstr "Premier"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<"
|
||||||
|
msgstr "<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">"
|
||||||
|
msgstr ">"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Last"
|
||||||
|
msgstr "Dernier"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "♻"
|
||||||
|
msgstr "♻"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Edit"
|
||||||
|
msgstr "Enregistrer et éditer"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create & Edit"
|
||||||
|
msgstr "Créer et éditer"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Duplicate"
|
||||||
|
msgstr "Dupliquer"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Readonly/Editable"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<<"
|
||||||
|
msgstr "<<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "0"
|
||||||
|
msgstr "0"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "/"
|
||||||
|
msgstr "/"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">>"
|
||||||
|
msgstr ">>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Unhandled widget"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "?"
|
||||||
|
msgstr "?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Done"
|
||||||
|
msgstr "Terminé"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open..."
|
||||||
|
msgstr "Ouvrir..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create..."
|
||||||
|
msgstr "Créer..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Search..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "..."
|
||||||
|
msgstr "..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Uploading ..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Select"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save As"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Clear"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Advanced Filter"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Filters --"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Actions --"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save Filter"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Manage Filters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Filter Name:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "(Any existing filter with the same name will be replaced)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Any of the following conditions must match"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "All the following conditions must match"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "None of the following conditions must match"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add condition"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & New"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"This wizard will export all data that matches the current search criteria to "
|
||||||
|
"a CSV file.\n"
|
||||||
|
" You can export all data or only the fields that can be "
|
||||||
|
"reimported after modification."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Type:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Compatible Export"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export all Data"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Formats"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Available fields"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields to export"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save fields list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove All"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save as:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Ok"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Saved exports:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Old Password:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New Password:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm Password:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "1. Import a .CSV file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Select a .CSV file to import. If you need a sample of file to import,\n"
|
||||||
|
" you should use the export tool with the \"Import Compatible\" option."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CSV File:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "2. Check your file format"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Options"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Does your file have titles?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Separator:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delimiter:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Encoding:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "UTF-8"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Latin 1"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Lines to skip"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "The import failed due to:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Here is a preview of the file we could not import:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP Web"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Version"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP is a trademark of the"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP SA Company"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Licenced under the terms of"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "GNU Affero General Public License"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "About OpenERP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"is a free enterprise-scale software system that is designed to boost\n"
|
||||||
|
" productivity and profit through data integration. It connects, "
|
||||||
|
"improves and\n"
|
||||||
|
" manages business processes in areas such as sales, finance, "
|
||||||
|
"supply chain,\n"
|
||||||
|
" project management, production, services, CRM, etc..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"The system is platform-independent, and can be installed on Windows, Mac OS "
|
||||||
|
"X,\n"
|
||||||
|
" and various Linux and other Unix-based distributions. Its "
|
||||||
|
"architecture enables\n"
|
||||||
|
" new functionality to be rapidly created, modifications to be "
|
||||||
|
"made to a\n"
|
||||||
|
" production system and migration to a new version to be "
|
||||||
|
"straightforward."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Depending on your needs, OpenERP is available through a web or application "
|
||||||
|
"client."
|
||||||
|
msgstr ""
|
|
@ -0,0 +1,709 @@
|
||||||
|
# Galician translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-19 07:54+0000\n"
|
||||||
|
"Last-Translator: Amós Oviedo <Unknown>\n"
|
||||||
|
"Language-Team: Galician <gl@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14165)\n"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:355
|
||||||
|
msgid ""
|
||||||
|
"Warning, the record has been modified, your changes will be discarded."
|
||||||
|
msgstr "Advertencia, o rexistro modificouse, os cambios serán descartados."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1659
|
||||||
|
msgid "<em> Search More...</em>"
|
||||||
|
msgstr "<em> Buscar máis...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1672
|
||||||
|
#, python-format
|
||||||
|
msgid "<em> Create \"<strong>%s</strong>\"</em>"
|
||||||
|
msgstr "<em> Crear \"<strong>%s</strong>\"</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1678
|
||||||
|
msgid "<em> Create and Edit...</em>"
|
||||||
|
msgstr "<em> Crear e Editar...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:568
|
||||||
|
msgid "You must choose at least one record."
|
||||||
|
msgstr "Debe seleccionar polo menos un rexistro."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:569
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Advertencia"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:609
|
||||||
|
msgid "Translations"
|
||||||
|
msgstr "Traducións"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save"
|
||||||
|
msgstr "Gardar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:615
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Pechar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "x"
|
||||||
|
msgstr "x"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{title}"
|
||||||
|
msgstr "#{title}"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{text}"
|
||||||
|
msgstr "#{text}"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Powered by"
|
||||||
|
msgstr "Desenvolvido por"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "openerp.com"
|
||||||
|
msgstr "openerp.com"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "."
|
||||||
|
msgstr "."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Loading..."
|
||||||
|
msgstr "Cargando…"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create"
|
||||||
|
msgstr "Crear"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Drop"
|
||||||
|
msgstr "Eliminar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Backup"
|
||||||
|
msgstr "Copia de seguridade"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Restore"
|
||||||
|
msgstr "Restaurar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "Contrasinal"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Back to Login"
|
||||||
|
msgstr "Voltar ó Inicio de sesión"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CREATE DATABASE"
|
||||||
|
msgstr "CREAR BASE DE DATOS"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master password:"
|
||||||
|
msgstr "Contrasinal maestra"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New database name:"
|
||||||
|
msgstr "Nome da nova base de datos:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Load Demonstration data:"
|
||||||
|
msgstr "Cargar datos de demostración:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Default language:"
|
||||||
|
msgstr "Idioma por defecto:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Admin password:"
|
||||||
|
msgstr "Contrasinal de Admin:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm password:"
|
||||||
|
msgstr "Confirmar contrasinal:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "DROP DATABASE"
|
||||||
|
msgstr "ELIMINAR BASE DE DATOS"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database:"
|
||||||
|
msgstr "Base de datos:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master Password:"
|
||||||
|
msgstr "Contrasinal Maestra"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "BACKUP DATABASE"
|
||||||
|
msgstr "COPIA DE SEGURIDADE DA BASE DE DATOS"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "RESTORE DATABASE"
|
||||||
|
msgstr "RESTAURAR BASE DE DATOS"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "File:"
|
||||||
|
msgstr "Arquivo:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CHANGE MASTER PASSWORD"
|
||||||
|
msgstr "CAMBIAR CONTRASINAL MAESTRA"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New master password:"
|
||||||
|
msgstr "Nova contrasinal maestra:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm new master password:"
|
||||||
|
msgstr "Confirmar nova contrasinal maestra:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User:"
|
||||||
|
msgstr "Usuario:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr "Contrasinal:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database"
|
||||||
|
msgstr "Base de datos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Login"
|
||||||
|
msgstr "Inicio de sesión"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Bad username or password"
|
||||||
|
msgstr "Nome de usuario ou contrasinal incorrectos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"We think that daily job activities can be more intuitive, efficient, "
|
||||||
|
"automated, .. and even fun."
|
||||||
|
msgstr ""
|
||||||
|
"Cremos que as actividades diarias de traballo poden ser máis intuitivas, "
|
||||||
|
"eficientes e automatizadas, .. e mesmo divertidas."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP's vision to be:"
|
||||||
|
msgstr "Los obxectivos de OpenERP son ser:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Full featured"
|
||||||
|
msgstr "Con todas as funcións"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Today's enterprise challenges are multiple. We provide one module for each "
|
||||||
|
"need."
|
||||||
|
msgstr ""
|
||||||
|
"Os retos actuais da empresa son múltiples. Ofrecemos un módulo para cada "
|
||||||
|
"necesidade."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open Source"
|
||||||
|
msgstr "Código aberto"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"To Build a great product, we rely on the knowledge of thousands of "
|
||||||
|
"contributors."
|
||||||
|
msgstr ""
|
||||||
|
"Para construir un gran producto, contamos coos coñecementos de miles de "
|
||||||
|
"contribuíntes."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User Friendly"
|
||||||
|
msgstr "Sinxelo de usar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"In order to be productive, people need clean and easy to use interface."
|
||||||
|
msgstr ""
|
||||||
|
"Co fin de ser produtivo, a xente necesita unha interface clara e sinxela de "
|
||||||
|
"usar."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "("
|
||||||
|
msgstr "("
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ")"
|
||||||
|
msgstr ")"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "LOGOUT"
|
||||||
|
msgstr "PECHAR SESIÓN"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "«"
|
||||||
|
msgstr "«"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "»"
|
||||||
|
msgstr "»"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_menu_item"
|
||||||
|
msgstr "oe_secondary_menu_item"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_submenu_item"
|
||||||
|
msgstr "oe_secondary_submenu_item"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Hide this tip"
|
||||||
|
msgstr "Ocultar esta suxerencia"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Disable all tips"
|
||||||
|
msgstr "Desactivar todas as suxerencias"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View#"
|
||||||
|
msgstr "Vista#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields"
|
||||||
|
msgstr "Campos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View labels"
|
||||||
|
msgstr "Ver etiquetas"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Sidebar Relates"
|
||||||
|
msgstr "Relaciónase coa barra lateral"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Field"
|
||||||
|
msgstr "Campo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ":"
|
||||||
|
msgstr ":"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate view"
|
||||||
|
msgstr "Traducir vista"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate sidebar"
|
||||||
|
msgstr "Traducir barra lateral"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "Borrar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "First"
|
||||||
|
msgstr "Primeiro"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<"
|
||||||
|
msgstr "<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">"
|
||||||
|
msgstr ">"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Last"
|
||||||
|
msgstr "Último"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "♻"
|
||||||
|
msgstr "♻"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Edit"
|
||||||
|
msgstr "Gardar e Editar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create & Edit"
|
||||||
|
msgstr "Crear e Editar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New"
|
||||||
|
msgstr "Novo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Duplicate"
|
||||||
|
msgstr "Duplicar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Readonly/Editable"
|
||||||
|
msgstr "Só Lectura/Editable"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<<"
|
||||||
|
msgstr "<<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "0"
|
||||||
|
msgstr "0"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "/"
|
||||||
|
msgstr "/"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">>"
|
||||||
|
msgstr ">>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "Engadir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Unhandled widget"
|
||||||
|
msgstr "Widget non controlado"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "?"
|
||||||
|
msgstr "?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#"
|
||||||
|
msgstr "#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Done"
|
||||||
|
msgstr "Feito"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open..."
|
||||||
|
msgstr "Abrir..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create..."
|
||||||
|
msgstr "Crear…"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Search..."
|
||||||
|
msgstr "Buscar..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "..."
|
||||||
|
msgstr "…"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Uploading ..."
|
||||||
|
msgstr "Subindo ..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Select"
|
||||||
|
msgstr "Seleccionar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save As"
|
||||||
|
msgstr "Gardar como"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Clear"
|
||||||
|
msgstr "Limpar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Advanced Filter"
|
||||||
|
msgstr "Filtro Avanzado"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Filters --"
|
||||||
|
msgstr "-- Filtros --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Actions --"
|
||||||
|
msgstr "-- Accións --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save Filter"
|
||||||
|
msgstr "Gardar Filtro"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Manage Filters"
|
||||||
|
msgstr "Xestionar filtros"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Filter Name:"
|
||||||
|
msgstr "Nome do Filtro"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "(Any existing filter with the same name will be replaced)"
|
||||||
|
msgstr "(Calquer filtro existente co mesmo nome será reemplazado)"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Any of the following conditions must match"
|
||||||
|
msgstr "Calquera das condicións seguintes deben coincidir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "All the following conditions must match"
|
||||||
|
msgstr "Todas as condicións seguintes deben coincidir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "None of the following conditions must match"
|
||||||
|
msgstr "Ningunha das seguintes condicións deben coincidir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add condition"
|
||||||
|
msgstr "Engadir condición"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "and"
|
||||||
|
msgstr "e"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Cancelar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & New"
|
||||||
|
msgstr "Gardar e Novo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Close"
|
||||||
|
msgstr "Gardar e Pechar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export"
|
||||||
|
msgstr "Exportar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"This wizard will export all data that matches the current search criteria to "
|
||||||
|
"a CSV file.\n"
|
||||||
|
" You can export all data or only the fields that can be "
|
||||||
|
"reimported after modification."
|
||||||
|
msgstr ""
|
||||||
|
"Este asistente exportaralle todos os datos que coincidan cos criterios de "
|
||||||
|
"procura actual a un arquivo CSV.\n"
|
||||||
|
" Pode exportar todos os datos ou só os campos que poden "
|
||||||
|
"importarse de novo despois da modificación."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Type:"
|
||||||
|
msgstr "Tipo de Exportación:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Compatible Export"
|
||||||
|
msgstr "Exportación compatible con importación"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export all Data"
|
||||||
|
msgstr "Exportar todos os datos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Formats"
|
||||||
|
msgstr "Formatos de Exportación"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Available fields"
|
||||||
|
msgstr "Campos dispoñibles"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields to export"
|
||||||
|
msgstr "Campos a exportar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save fields list"
|
||||||
|
msgstr "Gardar lista de campos"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Eliminar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove All"
|
||||||
|
msgstr "Eliminar Todo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Nome"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save as:"
|
||||||
|
msgstr "Gardar como:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Ok"
|
||||||
|
msgstr "Ok"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Saved exports:"
|
||||||
|
msgstr "Exportacións gardadas:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Old Password:"
|
||||||
|
msgstr "Contrasinal anterior:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New Password:"
|
||||||
|
msgstr "Contrasinal nova:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm Password:"
|
||||||
|
msgstr "Confirmar contrasinal:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Importar"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "1. Import a .CSV file"
|
||||||
|
msgstr "1. Importar un arquivo .CSV"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Select a .CSV file to import. If you need a sample of file to import,\n"
|
||||||
|
" you should use the export tool with the \"Import Compatible\" option."
|
||||||
|
msgstr ""
|
||||||
|
"Seleccione un arquivo .CSV para importar. Se necesita unha mostra de arquivo "
|
||||||
|
"para importar,\n"
|
||||||
|
" debería usar a ferramenta de exportación coa opción de \"Importación "
|
||||||
|
"Compatible\"."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CSV File:"
|
||||||
|
msgstr "Arquivo CSV:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "2. Check your file format"
|
||||||
|
msgstr "2. Comprobe o formato de arquivo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Options"
|
||||||
|
msgstr "Importar opcións"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Does your file have titles?"
|
||||||
|
msgstr "¿Ten o seu arquivo títulos?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Separator:"
|
||||||
|
msgstr "Separador:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delimiter:"
|
||||||
|
msgstr "Delimitador:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Encoding:"
|
||||||
|
msgstr "Codificación:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "UTF-8"
|
||||||
|
msgstr "UTF-8"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Latin 1"
|
||||||
|
msgstr "Latin 1"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Lines to skip"
|
||||||
|
msgstr "Liñas a omitir"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "The import failed due to:"
|
||||||
|
msgstr "A importación fallou debido a:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Here is a preview of the file we could not import:"
|
||||||
|
msgstr "Esta é a vista previa do arquivo que non se pode importar:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP Web"
|
||||||
|
msgstr "OpenERP Web"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Version"
|
||||||
|
msgstr "Versión"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||||
|
msgstr "Copyright © 2011-HOXE OpenERP SA. Todos os Dereitos Reservados."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP is a trademark of the"
|
||||||
|
msgstr "OpenERP é unha marca rexistrada da"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP SA Company"
|
||||||
|
msgstr "Compañía OpenERP SA"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Licenced under the terms of"
|
||||||
|
msgstr "Con licencia baixo os termos de"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "GNU Affero General Public License"
|
||||||
|
msgstr "GNU Affero General Public License"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "About OpenERP"
|
||||||
|
msgstr "Acerca de OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP"
|
||||||
|
msgstr "OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"is a free enterprise-scale software system that is designed to boost\n"
|
||||||
|
" productivity and profit through data integration. It connects, "
|
||||||
|
"improves and\n"
|
||||||
|
" manages business processes in areas such as sales, finance, "
|
||||||
|
"supply chain,\n"
|
||||||
|
" project management, production, services, CRM, etc..."
|
||||||
|
msgstr ""
|
||||||
|
"É un sistema software empresarial-escalar libre deseñado para mellorar\n"
|
||||||
|
" a productividade y beneficios a través da integración de datos. "
|
||||||
|
"Conecta, mellora e\n"
|
||||||
|
" xestiona os procesos de negocio en áreas como ventas, finanzas, "
|
||||||
|
"cadena de suministro,\n"
|
||||||
|
" xestión de proxectos, producción, servizos, CRM, etc..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"The system is platform-independent, and can be installed on Windows, Mac OS "
|
||||||
|
"X,\n"
|
||||||
|
" and various Linux and other Unix-based distributions. Its "
|
||||||
|
"architecture enables\n"
|
||||||
|
" new functionality to be rapidly created, modifications to be "
|
||||||
|
"made to a\n"
|
||||||
|
" production system and migration to a new version to be "
|
||||||
|
"straightforward."
|
||||||
|
msgstr ""
|
||||||
|
"O sistema é unha plataforma-independente, e pode ser instalada en Windows, "
|
||||||
|
"Mac OS X,\n"
|
||||||
|
" e varias distribucións Linux e outra basadas en Unix. A súa "
|
||||||
|
"arquitectura permite\n"
|
||||||
|
" crear novas funcionalidades rápidamente, as modificacións a "
|
||||||
|
"facer nun\n"
|
||||||
|
" sistema en producción e migración a unha nova versión son "
|
||||||
|
"sinxelas."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Depending on your needs, OpenERP is available through a web or application "
|
||||||
|
"client."
|
||||||
|
msgstr ""
|
||||||
|
"Segundo as súas necesidades, OpenERP está dispoñible a través dun cliente "
|
||||||
|
"web ou unha aplicación de escritorio."
|
|
@ -0,0 +1,689 @@
|
||||||
|
# Italian translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-08 13:39+0000\n"
|
||||||
|
"Last-Translator: Nicola Riolini - Micronaet <Unknown>\n"
|
||||||
|
"Language-Team: Italian <it@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-09 05:22+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14110)\n"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:355
|
||||||
|
msgid ""
|
||||||
|
"Warning, the record has been modified, your changes will be discarded."
|
||||||
|
msgstr ""
|
||||||
|
"Attenzione, il record è stato modificato, i vostri cambiamenti verranno "
|
||||||
|
"scartati."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1659
|
||||||
|
msgid "<em> Search More...</em>"
|
||||||
|
msgstr "<em> Cerca ancora...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1672
|
||||||
|
#, python-format
|
||||||
|
msgid "<em> Create \"<strong>%s</strong>\"</em>"
|
||||||
|
msgstr "<em> Crea \"<strong>%s</strong>\"</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1678
|
||||||
|
msgid "<em> Create and Edit...</em>"
|
||||||
|
msgstr "<em> Crea e modifica...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:568
|
||||||
|
msgid "You must choose at least one record."
|
||||||
|
msgstr "E' necessario selezionare almeno un record."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:569
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Attenzione"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:609
|
||||||
|
msgid "Translations"
|
||||||
|
msgstr "Traduzioni"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save"
|
||||||
|
msgstr "Salva"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:615
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Chiudi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "x"
|
||||||
|
msgstr "x"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{title}"
|
||||||
|
msgstr "#{title}"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{text}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Powered by"
|
||||||
|
msgstr "Powered by"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "openerp.com"
|
||||||
|
msgstr "openerp.com"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "."
|
||||||
|
msgstr "."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Loading..."
|
||||||
|
msgstr "Caricamento..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create"
|
||||||
|
msgstr "Crea"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Drop"
|
||||||
|
msgstr "Elimina"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Backup"
|
||||||
|
msgstr "Backup"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Restore"
|
||||||
|
msgstr "Ripristina"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "Password"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Back to Login"
|
||||||
|
msgstr "Ritorno al Login"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CREATE DATABASE"
|
||||||
|
msgstr "CREA DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master password:"
|
||||||
|
msgstr "Password principale"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New database name:"
|
||||||
|
msgstr "Nome nuovo database:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Load Demonstration data:"
|
||||||
|
msgstr "Caricadati dimostrativi:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Default language:"
|
||||||
|
msgstr "Lingua predefinita:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Admin password:"
|
||||||
|
msgstr "Password di amministrazione:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm password:"
|
||||||
|
msgstr "Conferma password:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "DROP DATABASE"
|
||||||
|
msgstr "ELIMINA DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database:"
|
||||||
|
msgstr "Database:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master Password:"
|
||||||
|
msgstr "Password principale"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "BACKUP DATABASE"
|
||||||
|
msgstr "BACKUP DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "RESTORE DATABASE"
|
||||||
|
msgstr "RIPRISTINA DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "File:"
|
||||||
|
msgstr "File:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CHANGE MASTER PASSWORD"
|
||||||
|
msgstr "CAMBIA PASSWORD PRINCIPALE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New master password:"
|
||||||
|
msgstr "Nuova password principale:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm new master password:"
|
||||||
|
msgstr "Conferma nuova password principale"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User:"
|
||||||
|
msgstr "Utente:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr "Password:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database"
|
||||||
|
msgstr "Database"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Login"
|
||||||
|
msgstr "Login"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Bad username or password"
|
||||||
|
msgstr "Username o password errati"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"We think that daily job activities can be more intuitive, efficient, "
|
||||||
|
"automated, .. and even fun."
|
||||||
|
msgstr ""
|
||||||
|
"Pensiamo che le attività quotidiane possano essere più intuitive, "
|
||||||
|
"efficienti, automatizzate...e anche più divertenti."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP's vision to be:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Full featured"
|
||||||
|
msgstr "Completo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Today's enterprise challenges are multiple. We provide one module for each "
|
||||||
|
"need."
|
||||||
|
msgstr ""
|
||||||
|
"Le esigenze odierne delle aziende sono molteplici. Noi forniamo un modulo "
|
||||||
|
"per ogni necessità."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open Source"
|
||||||
|
msgstr "Open Source"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"To Build a great product, we rely on the knowledge of thousands of "
|
||||||
|
"contributors."
|
||||||
|
msgstr ""
|
||||||
|
"Per creare un buon prodotto, facciamo affidamento sull'esperienza di "
|
||||||
|
"migliaia di contributori."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User Friendly"
|
||||||
|
msgstr "User Friendly"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"In order to be productive, people need clean and easy to use interface."
|
||||||
|
msgstr ""
|
||||||
|
"Per essere produttive, le persone necessitano di interfacce semplici e "
|
||||||
|
"pulite."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "("
|
||||||
|
msgstr "("
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ")"
|
||||||
|
msgstr ")"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "LOGOUT"
|
||||||
|
msgstr "LOGOUT"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "«"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "»"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_menu_item"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_submenu_item"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Hide this tip"
|
||||||
|
msgstr "Nascondi questo consiglio"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Disable all tips"
|
||||||
|
msgstr "Disabilita tutti i consigli"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View#"
|
||||||
|
msgstr "Vista à"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields"
|
||||||
|
msgstr "Campi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View labels"
|
||||||
|
msgstr "Visualizza etichette"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Sidebar Relates"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Field"
|
||||||
|
msgstr "Campo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ":"
|
||||||
|
msgstr ":"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate view"
|
||||||
|
msgstr "Traduci vista"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate sidebar"
|
||||||
|
msgstr "Traduci barra laterale"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "Elimina"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "First"
|
||||||
|
msgstr "Primo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<"
|
||||||
|
msgstr "<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">"
|
||||||
|
msgstr ">"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Last"
|
||||||
|
msgstr "Ultimo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "♻"
|
||||||
|
msgstr "♻"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Edit"
|
||||||
|
msgstr "Salva & Modifica"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create & Edit"
|
||||||
|
msgstr "Crea & Modifica"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New"
|
||||||
|
msgstr "Nuovo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Duplicate"
|
||||||
|
msgstr "Duplica"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Readonly/Editable"
|
||||||
|
msgstr "Sola lettura / Modificabile"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<<"
|
||||||
|
msgstr "<<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "0"
|
||||||
|
msgstr "0"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "/"
|
||||||
|
msgstr "/"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">>"
|
||||||
|
msgstr ">>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "Aggiungi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Unhandled widget"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "?"
|
||||||
|
msgstr "?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#"
|
||||||
|
msgstr "#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Done"
|
||||||
|
msgstr "Completato"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open..."
|
||||||
|
msgstr "Apri..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create..."
|
||||||
|
msgstr "Crea..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Search..."
|
||||||
|
msgstr "Cerca..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "..."
|
||||||
|
msgstr "..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Uploading ..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Select"
|
||||||
|
msgstr "Seleziona"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save As"
|
||||||
|
msgstr "Salva come"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Clear"
|
||||||
|
msgstr "Pulisci"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Advanced Filter"
|
||||||
|
msgstr "Filtro avanzato"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Filters --"
|
||||||
|
msgstr "-- Filtri --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Actions --"
|
||||||
|
msgstr "-- Azioni --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save Filter"
|
||||||
|
msgstr "Salva Filtro"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Manage Filters"
|
||||||
|
msgstr "Gestisci Filtri"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Filter Name:"
|
||||||
|
msgstr "Nome filtro:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "(Any existing filter with the same name will be replaced)"
|
||||||
|
msgstr "(Eventuali filtri esistenti con lo stesso nome saranno rimpiazzati)"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Any of the following conditions must match"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "All the following conditions must match"
|
||||||
|
msgstr "Tutte le seguenti condizioni deve verificarsi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "None of the following conditions must match"
|
||||||
|
msgstr "Nessuna delle seguenti condizioni deve verificarsi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add condition"
|
||||||
|
msgstr "Aggiungi condizione"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "and"
|
||||||
|
msgstr "e"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Annulla"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & New"
|
||||||
|
msgstr "Salva & Nuovo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Close"
|
||||||
|
msgstr "Salva & Chiudi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export"
|
||||||
|
msgstr "Esporta"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"This wizard will export all data that matches the current search criteria to "
|
||||||
|
"a CSV file.\n"
|
||||||
|
" You can export all data or only the fields that can be "
|
||||||
|
"reimported after modification."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Type:"
|
||||||
|
msgstr "Tipo di esportazione:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Compatible Export"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export all Data"
|
||||||
|
msgstr "Esporta tutti i dati"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Formats"
|
||||||
|
msgstr "Formati esportazione"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Available fields"
|
||||||
|
msgstr "Campi disponibili"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields to export"
|
||||||
|
msgstr "Campi da esportare"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save fields list"
|
||||||
|
msgstr "Salva l'elenco dei campi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Rimuovi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove All"
|
||||||
|
msgstr "Rimuovi tutto"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Nome"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save as:"
|
||||||
|
msgstr "Salva come:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Ok"
|
||||||
|
msgstr "Ok"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Saved exports:"
|
||||||
|
msgstr "Esportazioni salvate:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Old Password:"
|
||||||
|
msgstr "Vecchia Password:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New Password:"
|
||||||
|
msgstr "Nuova password:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm Password:"
|
||||||
|
msgstr "Conferma password:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Importa"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "1. Import a .CSV file"
|
||||||
|
msgstr "1. Importa un file .CSV"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Select a .CSV file to import. If you need a sample of file to import,\n"
|
||||||
|
" you should use the export tool with the \"Import Compatible\" option."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CSV File:"
|
||||||
|
msgstr "File CSV:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "2. Check your file format"
|
||||||
|
msgstr "2. Controlla il formato del tuo file"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Options"
|
||||||
|
msgstr "Opzioni di importazione"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Does your file have titles?"
|
||||||
|
msgstr "Il vostro file ha i titoli?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Separator:"
|
||||||
|
msgstr "Separatore:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delimiter:"
|
||||||
|
msgstr "Delimitatore:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Encoding:"
|
||||||
|
msgstr "Codifica:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "UTF-8"
|
||||||
|
msgstr "UTF-8"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Latin 1"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Lines to skip"
|
||||||
|
msgstr "Linee da saltare"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "The import failed due to:"
|
||||||
|
msgstr "L'importazione è fallita a causa di:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Here is a preview of the file we could not import:"
|
||||||
|
msgstr "Ecco un anteprima del file che non si è riuscito ad importare:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP Web"
|
||||||
|
msgstr "OpenERP Web"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Version"
|
||||||
|
msgstr "Versione"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP is a trademark of the"
|
||||||
|
msgstr "OpenERP è un marchio di"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP SA Company"
|
||||||
|
msgstr "OpenERP SA Company"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Licenced under the terms of"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "GNU Affero General Public License"
|
||||||
|
msgstr "GNU Affero General Public License"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "About OpenERP"
|
||||||
|
msgstr "Informazioni su OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP"
|
||||||
|
msgstr "OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"is a free enterprise-scale software system that is designed to boost\n"
|
||||||
|
" productivity and profit through data integration. It connects, "
|
||||||
|
"improves and\n"
|
||||||
|
" manages business processes in areas such as sales, finance, "
|
||||||
|
"supply chain,\n"
|
||||||
|
" project management, production, services, CRM, etc..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"The system is platform-independent, and can be installed on Windows, Mac OS "
|
||||||
|
"X,\n"
|
||||||
|
" and various Linux and other Unix-based distributions. Its "
|
||||||
|
"architecture enables\n"
|
||||||
|
" new functionality to be rapidly created, modifications to be "
|
||||||
|
"made to a\n"
|
||||||
|
" production system and migration to a new version to be "
|
||||||
|
"straightforward."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Depending on your needs, OpenERP is available through a web or application "
|
||||||
|
"client."
|
||||||
|
msgstr ""
|
||||||
|
"In base alle tue esigenze, OpenERP è disponibile tramite un browse web o "
|
||||||
|
"un'applicazione client."
|
|
@ -0,0 +1,689 @@
|
||||||
|
# Dutch (Belgium) translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-07 12:50+0000\n"
|
||||||
|
"Last-Translator: Niels Huylebroeck <Unknown>\n"
|
||||||
|
"Language-Team: Dutch (Belgium) <nl_BE@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-08 05:29+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14110)\n"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:355
|
||||||
|
msgid ""
|
||||||
|
"Warning, the record has been modified, your changes will be discarded."
|
||||||
|
msgstr ""
|
||||||
|
"Opgelet, het record werd gewijzigd, uw veranderingen zullen niet opgeslagen "
|
||||||
|
"worden."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1659
|
||||||
|
msgid "<em> Search More...</em>"
|
||||||
|
msgstr "<em> Uitgebreid zoeken...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1672
|
||||||
|
#, python-format
|
||||||
|
msgid "<em> Create \"<strong>%s</strong>\"</em>"
|
||||||
|
msgstr "<em> Creër \"<strong>%s</strong>\"</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1678
|
||||||
|
msgid "<em> Create and Edit...</em>"
|
||||||
|
msgstr "<em> Creër en bewerk...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:568
|
||||||
|
msgid "You must choose at least one record."
|
||||||
|
msgstr "U moet minstens een record selecteren."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:569
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Waarschuwing"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:609
|
||||||
|
msgid "Translations"
|
||||||
|
msgstr "Vertalingen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save"
|
||||||
|
msgstr "Opslaan"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:615
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Sluiten"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "x"
|
||||||
|
msgstr "x"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{title}"
|
||||||
|
msgstr "#{title}"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{text}"
|
||||||
|
msgstr "#{text}"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Powered by"
|
||||||
|
msgstr "Mogelijk gemaakt door"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "openerp.com"
|
||||||
|
msgstr "openerp.com"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "."
|
||||||
|
msgstr "."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Loading..."
|
||||||
|
msgstr "Laden..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create"
|
||||||
|
msgstr "Creër"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Drop"
|
||||||
|
msgstr "Drop"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Backup"
|
||||||
|
msgstr "Backup"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Restore"
|
||||||
|
msgstr "Restore"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "Wachtwoord"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Back to Login"
|
||||||
|
msgstr "Terug naar aanmelding"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CREATE DATABASE"
|
||||||
|
msgstr "CREATE DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master password:"
|
||||||
|
msgstr "Master wachtwoord:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New database name:"
|
||||||
|
msgstr "Nieuwe database naam:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Load Demonstration data:"
|
||||||
|
msgstr "Demonstratie data laden:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Default language:"
|
||||||
|
msgstr "Standaard taal:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Admin password:"
|
||||||
|
msgstr "Beheerder wachtwoord:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm password:"
|
||||||
|
msgstr "Bevestig wachtwoord:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "DROP DATABASE"
|
||||||
|
msgstr "DROP DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database:"
|
||||||
|
msgstr "Database:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master Password:"
|
||||||
|
msgstr "Master wachtwoord:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "BACKUP DATABASE"
|
||||||
|
msgstr "BACKUP DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "RESTORE DATABASE"
|
||||||
|
msgstr "RESTORE DATABASE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "File:"
|
||||||
|
msgstr "Bestand:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CHANGE MASTER PASSWORD"
|
||||||
|
msgstr "CHANGE MASTER PASSWORD"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New master password:"
|
||||||
|
msgstr "Nieuw master wachtwoord:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm new master password:"
|
||||||
|
msgstr "Bevestig nieuw master wachtwoord:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User:"
|
||||||
|
msgstr "Gebruiker:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr "Wachtwoord:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database"
|
||||||
|
msgstr "Database"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Login"
|
||||||
|
msgstr "Login"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Bad username or password"
|
||||||
|
msgstr "Verkeerde gebruikersnaam of wachtwoord"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"We think that daily job activities can be more intuitive, efficient, "
|
||||||
|
"automated, .. and even fun."
|
||||||
|
msgstr ""
|
||||||
|
"Wij geloven dat je dagelijkse werk intuitiver, efficienter, geautomatiseerd "
|
||||||
|
"en leuker kan zijn."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP's vision to be:"
|
||||||
|
msgstr "OpenERP's visie is:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Full featured"
|
||||||
|
msgstr "Volledig uitgerust"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Today's enterprise challenges are multiple. We provide one module for each "
|
||||||
|
"need."
|
||||||
|
msgstr ""
|
||||||
|
"Hedendaagse uitdaging voor bedrijven zijn alom. Wij voorzien een module voor "
|
||||||
|
"elke uitdaging."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open Source"
|
||||||
|
msgstr "Open Source"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"To Build a great product, we rely on the knowledge of thousands of "
|
||||||
|
"contributors."
|
||||||
|
msgstr ""
|
||||||
|
"Om een geweldig product te maken vertrouwen we op de kennis van duizenden "
|
||||||
|
"mensen."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User Friendly"
|
||||||
|
msgstr "Gebruiksvriendelijk"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"In order to be productive, people need clean and easy to use interface."
|
||||||
|
msgstr ""
|
||||||
|
"Om productief te kunnen zijn hebben mensen een mooie en gemakkelijke "
|
||||||
|
"interface nodig."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "("
|
||||||
|
msgstr "("
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ")"
|
||||||
|
msgstr ")"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "LOGOUT"
|
||||||
|
msgstr "LOGOUT"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "«"
|
||||||
|
msgstr "«"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "»"
|
||||||
|
msgstr "»"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_menu_item"
|
||||||
|
msgstr "oe_secondary_menu_item"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_submenu_item"
|
||||||
|
msgstr "oe_secondary_submenu_item"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Hide this tip"
|
||||||
|
msgstr "Verberg deze tip"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Disable all tips"
|
||||||
|
msgstr "Verberg alle tips"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View#"
|
||||||
|
msgstr "View#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields"
|
||||||
|
msgstr "Velden"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View labels"
|
||||||
|
msgstr "Toon labels"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Sidebar Relates"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Field"
|
||||||
|
msgstr "Veld"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ":"
|
||||||
|
msgstr ":"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate view"
|
||||||
|
msgstr "Vertaal scherm"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate sidebar"
|
||||||
|
msgstr "Vertaal balk"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "Verwijder"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "First"
|
||||||
|
msgstr "Eerste"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<"
|
||||||
|
msgstr "<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">"
|
||||||
|
msgstr ">"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Last"
|
||||||
|
msgstr "Laatste"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "♻"
|
||||||
|
msgstr "♻"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Edit"
|
||||||
|
msgstr "Opslaan & Bewerken"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create & Edit"
|
||||||
|
msgstr "Creër & Bewerk"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New"
|
||||||
|
msgstr "Nieuw"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Duplicate"
|
||||||
|
msgstr "Dupliceer"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Readonly/Editable"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<<"
|
||||||
|
msgstr "<<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "0"
|
||||||
|
msgstr "0"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "/"
|
||||||
|
msgstr "/"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">>"
|
||||||
|
msgstr ">>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "Toevoegen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Unhandled widget"
|
||||||
|
msgstr "Niet-verwerkbare widget"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "?"
|
||||||
|
msgstr "?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#"
|
||||||
|
msgstr "#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Done"
|
||||||
|
msgstr "Voltooid"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open..."
|
||||||
|
msgstr "Open..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create..."
|
||||||
|
msgstr "Creër..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Search..."
|
||||||
|
msgstr "Zoeken..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "..."
|
||||||
|
msgstr "..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Uploading ..."
|
||||||
|
msgstr "Uploaden ..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Select"
|
||||||
|
msgstr "Selecteer"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save As"
|
||||||
|
msgstr "Opslaan als"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Clear"
|
||||||
|
msgstr "Leegmaken"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Advanced Filter"
|
||||||
|
msgstr "Geavanceerde filter"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Filters --"
|
||||||
|
msgstr "-- Filters --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Actions --"
|
||||||
|
msgstr "-- Acties --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save Filter"
|
||||||
|
msgstr "Filter opslaan"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Manage Filters"
|
||||||
|
msgstr "Filters beheren"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Filter Name:"
|
||||||
|
msgstr "Filternaam:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "(Any existing filter with the same name will be replaced)"
|
||||||
|
msgstr "(Bestaande filters met dezelfde naam worden overschreven)"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Any of the following conditions must match"
|
||||||
|
msgstr "Een van de volgende voorwaarden moet overeenstemmen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "All the following conditions must match"
|
||||||
|
msgstr "Elke van de volgende voorwaarden moeten overeenstemmen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "None of the following conditions must match"
|
||||||
|
msgstr "Geen enkele van de volgende voorwaarden moeten overeenstemmen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add condition"
|
||||||
|
msgstr "Voorwaarde toevoegen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Annuleren"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & New"
|
||||||
|
msgstr "Opslaan & Nieuwe"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Close"
|
||||||
|
msgstr "Opslaan & Sluiten"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export"
|
||||||
|
msgstr "Exporteren"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"This wizard will export all data that matches the current search criteria to "
|
||||||
|
"a CSV file.\n"
|
||||||
|
" You can export all data or only the fields that can be "
|
||||||
|
"reimported after modification."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Type:"
|
||||||
|
msgstr "Export Type:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Compatible Export"
|
||||||
|
msgstr "Exporteren op een compatibele manier"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export all Data"
|
||||||
|
msgstr "Alles exporteren"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Formats"
|
||||||
|
msgstr "Export formaten"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Available fields"
|
||||||
|
msgstr "Beschikbare velden"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields to export"
|
||||||
|
msgstr "Te exporteren velden"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save fields list"
|
||||||
|
msgstr "Export definitie opslaan"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Verwijderen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove All"
|
||||||
|
msgstr "Alles verwijderen"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Naam"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save as:"
|
||||||
|
msgstr "Opslaan als:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Ok"
|
||||||
|
msgstr "Ok"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Saved exports:"
|
||||||
|
msgstr "Export definities"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Old Password:"
|
||||||
|
msgstr "Huidig wachtwoord:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New Password:"
|
||||||
|
msgstr "Nieuw wachtwoord:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm Password:"
|
||||||
|
msgstr "Bevestig wachtwoord:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Importeren"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "1. Import a .CSV file"
|
||||||
|
msgstr "1. Importeer een .CSV bestand"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Select a .CSV file to import. If you need a sample of file to import,\n"
|
||||||
|
" you should use the export tool with the \"Import Compatible\" option."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CSV File:"
|
||||||
|
msgstr "CSV Bestand:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "2. Check your file format"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Options"
|
||||||
|
msgstr "Import opties"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Does your file have titles?"
|
||||||
|
msgstr "Heeft uw bestand een hoofding ?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Separator:"
|
||||||
|
msgstr "Scheidingsteken"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delimiter:"
|
||||||
|
msgstr "Veld begrenzing"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Encoding:"
|
||||||
|
msgstr "Encodering:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "UTF-8"
|
||||||
|
msgstr "UTF-8"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Latin 1"
|
||||||
|
msgstr "Latin 1"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Lines to skip"
|
||||||
|
msgstr "Aantal lijnen overslaan"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "The import failed due to:"
|
||||||
|
msgstr "De import is niet gelukt omdat:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Here is a preview of the file we could not import:"
|
||||||
|
msgstr "Hier is een voorbeeld van het bestand dat we niet konden importeren:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP Web"
|
||||||
|
msgstr "OpenERP Web"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Version"
|
||||||
|
msgstr "Versie"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||||
|
msgstr "Copyright © 2011-TODAY OpenERP SA. Alle rechten voorbehouden."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP is a trademark of the"
|
||||||
|
msgstr "OpenERP is een handelsmerk van"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP SA Company"
|
||||||
|
msgstr "OpenERP SA Company"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Licenced under the terms of"
|
||||||
|
msgstr "Gelicensieërd onder de voorwaarden van"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "GNU Affero General Public License"
|
||||||
|
msgstr "GNU Affero General Public License"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "About OpenERP"
|
||||||
|
msgstr "About OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP"
|
||||||
|
msgstr "OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"is a free enterprise-scale software system that is designed to boost\n"
|
||||||
|
" productivity and profit through data integration. It connects, "
|
||||||
|
"improves and\n"
|
||||||
|
" manages business processes in areas such as sales, finance, "
|
||||||
|
"supply chain,\n"
|
||||||
|
" project management, production, services, CRM, etc..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"The system is platform-independent, and can be installed on Windows, Mac OS "
|
||||||
|
"X,\n"
|
||||||
|
" and various Linux and other Unix-based distributions. Its "
|
||||||
|
"architecture enables\n"
|
||||||
|
" new functionality to be rapidly created, modifications to be "
|
||||||
|
"made to a\n"
|
||||||
|
" production system and migration to a new version to be "
|
||||||
|
"straightforward."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Depending on your needs, OpenERP is available through a web or application "
|
||||||
|
"client."
|
||||||
|
msgstr ""
|
||||||
|
"Afhankelijk van uw behoefte is OpenERP beschikbaar via een web- of desktop-"
|
||||||
|
"applicatie."
|
|
@ -0,0 +1,707 @@
|
||||||
|
# Slovenian translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-19 07:07+0000\n"
|
||||||
|
"Last-Translator: Anze (Neotek) <Unknown>\n"
|
||||||
|
"Language-Team: Slovenian <sl@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14165)\n"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:355
|
||||||
|
msgid ""
|
||||||
|
"Warning, the record has been modified, your changes will be discarded."
|
||||||
|
msgstr ""
|
||||||
|
"Opozorilo, zapis je bil spremenjen, zato bodo vaše spremembe zavržene."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1659
|
||||||
|
msgid "<em> Search More...</em>"
|
||||||
|
msgstr "<em> Iskanje več...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1672
|
||||||
|
#, python-format
|
||||||
|
msgid "<em> Create \"<strong>%s</strong>\"</em>"
|
||||||
|
msgstr "<em> Ustvari \"<strong>%s</strong>\"</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1678
|
||||||
|
msgid "<em> Create and Edit...</em>"
|
||||||
|
msgstr "<em> Ustvari in uredi...</em>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:568
|
||||||
|
msgid "You must choose at least one record."
|
||||||
|
msgstr "Izbrati morate vsaj en zapis."
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:569
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Opozorilo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:609
|
||||||
|
msgid "Translations"
|
||||||
|
msgstr "Prevodi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save"
|
||||||
|
msgstr "Shrani"
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:615
|
||||||
|
msgid "Close"
|
||||||
|
msgstr "Zapri"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "x"
|
||||||
|
msgstr "x"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{title}"
|
||||||
|
msgstr "#{title}"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#{text}"
|
||||||
|
msgstr "#{text}"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Powered by"
|
||||||
|
msgstr "Poganja ga"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "openerp.com"
|
||||||
|
msgstr "openerp.com"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "."
|
||||||
|
msgstr "."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Loading..."
|
||||||
|
msgstr "Nalaganje …"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create"
|
||||||
|
msgstr "Ustvari"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Drop"
|
||||||
|
msgstr "Izbriši"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Backup"
|
||||||
|
msgstr "Varnostna kopija"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Restore"
|
||||||
|
msgstr "Obnovi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "Geslo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Back to Login"
|
||||||
|
msgstr "Nazaj na prijavo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CREATE DATABASE"
|
||||||
|
msgstr "USTVARI PODATKOVNO BAZO"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master password:"
|
||||||
|
msgstr "Glavno geslo:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New database name:"
|
||||||
|
msgstr "Ime nove podatkovne baze"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Load Demonstration data:"
|
||||||
|
msgstr "Naloži demonstracijske podatke:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Default language:"
|
||||||
|
msgstr "Privzeti jezik:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Admin password:"
|
||||||
|
msgstr "Admin geslo:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm password:"
|
||||||
|
msgstr "Potrdite geslo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "DROP DATABASE"
|
||||||
|
msgstr "IZBRIŠI PODATKOVNO BAZO"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database:"
|
||||||
|
msgstr "Podatkovna baza"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Master Password:"
|
||||||
|
msgstr "Glavno geslo:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "BACKUP DATABASE"
|
||||||
|
msgstr "VARNOSTNA KOPIJA PODATKOVNE BAZE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "RESTORE DATABASE"
|
||||||
|
msgstr "OBNOVITEV PODATKOVNE BAZE"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "File:"
|
||||||
|
msgstr "Datoteka:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CHANGE MASTER PASSWORD"
|
||||||
|
msgstr "SPREMENI GLAVNO GELSO"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New master password:"
|
||||||
|
msgstr "Novo glavno geslo:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm new master password:"
|
||||||
|
msgstr "Potrdi novo glavno geslo:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User:"
|
||||||
|
msgstr "Uporabnik:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr "Geslo:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Database"
|
||||||
|
msgstr "Podatkovna baza"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Login"
|
||||||
|
msgstr "Prijava"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Bad username or password"
|
||||||
|
msgstr "Napačno uporabniško ime ali geslo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"We think that daily job activities can be more intuitive, efficient, "
|
||||||
|
"automated, .. and even fun."
|
||||||
|
msgstr ""
|
||||||
|
"Menimo, da so lahko dnevne dejavnosti dela bolj intuitivna, učinkovita, "
|
||||||
|
"avtomatska, .. in celo zabavna."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP's vision to be:"
|
||||||
|
msgstr "Vizija OpenERP je:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Full featured"
|
||||||
|
msgstr "Oblikovno popoln"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Today's enterprise challenges are multiple. We provide one module for each "
|
||||||
|
"need."
|
||||||
|
msgstr ""
|
||||||
|
"Današnja podjetja imajo več izzivov. Nudimo en modul za vsako potrebo."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open Source"
|
||||||
|
msgstr "Odprta koda"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"To Build a great product, we rely on the knowledge of thousands of "
|
||||||
|
"contributors."
|
||||||
|
msgstr ""
|
||||||
|
"Za zgraditev odličnega izdeleka, se zanašamo na znanje tisočih sodelavcev."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "User Friendly"
|
||||||
|
msgstr "Prijazen do uporabnika"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"In order to be productive, people need clean and easy to use interface."
|
||||||
|
msgstr ""
|
||||||
|
"Da bi bili produktivni, ljudje potrebujejo čist in enostaven za uporabniški "
|
||||||
|
"vmesnik."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "("
|
||||||
|
msgstr "("
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ")"
|
||||||
|
msgstr ")"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "LOGOUT"
|
||||||
|
msgstr "ODJAVA"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "«"
|
||||||
|
msgstr "«"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "»"
|
||||||
|
msgstr "»"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_menu_item"
|
||||||
|
msgstr "oe_secondary_menu_item"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "oe_secondary_submenu_item"
|
||||||
|
msgstr "oe_secondary_submenu_item"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Hide this tip"
|
||||||
|
msgstr "Skrij ta namig"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Disable all tips"
|
||||||
|
msgstr "Onemogoči vse namige"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View#"
|
||||||
|
msgstr "Ogled#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields"
|
||||||
|
msgstr "Polja"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View labels"
|
||||||
|
msgstr "Ogled oznak"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Sidebar Relates"
|
||||||
|
msgstr "Sorodne stranske vrstice"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Field"
|
||||||
|
msgstr "Polje"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ":"
|
||||||
|
msgstr ":"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate view"
|
||||||
|
msgstr "Preveden pogled"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Translate sidebar"
|
||||||
|
msgstr "Prevedi stransko vrstico"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "Izbriši"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "First"
|
||||||
|
msgstr "Začetek"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<"
|
||||||
|
msgstr "<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">"
|
||||||
|
msgstr ">"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Last"
|
||||||
|
msgstr "Konec"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "♻"
|
||||||
|
msgstr "♻"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Edit"
|
||||||
|
msgstr "Shrani & Uredi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create & Edit"
|
||||||
|
msgstr "Ustvari & Uredi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New"
|
||||||
|
msgstr "Novo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Duplicate"
|
||||||
|
msgstr "Podvoji"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Readonly/Editable"
|
||||||
|
msgstr "Samo za branje/možno urejanje"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<<"
|
||||||
|
msgstr "<<"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "0"
|
||||||
|
msgstr "0"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "/"
|
||||||
|
msgstr "/"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">>"
|
||||||
|
msgstr ">>"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "Dodaj"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Unhandled widget"
|
||||||
|
msgstr "Neobravnavani gradnik"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "?"
|
||||||
|
msgstr "?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#"
|
||||||
|
msgstr "#"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Done"
|
||||||
|
msgstr "Končano"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Open..."
|
||||||
|
msgstr "Odpri ..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Create..."
|
||||||
|
msgstr "Ustvari ..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Search..."
|
||||||
|
msgstr "Iskanje ..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "..."
|
||||||
|
msgstr "..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Uploading ..."
|
||||||
|
msgstr "Nalaganje..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Select"
|
||||||
|
msgstr "Izberi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save As"
|
||||||
|
msgstr "Shrani kot"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Clear"
|
||||||
|
msgstr "Počisti"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Advanced Filter"
|
||||||
|
msgstr "Napredni filter"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Filters --"
|
||||||
|
msgstr "-- Filtr i--"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "-- Actions --"
|
||||||
|
msgstr "-- Dejanja --"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save Filter"
|
||||||
|
msgstr "Shrani filter"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Manage Filters"
|
||||||
|
msgstr "Upravljanje filtrov"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Filter Name:"
|
||||||
|
msgstr "Ime filtra:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "(Any existing filter with the same name will be replaced)"
|
||||||
|
msgstr "(Vsak obstoječ filter z istim imenom bo zamenjan)"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Any of the following conditions must match"
|
||||||
|
msgstr "Vsak od teh pogojev se mora ujemati"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "All the following conditions must match"
|
||||||
|
msgstr "Vsi naslednji pogoji se morajo ujemati"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "None of the following conditions must match"
|
||||||
|
msgstr "Nobena od naslednjih pogojev se morajo ujemati"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Add condition"
|
||||||
|
msgstr "Dodaj pogoj"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "and"
|
||||||
|
msgstr "in"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Prekliči"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & New"
|
||||||
|
msgstr "Shrani & Novo"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save & Close"
|
||||||
|
msgstr "Shrani & Zapri"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export"
|
||||||
|
msgstr "Izvozi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"This wizard will export all data that matches the current search criteria to "
|
||||||
|
"a CSV file.\n"
|
||||||
|
" You can export all data or only the fields that can be "
|
||||||
|
"reimported after modification."
|
||||||
|
msgstr ""
|
||||||
|
"Ta čarovnik bo izvozil vse podatke, ki se ujemajo s trenutnim kriterijem "
|
||||||
|
"iskanja, v datoteko CSV.\n"
|
||||||
|
" Izvozite lahko vse podatke ali samo polja, ki jih je mogoče "
|
||||||
|
"ponovno uvoziti po spremembi."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Type:"
|
||||||
|
msgstr "Tip izvoza:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Compatible Export"
|
||||||
|
msgstr "Uvozi kompatibilen izvoz"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export all Data"
|
||||||
|
msgstr "Izvozi vse podatke"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Export Formats"
|
||||||
|
msgstr "Oblike izvoza"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Available fields"
|
||||||
|
msgstr "Razpoložljiva polja"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Fields to export"
|
||||||
|
msgstr "Polja za izvoz"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save fields list"
|
||||||
|
msgstr "Shrani seznam polj"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Odstrani"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Remove All"
|
||||||
|
msgstr "Odstrani vse"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "Ime"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Save as:"
|
||||||
|
msgstr "Shrani kot:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Ok"
|
||||||
|
msgstr "Vredu"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Saved exports:"
|
||||||
|
msgstr "Shranjeni izvozi:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Old Password:"
|
||||||
|
msgstr "Staro geslo:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "New Password:"
|
||||||
|
msgstr "Novo geslo:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Confirm Password:"
|
||||||
|
msgstr "Potrditev gesla:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import"
|
||||||
|
msgstr "Uvozi"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "1. Import a .CSV file"
|
||||||
|
msgstr "1. Uvozi .CSV datoteko"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Select a .CSV file to import. If you need a sample of file to import,\n"
|
||||||
|
" you should use the export tool with the \"Import Compatible\" option."
|
||||||
|
msgstr ""
|
||||||
|
"Izberi datoteko .CSV za uvoz. Če potrebujete vzorec daoteke za uvoz,\n"
|
||||||
|
" uporabite orodje izvoza z možnostjo \"Uvozi kompatibilno\"."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CSV File:"
|
||||||
|
msgstr "CSV datoteka:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "2. Check your file format"
|
||||||
|
msgstr "2. Preveri format datoteke"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Options"
|
||||||
|
msgstr "Možnosti uvoza"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Does your file have titles?"
|
||||||
|
msgstr "Ali ima vaša datoteka naslove?"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Separator:"
|
||||||
|
msgstr "Ločitelj:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delimiter:"
|
||||||
|
msgstr "Razmejitelj:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Encoding:"
|
||||||
|
msgstr "Nabor znakov:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "UTF-8"
|
||||||
|
msgstr "UTF-8"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Latin 1"
|
||||||
|
msgstr "Latin 1"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Lines to skip"
|
||||||
|
msgstr "Vrstice za preskočit"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "The import failed due to:"
|
||||||
|
msgstr "Uvoz ni uspel zaradi:"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Here is a preview of the file we could not import:"
|
||||||
|
msgstr "Tukaj je predogled datoteke, ki je nismo mogli uvozit"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP Web"
|
||||||
|
msgstr "OpenERP Web"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Version"
|
||||||
|
msgstr "Različica"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||||
|
msgstr "Copyright © 2011-DANES OpenERP SA. Vse pravice pridržane."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP is a trademark of the"
|
||||||
|
msgstr "OpenERP je blagovna znamka"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP SA Company"
|
||||||
|
msgstr "podjetja OpenERP SA"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Licenced under the terms of"
|
||||||
|
msgstr "Licencirana pod pogoji"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "GNU Affero General Public License"
|
||||||
|
msgstr "GNU Affero General Public License"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "About OpenERP"
|
||||||
|
msgstr "O OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "OpenERP"
|
||||||
|
msgstr "OpenERP"
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"is a free enterprise-scale software system that is designed to boost\n"
|
||||||
|
" productivity and profit through data integration. It connects, "
|
||||||
|
"improves and\n"
|
||||||
|
" manages business processes in areas such as sales, finance, "
|
||||||
|
"supply chain,\n"
|
||||||
|
" project management, production, services, CRM, etc..."
|
||||||
|
msgstr ""
|
||||||
|
"je brezplačna podjetniškega obsega sistemska programska oprema, ki je "
|
||||||
|
"namenjena za povečanje\n"
|
||||||
|
" produktivnosti in dobička skozi podatkovno integracijo. "
|
||||||
|
"Povezuje, izboljša in\n"
|
||||||
|
" upravlja poslovne procese v okoljih kot so prodaja, finance, "
|
||||||
|
"veriga dobavljanja,\n"
|
||||||
|
" upravljanje projektov, proizvodnje, storitev, CRM, itd..."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"The system is platform-independent, and can be installed on Windows, Mac OS "
|
||||||
|
"X,\n"
|
||||||
|
" and various Linux and other Unix-based distributions. Its "
|
||||||
|
"architecture enables\n"
|
||||||
|
" new functionality to be rapidly created, modifications to be "
|
||||||
|
"made to a\n"
|
||||||
|
" production system and migration to a new version to be "
|
||||||
|
"straightforward."
|
||||||
|
msgstr ""
|
||||||
|
"Sistem je neodvisnen od platforme in ga je mogoče namestiti na Windows, Mac "
|
||||||
|
"OS X,\n"
|
||||||
|
" in na različne Linux in ostale Unix-bazirane distribucije. "
|
||||||
|
"Njegova arhitektura omogoča\n"
|
||||||
|
" nove funkcionalnosti, ki so lahko hitro ustvarjene, "
|
||||||
|
"modifikacija, ki se naredi v\n"
|
||||||
|
" produkcijskem sistemu in migracijo na novo verzijo, ki se "
|
||||||
|
"enostavno izvede."
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Depending on your needs, OpenERP is available through a web or application "
|
||||||
|
"client."
|
||||||
|
msgstr ""
|
||||||
|
"Glede na vaše potrebe, je OpenERP na voljo prek spleta ali programskega "
|
||||||
|
"klienta."
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2011-09-06 12:02+0200\n"
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -17,28 +17,40 @@ msgstr ""
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Generated-By: Babel 0.9.6\n"
|
"Generated-By: Babel 0.9.6\n"
|
||||||
|
|
||||||
#: addons/web/static/src/js/form.js:1473
|
#: addons/web/static/src/js/view_form.js:355
|
||||||
|
msgid "Warning, the record has been modified, your changes will be discarded."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/view_form.js:1659
|
||||||
msgid "<em> Search More...</em>"
|
msgid "<em> Search More...</em>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/js/form.js:1486
|
#: addons/web/static/src/js/view_form.js:1672
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "<em> Create \"<strong>%s</strong>\"</em>"
|
msgid "<em> Create \"<strong>%s</strong>\"</em>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/js/form.js:1492
|
#: addons/web/static/src/js/view_form.js:1678
|
||||||
msgid "<em> Create and Edit...</em>"
|
msgid "<em> Create and Edit...</em>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/js/views.js:484
|
#: addons/web/static/src/js/views.js:568
|
||||||
|
msgid "You must choose at least one record."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:569
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/js/views.js:609
|
||||||
msgid "Translations"
|
msgid "Translations"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/js/views.js:489 addons/web/static/src/xml/base.xml:0
|
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/js/views.js:490
|
#: addons/web/static/src/js/views.js:615
|
||||||
msgid "Close"
|
msgid "Close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -229,23 +241,31 @@ msgid "LOGOUT"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/xml/base.xml:0
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
msgid "h3"
|
msgid "«"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/xml/base.xml:0
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
msgid "<"
|
msgid "»"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/xml/base.xml:0
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
msgid ">"
|
msgid "oe_secondary_menu_item"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/xml/base.xml:0
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
msgid "</"
|
msgid "oe_secondary_submenu_item"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/xml/base.xml:0
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
msgid "h4"
|
msgid "Hide this tip"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Disable all tips"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "View#"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/xml/base.xml:0
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
@ -284,6 +304,14 @@ msgstr ""
|
||||||
msgid "First"
|
msgid "First"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "<"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ">"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/xml/base.xml:0
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
msgid "Last"
|
msgid "Last"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -292,10 +320,6 @@ msgstr ""
|
||||||
msgid "♻"
|
msgid "♻"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/xml/base.xml:0
|
|
||||||
msgid "View#"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: addons/web/static/src/xml/base.xml:0
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
msgid "Save & Edit"
|
msgid "Save & Edit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -308,6 +332,14 @@ msgstr ""
|
||||||
msgid "New"
|
msgid "New"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Duplicate"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Readonly/Editable"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/xml/base.xml:0
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
msgid "<<"
|
msgid "<<"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -336,6 +368,14 @@ msgstr ""
|
||||||
msgid "?"
|
msgid "?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "#"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Done"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/xml/base.xml:0
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
msgid "Open..."
|
msgid "Open..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -508,6 +548,69 @@ msgstr ""
|
||||||
msgid "Confirm Password:"
|
msgid "Confirm Password:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "1. Import a .CSV file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid ""
|
||||||
|
"Select a .CSV file to import. If you need a sample of file to import,\n"
|
||||||
|
" you should use the export tool with the \"Import Compatible\" "
|
||||||
|
"option."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "CSV File:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "2. Check your file format"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Import Options"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Does your file have titles?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Separator:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Delimiter:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Encoding:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "UTF-8"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Latin 1"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Lines to skip"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "The import failed due to:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
|
msgid "Here is a preview of the file we could not import:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: addons/web/static/src/xml/base.xml:0
|
#: addons/web/static/src/xml/base.xml:0
|
||||||
msgid "OpenERP Web"
|
msgid "OpenERP Web"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
Copyright 2011 Xavier Morel. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY XAVIER MOREL ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,59 @@
|
||||||
|
.. -*- restructuredtext -*-
|
||||||
|
|
||||||
|
In jQuery 1.5, jQuery has introduced a Deferred object in order to
|
||||||
|
better handle callbacks.
|
||||||
|
|
||||||
|
Along with Deferred, it introduced ``jQuery.when`` which allows, among
|
||||||
|
other things, for multiplexing deferreds (waiting on multiple
|
||||||
|
deferreds at the same time).
|
||||||
|
|
||||||
|
While this is very nice if all deferreds are available at the same
|
||||||
|
point, it doesn't really work if the resolution of a deferred can
|
||||||
|
generate more deferreds, or for collections of deferreds coming from
|
||||||
|
multiple sources (which may not be aware of one another).
|
||||||
|
|
||||||
|
Deferred.queue tries to be a solution to this. It is based on the
|
||||||
|
principle of FIFO multiple-producers multiple-consumers tasks queues,
|
||||||
|
such as Python's `queue.Queue`_. Any code with a reference to the
|
||||||
|
queue can add a promise to the queue, and the queue (which is a
|
||||||
|
promise itself) will only be resolved once all promises within are
|
||||||
|
resolved.
|
||||||
|
|
||||||
|
Quickstart
|
||||||
|
----------
|
||||||
|
|
||||||
|
Deferred.queue has a very simple life cycle: it is dormant when
|
||||||
|
created, it starts working as soon as promises get added to it (via
|
||||||
|
``.push``, or by providing them directly to its constructor), and as
|
||||||
|
soon as the last promise in the queue is resolved it resolves itself.
|
||||||
|
|
||||||
|
If any promise in the queue fails, the queue itself will be rejected
|
||||||
|
(without waiting for further promises).
|
||||||
|
|
||||||
|
Once a queue has been resolved or rejected, adding new promises to it
|
||||||
|
results in an error.
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
``jQuery.Deferred.queue([promises...])``
|
||||||
|
Creates a new deferred queue. Can be primed with a series of promise
|
||||||
|
objects.
|
||||||
|
|
||||||
|
``.push(promise...)``
|
||||||
|
Adds promises to the queue. Returns the queue itself (can be
|
||||||
|
chained).
|
||||||
|
|
||||||
|
If the queue has already been resolved or rejected, raises an error.
|
||||||
|
|
||||||
|
``.then([doneCallbacks][, failCallbacks])``
|
||||||
|
Promise/A ``then`` method.
|
||||||
|
|
||||||
|
``.done(doneCallbacks)``
|
||||||
|
jQuery ``done`` extension to promise objects
|
||||||
|
|
||||||
|
``.fail(failCallbacks)``
|
||||||
|
jQuery ``fail`` extension to promise objects
|
||||||
|
|
||||||
|
.. _queue.Queue:
|
||||||
|
http://docs.python.org/dev/library/queue.html
|
|
@ -0,0 +1,34 @@
|
||||||
|
(function ($) {
|
||||||
|
"use strict";
|
||||||
|
$.extend($.Deferred, {
|
||||||
|
queue: function () {
|
||||||
|
var queueDeferred = $.Deferred();
|
||||||
|
var promises = 0;
|
||||||
|
|
||||||
|
function resolve() {
|
||||||
|
if (--promises > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setTimeout($.proxy(queueDeferred, 'resolve'), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
var promise = $.extend(queueDeferred.promise(), {
|
||||||
|
push: function () {
|
||||||
|
if (this.isResolved() || this.isRejected()) {
|
||||||
|
throw new Error("Can not add promises to a resolved "
|
||||||
|
+ "or rejected promise queue");
|
||||||
|
}
|
||||||
|
|
||||||
|
promises += 1;
|
||||||
|
$.when.apply(null, arguments).then(
|
||||||
|
resolve, $.proxy(queueDeferred, 'reject'));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (arguments.length) {
|
||||||
|
promise.push.apply(promise, arguments);
|
||||||
|
}
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})(jQuery)
|
|
@ -0,0 +1,5 @@
|
||||||
|
repo: 076b192d0d8ab2b92d1dbcfa3da055382f30eaea
|
||||||
|
node: 87fb1b67d6a13f10a1a328104ee4d4b2c36801ec
|
||||||
|
branch: default
|
||||||
|
latesttag: 0.2
|
||||||
|
latesttagdistance: 1
|
|
@ -0,0 +1 @@
|
||||||
|
Parser and evaluator of Python expressions
|
|
@ -0,0 +1,14 @@
|
||||||
|
* Parser
|
||||||
|
since parsing expressions, try with a pratt parser
|
||||||
|
http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
|
||||||
|
http://effbot.org/zone/simple-top-down-parsing.htm
|
||||||
|
|
||||||
|
Evaluator
|
||||||
|
---------
|
||||||
|
|
||||||
|
* Stop busyworking trivial binary operator
|
||||||
|
* Make it *trivial* to build Python type-wrappers
|
||||||
|
* Implement Python's `data model
|
||||||
|
protocols<http://docs.python.org/reference/datamodel.html#basic-customization>`_
|
||||||
|
for *all* supported operations, optimizations can come later
|
||||||
|
* Automatically type-wrap everything (for now anyway)
|
|
@ -0,0 +1,546 @@
|
||||||
|
var py = {};
|
||||||
|
(function (exports) {
|
||||||
|
var NUMBER = /^\d$/,
|
||||||
|
NAME_FIRST = /^[a-zA-Z_]$/,
|
||||||
|
NAME = /^[a-zA-Z0-9_]$/;
|
||||||
|
|
||||||
|
var create = function (o, props) {
|
||||||
|
function F() {}
|
||||||
|
F.prototype = o;
|
||||||
|
var inst = new F;
|
||||||
|
for(var name in props) {
|
||||||
|
if(!props.hasOwnProperty(name)) { continue; }
|
||||||
|
inst[name] = props[name];
|
||||||
|
}
|
||||||
|
return inst;
|
||||||
|
};
|
||||||
|
|
||||||
|
var symbols = {};
|
||||||
|
var comparators = {};
|
||||||
|
var Base = {
|
||||||
|
nud: function () { throw new Error(this.id + " undefined as prefix"); },
|
||||||
|
led: function (led) { throw new Error(this.id + " undefined as infix"); },
|
||||||
|
toString: function () {
|
||||||
|
if (this.id === '(constant)' || this.id === '(number)' || this.id === '(name)' || this.id === '(string)') {
|
||||||
|
return [this.id.slice(0, this.id.length-1), ' ', this.value, ')'].join('');
|
||||||
|
} else if (this.id === '(end)') {
|
||||||
|
return '(end)';
|
||||||
|
} else if (this.id === '(comparator)' ) {
|
||||||
|
var repr = ['(comparator', this.expressions[0]];
|
||||||
|
for (var i=0;i<this.operators.length; ++i) {
|
||||||
|
repr.push(this.operators[i], this.expressions[i+1]);
|
||||||
|
}
|
||||||
|
return repr.join(' ') + ')';
|
||||||
|
}
|
||||||
|
var out = [this.id, this.first, this.second, this.third]
|
||||||
|
.filter(function (r){return r}).join(' ');
|
||||||
|
return '(' + out + ')';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function symbol(id, bp) {
|
||||||
|
bp = bp || 0;
|
||||||
|
var s = symbols[id];
|
||||||
|
if (s) {
|
||||||
|
if (bp > s.lbp) {
|
||||||
|
s.lbp = bp;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return symbols[id] = create(Base, {
|
||||||
|
id: id,
|
||||||
|
lbp: bp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function constant(id) {
|
||||||
|
symbol(id).nud = function () {
|
||||||
|
this.id = "(constant)";
|
||||||
|
this.value = id;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function prefix(id, bp, nud) {
|
||||||
|
symbol(id).nud = nud || function () {
|
||||||
|
this.first = expression(bp);
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function infix(id, bp, led) {
|
||||||
|
symbol(id, bp).led = led || function (left) {
|
||||||
|
this.first = left;
|
||||||
|
this.second = expression(bp);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function infixr(id, bp) {
|
||||||
|
symbol(id, bp).led = function (left) {
|
||||||
|
this.first = left;
|
||||||
|
this.second = expression(bp - 1);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function comparator(id) {
|
||||||
|
comparators[id] = true;
|
||||||
|
var bp = 60;
|
||||||
|
infix(id, bp, function (left) {
|
||||||
|
this.id = '(comparator)';
|
||||||
|
this.operators = [id];
|
||||||
|
this.expressions = [left, expression(bp)];
|
||||||
|
while (token.id in comparators) {
|
||||||
|
this.operators.push(token.id);
|
||||||
|
advance();
|
||||||
|
this.expressions.push(
|
||||||
|
expression(bp));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
constant('None'); constant('False'); constant('True');
|
||||||
|
|
||||||
|
symbol('(number)').nud = function () { return this; };
|
||||||
|
symbol('(name)').nud = function () { return this; };
|
||||||
|
symbol('(string)').nud = function () { return this; };
|
||||||
|
symbol('(end)');
|
||||||
|
|
||||||
|
symbol(':'); symbol(')'); symbol(']'); symbol('}'); symbol(',');
|
||||||
|
symbol('else');
|
||||||
|
|
||||||
|
symbol('lambda', 20).nud = function () {
|
||||||
|
this.first = [];
|
||||||
|
if (token.id !== ':') {
|
||||||
|
for(;;) {
|
||||||
|
if (token.id !== '(name)') {
|
||||||
|
throw new Error('Excepted an argument name');
|
||||||
|
}
|
||||||
|
this.first.push(token);
|
||||||
|
advance();
|
||||||
|
if (token.id !== ',') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
advance(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
advance(':');
|
||||||
|
this.second = expression();
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
infix('if', 20, function (left) {
|
||||||
|
this.first = left;
|
||||||
|
this.second = expression();
|
||||||
|
advance('else');
|
||||||
|
this.third = expression();
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
|
||||||
|
infixr('or', 30); infixr('and', 40); prefix('not', 50);
|
||||||
|
|
||||||
|
comparator('in'); comparator('not in');
|
||||||
|
comparator('is'); comparator('is not');
|
||||||
|
comparator('<'); comparator('<=');
|
||||||
|
comparator('>'); comparator('>=');
|
||||||
|
comparator('<>'); comparator('!='); comparator('==');
|
||||||
|
|
||||||
|
infix('|', 70); infix('^', 80), infix('&', 90);
|
||||||
|
|
||||||
|
infix('<<', 100); infix('>>', 100);
|
||||||
|
|
||||||
|
infix('+', 110); infix('-', 110);
|
||||||
|
|
||||||
|
infix('*', 120); infix('/', 120);
|
||||||
|
infix('//', 120), infix('%', 120);
|
||||||
|
|
||||||
|
prefix('-', 130); prefix('+', 130); prefix('~', 130);
|
||||||
|
|
||||||
|
infixr('**', 140);
|
||||||
|
|
||||||
|
infix('.', 150, function (left) {
|
||||||
|
if (token.id !== '(name)') {
|
||||||
|
throw new Error('Expected attribute name, got ', token.id);
|
||||||
|
}
|
||||||
|
this.first = left;
|
||||||
|
this.second = token;
|
||||||
|
advance();
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
symbol('(', 150).nud = function () {
|
||||||
|
this.first = [];
|
||||||
|
var comma = false;
|
||||||
|
if (token.id !== ')') {
|
||||||
|
while (true) {
|
||||||
|
if (token.id === ')') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.first.push(expression());
|
||||||
|
if (token.id !== ',') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
comma = true;
|
||||||
|
advance(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
advance(')');
|
||||||
|
if (!this.first.length || comma) {
|
||||||
|
return this;
|
||||||
|
} else {
|
||||||
|
return this.first[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
symbol('(').led = function (left) {
|
||||||
|
this.first = left;
|
||||||
|
this.second = [];
|
||||||
|
if (token.id !== ")") {
|
||||||
|
for(;;) {
|
||||||
|
this.second.push(expression());
|
||||||
|
if (token.id !== ',') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
advance(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
advance(")");
|
||||||
|
return this;
|
||||||
|
|
||||||
|
};
|
||||||
|
infix('[', 150, function (left) {
|
||||||
|
this.first = left;
|
||||||
|
this.second = expression();
|
||||||
|
advance("]");
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
symbol('[').nud = function () {
|
||||||
|
this.first = [];
|
||||||
|
if (token.id !== ']') {
|
||||||
|
for (;;) {
|
||||||
|
if (token.id === ']') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.first.push(expression());
|
||||||
|
if (token.id !== ',') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
advance(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
advance(']');
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
symbol('{').nud = function () {
|
||||||
|
this.first = [];
|
||||||
|
if (token.id !== '}') {
|
||||||
|
for(;;) {
|
||||||
|
if (token.id === '}') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var key = expression();
|
||||||
|
advance(':');
|
||||||
|
var value = expression();
|
||||||
|
this.first.push([key, value]);
|
||||||
|
if (token.id !== ',') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
advance(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
advance('}');
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
var longops = {
|
||||||
|
'*': ['*'],
|
||||||
|
'<': ['<', '=', '>'],
|
||||||
|
'>': ['=', '>'],
|
||||||
|
'!': ['='],
|
||||||
|
'=': ['='],
|
||||||
|
'/': ['/']
|
||||||
|
};
|
||||||
|
function Tokenizer() {
|
||||||
|
this.states = ['initial'];
|
||||||
|
this.tokens = [];
|
||||||
|
}
|
||||||
|
Tokenizer.prototype = {
|
||||||
|
builder: function (empty) {
|
||||||
|
var key = this.states[0] + '_builder';
|
||||||
|
if (empty) {
|
||||||
|
var value = this[key];
|
||||||
|
delete this[key];
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return this[key] = this[key] || [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
simple: function (type) {
|
||||||
|
this.tokens.push({type: type});
|
||||||
|
},
|
||||||
|
push: function (new_state) {
|
||||||
|
this.states.push(new_state);
|
||||||
|
},
|
||||||
|
pop: function () {
|
||||||
|
this.states.pop();
|
||||||
|
},
|
||||||
|
|
||||||
|
feed: function (str, index) {
|
||||||
|
var s = this.states;
|
||||||
|
return this[s[s.length - 1]](str, index);
|
||||||
|
},
|
||||||
|
|
||||||
|
initial: function (str, index) {
|
||||||
|
var character = str[index];
|
||||||
|
|
||||||
|
if (character in longops) {
|
||||||
|
var follow = longops[character];
|
||||||
|
for(var i=0, len=follow.length; i<len; ++i) {
|
||||||
|
if (str[index+1] === follow[i]) {
|
||||||
|
character += follow[i];
|
||||||
|
index++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (character === ' ') {
|
||||||
|
return index+1;
|
||||||
|
} else if (character === '\0') {
|
||||||
|
this.tokens.push(symbols['(end)']);
|
||||||
|
return index + 1
|
||||||
|
} else if (character === '"' || character === "'") {
|
||||||
|
this.push('string');
|
||||||
|
return index + 1;
|
||||||
|
} else if (NUMBER.test(character)) {
|
||||||
|
this.push('number');
|
||||||
|
return index;
|
||||||
|
} else if (NAME_FIRST.test(character)) {
|
||||||
|
this.push('name');
|
||||||
|
return index;
|
||||||
|
} else if (character in symbols) {
|
||||||
|
this.tokens.push(create(symbols[character]));
|
||||||
|
return index + 1;
|
||||||
|
}
|
||||||
|
throw new Error("Tokenizing failure of <<" + str + ">> at index " + index
|
||||||
|
+ ", character [[" + character + "]]"
|
||||||
|
+ "; parsed so far: " + this.tokens);
|
||||||
|
},
|
||||||
|
string: function (str, index) {
|
||||||
|
var character = str[index];
|
||||||
|
if (character === '"' || character === "'") {
|
||||||
|
this.tokens.push(create(symbols['(string)'], {
|
||||||
|
value: this.builder(true).join('')
|
||||||
|
}));
|
||||||
|
this.pop();
|
||||||
|
return index + 1;
|
||||||
|
}
|
||||||
|
this.builder().push(character);
|
||||||
|
return index + 1;
|
||||||
|
},
|
||||||
|
number: function (str, index) {
|
||||||
|
var character = str[index];
|
||||||
|
if (!NUMBER.test(character)) {
|
||||||
|
this.tokens.push(create(symbols['(number)'], {
|
||||||
|
value: parseFloat(this.builder(true).join(''))
|
||||||
|
}));
|
||||||
|
this.pop();
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
this.builder().push(character);
|
||||||
|
return index + 1;
|
||||||
|
},
|
||||||
|
name: function (str, index) {
|
||||||
|
var character = str[index];
|
||||||
|
if (!NAME.test(character)) {
|
||||||
|
var name = this.builder(true).join('');
|
||||||
|
var symbol = symbols[name];
|
||||||
|
if (symbol) {
|
||||||
|
if (name === 'in' && this.tokens[this.tokens.length-1].id === 'not') {
|
||||||
|
symbol = symbols['not in'];
|
||||||
|
this.tokens.pop();
|
||||||
|
} else if (name === 'not' && this.tokens[this.tokens.length-1].id === 'is') {
|
||||||
|
symbol = symbols['is not'];
|
||||||
|
this.tokens.pop();
|
||||||
|
}
|
||||||
|
this.tokens.push(create(symbol));
|
||||||
|
} else {
|
||||||
|
this.tokens.push(create(symbols['(name)'], {
|
||||||
|
value: name
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
this.pop();
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
this.builder().push(character);
|
||||||
|
return index + 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.tokenize = function tokenize(str) {
|
||||||
|
var index = 0,
|
||||||
|
tokenizer = new Tokenizer(str);
|
||||||
|
str += '\0';
|
||||||
|
|
||||||
|
do {
|
||||||
|
index = tokenizer.feed(str, index);
|
||||||
|
} while (index !== str.length);
|
||||||
|
return tokenizer.tokens;
|
||||||
|
};
|
||||||
|
|
||||||
|
var token, next;
|
||||||
|
function expression(rbp) {
|
||||||
|
rbp = rbp || 0;
|
||||||
|
var t = token;
|
||||||
|
token = next();
|
||||||
|
var left = t.nud();
|
||||||
|
while (rbp < token.lbp) {
|
||||||
|
t = token;
|
||||||
|
token = next();
|
||||||
|
left = t.led(left);
|
||||||
|
}
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
function advance(id) {
|
||||||
|
if (id && token.id !== id) {
|
||||||
|
throw new Error(
|
||||||
|
'Expected "' + id + '", got "' + token.id + '"');
|
||||||
|
}
|
||||||
|
token = next();
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.object = create({}, {});
|
||||||
|
exports.bool = function (arg) { return !!arg; };
|
||||||
|
exports.tuple = create(exports.object, {
|
||||||
|
__contains__: function (value) {
|
||||||
|
for(var i=0, len=this.values.length; i<len; ++i) {
|
||||||
|
if (this.values[i] === value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
toJSON: function () {
|
||||||
|
return this.values;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
exports.list = exports.tuple;
|
||||||
|
exports.dict = create(exports.object, {
|
||||||
|
toJSON: function () {
|
||||||
|
return this.values;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.parse = function (toks) {
|
||||||
|
var index = 0;
|
||||||
|
token = toks[0];
|
||||||
|
next = function () { return toks[++index]; };
|
||||||
|
return expression();
|
||||||
|
};
|
||||||
|
var evaluate_operator = function (operator, a, b) {
|
||||||
|
switch (operator) {
|
||||||
|
case '==': case 'is': return a === b;
|
||||||
|
case '!=': case 'is not': return a !== b;
|
||||||
|
case '<': return a < b;
|
||||||
|
case '<=': return a <= b;
|
||||||
|
case '>': return a > b;
|
||||||
|
case '>=': return a >= b;
|
||||||
|
case 'in':
|
||||||
|
if (typeof b === 'string') {
|
||||||
|
return b.indexOf(a) !== -1;
|
||||||
|
}
|
||||||
|
return b.__contains__(a);
|
||||||
|
case 'not in':
|
||||||
|
if (typeof b === 'string') {
|
||||||
|
return b.indexOf(a) === -1;
|
||||||
|
}
|
||||||
|
return !b.__contains__(a);
|
||||||
|
}
|
||||||
|
throw new Error('SyntaxError: unknown comparator [[' + operator + ']]');
|
||||||
|
};
|
||||||
|
exports.evaluate = function (expr, context) {
|
||||||
|
switch (expr.id) {
|
||||||
|
case '(name)':
|
||||||
|
var val = context[expr.value];
|
||||||
|
if (val === undefined) {
|
||||||
|
throw new Error("NameError: name '" + expr.value + "' is not defined");
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
case '(string)':
|
||||||
|
case '(number)':
|
||||||
|
return expr.value;
|
||||||
|
case '(constant)':
|
||||||
|
if (expr.value === 'None')
|
||||||
|
return null;
|
||||||
|
else if (expr.value === 'False')
|
||||||
|
return false;
|
||||||
|
else if (expr.value === 'True')
|
||||||
|
return true;
|
||||||
|
throw new Error("SyntaxError: unknown constant '" + expr.value + "'");
|
||||||
|
case '(comparator)':
|
||||||
|
var result, left = exports.evaluate(expr.expressions[0], context);
|
||||||
|
for(var i=0; i<expr.operators.length; ++i) {
|
||||||
|
result = evaluate_operator(
|
||||||
|
expr.operators[i],
|
||||||
|
left,
|
||||||
|
left = exports.evaluate(expr.expressions[i+1], context));
|
||||||
|
if (!result) { return false; }
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
case '-':
|
||||||
|
if (expr.second) {
|
||||||
|
throw new Error('SyntaxError: binary [-] not implemented yet');
|
||||||
|
}
|
||||||
|
return -(exports.evaluate(expr.first, context));
|
||||||
|
case 'not':
|
||||||
|
return !(exports.evaluate(expr.first, context));
|
||||||
|
case 'and':
|
||||||
|
return (exports.evaluate(expr.first, context)
|
||||||
|
&& exports.evaluate(expr.second, context));
|
||||||
|
case 'or':
|
||||||
|
return (exports.evaluate(expr.first, context)
|
||||||
|
|| exports.evaluate(expr.second, context));
|
||||||
|
case '(':
|
||||||
|
if (expr.second) {
|
||||||
|
var fn = exports.evaluate(expr.first, context), args=[];
|
||||||
|
for (var jj=0; jj<expr.second.length; ++jj) {
|
||||||
|
args.push(exports.evaluate(
|
||||||
|
expr.second[jj], context));
|
||||||
|
}
|
||||||
|
return fn.apply(null, args);
|
||||||
|
}
|
||||||
|
var tuple_exprs = expr.first,
|
||||||
|
tuple_values = [];
|
||||||
|
for (var j=0, len=tuple_exprs.length; j<len; ++j) {
|
||||||
|
tuple_values.push(exports.evaluate(
|
||||||
|
tuple_exprs[j], context));
|
||||||
|
}
|
||||||
|
return create(exports.tuple, {values: tuple_values});
|
||||||
|
case '[':
|
||||||
|
if (expr.second) {
|
||||||
|
throw new Error('SyntaxError: indexing not implemented yet');
|
||||||
|
}
|
||||||
|
var list_exprs = expr.first, list_values = [];
|
||||||
|
for (var k=0; k<list_exprs.length; ++k) {
|
||||||
|
list_values.push(exports.evaluate(
|
||||||
|
list_exprs[k], context));
|
||||||
|
}
|
||||||
|
return create(exports.list, {values: list_values});
|
||||||
|
case '{':
|
||||||
|
var dict_exprs = expr.first, dict_values = {};
|
||||||
|
for(var l=0; l<dict_exprs.length; ++l) {
|
||||||
|
dict_values[exports.evaluate(dict_exprs[l][0], context)] =
|
||||||
|
exports.evaluate(dict_exprs[l][1], context);
|
||||||
|
}
|
||||||
|
return create(exports.dict, {values: dict_values});
|
||||||
|
case '.':
|
||||||
|
if (expr.second.id !== '(name)') {
|
||||||
|
throw new Error('SyntaxError: ' + expr);
|
||||||
|
}
|
||||||
|
return exports.evaluate(expr.first, context)[expr.second.value];
|
||||||
|
default:
|
||||||
|
throw new Error('SyntaxError: Unknown node [[' + expr.id + ']]');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.eval = function (str, context) {
|
||||||
|
return exports.evaluate(
|
||||||
|
exports.parse(
|
||||||
|
exports.tokenize(
|
||||||
|
str)),
|
||||||
|
context);
|
||||||
|
}
|
||||||
|
})(typeof exports === 'undefined' ? py : exports);
|
|
@ -0,0 +1,90 @@
|
||||||
|
var py = require('../lib/py.js'),
|
||||||
|
assert = require('assert');
|
||||||
|
|
||||||
|
// Literals
|
||||||
|
assert.strictEqual(py.eval('1'), 1);
|
||||||
|
assert.strictEqual(py.eval('None'), null);
|
||||||
|
assert.strictEqual(py.eval('False'), false);
|
||||||
|
assert.strictEqual(py.eval('True'), true);
|
||||||
|
assert.strictEqual(py.eval('"somestring"'), 'somestring');
|
||||||
|
assert.strictEqual(py.eval("'somestring'"), 'somestring');
|
||||||
|
assert.deepEqual(py.eval("()").toJSON(), []);
|
||||||
|
assert.deepEqual(py.eval("[]").toJSON(), []);
|
||||||
|
assert.deepEqual(py.eval("{}").toJSON(), {});
|
||||||
|
assert.deepEqual(py.eval("(None, True, False, 0, 1, 'foo')").toJSON(),
|
||||||
|
[null, true, false, 0, 1, 'foo']);
|
||||||
|
assert.deepEqual(py.eval("[None, True, False, 0, 1, 'foo']").toJSON(),
|
||||||
|
[null, true, false, 0, 1, 'foo']);
|
||||||
|
assert.deepEqual(py.eval("{'foo': 1, foo: 2}", {foo: 'bar'}).toJSON(),
|
||||||
|
{foo: 1, bar: 2});
|
||||||
|
|
||||||
|
// Equality tests
|
||||||
|
assert.ok(py.eval(
|
||||||
|
"foo == 'foo'", {foo: 'foo'}));
|
||||||
|
// Inequality
|
||||||
|
assert.ok(py.eval(
|
||||||
|
"foo != bar", {foo: 'foo', bar: 'bar'}));
|
||||||
|
|
||||||
|
// Comparisons
|
||||||
|
assert.ok(py.eval('3 < 5'));
|
||||||
|
assert.ok(py.eval('5 >= 3'));
|
||||||
|
assert.ok(py.eval('3 >= 3'));
|
||||||
|
assert.ok(!py.eval('5 < 3'));
|
||||||
|
assert.ok(py.eval('1 < 3 < 5'));
|
||||||
|
assert.ok(py.eval('5 > 3 > 1'));
|
||||||
|
assert.ok(py.eval('1 < 3 > 2 == 2 > -2 not in (0, 1, 2)'));
|
||||||
|
// string rich comparisons
|
||||||
|
assert.ok(py.eval(
|
||||||
|
'date >= current', {date: '2010-06-08', current: '2010-06-05'}));
|
||||||
|
|
||||||
|
// Boolean operators
|
||||||
|
assert.ok(py.eval(
|
||||||
|
"foo == 'foo' or foo == 'bar'", {foo: 'bar'}));
|
||||||
|
assert.ok(py.eval(
|
||||||
|
"foo == 'foo' and bar == 'bar'", {foo: 'foo', bar: 'bar'}));
|
||||||
|
// - lazyness, second clauses NameError if not short-circuited
|
||||||
|
assert.ok(py.eval(
|
||||||
|
"foo == 'foo' or bar == 'bar'", {foo: 'foo'}));
|
||||||
|
assert.ok(!py.eval(
|
||||||
|
"foo == 'foo' and bar == 'bar'", {foo: 'bar'}));
|
||||||
|
|
||||||
|
// contains (in)
|
||||||
|
assert.ok(py.eval(
|
||||||
|
"foo in ('foo', 'bar')", {foo: 'bar'}));
|
||||||
|
assert.ok(py.eval('1 in (1, 2, 3, 4)'));
|
||||||
|
assert.ok(!py.eval('1 in (2, 3, 4)'));
|
||||||
|
assert.ok(py.eval('type in ("url",)', {type: 'url'}));
|
||||||
|
assert.ok(!py.eval('type in ("url",)', {type: 'ur'}));
|
||||||
|
assert.ok(py.eval('1 not in (2, 3, 4)'));
|
||||||
|
assert.ok(py.eval('type not in ("url",)', {type: 'ur'}));
|
||||||
|
|
||||||
|
assert.ok(py.eval(
|
||||||
|
"foo in ['foo', 'bar']", {foo: 'bar'}));
|
||||||
|
// string contains
|
||||||
|
assert.ok(py.eval('type in "view"', {type: 'view'}));
|
||||||
|
assert.ok(!py.eval('type in "view"', {type: 'bob'}));
|
||||||
|
assert.ok(py.eval('type in "url"', {type: 'ur'}));
|
||||||
|
|
||||||
|
// Literals
|
||||||
|
assert.strictEqual(py.eval('False'), false);
|
||||||
|
assert.strictEqual(py.eval('True'), true);
|
||||||
|
assert.strictEqual(py.eval('None'), null);
|
||||||
|
assert.ok(py.eval('foo == False', {foo: false}));
|
||||||
|
assert.ok(!py.eval('foo == False', {foo: true}));
|
||||||
|
|
||||||
|
// conversions
|
||||||
|
assert.strictEqual(
|
||||||
|
py.eval('bool(date_deadline)', {bool: py.bool, date_deadline: '2008'}),
|
||||||
|
true);
|
||||||
|
|
||||||
|
// getattr
|
||||||
|
assert.ok(py.eval('foo.bar', {foo: {bar: true}}));
|
||||||
|
assert.ok(!py.eval('foo.bar', {foo: {bar: false}}));
|
||||||
|
|
||||||
|
// complex expressions
|
||||||
|
assert.ok(py.eval(
|
||||||
|
"state=='pending' and not(date_deadline and (date_deadline < current_date))",
|
||||||
|
{state: 'pending', date_deadline: false}));
|
||||||
|
assert.ok(py.eval(
|
||||||
|
"state=='pending' and not(date_deadline and (date_deadline < current_date))",
|
||||||
|
{state: 'pending', date_deadline: '2010-05-08', current_date: '2010-05-08'}));;
|
|
@ -207,6 +207,7 @@ QWeb2.Engine = (function() {
|
||||||
this.reserved_words = QWeb2.RESERVED_WORDS.slice(0);
|
this.reserved_words = QWeb2.RESERVED_WORDS.slice(0);
|
||||||
this.actions_precedence = QWeb2.ACTIONS_PRECEDENCE.slice(0);
|
this.actions_precedence = QWeb2.ACTIONS_PRECEDENCE.slice(0);
|
||||||
this.word_replacement = QWeb2.tools.extend({}, QWeb2.WORD_REPLACEMENT);
|
this.word_replacement = QWeb2.tools.extend({}, QWeb2.WORD_REPLACEMENT);
|
||||||
|
this.format_text_node = null;
|
||||||
for (var i = 0; i < arguments.length; i++) {
|
for (var i = 0; i < arguments.length; i++) {
|
||||||
this.add_template(arguments[i]);
|
this.add_template(arguments[i]);
|
||||||
}
|
}
|
||||||
|
@ -317,12 +318,14 @@ QWeb2.Engine = (function() {
|
||||||
" dict = dict || {};\n" +
|
" dict = dict || {};\n" +
|
||||||
" dict['__template__'] = '" + template + "';\n" +
|
" dict['__template__'] = '" + template + "';\n" +
|
||||||
" var r = [];\n" +
|
" var r = [];\n" +
|
||||||
" /* START TEMPLATE */ try {\n" +
|
" /* START TEMPLATE */" +
|
||||||
|
(this.debug ? "" : " try {\n") +
|
||||||
(e.compile()) + "\n" +
|
(e.compile()) + "\n" +
|
||||||
" /* END OF TEMPLATE */ } catch(error) {\n" +
|
" /* END OF TEMPLATE */" +
|
||||||
|
(this.debug ? "" : " } catch(error) {\n" +
|
||||||
" if (console && console.exception) console.exception(error);\n" +
|
" if (console && console.exception) console.exception(error);\n" +
|
||||||
" context.engine.tools.exception('Runtime Error: ' + error, context);\n" +
|
" context.engine.tools.exception('Runtime Error: ' + error, context);\n") +
|
||||||
" }\n" +
|
(this.debug ? "" : " }\n") +
|
||||||
" return r.join('');";
|
" return r.join('');";
|
||||||
},
|
},
|
||||||
render : function(template, dict) {
|
render : function(template, dict) {
|
||||||
|
@ -486,12 +489,16 @@ QWeb2.Element = (function() {
|
||||||
},
|
},
|
||||||
_compile : function() {
|
_compile : function() {
|
||||||
switch (this.node.nodeType) {
|
switch (this.node.nodeType) {
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
this.top_string(this.node.data);
|
var text = this.node.data;
|
||||||
|
if (this.engine.format_text_node) {
|
||||||
|
text = this.engine.format_text_node.call(this, text);
|
||||||
|
}
|
||||||
|
this.top_string(text);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
this.compile_element();
|
this.compile_element();
|
||||||
}
|
}
|
||||||
var r = this._top.join('');
|
var r = this._top.join('');
|
||||||
if (this.process_children) {
|
if (this.process_children) {
|
||||||
|
|
|
@ -4,301 +4,436 @@
|
||||||
// Documentation: https://github.com/edtsech/underscore.string
|
// Documentation: https://github.com/edtsech/underscore.string
|
||||||
// Some code is borrowed from MooTools and Alexandru Marasteanu.
|
// Some code is borrowed from MooTools and Alexandru Marasteanu.
|
||||||
|
|
||||||
// Version 1.1.4
|
// Version 1.1.6
|
||||||
|
|
||||||
(function(){
|
|
||||||
// ------------------------- Baseline setup ---------------------------------
|
|
||||||
|
|
||||||
// Establish the root object, "window" in the browser, or "global" on the server.
|
(function(root){
|
||||||
var root = this;
|
'use strict';
|
||||||
|
|
||||||
var nativeTrim = String.prototype.trim;
|
if (typeof _ != 'undefined') {
|
||||||
|
var _reverse = _().reverse,
|
||||||
|
_include = _.include;
|
||||||
|
}
|
||||||
|
|
||||||
function str_repeat(i, m) {
|
// Defining helper functions.
|
||||||
for (var o = []; m > 0; o[--m] = i);
|
|
||||||
return o.join('');
|
var nativeTrim = String.prototype.trim;
|
||||||
|
|
||||||
|
var parseNumber = function(source) { return source * 1 || 0; };
|
||||||
|
|
||||||
|
var strRepeat = function(i, m) {
|
||||||
|
for (var o = []; m > 0; o[--m] = i);
|
||||||
|
return o.join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
var slice = function(a){
|
||||||
|
return Array.prototype.slice.call(a);
|
||||||
|
};
|
||||||
|
|
||||||
|
var defaultToWhiteSpace = function(characters){
|
||||||
|
if (characters) {
|
||||||
|
return _s.escapeRegExp(characters);
|
||||||
|
}
|
||||||
|
return '\\s';
|
||||||
|
};
|
||||||
|
|
||||||
|
var sArgs = function(method){
|
||||||
|
return function(){
|
||||||
|
var args = slice(arguments);
|
||||||
|
for(var i=0; i<args.length; i++)
|
||||||
|
args[i] = args[i] == null ? '' : '' + args[i];
|
||||||
|
return method.apply(null, args);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// sprintf() for JavaScript 0.7-beta1
|
||||||
|
// http://www.diveintojavascript.com/projects/javascript-sprintf
|
||||||
|
//
|
||||||
|
// Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
var sprintf = (function() {
|
||||||
|
function get_type(variable) {
|
||||||
|
return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
function defaultToWhiteSpace(characters){
|
var str_repeat = strRepeat;
|
||||||
if (characters) {
|
|
||||||
return _s.escapeRegExp(characters);
|
var str_format = function() {
|
||||||
|
if (!str_format.cache.hasOwnProperty(arguments[0])) {
|
||||||
|
str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
|
||||||
|
}
|
||||||
|
return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
str_format.format = function(parse_tree, argv) {
|
||||||
|
var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
|
||||||
|
for (i = 0; i < tree_length; i++) {
|
||||||
|
node_type = get_type(parse_tree[i]);
|
||||||
|
if (node_type === 'string') {
|
||||||
|
output.push(parse_tree[i]);
|
||||||
}
|
}
|
||||||
return '\\s';
|
else if (node_type === 'array') {
|
||||||
}
|
match = parse_tree[i]; // convenience purposes only
|
||||||
|
if (match[2]) { // keyword argument
|
||||||
var _s = {
|
arg = argv[cursor];
|
||||||
|
for (k = 0; k < match[2].length; k++) {
|
||||||
isBlank: function(str){
|
if (!arg.hasOwnProperty(match[2][k])) {
|
||||||
return !!str.match(/^\s*$/);
|
throw(sprintf('[_.sprintf] property "%s" does not exist', match[2][k]));
|
||||||
},
|
}
|
||||||
|
arg = arg[match[2][k]];
|
||||||
capitalize : function(str) {
|
|
||||||
return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase();
|
|
||||||
},
|
|
||||||
|
|
||||||
chop: function(str, step){
|
|
||||||
step = step || str.length;
|
|
||||||
var arr = [];
|
|
||||||
for (var i = 0; i < str.length;) {
|
|
||||||
arr.push(str.slice(i,i + step));
|
|
||||||
i = i + step;
|
|
||||||
}
|
}
|
||||||
return arr;
|
} else if (match[1]) { // positional argument (explicit)
|
||||||
},
|
arg = argv[match[1]];
|
||||||
|
}
|
||||||
|
else { // positional argument (implicit)
|
||||||
|
arg = argv[cursor++];
|
||||||
|
}
|
||||||
|
|
||||||
clean: function(str){
|
if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
|
||||||
return _s.strip(str.replace(/\s+/g, ' '));
|
throw(sprintf('[_.sprintf] expecting number but found %s', get_type(arg)));
|
||||||
},
|
}
|
||||||
|
switch (match[8]) {
|
||||||
|
case 'b': arg = arg.toString(2); break;
|
||||||
|
case 'c': arg = String.fromCharCode(arg); break;
|
||||||
|
case 'd': arg = parseInt(arg, 10); break;
|
||||||
|
case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
|
||||||
|
case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
|
||||||
|
case 'o': arg = arg.toString(8); break;
|
||||||
|
case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
|
||||||
|
case 'u': arg = Math.abs(arg); break;
|
||||||
|
case 'x': arg = arg.toString(16); break;
|
||||||
|
case 'X': arg = arg.toString(16).toUpperCase(); break;
|
||||||
|
}
|
||||||
|
arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
|
||||||
|
pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
|
||||||
|
pad_length = match[6] - String(arg).length;
|
||||||
|
pad = match[6] ? str_repeat(pad_character, pad_length) : '';
|
||||||
|
output.push(match[5] ? arg + pad : pad + arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.join('');
|
||||||
|
};
|
||||||
|
|
||||||
count: function(str, substr){
|
str_format.cache = {};
|
||||||
var count = 0, index;
|
|
||||||
for (var i=0; i < str.length;) {
|
|
||||||
index = str.indexOf(substr, i);
|
|
||||||
index >= 0 && count++;
|
|
||||||
i = i + (index >= 0 ? index : 0) + substr.length;
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
},
|
|
||||||
|
|
||||||
chars: function(str) {
|
str_format.parse = function(fmt) {
|
||||||
return str.split('');
|
var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
|
||||||
},
|
while (_fmt) {
|
||||||
|
if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
|
||||||
escapeHTML: function(str) {
|
parse_tree.push(match[0]);
|
||||||
return String(str||'').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>')
|
}
|
||||||
.replace(/"/g, '"').replace(/'/g, "'");
|
else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
|
||||||
},
|
parse_tree.push('%');
|
||||||
|
}
|
||||||
unescapeHTML: function(str) {
|
else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
|
||||||
return String(str||'').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
if (match[2]) {
|
||||||
.replace(/"/g, '"').replace(/'/g, "'");
|
arg_names |= 1;
|
||||||
},
|
var field_list = [], replacement_field = match[2], field_match = [];
|
||||||
|
if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
|
||||||
escapeRegExp: function(str){
|
field_list.push(field_match[1]);
|
||||||
// From MooTools core 1.2.4
|
while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
|
||||||
return String(str||'').replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
|
if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
|
||||||
},
|
field_list.push(field_match[1]);
|
||||||
|
|
||||||
insert: function(str, i, substr){
|
|
||||||
var arr = str.split('');
|
|
||||||
arr.splice(i, 0, substr);
|
|
||||||
return arr.join('');
|
|
||||||
},
|
|
||||||
|
|
||||||
includes: function(str, needle){
|
|
||||||
return str.indexOf(needle) !== -1;
|
|
||||||
},
|
|
||||||
|
|
||||||
join: function(sep) {
|
|
||||||
// TODO: Could this be faster by converting
|
|
||||||
// arguments to Array and using array.join(sep)?
|
|
||||||
sep = String(sep);
|
|
||||||
var str = "";
|
|
||||||
for (var i=1; i < arguments.length; i += 1) {
|
|
||||||
str += String(arguments[i]);
|
|
||||||
if ( i !== arguments.length-1 ) {
|
|
||||||
str += sep;
|
|
||||||
}
|
}
|
||||||
}
|
else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
|
||||||
return str;
|
field_list.push(field_match[1]);
|
||||||
},
|
|
||||||
|
|
||||||
lines: function(str) {
|
|
||||||
return str.split("\n");
|
|
||||||
},
|
|
||||||
|
|
||||||
// reverse: function(str){
|
|
||||||
// return Array.prototype.reverse.apply(str.split('')).join('');
|
|
||||||
// },
|
|
||||||
|
|
||||||
splice: function(str, i, howmany, substr){
|
|
||||||
var arr = str.split('');
|
|
||||||
arr.splice(i, howmany, substr);
|
|
||||||
return arr.join('');
|
|
||||||
},
|
|
||||||
|
|
||||||
startsWith: function(str, starts){
|
|
||||||
return str.length >= starts.length && str.substring(0, starts.length) === starts;
|
|
||||||
},
|
|
||||||
|
|
||||||
endsWith: function(str, ends){
|
|
||||||
return str.length >= ends.length && str.substring(str.length - ends.length) === ends;
|
|
||||||
},
|
|
||||||
|
|
||||||
succ: function(str){
|
|
||||||
var arr = str.split('');
|
|
||||||
arr.splice(str.length-1, 1, String.fromCharCode(str.charCodeAt(str.length-1) + 1));
|
|
||||||
return arr.join('');
|
|
||||||
},
|
|
||||||
|
|
||||||
titleize: function(str){
|
|
||||||
var arr = str.split(' '),
|
|
||||||
word;
|
|
||||||
for (var i=0; i < arr.length; i++) {
|
|
||||||
word = arr[i].split('');
|
|
||||||
if(typeof word[0] !== 'undefined') word[0] = word[0].toUpperCase();
|
|
||||||
i+1 === arr.length ? arr[i] = word.join('') : arr[i] = word.join('') + ' ';
|
|
||||||
}
|
|
||||||
return arr.join('');
|
|
||||||
},
|
|
||||||
|
|
||||||
camelize: function(str){
|
|
||||||
return _s.trim(str).replace(/(\-|_|\s)+(.)?/g, function(match, separator, chr) {
|
|
||||||
return chr ? chr.toUpperCase() : '';
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
underscored: function(str){
|
|
||||||
return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/\-|\s+/g, '_').toLowerCase();
|
|
||||||
},
|
|
||||||
|
|
||||||
dasherize: function(str){
|
|
||||||
return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1-$2').replace(/^([A-Z]+)/, '-$1').replace(/\_|\s+/g, '-').toLowerCase();
|
|
||||||
},
|
|
||||||
|
|
||||||
trim: function(str, characters){
|
|
||||||
if (!characters && nativeTrim) {
|
|
||||||
return nativeTrim.call(str);
|
|
||||||
}
|
|
||||||
characters = defaultToWhiteSpace(characters);
|
|
||||||
return str.replace(new RegExp('\^[' + characters + ']+|[' + characters + ']+$', 'g'), '');
|
|
||||||
},
|
|
||||||
|
|
||||||
ltrim: function(str, characters){
|
|
||||||
characters = defaultToWhiteSpace(characters);
|
|
||||||
return str.replace(new RegExp('\^[' + characters + ']+', 'g'), '');
|
|
||||||
},
|
|
||||||
|
|
||||||
rtrim: function(str, characters){
|
|
||||||
characters = defaultToWhiteSpace(characters);
|
|
||||||
return str.replace(new RegExp('[' + characters + ']+$', 'g'), '');
|
|
||||||
},
|
|
||||||
|
|
||||||
truncate: function(str, length, truncateStr){
|
|
||||||
truncateStr = truncateStr || '...';
|
|
||||||
return str.slice(0,length) + truncateStr;
|
|
||||||
},
|
|
||||||
|
|
||||||
words: function(str, delimiter) {
|
|
||||||
delimiter = delimiter || " ";
|
|
||||||
return str.split(delimiter);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
pad: function(str, length, padStr, type) {
|
|
||||||
|
|
||||||
var padding = '';
|
|
||||||
var padlen = 0;
|
|
||||||
|
|
||||||
if (!padStr) { padStr = ' '; }
|
|
||||||
else if (padStr.length > 1) { padStr = padStr[0]; }
|
|
||||||
switch(type) {
|
|
||||||
case "right":
|
|
||||||
padlen = (length - str.length);
|
|
||||||
padding = str_repeat(padStr, padlen);
|
|
||||||
str = str+padding;
|
|
||||||
break;
|
|
||||||
case "both":
|
|
||||||
padlen = (length - str.length);
|
|
||||||
padding = {
|
|
||||||
'left' : str_repeat(padStr, Math.ceil(padlen/2)),
|
|
||||||
'right': str_repeat(padStr, Math.floor(padlen/2))
|
|
||||||
};
|
|
||||||
str = padding.left+str+padding.right;
|
|
||||||
break;
|
|
||||||
default: // "left"
|
|
||||||
padlen = (length - str.length);
|
|
||||||
padding = str_repeat(padStr, padlen);;
|
|
||||||
str = padding+str;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
},
|
|
||||||
|
|
||||||
lpad: function(str, length, padStr) {
|
|
||||||
return _s.pad(str, length, padStr);
|
|
||||||
},
|
|
||||||
|
|
||||||
rpad: function(str, length, padStr) {
|
|
||||||
return _s.pad(str, length, padStr, 'right');
|
|
||||||
},
|
|
||||||
|
|
||||||
lrpad: function(str, length, padStr) {
|
|
||||||
return _s.pad(str, length, padStr, 'both');
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Credits for this function goes to
|
|
||||||
* http://www.diveintojavascript.com/projects/sprintf-for-javascript
|
|
||||||
*
|
|
||||||
* Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
|
|
||||||
* All rights reserved.
|
|
||||||
* */
|
|
||||||
sprintf: function(){
|
|
||||||
|
|
||||||
var i = 0, a, f = arguments[i++], o = [], m, p, c, x, s = '';
|
|
||||||
while (f) {
|
|
||||||
if (m = /^[^\x25]+/.exec(f)) {
|
|
||||||
o.push(m[0]);
|
|
||||||
}
|
|
||||||
else if (m = /^\x25{2}/.exec(f)) {
|
|
||||||
o.push('%');
|
|
||||||
}
|
|
||||||
else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) {
|
|
||||||
if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) {
|
|
||||||
throw('Too few arguments.');
|
|
||||||
}
|
|
||||||
if (/[^s]/.test(m[7]) && (typeof(a) != 'number')) {
|
|
||||||
throw('Expecting number but found ' + typeof(a));
|
|
||||||
}
|
|
||||||
switch (m[7]) {
|
|
||||||
case 'b': a = a.toString(2); break;
|
|
||||||
case 'c': a = String.fromCharCode(a); break;
|
|
||||||
case 'd': a = parseInt(a); break;
|
|
||||||
case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break;
|
|
||||||
case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break;
|
|
||||||
case 'o': a = a.toString(8); break;
|
|
||||||
case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break;
|
|
||||||
case 'u': a = Math.abs(a); break;
|
|
||||||
case 'x': a = a.toString(16); break;
|
|
||||||
case 'X': a = a.toString(16).toUpperCase(); break;
|
|
||||||
}
|
|
||||||
a = (/[def]/.test(m[7]) && m[2] && a >= 0 ? '+'+ a : a);
|
|
||||||
c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' ';
|
|
||||||
x = m[5] - String(a).length - s.length;
|
|
||||||
p = m[5] ? str_repeat(c, x) : '';
|
|
||||||
o.push(s + (m[4] ? a + p : p + a));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw('Huh ?!');
|
throw('[_.sprintf] huh?');
|
||||||
}
|
}
|
||||||
f = f.substring(m[0].length);
|
}
|
||||||
}
|
}
|
||||||
return o.join('');
|
else {
|
||||||
|
throw('[_.sprintf] huh?');
|
||||||
|
}
|
||||||
|
match[2] = field_list;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
arg_names |= 2;
|
||||||
|
}
|
||||||
|
if (arg_names === 3) {
|
||||||
|
throw('[_.sprintf] mixing positional and named placeholders is not (yet) supported');
|
||||||
|
}
|
||||||
|
parse_tree.push(match);
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
throw('[_.sprintf] huh?');
|
||||||
|
}
|
||||||
|
_fmt = _fmt.substring(match[0].length);
|
||||||
|
}
|
||||||
|
return parse_tree;
|
||||||
|
};
|
||||||
|
|
||||||
// Aliases
|
return str_format;
|
||||||
|
})();
|
||||||
|
|
||||||
_s.strip = _s.trim;
|
|
||||||
_s.lstrip = _s.ltrim;
|
|
||||||
_s.rstrip = _s.rtrim;
|
|
||||||
_s.center = _s.lrpad
|
|
||||||
_s.ljust = _s.lpad
|
|
||||||
_s.rjust = _s.rpad
|
|
||||||
|
|
||||||
// CommonJS module is defined
|
|
||||||
if (typeof window === 'undefined' && typeof module !== 'undefined') {
|
|
||||||
// Export module
|
|
||||||
module.exports = _s;
|
|
||||||
|
|
||||||
// Integrate with Underscore.js
|
// Defining underscore.string
|
||||||
} else if (typeof root._ !== 'undefined') {
|
|
||||||
root._.mixin(_s);
|
|
||||||
|
|
||||||
// Or define it
|
var _s = {
|
||||||
} else {
|
|
||||||
root._ = _s;
|
|
||||||
}
|
|
||||||
|
|
||||||
}());
|
isBlank: sArgs(function(str){
|
||||||
|
return (/^\s*$/).test(str);
|
||||||
|
}),
|
||||||
|
|
||||||
|
stripTags: sArgs(function(str){
|
||||||
|
return str.replace(/<\/?[^>]+>/ig, '');
|
||||||
|
}),
|
||||||
|
|
||||||
|
capitalize : sArgs(function(str) {
|
||||||
|
return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase();
|
||||||
|
}),
|
||||||
|
|
||||||
|
chop: sArgs(function(str, step){
|
||||||
|
step = parseNumber(step) || str.length;
|
||||||
|
var arr = [];
|
||||||
|
for (var i = 0; i < str.length;) {
|
||||||
|
arr.push(str.slice(i,i + step));
|
||||||
|
i = i + step;
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}),
|
||||||
|
|
||||||
|
clean: sArgs(function(str){
|
||||||
|
return _s.strip(str.replace(/\s+/g, ' '));
|
||||||
|
}),
|
||||||
|
|
||||||
|
count: sArgs(function(str, substr){
|
||||||
|
var count = 0, index;
|
||||||
|
for (var i=0; i < str.length;) {
|
||||||
|
index = str.indexOf(substr, i);
|
||||||
|
index >= 0 && count++;
|
||||||
|
i = i + (index >= 0 ? index : 0) + substr.length;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}),
|
||||||
|
|
||||||
|
chars: sArgs(function(str) {
|
||||||
|
return str.split('');
|
||||||
|
}),
|
||||||
|
|
||||||
|
escapeHTML: sArgs(function(str) {
|
||||||
|
return str.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>')
|
||||||
|
.replace(/"/g, '"').replace(/'/g, "'");
|
||||||
|
}),
|
||||||
|
|
||||||
|
unescapeHTML: sArgs(function(str) {
|
||||||
|
return str.replace(/</g, '<').replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"').replace(/'/g, "'").replace(/&/g, '&');
|
||||||
|
}),
|
||||||
|
|
||||||
|
escapeRegExp: sArgs(function(str){
|
||||||
|
// From MooTools core 1.2.4
|
||||||
|
return str.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
|
||||||
|
}),
|
||||||
|
|
||||||
|
insert: sArgs(function(str, i, substr){
|
||||||
|
var arr = str.split('');
|
||||||
|
arr.splice(parseNumber(i), 0, substr);
|
||||||
|
return arr.join('');
|
||||||
|
}),
|
||||||
|
|
||||||
|
includes: sArgs(function(str, needle){
|
||||||
|
return str.indexOf(needle) !== -1;
|
||||||
|
}),
|
||||||
|
|
||||||
|
include: function(obj, needle) {
|
||||||
|
if (!_include || (/string|number/).test(typeof obj)) {
|
||||||
|
return this.includes(obj, needle);
|
||||||
|
} else {
|
||||||
|
return _include(obj, needle);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
join: sArgs(function(sep) {
|
||||||
|
var args = slice(arguments);
|
||||||
|
return args.join(args.shift());
|
||||||
|
}),
|
||||||
|
|
||||||
|
lines: sArgs(function(str) {
|
||||||
|
return str.split("\n");
|
||||||
|
}),
|
||||||
|
|
||||||
|
reverse: function(obj){
|
||||||
|
if (!_reverse || (/string|number/).test(typeof obj)) {
|
||||||
|
return Array.prototype.reverse.apply(String(obj).split('')).join('');
|
||||||
|
} else {
|
||||||
|
return _reverse.call(_(obj));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
splice: sArgs(function(str, i, howmany, substr){
|
||||||
|
var arr = str.split('');
|
||||||
|
arr.splice(parseNumber(i), parseNumber(howmany), substr);
|
||||||
|
return arr.join('');
|
||||||
|
}),
|
||||||
|
|
||||||
|
startsWith: sArgs(function(str, starts){
|
||||||
|
return str.length >= starts.length && str.substring(0, starts.length) === starts;
|
||||||
|
}),
|
||||||
|
|
||||||
|
endsWith: sArgs(function(str, ends){
|
||||||
|
return str.length >= ends.length && str.substring(str.length - ends.length) === ends;
|
||||||
|
}),
|
||||||
|
|
||||||
|
succ: sArgs(function(str){
|
||||||
|
var arr = str.split('');
|
||||||
|
arr.splice(str.length-1, 1, String.fromCharCode(str.charCodeAt(str.length-1) + 1));
|
||||||
|
return arr.join('');
|
||||||
|
}),
|
||||||
|
|
||||||
|
titleize: sArgs(function(str){
|
||||||
|
var arr = str.split(' '),
|
||||||
|
word;
|
||||||
|
for (var i=0; i < arr.length; i++) {
|
||||||
|
word = arr[i].split('');
|
||||||
|
if(typeof word[0] !== 'undefined') word[0] = word[0].toUpperCase();
|
||||||
|
i+1 === arr.length ? arr[i] = word.join('') : arr[i] = word.join('') + ' ';
|
||||||
|
}
|
||||||
|
return arr.join('');
|
||||||
|
}),
|
||||||
|
|
||||||
|
camelize: sArgs(function(str){
|
||||||
|
return _s.trim(str).replace(/(\-|_|\s)+(.)?/g, function(match, separator, chr) {
|
||||||
|
return chr ? chr.toUpperCase() : '';
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
|
underscored: function(str){
|
||||||
|
return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/\-|\s+/g, '_').toLowerCase();
|
||||||
|
},
|
||||||
|
|
||||||
|
dasherize: function(str){
|
||||||
|
return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1-$2').replace(/^([A-Z]+)/, '-$1').replace(/\_|\s+/g, '-').toLowerCase();
|
||||||
|
},
|
||||||
|
|
||||||
|
trim: sArgs(function(str, characters){
|
||||||
|
if (!characters && nativeTrim) {
|
||||||
|
return nativeTrim.call(str);
|
||||||
|
}
|
||||||
|
characters = defaultToWhiteSpace(characters);
|
||||||
|
return str.replace(new RegExp('\^[' + characters + ']+|[' + characters + ']+$', 'g'), '');
|
||||||
|
}),
|
||||||
|
|
||||||
|
ltrim: sArgs(function(str, characters){
|
||||||
|
characters = defaultToWhiteSpace(characters);
|
||||||
|
return str.replace(new RegExp('\^[' + characters + ']+', 'g'), '');
|
||||||
|
}),
|
||||||
|
|
||||||
|
rtrim: sArgs(function(str, characters){
|
||||||
|
characters = defaultToWhiteSpace(characters);
|
||||||
|
return str.replace(new RegExp('[' + characters + ']+$', 'g'), '');
|
||||||
|
}),
|
||||||
|
|
||||||
|
truncate: sArgs(function(str, length, truncateStr){
|
||||||
|
truncateStr = truncateStr || '...';
|
||||||
|
length = parseNumber(length);
|
||||||
|
return str.length > length ? str.slice(0,length) + truncateStr : str;
|
||||||
|
}),
|
||||||
|
|
||||||
|
words: function(str, delimiter) {
|
||||||
|
return String(str).split(delimiter || " ");
|
||||||
|
},
|
||||||
|
|
||||||
|
pad: sArgs(function(str, length, padStr, type) {
|
||||||
|
var padding = '',
|
||||||
|
padlen = 0;
|
||||||
|
|
||||||
|
length = parseNumber(length);
|
||||||
|
|
||||||
|
if (!padStr) { padStr = ' '; }
|
||||||
|
else if (padStr.length > 1) { padStr = padStr.charAt(0); }
|
||||||
|
switch(type) {
|
||||||
|
case 'right':
|
||||||
|
padlen = (length - str.length);
|
||||||
|
padding = strRepeat(padStr, padlen);
|
||||||
|
str = str+padding;
|
||||||
|
break;
|
||||||
|
case 'both':
|
||||||
|
padlen = (length - str.length);
|
||||||
|
padding = {
|
||||||
|
'left' : strRepeat(padStr, Math.ceil(padlen/2)),
|
||||||
|
'right': strRepeat(padStr, Math.floor(padlen/2))
|
||||||
|
};
|
||||||
|
str = padding.left+str+padding.right;
|
||||||
|
break;
|
||||||
|
default: // 'left'
|
||||||
|
padlen = (length - str.length);
|
||||||
|
padding = strRepeat(padStr, padlen);;
|
||||||
|
str = padding+str;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}),
|
||||||
|
|
||||||
|
lpad: function(str, length, padStr) {
|
||||||
|
return _s.pad(str, length, padStr);
|
||||||
|
},
|
||||||
|
|
||||||
|
rpad: function(str, length, padStr) {
|
||||||
|
return _s.pad(str, length, padStr, 'right');
|
||||||
|
},
|
||||||
|
|
||||||
|
lrpad: function(str, length, padStr) {
|
||||||
|
return _s.pad(str, length, padStr, 'both');
|
||||||
|
},
|
||||||
|
|
||||||
|
sprintf: sprintf,
|
||||||
|
|
||||||
|
vsprintf: function(fmt, argv){
|
||||||
|
argv.unshift(fmt);
|
||||||
|
return sprintf.apply(null, argv);
|
||||||
|
},
|
||||||
|
|
||||||
|
toNumber: function(str, decimals) {
|
||||||
|
var num = parseNumber(parseNumber(str).toFixed(parseNumber(decimals)));
|
||||||
|
return (!(num === 0 && (str !== "0" && str !== 0))) ? num : Number.NaN;
|
||||||
|
},
|
||||||
|
|
||||||
|
strRight: sArgs(function(sourceStr, sep){
|
||||||
|
var pos = (!sep) ? -1 : sourceStr.indexOf(sep);
|
||||||
|
return (pos != -1) ? sourceStr.slice(pos+sep.length, sourceStr.length) : sourceStr;
|
||||||
|
}),
|
||||||
|
|
||||||
|
strRightBack: sArgs(function(sourceStr, sep){
|
||||||
|
var pos = (!sep) ? -1 : sourceStr.lastIndexOf(sep);
|
||||||
|
return (pos != -1) ? sourceStr.slice(pos+sep.length, sourceStr.length) : sourceStr;
|
||||||
|
}),
|
||||||
|
|
||||||
|
strLeft: sArgs(function(sourceStr, sep){
|
||||||
|
var pos = (!sep) ? -1 : sourceStr.indexOf(sep);
|
||||||
|
return (pos != -1) ? sourceStr.slice(0, pos) : sourceStr;
|
||||||
|
}),
|
||||||
|
|
||||||
|
strLeftBack: sArgs(function(sourceStr, sep){
|
||||||
|
var pos = sourceStr.lastIndexOf(sep);
|
||||||
|
return (pos != -1) ? sourceStr.slice(0, pos) : sourceStr;
|
||||||
|
})
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Aliases
|
||||||
|
|
||||||
|
_s.strip = _s.trim;
|
||||||
|
_s.lstrip = _s.ltrim;
|
||||||
|
_s.rstrip = _s.rtrim;
|
||||||
|
_s.center = _s.lrpad;
|
||||||
|
_s.ljust = _s.lpad;
|
||||||
|
_s.rjust = _s.rpad;
|
||||||
|
|
||||||
|
// CommonJS module is defined
|
||||||
|
if (typeof module !== 'undefined' && module.exports) {
|
||||||
|
// Export module
|
||||||
|
module.exports = _s;
|
||||||
|
|
||||||
|
// Integrate with Underscore.js
|
||||||
|
} else if (typeof root._ !== 'undefined') {
|
||||||
|
root._.mixin(_s);
|
||||||
|
|
||||||
|
// Or define it
|
||||||
|
} else {
|
||||||
|
root._ = _s;
|
||||||
|
}
|
||||||
|
|
||||||
|
}(this || window));
|
||||||
|
|
|
@ -40,6 +40,9 @@ body.openerp, .openerp textarea, .openerp input, .openerp select, .openerp optio
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loading */
|
/* Loading */
|
||||||
|
.loading {
|
||||||
|
cursor: wait;
|
||||||
|
}
|
||||||
.openerp .loading {
|
.openerp .loading {
|
||||||
display: none;
|
display: none;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
|
@ -125,7 +128,7 @@ body.openerp, .openerp textarea, .openerp input, .openerp select, .openerp optio
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.openerp .login.login_invalid .login_error_message {
|
.openerp .login .login_invalid .login_error_message {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +159,7 @@ body.openerp, .openerp textarea, .openerp input, .openerp select, .openerp optio
|
||||||
}
|
}
|
||||||
|
|
||||||
.db_container {
|
.db_container {
|
||||||
width: 15%;
|
width: 196px;
|
||||||
background: #666666;
|
background: #666666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,6 +225,7 @@ label.error {
|
||||||
background: #f0eeee;
|
background: #f0eeee;
|
||||||
}
|
}
|
||||||
.openerp .oe-application-container {
|
.openerp .oe-application-container {
|
||||||
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +304,7 @@ label.error {
|
||||||
text-shadow: 0 1px 0 #333;
|
text-shadow: 0 1px 0 #333;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
line-height: 14px;
|
line-height: 18px;
|
||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
.openerp .secondary_menu.oe_folded .oe_toggle_secondary_menu {
|
.openerp .secondary_menu.oe_folded .oe_toggle_secondary_menu {
|
||||||
|
@ -325,6 +329,7 @@ label.error {
|
||||||
background: #5A5858;
|
background: #5A5858;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.openerp .secondary_menu.oe_folded {
|
.openerp .secondary_menu.oe_folded {
|
||||||
|
@ -721,11 +726,15 @@ label.error {
|
||||||
.openerp .oe-listview .oe-field-cell {
|
.openerp .oe-listview .oe-field-cell {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.openerp .oe-listview .oe-field-cell progress {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
.openerp .oe-listview .oe-field-cell button {
|
.openerp .oe-listview .oe-field-cell button {
|
||||||
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: none;
|
border: none;
|
||||||
background: none;
|
background: none;
|
||||||
width: 100%;
|
width: 16px;
|
||||||
}
|
}
|
||||||
.openerp .oe-listview .oe-field-cell button:active {
|
.openerp .oe-listview .oe-field-cell button:active {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
|
@ -767,6 +776,10 @@ label.error {
|
||||||
.openerp .oe-listview .oe-list-footer span {
|
.openerp .oe-listview .oe-list-footer span {
|
||||||
margin: 0 1em;
|
margin: 0 1em;
|
||||||
}
|
}
|
||||||
|
.openerp .oe-listview .oe-list-footer progress {
|
||||||
|
vertical-align:-10% !important;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
/** list rounded corners
|
/** list rounded corners
|
||||||
|
|
||||||
|
@ -788,13 +801,15 @@ label.error {
|
||||||
-moz-border-radius-topright: 7px;
|
-moz-border-radius-topright: 7px;
|
||||||
border-top-right-radius: 7px;
|
border-top-right-radius: 7px;
|
||||||
}
|
}
|
||||||
.openerp .oe-listview table.oe-listview-content tfoot td:first-child,
|
.openerp .oe-listview table.oe-listview-content tfoot tr:last-child th:first-child,
|
||||||
|
.openerp .oe-listview table.oe-listview-content tfoot tr:last-child td:first-child,
|
||||||
.openerp .oe-listview table.oe-listview-content tbody:last-child tr:last-child th:first-child {
|
.openerp .oe-listview table.oe-listview-content tbody:last-child tr:last-child th:first-child {
|
||||||
-webkit-border-bottom-left-radius: 7px;
|
-webkit-border-bottom-left-radius: 7px;
|
||||||
-moz-border-radius-bottomleft: 7px;
|
-moz-border-radius-bottomleft: 7px;
|
||||||
border-bottom-left-radius: 7px;
|
border-bottom-left-radius: 7px;
|
||||||
}
|
}
|
||||||
.openerp .oe-listview table.oe-listview-content tfoot td:last-child,
|
.openerp .oe-listview table.oe-listview-content tfoot tr:last-child th:last-child,
|
||||||
|
.openerp .oe-listview table.oe-listview-content tfoot tr:last-child td:last-child,
|
||||||
.openerp .oe-listview table.oe-listview-content tbody:last-child tr:last-child td:last-child {
|
.openerp .oe-listview table.oe-listview-content tbody:last-child tr:last-child td:last-child {
|
||||||
-webkit-border-bottom-right-radius: 7px;
|
-webkit-border-bottom-right-radius: 7px;
|
||||||
-moz-border-radius-bottomright: 7px;
|
-moz-border-radius-bottomright: 7px;
|
||||||
|
@ -828,6 +843,9 @@ label.error {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Form */
|
/* Form */
|
||||||
|
.openerp .oe_frame.oe_forms {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
.openerp table.oe_frame td {
|
.openerp table.oe_frame td {
|
||||||
color: #4c4c4c;
|
color: #4c4c4c;
|
||||||
}
|
}
|
||||||
|
@ -855,7 +873,7 @@ label.error {
|
||||||
cursor: help;
|
cursor: help;
|
||||||
}
|
}
|
||||||
|
|
||||||
.openerp .oe_form_field label.oe_label, .openerp .oe_form_field label.oe_label_help {
|
.openerp .oe_forms label.oe_label, .openerp .oe_forms label.oe_label_help {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
margin: 3px 0 0 10px;
|
margin: 3px 0 0 10px;
|
||||||
}
|
}
|
||||||
|
@ -943,7 +961,7 @@ label.error {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.openerp input.oe-binary-file {
|
.openerp input.oe-binary-file {
|
||||||
z-index: 2;
|
z-index: 0;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
font-size: 50px;
|
font-size: 50px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -1357,19 +1375,20 @@ label.error {
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.oe-arrow-list {
|
ul.oe-arrow-list {
|
||||||
padding-left: 0.5em;
|
padding-left: 1.1em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
ul.oe-arrow-list li {
|
ul.oe-arrow-list li {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-left: -0.5em;
|
margin-left: -1em;
|
||||||
}
|
}
|
||||||
ul.oe-arrow-list li span {
|
ul.oe-arrow-list li span {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border-width:1em;
|
border-width:1em;
|
||||||
border-style:solid;
|
border-style:solid;
|
||||||
border-color: white;
|
border-color: #DEDEDE;
|
||||||
line-height:0em;
|
line-height:0em;
|
||||||
}
|
}
|
||||||
ul.oe-arrow-list .oe-arrow-list-before {
|
ul.oe-arrow-list .oe-arrow-list-before {
|
||||||
|
@ -1378,16 +1397,16 @@ ul.oe-arrow-list .oe-arrow-list-before {
|
||||||
}
|
}
|
||||||
ul.oe-arrow-list .oe-arrow-list-after {
|
ul.oe-arrow-list .oe-arrow-list-after {
|
||||||
border-color: rgba(0,0,0,0);
|
border-color: rgba(0,0,0,0);
|
||||||
border-left-color: white;
|
border-left-color: #DEDEDE;
|
||||||
border-right-width:0;
|
border-right-width:0;
|
||||||
}
|
}
|
||||||
ul.oe-arrow-list li.oe-arrow-list-selected span {
|
ul.oe-arrow-list li.oe-arrow-list-selected span {
|
||||||
border-color: #CFCCCC;
|
border-color: #B5B9FF;
|
||||||
}
|
}
|
||||||
ul.oe-arrow-list li.oe-arrow-list-selected .oe-arrow-list-before {
|
ul.oe-arrow-list li.oe-arrow-list-selected .oe-arrow-list-before {
|
||||||
border-left-color: rgba(0,0,0,0);
|
border-left-color: rgba(0,0,0,0);
|
||||||
}
|
}
|
||||||
ul.oe-arrow-list li.oe-arrow-list-selected .oe-arrow-list-after {
|
ul.oe-arrow-list li.oe-arrow-list-selected .oe-arrow-list-after {
|
||||||
border-color: rgba(0,0,0,0);
|
border-color: rgba(0,0,0,0);
|
||||||
border-left-color: #CFCCCC;
|
border-left-color: #B5B9FF;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
.openerp .oe_import_grid {
|
||||||
|
border: none;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
.openerp .oe_import_grid-header .oe_import_grid-cell {
|
||||||
|
background: url(../img/gradientlinebg.gif) repeat-x #CCCCCC;
|
||||||
|
border-bottom: 1px solid #E3E3E3;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.openerp .oe_import_grid-row .oe_import_grid-cell {
|
||||||
|
border-bottom: 1px solid #E3E3E3;
|
||||||
|
}
|
||||||
|
.openerp .separator.horizontal {
|
||||||
|
font-weight: bold;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
margin: 6px 4px 6px 1px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
.openerp .duplicate_fld{
|
||||||
|
background-color:#FF6666;
|
||||||
|
}
|
||||||
|
.openerp .select_fld{
|
||||||
|
background: none repeat scroll 0 0 white;
|
||||||
|
}
|
||||||
|
.openerp .ui-autocomplete {
|
||||||
|
max-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
After Width: | Height: | Size: 91 B |
After Width: | Height: | Size: 182 B |
|
@ -19,9 +19,9 @@
|
||||||
/**
|
/**
|
||||||
* OpenERP instance constructor
|
* OpenERP instance constructor
|
||||||
*
|
*
|
||||||
* @param {Boolean} skip_init if true, skips the built-in initialization
|
* @param {Array} modules list of modules to initialize
|
||||||
*/
|
*/
|
||||||
init: function(skip_init) {
|
init: function(modules) {
|
||||||
var new_instance = {
|
var new_instance = {
|
||||||
// links to the global openerp
|
// links to the global openerp
|
||||||
_openerp: openerp,
|
_openerp: openerp,
|
||||||
|
@ -35,8 +35,9 @@
|
||||||
web_mobile: {}
|
web_mobile: {}
|
||||||
};
|
};
|
||||||
openerp.sessions[new_instance._session_id] = new_instance;
|
openerp.sessions[new_instance._session_id] = new_instance;
|
||||||
if (!skip_init){
|
modules = modules || ["web"];
|
||||||
openerp.web(new_instance);
|
for(var i=0; i < modules.length; i++) {
|
||||||
|
openerp[modules[i]](new_instance);
|
||||||
}
|
}
|
||||||
return new_instance;
|
return new_instance;
|
||||||
}
|
}
|
||||||
|
@ -58,7 +59,7 @@ openerp.web = function(instance) {
|
||||||
openerp.web.formats(instance);
|
openerp.web.formats(instance);
|
||||||
openerp.web.chrome(instance);
|
openerp.web.chrome(instance);
|
||||||
openerp.web.data(instance);
|
openerp.web.data(instance);
|
||||||
var files = ["views","search","list","form","list_editable","web_mobile","view_tree","data_export"];
|
var files = ["views","search","list","form","list_editable","web_mobile","view_tree","data_export","data_import"];
|
||||||
for(var i=0; i<files.length; i++) {
|
for(var i=0; i<files.length; i++) {
|
||||||
if(openerp.web[files[i]]) {
|
if(openerp.web[files[i]]) {
|
||||||
openerp.web[files[i]](instance);
|
openerp.web[files[i]](instance);
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
/*---------------------------------------------------------
|
/*---------------------------------------------------------
|
||||||
* OpenERP Web chrome
|
* OpenERP Web chrome
|
||||||
*---------------------------------------------------------*/
|
*---------------------------------------------------------*/
|
||||||
|
|
||||||
openerp.web.chrome = function(openerp) {
|
openerp.web.chrome = function(openerp) {
|
||||||
var QWeb = openerp.web.qweb;
|
var QWeb = openerp.web.qweb;
|
||||||
|
|
||||||
openerp.web.Notification = openerp.web.Widget.extend(/** @lends openerp.web.Notification# */{
|
openerp.web.Notification = openerp.web.Widget.extend(/** @lends openerp.web.Notification# */{
|
||||||
/**
|
template: 'Notification',
|
||||||
* @constructs openerp.web.Notification
|
identifier_prefix: 'notification-',
|
||||||
* @extends openerp.web.Widget
|
|
||||||
*
|
init: function() {
|
||||||
* @param parent
|
this._super.apply(this, arguments);
|
||||||
* @param element_id
|
openerp.notification = this;
|
||||||
*/
|
},
|
||||||
init: function(parent, element_id) {
|
|
||||||
this._super(parent, element_id);
|
start: function() {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
this.$element.notify({
|
this.$element.notify({
|
||||||
speed: 500,
|
speed: 500,
|
||||||
expires: 1500
|
expires: 1500
|
||||||
|
@ -29,9 +29,12 @@ openerp.web.Notification = openerp.web.Widget.extend(/** @lends openerp.web.Not
|
||||||
warn: function(title, text) {
|
warn: function(title, text) {
|
||||||
this.$element.notify('create', 'oe_notification_alert', {
|
this.$element.notify('create', 'oe_notification_alert', {
|
||||||
title: title,
|
title: title,
|
||||||
text: text
|
text: text,
|
||||||
|
}, {
|
||||||
|
expires: false,
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog# */{
|
openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog# */{
|
||||||
|
@ -129,24 +132,15 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog#
|
||||||
// Destroy widget
|
// Destroy widget
|
||||||
this.close();
|
this.close();
|
||||||
this.$dialog.dialog('destroy');
|
this.$dialog.dialog('destroy');
|
||||||
|
this._super();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
openerp.web.CrashManager = openerp.web.Dialog.extend(/** @lends openerp.web.CrashManager# */{
|
openerp.web.CrashManager = openerp.web.SessionAware.extend({
|
||||||
identifier_prefix: 'dialog_crash',
|
|
||||||
/**
|
|
||||||
* @constructs opener.web.CrashManager
|
|
||||||
* @extends openerp.web.Dialog
|
|
||||||
*
|
|
||||||
* @param parent
|
|
||||||
*/
|
|
||||||
init: function(parent) {
|
init: function(parent) {
|
||||||
this._super(parent);
|
this._super((parent || {}).session);
|
||||||
this.session.on_rpc_error.add(this.on_rpc_error);
|
this.session.on_rpc_error.add(this.on_rpc_error);
|
||||||
},
|
},
|
||||||
on_button_Ok: function() {
|
|
||||||
this.close();
|
|
||||||
},
|
|
||||||
on_rpc_error: function(error) {
|
on_rpc_error: function(error) {
|
||||||
this.error = error;
|
this.error = error;
|
||||||
if (error.data.fault_code) {
|
if (error.data.fault_code) {
|
||||||
|
@ -157,20 +151,36 @@ openerp.web.CrashManager = openerp.web.Dialog.extend(/** @lends openerp.web.Cras
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error.code === 200 && error.type) {
|
if (error.code === 200 && error.type) {
|
||||||
this.dialog_title = "OpenERP " + _.capitalize(error.type);
|
this.on_managed_error(error);
|
||||||
this.template = 'DialogWarning';
|
|
||||||
this.open({
|
|
||||||
width: 'auto',
|
|
||||||
height: 'auto'
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
this.dialog_title = "OpenERP Error";
|
this.on_traceback(error);
|
||||||
this.template = 'DialogTraceback';
|
|
||||||
this.open({
|
|
||||||
width: 'auto',
|
|
||||||
height: 'auto'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
on_managed_error: function(error) {
|
||||||
|
$('<div>' + QWeb.render('DialogWarning', {error: error}) + '</div>').dialog({
|
||||||
|
title: "OpenERP " + _.capitalize(error.type),
|
||||||
|
buttons: {
|
||||||
|
Ok: function() {
|
||||||
|
$(this).dialog("close");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
on_traceback: function(error) {
|
||||||
|
var dialog = new openerp.web.Dialog(this, {
|
||||||
|
title: "OpenERP " + _.capitalize(error.type),
|
||||||
|
autoOpen: true,
|
||||||
|
width: '90%',
|
||||||
|
height: '90%',
|
||||||
|
min_width: '800px',
|
||||||
|
min_height: '600px',
|
||||||
|
buttons: {
|
||||||
|
Ok: function() {
|
||||||
|
$(this).dialog("close");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
dialog.$element.html(QWeb.render('DialogTraceback', {error: error}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -194,8 +204,10 @@ openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading#
|
||||||
//this.$element.html(QWeb.render("Loading", {}));
|
//this.$element.html(QWeb.render("Loading", {}));
|
||||||
this.$element.html("Loading ("+this.count+")");
|
this.$element.html("Loading ("+this.count+")");
|
||||||
this.$element.show();
|
this.$element.show();
|
||||||
|
this.widget_parent.$element.addClass('loading');
|
||||||
} else {
|
} else {
|
||||||
this.$element.fadeOut();
|
this.$element.fadeOut();
|
||||||
|
this.widget_parent.$element.removeClass('loading');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -218,9 +230,8 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||||
this.$element.closest(".openerp")
|
this.$element.closest(".openerp")
|
||||||
.removeClass("login-mode")
|
.removeClass("login-mode")
|
||||||
.addClass("database_block");
|
.addClass("database_block");
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var fetch_db = this.rpc("/web/database/get_list", {}, function(result) {
|
var fetch_db = this.rpc("/web/database/get_list", {}, function(result) {
|
||||||
self.db_list = result.db_list;
|
self.db_list = result.db_list;
|
||||||
});
|
});
|
||||||
|
@ -232,7 +243,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||||
self.lang_list = result.lang_list;
|
self.lang_list = result.lang_list;
|
||||||
});
|
});
|
||||||
$.when(fetch_db, fetch_langs).then(function () {self.do_create();});
|
$.when(fetch_db, fetch_langs).then(function () {self.do_create();});
|
||||||
|
|
||||||
this.$element.find('#db-create').click(this.do_create);
|
this.$element.find('#db-create').click(this.do_create);
|
||||||
this.$element.find('#db-drop').click(this.do_drop);
|
this.$element.find('#db-drop').click(this.do_drop);
|
||||||
this.$element.find('#db-backup').click(this.do_backup);
|
this.$element.find('#db-backup').click(this.do_backup);
|
||||||
|
@ -254,7 +265,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||||
.removeClass("database_block")
|
.removeClass("database_block")
|
||||||
.end()
|
.end()
|
||||||
.empty();
|
.empty();
|
||||||
|
this._super();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Converts a .serializeArray() result into a dict. Does not bother folding
|
* Converts a .serializeArray() result into a dict. Does not bother folding
|
||||||
|
@ -300,9 +311,9 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||||
|
|
||||||
var admin = result[1][0];
|
var admin = result[1][0];
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
self.stop();
|
|
||||||
self.widget_parent.do_login(
|
self.widget_parent.do_login(
|
||||||
info.db, admin.login, admin.password);
|
info.db, admin.login, admin.password);
|
||||||
|
self.stop();
|
||||||
$.unblockUI();
|
$.unblockUI();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -370,7 +381,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||||
}
|
}
|
||||||
$db_list.find(':selected').remove();
|
$db_list.find(':selected').remove();
|
||||||
self.db_list.splice(_.indexOf(self.db_list, db, true), 1);
|
self.db_list.splice(_.indexOf(self.db_list, db, true), 1);
|
||||||
self.notification.notify("Dropping database", "The database '" + db + "' has been dropped");
|
self.do_notify("Dropping database", "The database '" + db + "' has been dropped");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -399,7 +410,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||||
do_restore: function() {
|
do_restore: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.$option_id.html(QWeb.render("RestoreDB", self));
|
self.$option_id.html(QWeb.render("RestoreDB", self));
|
||||||
|
|
||||||
self.$option_id.find("form[name=restore_db_form]").validate({
|
self.$option_id.find("form[name=restore_db_form]").validate({
|
||||||
submitHandler: function (form) {
|
submitHandler: function (form) {
|
||||||
$.blockUI({message:'<img src="/web/static/src/img/throbber2.gif">'});
|
$.blockUI({message:'<img src="/web/static/src/img/throbber2.gif">'});
|
||||||
|
@ -455,7 +466,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||||
self.display_error(result);
|
self.display_error(result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.notification.notify("Changed Password", "Password has been changed successfully");
|
self.do_notify("Changed Password", "Password has been changed successfully");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -463,41 +474,43 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||||
});
|
});
|
||||||
|
|
||||||
openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
|
openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
|
||||||
remember_creditentials: true,
|
remember_credentials: true,
|
||||||
|
|
||||||
|
template: "Login",
|
||||||
|
identifier_prefix: 'oe-app-login-',
|
||||||
/**
|
/**
|
||||||
* @constructs openerp.web.Login
|
* @constructs openerp.web.Login
|
||||||
* @extends openerp.web.Widget
|
* @extends openerp.web.Widget
|
||||||
*
|
*
|
||||||
* @param parent
|
* @param parent
|
||||||
* @param element_id
|
* @param element_id
|
||||||
*/
|
*/
|
||||||
init: function(parent, element_id) {
|
|
||||||
this._super(parent, element_id);
|
init: function(parent) {
|
||||||
|
this._super(parent);
|
||||||
this.has_local_storage = typeof(localStorage) != 'undefined';
|
this.has_local_storage = typeof(localStorage) != 'undefined';
|
||||||
this.selected_db = null;
|
this.selected_db = null;
|
||||||
this.selected_login = null;
|
this.selected_login = null;
|
||||||
|
|
||||||
if (this.has_local_storage && this.remember_creditentials) {
|
if (this.has_local_storage && this.remember_credentials) {
|
||||||
this.selected_db = localStorage.getItem('last_db_login_success');
|
this.selected_db = localStorage.getItem('last_db_login_success');
|
||||||
this.selected_login = localStorage.getItem('last_login_login_success');
|
this.selected_login = localStorage.getItem('last_login_login_success');
|
||||||
if (jQuery.deparam(jQuery.param.querystring()).debug != undefined) {
|
if (jQuery.deparam(jQuery.param.querystring()).debug != undefined) {
|
||||||
this.selected_password = localStorage.getItem('last_password_login_success');
|
this.selected_password = localStorage.getItem('last_password_login_success');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var qs = jQuery.deparam(jQuery.param.querystring());
|
||||||
|
if (qs.db) {
|
||||||
|
this.selected_db = qs.db;
|
||||||
|
}
|
||||||
|
if (qs.login) {
|
||||||
|
this.selected_login = qs.login;
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
start: function() {
|
start: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.rpc("/web/database/get_list", {}, function(result) {
|
|
||||||
self.db_list = result.db_list;
|
|
||||||
self.display();
|
|
||||||
}, function() {
|
|
||||||
self.display();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
display: function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.$element.html(QWeb.render("Login", this));
|
|
||||||
this.database = new openerp.web.Database(
|
this.database = new openerp.web.Database(
|
||||||
this, "oe_database", "oe_db_options");
|
this, "oe_database", "oe_db_options");
|
||||||
|
|
||||||
|
@ -506,6 +519,17 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$element.find("form").submit(this.on_submit);
|
this.$element.find("form").submit(this.on_submit);
|
||||||
|
|
||||||
|
this.rpc("/web/database/get_list", {}, function(result) {
|
||||||
|
var tpl = openerp.web.qweb.render('Login_dblist', {db_list: result.db_list, selected_db: self.selected_db});
|
||||||
|
self.$element.find("input[name=db]").replaceWith(tpl)
|
||||||
|
},
|
||||||
|
function(error, event) {
|
||||||
|
if (error.data.fault_code === 'AccessDenied') {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
on_login_invalid: function() {
|
on_login_invalid: function() {
|
||||||
this.$element.closest(".openerp").addClass("login-mode");
|
this.$element.closest(".openerp").addClass("login-mode");
|
||||||
|
@ -534,7 +558,7 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
|
||||||
this.session.session_login(db, login, password, function() {
|
this.session.session_login(db, login, password, function() {
|
||||||
if(self.session.session_is_valid()) {
|
if(self.session.session_is_valid()) {
|
||||||
if (self.has_local_storage) {
|
if (self.has_local_storage) {
|
||||||
if(self.remember_creditentials) {
|
if(self.remember_credentials) {
|
||||||
localStorage.setItem('last_db_login_success', db);
|
localStorage.setItem('last_db_login_success', db);
|
||||||
localStorage.setItem('last_login_login_success', login);
|
localStorage.setItem('last_login_login_success', login);
|
||||||
if (jQuery.deparam(jQuery.param.querystring()).debug != undefined) {
|
if (jQuery.deparam(jQuery.param.querystring()).debug != undefined) {
|
||||||
|
@ -574,7 +598,7 @@ openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# *
|
||||||
/**
|
/**
|
||||||
* @constructs openerp.web.Header
|
* @constructs openerp.web.Header
|
||||||
* @extends openerp.web.Widget
|
* @extends openerp.web.Widget
|
||||||
*
|
*
|
||||||
* @param parent
|
* @param parent
|
||||||
*/
|
*/
|
||||||
init: function(parent) {
|
init: function(parent) {
|
||||||
|
@ -665,7 +689,7 @@ openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# *
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
on_action: function(action) {
|
on_action: function(action) {
|
||||||
},
|
},
|
||||||
on_preferences: function(){
|
on_preferences: function(){
|
||||||
|
@ -713,7 +737,7 @@ openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# *
|
||||||
action_manager.appendTo(this.dialog);
|
action_manager.appendTo(this.dialog);
|
||||||
action_manager.render(this.dialog);
|
action_manager.render(this.dialog);
|
||||||
},
|
},
|
||||||
|
|
||||||
change_password :function() {
|
change_password :function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.dialog = new openerp.web.Dialog(this,{
|
this.dialog = new openerp.web.Dialog(this,{
|
||||||
|
@ -758,7 +782,7 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{
|
||||||
/**
|
/**
|
||||||
* @constructs openerp.web.Menu
|
* @constructs openerp.web.Menu
|
||||||
* @extends openerp.web.Widget
|
* @extends openerp.web.Widget
|
||||||
*
|
*
|
||||||
* @param parent
|
* @param parent
|
||||||
* @param element_id
|
* @param element_id
|
||||||
* @param secondary_menu_id
|
* @param secondary_menu_id
|
||||||
|
@ -776,9 +800,8 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{
|
||||||
},
|
},
|
||||||
start: function() {
|
start: function() {
|
||||||
this.$secondary_menu.addClass(this.folded ? 'oe_folded' : 'oe_unfolded');
|
this.$secondary_menu.addClass(this.folded ? 'oe_folded' : 'oe_unfolded');
|
||||||
this.reload();
|
|
||||||
},
|
},
|
||||||
reload: function() {
|
do_reload: function() {
|
||||||
this.rpc("/web/menu/load", {}, this.on_loaded);
|
this.rpc("/web/menu/load", {}, this.on_loaded);
|
||||||
},
|
},
|
||||||
on_loaded: function(data) {
|
on_loaded: function(data) {
|
||||||
|
@ -820,7 +843,9 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{
|
||||||
this.session.active_id = id;
|
this.session.active_id = id;
|
||||||
this.rpc('/web/menu/action', {'menu_id': id}, this.on_menu_action_loaded);
|
this.rpc('/web/menu/action', {'menu_id': id}, this.on_menu_action_loaded);
|
||||||
}
|
}
|
||||||
ev.stopPropagation();
|
if (ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
do_menu_click: function($clicked_menu, manual) {
|
do_menu_click: function($clicked_menu, manual) {
|
||||||
|
@ -863,6 +888,7 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{
|
||||||
$sub_menu.hide();
|
$sub_menu.hide();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return manual;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -910,7 +936,7 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
|
||||||
/**
|
/**
|
||||||
* @constructs openerp.web.WebClient
|
* @constructs openerp.web.WebClient
|
||||||
* @extends openerp.web.Widget
|
* @extends openerp.web.Widget
|
||||||
*
|
*
|
||||||
* @param element_id
|
* @param element_id
|
||||||
*/
|
*/
|
||||||
init: function(element_id) {
|
init: function(element_id) {
|
||||||
|
@ -924,16 +950,13 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
|
||||||
}
|
}
|
||||||
this.$element.html(QWeb.render("Interface", params));
|
this.$element.html(QWeb.render("Interface", params));
|
||||||
|
|
||||||
|
this.notification = new openerp.web.Notification();
|
||||||
this.session = new openerp.web.Session();
|
this.session = new openerp.web.Session();
|
||||||
this.loading = new openerp.web.Loading(this,"oe_loading");
|
this.loading = new openerp.web.Loading(this,"oe_loading");
|
||||||
this.crashmanager = new openerp.web.CrashManager(this);
|
this.crashmanager = new openerp.web.CrashManager(this);
|
||||||
this.crashmanager.start();
|
|
||||||
|
|
||||||
// Do you autorize this ? will be replaced by notify() in controller
|
|
||||||
openerp.web.Widget.prototype.notification = new openerp.web.Notification(this, "oe_notification");
|
|
||||||
|
|
||||||
this.header = new openerp.web.Header(this);
|
this.header = new openerp.web.Header(this);
|
||||||
this.login = new openerp.web.Login(this, "oe_login");
|
this.login = new openerp.web.Login(this);
|
||||||
this.header.on_logout.add(this.login.on_logout);
|
this.header.on_logout.add(this.login.on_logout);
|
||||||
this.header.on_action.add(this.on_menu_action);
|
this.header.on_action.add(this.on_menu_action);
|
||||||
|
|
||||||
|
@ -951,12 +974,27 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
|
||||||
|
|
||||||
},
|
},
|
||||||
start: function() {
|
start: function() {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
this.notification.prependTo(this.$element);
|
||||||
this.header.appendTo($("#oe_header"));
|
this.header.appendTo($("#oe_header"));
|
||||||
this.session.start();
|
this.session.start();
|
||||||
this.login.start();
|
this.login.appendTo($('#oe_login'));
|
||||||
this.menu.start();
|
this.menu.start();
|
||||||
},
|
},
|
||||||
|
do_reload: function() {
|
||||||
|
this.session.session_restore();
|
||||||
|
this.menu.do_reload();
|
||||||
|
},
|
||||||
|
do_notify: function() {
|
||||||
|
var n = this.notification;
|
||||||
|
n.notify.apply(n, arguments);
|
||||||
|
},
|
||||||
|
do_warn: function() {
|
||||||
|
var n = this.notification;
|
||||||
|
n.warn.apply(n, arguments);
|
||||||
|
},
|
||||||
on_logged: function() {
|
on_logged: function() {
|
||||||
|
this.menu.do_reload();
|
||||||
if(this.action_manager)
|
if(this.action_manager)
|
||||||
this.action_manager.stop();
|
this.action_manager.stop();
|
||||||
this.action_manager = new openerp.web.ActionManager(this);
|
this.action_manager = new openerp.web.ActionManager(this);
|
||||||
|
@ -1000,7 +1038,7 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
|
||||||
self.execute_home_action(home_action[0], ds);
|
self.execute_home_action(home_action[0], ds);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
default_home: function () {
|
default_home: function () {
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Bundles the execution of the home action
|
* Bundles the execution of the home action
|
||||||
|
@ -1025,7 +1063,6 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
|
||||||
},
|
},
|
||||||
do_url_set_hash: function(url) {
|
do_url_set_hash: function(url) {
|
||||||
if(!this.url_external_hashchange) {
|
if(!this.url_external_hashchange) {
|
||||||
console.log("url set #hash to",url);
|
|
||||||
this.url_internal_hashchange = true;
|
this.url_internal_hashchange = true;
|
||||||
jQuery.bbq.pushState(url);
|
jQuery.bbq.pushState(url);
|
||||||
}
|
}
|
||||||
|
@ -1033,10 +1070,8 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
|
||||||
on_url_hashchange: function() {
|
on_url_hashchange: function() {
|
||||||
if(this.url_internal_hashchange) {
|
if(this.url_internal_hashchange) {
|
||||||
this.url_internal_hashchange = false;
|
this.url_internal_hashchange = false;
|
||||||
console.log("url jump to FLAG OFF");
|
|
||||||
} else {
|
} else {
|
||||||
var url = jQuery.deparam.fragment();
|
var url = jQuery.deparam.fragment();
|
||||||
console.log("url jump to",url);
|
|
||||||
this.url_external_hashchange = true;
|
this.url_external_hashchange = true;
|
||||||
this.action_manager.on_url_hashchange(url);
|
this.action_manager.on_url_hashchange(url);
|
||||||
this.url_external_hashchange = false;
|
this.url_external_hashchange = false;
|
||||||
|
@ -1046,7 +1081,8 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
|
||||||
this.action_manager.do_action(action);
|
this.action_manager.do_action(action);
|
||||||
},
|
},
|
||||||
do_about: function() {
|
do_about: function() {
|
||||||
}
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,8 +10,6 @@ if (!console.debug) {
|
||||||
}
|
}
|
||||||
|
|
||||||
openerp.web.core = function(openerp) {
|
openerp.web.core = function(openerp) {
|
||||||
openerp.web.qweb = new QWeb2.Engine();
|
|
||||||
openerp.web.qweb.debug = (window.location.search.indexOf('?debug') !== -1);
|
|
||||||
/**
|
/**
|
||||||
* John Resig Class with factory improvement
|
* John Resig Class with factory improvement
|
||||||
*/
|
*/
|
||||||
|
@ -287,14 +285,12 @@ openerp.web.Registry = openerp.web.Class.extend( /** @lends openerp.web.Registry
|
||||||
*/
|
*/
|
||||||
get_any: function (keys) {
|
get_any: function (keys) {
|
||||||
for (var i=0; i<keys.length; ++i) {
|
for (var i=0; i<keys.length; ++i) {
|
||||||
try {
|
var key = keys[i];
|
||||||
return this.get_object(keys[i]);
|
if (key === undefined || !(key in this.map)) {
|
||||||
} catch (e) {
|
continue;
|
||||||
if (e instanceof openerp.web.KeyNotFound) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.get_object(key);
|
||||||
}
|
}
|
||||||
throw new openerp.web.KeyNotFound(keys.join(','));
|
throw new openerp.web.KeyNotFound(keys.join(','));
|
||||||
},
|
},
|
||||||
|
@ -365,6 +361,9 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
|
||||||
this.context = {};
|
this.context = {};
|
||||||
this.shortcuts = [];
|
this.shortcuts = [];
|
||||||
this.active_id = null;
|
this.active_id = null;
|
||||||
|
// TODO: session should have an optional name indicating that they'll
|
||||||
|
// be saved to (and revived from) cookies
|
||||||
|
this.name = 'session';
|
||||||
},
|
},
|
||||||
start: function() {
|
start: function() {
|
||||||
this.session_restore();
|
this.session_restore();
|
||||||
|
@ -386,6 +385,8 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
|
||||||
var self = this;
|
var self = this;
|
||||||
// Construct a JSON-RPC2 request, method is currently unused
|
// Construct a JSON-RPC2 request, method is currently unused
|
||||||
params.session_id = this.session_id;
|
params.session_id = this.session_id;
|
||||||
|
if (this.debug)
|
||||||
|
params.debug = 1;
|
||||||
|
|
||||||
// Call using the rpc_mode
|
// Call using the rpc_mode
|
||||||
var deferred = $.Deferred();
|
var deferred = $.Deferred();
|
||||||
|
@ -480,14 +481,12 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
|
||||||
session_login: function(db, login, password, success_callback) {
|
session_login: function(db, login, password, success_callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var params = { db: db, login: login, password: password };
|
var params = { db: db, login: login, password: password };
|
||||||
this.rpc("/web/session/login", params, function(result) {
|
return this.rpc("/web/session/login", params, function(result) {
|
||||||
self.session_id = result.session_id;
|
self.session_id = result.session_id;
|
||||||
self.uid = result.uid;
|
self.uid = result.uid;
|
||||||
self.user_context = result.context;
|
self.user_context = result.context;
|
||||||
self.db = result.db;
|
self.db = result.db;
|
||||||
self.session_save();
|
self.session_save();
|
||||||
if (self.uid)
|
|
||||||
self.on_session_valid();
|
|
||||||
return true;
|
return true;
|
||||||
}).then(success_callback);
|
}).then(success_callback);
|
||||||
},
|
},
|
||||||
|
@ -529,7 +528,8 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
|
||||||
* @param name the cookie's name
|
* @param name the cookie's name
|
||||||
*/
|
*/
|
||||||
get_cookie: function (name) {
|
get_cookie: function (name) {
|
||||||
var nameEQ = this.element_id + '|' + name + '=';
|
if (!this.name) { return null; }
|
||||||
|
var nameEQ = this.name + '|' + name + '=';
|
||||||
var cookies = document.cookie.split(';');
|
var cookies = document.cookie.split(';');
|
||||||
for(var i=0; i<cookies.length; ++i) {
|
for(var i=0; i<cookies.length; ++i) {
|
||||||
var cookie = cookies[i].replace(/^\s*/, '');
|
var cookie = cookies[i].replace(/^\s*/, '');
|
||||||
|
@ -548,9 +548,11 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
|
||||||
* @param ttl the cookie's time to live, 1 year by default, set to -1 to delete
|
* @param ttl the cookie's time to live, 1 year by default, set to -1 to delete
|
||||||
*/
|
*/
|
||||||
set_cookie: function (name, value, ttl) {
|
set_cookie: function (name, value, ttl) {
|
||||||
|
if (!this.name) { return; }
|
||||||
ttl = ttl || 24*60*60*365;
|
ttl = ttl || 24*60*60*365;
|
||||||
document.cookie = [
|
document.cookie = [
|
||||||
this.element_id + '|' + name + '=' + encodeURIComponent(JSON.stringify(value)),
|
this.name + '|' + name + '=' + encodeURIComponent(JSON.stringify(value)),
|
||||||
|
'path=/',
|
||||||
'max-age=' + ttl,
|
'max-age=' + ttl,
|
||||||
'expires=' + new Date(new Date().getTime() + ttl*1000).toGMTString()
|
'expires=' + new Date(new Date().getTime() + ttl*1000).toGMTString()
|
||||||
].join(';');
|
].join(';');
|
||||||
|
@ -570,15 +572,11 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
|
||||||
var file_list = ["/web/static/lib/datejs/globalization/" +
|
var file_list = ["/web/static/lib/datejs/globalization/" +
|
||||||
self.user_context.lang.replace("_", "-") + ".js"
|
self.user_context.lang.replace("_", "-") + ".js"
|
||||||
];
|
];
|
||||||
if(self.debug) {
|
|
||||||
self.rpc('/web/webclient/csslist', {"mods": modules}, self.do_load_css);
|
self.rpc('/web/webclient/csslist', {"mods": modules}, self.do_load_css);
|
||||||
self.rpc('/web/webclient/jslist', {"mods": modules}, function(files) {
|
self.rpc('/web/webclient/jslist', {"mods": modules}, function(files) {
|
||||||
self.do_load_js(file_list.concat(files));
|
self.do_load_js(file_list.concat(files));
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
self.do_load_css(["/web/webclient/css?mods="+modules]);
|
|
||||||
self.do_load_js(file_list.concat(["/web/webclient/js?mods="+modules]));
|
|
||||||
}
|
|
||||||
openerp._modules_loaded = true;
|
openerp._modules_loaded = true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -587,7 +585,7 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
|
||||||
var self = this;
|
var self = this;
|
||||||
_.each(files, function (file) {
|
_.each(files, function (file) {
|
||||||
$('head').append($('<link>', {
|
$('head').append($('<link>', {
|
||||||
'href': file + (self.debug ? '?debug=' + (new Date().getTime()) : ''),
|
'href': file,
|
||||||
'rel': 'stylesheet',
|
'rel': 'stylesheet',
|
||||||
'type': 'text/css'
|
'type': 'text/css'
|
||||||
}));
|
}));
|
||||||
|
@ -599,14 +597,15 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
|
||||||
var file = files.shift();
|
var file = files.shift();
|
||||||
var tag = document.createElement('script');
|
var tag = document.createElement('script');
|
||||||
tag.type = 'text/javascript';
|
tag.type = 'text/javascript';
|
||||||
tag.src = file + (this.debug ? '?debug=' + (new Date().getTime()) : '');
|
tag.src = file;
|
||||||
tag.onload = tag.onreadystatechange = function() {
|
tag.onload = tag.onreadystatechange = function() {
|
||||||
if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done )
|
if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done )
|
||||||
return;
|
return;
|
||||||
tag.onload_done = true;
|
tag.onload_done = true;
|
||||||
self.do_load_js(files);
|
self.do_load_js(files);
|
||||||
};
|
};
|
||||||
document.head.appendChild(tag);
|
var head = document.head || document.getElementsByTagName('head')[0];
|
||||||
|
head.appendChild(tag);
|
||||||
} else {
|
} else {
|
||||||
this.on_modules_loaded();
|
this.on_modules_loaded();
|
||||||
}
|
}
|
||||||
|
@ -1045,6 +1044,21 @@ openerp.web.TranslationDataBase = openerp.web.Class.extend(/** @lends openerp.we
|
||||||
});
|
});
|
||||||
|
|
||||||
openerp.web._t = new openerp.web.TranslationDataBase().build_translation_function();
|
openerp.web._t = new openerp.web.TranslationDataBase().build_translation_function();
|
||||||
|
openerp.web.qweb = new QWeb2.Engine();
|
||||||
|
openerp.web.qweb.debug = (window.location.search.indexOf('?debug') !== -1);
|
||||||
|
openerp.web.qweb.format_text_node = function(s) {
|
||||||
|
// Note that 'this' is the Qweb Node of the text
|
||||||
|
var translation = this.node.parentNode.attributes['t-translation'];
|
||||||
|
if (translation && translation.value === 'off') {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
var ts = _.trim(s);
|
||||||
|
if (ts.length === 0) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
var tr = openerp.web._t(ts);
|
||||||
|
return tr === ts ? s : tr;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -233,6 +233,7 @@ openerp.web.StaticDataGroup = openerp.web.GrouplessDataGroup.extend( /** @lends
|
||||||
});
|
});
|
||||||
|
|
||||||
openerp.web.DataSet = openerp.web.Widget.extend( /** @lends openerp.web.DataSet# */{
|
openerp.web.DataSet = openerp.web.Widget.extend( /** @lends openerp.web.DataSet# */{
|
||||||
|
identifier_prefix: "dataset",
|
||||||
/**
|
/**
|
||||||
* DateaManagement interface between views and the collection of selected
|
* DateaManagement interface between views and the collection of selected
|
||||||
* OpenERP records (represents the view's state?)
|
* OpenERP records (represents the view's state?)
|
||||||
|
@ -242,16 +243,12 @@ openerp.web.DataSet = openerp.web.Widget.extend( /** @lends openerp.web.DataSet
|
||||||
*
|
*
|
||||||
* @param {String} model the OpenERP model this dataset will manage
|
* @param {String} model the OpenERP model this dataset will manage
|
||||||
*/
|
*/
|
||||||
init: function(source_controller, model, context) {
|
init: function(parent, model, context) {
|
||||||
// we don't want the dataset to be a child of anything!
|
this._super(parent);
|
||||||
this._super(null);
|
|
||||||
this.session = source_controller ? source_controller.session : undefined;
|
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.context = context || {};
|
this.context = context || {};
|
||||||
this.index = null;
|
this.index = null;
|
||||||
},
|
},
|
||||||
start: function() {
|
|
||||||
},
|
|
||||||
previous: function () {
|
previous: function () {
|
||||||
this.index -= 1;
|
this.index -= 1;
|
||||||
if (this.index < 0) {
|
if (this.index < 0) {
|
||||||
|
@ -266,6 +263,15 @@ openerp.web.DataSet = openerp.web.Widget.extend( /** @lends openerp.web.DataSet
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
select_id: function(id) {
|
||||||
|
var idx = _.indexOf(this.ids, id);
|
||||||
|
if (idx === -1) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
this.index = idx;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Read records.
|
* Read records.
|
||||||
*
|
*
|
||||||
|
@ -487,7 +493,7 @@ openerp.web.DataSetStatic = openerp.web.DataSet.extend({
|
||||||
offset = options.offset || 0,
|
offset = options.offset || 0,
|
||||||
limit = options.limit || false,
|
limit = options.limit || false,
|
||||||
fields = fields || false;
|
fields = fields || false;
|
||||||
var end_pos = limit && limit !== -1 ? offset + limit : undefined;
|
var end_pos = limit && limit !== -1 ? offset + limit : this.ids.length;
|
||||||
return this.read_ids(this.ids.slice(offset, end_pos), fields, callback);
|
return this.read_ids(this.ids.slice(offset, end_pos), fields, callback);
|
||||||
},
|
},
|
||||||
set_ids: function (ids) {
|
set_ids: function (ids) {
|
||||||
|
@ -549,13 +555,11 @@ openerp.web.DataSetSearch = openerp.web.DataSet.extend(/** @lends openerp.web.D
|
||||||
sort: this.sort(),
|
sort: this.sort(),
|
||||||
offset: offset,
|
offset: offset,
|
||||||
limit: options.limit || false
|
limit: options.limit || false
|
||||||
}, function (result) {
|
}).pipe(function (result) {
|
||||||
self.ids = result.ids;
|
self.ids = result.ids;
|
||||||
self.offset = offset;
|
self.offset = offset;
|
||||||
if (callback) {
|
return result.records;
|
||||||
callback(result.records);
|
}).then(callback);
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
get_domain: function (other_domain) {
|
get_domain: function (other_domain) {
|
||||||
if (other_domain) {
|
if (other_domain) {
|
||||||
|
@ -603,20 +607,27 @@ openerp.web.DataSetSearch = openerp.web.DataSet.extend(/** @lends openerp.web.D
|
||||||
});
|
});
|
||||||
openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
|
openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
|
||||||
virtual_id_prefix: "one2many_v_id_",
|
virtual_id_prefix: "one2many_v_id_",
|
||||||
virtual_id_regex: /one2many_v_id_.*/,
|
|
||||||
debug_mode: true,
|
debug_mode: true,
|
||||||
init: function() {
|
init: function() {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
this.reset_ids([]);
|
this.reset_ids([]);
|
||||||
|
this.last_default_get = {};
|
||||||
|
},
|
||||||
|
default_get: function(fields, callback) {
|
||||||
|
return this._super(fields).then(this.on_default_get).then(callback);
|
||||||
|
},
|
||||||
|
on_default_get: function(res) {
|
||||||
|
this.last_default_get = res;
|
||||||
},
|
},
|
||||||
create: function(data, callback, error_callback) {
|
create: function(data, callback, error_callback) {
|
||||||
var cached = {id:_.uniqueId(this.virtual_id_prefix), values: data};
|
var cached = {id:_.uniqueId(this.virtual_id_prefix), values: data,
|
||||||
this.to_create.push(cached);
|
defaults: this.last_default_get};
|
||||||
|
this.to_create.push(_.extend(_.clone(cached), {values: _.clone(cached.values)}));
|
||||||
this.cache.push(cached);
|
this.cache.push(cached);
|
||||||
this.on_change();
|
this.on_change();
|
||||||
var to_return = $.Deferred().then(callback);
|
var prom = $.Deferred().then(callback);
|
||||||
to_return.resolve({result: cached.id});
|
prom.resolve({result: cached.id});
|
||||||
return to_return.promise();
|
return prom.promise();
|
||||||
},
|
},
|
||||||
write: function (id, data, options, callback) {
|
write: function (id, data, options, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -637,6 +648,10 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
|
||||||
self.to_write.push(record);
|
self.to_write.push(record);
|
||||||
}
|
}
|
||||||
var cached = _.detect(this.cache, function(x) {return x.id === id;});
|
var cached = _.detect(this.cache, function(x) {return x.id === id;});
|
||||||
|
if (!cached) {
|
||||||
|
cached = {id: id, values: {}};
|
||||||
|
this.cache.push(cached);
|
||||||
|
}
|
||||||
$.extend(cached.values, record.values);
|
$.extend(cached.values, record.values);
|
||||||
if (dirty)
|
if (dirty)
|
||||||
this.on_change();
|
this.on_change();
|
||||||
|
@ -676,7 +691,8 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
|
||||||
var cached = _.detect(self.cache, function(x) {return x.id === id;});
|
var cached = _.detect(self.cache, function(x) {return x.id === id;});
|
||||||
var created = _.detect(self.to_create, function(x) {return x.id === id;});
|
var created = _.detect(self.to_create, function(x) {return x.id === id;});
|
||||||
if (created) {
|
if (created) {
|
||||||
_.each(fields, function(x) {if (cached.values[x] === undefined) cached.values[x] = false;});
|
_.each(fields, function(x) {if (cached.values[x] === undefined)
|
||||||
|
cached.values[x] = created.defaults[x] || false;});
|
||||||
} else {
|
} else {
|
||||||
if (!cached || !_.all(fields, function(x) {return cached.values[x] !== undefined}))
|
if (!cached || !_.all(fields, function(x) {return cached.values[x] !== undefined}))
|
||||||
to_get.push(id);
|
to_get.push(id);
|
||||||
|
@ -692,7 +708,7 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
|
||||||
throw "Record not correctly loaded";
|
throw "Record not correctly loaded";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setTimeout(function () {completion.resolve(records);}, 0);
|
completion.resolve(records);
|
||||||
};
|
};
|
||||||
if(to_get.length > 0) {
|
if(to_get.length > 0) {
|
||||||
var rpc_promise = this._super(to_get, fields, function(records) {
|
var rpc_promise = this._super(to_get, fields, function(records) {
|
||||||
|
@ -715,23 +731,53 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
|
||||||
return completion.promise();
|
return completion.promise();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
openerp.web.ReadOnlyDataSetSearch = openerp.web.DataSetSearch.extend({
|
openerp.web.BufferedDataSet.virtual_id_regex = /^one2many_v_id_.*$/;
|
||||||
|
|
||||||
|
openerp.web.ProxyDataSet = openerp.web.DataSetSearch.extend({
|
||||||
|
init: function() {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
this.create_function = null;
|
||||||
|
this.write_function = null;
|
||||||
|
this.read_function = null;
|
||||||
|
},
|
||||||
|
read_ids: function () {
|
||||||
|
if (this.read_function) {
|
||||||
|
return this.read_function.apply(null, arguments);
|
||||||
|
} else {
|
||||||
|
return this._super.apply(this, arguments);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
default_get: function(fields, callback) {
|
||||||
|
return this._super(fields, callback).then(this.on_default_get);
|
||||||
|
},
|
||||||
|
on_default_get: function(result) {},
|
||||||
create: function(data, callback, error_callback) {
|
create: function(data, callback, error_callback) {
|
||||||
this.on_create(data);
|
this.on_create(data);
|
||||||
var to_return = $.Deferred().then(callback);
|
if (this.create_function) {
|
||||||
setTimeout(function () {to_return.resolve({"result": undefined});}, 0);
|
return this.create_function(data, callback, error_callback);
|
||||||
return to_return.promise();
|
} else {
|
||||||
|
console.warn("trying to create a record using default proxy dataset behavior");
|
||||||
|
var to_return = $.Deferred().then(callback);
|
||||||
|
setTimeout(function () {to_return.resolve({"result": undefined});}, 0);
|
||||||
|
return to_return.promise();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
on_create: function(data) {},
|
on_create: function(data) {},
|
||||||
write: function (id, data, options, callback) {
|
write: function (id, data, options, callback) {
|
||||||
this.on_write(id, data);
|
this.on_write(id, data);
|
||||||
var to_return = $.Deferred().then(callback);
|
if (this.write_function) {
|
||||||
setTimeout(function () {to_return.resolve({"result": true});}, 0);
|
return this.write_function(id, data, options, callback);
|
||||||
return to_return.promise();
|
} else {
|
||||||
|
console.warn("trying to write a record using default proxy dataset behavior");
|
||||||
|
var to_return = $.Deferred().then(callback);
|
||||||
|
setTimeout(function () {to_return.resolve({"result": true});}, 0);
|
||||||
|
return to_return.promise();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
on_write: function(id, data) {},
|
on_write: function(id, data) {},
|
||||||
unlink: function(ids, callback, error_callback) {
|
unlink: function(ids, callback, error_callback) {
|
||||||
this.on_unlink(ids);
|
this.on_unlink(ids);
|
||||||
|
console.warn("trying to unlink a record using default proxy dataset behavior");
|
||||||
var to_return = $.Deferred().then(callback);
|
var to_return = $.Deferred().then(callback);
|
||||||
setTimeout(function () {to_return.resolve({"result": true});}, 0);
|
setTimeout(function () {to_return.resolve({"result": true});}, 0);
|
||||||
return to_return.promise();
|
return to_return.promise();
|
||||||
|
|
|
@ -0,0 +1,344 @@
|
||||||
|
openerp.web.data_import = function(openerp) {
|
||||||
|
var QWeb = openerp.web.qweb,
|
||||||
|
_t = openerp.web._t;
|
||||||
|
/**
|
||||||
|
* Safari does not deal well at all with raw JSON data being returned. As a
|
||||||
|
* result, we're going to cheat by using a pseudo-jsonp: instead of getting
|
||||||
|
* JSON data in the iframe, we're getting a ``script`` tag which consists of a
|
||||||
|
* function call and the returned data (the json dump).
|
||||||
|
*
|
||||||
|
* The function is an auto-generated name bound to ``window``, which calls
|
||||||
|
* back into the callback provided here.
|
||||||
|
*
|
||||||
|
* @param {Object} form the form element (DOM or jQuery) to use in the call
|
||||||
|
* @param {Object} attributes jquery.form attributes object
|
||||||
|
* @param {Function} callback function to call with the returned data
|
||||||
|
*/
|
||||||
|
function jsonp(form, attributes, callback) {
|
||||||
|
attributes = attributes || {};
|
||||||
|
var options = {jsonp: _.uniqueId('import_callback_')};
|
||||||
|
window[options.jsonp] = function () {
|
||||||
|
delete window[options.jsonp];
|
||||||
|
callback.apply(null, arguments);
|
||||||
|
};
|
||||||
|
if ('data' in attributes) {
|
||||||
|
_.extend(attributes.data, options);
|
||||||
|
} else {
|
||||||
|
_.extend(attributes, {data: options});
|
||||||
|
}
|
||||||
|
$(form).ajaxSubmit(attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
openerp.web.DataImport = openerp.web.Dialog.extend({
|
||||||
|
template: 'ImportDataView',
|
||||||
|
dialog_title: "Import Data",
|
||||||
|
init: function(parent, dataset){
|
||||||
|
var self = this;
|
||||||
|
this._super(parent, {});
|
||||||
|
this.model = parent.model;
|
||||||
|
this.fields = [];
|
||||||
|
this.all_fields = [];
|
||||||
|
this.fields_with_defaults = [];
|
||||||
|
this.required_fields = null;
|
||||||
|
|
||||||
|
var convert_fields = function (root, prefix) {
|
||||||
|
prefix = prefix || '';
|
||||||
|
_(root.fields).each(function (f) {
|
||||||
|
self.all_fields.push(prefix + f.name);
|
||||||
|
if (f.fields) {
|
||||||
|
convert_fields(f, prefix + f.id + '/');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
this.ready = $.Deferred.queue().then(function () {
|
||||||
|
self.required_fields = _(self.fields).chain()
|
||||||
|
.filter(function (field) {
|
||||||
|
return field.required &&
|
||||||
|
!_.include(self.fields_with_defaults, field.id); })
|
||||||
|
.pluck('name')
|
||||||
|
.value();
|
||||||
|
convert_fields(self);
|
||||||
|
self.all_fields.sort();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
start: function() {
|
||||||
|
var self = this;
|
||||||
|
this._super();
|
||||||
|
this.open({
|
||||||
|
modal: true,
|
||||||
|
width: '70%',
|
||||||
|
height: 'auto',
|
||||||
|
position: 'top',
|
||||||
|
buttons: [
|
||||||
|
{text: "Close", click: function() { self.stop(); }},
|
||||||
|
{text: "Import File", click: function() { self.do_import(); }, 'class': 'oe-dialog-import-button'}
|
||||||
|
],
|
||||||
|
close: function(event, ui) {
|
||||||
|
self.stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.toggle_import_button(false);
|
||||||
|
this.$element.find('#csvfile').change(this.on_autodetect_data);
|
||||||
|
this.$element.find('fieldset').change(this.on_autodetect_data);
|
||||||
|
this.$element.find('fieldset legend').click(function() {
|
||||||
|
$(this).next().toggle();
|
||||||
|
});
|
||||||
|
this.ready.push(new openerp.web.DataSet(this, this.model).call(
|
||||||
|
'fields_get', [], function (fields) {
|
||||||
|
self.graft_fields(fields);
|
||||||
|
self.ready.push(new openerp.web.DataSet(self, self.model)
|
||||||
|
.default_get(_.pluck(self.fields, 'id'), function (fields) {
|
||||||
|
_.each(fields, function(val, key) {
|
||||||
|
if (val) {
|
||||||
|
self.fields_with_defaults.push(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
graft_fields: function (fields, parent, level) {
|
||||||
|
parent = parent || this;
|
||||||
|
level = level || 0;
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
if (level === 0) {
|
||||||
|
parent.fields.push({
|
||||||
|
id: 'id',
|
||||||
|
name: 'id',
|
||||||
|
string: _t('External ID'),
|
||||||
|
required: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_(fields).each(function (field, field_name) {
|
||||||
|
if (field_name === 'id') { return; }
|
||||||
|
var f = {
|
||||||
|
id: field_name,
|
||||||
|
name: field_name,
|
||||||
|
string: field.string,
|
||||||
|
required: field.required
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (field.type) {
|
||||||
|
case 'many2many':
|
||||||
|
case 'many2one':
|
||||||
|
f.name += '/id';
|
||||||
|
break;
|
||||||
|
case 'one2many':
|
||||||
|
f.name += '/id';
|
||||||
|
f.fields = [];
|
||||||
|
// only fetch sub-fields to a depth of 2 levels
|
||||||
|
if (level < 2) {
|
||||||
|
self.ready.push(new openerp.web.DataSet(self, field.relation).call(
|
||||||
|
'fields_get', [], function (fields) {
|
||||||
|
self.graft_fields(fields, f, level+1);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parent.fields.push(f);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
toggle_import_button: function (newstate) {
|
||||||
|
this.$dialog.dialog('widget')
|
||||||
|
.find('.oe-dialog-import-button')
|
||||||
|
.button('option', 'disabled', !newstate);
|
||||||
|
},
|
||||||
|
do_import: function() {
|
||||||
|
if(!this.$element.find('#csvfile').val()) { return; }
|
||||||
|
var lines_to_skip = parseInt(this.$element.find('#csv_skip').val(), 10);
|
||||||
|
var with_headers = this.$element.find('#file_has_headers').prop('checked');
|
||||||
|
if (!lines_to_skip && with_headers) {
|
||||||
|
lines_to_skip = 1;
|
||||||
|
}
|
||||||
|
var indices = [], fields = [];
|
||||||
|
this.$element.find(".sel_fields").each(function(index, element) {
|
||||||
|
var val = element.value;
|
||||||
|
if (!val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
indices.push(index);
|
||||||
|
fields.push(val);
|
||||||
|
});
|
||||||
|
|
||||||
|
jsonp(this.$element.find('#import_data'), {
|
||||||
|
url: '/web/import/import_data',
|
||||||
|
data: {
|
||||||
|
model: this.model,
|
||||||
|
meta: JSON.stringify({
|
||||||
|
skip: lines_to_skip,
|
||||||
|
indices: indices,
|
||||||
|
fields: fields
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, this.on_import_results);
|
||||||
|
},
|
||||||
|
on_autodetect_data: function() {
|
||||||
|
if(!this.$element.find('#csvfile').val()) { return; }
|
||||||
|
jsonp(this.$element.find('#import_data'), {
|
||||||
|
url: '/web/import/detect_data'
|
||||||
|
}, this.on_import_results);
|
||||||
|
},
|
||||||
|
on_import_results: function(results) {
|
||||||
|
this.$element.find('#result').empty();
|
||||||
|
var headers, result_node = this.$element.find("#result");
|
||||||
|
|
||||||
|
if (results['records']) {
|
||||||
|
var lines_to_skip = parseInt(this.$element.find('#csv_skip').val(), 10),
|
||||||
|
with_headers = this.$element.find('#file_has_headers').prop('checked');
|
||||||
|
headers = with_headers ? results.records[0] : null;
|
||||||
|
|
||||||
|
result_node.append(QWeb.render('ImportView.result', {
|
||||||
|
'headers': headers,
|
||||||
|
'records': lines_to_skip ? results.records.slice(lines_to_skip)
|
||||||
|
: with_headers ? results.records.slice(1)
|
||||||
|
: results.records
|
||||||
|
}));
|
||||||
|
} else if (results['error']) {
|
||||||
|
result_node.append(QWeb.render('ImportView.error', {
|
||||||
|
'error': results['error']}));
|
||||||
|
} else if (results['success']) {
|
||||||
|
if (this.widget_parent.widget_parent.active_view == "list") {
|
||||||
|
this.widget_parent.reload_content();
|
||||||
|
}
|
||||||
|
this.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
this.ready.then(function () {
|
||||||
|
var $fields = self.$element.find('.sel_fields').bind('blur', function () {
|
||||||
|
if (this.value && !_(self.all_fields).contains(this.value)) {
|
||||||
|
this.value = '';
|
||||||
|
}
|
||||||
|
}).autocomplete({
|
||||||
|
minLength: 0,
|
||||||
|
source: self.all_fields,
|
||||||
|
change: self.on_check_field_values
|
||||||
|
}).focus(function () {
|
||||||
|
$(this).autocomplete('search');
|
||||||
|
});
|
||||||
|
// Column auto-detection
|
||||||
|
_(headers).each(function (header, index) {
|
||||||
|
var field_name = self.match_column_to_field(header);
|
||||||
|
if (field_name) {
|
||||||
|
$fields.eq(index).val(field_name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.on_check_field_values();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Returns the name of the field (nested) matching the provided column name
|
||||||
|
*
|
||||||
|
* @param {String} name column name to look for
|
||||||
|
* @param {Array} [fields] fields to look into for the provided name
|
||||||
|
* @returns {String|undefined}
|
||||||
|
*/
|
||||||
|
match_column_to_field: function (name, fields) {
|
||||||
|
fields = fields || this.fields;
|
||||||
|
var f;
|
||||||
|
f = _(fields).detect(function (field) {
|
||||||
|
// TODO: levenshtein between header and field.string
|
||||||
|
return field.name === name
|
||||||
|
|| field.string.toLowerCase() === name.toLowerCase();
|
||||||
|
});
|
||||||
|
if (f) { return f.name; }
|
||||||
|
|
||||||
|
// if ``name`` is a path (o2m), we need to recurse through its .fields
|
||||||
|
var index = name.indexOf('/');
|
||||||
|
if (index === -1) { return undefined; }
|
||||||
|
// Get the first path section, try to find the matching field
|
||||||
|
var column_name = name.substring(0, index);
|
||||||
|
f = _(fields).detect(function (field) {
|
||||||
|
// field.name for o2m is $foo/id, so we want to match on id
|
||||||
|
return field.id === column_name
|
||||||
|
|| field.string.toLowerCase() === column_name.toLowerCase()
|
||||||
|
});
|
||||||
|
if (!f) { return undefined; }
|
||||||
|
|
||||||
|
// if we found a matching field for the first path section, recurse in
|
||||||
|
// its own .fields to try and get the rest of the path matched
|
||||||
|
var rest = this.match_column_to_field(
|
||||||
|
name.substring(index+1), f.fields);
|
||||||
|
if (!rest) { return undefined; }
|
||||||
|
return f.id + '/' + rest;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Looks through all the field selections, and tries to find if two
|
||||||
|
* (or more) columns were matched to the same model field.
|
||||||
|
*
|
||||||
|
* Returns a map of the multiply-mapped fields to an array of offending
|
||||||
|
* columns (not actually columns, but the inputs containing the same field
|
||||||
|
* names).
|
||||||
|
*
|
||||||
|
* Also has the side-effect of marking the discovered inputs with the class
|
||||||
|
* ``duplicate_fld``.
|
||||||
|
*
|
||||||
|
* @returns {Object<String, Array<String>>} map of duplicate field matches to same-valued inputs
|
||||||
|
*/
|
||||||
|
find_duplicate_fields: function() {
|
||||||
|
// Maps values to DOM nodes, in order to discover duplicates
|
||||||
|
var values = {}, duplicates = {};
|
||||||
|
this.$element.find(".sel_fields").each(function(index, element) {
|
||||||
|
var value = element.value;
|
||||||
|
var $element = $(element).removeClass('duplicate_fld');
|
||||||
|
if (!value) { return; }
|
||||||
|
|
||||||
|
if (!(value in values)) {
|
||||||
|
values[value] = element;
|
||||||
|
} else {
|
||||||
|
var same_valued_field = values[value];
|
||||||
|
if (value in duplicates) {
|
||||||
|
duplicates[value].push(element);
|
||||||
|
} else {
|
||||||
|
duplicates[value] = [same_valued_field, element];
|
||||||
|
}
|
||||||
|
$element.add(same_valued_field).addClass('duplicate_fld');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return duplicates;
|
||||||
|
},
|
||||||
|
on_check_field_values: function () {
|
||||||
|
this.$element.find("#message, #msg").remove();
|
||||||
|
|
||||||
|
var required_valid = this.check_required();
|
||||||
|
|
||||||
|
var duplicates = this.find_duplicate_fields();
|
||||||
|
if (_.isEmpty(duplicates)) {
|
||||||
|
this.toggle_import_button(required_valid);
|
||||||
|
} else {
|
||||||
|
var $err = $('<div id="msg" style="color: red;">Destination fields should only be selected once, some fields are selected more than once:</div>').insertBefore(this.$element.find('#result'));
|
||||||
|
var $dupes = $('<dl>').appendTo($err);
|
||||||
|
_(duplicates).each(function(elements, value) {
|
||||||
|
$('<dt>').text(value).appendTo($dupes);
|
||||||
|
_(elements).each(function(element) {
|
||||||
|
var cell = $(element).closest('td');
|
||||||
|
$('<dd>').text(cell.parent().children().index(cell)).appendTo($dupes);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.toggle_import_button(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
check_required: function() {
|
||||||
|
if (!this.required_fields.length) { return true; }
|
||||||
|
|
||||||
|
var selected_fields = _(this.$element.find('.sel_fields').get()).chain()
|
||||||
|
.pluck('value')
|
||||||
|
.compact()
|
||||||
|
.value();
|
||||||
|
|
||||||
|
var missing_fields = _.difference(this.required_fields, selected_fields);
|
||||||
|
if (missing_fields.length) {
|
||||||
|
this.$element.find("#result").before('<div id="message" style="color:red">*Required Fields are not selected : ' + missing_fields + '.</div>');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
stop: function() {
|
||||||
|
$(this.$dialog).remove();
|
||||||
|
this._super();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
|
@ -28,10 +28,13 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
|
||||||
case 'float':
|
case 'float':
|
||||||
var precision = descriptor.digits ? descriptor.digits[1] : 2;
|
var precision = descriptor.digits ? descriptor.digits[1] : 2;
|
||||||
var int_part = Math.floor(value);
|
var int_part = Math.floor(value);
|
||||||
var dec_part = Math.abs(Math.floor((value % 1) * Math.pow(10, precision)));
|
var dec_part = _.sprintf(
|
||||||
return _.sprintf('%d%s%d',
|
'%.' + precision + 'f',
|
||||||
int_part,
|
Math.abs(value) % 1).substring(2);
|
||||||
openerp.web._t.database.parameters.decimal_point, dec_part);
|
return _.sprintf('%d%s%s',
|
||||||
|
int_part,
|
||||||
|
openerp.web._t.database.parameters.decimal_point,
|
||||||
|
dec_part);
|
||||||
case 'float_time':
|
case 'float_time':
|
||||||
return _.sprintf("%02d:%02d",
|
return _.sprintf("%02d:%02d",
|
||||||
Math.floor(value),
|
Math.floor(value),
|
||||||
|
@ -69,6 +72,13 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return value.format("%H:%M:%S");
|
return value.format("%H:%M:%S");
|
||||||
}
|
}
|
||||||
|
case 'selection':
|
||||||
|
// Each choice is [value, label]
|
||||||
|
var result = _(descriptor.selection).detect(function (choice) {
|
||||||
|
return choice[0] === value;
|
||||||
|
});
|
||||||
|
if (result) { return result[1]; }
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -179,9 +189,13 @@ openerp.web.auto_date_to_str = function(value, type) {
|
||||||
* @param {String} [column.string] button label
|
* @param {String} [column.string] button label
|
||||||
* @param {String} [column.icon] button icon
|
* @param {String} [column.icon] button icon
|
||||||
* @param {String} [value_if_empty=''] what to display if the field's value is ``false``
|
* @param {String} [value_if_empty=''] what to display if the field's value is ``false``
|
||||||
|
* @param {Boolean} [process_modifiers=true] should the modifiers be computed ?
|
||||||
*/
|
*/
|
||||||
openerp.web.format_cell = function (row_data, column, value_if_empty) {
|
openerp.web.format_cell = function (row_data, column, value_if_empty, process_modifiers) {
|
||||||
var attrs = column.modifiers_for(row_data);
|
var attrs = {};
|
||||||
|
if (process_modifiers !== false) {
|
||||||
|
attrs = column.modifiers_for(row_data);
|
||||||
|
}
|
||||||
if (attrs.invisible) { return ''; }
|
if (attrs.invisible) { return ''; }
|
||||||
if (column.tag === 'button') {
|
if (column.tag === 'button') {
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -13,24 +13,35 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
|
||||||
* @param view_id
|
* @param view_id
|
||||||
* @param defaults
|
* @param defaults
|
||||||
*/
|
*/
|
||||||
init: function(parent, dataset, view_id, defaults) {
|
init: function(parent, dataset, view_id, defaults, hidden) {
|
||||||
this._super(parent);
|
this._super(parent);
|
||||||
this.dataset = dataset;
|
this.dataset = dataset;
|
||||||
this.model = dataset.model;
|
this.model = dataset.model;
|
||||||
this.view_id = view_id;
|
this.view_id = view_id;
|
||||||
|
|
||||||
this.defaults = defaults || {};
|
this.defaults = defaults || {};
|
||||||
|
this.has_defaults = !_.isEmpty(this.defaults);
|
||||||
|
|
||||||
this.inputs = [];
|
this.inputs = [];
|
||||||
this.enabled_filters = [];
|
this.enabled_filters = [];
|
||||||
|
|
||||||
this.has_focus = false;
|
this.has_focus = false;
|
||||||
|
|
||||||
|
this.hidden = !!hidden;
|
||||||
|
this.headless = this.hidden && !this.has_defaults;
|
||||||
|
|
||||||
this.ready = $.Deferred();
|
this.ready = $.Deferred();
|
||||||
},
|
},
|
||||||
start: function() {
|
start: function() {
|
||||||
this._super();
|
this._super();
|
||||||
this.rpc("/web/searchview/load", {"model": this.model, "view_id":this.view_id}, this.on_loaded);
|
if (this.hidden) {
|
||||||
|
this.$element.hide();
|
||||||
|
}
|
||||||
|
if (this.headless) {
|
||||||
|
this.ready.resolve();
|
||||||
|
} else {
|
||||||
|
this.rpc("/web/searchview/load", {"model": this.model, "view_id":this.view_id}, this.on_loaded);
|
||||||
|
}
|
||||||
return this.ready.promise();
|
return this.ready.promise();
|
||||||
},
|
},
|
||||||
show: function () {
|
show: function () {
|
||||||
|
@ -105,8 +116,9 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
|
||||||
*/
|
*/
|
||||||
make_field: function (item, field) {
|
make_field: function (item, field) {
|
||||||
try {
|
try {
|
||||||
return new (openerp.web.search.fields.get_object(field.type))
|
return new (openerp.web.search.fields.get_any(
|
||||||
(item, field, this);
|
[item.attrs.widget, field.type]))
|
||||||
|
(item, field, this);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (! e instanceof openerp.web.KeyNotFound) {
|
if (! e instanceof openerp.web.KeyNotFound) {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -137,10 +149,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
|
||||||
'defaults': this.defaults
|
'defaults': this.defaults
|
||||||
});
|
});
|
||||||
|
|
||||||
// We don't understand why the following commented line does not work in Chrome but
|
this.$element.html(render);
|
||||||
// the non-commented line does. As far as we investigated, only God knows.
|
|
||||||
//this.$element.html(render);
|
|
||||||
jQuery(render).appendTo(this.$element);
|
|
||||||
this.$element.find(".oe_search-view-custom-filter-btn").click(ext.on_activate);
|
this.$element.find(".oe_search-view-custom-filter-btn").click(ext.on_activate);
|
||||||
|
|
||||||
var f = this.$element.find('form');
|
var f = this.$element.find('form');
|
||||||
|
@ -246,10 +255,13 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
|
||||||
* @param e jQuery event object coming from the "Search" button
|
* @param e jQuery event object coming from the "Search" button
|
||||||
*/
|
*/
|
||||||
do_search: function (e) {
|
do_search: function (e) {
|
||||||
|
if (this.headless && !this.has_defaults) {
|
||||||
|
return this.on_search([], [], []);
|
||||||
|
}
|
||||||
// reset filters management
|
// reset filters management
|
||||||
var select = this.$element.find(".oe_search-view-filters-management");
|
var select = this.$element.find(".oe_search-view-filters-management");
|
||||||
select.val("_filters");
|
select.val("_filters");
|
||||||
|
|
||||||
if (e && e.preventDefault) { e.preventDefault(); }
|
if (e && e.preventDefault) { e.preventDefault(); }
|
||||||
|
|
||||||
var data = this.build_search_data();
|
var data = this.build_search_data();
|
||||||
|
@ -324,10 +336,10 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
|
||||||
* @param {Array} errors a never-empty array of error objects
|
* @param {Array} errors a never-empty array of error objects
|
||||||
*/
|
*/
|
||||||
on_invalid: function (errors) {
|
on_invalid: function (errors) {
|
||||||
this.notification.notify("Invalid Search", "triggered from search view");
|
this.do_notify("Invalid Search", "triggered from search view");
|
||||||
},
|
},
|
||||||
do_clear: function () {
|
do_clear: function () {
|
||||||
this.$element.find('.filter_label').removeClass('enabled');
|
this.$element.find('.filter_label, .filter_icon').removeClass('enabled');
|
||||||
this.enabled_filters.splice(0);
|
this.enabled_filters.splice(0);
|
||||||
var string = $('a.searchview_group_string');
|
var string = $('a.searchview_group_string');
|
||||||
_.each(string, function(str){
|
_.each(string, function(str){
|
||||||
|
@ -631,6 +643,12 @@ openerp.web.search.Field = openerp.web.search.Input.extend( /** @lends openerp.w
|
||||||
this.attrs = _.extend({}, field, view_section.attrs);
|
this.attrs = _.extend({}, field, view_section.attrs);
|
||||||
this.filters = new openerp.web.search.FilterGroup(_.map(
|
this.filters = new openerp.web.search.FilterGroup(_.map(
|
||||||
view_section.children, function (filter_node) {
|
view_section.children, function (filter_node) {
|
||||||
|
if (filter_node.attrs.string &&
|
||||||
|
typeof console !== 'undefined' && console.debug) {
|
||||||
|
console.debug("Filter-in-field with a 'string' attribute "
|
||||||
|
+ "in view", view);
|
||||||
|
}
|
||||||
|
delete filter_node.attrs.string;
|
||||||
return new openerp.web.search.Filter(
|
return new openerp.web.search.Filter(
|
||||||
filter_node, view);
|
filter_node, view);
|
||||||
}), view);
|
}), view);
|
||||||
|
@ -748,9 +766,44 @@ openerp.web.search.FloatField = openerp.web.search.NumberField.extend(/** @lends
|
||||||
* @extends openerp.web.search.Field
|
* @extends openerp.web.search.Field
|
||||||
*/
|
*/
|
||||||
openerp.web.search.SelectionField = openerp.web.search.Field.extend(/** @lends openerp.web.search.SelectionField# */{
|
openerp.web.search.SelectionField = openerp.web.search.Field.extend(/** @lends openerp.web.search.SelectionField# */{
|
||||||
|
// This implementation is a basic <select> field, but it may have to be
|
||||||
|
// altered to be more in line with the GTK client, which uses a combo box
|
||||||
|
// (~ jquery.autocomplete):
|
||||||
|
// * If an option was selected in the list, behave as currently
|
||||||
|
// * If something which is not in the list was entered (via the text input),
|
||||||
|
// the default domain should become (`ilike` string_value) but **any
|
||||||
|
// ``context`` or ``filter_domain`` becomes falsy, idem if ``@operator``
|
||||||
|
// is specified. So at least get_domain needs to be quite a bit
|
||||||
|
// overridden (if there's no @value and there is no filter_domain and
|
||||||
|
// there is no @operator, return [[name, 'ilike', str_val]]
|
||||||
template: 'SearchView.field.selection',
|
template: 'SearchView.field.selection',
|
||||||
|
init: function () {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
// prepend empty option if there is no empty option in the selection list
|
||||||
|
this.prepend_empty = !_(this.attrs.selection).detect(function (item) {
|
||||||
|
return !item[1];
|
||||||
|
});
|
||||||
|
},
|
||||||
get_value: function () {
|
get_value: function () {
|
||||||
return this.$element.val();
|
var index = parseInt(this.$element.val(), 10);
|
||||||
|
if (isNaN(index)) { return null; }
|
||||||
|
var value = this.attrs.selection[index][0];
|
||||||
|
if (value === false) { return null; }
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* The selection field needs a default ``false`` value in case none is
|
||||||
|
* provided, so that selector options with a ``false`` value (convention
|
||||||
|
* for explicitly empty options) get selected by default rather than the
|
||||||
|
* first (value-holding) option in the selection.
|
||||||
|
*
|
||||||
|
* @param {Object} defaults search default values
|
||||||
|
*/
|
||||||
|
render: function (defaults) {
|
||||||
|
if (!defaults[this.attrs.name]) {
|
||||||
|
defaults[this.attrs.name] = false;
|
||||||
|
}
|
||||||
|
return this._super(defaults);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
openerp.web.search.BooleanField = openerp.web.search.SelectionField.extend(/** @lends openerp.web.search.BooleanField# */{
|
openerp.web.search.BooleanField = openerp.web.search.SelectionField.extend(/** @lends openerp.web.search.BooleanField# */{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
openerp.web.list = function (openerp) {
|
openerp.web.list = function (openerp) {
|
||||||
|
var _t = openerp.web._t;
|
||||||
var QWeb = openerp.web.qweb;
|
var QWeb = openerp.web.qweb;
|
||||||
openerp.web.views.add('list', 'openerp.web.ListView');
|
openerp.web.views.add('list', 'openerp.web.ListView');
|
||||||
openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView# */ {
|
openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView# */ {
|
||||||
|
@ -10,7 +11,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
// whether the column headers should be displayed
|
// whether the column headers should be displayed
|
||||||
'header': true,
|
'header': true,
|
||||||
// display addition button, with that label
|
// display addition button, with that label
|
||||||
'addable': "New",
|
'addable': _t("New"),
|
||||||
// whether the list view can be sorted, note that once a view has been
|
// whether the list view can be sorted, note that once a view has been
|
||||||
// sorted it can not be reordered anymore
|
// sorted it can not be reordered anymore
|
||||||
'sortable': true,
|
'sortable': true,
|
||||||
|
@ -49,6 +50,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
this.model = dataset.model;
|
this.model = dataset.model;
|
||||||
this.view_id = view_id;
|
this.view_id = view_id;
|
||||||
this.previous_colspan = null;
|
this.previous_colspan = null;
|
||||||
|
this.colors = null;
|
||||||
|
|
||||||
this.columns = [];
|
this.columns = [];
|
||||||
|
|
||||||
|
@ -75,6 +77,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
}
|
}
|
||||||
self.compute_aggregates();
|
self.compute_aggregates();
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Retrieves the view's number of records per page (|| section)
|
* Retrieves the view's number of records per page (|| section)
|
||||||
|
@ -131,6 +134,31 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
this.$element.addClass('oe-listview');
|
this.$element.addClass('oe-listview');
|
||||||
return this.reload_view(null, null, true);
|
return this.reload_view(null, null, true);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Returns the color for the provided record in the current view (from the
|
||||||
|
* ``@colors`` attribute)
|
||||||
|
*
|
||||||
|
* @param {Record} record record for the current row
|
||||||
|
* @returns {String} CSS color declaration
|
||||||
|
*/
|
||||||
|
color_for: function (record) {
|
||||||
|
if (!this.colors) { return ''; }
|
||||||
|
var context = _.extend({}, record.attributes, {
|
||||||
|
uid: this.session.uid,
|
||||||
|
current_date: new Date().toString('yyyy-MM-dd')
|
||||||
|
// TODO: time, datetime, relativedelta
|
||||||
|
});
|
||||||
|
for(var i=0, len=this.colors.length; i<len; ++i) {
|
||||||
|
var pair = this.colors[i],
|
||||||
|
color = pair[0],
|
||||||
|
expression = pair[1];
|
||||||
|
if (py.evaluate(expression, context)) {
|
||||||
|
return 'color: ' + color + ';';
|
||||||
|
}
|
||||||
|
// TODO: handle evaluation errors
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Called after loading the list view's description, sets up such things
|
* Called after loading the list view's description, sets up such things
|
||||||
* as the view table's columns, renders the table itself and hooks up the
|
* as the view table's columns, renders the table itself and hooks up the
|
||||||
|
@ -159,6 +187,17 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
this.fields_view = data;
|
this.fields_view = data;
|
||||||
this.name = "" + this.fields_view.arch.attrs.string;
|
this.name = "" + this.fields_view.arch.attrs.string;
|
||||||
|
|
||||||
|
if (this.fields_view.arch.attrs.colors) {
|
||||||
|
this.colors = _(this.fields_view.arch.attrs.colors.split(';')).chain()
|
||||||
|
.compact()
|
||||||
|
.map(function(color_pair) {
|
||||||
|
var pair = color_pair.split(':'),
|
||||||
|
color = pair[0],
|
||||||
|
expr = pair[1];
|
||||||
|
return [color, py.parse(py.tokenize(expr)), expr];
|
||||||
|
}).value();
|
||||||
|
}
|
||||||
|
|
||||||
this.setup_columns(this.fields_view.fields, grouped);
|
this.setup_columns(this.fields_view.fields, grouped);
|
||||||
|
|
||||||
this.$element.html(QWeb.render("ListView", this));
|
this.$element.html(QWeb.render("ListView", this));
|
||||||
|
@ -214,7 +253,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
'<option value="100">100</option>' +
|
'<option value="100">100</option>' +
|
||||||
'<option value="200">200</option>' +
|
'<option value="200">200</option>' +
|
||||||
'<option value="500">500</option>' +
|
'<option value="500">500</option>' +
|
||||||
'<option value="NaN">Unlimited</option>')
|
'<option value="NaN">' + _t("Unlimited") + '</option>')
|
||||||
.change(function () {
|
.change(function () {
|
||||||
var val = parseInt($select.val(), 10);
|
var val = parseInt($select.val(), 10);
|
||||||
self._limit = (isNaN(val) ? null : val);
|
self._limit = (isNaN(val) ? null : val);
|
||||||
|
@ -353,9 +392,6 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
if (this.sidebar) {
|
if (this.sidebar) {
|
||||||
this.sidebar.$element.show();
|
this.sidebar.$element.show();
|
||||||
}
|
}
|
||||||
if (!_(this.dataset.ids).isEmpty()) {
|
|
||||||
this.reload_content();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
do_hide: function () {
|
do_hide: function () {
|
||||||
this.$element.hide();
|
this.$element.hide();
|
||||||
|
@ -404,41 +440,22 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
self.compute_aggregates();
|
self.compute_aggregates();
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
* Event handler for a search, asks for the computation/folding of domains
|
|
||||||
* and contexts (and group-by), then reloads the view's content.
|
|
||||||
*
|
|
||||||
* @param {Array} domains a sequence of literal and non-literal domains
|
|
||||||
* @param {Array} contexts a sequence of literal and non-literal contexts
|
|
||||||
* @param {Array} groupbys a sequence of literal and non-literal group-by contexts
|
|
||||||
* @returns {$.Deferred} fold request evaluation promise
|
|
||||||
*/
|
|
||||||
do_search: function (domains, contexts, groupbys) {
|
|
||||||
return this.rpc('/web/session/eval_domain_and_context', {
|
|
||||||
domains: _([this.dataset.get_domain()].concat(domains)).compact(),
|
|
||||||
contexts: _([this.dataset.get_context()].concat(contexts)).compact(),
|
|
||||||
group_by_seq: groupbys
|
|
||||||
}, $.proxy(this, 'do_actual_search'));
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* Handler for the result of eval_domain_and_context, actually perform the
|
* Handler for the result of eval_domain_and_context, actually perform the
|
||||||
* searching
|
* searching
|
||||||
*
|
*
|
||||||
* @param {Object} results results of evaluating domain and process for a search
|
* @param {Object} results results of evaluating domain and process for a search
|
||||||
*/
|
*/
|
||||||
do_actual_search: function (results) {
|
do_search: function (domain, context, group_by) {
|
||||||
this.groups.datagroup = new openerp.web.DataGroup(
|
this.groups.datagroup = new openerp.web.DataGroup(
|
||||||
this, this.model,
|
this, this.model, domain, context, group_by);
|
||||||
results.domain,
|
|
||||||
results.context,
|
|
||||||
results.group_by);
|
|
||||||
this.groups.datagroup.sort = this.dataset._sort;
|
this.groups.datagroup.sort = this.dataset._sort;
|
||||||
|
|
||||||
if (_.isEmpty(results.group_by) && !results.context['group_by_no_leaf']) {
|
if (_.isEmpty(group_by) && !context['group_by_no_leaf']) {
|
||||||
results.group_by = null;
|
group_by = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.reload_view(!!results.group_by, results.context).then(
|
this.reload_view(!!group_by, context).then(
|
||||||
$.proxy(this, 'reload_content'));
|
$.proxy(this, 'reload_content'));
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
@ -447,7 +464,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
* @param {Array} ids the ids of the records to delete
|
* @param {Array} ids the ids of the records to delete
|
||||||
*/
|
*/
|
||||||
do_delete: function (ids) {
|
do_delete: function (ids) {
|
||||||
if (!ids.length) {
|
if (!(ids.length && confirm(_t("Are you sure to remove those records ?")))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -455,6 +472,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
_(ids).each(function (id) {
|
_(ids).each(function (id) {
|
||||||
self.records.remove(self.records.get(id));
|
self.records.remove(self.records.get(id));
|
||||||
});
|
});
|
||||||
|
self.configure_pager(self.dataset);
|
||||||
self.compute_aggregates();
|
self.compute_aggregates();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -467,7 +485,13 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
do_select: function (ids, records) {
|
do_select: function (ids, records) {
|
||||||
this.$element.find('.oe-list-delete')
|
this.$element.find('.oe-list-delete')
|
||||||
.attr('disabled', !ids.length);
|
.attr('disabled', !ids.length);
|
||||||
|
if (this.sidebar) {
|
||||||
|
if (ids.length) {
|
||||||
|
this.sidebar.do_unfold();
|
||||||
|
} else {
|
||||||
|
this.sidebar.do_fold();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!records.length) {
|
if (!records.length) {
|
||||||
this.compute_aggregates();
|
this.compute_aggregates();
|
||||||
return;
|
return;
|
||||||
|
@ -498,14 +522,8 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
* @param {openerp.web.DataSet} dataset dataset in which the record is available (may not be the listview's dataset in case of nested groups)
|
* @param {openerp.web.DataSet} dataset dataset in which the record is available (may not be the listview's dataset in case of nested groups)
|
||||||
*/
|
*/
|
||||||
do_activate_record: function (index, id, dataset) {
|
do_activate_record: function (index, id, dataset) {
|
||||||
var self = this;
|
this.dataset.ids = dataset.ids;
|
||||||
// TODO is it needed ?
|
this.select_record(index);
|
||||||
this.dataset.read_slice([],{
|
|
||||||
context: dataset.get_context(),
|
|
||||||
domain: dataset.get_domain()
|
|
||||||
}, function () {
|
|
||||||
self.select_record(index);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Handles signal for the addition of a new record (can be a creation,
|
* Handles signal for the addition of a new record (can be a creation,
|
||||||
|
@ -604,7 +622,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||||
}
|
}
|
||||||
|
|
||||||
$footer_cells.filter(_.sprintf('[data-field=%s]', column.id))
|
$footer_cells.filter(_.sprintf('[data-field=%s]', column.id))
|
||||||
.html(openerp.web.format_cell(aggregation, column));
|
.html(openerp.web.format_cell(aggregation, column, undefined, false));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
get_selected_ids: function() {
|
get_selected_ids: function() {
|
||||||
|
@ -750,24 +768,71 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
|
||||||
$row = $target.closest('tr'),
|
$row = $target.closest('tr'),
|
||||||
record_id = self.row_id($row);
|
record_id = self.row_id($row);
|
||||||
|
|
||||||
$(self).trigger('action', [field, record_id, function () {
|
// note: $.data converts data to number if it's composed only
|
||||||
|
// of digits, nice when storing actual numbers, not nice when
|
||||||
|
// storing strings composed only of digits. Force the action
|
||||||
|
// name to be a string
|
||||||
|
$(self).trigger('action', [field.toString(), record_id, function () {
|
||||||
return self.reload_record(self.records.get(record_id));
|
return self.reload_record(self.records.get(record_id));
|
||||||
}]);
|
}]);
|
||||||
})
|
})
|
||||||
.delegate('tr', 'click', function (e) {
|
.delegate('tr', 'click', function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
self.dataset.index = self.records.indexOf(
|
var row_id = self.row_id(e.currentTarget);
|
||||||
self.records.get(
|
if (row_id !== undefined) {
|
||||||
self.row_id(e.currentTarget)));
|
if (!self.dataset.select_id(row_id)) {
|
||||||
self.row_clicked(e);
|
throw "Could not find id in dataset"
|
||||||
|
}
|
||||||
|
self.row_clicked(e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
row_clicked: function () {
|
row_clicked: function () {
|
||||||
$(this).trigger(
|
$(this).trigger(
|
||||||
'row_link',
|
'row_link',
|
||||||
[this.records.at(this.dataset.index).get('id'),
|
[this.dataset.ids[this.dataset.index],
|
||||||
this.dataset]);
|
this.dataset]);
|
||||||
},
|
},
|
||||||
|
render_cell: function (record, column) {
|
||||||
|
var value;
|
||||||
|
if(column.type === 'reference') {
|
||||||
|
value = record.get(column.id);
|
||||||
|
var ref_match;
|
||||||
|
// Ensure that value is in a reference "shape", otherwise we're
|
||||||
|
// going to loop on performing name_get after we've resolved (and
|
||||||
|
// set) a human-readable version. m2o does not have this issue
|
||||||
|
// because the non-human-readable is just a number, where the
|
||||||
|
// human-readable version is a pair
|
||||||
|
if (value && (ref_match = /([\w\.]+),(\d+)/.exec(value))) {
|
||||||
|
// reference values are in the shape "$model,$id" (as a
|
||||||
|
// string), we need to split and name_get this pair in order
|
||||||
|
// to get a correctly displayable value in the field
|
||||||
|
var model = ref_match[1],
|
||||||
|
id = parseInt(ref_match[2], 10);
|
||||||
|
new openerp.web.DataSet(this.view, model).name_get([id], function(names) {
|
||||||
|
if (!names.length) { return; }
|
||||||
|
record.set(column.id, names[0][1]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (column.type === 'many2one') {
|
||||||
|
value = record.get(column.id);
|
||||||
|
// m2o values are usually name_get formatted, [Number, String]
|
||||||
|
// pairs, but in some cases only the id is provided. In these
|
||||||
|
// cases, we need to perform a name_get call to fetch the actual
|
||||||
|
// displayable value
|
||||||
|
if (typeof value === 'number' || value instanceof Number) {
|
||||||
|
// fetch the name, set it on the record (in the right field)
|
||||||
|
// and let the various registered events handle refreshing the
|
||||||
|
// row
|
||||||
|
new openerp.web.DataSet(this.view, column.relation)
|
||||||
|
.name_get([value], function (names) {
|
||||||
|
if (!names.length) { return; }
|
||||||
|
record.set(column.id, names[0]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return openerp.web.format_cell(record.toForm().data, column);
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
if (this.$current) {
|
if (this.$current) {
|
||||||
this.$current.remove();
|
this.$current.remove();
|
||||||
|
@ -775,7 +840,7 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
|
||||||
this.$current = this.$_element.clone(true);
|
this.$current = this.$_element.clone(true);
|
||||||
this.$current.empty().append(
|
this.$current.empty().append(
|
||||||
QWeb.render('ListView.rows', _.extend({
|
QWeb.render('ListView.rows', _.extend({
|
||||||
render_cell: openerp.web.format_cell}, this)));
|
render_cell: $.proxy(this, 'render_cell')}, this)));
|
||||||
this.pad_table_to(5);
|
this.pad_table_to(5);
|
||||||
},
|
},
|
||||||
pad_table_to: function (count) {
|
pad_table_to: function (count) {
|
||||||
|
@ -799,7 +864,9 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
|
||||||
cells.push('</tr>');
|
cells.push('</tr>');
|
||||||
|
|
||||||
var row = cells.join('');
|
var row = cells.join('');
|
||||||
this.$current.append(new Array(count - this.records.length + 1).join(row));
|
this.$current
|
||||||
|
.children('tr:not([data-id])').remove().end()
|
||||||
|
.append(new Array(count - this.records.length + 1).join(row));
|
||||||
this.refresh_zebra(this.records.length);
|
this.refresh_zebra(this.records.length);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
@ -880,7 +947,8 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
|
||||||
options: this.options,
|
options: this.options,
|
||||||
record: record,
|
record: record,
|
||||||
row_parity: (index % 2 === 0) ? 'even' : 'odd',
|
row_parity: (index % 2 === 0) ? 'even' : 'odd',
|
||||||
render_cell: openerp.web.format_cell
|
view: this.view,
|
||||||
|
render_cell: $.proxy(this, 'render_cell')
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
@ -1055,7 +1123,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
|
||||||
var group_column = _(self.columns).detect(function (column) {
|
var group_column = _(self.columns).detect(function (column) {
|
||||||
return column.id === group.grouped_on; });
|
return column.id === group.grouped_on; });
|
||||||
$group_column.html(openerp.web.format_cell(
|
$group_column.html(openerp.web.format_cell(
|
||||||
row_data, group_column, "Undefined"
|
row_data, group_column, _t("Undefined")
|
||||||
));
|
));
|
||||||
if (group.openable) {
|
if (group.openable) {
|
||||||
// Make openable if not terminal group & group_by_no_leaf
|
// Make openable if not terminal group & group_by_no_leaf
|
||||||
|
@ -1131,7 +1199,8 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
|
||||||
|
|
||||||
var fields = _.pluck(_.select(this.columns, function(x) {return x.tag == "field"}), 'name');
|
var fields = _.pluck(_.select(this.columns, function(x) {return x.tag == "field"}), 'name');
|
||||||
var options = { offset: page * limit, limit: limit };
|
var options = { offset: page * limit, limit: limit };
|
||||||
dataset.read_slice(fields, options , function (records) {
|
//TODO xmo: investigate why we need to put the setTimeout
|
||||||
|
setTimeout(function() {dataset.read_slice(fields, options , function (records) {
|
||||||
if (!self.datagroup.openable) {
|
if (!self.datagroup.openable) {
|
||||||
view.configure_pager(dataset);
|
view.configure_pager(dataset);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1150,7 +1219,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
|
||||||
self.records.add(records, {silent: true});
|
self.records.add(records, {silent: true});
|
||||||
list.render();
|
list.render();
|
||||||
d.resolve(list);
|
d.resolve(list);
|
||||||
});
|
});}, 0);
|
||||||
return d.promise();
|
return d.promise();
|
||||||
},
|
},
|
||||||
setup_resequence_rows: function (list, dataset) {
|
setup_resequence_rows: function (list, dataset) {
|
||||||
|
@ -1355,10 +1424,10 @@ var Record = openerp.web.Class.extend(/** @lends Record# */{
|
||||||
* @returns {Object} record displayable in a form view
|
* @returns {Object} record displayable in a form view
|
||||||
*/
|
*/
|
||||||
toForm: function () {
|
toForm: function () {
|
||||||
var form_data = {};
|
var form_data = {}, attrs = this.attributes;
|
||||||
_(this.attributes).each(function (value, key) {
|
for(var k in attrs) {
|
||||||
form_data[key] = {value: value};
|
form_data[k] = {value: attrs[k]};
|
||||||
});
|
}
|
||||||
|
|
||||||
return {data: form_data};
|
return {data: form_data};
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ openerp.web.list_editable = function (openerp) {
|
||||||
if (self.groups.get_selection().length) {
|
if (self.groups.get_selection().length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
self.configure_pager(self.dataset);
|
||||||
self.compute_aggregates();
|
self.compute_aggregates();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -56,11 +57,11 @@ openerp.web.list_editable = function (openerp) {
|
||||||
|| this.defaults.editable);
|
|| this.defaults.editable);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Replace do_actual_search to handle editability process
|
* Replace do_search to handle editability process
|
||||||
*/
|
*/
|
||||||
do_actual_search: function (results) {
|
do_search: function(domain, context, group_by) {
|
||||||
this.set_editable(results.context['set_editable']);
|
this.set_editable(context['set_editable']);
|
||||||
this._super(results);
|
this._super.apply(this, arguments);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Replace do_add_record to handle editability (and adding new record
|
* Replace do_add_record to handle editability (and adding new record
|
||||||
|
@ -120,6 +121,7 @@ openerp.web.list_editable = function (openerp) {
|
||||||
delete self.edition_id;
|
delete self.edition_id;
|
||||||
delete self.edition;
|
delete self.edition;
|
||||||
});
|
});
|
||||||
|
this.pad_table_to(5);
|
||||||
return cancelled.promise();
|
return cancelled.promise();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
@ -147,7 +149,7 @@ openerp.web.list_editable = function (openerp) {
|
||||||
var $new_row = $('<tr>', {
|
var $new_row = $('<tr>', {
|
||||||
id: _.uniqueId('oe-editable-row-'),
|
id: _.uniqueId('oe-editable-row-'),
|
||||||
'data-id': record_id,
|
'data-id': record_id,
|
||||||
'class': $(row).attr('class') + ' oe_forms',
|
'class': row ? $(row).attr('class') : '' + ' oe_forms',
|
||||||
click: function (e) {e.stopPropagation();}
|
click: function (e) {e.stopPropagation();}
|
||||||
})
|
})
|
||||||
.delegate('button.oe-edit-row-save', 'click', function () {
|
.delegate('button.oe-edit-row-save', 'click', function () {
|
||||||
|
@ -173,14 +175,26 @@ openerp.web.list_editable = function (openerp) {
|
||||||
});
|
});
|
||||||
if (row) {
|
if (row) {
|
||||||
$new_row.replaceAll(row);
|
$new_row.replaceAll(row);
|
||||||
} else if (self.options.editable === 'top') {
|
|
||||||
self.$current.prepend($new_row);
|
|
||||||
} else if (self.options.editable) {
|
} else if (self.options.editable) {
|
||||||
self.$current.append($new_row);
|
var $last_child = self.$current.children('tr:last');
|
||||||
|
if (self.records.length) {
|
||||||
|
if (self.options.editable === 'top') {
|
||||||
|
$new_row.insertBefore(
|
||||||
|
self.$current.children('[data-id]:first'));
|
||||||
|
} else {
|
||||||
|
$new_row.insertAfter(
|
||||||
|
self.$current.children('[data-id]:last'));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$new_row.prependTo(self.$current);
|
||||||
|
}
|
||||||
|
if ($last_child.is(':not([data-id])')) {
|
||||||
|
$last_child.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.edition = true;
|
self.edition = true;
|
||||||
self.edition_id = record_id;
|
self.edition_id = record_id;
|
||||||
self.edition_form = _.extend(new openerp.web.ListEditableFormView(self, self.dataset, false), {
|
self.edition_form = _.extend(new openerp.web.ListEditableFormView(self.view, self.dataset, false), {
|
||||||
form_template: 'ListView.row.form',
|
form_template: 'ListView.row.form',
|
||||||
registry: openerp.web.list.form.widgets,
|
registry: openerp.web.list.form.widgets,
|
||||||
$element: $new_row
|
$element: $new_row
|
||||||
|
@ -325,11 +339,13 @@ openerp.web.list_editable = function (openerp) {
|
||||||
this.$element.children().css('visibility', '');
|
this.$element.children().css('visibility', '');
|
||||||
if (this.modifiers.tree_invisible) {
|
if (this.modifiers.tree_invisible) {
|
||||||
var old_invisible = this.invisible;
|
var old_invisible = this.invisible;
|
||||||
this.invisible = !!this.modifiers.tree_invisible;
|
this.invisible = true;
|
||||||
this._super();
|
this._super();
|
||||||
this.invisible = old_invisible;
|
this.invisible = old_invisible;
|
||||||
} else if (this.invisible) {
|
} else if (this.invisible) {
|
||||||
this.$element.children().css('visibility', 'hidden');
|
this.$element.children().css('visibility', 'hidden');
|
||||||
|
} else {
|
||||||
|
this._super();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,6 +32,8 @@ openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView#
|
||||||
this.records = {};
|
this.records = {};
|
||||||
|
|
||||||
this.options = _.extend({}, this.defaults, options || {});
|
this.options = _.extend({}, this.defaults, options || {});
|
||||||
|
|
||||||
|
_.bindAll(this, 'color_for');
|
||||||
},
|
},
|
||||||
|
|
||||||
start: function () {
|
start: function () {
|
||||||
|
@ -107,6 +109,43 @@ openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView#
|
||||||
$select.change();
|
$select.change();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!this.fields_view.arch.attrs.colors) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.colors = _(this.fields_view.arch.attrs.colors.split(';')).chain()
|
||||||
|
.compact()
|
||||||
|
.map(function(color_pair) {
|
||||||
|
var pair = color_pair.split(':'),
|
||||||
|
color = pair[0],
|
||||||
|
expr = pair[1];
|
||||||
|
return [color, py.parse(py.tokenize(expr)), expr];
|
||||||
|
}).value();
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Returns the color for the provided record in the current view (from the
|
||||||
|
* ``@colors`` attribute)
|
||||||
|
*
|
||||||
|
* @param {Object} record record for the current row
|
||||||
|
* @returns {String} CSS color declaration
|
||||||
|
*/
|
||||||
|
color_for: function (record) {
|
||||||
|
if (!this.colors) { return ''; }
|
||||||
|
var context = _.extend({}, record, {
|
||||||
|
uid: this.session.uid,
|
||||||
|
current_date: new Date().toString('yyyy-MM-dd')
|
||||||
|
// TODO: time, datetime, relativedelta
|
||||||
|
});
|
||||||
|
for(var i=0, len=this.colors.length; i<len; ++i) {
|
||||||
|
var pair = this.colors[i],
|
||||||
|
color = pair[0],
|
||||||
|
expression = pair[1];
|
||||||
|
if (py.evaluate(expression, context)) {
|
||||||
|
return 'color: ' + color + ';';
|
||||||
|
}
|
||||||
|
// TODO: handle evaluation errors
|
||||||
|
}
|
||||||
|
return '';
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Sets up opening a row
|
* Sets up opening a row
|
||||||
|
@ -159,7 +198,8 @@ openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView#
|
||||||
'fields_view': self.fields_view.arch.children,
|
'fields_view': self.fields_view.arch.children,
|
||||||
'fields': self.fields,
|
'fields': self.fields,
|
||||||
'level': $curr_node.data('level') || 0,
|
'level': $curr_node.data('level') || 0,
|
||||||
'render': openerp.web.format_value
|
'render': openerp.web.format_value,
|
||||||
|
'color_for': self.color_for
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($curr_node.length) {
|
if ($curr_node.length) {
|
||||||
|
|
|
@ -68,9 +68,11 @@ db.web.ActionManager = db.web.Widget.extend({
|
||||||
},
|
},
|
||||||
on_url_hashchange: function(url) {
|
on_url_hashchange: function(url) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.rpc("/web/action/load", { action_id: url.action_id }, function(result) {
|
if(url && url.action_id) {
|
||||||
self.do_action(result.result);
|
self.rpc("/web/action/load", { action_id: url.action_id }, function(result) {
|
||||||
});
|
self.do_action(result.result);
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
do_action: function(action, on_close) {
|
do_action: function(action, on_close) {
|
||||||
var type = action.type.replace(/\./g,'_');
|
var type = action.type.replace(/\./g,'_');
|
||||||
|
@ -86,7 +88,7 @@ db.web.ActionManager = db.web.Widget.extend({
|
||||||
console.log("Action manager can't handle action of type " + action.type, action);
|
console.log("Action manager can't handle action of type " + action.type, action);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this[type](action, on_close);
|
return this[type](action, on_close);
|
||||||
},
|
},
|
||||||
ir_actions_act_window: function (action, on_close) {
|
ir_actions_act_window: function (action, on_close) {
|
||||||
if (action.target === 'new') {
|
if (action.target === 'new') {
|
||||||
|
@ -116,6 +118,15 @@ db.web.ActionManager = db.web.Widget.extend({
|
||||||
*/
|
*/
|
||||||
},
|
},
|
||||||
ir_actions_act_window_close: function (action, on_closed) {
|
ir_actions_act_window_close: function (action, on_closed) {
|
||||||
|
if (!this.dialog && on_closed) {
|
||||||
|
on_closed();
|
||||||
|
}
|
||||||
|
if (this.dialog && action.context) {
|
||||||
|
var model = action.context.active_model;
|
||||||
|
if (model === 'base.module.upgrade' || model === 'base.setup.installer' || model === 'base.module.upgrade') {
|
||||||
|
db.webclient.do_reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
this.dialog_stop();
|
this.dialog_stop();
|
||||||
},
|
},
|
||||||
ir_actions_server: function (action, on_closed) {
|
ir_actions_server: function (action, on_closed) {
|
||||||
|
@ -147,6 +158,9 @@ db.web.ActionManager = db.web.Widget.extend({
|
||||||
complete: $.unblockUI
|
complete: $.unblockUI
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
ir_actions_act_url: function (action) {
|
||||||
|
window.open(action.url, action.target === 'self' ? '_self' : '_blank');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -163,9 +177,10 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
|
||||||
*/
|
*/
|
||||||
init: function(parent, dataset, views) {
|
init: function(parent, dataset, views) {
|
||||||
this._super(parent);
|
this._super(parent);
|
||||||
this.model = dataset.model;
|
this.model = dataset ? dataset.model : undefined;
|
||||||
this.dataset = dataset;
|
this.dataset = dataset;
|
||||||
this.searchview = null;
|
this.searchview = null;
|
||||||
|
this.last_search = false;
|
||||||
this.active_view = null;
|
this.active_view = null;
|
||||||
this.views_src = _.map(views, function(x) {return x instanceof Array? {view_id: x[0], view_type: x[1]} : x;});
|
this.views_src = _.map(views, function(x) {return x instanceof Array? {view_id: x[0], view_type: x[1]} : x;});
|
||||||
this.views = {};
|
this.views = {};
|
||||||
|
@ -184,7 +199,6 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
|
||||||
start: function() {
|
start: function() {
|
||||||
this._super();
|
this._super();
|
||||||
var self = this;
|
var self = this;
|
||||||
this.dataset.start();
|
|
||||||
this.$element.find('.oe_vm_switch button').click(function() {
|
this.$element.find('.oe_vm_switch button').click(function() {
|
||||||
self.on_mode_switch($(this).data('view-type'));
|
self.on_mode_switch($(this).data('view-type'));
|
||||||
});
|
});
|
||||||
|
@ -225,35 +239,21 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
|
||||||
controller.set_embedded_view(view.embedded_view);
|
controller.set_embedded_view(view.embedded_view);
|
||||||
}
|
}
|
||||||
controller.do_switch_view.add_last(this.on_mode_switch);
|
controller.do_switch_view.add_last(this.on_mode_switch);
|
||||||
if (view_type === 'list' && this.flags.search_view === false && this.action && this.action['auto_search']) {
|
|
||||||
// In case the search view is not instantiated: manually call ListView#search
|
|
||||||
var domains = !_(self.action.domain).isEmpty()
|
|
||||||
? [self.action.domain] : [],
|
|
||||||
contexts = !_(self.action.context).isEmpty()
|
|
||||||
? [self.action.context] : [];
|
|
||||||
controller.on_loaded.add({
|
|
||||||
callback: function () {
|
|
||||||
controller.do_search(domains, contexts, []);
|
|
||||||
},
|
|
||||||
position: 'last',
|
|
||||||
unique: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
var container = $("#" + this.element_id + '_view_' + view_type);
|
var container = $("#" + this.element_id + '_view_' + view_type);
|
||||||
view_promise = controller.appendTo(container);
|
view_promise = controller.appendTo(container);
|
||||||
|
this.views[view_type].controller = controller;
|
||||||
$.when(view_promise).then(function() {
|
$.when(view_promise).then(function() {
|
||||||
self.on_controller_inited(view_type, controller);
|
self.on_controller_inited(view_type, controller);
|
||||||
|
if (self.searchview && view.controller.searchable !== false) {
|
||||||
|
self.do_searchview_search();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.views[view_type].controller = controller;
|
} else if (this.searchview && view.controller.searchable !== false) {
|
||||||
|
self.do_searchview_search();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (this.searchview) {
|
if (this.searchview) {
|
||||||
if (view.controller.searchable === false) {
|
this.searchview[(view.controller.searchable === false || this.searchview.hidden) ? 'hide' : 'show']();
|
||||||
this.searchview.hide();
|
|
||||||
} else {
|
|
||||||
this.searchview.show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$element
|
this.$element
|
||||||
|
@ -273,14 +273,6 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
|
||||||
}
|
}
|
||||||
return view_promise;
|
return view_promise;
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
* Event launched when a controller has been inited.
|
|
||||||
*
|
|
||||||
* @param {String} view_type type of view
|
|
||||||
* @param {String} view the inited controller
|
|
||||||
*/
|
|
||||||
on_controller_inited: function(view_type, view) {
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* Sets up the current viewmanager's search view.
|
* Sets up the current viewmanager's search view.
|
||||||
*
|
*
|
||||||
|
@ -294,14 +286,37 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
|
||||||
}
|
}
|
||||||
this.searchview = new db.web.SearchView(
|
this.searchview = new db.web.SearchView(
|
||||||
this, this.dataset,
|
this, this.dataset,
|
||||||
view_id, search_defaults);
|
view_id, search_defaults, this.flags.search_view === false);
|
||||||
|
|
||||||
this.searchview.on_search.add(function(domains, contexts, groupbys) {
|
this.searchview.on_search.add(this.do_searchview_search);
|
||||||
var controller = self.views[self.active_view].controller;
|
|
||||||
controller.do_search.call(controller, domains, contexts, groupbys);
|
|
||||||
});
|
|
||||||
return this.searchview.appendTo($("#" + this.element_id + "_search"));
|
return this.searchview.appendTo($("#" + this.element_id + "_search"));
|
||||||
},
|
},
|
||||||
|
do_searchview_search: function(domains, contexts, groupbys) {
|
||||||
|
var self = this,
|
||||||
|
controller = this.views[this.active_view].controller;
|
||||||
|
if (domains || contexts) {
|
||||||
|
this.rpc('/web/session/eval_domain_and_context', {
|
||||||
|
domains: [this.action.domain || []].concat(domains || []),
|
||||||
|
contexts: [this.action.context || {}].concat(contexts || []),
|
||||||
|
group_by_seq: groupbys || []
|
||||||
|
}, function (results) {
|
||||||
|
self.dataset.context = results.context;
|
||||||
|
self.dataset.domain = results.domain;
|
||||||
|
self.last_search = [results.domain, results.context, results.group_by];
|
||||||
|
controller.do_search(results.domain, results.context, results.group_by);
|
||||||
|
});
|
||||||
|
} else if (this.last_search) {
|
||||||
|
controller.do_search.apply(controller, this.last_search);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Event launched when a controller has been inited.
|
||||||
|
*
|
||||||
|
* @param {String} view_type type of view
|
||||||
|
* @param {String} view the inited controller
|
||||||
|
*/
|
||||||
|
on_controller_inited: function(view_type, view) {
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Called when one of the view want to execute an action
|
* Called when one of the view want to execute an action
|
||||||
*/
|
*/
|
||||||
|
@ -332,6 +347,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
|
||||||
// dataset initialization will take the session from ``this``, so if we
|
// dataset initialization will take the session from ``this``, so if we
|
||||||
// do not have it yet (and we don't, because we've not called our own
|
// do not have it yet (and we don't, because we've not called our own
|
||||||
// ``_super()``) rpc requests will blow up.
|
// ``_super()``) rpc requests will blow up.
|
||||||
|
this._super(parent, null, action.views);
|
||||||
this.session = parent.session;
|
this.session = parent.session;
|
||||||
this.action = action;
|
this.action = action;
|
||||||
var dataset = new db.web.DataSetSearch(this, action.res_model, action.context, action.domain);
|
var dataset = new db.web.DataSetSearch(this, action.res_model, action.context, action.domain);
|
||||||
|
@ -339,7 +355,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
|
||||||
dataset.ids.push(action.res_id);
|
dataset.ids.push(action.res_id);
|
||||||
dataset.index = 0;
|
dataset.index = 0;
|
||||||
}
|
}
|
||||||
this._super(parent, dataset, action.views);
|
this.dataset = dataset;
|
||||||
this.flags = this.action.flags || {};
|
this.flags = this.action.flags || {};
|
||||||
if (action.res_model == 'board.board' && action.views.length == 1 && action.views) {
|
if (action.res_model == 'board.board' && action.views.length == 1 && action.views) {
|
||||||
// Not elegant but allows to avoid form chrome (pager, save/new
|
// Not elegant but allows to avoid form chrome (pager, save/new
|
||||||
|
@ -360,28 +376,24 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
|
||||||
* launches an initial search after both views are done rendering.
|
* launches an initial search after both views are done rendering.
|
||||||
*/
|
*/
|
||||||
start: function() {
|
start: function() {
|
||||||
var self = this;
|
var self = this,
|
||||||
|
searchview_loaded,
|
||||||
|
search_defaults = {};
|
||||||
|
_.each(this.action.context, function (value, key) {
|
||||||
|
var match = /^search_default_(.*)$/.exec(key);
|
||||||
|
if (match) {
|
||||||
|
search_defaults[match[1]] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// init search view
|
||||||
|
var searchview_id = this.action['search_view_id'] && this.action['search_view_id'][0];
|
||||||
|
|
||||||
var searchview_loaded;
|
searchview_loaded = this.setup_search_view(searchview_id || false, search_defaults);
|
||||||
if (this.flags.search_view !== false) {
|
|
||||||
var search_defaults = {};
|
|
||||||
_.each(this.action.context, function (value, key) {
|
|
||||||
var match = /^search_default_(.*)$/.exec(key);
|
|
||||||
if (match) {
|
|
||||||
search_defaults[match[1]] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// init search view
|
|
||||||
var searchview_id = this.action['search_view_id'] && this.action['search_view_id'][0];
|
|
||||||
|
|
||||||
searchview_loaded = this.setup_search_view(
|
|
||||||
searchview_id || false, search_defaults);
|
|
||||||
}
|
|
||||||
|
|
||||||
var main_view_loaded = this._super();
|
var main_view_loaded = this._super();
|
||||||
|
|
||||||
var manager_ready = $.when(searchview_loaded, main_view_loaded);
|
var manager_ready = $.when(searchview_loaded, main_view_loaded);
|
||||||
if (searchview_loaded && this.action['auto_search']) {
|
if (searchview_loaded && this.action['auto_search'] !== false) {
|
||||||
// schedule auto_search
|
// schedule auto_search
|
||||||
manager_ready.then(this.searchview.do_search);
|
manager_ready.then(this.searchview.do_search);
|
||||||
}
|
}
|
||||||
|
@ -422,11 +434,16 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
|
||||||
on_mode_switch: function (view_type) {
|
on_mode_switch: function (view_type) {
|
||||||
var self = this;
|
var self = this;
|
||||||
return $.when(
|
return $.when(
|
||||||
this._super(view_type),
|
this._super(view_type),
|
||||||
this.shortcut_check(this.views[view_type])).then(function () {
|
this.shortcut_check(this.views[view_type])
|
||||||
var active_controller = self.views[self.active_view].controller;
|
).then(function() {
|
||||||
var view_id = active_controller.fields_view ? active_controller.fields_view.view_id : active_controller.view_id;
|
var controller = self.views[self.active_view].controller,
|
||||||
|
fvg = controller.fields_view,
|
||||||
|
view_id = (fvg && fvg.view_id) || '--';
|
||||||
self.$element.find('.oe_get_xml_view span').text(view_id);
|
self.$element.find('.oe_get_xml_view span').text(view_id);
|
||||||
|
if (!self.action.name && fvg) {
|
||||||
|
self.$element.find('.oe_view_title').text(fvg.arch.attrs.string || fvg.name);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
shortcut_check : function(view) {
|
shortcut_check : function(view) {
|
||||||
|
@ -471,7 +488,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
|
||||||
* Intercept do_action resolution from children views
|
* Intercept do_action resolution from children views
|
||||||
*/
|
*/
|
||||||
on_action_executed: function () {
|
on_action_executed: function () {
|
||||||
new db.web.DataSet(this, 'res.log')
|
return new db.web.DataSet(this, 'res.log')
|
||||||
.call('get', [], this.do_display_log);
|
.call('get', [], this.do_display_log);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
@ -512,9 +529,57 @@ db.web.Sidebar = db.web.Widget.extend({
|
||||||
self.do_toggle();
|
self.do_toggle();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
call_default_on_sidebar: function(item) {
|
||||||
|
var func_name = 'on_sidebar_' + _.underscored(item.label);
|
||||||
|
var fn = this.widget_parent[func_name];
|
||||||
|
if(typeof fn === 'function') {
|
||||||
|
fn(item);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
add_default_sections: function() {
|
||||||
|
this.add_section(_t('Customize'), 'customize');
|
||||||
|
this.add_items('customize', [
|
||||||
|
{
|
||||||
|
label: _t("Manage Views"),
|
||||||
|
callback: this.call_default_on_sidebar,
|
||||||
|
title: _t("Manage views of the current object"),
|
||||||
|
}, {
|
||||||
|
label: _t("Edit Workflow"),
|
||||||
|
callback: this.call_default_on_sidebar,
|
||||||
|
title: _t("Manage views of the current object"),
|
||||||
|
classname: 'oe_hide oe_sidebar_edit_workflow'
|
||||||
|
}, {
|
||||||
|
label: _t("Customize Object"),
|
||||||
|
callback: this.call_default_on_sidebar,
|
||||||
|
title: _t("Manage views of the current object"),
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
this.add_section(_t('Other Options'), 'other');
|
||||||
|
this.add_items('other', [
|
||||||
|
{
|
||||||
|
label: _t("Import"),
|
||||||
|
callback: this.call_default_on_sidebar,
|
||||||
|
}, {
|
||||||
|
label: _t("Export"),
|
||||||
|
callback: this.call_default_on_sidebar,
|
||||||
|
}, {
|
||||||
|
label: _t("Translate"),
|
||||||
|
callback: this.call_default_on_sidebar,
|
||||||
|
classname: 'oe_sidebar_translate oe_hide'
|
||||||
|
}, {
|
||||||
|
label: _t("View Log"),
|
||||||
|
callback: this.call_default_on_sidebar,
|
||||||
|
classname: 'oe_hide oe_sidebar_view_log'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
add_toolbar: function(toolbar) {
|
add_toolbar: function(toolbar) {
|
||||||
var self = this;
|
var self = this;
|
||||||
_.each([['print', "Reports"], ['action', "Actions"], ['relate', "Links"]], function(type) {
|
_.each([['print', _t("Reports")], ['action', _t("Actions")], ['relate', _t("Links")]], function(type) {
|
||||||
var items = toolbar[type[0]];
|
var items = toolbar[type[0]];
|
||||||
if (items.length) {
|
if (items.length) {
|
||||||
for (var i = 0; i < items.length; i++) {
|
for (var i = 0; i < items.length; i++) {
|
||||||
|
@ -524,15 +589,30 @@ db.web.Sidebar = db.web.Widget.extend({
|
||||||
classname: 'oe_sidebar_' + type[0]
|
classname: 'oe_sidebar_' + type[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.add_section(type[0], type[1], items);
|
self.add_section(type[1], type[0]);
|
||||||
|
self.add_items(type[0], items);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
add_section: function(code, name, items) {
|
|
||||||
// For each section, we pass a name/label and optionally an array of items.
|
add_section: function(name, code) {
|
||||||
// If no items are passed, then the section will be created as a custom section
|
if(!code) code = _.underscored(name);
|
||||||
// returning back an element_id to be used by a custom controller.
|
var $section = this.sections[code];
|
||||||
// Else, the section is a standard section with items displayed as links.
|
|
||||||
|
if(!$section) {
|
||||||
|
section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
|
||||||
|
var $section = $(db.web.qweb.render("Sidebar.section", {
|
||||||
|
section_id: section_id,
|
||||||
|
name: name,
|
||||||
|
classname: 'oe_sidebar_' + code,
|
||||||
|
}));
|
||||||
|
$section.appendTo(this.$element.find('div.sidebar-actions'));
|
||||||
|
this.sections[code] = $section;
|
||||||
|
}
|
||||||
|
return $section;
|
||||||
|
},
|
||||||
|
|
||||||
|
add_items: function(section_code, items) {
|
||||||
// An item is a dictonary : {
|
// An item is a dictonary : {
|
||||||
// label: label to be displayed for the link,
|
// label: label to be displayed for the link,
|
||||||
// action: action to be launch when the link is clicked,
|
// action: action to be launch when the link is clicked,
|
||||||
|
@ -541,25 +621,24 @@ db.web.Sidebar = db.web.Widget.extend({
|
||||||
// title: optional title for the link
|
// title: optional title for the link
|
||||||
// }
|
// }
|
||||||
// Note: The item should have one action or/and a callback
|
// Note: The item should have one action or/and a callback
|
||||||
|
//
|
||||||
|
|
||||||
var self = this,
|
var self = this,
|
||||||
section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
|
$section = this.add_section(_.titleize(section_code.replace('_', ' ')), section_code),
|
||||||
|
section_id = $section.attr('id');
|
||||||
|
|
||||||
if (items) {
|
if (items) {
|
||||||
for (var i = 0; i < items.length; i++) {
|
for (var i = 0; i < items.length; i++) {
|
||||||
items[i].element_id = _.uniqueId(section_id + '_item_');
|
items[i].element_id = _.uniqueId(section_id + '_item_');
|
||||||
this.items[items[i].element_id] = items[i];
|
this.items[items[i].element_id] = items[i];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
var $section = $(db.web.qweb.render("Sidebar.section", {
|
var $items = $(db.web.qweb.render("Sidebar.section.items", {items: items}));
|
||||||
section_id: section_id,
|
|
||||||
name: name,
|
$items.find('a.oe_sidebar_action_a').click(function() {
|
||||||
classname: 'oe_sidebar_' + code,
|
|
||||||
items: items
|
|
||||||
}));
|
|
||||||
if (items) {
|
|
||||||
$section.find('a.oe_sidebar_action_a').click(function() {
|
|
||||||
var item = self.items[$(this).attr('id')];
|
var item = self.items[$(this).attr('id')];
|
||||||
if (item.callback) {
|
if (item.callback) {
|
||||||
item.callback();
|
item.callback.apply(self, [item]);
|
||||||
}
|
}
|
||||||
if (item.action) {
|
if (item.action) {
|
||||||
var ids = self.widget_parent.get_selected_ids();
|
var ids = self.widget_parent.get_selected_ids();
|
||||||
|
@ -589,10 +668,13 @@ db.web.Sidebar = db.web.Widget.extend({
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var $ul = $section.find('ul');
|
||||||
|
if(!$ul.length) {
|
||||||
|
$ul = $('<ul/>').appendTo($section);
|
||||||
|
}
|
||||||
|
$items.appendTo($ul);
|
||||||
}
|
}
|
||||||
$section.appendTo(this.$element.find('div.sidebar-actions'));
|
|
||||||
this.sections[code] = $section;
|
|
||||||
return section_id;
|
|
||||||
},
|
},
|
||||||
do_fold: function() {
|
do_fold: function() {
|
||||||
this.$element.addClass('closed-sidebar').removeClass('open-sidebar');
|
this.$element.addClass('closed-sidebar').removeClass('open-sidebar');
|
||||||
|
@ -771,32 +853,45 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
|
||||||
var self = this;
|
var self = this;
|
||||||
var result_handler = function () {
|
var result_handler = function () {
|
||||||
if (on_closed) { on_closed.apply(null, arguments); }
|
if (on_closed) { on_closed.apply(null, arguments); }
|
||||||
self.widget_parent.on_action_executed.apply(null, arguments);
|
if (self.widget_parent && self.widget_parent.on_action_executed) {
|
||||||
|
return self.widget_parent.on_action_executed.apply(null, arguments);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
var context = new db.web.CompoundContext(dataset.get_context(), action_data.context || {});
|
||||||
|
|
||||||
var handler = function (r) {
|
var handler = function (r) {
|
||||||
var action = r.result;
|
var action = r.result;
|
||||||
if (action && action.constructor == Object) {
|
if (action && action.constructor == Object) {
|
||||||
action.context = action.context || {};
|
var ncontext = new db.web.CompoundContext(context);
|
||||||
_.extend(action.context, {
|
if (record_id) {
|
||||||
active_id: record_id || false,
|
ncontext.add({
|
||||||
active_ids: [record_id || false],
|
active_id: record_id,
|
||||||
active_model: dataset.model
|
active_ids: [record_id],
|
||||||
});
|
active_model: dataset.model
|
||||||
action.context = new db.web.CompoundContext(dataset.get_context(), action.context);
|
});
|
||||||
self.do_action(action, result_handler);
|
}
|
||||||
|
ncontext.add(action.context || {});
|
||||||
|
return self.rpc('/web/session/eval_domain_and_context', {
|
||||||
|
contexts: [ncontext],
|
||||||
|
domains: []
|
||||||
|
}).pipe(function (results) {
|
||||||
|
action.context = results.context;
|
||||||
|
/* niv: previously we were overriding once more with action_data.context,
|
||||||
|
* I assumed this was not a correct behavior and removed it
|
||||||
|
*/
|
||||||
|
return self.do_action(action, result_handler);
|
||||||
|
}, null);
|
||||||
} else {
|
} else {
|
||||||
result_handler();
|
return result_handler();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var context = new db.web.CompoundContext(dataset.get_context(), action_data.context || {});
|
|
||||||
|
|
||||||
if (action_data.special) {
|
if (action_data.special) {
|
||||||
handler({result: {"type":"ir.actions.act_window_close"}});
|
return handler({result: {"type":"ir.actions.act_window_close"}});
|
||||||
} else if (action_data.type=="object") {
|
} else if (action_data.type=="object") {
|
||||||
return dataset.call_button(action_data.name, [[record_id], context], handler);
|
return dataset.call_button(action_data.name, [[record_id], context], handler);
|
||||||
} else if (action_data.type=="action") {
|
} else if (action_data.type=="action") {
|
||||||
return this.rpc('/web/action/load', { action_id: parseInt(action_data.name, 10), context: context }, handler);
|
return this.rpc('/web/action/load', { action_id: parseInt(action_data.name, 10), context: context, do_not_eval: true}, handler);
|
||||||
} else {
|
} else {
|
||||||
return dataset.exec_workflow(record_id, action_data.name, handler);
|
return dataset.exec_workflow(record_id, action_data.name, handler);
|
||||||
}
|
}
|
||||||
|
@ -814,46 +909,17 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
|
||||||
},
|
},
|
||||||
do_switch_view: function(view) {
|
do_switch_view: function(view) {
|
||||||
},
|
},
|
||||||
set_common_sidebar_sections: function(sidebar) {
|
do_search: function(view) {
|
||||||
sidebar.add_section('customize', "Customize", [
|
|
||||||
{
|
|
||||||
label: "Manage Views",
|
|
||||||
callback: this.on_sidebar_manage_view,
|
|
||||||
title: "Manage views of the current object"
|
|
||||||
}, {
|
|
||||||
label: "Edit Workflow",
|
|
||||||
callback: this.on_sidebar_edit_workflow,
|
|
||||||
title: "Manage views of the current object",
|
|
||||||
classname: 'oe_hide oe_sidebar_edit_workflow'
|
|
||||||
}, {
|
|
||||||
label: "Customize Object",
|
|
||||||
callback: this.on_sidebar_customize_object,
|
|
||||||
title: "Manage views of the current object"
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
sidebar.add_section('other', "Other Options", [
|
|
||||||
{
|
|
||||||
label: "Import",
|
|
||||||
callback: this.on_sidebar_import
|
|
||||||
}, {
|
|
||||||
label: "Export",
|
|
||||||
callback: this.on_sidebar_export
|
|
||||||
}, {
|
|
||||||
label: "Translate",
|
|
||||||
callback: this.on_sidebar_translate,
|
|
||||||
classname: 'oe_sidebar_translate oe_hide'
|
|
||||||
}, {
|
|
||||||
label: "View Log",
|
|
||||||
callback: this.on_sidebar_view_log,
|
|
||||||
classname: 'oe_hide oe_sidebar_view_log'
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
},
|
},
|
||||||
on_sidebar_manage_view: function() {
|
|
||||||
|
set_common_sidebar_sections: function(sidebar) {
|
||||||
|
sidebar.add_default_sections();
|
||||||
|
},
|
||||||
|
on_sidebar_manage_views: function() {
|
||||||
if (this.fields_view && this.fields_view.arch) {
|
if (this.fields_view && this.fields_view.arch) {
|
||||||
$('<xmp>' + db.web.json_node_to_xml(this.fields_view.arch, true) + '</xmp>').dialog({ width: '95%', height: 600});
|
$('<xmp>' + db.web.json_node_to_xml(this.fields_view.arch, true) + '</xmp>').dialog({ width: '95%', height: 600});
|
||||||
} else {
|
} else {
|
||||||
this.notification.warn("Manage Views", "Could not find current view declaration");
|
this.do_warn("Manage Views", "Could not find current view declaration");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
on_sidebar_edit_workflow: function() {
|
on_sidebar_edit_workflow: function() {
|
||||||
|
@ -863,6 +929,8 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
|
||||||
console.log('Todo');
|
console.log('Todo');
|
||||||
},
|
},
|
||||||
on_sidebar_import: function() {
|
on_sidebar_import: function() {
|
||||||
|
var import_view = new db.web.DataImport(this, this.dataset);
|
||||||
|
import_view.start();
|
||||||
},
|
},
|
||||||
on_sidebar_export: function() {
|
on_sidebar_export: function() {
|
||||||
var export_view = new db.web.DataExport(this, this.dataset);
|
var export_view = new db.web.DataExport(this, this.dataset);
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
<!-- vim:fdl=1:
|
<!-- vim:fdl=1:
|
||||||
-->
|
-->
|
||||||
<templates id="template" xml:space="preserve">
|
<templates id="template" xml:space="preserve">
|
||||||
<t t-name="Interface">
|
<t t-name="Notification">
|
||||||
<div id="oe_loading" class="loading"></div>
|
<div class="oe_notification">
|
||||||
<div id="oe_notification" class="oe_notification">
|
|
||||||
<div id="oe_notification_default">
|
<div id="oe_notification_default">
|
||||||
<a class="ui-notify-cross ui-notify-close" href="#">x</a>
|
<a class="ui-notify-cross ui-notify-close" href="#">x</a>
|
||||||
<h1>#{title}</h1>
|
<h1>#{title}</h1>
|
||||||
|
@ -17,6 +16,9 @@
|
||||||
<p>#{text}</p>
|
<p>#{text}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</t>
|
||||||
|
<t t-name="Interface">
|
||||||
|
<div id="oe_loading" class="loading"></div>
|
||||||
<table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%" class="main_table">
|
<table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%" class="main_table">
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" valign="top">
|
<td colspan="2" valign="top">
|
||||||
|
@ -242,7 +244,23 @@
|
||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
</t>
|
</t>
|
||||||
|
|
||||||
|
<t t-name="Login_dblist">
|
||||||
|
<select name="db">
|
||||||
|
<t t-foreach="db_list" t-as="db">
|
||||||
|
<t t-if="selected_db === db">
|
||||||
|
<option t-att-value="db" selected="true">
|
||||||
|
<t t-esc="db"/></option>
|
||||||
|
</t>
|
||||||
|
<t t-if="selected_db !== db">
|
||||||
|
<option t-att-value="db"><t t-esc="db"/></option>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</select>
|
||||||
|
</t>
|
||||||
|
|
||||||
<t t-name="Login">
|
<t t-name="Login">
|
||||||
|
<div>
|
||||||
<form class="oe_forms">
|
<form class="oe_forms">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend style="">
|
<legend style="">
|
||||||
|
@ -253,33 +271,18 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td><label for="db">Database:</label></td>
|
<td><label for="db">Database:</label></td>
|
||||||
<td>
|
<td>
|
||||||
<t t-if="!db_list">
|
<input type="text" name="db" t-att-value="widget.selected_db || ''" autofocus="true"/>
|
||||||
<input type="text" name="db" t-att-value="selected_db || ''" autofocus="true"/>
|
|
||||||
</t>
|
|
||||||
<t t-if="db_list">
|
|
||||||
<select name="db">
|
|
||||||
<t t-foreach="db_list" t-as="db">
|
|
||||||
<t t-if="selected_db === db">
|
|
||||||
<option t-att-value="db" selected="true">
|
|
||||||
<t t-esc="db"/></option>
|
|
||||||
</t>
|
|
||||||
<t t-if="selected_db !== db">
|
|
||||||
<option t-att-value="db"><t t-esc="db"/></option>
|
|
||||||
</t>
|
|
||||||
</t>
|
|
||||||
</select>
|
|
||||||
</t>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><label for="login">User:</label></td>
|
<td><label for="login">User:</label></td>
|
||||||
<td><input type="text" name="login"
|
<td><input type="text" name="login"
|
||||||
t-att-value="selected_login || ''" autofocus="true"/></td>
|
t-att-value="widget.selected_login || ''" autofocus="true"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><label for="password">Password:</label></td>
|
<td><label for="password">Password:</label></td>
|
||||||
<td><input type="password" name="password"
|
<td><input type="password" name="password"
|
||||||
t-att-value="selected_password || ''"/></td>
|
t-att-value="widget.selected_password || ''"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td></td>
|
||||||
|
@ -330,6 +333,7 @@
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</t>
|
</t>
|
||||||
<t t-name="Header">
|
<t t-name="Header">
|
||||||
<div>
|
<div>
|
||||||
|
@ -445,11 +449,11 @@
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<a class="oe-shortcut-toggle" title="Add / Remove Shortcut..."
|
<a class="oe-shortcut-toggle" title="Add / Remove Shortcut..."
|
||||||
href="javascript: void(0)"> </a>
|
href="javascript: void(0)"> </a>
|
||||||
<h2 class="oe_view_title">
|
<button t-if="self.session.debug" class="oe_get_xml_view">
|
||||||
<t t-esc="self.action.name"/>
|
View#<span></span>
|
||||||
<button t-if="self.session.debug" class="oe_get_xml_view">
|
</button>
|
||||||
View#<span></span>
|
<h2 class="oe_view_title" t-if="self.flags.display_title !== false">
|
||||||
</button>
|
<t t-if="self.flags.display_title !== false" t-esc="self.action.name"/>
|
||||||
</h2>
|
</h2>
|
||||||
</t>
|
</t>
|
||||||
<t t-jquery=".oe-view-manager-header" t-operation="after">
|
<t t-jquery=".oe-view-manager-header" t-operation="after">
|
||||||
|
@ -465,17 +469,20 @@
|
||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
<t t-name="Sidebar.section">
|
<t t-name="Sidebar.section">
|
||||||
<h2><t t-esc="name"/></h2>
|
|
||||||
<div t-att-id="section_id" t-att-class="classname">
|
<div t-att-id="section_id" t-att-class="classname">
|
||||||
<ul t-if="items">
|
<h2><t t-esc="name"/></h2>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
|
||||||
|
|
||||||
|
<t t-name="Sidebar.section.items">
|
||||||
<li t-foreach="items" t-as="item" t-att-class="item.classname">
|
<li t-foreach="items" t-as="item" t-att-class="item.classname">
|
||||||
<a class="oe_sidebar_action_a" t-att-id="item.element_id" t-att-title="item.title" href="#">
|
<a class="oe_sidebar_action_a" t-att-id="item.element_id" t-att-title="item.title" href="#">
|
||||||
<t t-esc="item.label"/>
|
<t t-esc="item.label"/>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</t>
|
</t>
|
||||||
|
|
||||||
<t t-name="TranslateDialog">
|
<t t-name="TranslateDialog">
|
||||||
<ul class="oe_translate_tabs">
|
<ul class="oe_translate_tabs">
|
||||||
<li><a t-attf-href="##{widget.element_id}_fields">Fields</a></li>
|
<li><a t-attf-href="##{widget.element_id}_fields">Fields</a></li>
|
||||||
|
@ -537,7 +544,7 @@
|
||||||
<td t-foreach="fields_view" t-as="field"
|
<td t-foreach="fields_view" t-as="field"
|
||||||
t-if="!field.attrs.modifiers.tree_invisible"
|
t-if="!field.attrs.modifiers.tree_invisible"
|
||||||
t-att-data-id="record.id"
|
t-att-data-id="record.id"
|
||||||
t-att-style="!field_index ? 'background-position: ' + 19*level + 'px; padding-left: ' + 19*level + 'px' : undefined"
|
t-att-style="color_for(record) + (!field_index ? 'background-position: ' + 19*level + 'px; padding-left: ' + 19*level + 'px;' : '')"
|
||||||
t-att-class="!field_index and has_children ? 'treeview-tr' : 'treeview-td'">
|
t-att-class="!field_index and has_children ? 'treeview-tr' : 'treeview-td'">
|
||||||
<span t-if="!field.attrs.modifiers.invisible">
|
<span t-if="!field.attrs.modifiers.invisible">
|
||||||
<t t-esc="render(record[field.attrs.name], fields[field.attrs.name])" />
|
<t t-esc="render(record[field.attrs.name], fields[field.attrs.name])" />
|
||||||
|
@ -561,21 +568,7 @@
|
||||||
Delete
|
Delete
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
<th t-if="options.pager !== false" class="oe-list-pager">
|
<t t-call="Listview.navigation.button"/>
|
||||||
<button type="button" disabled="disabled"
|
|
||||||
data-pager-action="first">First</button>
|
|
||||||
<button type="button" disabled="disabled"
|
|
||||||
data-pager-action="previous"
|
|
||||||
><</button>
|
|
||||||
|
|
||||||
<span class="oe-pager-state">
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<button type="button" disabled="disabled"
|
|
||||||
data-pager-action="next">></button>
|
|
||||||
<button type="button" disabled="disabled"
|
|
||||||
data-pager-action="last">Last</button>
|
|
||||||
</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</th>
|
</th>
|
||||||
|
@ -605,8 +598,26 @@
|
||||||
</td>
|
</td>
|
||||||
<td t-if="options.deletable"/>
|
<td t-if="options.deletable"/>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<t t-call="Listview.navigation.button"/>
|
||||||
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
|
<th t-name="Listview.navigation.button" t-if="options.pager !== false"
|
||||||
|
class="oe-list-pager" t-att-colspan="columns_count">
|
||||||
|
<button type="button" disabled="disabled"
|
||||||
|
data-pager-action="first">First</button>
|
||||||
|
<button type="button" disabled="disabled"
|
||||||
|
data-pager-action="previous"><</button>
|
||||||
|
|
||||||
|
<span class="oe-pager-state">
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<button type="button" disabled="disabled"
|
||||||
|
data-pager-action="next">></button>
|
||||||
|
<button type="button" disabled="disabled"
|
||||||
|
data-pager-action="last">Last</button>
|
||||||
|
</th>
|
||||||
<t t-name="ListView.rows" t-foreach="records.length" t-as="index">
|
<t t-name="ListView.rows" t-foreach="records.length" t-as="index">
|
||||||
<t t-call="ListView.row">
|
<t t-call="ListView.row">
|
||||||
<t t-set="record" t-value="records.at(index)"/>
|
<t t-set="record" t-value="records.at(index)"/>
|
||||||
|
@ -614,7 +625,8 @@
|
||||||
</t>
|
</t>
|
||||||
</t>
|
</t>
|
||||||
<tr t-name="ListView.row" t-att-class="row_parity"
|
<tr t-name="ListView.row" t-att-class="row_parity"
|
||||||
t-att-data-id="record.get('id')">
|
t-att-data-id="record.get('id')"
|
||||||
|
t-att-style="view.color_for(record)">
|
||||||
<t t-foreach="columns" t-as="column">
|
<t t-foreach="columns" t-as="column">
|
||||||
<td t-if="column.meta">
|
<td t-if="column.meta">
|
||||||
|
|
||||||
|
@ -628,7 +640,7 @@
|
||||||
<td t-if="!column.meta and column.invisible !== '1'" t-att-title="column.help"
|
<td t-if="!column.meta and column.invisible !== '1'" t-att-title="column.help"
|
||||||
t-att-class="'oe-field-cell' + (align ? ' oe-number' : '')"
|
t-att-class="'oe-field-cell' + (align ? ' oe-number' : '')"
|
||||||
t-att-data-field="column.id">
|
t-att-data-field="column.id">
|
||||||
<t t-raw="render_cell(record.toForm().data, column)"/>
|
<t t-raw="render_cell(record, column)"/>
|
||||||
</td>
|
</td>
|
||||||
</t>
|
</t>
|
||||||
<td t-if="options.deletable" class='oe-record-delete' width="1">
|
<td t-if="options.deletable" class='oe-record-delete' width="1">
|
||||||
|
@ -639,19 +651,15 @@
|
||||||
<t t-raw="frame.render()"/>
|
<t t-raw="frame.render()"/>
|
||||||
</t>
|
</t>
|
||||||
<t t-name="FormView">
|
<t t-name="FormView">
|
||||||
<div class="oe_form_header" t-att-id="view.element_id + '_header'">
|
<div class="oe_form_header">
|
||||||
<div class="oe_form_buttons" t-if="view.options.action_buttons !== false">
|
<div class="oe_form_buttons" t-if="view.options.action_buttons !== false">
|
||||||
<!--<button type="button" class="oe_form_button_save">
|
<button type="button" class="oe_form_button_save">
|
||||||
<span class="oe_form_on_update">Save</span>
|
<span class="oe_form_on_update">Save</span>
|
||||||
<span class="oe_form_on_create">Create</span>
|
<span class="oe_form_on_create">Create</span>
|
||||||
</button>-->
|
|
||||||
<button type="button" class="oe_form_button_save_edit">
|
|
||||||
<span class="oe_form_on_update">Save & Edit</span>
|
|
||||||
<span class="oe_form_on_create">Create & Edit</span>
|
|
||||||
</button>
|
</button>
|
||||||
<!--<button type="button" class="oe_form_button_cancel">Cancel</button>-->
|
|
||||||
<button type="button" class="oe_form_button_new">New</button>
|
<button type="button" class="oe_form_button_new">New</button>
|
||||||
<button type="button" class="oe_form_button_duplicate oe_form_on_update">Duplicate</button>
|
<button type="button" class="oe_form_button_duplicate oe_form_on_update">Duplicate</button>
|
||||||
|
<button type="button" class="oe_form_button_toggle">Readonly/Editable</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_form_pager" t-if="view.options.pager !== false">
|
<div class="oe_form_pager" t-if="view.options.pager !== false">
|
||||||
<button type="button" data-pager-action="first">First</button>
|
<button type="button" data-pager-action="first">First</button>
|
||||||
|
@ -711,8 +719,7 @@
|
||||||
t-att-width="td.width"
|
t-att-width="td.width"
|
||||||
t-att-nowrap="td.nowrap or td.is_field_m2o? 'true' : undefined"
|
t-att-nowrap="td.nowrap or td.is_field_m2o? 'true' : undefined"
|
||||||
t-att-valign="td.table ? 'top' : undefined"
|
t-att-valign="td.table ? 'top' : undefined"
|
||||||
t-att-id="td.element_id"
|
t-attf-class="oe_form_frame_cell #{td.classname} #{td.element_class}"
|
||||||
t-attf-class="oe_form_frame_cell #{td.classname}"
|
|
||||||
>
|
>
|
||||||
<t t-raw="td.render()"/>
|
<t t-raw="td.render()"/>
|
||||||
</td>
|
</td>
|
||||||
|
@ -722,8 +729,8 @@
|
||||||
</t>
|
</t>
|
||||||
<t t-name="WidgetNotebook">
|
<t t-name="WidgetNotebook">
|
||||||
<ul>
|
<ul>
|
||||||
<li t-foreach="widget.pages" t-as="page" t-att-id="page.element_tab_id">
|
<li t-foreach="widget.pages" t-as="page">
|
||||||
<a t-att-href="'#' + page.element_id">
|
<a href="#">
|
||||||
<t t-esc="page.string"/>
|
<t t-esc="page.string"/>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -733,17 +740,23 @@
|
||||||
</t>
|
</t>
|
||||||
</t>
|
</t>
|
||||||
<t t-name="WidgetNotebookPage">
|
<t t-name="WidgetNotebookPage">
|
||||||
<div t-att-id="widget.element_id">
|
<div>
|
||||||
<t t-call="WidgetFrame"/>
|
<t t-call="WidgetFrame"/>
|
||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
|
<t t-name="WidgetNotebook.readonly">
|
||||||
|
<t t-foreach="widget.pages" t-as="page">
|
||||||
|
<h3><t t-esc="page.string"/></h3>
|
||||||
|
<t t-raw="page.render()"/>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
<t t-name="WidgetSeparator">
|
<t t-name="WidgetSeparator">
|
||||||
<div t-if="widget.orientation !== 'vertical'" t-att-class="'separator ' + widget.orientation">
|
<div t-if="widget.orientation !== 'vertical'" t-att-class="'separator ' + widget.orientation">
|
||||||
<t t-esc="widget.string"/>
|
<t t-esc="widget.string"/>
|
||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
<t t-name="WidgetLabel">
|
<t t-name="WidgetLabel">
|
||||||
<label t-att-for="widget.element_id + '_field'"
|
<label t-att-for="widget.element_id"
|
||||||
t-att-class="'oe_label' + (widget.help ? '_help' : '')"
|
t-att-class="'oe_label' + (widget.help ? '_help' : '')"
|
||||||
t-att-title="widget.help">
|
t-att-title="widget.help">
|
||||||
<t t-esc="widget.string"/>
|
<t t-esc="widget.string"/>
|
||||||
|
@ -757,12 +770,22 @@
|
||||||
<t t-name="FieldChar">
|
<t t-name="FieldChar">
|
||||||
<input type="text" size="1"
|
<input type="text" size="1"
|
||||||
t-att-name="widget.name"
|
t-att-name="widget.name"
|
||||||
t-att-id="widget.element_id + '_field'"
|
t-att-id="widget.element_id"
|
||||||
t-att-class="'field_' + widget.type"
|
t-attf-class="field_#{widget.type}"
|
||||||
t-attf-style="width: #{widget.field.translate ? '99' : '100'}%"
|
t-attf-style="width: #{widget.field.translate ? '99' : '100'}%"
|
||||||
/>
|
/>
|
||||||
<img class="oe_field_translate" t-if="widget.field.translate" src="/web/static/src/img/icons/terp-translate.png" width="16" height="16" border="0"/>
|
<img class="oe_field_translate" t-if="widget.field.translate" src="/web/static/src/img/icons/terp-translate.png" width="16" height="16" border="0"/>
|
||||||
</t>
|
</t>
|
||||||
|
<t t-name="FieldChar.readonly">
|
||||||
|
<div
|
||||||
|
t-att-id="widget.element_id"
|
||||||
|
t-attf-class="field_#{widget.type}"
|
||||||
|
t-attf-style="width: #{widget.field.translate ? '99' : '100'}%">
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
<t t-name="FieldURI.readonly">
|
||||||
|
<a href="#">#</a>
|
||||||
|
</t>
|
||||||
<t t-name="FieldEmail">
|
<t t-name="FieldEmail">
|
||||||
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -794,8 +817,8 @@
|
||||||
<t t-name="FieldText">
|
<t t-name="FieldText">
|
||||||
<textarea rows="6"
|
<textarea rows="6"
|
||||||
t-att-name="widget.name"
|
t-att-name="widget.name"
|
||||||
t-att-id="widget.element_id + '_field'"
|
t-att-id="widget.element_id"
|
||||||
t-att-class="'field_' + widget.type"
|
t-attf-class="field_#{widget.type}"
|
||||||
t-attf-style="width: #{widget.field.translate ? '99' : '100'}%"
|
t-attf-style="width: #{widget.field.translate ? '99' : '100'}%"
|
||||||
></textarea>
|
></textarea>
|
||||||
<img class="oe_field_translate" t-if="widget.field.translate" src="/web/static/src/img/icons/terp-translate.png" width="16" height="16" border="0"/>
|
<img class="oe_field_translate" t-if="widget.field.translate" src="/web/static/src/img/icons/terp-translate.png" width="16" height="16" border="0"/>
|
||||||
|
@ -814,8 +837,8 @@
|
||||||
<t t-name="FieldSelection">
|
<t t-name="FieldSelection">
|
||||||
<select
|
<select
|
||||||
t-att-name="widget.name"
|
t-att-name="widget.name"
|
||||||
t-att-id="widget.element_id + '_field'"
|
t-att-id="widget.element_id"
|
||||||
t-att-class="'field_' + widget.type"
|
t-attf-class="field_#{widget.type}"
|
||||||
style="width: 100%">
|
style="width: 100%">
|
||||||
<t t-foreach="widget.values" t-as="option">
|
<t t-foreach="widget.values" t-as="option">
|
||||||
<option><t t-esc="option[1]"/></option>
|
<option><t t-esc="option[1]"/></option>
|
||||||
|
@ -823,9 +846,10 @@
|
||||||
</select>
|
</select>
|
||||||
</t>
|
</t>
|
||||||
<t t-name="FieldMany2One">
|
<t t-name="FieldMany2One">
|
||||||
<div t-att-id="widget.element_id" class="oe-m2o">
|
<div class="oe-m2o">
|
||||||
<input t-att-id="widget.element_id + '_input'" type="text" size="1" style="width: 100%;"/>
|
<input type="text" size="1" style="width: 100%;"
|
||||||
<span class="oe-m2o-drop-down-button" t-att-id="widget.element_id + '_drop_down'">
|
t-att-id="widget.element_id"/>
|
||||||
|
<span class="oe-m2o-drop-down-button">
|
||||||
<img src="/web/static/src/img/down-arrow.png" /></span>
|
<img src="/web/static/src/img/down-arrow.png" /></span>
|
||||||
<span class="oe-m2o-cm-button" t-att-id="widget.name + '_open'">
|
<span class="oe-m2o-cm-button" t-att-id="widget.name + '_open'">
|
||||||
<img src="/web/static/src/img/icons/gtk-index.png"/></span>
|
<img src="/web/static/src/img/icons/gtk-index.png"/></span>
|
||||||
|
@ -848,8 +872,6 @@
|
||||||
</ul>
|
</ul>
|
||||||
</t>
|
</t>
|
||||||
<t t-name="FieldOne2Many">
|
<t t-name="FieldOne2Many">
|
||||||
<div t-att-id="widget.element_id">
|
|
||||||
</div>
|
|
||||||
</t>
|
</t>
|
||||||
<t t-name="FieldMany2Many">
|
<t t-name="FieldMany2Many">
|
||||||
<div t-att-id="widget.list_id"></div>
|
<div t-att-id="widget.list_id"></div>
|
||||||
|
@ -857,10 +879,10 @@
|
||||||
<t t-name="FieldReference">
|
<t t-name="FieldReference">
|
||||||
<table border="0" width="100%" cellpadding="0" cellspacing="0" class="oe_frame oe_forms">
|
<table border="0" width="100%" cellpadding="0" cellspacing="0" class="oe_frame oe_forms">
|
||||||
<tr>
|
<tr>
|
||||||
<td t-att-id="widget.selection.element_id" class="oe_form_frame_cell oe_form_selection">
|
<td t-attf-class="oe_form_frame_cell oe_form_selection #{widget.selection.element_class}">
|
||||||
<t t-raw="widget.selection.render()"/>
|
<t t-raw="widget.selection.render()"/>
|
||||||
</td>
|
</td>
|
||||||
<td t-att-id="widget.m2o.element_id" class="oe_form_frame_cell oe_form_many2one" nowrap="true">
|
<td t-attf-class="oe_form_frame_cell oe_form_many2one #{widget.m2o.element_class}" nowrap="true" style="display: none">
|
||||||
<t t-raw="widget.m2o.render()"/>
|
<t t-raw="widget.m2o.render()"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -869,8 +891,8 @@
|
||||||
<t t-name="FieldBoolean">
|
<t t-name="FieldBoolean">
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
t-att-name="widget.name"
|
t-att-name="widget.name"
|
||||||
t-att-id="widget.element_id + '_field'"
|
t-att-id="widget.element_id"
|
||||||
t-att-class="'field_' + widget.type"/>
|
t-attf-class="field_#{widget.type}"/>
|
||||||
</t>
|
</t>
|
||||||
<t t-name="FieldProgressBar">
|
<t t-name="FieldProgressBar">
|
||||||
<div t-opentag="true" class="oe-progressbar">
|
<div t-opentag="true" class="oe-progressbar">
|
||||||
|
@ -885,7 +907,7 @@
|
||||||
t-att-border="widget.readonly ? 0 : 1"
|
t-att-border="widget.readonly ? 0 : 1"
|
||||||
t-att-id="widget.element_id + '_field'"
|
t-att-id="widget.element_id + '_field'"
|
||||||
t-att-name="widget.name"
|
t-att-name="widget.name"
|
||||||
t-att-class="'field_' + widget.type"
|
t-attf-class="field_#{widget.type}"
|
||||||
t-att-width="widget.node.attrs.img_width || widget.node.attrs.width"
|
t-att-width="widget.node.attrs.img_width || widget.node.attrs.width"
|
||||||
t-att-height="widget.node.attrs.img_height || widget.node.attrs.height"
|
t-att-height="widget.node.attrs.img_height || widget.node.attrs.height"
|
||||||
/>
|
/>
|
||||||
|
@ -933,7 +955,7 @@
|
||||||
<input type="text" size="1"
|
<input type="text" size="1"
|
||||||
t-att-name="widget.name"
|
t-att-name="widget.name"
|
||||||
t-att-id="widget.element_id + '_field'"
|
t-att-id="widget.element_id + '_field'"
|
||||||
t-att-class="'field_' + widget.type" style="width: 100%"
|
t-attf-class="field_#{widget.type}" style="width: 100%"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td class="oe-binary" nowrap="true">
|
<td class="oe-binary" nowrap="true">
|
||||||
|
@ -978,7 +1000,6 @@
|
||||||
</t>
|
</t>
|
||||||
<t t-name="WidgetButton">
|
<t t-name="WidgetButton">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
t-att-id="widget.element_id + '_button'"
|
|
||||||
t-att-title="widget.help"
|
t-att-title="widget.help"
|
||||||
style="width: 100%" class="button">
|
style="width: 100%" class="button">
|
||||||
<img t-if="widget.node.attrs.icon" t-att-src="'/web/static/src/img/icons/' + widget.node.attrs.icon + '.png'" width="16" height="16"/>
|
<img t-if="widget.node.attrs.icon" t-att-src="'/web/static/src/img/icons/' + widget.node.attrs.icon + '.png'" width="16" height="16"/>
|
||||||
|
@ -1075,14 +1096,14 @@
|
||||||
<div style="white-space: nowrap;">
|
<div style="white-space: nowrap;">
|
||||||
<select t-att-name="attrs.name" t-att-id="element_id"
|
<select t-att-name="attrs.name" t-att-id="element_id"
|
||||||
t-att-autofocus="attrs.default_focus === '1' || undefined">
|
t-att-autofocus="attrs.default_focus === '1' || undefined">
|
||||||
<option/>
|
<option t-if="prepend_empty"/>
|
||||||
<t t-foreach="attrs.selection" t-as="option">
|
<t t-foreach="attrs.selection" t-as="option">
|
||||||
<t t-set="selected" t-value="defaults[attrs.name] === option[0]"/>
|
<t t-set="selected" t-value="defaults[attrs.name] === option[0]"/>
|
||||||
<option t-if="selected"
|
<option t-if="selected"
|
||||||
t-att-value="option[0]" selected="selected">
|
t-att-value="option_index" selected="selected">
|
||||||
<t t-esc="option[1]"/>
|
<t t-esc="option[1]"/>
|
||||||
</option>
|
</option>
|
||||||
<option t-if="!selected" t-att-value="option[0]">
|
<option t-if="!selected" t-att-value="option_index">
|
||||||
<t t-esc="option[1]"/>
|
<t t-esc="option[1]"/>
|
||||||
</option>
|
</option>
|
||||||
</t>
|
</t>
|
||||||
|
@ -1383,6 +1404,79 @@
|
||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
</t>
|
</t>
|
||||||
|
|
||||||
|
<t t-name="ImportView">
|
||||||
|
<a id="importview" href="javascript: void(0)" style="text-decoration: none;color: #3D3D3D;">Import</a>
|
||||||
|
</t>
|
||||||
|
<t t-name="ImportDataView">
|
||||||
|
<form name="import_data" id="import_data" action="" method="post" enctype="multipart/form-data">
|
||||||
|
<input type="hidden" name="session_id" t-att-value="session.session_id"/>
|
||||||
|
<h2 class="separator horizontal">1. Import a .CSV file</h2>
|
||||||
|
<p>Select a .CSV file to import. If you need a sample of file to import,
|
||||||
|
you should use the export tool with the "Import Compatible" option.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="csvfile">CSV File:</label>
|
||||||
|
<input type="file" id="csvfile" size="50" name="csvfile"/>
|
||||||
|
</p>
|
||||||
|
<h2 class="separator horizontal">2. Check your file format</h2>
|
||||||
|
<div id="result"></div>
|
||||||
|
<fieldset>
|
||||||
|
<legend style="cursor:pointer;">Import Options</legend>
|
||||||
|
<table style="display:none">
|
||||||
|
<tr>
|
||||||
|
<td colspan="4">
|
||||||
|
<label for="file_has_headers">Does your file have titles?</label>
|
||||||
|
<input type="checkbox" checked="checked"
|
||||||
|
id="file_has_headers"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label for="csv_separator">Separator:</label></td>
|
||||||
|
<td><input type="text" name="csvsep" id="csv_separator" value=","/></td>
|
||||||
|
<td><label for="csv_delimiter">Delimiter:</label></td>
|
||||||
|
<td><input type="text" name="csvdel" id="csv_delimiter" value='"'/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label for="csv_encoding">Encoding:</label></td>
|
||||||
|
<td>
|
||||||
|
<select name="csvcode" id="csv_encoding">
|
||||||
|
<option value="utf-8">UTF-8</option>
|
||||||
|
<option value="latin1">Latin 1</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td><label for="csv_skip" title="For use if CSV files have titles on multiple lines, skips more than a single line during import">
|
||||||
|
Lines to skip<sup>?</sup>:</label></td>
|
||||||
|
<td><input type="number" id="csv_skip" value="0" min="0"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</t>
|
||||||
|
<table t-name="ImportView.result"
|
||||||
|
class="oe_import_grid" width="100%" style="margin: 5px 0;">
|
||||||
|
<tr t-if="headers" class="oe_import_grid-header">
|
||||||
|
<td t-foreach="headers" t-as="header" class="oe_import_grid-cell">
|
||||||
|
<t t-esc="header"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td t-foreach="records[0]" t-as="column">
|
||||||
|
<input class="sel_fields"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr t-foreach="records" t-as="record" class="oe_import_grid-row">
|
||||||
|
<td t-foreach="record" t-as="cell" class="oe_import_grid-cell">
|
||||||
|
<t t-esc="cell"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<t t-name="ImportView.error">
|
||||||
|
<p style="white-space:pre-line;">The import failed due to:<t t-esc="error.message"/></p>
|
||||||
|
<t t-if="error.preview">
|
||||||
|
<p>Here is a preview of the file we could not import:</p>
|
||||||
|
<pre><t t-esc="error.preview"/></pre>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
|
||||||
<t t-name="About-Page">
|
<t t-name="About-Page">
|
||||||
<div>
|
<div>
|
||||||
<h1>OpenERP Web</h1>
|
<h1>OpenERP Web</h1>
|
||||||
|
|
|
@ -27,6 +27,18 @@ $(document).ready(function () {
|
||||||
var fl = 12.1234;
|
var fl = 12.1234;
|
||||||
var str = openerp.web.format_value(fl, {type:"float"});
|
var str = openerp.web.format_value(fl, {type:"float"});
|
||||||
equal(str, "12.12");
|
equal(str, "12.12");
|
||||||
|
equal(openerp.web.format_value(12.02, {type: 'float'}),
|
||||||
|
'12.02');
|
||||||
|
equal(openerp.web.format_value(0.0002, {type: 'float', digits: [1, 3]}),
|
||||||
|
'0.000');
|
||||||
|
equal(openerp.web.format_value(0.0002, {type: 'float', digits: [1, 4]}),
|
||||||
|
'0.0002');
|
||||||
|
equal(openerp.web.format_value(0.0002, {type: 'float', digits: [1, 6]}),
|
||||||
|
'0.000200');
|
||||||
|
equal(openerp.web.format_value(1, {type: 'float', digits: [1, 6]}),
|
||||||
|
'1.000000');
|
||||||
|
equal(openerp.web.format_value(1, {type: 'float'}),
|
||||||
|
'1.00');
|
||||||
});
|
});
|
||||||
test("parse_datetime", function () {
|
test("parse_datetime", function () {
|
||||||
var val = openerp.web.str_to_datetime("2009-05-04 12:34:23");
|
var val = openerp.web.str_to_datetime("2009-05-04 12:34:23");
|
||||||
|
@ -51,4 +63,4 @@ $(document).ready(function () {
|
||||||
var val = openerp.web.parse_value(str, {type:"float"});
|
var val = openerp.web.parse_value(str, {type:"float"});
|
||||||
equal(val, -134112.1234);
|
equal(val, -134112.1234);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<script src="/web/static/lib/datejs/sugarpak.js"></script>
|
<script src="/web/static/lib/datejs/sugarpak.js"></script>
|
||||||
<script src="/web/static/lib/datejs/extras.js"></script>
|
<script src="/web/static/lib/datejs/extras.js"></script>
|
||||||
|
|
||||||
<script src="/web/static/lib/qweb/qweb.js"></script>
|
<script src="/web/static/lib/qweb/qweb2.js"></script>
|
||||||
|
|
||||||
<script src="/web/static/src/js/boot.js"></script>
|
<script src="/web/static/src/js/boot.js"></script>
|
||||||
<script src="/web/static/src/js/core.js"></script>
|
<script src="/web/static/src/js/core.js"></script>
|
||||||
|
@ -31,11 +31,8 @@
|
||||||
<script src="/web/static/src/js/data.js"></script>
|
<script src="/web/static/src/js/data.js"></script>
|
||||||
<script src="/web/static/src/js/views.js"></script>
|
<script src="/web/static/src/js/views.js"></script>
|
||||||
<script src="/web/static/src/js/search.js"></script>
|
<script src="/web/static/src/js/search.js"></script>
|
||||||
<script src="/web/static/src/js/form.js"></script>
|
<script src="/web/static/src/js/view_form.js"></script>
|
||||||
<script src="/web/static/src/js/list.js"></script>
|
<script src="/web/static/src/js/view_list.js"></script>
|
||||||
<script type="text/javascript">
|
|
||||||
QWeb.add_template('/web/static/src/xml/web.xml');
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
<body id="oe" class="openerp">
|
<body id="oe" class="openerp">
|
||||||
<h1 id="qunit-header">OpenERP web Test Suite</h1>
|
<h1 id="qunit-header">OpenERP web Test Suite</h1>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "web calendar",
|
"name": "web calendar",
|
||||||
|
"category" : "Hidden",
|
||||||
"version": "2.0",
|
"version": "2.0",
|
||||||
"depends": ['web'],
|
"depends": ['web'],
|
||||||
"js": [
|
"js": [
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Danish translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-11 13:57+0000\n"
|
||||||
|
"Last-Translator: Jonas Mortensen <Unknown>\n"
|
||||||
|
"Language-Team: Danish <da@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-12 04:44+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14124)\n"
|
||||||
|
|
||||||
|
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
|
@ -0,0 +1,22 @@
|
||||||
|
# German translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-10 12:36+0000\n"
|
||||||
|
"Last-Translator: Felix Schubert <Unknown>\n"
|
||||||
|
"Language-Team: German <de@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14123)\n"
|
||||||
|
|
||||||
|
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Spanish translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-18 10:41+0000\n"
|
||||||
|
"Last-Translator: Amós Oviedo <Unknown>\n"
|
||||||
|
"Language-Team: Spanish <es@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-19 06:05+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14157)\n"
|
||||||
|
|
||||||
|
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Spanish (Ecuador) translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-07 15:54+0000\n"
|
||||||
|
"Last-Translator: Cristian Salamea (Gnuthink) <ovnicraft@gmail.com>\n"
|
||||||
|
"Language-Team: Spanish (Ecuador) <es_EC@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14110)\n"
|
||||||
|
|
||||||
|
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Estonian translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-10 19:20+0000\n"
|
||||||
|
"Last-Translator: Aare Vesi <Unknown>\n"
|
||||||
|
"Language-Team: Estonian <et@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14123)\n"
|
||||||
|
|
||||||
|
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
|
@ -0,0 +1,22 @@
|
||||||
|
# French translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-23 12:12+0000\n"
|
||||||
|
"Last-Translator: fhe (OpenERP) <Unknown>\n"
|
||||||
|
"Language-Team: French <fr@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14185)\n"
|
||||||
|
|
||||||
|
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Galician translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-19 10:25+0000\n"
|
||||||
|
"Last-Translator: Amós Oviedo <Unknown>\n"
|
||||||
|
"Language-Team: Galician <gl@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14165)\n"
|
||||||
|
|
||||||
|
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Italian translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-08 13:39+0000\n"
|
||||||
|
"Last-Translator: Nicola Riolini - Micronaet <Unknown>\n"
|
||||||
|
"Language-Team: Italian <it@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-09 05:22+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14110)\n"
|
||||||
|
|
||||||
|
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Dutch (Belgium) translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-07 09:05+0000\n"
|
||||||
|
"Last-Translator: Niels Huylebroeck <Unknown>\n"
|
||||||
|
"Language-Team: Dutch (Belgium) <nl_BE@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14110)\n"
|
||||||
|
|
||||||
|
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Slovak translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-23 14:42+0000\n"
|
||||||
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"Language-Team: Slovak <sk@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14185)\n"
|
||||||
|
|
||||||
|
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr ""
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Slovenian translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-19 06:26+0000\n"
|
||||||
|
"Last-Translator: Anze (Neotek) <Unknown>\n"
|
||||||
|
"Language-Team: Slovenian <sl@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14165)\n"
|
||||||
|
|
||||||
|
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||||
|
msgid " "
|
||||||
|
msgstr " "
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2011-09-06 12:02+0200\n"
|
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*---------------------------------------------------------*/
|
*---------------------------------------------------------*/
|
||||||
|
|
||||||
openerp.web_calendar = function(openerp) {
|
openerp.web_calendar = function(openerp) {
|
||||||
|
var _t = openerp.web._t;
|
||||||
var QWeb = openerp.web.qweb;
|
var QWeb = openerp.web.qweb;
|
||||||
QWeb.add_template('/web_calendar/static/src/xml/web_calendar.xml');
|
QWeb.add_template('/web_calendar/static/src/xml/web_calendar.xml');
|
||||||
openerp.web.views.add('calendar', 'openerp.web_calendar.CalendarView');
|
openerp.web.views.add('calendar', 'openerp.web_calendar.CalendarView');
|
||||||
|
@ -13,16 +14,13 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||||
this.set_default_options(options);
|
this.set_default_options(options);
|
||||||
this.dataset = dataset;
|
this.dataset = dataset;
|
||||||
this.model = dataset.model;
|
this.model = dataset.model;
|
||||||
|
this.fields_view = {};
|
||||||
this.view_id = view_id;
|
this.view_id = view_id;
|
||||||
this.domain = this.dataset.domain || [];
|
|
||||||
this.context = this.dataset.context || {};
|
|
||||||
this.has_been_loaded = $.Deferred();
|
this.has_been_loaded = $.Deferred();
|
||||||
this.creating_event_id = null;
|
this.creating_event_id = null;
|
||||||
this.dataset_events = [];
|
this.dataset_events = [];
|
||||||
if (this.options.action_views_ids.form) {
|
this.form_dialog = new openerp.web_calendar.CalendarFormDialog(this, {}, this.options.action_views_ids.form, dataset);
|
||||||
this.form_dialog = new openerp.web_calendar.CalendarFormDialog(this, {}, this.options.action_views_ids.form, dataset);
|
this.form_dialog.start();
|
||||||
this.form_dialog.start();
|
|
||||||
}
|
|
||||||
this.COLOR_PALETTE = ['#f57900', '#cc0000', '#d400a8', '#75507b', '#3465a4', '#73d216', '#c17d11', '#edd400',
|
this.COLOR_PALETTE = ['#f57900', '#cc0000', '#d400a8', '#75507b', '#3465a4', '#73d216', '#c17d11', '#edd400',
|
||||||
'#fcaf3e', '#ef2929', '#ff00c9', '#ad7fa8', '#729fcf', '#8ae234', '#e9b96e', '#fce94f',
|
'#fcaf3e', '#ef2929', '#ff00c9', '#ad7fa8', '#729fcf', '#8ae234', '#e9b96e', '#fce94f',
|
||||||
'#ff8e00', '#ff0000', '#b0008c', '#9000ff', '#0078ff', '#00ff00', '#e6ff00', '#ffff00',
|
'#ff8e00', '#ff0000', '#b0008c', '#9000ff', '#0078ff', '#00ff00', '#e6ff00', '#ffff00',
|
||||||
|
@ -31,10 +29,11 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||||
},
|
},
|
||||||
start: function() {
|
start: function() {
|
||||||
this._super();
|
this._super();
|
||||||
this.rpc("/web/view/load", {"model": this.model, "view_id": this.view_id, "view_type":"calendar", 'toolbar': true}, this.on_loaded);
|
return this.rpc("/web/view/load", {"model": this.model, "view_id": this.view_id, "view_type":"calendar", 'toolbar': true}, this.on_loaded);
|
||||||
},
|
},
|
||||||
stop: function() {
|
stop: function() {
|
||||||
scheduler.clearAll();
|
scheduler.clearAll();
|
||||||
|
this._super();
|
||||||
},
|
},
|
||||||
on_loaded: function(data) {
|
on_loaded: function(data) {
|
||||||
this.fields_view = data;
|
this.fields_view = data;
|
||||||
|
@ -46,6 +45,10 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||||
this.name = this.fields_view.name || this.fields_view.arch.attrs.string;
|
this.name = this.fields_view.name || this.fields_view.arch.attrs.string;
|
||||||
this.view_id = this.fields_view.view_id;
|
this.view_id = this.fields_view.view_id;
|
||||||
|
|
||||||
|
// mode, one of month, week or day
|
||||||
|
this.mode = this.fields_view.arch.attrs.mode;
|
||||||
|
|
||||||
|
// date_start is mandatory, date_delay and date_stop are optional
|
||||||
this.date_start = this.fields_view.arch.attrs.date_start;
|
this.date_start = this.fields_view.arch.attrs.date_start;
|
||||||
this.date_delay = this.fields_view.arch.attrs.date_delay;
|
this.date_delay = this.fields_view.arch.attrs.date_delay;
|
||||||
this.date_stop = this.fields_view.arch.attrs.date_stop;
|
this.date_stop = this.fields_view.arch.attrs.date_stop;
|
||||||
|
@ -54,6 +57,10 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||||
this.day_length = this.fields_view.arch.attrs.day_length || 8;
|
this.day_length = this.fields_view.arch.attrs.day_length || 8;
|
||||||
this.color_field = this.fields_view.arch.attrs.color;
|
this.color_field = this.fields_view.arch.attrs.color;
|
||||||
this.fields = this.fields_view.fields;
|
this.fields = this.fields_view.fields;
|
||||||
|
|
||||||
|
if (!this.date_start) {
|
||||||
|
throw new Error("Calendar view has not defined 'date_start' attribute.");
|
||||||
|
}
|
||||||
|
|
||||||
//* Calendar Fields *
|
//* Calendar Fields *
|
||||||
this.calendar_fields.date_start = {'name': this.date_start, 'kind': this.fields[this.date_start].type};
|
this.calendar_fields.date_start = {'name': this.date_start, 'kind': this.fields[this.date_start].type};
|
||||||
|
@ -67,9 +74,6 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||||
if (this.date_stop) {
|
if (this.date_stop) {
|
||||||
this.calendar_fields.date_stop = {'name': this.date_stop, 'kind': this.fields[this.date_stop].type};
|
this.calendar_fields.date_stop = {'name': this.date_stop, 'kind': this.fields[this.date_stop].type};
|
||||||
}
|
}
|
||||||
if (!this.date_delay && !this.date_stop) {
|
|
||||||
throw new Error("Calendar view has none of the following attributes : 'date_stop', 'date_delay'");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var fld = 0; fld < this.fields_view.arch.children.length; fld++) {
|
for (var fld = 0; fld < this.fields_view.arch.children.length; fld++) {
|
||||||
this.info_fields.push(this.fields_view.arch.children[fld].attrs.name);
|
this.info_fields.push(this.fields_view.arch.children[fld].attrs.name);
|
||||||
|
@ -79,8 +83,8 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||||
if (this.options.sidebar && this.options.sidebar_id) {
|
if (this.options.sidebar && this.options.sidebar_id) {
|
||||||
this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
|
this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
|
||||||
this.sidebar.start();
|
this.sidebar.start();
|
||||||
this.sidebar.navigator = new openerp.web_calendar.SidebarNavigator(this.sidebar, this.sidebar.add_section('navigator', "Navigator"), this);
|
this.sidebar.navigator = new openerp.web_calendar.SidebarNavigator(this.sidebar, this);
|
||||||
this.sidebar.responsible = new openerp.web_calendar.SidebarResponsible(this.sidebar, this.sidebar.add_section('responsible', "Responsible"), this);
|
this.sidebar.responsible = new openerp.web_calendar.SidebarResponsible(this.sidebar, this);
|
||||||
this.sidebar.add_toolbar(this.fields_view.toolbar);
|
this.sidebar.add_toolbar(this.fields_view.toolbar);
|
||||||
this.set_common_sidebar_sections(this.sidebar);
|
this.set_common_sidebar_sections(this.sidebar);
|
||||||
this.sidebar.do_unfold();
|
this.sidebar.do_unfold();
|
||||||
|
@ -91,9 +95,6 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||||
|
|
||||||
this.init_scheduler();
|
this.init_scheduler();
|
||||||
this.has_been_loaded.resolve();
|
this.has_been_loaded.resolve();
|
||||||
if (this.dataset.ids.length) {
|
|
||||||
this.dataset.read_ids(this.dataset.ids, _.keys(this.fields), this.on_events_loaded);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
init_scheduler: function() {
|
init_scheduler: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -110,9 +111,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||||
scheduler.config.drag_resize = true;
|
scheduler.config.drag_resize = true;
|
||||||
scheduler.config.drag_create = true;
|
scheduler.config.drag_create = true;
|
||||||
|
|
||||||
// Initialize Sceduler
|
scheduler.init('openerp_scheduler', null, this.mode || 'month');
|
||||||
this.mode = this.mode || 'month';
|
|
||||||
scheduler.init('openerp_scheduler', null, this.mode);
|
|
||||||
|
|
||||||
scheduler.detachAllEvents();
|
scheduler.detachAllEvents();
|
||||||
scheduler.attachEvent('onEventAdded', this.do_create_event);
|
scheduler.attachEvent('onEventAdded', this.do_create_event);
|
||||||
|
@ -157,7 +156,9 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||||
for (var e = 0; e < events.length; e++) {
|
for (var e = 0; e < events.length; e++) {
|
||||||
var evt = events[e];
|
var evt = events[e];
|
||||||
if (!evt[this.date_start]) {
|
if (!evt[this.date_start]) {
|
||||||
this.notification.warn("Start date is not defined for event :", evt['id']);
|
if (this.session.debug) {
|
||||||
|
this.do_warn("Start date is not defined for event :", evt['id']);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,10 +183,10 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.fields[this.date_start]['type'] == 'date') {
|
if (this.fields[this.date_start]['type'] == 'date') {
|
||||||
evt[this.date_start] = openerp.web.str_to_date(evt[this.date_start]).set({hour: 9}).toString('yyyy-MM-dd HH:mm:ss');
|
evt[this.date_start] = openerp.web.auto_str_to_date(evt[this.date_start]).set({hour: 9}).toString('yyyy-MM-dd HH:mm:ss');
|
||||||
}
|
}
|
||||||
if (this.date_stop && evt[this.date_stop] && this.fields[this.date_stop]['type'] == 'date') {
|
if (this.date_stop && evt[this.date_stop] && this.fields[this.date_stop]['type'] == 'date') {
|
||||||
evt[this.date_stop] = openerp.web.str_to_date(evt[this.date_stop]).set({hour: 17}).toString('yyyy-MM-dd HH:mm:ss');
|
evt[this.date_stop] = openerp.web.auto_str_to_date(evt[this.date_stop]).set({hour: 17}).toString('yyyy-MM-dd HH:mm:ss');
|
||||||
}
|
}
|
||||||
res_events.push(this.convert_event(evt));
|
res_events.push(this.convert_event(evt));
|
||||||
}
|
}
|
||||||
|
@ -199,7 +200,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||||
convert_event: function(evt) {
|
convert_event: function(evt) {
|
||||||
var date_start = openerp.web.str_to_datetime(evt[this.date_start]),
|
var date_start = openerp.web.str_to_datetime(evt[this.date_start]),
|
||||||
date_stop = this.date_stop ? openerp.web.str_to_datetime(evt[this.date_stop]) : null,
|
date_stop = this.date_stop ? openerp.web.str_to_datetime(evt[this.date_stop]) : null,
|
||||||
date_delay = evt[this.date_delay] || null,
|
date_delay = evt[this.date_delay] || 1.0,
|
||||||
res_text = '',
|
res_text = '',
|
||||||
res_description = [];
|
res_description = [];
|
||||||
|
|
||||||
|
@ -268,12 +269,14 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
do_edit_event: function(event_id) {
|
do_edit_event: function(event_id) {
|
||||||
|
var self = this;
|
||||||
event_id = parseInt(event_id, 10);
|
event_id = parseInt(event_id, 10);
|
||||||
var index = _.indexOf(this.dataset.ids, event_id);
|
var index = _.indexOf(this.dataset.ids, event_id);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
this.dataset.index = index;
|
this.dataset.index = index;
|
||||||
this.form_dialog.form.do_show();
|
this.form_dialog.form.do_show().then(function() {
|
||||||
this.form_dialog.open();
|
self.form_dialog.open();
|
||||||
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -292,26 +295,17 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
do_search: function(domains, contexts, groupbys) {
|
do_search: function(domain, context, group_by) {
|
||||||
var self = this;
|
var self = this;
|
||||||
scheduler.clearAll();
|
scheduler.clearAll();
|
||||||
$.when(this.has_been_loaded).then(function() {
|
$.when(this.has_been_loaded).then(function() {
|
||||||
self.rpc('/web/session/eval_domain_and_context', {
|
// TODO: handle non-empty results.group_by with read_group
|
||||||
domains: domains,
|
self.dataset.read_slice(_.keys(self.fields), {
|
||||||
contexts: contexts,
|
offset: 0,
|
||||||
group_by_seq: groupbys
|
limit: self.limit
|
||||||
}, function (results) {
|
}, function(events) {
|
||||||
// TODO: handle non-empty results.group_by with read_group
|
self.dataset_events = events;
|
||||||
self.dataset.context = self.context = results.context;
|
self.on_events_loaded(events);
|
||||||
self.dataset.domain = self.domain = results.domain;
|
|
||||||
self.dataset.read_slice(_.keys(self.fields), {
|
|
||||||
offset:0,
|
|
||||||
limit: self.limit
|
|
||||||
}, function(events) {
|
|
||||||
self.dataset_events = events;
|
|
||||||
self.on_events_loaded(events);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -371,13 +365,16 @@ openerp.web_calendar.CalendarFormDialog = openerp.web.Dialog.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
openerp.web_calendar.SidebarResponsible = openerp.web.Widget.extend({
|
openerp.web_calendar.SidebarResponsible = openerp.web.Widget.extend({
|
||||||
init: function(parent, element_id, view) {
|
init: function(parent, view) {
|
||||||
this._super(parent, element_id);
|
var $section = parent.add_section(_t('Responsible'), 'responsible');
|
||||||
|
this.$div = $('<div></div>');
|
||||||
|
$section.append(this.$div);
|
||||||
|
this._super(parent, $section.attr('id'));
|
||||||
this.view = view;
|
this.view = view;
|
||||||
this.$element.delegate('input:checkbox', 'change', this.on_filter_click);
|
this.$element.delegate('input:checkbox', 'change', this.on_filter_click);
|
||||||
},
|
},
|
||||||
on_events_loaded: function(filters) {
|
on_events_loaded: function(filters) {
|
||||||
this.$element.html(QWeb.render('CalendarView.sidebar.responsible', { filters: filters }));
|
this.$div.html(QWeb.render('CalendarView.sidebar.responsible', { filters: filters }));
|
||||||
},
|
},
|
||||||
on_filter_click: function(e) {
|
on_filter_click: function(e) {
|
||||||
var responsibles = [],
|
var responsibles = [],
|
||||||
|
@ -397,8 +394,9 @@ openerp.web_calendar.SidebarResponsible = openerp.web.Widget.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
openerp.web_calendar.SidebarNavigator = openerp.web.Widget.extend({
|
openerp.web_calendar.SidebarNavigator = openerp.web.Widget.extend({
|
||||||
init: function(parent, element_id, view) {
|
init: function(parent, view) {
|
||||||
this._super(parent, element_id);
|
var $section = parent.add_section(_t('Navigator'), 'navigator');
|
||||||
|
this._super(parent, $section.attr('id'));
|
||||||
this.view = view;
|
this.view = view;
|
||||||
},
|
},
|
||||||
on_events_loaded: function(events) {
|
on_events_loaded: function(events) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Web Chat",
|
"name": "Web Chat",
|
||||||
|
"category" : "Hidden",
|
||||||
"version": "2.0",
|
"version": "2.0",
|
||||||
"depends": ['web'],
|
"depends": ['web'],
|
||||||
"js": [
|
"js": [
|
||||||
|
@ -10,6 +11,6 @@
|
||||||
'static/src/js/web_chat.js'
|
'static/src/js/web_chat.js'
|
||||||
],
|
],
|
||||||
"css": [],
|
"css": [],
|
||||||
# 'active': True,
|
|
||||||
'active': False,
|
'active': False,
|
||||||
|
'installable': False,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import simplejson
|
import simplejson
|
||||||
import web.common as openerpweb
|
import web.common.http as openerpweb
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2011-09-06 12:03+0200\n"
|
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "web Dashboard",
|
"name": "web Dashboard",
|
||||||
|
"category" : "Hidden",
|
||||||
"version": "2.0",
|
"version": "2.0",
|
||||||
"depends": ['web'],
|
"depends": ['web'],
|
||||||
"js": [
|
"js": [
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import web.common as openerpweb
|
import web.common.http as openerpweb
|
||||||
|
|
||||||
WIDGET_CONTENT_PATTERN = """<!DOCTYPE html>
|
WIDGET_CONTENT_PATTERN = """<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
@ -24,5 +24,5 @@ class Widgets(openerpweb.Controller):
|
||||||
@openerpweb.httprequest
|
@openerpweb.httprequest
|
||||||
def content(self, request, widget_id):
|
def content(self, request, widget_id):
|
||||||
return WIDGET_CONTENT_PATTERN % request.session.model('res.widget').read(
|
return WIDGET_CONTENT_PATTERN % request.session.model('res.widget').read(
|
||||||
[widget_id], ['content'], request.session.eval_context(request.context)
|
[int(widget_id)], ['content'], request.session.eval_context(request.context)
|
||||||
)[0]
|
)[0]
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Danish translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-11 13:59+0000\n"
|
||||||
|
"Last-Translator: Jonas Mortensen <Unknown>\n"
|
||||||
|
"Language-Team: Danish <da@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-12 04:44+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14124)\n"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr "Nulstil"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Fortryd"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Add Widget"
|
||||||
|
msgstr "Tilføj widget"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Change layout"
|
||||||
|
msgstr "Skift layout"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Choose dashboard layout"
|
||||||
|
msgstr "Vælg layout for kontrolpanel"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "progress:"
|
||||||
|
msgstr "fremskridt:"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "%"
|
||||||
|
msgstr "%"
|
|
@ -0,0 +1,46 @@
|
||||||
|
# German translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-10 12:38+0000\n"
|
||||||
|
"Last-Translator: Felix Schubert <Unknown>\n"
|
||||||
|
"Language-Team: German <de@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14123)\n"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr "Zurücksetzen"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Rückgängig"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Add Widget"
|
||||||
|
msgstr "Widget hinzufügen"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Change layout"
|
||||||
|
msgstr "Layout wechseln"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Choose dashboard layout"
|
||||||
|
msgstr "Wählen Sie das Dashboard Layout"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "progress:"
|
||||||
|
msgstr "Fortschritt:"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "%"
|
||||||
|
msgstr "%"
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Spanish translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-18 10:44+0000\n"
|
||||||
|
"Last-Translator: Amós Oviedo <Unknown>\n"
|
||||||
|
"Language-Team: Spanish <es@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-19 06:05+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14157)\n"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr "Reiniciar"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Deshacer"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Add Widget"
|
||||||
|
msgstr "Añadir Widget"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Change layout"
|
||||||
|
msgstr "Cambiar disposición"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Choose dashboard layout"
|
||||||
|
msgstr "Cambiar disposición del tablero"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "progress:"
|
||||||
|
msgstr "progreso:"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "%"
|
||||||
|
msgstr "%"
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Spanish (Ecuador) translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-07 15:56+0000\n"
|
||||||
|
"Last-Translator: Cristian Salamea (Gnuthink) <ovnicraft@gmail.com>\n"
|
||||||
|
"Language-Team: Spanish (Ecuador) <es_EC@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14110)\n"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr "Reset"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Deshacer"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Add Widget"
|
||||||
|
msgstr "Agregar Widget"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Change layout"
|
||||||
|
msgstr "Cambiar disposición"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Choose dashboard layout"
|
||||||
|
msgstr "Elegir el diseño del panel de control"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "progress:"
|
||||||
|
msgstr "progreso:"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "%"
|
||||||
|
msgstr "%"
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Estonian translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-10 19:29+0000\n"
|
||||||
|
"Last-Translator: Aare Vesi <Unknown>\n"
|
||||||
|
"Language-Team: Estonian <et@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14123)\n"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr "Lähtesta"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Ennista"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Add Widget"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Change layout"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Choose dashboard layout"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "progress:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "%"
|
||||||
|
msgstr "%"
|
|
@ -0,0 +1,46 @@
|
||||||
|
# French translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-23 12:11+0000\n"
|
||||||
|
"Last-Translator: Xavier (Open ERP) <Unknown>\n"
|
||||||
|
"Language-Team: French <fr@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14185)\n"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Annuler"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Add Widget"
|
||||||
|
msgstr "Ajouter un Gadget"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Change layout"
|
||||||
|
msgstr "Changer la mise en page"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Choose dashboard layout"
|
||||||
|
msgstr "Choisissez la mise en page du tableau de bord"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "progress:"
|
||||||
|
msgstr "progrès"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "%"
|
||||||
|
msgstr "%"
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Galician translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-19 10:29+0000\n"
|
||||||
|
"Last-Translator: Amós Oviedo <Unknown>\n"
|
||||||
|
"Language-Team: Galician <gl@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14165)\n"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr "Reiniciar"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Desfacer"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Add Widget"
|
||||||
|
msgstr "Engadir un widget"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Change layout"
|
||||||
|
msgstr "Cambiar disposición"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Choose dashboard layout"
|
||||||
|
msgstr "Cambiar disposición do taboleiro"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "progress:"
|
||||||
|
msgstr "progreso:"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "%"
|
||||||
|
msgstr "%"
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Italian translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-07 09:00+0000\n"
|
||||||
|
"Last-Translator: Davide Corio - agilebg.com <davide.corio@agilebg.com>\n"
|
||||||
|
"Language-Team: Italian <it@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14110)\n"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr "Ripristina"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Annulla"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Add Widget"
|
||||||
|
msgstr "Aggiungi Widget"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Change layout"
|
||||||
|
msgstr "Cambia layout"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Choose dashboard layout"
|
||||||
|
msgstr "Scegli layout dashboard"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "progress:"
|
||||||
|
msgstr "avanzamento:"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "%"
|
||||||
|
msgstr "%"
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Dutch (Belgium) translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-07 09:04+0000\n"
|
||||||
|
"Last-Translator: Niels Huylebroeck <Unknown>\n"
|
||||||
|
"Language-Team: Dutch (Belgium) <nl_BE@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14110)\n"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr "Reset"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Ongedaan maken"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Add Widget"
|
||||||
|
msgstr "Widget toevoegen"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Change layout"
|
||||||
|
msgstr "Layout aanpassen"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Choose dashboard layout"
|
||||||
|
msgstr "Dashboard layout kiezen"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "progress:"
|
||||||
|
msgstr "vooruitgang:"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "%"
|
||||||
|
msgstr "%"
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Slovak translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-23 14:45+0000\n"
|
||||||
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"Language-Team: Slovak <sk@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14185)\n"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Add Widget"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Change layout"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Choose dashboard layout"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "progress:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "%"
|
||||||
|
msgstr ""
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Slovenian translation for openerp-web
|
||||||
|
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||||
|
# This file is distributed under the same license as the openerp-web package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: openerp-web\n"
|
||||||
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||||
|
"PO-Revision-Date: 2011-10-19 06:25+0000\n"
|
||||||
|
"Last-Translator: Anze (Neotek) <Unknown>\n"
|
||||||
|
"Language-Team: Slovenian <sl@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
|
||||||
|
"X-Generator: Launchpad (build 14165)\n"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr "Ponastavi"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Razveljavi"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Add Widget"
|
||||||
|
msgstr "Dodaj gradnik"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Change layout"
|
||||||
|
msgstr "Spreminjanje postavitve"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "Choose dashboard layout"
|
||||||
|
msgstr "Izberite postavitev nadzorne plošče"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "progress:"
|
||||||
|
msgstr "napredek:"
|
||||||
|
|
||||||
|
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||||
|
msgid "%"
|
||||||
|
msgstr "%"
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2011-09-06 12:02+0200\n"
|
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
|
|
@ -7,17 +7,38 @@
|
||||||
}
|
}
|
||||||
.openerp .oe-dashboard-action {
|
.openerp .oe-dashboard-action {
|
||||||
margin: 0 0.5em 0.5em 0;
|
margin: 0 0.5em 0.5em 0;
|
||||||
padding: 2px;
|
padding: 0px;
|
||||||
}
|
background-color: white;
|
||||||
.openerp .oe-dashboard-action:hover {
|
border-radius: 3px;
|
||||||
border: 1px dashed #ccc;
|
-moz-border-radius: 3px;
|
||||||
padding: 1px;
|
-webkit-border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.openerp .oe-dashboard-action .oe-dashboard-action-header {
|
.openerp .oe-dashboard-action .oe-dashboard-action-header {
|
||||||
font-size: 125%;
|
font-size: 85%;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-indent: 10px;
|
||||||
|
vertical-align: center;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
background: white url("/web/static/src/img/box-a-header-a.gif") 0% 0% repeat-x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.openerp h2.oe-dashboard-action-header {
|
||||||
|
margin: 0;
|
||||||
|
padding:4px 4px;
|
||||||
|
-moz-border-radius-topleft: 3px;
|
||||||
|
-webkit-border-top-left-radius: 3px;
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
-moz-border-radius-topright: 3px;
|
||||||
|
-webkit-border-top-right-radius: 3px;
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
}
|
||||||
|
.openerp h2.oe-dashboard-action-header-empty {
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
.openerp a.oe-dashboard-action-rename {
|
.openerp a.oe-dashboard-action-rename {
|
||||||
float: left;
|
float: left;
|
||||||
padding-right: 4px;
|
padding-right: 4px;
|
||||||
|
@ -57,6 +78,12 @@
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Base overwriting */
|
||||||
|
.openerp .oe-dashboard .oe-listview-content, .openerp .oe-dashboard .ui-widget-header {
|
||||||
|
border:none !important;
|
||||||
|
padding:0px 3px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Layouts */
|
/* Layouts */
|
||||||
.openerp .oe-dashboard-layout_1 .oe-dashboard-column.index_0 {
|
.openerp .oe-dashboard-layout_1 .oe-dashboard-column.index_0 {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -234,6 +261,46 @@
|
||||||
.openerp .oe-dashboard-action .view-manager-main-content {
|
.openerp .oe-dashboard-action .view-manager-main-content {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
.openerp .oe-dashboard-action-header .ui-icon, .openerp .oe-dashboard-action-header .oe-dashboard-action-rename {
|
|
||||||
display: none;
|
.oe-static-home {
|
||||||
|
padding: 0.5em 0.5em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.oe-static-home h1 {
|
||||||
|
margin: 0 0 0.3em
|
||||||
|
}
|
||||||
|
.oe-static-home-banner {
|
||||||
|
display: inline-block;
|
||||||
|
margin: auto 0;
|
||||||
|
padding: 0.5em 5em;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.oe-static-home-banner li {
|
||||||
|
font-size: 150%;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.oe-static-home address {
|
||||||
|
font-style: normal;
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.oe-static-home-tiles {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.oe-static-home-tiles td {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
.oe-static-home-tile {
|
||||||
|
margin: 0.5em;
|
||||||
|
padding: 0 1em;
|
||||||
|
}
|
||||||
|
.oe-static-home-tile-logo {
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
.oe-static-home-tile-text h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0.2em;
|
||||||
|
}
|
||||||
|
.oe-static-home-tile-text p {
|
||||||
|
margin: 0.5em 0;
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
@ -2,6 +2,11 @@ openerp.web_dashboard = function(openerp) {
|
||||||
var QWeb = openerp.web.qweb;
|
var QWeb = openerp.web.qweb;
|
||||||
QWeb.add_template('/web_dashboard/static/src/xml/web_dashboard.xml');
|
QWeb.add_template('/web_dashboard/static/src/xml/web_dashboard.xml');
|
||||||
|
|
||||||
|
if (!openerp.web_dashboard) {
|
||||||
|
/** @namespace */
|
||||||
|
openerp.web_dashboard = {};
|
||||||
|
}
|
||||||
|
|
||||||
openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
|
openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
|
||||||
init: function(view, node) {
|
init: function(view, node) {
|
||||||
this._super(view, node);
|
this._super(view, node);
|
||||||
|
@ -43,9 +48,6 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
//this.$element.find('a.oe-dashboard-action-rename').live('click', this.on_rename);
|
//this.$element.find('a.oe-dashboard-action-rename').live('click', this.on_rename);
|
||||||
this.$element.find('.oe-dashboard-action').live('mouseover mouseout', function(event) {
|
|
||||||
$(this).find('.oe-dashboard-action-header .ui-icon, .oe-dashboard-action-header .oe-dashboard-action-rename').toggle(event.type == 'mouseover');
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
on_undo: function() {
|
on_undo: function() {
|
||||||
this.rpc('/web/view/undo_custom', {
|
this.rpc('/web/view/undo_custom', {
|
||||||
|
@ -217,6 +219,8 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
on_load_action: function(result) {
|
on_load_action: function(result) {
|
||||||
|
var self = this;
|
||||||
|
var action_orig = _.extend({}, result.result);
|
||||||
var action = result.result;
|
var action = result.result;
|
||||||
action.flags = {
|
action.flags = {
|
||||||
search_view : false,
|
search_view : false,
|
||||||
|
@ -224,12 +228,21 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
|
||||||
views_switcher : false,
|
views_switcher : false,
|
||||||
action_buttons : false,
|
action_buttons : false,
|
||||||
pager: false,
|
pager: false,
|
||||||
low_profile: true
|
low_profile: true,
|
||||||
|
display_title: false
|
||||||
};
|
};
|
||||||
var am = new openerp.web.ActionManager(this);
|
var am = new openerp.web.ActionManager(this);
|
||||||
this.action_managers.push(am);
|
this.action_managers.push(am);
|
||||||
am.appendTo($("#"+this.view.element_id + '_action_' + action.id));
|
am.appendTo($("#"+this.view.element_id + '_action_' + action.id));
|
||||||
am.do_action(action);
|
am.do_action(action);
|
||||||
|
am.do_action = function(action) {
|
||||||
|
self.do_action(action);
|
||||||
|
}
|
||||||
|
if (am.inner_viewmanager) {
|
||||||
|
am.inner_viewmanager.on_mode_switch.add(function(mode) {
|
||||||
|
self.do_action(action_orig);
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
// We should start with three columns available
|
// We should start with three columns available
|
||||||
|
@ -243,12 +256,10 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
|
||||||
return QWeb.render(this.template, this);
|
return QWeb.render(this.template, this);
|
||||||
},
|
},
|
||||||
do_reload: function() {
|
do_reload: function() {
|
||||||
_.each(this.action_managers, function(am) {
|
var view_manager = this.view.widget_parent,
|
||||||
am.stop();
|
action_manager = view_manager.widget_parent;
|
||||||
});
|
|
||||||
this.action_managers = [];
|
|
||||||
this.view.stop();
|
this.view.stop();
|
||||||
this.view.start();
|
action_manager.do_action(view_manager.action);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
openerp.web.form.DashBoardLegacy = openerp.web.form.DashBoard.extend({
|
openerp.web.form.DashBoardLegacy = openerp.web.form.DashBoard.extend({
|
||||||
|
@ -279,20 +290,19 @@ openerp.web.form.widgets.add('hpaned', 'openerp.web.form.DashBoardLegacy');
|
||||||
openerp.web.form.widgets.add('vpaned', 'openerp.web.form.DashBoardLegacy');
|
openerp.web.form.widgets.add('vpaned', 'openerp.web.form.DashBoardLegacy');
|
||||||
openerp.web.form.widgets.add('board', 'openerp.web.form.DashBoard');
|
openerp.web.form.widgets.add('board', 'openerp.web.form.DashBoard');
|
||||||
|
|
||||||
openerp.web.client_actions.add(
|
/*
|
||||||
'board.config.overview', 'openerp.web_dashboard.ConfigOverview'
|
* ConfigOverview
|
||||||
);
|
* This client action designed to be used as a dashboard widget display
|
||||||
if (!openerp.web_dashboard) {
|
* ir.actions.todo in a fancy way
|
||||||
/** @namespace */
|
*/
|
||||||
openerp.web_dashboard = {};
|
openerp.web.client_actions.add( 'board.config.overview', 'openerp.web_dashboard.ConfigOverview');
|
||||||
}
|
|
||||||
openerp.web_dashboard.ConfigOverview = openerp.web.View.extend({
|
openerp.web_dashboard.ConfigOverview = openerp.web.View.extend({
|
||||||
template: 'ConfigOverview',
|
template: 'ConfigOverview',
|
||||||
init: function (parent) {
|
init: function (parent) {
|
||||||
this._super(parent);
|
this._super(parent);
|
||||||
this.dataset = new openerp.web.DataSetSearch(
|
this.dataset = new openerp.web.DataSetSearch(
|
||||||
this, 'ir.actions.todo');
|
this, 'ir.actions.todo');
|
||||||
this.dataset.domain = [['type', '=', 'manual']];
|
this.dataset.domain = [['type', '!=', 'automatic']];
|
||||||
},
|
},
|
||||||
start: function () {
|
start: function () {
|
||||||
this._super();
|
this._super();
|
||||||
|
@ -301,7 +311,7 @@ openerp.web_dashboard.ConfigOverview = openerp.web.View.extend({
|
||||||
.then(this.on_records_loaded);
|
.then(this.on_records_loaded);
|
||||||
},
|
},
|
||||||
on_records_loaded: function (read_response, progress_response) {
|
on_records_loaded: function (read_response, progress_response) {
|
||||||
var records = read_response[0].records,
|
var records = read_response,
|
||||||
progress = progress_response[0];
|
progress = progress_response[0];
|
||||||
|
|
||||||
var grouped_todos = _(records).chain()
|
var grouped_todos = _(records).chain()
|
||||||
|
@ -348,35 +358,146 @@ openerp.web_dashboard.ConfigOverview = openerp.web.View.extend({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
openerp.web.client_actions.add(
|
/*
|
||||||
'board.home.applications', 'openerp.web_dashboard.ApplicationTiles');
|
* ApplicationTiles
|
||||||
|
* This client action designed to be used as a dashboard widget display
|
||||||
|
* either a list of application to install (if none is installed yet) or
|
||||||
|
* a list of root menu
|
||||||
|
*/
|
||||||
|
openerp.web.client_actions.add( 'board.home.applications', 'openerp.web_dashboard.ApplicationTiles');
|
||||||
|
openerp.web_dashboard.apps = {
|
||||||
|
applications: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
module: 'crm', name: 'CRM',
|
||||||
|
help: "Acquire leads, follow opportunities, manage prospects and phone calls, \u2026"
|
||||||
|
}, {
|
||||||
|
module: 'sale', name: 'Sales',
|
||||||
|
help: "Do quotations, follow sales orders, invoice and control deliveries"
|
||||||
|
}, {
|
||||||
|
module: 'account_voucher', name: 'Invoicing',
|
||||||
|
help: "Send invoice, track payments and reminders"
|
||||||
|
}, {
|
||||||
|
module: 'point_of_sale', name: 'Point of Sales',
|
||||||
|
help: "Manage shop sales, use touch-screen POS"
|
||||||
|
}
|
||||||
|
], [
|
||||||
|
{
|
||||||
|
module: 'purchase', name: 'Purchase',
|
||||||
|
help: "Do purchase orders, control invoices and reception, follow your suppliers, \u2026"
|
||||||
|
}, {
|
||||||
|
module: 'stock', name: 'Warehouse',
|
||||||
|
help: "Track your stocks, schedule product moves, manage incoming and outgoing shipments, \u2026"
|
||||||
|
}, {
|
||||||
|
module: 'mrp', name: 'Manufacturing',
|
||||||
|
help: "Manage your manufacturing, control your supply chain, personalize master data, \u2026"
|
||||||
|
}, {
|
||||||
|
module: 'account_accountant', name: 'Accounting and Finance',
|
||||||
|
help: "Record financial operations, automate followup, manage multi-currency, \u2026"
|
||||||
|
}
|
||||||
|
], [
|
||||||
|
{
|
||||||
|
module: 'project', name: 'Projects',
|
||||||
|
help: "Manage projects, track tasks, invoice task works, follow issues, \u2026"
|
||||||
|
}, {
|
||||||
|
module: 'hr', name: 'Human Resources',
|
||||||
|
help: "Manage employees and their contracts, follow laves, recruit people, \u2026"
|
||||||
|
}, {
|
||||||
|
module: 'marketing', name: 'Marketing',
|
||||||
|
help: "Manage campaigns, follow activities, automate emails, \u2026"
|
||||||
|
}, {
|
||||||
|
module: 'knowledge', name: 'Knowledge',
|
||||||
|
help: "Track your documents, browse your files, \u2026"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
};
|
||||||
openerp.web_dashboard.ApplicationTiles = openerp.web.View.extend({
|
openerp.web_dashboard.ApplicationTiles = openerp.web.View.extend({
|
||||||
template: 'ApplicationTiles',
|
template: 'ApplicationTiles',
|
||||||
start: function () {
|
start: function () {
|
||||||
this._super();
|
|
||||||
var self = this;
|
var self = this;
|
||||||
return new openerp.web.DataSetSearch(
|
this._super();
|
||||||
this, 'ir.ui.menu', null, [['parent_id', '=', false]])
|
// Check for installed application
|
||||||
.read_slice( ['name', 'web_icon_data', 'web_icon_hover_data'], {}, function (applications) {
|
var Installer = new openerp.web.DataSet(this, 'base.setup.installer');
|
||||||
// Create a matrix of 3*x applications
|
Installer.call('default_get', [], function (installed_modules) {
|
||||||
var rows = [];
|
var installed = _(installed_modules).any(function (active, name) {
|
||||||
while (applications.length) {
|
return _.startsWith(name, 'cat') && active; });
|
||||||
rows.push(applications.splice(0, 3));
|
|
||||||
|
if(installed) {
|
||||||
|
self.do_display_root_menu();
|
||||||
|
} else {
|
||||||
|
self.do_display_installer();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
do_display_root_menu: function() {
|
||||||
|
var self = this;
|
||||||
|
var dss = new openerp.web.DataSetSearch( this, 'ir.ui.menu', null, [['parent_id', '=', false]]);
|
||||||
|
var r = dss.read_slice( ['name', 'web_icon_data', 'web_icon_hover_data'], {}, function (applications) {
|
||||||
|
// Create a matrix of 3*x applications
|
||||||
|
var rows = [];
|
||||||
|
while (applications.length) {
|
||||||
|
rows.push(applications.splice(0, 3));
|
||||||
|
}
|
||||||
|
var tiles = QWeb.render( 'ApplicationTiles.content', {rows: rows});
|
||||||
|
self.$element.append(tiles)
|
||||||
|
.find('.oe-dashboard-home-tile')
|
||||||
|
.click(function () {
|
||||||
|
openerp.webclient.menu.on_menu_click(null, $(this).data('menuid'))
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return r;
|
||||||
|
},
|
||||||
|
do_display_installer: function() {
|
||||||
|
var self = this;
|
||||||
|
var render_ctx = {
|
||||||
|
url: window.location.protocol + '//' + window.location.host + window.location.pathname,
|
||||||
|
session: self.session,
|
||||||
|
rows: openerp.web_dashboard.apps.applications
|
||||||
|
};
|
||||||
|
var installer = QWeb.render('StaticHome', render_ctx);
|
||||||
|
self.$element.append(installer);
|
||||||
|
this.$element.delegate('.oe-static-home-tile-text button', 'click', function () {
|
||||||
|
self.install_module($(this).val());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
install_module: function (module_name) {
|
||||||
|
var self = this;
|
||||||
|
var Modules = new openerp.web.DataSetSearch(
|
||||||
|
this, 'ir.module.module', null,
|
||||||
|
[['name', '=', module_name], ['state', '=', 'uninstalled']]);
|
||||||
|
var Upgrade = new openerp.web.DataSet(this, 'base.module.upgrade');
|
||||||
|
|
||||||
|
$.blockUI({message:'<img src="/web/static/src/img/throbber2.gif">'});
|
||||||
|
Modules.read_slice(['id'], {}, function (records) {
|
||||||
|
if (!(records.length === 1)) { $.unblockUI(); return; }
|
||||||
|
Modules.call('state_update',
|
||||||
|
[_.pluck(records, 'id'), 'to install', ['uninstalled']],
|
||||||
|
function () {
|
||||||
|
Upgrade.call('upgrade_module', [[]], function () {
|
||||||
|
self.run_configuration_wizards();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
self.$element
|
)
|
||||||
.append(QWeb.render(
|
});
|
||||||
'ApplicationTiles.content', {rows: rows}))
|
},
|
||||||
.find('.oe-dashboard-home-tile')
|
run_configuration_wizards: function () {
|
||||||
.click(function () {
|
var self = this;
|
||||||
var $this = $(this);
|
new openerp.web.DataSet(this, 'res.config').call('start', [[]], function (action) {
|
||||||
$this.closest('.openerp')
|
$.unblockUI();
|
||||||
.find('.menu a[data-menu=' + $this.data('menuid') + ']')
|
self.widget_parent.widget_parent.do_action(action, function () {
|
||||||
.click();});
|
openerp.webclient.do_reload();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
openerp.web.client_actions.add(
|
|
||||||
'board.home.widgets', 'openerp.web_dashboard.Widget');
|
/*
|
||||||
|
* Widgets
|
||||||
|
* This client action designed to be used as a dashboard widget display
|
||||||
|
* the html content of a res_widget given as argument
|
||||||
|
*/
|
||||||
|
openerp.web.client_actions.add( 'board.home.widgets', 'openerp.web_dashboard.Widget');
|
||||||
openerp.web_dashboard.Widget = openerp.web.View.extend(/** @lends openerp.web_dashboard.Widgets# */{
|
openerp.web_dashboard.Widget = openerp.web.View.extend(/** @lends openerp.web_dashboard.Widgets# */{
|
||||||
template: 'HomeWidget',
|
template: 'HomeWidget',
|
||||||
/**
|
/**
|
||||||
|
@ -410,4 +531,5 @@ openerp.web_dashboard.Widget = openerp.web.View.extend(/** @lends openerp.web_da
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,8 +30,10 @@
|
||||||
</t>
|
</t>
|
||||||
<t t-name="DashBoard.action">
|
<t t-name="DashBoard.action">
|
||||||
<div t-att-data-id="action.attrs.name" class="oe-dashboard-action">
|
<div t-att-data-id="action.attrs.name" class="oe-dashboard-action">
|
||||||
<h2 class="oe-dashboard-action-header oe_view_title">
|
<h2 t-attf-class="oe-dashboard-action-header oe_view_title #{action.attrs.string ? '' : 'oe-dashboard-action-header-empty'}">
|
||||||
<input class="oe-dashboard-action-input" type="text" name="title" value="" style="display: none"/>
|
<input class="oe-dashboard-action-input" type="text" name="title" value="" style="display: none"/>
|
||||||
|
<t t-esc="action.attrs.string"/>
|
||||||
|
<t t-if="!action.attrs.string">&nbsp;</t>
|
||||||
<span class='ui-icon ui-icon-closethick'></span>
|
<span class='ui-icon ui-icon-closethick'></span>
|
||||||
<span class='ui-icon ui-icon-minusthick oe-dashboard-fold' t-if="!action.attrs.fold"></span>
|
<span class='ui-icon ui-icon-minusthick oe-dashboard-fold' t-if="!action.attrs.fold"></span>
|
||||||
<span class='ui-icon ui-icon-plusthick oe-dashboard-fold' t-if="action.attrs.fold"></span>
|
<span class='ui-icon ui-icon-plusthick oe-dashboard-fold' t-if="action.attrs.fold"></span>
|
||||||
|
@ -110,4 +112,36 @@
|
||||||
<h3><t t-esc="widget.title"/></h3>
|
<h3><t t-esc="widget.title"/></h3>
|
||||||
<iframe width="100%" frameborder="0" t-att-src="url"/>
|
<iframe width="100%" frameborder="0" t-att-src="url"/>
|
||||||
</t>
|
</t>
|
||||||
|
<div t-name="StaticHome" class="oe-static-home">
|
||||||
|
<h1>Welcome to your new OpenERP instance.</h1>
|
||||||
|
<div class="oe-static-home-banner">
|
||||||
|
<li>Remember to bookmark this page.</li>
|
||||||
|
<li>Remember your login: <i><t t-esc="session.login"/></i></li>
|
||||||
|
<li>Choose the first OpenERP Application you want to install..</li>
|
||||||
|
</div>
|
||||||
|
<div class="oe-static-home-tiles">
|
||||||
|
<table width="100%">
|
||||||
|
<tr t-foreach="rows" t-as="row">
|
||||||
|
<td t-foreach="row" t-as="application" width="25%">
|
||||||
|
<table class="oe-static-home-tile">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div class="oe-static-home-tile-logo">
|
||||||
|
<img t-att-src="'/web_dashboard/static/src/img/installer_' + application.module + '.png'"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="oe-static-home-tile-text">
|
||||||
|
<h2><t t-esc="application.name"/></h2>
|
||||||
|
<p><t t-esc="application.help"/></p>
|
||||||
|
<button type="button" t-att-value="application.module"> Install</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|