[MERGE]merge main view editor branch upto 884 revision.

bzr revid: kch@tinyerp.com-20111017103740-v7lrybz3gkq2ujxa
This commit is contained in:
Kunal Chavda (OpenERP) 2011-10-17 16:07:40 +05:30
commit f76bdfb1fa
109 changed files with 7716 additions and 1841 deletions

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)

View File

@ -1,5 +1,6 @@
{
"name" : "web",
"category" : "Hidden",
"depends" : [],
'active': True,
'post_load' : 'wsgi_postload',

View File

@ -1,2 +1,6 @@
#!/usr/bin/python
from dispatch import *
import http
import nonliterals
import release
import session
import xml2json

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)

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)

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

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(
@ -24,3 +297,158 @@ def session(request, storage_path, session_cookie='sessionid'):
yield request.session
finally:
session_store.save(request.session)
#----------------------------------------------------------
# OpenERP Web Module/Controller Loading and URL Routing
#----------------------------------------------------------
addons_module = {}
addons_manifest = {}
controllers_class = {}
controllers_object = {}
controllers_path = {}
class ControllerType(type):
def __init__(cls, name, bases, attrs):
super(ControllerType, cls).__init__(name, bases, attrs)
controllers_class["%s.%s" % (cls.__module__, cls.__name__)] = cls
class Controller(object):
__metaclass__ = ControllerType
class Root(object):
"""Root WSGI application for the OpenERP Web Client.
:param options: mandatory initialization options object, must provide
the following attributes:
``server_host`` (``str``)
hostname of the OpenERP server to dispatch RPC to
``server_port`` (``int``)
RPC port of the OpenERP server
``serve_static`` (``bool | None``)
whether this application should serve the various
addons's static files
``storage_path`` (``str``)
filesystem path where HTTP session data will be stored
``dbfilter`` (``str``)
only used in case the list of databases is requested
by the server, will be filtered by this pattern
"""
def __init__(self, options):
self.root = '/web/webclient/home'
self.config = options
if self.config.backend == 'local':
conn = openerplib.get_connector(protocol='local')
else:
conn = openerplib.get_connector(hostname=self.config.server_host,
port=self.config.server_port)
self.config.connector = conn
self.session_cookie = 'sessionid'
self.addons = {}
static_dirs = self._load_addons()
if options.serve_static:
self.dispatch = werkzeug.wsgi.SharedDataMiddleware(
self.dispatch, static_dirs)
if options.session_storage:
if not os.path.exists(options.session_storage):
os.mkdir(options.session_storage, 0700)
self.session_storage = options.session_storage
def __call__(self, environ, start_response):
""" Handle a WSGI request
"""
return self.dispatch(environ, start_response)
def dispatch(self, environ, start_response):
"""
Performs the actual WSGI dispatching for the application, may be
wrapped during the initialization of the object.
Call the object directly.
"""
request = werkzeug.wrappers.Request(environ)
request.parameter_storage_class = werkzeug.datastructures.ImmutableDict
if request.path == '/':
params = urllib.urlencode(dict(request.args, debug=''))
return werkzeug.utils.redirect(self.root + '?' + params, 301)(
environ, start_response)
elif request.path == '/mobile':
return werkzeug.utils.redirect(
'/web_mobile/static/src/web_mobile.html', 301)(environ, start_response)
handler = self.find_handler(*(request.path.split('/')[1:]))
if not handler:
response = werkzeug.exceptions.NotFound()
else:
with session_context(request, self.session_storage, self.session_cookie) as session:
result = handler( request, self.config)
if isinstance(result, basestring):
headers=[('Content-Type', 'text/html; charset=utf-8'), ('Content-Length', len(result))]
response = werkzeug.wrappers.Response(result, headers=headers)
else:
response = result
if hasattr(response, 'set_cookie'):
response.set_cookie(self.session_cookie, session.sid)
return response(environ, start_response)
def _load_addons(self):
"""
Loads all addons at the specified addons path, returns a mapping of
static URLs to the corresponding directories
"""
statics = {}
for addons_path in self.config.addons_path:
if addons_path not in sys.path:
sys.path.insert(0, addons_path)
for module in os.listdir(addons_path):
if module not in addons_module:
manifest_path = os.path.join(addons_path, module, '__openerp__.py')
path_static = os.path.join(addons_path, module, 'static')
if os.path.isfile(manifest_path) and os.path.isdir(path_static):
manifest = ast.literal_eval(open(manifest_path).read())
manifest['addons_path'] = addons_path
_logger.info("Loading %s", module)
m = __import__(module)
addons_module[module] = m
addons_manifest[module] = manifest
statics['/%s/static' % module] = path_static
for k, v in controllers_class.items():
if k not in controllers_object:
o = v()
controllers_object[k] = o
if hasattr(o, '_cp_path'):
controllers_path[o._cp_path] = o
return statics
def find_handler(self, *l):
"""
Tries to discover the controller handling the request for the path
specified by the provided parameters
:param l: path sections to a controller or controller method
:returns: a callable matching the path sections, or ``None``
:rtype: ``Controller | None``
"""
if len(l) > 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
#

View File

@ -131,7 +131,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 +179,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 +205,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 +219,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))

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,6 +126,7 @@ 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 NetRPC_Exception(Exception):
@ -212,18 +240,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 +350,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:

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

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

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import ast
import base64
import csv
import glob
@ -9,60 +10,16 @@ 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
@ -200,7 +157,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:
@ -358,13 +315,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 +365,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 []):
@ -817,7 +783,7 @@ 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'):
@ -882,7 +848,7 @@ class View(openerpweb.Controller):
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`
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
@ -892,14 +858,14 @@ class View(openerpweb.Controller):
if not isinstance(domain, (str, unicode)):
return domain
try:
return openerpweb.ast.literal_eval(domain)
return ast.literal_eval(domain)
except ValueError:
# not a literal
return openerpweb.nonliterals.Domain(session, domain)
return web.common.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`
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
@ -909,9 +875,9 @@ class View(openerpweb.Controller):
if not isinstance(context, (str, unicode)):
return context
try:
return openerpweb.ast.literal_eval(context)
return ast.literal_eval(context)
except ValueError:
return openerpweb.nonliterals.Context(session, context)
return web.common.nonliterals.Context(session, context)
def parse_domains_and_contexts(self, elem, session):
""" Converts domains and contexts from the view into Python objects,
@ -999,10 +965,10 @@ class SearchView(View):
@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,16 +991,17 @@ 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):
@ -1393,7 +1360,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 = {}
@ -1432,7 +1399,6 @@ class Reports(View):
('Content-Length', len(report))],
cookies={'fileToken': int(token)})
class Import(View):
_cp_path = "/web/import"

707
addons/web/po/da.po Normal file
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-10-11 14:21+0000\n"
"Last-Translator: Jonas Mortensen <Unknown>\n"
"Language-Team: Danish <da@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-10-12 04:44+0000\n"
"X-Generator: Launchpad (build 14124)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
"Warning, the record has been modified, your changes will be discarded."
msgstr ""
"Advarsel, registreringen er blevet ændret, dine ændringer vil derfor blive "
"kasseret."
#: addons/web/static/src/js/view_form.js:1659
msgid "<em>   Search More...</em>"
msgstr "<em>   Søg efter mere....</em>"
#: addons/web/static/src/js/view_form.js:1672
#, python-format
msgid "<em>   Create \"<strong>%s</strong>\"</em>"
msgstr "<em>   Create \"<strong>%s</strong>\"</em>"
#: addons/web/static/src/js/view_form.js:1678
msgid "<em>   Create and Edit...</em>"
msgstr "<em>   Opret og rediger...</em>"
#: addons/web/static/src/js/views.js:568
msgid "You must choose at least one record."
msgstr "Du skal vælge mindst en registrering."
#: addons/web/static/src/js/views.js:569
msgid "Warning"
msgstr "Advarsel"
#: addons/web/static/src/js/views.js:609
msgid "Translations"
msgstr "Oversættelser"
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
msgid "Save"
msgstr "Gem"
#: addons/web/static/src/js/views.js:615
msgid "Close"
msgstr "Luk"
#: addons/web/static/src/xml/base.xml:0
msgid "x"
msgstr "x"
#: addons/web/static/src/xml/base.xml:0
msgid "#{title}"
msgstr "#(titel)"
#: addons/web/static/src/xml/base.xml:0
msgid "#{text}"
msgstr "#(tekst)"
#: addons/web/static/src/xml/base.xml:0
msgid "Powered by"
msgstr "Drevet af"
#: addons/web/static/src/xml/base.xml:0
msgid "openerp.com"
msgstr "openerp.com"
#: addons/web/static/src/xml/base.xml:0
msgid "."
msgstr ","
#: addons/web/static/src/xml/base.xml:0
msgid "Loading..."
msgstr "Indlæser..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create"
msgstr "Opret"
#: addons/web/static/src/xml/base.xml:0
msgid "Drop"
msgstr "Drop"
#: addons/web/static/src/xml/base.xml:0
msgid "Backup"
msgstr "Sikkerhedskopi"
#: addons/web/static/src/xml/base.xml:0
msgid "Restore"
msgstr "Gendan"
#: addons/web/static/src/xml/base.xml:0
msgid "Password"
msgstr "Adgangskode"
#: addons/web/static/src/xml/base.xml:0
msgid "Back to Login"
msgstr "Tilbage til log ind"
#: addons/web/static/src/xml/base.xml:0
msgid "CREATE DATABASE"
msgstr "OPRET DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "Master password:"
msgstr "Hovedadgangskode"
#: addons/web/static/src/xml/base.xml:0
msgid "New database name:"
msgstr "Nyt database navn:"
#: addons/web/static/src/xml/base.xml:0
msgid "Load Demonstration data:"
msgstr "Indlæs demonstrations data:"
#: addons/web/static/src/xml/base.xml:0
msgid "Default language:"
msgstr "Standardsprog:"
#: addons/web/static/src/xml/base.xml:0
msgid "Admin password:"
msgstr "Administrators adgangskode:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm password:"
msgstr "Bekræft adgangskode:"
#: addons/web/static/src/xml/base.xml:0
msgid "DROP DATABASE"
msgstr "SLET DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "Database:"
msgstr "Database:"
#: addons/web/static/src/xml/base.xml:0
msgid "Master Password:"
msgstr "Hovedadgangskode"
#: addons/web/static/src/xml/base.xml:0
msgid "BACKUP DATABASE"
msgstr "SIKKERHEDSKOPIER DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "RESTORE DATABASE"
msgstr "GENDAN DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "File:"
msgstr "Fil:"
#: addons/web/static/src/xml/base.xml:0
msgid "CHANGE MASTER PASSWORD"
msgstr "Skift hovedadgangskode"
#: addons/web/static/src/xml/base.xml:0
msgid "New master password:"
msgstr "Ny hovedadgangskode"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm new master password:"
msgstr "Bekræft ny hovedadgangskode"
#: addons/web/static/src/xml/base.xml:0
msgid "User:"
msgstr "Bruger:"
#: addons/web/static/src/xml/base.xml:0
msgid "Password:"
msgstr "Adgangskode:"
#: addons/web/static/src/xml/base.xml:0
msgid "Database"
msgstr "Database"
#: addons/web/static/src/xml/base.xml:0
msgid "Login"
msgstr "Log ind"
#: addons/web/static/src/xml/base.xml:0
msgid "Bad username or password"
msgstr "Forkert brugernavn eller adgangskode"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"We think that daily job activities can be more intuitive, efficient, "
"automated, .. and even fun."
msgstr ""
"Vi tror at daglige arbejdsaktiviteter kan blive mere intuitive, effektive og "
"automatiserede, .. and even fun."
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP's vision to be:"
msgstr "OpenERP´s vision at være:"
#: addons/web/static/src/xml/base.xml:0
msgid "Full featured"
msgstr "Fuldt udbygget"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Today's enterprise challenges are multiple. We provide one module for each "
"need."
msgstr ""
"Udfordringer det stilles til nutidens virksomheder er blevet store. Vi "
"leverer moduler til et hvert behov."
#: addons/web/static/src/xml/base.xml:0
msgid "Open Source"
msgstr "Open source"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"To Build a great product, we rely on the knowledge of thousands of "
"contributors."
msgstr ""
"For at bygge et godt produkt, stoler vi på viden fra tusindevis af "
"bidragydere."
#: addons/web/static/src/xml/base.xml:0
msgid "User Friendly"
msgstr "Brugervenlig"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"In order to be productive, people need clean and easy to use interface."
msgstr "For at være produktiv kræves et nemt og brugervenligt interface."
#: addons/web/static/src/xml/base.xml:0
msgid "("
msgstr "("
#: addons/web/static/src/xml/base.xml:0
msgid ")"
msgstr ")"
#: addons/web/static/src/xml/base.xml:0
msgid "LOGOUT"
msgstr "LOG UD"
#: addons/web/static/src/xml/base.xml:0
msgid "&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 ""
#: 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
addons/web/po/de.po Normal file
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-10-11 05:42+0000\n"
"X-Generator: Launchpad (build 14123)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
"Warning, the record has been modified, your changes will be discarded."
msgstr ""
"Achtung der Datensatz wurde bearbeitet, alle Änderungen werden verworfen!"
#: addons/web/static/src/js/view_form.js:1659
msgid "<em>   Search More...</em>"
msgstr "<em>   Suche mehr...</em>"
#: addons/web/static/src/js/view_form.js:1672
#, python-format
msgid "<em>   Create \"<strong>%s</strong>\"</em>"
msgstr "<em>   Anlegen \"<strong>%s</strong>\"</em>"
#: addons/web/static/src/js/view_form.js:1678
msgid "<em>   Create and Edit...</em>"
msgstr "<em>   Anlegen und Bearbeiten...</em>"
#: addons/web/static/src/js/views.js:568
msgid "You must choose at least one record."
msgstr "Sie müssen mindestens einen Datensatz auswählen"
#: addons/web/static/src/js/views.js:569
msgid "Warning"
msgstr "Warnung!"
#: addons/web/static/src/js/views.js:609
msgid "Translations"
msgstr "Übersetzungen"
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
msgid "Save"
msgstr "Speichern"
#: addons/web/static/src/js/views.js:615
msgid "Close"
msgstr "Schließen"
#: addons/web/static/src/xml/base.xml:0
msgid "x"
msgstr "x"
#: addons/web/static/src/xml/base.xml:0
msgid "#{title}"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "#{text}"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Powered by"
msgstr "unterstützt durch"
#: addons/web/static/src/xml/base.xml:0
msgid "openerp.com"
msgstr "openerp.com"
#: addons/web/static/src/xml/base.xml:0
msgid "."
msgstr "."
#: addons/web/static/src/xml/base.xml:0
msgid "Loading..."
msgstr "Lade..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create"
msgstr "Erzeugen"
#: addons/web/static/src/xml/base.xml:0
msgid "Drop"
msgstr "Löschen"
#: addons/web/static/src/xml/base.xml:0
msgid "Backup"
msgstr "Sichern"
#: addons/web/static/src/xml/base.xml:0
msgid "Restore"
msgstr "Wiederherstellen"
#: addons/web/static/src/xml/base.xml:0
msgid "Password"
msgstr "Passwort"
#: addons/web/static/src/xml/base.xml:0
msgid "Back to Login"
msgstr "Zurück zur Anmeldung"
#: addons/web/static/src/xml/base.xml:0
msgid "CREATE DATABASE"
msgstr "Datenbank anlegen"
#: addons/web/static/src/xml/base.xml:0
msgid "Master password:"
msgstr "Master Passwort"
#: addons/web/static/src/xml/base.xml:0
msgid "New database name:"
msgstr "Name der neuen Datenbank:"
#: addons/web/static/src/xml/base.xml:0
msgid "Load Demonstration data:"
msgstr "Beispieldaten laden:"
#: addons/web/static/src/xml/base.xml:0
msgid "Default language:"
msgstr "Standardsprache:"
#: addons/web/static/src/xml/base.xml:0
msgid "Admin password:"
msgstr "Admin Passwort"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm password:"
msgstr "Passwort wiederholen:"
#: addons/web/static/src/xml/base.xml:0
msgid "DROP DATABASE"
msgstr "Datenbank löschen"
#: addons/web/static/src/xml/base.xml:0
msgid "Database:"
msgstr "Datenbank:"
#: addons/web/static/src/xml/base.xml:0
msgid "Master Password:"
msgstr "Master Passwort"
#: addons/web/static/src/xml/base.xml:0
msgid "BACKUP DATABASE"
msgstr "Datenbank sichern"
#: addons/web/static/src/xml/base.xml:0
msgid "RESTORE DATABASE"
msgstr "Datenbank wiederherstellen"
#: addons/web/static/src/xml/base.xml:0
msgid "File:"
msgstr "Datei:"
#: addons/web/static/src/xml/base.xml:0
msgid "CHANGE MASTER PASSWORD"
msgstr "Master Passwort ändern"
#: addons/web/static/src/xml/base.xml:0
msgid "New master password:"
msgstr "Neues Master Passwort:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm new master password:"
msgstr "Bestätigen Sie das neue Master Passwort:"
#: addons/web/static/src/xml/base.xml:0
msgid "User:"
msgstr "Benutzer:"
#: addons/web/static/src/xml/base.xml:0
msgid "Password:"
msgstr "Passwort:"
#: addons/web/static/src/xml/base.xml:0
msgid "Database"
msgstr "Datenbank"
#: addons/web/static/src/xml/base.xml:0
msgid "Login"
msgstr "Anmeldung"
#: addons/web/static/src/xml/base.xml:0
msgid "Bad username or password"
msgstr "Falscher Benutzername oder Passwort"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"We think that daily job activities can be more intuitive, efficient, "
"automated, .. and even fun."
msgstr ""
"Wir sind der Überzeugung, das die tägliche Arbeit intuitiver, effizienter, "
"automatisierter und mit mehr Spaß verbunden sein kann."
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP's vision to be:"
msgstr "OpenERP's Vision ist:"
#: addons/web/static/src/xml/base.xml:0
msgid "Full featured"
msgstr "vollständiges"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Today's enterprise challenges are multiple. We provide one module for each "
"need."
msgstr ""
"Die heutigen Unternehmensherausforderungen sind vielfältig. Wir bieten Ihnen "
"ein Modul für jede Anforderung."
#: addons/web/static/src/xml/base.xml:0
msgid "Open Source"
msgstr "Open Source"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"To Build a great product, we rely on the knowledge of thousands of "
"contributors."
msgstr ""
"Um ein grossartiges Produkt bereitzustellen, vertrauen wir auf das Wissen "
"von Tausenden von Unterstützern"
#: addons/web/static/src/xml/base.xml:0
msgid "User Friendly"
msgstr "Benutzerfreundlich"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"In order to be productive, people need clean and easy to use interface."
msgstr ""
"Um produktiv arbeiten zu können, benötigen die Mitarbeiter eine einfache und "
"klar strukturierte Oberfläche."
#: addons/web/static/src/xml/base.xml:0
msgid "("
msgstr "("
#: addons/web/static/src/xml/base.xml:0
msgid ")"
msgstr ")"
#: addons/web/static/src/xml/base.xml:0
msgid "LOGOUT"
msgstr "Abmeldung"
#: addons/web/static/src/xml/base.xml:0
msgid "&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
addons/web/po/es_EC.po Normal file
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-10-08 05:29+0000\n"
"X-Generator: Launchpad (build 14110)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
"Warning, the record has been modified, your changes will be discarded."
msgstr ""
"Aviso, el registro ha sido modificado, sus cambios serán descartados."
#: addons/web/static/src/js/view_form.js:1659
msgid "<em>   Search More...</em>"
msgstr "<em>   Buscar Más...</em>"
#: addons/web/static/src/js/view_form.js:1672
#, python-format
msgid "<em>   Create \"<strong>%s</strong>\"</em>"
msgstr "<em>   Crear \"<strong>%s</strong>\"</em>"
#: addons/web/static/src/js/view_form.js:1678
msgid "<em>   Create and Edit...</em>"
msgstr "<em>   Crear y Editar...</em>"
#: addons/web/static/src/js/views.js:568
msgid "You must choose at least one record."
msgstr "Debe seleccionar al menos un registro."
#: addons/web/static/src/js/views.js:569
msgid "Warning"
msgstr "Advertencia"
#: addons/web/static/src/js/views.js:609
msgid "Translations"
msgstr "Traducciones"
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
msgid "Save"
msgstr "Guardar"
#: addons/web/static/src/js/views.js:615
msgid "Close"
msgstr "Cerrar"
#: addons/web/static/src/xml/base.xml:0
msgid "x"
msgstr "x"
#: addons/web/static/src/xml/base.xml:0
msgid "#{title}"
msgstr "#{title}"
#: addons/web/static/src/xml/base.xml:0
msgid "#{text}"
msgstr "#{text}"
#: addons/web/static/src/xml/base.xml:0
msgid "Powered by"
msgstr "Powered by"
#: addons/web/static/src/xml/base.xml:0
msgid "openerp.com"
msgstr "openerp.com"
#: addons/web/static/src/xml/base.xml:0
msgid "."
msgstr "."
#: addons/web/static/src/xml/base.xml:0
msgid "Loading..."
msgstr "Cargando..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create"
msgstr "Crear"
#: addons/web/static/src/xml/base.xml:0
msgid "Drop"
msgstr "Borrar"
#: addons/web/static/src/xml/base.xml:0
msgid "Backup"
msgstr "Respaldar"
#: addons/web/static/src/xml/base.xml:0
msgid "Restore"
msgstr "Restaurar"
#: addons/web/static/src/xml/base.xml:0
msgid "Password"
msgstr "Contraseña"
#: addons/web/static/src/xml/base.xml:0
msgid "Back to Login"
msgstr "Regresar a inicio de sesión"
#: addons/web/static/src/xml/base.xml:0
msgid "CREATE DATABASE"
msgstr "CREATE DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "Master password:"
msgstr "Master password:"
#: addons/web/static/src/xml/base.xml:0
msgid "New database name:"
msgstr "Nuevo nombre de la base de datos:"
#: addons/web/static/src/xml/base.xml:0
msgid "Load Demonstration data:"
msgstr "Cargar datos de demostración"
#: addons/web/static/src/xml/base.xml:0
msgid "Default language:"
msgstr "Lenguaje por defecto:"
#: addons/web/static/src/xml/base.xml:0
msgid "Admin password:"
msgstr "Admin password:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm password:"
msgstr "Confirmar password:"
#: addons/web/static/src/xml/base.xml:0
msgid "DROP DATABASE"
msgstr "DROP DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "Database:"
msgstr "Base de datos:"
#: addons/web/static/src/xml/base.xml:0
msgid "Master Password:"
msgstr "Master Password:"
#: addons/web/static/src/xml/base.xml:0
msgid "BACKUP DATABASE"
msgstr "BACKUP DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "RESTORE DATABASE"
msgstr "RESTORE DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "File:"
msgstr "Archivo:"
#: addons/web/static/src/xml/base.xml:0
msgid "CHANGE MASTER PASSWORD"
msgstr "CHANGE MASTER PASSWORD"
#: addons/web/static/src/xml/base.xml:0
msgid "New master password:"
msgstr "New master password:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm new master password:"
msgstr "Confirmar nueva master password:"
#: addons/web/static/src/xml/base.xml:0
msgid "User:"
msgstr "Usuario:"
#: addons/web/static/src/xml/base.xml:0
msgid "Password:"
msgstr "Contraseña:"
#: addons/web/static/src/xml/base.xml:0
msgid "Database"
msgstr "Bases de datos"
#: addons/web/static/src/xml/base.xml:0
msgid "Login"
msgstr "Iniciar sesión"
#: addons/web/static/src/xml/base.xml:0
msgid "Bad username or password"
msgstr "Usuario o contraseña incorrectos"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"We think that daily job activities can be more intuitive, efficient, "
"automated, .. and even fun."
msgstr ""
"Pensamos que el trabajo diario debe ser mas intuitivo, eficiente, "
"automatizado, ... e incluso divertido."
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP's vision to be:"
msgstr "OpenERP's vision to be:"
#: addons/web/static/src/xml/base.xml:0
msgid "Full featured"
msgstr "Full featured"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Today's enterprise challenges are multiple. We provide one module for each "
"need."
msgstr ""
"Today's enterprise challenges are multiple. We provide one module for each "
"need."
#: addons/web/static/src/xml/base.xml:0
msgid "Open Source"
msgstr "Open Source"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"To Build a great product, we rely on the knowledge of thousands of "
"contributors."
msgstr ""
"To Build a great product, we rely on the knowledge of thousands of "
"contributors."
#: addons/web/static/src/xml/base.xml:0
msgid "User Friendly"
msgstr "User Friendly"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"In order to be productive, people need clean and easy to use interface."
msgstr ""
"Para ser productivo, los usuarios necesitan una interfaz limpia y fácil de "
"usar."
#: addons/web/static/src/xml/base.xml:0
msgid "("
msgstr "("
#: addons/web/static/src/xml/base.xml:0
msgid ")"
msgstr ")"
#: addons/web/static/src/xml/base.xml:0
msgid "LOGOUT"
msgstr "LOGOUT"
#: addons/web/static/src/xml/base.xml:0
msgid "&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
addons/web/po/et.po Normal file
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-10-11 05:42+0000\n"
"X-Generator: Launchpad (build 14123)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
"Warning, the record has been modified, your changes will be discarded."
msgstr ""
#: addons/web/static/src/js/view_form.js:1659
msgid "<em>   Search More...</em>"
msgstr ""
#: addons/web/static/src/js/view_form.js:1672
#, python-format
msgid "<em>   Create \"<strong>%s</strong>\"</em>"
msgstr ""
#: addons/web/static/src/js/view_form.js:1678
msgid "<em>   Create and Edit...</em>"
msgstr ""
#: addons/web/static/src/js/views.js:568
msgid "You must choose at least one record."
msgstr ""
#: addons/web/static/src/js/views.js:569
msgid "Warning"
msgstr "Hoiatus"
#: addons/web/static/src/js/views.js:609
msgid "Translations"
msgstr "Tõlked"
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
msgid "Save"
msgstr "Salvesta"
#: addons/web/static/src/js/views.js:615
msgid "Close"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "x"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "#{title}"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "#{text}"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Powered by"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "openerp.com"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Loading..."
msgstr "Laadimine..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create"
msgstr "Loo"
#: addons/web/static/src/xml/base.xml:0
msgid "Drop"
msgstr "Hülga"
#: addons/web/static/src/xml/base.xml:0
msgid "Backup"
msgstr "Varunda"
#: addons/web/static/src/xml/base.xml:0
msgid "Restore"
msgstr "Taasta"
#: addons/web/static/src/xml/base.xml:0
msgid "Password"
msgstr "Salasõna"
#: addons/web/static/src/xml/base.xml:0
msgid "Back to Login"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "CREATE DATABASE"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Master password:"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "New database name:"
msgstr "Uue andmebaasi nimi:"
#: addons/web/static/src/xml/base.xml:0
msgid "Load Demonstration data:"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Default language:"
msgstr "Vaikekeel:"
#: addons/web/static/src/xml/base.xml:0
msgid "Admin password:"
msgstr "Admin salasõna:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm password:"
msgstr "Salasõna uuesti:"
#: addons/web/static/src/xml/base.xml:0
msgid "DROP DATABASE"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Database:"
msgstr "Andmebaas:"
#: addons/web/static/src/xml/base.xml:0
msgid "Master Password:"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "BACKUP DATABASE"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "RESTORE DATABASE"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "File:"
msgstr "Fail:"
#: addons/web/static/src/xml/base.xml:0
msgid "CHANGE MASTER PASSWORD"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "New master password:"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm new master password:"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "User:"
msgstr "Kasutaja:"
#: addons/web/static/src/xml/base.xml:0
msgid "Password:"
msgstr "Salasõna:"
#: addons/web/static/src/xml/base.xml:0
msgid "Database"
msgstr "Andmebaas"
#: addons/web/static/src/xml/base.xml:0
msgid "Login"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Bad username or password"
msgstr "Vale kasutajanimi või salasõna"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"We think that daily job activities can be more intuitive, efficient, "
"automated, .. and even fun."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP's vision to be:"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Full featured"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Today's enterprise challenges are multiple. We provide one module for each "
"need."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Open Source"
msgstr "Avatud lähtekoodiga"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"To Build a great product, we rely on the knowledge of thousands of "
"contributors."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "User Friendly"
msgstr "Kasutajasõbralik"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"In order to be productive, people need clean and easy to use interface."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "("
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ")"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "LOGOUT"
msgstr "VÄLJU"
#: addons/web/static/src/xml/base.xml:0
msgid "&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 ""

689
addons/web/po/it.po Normal file
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-10-09 05:22+0000\n"
"X-Generator: Launchpad (build 14110)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
"Warning, the record has been modified, your changes will be discarded."
msgstr ""
"Attenzione, il record è stato modificato, i vostri cambiamenti verranno "
"scartati."
#: addons/web/static/src/js/view_form.js:1659
msgid "<em>   Search More...</em>"
msgstr "<em>   Cerca ancora...</em>"
#: addons/web/static/src/js/view_form.js:1672
#, python-format
msgid "<em>   Create \"<strong>%s</strong>\"</em>"
msgstr "<em>   Crea \"<strong>%s</strong>\"</em>"
#: addons/web/static/src/js/view_form.js:1678
msgid "<em>   Create and Edit...</em>"
msgstr "<em>   Crea e modifica...</em>"
#: addons/web/static/src/js/views.js:568
msgid "You must choose at least one record."
msgstr "E' necessario selezionare almeno un record."
#: addons/web/static/src/js/views.js:569
msgid "Warning"
msgstr "Attenzione"
#: addons/web/static/src/js/views.js:609
msgid "Translations"
msgstr "Traduzioni"
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
msgid "Save"
msgstr "Salva"
#: addons/web/static/src/js/views.js:615
msgid "Close"
msgstr "Chiudi"
#: addons/web/static/src/xml/base.xml:0
msgid "x"
msgstr "x"
#: addons/web/static/src/xml/base.xml:0
msgid "#{title}"
msgstr "#{title}"
#: addons/web/static/src/xml/base.xml:0
msgid "#{text}"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Powered by"
msgstr "Powered by"
#: addons/web/static/src/xml/base.xml:0
msgid "openerp.com"
msgstr "openerp.com"
#: addons/web/static/src/xml/base.xml:0
msgid "."
msgstr "."
#: addons/web/static/src/xml/base.xml:0
msgid "Loading..."
msgstr "Caricamento..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create"
msgstr "Crea"
#: addons/web/static/src/xml/base.xml:0
msgid "Drop"
msgstr "Elimina"
#: addons/web/static/src/xml/base.xml:0
msgid "Backup"
msgstr "Backup"
#: addons/web/static/src/xml/base.xml:0
msgid "Restore"
msgstr "Ripristina"
#: addons/web/static/src/xml/base.xml:0
msgid "Password"
msgstr "Password"
#: addons/web/static/src/xml/base.xml:0
msgid "Back to Login"
msgstr "Ritorno al Login"
#: addons/web/static/src/xml/base.xml:0
msgid "CREATE DATABASE"
msgstr "CREA DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "Master password:"
msgstr "Password principale"
#: addons/web/static/src/xml/base.xml:0
msgid "New database name:"
msgstr "Nome nuovo database:"
#: addons/web/static/src/xml/base.xml:0
msgid "Load Demonstration data:"
msgstr "Caricadati dimostrativi:"
#: addons/web/static/src/xml/base.xml:0
msgid "Default language:"
msgstr "Lingua predefinita:"
#: addons/web/static/src/xml/base.xml:0
msgid "Admin password:"
msgstr "Password di amministrazione:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm password:"
msgstr "Conferma password:"
#: addons/web/static/src/xml/base.xml:0
msgid "DROP DATABASE"
msgstr "ELIMINA DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "Database:"
msgstr "Database:"
#: addons/web/static/src/xml/base.xml:0
msgid "Master Password:"
msgstr "Password principale"
#: addons/web/static/src/xml/base.xml:0
msgid "BACKUP DATABASE"
msgstr "BACKUP DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "RESTORE DATABASE"
msgstr "RIPRISTINA DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "File:"
msgstr "File:"
#: addons/web/static/src/xml/base.xml:0
msgid "CHANGE MASTER PASSWORD"
msgstr "CAMBIA PASSWORD PRINCIPALE"
#: addons/web/static/src/xml/base.xml:0
msgid "New master password:"
msgstr "Nuova password principale:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm new master password:"
msgstr "Conferma nuova password principale"
#: addons/web/static/src/xml/base.xml:0
msgid "User:"
msgstr "Utente:"
#: addons/web/static/src/xml/base.xml:0
msgid "Password:"
msgstr "Password:"
#: addons/web/static/src/xml/base.xml:0
msgid "Database"
msgstr "Database"
#: addons/web/static/src/xml/base.xml:0
msgid "Login"
msgstr "Login"
#: addons/web/static/src/xml/base.xml:0
msgid "Bad username or password"
msgstr "Username o password errati"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"We think that daily job activities can be more intuitive, efficient, "
"automated, .. and even fun."
msgstr ""
"Pensiamo che le attività quotidiane possano essere più intuitive, "
"efficienti, automatizzate...e anche più divertenti."
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP's vision to be:"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Full featured"
msgstr "Completo"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Today's enterprise challenges are multiple. We provide one module for each "
"need."
msgstr ""
"Le esigenze odierne delle aziende sono molteplici. Noi forniamo un modulo "
"per ogni necessità."
#: addons/web/static/src/xml/base.xml:0
msgid "Open Source"
msgstr "Open Source"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"To Build a great product, we rely on the knowledge of thousands of "
"contributors."
msgstr ""
"Per creare un buon prodotto, facciamo affidamento sull'esperienza di "
"migliaia di contributori."
#: addons/web/static/src/xml/base.xml:0
msgid "User Friendly"
msgstr "User Friendly"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"In order to be productive, people need clean and easy to use interface."
msgstr ""
"Per essere produttive, le persone necessitano di interfacce semplici e "
"pulite."
#: addons/web/static/src/xml/base.xml:0
msgid "("
msgstr "("
#: addons/web/static/src/xml/base.xml:0
msgid ")"
msgstr ")"
#: addons/web/static/src/xml/base.xml:0
msgid "LOGOUT"
msgstr "LOGOUT"
#: addons/web/static/src/xml/base.xml:0
msgid "&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
addons/web/po/nl_BE.po Normal file
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-10-08 05:29+0000\n"
"X-Generator: Launchpad (build 14110)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
"Warning, the record has been modified, your changes will be discarded."
msgstr ""
"Opgelet, het record werd gewijzigd, uw veranderingen zullen niet opgeslagen "
"worden."
#: addons/web/static/src/js/view_form.js:1659
msgid "<em>   Search More...</em>"
msgstr "<em>   Uitgebreid zoeken...</em>"
#: addons/web/static/src/js/view_form.js:1672
#, python-format
msgid "<em>   Create \"<strong>%s</strong>\"</em>"
msgstr "<em>   Creër \"<strong>%s</strong>\"</em>"
#: addons/web/static/src/js/view_form.js:1678
msgid "<em>   Create and Edit...</em>"
msgstr "<em>   Creër en bewerk...</em>"
#: addons/web/static/src/js/views.js:568
msgid "You must choose at least one record."
msgstr "U moet minstens een record selecteren."
#: addons/web/static/src/js/views.js:569
msgid "Warning"
msgstr "Waarschuwing"
#: addons/web/static/src/js/views.js:609
msgid "Translations"
msgstr "Vertalingen"
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
msgid "Save"
msgstr "Opslaan"
#: addons/web/static/src/js/views.js:615
msgid "Close"
msgstr "Sluiten"
#: addons/web/static/src/xml/base.xml:0
msgid "x"
msgstr "x"
#: addons/web/static/src/xml/base.xml:0
msgid "#{title}"
msgstr "#{title}"
#: addons/web/static/src/xml/base.xml:0
msgid "#{text}"
msgstr "#{text}"
#: addons/web/static/src/xml/base.xml:0
msgid "Powered by"
msgstr "Mogelijk gemaakt door"
#: addons/web/static/src/xml/base.xml:0
msgid "openerp.com"
msgstr "openerp.com"
#: addons/web/static/src/xml/base.xml:0
msgid "."
msgstr "."
#: addons/web/static/src/xml/base.xml:0
msgid "Loading..."
msgstr "Laden..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create"
msgstr "Creër"
#: addons/web/static/src/xml/base.xml:0
msgid "Drop"
msgstr "Drop"
#: addons/web/static/src/xml/base.xml:0
msgid "Backup"
msgstr "Backup"
#: addons/web/static/src/xml/base.xml:0
msgid "Restore"
msgstr "Restore"
#: addons/web/static/src/xml/base.xml:0
msgid "Password"
msgstr "Wachtwoord"
#: addons/web/static/src/xml/base.xml:0
msgid "Back to Login"
msgstr "Terug naar aanmelding"
#: addons/web/static/src/xml/base.xml:0
msgid "CREATE DATABASE"
msgstr "CREATE DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "Master password:"
msgstr "Master wachtwoord:"
#: addons/web/static/src/xml/base.xml:0
msgid "New database name:"
msgstr "Nieuwe database naam:"
#: addons/web/static/src/xml/base.xml:0
msgid "Load Demonstration data:"
msgstr "Demonstratie data laden:"
#: addons/web/static/src/xml/base.xml:0
msgid "Default language:"
msgstr "Standaard taal:"
#: addons/web/static/src/xml/base.xml:0
msgid "Admin password:"
msgstr "Beheerder wachtwoord:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm password:"
msgstr "Bevestig wachtwoord:"
#: addons/web/static/src/xml/base.xml:0
msgid "DROP DATABASE"
msgstr "DROP DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "Database:"
msgstr "Database:"
#: addons/web/static/src/xml/base.xml:0
msgid "Master Password:"
msgstr "Master wachtwoord:"
#: addons/web/static/src/xml/base.xml:0
msgid "BACKUP DATABASE"
msgstr "BACKUP DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "RESTORE DATABASE"
msgstr "RESTORE DATABASE"
#: addons/web/static/src/xml/base.xml:0
msgid "File:"
msgstr "Bestand:"
#: addons/web/static/src/xml/base.xml:0
msgid "CHANGE MASTER PASSWORD"
msgstr "CHANGE MASTER PASSWORD"
#: addons/web/static/src/xml/base.xml:0
msgid "New master password:"
msgstr "Nieuw master wachtwoord:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm new master password:"
msgstr "Bevestig nieuw master wachtwoord:"
#: addons/web/static/src/xml/base.xml:0
msgid "User:"
msgstr "Gebruiker:"
#: addons/web/static/src/xml/base.xml:0
msgid "Password:"
msgstr "Wachtwoord:"
#: addons/web/static/src/xml/base.xml:0
msgid "Database"
msgstr "Database"
#: addons/web/static/src/xml/base.xml:0
msgid "Login"
msgstr "Login"
#: addons/web/static/src/xml/base.xml:0
msgid "Bad username or password"
msgstr "Verkeerde gebruikersnaam of wachtwoord"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"We think that daily job activities can be more intuitive, efficient, "
"automated, .. and even fun."
msgstr ""
"Wij geloven dat je dagelijkse werk intuitiver, efficienter, geautomatiseerd "
"en leuker kan zijn."
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP's vision to be:"
msgstr "OpenERP's visie is:"
#: addons/web/static/src/xml/base.xml:0
msgid "Full featured"
msgstr "Volledig uitgerust"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Today's enterprise challenges are multiple. We provide one module for each "
"need."
msgstr ""
"Hedendaagse uitdaging voor bedrijven zijn alom. Wij voorzien een module voor "
"elke uitdaging."
#: addons/web/static/src/xml/base.xml:0
msgid "Open Source"
msgstr "Open Source"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"To Build a great product, we rely on the knowledge of thousands of "
"contributors."
msgstr ""
"Om een geweldig product te maken vertrouwen we op de kennis van duizenden "
"mensen."
#: addons/web/static/src/xml/base.xml:0
msgid "User Friendly"
msgstr "Gebruiksvriendelijk"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"In order to be productive, people need clean and easy to use interface."
msgstr ""
"Om productief te kunnen zijn hebben mensen een mooie en gemakkelijke "
"interface nodig."
#: addons/web/static/src/xml/base.xml:0
msgid "("
msgstr "("
#: addons/web/static/src/xml/base.xml:0
msgid ")"
msgstr ")"
#: addons/web/static/src/xml/base.xml:0
msgid "LOGOUT"
msgstr "LOGOUT"
#: addons/web/static/src/xml/base.xml:0
msgid "&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."

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 ""

View File

@ -300,7 +300,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 +325,7 @@ label.error {
background: #5A5858;
vertical-align: top;
height: 100%;
display: block;
position: relative;
}
.openerp .secondary_menu.oe_folded {
@ -721,11 +722,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 +772,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
@ -828,6 +837,9 @@ label.error {
}
/* Form */
.openerp .oe_frame.oe_forms {
clear: both;
}
.openerp table.oe_frame td {
color: #4c4c4c;
}
@ -855,7 +867,7 @@ label.error {
cursor: help;
}
.openerp .oe_form_field label.oe_label, .openerp .oe_form_field label.oe_label_help {
.openerp .oe_forms label.oe_label, .openerp .oe_forms label.oe_label_help {
text-align: right;
margin: 3px 0 0 10px;
}
@ -943,7 +955,7 @@ label.error {
position: relative;
}
.openerp input.oe-binary-file {
z-index: 2;
z-index: 0;
line-height: 0;
font-size: 50px;
position: absolute;

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

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
@ -28,9 +29,12 @@ openerp.web.Notification = openerp.web.Widget.extend(/** @lends openerp.web.Not
warn: function(title, text) {
this.$element.notify('create', 'oe_notification_alert', {
title: title,
text: text
text: text,
}, {
expires: false,
});
}
},
});
openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog# */{
@ -369,7 +373,7 @@ 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.do_notify("Dropping database", "The database '" + db + "' has been dropped");
});
}
});
@ -454,7 +458,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 +466,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,13 +484,22 @@ 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;
@ -537,7 +550,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 +792,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 +835,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 +880,7 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{
$sub_menu.hide();
return true;
}
return manual;
} else {
return true;
}
@ -927,14 +942,12 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
}
this.$element.html(QWeb.render("Interface", params));
this.notification = new openerp.web.Notification();
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.header = new openerp.web.Header(this);
this.login = new openerp.web.Login(this);
this.header.on_logout.add(this.login.on_logout);
@ -954,12 +967,27 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
},
start: function() {
this._super.apply(this, arguments);
this.notification.prependTo(this.$element);
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 +1074,8 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
this.action_manager.do_action(action);
},
do_about: function() {
}
},
});
};

View File

@ -287,14 +287,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(','));
},
@ -480,7 +478,7 @@ 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;

View File

@ -610,40 +610,120 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
on_default_get: function(res) {
this.last_default_get = res;
},
/**
* Makes sure this dataset has the fields_get for its model stored locally,
* so create/write methods are able to determine if written fields are m2os
* and can name_get those fields if that's the case (in order to cache a
* correct m2o value for them)
*
* @returns {$.Deferred} whether the fields_get is done executing, provides the fields_get value to its callbacks
*/
ensure_has_fields: function () {
var self = this;
if (this.fields_get) {
var d = $.Deferred();
setTimeout(function () { d.resolve(self.fields_get, true); }, 0);
return d.promise();
} else {
return self.call('fields_get', [], function (fields_get) {
self.fields_get = fields_get;
});
}
},
/**
* Relational fields may not be written in the same format they are read.
*
* Since the BufferedDataSet is a bit dumb, it returns what it's got stored
* in its cache, which for modified value is what it was given. This breaks
* some basic contracts of openerp such as m2o read being in the
* ``name_get`` format.
*
* Because create & write are supposed to be asynchronous, though, it
* should be easy to just name_get all incorrect values.
*
* @param {Object} data form-data to write to the cache
* @returns {$.Deferred} resolved with a fixed data dictionary
*/
fix_relational: function (data) {
var self = this;
var results = $.Deferred();
this.ensure_has_fields().then(function (fields) {
var fields_to_fix = _(fields).chain()
.map(function (d, k) { return {key: k, descriptor: d}; })
.filter(function (field) {
// keep m2o fields which are in the data dict
return field.descriptor.type === 'many2one' &&
data[field.key];
}).pluck('key')
.value();
var name_gets = _(fields_to_fix).map(function (field) {
return new openerp.web.DataSet(self, self.fields_get[field].relation)
.name_get([data[field]], null);
});
// null-concat forces stupid bastard `when` to always return an
// array containing the Array-ified results of all the name_gets.
// otherwise, if there's a single field to fix it returns the
// results of the unique name_get directly.
$.when.apply(null, name_gets.concat([null])).then(function () {
var record = _.extend({}, data);
for(var i=0; i<fields_to_fix.length; ++i) {
// Each argument is [[name_get], success, jqXhr] and we
// want just the name_get pair
record[fields_to_fix[i]] = arguments[i][0][0];
}
results.resolve(record);
});
});
return results;
},
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.cache.push(cached);
this.on_change();
var self = this;
var prom = $.Deferred().then(callback);
setTimeout(function() {prom.resolve({result: cached.id});}, 0);
this.fix_relational(data).then(function (fixed_m2o_data) {
var cached = {
id:_.uniqueId(self.virtual_id_prefix),
values: fixed_m2o_data,
defaults: self.last_default_get
};
self.to_create.push(_.extend(_.clone(cached), {
values: _.clone(data)}));
self.cache.push(cached);
self.on_change();
prom.resolve({result: cached.id});
});
return prom.promise();
},
write: function (id, data, options, callback) {
var self = this;
var record = _.detect(this.to_create, function(x) {return x.id === id;});
record = record || _.detect(this.to_write, function(x) {return x.id === id;});
var dirty = false;
if (record) {
for (var k in data) {
if (record.values[k] === undefined || record.values[k] !== data[k]) {
dirty = true;
break;
}
}
$.extend(record.values, data);
} else {
dirty = true;
record = {id: id, values: data};
self.to_write.push(record);
}
var cached = _.detect(this.cache, function(x) {return x.id === id;});
$.extend(cached.values, record.values);
if (dirty)
this.on_change();
var to_return = $.Deferred().then(callback);
to_return.resolve({result: true});
this.fix_relational(data).then(function (fixed_m2o_data) {
var record = _.detect(self.to_create, function(x) {return x.id === id;});
record = record || _.detect(self.to_write, function(x) {return x.id === id;});
var dirty = false;
if (record) {
for (var k in data) {
if (record.values[k] === undefined || record.values[k] !== data[k]) {
dirty = true;
break;
}
}
_.extend(record.values, data);
} else {
dirty = true;
record = {id: id, values: data};
self.to_write.push(record);
}
var cached = _.detect(self.cache, function(x) {return x.id === id;});
if (!cached) {
cached = {id: id, values: {}};
this.cache.push(cached);
}
_.extend(cached.values, fixed_m2o_data);
if (dirty)
self.on_change();
to_return.resolve({result: true});
});
return to_return.promise();
},
unlink: function(ids, callback, error_callback) {
@ -695,7 +775,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 +800,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();

View File

@ -69,6 +69,13 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
} catch (e) {
return value.format("%H:%M:%S");
}
case 'selection':
// Each choice is [value, label]
var result = _(descriptor.selection).detect(function (choice) {
return choice[0] === value;
});
if (result) { return result[1]; }
return;
default:
return value;
}
@ -179,9 +186,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 [

View File

@ -13,24 +13,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 () {
@ -105,8 +116,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;
@ -137,10 +149,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');
@ -246,10 +255,13 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
* @param e jQuery event object coming from the "Search" button
*/
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 +336,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("Invalid Search", "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){
@ -748,9 +760,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# */{

View File

@ -32,241 +32,247 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
this.xml_id = 0;
this.property = openerp.web.ViewEditor.property_widget;
},
start: function() {
this.View_editor();
},
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,
views_switcher: false,
action_buttons:false,
search_view:false,
pager:false,
radio:true
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,
views_switcher: false,
action_buttons:false,
search_view:false,
pager:false,
radio:true
},
};
var action_manager = new openerp.web.ActionManager(this);
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(){
$(this).dialog('destroy');
}
},
};
var action_manager = new openerp.web.ActionManager(this);
this.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(){
$(this).dialog('destroy');
}
});
this.view_edit_dialog.start();
this.view_edit_dialog.open();
action_manager.appendTo(this.view_edit_dialog);
action_manager.do_action(action);
},
});
this.dialog.start();
this.dialog.open();
action_manager.appendTo(this.dialog);
action_manager.do_action(action);
},
check_attr:function(xml,tag,level){
check_attr: function(xml, tag, level) {
var obj = new Object();
obj.child_id = [];
obj.id = this.xml_id++;
obj.level = level;
var vidhin = xml;
var att_list = [];
obj.level = level+1;
var render_name = "<" + tag;
var xml_tag = "<" + tag;
obj.att_list = [];
obj.att_list.push(tag);
$(xml).each(function() {
att_list = this.attributes;
att_list = _.select(att_list, function(attrs){
xml_tag += ' ' +attrs.nodeName+'='+'"'+attrs.nodeValue+'"';
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+'"';}
}
_.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 + '"';
}
if (attrs.nodeName != "position") {
obj.att_list.push( [attrs.nodeName,attrs.nodeValue] );
}
});
render_name+= ">";
});
render_name+= ">";
xml_tag+= ">";
});
obj.main_xml = xml;
obj.name = render_name;
return obj;
},
save_object : function(val,parent_list,child_obj_list){
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(key,val) {
if(val.id==check_id){
if(p_list.length!=0){
self.save_object(val,p_list,child_obj_list);
}else{
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;
return false;
}
}
});
}else{
} else {
val.child_id = child_obj_list;
}
},
children_function : function(xml,root,parent_list,parent_id,main_object,parent_child_id){
xml_node_create: function(xml, root, parent_list, parent_id, main_object){
var self = this;
var child_obj_list = [];
var parent_child_id = parent_child_id;
var parent_list = parent_list;
var main_object = main_object;
var children_list = $(xml).filter(root).children();
var parents = $(children_list[0]).parents().get();
_.each(children_list, function(child_node){
var string = self.check_attr(child_node,child_node.tagName.toLowerCase(),parents.length);
child_obj_list.push(string);
_.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){
var child_ids = _.map(child_obj_list ,function(num){return num.id;});
parent_child_id.push({'key': parent_id, 'value': child_ids});
var parents = $(children_list[0]).parents().get();
if(parents.length <= parent_list.length){
parent_list.splice(parents.length-1);
if (children_list.length != 0) {
if (parents.length <= parent_list.length) {
parent_list.splice(parents.length - 1);
}
parent_list.push(parent_id);
$.each(main_object, function(key,val) {
self.save_object(val,parent_list.slice(1),child_obj_list);
});
self.save_object(main_object[0], parent_list.slice(1), child_obj_list);
}
for(var i=0;i<children_list.length;i++){
self.children_function
(children_list[i],children_list[i].tagName.toLowerCase(),
parent_list,child_obj_list[i].id,main_object,parent_child_id);
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":main_object,"parent_child_id":parent_child_id};
return main_object;
},
parse_xml :function(arch,view_id){
var self = this;
parse_xml: function(arch, view_id) {
var root = $(arch).filter(":first")[0];
var tag = root.tagName.toLowerCase();
var root_object = self.check_attr(root,tag,this.xml_id);
return self.children_function(arch,tag,[],this.xml_id-1,[root_object],[]);
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(){
get_data: function() {
var self = this;
var view_id =(($("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(view_id)],['arch'],function (arch){
var 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(view_id)], ['arch'], function (arch) {
one_object = self.parse_xml(arch[0].arch,view_id);
one_object.arch = arch[0].arch;
dataset = new openerp.web.DataSetSearch(self,'ir.ui.view', null, null);
dataset.read_slice([],{domain : [['inherit_id','=',parseInt(view_id)]]},function (result) {
_.each(result,function(res){
self.inherit_view(one_object,res);
dataset = new openerp.web.DataSetSearch(self, 'ir.ui.view', null, null);
dataset.read_slice([], {domain : [['inherit_id','=', parseInt(view_id)]]}, function (result) {
_.each(result, function(res) {
self.inherit_view(one_object, res);
});
return self.edit_view(one_object);
return self.edit_view({"main_object": one_object,
"parent_child_id": self.parent_child_list(one_object, [])});
});
});
},
inherit_view : function(one_object,result){
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 xpath_list = [];
var part_expr = [];
var position ;
if(root[0].tagName.toLowerCase() == "data"){
_.each($(root).find('xpath'),function(xpath){
xpath_list.push(xpath);
});
} else if(root[0].tagName.toLowerCase() == "xpath"){
xpath_list.push(root[0]);
var xml_list = [];
if (root[0].tagName.toLowerCase() == "data") {
xml_list = $(root[0]).children();
} else {
xml_list.push(root[0]);
}
_.each(xpath_list,function(element){
var xpath_object = self.parse_xml(element,result.id);
var expr = $(element).attr('expr');
var position = $(element).attr('position');
part_expr = expr.split("/");
if(part_expr[0]=="" && part_expr[1]==""){
part_expr = part_expr.splice(2);
}else if(part_expr[0]==""){
part_expr = part_expr.splice(1);
}
if(part_expr[part_expr.length-1].search("@")!=-1){
var part = part_expr[part_expr.length-1];
var xpath_list = $.trim(part.replace(/[^a-zA-Z 0-9 _]+/g,' ')).split(" ");
one_object['parent_child_id'].push(xpath_object['parent_child_id'][0]);
$.each(one_object['main_object'], function(key,val) {
var id = self.search_object(val,xpath_list,[],position,xpath_object['main_object'],[]);
_.detect(one_object['parent_child_id'],function(res){
if(res.key==id){
res.value.push(xpath_object['main_object'][0].id);
}
});
_.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 {
check_list = [_.flatten(xpath_object[0].child_id[0].att_list)];
}
self.full_path_search(check_list ,one_object ,xpath_object);
});
},
search_object:function(val,list,p_list,position,xpath_object,r_list){
full_path_search: function(check_list ,val ,xpath_object) {
var self = this;
var return_list = r_list;
var main_list = $.trim(val.name.replace(/[^a-zA-Z 0-9 _]+/g,' ')).split(" ");
var insert = _.intersection(main_list,list);
var check = _.indexOf(p_list.child_id,xpath_object[0]);
if(check == -1){
if(insert.length == list.length){
var level = val.level;
$.each(xpath_object, function(key,val) {
self.increase_level(val,level)
});
var index = _.indexOf(p_list.child_id,val);
if(position == "before"){
if(index!=0){index--;}
}else if(position == "after"){
index++;
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 != 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;
}
p_list.child_id.splice(index,0,xpath_object[0]);
return_list.push(p_list.id);
}else{
if(val.child_id.length!=0){p_list = val;}
$.each(val.child_id, function(key,val) {
self.search_object(val,list,p_list,position,xpath_object,return_list);
}
else {
_.each(val,function(element){
self.full_path_search(check_list ,element.child_id ,xpath_object);
});
}
}
return return_list;
},
increase_level :function(val,level){
increase_level: function(val, level) {
var self = this;
val.level = level;
$.each(val.child_id, function(key,val) {
self.increase_level(val,level+1);
_.each(val.child_id, function(val, key) {
self.increase_level(val, level + 1);
});
},
edit_view : function(one_object){
edit_view: function(one_object) {
var self = this;
this.dialog = new openerp.web.Dialog(this,{
this.edit_xml_dialog = new openerp.web.Dialog(this,{
modal: true,
title: 'Edit Xml',
width: 750,
@ -283,135 +289,134 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
}
}
});
this.dialog.start().open();
this.dialog.$element.html(QWeb.render('view_editor', {
'data': one_object['main_object'],
}));
$("tr[id^='viewedit-']").click(function() {
$("tr[id^='viewedit-']").removeClass('ui-selected');
$(this).addClass('ui-selected');
});
$("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']);
}
});
$("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 = side.attr('level');
var list_shift =[];
var last_tr;
var cur_tr = side;
list_shift.push(side);
var next_tr;
switch (this.id)
{
case "side-add":
break;
case "side-remove":
break;
case "side-edit":
var tag, fld_name;
var tr = $(this).closest("tr[id^='viewedit-']").find('a').text();
var tag_fld = tr.split(" ");
if (tag_fld.length > 3){
tag = tag_fld[1].replace(/[^a-zA-Z 0-9]+/g,'');
fld_name = tag_fld[2].split("=")[1].replace(/[^a-zA-Z _ 0-9]+/g,'');
}else{
tag = tag_fld[1].replace(/[^a-zA-Z 0-9]+/g,'');
}
var properties = _PROPERTIES[tag];
self.on_edit_node(properties,fld_name);
break;
case "side-up":
while(1){
var prev_tr = cur_tr.prev();
if(level >= prev_tr.attr('level') || prev_tr.length==0){
last_tr = prev_tr;
break;
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() {
$("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 = side.attr('level');
var list_shift =[];
var last_tr;
var cur_tr = side;
list_shift.push(side);
var next_tr;
switch (this.id) {
case "side-add":
break;
case "side-remove":
break;
case "side-edit":
var tag, fld_name;
var tr = $(this).closest("tr[id^='viewedit-']").find('a').text();
var tag_fld = tr.split(" ");
if (tag_fld.length > 3){
tag = tag_fld[1].replace(/[^a-zA-Z 0-9]+/g,'');
fld_name = tag_fld[2].split("=")[1].replace(/[^a-zA-Z _ 0-9]+/g,'');
}else{
tag = tag_fld[1].replace(/[^a-zA-Z 0-9]+/g,'');
}
cur_tr = prev_tr;
}
if(img){
while(1){
next_tr = side.next();
if(next_tr.attr('level') <= level || next_tr.length==0){
break;
}else{
list_shift.push(next_tr);
side = next_tr;
var properties = _PROPERTIES[tag];
self.on_edit_node(properties,fld_name);
break;
case "side-up":
while (1) {
var prev_tr = cur_tr.prev();
if(level >= 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 (next_tr.attr('level') <= level || next_tr.length == 0) {
break;
} else {
list_shift.push(next_tr);
side = next_tr;
}
}
}
if (last_tr.length != 0 && last_tr.attr('level') == level) {
_.each(list_shift, function(rec) {
$(last_tr).before(rec);
});
}
break;
case "side-down":
if (img) {
while (1) {
next_tr = cur_tr.next();
if (next_tr.attr('level') <= level || next_tr.length == 0) {
last_tr = next_tr;
break;
} else {
list_shift.push(next_tr);
cur_tr = next_tr;
}
}
}
if(last_tr.length!=0 && last_tr.attr('level') == level){
_.each(list_shift,function(rec){
$(last_tr).before(rec);
else {
last_tr = cur_tr.next();
}
if (last_tr.length != 0 && 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) {
this.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);
});
}
break;
case "side-down":
if(img){
while(1){
next_tr = cur_tr.next();
if(next_tr.attr('level') <= level || next_tr.length==0){
last_tr = next_tr;
break;
}else{
list_shift.push(next_tr);
cur_tr = next_tr;
}
}
break;
}
else{
last_tr = cur_tr.next();
}
if(last_tr.length != 0 && 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){
$("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);
});
}
break;
}
});
});
},
on_expand: function(self){
var level = $(self).closest("tr[id^='viewedit-']").attr('level');
var cur_tr = $(self).closest("tr[id^='viewedit-']");
while (1){
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 (nxt_tr.attr('level') > level){
if (parseInt(nxt_tr.attr('level')) > level){
cur_tr = nxt_tr;
nxt_tr.hide();
}else return nxt_tr;
} else return nxt_tr;
}
},
on_collapse: function(self,parent_child_id,id,main_object){
var id = self.id.split('-')[1];
var datas = _.detect(parent_child_id,function(res){
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 = $("tr[id='viewedit-"+rec+"']");
_.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();
});

View File

@ -11,6 +11,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
*/
searchable: false,
form_template: "FormView",
identifier_prefix: 'formview-',
/**
* @constructs openerp.web.FormView
* @extends openerp.web.View
@ -32,7 +33,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.widgets_counter = 0;
this.fields = {};
this.datarecord = {};
this.ready = false;
this.show_invalid = true;
this.dirty_for_user = false;
this.default_focus_field = null;
@ -43,6 +43,10 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.translatable_fields = [];
_.defaults(this.options, {"always_show_new_button": true,
"not_interactible_on_create": false});
this.mutating_lock = $.Deferred();
this.initial_mutating_lock = this.mutating_lock;
this.on_change_lock = $.Deferred().resolve();
this.reload_lock = $.Deferred().resolve();
},
start: function() {
this._super();
@ -118,7 +122,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
this.sidebar.start();
this.sidebar.do_unfold();
this.sidebar.attachments = new openerp.web.form.SidebarAttachments(this.sidebar, this.sidebar.add_section('attachments', "Attachments"), this);
this.sidebar.attachments = new openerp.web.form.SidebarAttachments(this.sidebar, this);
this.sidebar.add_toolbar(this.fields_view.toolbar);
this.set_common_sidebar_sections(this.sidebar);
}
@ -179,7 +183,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
}
this.on_form_changed();
this.show_invalid = this.ready = true;
this.initial_mutating_lock.resolve();
this.show_invalid = true;
this.do_update_pager(record.id == null);
if (this.sidebar) {
this.sidebar.attachments.do_update();
@ -222,69 +227,78 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
$pager.find('span.oe_pager_count').html(this.dataset.ids.length);
},
do_onchange: function(widget, processed) {
processed = processed || [];
if (widget.node.attrs.on_change) {
var self = this;
this.ready = false;
var onchange = _.trim(widget.node.attrs.on_change);
var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/);
if (call) {
var method = call[1], args = [];
var context_index = null;
var argument_replacement = {
'False' : function() {return false;},
'True' : function() {return true;},
'None' : function() {return null;},
'context': function(i) {
context_index = i;
var ctx = widget.build_context ? widget.build_context() : {};
return ctx;
}
};
var parent_fields = null;
_.each(call[2].split(','), function(a, i) {
var field = _.trim(a);
if (field in argument_replacement) {
args.push(argument_replacement[field](i));
return;
} else if (self.fields[field]) {
var value = self.fields[field].get_on_change_value();
args.push(value == null ? false : value);
return;
} else {
var splitted = field.split('.');
if (splitted.length > 1 && _.trim(splitted[0]) === "parent" && self.dataset.parent_view) {
if (parent_fields === null) {
parent_fields = self.dataset.parent_view.get_fields_values();
}
var p_val = parent_fields[_.trim(splitted[1])];
if (p_val !== undefined) {
args.push(p_val == null ? false : p_val);
return;
var self = this;
var act = function() {
try {
processed = processed || [];
if (widget.node.attrs.on_change) {
var onchange = _.trim(widget.node.attrs.on_change);
var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/);
if (call) {
var method = call[1], args = [];
var context_index = null;
var argument_replacement = {
'False' : function() {return false;},
'True' : function() {return true;},
'None' : function() {return null;},
'context': function(i) {
context_index = i;
var ctx = widget.build_context ? widget.build_context() : {};
return ctx;
}
};
var parent_fields = null;
_.each(call[2].split(','), function(a, i) {
var field = _.trim(a);
if (field in argument_replacement) {
args.push(argument_replacement[field](i));
return;
} else if (self.fields[field]) {
var value = self.fields[field].get_on_change_value();
args.push(value == null ? false : value);
return;
} else {
var splitted = field.split('.');
if (splitted.length > 1 && _.trim(splitted[0]) === "parent" && self.dataset.parent_view) {
if (parent_fields === null) {
parent_fields = self.dataset.parent_view.get_fields_values();
}
var p_val = parent_fields[_.trim(splitted[1])];
if (p_val !== undefined) {
args.push(p_val == null ? false : p_val);
return;
}
}
}
}
throw "Could not get field with name '" + field +
"' for onchange '" + onchange + "'";
});
var ajax = {
url: '/web/dataset/call',
async: false
};
return this.rpc(ajax, {
model: this.dataset.model,
method: method,
args: [(this.datarecord.id == null ? [] : [this.datarecord.id])].concat(args),
context_id: context_index === null ? null : context_index + 1
}, function(response) {
self.on_processed_onchange(response, processed);
});
} else {
console.log("Wrong on_change format", on_change);
throw "Could not get field with name '" + field +
"' for onchange '" + onchange + "'";
});
var ajax = {
url: '/web/dataset/call',
async: false
};
return self.rpc(ajax, {
model: self.dataset.model,
method: method,
args: [(self.datarecord.id == null ? [] : [self.datarecord.id])].concat(args),
context_id: context_index === null ? null : context_index + 1
}).pipe(function(response) {
return self.on_processed_onchange(response, processed);
});
} else {
console.log("Wrong on_change format", on_change);
}
}
}
} catch(e) {
console.error(e);
return $.Deferred().reject();
}
};
this.on_change_lock = this.on_change_lock.pipe(act, act);
return this.on_change_lock;
},
on_processed_onchange: function(response, processed) {
try {
var result = response;
if (result.value) {
for (var f in result.value) {
@ -317,7 +331,11 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
if (result.domain) {
// TODO:
}
this.ready = true;
return $.Deferred().resolve();
} catch(e) {
console.error(e);
return $.Deferred().reject();
}
},
on_button_new: function() {
var self = this;
@ -364,42 +382,50 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
*/
do_save: function(success, prepend_on_create) {
var self = this;
if (!this.ready) {
return $.Deferred().reject();
}
var form_dirty = false,
form_invalid = false,
values = {},
first_invalid_field = null;
for (var f in this.fields) {
f = this.fields[f];
if (!f.is_valid()) {
form_invalid = true;
f.update_dom();
if (!first_invalid_field) {
first_invalid_field = f;
var action = function() {
try {
if (!self.initial_mutating_lock.isResolved() && !self.initial_mutating_lock.isRejected())
return;
var form_dirty = false,
form_invalid = false,
values = {},
first_invalid_field = null;
for (var f in self.fields) {
f = self.fields[f];
if (!f.is_valid()) {
form_invalid = true;
f.update_dom();
if (!first_invalid_field) {
first_invalid_field = f;
}
} else if (f.is_dirty()) {
form_dirty = true;
values[f.name] = f.get_value();
}
} else if (f.is_dirty()) {
form_dirty = true;
values[f.name] = f.get_value();
}
}
if (form_invalid) {
first_invalid_field.focus();
this.on_invalid();
return $.Deferred().reject();
} else {
console.log("About to save", values);
if (!this.datarecord.id) {
return this.dataset.create(values).pipe(function(r) {
return self.on_created(r, undefined, prepend_on_create);
}).then(success);
if (form_invalid) {
first_invalid_field.focus();
self.on_invalid();
return $.Deferred().reject();
} else {
return this.dataset.write(this.datarecord.id, values, {}).pipe(function(r) {
return self.on_saved(r);
}).then(success);
console.log("About to save", values);
if (!self.datarecord.id) {
return self.dataset.create(values).pipe(function(r) {
return self.on_created(r, undefined, prepend_on_create);
}).then(success);
} else {
return self.dataset.write(self.datarecord.id, values, {}).pipe(function(r) {
return self.on_saved(r);
}).then(success);
}
}
}
} catch (e) {
console.error(e);
return $.Deferred().reject();
}
};
this.mutating_lock = this.mutating_lock.pipe(action, action);
return this.mutating_lock;
},
do_save_edit: function() {
this.do_save();
@ -417,7 +443,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
});
msg += "</ul>";
this.notification.warn("The following fields are invalid :", msg);
this.do_warn("The following fields are invalid :", msg);
},
on_saved: function(r, success) {
if (!r.result) {
@ -425,7 +451,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
return $.Deferred().reject();
} else {
this.reload();
return $.Deferred().then(success).resolve(r);
return $.when(r).then(success);
}
},
/**
@ -460,12 +486,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
console.debug("The record has been created with id #" + this.datarecord.id);
this.reload();
return $.Deferred().then(success).resolve(_.extend(r, {created: true}));
return $.when(_.extend(r, {created: true})).then(success);
}
},
do_search: function (domains, contexts, groupbys) {
console.debug("Searching form");
},
on_action: function (action) {
console.debug('Executing action', action);
},
@ -473,11 +496,16 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
console.debug("Cancelling form");
},
reload: function() {
if (this.dataset.index == null || this.dataset.index < 0) {
this.on_button_new();
} else {
this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
}
var self = this;
var act = function() {
if (self.dataset.index == null || self.dataset.index < 0) {
return $.when(self.on_button_new());
} else {
return self.dataset.read_index(_.keys(self.fields_view.fields), self.on_record_loaded);
}
};
this.reload_lock = this.reload_lock.pipe(act, act);
return this.reload_lock;
},
get_fields_values: function() {
var values = {};
@ -543,8 +571,12 @@ openerp.web.FormDialog = openerp.web.Dialog.extend({
openerp.web.form = {};
openerp.web.form.SidebarAttachments = openerp.web.Widget.extend({
init: function(parent, element_id, form_view) {
this._super(parent, element_id);
init: function(parent, form_view) {
var $section = parent.add_section(_t('Attachments'), 'attachments');
this.$div = $('<div class="oe-sidebar-attachments"></div>');
$section.append(this.$div);
this._super(parent, $section.attr('id'));
this.view = form_view;
},
do_update: function() {
@ -562,7 +594,7 @@ openerp.web.form.SidebarAttachments = openerp.web.Widget.extend({
},
on_attachments_loaded: function(attachments) {
this.attachments = attachments;
this.$element.html(QWeb.render('FormView.sidebar.attachments', this));
this.$div.html(QWeb.render('FormView.sidebar.attachments', this));
this.$element.find('.oe-binary-file').change(this.on_attachment_changed);
this.$element.find('.oe-sidebar-attachment-delete').click(this.on_attachment_delete);
},
@ -584,7 +616,7 @@ openerp.web.form.SidebarAttachments = openerp.web.Widget.extend({
ids: [parseInt($e.attr('data-id'))]
}, function(r) {
$e.parent().remove();
self.notification.notify("Delete an attachment", "The attachment '" + name + "' has been deleted");
self.do_notify("Delete an attachment", "The attachment '" + name + "' has been deleted");
});
}
}
@ -688,7 +720,8 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.
this.width = this.node.attrs.width;
},
start: function() {
this.$element = this.view.$element.find('.' + this.element_class);
this.$element = this.view.$element.find(
'.' + this.element_class.replace(/[^\r\n\f0-9A-Za-z_-]/g, "\\$&"));
},
process_modifiers: function() {
var compute_domain = openerp.web.form.compute_domain;
@ -702,6 +735,51 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.
render: function() {
var template = this.template;
return QWeb.render(template, { "widget": this });
},
_build_view_fields_values: function() {
var a_dataset = this.view.dataset;
var fields_values = this.view.get_fields_values();
var parent_values = a_dataset.parent_view ? a_dataset.parent_view.get_fields_values() : {};
fields_values.parent = parent_values;
return fields_values;
},
_build_eval_context: function() {
var a_dataset = this.view.dataset;
return new openerp.web.CompoundContext(a_dataset.get_context(), this._build_view_fields_values());
},
/**
* Builds a new context usable for operations related to fields by merging
* the fields'context with the action's context.
*/
build_context: function() {
var f_context = (this.field || {}).context || {};
if (!!f_context.__ref) {
var fields_values = this._build_eval_context();
f_context = new openerp.web.CompoundDomain(f_context).set_eval_context(fields_values);
}
// maybe the default_get should only be used when we do a default_get?
var v_contexts = _.compact([this.node.attrs.default_get || null,
this.node.attrs.context || null]);
var v_context = new openerp.web.CompoundContext();
_.each(v_contexts, function(x) {v_context.add(x);});
if (_.detect(v_contexts, function(x) {return !!x.__ref;})) {
var fields_values = this._build_eval_context();
v_context.set_eval_context(fields_values);
}
// if there is a context on the node, overrides the model's context
var ctx = v_contexts.length > 0 ? v_context : f_context;
return ctx;
},
build_domain: function() {
var f_domain = this.field.domain || [];
var n_domain = this.node.attrs.domain || null;
// if there is a domain on the node, overrides the model's domain
var final_domain = n_domain !== null ? n_domain : f_domain;
if (!(final_domain instanceof Array)) {
var fields_values = this._build_eval_context();
final_domain = new openerp.web.CompoundDomain(final_domain).set_eval_context(fields_values);
}
return final_domain;
}
});
@ -757,6 +835,10 @@ openerp.web.form.WidgetFrame = openerp.web.form.Widget.extend({
var type = {};
if (node.tag == 'field') {
type = this.view.fields_view.fields[node.attrs.name] || {};
if (node.attrs.widget == 'statusbar') {
// This way we can retain backward compatibility between addons and old clients
node.attrs.nolabel = '1';
}
}
var widget = new (this.view.registry.get_any(
[node.attrs.widget, type.type, node.tag])) (this.view, node);
@ -792,7 +874,7 @@ openerp.web.form.WidgetNotebook = openerp.web.form.Widget.extend({
for (var i = 0; i < node.children.length; i++) {
var n = node.children[i];
if (n.tag == "page") {
var page = new openerp.web.form.WidgetNotebookPage(
var page = new (this.view.registry.get_object('notebookpage'))(
this.view, n, this, this.pages.length);
this.pages.push(page);
}
@ -811,7 +893,7 @@ openerp.web.form.WidgetNotebook = openerp.web.form.Widget.extend({
page.id = self.pages[index].element_id;
});
this.$element.tabs();
this.view.on_button_new.add_last(this.do_select_first_visible_tab);
this.view.on_button_new.add_first(this.do_select_first_visible_tab);
},
do_select_first_visible_tab: function() {
for (var i = 0; i < this.pages.length; i++) {
@ -898,11 +980,11 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
self.on_confirmed().then(function() {
def.resolve();
});
$(self).dialog("close");
$(this).dialog("close");
},
Cancel: function() {
def.resolve();
$(self).dialog("close");
$(this).dialog("close");
}
}
});
@ -911,7 +993,7 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
return self.on_confirmed();
}
};
if ((!this.node.attrs.special && this.view.dirty_for_user) || !this.view.datarecord.id) {
if (!this.node.attrs.special) {
return this.view.recursive_save().pipe(exec_action);
} else {
return exec_action();
@ -920,8 +1002,15 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
on_confirmed: function() {
var self = this;
var context = this.node.attrs.context;
if (context && context.__ref) {
context = new openerp.web.CompoundContext(context);
context.set_eval_context(this._build_eval_context());
}
return this.view.do_execute_action(
this.node.attrs, this.view.dataset, this.view.datarecord.id, function () {
_.extend({}, this.node.attrs, {context: context}),
this.view.dataset, this.view.datarecord.id, function () {
self.view.reload();
});
},
@ -1068,46 +1157,6 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
this.invalid = false;
},
focus: function() {
},
_build_view_fields_values: function() {
var a_dataset = this.view.dataset;
var fields_values = this.view.get_fields_values();
var parent_values = a_dataset.parent_view ? a_dataset.parent_view.get_fields_values() : {};
fields_values.parent = parent_values;
return fields_values;
},
_build_eval_context: function() {
var a_dataset = this.view.dataset;
return new openerp.web.CompoundContext(a_dataset.get_context(), this._build_view_fields_values());
},
/**
* Builds a new context usable for operations related to fields by merging
* the fields'context with the action's context.
*/
build_context: function() {
var f_context = this.field.context || null;
// maybe the default_get should only be used when we do a default_get?
var v_contexts = _.compact([this.node.attrs.default_get || null,
this.node.attrs.context || null]);
var v_context = new openerp.web.CompoundContext();
_.each(v_contexts, function(x) {v_context.add(x);});
if (_.detect(v_contexts, function(x) {return !!x.__ref;})) {
var fields_values = this._build_eval_context();
v_context.set_eval_context(fields_values);
}
// if there is a context on the node, overrides the model's context
var ctx = v_contexts.length > 0 ? v_context : f_context;
return ctx;
},
build_domain: function() {
var f_domain = this.field.domain || null;
var v_domain = this.node.attrs.domain || [];
if (!(v_domain instanceof Array) || true) { //TODO niv: remove || true
var fields_values = this._build_eval_context();
v_domain = new openerp.web.CompoundDomain(v_domain).set_eval_context(fields_values);
}
// if there is a domain on the node, overrides the model's domain
return f_domain || v_domain;
}
});
@ -1153,7 +1202,7 @@ openerp.web.form.FieldEmail = openerp.web.form.FieldChar.extend({
},
on_button_clicked: function() {
if (!this.value || !this.is_valid()) {
this.notification.warn("E-mail error", "Can't send email to invalid e-mail address");
this.do_warn("E-mail error", "Can't send email to invalid e-mail address");
} else {
location.href = 'mailto:' + this.value;
}
@ -1168,7 +1217,7 @@ openerp.web.form.FieldUrl = openerp.web.form.FieldChar.extend({
},
on_button_clicked: function() {
if (!this.value) {
this.notification.warn("Resource error", "This resource is empty");
this.do_warn("Resource error", "This resource is empty");
} else {
window.open(this.value);
}
@ -1787,6 +1836,9 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
result.result.context = _.extend(result.result.context || {}, additional_context);
self.do_action(result.result);
});
},
focus: function () {
this.$input.focus();
}
});
@ -1842,6 +1894,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
this._super(view, node);
this.is_started = $.Deferred();
this.form_last_update = $.Deferred();
this.init_form_last_update = this.form_last_update;
this.disable_utility_classes = true;
},
start: function() {
@ -1883,7 +1936,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
form: 'openerp.web.form.One2ManyFormView'
});
var once = $.Deferred().then(function() {
self.form_last_update.resolve();
self.init_form_last_update.resolve();
});
this.viewmanager.on_controller_inited.add_last(function(view_type, controller) {
if (view_type == "list") {
@ -1896,6 +1949,8 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
self.save_form_view();
});
controller.$element.find(".oe_form_button_save_edit").hide();
} else if (view_type == "graph") {
self.reload_current_view()
}
self.is_started.resolve();
});
@ -1915,9 +1970,12 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
if (this.dataset.index === null && this.dataset.ids.length >= 1) {
this.dataset.index = 0;
}
this.form_last_update.then(function() {
this.form_last_update = view.do_show();
});
var act = function() {
return view.do_show();
}
this.form_last_update = this.form_last_update.pipe(act, act);;
} else if (self.viewmanager.active_view === "graph") {
view.do_search(this.build_domain(), this.dataset.get_context(), []);
}
},
set_value: function(value) {
@ -2006,9 +2064,10 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
var view = this.viewmanager.views[this.viewmanager.active_view].controller;
if (this.viewmanager.active_view === "form") {
var res = $.when(view.do_save());
if (!res.isResolved() && !res.isRejected()) {
throw "Asynchronous get_value() is not supported in form view.";
}
// it seems line there are some cases when this happens
/*if (!res.isResolved() && !res.isRejected()) {
console.warn("Asynchronous get_value() is not supported in form view.");
}*/
return res;
}
}
@ -2020,6 +2079,8 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
},
validate: function() {
this.invalid = false;
if (!this.viewmanager.views[this.viewmanager.active_view])
return;
var view = this.viewmanager.views[this.viewmanager.active_view].controller;
if (this.viewmanager.active_view === "form") {
for (var f in view.fields) {
@ -2062,11 +2123,14 @@ openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
pop.select_element(self.o2m.field.relation,{
initial_view: "form",
alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined,
create_function: function(data) {
return self.o2m.dataset.create(data, function(r) {
create_function: function(data, callback, error_callback) {
return self.o2m.dataset.create(data).then(function(r) {
self.o2m.dataset.set_ids(self.o2m.dataset.ids.concat([r.result]));
self.o2m.dataset.on_change();
});
}).then(callback, error_callback);
},
read_function: function() {
return self.o2m.dataset.read_ids.apply(self.o2m.dataset, arguments);
},
parent_view: self.o2m.view,
form_view_options: {'not_interactible_on_create':true}
@ -2203,6 +2267,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
* - parent_view
* - form_view_options
* - list_view_options
* - read_function
*/
select_element: function(model, options, domain, context) {
var self = this;
@ -2211,7 +2276,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
this.context = context || {};
this.options = _.defaults(options || {}, {"initial_view": "search", "create_function": function() {
return self.create_row.apply(self, arguments);
}});
}, read_function: null});
this.initial_ids = this.options.initial_ids;
this.created_elements = [];
openerp.web.form.dialog(this.render(), {close:function() {
@ -2221,8 +2286,18 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
},
start: function() {
this._super();
this.dataset = new openerp.web.ReadOnlyDataSetSearch(this, this.model,
var self = this;
this.dataset = new openerp.web.ProxyDataSet(this, this.model,
this.context);
this.dataset.create_function = function() {
return self.options.create_function.apply(null, arguments).then(function(r) {
self.created_elements.push(r.result);
});
};
this.dataset.write_function = function() {
return self.write_row.apply(self, arguments);
};
this.dataset.read_function = this.options.read_function;
this.dataset.parent_view = this.options.parent_view;
this.dataset.on_default_get.add(this.on_default_get);
if (this.options.initial_view == "search") {
@ -2243,11 +2318,11 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
});
this.searchview.on_search.add(function(domains, contexts, groupbys) {
if (self.initial_ids) {
self.view_list.do_search.call(self, domains.concat([[["id", "in", self.initial_ids]], self.domain]),
self.do_search(domains.concat([[["id", "in", self.initial_ids]], self.domain]),
contexts, groupbys);
self.initial_ids = undefined;
} else {
self.view_list.do_search.call(self, domains.concat([self.domain]), contexts, groupbys);
self.do_search(domains.concat([self.domain]), contexts, groupbys);
}
});
this.searchview.on_loaded.add_last(function () {
@ -2274,15 +2349,30 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
}).pipe(function() {
self.searchview.do_search();
});
});
this.searchview.appendTo($("#" + this.element_id + "_search"));
},
create_row: function(data) {
do_search: function(domains, contexts, groupbys) {
var self = this;
this.rpc('/web/session/eval_domain_and_context', {
domains: domains || [],
contexts: contexts || [],
group_by_seq: groupbys || []
}, function (results) {
self.view_list.do_search(results.domain, results.context, results.group_by);
});
},
create_row: function() {
var self = this;
var wdataset = new openerp.web.DataSetSearch(this, this.model, this.context, this.domain);
wdataset.parent_view = this.options.parent_view;
return wdataset.create(data);
return wdataset.create.apply(wdataset, arguments);
},
write_row: function() {
var self = this;
var wdataset = new openerp.web.DataSetSearch(this, this.model, this.context, this.domain);
wdataset.parent_view = this.options.parent_view;
return wdataset.write.apply(wdataset, arguments);
},
on_select_elements: function(element_ids) {
},
@ -2313,33 +2403,25 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
$buttons.html(QWeb.render("SelectCreatePopup.form.buttons", {widget:self}));
var $nbutton = $buttons.find(".oe_selectcreatepopup-form-save-new");
$nbutton.click(function() {
self._created = $.Deferred().then(function() {
self._created = undefined;
self.view_form.on_button_new();
$.when(self.view_form.do_save()).then(function() {
self.view_form.reload_lock.then(function() {
self.view_form.on_button_new();
});
});
self.view_form.do_save();
});
var $nbutton = $buttons.find(".oe_selectcreatepopup-form-save");
$nbutton.click(function() {
self._created = $.Deferred().then(function() {
self._created = undefined;
self.check_exit();
$.when(self.view_form.do_save()).then(function() {
self.view_form.reload_lock.then(function() {
self.check_exit();
});
});
self.view_form.do_save();
});
var $cbutton = $buttons.find(".oe_selectcreatepopup-form-close");
$cbutton.click(function() {
self.check_exit();
});
});
this.dataset.on_create.add(function(data) {
self.options.create_function(data).then(function(r) {
self.created_elements.push(r.result);
if (self._created) {
self._created.resolve();
}
});
});
this.view_form.do_show();
},
check_exit: function() {
@ -2401,7 +2483,6 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
this.setup_form_view();
},
on_write: function(id, data) {
this.stop();
if (!this.options.auto_write)
return;
var self = this;
@ -2424,7 +2505,9 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
$buttons.html(QWeb.render("FormOpenPopup.form.buttons"));
var $nbutton = $buttons.find(".oe_formopenpopup-form-save");
$nbutton.click(function() {
self.view_form.do_save();
self.view_form.do_save().then(function() {
self.stop();
});
});
var $cbutton = $buttons.find(".oe_formopenpopup-form-close");
$cbutton.click(function() {
@ -2436,7 +2519,7 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
}
});
openerp.web.form.FormOpenDataset = openerp.web.ReadOnlyDataSetSearch.extend({
openerp.web.form.FormOpenDataset = openerp.web.ProxyDataSet.extend({
read_ids: function() {
if (this.fop.options.read_function) {
return this.fop.options.read_function.apply(null, arguments);
@ -2462,6 +2545,9 @@ openerp.web.form.FieldReference = openerp.web.form.Field.extend({
};
this.get_fields_values = view.get_fields_values;
this.do_onchange = this.on_form_changed = this.on_nop;
this.dataset = this.view.dataset;
this.widgets_counter = 0;
this.view_id = 'reference_' + _.uniqueId();
this.widgets = {};
this.fields = {};
this.selection = new openerp.web.form.FieldSelection(this, { attrs: {
@ -2477,8 +2563,10 @@ openerp.web.form.FieldReference = openerp.web.form.Field.extend({
on_nop: function() {
},
on_selection_changed: function() {
this.m2o.field.relation = this.selection.get_value();
var sel = this.selection.get_value();
this.m2o.field.relation = sel;
this.m2o.set_value(null);
this.m2o.$element.toggle(sel !== false);
},
start: function() {
this._super();
@ -2522,10 +2610,6 @@ openerp.web.form.FieldBinary = openerp.web.form.Field.extend({
this.$element.find('button.oe-binary-file-save').click(this.on_save_as);
this.$element.find('.oe-binary-file-clear').click(this.on_clear);
},
update_dom: function() {
this._super.apply(this, arguments);
this.$element.find('.oe-binary').toggle(!this.readonly);
},
human_filesize : function(size) {
var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
var i = 0;
@ -2543,29 +2627,28 @@ openerp.web.form.FieldBinary = openerp.web.form.Field.extend({
if ($(e.target).val() != '') {
this.$element.find('form.oe-binary-form input[name=session_id]').val(this.session.session_id);
this.$element.find('form.oe-binary-form').submit();
this.toggle_progress();
this.$element.find('.oe-binary-progress').show();
this.$element.find('.oe-binary').hide();
}
},
toggle_progress: function() {
this.$element.find('.oe-binary-progress, .oe-binary').toggle();
},
on_file_uploaded: function(size, name, content_type, file_base64) {
delete(window[this.iframe]);
if (size === false) {
this.notification.warn("File Upload", "There was a problem while uploading your file");
this.do_warn("File Upload", "There was a problem while uploading your file");
// TODO: use openerp web crashmanager
console.warn("Error while uploading file : ", name);
} else {
this.on_file_uploaded_and_valid.apply(this, arguments);
this.on_ui_change();
}
this.toggle_progress();
this.$element.find('.oe-binary-progress').hide();
this.$element.find('.oe-binary').show();
},
on_file_uploaded_and_valid: function(size, name, content_type, file_base64) {
},
on_save_as: function() {
if (!this.view.datarecord.id) {
this.notification.warn("Can't save file", "The record has not yet been saved");
this.do_warn("Can't save file", "The record has not yet been saved");
} else {
var url = '/web/binary/saveas?session_id=' + this.session.session_id + '&model=' +
this.view.dataset.model +'&id=' + (this.view.datarecord.id || '') + '&field=' + this.name +
@ -2585,6 +2668,10 @@ openerp.web.form.FieldBinary = openerp.web.form.Field.extend({
openerp.web.form.FieldBinaryFile = openerp.web.form.FieldBinary.extend({
template: 'FieldBinaryFile',
update_dom: function() {
this._super.apply(this, arguments);
this.$element.find('.oe-binary-file-set, .oe-binary-file-clear').toggle(!this.readonly);
},
set_value: function(value) {
this._super.apply(this, arguments);
var show_value = (value != null && value !== false) ? value : '';
@ -2617,6 +2704,10 @@ openerp.web.form.FieldBinaryImage = openerp.web.form.FieldBinary.extend({
this._super.apply(this, arguments);
this.$image = this.$element.find('img.oe-binary-image');
},
update_dom: function() {
this._super.apply(this, arguments);
this.$element.find('.oe-binary').toggle(!this.readonly);
},
set_value: function(value) {
this._super.apply(this, arguments);
this.set_image_maxwidth();
@ -2781,6 +2872,7 @@ openerp.web.form.widgets = new openerp.web.Registry({
'frame' : 'openerp.web.form.WidgetFrame',
'group' : 'openerp.web.form.WidgetFrame',
'notebook' : 'openerp.web.form.WidgetNotebook',
'notebookpage' : 'openerp.web.form.WidgetNotebookPage',
'separator' : 'openerp.web.form.WidgetSeparator',
'label' : 'openerp.web.form.WidgetLabel',
'button' : 'openerp.web.form.WidgetButton',

View File

@ -391,9 +391,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();
@ -442,41 +439,22 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
self.compute_aggregates();
}));
},
/**
* Event handler for a search, asks for the computation/folding of domains
* and contexts (and group-by), then reloads the view's content.
*
* @param {Array} domains a sequence of literal and non-literal domains
* @param {Array} contexts a sequence of literal and non-literal contexts
* @param {Array} groupbys a sequence of literal and non-literal group-by contexts
* @returns {$.Deferred} fold request evaluation promise
*/
do_search: function (domains, contexts, groupbys) {
return this.rpc('/web/session/eval_domain_and_context', {
domains: _([this.dataset.get_domain()].concat(domains)).compact(),
contexts: _([this.dataset.get_context()].concat(contexts)).compact(),
group_by_seq: groupbys
}, $.proxy(this, 'do_actual_search'));
},
/**
* Handler for the result of eval_domain_and_context, actually perform the
* searching
*
* @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'));
},
/**
@ -493,6 +471,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();
});
},
@ -505,7 +484,13 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
do_select: function (ids, records) {
this.$element.find('.oe-list-delete')
.attr('disabled', !ids.length);
if (this.sidebar) {
if (ids.length) {
this.sidebar.do_unfold();
} else {
this.sidebar.do_fold();
}
}
if (!records.length) {
this.compute_aggregates();
return;
@ -536,14 +521,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,
@ -642,7 +621,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
}
$footer_cells.filter(_.sprintf('[data-field=%s]', column.id))
.html(openerp.web.format_cell(aggregation, column));
.html(openerp.web.format_cell(aggregation, column, undefined, false));
});
},
get_selected_ids: function() {
@ -806,6 +785,26 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
[this.records.at(this.dataset.index).get('id'),
this.dataset]);
},
render_cell: function (record, column) {
if (column.type === 'many2one') {
var 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();
@ -813,7 +812,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) {
@ -837,7 +836,9 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
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);
},
/**
@ -918,7 +919,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')
});
},
/**
@ -1169,7 +1171,8 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
var fields = _.pluck(_.select(this.columns, function(x) {return x.tag == "field"}), 'name');
var options = { offset: page * limit, limit: limit };
dataset.read_slice(fields, options , function (records) {
//TODO xmo: investigate why we need to put the setTimeout
setTimeout(function() {dataset.read_slice(fields, options , function (records) {
if (!self.datagroup.openable) {
view.configure_pager(dataset);
} else {
@ -1188,7 +1191,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) {

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
@ -120,6 +121,7 @@ openerp.web.list_editable = function (openerp) {
delete self.edition_id;
delete self.edition;
});
this.pad_table_to(5);
return cancelled.promise();
},
/**
@ -147,7 +149,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 +175,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
@ -325,11 +339,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();
}
}
});

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) {

View File

@ -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,'_');
@ -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') {
db.webclient.do_reload();
}
}
this.dialog_stop();
},
ir_actions_server: function (action, on_closed) {
@ -166,6 +177,7 @@ 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 = {};
@ -224,35 +236,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
@ -272,14 +270,6 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
}
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.
*
@ -293,14 +283,37 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
}
this.searchview = new db.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
*/
@ -360,28 +373,24 @@ 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);
}
@ -511,9 +520,57 @@ db.web.Sidebar = db.web.Widget.extend({
self.do_toggle();
});
},
call_default_on_sidebar: function(item) {
var func_name = 'on_sidebar_' + _.underscored(item.label);
var fn = this.widget_parent[func_name];
if(typeof fn === 'function') {
fn(item);
}
},
add_default_sections: function() {
this.add_section(_t('Customize'), 'customize');
this.add_items('customize', [
{
label: _t("Manage Views"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object"),
}, {
label: _t("Edit Workflow"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object"),
classname: 'oe_hide oe_sidebar_edit_workflow'
}, {
label: _t("Customize Object"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object"),
}
]);
this.add_section(_t('Other Options'), 'other');
this.add_items('other', [
{
label: _t("Import"),
callback: this.call_default_on_sidebar,
}, {
label: _t("Export"),
callback: this.call_default_on_sidebar,
}, {
label: _t("Translate"),
callback: this.call_default_on_sidebar,
classname: 'oe_sidebar_translate oe_hide'
}, {
label: _t("View Log"),
callback: this.call_default_on_sidebar,
classname: 'oe_hide oe_sidebar_view_log'
}
]);
},
add_toolbar: function(toolbar) {
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 +580,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 = _.underscored(name);
var $section = this.sections[code];
if(!$section) {
section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
var $section = $(db.web.qweb.render("Sidebar.section", {
section_id: section_id,
name: name,
classname: 'oe_sidebar_' + code,
}));
$section.appendTo(this.$element.find('div.sidebar-actions'));
this.sections[code] = $section;
}
return $section;
},
add_items: function(section_code, items) {
// An item is a dictonary : {
// label: label to be displayed for the link,
// action: action to be launch when the link is clicked,
@ -540,25 +612,24 @@ 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(_.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 = $(db.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();
@ -588,10 +659,13 @@ db.web.Sidebar = db.web.Widget.extend({
}
return false;
});
var $ul = $section.find('ul');
if(!$ul.length) {
$ul = $('<ul/>').appendTo($section);
}
$items.appendTo($ul);
}
$section.appendTo(this.$element.find('div.sidebar-actions'));
this.sections[code] = $section;
return section_id;
},
do_fold: function() {
this.$element.addClass('closed-sidebar').removeClass('open-sidebar');
@ -770,7 +844,9 @@ 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 handler = function (r) {
var action = r.result;
@ -783,7 +859,8 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
}],
domains: []
}).pipe(function (results) {
action.context = results.context
action.context = new db.web.CompoundContext(
results.context, action_data.context);
return self.do_action(action, result_handler);
});
} else {
@ -816,47 +893,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) {
var view_editor = new db.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() {

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" class="loading"></div>
<table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%" class="main_table">
<tr>
<td colspan="2" valign="top">
@ -447,8 +449,8 @@
</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"/>
<h2 class="oe_view_title" t-if="self.session.debug || self.flags.display_title !==false">
<t t-if="self.flags.display_title !==false" t-esc="self.action.name"/>
<button t-if="self.session.debug" class="oe_get_xml_view">
View#<span></span>
</button>
@ -467,17 +469,20 @@
</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>
@ -539,7 +544,7 @@
<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])" />
@ -640,7 +645,7 @@
<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-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">
@ -776,7 +781,7 @@
<input type="text" size="12"
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}"
/>
<!-- 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"/-->
@ -784,7 +789,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}"
t-attf-style="width: #{widget.field.translate ? '99' : '100'}%">
</div>
</t>
@ -823,7 +828,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"/>
@ -842,8 +847,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>
@ -851,8 +856,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'">
@ -886,7 +892,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>
@ -895,8 +901,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">
@ -911,7 +917,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"
/>
@ -959,7 +965,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">
@ -1004,7 +1010,6 @@
</t>
<t t-name="WidgetButton">
<button type="button"
t-attf-class="#{widget.element_class}"
t-att-title="widget.help"
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"/>
@ -1101,14 +1106,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>
@ -1302,20 +1307,24 @@
<td align="left" class="view_editor" width="15%">
<table cellspacing="0" cellpadding ="0" width="100%">
<tr>
<td>
<img id="side-add" src="/web/static/src/img/icons/gtk-add.png" style="cursor: pointer;"/>
<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>
<td width="20%">
<img id="side-remove" src="/web/static/src/img/icons/gtk-remove.png" style="cursor: pointer;"/>
</td>
<td>
<img id="side-edit" src="/web/static/src/img/icons/gtk-edit.png" style="cursor: pointer;"/>
<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>
<img id="side-up" src="/web/static/src/img/icons/gtk-go-up.png" style="cursor: pointer;"/>
<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>
<img id="side-down" src="/web/static/src/img/icons/gtk-go-down.png" style="cursor: pointer;"/>
<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>
@ -1570,4 +1579,4 @@
<t t-name="EmptyComponent">
<div></div>
</t>
</templates>
</templates>

View File

@ -1,5 +1,6 @@
{
"name": "web calendar",
"category" : "Hidden",
"version": "2.0",
"depends": ['web'],
"js": [

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-10-12 04:44+0000\n"
"X-Generator: Launchpad (build 14124)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"

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-10-11 05:42+0000\n"
"X-Generator: Launchpad (build 14123)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"

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-10-08 05:30+0000\n"
"X-Generator: Launchpad (build 14110)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"

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-10-11 05:42+0000\n"
"X-Generator: Launchpad (build 14123)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"

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-12 05:03+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: French <fr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-10-13 04:46+0000\n"
"X-Generator: Launchpad (build 14124)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr ""

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-10-09 05:22+0000\n"
"X-Generator: Launchpad (build 14110)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"

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-10-08 05:30+0000\n"
"X-Generator: Launchpad (build 14110)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"

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"

View File

@ -3,6 +3,7 @@
*---------------------------------------------------------*/
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');
@ -13,9 +14,8 @@ 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 = [];
@ -31,7 +31,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 +47,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 +59,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 +76,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 +85,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 +97,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 +113,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);
@ -200,7 +200,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
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 = [];
@ -293,26 +293,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 +363,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 +392,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) {

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,
}

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__)

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"

View File

@ -1,5 +1,6 @@
{
"name": "web Dashboard",
"category" : "Hidden",
"version": "2.0",
"depends": ['web'],
"js": [

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]

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-10-12 04:44+0000\n"
"X-Generator: Launchpad (build 14124)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
msgstr "Nulstil"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Undo"
msgstr "Fortryd"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Add Widget"
msgstr "Tilføj widget"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Change layout"
msgstr "Skift layout"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Choose dashboard layout"
msgstr "Vælg layout for kontrolpanel"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "progress:"
msgstr "fremskridt:"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "%"
msgstr "%"

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-10-11 05:42+0000\n"
"X-Generator: Launchpad (build 14123)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
msgstr "Zurücksetzen"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Undo"
msgstr "Rückgängig"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Add Widget"
msgstr "Widget hinzufügen"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Change layout"
msgstr "Layout wechseln"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Choose dashboard layout"
msgstr "Wählen Sie das Dashboard Layout"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "progress:"
msgstr "Fortschritt:"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "%"
msgstr "%"

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-10-08 05:30+0000\n"
"X-Generator: Launchpad (build 14110)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
msgstr "Reset"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Undo"
msgstr "Deshacer"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Add Widget"
msgstr "Agregar Widget"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Change layout"
msgstr "Cambiar disposición"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Choose dashboard layout"
msgstr "Elegir el diseño del panel de control"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "progress:"
msgstr "progreso:"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "%"
msgstr "%"

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-10-11 05:42+0000\n"
"X-Generator: Launchpad (build 14123)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
msgstr "Lähtesta"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Undo"
msgstr "Ennista"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Add Widget"
msgstr ""
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Change layout"
msgstr ""
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Choose dashboard layout"
msgstr ""
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "progress:"
msgstr ""
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "%"
msgstr "%"

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-12 05:10+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: French <fr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-10-13 04:46+0000\n"
"X-Generator: Launchpad (build 14124)\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 ""

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-10-08 05:30+0000\n"
"X-Generator: Launchpad (build 14110)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
msgstr "Ripristina"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Undo"
msgstr "Annulla"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Add Widget"
msgstr "Aggiungi Widget"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Change layout"
msgstr "Cambia layout"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Choose dashboard layout"
msgstr "Scegli layout dashboard"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "progress:"
msgstr "avanzamento:"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "%"
msgstr "%"

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-10-08 05:30+0000\n"
"X-Generator: Launchpad (build 14110)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
msgstr "Reset"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Undo"
msgstr "Ongedaan maken"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Add Widget"
msgstr "Widget toevoegen"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Change layout"
msgstr "Layout aanpassen"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Choose dashboard layout"
msgstr "Dashboard layout kiezen"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "progress:"
msgstr "vooruitgang:"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "%"
msgstr "%"

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"

View File

@ -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;
}

View File

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@ -2,6 +2,11 @@ openerp.web_dashboard = function(openerp) {
var QWeb = openerp.web.qweb;
QWeb.add_template('/web_dashboard/static/src/xml/web_dashboard.xml');
if (!openerp.web_dashboard) {
/** @namespace */
openerp.web_dashboard = {};
}
openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
init: function(view, node) {
this._super(view, node);
@ -43,9 +48,6 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
});
//this.$element.find('a.oe-dashboard-action-rename').live('click', this.on_rename);
this.$element.find('.oe-dashboard-action').live('mouseover mouseout', function(event) {
$(this).find('.oe-dashboard-action-header .ui-icon, .oe-dashboard-action-header .oe-dashboard-action-rename').toggle(event.type == 'mouseover');
});
},
on_undo: function() {
this.rpc('/web/view/undo_custom', {
@ -217,6 +219,8 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
});
},
on_load_action: function(result) {
var self = this;
var action_orig = _.extend({}, result.result);
var action = result.result;
action.flags = {
search_view : false,
@ -224,12 +228,21 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
views_switcher : false,
action_buttons : false,
pager: false,
low_profile: true
low_profile: true,
display_title: false
};
var am = new openerp.web.ActionManager(this);
this.action_managers.push(am);
am.appendTo($("#"+this.view.element_id + '_action_' + action.id));
am.do_action(action);
am.do_action = function(action) {
self.do_action(action);
}
if (am.inner_viewmanager) {
am.inner_viewmanager.on_mode_switch.add(function(mode) {
self.do_action(action_orig);
});
}
},
render: function() {
// We should start with three columns available
@ -243,12 +256,10 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
return QWeb.render(this.template, this);
},
do_reload: function() {
_.each(this.action_managers, function(am) {
am.stop();
});
this.action_managers = [];
var view_manager = this.view.widget_parent,
action_manager = view_manager.widget_parent;
this.view.stop();
this.view.start();
action_manager.do_action(view_manager.action);
}
});
openerp.web.form.DashBoardLegacy = openerp.web.form.DashBoard.extend({
@ -279,20 +290,19 @@ openerp.web.form.widgets.add('hpaned', 'openerp.web.form.DashBoardLegacy');
openerp.web.form.widgets.add('vpaned', 'openerp.web.form.DashBoardLegacy');
openerp.web.form.widgets.add('board', 'openerp.web.form.DashBoard');
openerp.web.client_actions.add(
'board.config.overview', 'openerp.web_dashboard.ConfigOverview'
);
if (!openerp.web_dashboard) {
/** @namespace */
openerp.web_dashboard = {};
}
/*
* ConfigOverview
* This client action designed to be used as a dashboard widget display
* ir.actions.todo in a fancy way
*/
openerp.web.client_actions.add( 'board.config.overview', 'openerp.web_dashboard.ConfigOverview');
openerp.web_dashboard.ConfigOverview = openerp.web.View.extend({
template: 'ConfigOverview',
init: function (parent) {
this._super(parent);
this.dataset = new openerp.web.DataSetSearch(
this, 'ir.actions.todo');
this.dataset.domain = [['type', '=', 'manual']];
this.dataset.domain = [['type', '!=', 'automatic']];
},
start: function () {
this._super();
@ -348,35 +358,146 @@ openerp.web_dashboard.ConfigOverview = openerp.web.View.extend({
}
});
openerp.web.client_actions.add(
'board.home.applications', 'openerp.web_dashboard.ApplicationTiles');
/*
* ApplicationTiles
* This client action designed to be used as a dashboard widget display
* either a list of application to install (if none is installed yet) or
* a list of root menu
*/
openerp.web.client_actions.add( 'board.home.applications', 'openerp.web_dashboard.ApplicationTiles');
openerp.web_dashboard.apps = {
applications: [
[
{
module: 'crm', name: 'CRM',
help: "Acquire leads, follow opportunities, manage prospects and phone calls, \u2026"
}, {
module: 'sale', name: 'Sales',
help: "Do quotations, follow sales orders, invoice and control deliveries"
}, {
module: 'account_voucher', name: 'Invoicing',
help: "Send invoice, track payments and reminders"
}, {
module: 'project', name: 'Projects',
help: "Manage projects, track tasks, invoice task works, follow issues, \u2026"
}
], [
{
module: 'purchase', name: 'Purchase',
help: "Do purchase orders, control invoices and reception, follow your suppliers, \u2026"
}, {
module: 'stock', name: 'Warehouse',
help: "Track your stocks, schedule product moves, manage incoming and outgoing shipments, \u2026"
}, {
module: 'hr', name: 'Human Resources',
help: "Manage employees and their contracts, follow laves, recruit people, \u2026"
}, {
module: 'point_of_sale', name: 'Point of Sales',
help: "Manage shop sales, use touch-screen POS"
}
], [
{
module: 'profile_tools', name: 'Extra Tools',
help: "Track ideas, manage lunch, create surveys, share data"
}, {
module: 'mrp', name: 'Manufacturing',
help: "Manage your manufacturing, control your supply chain, personalize master data, \u2026"
}, {
module: 'marketing', name: 'Marketing',
help: "Manage campaigns, follow activities, automate emails, \u2026"
}, {
module: 'knowledge', name: 'Knowledge',
help: "Track your documents, browse your files, \u2026"
}
]
]
};
openerp.web_dashboard.ApplicationTiles = openerp.web.View.extend({
template: 'ApplicationTiles',
start: function () {
this._super();
var self = this;
return new openerp.web.DataSetSearch(
this, 'ir.ui.menu', null, [['parent_id', '=', false]])
.read_slice( ['name', 'web_icon_data', 'web_icon_hover_data'], {}, function (applications) {
// Create a matrix of 3*x applications
var rows = [];
while (applications.length) {
rows.push(applications.splice(0, 3));
this._super();
// Check for installed application
var Installer = new openerp.web.DataSet(this, 'base.setup.installer');
Installer.call('default_get', [], function (installed_modules) {
var installed = _(installed_modules).any(function (active, name) {
return _.startsWith(name, 'cat') && active; });
if(installed) {
self.do_display_root_menu();
} else {
self.do_display_installer();
}
});
},
do_display_root_menu: function() {
var self = this;
var dss = new openerp.web.DataSetSearch( this, 'ir.ui.menu', null, [['parent_id', '=', false]]);
var r = dss.read_slice( ['name', 'web_icon_data', 'web_icon_hover_data'], {}, function (applications) {
// Create a matrix of 3*x applications
var rows = [];
while (applications.length) {
rows.push(applications.splice(0, 3));
}
var tiles = QWeb.render( 'ApplicationTiles.content', {rows: rows});
self.$element.append(tiles)
.find('.oe-dashboard-home-tile')
.click(function () {
openerp.webclient.menu.on_menu_click(null, $(this).data('menuid'))
});
});
return r;
},
do_display_installer: function() {
var self = this;
var render_ctx = {
url: window.location.protocol + '//' + window.location.host + window.location.pathname,
session: self.session,
rows: openerp.web_dashboard.apps.applications
};
var installer = QWeb.render('StaticHome', render_ctx);
self.$element.append(installer);
this.$element.delegate('.oe-static-home-tile-text button', 'click', function () {
self.install_module($(this).val());
});
},
install_module: function (module_name) {
var self = this;
var Modules = new openerp.web.DataSetSearch(
this, 'ir.module.module', null,
[['name', '=', module_name], ['state', '=', 'uninstalled']]);
var Upgrade = new openerp.web.DataSet(this, 'base.module.upgrade');
$.blockUI({message:'<img src="/web/static/src/img/throbber2.gif">'});
Modules.read_slice(['id'], {}, function (records) {
if (!(records.length === 1)) { $.unblockUI(); return; }
Modules.call('state_update',
[_.pluck(records, 'id'), 'to install', ['uninstalled']],
function () {
Upgrade.call('upgrade_module', [[]], function () {
self.run_configuration_wizards();
});
}
self.$element
.append(QWeb.render(
'ApplicationTiles.content', {rows: rows}))
.find('.oe-dashboard-home-tile')
.click(function () {
var $this = $(this);
$this.closest('.openerp')
.find('.menu a[data-menu=' + $this.data('menuid') + ']')
.click();});
)
});
},
run_configuration_wizards: function () {
var self = this;
new openerp.web.DataSet(this, 'res.config').call('start', [[]], function (action) {
$.unblockUI();
self.widget_parent.widget_parent.do_action(action, function () {
openerp.webclient.do_reload();
});
});
}
});
openerp.web.client_actions.add(
'board.home.widgets', 'openerp.web_dashboard.Widget');
/*
* Widgets
* This client action designed to be used as a dashboard widget display
* the html content of a res_widget given as argument
*/
openerp.web.client_actions.add( 'board.home.widgets', 'openerp.web_dashboard.Widget');
openerp.web_dashboard.Widget = openerp.web.View.extend(/** @lends openerp.web_dashboard.Widgets# */{
template: 'HomeWidget',
/**
@ -410,4 +531,5 @@ openerp.web_dashboard.Widget = openerp.web.View.extend(/** @lends openerp.web_da
}));
}
});
};

View File

@ -30,8 +30,10 @@
</t>
<t t-name="DashBoard.action">
<div t-att-data-id="action.attrs.name" class="oe-dashboard-action">
<h2 class="oe-dashboard-action-header oe_view_title">
<h2 t-attf-class="oe-dashboard-action-header oe_view_title #{action.attrs.string ? '' : 'oe-dashboard-action-header-empty'}">
<input class="oe-dashboard-action-input" type="text" name="title" value="" style="display: none"/>
<t t-esc="action.attrs.string"/>
<t t-if="!action.attrs.string">&amp;nbsp;</t>
<span class='ui-icon ui-icon-closethick'></span>
<span class='ui-icon ui-icon-minusthick oe-dashboard-fold' t-if="!action.attrs.fold"></span>
<span class='ui-icon ui-icon-plusthick oe-dashboard-fold' t-if="action.attrs.fold"></span>
@ -110,4 +112,36 @@
<h3><t t-esc="widget.title"/></h3>
<iframe width="100%" frameborder="0" t-att-src="url"/>
</t>
<div t-name="StaticHome" class="oe-static-home">
<h1>Welcome to your new OpenERP instance.</h1>
<div class="oe-static-home-banner">
<li>Remember to bookmark this page.</li>
<li>Remember your login: <i><t t-esc="session.login"/></i></li>
<li>Choose the first OpenERP Application you want to install..</li>
</div>
<div class="oe-static-home-tiles">
<table width="100%">
<tr t-foreach="rows" t-as="row">
<td t-foreach="row" t-as="application" width="25%">
<table class="oe-static-home-tile">
<tr>
<td>
<div class="oe-static-home-tile-logo">
<img t-att-src="'/web_dashboard/static/src/img/installer_' + application.module + '.png'"/>
</div>
</td>
<td>
<div class="oe-static-home-tile-text">
<h2><t t-esc="application.name"/></h2>
<p><t t-esc="application.help"/></p>
<button type="button" t-att-value="application.module"> Install</button>
</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</div>
</template>

View File

@ -1,8 +0,0 @@
{
"name" : "OpenERP Web installer home",
"version" : "2.0",
"depends" : ['web'],
'active': True,
'js': ['static/src/js/home.js'],
'css': ['static/src/css/home.css']
}

View File

@ -1,21 +1,21 @@
# Translations template for PROJECT.
# Copyright (C) 2011 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# 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.
#
#, fuzzy
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"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"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-12 05:07+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language-Team: French <fr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 0.9.6\n"
"X-Launchpad-Export-Date: 2011-10-13 04:46+0000\n"
"X-Generator: Launchpad (build 14124)\n"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Welcome to your new OpenERP instance."
@ -36,4 +36,3 @@ msgstr ""
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Install"
msgstr ""

View File

@ -1,42 +0,0 @@
.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;
}

View File

@ -1,127 +0,0 @@
openerp.web_default_home = function (openerp) {
var QWeb = openerp.web.qweb;
QWeb.add_template('/web_default_home/static/src/xml/web_default_home.xml');
openerp.web_default_home = {
applications: [
[
{
module: 'crm', name: 'CRM',
help: "Acquire leads, follow opportunities, manage prospects and phone calls, \u2026"
}, {
module: 'sale', name: 'Sales',
help: "Do quotations, follow sales orders, invoice and control deliveries"
}, {
module: 'account_voucher', name: 'Invoicing',
help: "Send invoice, track payments and reminders"
}, {
module: 'project', name: 'Projects',
help: "Manage projects, track tasks, invoice task works, follow issues, \u2026"
}
], [
{
module: 'purchase', name: 'Purchase',
help: "Do purchase orders, control invoices and reception, follow your suppliers, \u2026"
}, {
module: 'stock', name: 'Warehouse',
help: "Track your stocks, schedule product moves, manage incoming and outgoing shipments, \u2026"
}, {
module: 'hr', name: 'Human Resources',
help: "Manage employees and their contracts, follow laves, recruit people, \u2026"
}, {
module: 'point_of_sale', name: 'Point of Sales',
help: "Manage shop sales, use touch-screen POS"
}
], [
{
module: 'profile_tools', name: 'Extra Tools',
help: "Track ideas, manage lunch, create surveys, share data"
}, {
module: 'mrp', name: 'Manufacturing',
help: "Manage your manufacturing, control your supply chain, personalize master data, \u2026"
}, {
module: 'marketing', name: 'Marketing',
help: "Manage campaigns, follow activities, automate emails, \u2026"
}, {
module: 'knowledge', name: 'Knowledge',
help: "Track your documents, browse your files, \u2026"
}
]
]
};
openerp.web.WebClient.include({
default_home: function () {
var self = this,
// resig class can't handle _super in async contexts, by the
// time async callback comes back, _super has already been
// reset to a baseline value of this.prototype (or something
// like that)
old_home = this._super;
var Installer = new openerp.web.DataSet(
this, 'base.setup.installer');
Installer.call('already_installed', [], function (installed_modules) {
if (!_(installed_modules).isEmpty()) {
return old_home.call(self);
}
self.action_manager.do_action({
type: 'ir.actions.client',
tag: 'home.default'
})
}, function (err, event) {
event.preventDefault();
return old_home.call(self);
});
}
});
openerp.web.client_actions.add(
'home.default', 'openerp.web_default_home.DefaultHome');
openerp.web_default_home.DefaultHome = openerp.web.View.extend({
template: 'StaticHome',
start: function () {
var r = this._super(), self = this;
this.$element.delegate('.oe-static-home-tile-text button', 'click', function () {
self.install_module($(this).val());
});
return r;
},
render: function () {
return this._super({
url: window.location.protocol + '//' + window.location.host + window.location.pathname,
session: this.session,
rows: openerp.web_default_home.applications
})
},
install_module: function (module_name) {
var self = this;
var Modules = new openerp.web.DataSetSearch(
this, 'ir.module.module', null,
[['name', '=', module_name], ['state', '=', 'uninstalled']]);
var Upgrade = new openerp.web.DataSet(this, 'base.module.upgrade');
$.blockUI({message:'<img src="/web/static/src/img/throbber2.gif">'});
Modules.read_slice(['id'], {}, function (records) {
if (!(records.length === 1)) { return; }
Modules.call('state_update',
[_.pluck(records, 'id'), 'to install', ['uninstalled']],
function () {
Upgrade.call('upgrade_module', [[]], function () {
self.run_configuration_wizards();
});
}
)
});
},
run_configuration_wizards: function () {
var self = this;
new openerp.web.DataSet(this, 'res.config').call('start', [[]], function (action) {
$.unblockUI();
self.do_action(action, function () {
// TODO: less brutal reloading
window.location.reload(true);
});
});
}
});
};

View File

@ -1,34 +0,0 @@
<template>
<div t-name="StaticHome" class="oe-static-home">
<h1>Welcome to your new OpenERP instance.</h1>
<div class="oe-static-home-banner">
<li>Remember to bookmark this page.</li>
<li>Remember your login: <i><t t-esc="session.login"/></i></li>
<li>Choose the first OpenERP Application you want to install..</li>
</div>
<div class="oe-static-home-tiles">
<table width="100%">
<tr t-foreach="rows" t-as="row">
<td t-foreach="row" t-as="application" width="25%">
<table class="oe-static-home-tile">
<tr>
<td>
<div class="oe-static-home-tile-logo">
<img t-att-src="'/web_default_home/static/src/img/' + application.module + '.png'"/>
</div>
</td>
<td>
<div class="oe-static-home-tile-text">
<h2><t t-esc="application.name"/></h2>
<p><t t-esc="application.help"/></p>
<button type="button" t-att-value="application.module"> Install</button>
</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</div>
</template>

View File

@ -1,5 +1,6 @@
{
"name" : "OpenERP Web Diagram",
"category" : "Hidden",
"version" : "2.0",
"depends" : ["base"],
"js": [

View File

@ -1,4 +1,4 @@
import web.common as openerpweb
import web.common.http as openerpweb
from web.controllers.main import View
class DiagramView(View):

View File

@ -0,0 +1,54 @@
# 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 14:05+0000\n"
"Last-Translator: Jonas Mortensen <Unknown>\n"
"Language-Team: Danish <da@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-10-12 04:44+0000\n"
"X-Generator: Launchpad (build 14124)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
msgstr "Ny tilstand"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Edge"
msgstr ""
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Show Grid:"
msgstr "Vis gitter:"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "First"
msgstr "Første"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "<<"
msgstr "<<"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "0"
msgstr "0"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "/"
msgstr "/"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid ">>"
msgstr ">>"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Last"
msgstr "Sidste"

View File

@ -0,0 +1,54 @@
# 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:41+0000\n"
"Last-Translator: Felix Schubert <Unknown>\n"
"Language-Team: German <de@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
"X-Generator: Launchpad (build 14123)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
msgstr "Neuer Knoten"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Edge"
msgstr ""
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Show Grid:"
msgstr ""
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "First"
msgstr "Anfang"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "<<"
msgstr "<<"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "0"
msgstr "0"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "/"
msgstr "/"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid ">>"
msgstr ">>"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Last"
msgstr "Ende"

View File

@ -0,0 +1,54 @@
# 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 16:02+0000\n"
"Last-Translator: Cristian Salamea (Gnuthink) <ovnicraft@gmail.com>\n"
"Language-Team: Spanish (Ecuador) <es_EC@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
"X-Generator: Launchpad (build 14110)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
msgstr "Nuevo Nodo"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Edge"
msgstr "Nueva arista"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Show Grid:"
msgstr "Mostrar cuadrícula"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "First"
msgstr "Primero"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "<<"
msgstr "<<"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "0"
msgstr "0"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "/"
msgstr "/"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid ">>"
msgstr ">>"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Last"
msgstr "Último"

View File

@ -0,0 +1,54 @@
# 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:24+0000\n"
"Last-Translator: Aare Vesi <Unknown>\n"
"Language-Team: Estonian <et@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
"X-Generator: Launchpad (build 14123)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
msgstr ""
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Edge"
msgstr ""
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Show Grid:"
msgstr ""
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "First"
msgstr "Esimene"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "<<"
msgstr "<<"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "0"
msgstr "0"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "/"
msgstr "/"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid ">>"
msgstr ">>"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Last"
msgstr "Viimane"

View File

@ -0,0 +1,54 @@
# 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-08 13:41+0000\n"
"Last-Translator: Nicola Riolini - Micronaet <Unknown>\n"
"Language-Team: Italian <it@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-10-09 05:22+0000\n"
"X-Generator: Launchpad (build 14110)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
msgstr "Nuovo Nodo"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Edge"
msgstr ""
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Show Grid:"
msgstr "Mostra griglia"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "First"
msgstr "Primo"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "<<"
msgstr "<<"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "0"
msgstr "0"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "/"
msgstr "/"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid ">>"
msgstr ">>"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Last"
msgstr "Ultimo"

View File

@ -0,0 +1,54 @@
# 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:08+0000\n"
"Last-Translator: Niels Huylebroeck <Unknown>\n"
"Language-Team: Dutch (Belgium) <nl_BE@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
"X-Generator: Launchpad (build 14110)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
msgstr "Nieuw knooppunt"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Edge"
msgstr "Nieuwe verbinding"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Show Grid:"
msgstr "Toon raster:"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "First"
msgstr "Begin"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "<<"
msgstr "<<"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "0"
msgstr "0"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "/"
msgstr "/"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid ">>"
msgstr ">>"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Last"
msgstr "Einde"

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"

View File

@ -1,5 +1,6 @@
{
"name": "web Gantt",
"category" : "Hidden",
"version": "2.0",
"depends": ['web'],
"js": [

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"

View File

@ -509,15 +509,7 @@ init: function(parent, dataset, view_id) {
do_search: function (domains, contexts, groupbys) {
var self = this;
this.grp = groupbys;
return this.rpc('/web/session/eval_domain_and_context', {
domains: domains,
contexts: contexts,
group_by_seq: groupbys
}, function (results) {
self.dataset.context = results.context;
self.dataset.domain = results.domain;
self.reload_gantt();
});
self.reload_gantt();
}
});

View File

@ -1,5 +1,6 @@
{
"name": "web Graph",
"category" : "Hidden",
"version": "2.0",
"depends": ['web'],
"js": [
@ -7,4 +8,4 @@
"static/src/js/graph.js"],
"css": ["static/lib/dhtmlxGraph/codebase/dhtmlxchart.css"],
"active": True
}
}

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"

View File

@ -17,8 +17,9 @@ QWeb.add_template('/web_graph/static/src/xml/web_graph.xml');
openerp.web.views.add('graph', 'openerp.web_graph.GraphView');
openerp.web_graph.GraphView = openerp.web.View.extend({
init: function(parent, dataset, view_id) {
init: function(parent, dataset, view_id, options) {
this._super(parent);
this.set_default_options(options);
this.dataset = dataset;
this.view_id = view_id;
@ -27,9 +28,9 @@ openerp.web_graph.GraphView = openerp.web.View.extend({
this.ordinate = null;
this.columns = [];
this.group_field = null;
this.is_loaded = $.Deferred();
},
do_show: function () {
// TODO: re-trigger search
this.$element.show();
},
do_hide: function () {
@ -38,17 +39,24 @@ openerp.web_graph.GraphView = openerp.web.View.extend({
start: function() {
var self = this;
this._super();
var loaded;
if (this.embedded_view) {
loaded = $.when([self.embedded_view]);
} else {
loaded = this.rpc('/web/view/load', {
model: this.dataset.model,
view_id: this.view_id,
view_type: 'graph'
});
}
return $.when(
this.dataset.call('fields_get', []),
this.rpc('/web/view/load', {
model: this.dataset.model,
view_id: this.view_id,
view_type: 'graph'
})).then(function (fields_result, view_result) {
loaded)
.then(function (fields_result, view_result) {
self.fields = fields_result[0];
self.fields_view = view_result[0];
self.on_loaded();
});
});
},
/**
* Returns all object fields involved in the graph view
@ -79,9 +87,7 @@ openerp.web_graph.GraphView = openerp.web.View.extend({
}
}, this);
this.ordinate = this.columns[0].name;
this.dataset.read_slice(
this.list_fields(), {}, $.proxy(this, 'schedule_chart'));
this.is_loaded.resolve();
},
schedule_chart: function(results) {
var self = this;
@ -366,23 +372,16 @@ openerp.web_graph.GraphView = openerp.web.View.extend({
});
},
do_search: function(domains, contexts, groupbys) {
do_search: function(domain, context, group_by) {
var self = this;
this.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?
if(!_(results.group_by).isEmpty()){
self.abscissa = results.group_by[0];
return $.when(this.is_loaded).pipe(function() {
// TODO: handle non-empty group_by with read_group?
if (!_(group_by).isEmpty()) {
self.abscissa = group_by[0];
} else {
self.abscissa = self.first_field;
}
self.dataset.read_slice(self.list_fields(), {
context: results.context,
domain: results.domain
}, $.proxy(self, 'schedule_chart'));
return self.dataset.read_slice(self.list_fields(), {}, $.proxy(self, 'schedule_chart'));
});
}
});

View File

@ -1,5 +1,6 @@
{
"name": "Hello",
"category" : "Hidden",
"version": "2.0",
"depends": [],
"js": ["static/*/*.js", "static/*/js/*.js"],

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"

View File

@ -1,5 +1,6 @@
{
"name" : "Base Kanban",
"category" : "Hidden",
"version" : "2.0",
"depends" : ["web"],
"js": [

View File

@ -9,8 +9,6 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
this.set_default_options(options);
this.dataset = dataset;
this.model = dataset.model;
this.domain = dataset.domain;
this.context = dataset.context;
this.view_id = view_id;
this.fields_view = {};
this.group_by = [];
@ -33,9 +31,6 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
var self = this;
this.fields_view = data;
this.add_qweb_template();
if (this.qweb.has_template('kanban-box')) {
this.do_actual_search();
}
},
add_qweb_template: function() {
var group_operator = ["avg", "max", "min", "sum", "count"]
@ -294,7 +289,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
this.do_execute_action(
button_attrs, dataset,
record_id, function () {
self.do_actual_search();
self.on_reload_record(record_id);
}
);
},
@ -427,28 +422,18 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
});
return new_record;
},
do_search: function (domains, contexts, group_by) {
do_search: function (domain, context, group_by) {
var self = this;
this.rpc('/web/session/eval_domain_and_context', {
domains: [this.dataset.get_domain()].concat(domains),
contexts: [this.dataset.get_context()].concat(contexts),
group_by_seq: group_by
}, function (results) {
self.domain = results.domain;
self.context = results.context;
self.group_by = results.group_by;
self.do_actual_search();
});
},
do_actual_search : function () {
self.group_by = group_by;
var self = this,
group_by = self.group_by;
if (!group_by.length && this.fields_view.arch.attrs.default_group_by) {
group_by = [this.fields_view.arch.attrs.default_group_by];
self.group_by = group_by;
}
self.datagroup = new openerp.web.DataGroup(self, self.model, self.domain, self.context, group_by);
self.datagroup.list(_.keys(self.fields_view.fields),
self.datagroup = new openerp.web.DataGroup(self, self.model, domain, context, group_by);
self.datagroup.list(
_.keys(self.fields_view.fields),
function (groups) {
self.groups = groups;
if (groups.length) {
@ -461,9 +446,12 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
},
function (dataset) {
self.groups = [];
self.dataset.read_slice([], {'domain': self.domain, 'context': self.context}, function(records) {
if (records.length) self.all_display_data = [{'records': records, 'value':false, 'header' : false, 'ids': self.dataset.ids}];
else self.all_display_data = [];
self.dataset.read_slice([], {}, function(records) {
if (records.length) {
self.all_display_data = [{'records': records, 'value':false, 'header' : false, 'ids': self.dataset.ids}];
} else {
self.all_display_data = [];
}
self.$element.find(".oe_kanban_view").remove();
self.on_show_data();
});
@ -487,7 +475,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
_.each(self.aggregates, function(value, key) {
group_aggregates[value] = group.aggregates[key];
});
self.dataset.read_slice([], {'domain': group.domain, 'context': group.context}, function(records) {
self.dataset.read_slice([], {'domain': group.domain, 'conext': group.context}, function(records) {
self.all_display_data.push({"value" : group_value, "records": records, 'header':group_name, 'ids': self.dataset.ids, 'aggregates': group_aggregates});
if (datagroups.length == self.all_display_data.length) {
self.$element.find(".oe_kanban_view").remove();

View File

@ -1,5 +1,6 @@
{
"name" : "OpenERP Web mobile",
"category" : "Hidden",
"version" : "2.0",
"depends" : [],
'active': True,

View File

@ -0,0 +1,66 @@
# 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:54+0000\n"
"Last-Translator: Jonas Mortensen <Unknown>\n"
"Language-Team: Danish <da@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-10-12 04:44+0000\n"
"X-Generator: Launchpad (build 14124)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
msgstr "OpenERP"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Database:"
msgstr "Database:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Login:"
msgstr "Log ind:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Password:"
msgstr "Adgangskode:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Login"
msgstr "Log ind"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Bad username or password"
msgstr "Forkert brugernavn eller adgangskode"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Favourite"
msgstr "Favorit"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Preference"
msgstr "Præference"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Applications"
msgstr "Applikationer"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Options"
msgstr "Indstillinger"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Logout"
msgstr "Log ud"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid ":"
msgstr ":"

View File

@ -0,0 +1,66 @@
# 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:36+0000\n"
"Last-Translator: Felix Schubert <Unknown>\n"
"Language-Team: German <de@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
"X-Generator: Launchpad (build 14123)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
msgstr "OpenERP"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Database:"
msgstr "Datenbank:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Login:"
msgstr "Benutzername:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Password:"
msgstr "Passwort:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Login"
msgstr "Anmeldung"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Bad username or password"
msgstr "Falscher Benutzername oder Passwort"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Favourite"
msgstr "Favorit"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Preference"
msgstr "Einstellungen"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Applications"
msgstr "Anwendungen"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Options"
msgstr "Einstellungen"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Logout"
msgstr "Abmeldung"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid ":"
msgstr ":"

View File

@ -0,0 +1,66 @@
# 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 17:50+0000\n"
"Last-Translator: Cristian Salamea (Gnuthink) <ovnicraft@gmail.com>\n"
"Language-Team: Spanish (Ecuador) <es_EC@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
"X-Generator: Launchpad (build 14110)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
msgstr "OpenERP"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Database:"
msgstr "Base de datos:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Login:"
msgstr "Iniciar sesión:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Password:"
msgstr "Contraseña:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Login"
msgstr "Iniciar sesión"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Bad username or password"
msgstr "Usuario o contraseña incorrecta"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Favourite"
msgstr "Favorito"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Preference"
msgstr "Preferencia"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Applications"
msgstr "Aplicaciones"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Options"
msgstr "Opciones"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Logout"
msgstr "Salir"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid ":"
msgstr ":"

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