[MERGE]Merge main branch upto revision 1488.

bzr revid: kch@tinyerp.com-20111116132920-isodqm71wdzpm7av
This commit is contained in:
Kunal Chavda (OpenERP)
2011-11-16 18:59:20 +05:30
191 changed files with 20065 additions and 3667 deletions
+1 -2
View File
@@ -1,6 +1,5 @@
import common
import controllers
import common.dispatch
import logging
import optparse
@@ -22,6 +21,6 @@ def wsgi_postload():
o.serve_static = True
o.backend = 'local'
app = common.dispatch.Root(o)
app = common.http.Root(o)
openerp.wsgi.register_wsgi_handler(app)
+9
View File
@@ -1,5 +1,6 @@
{
"name" : "web",
"category" : "Hidden",
"depends" : [],
'active': True,
'post_load' : 'wsgi_postload',
@@ -10,6 +11,7 @@
"static/lib/datejs/sugarpak.js",
"static/lib/datejs/extras.js",
"static/lib/jquery/jquery-1.6.2.js",
"static/lib/jquery.MD5/jquery.md5.js",
"static/lib/jquery.form/jquery.form.js",
"static/lib/jquery.validate/jquery.validate.js",
"static/lib/jquery.ba-bbq/jquery.ba-bbq.js",
@@ -21,6 +23,8 @@
"static/lib/jquery.ui/js/jquery-ui-timepicker-addon.js",
"static/lib/jquery.ui.notify/js/jquery.notify.js",
"static/lib/jquery.deferred-queue/jquery.deferred-queue.js",
"static/lib/jquery.scrollTo/jquery.scrollTo-min.js",
"static/lib/jquery.tipTip/jquery.tipTip.js",
"static/lib/json/json2.js",
"static/lib/qweb/qweb2.js",
"static/lib/underscore/underscore.js",
@@ -41,13 +45,18 @@
"static/src/js/view_list.js",
"static/src/js/view_list_editable.js",
"static/src/js/view_tree.js",
"static/src/js/view_editor.js"
],
'css' : [
"static/lib/jquery.superfish/css/superfish.css",
"static/lib/jquery.ui/css/smoothness/jquery-ui-1.8.9.custom.css",
"static/lib/jquery.ui.notify/css/ui.notify.css",
"static/lib/jquery.tipTip/tipTip.css",
"static/src/css/base.css",
"static/src/css/data_export.css",
"static/src/css/data_import.css",
],
'qweb' : [
"static/src/xml/*.xml",
],
}
+5 -1
View File
@@ -1,2 +1,6 @@
#!/usr/bin/python
from dispatch import *
import http
import nonliterals
import release
import session
import xml2json
-48
View File
@@ -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)
-88
View File
@@ -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)
-428
View File
@@ -1,428 +0,0 @@
#!/usr/bin/python
from __future__ import with_statement
import functools
import logging
import urllib
import os
import pprint
import sys
import traceback
import uuid
import xmlrpclib
import simplejson
import werkzeug.datastructures
import werkzeug.exceptions
import werkzeug.utils
import werkzeug.wrappers
import werkzeug.wsgi
import ast
import nonliterals
import http
import session
import openerplib
__all__ = ['Root', 'jsonrequest', 'httprequest', 'Controller',
'WebRequest', 'JsonRequest', 'HttpRequest']
_logger = logging.getLogger(__name__)
#-----------------------------------------------------------
# Globals (wont move into a pool)
#-----------------------------------------------------------
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:: 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):
_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 = '/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 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 = {}
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) > 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
+459 -2
View File
@@ -1,13 +1,286 @@
# -*- coding: utf-8 -*-
#----------------------------------------------------------
# OpenERP Web HTTP layer
#----------------------------------------------------------
import ast
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.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 = {}
@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)
if not session_store:
session_store = werkzeug.contrib.sessions.FilesystemSessionStore(
@@ -23,4 +296,188 @@ def session(request, storage_path, session_cookie='sessionid'):
try:
yield request.session
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)
#----------------------------------------------------------
# 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(request.args)
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
#
+20 -10
View File
@@ -21,12 +21,14 @@ class NonLiteralEncoder(simplejson.encoder.JSONEncoder):
if isinstance(object, Domain):
return {
'__ref': 'domain',
'__id': object.key
'__id': object.key,
'__debug': object.get_domain_string()
}
elif isinstance(object, Context):
return {
'__ref': 'context',
'__id': object.key
'__id': object.key,
'__debug': object.get_context_string()
}
elif isinstance(object, CompoundDomain):
return {
@@ -42,7 +44,7 @@ class NonLiteralEncoder(simplejson.encoder.JSONEncoder):
}
raise TypeError('Could not encode unknown non-literal %s' % object)
_ALLOWED_KEYS = frozenset(['__ref', "__id", '__domains',
_ALLOWED_KEYS = frozenset(['__ref', "__id", '__domains', '__debug',
'__contexts', '__eval_context', 'own_values'])
def non_literal_decoder(dct):
@@ -53,8 +55,8 @@ def non_literal_decoder(dct):
``own_values`` dict key.
"""
if '__ref' in dct:
for x in dct.keys():
if not x in _ALLOWED_KEYS:
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':
domain = Domain(None, key=dct['__id'])
@@ -131,7 +133,10 @@ class Domain(BaseDomain):
ctx = self.session.evaluation_context(context)
if 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):
def __init__(self, session, context_string=None, key=None):
@@ -176,7 +181,10 @@ class Context(BaseContext):
ctx = self.session.evaluation_context(context)
if 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):
def __getattr__(self, name):
@@ -199,6 +207,11 @@ class CompoundDomain(BaseDomain):
self.add(domain)
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 = []
for domain in self.domains:
if not isinstance(domain, (list, BaseDomain)):
@@ -208,9 +221,6 @@ class CompoundDomain(BaseDomain):
if isinstance(domain, list):
final_domain.extend(domain)
continue
ctx = dict(context or {})
ctx.update(self.get_eval_context() or {})
domain.session = self.session
final_domain.extend(domain.evaluate(ctx))
+69 -10
View File
@@ -55,6 +55,33 @@ _logger = logging.getLogger(__name__)
def _getChildLogger(logger, 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):
"""
The base abstract class representing a connection to an OpenERP Server.
@@ -99,8 +126,21 @@ class XmlRPCConnector(Connector):
def send(self, service_name, method, *args):
url = '%s/%s' % (self.url, service_name)
service = xmlrpclib.ServerProxy(url)
# TODO should try except and wrap exception into LibException
return getattr(service, method)(*args)
class XmlRPCSConnector(XmlRPCConnector):
"""
A type of connector that uses the secured XMLRPC protocol.
"""
PROTOCOL = 'xmlrpcs'
__logger = _getChildLogger(_logger, 'connector.xmlrpcs')
def __init__(self, hostname, port=8071):
super(XmlRPCSConnector, self).__init__(hostname, port)
self.url = 'https://%s:%d/xmlrpc' % (self.hostname, self.port)
class NetRPC_Exception(Exception):
"""
Exception for NetRPC errors.
@@ -212,18 +252,34 @@ class LocalConnector(Connector):
def send(self, service_name, method, *args):
import openerp
# TODO Exception handling
# This will be changed to be xmlrpc compatible
# OpenERPWarning code 1
# OpenERPException code 2
import traceback
try:
result = openerp.netsvc.dispatch_rpc(service_name, method, args)
except:
exc_type, exc_value, exc_tb = sys.exc_info()
fault = xmlrpclib.Fault(1, "%s:%s" % (exc_type, exc_value))
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):
"""
A class to execute RPC calls on a specific service of the remote server.
@@ -306,7 +362,7 @@ class Connection(object):
return
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)
if not self.user_id:
@@ -394,6 +450,7 @@ class Model(object):
:return: A list of dictionaries containing all the specified fields.
"""
record_ids = self.search(domain or [], offset, limit or False, order or False, context or {})
if not record_ids: return []
records = self.read(record_ids, fields or [], context or {})
return records
@@ -406,15 +463,17 @@ def get_connector(hostname=None, protocol="xmlrpc", port="auto"):
:param port: The number of the port. Defaults to auto.
"""
if port == 'auto':
port = 8069 if protocol=="xmlrpc" else 8070
port = 8069 if protocol=="xmlrpc" else (8070 if protocol == "netrpc" else 8071)
if protocol == "xmlrpc":
return XmlRPCConnector(hostname, port)
elif protocol == "xmlrpcs":
return XmlRPCSConnector(hostname, port)
elif protocol == "netrpc":
return NetRPCConnector(hostname, port)
elif protocol == "local":
return LocalConnector()
else:
raise ValueError("You must choose xmlrpc or netrpc or local")
raise ValueError("You must choose xmlrpc(s), netrpc or local")
def get_connection(hostname=None, protocol="xmlrpc", port='auto', database=None,
login=None, password=None, user_id=None):
+1 -2
View File
@@ -1,17 +1,16 @@
#!/usr/bin/python
import datetime
import dateutil.relativedelta
import logging
import time
import openerplib
import nonliterals
import logging
_logger = logging.getLogger(__name__)
#----------------------------------------------------------
# OpenERPSession RPC openerp backend access
#----------------------------------------------------------
class OpenERPSession(object):
"""
An OpenERP RPC session, a given user can own multiple such sessions
+38
View File
@@ -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
+222 -170
View File
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import ast
import base64
import csv
import glob
@@ -8,103 +9,88 @@ import operator
import os
import re
import simplejson
import textwrap
import xmlrpclib
import time
import xmlrpclib
import zlib
from xml.etree import ElementTree
from cStringIO import StringIO
from babel.messages.pofile import read_po
import babel.messages.pofile
import web.common.dispatch as openerpweb
import web.common.ast
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
import web.common
openerpweb = web.common.http
#----------------------------------------------------------
# OpenERP Web web Controllers
#----------------------------------------------------------
# TODO change into concat_file(addons,key) taking care of addons_path
def concat_files(addons_path, file_list):
""" Concatenate file content
def concat_xml(file_list):
"""Concatenate xml files
return (concat,timestamp)
concat: concatenation of file content
timestamp: max(os.path.getmtime of file_list)
"""
files_content = []
root = None
files_timestamp = 0
for i in file_list:
fname = os.path.join(addons_path, i[1:])
for fname in file_list:
ftime = os.path.getmtime(fname)
if ftime > files_timestamp:
files_timestamp = ftime
files_content.append(open(fname).read())
xml = ElementTree.parse(fname).getroot()
if root is None:
root = ElementTree.Element(xml.tag)
#elif root.tag != xml.tag:
# raise ValueError("Root tags missmatch: %r != %r" % (root.tag, xml.tag))
for child in xml.getchildren():
root.append(child)
return ElementTree.tostring(root, 'utf-8'), files_timestamp
def concat_files(file_list, reader=None):
""" Concatenate file content
return (concat,timestamp)
concat: concatenation of file content, read by `reader`
timestamp: max(os.path.getmtime of file_list)
"""
if reader is None:
def reader(f):
with open(f) as fp:
return fp.read()
files_content = []
files_timestamp = 0
for fname in file_list:
ftime = os.path.getmtime(fname)
if ftime > files_timestamp:
files_timestamp = ftime
files_content.append(reader(fname))
files_concat = "".join(files_content)
return files_concat,files_timestamp
home_template = textwrap.dedent("""<!DOCTYPE html>
html_template = """<!DOCTYPE html>
<html style="height: 100%%">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>OpenERP</title>
<link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/>
%(css)s
%(javascript)s
%(js)s
<script type="text/javascript">
$(function() {
var c = new openerp.init(%(modules)s);
var wc = new c.web.WebClient("oe");
wc.start();
var s = new openerp.init(%(modules)s);
%(init)s
});
</script>
</head>
<body id="oe" class="openerp"></body>
</html>
""")
"""
class WebClient(openerpweb.Controller):
_cp_path = "/web/webclient"
@@ -113,62 +99,101 @@ class WebClient(openerpweb.Controller):
return addons
def manifest_glob(self, req, addons, key):
if addons==None:
if addons is None:
addons = self.server_wide_modules(req)
else:
addons = addons.split(',')
files = []
for addon in addons:
manifest = openerpweb.addons_manifest.get(addon, None)
if not manifest:
continue
addons_path = manifest['addons_path']
# 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.join(addons_path, addon, pattern)):
files.append(path[len(addons_path):])
return files
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
def csslist(self, req, mods=None):
return self.manifest_glob(req, mods, 'css')
return self.manifest_list(req, mods, 'css')
@openerpweb.jsonrequest
def jslist(self, req, mods=None):
return self.manifest_glob(req, mods, 'js')
return self.manifest_list(req, mods, 'js')
@openerpweb.jsonrequest
def qweblist(self, req, mods=None):
return self.manifest_list(req, mods, 'qweb')
@openerpweb.httprequest
def css(self, req, mods=None):
files = self.manifest_glob(req, mods, 'css')
content,timestamp = concat_files(req.config.addons_path, files)
# TODO request set the Date of last modif and Etag
files = list(self.manifest_glob(req, mods, 'css'))
file_map = dict(files)
rx_import = re.compile(r"""@import\s+('|")(?!'|"|/|https?://)""", re.U)
rx_url = re.compile(r"""url\s*\(\s*('|"|)(?!'|"|/|https?://)""", re.U)
def reader(f):
"""read the a css file and absolutify all relative uris"""
with open(f) as fp:
data = fp.read()
web_path = file_map[f]
web_dir = os.path.dirname(web_path)
data = re.sub(
rx_import,
r"""@import \1%s/""" % (web_dir,),
data,
)
data = re.sub(
rx_url,
r"""url(\1%s/""" % (web_dir,),
data,
)
return data
content,timestamp = concat_files((f[0] for f in files), reader)
# TODO use timestamp to set Last mofified date and E-tag
return req.make_response(content, [('Content-Type', 'text/css')])
@openerpweb.httprequest
def js(self, req, mods=None):
files = self.manifest_glob(req, mods, 'js')
content,timestamp = concat_files(req.config.addons_path, files)
# TODO request set the Date of last modif and Etag
files = [f[0] for f in self.manifest_glob(req, mods, 'js')]
content,timestamp = concat_files(files)
# TODO use timestamp to set Last mofified date and E-tag
return req.make_response(content, [('Content-Type', 'application/javascript')])
@openerpweb.httprequest
def qweb(self, req, mods=None):
files = [f[0] for f in self.manifest_glob(req, mods, 'qweb')]
content,timestamp = concat_xml(files)
# TODO use timestamp to set Last mofified date and E-tag
return req.make_response(content, [('Content-Type', 'text/xml')])
@openerpweb.httprequest
def home(self, req, s_action=None, **kw):
# script tags
jslist = ['/web/webclient/js']
if req.debug:
jslist = [i + '?debug=' + str(time.time()) for i in self.manifest_glob(req, None, 'js')]
js = "\n ".join(['<script type="text/javascript" src="%s"></script>'%i for i in jslist])
js = "\n ".join('<script type="text/javascript" src="%s"></script>'%i for i in self.manifest_list(req, None, 'js'))
css = "\n ".join('<link rel="stylesheet" href="%s">'%i for i in self.manifest_list(req, None, 'css'))
# css tags
csslist = ['/web/webclient/css']
if req.debug:
csslist = [i + '?debug=' + str(time.time()) for i in self.manifest_glob(req, None, 'css')]
css = "\n ".join(['<link rel="stylesheet" href="%s">'%i for i in csslist])
r = home_template % {
'javascript': js,
r = html_template % {
'js': js,
'css': css,
'modules': simplejson.dumps(self.server_wide_modules(req)),
'init': 'new s.web.WebClient("oe").start();',
}
return r
@@ -200,7 +225,7 @@ class WebClient(openerpweb.Controller):
continue
try:
with open(f_name) as t_file:
po = read_po(t_file)
po = babel.messages.pofile.read_po(t_file)
except:
continue
for x in po:
@@ -282,7 +307,7 @@ class Database(openerpweb.Controller):
@openerpweb.httprequest
def restore(self, req, db_file, restore_pwd, new_db):
try:
data = base64.b64encode(db_file.file.read())
data = base64.b64encode(db_file.read())
req.session.proxy("db").restore(restore_pwd, new_db, data)
return ''
except xmlrpclib.Fault, e:
@@ -358,13 +383,22 @@ class Session(openerpweb.Controller):
@openerpweb.jsonrequest
def modules(self, req):
# TODO query server for installed web modules
mods = []
for name, manifest in openerpweb.addons_manifest.items():
# TODO replace by ir.module.module installed web
if name not in req.config.server_wide_modules and manifest.get('active', True):
mods.append(name)
return mods
# Compute available candidates module
loadable = openerpweb.addons_manifest.iterkeys()
loaded = req.config.server_wide_modules
candidates = [mod for mod in loadable if mod not in loaded]
# 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
def eval_domain_and_context(self, req, contexts, domains,
@@ -399,8 +433,8 @@ class Session(openerpweb.Controller):
no group by should be performed)
"""
context, domain = eval_context_and_domain(req.session,
openerpweb.nonliterals.CompoundContext(*(contexts or [])),
openerpweb.nonliterals.CompoundDomain(*(domains or [])))
web.common.nonliterals.CompoundContext(*(contexts or [])),
web.common.nonliterals.CompoundDomain(*(domains or [])))
group_by_sequence = []
for candidate in (group_by_seq or []):
@@ -479,18 +513,24 @@ def load_actions_from_ir_values(req, key, key2, models, meta):
return [(id, name, clean_action(req, action))
for id, name, action in actions]
def clean_action(req, action):
def clean_action(req, action, do_not_eval=False):
action.setdefault('flags', {})
context = req.session.eval_context(req.context)
eval_ctx = req.session.evaluation_context(context)
# values come from the server, we can just eval them
if isinstance(action.get('context'), basestring):
action['context'] = eval( action['context'], eval_ctx ) or {}
if not do_not_eval:
# values come from the server, we can just eval them
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 []
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 'type' not in action:
action['type'] = 'ir.actions.act_window_close'
@@ -558,7 +598,7 @@ def fix_view_modes(action):
if 'views' not in action:
generate_views(action)
if action.pop('view_type') != 'form':
if action.pop('view_type', 'form') != 'form':
return action
action['views'] = [
@@ -817,16 +857,16 @@ class View(openerpweb.Controller):
xml = self.transform_view(arch, session, evaluation_context)
else:
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():
if field.get('views'):
for view in field["views"].itervalues():
self.process_view(session, view, None, transform)
if field.get('domain'):
field["domain"] = self.parse_domain(field["domain"], session)
field["domain"] = parse_domain(field["domain"], session)
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):
"""
@@ -838,10 +878,10 @@ class View(openerpweb.Controller):
for actions in toolbar.itervalues():
for action in actions:
if 'context' in action:
action['context'] = self.parse_context(
action['context'] = parse_context(
action['context'], req.session)
if 'domain' in action:
action['domain'] = self.parse_domain(
action['domain'] = parse_domain(
action['domain'], req.session)
@openerpweb.jsonrequest
@@ -880,39 +920,6 @@ class View(openerpweb.Controller):
self.parse_domains_and_contexts(elem, session)
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):
""" Converts domains and contexts from the view into Python objects,
either literals if they can be parsed by literal_eval or a special
@@ -927,16 +934,51 @@ class View(openerpweb.Controller):
for el in ['domain', 'filter_domain']:
domain = elem.get(el, '').strip()
if domain:
elem.set(el, self.parse_domain(domain, session))
elem.set(el, parse_domain(domain, session))
elem.set(el + '_string', domain)
for el in ['context', 'default_get']:
context_string = elem.get(el, '').strip()
if context_string:
elem.set(el, self.parse_context(context_string, session))
elem.set(el, parse_context(context_string, session))
elem.set(el + '_string', context_string)
@openerpweb.jsonrequest
def load(self, req, model, view_id, view_type, toolbar=False):
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):
_cp_path = "/web/listview"
@@ -982,9 +1024,9 @@ class SearchView(View):
for field in fields.values():
# shouldn't convert the views too?
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'):
field["context"] = self.parse_domain(field["context"], req.session)
field["context"] = parse_context(field["context"], req.session)
return {'fields': fields}
@openerpweb.jsonrequest
@@ -992,17 +1034,17 @@ class SearchView(View):
Model = req.session.model("ir.filters")
filters = Model.get_filters(model)
for filter in filters:
filter["context"] = req.session.eval_context(self.parse_context(filter["context"], req.session))
filter["domain"] = req.session.eval_domain(self.parse_domain(filter["domain"], req.session))
filter["context"] = req.session.eval_context(parse_context(filter["context"], req.session))
filter["domain"] = req.session.eval_domain(parse_domain(filter["domain"], req.session))
return filters
@openerpweb.jsonrequest
def save_filter(self, req, model, name, context_to_save, domain):
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 = ctx.evaluate()
domain = openerpweb.nonliterals.CompoundDomain(domain)
domain = web.common.nonliterals.CompoundDomain(domain)
domain.session = req.session
domain = domain.evaluate()
uid = req.session._uid
@@ -1025,23 +1067,27 @@ class Binary(openerpweb.Controller):
try:
if not id:
res = Model.default_get([field], context).get(field, '')
res = Model.default_get([field], context).get(field)
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)
except (TypeError, xmlrpclib.Fault):
image_data = self.placeholder(req)
return req.make_response(image_data, [
('Content-Type', 'image/png'), ('Content-Length', len(image_data))])
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
def saveas(self, req, model, id, field, fieldname, **kw):
Model = req.session.model(model)
context = req.session.eval_context(req.context)
res = Model.read([int(id)], [field, fieldname], context)[0]
filecontent = res.get(field, '')
if id:
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:
return req.not_found()
else:
@@ -1105,7 +1151,7 @@ class Action(openerpweb.Controller):
_cp_path = "/web/action"
@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')
value = False
context = req.session.eval_context(req.context)
@@ -1117,7 +1163,7 @@ class Action(openerpweb.Controller):
ctx.update(context)
action = req.session.model(action_type[0]['type']).read([action_id], False, ctx)
if action:
value = clean_action(req, action[0])
value = clean_action(req, action[0], do_not_eval)
return {'result': value}
@openerpweb.jsonrequest
@@ -1149,19 +1195,26 @@ class Export(View):
@openerpweb.jsonrequest
def get_fields(self, req, model, prefix='', parent_name= '',
import_compat=True, parent_field_type=None):
import_compat=True, parent_field_type=None,
exclude=None):
if import_compat and parent_field_type == "many2one":
fields = {}
else:
fields = self.fields_get(req, model)
fields['.id'] = fields.pop('id') if 'id' in fields else {'string': 'ID'}
if import_compat:
fields.pop('id', None)
else:
fields['.id'] = fields.pop('id', {'string': 'ID'})
fields_sequence = sorted(fields.iteritems(),
key=lambda field: field[1].get('string', ''))
records = []
for field_name, field in fields_sequence:
if import_compat and (exclude and field_name in exclude):
continue
if import_compat and field.get('readonly'):
# If none of the field's states unsets readonly, skip the field
if all(dict(attrs).get('readonly', True)
@@ -1173,7 +1226,8 @@ class Export(View):
record = {'id': id, 'string': name,
'value': id, 'children': False,
'field_type': field.get('type'),
'required': field.get('required')}
'required': field.get('required'),
'relation_field': field.get('relation_field')}
records.append(record)
if len(name.split('/')) < 3 and 'relation' in field:
@@ -1205,7 +1259,6 @@ class Export(View):
def fields_info(self, req, model, export_fields):
info = {}
fields = self.fields_get(req, model)
fields['.id'] = fields.pop('id') if 'id' in fields else {'string': 'ID'}
# To make fields retrieval more efficient, fetch all sub-fields of a
# given field at the same time. Because the order in the export list is
@@ -1366,6 +1419,7 @@ class ExcelExport(Export):
for cell_index, cell_value in enumerate(row):
if isinstance(cell_value, basestring):
cell_value = re.sub("\r", " ", cell_value)
if cell_value is False: cell_value = None
worksheet.write(row_index + 1, cell_index, cell_value, style)
fp = StringIO()
@@ -1393,7 +1447,7 @@ class Reports(View):
report_srv = req.session.proxy("report")
context = req.session.eval_context(
openerpweb.nonliterals.CompoundContext(
web.common.nonliterals.CompoundContext(
req.context or {}, action[ "context"]))
report_data = {}
@@ -1401,10 +1455,9 @@ class Reports(View):
if 'report_type' in action:
report_data['report_type'] = action['report_type']
if 'datas' in action:
if 'form' in action['datas']:
report_data['form'] = action['datas']['form']
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(
req.session._db, req.session._uid, req.session._password,
@@ -1432,7 +1485,6 @@ class Reports(View):
('Content-Length', len(report))],
cookies={'fileToken': int(token)})
class Import(View):
_cp_path = "/web/import"
@@ -1442,7 +1494,7 @@ class Import(View):
return fields
@openerpweb.httprequest
def detect_data(self, req, csvfile, csvsep, csvdel, csvcode, jsonp):
def detect_data(self, req, csvfile, csvsep=',', csvdel='"', csvcode='utf-8', jsonp='callback'):
try:
data = list(csv.reader(
csvfile, quotechar=str(csvdel), delimiter=str(csvsep)))
+699
View File
@@ -0,0 +1,699 @@
# Arabic 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-11-08 05:44+0000\n"
"Last-Translator: Ahmad Khayyat <Unknown>\n"
"Language-Team: Arabic <ar@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-11-09 05:09+0000\n"
"X-Generator: Launchpad (build 14263)\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 "<em>    مزيداً من البحث...</em>"
#: addons/web/static/src/js/view_form.js:1672
#, python-format
msgid "<em>   Create \"<strong>%s</strong>\"</em>"
msgstr "<em>   إنشاء \"<strong>%s</strong>\"</em>"
#: addons/web/static/src/js/view_form.js:1678
msgid "<em>   Create and Edit...</em>"
msgstr "<em>   إنشاء و تحرير...</em>"
#: 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"
msgstr "ترجمات"
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
msgid "Save"
msgstr "حفظ"
#: addons/web/static/src/js/views.js:615
msgid "Close"
msgstr "إغلاق"
#: 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 "#{text}"
#: addons/web/static/src/xml/base.xml:0
msgid "Powered by"
msgstr "مدعوم من kifcaliph و"
#: 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 "جاري التحميل..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create"
msgstr "إنشاء"
#: addons/web/static/src/xml/base.xml:0
msgid "Drop"
msgstr "إزالة"
#: addons/web/static/src/xml/base.xml:0
msgid "Backup"
msgstr "نسخة إحتياطية"
#: addons/web/static/src/xml/base.xml:0
msgid "Restore"
msgstr "استرجاع"
#: addons/web/static/src/xml/base.xml:0
msgid "Password"
msgstr "كلمة المرور"
#: 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 "اسم قاعدة البيانات الجديدة:"
#: 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 "اللغة الافتراضية:"
#: addons/web/static/src/xml/base.xml:0
msgid "Admin password:"
msgstr "كلمة مرور المشرف العام:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm password:"
msgstr "تأكيد كلمة المرور:"
#: addons/web/static/src/xml/base.xml:0
msgid "DROP DATABASE"
msgstr "إسقاط قاعدة البيانات"
#: addons/web/static/src/xml/base.xml:0
msgid "Database:"
msgstr "قاعدة البيانات:"
#: 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 "ملف:"
#: 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 "مستخدم:"
#: addons/web/static/src/xml/base.xml:0
msgid "Password:"
msgstr "كلمة المرور:"
#: addons/web/static/src/xml/base.xml:0
msgid "Database"
msgstr "قاعدة بيانات"
#: 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 "اسم مستخدم او كلمة مرور خاطئة"
#: 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 "رؤي برنامج OpenERP هي:"
#: 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 "تسجيل الخروج"
#: addons/web/static/src/xml/base.xml:0
msgid "&laquo;"
msgstr "&laquo;"
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
msgstr "&raquo;"
#: 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 "إخفاء هذه الملحوظة"
#: addons/web/static/src/xml/base.xml:0
msgid "Disable all tips"
msgstr "تعطيل جميع الإرشادات"
#: addons/web/static/src/xml/base.xml:0
msgid "View#"
msgstr "View#"
#: 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 "حذف"
#: addons/web/static/src/xml/base.xml:0
msgid "First"
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 "Last"
msgstr "الأخير"
#: addons/web/static/src/xml/base.xml:0
msgid "♻"
msgstr "♻"
#: addons/web/static/src/xml/base.xml:0
msgid "Save & Edit"
msgstr "حفظ و تحرير"
#: addons/web/static/src/xml/base.xml:0
msgid "Create & Edit"
msgstr "إنشاء و تحرير"
#: addons/web/static/src/xml/base.xml:0
msgid "New"
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
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 "تم"
#: addons/web/static/src/xml/base.xml:0
msgid "Open..."
msgstr "فتح..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create..."
msgstr "إنشاء..."
#: 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 ""
"هذا المعالج سيقوم بتصدير كافة البيانات التي تطابق شروط البحث الحالية لملف "
"CSV.\n"
" يمكنك تصدير كل البيانات أو الحقول التي يمكن إستيرادها بعد "
"التعديل."
#: 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 "&nbsp;"
msgstr "&nbsp;"
#: 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 "إستيراد ملف .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 ""
"اختر ملف .CSV للإستيراد. إذا كنت بحاجة إلى عينة ملف للاستيراد،\n"
" يجب عليك إستخدام أداة تصدير مع الخيار \" Compatible\" option."
#: addons/web/static/src/xml/base.xml:0
msgid "CSV File:"
msgstr "ملف CSV :"
#: 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 "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 "OpenERP عبر الإنترنت"
#: 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 "جميع حقوق النشر محفوظة لـ © 2011-TODAY OpenERP SA."
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP is a trademark of the"
msgstr "OpenERP هي علامة تجارية لـ"
#: 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 "النظام مرخص بشروط"
#: 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 "عن 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 ""
"هو نظام حر يناسب المؤسسات و الشركات و تم تصميمه لتعزيز\n"
" الإنتاجية و الربح من خلال تكامل البيانات. فيمكنك من ربط، و "
"تحسين، و\n"
" إدارة العمليات التجارية في إدارات مثل المبيعات، المحاسبة "
"المالية، المخازن،\n"
" إدارة المشروعات، الإنتاج و العمليات الصناعية، و القطاع الخدمي، , "
"إدارة علاقات العملاء..."
#: 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 ""
"يعمل البرنامج مع العديد من الأنظمة مثل Windows، و Mac OS X، و\n"
" معظم أنظمة لينكس بالإضافة إلي اليونكس. فلقد تم تصميمه ليتيح "
"إمكانية\n"
" إضافة وظائف أخري له بسهولة، و برمجته و تعديله بسرعه ليلائم "
"الواقع العملي\n"
" كما أنه يتيح سهولة نقل البيانات من إصدار إلي إصدار."
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Depending on your needs, OpenERP is available through a web or application "
"client."
msgstr ""
"حسب إحتياجاتك، نظام OpenERP متاح من خلال تطبيق الويب أو البرنامج المحلي."
+707
View File
@@ -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-11-08 21:58+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-11-09 05:09+0000\n"
"X-Generator: Launchpad (build 14263)\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 "&laquo;"
msgstr "&laquo;"
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
msgstr "&raquo;"
#: 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 "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 "&nbsp;"
msgstr "&nbsp;"
#: 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."
+708
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "&laquo;"
msgstr "&laquo;"
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
msgstr "&raquo;"
#: 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 "&nbsp;"
msgstr "&nbsp;"
#: 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."
+710
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "&laquo;"
msgstr "&laquo;"
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
msgstr "&raquo;"
#: 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 "&nbsp;"
msgstr "&nbsp;"
#: 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."
+710
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "&laquo;"
msgstr "&laquo;"
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
msgstr "&raquo;"
#: 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 "&nbsp;"
msgstr "&nbsp;"
#: 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."
+677
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "&laquo;"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
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 "&nbsp;"
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 ""
+678
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "&laquo;"
msgstr "&laquo;"
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
msgstr "&raquo;"
#: 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 "&nbsp;"
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 ""
+709
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "&laquo;"
msgstr "&laquo;"
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
msgstr "&raquo;"
#: 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 "&nbsp;"
msgstr "&nbsp;"
#: 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."
+689
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "&laquo;"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
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 "&nbsp;"
msgstr "&nbsp;"
#: 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."
+689
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "&laquo;"
msgstr "&laquo;"
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
msgstr "&raquo;"
#: 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 "&nbsp;"
msgstr "&nbsp;"
#: 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."
+687
View File
@@ -0,0 +1,687 @@
# Polish 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-11-04 16:44+0000\n"
"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
"Language-Team: Polish <pl@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-11-05 06:04+0000\n"
"X-Generator: Launchpad (build 14231)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
"Warning, the record has been modified, your changes will be discarded."
msgstr "Uwaga, rekord został zmodyfikowany, twoje zmiany zostaną odrzucone."
#: addons/web/static/src/js/view_form.js:1659
msgid "<em>   Search More...</em>"
msgstr "<em>   Szukaj dalej...</em>"
#: addons/web/static/src/js/view_form.js:1672
#, python-format
msgid "<em>   Create \"<strong>%s</strong>\"</em>"
msgstr "<em>   Utwórz \"<strong>%s</strong>\"</em>"
#: addons/web/static/src/js/view_form.js:1678
msgid "<em>   Create and Edit...</em>"
msgstr "<em>   Utwórz i edytuj...</em>"
#: addons/web/static/src/js/views.js:568
msgid "You must choose at least one record."
msgstr "Musisz wybrac co najmniej jeden rekord."
#: addons/web/static/src/js/views.js:569
msgid "Warning"
msgstr "Ostrzeżenie"
#: addons/web/static/src/js/views.js:609
msgid "Translations"
msgstr "Tłumaczenia"
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
msgid "Save"
msgstr "Zapisz"
#: addons/web/static/src/js/views.js:615
msgid "Close"
msgstr "Zamknij"
#: 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 "Wczytywanie..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create"
msgstr "Utwórz"
#: addons/web/static/src/xml/base.xml:0
msgid "Drop"
msgstr "Usuń bazę danych"
#: addons/web/static/src/xml/base.xml:0
msgid "Backup"
msgstr "Kopia zapasowa bazy danych"
#: addons/web/static/src/xml/base.xml:0
msgid "Restore"
msgstr "Odtwórz bazę danych"
#: addons/web/static/src/xml/base.xml:0
msgid "Password"
msgstr "Hasło"
#: addons/web/static/src/xml/base.xml:0
msgid "Back to Login"
msgstr "Wróć do logowania"
#: addons/web/static/src/xml/base.xml:0
msgid "CREATE DATABASE"
msgstr "UTWÓRZ BAZĘ DANYCH"
#: addons/web/static/src/xml/base.xml:0
msgid "Master password:"
msgstr "Hasło madrzędne:"
#: addons/web/static/src/xml/base.xml:0
msgid "New database name:"
msgstr "Nazwa nowej bazy danych:"
#: addons/web/static/src/xml/base.xml:0
msgid "Load Demonstration data:"
msgstr "Wczytaj dane demonstracyjne:"
#: addons/web/static/src/xml/base.xml:0
msgid "Default language:"
msgstr "Domyślny język:"
#: addons/web/static/src/xml/base.xml:0
msgid "Admin password:"
msgstr "Hasło admina:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm password:"
msgstr "Potwierdź hasło:"
#: addons/web/static/src/xml/base.xml:0
msgid "DROP DATABASE"
msgstr "USUŃ BAZĘ DANYCH"
#: addons/web/static/src/xml/base.xml:0
msgid "Database:"
msgstr "Baza danych:"
#: addons/web/static/src/xml/base.xml:0
msgid "Master Password:"
msgstr "Hasło nadrzędne:"
#: addons/web/static/src/xml/base.xml:0
msgid "BACKUP DATABASE"
msgstr "ZAPISZ BAZĘ"
#: addons/web/static/src/xml/base.xml:0
msgid "RESTORE DATABASE"
msgstr "ODTWÓRZ BAZĘ"
#: addons/web/static/src/xml/base.xml:0
msgid "File:"
msgstr "Plik:"
#: addons/web/static/src/xml/base.xml:0
msgid "CHANGE MASTER PASSWORD"
msgstr "ZMIEŃ HASŁO NADRZĘDNE"
#: addons/web/static/src/xml/base.xml:0
msgid "New master password:"
msgstr "Nowe hasło nadrzędne:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm new master password:"
msgstr "Potwierdź nowe hasło nadrzędne:"
#: addons/web/static/src/xml/base.xml:0
msgid "User:"
msgstr "Użytkownik:"
#: addons/web/static/src/xml/base.xml:0
msgid "Password:"
msgstr "Hasło:"
#: addons/web/static/src/xml/base.xml:0
msgid "Database"
msgstr "Baza danych"
#: 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 "Niepoprawna nazwa użytkownika lub hasło"
#: 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 ""
"Sądzimy, że codzienne zadania mogą być bardziej intuicyjne, efektywne, "
"zautomatyzowan, ... a nawet przyjemne."
#: 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 ""
"Przy budowie wielkiego produktu polegamy na wiedzy tysięcy społeczników."
#: addons/web/static/src/xml/base.xml:0
msgid "User Friendly"
msgstr "Przyjazne dla użytkownika"
#: 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 "WYLOGUJ"
#: addons/web/static/src/xml/base.xml:0
msgid "&laquo;"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
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 "Ukryj tę wskazówkę"
#: addons/web/static/src/xml/base.xml:0
msgid "Disable all tips"
msgstr "Wyłącz wszystkie wskazówki"
#: addons/web/static/src/xml/base.xml:0
msgid "View#"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Fields"
msgstr "Pola"
#: addons/web/static/src/xml/base.xml:0
msgid "View labels"
msgstr "Pokaż etykiety"
#: addons/web/static/src/xml/base.xml:0
msgid "Sidebar Relates"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Field"
msgstr "Pole"
#: addons/web/static/src/xml/base.xml:0
msgid ":"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Translate view"
msgstr "Przetłumacz widok"
#: addons/web/static/src/xml/base.xml:0
msgid "Translate sidebar"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Delete"
msgstr "Usuń"
#: addons/web/static/src/xml/base.xml:0
msgid "First"
msgstr "Pierwsze"
#: 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 "Ostatnie"
#: addons/web/static/src/xml/base.xml:0
msgid "♻"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Save & Edit"
msgstr "Zapisz i edytuj"
#: addons/web/static/src/xml/base.xml:0
msgid "Create & Edit"
msgstr "Utwórz i edytuj"
#: addons/web/static/src/xml/base.xml:0
msgid "New"
msgstr "Nowy"
#: addons/web/static/src/xml/base.xml:0
msgid "Duplicate"
msgstr "Duplikuj"
#: addons/web/static/src/xml/base.xml:0
msgid "Readonly/Editable"
msgstr "Tylko odczyt/Edytowalne"
#: 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 "Dodaj"
#: 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 "Wykonano"
#: addons/web/static/src/xml/base.xml:0
msgid "Open..."
msgstr "Otwórz..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create..."
msgstr "Utwórz..."
#: addons/web/static/src/xml/base.xml:0
msgid "Search..."
msgstr "Wyszukaj..."
#: 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 "Wybierz"
#: addons/web/static/src/xml/base.xml:0
msgid "Save As"
msgstr "Zapisz jako"
#: addons/web/static/src/xml/base.xml:0
msgid "Clear"
msgstr "Wyczyść"
#: addons/web/static/src/xml/base.xml:0
msgid "Advanced Filter"
msgstr "Zaawansowany filtr"
#: addons/web/static/src/xml/base.xml:0
msgid "-- Filters --"
msgstr "-- Filtry --"
#: addons/web/static/src/xml/base.xml:0
msgid "-- Actions --"
msgstr "-- Akcje --"
#: addons/web/static/src/xml/base.xml:0
msgid "Save Filter"
msgstr "Zapisz filtr"
#: addons/web/static/src/xml/base.xml:0
msgid "Manage Filters"
msgstr "Zarządzaj filtrami"
#: addons/web/static/src/xml/base.xml:0
msgid "Filter Name:"
msgstr "Nazwa filtra:"
#: addons/web/static/src/xml/base.xml:0
msgid "(Any existing filter with the same name will be replaced)"
msgstr "(Każdy filtr o tej samej nazwie zostanie zamazany)"
#: addons/web/static/src/xml/base.xml:0
msgid "Any of the following conditions must match"
msgstr "Jeden z tych warunków musi być spełniony"
#: addons/web/static/src/xml/base.xml:0
msgid "All the following conditions must match"
msgstr "Wszystkie warunki muszą być spełnione"
#: addons/web/static/src/xml/base.xml:0
msgid "None of the following conditions must match"
msgstr "Żadeń z tych warunków nie może być spełniony"
#: addons/web/static/src/xml/base.xml:0
msgid "Add condition"
msgstr "Dodaj warunek"
#: addons/web/static/src/xml/base.xml:0
msgid "and"
msgstr "i"
#: addons/web/static/src/xml/base.xml:0
msgid "Cancel"
msgstr "Anuluj"
#: addons/web/static/src/xml/base.xml:0
msgid "Save & New"
msgstr "Zapisz i nowy"
#: addons/web/static/src/xml/base.xml:0
msgid "Save & Close"
msgstr "Zapisz i zamknij"
#: addons/web/static/src/xml/base.xml:0
msgid "Export"
msgstr "Eksportuj"
#: 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 ""
"Ten kreator wyeksportuje wszystkie dane, które spełniają bieżące kryteria "
"wyszukiwania, do pliku CSV.\n"
" Możesz eksportować wszystkie dane lub tylko pola, które mają być "
"importowane po zmianie."
#: addons/web/static/src/xml/base.xml:0
msgid "Export Type:"
msgstr "Typ eksportu:"
#: addons/web/static/src/xml/base.xml:0
msgid "Import Compatible Export"
msgstr "Eksport kompatybilny z importem"
#: addons/web/static/src/xml/base.xml:0
msgid "Export all Data"
msgstr "Eksportuj wszystkie dane"
#: addons/web/static/src/xml/base.xml:0
msgid "Export Formats"
msgstr "Format eksportu"
#: addons/web/static/src/xml/base.xml:0
msgid "Available fields"
msgstr "Dostępne pola"
#: addons/web/static/src/xml/base.xml:0
msgid "Fields to export"
msgstr "Pola do eksportu"
#: addons/web/static/src/xml/base.xml:0
msgid "Save fields list"
msgstr "Zapisz listę pól"
#: addons/web/static/src/xml/base.xml:0
msgid "Remove"
msgstr "Usuń"
#: addons/web/static/src/xml/base.xml:0
msgid "Remove All"
msgstr "Usuń wszystko"
#: addons/web/static/src/xml/base.xml:0
msgid "Name"
msgstr "Nazwa"
#: addons/web/static/src/xml/base.xml:0
msgid "&nbsp;"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Save as:"
msgstr "Zapisz jako:"
#: addons/web/static/src/xml/base.xml:0
msgid "Ok"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Saved exports:"
msgstr "Zapisane eksporty"
#: addons/web/static/src/xml/base.xml:0
msgid "Old Password:"
msgstr "Poprzednie hasło:"
#: addons/web/static/src/xml/base.xml:0
msgid "New Password:"
msgstr "Nowe hasło:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm Password:"
msgstr "Potwierdź hasło:"
#: addons/web/static/src/xml/base.xml:0
msgid "Import"
msgstr "Importuj"
#: addons/web/static/src/xml/base.xml:0
msgid "1. Import a .CSV file"
msgstr "1. Importuj plik .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 ""
"Wybierz plik .CSV do importu. Jeśli chcesz zobaczyć przykład pliku do "
"importu,\n"
" powinieneś wyeksportować dane z opcją \"Kompatybilne z importem\"."
#: addons/web/static/src/xml/base.xml:0
msgid "CSV File:"
msgstr "Plik CSV:"
#: addons/web/static/src/xml/base.xml:0
msgid "2. Check your file format"
msgstr "2. Sprawdź format pliku"
#: addons/web/static/src/xml/base.xml:0
msgid "Import Options"
msgstr "Opcje importu"
#: addons/web/static/src/xml/base.xml:0
msgid "Does your file have titles?"
msgstr "Czy plik zawiera nazwy pól?"
#: addons/web/static/src/xml/base.xml:0
msgid "Separator:"
msgstr "Separator:"
#: addons/web/static/src/xml/base.xml:0
msgid "Delimiter:"
msgstr "Znak dziesiętny:"
#: addons/web/static/src/xml/base.xml:0
msgid "Encoding:"
msgstr "Kodowanie:"
#: 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 "Linie do pominięcia"
#: addons/web/static/src/xml/base.xml:0
msgid "The import failed due to:"
msgstr "Import się nie udał z powodu:"
#: addons/web/static/src/xml/base.xml:0
msgid "Here is a preview of the file we could not import:"
msgstr "Oto podgląd pliku, którego nie można zaimportować:"
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP Web"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Version"
msgstr "Wersja"
#: 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 ""
+683
View File
@@ -0,0 +1,683 @@
# Brazilian Portuguese 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-11-12 18:57+0000\n"
"Last-Translator: Cristiano Gavião <Unknown>\n"
"Language-Team: Brazilian Portuguese <pt_BR@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-11-13 05:56+0000\n"
"X-Generator: Launchpad (build 14277)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
"Warning, the record has been modified, your changes will be discarded."
msgstr "Aviso, o registro foi modificado, suas alterações serão descartadas."
#: addons/web/static/src/js/view_form.js:1659
msgid "<em>   Search More...</em>"
msgstr "<em>   Procurar Mais...</em>"
#: 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 ""
#: addons/web/static/src/js/views.js:609
msgid "Translations"
msgstr ""
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
msgid "Save"
msgstr ""
#: addons/web/static/src/js/views.js:615
msgid "Close"
msgstr "Fechar"
#: 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 "Carregando..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create"
msgstr "Criar"
#: addons/web/static/src/xml/base.xml:0
msgid "Drop"
msgstr "Soltar"
#: addons/web/static/src/xml/base.xml:0
msgid "Backup"
msgstr "Cópia de Segurança"
#: addons/web/static/src/xml/base.xml:0
msgid "Restore"
msgstr "Restaurar"
#: addons/web/static/src/xml/base.xml:0
msgid "Password"
msgstr "Senha"
#: addons/web/static/src/xml/base.xml:0
msgid "Back to Login"
msgstr "Voltar ao Login"
#: addons/web/static/src/xml/base.xml:0
msgid "CREATE DATABASE"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Master password:"
msgstr "Senha mestre"
#: addons/web/static/src/xml/base.xml:0
msgid "New database name:"
msgstr "Nome da nova base de dados:"
#: addons/web/static/src/xml/base.xml:0
msgid "Load Demonstration data:"
msgstr "Carregar dados de demonstração:"
#: addons/web/static/src/xml/base.xml:0
msgid "Default language:"
msgstr "Idioma padrão:"
#: addons/web/static/src/xml/base.xml:0
msgid "Admin password:"
msgstr "Senha de Administrador"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm password:"
msgstr "Confirme a senha:"
#: addons/web/static/src/xml/base.xml:0
msgid "DROP DATABASE"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Database:"
msgstr "Base de dados:"
#: addons/web/static/src/xml/base.xml:0
msgid "Master Password:"
msgstr "Senha Mestre"
#: 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 "Arquivo:"
#: 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 "Nova senha mestre:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm new master password:"
msgstr "Confirme nova senha mestre"
#: addons/web/static/src/xml/base.xml:0
msgid "User:"
msgstr "Usuário:"
#: addons/web/static/src/xml/base.xml:0
msgid "Password:"
msgstr "Senha:"
#: addons/web/static/src/xml/base.xml:0
msgid "Database"
msgstr "Base de dados"
#: addons/web/static/src/xml/base.xml:0
msgid "Login"
msgstr "Autenticação"
#: addons/web/static/src/xml/base.xml:0
msgid "Bad username or password"
msgstr "Nome de usuário ou senha inválido"
#: 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 as atividades de trabalho diário pode ser mais intuitivas, "
"eficiente, automatizadas .. e até mesmo divertidas."
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP's vision to be:"
msgstr "OpenERP vislumbra ser:"
#: 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 ""
"Os desafios atuais da empresa são múltiplos. Nós fornecemos um módulo para "
"cada necessidade."
#: 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 um grande produto, contamos com o conhecimento de milhares de "
"contribuintes."
#: addons/web/static/src/xml/base.xml:0
msgid "User Friendly"
msgstr "Uso Amigável"
#: 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 "DESCONECTAR"
#: addons/web/static/src/xml/base.xml:0
msgid "&laquo;"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
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 "Esconder dica"
#: addons/web/static/src/xml/base.xml:0
msgid "Disable all tips"
msgstr "Desligar todas as dicas"
#: 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 "Visão de Tradução"
#: addons/web/static/src/xml/base.xml:0
msgid "Translate sidebar"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Delete"
msgstr "Excluir"
#: 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 "Salvar & Editar"
#: addons/web/static/src/xml/base.xml:0
msgid "Create & Edit"
msgstr "Criar & 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 "Apenas Leitura/Editável"
#: 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 "Adicionar"
#: 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 "Concluído"
#: addons/web/static/src/xml/base.xml:0
msgid "Open..."
msgstr "Abrir..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create..."
msgstr "Criar..."
#: addons/web/static/src/xml/base.xml:0
msgid "Search..."
msgstr "Pesquisar..."
#: addons/web/static/src/xml/base.xml:0
msgid "..."
msgstr "..."
#: addons/web/static/src/xml/base.xml:0
msgid "Uploading ..."
msgstr "Transferindo ..."
#: addons/web/static/src/xml/base.xml:0
msgid "Select"
msgstr "Selecionar"
#: addons/web/static/src/xml/base.xml:0
msgid "Save As"
msgstr "Salvar 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 Avançado"
#: addons/web/static/src/xml/base.xml:0
msgid "-- Filters --"
msgstr "-- Filtros --"
#: addons/web/static/src/xml/base.xml:0
msgid "-- Actions --"
msgstr "-- Ações --"
#: addons/web/static/src/xml/base.xml:0
msgid "Save Filter"
msgstr "Salvar filtro"
#: addons/web/static/src/xml/base.xml:0
msgid "Manage Filters"
msgstr "Gerenciar 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 "(Qualquer filtro existente com o mesmo nome será substituído)"
#: addons/web/static/src/xml/base.xml:0
msgid "Any of the following conditions must match"
msgstr "Qualquer das seguintes condições deve ser verdadeira"
#: addons/web/static/src/xml/base.xml:0
msgid "All the following conditions must match"
msgstr "Todas as seguintes condições devem ser verdadeiras"
#: addons/web/static/src/xml/base.xml:0
msgid "None of the following conditions must match"
msgstr "Nenhuma das seguintes condições deve ser verdadeira"
#: addons/web/static/src/xml/base.xml:0
msgid "Add condition"
msgstr "Adicionar condição"
#: 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 "Salvar & Novo"
#: addons/web/static/src/xml/base.xml:0
msgid "Save & Close"
msgstr "Salvar & Fechar"
#: 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 ""
#: addons/web/static/src/xml/base.xml:0
msgid "Export Type:"
msgstr "Tipo de Exportação:"
#: addons/web/static/src/xml/base.xml:0
msgid "Import Compatible Export"
msgstr "Importar Exportação Compatível"
#: addons/web/static/src/xml/base.xml:0
msgid "Export all Data"
msgstr "Exportar todos os Dados"
#: addons/web/static/src/xml/base.xml:0
msgid "Export Formats"
msgstr "Formatos de Exportação"
#: addons/web/static/src/xml/base.xml:0
msgid "Available fields"
msgstr "Campos Disponíveis"
#: addons/web/static/src/xml/base.xml:0
msgid "Fields to export"
msgstr "Campos para exportar"
#: addons/web/static/src/xml/base.xml:0
msgid "Save fields list"
msgstr "Salvar lista de campos"
#: addons/web/static/src/xml/base.xml:0
msgid "Remove"
msgstr "Remover"
#: addons/web/static/src/xml/base.xml:0
msgid "Remove All"
msgstr "Remover Tudo"
#: addons/web/static/src/xml/base.xml:0
msgid "Name"
msgstr "Nome"
#: addons/web/static/src/xml/base.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
#: addons/web/static/src/xml/base.xml:0
msgid "Save as:"
msgstr "Salvar 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 ""
#: addons/web/static/src/xml/base.xml:0
msgid "Old Password:"
msgstr "Senha antiga"
#: addons/web/static/src/xml/base.xml:0
msgid "New Password:"
msgstr "Nova Senha:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm Password:"
msgstr ""
#: 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 "Importar um 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 ""
#: 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 "Verifique seu formato de arquivo"
#: 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 "Separador:"
#: addons/web/static/src/xml/base.xml:0
msgid "Delimiter:"
msgstr "Delimitador:"
#: addons/web/static/src/xml/base.xml:0
msgid "Encoding:"
msgstr "Codificação:"
#: 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 "Linhas para ignorar"
#: 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 "OpenERP Web"
#: addons/web/static/src/xml/base.xml:0
msgid "Version"
msgstr "Versão"
#: 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 é uma marca de"
#: 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 "Licenciado sobre os termos de"
#: 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 "Sobre 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 ""
+707
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "&laquo;"
msgstr "&laquo;"
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
msgstr "&raquo;"
#: 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 "&nbsp;"
msgstr "&nbsp;"
#: 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."
+119 -16
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\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"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,28 +17,40 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\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>"
msgstr ""
#: addons/web/static/src/js/form.js:1486
#: addons/web/static/src/js/view_form.js:1672
#, python-format
msgid "<em>   Create \"<strong>%s</strong>\"</em>"
msgstr ""
#: addons/web/static/src/js/form.js:1492
#: addons/web/static/src/js/view_form.js:1678
msgid "<em>   Create and Edit...</em>"
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"
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"
msgstr ""
#: addons/web/static/src/js/views.js:490
#: addons/web/static/src/js/views.js:615
msgid "Close"
msgstr ""
@@ -229,23 +241,31 @@ msgid "LOGOUT"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "h3"
msgid "&laquo;"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "<"
msgid "&raquo;"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ">"
msgid "oe_secondary_menu_item"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "</"
msgid "oe_secondary_submenu_item"
msgstr ""
#: 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 ""
#: addons/web/static/src/xml/base.xml:0
@@ -284,6 +304,14 @@ msgstr ""
msgid "First"
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 "Last"
msgstr ""
@@ -292,10 +320,6 @@ msgstr ""
msgid "♻"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "View#"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Save & Edit"
msgstr ""
@@ -308,6 +332,14 @@ msgstr ""
msgid "New"
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
msgid "<<"
msgstr ""
@@ -336,6 +368,14 @@ msgstr ""
msgid "?"
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
msgid "Open..."
msgstr ""
@@ -508,6 +548,69 @@ msgstr ""
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 ""
@@ -0,0 +1,32 @@
# jQuery MD5 Plugin
## Usage
Create ([hex](http://en.wikipedia.org/wiki/Hexadecimal)-encoded) [MD5](http://en.wikipedia.org/wiki/MD5) hash of a given string value:
var md5 = $.md5('value');
Create ([hex](http://en.wikipedia.org/wiki/Hexadecimal)-encoded) [HMAC](http://en.wikipedia.org/wiki/HMAC)-MD5 hash of a given string value and key:
var md5 = $.md5('value', 'key');
Create raw [MD5](http://en.wikipedia.org/wiki/MD5) hash of a given string value:
var md5 = $.md5('value', null, true);
Create raw [HMAC](http://en.wikipedia.org/wiki/HMAC)-MD5 hash of a given string value and key:
var md5 = $.md5('value', 'key', true);
## Requirements
None.
If [jQuery](http://jquery.com/) is not available, the md5 function will be added to the global object:
var md5 = md5('value');
## License
Released under the [MIT license](http://creativecommons.org/licenses/MIT/).
## Source Code & Download
* Browse and checkout the [source code](https://github.com/blueimp/jQuery-MD5).
* [Download](https://github.com/blueimp/jQuery-MD5/archives/master) the project to add the plugin to your website.
@@ -0,0 +1,32 @@
jQuery MD5 Plugin
=================
Usage
-----
Create (hex-encoded) MD5 hash of a given string value:
var md5 = $.md5('value');
Create (hex-encoded) HMAC-MD5 hash of a given string value and key:
var md5 = $.md5('value', 'key');
Create raw MD5 hash of a given string value:
var md5 = $.md5('value', null, true);
Create raw HMAC-MD5 hash of a given string value and key:
var md5 = $.md5('value', 'key', true);
Requirements
------------
None.
If jQuery is not available, the md5 function will be added to the global object:
var md5 = md5('value');
License
-------
Released under the MIT license:
http://creativecommons.org/licenses/MIT/
Source Code & Download
----------------------
https://github.com/blueimp/jQuery-MD5
@@ -0,0 +1,269 @@
/*
* jQuery MD5 Plugin 1.2.1
* https://github.com/blueimp/jQuery-MD5
*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://creativecommons.org/licenses/MIT/
*
* Based on
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
*/
/*jslint bitwise: true */
/*global unescape, jQuery */
(function ($) {
'use strict';
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add(x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF),
msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function bit_rol(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
}
/*
* These functions implement the four basic operations the algorithm uses.
*/
function md5_cmn(q, a, b, x, s, t) {
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
}
function md5_ff(a, b, c, d, x, s, t) {
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t) {
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t) {
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t) {
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}
/*
* Calculate the MD5 of an array of little-endian words, and a bit length.
*/
function binl_md5(x, len) {
/* append padding */
x[len >> 5] |= 0x80 << ((len) % 32);
x[(((len + 64) >>> 9) << 4) + 14] = len;
var i, olda, oldb, oldc, oldd,
a = 1732584193,
b = -271733879,
c = -1732584194,
d = 271733878;
for (i = 0; i < x.length; i += 16) {
olda = a;
oldb = b;
oldc = c;
oldd = d;
a = md5_ff(a, b, c, d, x[i], 7, -680876936);
d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
b = md5_gg(b, c, d, a, x[i], 20, -373897302);
a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
d = md5_hh(d, a, b, c, x[i], 11, -358537222);
c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
a = md5_ii(a, b, c, d, x[i], 6, -198630844);
d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
}
return [a, b, c, d];
}
/*
* Convert an array of little-endian words to a string
*/
function binl2rstr(input) {
var i,
output = '';
for (i = 0; i < input.length * 32; i += 8) {
output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
}
return output;
}
/*
* Convert a raw string to an array of little-endian words
* Characters >255 have their high-byte silently ignored.
*/
function rstr2binl(input) {
var i,
output = [];
output[(input.length >> 2) - 1] = undefined;
for (i = 0; i < output.length; i += 1) {
output[i] = 0;
}
for (i = 0; i < input.length * 8; i += 8) {
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
}
return output;
}
/*
* Calculate the MD5 of a raw string
*/
function rstr_md5(s) {
return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
}
/*
* Calculate the HMAC-MD5, of a key and some data (raw strings)
*/
function rstr_hmac_md5(key, data) {
var i,
bkey = rstr2binl(key),
ipad = [],
opad = [],
hash;
ipad[15] = opad[15] = undefined;
if (bkey.length > 16) {
bkey = binl_md5(bkey, key.length * 8);
}
for (i = 0; i < 16; i += 1) {
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
}
/*
* Convert a raw string to a hex string
*/
function rstr2hex(input) {
var hex_tab = '0123456789abcdef',
output = '',
x,
i;
for (i = 0; i < input.length; i += 1) {
x = input.charCodeAt(i);
output += hex_tab.charAt((x >>> 4) & 0x0F) +
hex_tab.charAt(x & 0x0F);
}
return output;
}
/*
* Encode a string as utf-8
*/
function str2rstr_utf8(input) {
return unescape(encodeURIComponent(input));
}
/*
* Take string arguments and return either raw or hex encoded strings
*/
function raw_md5(s) {
return rstr_md5(str2rstr_utf8(s));
}
function hex_md5(s) {
return rstr2hex(raw_md5(s));
}
function raw_hmac_md5(k, d) {
return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d));
}
function hex_hmac_md5(k, d) {
return rstr2hex(raw_hmac_md5(k, d));
}
$.md5 = function (string, key, raw) {
if (!key) {
if (!raw) {
return hex_md5(string);
} else {
return raw_md5(string);
}
}
if (!raw) {
return hex_hmac_md5(key, string);
} else {
return raw_hmac_md5(key, string);
}
};
}(typeof jQuery === 'function' ? jQuery : this));
@@ -0,0 +1,43 @@
<!DOCTYPE HTML>
<!--
/*
* jQuery MD5 Plugin Tests 1.1
* https://github.com/blueimp/jQuery-MD5
*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://creativecommons.org/licenses/MIT/
*/
-->
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery MD5 Plugin Tests</title>
<link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css">
</head>
<body>
<h1 id="qunit-header">jQuery MD5 Plugin Tests</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script>
(function ($) {
'use strict';
var nojquery = /nojquery=true/.test(location.search);
$('<label><input type="checkbox">nojquery<\/label>').click(function () {
location.search = nojquery ? '' : '?nojquery=true';
}).appendTo('body').children(':first').attr('checked', nojquery);
if (nojquery) {
window.jQuery = null;
}
}(window.jQuery));
</script>
<script src="../jquery.md5.js"></script>
<script src="http://code.jquery.com/qunit/git/qunit.js"></script>
<script src="tests.js"></script>
</body>
</html>
@@ -0,0 +1,57 @@
/*
* jQuery MD5 Plugin Tests 1.1
* https://github.com/blueimp/jQuery-MD5
*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://creativecommons.org/licenses/MIT/
*/
/*global jQuery, module, test, strictEqual */
(function ($) {
'use strict';
module('Hex-encoded MD5');
test('Creating hex-encoded MD5 hash of an ASCII value', function () {
strictEqual($.md5('value'), '2063c1608d6e0baf80249c42e2be5804');
});
test('Creating hex-encoded MD5 hash of an UTF-8 value', function () {
strictEqual($.md5('日本'), '4dbed2e657457884e67137d3514119b3');
});
module('Hex-encoded HMAC-MD5');
test('Creating hex-encoded HMAC-MD5 hash of an ASCII value and key', function () {
strictEqual($.md5('value', 'key'), '01433efd5f16327ea4b31144572c67f6');
});
test('Creating hex-encoded HMAC-MD5 hash of an UTF-8 value and key', function () {
strictEqual($.md5('日本', '日本'), 'c78b8c7357926981cc04740bd3e9d015');
});
module('Raw MD5');
test('Creating raw MD5 hash of an ASCII value', function () {
strictEqual($.md5('value', null, true), ' c\xc1`\x8dn\x0b\xaf\x80$\x9cB\xe2\xbeX\x04');
});
test('Creating raw MD5 hash of an UTF-8 value', function () {
strictEqual($.md5('日本', null, true), 'M\xbe\xd2\xe6WEx\x84\xe6q7\xd3QA\x19\xb3');
});
module('Raw HMAC-MD5');
test('Creating raw HMAC-MD5 hash of an ASCII value and key', function () {
strictEqual($.md5('value', 'key', true), '\x01C>\xfd_\x162~\xa4\xb3\x11DW,g\xf6');
});
test('Creating raw HMAC-MD5 hash of an UTF-8 value and key', function () {
strictEqual($.md5('日本', '日本', true), '\xc7\x8b\x8csW\x92i\x81\xcc\x04t\x0b\xd3\xe9\xd0\x15');
});
}(typeof jQuery === 'function' ? jQuery : this));
@@ -0,0 +1,91 @@
1.4.2
[Feature]
- The plugin support percentages as target ('50%' or {top:'50%', left:'45%'})
- Exposed the max() calculation as $.scrollTo.max
[Enhancement]
- Renamed $.fn.scrollable to $.fn._scrollable to avoid conflicts with other plugins
[Fix]
- Fixing max calculations for regular DOM elements
1.4.1
[Feature]
- The target can be 'max' to scroll to the end while keeping it elegant.
[Enhancement]
- Default duration is 0 for jquery +1.3. Means sync animation
- The plugin works on all major browsers, on compat & quirks modes, including iframes.
- In addition to window/document, if html or body are received, the plugin will choose the right one.
[Fix]
- The plugin accepts floating numbers, Thanks Ramin
- Using jQuery.nodeName where neccessary so that this works on xml+xhtml
- The max() internal function wasn't completely accurrate, now it is 98% (except for IE on quirks mode and it's not too noticeable).
1.4
[Fix]
- Fixed the problem when scrolling the window to absolute positioned elements on Safari.
- Fixed the problem on Opera 9.5 when scrolling the window. That it always scrolls to 0.
[Feature]
- Added the settings object as 2nd argument to the onAfter callback.
- The 3rd argument of scrollTo can be just a function and it's used as the onAfter.
- Added full support for iframes (even max scroll calculation).
- Instead of $.scrollTo, $(window).scrollTo() and $(document).scrollTo() can be used.
- Added $().scrollable() that returns the real element to scroll, f.e: $(window).scrollable() == [body|html], works for iframes.
[Enhancement]
- Cleaned the code a bit, specially the comments
1.3.3
[Change]
- Changed the licensing from GPL to GPL+MIT.
1.3.2
[Enhancement]
- Small improvements to make the code shorter.
[Change]
- Removed the last argument received by onAfter as it was the same as the 'this' but jqueryfied.
1.3.1
[Feature]
- Exposed $.scrollTo.window() to get the element that needs to be animated, to scroll the window.
- Added option 'over'.
[Enhancement]
- Made the code as short as possible.
[Change]
- Changed the arguments received by onAfter
1.3
[Enhancement]
- Added semicolon to the start, for safe file concatenation
- Added a limit check, values below 0 or over the maximum are fixed.
- Now it should work faster, only one of html or body go through all the processing, instead of both for all browsers.
[Fix]
- Fixed the behavior for Opera, which seemed to react to both changes on <html> and <body>.
- The border is also reduced, when 'margin' is set to true.
[Change]
- The option speed has been renamed to duration.
[Feature]
- The duration can be specified with a number as 2nd argument, and the rest of the settings as the third ( like $().animate )
- Remade the demo
1.2.4
[Enhancement]
- The target can be in the form of { top:x, left:y } allowing different position for each axis.
[Feature]
- The option 'offset' has been added, to scroll behind or past the target. Can be a number(both axes) or { top:x, left:y }.
1.2.3
[Feature]
- Exposed the defaults.
[Enhancement]
- Made the callback functions receive more parameters.
1.2.2
[Fix]
- Fixed a bug, I didn't have to add the scrolled amount if it was body or html.
1.2
[Change]
- The option 'onafter' is now called 'onAfter'.
[Feature]
- Two axes can be scrolled together, this is set with the option 'axis'.
- In case 2 axes are chosen, the scrolling can be queued: one scrolls, and then the other.
- There's an intermediary event, 'onAfterFirst' called in case the axes are queued, after the first ends.
- If the option 'margin' is set to true, the plugin will take in account, the margin of the target(no use if target is a value).
@@ -0,0 +1,11 @@
/**
* jQuery.ScrollTo - Easy element scrolling using jQuery.
* Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
* Dual licensed under MIT and GPL.
* Date: 5/25/2009
* @author Ariel Flesler
* @version 1.4.2
*
* http://flesler.blogspot.com/2007/10/jqueryscrollto.html
*/
;(function(d){var k=d.scrollTo=function(a,i,e){d(window).scrollTo(a,i,e)};k.defaults={axis:'xy',duration:parseFloat(d.fn.jquery)>=1.3?0:1};k.window=function(a){return d(window)._scrollable()};d.fn._scrollable=function(){return this.map(function(){var a=this,i=!a.nodeName||d.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!i)return a;var e=(a.contentWindow||a).document||a.ownerDocument||a;return d.browser.safari||e.compatMode=='BackCompat'?e.body:e.documentElement})};d.fn.scrollTo=function(n,j,b){if(typeof j=='object'){b=j;j=0}if(typeof b=='function')b={onAfter:b};if(n=='max')n=9e9;b=d.extend({},k.defaults,b);j=j||b.speed||b.duration;b.queue=b.queue&&b.axis.length>1;if(b.queue)j/=2;b.offset=p(b.offset);b.over=p(b.over);return this._scrollable().each(function(){var q=this,r=d(q),f=n,s,g={},u=r.is('html,body');switch(typeof f){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(f)){f=p(f);break}f=d(f,this);case'object':if(f.is||f.style)s=(f=d(f)).offset()}d.each(b.axis.split(''),function(a,i){var e=i=='x'?'Left':'Top',h=e.toLowerCase(),c='scroll'+e,l=q[c],m=k.max(q,i);if(s){g[c]=s[h]+(u?0:l-r.offset()[h]);if(b.margin){g[c]-=parseInt(f.css('margin'+e))||0;g[c]-=parseInt(f.css('border'+e+'Width'))||0}g[c]+=b.offset[h]||0;if(b.over[h])g[c]+=f[i=='x'?'width':'height']()*b.over[h]}else{var o=f[h];g[c]=o.slice&&o.slice(-1)=='%'?parseFloat(o)/100*m:o}if(/^\d+$/.test(g[c]))g[c]=g[c]<=0?0:Math.min(g[c],m);if(!a&&b.queue){if(l!=g[c])t(b.onAfterFirst);delete g[c]}});t(b.onAfter);function t(a){r.animate(g,j,b.easing,a&&function(){a.call(this,n,b)})}}).end()};k.max=function(a,i){var e=i=='x'?'Width':'Height',h='scroll'+e;if(!d(a).is('html,body'))return a[h]-d(a)[e.toLowerCase()]();var c='client'+e,l=a.ownerDocument.documentElement,m=a.ownerDocument.body;return Math.max(l[h],m[h])-Math.min(l[c],m[c])};function p(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);
@@ -0,0 +1,215 @@
/**
* jQuery.ScrollTo
* Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
* Dual licensed under MIT and GPL.
* Date: 5/25/2009
*
* @projectDescription Easy element scrolling using jQuery.
* http://flesler.blogspot.com/2007/10/jqueryscrollto.html
* Works with jQuery +1.2.6. Tested on FF 2/3, IE 6/7/8, Opera 9.5/6, Safari 3, Chrome 1 on WinXP.
*
* @author Ariel Flesler
* @version 1.4.2
*
* @id jQuery.scrollTo
* @id jQuery.fn.scrollTo
* @param {String, Number, DOMElement, jQuery, Object} target Where to scroll the matched elements.
* The different options for target are:
* - A number position (will be applied to all axes).
* - A string position ('44', '100px', '+=90', etc ) will be applied to all axes
* - A jQuery/DOM element ( logically, child of the element to scroll )
* - A string selector, that will be relative to the element to scroll ( 'li:eq(2)', etc )
* - A hash { top:x, left:y }, x and y can be any kind of number/string like above.
* - A percentage of the container's dimension/s, for example: 50% to go to the middle.
* - The string 'max' for go-to-end.
* @param {Number} duration The OVERALL length of the animation, this argument can be the settings object instead.
* @param {Object,Function} settings Optional set of settings or the onAfter callback.
* @option {String} axis Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'.
* @option {Number} duration The OVERALL length of the animation.
* @option {String} easing The easing method for the animation.
* @option {Boolean} margin If true, the margin of the target element will be deducted from the final position.
* @option {Object, Number} offset Add/deduct from the end position. One number for both axes or { top:x, left:y }.
* @option {Object, Number} over Add/deduct the height/width multiplied by 'over', can be { top:x, left:y } when using both axes.
* @option {Boolean} queue If true, and both axis are given, the 2nd axis will only be animated after the first one ends.
* @option {Function} onAfter Function to be called after the scrolling ends.
* @option {Function} onAfterFirst If queuing is activated, this function will be called after the first scrolling ends.
* @return {jQuery} Returns the same jQuery object, for chaining.
*
* @desc Scroll to a fixed position
* @example $('div').scrollTo( 340 );
*
* @desc Scroll relatively to the actual position
* @example $('div').scrollTo( '+=340px', { axis:'y' } );
*
* @dec Scroll using a selector (relative to the scrolled element)
* @example $('div').scrollTo( 'p.paragraph:eq(2)', 500, { easing:'swing', queue:true, axis:'xy' } );
*
* @ Scroll to a DOM element (same for jQuery object)
* @example var second_child = document.getElementById('container').firstChild.nextSibling;
* $('#container').scrollTo( second_child, { duration:500, axis:'x', onAfter:function(){
* alert('scrolled!!');
* }});
*
* @desc Scroll on both axes, to different values
* @example $('div').scrollTo( { top: 300, left:'+=200' }, { axis:'xy', offset:-20 } );
*/
;(function( $ ){
var $scrollTo = $.scrollTo = function( target, duration, settings ){
$(window).scrollTo( target, duration, settings );
};
$scrollTo.defaults = {
axis:'xy',
duration: parseFloat($.fn.jquery) >= 1.3 ? 0 : 1
};
// Returns the element that needs to be animated to scroll the window.
// Kept for backwards compatibility (specially for localScroll & serialScroll)
$scrollTo.window = function( scope ){
return $(window)._scrollable();
};
// Hack, hack, hack :)
// Returns the real elements to scroll (supports window/iframes, documents and regular nodes)
$.fn._scrollable = function(){
return this.map(function(){
var elem = this,
isWin = !elem.nodeName || $.inArray( elem.nodeName.toLowerCase(), ['iframe','#document','html','body'] ) != -1;
if( !isWin )
return elem;
var doc = (elem.contentWindow || elem).document || elem.ownerDocument || elem;
return $.browser.safari || doc.compatMode == 'BackCompat' ?
doc.body :
doc.documentElement;
});
};
$.fn.scrollTo = function( target, duration, settings ){
if( typeof duration == 'object' ){
settings = duration;
duration = 0;
}
if( typeof settings == 'function' )
settings = { onAfter:settings };
if( target == 'max' )
target = 9e9;
settings = $.extend( {}, $scrollTo.defaults, settings );
// Speed is still recognized for backwards compatibility
duration = duration || settings.speed || settings.duration;
// Make sure the settings are given right
settings.queue = settings.queue && settings.axis.length > 1;
if( settings.queue )
// Let's keep the overall duration
duration /= 2;
settings.offset = both( settings.offset );
settings.over = both( settings.over );
return this._scrollable().each(function(){
var elem = this,
$elem = $(elem),
targ = target, toff, attr = {},
win = $elem.is('html,body');
switch( typeof targ ){
// A number will pass the regex
case 'number':
case 'string':
if( /^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(targ) ){
targ = both( targ );
// We are done
break;
}
// Relative selector, no break!
targ = $(targ,this);
case 'object':
// DOMElement / jQuery
if( targ.is || targ.style )
// Get the real position of the target
toff = (targ = $(targ)).offset();
}
$.each( settings.axis.split(''), function( i, axis ){
var Pos = axis == 'x' ? 'Left' : 'Top',
pos = Pos.toLowerCase(),
key = 'scroll' + Pos,
old = elem[key],
max = $scrollTo.max(elem, axis);
if( toff ){// jQuery / DOMElement
attr[key] = toff[pos] + ( win ? 0 : old - $elem.offset()[pos] );
// If it's a dom element, reduce the margin
if( settings.margin ){
attr[key] -= parseInt(targ.css('margin'+Pos)) || 0;
attr[key] -= parseInt(targ.css('border'+Pos+'Width')) || 0;
}
attr[key] += settings.offset[pos] || 0;
if( settings.over[pos] )
// Scroll to a fraction of its width/height
attr[key] += targ[axis=='x'?'width':'height']() * settings.over[pos];
}else{
var val = targ[pos];
// Handle percentage values
attr[key] = val.slice && val.slice(-1) == '%' ?
parseFloat(val) / 100 * max
: val;
}
// Number or 'number'
if( /^\d+$/.test(attr[key]) )
// Check the limits
attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max );
// Queueing axes
if( !i && settings.queue ){
// Don't waste time animating, if there's no need.
if( old != attr[key] )
// Intermediate animation
animate( settings.onAfterFirst );
// Don't animate this axis again in the next iteration.
delete attr[key];
}
});
animate( settings.onAfter );
function animate( callback ){
$elem.animate( attr, duration, settings.easing, callback && function(){
callback.call(this, target, settings);
});
};
}).end();
};
// Max scrolling position, works on quirks mode
// It only fails (not too badly) on IE, quirks mode.
$scrollTo.max = function( elem, axis ){
var Dim = axis == 'x' ? 'Width' : 'Height',
scroll = 'scroll'+Dim;
if( !$(elem).is('html,body') )
return elem[scroll] - $(elem)[Dim.toLowerCase()]();
var size = 'client' + Dim,
html = elem.ownerDocument.documentElement,
body = elem.ownerDocument.body;
return Math.max( html[scroll], body[scroll] )
- Math.min( html[size] , body[size] );
};
function both( val ){
return typeof val == 'object' ? val : { top:val, left:val };
};
})( jQuery );
@@ -0,0 +1,52 @@
--- jquery.tipTip_old.js 2011-11-14 21:40:55.000000000 +0100
+++ jquery.tipTip.js 2011-11-15 10:09:35.000000000 +0100
@@ -31,7 +31,7 @@
fadeIn: 200,
fadeOut: 200,
attribute: "title",
- content: false, // HTML or String to fill TipTIp with
+ content: false, // HTML String or function to fill TipTIp with
enter: function(){},
exit: function(){}
};
@@ -51,12 +51,7 @@
return this.each(function(){
var org_elem = $(this);
- if(opts.content){
- var org_title = opts.content;
- } else {
- var org_title = org_elem.attr(opts.attribute);
- }
- if(org_title != ""){
+ if(opts.content || org_elem.attr(opts.attribute)){
if(!opts.content){
org_elem.removeAttr(opts.attribute); //remove original Attribute
}
@@ -99,6 +94,8 @@
function active_tiptip(){
opts.enter.call(this);
+ var org_title = typeof opts.content === 'function' ? opts.content() : opts.content;
+ org_title = org_title || org_elem.attr(opts.attribute);
tiptip_content.html(org_title);
tiptip_holder.hide().removeAttr("class").css("margin","0");
tiptip_arrow.removeAttr("style");
@@ -176,8 +173,15 @@
tiptip_arrow.css({"margin-left": arrow_left+"px", "margin-top": arrow_top+"px"});
tiptip_holder.css({"margin-left": marg_left+"px", "margin-top": marg_top+"px"}).attr("class","tip"+t_class);
- if (timeout){ clearTimeout(timeout); }
- timeout = setTimeout(function(){ tiptip_holder.stop(true,true).fadeIn(opts.fadeIn); }, opts.delay);
+ if (timeout) {
+ clearTimeout(timeout);
+ }
+ timeout = setTimeout(function() {
+ tiptip_holder.stop(true,true);
+ if ($.contains(document.documentElement, org_elem[0])) {
+ tiptip_holder.fadeIn(opts.fadeIn);
+ }
+ }, opts.delay);
}
function deactive_tiptip(){
@@ -0,0 +1,193 @@
/*
* TipTip
* Copyright 2010 Drew Wilson
* www.drewwilson.com
* code.drewwilson.com/entry/tiptip-jquery-plugin
*
* Version 1.3 - Updated: Mar. 23, 2010
*
* This Plug-In will create a custom tooltip to replace the default
* browser tooltip. It is extremely lightweight and very smart in
* that it detects the edges of the browser window and will make sure
* the tooltip stays within the current window size. As a result the
* tooltip will adjust itself to be displayed above, below, to the left
* or to the right depending on what is necessary to stay within the
* browser window. It is completely customizable as well via CSS.
*
* This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/
(function($){
$.fn.tipTip = function(options) {
var defaults = {
activation: "hover",
keepAlive: false,
maxWidth: "200px",
edgeOffset: 3,
defaultPosition: "bottom",
delay: 400,
fadeIn: 200,
fadeOut: 200,
attribute: "title",
content: false, // HTML String or function to fill TipTIp with
enter: function(){},
exit: function(){}
};
var opts = $.extend(defaults, options);
// Setup tip tip elements and render them to the DOM
if($("#tiptip_holder").length <= 0){
var tiptip_holder = $('<div id="tiptip_holder" style="max-width:'+ opts.maxWidth +';"></div>');
var tiptip_content = $('<div id="tiptip_content"></div>');
var tiptip_arrow = $('<div id="tiptip_arrow"></div>');
$("body").append(tiptip_holder.html(tiptip_content).prepend(tiptip_arrow.html('<div id="tiptip_arrow_inner"></div>')));
} else {
var tiptip_holder = $("#tiptip_holder");
var tiptip_content = $("#tiptip_content");
var tiptip_arrow = $("#tiptip_arrow");
}
return this.each(function(){
var org_elem = $(this);
if(opts.content || org_elem.attr(opts.attribute)){
if(!opts.content){
org_elem.removeAttr(opts.attribute); //remove original Attribute
}
var timeout = false;
if(opts.activation == "hover"){
org_elem.hover(function(){
active_tiptip();
}, function(){
if(!opts.keepAlive){
deactive_tiptip();
}
});
if(opts.keepAlive){
tiptip_holder.hover(function(){}, function(){
deactive_tiptip();
});
}
} else if(opts.activation == "focus"){
org_elem.focus(function(){
active_tiptip();
}).blur(function(){
deactive_tiptip();
});
} else if(opts.activation == "click"){
org_elem.click(function(){
active_tiptip();
return false;
}).hover(function(){},function(){
if(!opts.keepAlive){
deactive_tiptip();
}
});
if(opts.keepAlive){
tiptip_holder.hover(function(){}, function(){
deactive_tiptip();
});
}
}
function active_tiptip(){
opts.enter.call(this);
var org_title = typeof opts.content === 'function' ? opts.content() : opts.content;
org_title = org_title || org_elem.attr(opts.attribute);
tiptip_content.html(org_title);
tiptip_holder.hide().removeAttr("class").css("margin","0");
tiptip_arrow.removeAttr("style");
var top = parseInt(org_elem.offset()['top']);
var left = parseInt(org_elem.offset()['left']);
var org_width = parseInt(org_elem.outerWidth());
var org_height = parseInt(org_elem.outerHeight());
var tip_w = tiptip_holder.outerWidth();
var tip_h = tiptip_holder.outerHeight();
var w_compare = Math.round((org_width - tip_w) / 2);
var h_compare = Math.round((org_height - tip_h) / 2);
var marg_left = Math.round(left + w_compare);
var marg_top = Math.round(top + org_height + opts.edgeOffset);
var t_class = "";
var arrow_top = "";
var arrow_left = Math.round(tip_w - 12) / 2;
if(opts.defaultPosition == "bottom"){
t_class = "_bottom";
} else if(opts.defaultPosition == "top"){
t_class = "_top";
} else if(opts.defaultPosition == "left"){
t_class = "_left";
} else if(opts.defaultPosition == "right"){
t_class = "_right";
}
var right_compare = (w_compare + left) < parseInt($(window).scrollLeft());
var left_compare = (tip_w + left) > parseInt($(window).width());
if((right_compare && w_compare < 0) || (t_class == "_right" && !left_compare) || (t_class == "_left" && left < (tip_w + opts.edgeOffset + 5))){
t_class = "_right";
arrow_top = Math.round(tip_h - 13) / 2;
arrow_left = -12;
marg_left = Math.round(left + org_width + opts.edgeOffset);
marg_top = Math.round(top + h_compare);
} else if((left_compare && w_compare < 0) || (t_class == "_left" && !right_compare)){
t_class = "_left";
arrow_top = Math.round(tip_h - 13) / 2;
arrow_left = Math.round(tip_w);
marg_left = Math.round(left - (tip_w + opts.edgeOffset + 5));
marg_top = Math.round(top + h_compare);
}
var top_compare = (top + org_height + opts.edgeOffset + tip_h + 8) > parseInt($(window).height() + $(window).scrollTop());
var bottom_compare = ((top + org_height) - (opts.edgeOffset + tip_h + 8)) < 0;
if(top_compare || (t_class == "_bottom" && top_compare) || (t_class == "_top" && !bottom_compare)){
if(t_class == "_top" || t_class == "_bottom"){
t_class = "_top";
} else {
t_class = t_class+"_top";
}
arrow_top = tip_h;
marg_top = Math.round(top - (tip_h + 5 + opts.edgeOffset));
} else if(bottom_compare | (t_class == "_top" && bottom_compare) || (t_class == "_bottom" && !top_compare)){
if(t_class == "_top" || t_class == "_bottom"){
t_class = "_bottom";
} else {
t_class = t_class+"_bottom";
}
arrow_top = -12;
marg_top = Math.round(top + org_height + opts.edgeOffset);
}
if(t_class == "_right_top" || t_class == "_left_top"){
marg_top = marg_top + 5;
} else if(t_class == "_right_bottom" || t_class == "_left_bottom"){
marg_top = marg_top - 5;
}
if(t_class == "_left_top" || t_class == "_left_bottom"){
marg_left = marg_left + 5;
}
tiptip_arrow.css({"margin-left": arrow_left+"px", "margin-top": arrow_top+"px"});
tiptip_holder.css({"margin-left": marg_left+"px", "margin-top": marg_top+"px"}).attr("class","tip"+t_class);
if (timeout){ clearTimeout(timeout); }
timeout = setTimeout(function() {
tiptip_holder.stop(true,true);
if ($.contains(document.documentElement, org_elem[0])) {
tiptip_holder.fadeIn(opts.fadeIn);
}
}, opts.delay);
}
function deactive_tiptip(){
opts.exit.call(this);
if (timeout){ clearTimeout(timeout); }
tiptip_holder.fadeOut(opts.fadeOut);
}
}
});
}
})(jQuery);
@@ -0,0 +1,191 @@
/*
* TipTip
* Copyright 2010 Drew Wilson
* www.drewwilson.com
* code.drewwilson.com/entry/tiptip-jquery-plugin
*
* Version 1.3 - Updated: Mar. 23, 2010
*
* This Plug-In will create a custom tooltip to replace the default
* browser tooltip. It is extremely lightweight and very smart in
* that it detects the edges of the browser window and will make sure
* the tooltip stays within the current window size. As a result the
* tooltip will adjust itself to be displayed above, below, to the left
* or to the right depending on what is necessary to stay within the
* browser window. It is completely customizable as well via CSS.
*
* This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/
(function($){
$.fn.tipTip = function(options) {
var defaults = {
activation: "hover",
keepAlive: false,
maxWidth: "200px",
edgeOffset: 3,
defaultPosition: "bottom",
delay: 400,
fadeIn: 200,
fadeOut: 200,
attribute: "title",
content: false, // HTML or String to fill TipTIp with
enter: function(){},
exit: function(){}
};
var opts = $.extend(defaults, options);
// Setup tip tip elements and render them to the DOM
if($("#tiptip_holder").length <= 0){
var tiptip_holder = $('<div id="tiptip_holder" style="max-width:'+ opts.maxWidth +';"></div>');
var tiptip_content = $('<div id="tiptip_content"></div>');
var tiptip_arrow = $('<div id="tiptip_arrow"></div>');
$("body").append(tiptip_holder.html(tiptip_content).prepend(tiptip_arrow.html('<div id="tiptip_arrow_inner"></div>')));
} else {
var tiptip_holder = $("#tiptip_holder");
var tiptip_content = $("#tiptip_content");
var tiptip_arrow = $("#tiptip_arrow");
}
return this.each(function(){
var org_elem = $(this);
if(opts.content){
var org_title = opts.content;
} else {
var org_title = org_elem.attr(opts.attribute);
}
if(org_title != ""){
if(!opts.content){
org_elem.removeAttr(opts.attribute); //remove original Attribute
}
var timeout = false;
if(opts.activation == "hover"){
org_elem.hover(function(){
active_tiptip();
}, function(){
if(!opts.keepAlive){
deactive_tiptip();
}
});
if(opts.keepAlive){
tiptip_holder.hover(function(){}, function(){
deactive_tiptip();
});
}
} else if(opts.activation == "focus"){
org_elem.focus(function(){
active_tiptip();
}).blur(function(){
deactive_tiptip();
});
} else if(opts.activation == "click"){
org_elem.click(function(){
active_tiptip();
return false;
}).hover(function(){},function(){
if(!opts.keepAlive){
deactive_tiptip();
}
});
if(opts.keepAlive){
tiptip_holder.hover(function(){}, function(){
deactive_tiptip();
});
}
}
function active_tiptip(){
opts.enter.call(this);
tiptip_content.html(org_title);
tiptip_holder.hide().removeAttr("class").css("margin","0");
tiptip_arrow.removeAttr("style");
var top = parseInt(org_elem.offset()['top']);
var left = parseInt(org_elem.offset()['left']);
var org_width = parseInt(org_elem.outerWidth());
var org_height = parseInt(org_elem.outerHeight());
var tip_w = tiptip_holder.outerWidth();
var tip_h = tiptip_holder.outerHeight();
var w_compare = Math.round((org_width - tip_w) / 2);
var h_compare = Math.round((org_height - tip_h) / 2);
var marg_left = Math.round(left + w_compare);
var marg_top = Math.round(top + org_height + opts.edgeOffset);
var t_class = "";
var arrow_top = "";
var arrow_left = Math.round(tip_w - 12) / 2;
if(opts.defaultPosition == "bottom"){
t_class = "_bottom";
} else if(opts.defaultPosition == "top"){
t_class = "_top";
} else if(opts.defaultPosition == "left"){
t_class = "_left";
} else if(opts.defaultPosition == "right"){
t_class = "_right";
}
var right_compare = (w_compare + left) < parseInt($(window).scrollLeft());
var left_compare = (tip_w + left) > parseInt($(window).width());
if((right_compare && w_compare < 0) || (t_class == "_right" && !left_compare) || (t_class == "_left" && left < (tip_w + opts.edgeOffset + 5))){
t_class = "_right";
arrow_top = Math.round(tip_h - 13) / 2;
arrow_left = -12;
marg_left = Math.round(left + org_width + opts.edgeOffset);
marg_top = Math.round(top + h_compare);
} else if((left_compare && w_compare < 0) || (t_class == "_left" && !right_compare)){
t_class = "_left";
arrow_top = Math.round(tip_h - 13) / 2;
arrow_left = Math.round(tip_w);
marg_left = Math.round(left - (tip_w + opts.edgeOffset + 5));
marg_top = Math.round(top + h_compare);
}
var top_compare = (top + org_height + opts.edgeOffset + tip_h + 8) > parseInt($(window).height() + $(window).scrollTop());
var bottom_compare = ((top + org_height) - (opts.edgeOffset + tip_h + 8)) < 0;
if(top_compare || (t_class == "_bottom" && top_compare) || (t_class == "_top" && !bottom_compare)){
if(t_class == "_top" || t_class == "_bottom"){
t_class = "_top";
} else {
t_class = t_class+"_top";
}
arrow_top = tip_h;
marg_top = Math.round(top - (tip_h + 5 + opts.edgeOffset));
} else if(bottom_compare | (t_class == "_top" && bottom_compare) || (t_class == "_bottom" && !top_compare)){
if(t_class == "_top" || t_class == "_bottom"){
t_class = "_bottom";
} else {
t_class = t_class+"_bottom";
}
arrow_top = -12;
marg_top = Math.round(top + org_height + opts.edgeOffset);
}
if(t_class == "_right_top" || t_class == "_left_top"){
marg_top = marg_top + 5;
} else if(t_class == "_right_bottom" || t_class == "_left_bottom"){
marg_top = marg_top - 5;
}
if(t_class == "_left_top" || t_class == "_left_bottom"){
marg_left = marg_left + 5;
}
tiptip_arrow.css({"margin-left": arrow_left+"px", "margin-top": arrow_top+"px"});
tiptip_holder.css({"margin-left": marg_left+"px", "margin-top": marg_top+"px"}).attr("class","tip"+t_class);
if (timeout){ clearTimeout(timeout); }
timeout = setTimeout(function(){ tiptip_holder.stop(true,true).fadeIn(opts.fadeIn); }, opts.delay);
}
function deactive_tiptip(){
opts.exit.call(this);
if (timeout){ clearTimeout(timeout); }
tiptip_holder.fadeOut(opts.fadeOut);
}
}
});
}
})(jQuery);
@@ -0,0 +1,113 @@
/* TipTip CSS - Version 1.2 */
#tiptip_holder {
display: none;
position: absolute;
top: 0;
left: 0;
z-index: 99999;
}
#tiptip_holder.tip_top {
padding-bottom: 5px;
}
#tiptip_holder.tip_bottom {
padding-top: 5px;
}
#tiptip_holder.tip_right {
padding-left: 5px;
}
#tiptip_holder.tip_left {
padding-right: 5px;
}
#tiptip_content {
font-size: 11px;
color: #fff;
text-shadow: 0 0 2px #000;
padding: 4px 8px;
border: 1px solid rgba(255,255,255,0.25);
background-color: rgb(25,25,25);
background-color: rgba(25,25,25,0.92);
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(transparent), to(#000));
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
box-shadow: 0 0 3px #555;
-webkit-box-shadow: 0 0 3px #555;
-moz-box-shadow: 0 0 3px #555;
}
#tiptip_arrow, #tiptip_arrow_inner {
position: absolute;
border-color: transparent;
border-style: solid;
border-width: 6px;
height: 0;
width: 0;
}
#tiptip_holder.tip_top #tiptip_arrow {
border-top-color: #fff;
border-top-color: rgba(255,255,255,0.35);
}
#tiptip_holder.tip_bottom #tiptip_arrow {
border-bottom-color: #fff;
border-bottom-color: rgba(255,255,255,0.35);
}
#tiptip_holder.tip_right #tiptip_arrow {
border-right-color: #fff;
border-right-color: rgba(255,255,255,0.35);
}
#tiptip_holder.tip_left #tiptip_arrow {
border-left-color: #fff;
border-left-color: rgba(255,255,255,0.35);
}
#tiptip_holder.tip_top #tiptip_arrow_inner {
margin-top: -7px;
margin-left: -6px;
border-top-color: rgb(25,25,25);
border-top-color: rgba(25,25,25,0.92);
}
#tiptip_holder.tip_bottom #tiptip_arrow_inner {
margin-top: -5px;
margin-left: -6px;
border-bottom-color: rgb(25,25,25);
border-bottom-color: rgba(25,25,25,0.92);
}
#tiptip_holder.tip_right #tiptip_arrow_inner {
margin-top: -6px;
margin-left: -5px;
border-right-color: rgb(25,25,25);
border-right-color: rgba(25,25,25,0.92);
}
#tiptip_holder.tip_left #tiptip_arrow_inner {
margin-top: -6px;
margin-left: -7px;
border-left-color: rgb(25,25,25);
border-left-color: rgba(25,25,25,0.92);
}
/* Webkit Hacks */
@media screen and (-webkit-min-device-pixel-ratio:0) {
#tiptip_content {
padding: 4px 8px 5px 8px;
background-color: rgba(45,45,45,0.88);
}
#tiptip_holder.tip_bottom #tiptip_arrow_inner {
border-bottom-color: rgba(45,45,45,0.88);
}
#tiptip_holder.tip_top #tiptip_arrow_inner {
border-top-color: rgba(20,20,20,0.92);
}
}
+16 -9
View File
@@ -207,6 +207,7 @@ QWeb2.Engine = (function() {
this.reserved_words = QWeb2.RESERVED_WORDS.slice(0);
this.actions_precedence = QWeb2.ACTIONS_PRECEDENCE.slice(0);
this.word_replacement = QWeb2.tools.extend({}, QWeb2.WORD_REPLACEMENT);
this.format_text_node = null;
for (var i = 0; i < arguments.length; i++) {
this.add_template(arguments[i]);
}
@@ -317,12 +318,14 @@ QWeb2.Engine = (function() {
" dict = dict || {};\n" +
" dict['__template__'] = '" + template + "';\n" +
" var r = [];\n" +
" /* START TEMPLATE */ try {\n" +
" /* START TEMPLATE */" +
(this.debug ? "" : " try {\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" +
" context.engine.tools.exception('Runtime Error: ' + error, context);\n" +
" }\n" +
" context.engine.tools.exception('Runtime Error: ' + error, context);\n") +
(this.debug ? "" : " }\n") +
" return r.join('');";
},
render : function(template, dict) {
@@ -486,12 +489,16 @@ QWeb2.Element = (function() {
},
_compile : function() {
switch (this.node.nodeType) {
case 3:
case 4:
this.top_string(this.node.data);
case 3:
case 4:
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;
case 1:
this.compile_element();
case 1:
this.compile_element();
}
var r = this._top.join('');
if (this.process_children) {
+30
View File
@@ -0,0 +1,30 @@
// Underscore.js 1.2.2
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the MIT license.
// Portions of Underscore are inspired or borrowed from Prototype,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore
(function(){function r(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(b.isFunction(a.isEqual))return a.isEqual(c);if(b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return String(a)==String(c);case "[object Number]":return a=+a,c=+c,a!=a?c!=c:a==0?1/a==1/c:a==c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&r(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(m.call(a,h)&&(f++,!(g=m.call(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(m.call(c,
h)&&!f--)break;g=!f}}d.pop();return g}var s=this,F=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,G=k.unshift,l=p.toString,m=p.hasOwnProperty,v=k.forEach,w=k.map,x=k.reduce,y=k.reduceRight,z=k.filter,A=k.every,B=k.some,q=k.indexOf,C=k.lastIndexOf,p=Array.isArray,H=Object.keys,t=Function.prototype.bind,b=function(a){return new n(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else typeof define==="function"&&define.amd?
define("underscore",function(){return b}):s._=b;b.VERSION="1.2.2";var j=b.each=b.forEach=function(a,c,b){if(a!=null)if(v&&a.forEach===v)a.forEach(c,b);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(b,a[e],e,a)===o)break}else for(e in a)if(m.call(a,e)&&c.call(b,a[e],e,a)===o)break};b.map=function(a,c,b){var e=[];if(a==null)return e;if(w&&a.map===w)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=
d!==void 0;a==null&&(a=[]);if(x&&a.reduce===x)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){a==null&&(a=[]);if(y&&a.reduceRight===y)return e&&(c=b.bind(c,e)),d!==void 0?a.reduceRight(c,d):a.reduceRight(c);a=(b.isArray(a)?a.slice():b.toArray(a)).reverse();return b.reduce(a,c,d,e)};b.find=b.detect=function(a,c,b){var e;
D(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.filter===z)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(A&&a.every===A)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,a,g,h)))return o});
return e};var D=b.some=b.any=function(a,c,d){var c=c||b.identity,e=false;if(a==null)return e;if(B&&a.some===B)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return q&&a.indexOf===q?a.indexOf(c)!=-1:b=D(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(c.call?c||a:a[c]).apply(a,d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};
b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});return e.value};b.shuffle=function(a){var c=[],b;
j(a,function(a,f){f==0?c[0]=a:(b=Math.floor(Math.random()*(f+1)),c[f]=c[b],c[b]=a)});return c};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,c){var b=a.criteria,d=c.criteria;return b<d?-1:b>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,c){var b=e(a,c);(d[b]||(d[b]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<
f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=b.tail=function(a,b,d){return i.call(a,b==null||
d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);return e};b.union=function(){return b.uniq(b.flatten(arguments,
true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a,c){return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(q&&a.indexOf===q)return a.indexOf(c);
for(d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(C&&a.lastIndexOf===C)return a.lastIndexOf(b);for(var d=a.length;d--;)if(a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};var E=function(){};b.bind=function(a,c){var d,e;if(a.bind===t&&t)return t.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;
e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));E.prototype=a.prototype;var b=new E,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var b=c.apply(this,arguments);return m.call(d,b)?d[b]:d[b]=a.apply(this,arguments)}};b.delay=
function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=
null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments));return b.apply(this,d)}};b.compose=function(){var a=i.call(arguments);return function(){for(var b=i.call(arguments),d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=H||function(a){if(a!==
Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)m.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?
a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(m.call(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=l.call(arguments)=="[object Arguments]"?function(a){return l.call(a)=="[object Arguments]"}:
function(a){return!(!a||!m.call(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};
b.isUndefined=function(a){return a===void 0};b.noConflict=function(){s._=F;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")};b.mixin=function(a){j(b.functions(a),function(c){I(c,b[c]=a[c])})};var J=0;b.uniqueId=function(a){var b=J++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,
interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape,function(a,b){return"',_.escape("+b.replace(/\\'/g,"'")+"),'"}).replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,
"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e(a,b)}};var n=function(a){this._wrapped=a};b.prototype=n.prototype;var u=function(a,c){return c?b(a).chain():a},I=function(a,c){n.prototype[a]=function(){var a=i.call(arguments);G.call(a,this._wrapped);return u(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];n.prototype[a]=function(){b.apply(this._wrapped,
arguments);return u(this._wrapped,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];n.prototype[a]=function(){return u(b.apply(this._wrapped,arguments),this._chain)}});n.prototype.chain=function(){this._chain=true;return this};n.prototype.value=function(){return this._wrapped}}).call(this);
+237 -99
View File
@@ -1,4 +1,4 @@
// Underscore.js 1.1.7
// Underscore.js 1.2.2
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the MIT license.
// Portions of Underscore are inspired or borrowed from Prototype,
@@ -48,19 +48,26 @@
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) { return new wrapper(obj); };
// Export the Underscore object for **CommonJS**, with backwards-compatibility
// for the old `require()` API. If we're not in CommonJS, add `_` to the
// global object.
if (typeof module !== 'undefined' && module.exports) {
module.exports = _;
_._ = _;
// Export the Underscore object for **Node.js** and **"CommonJS"**, with
// backwards-compatibility for the old `require()` API. If we're not in
// CommonJS, add `_` to the global object.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else if (typeof define === 'function' && define.amd) {
// Register as a named module with AMD.
define('underscore', function() {
return _;
});
} else {
// Exported as a string, for Closure Compiler "advanced" mode.
root['_'] = _;
}
// Current version.
_.VERSION = '1.1.7';
_.VERSION = '1.2.2';
// Collection Functions
// --------------------
@@ -187,7 +194,7 @@
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
each(obj, function(value, index, list) {
if (result |= iterator.call(context, value, index, list)) return breaker;
if (result || (result = iterator.call(context, value, index, list))) return breaker;
});
return !!result;
};
@@ -198,8 +205,8 @@
var found = false;
if (obj == null) return found;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
any(obj, function(value) {
if (found = value === target) return true;
found = any(obj, function(value) {
return value === target;
});
return found;
};
@@ -220,6 +227,7 @@
// Return the maximum element or (element-based computation).
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return -Infinity;
var result = {computed : -Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
@@ -231,6 +239,7 @@
// Return the minimum element (or element-based computation).
_.min = function(obj, iterator, context) {
if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return Infinity;
var result = {computed : Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
@@ -239,6 +248,21 @@
return result.value;
};
// Shuffle an array.
_.shuffle = function(obj) {
var shuffled = [], rand;
each(obj, function(value, index, list) {
if (index == 0) {
shuffled[0] = value;
} else {
rand = Math.floor(Math.random() * (index + 1));
shuffled[index] = shuffled[rand];
shuffled[rand] = value;
}
});
return shuffled;
};
// Sort the object's values by a criterion produced by an iterator.
_.sortBy = function(obj, iterator, context) {
return _.pluck(_.map(obj, function(value, index, list) {
@@ -252,9 +276,11 @@
}), 'value');
};
// Groups the object's values by a criterion produced by an iterator
_.groupBy = function(obj, iterator) {
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = function(obj, val) {
var result = {};
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
each(obj, function(value, index) {
var key = iterator(value, index);
(result[key] || (result[key] = [])).push(value);
@@ -298,6 +324,24 @@
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
};
// Returns everything but the last entry of the array. Especcialy useful on
// the arguments object. Passing **n** will return all the values in
// the array, excluding the last N. The **guard** check allows it to work with
// `_.map`.
_.initial = function(array, n, guard) {
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
};
// Get the last element of an array. Passing **n** will return the last N
// values in the array. The **guard** check allows it to work with `_.map`.
_.last = function(array, n, guard) {
if ((n != null) && !guard) {
return slice.call(array, Math.max(array.length - n, 0));
} else {
return array[array.length - 1];
}
};
// Returns everything but the first entry of the array. Aliased as `tail`.
// Especially useful on the arguments object. Passing an **index** will return
// the rest of the values in the array from that index onward. The **guard**
@@ -306,20 +350,15 @@
return slice.call(array, (index == null) || guard ? 1 : index);
};
// Get the last element of an array.
_.last = function(array) {
return array[array.length - 1];
};
// Trim out all falsy values from an array.
_.compact = function(array) {
return _.filter(array, function(value){ return !!value; });
};
// Return a completely flattened version of an array.
_.flatten = function(array) {
_.flatten = function(array, shallow) {
return _.reduce(array, function(memo, value) {
if (_.isArray(value)) return memo.concat(_.flatten(value));
if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
memo[memo.length] = value;
return memo;
}, []);
@@ -333,17 +372,23 @@
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
_.uniq = _.unique = function(array, isSorted) {
return _.reduce(array, function(memo, el, i) {
if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el;
_.uniq = _.unique = function(array, isSorted, iterator) {
var initial = iterator ? _.map(array, iterator) : array;
var result = [];
_.reduce(initial, function(memo, el, i) {
if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
memo[memo.length] = el;
result[result.length] = array[i];
}
return memo;
}, []);
return result;
};
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
return _.uniq(_.flatten(arguments));
return _.uniq(_.flatten(arguments, true));
};
// Produce an array that contains every item shared between all the
@@ -391,7 +436,6 @@
return -1;
};
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
_.lastIndexOf = function(array, item) {
if (array == null) return -1;
@@ -426,15 +470,25 @@
// Function (ahem) Functions
// ------------------
// Reusable constructor function for prototype setting.
var ctor = function(){};
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Binding with arguments is also known as `curry`.
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
// We check for `func.bind` first, to fail fast when `func` is undefined.
_.bind = function(func, obj) {
_.bind = function bind(func, context) {
var bound, args;
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
var args = slice.call(arguments, 2);
return function() {
return func.apply(obj, args.concat(slice.call(arguments)));
if (!_.isFunction(func)) throw new TypeError;
args = slice.call(arguments, 2);
return bound = function() {
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
ctor.prototype = func.prototype;
var self = new ctor;
var result = func.apply(self, args.concat(slice.call(arguments)));
if (Object(result) === result) return result;
return self;
};
};
@@ -470,31 +524,43 @@
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
};
// Internal function used to implement `_.throttle` and `_.debounce`.
var limit = function(func, wait, debounce) {
var timeout;
return function() {
var context = this, args = arguments;
var throttler = function() {
timeout = null;
func.apply(context, args);
};
if (debounce) clearTimeout(timeout);
if (debounce || !timeout) timeout = setTimeout(throttler, wait);
};
};
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time.
_.throttle = function(func, wait) {
return limit(func, wait, false);
var context, args, timeout, throttling, more;
var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
return function() {
context = this; args = arguments;
var later = function() {
timeout = null;
if (more) func.apply(context, args);
whenDone();
};
if (!timeout) timeout = setTimeout(later, wait);
if (throttling) {
more = true;
} else {
func.apply(context, args);
}
whenDone();
throttling = true;
};
};
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds.
_.debounce = function(func, wait) {
return limit(func, wait, true);
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
func.apply(context, args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};
// Returns a function that will be executed at most one time, no matter how
@@ -533,12 +599,12 @@
// Returns a function that will only be executed after being called N times.
_.after = function(times, func) {
if (times <= 0) return func();
return function() {
if (--times < 1) { return func.apply(this, arguments); }
};
};
// Object Functions
// ----------------
@@ -588,6 +654,7 @@
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
if (!_.isObject(obj)) return obj;
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
@@ -599,47 +666,103 @@
return obj;
};
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
// Check object identity.
if (a === b) return true;
// Different types?
var atype = typeof(a), btype = typeof(b);
if (atype != btype) return false;
// Basic equality test (watch out for coercions).
if (a == b) return true;
// One is falsy and the other truthy.
if ((!a && b) || (a && !b)) return false;
// Internal recursive comparison function.
function eq(a, b, stack) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
if (a === b) return a !== 0 || 1 / a == 1 / b;
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
// Unwrap any wrapped objects.
if (a._chain) a = a._wrapped;
if (b._chain) b = b._wrapped;
// One of them implements an isEqual()?
if (a.isEqual) return a.isEqual(b);
if (b.isEqual) return b.isEqual(a);
// Check dates' integer values.
if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
// Both are NaN?
if (_.isNaN(a) && _.isNaN(b)) return false;
// Compare regular expressions.
if (_.isRegExp(a) && _.isRegExp(b))
return a.source === b.source &&
a.global === b.global &&
a.ignoreCase === b.ignoreCase &&
a.multiline === b.multiline;
// If a is not an object by this point, we can't handle it.
if (atype !== 'object') return false;
// Check for different array lengths before comparing contents.
if (a.length && (a.length !== b.length)) return false;
// Nothing else worked, deep compare the contents.
var aKeys = _.keys(a), bKeys = _.keys(b);
// Different object sizes?
if (aKeys.length != bKeys.length) return false;
// Recursive comparison of contents.
for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false;
return true;
// Invoke a custom `isEqual` method if one is provided.
if (_.isFunction(a.isEqual)) return a.isEqual(b);
if (_.isFunction(b.isEqual)) return b.isEqual(a);
// Compare `[[Class]]` names.
var className = toString.call(a);
if (className != toString.call(b)) return false;
switch (className) {
// Strings, numbers, dates, and booleans are compared by value.
case '[object String]':
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
return String(a) == String(b);
case '[object Number]':
a = +a;
b = +b;
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
// other numeric values.
return a != a ? b != b : (a == 0 ? 1 / a == 1 / b : a == b);
case '[object Date]':
case '[object Boolean]':
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
// millisecond representations. Note that invalid dates with millisecond representations
// of `NaN` are not equivalent.
return +a == +b;
// RegExps are compared by their source patterns and flags.
case '[object RegExp]':
return a.source == b.source &&
a.global == b.global &&
a.multiline == b.multiline &&
a.ignoreCase == b.ignoreCase;
}
if (typeof a != 'object' || typeof b != 'object') return false;
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
var length = stack.length;
while (length--) {
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if (stack[length] == a) return true;
}
// Add the first object to the stack of traversed objects.
stack.push(a);
var size = 0, result = true;
// Recursively compare objects and arrays.
if (className == '[object Array]') {
// Compare array lengths to determine if a deep comparison is necessary.
size = a.length;
result = size == b.length;
if (result) {
// Deep compare the contents, ignoring non-numeric properties.
while (size--) {
// Ensure commutative equality for sparse arrays.
if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
}
}
} else {
// Objects with different constructors are not equivalent.
if ("constructor" in a != "constructor" in b || a.constructor != b.constructor) return false;
// Deep compare objects.
for (var key in a) {
if (hasOwnProperty.call(a, key)) {
// Count the expected number of properties.
size++;
// Deep compare each member.
if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
}
}
// Ensure that both objects contain the same number of properties.
if (result) {
for (key in b) {
if (hasOwnProperty.call(b, key) && !(size--)) break;
}
result = !size;
}
}
// Remove the first object from the stack of traversed objects.
stack.pop();
return result;
}
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
return eq(a, b, []);
};
// Is a given array or object empty?
// Is a given array, string, or object empty?
// An "empty" object has no enumerable own-properties.
_.isEmpty = function(obj) {
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
@@ -654,7 +777,7 @@
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) === '[object Array]';
return toString.call(obj) == '[object Array]';
};
// Is a given variable an object?
@@ -663,44 +786,50 @@
};
// Is a given variable an arguments object?
_.isArguments = function(obj) {
return !!(obj && hasOwnProperty.call(obj, 'callee'));
};
if (toString.call(arguments) == '[object Arguments]') {
_.isArguments = function(obj) {
return toString.call(obj) == '[object Arguments]';
};
} else {
_.isArguments = function(obj) {
return !!(obj && hasOwnProperty.call(obj, 'callee'));
};
}
// Is a given value a function?
_.isFunction = function(obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
return toString.call(obj) == '[object Function]';
};
// Is a given value a string?
_.isString = function(obj) {
return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
return toString.call(obj) == '[object String]';
};
// Is a given value a number?
_.isNumber = function(obj) {
return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
return toString.call(obj) == '[object Number]';
};
// Is the given value `NaN`? `NaN` happens to be the only value in JavaScript
// that does not equal itself.
// Is the given value `NaN`?
_.isNaN = function(obj) {
// `NaN` is the only value for which `===` is not reflexive.
return obj !== obj;
};
// Is a given value a boolean?
_.isBoolean = function(obj) {
return obj === true || obj === false;
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
};
// Is a given value a date?
_.isDate = function(obj) {
return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
return toString.call(obj) == '[object Date]';
};
// Is the given value a regular expression?
_.isRegExp = function(obj) {
return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
return toString.call(obj) == '[object RegExp]';
};
// Is a given value equal to null?
@@ -733,6 +862,11 @@
for (var i = 0; i < n; i++) iterator.call(context, i);
};
// Escape a string for HTML interpolation.
_.escape = function(string) {
return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
};
// Add your own custom functions to the Underscore object, ensuring that
// they're correctly added to the OOP wrapper as well.
_.mixin = function(obj) {
@@ -753,7 +887,8 @@
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// JavaScript micro-templating, similar to John Resig's implementation.
@@ -765,19 +900,22 @@
'with(obj||{}){__p.push(\'' +
str.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'")
.replace(c.escape, function(match, code) {
return "',_.escape(" + code.replace(/\\'/g, "'") + "),'";
})
.replace(c.interpolate, function(match, code) {
return "'," + code.replace(/\\'/g, "'") + ",'";
})
.replace(c.evaluate || null, function(match, code) {
return "');" + code.replace(/\\'/g, "'")
.replace(/[\r\n\t]/g, ' ') + "__p.push('";
.replace(/[\r\n\t]/g, ' ') + ";__p.push('";
})
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
.replace(/\t/g, '\\t')
+ "');}return __p.join('');";
var func = new Function('obj', tmpl);
return data ? func(data) : func;
var func = new Function('obj', '_', tmpl);
return data ? func(data, _) : function(data) { return func(data, _) };
};
// The OOP Wrapper
@@ -836,4 +974,4 @@
return this._wrapped;
};
})();
}).call(this);
@@ -1,20 +1,14 @@
// Underscore.string
// (c) 2010 Esa-Matti Suuronen <esa-matti aet suuronen dot org>
// Underscore.strings is freely distributable under the terms of the MIT license.
// Documentation: https://github.com/edtsech/underscore.string
// Documentation: https://github.com/epeli/underscore.string
// Some code is borrowed from MooTools and Alexandru Marasteanu.
// Version 1.1.6
// Version 1.2.0
(function(root){
'use strict';
if (typeof _ != 'undefined') {
var _reverse = _().reverse,
_include = _.include;
}
// Defining helper functions.
var nativeTrim = String.prototype.trim;
@@ -22,7 +16,7 @@
var parseNumber = function(source) { return source * 1 || 0; };
var strRepeat = function(i, m) {
for (var o = []; m > 0; o[--m] = i);
for (var o = []; m > 0; o[--m] = i) {}
return o.join('');
};
@@ -174,6 +168,8 @@
var _s = {
VERSION: '1.2.0',
isBlank: sArgs(function(str){
return (/^\s*$/).test(str);
}),
@@ -235,18 +231,10 @@
return arr.join('');
}),
includes: sArgs(function(str, needle){
include: 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());
@@ -256,13 +244,9 @@
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));
}
},
reverse: sArgs(function(str){
return Array.prototype.reverse.apply(String(str).split('')).join('');
}),
splice: sArgs(function(str, i, howmany, substr){
var arr = str.split('');
@@ -309,6 +293,10 @@
return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1-$2').replace(/^([A-Z]+)/, '-$1').replace(/\_|\s+/g, '-').toLowerCase();
},
humanize: function(str){
return _s.capitalize(this.underscored(str).replace(/_id$/,'').replace(/_/g, ' '));
},
trim: sArgs(function(str, characters){
if (!characters && nativeTrim) {
return nativeTrim.call(str);
@@ -333,6 +321,27 @@
return str.length > length ? str.slice(0,length) + truncateStr : str;
}),
/**
* _s.prune: a more elegant version of truncate
* prune extra chars, never leaving a half-chopped word.
* @author github.com/sergiokas
*/
prune: sArgs(function(str, length, pruneStr){
pruneStr = pruneStr || '...';
length = parseNumber(length);
var pruned = '';
// Check if we're in the middle of a word
if( str.substring(length-1, length+1).search(/^\w\w$/) === 0 )
pruned = _s.rtrim(str.slice(0,length).replace(/([\W][\w]*)$/,''));
else
pruned = _s.rtrim(str.slice(0,length));
pruned = pruned.replace(/\W+$/,'');
return (pruned.length+pruneStr.length>str.length) ? str : pruned + pruneStr;
}),
words: function(str, delimiter) {
return String(str).split(delimiter || " ");
},
@@ -409,31 +418,51 @@
strLeftBack: sArgs(function(sourceStr, sep){
var pos = sourceStr.lastIndexOf(sep);
return (pos != -1) ? sourceStr.slice(0, pos) : sourceStr;
})
}),
exports: function() {
var result = {};
for (var prop in this) {
if (!this.hasOwnProperty(prop) || prop == 'include' || prop == 'contains' || prop == 'reverse') continue;
result[prop] = this[prop];
}
return result;
}
};
// 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;
_s.strip = _s.trim;
_s.lstrip = _s.ltrim;
_s.rstrip = _s.rtrim;
_s.center = _s.lrpad;
_s.ljust = _s.lpad;
_s.rjust = _s.rpad;
_s.contains = _s.include;
// CommonJS module is defined
if (typeof module !== 'undefined' && module.exports) {
// Export module
module.exports = _s;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
// Export module
module.exports = _s;
}
exports._s = _s;
// Integrate with Underscore.js
} else if (typeof root._ !== 'undefined') {
root._.mixin(_s);
// root._.mixin(_s);
root._.string = _s;
root._.str = root._.string;
// Or define it
} else {
root._ = _s;
root._ = {
string: _s,
str: _s
};
}
}(this || window));
@@ -0,0 +1,14 @@
(function(k){var o=String.prototype.trim,l=function(a,b){for(var c=[];b>0;c[--b]=a);return c.join("")},d=function(a){return function(){for(var b=Array.prototype.slice.call(arguments),c=0;c<b.length;c++)b[c]=b[c]==null?"":""+b[c];return a.apply(null,b)}},m=function(){function a(a){return Object.prototype.toString.call(a).slice(8,-1).toLowerCase()}var b=function(){b.cache.hasOwnProperty(arguments[0])||(b.cache[arguments[0]]=b.parse(arguments[0]));return b.format.call(null,b.cache[arguments[0]],arguments)};
b.format=function(b,n){var e=1,d=b.length,f="",j=[],h,i,g,k;for(h=0;h<d;h++)if(f=a(b[h]),f==="string")j.push(b[h]);else if(f==="array"){g=b[h];if(g[2]){f=n[e];for(i=0;i<g[2].length;i++){if(!f.hasOwnProperty(g[2][i]))throw m('[_.sprintf] property "%s" does not exist',g[2][i]);f=f[g[2][i]]}}else f=g[1]?n[g[1]]:n[e++];if(/[^s]/.test(g[8])&&a(f)!="number")throw m("[_.sprintf] expecting number but found %s",a(f));switch(g[8]){case "b":f=f.toString(2);break;case "c":f=String.fromCharCode(f);break;case "d":f=
parseInt(f,10);break;case "e":f=g[7]?f.toExponential(g[7]):f.toExponential();break;case "f":f=g[7]?parseFloat(f).toFixed(g[7]):parseFloat(f);break;case "o":f=f.toString(8);break;case "s":f=(f=String(f))&&g[7]?f.substring(0,g[7]):f;break;case "u":f=Math.abs(f);break;case "x":f=f.toString(16);break;case "X":f=f.toString(16).toUpperCase()}f=/[def]/.test(g[8])&&g[3]&&f>=0?"+"+f:f;i=g[4]?g[4]=="0"?"0":g[4].charAt(1):" ";k=g[6]-String(f).length;i=g[6]?l(i,k):"";j.push(g[5]?f+i:i+f)}return j.join("")};b.cache=
{};b.parse=function(a){for(var b=[],e=[],d=0;a;){if((b=/^[^\x25]+/.exec(a))!==null)e.push(b[0]);else if((b=/^\x25{2}/.exec(a))!==null)e.push("%");else if((b=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(a))!==null){if(b[2]){d|=1;var f=[],j=b[2],h=[];if((h=/^([a-z_][a-z_\d]*)/i.exec(j))!==null)for(f.push(h[1]);(j=j.substring(h[0].length))!=="";)if((h=/^\.([a-z_][a-z_\d]*)/i.exec(j))!==null)f.push(h[1]);else if((h=/^\[(\d+)\]/.exec(j))!==null)f.push(h[1]);
else throw"[_.sprintf] huh?";else throw"[_.sprintf] huh?";b[2]=f}else d|=2;if(d===3)throw"[_.sprintf] mixing positional and named placeholders is not (yet) supported";e.push(b)}else throw"[_.sprintf] huh?";a=a.substring(b[0].length)}return e};return b}(),e={VERSION:"1.2.0",isBlank:d(function(a){return/^\s*$/.test(a)}),stripTags:d(function(a){return a.replace(/<\/?[^>]+>/ig,"")}),capitalize:d(function(a){return a.charAt(0).toUpperCase()+a.substring(1).toLowerCase()}),chop:d(function(a,b){for(var b=
b*1||0||a.length,c=[],e=0;e<a.length;)c.push(a.slice(e,e+b)),e+=b;return c}),clean:d(function(a){return e.strip(a.replace(/\s+/g," "))}),count:d(function(a,b){for(var c=0,e,d=0;d<a.length;)e=a.indexOf(b,d),e>=0&&c++,d=d+(e>=0?e:0)+b.length;return c}),chars:d(function(a){return a.split("")}),escapeHTML:d(function(a){return a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}),unescapeHTML:d(function(a){return a.replace(/&lt;/g,"<").replace(/&gt;/g,
">").replace(/&quot;/g,'"').replace(/&apos;/g,"'").replace(/&amp;/g,"&")}),escapeRegExp:d(function(a){return a.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1")}),insert:d(function(a,b,c){a=a.split("");a.splice(b*1||0,0,c);return a.join("")}),include:d(function(a,b){return a.indexOf(b)!==-1}),join:d(function(a){var b=Array.prototype.slice.call(arguments);return b.join(b.shift())}),lines:d(function(a){return a.split("\n")}),reverse:d(function(a){return Array.prototype.reverse.apply(String(a).split("")).join("")}),
splice:d(function(a,b,c,e){a=a.split("");a.splice(b*1||0,c*1||0,e);return a.join("")}),startsWith:d(function(a,b){return a.length>=b.length&&a.substring(0,b.length)===b}),endsWith:d(function(a,b){return a.length>=b.length&&a.substring(a.length-b.length)===b}),succ:d(function(a){var b=a.split("");b.splice(a.length-1,1,String.fromCharCode(a.charCodeAt(a.length-1)+1));return b.join("")}),titleize:d(function(a){for(var a=a.split(" "),b,c=0;c<a.length;c++)b=a[c].split(""),typeof b[0]!=="undefined"&&(b[0]=
b[0].toUpperCase()),c+1===a.length?a[c]=b.join(""):a[c]=b.join("")+" ";return a.join("")}),camelize:d(function(a){return e.trim(a).replace(/(\-|_|\s)+(.)?/g,function(a,c,e){return e?e.toUpperCase():""})}),underscored:function(a){return e.trim(a).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/\-|\s+/g,"_").toLowerCase()},dasherize:function(a){return e.trim(a).replace(/([a-z\d])([A-Z]+)/g,"$1-$2").replace(/^([A-Z]+)/,"-$1").replace(/\_|\s+/g,"-").toLowerCase()},humanize:function(a){return e.capitalize(this.underscored(a).replace(/_id$/,
"").replace(/_/g," "))},trim:d(function(a,b){if(!b&&o)return o.call(a);b=b?e.escapeRegExp(b):"\\s";return a.replace(RegExp("^["+b+"]+|["+b+"]+$","g"),"")}),ltrim:d(function(a,b){b=b?e.escapeRegExp(b):"\\s";return a.replace(RegExp("^["+b+"]+","g"),"")}),rtrim:d(function(a,b){b=b?e.escapeRegExp(b):"\\s";return a.replace(RegExp("["+b+"]+$","g"),"")}),truncate:d(function(a,b,c){b=b*1||0;return a.length>b?a.slice(0,b)+(c||"..."):a}),prune:d(function(a,b,c){var c=c||"...",b=b*1||0,d="",d=a.substring(b-
1,b+1).search(/^\w\w$/)===0?e.rtrim(a.slice(0,b).replace(/([\W][\w]*)$/,"")):e.rtrim(a.slice(0,b)),d=d.replace(/\W+$/,"");return d.length+c.length>a.length?a:d+c}),words:function(a,b){return String(a).split(b||" ")},pad:d(function(a,b,c,e){var d="",d=0,b=b*1||0;c?c.length>1&&(c=c.charAt(0)):c=" ";switch(e){case "right":d=b-a.length;d=l(c,d);a+=d;break;case "both":d=b-a.length;d={left:l(c,Math.ceil(d/2)),right:l(c,Math.floor(d/2))};a=d.left+a+d.right;break;default:d=b-a.length,d=l(c,d),a=d+a}return a}),
lpad:function(a,b,c){return e.pad(a,b,c)},rpad:function(a,b,c){return e.pad(a,b,c,"right")},lrpad:function(a,b,c){return e.pad(a,b,c,"both")},sprintf:m,vsprintf:function(a,b){b.unshift(a);return m.apply(null,b)},toNumber:function(a,b){var c;c=(a*1||0).toFixed(b*1||0)*1||0;return!(c===0&&a!=="0"&&a!==0)?c:Number.NaN},strRight:d(function(a,b){var c=!b?-1:a.indexOf(b);return c!=-1?a.slice(c+b.length,a.length):a}),strRightBack:d(function(a,b){var c=!b?-1:a.lastIndexOf(b);return c!=-1?a.slice(c+b.length,
a.length):a}),strLeft:d(function(a,b){var c=!b?-1:a.indexOf(b);return c!=-1?a.slice(0,c):a}),strLeftBack:d(function(a,b){var c=a.lastIndexOf(b);return c!=-1?a.slice(0,c):a}),exports:function(){var a={},b;for(b in this)if(this.hasOwnProperty(b)&&!(b=="include"||b=="contains"||b=="reverse"))a[b]=this[b];return a}};e.strip=e.trim;e.lstrip=e.ltrim;e.rstrip=e.rtrim;e.center=e.lrpad;e.ljust=e.lpad;e.rjust=e.rpad;e.contains=e.include;if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)module.exports=
e;exports._s=e}else typeof k._!=="undefined"?(k._.string=e,k._.str=k._.string):k._={string:e,str:e}})(this||window);
+153 -20
View File
@@ -26,7 +26,7 @@ body.openerp, .openerp textarea, .openerp input, .openerp select, .openerp optio
margin: 0;
}
.openerp .oe-number {
.openerp .oe-listview .oe-number {
text-align: right !important;
}
.openerp .oe_hide {
@@ -40,6 +40,9 @@ body.openerp, .openerp textarea, .openerp input, .openerp select, .openerp optio
}
/* Loading */
.loading {
cursor: wait;
}
.openerp .loading {
display: none;
z-index: 100;
@@ -156,7 +159,7 @@ body.openerp, .openerp textarea, .openerp input, .openerp select, .openerp optio
}
.db_container {
width: 15%;
width: 196px;
background: #666666;
}
@@ -222,6 +225,7 @@ label.error {
background: #f0eeee;
}
.openerp .oe-application-container {
width: 100%;
height: 100%;
}
@@ -300,7 +304,7 @@ label.error {
text-shadow: 0 1px 0 #333;
text-align: center;
font-size: 18px;
line-height: 14px;
line-height: 18px;
right: 0;
}
.openerp .secondary_menu.oe_folded .oe_toggle_secondary_menu {
@@ -325,6 +329,7 @@ label.error {
background: #5A5858;
vertical-align: top;
height: 100%;
display: block;
position: relative;
}
.openerp .secondary_menu.oe_folded {
@@ -649,6 +654,9 @@ label.error {
display: none;
}
.openerp .oe_search-view-buttons {
padding: 10px 0 10px 0;
}
.openerp .oe_search-view-custom-filter-btn span {
background: url(/web/static/src/img/icons/gtk-add.png) repeat-y;
padding-left: 18px;
@@ -705,7 +713,26 @@ label.error {
.openerp .oe-listview th {
vertical-align: middle;
text-align: left;
padding: 1px 2px;
}
.openerp .oe-listview th.oe-record-selector,
.openerp .oe-listview td.oe-button,
.openerp .oe-listview td.oe-record-delete {
padding: 0 1px;
}
/* Could use :not selectors if they were supported by MSIE8... */
.openerp .oe-listview tbody td {
border-left: 1px solid #dadada;
}
.openerp .oe-listview tbody td:first-child,
.openerp .oe-listview tbody td.oe-button,
.openerp .oe-listview tbody td.oe-button+td,
.openerp .oe-listview tbody th.oe-record-selector+td,
.openerp .oe-listview tbody td.oe-record-delete {
border-left: none;
}
.openerp .oe-listview td.oe-record-delete {
text-align: right;
}
@@ -721,11 +748,15 @@ label.error {
.openerp .oe-listview .oe-field-cell {
cursor: pointer;
}
.openerp .oe-listview .oe-field-cell progress {
width: 100%;
}
.openerp .oe-listview .oe-field-cell button {
margin: 0;
padding: 0;
border: none;
background: none;
width: 100%;
width: 16px;
}
.openerp .oe-listview .oe-field-cell button:active {
opacity: 0.5;
@@ -767,6 +798,10 @@ label.error {
.openerp .oe-listview .oe-list-footer span {
margin: 0 1em;
}
.openerp .oe-listview .oe-list-footer progress {
vertical-align:-10% !important;
width: 100%;
}
/** list rounded corners
@@ -788,13 +823,15 @@ label.error {
-moz-border-radius-topright: 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 {
-webkit-border-bottom-left-radius: 7px;
-moz-border-radius-bottomleft: 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 {
-webkit-border-bottom-right-radius: 7px;
-moz-border-radius-bottomright: 7px;
@@ -807,6 +844,9 @@ label.error {
background: none;
border-width: 0;
}
.openerp .oe_form_notebook .ui-tabs-panel {
padding: 4px;
}
.openerp .oe_form_notebook ul.ui-tabs-nav {
padding-left: 0;
background: transparent;
@@ -828,9 +868,23 @@ label.error {
}
/* Form */
.openerp table.oe_frame td {
.openerp .oe_frame.oe_forms {
clear: both;
}
.openerp table.oe_frame {
color: #4c4c4c;
}
.openerp fieldset.oe_group_box {
border: 1px solid #AAAAAA;
moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
background: #F9F9F9;
padding: 4px;
}
.openerp fieldset.oe_group_box legend {
font-weight: bold;
}
.openerp td.oe_form_frame_cell {
padding: 2px;
position: relative;
@@ -854,9 +908,24 @@ label.error {
.openerp label.oe_label_help {
cursor: help;
}
.openerp #tiptip_content {
font-size: 12px;
}
.openerp .oe_tooltip_string {
color: #FD5;
font-weight: bold;
font-size: 13px;
}
.openerp .oe_tooltip_technical {
padding: 0 0 4px 0;
margin: 5px 0 0 15px;
list-style: circle;
}
.openerp .oe_tooltip_technical_title {
font-weight: bold;
}
.openerp .oe_form_field label.oe_label, .openerp .oe_form_field label.oe_label_help {
text-align: right;
.openerp .oe_forms label.oe_label, .openerp .oe_forms label.oe_label_help {
margin: 3px 0 0 10px;
}
.openerp label.oe_label_help span {
@@ -867,6 +936,18 @@ label.error {
top: -4px;
padding: 0 2px;
}
.openerp .oe_align_left {
text-align: left;
}
.openerp .oe_align_right {
text-align: right;
}
.openerp .oe_align_center {
text-align: center;
}
.openerp .oe_forms .oe_form_paragraph {
margin: 3px 0 0 0;
}
/* Inputs */
.openerp .oe_forms input[type="text"], .openerp .oe_forms input[type="password"], .openerp .oe_forms select, .openerp .oe_forms textarea {
@@ -943,7 +1024,7 @@ label.error {
position: relative;
}
.openerp input.oe-binary-file {
z-index: 2;
z-index: 0;
line-height: 0;
font-size: 50px;
position: absolute;
@@ -1051,20 +1132,43 @@ label.error {
}
.openerp .oe-view-manager-logs {
clear: both;
font-size: 85%;
margin: 0.25em 0;
background: #fff;
padding: 0 10px;
margin: 0.25em 0;
font-size: 85%;
color: #4C4C4C;
position: relative;
overflow: hidden;
}
.openerp .oe-view-manager-logs ul {
margin: 0;
padding: 0 10px;
list-style: none;
}
.openerp .oe-view-manager-logs li:before {
content: '→ ';
content: '\2192 ';
}
.openerp .oe-view-manager-logs a {
text-decoration: none;
color: inherit;
}
/* only display first three log items of a folded logs list */
.openerp .oe-view-manager-logs.oe-folded li:nth-child(n+4) {
display: none;
}
/* display link to more logs if there are more logs to view and the logview is
currently folded */
.openerp .oe-view-manager-logs a.oe-more-logs {
display: none;
}
.openerp .oe-view-manager-logs.oe-folded.oe-has-more a.oe-more-logs {
display: block;
}
.openerp .oe-view-manager-logs a.oe-remove-everything {
position: absolute;
top: 0;
right: 0;
cursor: pointer;
}
.openerp .view-manager-main-sidebar {
width: 180px;
@@ -1357,19 +1461,20 @@ label.error {
}
ul.oe-arrow-list {
padding-left: 0.5em;
padding-left: 1.1em;
margin: 0;
white-space: nowrap;
}
ul.oe-arrow-list li {
display: inline-block;
margin-left: -0.5em;
margin-left: -1em;
}
ul.oe-arrow-list li span {
vertical-align: top;
display: inline-block;
border-width:1em;
border-style:solid;
border-color: white;
border-color: #DEDEDE;
line-height:0em;
}
ul.oe-arrow-list .oe-arrow-list-before {
@@ -1378,16 +1483,44 @@ ul.oe-arrow-list .oe-arrow-list-before {
}
ul.oe-arrow-list .oe-arrow-list-after {
border-color: rgba(0,0,0,0);
border-left-color: white;
border-left-color: #DEDEDE;
border-right-width:0;
}
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 {
border-left-color: rgba(0,0,0,0);
}
ul.oe-arrow-list li.oe-arrow-list-selected .oe-arrow-list-after {
border-color: rgba(0,0,0,0);
border-left-color: #CFCCCC;
border-left-color: #B5B9FF;
}
.openerp .oe_view_editor {
border-collapse: collapse;
padding: 0;
align: left;
width: 100%;
}
.openerp .oe_view_editor_colum{
font-size: 90%;
font-weight: normal;
padding: 0;
border-bottom: 1px solid #CFCCCC;
}
.openerp .oe_view_editor_row:hover{
background-color: #F3F3F3;
}
.openerp .oe_view_editor_tree_grid{
text-align: left;
white-space: nowrap;
border-collapse: collapse;
width: 100%;
}
.openerp .oe_view_editor_tree_grid a:hover {
color: blue;
}
.openerp .oe_view_editor_tree_grid a {
display: block;
}
+16
View File
@@ -11,6 +11,22 @@
.openerp .oe_import_grid-row .oe_import_grid-cell {
border-bottom: 1px solid #E3E3E3;
}
.openerp .oe-import-no-result .oe-import-result {
display: none;
}
.openerp .oe-import fieldset {
cursor: pointer;
}
.openerp .oe-import fieldset legend:before {
content: '\25BC ';
}
.openerp .oe-import fieldset.oe-closed legend:before {
content: '\25B6 ';
}
.openerp .oe-import fieldset.oe-closed table {
display: none;
}
.openerp .separator.horizontal {
font-weight: bold;
border-bottom-width: 1px;
Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

+6 -1
View File
@@ -59,12 +59,17 @@ openerp.web = function(instance) {
openerp.web.formats(instance);
openerp.web.chrome(instance);
openerp.web.data(instance);
var files = ["views","search","list","form","list_editable","web_mobile","view_tree","data_export","data_import"];
var files = ["views","search","list","form","list_editable","web_mobile","view_tree","data_export","data_import","view_editor"];
for(var i=0; i<files.length; i++) {
if(openerp.web[files[i]]) {
openerp.web[files[i]](instance);
}
}
instance.log = function() {
if (instance.connection.debug && window.console) {
console.log.apply(console, arguments);
}
}
};
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
+140 -71
View File
@@ -5,15 +5,16 @@ openerp.web.chrome = function(openerp) {
var QWeb = openerp.web.qweb;
openerp.web.Notification = openerp.web.Widget.extend(/** @lends openerp.web.Notification# */{
/**
* @constructs openerp.web.Notification
* @extends openerp.web.Widget
*
* @param parent
* @param element_id
*/
init: function(parent, element_id) {
this._super(parent, element_id);
template: 'Notification',
identifier_prefix: 'notification-',
init: function() {
this._super.apply(this, arguments);
openerp.notification = this;
},
start: function() {
this._super.apply(this, arguments);
this.$element.notify({
speed: 500,
expires: 1500
@@ -29,8 +30,11 @@ openerp.web.Notification = openerp.web.Widget.extend(/** @lends openerp.web.Not
this.$element.notify('create', 'oe_notification_alert', {
title: title,
text: text
}, {
expires: false
});
}
});
openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog# */{
@@ -105,7 +109,7 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog#
}
},
start: function () {
this.$dialog = $('<div id="' + this.element_id + '"></div>').dialog(this.dialog_options);
this.$dialog = $(this.$element).dialog(this.dialog_options);
this._super();
return this;
},
@@ -132,20 +136,10 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog#
}
});
openerp.web.CrashManager = openerp.web.Dialog.extend(/** @lends openerp.web.CrashManager# */{
identifier_prefix: 'dialog_crash',
/**
* @constructs opener.web.CrashManager
* @extends openerp.web.Dialog
*
* @param parent
*/
init: function(parent) {
this._super(parent);
this.session.on_rpc_error.add(this.on_rpc_error);
},
on_button_Ok: function() {
this.close();
openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
init: function() {
this._super();
openerp.connection.on_rpc_error.add(this.on_rpc_error);
},
on_rpc_error: function(error) {
this.error = error;
@@ -157,24 +151,41 @@ openerp.web.CrashManager = openerp.web.Dialog.extend(/** @lends openerp.web.Cras
}
}
if (error.code === 200 && error.type) {
this.dialog_title = "OpenERP " + _.capitalize(error.type);
this.template = 'DialogWarning';
this.open({
width: 'auto',
height: 'auto'
});
this.on_managed_error(error);
} else {
this.dialog_title = "OpenERP Error";
this.template = 'DialogTraceback';
this.open({
width: 'auto',
height: 'auto'
});
this.on_traceback(error);
}
},
on_managed_error: function(error) {
$('<div>' + QWeb.render('DialogWarning', {error: error}) + '</div>').dialog({
title: "OpenERP " + _.str.capitalize(error.type),
buttons: {
Ok: function() {
$(this).dialog("close");
}
}
});
},
on_traceback: function(error) {
var dialog = new openerp.web.Dialog(this, {
title: "OpenERP " + _.str.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}));
}
});
openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading# */{
openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading# */{
template: 'Loading',
/**
* @constructs openerp.web.Loading
* @extends openerp.web.Widget
@@ -182,20 +193,39 @@ openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading#
* @param parent
* @param element_id
*/
init: function(parent, element_id) {
this._super(parent, element_id);
init: function(parent) {
this._super(parent);
this.count = 0;
this.blocked_ui = false;
this.session.on_rpc_request.add_first(this.on_rpc_event, 1);
this.session.on_rpc_response.add_last(this.on_rpc_event, -1);
},
on_rpc_event : function(increment) {
var self = this;
if (!this.count && increment === 1) {
// Block UI after 3s
this.long_running_timer = setTimeout(function () {
self.blocked_ui = true;
$.blockUI();
}, 3000);
}
this.count += increment;
if (this.count) {
if (this.count > 0) {
//this.$element.html(QWeb.render("Loading", {}));
this.$element.html("Loading ("+this.count+")");
this.$element.show();
this.widget_parent.$element.addClass('loading');
} else {
this.count = 0;
clearTimeout(this.long_running_timer);
// Don't unblock if blocked by somebody else
if (self.blocked_ui) {
this.blocked_ui = false;
$.unblockUI();
}
this.$element.fadeOut();
this.widget_parent.$element.removeClass('loading');
}
}
});
@@ -214,10 +244,8 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
this.$option_id = $('#' + option_id);
},
start: function() {
this._super();
this.$element.html(QWeb.render("Database", this));
this.$element.closest(".openerp")
.removeClass("login-mode")
.addClass("database_block");
var self = this;
var fetch_db = this.rpc("/web/database/get_list", {}, function(result) {
@@ -238,23 +266,30 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
this.$element.find('#db-restore').click(this.do_restore);
this.$element.find('#db-change-password').click(this.do_change_password);
this.$element.find('#back-to-login').click(function() {
self.stop();
self.hide();
});
},
stop: function () {
this.hide();
this.$option_id.empty();
this.$element
.find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login')
.unbind('click')
.end()
.closest(".openerp")
.addClass("login-mode")
.removeClass("database_block")
.end()
.empty();
this._super();
},
show: function () {
this.$element.closest(".openerp")
.removeClass("login-mode")
.addClass("database_block");
},
hide: function () {
this.$element.closest(".openerp")
.addClass("login-mode")
.removeClass("database_block")
},
/**
* Converts a .serializeArray() result into a dict. Does not bother folding
* multiple identical keys into an array, last key wins.
@@ -331,7 +366,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
self.$option_id.find("form[name=create_db_form]").validate({
submitHandler: function (form) {
var fields = $(form).serializeArray();
$.blockUI({message:'<img src="/web/static/src/img/throbber2.gif">'});
$.blockUI();
self.rpc("/web/database/create", {'fields': fields}, function(result) {
if (result.error) {
$.unblockUI();
@@ -340,6 +375,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
}
self.db_list.push(self.to_object(fields)['db_name']);
self.db_list.sort();
self.widget_parent.set_db_list(self.db_list);
var form_obj = self.to_object(fields);
self.wait_for_newdb(result, {
password: form_obj['super_admin_pwd'],
@@ -369,7 +405,8 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
}
$db_list.find(':selected').remove();
self.db_list.splice(_.indexOf(self.db_list, db, true), 1);
self.notification.notify("Dropping database", "The database '" + db + "' has been dropped");
self.widget_parent.set_db_list(self.db_list);
self.do_notify("Dropping database", "The database '" + db + "' has been dropped");
});
}
});
@@ -380,7 +417,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
.html(QWeb.render("BackupDB", self))
.find("form[name=backup_db_form]").validate({
submitHandler: function (form) {
$.blockUI({message:'<img src="/web/static/src/img/throbber2.gif">'});
$.blockUI();
self.session.get_file({
form: form,
error: function (body) {
@@ -401,7 +438,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
self.$option_id.find("form[name=restore_db_form]").validate({
submitHandler: function (form) {
$.blockUI({message:'<img src="/web/static/src/img/throbber2.gif">'});
$.blockUI();
$(form).ajaxSubmit({
url: '/web/database/restore',
type: 'POST',
@@ -454,7 +491,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
self.display_error(result);
return;
}
self.notification.notify("Changed Password", "Password has been changed successfully");
self.do_notify("Changed Password", "Password has been changed successfully");
});
}
});
@@ -462,7 +499,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
});
openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
remember_creditentials: true,
remember_credentials: true,
template: "Login",
identifier_prefix: 'oe-app-login-',
@@ -480,28 +517,37 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
this.selected_db = 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_login = localStorage.getItem('last_login_login_success');
if (jQuery.deparam(jQuery.param.querystring()).debug != undefined) {
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() {
var self = this;
this.database = new openerp.web.Database(
this, "oe_database", "oe_db_options");
this.database.start();
this.$element.find('#oe-db-config').click(function() {
self.database.start();
self.database.show();
});
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)
self.set_db_list(result.db_list);
},
function(error, event) {
if (error.data.fault_code === 'AccessDenied') {
@@ -510,6 +556,15 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
});
},
stop: function () {
this.database.stop();
this._super();
},
set_db_list: function (list) {
this.$element.find("[name=db]").replaceWith(
openerp.web.qweb.render('Login_dblist', {
db_list: list, selected_db: this.selected_db}))
},
on_login_invalid: function() {
this.$element.closest(".openerp").addClass("login-mode");
},
@@ -537,7 +592,7 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
this.session.session_login(db, login, password, function() {
if(self.session.session_is_valid()) {
if (self.has_local_storage) {
if(self.remember_creditentials) {
if(self.remember_credentials) {
localStorage.setItem('last_db_login_success', db);
localStorage.setItem('last_login_login_success', login);
if (jQuery.deparam(jQuery.param.querystring()).debug != undefined) {
@@ -779,9 +834,8 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{
},
start: function() {
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);
},
on_loaded: function(data) {
@@ -823,7 +877,9 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{
this.session.active_id = id;
this.rpc('/web/menu/action', {'menu_id': id}, this.on_menu_action_loaded);
}
ev.stopPropagation();
if (ev) {
ev.stopPropagation();
}
return false;
},
do_menu_click: function($clicked_menu, manual) {
@@ -866,6 +922,7 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{
$sub_menu.hide();
return true;
}
return manual;
} else {
return true;
}
@@ -920,20 +977,15 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
this._super(null, element_id);
openerp.webclient = this;
QWeb.add_template("/web/static/src/xml/base.xml");
var params = {};
if(jQuery.param != undefined && jQuery.deparam(jQuery.param.querystring()).kitten != undefined) {
this.$element.addClass("kitten-mode-activated");
}
this.$element.html(QWeb.render("Interface", params));
this.session = new openerp.web.Session();
this.loading = new openerp.web.Loading(this,"oe_loading");
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.notification = new openerp.web.Notification(this);
this.loading = new openerp.web.Loading(this);
this.crashmanager = new openerp.web.CrashManager();
this.header = new openerp.web.Header(this);
this.login = new openerp.web.Login(this);
@@ -954,12 +1006,28 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
},
start: function() {
this._super.apply(this, arguments);
this.notification.prependTo(this.$element);
this.loading.appendTo($('#oe_loading'));
this.header.appendTo($("#oe_header"));
this.session.start();
this.login.appendTo($('#oe_login'));
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() {
this.menu.do_reload();
if(this.action_manager)
this.action_manager.stop();
this.action_manager = new openerp.web.ActionManager(this);
@@ -1046,7 +1114,8 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
this.action_manager.do_action(action);
},
do_about: function() {
}
},
});
};
+98 -76
View File
@@ -10,8 +10,6 @@ if (!console.debug) {
}
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
*/
@@ -239,8 +237,8 @@ openerp.web.Registry = openerp.web.Class.extend( /** @lends openerp.web.Registry
* registry was created.
*
* An object path is simply a dotted name from the openerp root to the
* object pointed to (e.g. ``"openerp.web.Session"`` for an OpenERP
* session object).
* object pointed to (e.g. ``"openerp.web.Connection"`` for an OpenERP
* connection object).
*
* @constructs openerp.web.Registry
* @param {Object} mapping a mapping of keys to object-paths
@@ -287,14 +285,12 @@ openerp.web.Registry = openerp.web.Class.extend( /** @lends openerp.web.Registry
*/
get_any: function (keys) {
for (var i=0; i<keys.length; ++i) {
try {
return this.get_object(keys[i]);
} catch (e) {
if (e instanceof openerp.web.KeyNotFound) {
continue;
}
throw e;
var key = keys[i];
if (key === undefined || !(key in this.map)) {
continue;
}
return this.get_object(key);
}
throw new openerp.web.KeyNotFound(keys.join(','));
},
@@ -342,9 +338,9 @@ openerp.web.CallbackEnabled = openerp.web.Class.extend(/** @lends openerp.web.Ca
}
});
openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web.Session# */{
openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.web.Connection# */{
/**
* @constructs openerp.web.Session
* @constructs openerp.web.Connection
* @extends openerp.web.CallbackEnabled
*
* @param {String} [server] JSON-RPC endpoint hostname
@@ -365,7 +361,12 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
this.context = {};
this.shortcuts = [];
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';
this.do_load_qweb(['/web/webclient/qweb']);
},
start: function() {
this.session_restore();
},
@@ -386,6 +387,8 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
var self = this;
// Construct a JSON-RPC2 request, method is currently unused
params.session_id = this.session_id;
if (this.debug)
params.debug = 1;
// Call using the rpc_mode
var deferred = $.Deferred();
@@ -480,15 +483,17 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
session_login: function(db, login, password, success_callback) {
var self = this;
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.uid = result.uid;
self.user_context = result.context;
self.db = result.db;
self.session_save();
self.on_session_valid();
return true;
}).then(success_callback);
},
login: function() { this.session_login.apply(this, arguments); },
/**
* Reloads uid and session_id from local storage, if they exist
*/
@@ -527,7 +532,8 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
* @param name the cookie's 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(';');
for(var i=0; i<cookies.length; ++i) {
var cookie = cookies[i].replace(/^\s*/, '');
@@ -546,9 +552,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
*/
set_cookie: function (name, value, ttl) {
if (!this.name) { return; }
ttl = ttl || 24*60*60*365;
document.cookie = [
this.element_id + '|' + name + '=' + encodeURIComponent(JSON.stringify(value)),
this.name + '|' + name + '=' + encodeURIComponent(JSON.stringify(value)),
'path=/',
'max-age=' + ttl,
'expires=' + new Date(new Date().getTime() + ttl*1000).toGMTString()
].join(';');
@@ -568,15 +576,12 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
var file_list = ["/web/static/lib/datejs/globalization/" +
self.user_context.lang.replace("_", "-") + ".js"
];
if(self.debug) {
self.rpc('/web/webclient/csslist', {"mods": modules}, self.do_load_css);
self.rpc('/web/webclient/jslist', {"mods": modules}, function(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]));
}
self.rpc('/web/webclient/csslist', {"mods": modules}, self.do_load_css);
self.rpc('/web/webclient/jslist', {"mods": modules}, function(files) {
self.do_load_js(file_list.concat(files));
});
self.rpc('/web/webclient/qweblist', {"mods": modules}, self.do_load_qweb);
openerp._modules_loaded = true;
});
});
@@ -585,7 +590,7 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
var self = this;
_.each(files, function (file) {
$('head').append($('<link>', {
'href': file + (self.debug ? '?debug=' + (new Date().getTime()) : ''),
'href': file,
'rel': 'stylesheet',
'type': 'text/css'
}));
@@ -597,18 +602,25 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
var file = files.shift();
var tag = document.createElement('script');
tag.type = 'text/javascript';
tag.src = file + (this.debug ? '?debug=' + (new Date().getTime()) : '');
tag.src = file;
tag.onload = tag.onreadystatechange = function() {
if ( (tag.readyState && tag.readyState != "loaded" && tag.readyState != "complete") || tag.onload_done )
return;
tag.onload_done = true;
self.do_load_js(files);
};
document.head.appendChild(tag);
var head = document.head || document.getElementsByTagName('head')[0];
head.appendChild(tag);
} else {
this.on_modules_loaded();
}
},
do_load_qweb: function(files) {
var self = this;
_.each(files, function(file) {
openerp.web.qweb.add_template(file);
});
},
on_modules_loaded: function() {
for(var j=0; j<this.module_list.length; j++) {
var mod = this.module_list[j];
@@ -704,7 +716,7 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
if (parseInt(cookie_val, 10) !== token) { continue; }
// clear cookie
document.cookie = _.sprintf("%s=;expires=%s;path=/",
document.cookie = _.str.sprintf("%s=;expires=%s;path=/",
cookie_name, new Date().toGMTString());
if (options.success) { options.success(); }
complete();
@@ -715,36 +727,6 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
}
});
openerp.web.SessionAware = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.SessionAware# */{
/**
* Utility class that any class is allowed to extend to easy common manipulations.
*
* It provides rpc calls, callback on all methods preceded by "on_" or "do_" and a
* logging facility.
*
* @constructs openerp.web.SessionAware
* @extends openerp.web.CallbackEnabled
*
* @param {openerp.web.Session} session
*/
init: function(session) {
this._super();
this.session = session;
},
/**
* Performs a JSON-RPC call
*
* @param {String} url endpoint url
* @param {Object} data RPC parameters
* @param {Function} success RPC call success callback
* @param {Function} error RPC call error callback
* @returns {jQuery.Deferred} deferred object for the RPC call
*/
rpc: function(url, data, success, error) {
return this.session.rpc(url, data, success, error);
}
});
/**
* Base class for all visual components. Provides a lot of functionalities helpful
* for the management of a part of the DOM.
@@ -755,8 +737,6 @@ openerp.web.SessionAware = openerp.web.CallbackEnabled.extend(/** @lends openerp
* destroyed too).
* - Insertion in DOM.
*
* Widget also extends SessionAware for ease of use.
*
* Guide to create implementations of the Widget class:
* ==============================================
*
@@ -797,7 +777,7 @@ openerp.web.SessionAware = openerp.web.CallbackEnabled.extend(/** @lends openerp
*
* That will kill the widget in a clean way and erase its content from the dom.
*/
openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widget# */{
openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.Widget# */{
/**
* The name of the QWeb template that will be used for rendering. Must be
* redefined in subclasses or the default render() method can not be used.
@@ -812,11 +792,16 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
* @type string
*/
identifier_prefix: 'generic-identifier-',
/**
* Tag name when creating a default $element.
* @type string
*/
tag_name: 'div',
/**
* Construct the widget and set its parent if a parent is given.
*
* @constructs openerp.web.Widget
* @extends openerp.web.SessionAware
* @extends openerp.web.CallbackEnabled
*
* @param {openerp.web.Widget} parent Binds the current instance to the given Widget instance.
* When that widget is destroyed by calling stop(), the current instance will be
@@ -827,13 +812,14 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
* for new components this argument should not be provided any more.
*/
init: function(parent, /** @deprecated */ element_id) {
this._super((parent || {}).session);
this._super();
this.session = openerp.connection;
// if given an element_id, try to get the associated DOM element and save
// a reference in this.$element. Else just generate a unique identifier.
this.element_id = element_id;
this.element_id = this.element_id || _.uniqueId(this.identifier_prefix);
var tmp = document.getElementById(this.element_id);
this.$element = tmp ? $(tmp) : undefined;
this.$element = tmp ? $(tmp) : $(document.createElement(this.tag_name));
this.widget_parent = parent;
this.widget_children = [];
@@ -888,8 +874,7 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
}, target);
},
_render_and_insert: function(insertion, target) {
var rendered = this.render();
this.$element = $(rendered);
this.render_element();
if (target instanceof openerp.web.Widget)
target = target.$element;
insertion(target);
@@ -897,6 +882,18 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
return this.start();
},
on_inserted: function(element, widget) {},
/**
* Renders the element and insert the result of the render() method in this.$element.
*/
render_element: function() {
var rendered = this.render();
if (rendered) {
var elem = $(rendered);
this.$element.replaceWith(elem);
this.$element = elem;
}
return this;
},
/**
* Renders the widget using QWeb, `this.template` must be defined.
* The context given to QWeb contains the "widget" key that references `this`.
@@ -904,7 +901,9 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
* @param {Object} additional Additional context arguments to pass to the template.
*/
render: function (additional) {
return openerp.web.qweb.render(this.template, _.extend({widget: this}, additional || {}));
if (this.template)
return openerp.web.qweb.render(this.template, _.extend({widget: this}, additional || {}));
return null;
},
/**
* Method called after rendering. Mostly used to bind actions, perform asynchronous
@@ -916,12 +915,6 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
* @returns {jQuery.Deferred}
*/
start: function() {
/* The default implementation is only useful for retro-compatibility, it is
not necessary to call it using _super() when using Widget for new components. */
if (!this.$element) {
var tmp = document.getElementById(this.element_id);
this.$element = tmp ? $(tmp) : undefined;
}
return $.Deferred().done().promise();
},
/**
@@ -966,7 +959,7 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
rpc: function(url, data, success, error) {
var def = $.Deferred().then(success, error);
var self = this;
this._super(url, data). then(function() {
openerp.connection.rpc(url, data). then(function() {
if (!self.widget_is_stopped)
def.resolve.apply(def, arguments);
}, function() {
@@ -1000,7 +993,7 @@ openerp.web.TranslationDataBase = openerp.web.Class.extend(/** @lends openerp.we
this.parameters = {"direction": 'ltr',
"date_format": '%m/%d/%Y',
"time_format": '%H:%M:%S',
"grouping": "[]",
"grouping": [],
"decimal_point": ".",
"thousands_sep": ","};
},
@@ -1016,6 +1009,8 @@ openerp.web.TranslationDataBase = openerp.web.Class.extend(/** @lends openerp.we
});
if (translation_bundle.lang_parameters) {
this.parameters = translation_bundle.lang_parameters;
this.parameters.grouping = py.eval(
this.parameters.grouping).toJSON();
}
},
add_module_translation: function(mod) {
@@ -1042,7 +1037,34 @@ openerp.web.TranslationDataBase = openerp.web.Class.extend(/** @lends openerp.we
}
});
if ($.blockUI) {
$.blockUI.defaults.baseZ = 1100;
$.blockUI.defaults.message = '<img src="/web/static/src/img/throbber2.gif">';
}
/** Configure default qweb */
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.default_dict = {
'_' : _
}
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 = _.str.trim(s);
if (ts.length === 0) {
return s;
}
var tr = openerp.web._t(ts);
return tr === ts ? s : tr;
}
/** Setup default connection */
openerp.connection = new openerp.web.Connection();
};
+61 -19
View File
@@ -32,7 +32,7 @@ openerp.web.DataGroup = openerp.web.Widget.extend( /** @lends openerp.web.DataG
* @constructs openerp.web.DataGroup
* @extends openerp.web.Widget
*
* @param {openerp.web.Session} session Current OpenERP session
* @param {openerp.web.Widget} parent widget
* @param {String} model name of the model managed by this DataGroup
* @param {Array} domain search domain for this DataGroup
* @param {Object} context context of the DataGroup's searches
@@ -119,17 +119,18 @@ openerp.web.ContainerDataGroup = openerp.web.DataGroup.extend( /** @lends opener
aggregates[key] = value || 0;
});
var group_size = fixed_group[field_name + '_count'] || fixed_group.__count || 0;
var leaf_group = fixed_group.__context.group_by.length === 0;
return {
__context: fixed_group.__context,
__domain: fixed_group.__domain,
grouped_on: field_name,
// if terminal group (or no group) and group_by_no_leaf => use group.__count
length: fixed_group[field_name + '_count'] || fixed_group.__count,
length: group_size,
value: fixed_group[field_name],
openable: !(this.context['group_by_no_leaf']
&& fixed_group.__context.group_by.length === 0),
// A group is openable if it's not a leaf in group_by_no_leaf mode
openable: !(leaf_group && this.context['group_by_no_leaf']),
aggregates: aggregates
};
@@ -263,6 +264,15 @@ openerp.web.DataSet = openerp.web.Widget.extend( /** @lends openerp.web.DataSet
}
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.
*
@@ -484,7 +494,7 @@ openerp.web.DataSetStatic = openerp.web.DataSet.extend({
offset = options.offset || 0,
limit = options.limit || 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);
},
set_ids: function (ids) {
@@ -613,11 +623,11 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
create: function(data, callback, error_callback) {
var cached = {id:_.uniqueId(this.virtual_id_prefix), values: data,
defaults: this.last_default_get};
this.to_create.push(cached);
this.to_create.push(_.extend(_.clone(cached), {values: _.clone(cached.values)}));
this.cache.push(cached);
this.on_change();
var prom = $.Deferred().then(callback);
setTimeout(function() {prom.resolve({result: cached.id});}, 0);
prom.resolve({result: cached.id});
return prom.promise();
},
write: function (id, data, options, callback) {
@@ -639,6 +649,10 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
self.to_write.push(record);
}
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);
if (dirty)
this.on_change();
@@ -695,7 +709,7 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
throw "Record not correctly loaded";
}
}
setTimeout(function () {completion.resolve(records);}, 0);
completion.resolve(records);
};
if(to_get.length > 0) {
var rpc_promise = this._super(to_get, fields, function(records) {
@@ -720,27 +734,51 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
});
openerp.web.BufferedDataSet.virtual_id_regex = /^one2many_v_id_.*$/;
openerp.web.ReadOnlyDataSetSearch = openerp.web.DataSetSearch.extend({
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) {
this.on_create(data);
var to_return = $.Deferred().then(callback);
setTimeout(function () {to_return.resolve({"result": undefined});}, 0);
return to_return.promise();
if (this.create_function) {
return this.create_function(data, callback, error_callback);
} 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) {},
write: function (id, data, options, callback) {
this.on_write(id, data);
var to_return = $.Deferred().then(callback);
setTimeout(function () {to_return.resolve({"result": true});}, 0);
return to_return.promise();
if (this.write_function) {
return this.write_function(id, data, options, callback);
} 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) {},
unlink: function(ids, callback, error_callback) {
this.on_unlink(ids);
console.warn("trying to unlink 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();
@@ -748,11 +786,15 @@ openerp.web.ReadOnlyDataSetSearch = openerp.web.DataSetSearch.extend({
on_unlink: function(ids) {}
});
openerp.web.Model = openerp.web.SessionAware.extend({
init: function(session, model_name) {
this._super(session);
openerp.web.Model = openerp.web.CallbackEnabled.extend({
init: function(_, model_name) {
this._super();
this.model_name = model_name;
},
rpc: function() {
var c = openerp.connection;
return c.rpc.apply(c, arguments);
},
get_func: function(method_name) {
var self = this;
return function() {
+7 -2
View File
@@ -165,7 +165,11 @@ openerp.web.DataExport = openerp.web.Dialog.extend({
}
var model = record['params']['model'],
prefix = record['params']['prefix'],
name = record['params']['name'];
name = record['params']['name'],
exclude_fields = [];
if (record['relation_field']) {
exclude_fields.push(record['relation_field']);
}
if (!record.loaded) {
var import_comp = self.$element.find("#import_compat").val();
@@ -174,7 +178,8 @@ openerp.web.DataExport = openerp.web.Dialog.extend({
prefix: prefix,
parent_name: name,
import_compat: Boolean(import_comp),
parent_field_type : record['field_type']
parent_field_type : record['field_type'],
exclude: exclude_fields
}, function(results) {
record.loaded = true;
self.on_show_data(results, record.id);
+75 -13
View File
@@ -1,5 +1,6 @@
openerp.web.data_import = function(openerp) {
var QWeb = openerp.web.qweb;
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
@@ -37,6 +38,7 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
this.model = parent.model;
this.fields = [];
this.all_fields = [];
this.fields_with_defaults = [];
this.required_fields = null;
var convert_fields = function (root, prefix) {
@@ -50,7 +52,9 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
};
this.ready = $.Deferred.queue().then(function () {
self.required_fields = _(self.fields).chain()
.filter(function (field) { return field.required; })
.filter(function (field) {
return field.required &&
!_.include(self.fields_with_defaults, field.id); })
.pluck('name')
.value();
convert_fields(self);
@@ -66,8 +70,8 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
height: 'auto',
position: 'top',
buttons: [
{text: "Close", click: function() { self.stop(); }},
{text: "Import File", click: function() { self.do_import(); }, 'class': 'oe-dialog-import-button'}
{text: _t("Close"), click: function() { self.stop(); }},
{text: _t("Import File"), click: function() { self.do_import(); }, 'class': 'oe-dialog-import-button'}
],
close: function(event, ui) {
self.stop();
@@ -76,20 +80,38 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
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.$element.delegate('fieldset legend', 'click', function() {
$(this).parent().toggleClass('oe-closed');
});
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,
@@ -172,9 +194,11 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
: with_headers ? results.records.slice(1)
: results.records
}));
this.$element.find('fieldset').addClass('oe-closed');
} else if (results['error']) {
result_node.append(QWeb.render('ImportView.error', {
'error': results['error']}));
this.$element.find('fieldset').removeClass('oe-closed');
} else if (results['success']) {
if (this.widget_parent.widget_parent.active_view == "list") {
this.widget_parent.reload_content();
@@ -182,6 +206,11 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
this.stop();
return;
}
this.$element.find('form').removeClass('oe-import-no-result');
this.$element.delegate('.oe-m2o-drop-down-button', 'click', function () {
$(this).prev('input').focus();
});
var self = this;
this.ready.then(function () {
@@ -198,17 +227,50 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
});
// Column auto-detection
_(headers).each(function (header, index) {
var f =_(self.fields).detect(function (field) {
// TODO: levenshtein between header and field.string
return field.name === header || field.string.toLowerCase() === header;
});
if (f) {
$fields.eq(index).val(f.name);
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.
+6 -6
View File
@@ -18,11 +18,11 @@ openerp.web.str_to_datetime = function(str) {
var regex = /^(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d)(?:\.\d+)?$/;
var res = regex.exec(str);
if ( !res ) {
throw "'" + str + "' is not a valid datetime";
throw new Error("'" + str + "' is not a valid datetime");
}
var obj = Date.parse(res[1] + " GMT");
if (! obj) {
throw "'" + str + "' is not a valid datetime";
throw new Error("'" + str + "' is not a valid datetime");
}
return obj;
};
@@ -41,11 +41,11 @@ openerp.web.str_to_date = function(str) {
var regex = /^\d\d\d\d-\d\d-\d\d$/;
var res = regex.exec(str);
if ( !res ) {
throw "'" + str + "' is not a valid date";
throw new Error("'" + str + "' is not a valid date");
}
var obj = Date.parse(str);
if (! obj) {
throw "'" + str + "' is not a valid date";
throw new Error("'" + str + "' is not a valid date");
}
return obj;
};
@@ -64,11 +64,11 @@ openerp.web.str_to_time = function(str) {
var regex = /^(\d\d:\d\d:\d\d)(?:\.\d+)?$/;
var res = regex.exec(str);
if ( !res ) {
throw "'" + str + "' is not a valid time";
throw new Error("'" + str + "' is not a valid time");
}
var obj = Date.parse(res[1]);
if (! obj) {
throw "'" + str + "' is not a valid time";
throw new Error("'" + str + "' is not a valid time");
}
return obj;
};
+126 -59
View File
@@ -1,6 +1,66 @@
openerp.web.formats = function(openerp) {
var _t = openerp.web._t;
/**
* Intersperses ``separator`` in ``str`` at the positions indicated by
* ``indices``.
*
* ``indices`` is an array of relative offsets (from the previous insertion
* position, starting from the end of the string) at which to insert
* ``separator``.
*
* There are two special values:
*
* ``-1``
* indicates the insertion should end now
* ``0``
* indicates that the previous section pattern should be repeated (until all
* of ``str`` is consumed)
*
* @param {String} str
* @param {Array<Number>} indices
* @param {String} separator
* @returns {String}
*/
openerp.web.intersperse = function (str, indices, separator) {
separator = separator || '';
var result = [], last = str.length;
for(var i=0; i<indices.length; ++i) {
var section = indices[i];
if (section === -1 || last <= 0) {
// Done with string, or -1 (stops formatting string)
break;
} else if(section === 0 && i === 0) {
// repeats previous section, which there is none => stop
break;
} else if (section === 0) {
// repeat previous section forever
//noinspection AssignmentToForLoopParameterJS
section = indices[--i];
}
result.push(str.substring(last-section, last));
last -= section;
}
var s = str.substring(0, last);
if (s) { result.push(s); }
return result.reverse().join(separator);
};
/**
* Insert "thousands" separators in the provided number (which is actually
* a string)
*
* @param {String} num
* @returns {String}
*/
openerp.web.insert_thousand_seps = function (num) {
var negative = num[0] === '-';
num = (negative ? num.slice(1) : num);
return (negative ? '-' : '') + openerp.web.intersperse(
num, _t.database.parameters.grouping, _t.database.parameters.thousands_sep);
};
/**
* Formats a single atomic value based on a field descriptor
*
@@ -16,28 +76,34 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
if (typeof value === 'number' && isNaN(value)) {
value = false;
}
//noinspection FallthroughInSwitchStatementJS
switch (value) {
case '':
if (descriptor.type === 'char') {
return '';
}
console.warn('Field', descriptor, 'had an empty string as value, treating as false...');
case false:
case Infinity:
case -Infinity:
return value_if_empty === undefined ? '' : value_if_empty;
}
var l10n = _t.database.parameters;
switch (descriptor.widget || descriptor.type) {
case 'integer':
return _.sprintf('%d', value);
return openerp.web.insert_thousand_seps(
_.str.sprintf('%d', value));
case 'float':
var precision = descriptor.digits ? descriptor.digits[1] : 2;
var int_part = Math.floor(value);
var dec_part = Math.abs(Math.floor((value % 1) * Math.pow(10, precision)));
return _.sprintf('%d%s%d',
int_part,
openerp.web._t.database.parameters.decimal_point, dec_part);
var formatted = _.str.sprintf('%.' + precision + 'f', value).split('.');
formatted[0] = openerp.web.insert_thousand_seps(formatted[0]);
return formatted.join(l10n.decimal_point);
case 'float_time':
return _.sprintf("%02d:%02d",
return _.str.sprintf("%02d:%02d",
Math.floor(value),
Math.round((value % 1) * 60));
case 'progressbar':
return _.sprintf(
return _.str.sprintf(
'<progress value="%.2f" max="100.0">%.2f%%</progress>',
value, value);
case 'many2one':
@@ -46,35 +112,32 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
case 'datetime':
if (typeof(value) == "string")
value = openerp.web.auto_str_to_date(value);
try {
return value.toString(_.sprintf("%s %s", Date.CultureInfo.formatPatterns.shortDate,
Date.CultureInfo.formatPatterns.longTime));
} catch (e) {
return value.format("%m/%d/%Y %H:%M:%S");
}
return value;
return value.format(l10n.date_format
+ ' ' + l10n.time_format);
case 'date':
if (typeof(value) == "string")
value = openerp.web.auto_str_to_date(value);
try {
return value.toString(Date.CultureInfo.formatPatterns.shortDate);
} catch (e) {
return value.format("%m/%d/%Y");
}
return value.format(l10n.date_format);
case 'time':
if (typeof(value) == "string")
value = openerp.web.auto_str_to_date(value);
try {
return value.toString(Date.CultureInfo.formatPatterns.longTime);
} catch (e) {
return value.format("%H:%M:%S");
}
return value.format(l10n.time_format);
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:
return value;
}
};
openerp.web.parse_value = function (value, descriptor, value_if_empty) {
var date_pattern = Date.normalizeFormat(_t.database.parameters.date_format),
time_pattern = Date.normalizeFormat(_t.database.parameters.time_format);
switch (value) {
case false:
case "":
@@ -89,7 +152,7 @@ openerp.web.parse_value = function (value, descriptor, value_if_empty) {
} while(tmp !== value);
tmp = Number(value);
if (isNaN(tmp))
throw value + " is not a correct integer";
throw new Error(value + " is not a correct integer");
return tmp;
case 'float':
var tmp = Number(value);
@@ -103,42 +166,42 @@ openerp.web.parse_value = function (value, descriptor, value_if_empty) {
} while(tmp !== tmp2);
tmp = Number(tmp);
if (isNaN(tmp))
throw value + " is not a correct float";
throw new Error(value + " is not a correct float");
return tmp;
case 'float_time':
var tmp = value.split(":");
if (tmp.length != 2)
throw value + " is not a correct float_time";
var tmp1 = openerp.web.parse_value(tmp[0], {type: "integer"});
var tmp2 = openerp.web.parse_value(tmp[1], {type: "integer"});
return tmp1 + (tmp2 / 60);
var float_time_pair = value.split(":");
if (float_time_pair.length != 2)
return openerp.web.parse_value(value, {type: "float"});
var hours = openerp.web.parse_value(float_time_pair[0], {type: "integer"});
var minutes = openerp.web.parse_value(float_time_pair[1], {type: "integer"});
return hours + (minutes / 60);
case 'progressbar':
return openerp.web.parse_value(value, {type: "float"});
case 'datetime':
var tmp = Date.parseExact(value, _.sprintf("%s %s", Date.CultureInfo.formatPatterns.shortDate,
Date.CultureInfo.formatPatterns.longTime));
if (tmp !== null)
return openerp.web.datetime_to_str(tmp);
tmp = Date.parse(value);
if (tmp !== null)
return openerp.web.datetime_to_str(tmp);
throw value + " is not a valid datetime";
var datetime = Date.parseExact(
value, (date_pattern + ' ' + time_pattern));
if (datetime !== null)
return openerp.web.datetime_to_str(datetime);
datetime = Date.parse(value);
if (datetime !== null)
return openerp.web.datetime_to_str(datetime);
throw new Error(value + " is not a valid datetime");
case 'date':
var tmp = Date.parseExact(value, Date.CultureInfo.formatPatterns.shortDate);
if (tmp !== null)
return openerp.web.date_to_str(tmp);
tmp = Date.parse(value);
if (tmp !== null)
return openerp.web.date_to_str(tmp);
throw value + " is not a valid date";
var date = Date.parseExact(value, date_pattern);
if (date !== null)
return openerp.web.date_to_str(date);
date = Date.parse(value);
if (date !== null)
return openerp.web.date_to_str(date);
throw new Error(value + " is not a valid date");
case 'time':
var tmp = Date.parseExact(value, Date.CultureInfo.formatPatterns.longTime);
if (tmp !== null)
return openerp.web.time_to_str(tmp);
tmp = Date.parse(value);
if (tmp !== null)
return openerp.web.time_to_str(tmp);
throw value + " is not a valid time";
var time = Date.parseExact(value, time_pattern);
if (time !== null)
return openerp.web.time_to_str(time);
time = Date.parse(value);
if (time !== null)
return openerp.web.time_to_str(time);
throw new Error(value + " is not a valid time");
}
return value;
};
@@ -153,7 +216,7 @@ openerp.web.auto_str_to_date = function(value, type) {
try {
return openerp.web.str_to_time(value);
} catch(e) {}
throw "'" + value + "' is not a valid date, datetime nor time"
throw new Error("'" + value + "' is not a valid date, datetime nor time");
};
openerp.web.auto_date_to_str = function(value, type) {
@@ -165,7 +228,7 @@ openerp.web.auto_date_to_str = function(value, type) {
case 'time':
return openerp.web.time_to_str(value);
default:
throw type + " is not convertible to date, datetime nor time"
throw new Error(type + " is not convertible to date, datetime nor time");
}
};
@@ -179,9 +242,13 @@ openerp.web.auto_date_to_str = function(value, type) {
* @param {String} [column.string] button label
* @param {String} [column.icon] button icon
* @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) {
var attrs = column.modifiers_for(row_data);
openerp.web.format_cell = function (row_data, column, value_if_empty, process_modifiers) {
var attrs = {};
if (process_modifiers !== false) {
attrs = column.modifiers_for(row_data);
}
if (attrs.invisible) { return ''; }
if (column.tag === 'button') {
return [
+154 -79
View File
@@ -1,5 +1,6 @@
openerp.web.search = function(openerp) {
var QWeb = openerp.web.qweb;
var QWeb = openerp.web.qweb,
_t = openerp.web._t;
openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.SearchView# */{
template: "EmptyComponent",
@@ -13,24 +14,35 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
* @param view_id
* @param defaults
*/
init: function(parent, dataset, view_id, defaults) {
init: function(parent, dataset, view_id, defaults, hidden) {
this._super(parent);
this.dataset = dataset;
this.model = dataset.model;
this.view_id = view_id;
this.defaults = defaults || {};
this.has_defaults = !_.isEmpty(this.defaults);
this.inputs = [];
this.enabled_filters = [];
this.has_focus = false;
this.hidden = !!hidden;
this.headless = this.hidden && !this.has_defaults;
this.ready = $.Deferred();
},
start: function() {
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();
},
show: function () {
@@ -52,6 +64,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
rows.push(row);
var filters = [];
_.each(items, function (item) {
if (item.attrs.invisible === '1') { return; }
if (filters.length && item.tag !== 'filter') {
row.push(
new openerp.web.search.FilterGroup(
@@ -105,8 +118,9 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
*/
make_field: function (item, field) {
try {
return new (openerp.web.search.fields.get_object(field.type))
(item, field, this);
return new (openerp.web.search.fields.get_any(
[item.attrs.widget, field.type]))
(item, field, this);
} catch (e) {
if (! e instanceof openerp.web.KeyNotFound) {
throw e;
@@ -121,6 +135,12 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
}
},
on_loaded: function(data) {
if (data.fields_view.type !== 'search' ||
data.fields_view.arch.tag !== 'search') {
throw new Error(_.str.sprintf(
"Got non-search view after asking for a search view: type %s, arch root %s",
data.fields_view.type, data.fields_view.arch.tag));
}
var self = this,
lines = this.make_widgets(
data.fields_view['arch'].children,
@@ -137,10 +157,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
'defaults': this.defaults
});
// We don't understand why the following commented line does not work in Chrome but
// the non-commented line does. As far as we investigated, only God knows.
//this.$element.html(render);
jQuery(render).appendTo(this.$element);
this.$element.html(render);
this.$element.find(".oe_search-view-custom-filter-btn").click(ext.on_activate);
var f = this.$element.find('form');
@@ -201,12 +218,12 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
var $dial = $(dial_html);
$dial.dialog({
modal: true,
title: "Filter Entry",
buttons: {
Cancel: function() {
title: _t("Filter Entry"),
buttons: [
{text: _t("Cancel"), click: function() {
$(this).dialog("close");
},
OK: function() {
}},
{text: _t("OK"), click: function() {
$(this).dialog("close");
var name = $(this).find("input").val();
self.rpc('/web/searchview/save_filter', {
@@ -217,8 +234,8 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
}).then(function() {
self.reload_managed_filters();
});
}
}
}}
]
});
} else { // manage_filters
select.val("_filters");
@@ -246,10 +263,13 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
* @param e jQuery event object coming from the "Search" button
*/
do_search: function (e) {
if (this.headless && !this.has_defaults) {
return this.on_search([], [], []);
}
// reset filters management
var select = this.$element.find(".oe_search-view-filters-management");
select.val("_filters");
if (e && e.preventDefault) { e.preventDefault(); }
var data = this.build_search_data();
@@ -324,10 +344,10 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
* @param {Array} errors a never-empty array of error objects
*/
on_invalid: function (errors) {
this.notification.notify("Invalid Search", "triggered from search view");
this.do_notify(_t("Invalid Search"), _t("triggered from search view"));
},
do_clear: function () {
this.$element.find('.filter_label').removeClass('enabled');
this.$element.find('.filter_label, .filter_icon').removeClass('enabled');
this.enabled_filters.splice(0);
var string = $('a.searchview_group_string');
_.each(string, function(str){
@@ -336,7 +356,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
this.$element.find('table:last').hide();
$('.searchview_extended_groups_list').empty();
setTimeout(this.on_clear);
setTimeout(this.on_clear, 0);
},
/**
* Triggered when the search view gets cleared
@@ -405,8 +425,10 @@ openerp.web.search.Invalid = openerp.web.Class.extend( /** @lends openerp.web.se
this.message = message;
},
toString: function () {
return ('Incorrect value for field ' + this.field +
': [' + this.value + '] is ' + this.message);
return _.str.sprintf(
_t("Incorrect value for field %(fieldname)s: [%(value)s] is %(message)s"),
{fieldname: this.field, value: this.value, message: this.message}
);
}
});
openerp.web.search.Widget = openerp.web.Widget.extend( /** @lends openerp.web.search.Widget# */{
@@ -420,6 +442,7 @@ openerp.web.search.Widget = openerp.web.Widget.extend( /** @lends openerp.web.se
* @param view the ancestor view of this widget
*/
init: function (view) {
this._super(view);
this.view = view;
},
/**
@@ -460,10 +483,8 @@ openerp.web.search.Widget = openerp.web.Widget.extend( /** @lends openerp.web.se
this._super();
},
render: function (defaults) {
return QWeb.render(
this.template, _.extend(this, {
defaults: defaults
}));
// FIXME
return this._super(_.extend(this, {defaults: defaults}));
}
});
openerp.web.search.add_expand_listener = function($root) {
@@ -631,6 +652,12 @@ openerp.web.search.Field = openerp.web.search.Input.extend( /** @lends openerp.w
this.attrs = _.extend({}, field, view_section.attrs);
this.filters = new openerp.web.search.FilterGroup(_.map(
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(
filter_node, view);
}), view);
@@ -720,7 +747,7 @@ openerp.web.search.NumberField = openerp.web.search.Field.extend(/** @lends open
* @extends openerp.web.search.NumberField
*/
openerp.web.search.IntegerField = openerp.web.search.NumberField.extend(/** @lends openerp.web.search.IntegerField# */{
error_message: "not a valid integer",
error_message: _t("not a valid integer"),
parse: function (value) {
try {
return openerp.web.parse_value(value, {'widget': 'integer'});
@@ -734,7 +761,7 @@ openerp.web.search.IntegerField = openerp.web.search.NumberField.extend(/** @len
* @extends openerp.web.search.NumberField
*/
openerp.web.search.FloatField = openerp.web.search.NumberField.extend(/** @lends openerp.web.search.FloatField# */{
error_message: "not a valid number",
error_message: _t("not a valid number"),
parse: function (value) {
try {
return openerp.web.parse_value(value, {'widget': 'float'});
@@ -748,9 +775,44 @@ openerp.web.search.FloatField = openerp.web.search.NumberField.extend(/** @lends
* @extends openerp.web.search.Field
*/
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',
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 () {
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# */{
@@ -910,15 +972,18 @@ openerp.web.search.ExtendedSearch = openerp.web.OldWidget.extend({
this.check_last_element();
},
start: function () {
this._super();
if (!this.$element) {
return; // not a logical state but sometimes it happens
}
this.$element = $("#" + this.element_id);
this.$element.closest("table.oe-searchview-render-line").css("display", "none");
var self = this;
this.rpc("/web/searchview/fields_get",
{"model": this.model}, function(data) {
self.fields = data.fields;
if (!('id' in self.fields)) {
self.fields.id = {
string: 'ID',
type: 'id'
}
}
openerp.web.search.add_expand_listener(self.$element);
self.$element.find('.searchview_extended_add_group').click(function (e) {
self.add_group();
@@ -975,7 +1040,7 @@ openerp.web.search.ExtendedSearchGroup = openerp.web.OldWidget.extend({
prop.start();
},
start: function () {
this._super();
this.$element = $("#" + this.element_id);
var _this = this;
this.add_prop();
this.$element.find('.searchview_extended_add_proposition').click(function () {
@@ -1027,7 +1092,7 @@ openerp.web.search.ExtendedSearchProposition = openerp.web.OldWidget.extend(/**
this.value = null;
},
start: function () {
this._super();
this.$element = $("#" + this.element_id);
this.select_field(this.fields.length > 0 ? this.fields[0] : null);
var _this = this;
this.$element.find(".searchview_extended_prop_field").change(function() {
@@ -1103,33 +1168,38 @@ openerp.web.search.ExtendedSearchProposition = openerp.web.OldWidget.extend(/**
}
});
openerp.web.search.ExtendedSearchProposition.Char = openerp.web.OldWidget.extend({
openerp.web.search.ExtendedSearchProposition.Field = openerp.web.OldWidget.extend({
start: function () {
this.$element = $("#" + this.element_id);
}
});
openerp.web.search.ExtendedSearchProposition.Char = openerp.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.char',
identifier_prefix: 'extended-search-proposition-char',
operators: [
{value: "ilike", text: "contains"},
{value: "not ilike", text: "doesn't contain"},
{value: "=", text: "is equal to"},
{value: "!=", text: "is not equal to"},
{value: ">", text: "greater than"},
{value: "<", text: "less than"},
{value: ">=", text: "greater or equal than"},
{value: "<=", text: "less or equal than"}
{value: "ilike", text: _t("contains")},
{value: "not ilike", text: _t("doesn't contain")},
{value: "=", text: _t("is equal to")},
{value: "!=", text: _t("is not equal to")},
{value: ">", text: _t("greater than")},
{value: "<", text: _t("less than")},
{value: ">=", text: _t("greater or equal than")},
{value: "<=", text: _t("less or equal than")}
],
get_value: function() {
return this.$element.val();
}
});
openerp.web.search.ExtendedSearchProposition.DateTime = openerp.web.OldWidget.extend({
openerp.web.search.ExtendedSearchProposition.DateTime = openerp.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.empty',
identifier_prefix: 'extended-search-proposition-datetime',
operators: [
{value: "=", text: "is equal to"},
{value: "!=", text: "is not equal to"},
{value: ">", text: "greater than"},
{value: "<", text: "less than"},
{value: ">=", text: "greater or equal than"},
{value: "<=", text: "less or equal than"}
{value: "=", text: _t("is equal to")},
{value: "!=", text: _t("is not equal to")},
{value: ">", text: _t("greater than")},
{value: "<", text: _t("less than")},
{value: ">=", text: _t("greater or equal than")},
{value: "<=", text: _t("less or equal than")}
],
get_value: function() {
return this.datewidget.get_value();
@@ -1140,16 +1210,16 @@ openerp.web.search.ExtendedSearchProposition.DateTime = openerp.web.OldWidget.ex
this.datewidget.prependTo(this.$element);
}
});
openerp.web.search.ExtendedSearchProposition.Date = openerp.web.OldWidget.extend({
openerp.web.search.ExtendedSearchProposition.Date = openerp.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.empty',
identifier_prefix: 'extended-search-proposition-date',
operators: [
{value: "=", text: "is equal to"},
{value: "!=", text: "is not equal to"},
{value: ">", text: "greater than"},
{value: "<", text: "less than"},
{value: ">=", text: "greater or equal than"},
{value: "<=", text: "less or equal than"}
{value: "=", text: _t("is equal to")},
{value: "!=", text: _t("is not equal to")},
{value: ">", text: _t("greater than")},
{value: "<", text: _t("less than")},
{value: ">=", text: _t("greater or equal than")},
{value: "<=", text: _t("less or equal than")}
],
get_value: function() {
return this.datewidget.get_value();
@@ -1160,16 +1230,16 @@ openerp.web.search.ExtendedSearchProposition.Date = openerp.web.OldWidget.extend
this.datewidget.prependTo(this.$element);
}
});
openerp.web.search.ExtendedSearchProposition.Integer = openerp.web.OldWidget.extend({
openerp.web.search.ExtendedSearchProposition.Integer = openerp.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.integer',
identifier_prefix: 'extended-search-proposition-integer',
operators: [
{value: "=", text: "is equal to"},
{value: "!=", text: "is not equal to"},
{value: ">", text: "greater than"},
{value: "<", text: "less than"},
{value: ">=", text: "greater or equal than"},
{value: "<=", text: "less or equal than"}
{value: "=", text: _t("is equal to")},
{value: "!=", text: _t("is not equal to")},
{value: ">", text: _t("greater than")},
{value: "<", text: _t("less than")},
{value: ">=", text: _t("greater or equal than")},
{value: "<=", text: _t("less or equal than")}
],
get_value: function() {
try {
@@ -1179,16 +1249,19 @@ openerp.web.search.ExtendedSearchProposition.Integer = openerp.web.OldWidget.ext
}
}
});
openerp.web.search.ExtendedSearchProposition.Float = openerp.web.OldWidget.extend({
openerp.web.search.ExtendedSearchProposition.Id = openerp.web.search.ExtendedSearchProposition.Integer.extend({
operators: [{value: "=", text: _t("is")}]
});
openerp.web.search.ExtendedSearchProposition.Float = openerp.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.float',
identifier_prefix: 'extended-search-proposition-float',
operators: [
{value: "=", text: "is equal to"},
{value: "!=", text: "is not equal to"},
{value: ">", text: "greater than"},
{value: "<", text: "less than"},
{value: ">=", text: "greater or equal than"},
{value: "<=", text: "less or equal than"}
{value: "=", text: _t("is equal to")},
{value: "!=", text: _t("is not equal to")},
{value: ">", text: _t("greater than")},
{value: "<", text: _t("less than")},
{value: ">=", text: _t("greater or equal than")},
{value: "<=", text: _t("less or equal than")}
],
get_value: function() {
try {
@@ -1198,12 +1271,12 @@ openerp.web.search.ExtendedSearchProposition.Float = openerp.web.OldWidget.exten
}
}
});
openerp.web.search.ExtendedSearchProposition.Selection = openerp.web.OldWidget.extend({
openerp.web.search.ExtendedSearchProposition.Selection = openerp.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.selection',
identifier_prefix: 'extended-search-proposition-selection',
operators: [
{value: "=", text: "is"},
{value: "!=", text: "is not"}
{value: "=", text: _t("is")},
{value: "!=", text: _t("is not")}
],
set_field: function(field) {
this.field = field;
@@ -1212,12 +1285,12 @@ openerp.web.search.ExtendedSearchProposition.Selection = openerp.web.OldWidget.e
return this.$element.val();
}
});
openerp.web.search.ExtendedSearchProposition.Boolean = openerp.web.OldWidget.extend({
openerp.web.search.ExtendedSearchProposition.Boolean = openerp.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.boolean',
identifier_prefix: 'extended-search-proposition-boolean',
operators: [
{value: "=", text: "is true"},
{value: "!=", text: "is false"}
{value: "=", text: _t("is true")},
{value: "!=", text: _t("is false")}
],
get_value: function() {
return true;
@@ -1236,7 +1309,9 @@ openerp.web.search.custom_filters = new openerp.web.Registry({
'integer': 'openerp.web.search.ExtendedSearchProposition.Integer',
'float': 'openerp.web.search.ExtendedSearchProposition.Float',
'boolean': 'openerp.web.search.ExtendedSearchProposition.Boolean',
'selection': 'openerp.web.search.ExtendedSearchProposition.Selection'
'selection': 'openerp.web.search.ExtendedSearchProposition.Selection',
'id': 'openerp.web.search.ExtendedSearchProposition.Id'
});
};
+516
View File
@@ -0,0 +1,516 @@
openerp.web.view_editor = function(openerp) {
var QWeb = openerp.web.qweb;
openerp.web.ViewEditor = openerp.web.Widget.extend({
init: function(parent, element_id, dataset, view, options) {
this._super(parent);
this.element_id = element_id
this.parent = parent
this.dataset = dataset;
this.model = dataset.model;
this.xml_id = 0;
},
start: function() {
this.init_view_editor();
},
init_view_editor: function() {
var self = this;
var action = {
name:'ViewEditor',
context:this.session.user_context,
domain: [["model", "=", this.dataset.model]],
res_model : 'ir.ui.view',
views : [[false, 'list']],
type: 'ir.actions.act_window',
target: "current",
limit : 80,
auto_search : true,
flags: {
sidebar: false,
deletable: false,
views_switcher: false,
action_buttons:false,
search_view:false,
pager:false,
radio: true
},
};
this.view_edit_dialog = new openerp.web.Dialog(this, {
modal: true,
title: 'ViewEditor',
width: 750,
height: 500,
buttons: {
"Create": function(){
//to do
},
"Edit": function(){
self.xml_id=0;
self.get_data();
},
"Close": function(){
self.view_edit_dialog.close();
}
},
});
this.view_edit_dialog.start().open();
var action_manager = new openerp.web.ActionManager(this);
action_manager.appendTo(this.view_edit_dialog);
action_manager.do_action(action);
},
check_attr: function(xml, tag, level) {
var obj = {'child_id': [], 'id': this.xml_id++, 'level': level+1, 'att_list': [], 'name': ""};
var render_name = "<" + tag;
obj.att_list.push(tag);
$(xml).each(function() {
_.each(this.attributes, function(attrs){
if (tag != 'button') {
if (attrs.nodeName == "string" || attrs.nodeName == "name" || attrs.nodeName == "index") {
render_name += ' ' + attrs.nodeName + '=' + '"' + attrs.nodeValue + '"' ;
}
} else {
if (attrs.nodeName == "name") {
render_name += ' ' + attrs.nodeName + '=' + '"' + attrs.nodeValue + '"';
}
}
obj.att_list.push( [attrs.nodeName,attrs.nodeValue] );
});
render_name+= ">";
});
obj.name = render_name;
return obj;
},
save_object: function(val, parent_list, child_obj_list) {
var self = this;
var check_id = parent_list[0];
var p_list = parent_list.slice(1);
if (val.child_id.length != 0) {
_.each(val.child_id, function(val, key) {
if (val.id == check_id) {
if (p_list.length!=0) {
self.save_object(val, p_list, child_obj_list);
} else {
val.child_id = child_obj_list;
return false;
}
}
});
} else {
val.child_id = child_obj_list;
}
},
xml_node_create: function(xml, root, parent_list, parent_id, main_object){
var self = this;
var child_obj_list = [];
var children_list = $(xml).filter(root).children();
var parents = $(children_list[0]).parents().get();
_.each(children_list, function (child_node) {
child_obj_list.push(self.check_attr(child_node,child_node.tagName.toLowerCase(),parents.length));
});
if (children_list.length != 0) {
if (parents.length <= parent_list.length) {
parent_list.splice(parents.length - 1);
}
parent_list.push(parent_id);
self.save_object(main_object[0], parent_list.slice(1), child_obj_list);
}
for (var i = 0; i < children_list.length; i++) {
self.xml_node_create
(children_list[i], children_list[i].tagName.toLowerCase(),
parent_list, child_obj_list[i].id, main_object);
}
return main_object;
},
parse_xml: function(arch, view_id) {
var root = $(arch).filter(":first")[0];
var tag = root.tagName.toLowerCase();
var obj ={'child_id':[],'id':this.xml_id++,'level':0,'att_list':[],'name':"<view view_id='"+view_id+"'>"};
var root_object = this.check_attr(root,tag,0);
obj.child_id = this.xml_node_create(arch, tag, [], this.xml_id-1, [root_object], [])
return [obj];
},
get_data: function() {
var self = this;
var view_arch_list = [];
self.main_view_id =((this.view_edit_dialog.$element.find("input[name='radiogroup']:checked").parent()).parent()).attr('data-id');
var ve_dataset = new openerp.web.DataSet(this, 'ir.ui.view');
ve_dataset.read_ids([parseInt(self.main_view_id)], ['arch', 'type'], function (arch) {
one_object = self.parse_xml(arch[0].arch,self.main_view_id);
self.main_view_type = arch[0].type
view_arch_list.push({"view_id" : self.main_view_id, "arch" : arch[0].arch});
dataset = new openerp.web.DataSetSearch(self, 'ir.ui.view', null, null);
dataset.read_slice([], {domain : [['inherit_id','=', parseInt(self.main_view_id)]]}, function (result) {
_.each(result, function(res) {
view_arch_list.push({"view_id":res.id,"arch":res.arch});
self.inherit_view(one_object, res);
});
return self.edit_view({"main_object": one_object,
"parent_child_id": self.parent_child_list(one_object, []),
"arch": view_arch_list});
});
});
},
parent_child_list : function(one_object, p_list) {
var self = this;
_.each(one_object , function(element){
if(element.child_id.length != 0){
p_list.push({"key":element.id,"value":_.pluck(element.child_id, 'id')});
self.parent_child_list(element.child_id, p_list);
}
});
return p_list;
},
inherit_view : function(one_object, result) {
var self = this;
var root = $(result.arch).filter('*');
var xml_list = [];
if (root[0].tagName.toLowerCase() == "data") {
xml_list = $(root[0]).children();
} else {
xml_list.push(root[0]);
}
_.each(xml_list , function(xml){
var parent_id;
var check_list = [];
var xpath_object = self.parse_xml(xml,result.id);
if (xml.tagName.toLowerCase() == "xpath" ) {
var part_expr = _.without($(xml).attr('expr').split("/"),"");
_.each(part_expr,function(part){
check_list.push(_.without($.trim(part.replace(/[^a-zA-Z 0-9 _]+/g,'!')).split("!"),""));
});
} else {
var temp = [];
_.each(xpath_object[0].child_id[0].att_list, function(list){
if(!_.include(list, "position")){
temp.push(list);
}
});
check_list = [_.flatten(temp)];
}
self.full_path_search(check_list ,one_object ,xpath_object);
});
},
full_path_search: function(check_list ,val ,xpath_object) {
var self = this;
if(xpath_object.length!=0){
var check = check_list[0];
var obj;
switch (check.length) {
case 2:
if(parseInt(check[1])){
var list_1 = _.select(val,function(element){
var main_list = _.flatten(element.att_list);
return _.include(main_list, check[0]);
});
obj = val[_.indexOf(val,list_1[parseInt(check[1])-1])];
} else {
obj = _.detect(val, function(element){
var main_list = _.flatten(element.att_list);
return _.include(main_list, check[0]);
});
}
break;
case 3:
obj = _.detect(val,function(element){
var main_list = _.flatten(element.att_list);
check = _.uniq(check);
var insert = _.intersection(main_list,check);
if(insert.length == check.length ){return element;}
});
break;
case 1:
var list_1 = _.select(val,function(element){
var main_list = _.flatten(element.att_list);
return _.include(main_list, check[0]);
});
if(list_1.length != 0){
(check_list.length == 1)? obj = list_1[0] : check_list.shift();
}
break;
}
if(obj) {
check_list.shift();
if (check_list.length !=0){
self.full_path_search(check_list ,obj.child_id ,xpath_object);
} else {
var level = obj.level+1;
self.increase_level(xpath_object[0], level)
obj.child_id.push(xpath_object[0]);
xpath_object.pop();
return;
}
}
else {
_.each(val,function(element){
self.full_path_search(check_list ,element.child_id ,xpath_object);
});
}
}
},
increase_level: function(val, level) {
var self = this;
val.level = level;
_.each(val.child_id, function(val, key) {
self.increase_level(val, level + 1);
});
},
edit_view: function(one_object) {
var self = this;
this.edit_xml_dialog = new openerp.web.Dialog(this,{
modal: true,
title: 'View Editor',
width: 750,
height: 500,
buttons: {
"Inherited View": function(){
//todo
},
"Preview": function(){
var action = {
context:self.session.user_context,
res_model : self.model,
views : [[self.main_view_id, self.main_view_type]],
type: 'ir.actions.act_window',
target: "new",
flags: {
sidebar: false,
views_switcher: false,
action_buttons:false,
search_view:false,
pager:false,
},
};
var action_manager = new openerp.web.ActionManager(self);
action_manager.do_action(action);
},
"Close": function(){
self.edit_xml_dialog.close();
}
}
});
this.edit_xml_dialog.start().open();
this.edit_xml_dialog.$element.html(QWeb.render('view_editor', {
'data': one_object['main_object'],
}));
this.edit_xml_dialog.$element.find("tr[id^='viewedit-']").click(function() {
self.edit_xml_dialog.$element.find("tr[id^='viewedit-']").removeClass('ui-selected');
$(this).addClass('ui-selected');
});
this.edit_xml_dialog.$element.find("img[id^='parentimg-']").click(function() {
if ($(this).attr('src') == '/web/static/src/img/collapse.gif') {
$(this).attr('src', '/web/static/src/img/expand.gif');
self.on_expand(this);
} else {
$(this).attr('src', '/web/static/src/img/collapse.gif');
var id = this.id.split('-')[1];
self.on_collapse(this,one_object['parent_child_id'], one_object['main_object']);
}
});
this.edit_xml_dialog.$element.find("img[id^='side-']").click(function() {
var side = $(this).closest("tr[id^='viewedit-']")
var id_tr = (side.attr('id')).split('-')[1];
var img = side.find("img[id='parentimg-"+id_tr+"']").attr('src'); ;
var level = parseInt(side.attr('level'));
var list_shift =[];
var last_tr;
var cur_tr = side;
list_shift.push(side);
var next_tr;
var ls = side;
var view_id;
var view_xml_id;
while(1){
ls = ls.prev();
if((self.edit_xml_dialog.$element.find(ls).find('a').text()).search("view_id") != -1
&& parseInt(ls.attr('level')) < level){
view_id = parseInt(($(ls).find('a').text()).replace(/[^0-9]+/g,''));
view_xml_id = (ls.attr('id')).split('-')[1];
break;
}
}
switch (this.id) {
case "side-add":
break;
case "side-remove":
break;
case "side-edit":
break;
case "side-up":
while (1) {
var prev_tr = cur_tr.prev();
if(level >= parseInt(prev_tr.attr('level')) || prev_tr.length == 0) {
last_tr = prev_tr;
break;
}
cur_tr = prev_tr;
}
if (img) {
while (1) {
next_tr = side.next();
if ( parseInt(next_tr.attr('level')) <= level || next_tr.length == 0) {
break;
} else {
list_shift.push(next_tr);
side = next_tr;
}
}
}
if (last_tr.length != 0 && parseInt(last_tr.attr('level')) == level &&
(self.edit_xml_dialog.$element.find(last_tr).find('a').text()).search("view_id") == -1) {
_.each(list_shift, function(rec) {
$(last_tr).before(rec);
});
self.save_move_arch(one_object, view_id, view_xml_id, id_tr, level, "up");
}
break;
case "side-down":
if (img) {
while (1) {
next_tr = cur_tr.next();
if ( parseInt(next_tr.attr('level')) <= level || next_tr.length == 0) {
last_tr = next_tr;
break;
} else {
list_shift.push(next_tr);
cur_tr = next_tr;
}
}
}
else {
last_tr = cur_tr.next();
}
if((self.edit_xml_dialog.$element.find(last_tr).find('a').text()).search("view_id") != -1){
return;
}
if (last_tr.length != 0 && parseInt(last_tr.attr('level')) == level) {
var last_tr_id = (last_tr.attr('id')).split('-')[1];
img = last_tr.find("img[id='parentimg-" + last_tr_id + "']").attr('src');
if (img) {
self.edit_xml_dialog.$element.find("img[id='parentimg-" + last_tr_id + "']").
attr('src', '/web/static/src/img/expand.gif');
while (1) {
var next_tr = last_tr.next();
if (next_tr.attr('level') <= level || next_tr.length == 0) break;
next_tr.hide();
last_tr = next_tr;
}
}
list_shift.reverse();
_.each(list_shift, function(rec) {
$(last_tr).after(rec);
});
self.save_move_arch(one_object, view_id, view_xml_id, id_tr, level, "down");
}
break;
}
});
},
save_move_arch: function(one_object, view_id, view_xml_id, id_tr, level, move_direct){
var self = this;
var arch = _.detect(one_object['arch'],function(element){
return element.view_id == view_id;
});
var obj = self.get_view_object(view_xml_id, one_object['main_object'], []);
if(($(arch.arch).filter("data")).length != 0 && view_xml_id != 0){
var check_list = _.flatten(obj[0].child_id[0].att_list);
arch.arch = _.detect($(arch.arch).children(), function(xml_child){
var temp_obj = self.check_attr(xml_child, xml_child.tagName.toLowerCase());
var main_list = _.flatten(temp_obj.att_list);
check_list = _.uniq(check_list);
var insert = _.intersection(main_list,check_list);
if(insert.length == check_list.length ){return xml_child;}
});
}
return self.get_node(arch.arch, obj[0].child_id[0], parseInt(id_tr), [], parseInt(level),
parseInt(view_id), arch, move_direct);
},
get_view_object: function(view_xml_id, one_object,result){
var self = this;
if(result.length==0){
var check = _.detect(one_object , function(obj){
return view_xml_id==obj.id;
});
if(check){result.push(check);};
_.each(one_object, function(obj){
self.get_view_object(view_xml_id, obj.child_id, result);
});
}
return result;
},
get_node: function(arch1, obj, id, child_list, level, view_id, arch, move_direct){
var self = this;
var children_list = $(arch1).children();
var list_obj_xml = _.zip(children_list,obj.child_id);
if (id) {
if (obj.id == id) {
var id;
var parent = $(arch1).parents();
var index = _.indexOf(child_list, obj)
var re_insert_obj = child_list.splice(index, 1);
if (move_direct == "down") {
var next = $(arch1).next();
$(next).after(arch1);
child_list.splice(index+1, 0, re_insert_obj[0]);
} else {
var prev = $(arch1).prev();
$(prev).before(arch1);
child_list.splice(index-1, 0, re_insert_obj[0]);
}
parent = parent[parent.length-1];
var convert_to_utf = self.xml2Str(parent);
if (convert_to_utf) {
convert_to_utf = convert_to_utf.replace('xmlns="http://www.w3.org/1999/xhtml"', "");
convert_to_utf = '<?xml version="1.0"?>' + convert_to_utf;
arch.arch = convert_to_utf;
dataset = new openerp.web.DataSet(this, 'ir.ui.view');
dataset.write(parseInt(view_id),{"arch":convert_to_utf}, function(r) {
});
}
}
if (obj.level <= level) {
_.each(list_obj_xml, function(child_node) {
self.get_node(child_node[0], child_node[1], id, obj.child_id, level, view_id, arch, move_direct);
});
}
}
},
xml2Str: function(xmlNode) {
try {
return (new XMLSerializer()).serializeToString(xmlNode);
}
catch (e) {
try {
return xmlNode.xml;
}
catch (e) {
return false;
}
}
},
on_expand: function(expand_img){
var level = parseInt($(expand_img).closest("tr[id^='viewedit-']").attr('level'));
var cur_tr = $(expand_img).closest("tr[id^='viewedit-']");
while (1) {
var nxt_tr = cur_tr.next();
if (parseInt(nxt_tr.attr('level')) > level){
cur_tr = nxt_tr;
nxt_tr.hide();
} else return nxt_tr;
}
},
on_collapse: function(collapse_img, parent_child_id, id, main_object) {
var self = this;
var id = collapse_img.id.split('-')[1];
var datas = _.detect(parent_child_id,function(res) {
return res.key == id;
});
_.each(datas.value, function(rec) {
var tr = self.edit_xml_dialog.$element.find("tr[id='viewedit-"+rec+"']");
tr.find("img[id='parentimg-"+rec+"']").attr('src','/web/static/src/img/expand.gif');
tr.show();
});
}
});
};
File diff suppressed because it is too large Load Diff
+156 -65
View File
@@ -1,4 +1,5 @@
openerp.web.list = function (openerp) {
var _t = openerp.web._t;
var QWeb = openerp.web.qweb;
openerp.web.views.add('list', '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
'header': true,
// display addition button, with that label
'addable': "New",
'addable': _t("Create"),
// whether the list view can be sorted, note that once a view has been
// sorted it can not be reordered anymore
'sortable': true,
@@ -200,8 +201,15 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
this.setup_columns(this.fields_view.fields, grouped);
this.$element.html(QWeb.render("ListView", this));
// Head hook
this.$element.find('.all-record-selector').click(function(){
self.$element.find('.oe-record-selector input').prop('checked',
self.$element.find('.all-record-selector').prop('checked') || false);
var selection = self.groups.get_selection();
$(self.groups).trigger(
'selected', [selection.ids, selection.records]);
});
this.$element.find('.oe-list-add')
.click(this.do_add_record)
.attr('disabled', grouped && this.options.editable);
@@ -252,7 +260,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
'<option value="100">100</option>' +
'<option value="200">200</option>' +
'<option value="500">500</option>' +
'<option value="NaN">Unlimited</option>')
'<option value="NaN">' + _t("Unlimited") + '</option>')
.change(function () {
var val = parseInt($select.val(), 10);
self._limit = (isNaN(val) ? null : val);
@@ -287,7 +295,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
} else {
last = first + limit;
}
this.$element.find('span.oe-pager-state').empty().text(_.sprintf(
this.$element.find('span.oe-pager-state').empty().text(_.str.sprintf(
"[%d to %d] of %d", first + 1, last, total));
this.$element
@@ -357,6 +365,9 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
return {};
}
var aggregation_func = column['group_operator'] || 'sum';
if (!(aggregation_func in column)) {
return {};
}
return _.extend({}, column, {
'function': aggregation_func,
@@ -391,9 +402,6 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
if (this.sidebar) {
this.sidebar.$element.show();
}
if (!_(this.dataset.ids).isEmpty()) {
this.reload_content();
}
},
do_hide: function () {
this.$element.hide();
@@ -426,10 +434,13 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
},
/**
* re-renders the content of the list view
*
* @returns {$.Deferred} promise to content reloading
*/
reload_content: function () {
var self = this;
this.records.reset();
var reloaded = $.Deferred();
this.$element.find('.oe-listview-content').append(
this.groups.render(function () {
if (self.dataset.index == null) {
@@ -440,23 +451,9 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
}
}
self.compute_aggregates();
reloaded.resolve();
}));
},
/**
* 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'));
return reloaded.promise();
},
/**
* Handler for the result of eval_domain_and_context, actually perform the
@@ -464,19 +461,16 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
*
* @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, this.model,
results.domain,
results.context,
results.group_by);
this, this.model, domain, context, group_by);
this.groups.datagroup.sort = this.dataset._sort;
if (_.isEmpty(results.group_by) && !results.context['group_by_no_leaf']) {
results.group_by = null;
if (_.isEmpty(group_by) && !context['group_by_no_leaf']) {
group_by = null;
}
this.reload_view(!!results.group_by, results.context).then(
this.reload_view(!!group_by, context).then(
$.proxy(this, 'reload_content'));
},
/**
@@ -485,7 +479,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
* @param {Array} ids the ids of the records to delete
*/
do_delete: function (ids) {
if (!ids.length) {
if (!(ids.length && confirm(_t("Do you really want to remove these records?")))) {
return;
}
var self = this;
@@ -493,6 +487,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
_(ids).each(function (id) {
self.records.remove(self.records.get(id));
});
self.configure_pager(self.dataset);
self.compute_aggregates();
});
},
@@ -532,6 +527,17 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
return field.name === name;
});
if (!action) { return; }
var c = new openerp.web.CompoundContext();
c.set_eval_context(_.extend({
active_id: id,
active_ids: [id],
active_model: this.dataset.model
}, this.records.get(id).toContext()));
if (action.context) {
c.add(action.context);
}
action.context = c;
this.do_execute_action(action, this.dataset, id, callback);
},
/**
@@ -542,14 +548,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)
*/
do_activate_record: function (index, id, dataset) {
var self = this;
// TODO is it needed ?
this.dataset.read_slice([],{
context: dataset.get_context(),
domain: dataset.get_domain()
}, function () {
self.select_record(index);
});
this.dataset.ids = dataset.ids;
this.select_record(index);
},
/**
* Handles signal for the addition of a new record (can be a creation,
@@ -647,8 +647,8 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
return;
}
$footer_cells.filter(_.sprintf('[data-field=%s]', column.id))
.html(openerp.web.format_cell(aggregation, column));
$footer_cells.filter(_.str.sprintf('[data-field=%s]', column.id))
.html(openerp.web.format_cell(aggregation, column, undefined, false));
});
},
get_selected_ids: function() {
@@ -794,24 +794,71 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
$row = $target.closest('tr'),
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));
}]);
})
.delegate('tr', 'click', function (e) {
e.stopPropagation();
self.dataset.index = self.records.indexOf(
self.records.get(
self.row_id(e.currentTarget)));
self.row_clicked(e);
var row_id = self.row_id(e.currentTarget);
if (row_id !== undefined) {
if (!self.dataset.select_id(row_id)) {
throw "Could not find id in dataset"
}
self.row_clicked(e);
}
});
},
row_clicked: function () {
$(this).trigger(
'row_link',
[this.records.at(this.dataset.index).get('id'),
[this.dataset.ids[this.dataset.index],
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 () {
if (this.$current) {
this.$current.remove();
@@ -819,7 +866,7 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
this.$current = this.$_element.clone(true);
this.$current.empty().append(
QWeb.render('ListView.rows', _.extend({
render_cell: openerp.web.format_cell}, this)));
render_cell: $.proxy(this, 'render_cell')}, this)));
this.pad_table_to(5);
},
pad_table_to: function (count) {
@@ -829,21 +876,28 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
}
var cells = [];
if (this.options.selectable) {
cells.push('<td title="selection"></td>');
cells.push('<th class="oe-record-selector"></td>');
}
_(this.columns).each(function(column) {
if (column.invisible !== '1') {
if (column.invisible === '1') {
return;
}
if (column.tag === 'button') {
cells.push('<td class="oe-button" title="' + column.string + '">&nbsp;</td>');
} else {
cells.push('<td title="' + column.string + '">&nbsp;</td>');
}
});
if (this.options.deletable) {
cells.push('<td><button type="button" style="visibility: hidden"> </button></td>');
cells.push('<td class="oe-record-delete"><button type="button" style="visibility: hidden"> </button></td>');
}
cells.unshift('<tr>');
cells.push('</tr>');
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);
},
/**
@@ -924,7 +978,8 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
options: this.options,
record: record,
row_parity: (index % 2 === 0) ? 'even' : 'odd',
render_cell: openerp.web.format_cell
view: this.view,
render_cell: $.proxy(this, 'render_cell')
});
},
/**
@@ -1072,7 +1127,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
child.datagroup = group;
var $row = child.$row = $('<tr>');
if (group.openable) {
if (group.openable && group.length) {
$row.click(function (e) {
if (!$row.data('open')) {
$row.data('open', true)
@@ -1098,10 +1153,19 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
row_data[group.grouped_on] = group;
var group_column = _(self.columns).detect(function (column) {
return column.id === group.grouped_on; });
$group_column.html(openerp.web.format_cell(
row_data, group_column, "Undefined"
));
if (group.openable) {
try {
$group_column.html(openerp.web.format_cell(
row_data, group_column, _t("Undefined")));
} catch (e) {
$group_column.html(row_data[group_column.id].value);
}
if (!group.length) {
// Kinda-ugly hack: jquery-ui has no "empty" icon, so set
// wonky background position to ensure nothing is displayed
// there but the rest of the behavior is ui-icon's
$group_column.prepend(
'<span class="ui-icon" style="float: left; background-position: 150px 150px">');
} else if (group.openable) {
// Make openable if not terminal group & group_by_no_leaf
$group_column
.prepend('<span class="ui-icon ui-icon-triangle-1-e" style="float: left;">');
@@ -1128,7 +1192,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
format = "%.2f";
}
$('<td>')
.text(_.sprintf(format, value))
.text(_.str.sprintf(format, value))
.appendTo($row);
} else {
$row.append('<td>');
@@ -1175,14 +1239,19 @@ 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 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) {
// FIXME: ignominious hacks, parents (aka form view) should not send two ListView#reload_content concurrently
if (self.records.length) {
self.records.reset(null, {silent: true});
}
if (!self.datagroup.openable) {
view.configure_pager(dataset);
} else {
var pages = Math.ceil(dataset.ids.length / limit);
self.$row
.find('.oe-pager-state')
.text(_.sprintf('%d/%d', page + 1, pages))
.text(_.str.sprintf('%d/%d', page + 1, pages))
.end()
.find('button[data-pager-action=previous]')
.attr('disabled', page === 0)
@@ -1194,7 +1263,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
self.records.add(records, {silent: true});
list.render();
d.resolve(list);
});
});}, 0);
return d.promise();
},
setup_resequence_rows: function (list, dataset) {
@@ -1405,6 +1474,25 @@ var Record = openerp.web.Class.extend(/** @lends Record# */{
}
return {data: form_data};
},
/**
* Converts the current record to a format expected by context evaluations
* (identical to record.attributes, except m2o fields are their integer
* value rather than a pair)
*/
toContext: function () {
var output = {}, attrs = this.attributes;
for(var k in attrs) {
var val = attrs[k];
if (typeof val !== 'object') {
output[k] = val;
} else if (val instanceof Array) {
output[k] = val[0];
} else {
throw new Error("Can't convert value " + val + " to context");
}
}
return output;
}
});
Record.include(Events);
@@ -1516,7 +1604,8 @@ var Collection = openerp.web.Class.extend(/** @lends Collection# */{
* @param {Array} [records]
* @returns this
*/
reset: function (records) {
reset: function (records, options) {
options = options || {};
_(this._proxies).each(function (proxy) {
proxy.reset();
});
@@ -1527,7 +1616,9 @@ var Collection = openerp.web.Class.extend(/** @lends Collection# */{
if (records) {
this.add(records);
}
this.trigger('reset', this);
if (!options.silent) {
this.trigger('reset', this);
}
return this;
},
/**
+90 -33
View File
@@ -22,6 +22,7 @@ openerp.web.list_editable = function (openerp) {
if (self.groups.get_selection().length) {
return;
}
self.configure_pager(self.dataset);
self.compute_aggregates();
}
})
@@ -56,11 +57,11 @@ openerp.web.list_editable = function (openerp) {
|| this.defaults.editable);
},
/**
* Replace do_actual_search to handle editability process
* Replace do_search to handle editability process
*/
do_actual_search: function (results) {
this.set_editable(results.context['set_editable']);
this._super(results);
do_search: function(domain, context, group_by) {
this.set_editable(context['set_editable']);
this._super.apply(this, arguments);
},
/**
* Replace do_add_record to handle editability (and adding new record
@@ -77,6 +78,17 @@ openerp.web.list_editable = function (openerp) {
// tree/@editable takes priority on everything else if present.
this.options.editable = data.arch.attrs.editable || this.options.editable;
return this._super(data, grouped);
},
/**
* Ensures the editable list is saved (saves any pending edition if
* needed, or tries to)
*
* Returns a deferred to the end of the saving.
*
* @returns {$.Deferred}
*/
ensure_saved: function () {
return this.groups.ensure_saved();
}
});
@@ -85,6 +97,18 @@ openerp.web.list_editable = function (openerp) {
new_record: function () {
// TODO: handle multiple children
this.children[null].new_record();
},
/**
* Ensures descendant editable List instances are all saved if they have
* pending editions.
*
* @returns {$.Deferred}
*/
ensure_saved: function () {
return $.when.apply(null,
_.invoke(
_.values(this.children),
'ensure_saved'));
}
});
@@ -120,6 +144,7 @@ openerp.web.list_editable = function (openerp) {
delete self.edition_id;
delete self.edition;
});
this.pad_table_to(5);
return cancelled.promise();
},
/**
@@ -147,7 +172,7 @@ openerp.web.list_editable = function (openerp) {
var $new_row = $('<tr>', {
id: _.uniqueId('oe-editable-row-'),
'data-id': record_id,
'class': $(row).attr('class') + ' oe_forms',
'class': row ? $(row).attr('class') : '' + ' oe_forms',
click: function (e) {e.stopPropagation();}
})
.delegate('button.oe-edit-row-save', 'click', function () {
@@ -173,14 +198,26 @@ openerp.web.list_editable = function (openerp) {
});
if (row) {
$new_row.replaceAll(row);
} else if (self.options.editable === 'top') {
self.$current.prepend($new_row);
} 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_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',
registry: openerp.web.list.form.widgets,
$element: $new_row
@@ -240,9 +277,11 @@ openerp.web.list_editable = function (openerp) {
* sibling if asked.
*
* @param {Boolean} [edit_next=false] should the next row become editable
* @returns {$.Deferred}
*/
save_row: function (edit_next) {
var self = this;
//noinspection JSPotentiallyInvalidConstructorUsage
var self = this, done = $.Deferred();
this.edition_form.do_save(function (result) {
if (result.created && !self.edition_id) {
self.records.add({id: result.result},
@@ -253,28 +292,44 @@ openerp.web.list_editable = function (openerp) {
next_record = self.records.at(
self.records.indexOf(edited_record) + 1);
self.handle_onwrite(self.edition_id);
self.cancel_pending_edition().then(function () {
$(self).trigger('saved', [self.dataset]);
if (!edit_next) {
return;
}
if (result.created) {
self.new_record();
return;
}
var next_record_id;
if (next_record) {
next_record_id = next_record.get('id');
self.dataset.index = _(self.dataset.ids)
.indexOf(next_record_id);
} else {
self.dataset.index = 0;
next_record_id = self.records.at(0).get('id');
}
self.edit_record(next_record_id);
});
}, this.options.editable === 'top');
$.when(
self.handle_onwrite(self.edition_id),
self.cancel_pending_edition().then(function () {
$(self).trigger('saved', [self.dataset]);
if (!edit_next) {
return;
}
if (result.created) {
self.new_record();
return;
}
var next_record_id;
if (next_record) {
next_record_id = next_record.get('id');
self.dataset.index = _(self.dataset.ids)
.indexOf(next_record_id);
} else {
self.dataset.index = 0;
next_record_id = self.records.at(0).get('id');
}
self.edit_record(next_record_id);
})).then(function () {
done.resolve();
});
}, this.options.editable === 'top').fail(function () {
done.reject();
});
return done.promise();
},
/**
* If the current list is being edited, ensures it's saved
*/
ensure_saved: function () {
if (this.edition) {
return this.save_row();
}
//noinspection JSPotentiallyInvalidConstructorUsage
return $.Deferred().resolve().promise();
},
/**
* Cancels the edition of the row for the current dataset index
@@ -325,11 +380,13 @@ openerp.web.list_editable = function (openerp) {
this.$element.children().css('visibility', '');
if (this.modifiers.tree_invisible) {
var old_invisible = this.invisible;
this.invisible = !!this.modifiers.tree_invisible;
this.invisible = true;
this._super();
this.invisible = old_invisible;
} else if (this.invisible) {
this.$element.children().css('visibility', 'hidden');
} else {
this._super();
}
}
});
+41 -1
View File
@@ -32,6 +32,8 @@ openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView#
this.records = {};
this.options = _.extend({}, this.defaults, options || {});
_.bindAll(this, 'color_for');
},
start: function () {
@@ -107,6 +109,43 @@ openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView#
$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
@@ -159,7 +198,8 @@ openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView#
'fields_view': self.fields_view.arch.children,
'fields': self.fields,
'level': $curr_node.data('level') || 0,
'render': openerp.web.format_value
'render': openerp.web.format_value,
'color_for': self.color_for
});
if ($curr_node.length) {
+319 -222
View File
@@ -2,21 +2,21 @@
* OpenERP web library
*---------------------------------------------------------*/
openerp.web.views = function(db) {
openerp.web.views = function(session) {
var _t = db.web._t;
var _t = session.web._t;
/**
* Registry for all the client actions key: tag value: widget
*/
db.web.client_actions = new db.web.Registry();
session.web.client_actions = new session.web.Registry();
/**
* Registry for all the main views
*/
db.web.views = new db.web.Registry();
session.web.views = new session.web.Registry();
db.web.ActionManager = db.web.Widget.extend({
session.web.ActionManager = session.web.Widget.extend({
identifier_prefix: "actionmanager",
init: function(parent) {
this._super(parent);
@@ -68,9 +68,11 @@ db.web.ActionManager = db.web.Widget.extend({
},
on_url_hashchange: function(url) {
var self = this;
self.rpc("/web/action/load", { action_id: url.action_id }, function(result) {
self.do_action(result.result);
});
if(url && url.action_id) {
self.rpc("/web/action/load", { action_id: url.action_id }, function(result) {
self.do_action(result.result);
});
}
},
do_action: function(action, on_close) {
var type = action.type.replace(/\./g,'_');
@@ -91,20 +93,20 @@ db.web.ActionManager = db.web.Widget.extend({
ir_actions_act_window: function (action, on_close) {
if (action.target === 'new') {
if (this.dialog == null) {
this.dialog = new db.web.Dialog(this, { title: action.name, width: '80%' });
this.dialog = new session.web.Dialog(this, { title: action.name, width: '80%' });
if(on_close)
this.dialog.on_close.add(on_close);
this.dialog.start();
} else {
this.dialog_viewmanager.stop();
}
this.dialog_viewmanager = new db.web.ViewManagerAction(this, action);
this.dialog_viewmanager = new session.web.ViewManagerAction(this, action);
this.dialog_viewmanager.appendTo(this.dialog.$element);
this.dialog.open();
} else {
this.dialog_stop();
this.content_stop();
this.inner_viewmanager = new db.web.ViewManagerAction(this, action);
this.inner_viewmanager = new session.web.ViewManagerAction(this, action);
this.inner_viewmanager.appendTo(this.$element);
this.url_update(action);
}
@@ -116,6 +118,15 @@ db.web.ActionManager = db.web.Widget.extend({
*/
},
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') {
session.webclient.do_reload();
}
}
this.dialog_stop();
},
ir_actions_server: function (action, on_closed) {
@@ -129,7 +140,7 @@ db.web.ActionManager = db.web.Widget.extend({
},
ir_actions_client: function (action) {
this.content_stop();
var ClientWidget = db.web.client_actions.get_object(action.tag);
var ClientWidget = session.web.client_actions.get_object(action.tag);
(this.client_widget = new ClientWidget(this, action.params)).appendTo(this);
},
ir_actions_report_xml: function(action) {
@@ -147,15 +158,18 @@ db.web.ActionManager = db.web.Widget.extend({
complete: $.unblockUI
});
});
},
ir_actions_act_url: function (action) {
window.open(action.url, action.target === 'self' ? '_self' : '_blank');
}
});
db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
session.web.ViewManager = session.web.Widget.extend(/** @lends session.web.ViewManager# */{
identifier_prefix: "viewmanager",
template: "ViewManager",
/**
* @constructs db.web.ViewManager
* @extends db.web.Widget
* @constructs session.web.ViewManager
* @extends session.web.Widget
*
* @param parent
* @param dataset
@@ -166,14 +180,15 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
this.model = dataset ? dataset.model : undefined;
this.dataset = dataset;
this.searchview = null;
this.last_search = false;
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 = {};
this.flags = this.flags || {};
this.registry = db.web.views;
this.registry = session.web.views;
},
render: function() {
return db.web.qweb.render(this.template, {
return session.web.qweb.render(this.template, {
self: this,
prefix: this.element_id,
views: this.views_src});
@@ -224,35 +239,21 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
controller.set_embedded_view(view.embedded_view);
}
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);
view_promise = controller.appendTo(container);
this.views[view_type].controller = controller;
$.when(view_promise).then(function() {
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 (view.controller.searchable === false) {
this.searchview.hide();
} else {
this.searchview.show();
}
this.searchview[(view.controller.searchable === false || this.searchview.hidden) ? 'hide' : 'show']();
}
this.$element
@@ -270,16 +271,12 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
}
}
}
$.when(view_promise).then(function () {
self.$element.find('.oe_view_title:first').text(
self.display_title());
});
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.
*
@@ -291,16 +288,39 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
if (this.searchview) {
this.searchview.stop();
}
this.searchview = new db.web.SearchView(
this.searchview = new session.web.SearchView(
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) {
var controller = self.views[self.active_view].controller;
controller.do_search.call(controller, domains, contexts, groupbys);
});
this.searchview.on_search.add(this.do_searchview_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
*/
@@ -315,16 +335,24 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
/**
* Called by children view after executing an action
*/
on_action_executed: function () {}
on_action_executed: function () {},
display_title: function () {
var view = this.views[this.active_view];
if (view) {
// ick
return view.controller.fields_view.arch.attrs.string;
}
return '';
}
});
db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.ViewManagerAction# */{
session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepnerp.web.ViewManagerAction# */{
template:"ViewManagerAction",
/**
* @constructs db.web.ViewManagerAction
* @extends db.web.ViewManager
* @constructs session.web.ViewManagerAction
* @extends session.web.ViewManager
*
* @param {db.web.ActionManager} parent parent object/widget
* @param {session.web.ActionManager} parent parent object/widget
* @param {Object} action descriptor for the action this viewmanager needs to manage its views.
*/
init: function(parent, action) {
@@ -334,7 +362,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
this._super(parent, null, action.views);
this.session = parent.session;
this.action = action;
var dataset = new db.web.DataSetSearch(this, action.res_model, action.context, action.domain);
var dataset = new session.web.DataSetSearch(this, action.res_model, action.context, action.domain);
if (action.res_id) {
dataset.ids.push(action.res_id);
dataset.index = 0;
@@ -360,40 +388,36 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
* launches an initial search after both views are done rendering.
*/
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;
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);
}
searchview_loaded = this.setup_search_view(searchview_id || false, search_defaults);
var main_view_loaded = this._super();
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
manager_ready.then(this.searchview.do_search);
}
this.$element.find('.oe_get_xml_view').click(function () {
// TODO: add search view?
$('<pre>').text(db.web.json_node_to_xml(
$('<pre>').text(session.web.json_node_to_xml(
self.views[self.active_view].controller.fields_view.arch, true))
.dialog({ width: '95%'});
});
if (this.action.help && !this.flags.low_profile) {
var Users = new db.web.DataSet(self, 'res.users'),
var Users = new session.web.DataSet(self, 'res.users'),
header = this.$element.find('.oe-view-manager-header');
header.delegate('blockquote button', 'click', function() {
var $this = $(this);
@@ -417,15 +441,41 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
}
}
var $res_logs = this.$element.find('.oe-view-manager-logs:first');
$res_logs.delegate('a.oe-more-logs', 'click', function () {
$res_logs.removeClass('oe-folded');
return false;
}).delegate('a.oe-remove-everything', 'click', function () {
$res_logs.removeClass('oe-has-more')
.find('ul').empty();
return false;
});
return manager_ready;
},
on_mode_switch: function (view_type) {
var self = this;
return $.when(
this._super(view_type),
this.shortcut_check(this.views[view_type])).then(function () {
var view_id = self.views[self.active_view].controller.fields_view.view_id;
this._super(view_type),
this.shortcut_check(this.views[view_type])
).then(function() {
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);
if (!self.action.name && fvg) {
self.$element.find('.oe_view_title').text(fvg.arch.attrs.string || fvg.name);
}
var $title = self.$element.find('.oe_view_title'),
$search_prefix = $title.find('span.oe_searchable_view');
if (controller.searchable !== false) {
if (!$search_prefix.length) {
$title.prepend('<span class="oe_searchable_view">' + _t("Search: ") + '</span>');
}
} else {
$search_prefix.remove();
}
});
},
shortcut_check : function(view) {
@@ -433,7 +483,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
var grandparent = this.widget_parent && this.widget_parent.widget_parent;
// display shortcuts if on the first view for the action
var $shortcut_toggle = this.$element.find('.oe-shortcut-toggle');
if (!(grandparent instanceof db.web.WebClient) ||
if (!(grandparent instanceof session.web.WebClient) ||
!(view.view_type === this.views_src[0].view_type
&& view.view_id === this.views_src[0].view_id)) {
$shortcut_toggle.hide();
@@ -470,7 +520,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
* Intercept do_action resolution from children views
*/
on_action_executed: function () {
return new db.web.DataSet(this, 'res.log')
return new session.web.DataSet(this, 'res.log')
.call('get', [], this.do_display_log);
},
/**
@@ -478,10 +528,14 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
*/
do_display_log: function (log_records) {
var self = this,
$logs = this.$element.find('ul.oe-view-manager-logs:first').empty();
_(log_records).each(function (record) {
$(_.sprintf('<li><a href="#">%s</a></li>', record.name))
.appendTo($logs)
cutoff = 3,
$logs = this.$element.find('.oe-view-manager-logs:first')
.addClass('oe-folded'),
$logs_list = $logs.find('ul').empty();
$logs.toggleClass('oe-has-more', log_records.length > cutoff);
_(log_records.reverse()).each(function (record) {
$(_.str.sprintf('<li><a href="#">%s</a></li>', record.name))
.appendTo($logs_list)
.delegate('a', 'click', function (e) {
self.do_action({
type: 'ir.actions.act_window',
@@ -494,10 +548,13 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
return false;
});
});
},
display_title: function () {
return this.action.name;
}
});
db.web.Sidebar = db.web.Widget.extend({
session.web.Sidebar = session.web.Widget.extend({
init: function(parent, element_id) {
this._super(parent, element_id);
this.items = {};
@@ -506,14 +563,55 @@ db.web.Sidebar = db.web.Widget.extend({
start: function() {
this._super(this);
var self = this;
this.$element.html(db.web.qweb.render('Sidebar'));
this.$element.html(session.web.qweb.render('Sidebar'));
this.$element.find(".toggle-sidebar").click(function(e) {
self.do_toggle();
});
},
add_default_sections: function() {
if (this.session.uid === 1) {
this.add_section(_t('Customize'), 'customize');
this.add_items('customize', [
{
label: _t("Manage Views"),
callback: this.widget_parent.on_sidebar_manage_views,
title: _t("Manage views of the current object")
}, {
label: _t("Edit Workflow"),
callback: this.widget_parent.on_sidebar_edit_workflow,
title: _t("Manage views of the current object"),
classname: 'oe_hide oe_sidebar_edit_workflow'
}, {
label: _t("Customize Object"),
callback: this.widget_parent.on_sidebar_customize_object,
title: _t("Manage views of the current object")
}, {
label: _t("Translate"),
callback: this.widget_parent.on_sidebar_translate,
title: _t("Technical translation")
}
]);
}
this.add_section(_t('Other Options'), 'other');
this.add_items('other', [
{
label: _t("Import"),
callback: this.widget_parent.on_sidebar_import
}, {
label: _t("Export"),
callback: this.widget_parent.on_sidebar_export
}, {
label: _t("View Log"),
callback: this.widget_parent.on_sidebar_view_log,
classname: 'oe_hide oe_sidebar_view_log'
}
]);
},
add_toolbar: function(toolbar) {
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]];
if (items.length) {
for (var i = 0; i < items.length; i++) {
@@ -523,15 +621,30 @@ db.web.Sidebar = db.web.Widget.extend({
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.
// If no items are passed, then the section will be created as a custom section
// returning back an element_id to be used by a custom controller.
// Else, the section is a standard section with items displayed as links.
add_section: function(name, code) {
if(!code) code = _.str.underscored(name);
var $section = this.sections[code];
if(!$section) {
var section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
$section = $(session.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 : {
// label: label to be displayed for the link,
// action: action to be launch when the link is clicked,
@@ -540,58 +653,70 @@ db.web.Sidebar = db.web.Widget.extend({
// title: optional title for the link
// }
// Note: The item should have one action or/and a callback
//
var self = this,
section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
$section = this.add_section(_.str.titleize(section_code.replace('_', ' ')), section_code),
section_id = $section.attr('id');
if (items) {
for (var i = 0; i < items.length; i++) {
items[i].element_id = _.uniqueId(section_id + '_item_');
this.items[items[i].element_id] = items[i];
}
}
var $section = $(db.web.qweb.render("Sidebar.section", {
section_id: section_id,
name: name,
classname: 'oe_sidebar_' + code,
items: items
}));
if (items) {
$section.find('a.oe_sidebar_action_a').click(function() {
var $items = $(session.web.qweb.render("Sidebar.section.items", {items: items}));
$items.find('a.oe_sidebar_action_a').click(function() {
var item = self.items[$(this).attr('id')];
if (item.callback) {
item.callback();
item.callback.apply(self, [item]);
}
if (item.action) {
var ids = self.widget_parent.get_selected_ids();
if (ids.length == 0) {
//TODO: make prettier warning?
$("<div />").text(_t("You must choose at least one record.")).dialog({
title: _t("Warning"),
modal: true
if (self.widget_parent instanceof session.web.FormView) {
self.widget_parent.do_save(function() {
self.on_item_action_clicked(item);
});
return false;
} else {
self.on_item_action_clicked(item);
}
var additional_context = {
active_id: ids[0],
active_ids: ids,
active_model: self.widget_parent.dataset.model
};
self.rpc("/web/action/load", {
action_id: item.action.id,
context: additional_context
}, function(result) {
result.result.context = _.extend(result.result.context || {},
additional_context);
result.result.flags = result.result.flags || {};
result.result.flags.new_window = true;
self.do_action(result.result);
});
}
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;
},
on_item_action_clicked: function(item) {
var self = this;
var ids = self.widget_parent.get_selected_ids();
if (ids.length == 0) {
//TODO: make prettier warning?
$("<div />").text(_t("You must choose at least one record.")).dialog({
title: _t("Warning"),
modal: true
});
return false;
}
var additional_context = {
active_id: ids[0],
active_ids: ids,
active_model: self.widget_parent.dataset.model
};
self.rpc("/web/action/load", {
action_id: item.action.id,
context: additional_context
}, function(result) {
result.result.context = _.extend(result.result.context || {},
additional_context);
result.result.flags = result.result.flags || {};
result.result.flags.new_window = true;
self.do_action(result.result);
});
},
do_fold: function() {
this.$element.addClass('closed-sidebar').removeClass('open-sidebar');
@@ -604,7 +729,7 @@ db.web.Sidebar = db.web.Widget.extend({
}
});
db.web.TranslateDialog = db.web.Dialog.extend({
session.web.TranslateDialog = session.web.Dialog.extend({
dialog_title: _t("Translations"),
init: function(view) {
// TODO fme: should add the language to fields_view_get because between the fields view get
@@ -624,19 +749,14 @@ db.web.TranslateDialog = db.web.Dialog.extend({
this.translatable_fields_keys = _.map(this.view.translatable_fields || [], function(i) { return i.name });
this.languages = null;
this.languages_loaded = $.Deferred();
(new db.web.DataSetSearch(this, 'res.lang', this.view.dataset.get_context(),
(new session.web.DataSetSearch(this, 'res.lang', this.view.dataset.get_context(),
[['translatable', '=', '1']])).read_slice(['code', 'name'], { sort: 'id' }, this.on_languages_loaded);
},
start: function() {
var self = this;
this._super();
$.when(this.languages_loaded).then(function() {
self.$element.html(db.web.qweb.render('TranslateDialog', { widget: self }));
self.$element.tabs();
if (!(self.view.translatable_fields && self.view.translatable_fields.length)) {
self.hide_tabs('fields');
self.select_tab('view');
}
self.$element.html(session.web.qweb.render('TranslateDialog', { widget: self }));
self.$fields_form = self.$element.find('.oe_translation_form');
self.$fields_form.find('.oe_trad_field').change(function() {
$(this).toggleClass('touched', ($(this).val() != $(this).attr('data-value')));
@@ -679,21 +799,6 @@ db.web.TranslateDialog = db.web.Dialog.extend({
});
$.when.apply(null, deffered).then(callback);
},
show_tabs: function() {
for (var i = 0; i < arguments.length; i++) {
this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().show();
}
},
hide_tabs: function() {
for (var i = 0; i < arguments.length; i++) {
this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().hide();
}
},
select_tab: function(name) {
this.show_tabs(name);
var index = this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().index() - 1;
this.$element.tabs('select', index);
},
open: function(field) {
var self = this,
sup = this._super;
@@ -702,7 +807,9 @@ db.web.TranslateDialog = db.web.Dialog.extend({
self.do_load_fields_values(function() {
sup.call(self);
if (field) {
// TODO: focus and scroll to field
var $field_input = self.$element.find('tr[data-field="' + field.name + '"] td:nth-child(2) *:first-child');
self.$element.scrollTo($field_input);
$field_input.focus();
}
});
} else {
@@ -736,7 +843,7 @@ db.web.TranslateDialog = db.web.Dialog.extend({
}
});
db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{
template: "EmptyComponent",
set_default_options: function(options) {
this.options = options || {};
@@ -750,7 +857,7 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
},
open_translate_dialog: function(field) {
if (!this.translate_dialog) {
this.translate_dialog = new db.web.TranslateDialog(this).start();
this.translate_dialog = new session.web.TranslateDialog(this).start();
}
this.translate_dialog.open(field);
},
@@ -762,7 +869,7 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
* @param {String} [action_data.special=null] special action handlers (currently: only ``'cancel'``)
* @param {String} [action_data.type='workflow'] the action type, if present, one of ``'object'``, ``'action'`` or ``'workflow'``
* @param {Object} [action_data.context=null] additional action context, to add to the current context
* @param {db.web.DataSet} dataset a dataset object used to communicate with the server
* @param {session.web.DataSet} dataset a dataset object used to communicate with the server
* @param {Object} [record_id] the identifier of the object on which the action is to be applied
* @param {Function} on_closed callback to execute when dialog is closed or when the action does not generate any result (no new action)
*/
@@ -770,35 +877,45 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
var self = this;
var result_handler = function () {
if (on_closed) { on_closed.apply(null, arguments); }
return 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 session.web.CompoundContext(dataset.get_context(), action_data.context || {});
var handler = function (r) {
var action = r.result;
if (action && action.constructor == Object) {
return self.rpc('/web/session/eval_domain_and_context', {
contexts: [dataset.get_context(), action.context || {}, {
active_id: record_id || false,
active_ids: [record_id || false],
var ncontext = new session.web.CompoundContext(context);
if (record_id) {
ncontext.add({
active_id: record_id,
active_ids: [record_id],
active_model: dataset.model
}],
});
}
ncontext.add(action.context || {});
return self.rpc('/web/session/eval_domain_and_context', {
contexts: [ncontext],
domains: []
}).pipe(function (results) {
action.context = results.context
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 {
return result_handler();
}
};
var context = new db.web.CompoundContext(dataset.get_context(), action_data.context || {});
if (action_data.special) {
return handler({result: {"type":"ir.actions.act_window_close"}});
} else if (action_data.type=="object") {
return dataset.call_button(action_data.name, [[record_id], context], handler);
} 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 {
return dataset.exec_workflow(record_id, action_data.name, handler);
}
@@ -806,7 +923,7 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
/**
* Directly set a view to use instead of calling fields_view_get. This method must
* be called before start(). When an embedded view is set, underlying implementations
* of db.web.View must use the provided view instead of any other one.
* of session.web.View must use the provided view instead of any other one.
*
* @param embedded_view A view.
*/
@@ -816,46 +933,18 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
},
do_switch_view: function(view) {
},
set_common_sidebar_sections: function(sidebar) {
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'
}
]);
do_search: function(view) {
},
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) {
$('<xmp>' + db.web.json_node_to_xml(this.fields_view.arch, true) + '</xmp>').dialog({ width: '95%', height: 600});
var view_editor = new session.web.ViewEditor(this, this.$element, this.dataset, this.fields_view.arch);
view_editor.start();
} 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() {
@@ -865,33 +954,41 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
console.log('Todo');
},
on_sidebar_import: function() {
var import_view = new db.web.DataImport(this, this.dataset);
var import_view = new session.web.DataImport(this, this.dataset);
import_view.start();
},
on_sidebar_export: function() {
var export_view = new db.web.DataExport(this, this.dataset);
var export_view = new session.web.DataExport(this, this.dataset);
export_view.start();
},
on_sidebar_translate: function() {
this.open_translate_dialog();
return this.do_action({
res_model : 'ir.translation',
domain : [['type', '!=', 'object'], '|', ['name', '=', this.dataset.model], ['name', 'ilike', this.dataset.model + ',']],
views: [[false, 'list'], [false, 'form']],
type : 'ir.actions.act_window',
auto_search : true,
view_type : "list",
view_mode : "list"
});
},
on_sidebar_view_log: function() {
}
});
db.web.json_node_to_xml = function(node, single_quote, indent) {
session.web.json_node_to_xml = function(node, human_readable, indent) {
// For debugging purpose, this function will convert a json node back to xml
// Maybe usefull for xml view editor
indent = indent || 0;
var sindent = (human_readable ? (new Array(indent + 1).join('\t')) : ''),
r = sindent + '<' + node.tag,
cr = human_readable ? '\n' : '';
if (typeof(node) === 'string') {
return node;
}
else if (typeof(node.tag) !== 'string' || !node.children instanceof Array || !node.attrs instanceof Object) {
return sindent + node;
} else if (typeof(node.tag) !== 'string' || !node.children instanceof Array || !node.attrs instanceof Object) {
throw("Node a json node");
}
indent = indent || 0;
var sindent = new Array(indent + 1).join('\t'),
r = sindent + '<' + node.tag;
for (var attr in node.attrs) {
var vattr = node.attrs[attr];
if (typeof(vattr) !== 'string') {
@@ -899,19 +996,19 @@ db.web.json_node_to_xml = function(node, single_quote, indent) {
vattr = JSON.stringify(vattr);
}
vattr = vattr.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
if (single_quote) {
if (human_readable) {
vattr = vattr.replace(/&quot;/g, "'");
}
r += ' ' + attr + '="' + vattr + '"';
}
if (node.children && node.children.length) {
r += '>\n';
r += '>' + cr;
var childs = [];
for (var i = 0, ii = node.children.length; i < ii; i++) {
childs.push(db.web.json_node_to_xml(node.children[i], single_quote, indent + 1));
childs.push(session.web.json_node_to_xml(node.children[i], human_readable, indent + 1));
}
r += childs.join('\n');
r += '\n' + sindent + '</' + node.tag + '>';
r += childs.join(cr);
r += cr + sindent + '</' + node.tag + '>';
return r;
} else {
return r + '/>';
+304 -136
View File
@@ -2,9 +2,8 @@
<!-- vim:fdl=1:
-->
<templates id="template" xml:space="preserve">
<t t-name="Interface">
<div id="oe_loading" class="loading"></div>
<div id="oe_notification" class="oe_notification">
<t t-name="Notification">
<div class="oe_notification">
<div id="oe_notification_default">
<a class="ui-notify-cross ui-notify-close" href="#">x</a>
<h1>#{title}</h1>
@@ -17,6 +16,9 @@
<p>#{text}</p>
</div>
</div>
</t>
<t t-name="Interface">
<div id="oe_loading"></div>
<table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%" class="main_table">
<tr>
<td colspan="2" valign="top">
@@ -61,7 +63,9 @@
</table>
</t>
<t t-name="Loading">
<div class="loading">
Loading...
</div>
</t>
<t t-name="Database">
<ul class="db_options" style="padding: 0px; display: inline;">
@@ -413,6 +417,9 @@
<tr>
<td class="view-manager-main-content">
<div class="oe-view-manager-header">
<h2 class="oe_view_title" t-if="self.flags.display_title !== false">
<t t-esc="self.display_title()"/>
</h2>
<div class="oe_vm_switch">
<t t-if="views.length != 1" t-foreach="views" t-as="view">
<button type="button" t-att-data-view-type="view.view_type">
@@ -447,15 +454,16 @@
</blockquote>
<a class="oe-shortcut-toggle" title="Add / Remove Shortcut..."
href="javascript: void(0)"> </a>
<h2 class="oe_view_title">
<t t-esc="self.action.name"/>
<button t-if="self.session.debug" class="oe_get_xml_view">
View#<span></span>
</button>
</h2>
<button t-if="self.session.debug" class="oe_get_xml_view">
View#<span></span>
</button>
</t>
<t t-jquery=".oe-view-manager-header" t-operation="after">
<ul class="oe-view-manager-logs"></ul>
<div class="oe-view-manager-logs oe-folded">
<ul></ul>
<a class="oe-more-logs" href="#">More…</a>
<a class="oe-remove-everything ui-icon ui-icon-closethick"/>
</div>
</t>
</t>
@@ -467,50 +475,38 @@
</div>
</t>
<t t-name="Sidebar.section">
<h2><t t-esc="name"/></h2>
<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">
<a class="oe_sidebar_action_a" t-att-id="item.element_id" t-att-title="item.title" href="#">
<t t-esc="item.label"/>
</a>
</li>
</ul>
</div>
</t>
<t t-name="TranslateDialog">
<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}_view">View labels</a></li>
<li><a t-attf-href="##{widget.element_id}_sidebar">Sidebar Relates</a></li>
</ul>
<div t-attf-id="#{widget.element_id}_fields">
<table t-if="widget.view.translatable_fields" class="oe_frame oe_forms oe_translation_form" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="oe_form_separator" width="1%" nowrap="nowrap">
<div class="separator horizontal">Field</div>
</td>
<th t-foreach="widget.languages" align="left">
<div class="separator horizontal"><t t-esc="name"/></div>
</th>
</tr>
<tr t-foreach="widget.view.translatable_fields" t-as="field">
<td class="oe_form_frame_cell" width="1%" nowrap="nowrap">
<label class="oe_label"><t t-esc="field.string"/>:</label>
</td>
<td t-foreach="widget.languages" t-as="lg" class="oe_form_frame_cell">
<input t-if="field.type == 'char'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field" style="width: 100%"/>
<textarea t-if="field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" style="width: 100%"></textarea>
</td>
</tr>
</table>
</div>
<div t-attf-id="#{widget.element_id}_view">
Translate view
</div>
<div t-attf-id="#{widget.element_id}_sidebar">
Translate sidebar
</div>
<table t-if="widget.view.translatable_fields" class="oe_frame oe_forms oe_translation_form" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="oe_form_separator" width="1%" nowrap="nowrap">
<div class="separator horizontal">Field</div>
</td>
<th t-foreach="widget.languages" align="left">
<div class="separator horizontal"><t t-esc="name"/></div>
</th>
</tr>
<tr t-foreach="widget.view.translatable_fields" t-as="field" t-att-data-field="field.name">
<td class="oe_form_frame_cell" width="1%" nowrap="nowrap">
<label class="oe_label"><t t-esc="field.string"/>:</label>
</td>
<td t-foreach="widget.languages" t-as="lg" class="oe_form_frame_cell">
<input t-if="field.type == 'char'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field" style="width: 100%"/>
<textarea t-if="field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" style="width: 100%"></textarea>
</td>
</tr>
</table>
</t>
<t t-name="TreeView">
<select t-if="toolbar" style="width: 30%">
@@ -539,13 +535,14 @@
<td t-foreach="fields_view" t-as="field"
t-if="!field.attrs.modifiers.tree_invisible"
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'">
<span t-if="!field.attrs.modifiers.invisible">
<t t-esc="render(record[field.attrs.name], fields[field.attrs.name])" />
</span>
</td>
</tr>
<table t-name="ListView" class="oe-listview-content">
<t t-set="columns_count" t-value="visible_columns.length + (options.selectable ? 1 : 0) + (options.deletable ? 1 : 0)"/>
<thead class="ui-widget-header">
@@ -563,21 +560,7 @@
Delete
</button>
</td>
<th t-if="options.pager !== false" class="oe-list-pager">
<button type="button" disabled="disabled"
data-pager-action="first">First</button>
<button type="button" disabled="disabled"
data-pager-action="previous"
>&lt;</button>
<span class="oe-pager-state">
</span>
<button type="button" disabled="disabled"
data-pager-action="next">&gt;</button>
<button type="button" disabled="disabled"
data-pager-action="last">Last</button>
</th>
<t t-call="Listview.navigation.button"/>
</tr>
</table>
</th>
@@ -588,7 +571,8 @@
<t t-esc="column.string"/>
</th>
</t>
<th t-if="options.selectable" width="1"/>
<th t-if="options.selectable" width="1" >
<input type="checkbox" class="all-record-selector"/> </th>
<t t-foreach="columns" t-as="column">
<th t-if="!column.meta and column.invisible !== '1'" t-att-data-id="column.id"
t-att-class="((options.sortable and column.tag !== 'button') ? 'oe-sortable' : null)">
@@ -607,8 +591,26 @@
</td>
<td t-if="options.deletable"/>
</tr>
<tr>
<t t-call="Listview.navigation.button"/>
</tr>
</tfoot>
</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">&lt;</button>
<span class="oe-pager-state">
</span>
<button type="button" disabled="disabled"
data-pager-action="next">&gt;</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-call="ListView.row">
<t t-set="record" t-value="records.at(index)"/>
@@ -623,15 +625,25 @@
</td>
</t>
<th t-if="options.selectable" class="oe-record-selector" width="1">
<input type="checkbox"/>
</th>
<t t-if="options.radio">
<th t-if="options.selectable" class="oe-record-selector" width="1">
<input type="radio" name ="radiogroup"/>
</th>
</t>
<t t-if="!options.radio">
<th t-if="options.selectable" class="oe-record-selector" width="1">
<input type="checkbox"/>
</th>
</t>
<t t-foreach="columns" t-as="column">
<t t-set="align" t-value="column.type === 'integer' or column.type == 'float'"/>
<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' : '')
+ (column.tag === 'button' ? ' oe-button' : '')"
t-att-data-field="column.id">
<t t-raw="render_cell(record.toForm().data, column)"/>
<t t-raw="render_cell(record, column)"/>
</td>
</t>
<td t-if="options.deletable" class='oe-record-delete' width="1">
@@ -641,23 +653,20 @@
<t t-name="ListView.row.form">
<t t-raw="frame.render()"/>
</t>
<t t-name="FormView">
<div class="oe_form_header">
<div class="oe_form_buttons" t-if="view.options.action_buttons !== false">
<!--<button type="button" class="oe_form_button_save">
<span class="oe_form_on_update">Save</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 &amp; Edit</span>
<span class="oe_form_on_create">Create &amp; Edit</span>
<div class="oe_form_buttons" t-if="widget.options.action_buttons !== false">
<button type="button" class="oe_form_button_save oe_form_on_editable">Save</button>
<button type="button" class="oe_form_button_toggle">
<span class="oe_form_on_editable">Cancel</span>
<span class="oe_form_on_readonly">Edit</span>
</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_duplicate oe_form_on_update">Duplicate</button>
<button type="button" class="oe_form_button_toggle">Readonly/Editable</button>
<button type="button" class="oe_form_button_new oe_form_on_readonly">Create</button>
<button type="button" class="oe_form_button_duplicate oe_form_on_readonly">Duplicate</button>
<button type="button" class="oe_form_button_delete oe_form_on_readonly">Delete</button>
</div>
<div class="oe_form_pager" t-if="view.options.pager !== false">
<div class="oe_form_pager" t-if="widget.options.pager !== false">
<button type="button" data-pager-action="first">First</button>
<button type="button" data-pager-action="previous">&lt;&lt;</button>
@@ -723,6 +732,17 @@
</tr>
</table>
</t>
<t t-name="WidgetGroup">
<t t-if="widget.string">
<fieldset class="oe_group_box">
<legend><t t-esc="widget.string"/></legend>
<t t-call="WidgetFrame"/>
</fieldset>
</t>
<t t-if="!widget.string">
<t t-call="WidgetFrame"/>
</t>
</t>
<t t-name="WidgetNotebook">
<ul>
<li t-foreach="widget.pages" t-as="page">
@@ -735,17 +755,24 @@
<t t-raw="page.render()"/>
</t>
</t>
<t t-name="WidgetNotebook.tooltip">
<t t-foreach="widget.pages" t-as="page">
<div class="oe_tooltip_string">
Notebook Page "<t t-esc="page.string"/>"
</div>
<ul class="oe_tooltip_technical">
<li data-item="modifiers">
<span class="oe_tooltip_technical_title">Modifiers:</span>
<t t-esc="page.node.attrs.modifiers"/>
</li>
</ul>
</t>
</t>
<t t-name="WidgetNotebookPage">
<div>
<t t-call="WidgetFrame"/>
</div>
</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">
<div t-if="widget.orientation !== 'vertical'" t-att-class="'separator ' + widget.orientation">
<t t-esc="widget.string"/>
@@ -753,21 +780,80 @@
</t>
<t t-name="WidgetLabel">
<label t-att-for="widget.element_id"
t-att-class="'oe_label' + (widget.help ? '_help' : '')"
t-att-title="widget.help">
t-attf-class="oe_label#{widget.help ? '_help' : ''} oe_align_#{widget.align}">
<t t-esc="widget.string"/>
<span t-if="widget.help">?</span>
<t t-if="widget.string and widget.node.tag != 'label'">:</t>
</label>
</t>
<t t-name="WidgetLabel.tooltip">
<div class="oe_tooltip_string" t-if="widget.string">
<t t-esc="widget.string"/> <t t-if="debug and widget.nolabel">(nolabel)</t>
</div>
<p t-if="widget.help" class="oe_tooltip_help">
<t t-esc="widget.help"/>
</p>
<ul t-if="debug" class="oe_tooltip_technical">
<li data-item="field" t-if="widget.name">
<span class="oe_tooltip_technical_title">Field:</span>
<t t-esc="widget.name"/>
</li>
<li data-item="object" t-if="widget.view and widget.view.fields_view">
<span class="oe_tooltip_technical_title">Object:</span>
<t t-esc="widget.view.fields_view.model"/>
</li>
<li data-item="type" t-if="widget.field">
<span class="oe_tooltip_technical_title">Type:</span>
<t t-esc="widget.field.type"/>
</li>
<li t-if="widget.node.attrs.widget" data-item="widget">
<span class="oe_tooltip_technical_title">Widget:</span>
<t t-esc="widget.node.attrs.widget"/>
</li>
<li t-if="widget.node.attrs.size || (widget.field and widget.field.size)" data-item="size">
<span class="oe_tooltip_technical_title">Size:</span>
<t t-esc="widget.node.attrs.size || widget.field.size"/>
</li>
<li t-if="widget.node.attrs.context" data-item="context">
<span class="oe_tooltip_technical_title">Context:</span>
<t t-esc="widget.node.attrs.context_string"/>
</li>
<li t-if="widget.node.attrs.domain" data-item="domain">
<span class="oe_tooltip_technical_title">Domain:</span>
<t t-esc="widget.node.attrs.domain_string"/>
</li>
<li t-if="widget.node.attrs.modifiers and widget.node.attrs.modifiers != '{}'" data-item="modifiers">
<span class="oe_tooltip_technical_title">Modifiers:</span>
<t t-esc="widget.node.attrs.modifiers"/>
</li>
<li t-if="widget.node.attrs.on_change" data-item="on_change">
<span class="oe_tooltip_technical_title">On change:</span>
<t t-esc="widget.node.attrs.on_change"/>
</li>
<li t-if="widget.field and widget.field.relation" data-item="relation">
<span class="oe_tooltip_technical_title">Relation:</span>
<t t-esc="widget.field.relation"/>
</li>
<li t-if="widget.field and widget.field.selection" data-item="selection">
<span class="oe_tooltip_technical_title">Selection:</span>
<ul>
<li t-foreach="widget.field.selection" t-as="option">
[<t t-esc="option[0]"/>]
<t t-if="option[1]"> - </t>
<t t-esc="option[1]"/>
</li>
</ul>
</li>
</ul>
</t>
<t t-name="WidgetParagraph">
<p class="oe_form_paragraph"><t t-esc="widget.string"/></p>
<p t-attf-class="oe_form_paragraph oe_align_#{widget.align}"><t t-esc="widget.string"/></p>
</t>
<t t-name="FieldChar">
<input type="text" size="1"
<input t-att-type="widget.password ? 'password' : 'text'" size="1"
t-att-name="widget.name"
t-att-id="widget.element_id"
t-attf-class="field_#{widget.type} #{widget.element_class}"
t-attf-class="field_#{widget.type} #{_(['integer', 'float', 'float_time']).contains(widget.type) ? 'oe-number' : ''}"
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"/>
@@ -775,7 +861,7 @@
<t t-name="FieldChar.readonly">
<div
t-att-id="widget.element_id"
t-attf-class="field_#{widget.type} #{widget.element_class}"
t-attf-class="field_#{widget.type} #{_(['integer', 'float', 'float_time']).contains(widget.type) ? 'oe-number' : ''}"
t-attf-style="width: #{widget.field.translate ? '99' : '100'}%">
</div>
</t>
@@ -814,7 +900,7 @@
<textarea rows="6"
t-att-name="widget.name"
t-att-id="widget.element_id"
t-attf-class="field_#{widget.type} #{widget.element_class}"
t-attf-class="field_#{widget.type}"
t-attf-style="width: #{widget.field.translate ? '99' : '100'}%"
></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"/>
@@ -833,8 +919,8 @@
<t t-name="FieldSelection">
<select
t-att-name="widget.name"
t-att-id="widget.element_id + '_field'"
t-attf-class="field_#{widget.type} #{widget.element_class}"
t-att-id="widget.element_id"
t-attf-class="field_#{widget.type}"
style="width: 100%">
<t t-foreach="widget.values" t-as="option">
<option><t t-esc="option[1]"/></option>
@@ -842,8 +928,9 @@
</select>
</t>
<t t-name="FieldMany2One">
<div t-att-class="widget.element_class" class="oe-m2o">
<input type="text" size="1" style="width: 100%;"/>
<div class="oe-m2o">
<input type="text" size="1" style="width: 100%;"
t-att-id="widget.element_id"/>
<span class="oe-m2o-drop-down-button">
<img src="/web/static/src/img/down-arrow.png" /></span>
<span class="oe-m2o-cm-button" t-att-id="widget.name + '_open'">
@@ -854,9 +941,9 @@
</t>
<t t-name="FieldMany2One.context_menu">
<ul>
<li t-att-id="widget.cm_id + '_open'" style="color:grey">Open...</li>
<li t-att-id="widget.cm_id + '_create'">Create...</li>
<li t-att-id="widget.cm_id + '_search'" class="oe_m2o_menu_item_mandatory">Search...</li>
<li t-att-id="widget.cm_id + '_open'" style="color:grey" class="oe_m2o_menu_item_mandatory">Open...</li>
<li t-att-id="widget.cm_id + '_create'" class="oe_m2o_menu_item_noreadonly">Create...</li>
<li t-att-id="widget.cm_id + '_search'" class="oe_m2o_menu_item_noreadonly">Search...</li>
<t t-set="i" t-value="0"/>
<t t-foreach="widget.related_entries" t-as="entry">
<li t-att-id="widget.cm_id + '_related_' + i" style="color:grey" class="oe_m2o_menu_item_mandatory">
@@ -877,7 +964,7 @@
<td t-attf-class="oe_form_frame_cell oe_form_selection #{widget.selection.element_class}">
<t t-raw="widget.selection.render()"/>
</td>
<td class="oe_form_frame_cell oe_form_many2one #{widget.selection.element_class}" 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()"/>
</td>
</tr>
@@ -886,8 +973,8 @@
<t t-name="FieldBoolean">
<input type="checkbox"
t-att-name="widget.name"
t-att-id="widget.element_id + '_field'"
t-attf-class="field_#{widget.type} #{widget.element_class}"/>
t-att-id="widget.element_id"
t-attf-class="field_#{widget.type}"/>
</t>
<t t-name="FieldProgressBar">
<div t-opentag="true" class="oe-progressbar">
@@ -902,7 +989,7 @@
t-att-border="widget.readonly ? 0 : 1"
t-att-id="widget.element_id + '_field'"
t-att-name="widget.name"
t-attf-class="field_#{widget.type} #{widget.element_class}"
t-attf-class="field_#{widget.type}"
t-att-width="widget.node.attrs.img_width || widget.node.attrs.width"
t-att-height="widget.node.attrs.img_height || widget.node.attrs.height"
/>
@@ -950,7 +1037,7 @@
<input type="text" size="1"
t-att-name="widget.name"
t-att-id="widget.element_id + '_field'"
t-attf-class="field_#{widget.type} #{widget.element_class}" style="width: 100%"
t-attf-class="field_#{widget.type}" style="width: 100%"
/>
</td>
<td class="oe-binary" nowrap="true">
@@ -994,18 +1081,47 @@
</table>
</t>
<t t-name="WidgetButton">
<button type="button"
t-attf-class="#{widget.element_class}"
t-att-title="widget.help"
style="width: 100%" class="button">
<button type="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"/>
<span t-if="widget.string"><t t-esc="widget.string"/></span>
</button>
</t>
<t t-name="WidgetButton.tooltip" t-extend="WidgetLabel.tooltip">
<t t-jquery="div.oe_tooltip_string" t-operation="replace">
<div class="oe_tooltip_string" t-if="debug || widget.string">
<t t-if="debug">
Button
<t t-if="widget.string">: </t>
<t t-if="!widget.string"> (no string)</t>
</t>
<t t-esc="widget.string"/>
</div>
</t>
<t t-jquery="ul.oe_tooltip_technical" t-operation="append">
<li t-if="widget.node.attrs.special" data-item="special">
<span class="oe_tooltip_technical_title">Special:</span>
<t t-esc="widget.node.attrs.special"/>
</li>
<t t-set="button_type" t-value="widget.node.attrs.type"/>
<li t-if="button_type" data-item="button_type">
<span class="oe_tooltip_technical_title">Button Type:</span>
<t t-esc="button_type"/>
</li>
<li t-if="button_type === 'object'" data-item="button_method">
<span class="oe_tooltip_technical_title">Method:</span>
<t t-esc="widget.node.attrs.name"/>
</li>
<li t-if="button_type === 'action'" data-item="button_action">
<span class="oe_tooltip_technical_title">Action ID:</span>
<t t-esc="widget.node.attrs.name"/>
</li>
</t>
</t>
<t t-name="SearchView">
<form class="oe_forms">
<t t-call="SearchView.render_lines"/>
<div class="oe_search-view-buttons" style="text-align: right;">
<div class="oe_search-view-buttons">
<input type="submit" value="Search"/>
<input type="reset" value="Clear"/>
<button class="oe_search-view-custom-filter-btn"><span>Advanced Filter</span></button>
@@ -1092,14 +1208,14 @@
<div style="white-space: nowrap;">
<select t-att-name="attrs.name" t-att-id="element_id"
t-att-autofocus="attrs.default_focus === '1' || undefined">
<option/>
<option t-if="prepend_empty"/>
<t t-foreach="attrs.selection" t-as="option">
<t t-set="selected" t-value="defaults[attrs.name] === option[0]"/>
<option t-if="selected"
t-att-value="option[0]" selected="selected">
t-att-value="option_index" selected="selected">
<t t-esc="option[1]"/>
</option>
<option t-if="!selected" t-att-value="option[0]">
<option t-if="!selected" t-att-value="option_index">
<t t-esc="option[1]"/>
</option>
</t>
@@ -1271,6 +1387,55 @@
.unwrap();
</t>
</t>
<t t-name="view_editor">
<table class="oe_view_editor">
<t t-call="view_editor.row"/>
</table>
</t>
<tr t-name="view_editor.row" class="oe_view_editor_row" t-att-id="'viewedit-' + rec.id" t-att-level="rec.level" t-foreach="data" t-as="rec">
<td class="oe_view_editor_colum" width="85%">
<table class="oe_view_editor_tree_grid">
<tr>
<td width="16px" t-att-style="'background-position: ' + 20*rec.level + 'px; padding-left: ' + 20*rec.level + 'px'">
<img t-if="rec.child_id.length" t-att-id="'parentimg-' + rec.id"
src="/web/static/src/img/collapse.gif" width="16" height="16" border="0"/>
</td>
<td style="cursor: pointer;">
<a style="text-decoration:none" href="javascript:void(0);"> <t t-esc="rec.name"/> </a>
</td>
</tr>
</table>
</td>
<td align="left" class="oe_view_editor_colum" width="15%">
<table width="100%">
<tr>
<td width="20%">
<img t-if="rec.att_list.length"
id="side-add" src="/web/static/src/img/icons/gtk-add.png" style="cursor: pointer;"/>
</td>
<td width="20%">
<img id="side-remove" src="/web/static/src/img/icons/gtk-remove.png" style="cursor: pointer;"/>
</td>
<td width="20%">
<img t-if="rec.att_list.length"
id="side-edit" src="/web/static/src/img/icons/gtk-edit.png" style="cursor: pointer;"/>
</td>
<td width="20%">
<img t-if="rec.att_list.length"
id="side-up" src="/web/static/src/img/icons/gtk-go-up.png" style="cursor: pointer;"/>
</td>
<td width="20%">
<img t-if="rec.att_list.length"
id="side-down" src="/web/static/src/img/icons/gtk-go-down.png" style="cursor: pointer;"/>
</td>
</tr>
</table>
</td>
<t t-if="rec.child_id.length">
<t t-set="data" t-value="rec.child_id"/>
<t t-call="view_editor.row"/>
</t>
</tr>
<t t-name="ExportView">
<a id="exportview" href="javascript: void(0)" style="text-decoration: none;color: #3D3D3D;">Export</a>
@@ -1405,7 +1570,8 @@
<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">
<form name="import_data" id="import_data" action="" method="post" enctype="multipart/form-data"
class="oe-import oe-import-no-result">
<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,
@@ -1415,11 +1581,11 @@
<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">
<h2 class="separator horizontal oe-import-result">2. Check your file format</h2>
<div id="result" class="oe-import-result"></div>
<fieldset class="oe-closed oe-import-result">
<legend>Import Options</legend>
<table>
<tr>
<td colspan="4">
<label for="file_has_headers">Does your file have titles?</label>
@@ -1449,22 +1615,24 @@
</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.result">
<table 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" placeholder="--- Don't Import ---"/><span class="oe-m2o-drop-down-button">
<img src="/web/static/src/img/down-arrow.png" /></span>
</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 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">
+80 -19
View File
@@ -11,38 +11,58 @@ $(document).ready(function () {
test("format_datetime", function () {
var date = openerp.web.str_to_datetime("2009-05-04 12:34:23");
var str = openerp.web.format_value(date, {type:"datetime"});
equal(str, date.toString("M/d/yyyy h:mm:ss tt"));
equal(str, date.toString("MM/dd/yyyy HH:mm:ss"));
});
test("format_date", function () {
var date = openerp.web.str_to_datetime("2009-05-04 12:34:23");
var str = openerp.web.format_value(date, {type:"date"});
equal(str, date.toString("M/d/yyyy"));
equal(str, date.toString("MM/dd/yyyy"));
});
test("format_time", function () {
var date = openerp.web.str_to_datetime("2009-05-04 12:34:23");
var str = openerp.web.format_value(date, {type:"time"});
equal(str, date.toString("h:mm:ss tt"));
equal(str, date.toString("HH:mm:ss"));
});
test("format_float", function () {
var fl = 12.1234;
var str = openerp.web.format_value(fl, {type:"float"});
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');
equal(openerp.web.format_value(-11.25, {type: 'float'}),
"-11.25");
openerp.web._t.database.parameters.grouping = [1, 2, -1];
equal(openerp.web.format_value(1111111.25, {type: 'float'}),
"1111,11,1.25");
openerp.web._t.database.parameters.grouping = [1, 0];
equal(openerp.web.format_value(-11.25, {type: 'float'}),
"-1,1.25");
});
test("parse_datetime", function () {
var val = openerp.web.str_to_datetime("2009-05-04 12:34:23");
var res = openerp.web.parse_value(val.toString("M/d/yyyy h:mm:ss tt"), {type:"datetime"});
equal(val.toString("M/d/yyyy h:mm:ss tt"), res.toString("M/d/yyyy h:mm:ss tt"));
});
test("parse_date", function () {
var val = openerp.web.str_to_date("2009-05-04");
var res = openerp.web.parse_value(val.toString("M/d/yyyy"), {type:"date"});
equal(val.toString("M/d/yyyy"), res.toString("M/d/yyyy"));
});
test("parse_time", function () {
var val = openerp.web.str_to_time("12:34:23");
var res = openerp.web.parse_value(val.toString("h:mm:ss tt"), {type:"time"});
equal(val.toString("h:mm:ss tt"), res.toString("h:mm:ss tt"));
});
// test("parse_datetime", function () {
// var val = openerp.web.str_to_datetime("2009-05-04 12:34:23");
// var res = openerp.web.parse_value(val.toString("MM/dd/yyyy HH:mm:ss"), {type:"datetime"});
// equal(val.toString("MM/dd/yyyy HH:mm:ss"), res.toString("MM/dd/yyyy HH:mm:ss"));
// });
// test("parse_date", function () {
// var val = openerp.web.str_to_date("2009-05-04");
// var res = openerp.web.parse_value(val.toString("MM/dd/yyyy"), {type:"date"});
// equal(val.toString("MM/dd/yyyy"), res.toString("MM/dd/yyyy"));
// });
// test("parse_time", function () {
// var val = openerp.web.str_to_time("12:34:23");
// var res = openerp.web.parse_value(val.toString("HH:mm:ss"), {type:"time"});
// equal(val.toString("HH:mm:ss"), res.toString("HH:mm:ss"));
// });
test("parse_float", function () {
var str = "134,112.1234";
var val = openerp.web.parse_value(str, {type:"float"});
@@ -51,4 +71,45 @@ $(document).ready(function () {
var val = openerp.web.parse_value(str, {type:"float"});
equal(val, -134112.1234);
});
});
test('intersperse', function () {
var g = openerp.web.intersperse;
equal(g("", []), "");
equal(g("0", []), "0");
equal(g("012", []), "012");
equal(g("1", []), "1");
equal(g("12", []), "12");
equal(g("123", []), "123");
equal(g("1234", []), "1234");
equal(g("123456789", []), "123456789");
equal(g("&ab%#@1", []), "&ab%#@1");
equal(g("0", []), "0");
equal(g("0", [1]), "0");
equal(g("0", [2]), "0");
equal(g("0", [200]), "0");
equal(g("12345678", [0], '.'), '12345678');
equal(g("", [1], '.'), '');
equal(g("12345678", [1], '.'), '1234567.8');
equal(g("12345678", [1], '.'), '1234567.8');
equal(g("12345678", [2], '.'), '123456.78');
equal(g("12345678", [2, 1], '.'), '12345.6.78');
equal(g("12345678", [2, 0], '.'), '12.34.56.78');
equal(g("12345678", [-1, 2], '.'), '12345678');
equal(g("12345678", [2, -1], '.'), '123456.78');
equal(g("12345678", [2, 0, 1], '.'), '12.34.56.78');
equal(g("12345678", [2, 0, 0], '.'), '12.34.56.78');
equal(g("12345678", [2, 0, -1], '.'), '12.34.56.78');
});
test('format_integer', function () {
openerp.web._t.database.parameters.grouping = [3, 3, 3, 3];
equal(openerp.web.format_value(1000000, {type: 'integer'}),
'1,000,000');
openerp.web._t.database.parameters.grouping = [3, 2, -1];
equal(openerp.web.format_value(106500, {type: 'integer'}),
'1,06,500');
openerp.web._t.database.parameters.grouping = [1, 2, -1];
equal(openerp.web.format_value(106500, {type: 'integer'}),
'106,50,0');
});
});
+5 -6
View File
@@ -21,7 +21,9 @@
<script src="/web/static/lib/datejs/sugarpak.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/lib/py.parse/lib/py.js"></script>
<script src="/web/static/src/js/boot.js"></script>
<script src="/web/static/src/js/core.js"></script>
@@ -31,11 +33,8 @@
<script src="/web/static/src/js/data.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/form.js"></script>
<script src="/web/static/src/js/list.js"></script>
<script type="text/javascript">
QWeb.add_template('/web/static/src/xml/web.xml');
</script>
<script src="/web/static/src/js/view_form.js"></script>
<script src="/web/static/src/js/view_list.js"></script>
</head>
<body id="oe" class="openerp">
<h1 id="qunit-header">OpenERP web Test Suite</h1>
+4
View File
@@ -1,5 +1,6 @@
{
"name": "web calendar",
"category" : "Hidden",
"version": "2.0",
"depends": ['web'],
"js": [
@@ -10,5 +11,8 @@
"css": ['static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.css',
'static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_ext.css'
],
'qweb' : [
"static/src/xml/*.xml",
],
'active': True
}
+22
View File
@@ -0,0 +1,22 @@
# Arabic 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-11-03 15:02+0000\n"
"Last-Translator: kifcaliph <kifcaliph@hotmail.com>\n"
"Language-Team: Arabic <ar@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-11-04 05:32+0000\n"
"X-Generator: Launchpad (build 14231)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
+22
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
+22
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
+22
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
+22
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
+22
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
+22
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
+22
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
+22
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
+22
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
+22
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr ""
+22
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
+1 -1
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\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"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
+57 -57
View File
@@ -3,8 +3,8 @@
*---------------------------------------------------------*/
openerp.web_calendar = function(openerp) {
var _t = openerp.web._t;
var QWeb = openerp.web.qweb;
QWeb.add_template('/web_calendar/static/src/xml/web_calendar.xml');
openerp.web.views.add('calendar', 'openerp.web_calendar.CalendarView');
openerp.web_calendar.CalendarView = openerp.web.View.extend({
// Dhtmlx scheduler ?
@@ -13,16 +13,13 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
this.set_default_options(options);
this.dataset = dataset;
this.model = dataset.model;
this.fields_view = {};
this.view_id = view_id;
this.domain = this.dataset.domain || [];
this.context = this.dataset.context || {};
this.has_been_loaded = $.Deferred();
this.creating_event_id = null;
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.start();
}
this.form_dialog = new openerp.web_calendar.CalendarFormDialog(this, {}, this.options.action_views_ids.form, dataset);
this.form_dialog.start();
this.COLOR_PALETTE = ['#f57900', '#cc0000', '#d400a8', '#75507b', '#3465a4', '#73d216', '#c17d11', '#edd400',
'#fcaf3e', '#ef2929', '#ff00c9', '#ad7fa8', '#729fcf', '#8ae234', '#e9b96e', '#fce94f',
'#ff8e00', '#ff0000', '#b0008c', '#9000ff', '#0078ff', '#00ff00', '#e6ff00', '#ffff00',
@@ -31,7 +28,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
},
start: function() {
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() {
scheduler.clearAll();
@@ -47,6 +44,10 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
this.name = this.fields_view.name || this.fields_view.arch.attrs.string;
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_delay = this.fields_view.arch.attrs.date_delay;
this.date_stop = this.fields_view.arch.attrs.date_stop;
@@ -55,6 +56,10 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
this.day_length = this.fields_view.arch.attrs.day_length || 8;
this.color_field = this.fields_view.arch.attrs.color;
this.fields = this.fields_view.fields;
if (!this.date_start) {
throw new Error("Calendar view has not defined 'date_start' attribute.");
}
//* Calendar Fields *
this.calendar_fields.date_start = {'name': this.date_start, 'kind': this.fields[this.date_start].type};
@@ -68,9 +73,6 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
if (this.date_stop) {
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++) {
this.info_fields.push(this.fields_view.arch.children[fld].attrs.name);
@@ -80,8 +82,8 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
if (this.options.sidebar && this.options.sidebar_id) {
this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
this.sidebar.start();
this.sidebar.navigator = new openerp.web_calendar.SidebarNavigator(this.sidebar, this.sidebar.add_section('navigator', "Navigator"), this);
this.sidebar.responsible = new openerp.web_calendar.SidebarResponsible(this.sidebar, this.sidebar.add_section('responsible', "Responsible"), this);
this.sidebar.navigator = new openerp.web_calendar.SidebarNavigator(this.sidebar, this);
this.sidebar.responsible = new openerp.web_calendar.SidebarResponsible(this.sidebar, this);
this.sidebar.add_toolbar(this.fields_view.toolbar);
this.set_common_sidebar_sections(this.sidebar);
this.sidebar.do_unfold();
@@ -92,9 +94,6 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
this.init_scheduler();
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() {
var self = this;
@@ -111,9 +110,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
scheduler.config.drag_resize = true;
scheduler.config.drag_create = true;
// Initialize Sceduler
this.mode = this.mode || 'month';
scheduler.init('openerp_scheduler', null, this.mode);
scheduler.init('openerp_scheduler', null, this.mode || 'month');
scheduler.detachAllEvents();
scheduler.attachEvent('onEventAdded', this.do_create_event);
@@ -122,20 +119,24 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
scheduler.attachEvent('onDblClick', this.do_edit_event);
scheduler.attachEvent('onBeforeLightbox', this.do_edit_event);
this.mini_calendar = scheduler.renderCalendar({
container: this.sidebar.navigator.element_id,
navigation: true,
date: scheduler._date,
handler: function(date, calendar) {
scheduler.setCurrentView(date, 'day');
}
});
if (this.options.sidebar) {
this.mini_calendar = scheduler.renderCalendar({
container: this.sidebar.navigator.element_id,
navigation: true,
date: scheduler._date,
handler: function(date, calendar) {
scheduler.setCurrentView(date, 'day');
}
});
}
},
refresh_scheduler: function() {
scheduler.setCurrentView(scheduler._date);
},
refresh_minical: function() {
scheduler.updateCalendar(this.mini_calendar);
if (this.options.sidebar) {
scheduler.updateCalendar(this.mini_calendar);
}
},
reload_event: function(id) {
this.dataset.read_ids([id], _.keys(this.fields), this.on_events_loaded);
@@ -158,7 +159,9 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
for (var e = 0; e < events.length; e++) {
var evt = events[e];
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;
}
@@ -183,24 +186,24 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
}
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') {
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));
}
scheduler.parse(res_events, 'json');
this.refresh_scheduler();
this.refresh_minical();
if (!no_filter_reload) {
if (!no_filter_reload && this.options.sidebar) {
this.sidebar.responsible.on_events_loaded(sidebar_items);
}
},
convert_event: function(evt) {
var date_start = openerp.web.str_to_datetime(evt[this.date_start]),
date_stop = this.date_stop ? openerp.web.str_to_datetime(evt[this.date_stop]) : null,
date_delay = evt[this.date_delay] || null,
date_delay = evt[this.date_delay] || 1.0,
res_text = '',
res_description = [];
@@ -269,12 +272,14 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
}
},
do_edit_event: function(event_id) {
var self = this;
event_id = parseInt(event_id, 10);
var index = _.indexOf(this.dataset.ids, event_id);
if (index > -1) {
this.dataset.index = index;
this.form_dialog.form.do_show();
this.form_dialog.open();
this.form_dialog.form.do_show().then(function() {
self.form_dialog.open();
});
return false;
}
return true;
@@ -293,26 +298,17 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
}
return data;
},
do_search: function(domains, contexts, groupbys) {
do_search: function(domain, context, group_by) {
var self = this;
scheduler.clearAll();
$.when(this.has_been_loaded).then(function() {
self.rpc('/web/session/eval_domain_and_context', {
domains: domains,
contexts: contexts,
group_by_seq: groupbys
}, function (results) {
// TODO: handle non-empty results.group_by with read_group
self.dataset.context = self.context = results.context;
self.dataset.domain = self.domain = results.domain;
self.dataset.read_slice(_.keys(self.fields), {
offset:0,
limit: self.limit
}, function(events) {
self.dataset_events = events;
self.on_events_loaded(events);
}
);
// TODO: handle non-empty results.group_by with read_group
self.dataset.read_slice(_.keys(self.fields), {
offset: 0,
limit: self.limit
}, function(events) {
self.dataset_events = events;
self.on_events_loaded(events);
});
});
},
@@ -372,13 +368,16 @@ openerp.web_calendar.CalendarFormDialog = openerp.web.Dialog.extend({
});
openerp.web_calendar.SidebarResponsible = openerp.web.Widget.extend({
init: function(parent, element_id, view) {
this._super(parent, element_id);
init: function(parent, view) {
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.$element.delegate('input:checkbox', 'change', this.on_filter_click);
},
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) {
var responsibles = [],
@@ -398,8 +397,9 @@ openerp.web_calendar.SidebarResponsible = openerp.web.Widget.extend({
});
openerp.web_calendar.SidebarNavigator = openerp.web.Widget.extend({
init: function(parent, element_id, view) {
this._super(parent, element_id);
init: function(parent, view) {
var $section = parent.add_section(_t('Navigator'), 'navigator');
this._super(parent, $section.attr('id'));
this.view = view;
},
on_events_loaded: function(events) {
+2 -1
View File
@@ -1,5 +1,6 @@
{
"name": "Web Chat",
"category" : "Hidden",
"version": "2.0",
"depends": ['web'],
"js": [
@@ -10,6 +11,6 @@
'static/src/js/web_chat.js'
],
"css": [],
# 'active': True,
'active': False,
'installable': False,
}
+1 -1
View File
@@ -2,7 +2,7 @@
import time
import simplejson
import web.common as openerpweb
import web.common.http as openerpweb
import logging
_logger = logging.getLogger(__name__)
+1 -1
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\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"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
+4
View File
@@ -1,10 +1,14 @@
{
"name": "web Dashboard",
"category" : "Hidden",
"version": "2.0",
"depends": ['web'],
"js": [
'static/src/js/dashboard.js'
],
"css": ['static/src/css/dashboard.css'],
'qweb' : [
"static/src/xml/*.xml",
],
'active': True
}
+2 -2
View File
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
import web.common as openerpweb
import web.common.http as openerpweb
WIDGET_CONTENT_PATTERN = """<!DOCTYPE html>
<html>
@@ -24,5 +24,5 @@ class Widgets(openerpweb.Controller):
@openerpweb.httprequest
def content(self, request, widget_id):
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]
+46
View File
@@ -0,0 +1,46 @@
# Arabic 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-11-03 15:09+0000\n"
"Last-Translator: kifcaliph <kifcaliph@hotmail.com>\n"
"Language-Team: Arabic <ar@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-11-04 05:32+0000\n"
"X-Generator: Launchpad (build 14231)\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 "%"
+46
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "%"
+46
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "%"
+46
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "%"
+46
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "%"
+46
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "%"
+46
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "%"
+46
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "%"
+46
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "%"
+46
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "%"
+46
View File
@@ -0,0 +1,46 @@
# Polish 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-11-04 16:28+0000\n"
"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
"Language-Team: Polish <pl@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-11-05 06:04+0000\n"
"X-Generator: Launchpad (build 14231)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
msgstr "Przywróć"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Undo"
msgstr "Cofnij"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Add Widget"
msgstr "Dodaj kontrolkę"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Change layout"
msgstr "Zmień układ"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Choose dashboard layout"
msgstr "Wybierz układ konsoli"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "progress:"
msgstr "postęp:"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "%"
msgstr ""
+46
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 ""
+46
View File
@@ -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-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\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 "%"
+1 -1
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\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"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -7,17 +7,38 @@
}
.openerp .oe-dashboard-action {
margin: 0 0.5em 0.5em 0;
padding: 2px;
}
.openerp .oe-dashboard-action:hover {
border: 1px dashed #ccc;
padding: 1px;
padding: 0px;
background-color: white;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
.openerp .oe-dashboard-action .oe-dashboard-action-header {
font-size: 125%;
font-size: 85%;
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 {
float: left;
padding-right: 4px;
@@ -57,6 +78,12 @@
visibility: hidden;
}
/* Base overwriting */
.openerp .oe-dashboard .oe-listview-content, .openerp .oe-dashboard .ui-widget-header {
border:none !important;
padding:0px 3px;
}
/* Layouts */
.openerp .oe-dashboard-layout_1 .oe-dashboard-column.index_0 {
width: 100%;
@@ -234,6 +261,46 @@
.openerp .oe-dashboard-action .view-manager-main-content {
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

Some files were not shown because too many files have changed in this diff Show More