[MERGE] trunk.
bzr revid: vda@tinyerp.com-20111123102917-w5tbmo4fox75t6mz
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
"static/lib/jquery.ui.notify/js/jquery.notify.js",
|
||||
"static/lib/jquery.deferred-queue/jquery.deferred-queue.js",
|
||||
"static/lib/jquery.scrollTo/jquery.scrollTo-min.js",
|
||||
"static/lib/jquery.tipTip/jquery.tipTip.js",
|
||||
"static/lib/json/json2.js",
|
||||
"static/lib/qweb/qweb2.js",
|
||||
"static/lib/underscore/underscore.js",
|
||||
@@ -50,6 +51,7 @@
|
||||
"static/lib/jquery.superfish/css/superfish.css",
|
||||
"static/lib/jquery.ui/css/smoothness/jquery-ui-1.8.9.custom.css",
|
||||
"static/lib/jquery.ui.notify/css/ui.notify.css",
|
||||
"static/lib/jquery.tipTip/tipTip.css",
|
||||
"static/src/css/base.css",
|
||||
"static/src/css/data_export.css",
|
||||
"static/src/css/data_import.css",
|
||||
|
||||
@@ -403,7 +403,7 @@ class Root(object):
|
||||
request.parameter_storage_class = werkzeug.datastructures.ImmutableDict
|
||||
|
||||
if request.path == '/':
|
||||
params = urllib.urlencode(dict(request.args, debug=''))
|
||||
params = urllib.urlencode(request.args)
|
||||
return werkzeug.utils.redirect(self.root + '?' + params, 301)(
|
||||
environ, start_response)
|
||||
elif request.path == '/mobile':
|
||||
|
||||
@@ -268,13 +268,18 @@ class Database(openerpweb.Controller):
|
||||
params['db_lang'],
|
||||
params['create_admin_pwd']
|
||||
)
|
||||
|
||||
|
||||
try:
|
||||
return req.session.proxy("db").create(*create_attrs)
|
||||
except xmlrpclib.Fault, e:
|
||||
if e.faultCode and e.faultCode.split(':')[0] == 'AccessDenied':
|
||||
return {'error': e.faultCode, 'title': 'Create Database'}
|
||||
return {'error': 'Could not create database !', 'title': 'Create Database'}
|
||||
if e.faultCode and isinstance(e.faultCode, str)\
|
||||
and e.faultCode.split(':')[0] == 'AccessDenied':
|
||||
return {'error': e.faultCode, 'title': 'Database creation error'}
|
||||
return {
|
||||
'error': "Could not create database '%s': %s" % (
|
||||
params['db_name'], e.faultString),
|
||||
'title': 'Database creation error'
|
||||
}
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def drop(self, req, fields):
|
||||
@@ -307,7 +312,7 @@ class Database(openerpweb.Controller):
|
||||
@openerpweb.httprequest
|
||||
def restore(self, req, db_file, restore_pwd, new_db):
|
||||
try:
|
||||
data = base64.b64encode(db_file.file.read())
|
||||
data = base64.b64encode(db_file.read())
|
||||
req.session.proxy("db").restore(restore_pwd, new_db, data)
|
||||
return ''
|
||||
except xmlrpclib.Fault, e:
|
||||
@@ -338,7 +343,8 @@ class Session(openerpweb.Controller):
|
||||
"session_id": req.session_id,
|
||||
"uid": req.session._uid,
|
||||
"context": ctx,
|
||||
"db": req.session._db
|
||||
"db": req.session._db,
|
||||
"login": req.session._login
|
||||
}
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
@@ -347,7 +353,8 @@ class Session(openerpweb.Controller):
|
||||
return {
|
||||
"uid": req.session._uid,
|
||||
"context": req.session.get_context() if req.session._uid else False,
|
||||
"db": req.session._db
|
||||
"db": req.session._db,
|
||||
"login": req.session._login
|
||||
}
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
@@ -935,10 +942,12 @@ class View(openerpweb.Controller):
|
||||
domain = elem.get(el, '').strip()
|
||||
if domain:
|
||||
elem.set(el, parse_domain(domain, session))
|
||||
elem.set(el + '_string', domain)
|
||||
for el in ['context', 'default_get']:
|
||||
context_string = elem.get(el, '').strip()
|
||||
if context_string:
|
||||
elem.set(el, parse_context(context_string, session))
|
||||
elem.set(el + '_string', context_string)
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def load(self, req, model, view_id, view_type, toolbar=False):
|
||||
@@ -1417,6 +1426,7 @@ class ExcelExport(Export):
|
||||
for cell_index, cell_value in enumerate(row):
|
||||
if isinstance(cell_value, basestring):
|
||||
cell_value = re.sub("\r", " ", cell_value)
|
||||
if cell_value is False: cell_value = None
|
||||
worksheet.write(row_index + 1, cell_index, cell_value, style)
|
||||
|
||||
fp = StringIO()
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-09 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14263)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:49+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-09 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14263)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:49+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-05 06:04+0000\n"
|
||||
"X-Generator: Launchpad (build 14231)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
|
||||
@@ -0,0 +1,688 @@
|
||||
# Portuguese translation for openerp-web
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openerp-web package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openerp-web\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||
"PO-Revision-Date: 2011-11-21 22:22+0000\n"
|
||||
"Last-Translator: Daniel Reis <Unknown>\n"
|
||||
"Language-Team: Portuguese <pt@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-22 05:13+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
"Warning, the record has been modified, your changes will be discarded."
|
||||
msgstr ""
|
||||
"Atenção, o o registo foi modificado, as suas alterações serão descartadas."
|
||||
|
||||
#: 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 "Escolha pelo menos um registo."
|
||||
|
||||
#: addons/web/static/src/js/views.js:569
|
||||
msgid "Warning"
|
||||
msgstr "Aviso"
|
||||
|
||||
#: addons/web/static/src/js/views.js:609
|
||||
msgid "Translations"
|
||||
msgstr "Traduções"
|
||||
|
||||
#: 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 "Fechar"
|
||||
|
||||
#: 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 ""
|
||||
|
||||
#: 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 "A carregar ..."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Create"
|
||||
msgstr "Criar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Drop"
|
||||
msgstr "Excluir"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Backup"
|
||||
msgstr "Cópia de segurança"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Restore"
|
||||
msgstr "Restaurar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Password"
|
||||
msgstr "Senha"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Back to Login"
|
||||
msgstr ""
|
||||
|
||||
#: 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 "Nome da nova base de dados"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Load Demonstration data:"
|
||||
msgstr "Carregar dados de demonstração"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Default language:"
|
||||
msgstr "Idioma predefinido:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Admin password:"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Confirm password:"
|
||||
msgstr "Confirmar senha:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "DROP DATABASE"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Database:"
|
||||
msgstr "Base de dados:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Master Password:"
|
||||
msgstr ""
|
||||
|
||||
#: 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 "Ficheiro:"
|
||||
|
||||
#: 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 "Utilizador:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Password:"
|
||||
msgstr "Senha:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Database"
|
||||
msgstr "Base de dados"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Login"
|
||||
msgstr "Iniciar sessão"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Bad username or password"
|
||||
msgstr "Nome de utilizador ou senha 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 as atividades do trabalho diário pode ser mais intuitivas, "
|
||||
"eficientes, automatizadas, ... e até mesmo divertidas."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "OpenERP's vision to be:"
|
||||
msgstr "A visão do OpenERP é:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Full featured"
|
||||
msgstr "Pleno de funcionalidade"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ""
|
||||
"Today's enterprise challenges are multiple. We provide one module for each "
|
||||
"need."
|
||||
msgstr ""
|
||||
"Os desafios atuais das empresas são múltiplos. Nós fornecemos um módulo para "
|
||||
"cada necessidade."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Open Source"
|
||||
msgstr "Código aberto"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ""
|
||||
"To Build a great product, we rely on the knowledge of thousands of "
|
||||
"contributors."
|
||||
msgstr ""
|
||||
"Para construir um grande produto, nós contamos com o conhecimento de "
|
||||
"milhares de contribuidores."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "User Friendly"
|
||||
msgstr "Amigável para o utilizador"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ""
|
||||
"In order to be productive, people need clean and easy to use interface."
|
||||
msgstr ""
|
||||
"Para serem produtivas, as pessoas precisam de uma interface simples e 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 "SAIR"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "«"
|
||||
msgstr "«"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "»"
|
||||
msgstr "»"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "oe_secondary_menu_item"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "oe_secondary_submenu_item"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Hide this tip"
|
||||
msgstr "Ocultar esta dica"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Disable all tips"
|
||||
msgstr "Desativar todas as dicas"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "View#"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Fields"
|
||||
msgstr "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 ""
|
||||
|
||||
#: 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 "Traduzir vista"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Translate sidebar"
|
||||
msgstr "Traduzir barra lateral"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Delete"
|
||||
msgstr "Apagar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "First"
|
||||
msgstr "Primeiro"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "<"
|
||||
msgstr "<"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ">"
|
||||
msgstr ">"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Last"
|
||||
msgstr "Último"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "♻"
|
||||
msgstr "♻"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save & Edit"
|
||||
msgstr "Gravar & Editar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Create & Edit"
|
||||
msgstr "Criar & Editar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "New"
|
||||
msgstr "Novo"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Duplicate"
|
||||
msgstr "Duplicar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Readonly/Editable"
|
||||
msgstr ""
|
||||
|
||||
#: 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 "Acrescentar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Unhandled widget"
|
||||
msgstr "Widget não tratado"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "?"
|
||||
msgstr "?"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "#"
|
||||
msgstr "#"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Done"
|
||||
msgstr "Concluído"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Open..."
|
||||
msgstr "Abrir..."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Create..."
|
||||
msgstr "Criar..."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Search..."
|
||||
msgstr "Procurar..."
|
||||
|
||||
#: 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 "Selecionar"
|
||||
|
||||
#: 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 "Limpar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Advanced Filter"
|
||||
msgstr "Filtro avançados"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "-- Filters --"
|
||||
msgstr "-- Filtros --"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "-- Actions --"
|
||||
msgstr "-- Ações --"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save Filter"
|
||||
msgstr "Guardar filtro"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Manage Filters"
|
||||
msgstr "Gerir filtros"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Filter Name:"
|
||||
msgstr "Nome do filtro:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "(Any existing filter with the same name will be replaced)"
|
||||
msgstr "(filtros existentes com esse nome serão substituídos)"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Any of the following conditions must match"
|
||||
msgstr "Deve satisfazer alguma das seguintes condições"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "All the following conditions must match"
|
||||
msgstr "Deve satisfazer toas as seguintes condições"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "None of the following conditions must match"
|
||||
msgstr "Não deve satisfazernenhuma das seguintes condições"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Add condition"
|
||||
msgstr "Acrescentar condição"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "and"
|
||||
msgstr "e"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save & New"
|
||||
msgstr "Guardar & Novo"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save & Close"
|
||||
msgstr "Guardar & Fechar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Export"
|
||||
msgstr "Exportar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ""
|
||||
"This wizard will export all data that matches the current search criteria to "
|
||||
"a CSV file.\n"
|
||||
" You can export all data or only the fields that can be "
|
||||
"reimported after modification."
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Export Type:"
|
||||
msgstr "Tipo de exportação:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Import Compatible Export"
|
||||
msgstr "Exportação compatível com importação"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Export all Data"
|
||||
msgstr "Exportar todos os dados"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Export Formats"
|
||||
msgstr "Formatos de exportação"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Available fields"
|
||||
msgstr "Campos disponíveis"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Fields to export"
|
||||
msgstr "Campos a exportar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save fields list"
|
||||
msgstr "Gravar lista de campos"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Remove"
|
||||
msgstr "Remover"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Remove All"
|
||||
msgstr "Remover tudo"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid " "
|
||||
msgstr " "
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save as:"
|
||||
msgstr "Guardar como:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Ok"
|
||||
msgstr "Ok"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Saved exports:"
|
||||
msgstr "Exportações guardadas:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Old Password:"
|
||||
msgstr "Senha antiga:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "New Password:"
|
||||
msgstr "Nova senha:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Confirm Password:"
|
||||
msgstr "Confirme a senha:"
|
||||
|
||||
#: 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 um ficheiro .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 "Ficheiro CSV:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "2. Check your file format"
|
||||
msgstr "2. Verifique o formato do ficheiro"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Import Options"
|
||||
msgstr "Opções de importação"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Does your file have titles?"
|
||||
msgstr "O ficheiro tem 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 "Codificação:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "UTF-8"
|
||||
msgstr "UTF-8"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Latin 1"
|
||||
msgstr "Latin-1"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Lines to skip"
|
||||
msgstr "Linhas a ignorar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "The import failed due to:"
|
||||
msgstr "Importação falhou devido a:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Here is a preview of the file we could not import:"
|
||||
msgstr "Previsão do ficheiro que não conseguiu ser importado:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "OpenERP Web"
|
||||
msgstr "OpenERP Web"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Version"
|
||||
msgstr "Versão"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||
msgstr "Copyright © 2011-HOJE OpenERP SA. Todos os direitos reservados."
|
||||
|
||||
#: 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 "Acerca do 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 ""
|
||||
"Dependendo de suas necessidades, o OpenERP está disponível através da web ou "
|
||||
"de uma aplicação cliente."
|
||||
@@ -0,0 +1,683 @@
|
||||
# Brazilian Portuguese translation for openerp-web
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openerp-web package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openerp-web\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||
"PO-Revision-Date: 2011-11-12 18:57+0000\n"
|
||||
"Last-Translator: Cristiano Gavião <Unknown>\n"
|
||||
"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
"Warning, the record has been modified, your changes will be discarded."
|
||||
msgstr "Aviso, o registro foi modificado, suas alterações serão descartadas."
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:1659
|
||||
msgid "<em> Search More...</em>"
|
||||
msgstr "<em> Procurar Mais...</em>"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:1672
|
||||
#, python-format
|
||||
msgid "<em> Create \"<strong>%s</strong>\"</em>"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:1678
|
||||
msgid "<em> Create and Edit...</em>"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/js/views.js:568
|
||||
msgid "You must choose at least one record."
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/js/views.js:569
|
||||
msgid "Warning"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/js/views.js:609
|
||||
msgid "Translations"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/js/views.js:615
|
||||
msgid "Close"
|
||||
msgstr "Fechar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "x"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "#{title}"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "#{text}"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Powered by"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "openerp.com"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "."
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Loading..."
|
||||
msgstr "Carregando..."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Create"
|
||||
msgstr "Criar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Drop"
|
||||
msgstr "Soltar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Backup"
|
||||
msgstr "Cópia de Segurança"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Restore"
|
||||
msgstr "Restaurar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Password"
|
||||
msgstr "Senha"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Back to Login"
|
||||
msgstr "Voltar ao Login"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "CREATE DATABASE"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Master password:"
|
||||
msgstr "Senha mestre"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "New database name:"
|
||||
msgstr "Nome da nova base de dados:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Load Demonstration data:"
|
||||
msgstr "Carregar dados de demonstração:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Default language:"
|
||||
msgstr "Idioma padrão:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Admin password:"
|
||||
msgstr "Senha de Administrador"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Confirm password:"
|
||||
msgstr "Confirme a senha:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "DROP DATABASE"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Database:"
|
||||
msgstr "Base de dados:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Master Password:"
|
||||
msgstr "Senha Mestre"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "BACKUP DATABASE"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "RESTORE DATABASE"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "File:"
|
||||
msgstr "Arquivo:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "CHANGE MASTER PASSWORD"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "New master password:"
|
||||
msgstr "Nova senha mestre:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Confirm new master password:"
|
||||
msgstr "Confirme nova senha mestre"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "User:"
|
||||
msgstr "Usuário:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Password:"
|
||||
msgstr "Senha:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Database"
|
||||
msgstr "Base de dados"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Login"
|
||||
msgstr "Autenticação"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Bad username or password"
|
||||
msgstr "Nome de usuário ou senha inválido"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ""
|
||||
"We think that daily job activities can be more intuitive, efficient, "
|
||||
"automated, .. and even fun."
|
||||
msgstr ""
|
||||
"Pensamos que as atividades de trabalho diário pode ser mais intuitivas, "
|
||||
"eficiente, automatizadas .. e até mesmo divertidas."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "OpenERP's vision to be:"
|
||||
msgstr "OpenERP vislumbra ser:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Full featured"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ""
|
||||
"Today's enterprise challenges are multiple. We provide one module for each "
|
||||
"need."
|
||||
msgstr ""
|
||||
"Os desafios atuais da empresa são múltiplos. Nós fornecemos um módulo para "
|
||||
"cada necessidade."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Open Source"
|
||||
msgstr "Código Aberto"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ""
|
||||
"To Build a great product, we rely on the knowledge of thousands of "
|
||||
"contributors."
|
||||
msgstr ""
|
||||
"Para construir um grande produto, contamos com o conhecimento de milhares de "
|
||||
"contribuintes."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "User Friendly"
|
||||
msgstr "Uso Amigável"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ""
|
||||
"In order to be productive, people need clean and easy to use interface."
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "("
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ")"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "LOGOUT"
|
||||
msgstr "DESCONECTAR"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "«"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "»"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "oe_secondary_menu_item"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "oe_secondary_submenu_item"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Hide this tip"
|
||||
msgstr "Esconder dica"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Disable all tips"
|
||||
msgstr "Desligar todas as dicas"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "View#"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Fields"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "View labels"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Sidebar Relates"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Field"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ":"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Translate view"
|
||||
msgstr "Visão de Tradução"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Translate sidebar"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Delete"
|
||||
msgstr "Excluir"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "First"
|
||||
msgstr "Primeiro"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "<"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ">"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Last"
|
||||
msgstr "Último"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "♻"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save & Edit"
|
||||
msgstr "Salvar & Editar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Create & Edit"
|
||||
msgstr "Criar & Editar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "New"
|
||||
msgstr "Novo"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Duplicate"
|
||||
msgstr "Duplicar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Readonly/Editable"
|
||||
msgstr "Apenas Leitura/Editável"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "<<"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "0"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "/"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ">>"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Add"
|
||||
msgstr "Adicionar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Unhandled widget"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "?"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "#"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Done"
|
||||
msgstr "Concluído"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Open..."
|
||||
msgstr "Abrir..."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Create..."
|
||||
msgstr "Criar..."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Search..."
|
||||
msgstr "Pesquisar..."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "..."
|
||||
msgstr "..."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Uploading ..."
|
||||
msgstr "Transferindo ..."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Select"
|
||||
msgstr "Selecionar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save As"
|
||||
msgstr "Salvar como"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Clear"
|
||||
msgstr "Limpar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Advanced Filter"
|
||||
msgstr "Filtro Avançado"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "-- Filters --"
|
||||
msgstr "-- Filtros --"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "-- Actions --"
|
||||
msgstr "-- Ações --"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save Filter"
|
||||
msgstr "Salvar filtro"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Manage Filters"
|
||||
msgstr "Gerenciar Filtros"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Filter Name:"
|
||||
msgstr "Nome do Filtro"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "(Any existing filter with the same name will be replaced)"
|
||||
msgstr "(Qualquer filtro existente com o mesmo nome será substituído)"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Any of the following conditions must match"
|
||||
msgstr "Qualquer das seguintes condições deve ser verdadeira"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "All the following conditions must match"
|
||||
msgstr "Todas as seguintes condições devem ser verdadeiras"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "None of the following conditions must match"
|
||||
msgstr "Nenhuma das seguintes condições deve ser verdadeira"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Add condition"
|
||||
msgstr "Adicionar condição"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "and"
|
||||
msgstr "e"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save & New"
|
||||
msgstr "Salvar & Novo"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save & Close"
|
||||
msgstr "Salvar & Fechar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Export"
|
||||
msgstr "Exportar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ""
|
||||
"This wizard will export all data that matches the current search criteria to "
|
||||
"a CSV file.\n"
|
||||
" You can export all data or only the fields that can be "
|
||||
"reimported after modification."
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Export Type:"
|
||||
msgstr "Tipo de Exportação:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Import Compatible Export"
|
||||
msgstr "Importar Exportação Compatível"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Export all Data"
|
||||
msgstr "Exportar todos os Dados"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Export Formats"
|
||||
msgstr "Formatos de Exportação"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Available fields"
|
||||
msgstr "Campos Disponíveis"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Fields to export"
|
||||
msgstr "Campos para exportar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save fields list"
|
||||
msgstr "Salvar lista de campos"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Remove"
|
||||
msgstr "Remover"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Remove All"
|
||||
msgstr "Remover Tudo"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid " "
|
||||
msgstr " "
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Save as:"
|
||||
msgstr "Salvar como:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Ok"
|
||||
msgstr "Ok"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Saved exports:"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Old Password:"
|
||||
msgstr "Senha antiga"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "New Password:"
|
||||
msgstr "Nova Senha:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Confirm Password:"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Import"
|
||||
msgstr "Importar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "1. Import a .CSV file"
|
||||
msgstr "Importar um arquivo CSV."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ""
|
||||
"Select a .CSV file to import. If you need a sample of file to import,\n"
|
||||
" you should use the export tool with the \"Import Compatible\" option."
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "CSV File:"
|
||||
msgstr "Arquivo CSV."
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "2. Check your file format"
|
||||
msgstr "Verifique seu formato de arquivo"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Import Options"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Does your file have titles?"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Separator:"
|
||||
msgstr "Separador:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Delimiter:"
|
||||
msgstr "Delimitador:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Encoding:"
|
||||
msgstr "Codificação:"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "UTF-8"
|
||||
msgstr "UTF-8"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Latin 1"
|
||||
msgstr "Latin 1"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Lines to skip"
|
||||
msgstr "Linhas para ignorar"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "The import failed due to:"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Here is a preview of the file we could not import:"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "OpenERP Web"
|
||||
msgstr "OpenERP Web"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Version"
|
||||
msgstr "Versão"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "OpenERP is a trademark of the"
|
||||
msgstr "OpenERP é uma marca de"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "OpenERP SA Company"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "Licenced under the terms of"
|
||||
msgstr "Licenciado sobre os termos de"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "GNU Affero General Public License"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "About OpenERP"
|
||||
msgstr "Sobre OpenERP"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid "OpenERP"
|
||||
msgstr "OpenERP"
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ""
|
||||
"is a free enterprise-scale software system that is designed to boost\n"
|
||||
" productivity and profit through data integration. It connects, "
|
||||
"improves and\n"
|
||||
" manages business processes in areas such as sales, finance, "
|
||||
"supply chain,\n"
|
||||
" project management, production, services, CRM, etc..."
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ""
|
||||
"The system is platform-independent, and can be installed on Windows, Mac OS "
|
||||
"X,\n"
|
||||
" and various Linux and other Unix-based distributions. Its "
|
||||
"architecture enables\n"
|
||||
" new functionality to be rapidly created, modifications to be "
|
||||
"made to a\n"
|
||||
" production system and migration to a new version to be "
|
||||
"straightforward."
|
||||
msgstr ""
|
||||
|
||||
#: addons/web/static/src/xml/base.xml:0
|
||||
msgid ""
|
||||
"Depending on your needs, OpenERP is available through a web or application "
|
||||
"client."
|
||||
msgstr ""
|
||||
+2
-2
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web/static/src/js/view_form.js:355
|
||||
msgid ""
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
--- jquery.tipTip_old.js 2011-11-14 21:40:55.000000000 +0100
|
||||
+++ jquery.tipTip.js 2011-11-15 10:09:35.000000000 +0100
|
||||
@@ -31,7 +31,7 @@
|
||||
fadeIn: 200,
|
||||
fadeOut: 200,
|
||||
attribute: "title",
|
||||
- content: false, // HTML or String to fill TipTIp with
|
||||
+ content: false, // HTML String or function to fill TipTIp with
|
||||
enter: function(){},
|
||||
exit: function(){}
|
||||
};
|
||||
@@ -51,12 +51,7 @@
|
||||
|
||||
return this.each(function(){
|
||||
var org_elem = $(this);
|
||||
- if(opts.content){
|
||||
- var org_title = opts.content;
|
||||
- } else {
|
||||
- var org_title = org_elem.attr(opts.attribute);
|
||||
- }
|
||||
- if(org_title != ""){
|
||||
+ if(opts.content || org_elem.attr(opts.attribute)){
|
||||
if(!opts.content){
|
||||
org_elem.removeAttr(opts.attribute); //remove original Attribute
|
||||
}
|
||||
@@ -99,6 +94,8 @@
|
||||
|
||||
function active_tiptip(){
|
||||
opts.enter.call(this);
|
||||
+ var org_title = typeof opts.content === 'function' ? opts.content() : opts.content;
|
||||
+ org_title = org_title || org_elem.attr(opts.attribute);
|
||||
tiptip_content.html(org_title);
|
||||
tiptip_holder.hide().removeAttr("class").css("margin","0");
|
||||
tiptip_arrow.removeAttr("style");
|
||||
@@ -176,8 +173,15 @@
|
||||
tiptip_arrow.css({"margin-left": arrow_left+"px", "margin-top": arrow_top+"px"});
|
||||
tiptip_holder.css({"margin-left": marg_left+"px", "margin-top": marg_top+"px"}).attr("class","tip"+t_class);
|
||||
|
||||
- if (timeout){ clearTimeout(timeout); }
|
||||
- timeout = setTimeout(function(){ tiptip_holder.stop(true,true).fadeIn(opts.fadeIn); }, opts.delay);
|
||||
+ if (timeout) {
|
||||
+ clearTimeout(timeout);
|
||||
+ }
|
||||
+ timeout = setTimeout(function() {
|
||||
+ tiptip_holder.stop(true,true);
|
||||
+ if ($.contains(document.documentElement, org_elem[0])) {
|
||||
+ tiptip_holder.fadeIn(opts.fadeIn);
|
||||
+ }
|
||||
+ }, opts.delay);
|
||||
}
|
||||
|
||||
function deactive_tiptip(){
|
||||
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* TipTip
|
||||
* Copyright 2010 Drew Wilson
|
||||
* www.drewwilson.com
|
||||
* code.drewwilson.com/entry/tiptip-jquery-plugin
|
||||
*
|
||||
* Version 1.3 - Updated: Mar. 23, 2010
|
||||
*
|
||||
* This Plug-In will create a custom tooltip to replace the default
|
||||
* browser tooltip. It is extremely lightweight and very smart in
|
||||
* that it detects the edges of the browser window and will make sure
|
||||
* the tooltip stays within the current window size. As a result the
|
||||
* tooltip will adjust itself to be displayed above, below, to the left
|
||||
* or to the right depending on what is necessary to stay within the
|
||||
* browser window. It is completely customizable as well via CSS.
|
||||
*
|
||||
* This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
|
||||
(function($){
|
||||
$.fn.tipTip = function(options) {
|
||||
var defaults = {
|
||||
activation: "hover",
|
||||
keepAlive: false,
|
||||
maxWidth: "200px",
|
||||
edgeOffset: 3,
|
||||
defaultPosition: "bottom",
|
||||
delay: 400,
|
||||
fadeIn: 200,
|
||||
fadeOut: 200,
|
||||
attribute: "title",
|
||||
content: false, // HTML String or function to fill TipTIp with
|
||||
enter: function(){},
|
||||
exit: function(){}
|
||||
};
|
||||
var opts = $.extend(defaults, options);
|
||||
|
||||
// Setup tip tip elements and render them to the DOM
|
||||
if($("#tiptip_holder").length <= 0){
|
||||
var tiptip_holder = $('<div id="tiptip_holder" style="max-width:'+ opts.maxWidth +';"></div>');
|
||||
var tiptip_content = $('<div id="tiptip_content"></div>');
|
||||
var tiptip_arrow = $('<div id="tiptip_arrow"></div>');
|
||||
$("body").append(tiptip_holder.html(tiptip_content).prepend(tiptip_arrow.html('<div id="tiptip_arrow_inner"></div>')));
|
||||
} else {
|
||||
var tiptip_holder = $("#tiptip_holder");
|
||||
var tiptip_content = $("#tiptip_content");
|
||||
var tiptip_arrow = $("#tiptip_arrow");
|
||||
}
|
||||
|
||||
return this.each(function(){
|
||||
var org_elem = $(this);
|
||||
if(opts.content || org_elem.attr(opts.attribute)){
|
||||
if(!opts.content){
|
||||
org_elem.removeAttr(opts.attribute); //remove original Attribute
|
||||
}
|
||||
var timeout = false;
|
||||
|
||||
if(opts.activation == "hover"){
|
||||
org_elem.hover(function(){
|
||||
active_tiptip();
|
||||
}, function(){
|
||||
if(!opts.keepAlive){
|
||||
deactive_tiptip();
|
||||
}
|
||||
});
|
||||
if(opts.keepAlive){
|
||||
tiptip_holder.hover(function(){}, function(){
|
||||
deactive_tiptip();
|
||||
});
|
||||
}
|
||||
} else if(opts.activation == "focus"){
|
||||
org_elem.focus(function(){
|
||||
active_tiptip();
|
||||
}).blur(function(){
|
||||
deactive_tiptip();
|
||||
});
|
||||
} else if(opts.activation == "click"){
|
||||
org_elem.click(function(){
|
||||
active_tiptip();
|
||||
return false;
|
||||
}).hover(function(){},function(){
|
||||
if(!opts.keepAlive){
|
||||
deactive_tiptip();
|
||||
}
|
||||
});
|
||||
if(opts.keepAlive){
|
||||
tiptip_holder.hover(function(){}, function(){
|
||||
deactive_tiptip();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function active_tiptip(){
|
||||
opts.enter.call(this);
|
||||
var org_title = typeof opts.content === 'function' ? opts.content() : opts.content;
|
||||
org_title = org_title || org_elem.attr(opts.attribute);
|
||||
tiptip_content.html(org_title);
|
||||
tiptip_holder.hide().removeAttr("class").css("margin","0");
|
||||
tiptip_arrow.removeAttr("style");
|
||||
|
||||
var top = parseInt(org_elem.offset()['top']);
|
||||
var left = parseInt(org_elem.offset()['left']);
|
||||
var org_width = parseInt(org_elem.outerWidth());
|
||||
var org_height = parseInt(org_elem.outerHeight());
|
||||
var tip_w = tiptip_holder.outerWidth();
|
||||
var tip_h = tiptip_holder.outerHeight();
|
||||
var w_compare = Math.round((org_width - tip_w) / 2);
|
||||
var h_compare = Math.round((org_height - tip_h) / 2);
|
||||
var marg_left = Math.round(left + w_compare);
|
||||
var marg_top = Math.round(top + org_height + opts.edgeOffset);
|
||||
var t_class = "";
|
||||
var arrow_top = "";
|
||||
var arrow_left = Math.round(tip_w - 12) / 2;
|
||||
|
||||
if(opts.defaultPosition == "bottom"){
|
||||
t_class = "_bottom";
|
||||
} else if(opts.defaultPosition == "top"){
|
||||
t_class = "_top";
|
||||
} else if(opts.defaultPosition == "left"){
|
||||
t_class = "_left";
|
||||
} else if(opts.defaultPosition == "right"){
|
||||
t_class = "_right";
|
||||
}
|
||||
|
||||
var right_compare = (w_compare + left) < parseInt($(window).scrollLeft());
|
||||
var left_compare = (tip_w + left) > parseInt($(window).width());
|
||||
|
||||
if((right_compare && w_compare < 0) || (t_class == "_right" && !left_compare) || (t_class == "_left" && left < (tip_w + opts.edgeOffset + 5))){
|
||||
t_class = "_right";
|
||||
arrow_top = Math.round(tip_h - 13) / 2;
|
||||
arrow_left = -12;
|
||||
marg_left = Math.round(left + org_width + opts.edgeOffset);
|
||||
marg_top = Math.round(top + h_compare);
|
||||
} else if((left_compare && w_compare < 0) || (t_class == "_left" && !right_compare)){
|
||||
t_class = "_left";
|
||||
arrow_top = Math.round(tip_h - 13) / 2;
|
||||
arrow_left = Math.round(tip_w);
|
||||
marg_left = Math.round(left - (tip_w + opts.edgeOffset + 5));
|
||||
marg_top = Math.round(top + h_compare);
|
||||
}
|
||||
|
||||
var top_compare = (top + org_height + opts.edgeOffset + tip_h + 8) > parseInt($(window).height() + $(window).scrollTop());
|
||||
var bottom_compare = ((top + org_height) - (opts.edgeOffset + tip_h + 8)) < 0;
|
||||
|
||||
if(top_compare || (t_class == "_bottom" && top_compare) || (t_class == "_top" && !bottom_compare)){
|
||||
if(t_class == "_top" || t_class == "_bottom"){
|
||||
t_class = "_top";
|
||||
} else {
|
||||
t_class = t_class+"_top";
|
||||
}
|
||||
arrow_top = tip_h;
|
||||
marg_top = Math.round(top - (tip_h + 5 + opts.edgeOffset));
|
||||
} else if(bottom_compare | (t_class == "_top" && bottom_compare) || (t_class == "_bottom" && !top_compare)){
|
||||
if(t_class == "_top" || t_class == "_bottom"){
|
||||
t_class = "_bottom";
|
||||
} else {
|
||||
t_class = t_class+"_bottom";
|
||||
}
|
||||
arrow_top = -12;
|
||||
marg_top = Math.round(top + org_height + opts.edgeOffset);
|
||||
}
|
||||
|
||||
if(t_class == "_right_top" || t_class == "_left_top"){
|
||||
marg_top = marg_top + 5;
|
||||
} else if(t_class == "_right_bottom" || t_class == "_left_bottom"){
|
||||
marg_top = marg_top - 5;
|
||||
}
|
||||
if(t_class == "_left_top" || t_class == "_left_bottom"){
|
||||
marg_left = marg_left + 5;
|
||||
}
|
||||
tiptip_arrow.css({"margin-left": arrow_left+"px", "margin-top": arrow_top+"px"});
|
||||
tiptip_holder.css({"margin-left": marg_left+"px", "margin-top": marg_top+"px"}).attr("class","tip"+t_class);
|
||||
|
||||
if (timeout){ clearTimeout(timeout); }
|
||||
timeout = setTimeout(function() {
|
||||
tiptip_holder.stop(true,true);
|
||||
if ($.contains(document.documentElement, org_elem[0])) {
|
||||
tiptip_holder.fadeIn(opts.fadeIn);
|
||||
}
|
||||
}, opts.delay);
|
||||
}
|
||||
|
||||
function deactive_tiptip(){
|
||||
opts.exit.call(this);
|
||||
if (timeout){ clearTimeout(timeout); }
|
||||
tiptip_holder.fadeOut(opts.fadeOut);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* TipTip
|
||||
* Copyright 2010 Drew Wilson
|
||||
* www.drewwilson.com
|
||||
* code.drewwilson.com/entry/tiptip-jquery-plugin
|
||||
*
|
||||
* Version 1.3 - Updated: Mar. 23, 2010
|
||||
*
|
||||
* This Plug-In will create a custom tooltip to replace the default
|
||||
* browser tooltip. It is extremely lightweight and very smart in
|
||||
* that it detects the edges of the browser window and will make sure
|
||||
* the tooltip stays within the current window size. As a result the
|
||||
* tooltip will adjust itself to be displayed above, below, to the left
|
||||
* or to the right depending on what is necessary to stay within the
|
||||
* browser window. It is completely customizable as well via CSS.
|
||||
*
|
||||
* This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
|
||||
(function($){
|
||||
$.fn.tipTip = function(options) {
|
||||
var defaults = {
|
||||
activation: "hover",
|
||||
keepAlive: false,
|
||||
maxWidth: "200px",
|
||||
edgeOffset: 3,
|
||||
defaultPosition: "bottom",
|
||||
delay: 400,
|
||||
fadeIn: 200,
|
||||
fadeOut: 200,
|
||||
attribute: "title",
|
||||
content: false, // HTML or String to fill TipTIp with
|
||||
enter: function(){},
|
||||
exit: function(){}
|
||||
};
|
||||
var opts = $.extend(defaults, options);
|
||||
|
||||
// Setup tip tip elements and render them to the DOM
|
||||
if($("#tiptip_holder").length <= 0){
|
||||
var tiptip_holder = $('<div id="tiptip_holder" style="max-width:'+ opts.maxWidth +';"></div>');
|
||||
var tiptip_content = $('<div id="tiptip_content"></div>');
|
||||
var tiptip_arrow = $('<div id="tiptip_arrow"></div>');
|
||||
$("body").append(tiptip_holder.html(tiptip_content).prepend(tiptip_arrow.html('<div id="tiptip_arrow_inner"></div>')));
|
||||
} else {
|
||||
var tiptip_holder = $("#tiptip_holder");
|
||||
var tiptip_content = $("#tiptip_content");
|
||||
var tiptip_arrow = $("#tiptip_arrow");
|
||||
}
|
||||
|
||||
return this.each(function(){
|
||||
var org_elem = $(this);
|
||||
if(opts.content){
|
||||
var org_title = opts.content;
|
||||
} else {
|
||||
var org_title = org_elem.attr(opts.attribute);
|
||||
}
|
||||
if(org_title != ""){
|
||||
if(!opts.content){
|
||||
org_elem.removeAttr(opts.attribute); //remove original Attribute
|
||||
}
|
||||
var timeout = false;
|
||||
|
||||
if(opts.activation == "hover"){
|
||||
org_elem.hover(function(){
|
||||
active_tiptip();
|
||||
}, function(){
|
||||
if(!opts.keepAlive){
|
||||
deactive_tiptip();
|
||||
}
|
||||
});
|
||||
if(opts.keepAlive){
|
||||
tiptip_holder.hover(function(){}, function(){
|
||||
deactive_tiptip();
|
||||
});
|
||||
}
|
||||
} else if(opts.activation == "focus"){
|
||||
org_elem.focus(function(){
|
||||
active_tiptip();
|
||||
}).blur(function(){
|
||||
deactive_tiptip();
|
||||
});
|
||||
} else if(opts.activation == "click"){
|
||||
org_elem.click(function(){
|
||||
active_tiptip();
|
||||
return false;
|
||||
}).hover(function(){},function(){
|
||||
if(!opts.keepAlive){
|
||||
deactive_tiptip();
|
||||
}
|
||||
});
|
||||
if(opts.keepAlive){
|
||||
tiptip_holder.hover(function(){}, function(){
|
||||
deactive_tiptip();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function active_tiptip(){
|
||||
opts.enter.call(this);
|
||||
tiptip_content.html(org_title);
|
||||
tiptip_holder.hide().removeAttr("class").css("margin","0");
|
||||
tiptip_arrow.removeAttr("style");
|
||||
|
||||
var top = parseInt(org_elem.offset()['top']);
|
||||
var left = parseInt(org_elem.offset()['left']);
|
||||
var org_width = parseInt(org_elem.outerWidth());
|
||||
var org_height = parseInt(org_elem.outerHeight());
|
||||
var tip_w = tiptip_holder.outerWidth();
|
||||
var tip_h = tiptip_holder.outerHeight();
|
||||
var w_compare = Math.round((org_width - tip_w) / 2);
|
||||
var h_compare = Math.round((org_height - tip_h) / 2);
|
||||
var marg_left = Math.round(left + w_compare);
|
||||
var marg_top = Math.round(top + org_height + opts.edgeOffset);
|
||||
var t_class = "";
|
||||
var arrow_top = "";
|
||||
var arrow_left = Math.round(tip_w - 12) / 2;
|
||||
|
||||
if(opts.defaultPosition == "bottom"){
|
||||
t_class = "_bottom";
|
||||
} else if(opts.defaultPosition == "top"){
|
||||
t_class = "_top";
|
||||
} else if(opts.defaultPosition == "left"){
|
||||
t_class = "_left";
|
||||
} else if(opts.defaultPosition == "right"){
|
||||
t_class = "_right";
|
||||
}
|
||||
|
||||
var right_compare = (w_compare + left) < parseInt($(window).scrollLeft());
|
||||
var left_compare = (tip_w + left) > parseInt($(window).width());
|
||||
|
||||
if((right_compare && w_compare < 0) || (t_class == "_right" && !left_compare) || (t_class == "_left" && left < (tip_w + opts.edgeOffset + 5))){
|
||||
t_class = "_right";
|
||||
arrow_top = Math.round(tip_h - 13) / 2;
|
||||
arrow_left = -12;
|
||||
marg_left = Math.round(left + org_width + opts.edgeOffset);
|
||||
marg_top = Math.round(top + h_compare);
|
||||
} else if((left_compare && w_compare < 0) || (t_class == "_left" && !right_compare)){
|
||||
t_class = "_left";
|
||||
arrow_top = Math.round(tip_h - 13) / 2;
|
||||
arrow_left = Math.round(tip_w);
|
||||
marg_left = Math.round(left - (tip_w + opts.edgeOffset + 5));
|
||||
marg_top = Math.round(top + h_compare);
|
||||
}
|
||||
|
||||
var top_compare = (top + org_height + opts.edgeOffset + tip_h + 8) > parseInt($(window).height() + $(window).scrollTop());
|
||||
var bottom_compare = ((top + org_height) - (opts.edgeOffset + tip_h + 8)) < 0;
|
||||
|
||||
if(top_compare || (t_class == "_bottom" && top_compare) || (t_class == "_top" && !bottom_compare)){
|
||||
if(t_class == "_top" || t_class == "_bottom"){
|
||||
t_class = "_top";
|
||||
} else {
|
||||
t_class = t_class+"_top";
|
||||
}
|
||||
arrow_top = tip_h;
|
||||
marg_top = Math.round(top - (tip_h + 5 + opts.edgeOffset));
|
||||
} else if(bottom_compare | (t_class == "_top" && bottom_compare) || (t_class == "_bottom" && !top_compare)){
|
||||
if(t_class == "_top" || t_class == "_bottom"){
|
||||
t_class = "_bottom";
|
||||
} else {
|
||||
t_class = t_class+"_bottom";
|
||||
}
|
||||
arrow_top = -12;
|
||||
marg_top = Math.round(top + org_height + opts.edgeOffset);
|
||||
}
|
||||
|
||||
if(t_class == "_right_top" || t_class == "_left_top"){
|
||||
marg_top = marg_top + 5;
|
||||
} else if(t_class == "_right_bottom" || t_class == "_left_bottom"){
|
||||
marg_top = marg_top - 5;
|
||||
}
|
||||
if(t_class == "_left_top" || t_class == "_left_bottom"){
|
||||
marg_left = marg_left + 5;
|
||||
}
|
||||
tiptip_arrow.css({"margin-left": arrow_left+"px", "margin-top": arrow_top+"px"});
|
||||
tiptip_holder.css({"margin-left": marg_left+"px", "margin-top": marg_top+"px"}).attr("class","tip"+t_class);
|
||||
|
||||
if (timeout){ clearTimeout(timeout); }
|
||||
timeout = setTimeout(function(){ tiptip_holder.stop(true,true).fadeIn(opts.fadeIn); }, opts.delay);
|
||||
}
|
||||
|
||||
function deactive_tiptip(){
|
||||
opts.exit.call(this);
|
||||
if (timeout){ clearTimeout(timeout); }
|
||||
tiptip_holder.fadeOut(opts.fadeOut);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,113 @@
|
||||
/* TipTip CSS - Version 1.2 */
|
||||
|
||||
#tiptip_holder {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_top {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_bottom {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_right {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_left {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
#tiptip_content {
|
||||
font-size: 11px;
|
||||
color: #fff;
|
||||
text-shadow: 0 0 2px #000;
|
||||
padding: 4px 8px;
|
||||
border: 1px solid rgba(255,255,255,0.25);
|
||||
background-color: rgb(25,25,25);
|
||||
background-color: rgba(25,25,25,0.92);
|
||||
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(transparent), to(#000));
|
||||
border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
box-shadow: 0 0 3px #555;
|
||||
-webkit-box-shadow: 0 0 3px #555;
|
||||
-moz-box-shadow: 0 0 3px #555;
|
||||
}
|
||||
|
||||
#tiptip_arrow, #tiptip_arrow_inner {
|
||||
position: absolute;
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
border-width: 6px;
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_top #tiptip_arrow {
|
||||
border-top-color: #fff;
|
||||
border-top-color: rgba(255,255,255,0.35);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_bottom #tiptip_arrow {
|
||||
border-bottom-color: #fff;
|
||||
border-bottom-color: rgba(255,255,255,0.35);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_right #tiptip_arrow {
|
||||
border-right-color: #fff;
|
||||
border-right-color: rgba(255,255,255,0.35);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_left #tiptip_arrow {
|
||||
border-left-color: #fff;
|
||||
border-left-color: rgba(255,255,255,0.35);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_top #tiptip_arrow_inner {
|
||||
margin-top: -7px;
|
||||
margin-left: -6px;
|
||||
border-top-color: rgb(25,25,25);
|
||||
border-top-color: rgba(25,25,25,0.92);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_bottom #tiptip_arrow_inner {
|
||||
margin-top: -5px;
|
||||
margin-left: -6px;
|
||||
border-bottom-color: rgb(25,25,25);
|
||||
border-bottom-color: rgba(25,25,25,0.92);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_right #tiptip_arrow_inner {
|
||||
margin-top: -6px;
|
||||
margin-left: -5px;
|
||||
border-right-color: rgb(25,25,25);
|
||||
border-right-color: rgba(25,25,25,0.92);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_left #tiptip_arrow_inner {
|
||||
margin-top: -6px;
|
||||
margin-left: -7px;
|
||||
border-left-color: rgb(25,25,25);
|
||||
border-left-color: rgba(25,25,25,0.92);
|
||||
}
|
||||
|
||||
/* Webkit Hacks */
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
#tiptip_content {
|
||||
padding: 4px 8px 5px 8px;
|
||||
background-color: rgba(45,45,45,0.88);
|
||||
}
|
||||
#tiptip_holder.tip_bottom #tiptip_arrow_inner {
|
||||
border-bottom-color: rgba(45,45,45,0.88);
|
||||
}
|
||||
#tiptip_holder.tip_top #tiptip_arrow_inner {
|
||||
border-top-color: rgba(20,20,20,0.92);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
// TODO: t-set + t-value + children node == scoped variable ?
|
||||
var QWeb2 = {
|
||||
expressions_cache: {},
|
||||
RESERVED_WORDS: 'true,false,NaN,null,undefined,debugger,in,instanceof,new,function,return,this,typeof,eval,Math,RegExp,Array,Object,Date'.split(','),
|
||||
RESERVED_WORDS: 'true,false,NaN,null,undefined,debugger,console,in,instanceof,new,function,return,this,typeof,eval,Math,RegExp,Array,Object,Date'.split(','),
|
||||
ACTIONS_PRECEDENCE: 'foreach,if,call,set,esc,escf,raw,rawf,js,debug,log'.split(','),
|
||||
WORD_REPLACEMENT: {
|
||||
'and': '&&',
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// Underscore.js 1.2.2
|
||||
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
|
||||
// Underscore is freely distributable under the MIT license.
|
||||
// Portions of Underscore are inspired or borrowed from Prototype,
|
||||
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
||||
// For all details and documentation:
|
||||
// http://documentcloud.github.com/underscore
|
||||
(function(){function r(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(b.isFunction(a.isEqual))return a.isEqual(c);if(b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return String(a)==String(c);case "[object Number]":return a=+a,c=+c,a!=a?c!=c:a==0?1/a==1/c:a==c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
|
||||
c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&r(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(m.call(a,h)&&(f++,!(g=m.call(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(m.call(c,
|
||||
h)&&!f--)break;g=!f}}d.pop();return g}var s=this,F=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,G=k.unshift,l=p.toString,m=p.hasOwnProperty,v=k.forEach,w=k.map,x=k.reduce,y=k.reduceRight,z=k.filter,A=k.every,B=k.some,q=k.indexOf,C=k.lastIndexOf,p=Array.isArray,H=Object.keys,t=Function.prototype.bind,b=function(a){return new n(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else typeof define==="function"&&define.amd?
|
||||
define("underscore",function(){return b}):s._=b;b.VERSION="1.2.2";var j=b.each=b.forEach=function(a,c,b){if(a!=null)if(v&&a.forEach===v)a.forEach(c,b);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(b,a[e],e,a)===o)break}else for(e in a)if(m.call(a,e)&&c.call(b,a[e],e,a)===o)break};b.map=function(a,c,b){var e=[];if(a==null)return e;if(w&&a.map===w)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=
|
||||
d!==void 0;a==null&&(a=[]);if(x&&a.reduce===x)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){a==null&&(a=[]);if(y&&a.reduceRight===y)return e&&(c=b.bind(c,e)),d!==void 0?a.reduceRight(c,d):a.reduceRight(c);a=(b.isArray(a)?a.slice():b.toArray(a)).reverse();return b.reduce(a,c,d,e)};b.find=b.detect=function(a,c,b){var e;
|
||||
D(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.filter===z)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(A&&a.every===A)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,a,g,h)))return o});
|
||||
return e};var D=b.some=b.any=function(a,c,d){var c=c||b.identity,e=false;if(a==null)return e;if(B&&a.some===B)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return q&&a.indexOf===q?a.indexOf(c)!=-1:b=D(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(c.call?c||a:a[c]).apply(a,d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};
|
||||
b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});return e.value};b.shuffle=function(a){var c=[],b;
|
||||
j(a,function(a,f){f==0?c[0]=a:(b=Math.floor(Math.random()*(f+1)),c[f]=c[b],c[b]=a)});return c};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,c){var b=a.criteria,d=c.criteria;return b<d?-1:b>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,c){var b=e(a,c);(d[b]||(d[b]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<
|
||||
f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=b.tail=function(a,b,d){return i.call(a,b==null||
|
||||
d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);return e};b.union=function(){return b.uniq(b.flatten(arguments,
|
||||
true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a,c){return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(q&&a.indexOf===q)return a.indexOf(c);
|
||||
for(d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(C&&a.lastIndexOf===C)return a.lastIndexOf(b);for(var d=a.length;d--;)if(a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};var E=function(){};b.bind=function(a,c){var d,e;if(a.bind===t&&t)return t.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;
|
||||
e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));E.prototype=a.prototype;var b=new E,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var b=c.apply(this,arguments);return m.call(d,b)?d[b]:d[b]=a.apply(this,arguments)}};b.delay=
|
||||
function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=
|
||||
null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments));return b.apply(this,d)}};b.compose=function(){var a=i.call(arguments);return function(){for(var b=i.call(arguments),d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=H||function(a){if(a!==
|
||||
Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)m.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?
|
||||
a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(m.call(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=l.call(arguments)=="[object Arguments]"?function(a){return l.call(a)=="[object Arguments]"}:
|
||||
function(a){return!(!a||!m.call(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};
|
||||
b.isUndefined=function(a){return a===void 0};b.noConflict=function(){s._=F;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),function(c){I(c,b[c]=a[c])})};var J=0;b.uniqueId=function(a){var b=J++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,
|
||||
interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape,function(a,b){return"',_.escape("+b.replace(/\\'/g,"'")+"),'"}).replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,
|
||||
"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e(a,b)}};var n=function(a){this._wrapped=a};b.prototype=n.prototype;var u=function(a,c){return c?b(a).chain():a},I=function(a,c){n.prototype[a]=function(){var a=i.call(arguments);G.call(a,this._wrapped);return u(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];n.prototype[a]=function(){b.apply(this._wrapped,
|
||||
arguments);return u(this._wrapped,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];n.prototype[a]=function(){return u(b.apply(this._wrapped,arguments),this._chain)}});n.prototype.chain=function(){this._chain=true;return this};n.prototype.value=function(){return this._wrapped}}).call(this);
|
||||
@@ -1,4 +1,4 @@
|
||||
// Underscore.js 1.1.7
|
||||
// Underscore.js 1.2.2
|
||||
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
|
||||
// Underscore is freely distributable under the MIT license.
|
||||
// Portions of Underscore are inspired or borrowed from Prototype,
|
||||
@@ -48,19 +48,26 @@
|
||||
// Create a safe reference to the Underscore object for use below.
|
||||
var _ = function(obj) { return new wrapper(obj); };
|
||||
|
||||
// Export the Underscore object for **CommonJS**, with backwards-compatibility
|
||||
// for the old `require()` API. If we're not in CommonJS, add `_` to the
|
||||
// global object.
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = _;
|
||||
_._ = _;
|
||||
// Export the Underscore object for **Node.js** and **"CommonJS"**, with
|
||||
// backwards-compatibility for the old `require()` API. If we're not in
|
||||
// CommonJS, add `_` to the global object.
|
||||
if (typeof exports !== 'undefined') {
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
exports = module.exports = _;
|
||||
}
|
||||
exports._ = _;
|
||||
} else if (typeof define === 'function' && define.amd) {
|
||||
// Register as a named module with AMD.
|
||||
define('underscore', function() {
|
||||
return _;
|
||||
});
|
||||
} else {
|
||||
// Exported as a string, for Closure Compiler "advanced" mode.
|
||||
root['_'] = _;
|
||||
}
|
||||
|
||||
// Current version.
|
||||
_.VERSION = '1.1.7';
|
||||
_.VERSION = '1.2.2';
|
||||
|
||||
// Collection Functions
|
||||
// --------------------
|
||||
@@ -187,7 +194,7 @@
|
||||
if (obj == null) return result;
|
||||
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
|
||||
each(obj, function(value, index, list) {
|
||||
if (result |= iterator.call(context, value, index, list)) return breaker;
|
||||
if (result || (result = iterator.call(context, value, index, list))) return breaker;
|
||||
});
|
||||
return !!result;
|
||||
};
|
||||
@@ -198,8 +205,8 @@
|
||||
var found = false;
|
||||
if (obj == null) return found;
|
||||
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
|
||||
any(obj, function(value) {
|
||||
if (found = value === target) return true;
|
||||
found = any(obj, function(value) {
|
||||
return value === target;
|
||||
});
|
||||
return found;
|
||||
};
|
||||
@@ -220,6 +227,7 @@
|
||||
// Return the maximum element or (element-based computation).
|
||||
_.max = function(obj, iterator, context) {
|
||||
if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
|
||||
if (!iterator && _.isEmpty(obj)) return -Infinity;
|
||||
var result = {computed : -Infinity};
|
||||
each(obj, function(value, index, list) {
|
||||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||||
@@ -231,6 +239,7 @@
|
||||
// Return the minimum element (or element-based computation).
|
||||
_.min = function(obj, iterator, context) {
|
||||
if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
|
||||
if (!iterator && _.isEmpty(obj)) return Infinity;
|
||||
var result = {computed : Infinity};
|
||||
each(obj, function(value, index, list) {
|
||||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||||
@@ -239,6 +248,21 @@
|
||||
return result.value;
|
||||
};
|
||||
|
||||
// Shuffle an array.
|
||||
_.shuffle = function(obj) {
|
||||
var shuffled = [], rand;
|
||||
each(obj, function(value, index, list) {
|
||||
if (index == 0) {
|
||||
shuffled[0] = value;
|
||||
} else {
|
||||
rand = Math.floor(Math.random() * (index + 1));
|
||||
shuffled[index] = shuffled[rand];
|
||||
shuffled[rand] = value;
|
||||
}
|
||||
});
|
||||
return shuffled;
|
||||
};
|
||||
|
||||
// Sort the object's values by a criterion produced by an iterator.
|
||||
_.sortBy = function(obj, iterator, context) {
|
||||
return _.pluck(_.map(obj, function(value, index, list) {
|
||||
@@ -252,9 +276,11 @@
|
||||
}), 'value');
|
||||
};
|
||||
|
||||
// Groups the object's values by a criterion produced by an iterator
|
||||
_.groupBy = function(obj, iterator) {
|
||||
// Groups the object's values by a criterion. Pass either a string attribute
|
||||
// to group by, or a function that returns the criterion.
|
||||
_.groupBy = function(obj, val) {
|
||||
var result = {};
|
||||
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
|
||||
each(obj, function(value, index) {
|
||||
var key = iterator(value, index);
|
||||
(result[key] || (result[key] = [])).push(value);
|
||||
@@ -298,6 +324,24 @@
|
||||
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
|
||||
};
|
||||
|
||||
// Returns everything but the last entry of the array. Especcialy useful on
|
||||
// the arguments object. Passing **n** will return all the values in
|
||||
// the array, excluding the last N. The **guard** check allows it to work with
|
||||
// `_.map`.
|
||||
_.initial = function(array, n, guard) {
|
||||
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
|
||||
};
|
||||
|
||||
// Get the last element of an array. Passing **n** will return the last N
|
||||
// values in the array. The **guard** check allows it to work with `_.map`.
|
||||
_.last = function(array, n, guard) {
|
||||
if ((n != null) && !guard) {
|
||||
return slice.call(array, Math.max(array.length - n, 0));
|
||||
} else {
|
||||
return array[array.length - 1];
|
||||
}
|
||||
};
|
||||
|
||||
// Returns everything but the first entry of the array. Aliased as `tail`.
|
||||
// Especially useful on the arguments object. Passing an **index** will return
|
||||
// the rest of the values in the array from that index onward. The **guard**
|
||||
@@ -306,20 +350,15 @@
|
||||
return slice.call(array, (index == null) || guard ? 1 : index);
|
||||
};
|
||||
|
||||
// Get the last element of an array.
|
||||
_.last = function(array) {
|
||||
return array[array.length - 1];
|
||||
};
|
||||
|
||||
// Trim out all falsy values from an array.
|
||||
_.compact = function(array) {
|
||||
return _.filter(array, function(value){ return !!value; });
|
||||
};
|
||||
|
||||
// Return a completely flattened version of an array.
|
||||
_.flatten = function(array) {
|
||||
_.flatten = function(array, shallow) {
|
||||
return _.reduce(array, function(memo, value) {
|
||||
if (_.isArray(value)) return memo.concat(_.flatten(value));
|
||||
if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
|
||||
memo[memo.length] = value;
|
||||
return memo;
|
||||
}, []);
|
||||
@@ -333,17 +372,23 @@
|
||||
// Produce a duplicate-free version of the array. If the array has already
|
||||
// been sorted, you have the option of using a faster algorithm.
|
||||
// Aliased as `unique`.
|
||||
_.uniq = _.unique = function(array, isSorted) {
|
||||
return _.reduce(array, function(memo, el, i) {
|
||||
if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el;
|
||||
_.uniq = _.unique = function(array, isSorted, iterator) {
|
||||
var initial = iterator ? _.map(array, iterator) : array;
|
||||
var result = [];
|
||||
_.reduce(initial, function(memo, el, i) {
|
||||
if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
|
||||
memo[memo.length] = el;
|
||||
result[result.length] = array[i];
|
||||
}
|
||||
return memo;
|
||||
}, []);
|
||||
return result;
|
||||
};
|
||||
|
||||
// Produce an array that contains the union: each distinct element from all of
|
||||
// the passed-in arrays.
|
||||
_.union = function() {
|
||||
return _.uniq(_.flatten(arguments));
|
||||
return _.uniq(_.flatten(arguments, true));
|
||||
};
|
||||
|
||||
// Produce an array that contains every item shared between all the
|
||||
@@ -391,7 +436,6 @@
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
|
||||
_.lastIndexOf = function(array, item) {
|
||||
if (array == null) return -1;
|
||||
@@ -426,15 +470,25 @@
|
||||
// Function (ahem) Functions
|
||||
// ------------------
|
||||
|
||||
// Reusable constructor function for prototype setting.
|
||||
var ctor = function(){};
|
||||
|
||||
// Create a function bound to a given object (assigning `this`, and arguments,
|
||||
// optionally). Binding with arguments is also known as `curry`.
|
||||
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
|
||||
// We check for `func.bind` first, to fail fast when `func` is undefined.
|
||||
_.bind = function(func, obj) {
|
||||
_.bind = function bind(func, context) {
|
||||
var bound, args;
|
||||
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
||||
var args = slice.call(arguments, 2);
|
||||
return function() {
|
||||
return func.apply(obj, args.concat(slice.call(arguments)));
|
||||
if (!_.isFunction(func)) throw new TypeError;
|
||||
args = slice.call(arguments, 2);
|
||||
return bound = function() {
|
||||
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
|
||||
ctor.prototype = func.prototype;
|
||||
var self = new ctor;
|
||||
var result = func.apply(self, args.concat(slice.call(arguments)));
|
||||
if (Object(result) === result) return result;
|
||||
return self;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -470,31 +524,43 @@
|
||||
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
|
||||
};
|
||||
|
||||
// Internal function used to implement `_.throttle` and `_.debounce`.
|
||||
var limit = function(func, wait, debounce) {
|
||||
var timeout;
|
||||
return function() {
|
||||
var context = this, args = arguments;
|
||||
var throttler = function() {
|
||||
timeout = null;
|
||||
func.apply(context, args);
|
||||
};
|
||||
if (debounce) clearTimeout(timeout);
|
||||
if (debounce || !timeout) timeout = setTimeout(throttler, wait);
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function, that, when invoked, will only be triggered at most once
|
||||
// during a given window of time.
|
||||
_.throttle = function(func, wait) {
|
||||
return limit(func, wait, false);
|
||||
var context, args, timeout, throttling, more;
|
||||
var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
|
||||
return function() {
|
||||
context = this; args = arguments;
|
||||
var later = function() {
|
||||
timeout = null;
|
||||
if (more) func.apply(context, args);
|
||||
whenDone();
|
||||
};
|
||||
if (!timeout) timeout = setTimeout(later, wait);
|
||||
if (throttling) {
|
||||
more = true;
|
||||
} else {
|
||||
func.apply(context, args);
|
||||
}
|
||||
whenDone();
|
||||
throttling = true;
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function, that, as long as it continues to be invoked, will not
|
||||
// be triggered. The function will be called after it stops being called for
|
||||
// N milliseconds.
|
||||
_.debounce = function(func, wait) {
|
||||
return limit(func, wait, true);
|
||||
var timeout;
|
||||
return function() {
|
||||
var context = this, args = arguments;
|
||||
var later = function() {
|
||||
timeout = null;
|
||||
func.apply(context, args);
|
||||
};
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function that will be executed at most one time, no matter how
|
||||
@@ -533,12 +599,12 @@
|
||||
|
||||
// Returns a function that will only be executed after being called N times.
|
||||
_.after = function(times, func) {
|
||||
if (times <= 0) return func();
|
||||
return function() {
|
||||
if (--times < 1) { return func.apply(this, arguments); }
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Object Functions
|
||||
// ----------------
|
||||
|
||||
@@ -588,6 +654,7 @@
|
||||
|
||||
// Create a (shallow-cloned) duplicate of an object.
|
||||
_.clone = function(obj) {
|
||||
if (!_.isObject(obj)) return obj;
|
||||
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
|
||||
};
|
||||
|
||||
@@ -599,47 +666,103 @@
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Perform a deep comparison to check if two objects are equal.
|
||||
_.isEqual = function(a, b) {
|
||||
// Check object identity.
|
||||
if (a === b) return true;
|
||||
// Different types?
|
||||
var atype = typeof(a), btype = typeof(b);
|
||||
if (atype != btype) return false;
|
||||
// Basic equality test (watch out for coercions).
|
||||
if (a == b) return true;
|
||||
// One is falsy and the other truthy.
|
||||
if ((!a && b) || (a && !b)) return false;
|
||||
// Internal recursive comparison function.
|
||||
function eq(a, b, stack) {
|
||||
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
||||
// See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
|
||||
if (a === b) return a !== 0 || 1 / a == 1 / b;
|
||||
// A strict comparison is necessary because `null == undefined`.
|
||||
if (a == null || b == null) return a === b;
|
||||
// Unwrap any wrapped objects.
|
||||
if (a._chain) a = a._wrapped;
|
||||
if (b._chain) b = b._wrapped;
|
||||
// One of them implements an isEqual()?
|
||||
if (a.isEqual) return a.isEqual(b);
|
||||
if (b.isEqual) return b.isEqual(a);
|
||||
// Check dates' integer values.
|
||||
if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
|
||||
// Both are NaN?
|
||||
if (_.isNaN(a) && _.isNaN(b)) return false;
|
||||
// Compare regular expressions.
|
||||
if (_.isRegExp(a) && _.isRegExp(b))
|
||||
return a.source === b.source &&
|
||||
a.global === b.global &&
|
||||
a.ignoreCase === b.ignoreCase &&
|
||||
a.multiline === b.multiline;
|
||||
// If a is not an object by this point, we can't handle it.
|
||||
if (atype !== 'object') return false;
|
||||
// Check for different array lengths before comparing contents.
|
||||
if (a.length && (a.length !== b.length)) return false;
|
||||
// Nothing else worked, deep compare the contents.
|
||||
var aKeys = _.keys(a), bKeys = _.keys(b);
|
||||
// Different object sizes?
|
||||
if (aKeys.length != bKeys.length) return false;
|
||||
// Recursive comparison of contents.
|
||||
for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false;
|
||||
return true;
|
||||
// Invoke a custom `isEqual` method if one is provided.
|
||||
if (_.isFunction(a.isEqual)) return a.isEqual(b);
|
||||
if (_.isFunction(b.isEqual)) return b.isEqual(a);
|
||||
// Compare `[[Class]]` names.
|
||||
var className = toString.call(a);
|
||||
if (className != toString.call(b)) return false;
|
||||
switch (className) {
|
||||
// Strings, numbers, dates, and booleans are compared by value.
|
||||
case '[object String]':
|
||||
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
|
||||
// equivalent to `new String("5")`.
|
||||
return String(a) == String(b);
|
||||
case '[object Number]':
|
||||
a = +a;
|
||||
b = +b;
|
||||
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
|
||||
// other numeric values.
|
||||
return a != a ? b != b : (a == 0 ? 1 / a == 1 / b : a == b);
|
||||
case '[object Date]':
|
||||
case '[object Boolean]':
|
||||
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
|
||||
// millisecond representations. Note that invalid dates with millisecond representations
|
||||
// of `NaN` are not equivalent.
|
||||
return +a == +b;
|
||||
// RegExps are compared by their source patterns and flags.
|
||||
case '[object RegExp]':
|
||||
return a.source == b.source &&
|
||||
a.global == b.global &&
|
||||
a.multiline == b.multiline &&
|
||||
a.ignoreCase == b.ignoreCase;
|
||||
}
|
||||
if (typeof a != 'object' || typeof b != 'object') return false;
|
||||
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
||||
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
||||
var length = stack.length;
|
||||
while (length--) {
|
||||
// Linear search. Performance is inversely proportional to the number of
|
||||
// unique nested structures.
|
||||
if (stack[length] == a) return true;
|
||||
}
|
||||
// Add the first object to the stack of traversed objects.
|
||||
stack.push(a);
|
||||
var size = 0, result = true;
|
||||
// Recursively compare objects and arrays.
|
||||
if (className == '[object Array]') {
|
||||
// Compare array lengths to determine if a deep comparison is necessary.
|
||||
size = a.length;
|
||||
result = size == b.length;
|
||||
if (result) {
|
||||
// Deep compare the contents, ignoring non-numeric properties.
|
||||
while (size--) {
|
||||
// Ensure commutative equality for sparse arrays.
|
||||
if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Objects with different constructors are not equivalent.
|
||||
if ("constructor" in a != "constructor" in b || a.constructor != b.constructor) return false;
|
||||
// Deep compare objects.
|
||||
for (var key in a) {
|
||||
if (hasOwnProperty.call(a, key)) {
|
||||
// Count the expected number of properties.
|
||||
size++;
|
||||
// Deep compare each member.
|
||||
if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
|
||||
}
|
||||
}
|
||||
// Ensure that both objects contain the same number of properties.
|
||||
if (result) {
|
||||
for (key in b) {
|
||||
if (hasOwnProperty.call(b, key) && !(size--)) break;
|
||||
}
|
||||
result = !size;
|
||||
}
|
||||
}
|
||||
// Remove the first object from the stack of traversed objects.
|
||||
stack.pop();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Perform a deep comparison to check if two objects are equal.
|
||||
_.isEqual = function(a, b) {
|
||||
return eq(a, b, []);
|
||||
};
|
||||
|
||||
// Is a given array or object empty?
|
||||
// Is a given array, string, or object empty?
|
||||
// An "empty" object has no enumerable own-properties.
|
||||
_.isEmpty = function(obj) {
|
||||
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
|
||||
for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
|
||||
@@ -654,7 +777,7 @@
|
||||
// Is a given value an array?
|
||||
// Delegates to ECMA5's native Array.isArray
|
||||
_.isArray = nativeIsArray || function(obj) {
|
||||
return toString.call(obj) === '[object Array]';
|
||||
return toString.call(obj) == '[object Array]';
|
||||
};
|
||||
|
||||
// Is a given variable an object?
|
||||
@@ -663,44 +786,50 @@
|
||||
};
|
||||
|
||||
// Is a given variable an arguments object?
|
||||
_.isArguments = function(obj) {
|
||||
return !!(obj && hasOwnProperty.call(obj, 'callee'));
|
||||
};
|
||||
if (toString.call(arguments) == '[object Arguments]') {
|
||||
_.isArguments = function(obj) {
|
||||
return toString.call(obj) == '[object Arguments]';
|
||||
};
|
||||
} else {
|
||||
_.isArguments = function(obj) {
|
||||
return !!(obj && hasOwnProperty.call(obj, 'callee'));
|
||||
};
|
||||
}
|
||||
|
||||
// Is a given value a function?
|
||||
_.isFunction = function(obj) {
|
||||
return !!(obj && obj.constructor && obj.call && obj.apply);
|
||||
return toString.call(obj) == '[object Function]';
|
||||
};
|
||||
|
||||
// Is a given value a string?
|
||||
_.isString = function(obj) {
|
||||
return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
|
||||
return toString.call(obj) == '[object String]';
|
||||
};
|
||||
|
||||
// Is a given value a number?
|
||||
_.isNumber = function(obj) {
|
||||
return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
|
||||
return toString.call(obj) == '[object Number]';
|
||||
};
|
||||
|
||||
// Is the given value `NaN`? `NaN` happens to be the only value in JavaScript
|
||||
// that does not equal itself.
|
||||
// Is the given value `NaN`?
|
||||
_.isNaN = function(obj) {
|
||||
// `NaN` is the only value for which `===` is not reflexive.
|
||||
return obj !== obj;
|
||||
};
|
||||
|
||||
// Is a given value a boolean?
|
||||
_.isBoolean = function(obj) {
|
||||
return obj === true || obj === false;
|
||||
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
|
||||
};
|
||||
|
||||
// Is a given value a date?
|
||||
_.isDate = function(obj) {
|
||||
return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
|
||||
return toString.call(obj) == '[object Date]';
|
||||
};
|
||||
|
||||
// Is the given value a regular expression?
|
||||
_.isRegExp = function(obj) {
|
||||
return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
|
||||
return toString.call(obj) == '[object RegExp]';
|
||||
};
|
||||
|
||||
// Is a given value equal to null?
|
||||
@@ -733,6 +862,11 @@
|
||||
for (var i = 0; i < n; i++) iterator.call(context, i);
|
||||
};
|
||||
|
||||
// Escape a string for HTML interpolation.
|
||||
_.escape = function(string) {
|
||||
return (''+string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/');
|
||||
};
|
||||
|
||||
// Add your own custom functions to the Underscore object, ensuring that
|
||||
// they're correctly added to the OOP wrapper as well.
|
||||
_.mixin = function(obj) {
|
||||
@@ -753,7 +887,8 @@
|
||||
// following template settings to use alternative delimiters.
|
||||
_.templateSettings = {
|
||||
evaluate : /<%([\s\S]+?)%>/g,
|
||||
interpolate : /<%=([\s\S]+?)%>/g
|
||||
interpolate : /<%=([\s\S]+?)%>/g,
|
||||
escape : /<%-([\s\S]+?)%>/g
|
||||
};
|
||||
|
||||
// JavaScript micro-templating, similar to John Resig's implementation.
|
||||
@@ -765,19 +900,22 @@
|
||||
'with(obj||{}){__p.push(\'' +
|
||||
str.replace(/\\/g, '\\\\')
|
||||
.replace(/'/g, "\\'")
|
||||
.replace(c.escape, function(match, code) {
|
||||
return "',_.escape(" + code.replace(/\\'/g, "'") + "),'";
|
||||
})
|
||||
.replace(c.interpolate, function(match, code) {
|
||||
return "'," + code.replace(/\\'/g, "'") + ",'";
|
||||
})
|
||||
.replace(c.evaluate || null, function(match, code) {
|
||||
return "');" + code.replace(/\\'/g, "'")
|
||||
.replace(/[\r\n\t]/g, ' ') + "__p.push('";
|
||||
.replace(/[\r\n\t]/g, ' ') + ";__p.push('";
|
||||
})
|
||||
.replace(/\r/g, '\\r')
|
||||
.replace(/\n/g, '\\n')
|
||||
.replace(/\t/g, '\\t')
|
||||
+ "');}return __p.join('');";
|
||||
var func = new Function('obj', tmpl);
|
||||
return data ? func(data) : func;
|
||||
var func = new Function('obj', '_', tmpl);
|
||||
return data ? func(data, _) : function(data) { return func(data, _) };
|
||||
};
|
||||
|
||||
// The OOP Wrapper
|
||||
@@ -836,4 +974,4 @@
|
||||
return this._wrapped;
|
||||
};
|
||||
|
||||
})();
|
||||
}).call(this);
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
// Underscore.string
|
||||
// (c) 2010 Esa-Matti Suuronen <esa-matti aet suuronen dot org>
|
||||
// Underscore.strings is freely distributable under the terms of the MIT license.
|
||||
// Documentation: https://github.com/edtsech/underscore.string
|
||||
// Documentation: https://github.com/epeli/underscore.string
|
||||
// Some code is borrowed from MooTools and Alexandru Marasteanu.
|
||||
|
||||
// Version 1.1.6
|
||||
|
||||
// Version 1.2.0
|
||||
|
||||
(function(root){
|
||||
'use strict';
|
||||
|
||||
if (typeof _ != 'undefined') {
|
||||
var _reverse = _().reverse,
|
||||
_include = _.include;
|
||||
}
|
||||
|
||||
// Defining helper functions.
|
||||
|
||||
var nativeTrim = String.prototype.trim;
|
||||
@@ -22,7 +16,7 @@
|
||||
var parseNumber = function(source) { return source * 1 || 0; };
|
||||
|
||||
var strRepeat = function(i, m) {
|
||||
for (var o = []; m > 0; o[--m] = i);
|
||||
for (var o = []; m > 0; o[--m] = i) {}
|
||||
return o.join('');
|
||||
};
|
||||
|
||||
@@ -174,6 +168,8 @@
|
||||
|
||||
var _s = {
|
||||
|
||||
VERSION: '1.2.0',
|
||||
|
||||
isBlank: sArgs(function(str){
|
||||
return (/^\s*$/).test(str);
|
||||
}),
|
||||
@@ -235,18 +231,10 @@
|
||||
return arr.join('');
|
||||
}),
|
||||
|
||||
includes: sArgs(function(str, needle){
|
||||
include: sArgs(function(str, needle){
|
||||
return str.indexOf(needle) !== -1;
|
||||
}),
|
||||
|
||||
include: function(obj, needle) {
|
||||
if (!_include || (/string|number/).test(typeof obj)) {
|
||||
return this.includes(obj, needle);
|
||||
} else {
|
||||
return _include(obj, needle);
|
||||
}
|
||||
},
|
||||
|
||||
join: sArgs(function(sep) {
|
||||
var args = slice(arguments);
|
||||
return args.join(args.shift());
|
||||
@@ -256,13 +244,9 @@
|
||||
return str.split("\n");
|
||||
}),
|
||||
|
||||
reverse: function(obj){
|
||||
if (!_reverse || (/string|number/).test(typeof obj)) {
|
||||
return Array.prototype.reverse.apply(String(obj).split('')).join('');
|
||||
} else {
|
||||
return _reverse.call(_(obj));
|
||||
}
|
||||
},
|
||||
reverse: sArgs(function(str){
|
||||
return Array.prototype.reverse.apply(String(str).split('')).join('');
|
||||
}),
|
||||
|
||||
splice: sArgs(function(str, i, howmany, substr){
|
||||
var arr = str.split('');
|
||||
@@ -309,6 +293,10 @@
|
||||
return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1-$2').replace(/^([A-Z]+)/, '-$1').replace(/\_|\s+/g, '-').toLowerCase();
|
||||
},
|
||||
|
||||
humanize: function(str){
|
||||
return _s.capitalize(this.underscored(str).replace(/_id$/,'').replace(/_/g, ' '));
|
||||
},
|
||||
|
||||
trim: sArgs(function(str, characters){
|
||||
if (!characters && nativeTrim) {
|
||||
return nativeTrim.call(str);
|
||||
@@ -333,6 +321,27 @@
|
||||
return str.length > length ? str.slice(0,length) + truncateStr : str;
|
||||
}),
|
||||
|
||||
/**
|
||||
* _s.prune: a more elegant version of truncate
|
||||
* prune extra chars, never leaving a half-chopped word.
|
||||
* @author github.com/sergiokas
|
||||
*/
|
||||
prune: sArgs(function(str, length, pruneStr){
|
||||
pruneStr = pruneStr || '...';
|
||||
length = parseNumber(length);
|
||||
var pruned = '';
|
||||
|
||||
// Check if we're in the middle of a word
|
||||
if( str.substring(length-1, length+1).search(/^\w\w$/) === 0 )
|
||||
pruned = _s.rtrim(str.slice(0,length).replace(/([\W][\w]*)$/,''));
|
||||
else
|
||||
pruned = _s.rtrim(str.slice(0,length));
|
||||
|
||||
pruned = pruned.replace(/\W+$/,'');
|
||||
|
||||
return (pruned.length+pruneStr.length>str.length) ? str : pruned + pruneStr;
|
||||
}),
|
||||
|
||||
words: function(str, delimiter) {
|
||||
return String(str).split(delimiter || " ");
|
||||
},
|
||||
@@ -409,31 +418,51 @@
|
||||
strLeftBack: sArgs(function(sourceStr, sep){
|
||||
var pos = sourceStr.lastIndexOf(sep);
|
||||
return (pos != -1) ? sourceStr.slice(0, pos) : sourceStr;
|
||||
})
|
||||
}),
|
||||
|
||||
exports: function() {
|
||||
var result = {};
|
||||
|
||||
for (var prop in this) {
|
||||
if (!this.hasOwnProperty(prop) || prop == 'include' || prop == 'contains' || prop == 'reverse') continue;
|
||||
result[prop] = this[prop];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Aliases
|
||||
|
||||
_s.strip = _s.trim;
|
||||
_s.lstrip = _s.ltrim;
|
||||
_s.rstrip = _s.rtrim;
|
||||
_s.center = _s.lrpad;
|
||||
_s.ljust = _s.lpad;
|
||||
_s.rjust = _s.rpad;
|
||||
_s.strip = _s.trim;
|
||||
_s.lstrip = _s.ltrim;
|
||||
_s.rstrip = _s.rtrim;
|
||||
_s.center = _s.lrpad;
|
||||
_s.ljust = _s.lpad;
|
||||
_s.rjust = _s.rpad;
|
||||
_s.contains = _s.include;
|
||||
|
||||
// CommonJS module is defined
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
// Export module
|
||||
module.exports = _s;
|
||||
if (typeof exports !== 'undefined') {
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
// Export module
|
||||
module.exports = _s;
|
||||
}
|
||||
exports._s = _s;
|
||||
|
||||
// Integrate with Underscore.js
|
||||
} else if (typeof root._ !== 'undefined') {
|
||||
root._.mixin(_s);
|
||||
// root._.mixin(_s);
|
||||
root._.string = _s;
|
||||
root._.str = root._.string;
|
||||
|
||||
// Or define it
|
||||
} else {
|
||||
root._ = _s;
|
||||
root._ = {
|
||||
string: _s,
|
||||
str: _s
|
||||
};
|
||||
}
|
||||
|
||||
}(this || window));
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
(function(k){var o=String.prototype.trim,l=function(a,b){for(var c=[];b>0;c[--b]=a);return c.join("")},d=function(a){return function(){for(var b=Array.prototype.slice.call(arguments),c=0;c<b.length;c++)b[c]=b[c]==null?"":""+b[c];return a.apply(null,b)}},m=function(){function a(a){return Object.prototype.toString.call(a).slice(8,-1).toLowerCase()}var b=function(){b.cache.hasOwnProperty(arguments[0])||(b.cache[arguments[0]]=b.parse(arguments[0]));return b.format.call(null,b.cache[arguments[0]],arguments)};
|
||||
b.format=function(b,n){var e=1,d=b.length,f="",j=[],h,i,g,k;for(h=0;h<d;h++)if(f=a(b[h]),f==="string")j.push(b[h]);else if(f==="array"){g=b[h];if(g[2]){f=n[e];for(i=0;i<g[2].length;i++){if(!f.hasOwnProperty(g[2][i]))throw m('[_.sprintf] property "%s" does not exist',g[2][i]);f=f[g[2][i]]}}else f=g[1]?n[g[1]]:n[e++];if(/[^s]/.test(g[8])&&a(f)!="number")throw m("[_.sprintf] expecting number but found %s",a(f));switch(g[8]){case "b":f=f.toString(2);break;case "c":f=String.fromCharCode(f);break;case "d":f=
|
||||
parseInt(f,10);break;case "e":f=g[7]?f.toExponential(g[7]):f.toExponential();break;case "f":f=g[7]?parseFloat(f).toFixed(g[7]):parseFloat(f);break;case "o":f=f.toString(8);break;case "s":f=(f=String(f))&&g[7]?f.substring(0,g[7]):f;break;case "u":f=Math.abs(f);break;case "x":f=f.toString(16);break;case "X":f=f.toString(16).toUpperCase()}f=/[def]/.test(g[8])&&g[3]&&f>=0?"+"+f:f;i=g[4]?g[4]=="0"?"0":g[4].charAt(1):" ";k=g[6]-String(f).length;i=g[6]?l(i,k):"";j.push(g[5]?f+i:i+f)}return j.join("")};b.cache=
|
||||
{};b.parse=function(a){for(var b=[],e=[],d=0;a;){if((b=/^[^\x25]+/.exec(a))!==null)e.push(b[0]);else if((b=/^\x25{2}/.exec(a))!==null)e.push("%");else if((b=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(a))!==null){if(b[2]){d|=1;var f=[],j=b[2],h=[];if((h=/^([a-z_][a-z_\d]*)/i.exec(j))!==null)for(f.push(h[1]);(j=j.substring(h[0].length))!=="";)if((h=/^\.([a-z_][a-z_\d]*)/i.exec(j))!==null)f.push(h[1]);else if((h=/^\[(\d+)\]/.exec(j))!==null)f.push(h[1]);
|
||||
else throw"[_.sprintf] huh?";else throw"[_.sprintf] huh?";b[2]=f}else d|=2;if(d===3)throw"[_.sprintf] mixing positional and named placeholders is not (yet) supported";e.push(b)}else throw"[_.sprintf] huh?";a=a.substring(b[0].length)}return e};return b}(),e={VERSION:"1.2.0",isBlank:d(function(a){return/^\s*$/.test(a)}),stripTags:d(function(a){return a.replace(/<\/?[^>]+>/ig,"")}),capitalize:d(function(a){return a.charAt(0).toUpperCase()+a.substring(1).toLowerCase()}),chop:d(function(a,b){for(var b=
|
||||
b*1||0||a.length,c=[],e=0;e<a.length;)c.push(a.slice(e,e+b)),e+=b;return c}),clean:d(function(a){return e.strip(a.replace(/\s+/g," "))}),count:d(function(a,b){for(var c=0,e,d=0;d<a.length;)e=a.indexOf(b,d),e>=0&&c++,d=d+(e>=0?e:0)+b.length;return c}),chars:d(function(a){return a.split("")}),escapeHTML:d(function(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}),unescapeHTML:d(function(a){return a.replace(/</g,"<").replace(/>/g,
|
||||
">").replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&")}),escapeRegExp:d(function(a){return a.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1")}),insert:d(function(a,b,c){a=a.split("");a.splice(b*1||0,0,c);return a.join("")}),include:d(function(a,b){return a.indexOf(b)!==-1}),join:d(function(a){var b=Array.prototype.slice.call(arguments);return b.join(b.shift())}),lines:d(function(a){return a.split("\n")}),reverse:d(function(a){return Array.prototype.reverse.apply(String(a).split("")).join("")}),
|
||||
splice:d(function(a,b,c,e){a=a.split("");a.splice(b*1||0,c*1||0,e);return a.join("")}),startsWith:d(function(a,b){return a.length>=b.length&&a.substring(0,b.length)===b}),endsWith:d(function(a,b){return a.length>=b.length&&a.substring(a.length-b.length)===b}),succ:d(function(a){var b=a.split("");b.splice(a.length-1,1,String.fromCharCode(a.charCodeAt(a.length-1)+1));return b.join("")}),titleize:d(function(a){for(var a=a.split(" "),b,c=0;c<a.length;c++)b=a[c].split(""),typeof b[0]!=="undefined"&&(b[0]=
|
||||
b[0].toUpperCase()),c+1===a.length?a[c]=b.join(""):a[c]=b.join("")+" ";return a.join("")}),camelize:d(function(a){return e.trim(a).replace(/(\-|_|\s)+(.)?/g,function(a,c,e){return e?e.toUpperCase():""})}),underscored:function(a){return e.trim(a).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/\-|\s+/g,"_").toLowerCase()},dasherize:function(a){return e.trim(a).replace(/([a-z\d])([A-Z]+)/g,"$1-$2").replace(/^([A-Z]+)/,"-$1").replace(/\_|\s+/g,"-").toLowerCase()},humanize:function(a){return e.capitalize(this.underscored(a).replace(/_id$/,
|
||||
"").replace(/_/g," "))},trim:d(function(a,b){if(!b&&o)return o.call(a);b=b?e.escapeRegExp(b):"\\s";return a.replace(RegExp("^["+b+"]+|["+b+"]+$","g"),"")}),ltrim:d(function(a,b){b=b?e.escapeRegExp(b):"\\s";return a.replace(RegExp("^["+b+"]+","g"),"")}),rtrim:d(function(a,b){b=b?e.escapeRegExp(b):"\\s";return a.replace(RegExp("["+b+"]+$","g"),"")}),truncate:d(function(a,b,c){b=b*1||0;return a.length>b?a.slice(0,b)+(c||"..."):a}),prune:d(function(a,b,c){var c=c||"...",b=b*1||0,d="",d=a.substring(b-
|
||||
1,b+1).search(/^\w\w$/)===0?e.rtrim(a.slice(0,b).replace(/([\W][\w]*)$/,"")):e.rtrim(a.slice(0,b)),d=d.replace(/\W+$/,"");return d.length+c.length>a.length?a:d+c}),words:function(a,b){return String(a).split(b||" ")},pad:d(function(a,b,c,e){var d="",d=0,b=b*1||0;c?c.length>1&&(c=c.charAt(0)):c=" ";switch(e){case "right":d=b-a.length;d=l(c,d);a+=d;break;case "both":d=b-a.length;d={left:l(c,Math.ceil(d/2)),right:l(c,Math.floor(d/2))};a=d.left+a+d.right;break;default:d=b-a.length,d=l(c,d),a=d+a}return a}),
|
||||
lpad:function(a,b,c){return e.pad(a,b,c)},rpad:function(a,b,c){return e.pad(a,b,c,"right")},lrpad:function(a,b,c){return e.pad(a,b,c,"both")},sprintf:m,vsprintf:function(a,b){b.unshift(a);return m.apply(null,b)},toNumber:function(a,b){var c;c=(a*1||0).toFixed(b*1||0)*1||0;return!(c===0&&a!=="0"&&a!==0)?c:Number.NaN},strRight:d(function(a,b){var c=!b?-1:a.indexOf(b);return c!=-1?a.slice(c+b.length,a.length):a}),strRightBack:d(function(a,b){var c=!b?-1:a.lastIndexOf(b);return c!=-1?a.slice(c+b.length,
|
||||
a.length):a}),strLeft:d(function(a,b){var c=!b?-1:a.indexOf(b);return c!=-1?a.slice(0,c):a}),strLeftBack:d(function(a,b){var c=a.lastIndexOf(b);return c!=-1?a.slice(0,c):a}),exports:function(){var a={},b;for(b in this)if(this.hasOwnProperty(b)&&!(b=="include"||b=="contains"||b=="reverse"))a[b]=this[b];return a}};e.strip=e.trim;e.lstrip=e.ltrim;e.rstrip=e.rtrim;e.center=e.lrpad;e.ljust=e.lpad;e.rjust=e.rpad;e.contains=e.include;if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)module.exports=
|
||||
e;exports._s=e}else typeof k._!=="undefined"?(k._.string=e,k._.str=k._.string):k._={string:e,str:e}})(this||window);
|
||||
@@ -26,7 +26,7 @@ body.openerp, .openerp textarea, .openerp input, .openerp select, .openerp optio
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.openerp .oe-number {
|
||||
.openerp .oe-listview .oe-number {
|
||||
text-align: right !important;
|
||||
}
|
||||
.openerp .oe_hide {
|
||||
@@ -713,7 +713,26 @@ label.error {
|
||||
.openerp .oe-listview th {
|
||||
vertical-align: middle;
|
||||
text-align: left;
|
||||
padding: 1px 2px;
|
||||
}
|
||||
.openerp .oe-listview th.oe-record-selector,
|
||||
.openerp .oe-listview td.oe-button,
|
||||
.openerp .oe-listview td.oe-record-delete {
|
||||
padding: 0 1px;
|
||||
}
|
||||
|
||||
/* Could use :not selectors if they were supported by MSIE8... */
|
||||
.openerp .oe-listview tbody td {
|
||||
border-left: 1px solid #dadada;
|
||||
}
|
||||
.openerp .oe-listview tbody td:first-child,
|
||||
.openerp .oe-listview tbody td.oe-button,
|
||||
.openerp .oe-listview tbody td.oe-button+td,
|
||||
.openerp .oe-listview tbody th.oe-record-selector+td,
|
||||
.openerp .oe-listview tbody td.oe-record-delete {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.openerp .oe-listview td.oe-record-delete {
|
||||
text-align: right;
|
||||
}
|
||||
@@ -790,33 +809,33 @@ label.error {
|
||||
also on the first and last children of the first and last row
|
||||
*/
|
||||
.openerp .oe-listview table.oe-listview-content {
|
||||
-webkit-border-radius: 7px;
|
||||
-moz-border-radius: 7px;
|
||||
border-radius: 7px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.openerp .oe-listview table.oe-listview-content thead tr:first-child th:first-child {
|
||||
-webkit-border-top-left-radius: 7px;
|
||||
-moz-border-radius-topleft: 7px;
|
||||
border-top-left-radius: 7px;
|
||||
-webkit-border-top-left-radius: 4px;
|
||||
-moz-border-radius-topleft: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
}
|
||||
.openerp .oe-listview table.oe-listview-content thead tr:first-child th:last-child {
|
||||
-webkit-border-top-right-radius: 7px;
|
||||
-moz-border-radius-topright: 7px;
|
||||
border-top-right-radius: 7px;
|
||||
-webkit-border-top-right-radius: 4px;
|
||||
-moz-border-radius-topright: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.openerp .oe-listview table.oe-listview-content tfoot tr:last-child th:first-child,
|
||||
.openerp .oe-listview table.oe-listview-content tfoot tr:last-child td:first-child,
|
||||
.openerp .oe-listview table.oe-listview-content tbody:last-child tr:last-child th:first-child {
|
||||
-webkit-border-bottom-left-radius: 7px;
|
||||
-moz-border-radius-bottomleft: 7px;
|
||||
border-bottom-left-radius: 7px;
|
||||
-webkit-border-bottom-left-radius: 4px;
|
||||
-moz-border-radius-bottomleft: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.openerp .oe-listview table.oe-listview-content tfoot tr:last-child th:last-child,
|
||||
.openerp .oe-listview table.oe-listview-content tfoot tr:last-child td:last-child,
|
||||
.openerp .oe-listview table.oe-listview-content tbody:last-child tr:last-child td:last-child {
|
||||
-webkit-border-bottom-right-radius: 7px;
|
||||
-moz-border-radius-bottomright: 7px;
|
||||
border-bottom-right-radius: 7px;
|
||||
-webkit-border-bottom-right-radius: 4px;
|
||||
-moz-border-radius-bottomright: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
/* Notebook */
|
||||
@@ -825,6 +844,9 @@ label.error {
|
||||
background: none;
|
||||
border-width: 0;
|
||||
}
|
||||
.openerp .oe_form_notebook .ui-tabs-panel {
|
||||
padding: 4px;
|
||||
}
|
||||
.openerp .oe_form_notebook ul.ui-tabs-nav {
|
||||
padding-left: 0;
|
||||
background: transparent;
|
||||
@@ -852,6 +874,17 @@ label.error {
|
||||
.openerp table.oe_frame {
|
||||
color: #4c4c4c;
|
||||
}
|
||||
.openerp fieldset.oe_group_box {
|
||||
border: 1px solid #AAAAAA;
|
||||
moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
background: #F9F9F9;
|
||||
padding: 4px;
|
||||
}
|
||||
.openerp fieldset.oe_group_box legend {
|
||||
font-weight: bold;
|
||||
}
|
||||
.openerp td.oe_form_frame_cell {
|
||||
padding: 2px;
|
||||
position: relative;
|
||||
@@ -875,6 +908,22 @@ label.error {
|
||||
.openerp label.oe_label_help {
|
||||
cursor: help;
|
||||
}
|
||||
.openerp #tiptip_content {
|
||||
font-size: 12px;
|
||||
}
|
||||
.openerp .oe_tooltip_string {
|
||||
color: #FD5;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
}
|
||||
.openerp .oe_tooltip_technical {
|
||||
padding: 0 0 4px 0;
|
||||
margin: 5px 0 0 15px;
|
||||
list-style: circle;
|
||||
}
|
||||
.openerp .oe_tooltip_technical_title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.openerp .oe_forms label.oe_label, .openerp .oe_forms label.oe_label_help {
|
||||
margin: 3px 0 0 10px;
|
||||
@@ -918,20 +967,25 @@ label.error {
|
||||
.openerp .oe_forms textarea {
|
||||
resize:vertical;
|
||||
}
|
||||
.openerp .oe_forms input[type="text"], .openerp .oe_forms input[type="password"], .openerp .oe_forms select, .openerp .oe_forms .button {
|
||||
.openerp .oe_forms input[type="text"], .openerp .oe_forms input[type="password"], .openerp .oe_forms select, .openerp .oe_forms .oe_button {
|
||||
height: 22px;
|
||||
}
|
||||
.openerp .oe_forms input.field_datetime {
|
||||
min-width: 11em;
|
||||
}
|
||||
.openerp .oe_forms.oe_frame .oe_datepicker_root {
|
||||
width: 100%;
|
||||
}
|
||||
.openerp .oe_forms .button {
|
||||
.openerp .oe_forms .oe_button {
|
||||
color: #4c4c4c;
|
||||
white-space: nowrap;
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.openerp .oe_forms .button span {
|
||||
@-moz-document url-prefix() {
|
||||
/* Strange firefox behaviour on width: 100% + white-space: nowrap */
|
||||
.openerp .oe_forms .oe_button {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
.openerp .oe_forms .oe_button span {
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
}
|
||||
@@ -940,13 +994,20 @@ label.error {
|
||||
cursor: pointer;
|
||||
right: 5px;
|
||||
top: 3px;
|
||||
z-index: 2;
|
||||
}
|
||||
.openerp .oe_datepicker_container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: none;
|
||||
}
|
||||
.openerp .oe_datepicker_root {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
.openerp .oe_datepicker_root input[type="text"] {
|
||||
min-width: 160px;
|
||||
.openerp .oe_forms.oe_frame .oe_datepicker_root {
|
||||
width: 100%;
|
||||
}
|
||||
.openerp .oe_input_icon_disabled {
|
||||
position: absolute;
|
||||
@@ -954,7 +1015,7 @@ label.error {
|
||||
opacity: 0.5;
|
||||
filter:alpha(opacity=50);
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
top: 3px;
|
||||
}
|
||||
.openerp img.oe_field_translate {
|
||||
margin-left: -21px;
|
||||
@@ -1249,6 +1310,14 @@ label.error {
|
||||
background: 1px 3px url(/web/static/src/img/icons/gtk-print.png) no-repeat;
|
||||
}
|
||||
|
||||
.openerp .oe-running-kitten {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.openerp.kitten-mode-activated .oe-running-kitten {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
.openerp.kitten-mode-activated .main_table {
|
||||
background: url(http://placekitten.com/g/1500/800) repeat;
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
|
||||
},
|
||||
on_managed_error: function(error) {
|
||||
$('<div>' + QWeb.render('DialogWarning', {error: error}) + '</div>').dialog({
|
||||
title: "OpenERP " + _.capitalize(error.type),
|
||||
title: "OpenERP " + _.str.capitalize(error.type),
|
||||
buttons: {
|
||||
Ok: function() {
|
||||
$(this).dialog("close");
|
||||
@@ -168,7 +168,7 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
|
||||
},
|
||||
on_traceback: function(error) {
|
||||
var dialog = new openerp.web.Dialog(this, {
|
||||
title: "OpenERP " + _.capitalize(error.type),
|
||||
title: "OpenERP " + _.str.capitalize(error.type),
|
||||
autoOpen: true,
|
||||
width: '90%',
|
||||
height: '90%',
|
||||
@@ -184,7 +184,8 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
|
||||
}
|
||||
});
|
||||
|
||||
openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading# */{
|
||||
openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading# */{
|
||||
template: 'Loading',
|
||||
/**
|
||||
* @constructs openerp.web.Loading
|
||||
* @extends openerp.web.Widget
|
||||
@@ -192,8 +193,8 @@ openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading#
|
||||
* @param parent
|
||||
* @param element_id
|
||||
*/
|
||||
init: function(parent, element_id) {
|
||||
this._super(parent, element_id);
|
||||
init: function(parent) {
|
||||
this._super(parent);
|
||||
this.count = 0;
|
||||
this.blocked_ui = false;
|
||||
this.session.on_rpc_request.add_first(this.on_rpc_event, 1);
|
||||
@@ -210,12 +211,13 @@ openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading#
|
||||
}
|
||||
|
||||
this.count += increment;
|
||||
if (this.count) {
|
||||
if (this.count > 0) {
|
||||
//this.$element.html(QWeb.render("Loading", {}));
|
||||
this.$element.html("Loading ("+this.count+")");
|
||||
this.$element.show();
|
||||
this.widget_parent.$element.addClass('loading');
|
||||
} else {
|
||||
this.count = 0;
|
||||
clearTimeout(this.long_running_timer);
|
||||
// Don't unblock if blocked by somebody else
|
||||
if (self.blocked_ui) {
|
||||
@@ -242,10 +244,8 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||
this.$option_id = $('#' + option_id);
|
||||
},
|
||||
start: function() {
|
||||
this._super();
|
||||
this.$element.html(QWeb.render("Database", this));
|
||||
this.$element.closest(".openerp")
|
||||
.removeClass("login-mode")
|
||||
.addClass("database_block");
|
||||
|
||||
var self = this;
|
||||
var fetch_db = this.rpc("/web/database/get_list", {}, function(result) {
|
||||
@@ -266,23 +266,30 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||
this.$element.find('#db-restore').click(this.do_restore);
|
||||
this.$element.find('#db-change-password').click(this.do_change_password);
|
||||
this.$element.find('#back-to-login').click(function() {
|
||||
self.stop();
|
||||
self.hide();
|
||||
});
|
||||
},
|
||||
stop: function () {
|
||||
this.hide();
|
||||
this.$option_id.empty();
|
||||
|
||||
this.$element
|
||||
.find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login')
|
||||
.unbind('click')
|
||||
.end()
|
||||
.closest(".openerp")
|
||||
.addClass("login-mode")
|
||||
.removeClass("database_block")
|
||||
.end()
|
||||
.empty();
|
||||
this._super();
|
||||
},
|
||||
show: function () {
|
||||
this.$element.closest(".openerp")
|
||||
.removeClass("login-mode")
|
||||
.addClass("database_block");
|
||||
},
|
||||
hide: function () {
|
||||
this.$element.closest(".openerp")
|
||||
.addClass("login-mode")
|
||||
.removeClass("database_block")
|
||||
},
|
||||
/**
|
||||
* Converts a .serializeArray() result into a dict. Does not bother folding
|
||||
* multiple identical keys into an array, last key wins.
|
||||
@@ -368,6 +375,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
||||
}
|
||||
self.db_list.push(self.to_object(fields)['db_name']);
|
||||
self.db_list.sort();
|
||||
self.widget_parent.set_db_list(self.db_list);
|
||||
var form_obj = self.to_object(fields);
|
||||
self.wait_for_newdb(result, {
|
||||
password: form_obj['super_admin_pwd'],
|
||||
@@ -397,6 +405,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.widget_parent.set_db_list(self.db_list);
|
||||
self.do_notify("Dropping database", "The database '" + db + "' has been dropped");
|
||||
});
|
||||
}
|
||||
@@ -529,16 +538,16 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
|
||||
var self = this;
|
||||
this.database = new openerp.web.Database(
|
||||
this, "oe_database", "oe_db_options");
|
||||
this.database.start();
|
||||
|
||||
this.$element.find('#oe-db-config').click(function() {
|
||||
self.database.start();
|
||||
self.database.show();
|
||||
});
|
||||
|
||||
this.$element.find("form").submit(this.on_submit);
|
||||
|
||||
this.rpc("/web/database/get_list", {}, function(result) {
|
||||
var tpl = openerp.web.qweb.render('Login_dblist', {db_list: result.db_list, selected_db: self.selected_db});
|
||||
self.$element.find("input[name=db]").replaceWith(tpl)
|
||||
self.set_db_list(result.db_list);
|
||||
},
|
||||
function(error, event) {
|
||||
if (error.data.fault_code === 'AccessDenied') {
|
||||
@@ -547,6 +556,15 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
|
||||
});
|
||||
|
||||
},
|
||||
stop: function () {
|
||||
this.database.stop();
|
||||
this._super();
|
||||
},
|
||||
set_db_list: function (list) {
|
||||
this.$element.find("[name=db]").replaceWith(
|
||||
openerp.web.qweb.render('Login_dblist', {
|
||||
db_list: list, selected_db: this.selected_db}))
|
||||
},
|
||||
on_login_invalid: function() {
|
||||
this.$element.closest(".openerp").addClass("login-mode");
|
||||
},
|
||||
@@ -966,7 +984,7 @@ 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);
|
||||
this.loading = new openerp.web.Loading(this,"oe_loading");
|
||||
this.loading = new openerp.web.Loading(this);
|
||||
this.crashmanager = new openerp.web.CrashManager();
|
||||
|
||||
this.header = new openerp.web.Header(this);
|
||||
@@ -990,6 +1008,7 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.notification.prependTo(this.$element);
|
||||
this.loading.appendTo($('#oe_loading'));
|
||||
this.header.appendTo($("#oe_header"));
|
||||
this.session.start();
|
||||
this.login.appendTo($('#oe_login'));
|
||||
@@ -1095,7 +1114,7 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
|
||||
this.action_manager.do_action(action);
|
||||
},
|
||||
do_about: function() {
|
||||
},
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -125,7 +125,11 @@ openerp.web.callback = function(obj, method) {
|
||||
callback.callback_chain.splice(i, 1);
|
||||
i -= 1;
|
||||
}
|
||||
r = c.callback.apply(c.self, c.args.concat(args));
|
||||
var result = c.callback.apply(c.self, c.args.concat(args));
|
||||
if (c.callback === method) {
|
||||
// return the result of the original method
|
||||
r = result;
|
||||
}
|
||||
// TODO special value to stop the chain
|
||||
// openerp.web.callback_stop
|
||||
}
|
||||
@@ -354,6 +358,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
|
||||
this.debug = (window.location.search.indexOf('?debug') !== -1);
|
||||
this.session_id = false;
|
||||
this.uid = false;
|
||||
this.username = false;
|
||||
this.user_context= {};
|
||||
this.db = false;
|
||||
this.module_list = [];
|
||||
@@ -484,10 +489,13 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
|
||||
var self = this;
|
||||
var params = { db: db, login: login, password: password };
|
||||
return this.rpc("/web/session/login", params, function(result) {
|
||||
self.session_id = result.session_id;
|
||||
self.uid = result.uid;
|
||||
self.user_context = result.context;
|
||||
self.db = result.db;
|
||||
_.extend(self, {
|
||||
session_id: result.session_id,
|
||||
uid: result.uid,
|
||||
user_context: result.context,
|
||||
db: result.db,
|
||||
username: result.login
|
||||
});
|
||||
self.session_save();
|
||||
self.on_session_valid();
|
||||
return true;
|
||||
@@ -501,13 +509,24 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
|
||||
var self = this;
|
||||
this.session_id = this.get_cookie('session_id');
|
||||
return this.rpc("/web/session/get_session_info", {}).then(function(result) {
|
||||
self.uid = result.uid;
|
||||
self.user_context = result.context;
|
||||
self.db = result.db;
|
||||
if (self.uid)
|
||||
self.on_session_valid();
|
||||
else
|
||||
self.on_session_invalid();
|
||||
// If immediately follows a login (triggered by trying to restore
|
||||
// an invalid session or no session at all), refresh session data
|
||||
// (should not change, but just in case...) but should not call
|
||||
// on_session_valid again as it triggers reloading the menu
|
||||
var already_logged = self.uid;
|
||||
_.extend(self, {
|
||||
uid: result.uid,
|
||||
user_context: result.context,
|
||||
db: result.db,
|
||||
username: result.login
|
||||
});
|
||||
if (!already_logged) {
|
||||
if (self.uid) {
|
||||
self.on_session_valid();
|
||||
} else {
|
||||
self.on_session_invalid();
|
||||
}
|
||||
}
|
||||
}, function() {
|
||||
self.on_session_invalid();
|
||||
});
|
||||
@@ -716,7 +735,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
|
||||
if (parseInt(cookie_val, 10) !== token) { continue; }
|
||||
|
||||
// clear cookie
|
||||
document.cookie = _.sprintf("%s=;expires=%s;path=/",
|
||||
document.cookie = _.str.sprintf("%s=;expires=%s;path=/",
|
||||
cookie_name, new Date().toGMTString());
|
||||
if (options.success) { options.success(); }
|
||||
complete();
|
||||
@@ -798,7 +817,7 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
|
||||
*/
|
||||
tag_name: 'div',
|
||||
/**
|
||||
* Construct the widget and set its parent if a parent is given.
|
||||
* Constructs the widget and sets its parent if a parent is given.
|
||||
*
|
||||
* @constructs openerp.web.Widget
|
||||
* @extends openerp.web.CallbackEnabled
|
||||
@@ -830,7 +849,7 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
|
||||
this.widget_is_stopped = false;
|
||||
},
|
||||
/**
|
||||
* Render the current widget and appends it to the given jQuery object or Widget.
|
||||
* Renders the current widget and appends it to the given jQuery object or Widget.
|
||||
*
|
||||
* @param target A jQuery object or a Widget instance.
|
||||
*/
|
||||
@@ -841,7 +860,7 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
|
||||
}, target);
|
||||
},
|
||||
/**
|
||||
* Render the current widget and prepends it to the given jQuery object or Widget.
|
||||
* Renders the current widget and prepends it to the given jQuery object or Widget.
|
||||
*
|
||||
* @param target A jQuery object or a Widget instance.
|
||||
*/
|
||||
@@ -852,7 +871,7 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
|
||||
}, target);
|
||||
},
|
||||
/**
|
||||
* Render the current widget and inserts it after to the given jQuery object or Widget.
|
||||
* Renders the current widget and inserts it after to the given jQuery object or Widget.
|
||||
*
|
||||
* @param target A jQuery object or a Widget instance.
|
||||
*/
|
||||
@@ -863,7 +882,7 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
|
||||
}, target);
|
||||
},
|
||||
/**
|
||||
* Render the current widget and inserts it before to the given jQuery object or Widget.
|
||||
* Renders the current widget and inserts it before to the given jQuery object or Widget.
|
||||
*
|
||||
* @param target A jQuery object or a Widget instance.
|
||||
*/
|
||||
@@ -873,6 +892,16 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
|
||||
self.$element.insertBefore(t);
|
||||
}, target);
|
||||
},
|
||||
/**
|
||||
* Renders the current widget and replaces the given jQuery object.
|
||||
*
|
||||
* @param target A jQuery object or a Widget instance.
|
||||
*/
|
||||
replace: function(target) {
|
||||
return this._render_and_insert(_.bind(function(t) {
|
||||
this.$element.replaceAll(t);
|
||||
}, this), target);
|
||||
},
|
||||
_render_and_insert: function(insertion, target) {
|
||||
this.render_element();
|
||||
if (target instanceof openerp.web.Widget)
|
||||
@@ -887,8 +916,11 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
|
||||
*/
|
||||
render_element: function() {
|
||||
var rendered = this.render();
|
||||
if (rendered || rendered === "")
|
||||
this.$element = $(rendered);
|
||||
if (rendered) {
|
||||
var elem = $(rendered);
|
||||
this.$element.replaceWith(elem);
|
||||
this.$element = elem;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
@@ -900,7 +932,7 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
|
||||
render: function (additional) {
|
||||
if (this.template)
|
||||
return openerp.web.qweb.render(this.template, _.extend({widget: this}, additional || {}));
|
||||
return false;
|
||||
return null;
|
||||
},
|
||||
/**
|
||||
* Method called after rendering. Mostly used to bind actions, perform asynchronous
|
||||
@@ -912,16 +944,10 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
|
||||
* @returns {jQuery.Deferred}
|
||||
*/
|
||||
start: function() {
|
||||
/* The default implementation is only useful for retro-compatibility, it is
|
||||
not necessary to call it using _super() when using Widget for new components. */
|
||||
if (!this.$element) {
|
||||
var tmp = document.getElementById(this.element_id);
|
||||
this.$element = tmp ? $(tmp) : undefined;
|
||||
}
|
||||
return $.Deferred().done().promise();
|
||||
},
|
||||
/**
|
||||
* Destroys the current widget, also destroy all its children before destroying itself.
|
||||
* Destroys the current widget, also destroys all its children before destroying itself.
|
||||
*/
|
||||
stop: function() {
|
||||
_.each(_.clone(this.widget_children), function(el) {
|
||||
@@ -937,7 +963,7 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
|
||||
this.widget_is_stopped = true;
|
||||
},
|
||||
/**
|
||||
* Inform the action manager to do an action. Of course, this suppose that
|
||||
* Informs the action manager to do an action. This supposes that
|
||||
* the action manager can be found amongst the ancestors of the current widget.
|
||||
* If that's not the case this method will simply return `false`.
|
||||
*/
|
||||
@@ -996,7 +1022,7 @@ openerp.web.TranslationDataBase = openerp.web.Class.extend(/** @lends openerp.we
|
||||
this.parameters = {"direction": 'ltr',
|
||||
"date_format": '%m/%d/%Y',
|
||||
"time_format": '%H:%M:%S',
|
||||
"grouping": "[]",
|
||||
"grouping": [],
|
||||
"decimal_point": ".",
|
||||
"thousands_sep": ","};
|
||||
},
|
||||
@@ -1012,6 +1038,8 @@ openerp.web.TranslationDataBase = openerp.web.Class.extend(/** @lends openerp.we
|
||||
});
|
||||
if (translation_bundle.lang_parameters) {
|
||||
this.parameters = translation_bundle.lang_parameters;
|
||||
this.parameters.grouping = py.eval(
|
||||
this.parameters.grouping).toJSON();
|
||||
}
|
||||
},
|
||||
add_module_translation: function(mod) {
|
||||
@@ -1056,7 +1084,7 @@ openerp.web.qweb.format_text_node = function(s) {
|
||||
if (translation && translation.value === 'off') {
|
||||
return s;
|
||||
}
|
||||
var ts = _.trim(s);
|
||||
var ts = _.str.trim(s);
|
||||
if (ts.length === 0) {
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -119,17 +119,18 @@ openerp.web.ContainerDataGroup = openerp.web.DataGroup.extend( /** @lends opener
|
||||
aggregates[key] = value || 0;
|
||||
});
|
||||
|
||||
var group_size = fixed_group[field_name + '_count'] || fixed_group.__count || 0;
|
||||
var leaf_group = fixed_group.__context.group_by.length === 0;
|
||||
return {
|
||||
__context: fixed_group.__context,
|
||||
__domain: fixed_group.__domain,
|
||||
|
||||
grouped_on: field_name,
|
||||
// if terminal group (or no group) and group_by_no_leaf => use group.__count
|
||||
length: fixed_group[field_name + '_count'] || fixed_group.__count,
|
||||
length: group_size,
|
||||
value: fixed_group[field_name],
|
||||
|
||||
openable: !(this.context['group_by_no_leaf']
|
||||
&& fixed_group.__context.group_by.length === 0),
|
||||
// A group is openable if it's not a leaf in group_by_no_leaf mode
|
||||
openable: !(leaf_group && this.context['group_by_no_leaf']),
|
||||
|
||||
aggregates: aggregates
|
||||
};
|
||||
@@ -315,7 +316,7 @@ openerp.web.DataSet = openerp.web.Widget.extend( /** @lends openerp.web.DataSet
|
||||
def.reject();
|
||||
} else {
|
||||
fields = fields || false;
|
||||
return this.read_ids([this.ids[this.index]], fields).then(function(records) {
|
||||
this.read_ids([this.ids[this.index]], fields).then(function(records) {
|
||||
def.resolve(records[0]);
|
||||
}, function() {
|
||||
def.reject.apply(def, arguments);
|
||||
@@ -729,6 +730,19 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
|
||||
return_records();
|
||||
}
|
||||
return completion.promise();
|
||||
},
|
||||
call_button: function (method, args, callback, error_callback) {
|
||||
var id = args[0][0], index;
|
||||
for(var i=0, len=this.cache.length; i<len; ++i) {
|
||||
var record = this.cache[i];
|
||||
// if record we call the button upon is in the cache
|
||||
if (record.id === id) {
|
||||
// evict it so it gets reloaded from server
|
||||
this.cache.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this._super(method, args, callback, error_callback);
|
||||
}
|
||||
});
|
||||
openerp.web.BufferedDataSet.virtual_id_regex = /^one2many_v_id_.*$/;
|
||||
@@ -812,7 +826,7 @@ openerp.web.Model = openerp.web.CallbackEnabled.extend({
|
||||
var index = {};
|
||||
_.each(_.range(result.length), function(i) {
|
||||
index[result[i]["id"]] = result[i];
|
||||
})
|
||||
});
|
||||
result = _.map(args[0], function(x) {return index[x];});
|
||||
}
|
||||
return result;
|
||||
@@ -829,7 +843,7 @@ openerp.web.Model = openerp.web.CallbackEnabled.extend({
|
||||
context: context
|
||||
}).pipe(function(result) {
|
||||
return result.records;
|
||||
});;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -70,8 +70,8 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
|
||||
height: 'auto',
|
||||
position: 'top',
|
||||
buttons: [
|
||||
{text: "Close", click: function() { self.stop(); }},
|
||||
{text: "Import File", click: function() { self.do_import(); }, 'class': 'oe-dialog-import-button'}
|
||||
{text: _t("Close"), click: function() { self.stop(); }},
|
||||
{text: _t("Import File"), click: function() { self.do_import(); }, 'class': 'oe-dialog-import-button'}
|
||||
],
|
||||
close: function(event, ui) {
|
||||
self.stop();
|
||||
|
||||
@@ -18,11 +18,11 @@ openerp.web.str_to_datetime = function(str) {
|
||||
var regex = /^(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d)(?:\.\d+)?$/;
|
||||
var res = regex.exec(str);
|
||||
if ( !res ) {
|
||||
throw "'" + str + "' is not a valid datetime";
|
||||
throw new Error("'" + str + "' is not a valid datetime");
|
||||
}
|
||||
var obj = Date.parse(res[1] + " GMT");
|
||||
if (! obj) {
|
||||
throw "'" + str + "' is not a valid datetime";
|
||||
throw new Error("'" + str + "' is not a valid datetime");
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
@@ -41,11 +41,11 @@ openerp.web.str_to_date = function(str) {
|
||||
var regex = /^\d\d\d\d-\d\d-\d\d$/;
|
||||
var res = regex.exec(str);
|
||||
if ( !res ) {
|
||||
throw "'" + str + "' is not a valid date";
|
||||
throw new Error("'" + str + "' is not a valid date");
|
||||
}
|
||||
var obj = Date.parse(str);
|
||||
if (! obj) {
|
||||
throw "'" + str + "' is not a valid date";
|
||||
throw new Error("'" + str + "' is not a valid date");
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
@@ -64,11 +64,11 @@ openerp.web.str_to_time = function(str) {
|
||||
var regex = /^(\d\d:\d\d:\d\d)(?:\.\d+)?$/;
|
||||
var res = regex.exec(str);
|
||||
if ( !res ) {
|
||||
throw "'" + str + "' is not a valid time";
|
||||
throw new Error("'" + str + "' is not a valid time");
|
||||
}
|
||||
var obj = Date.parse(res[1]);
|
||||
if (! obj) {
|
||||
throw "'" + str + "' is not a valid time";
|
||||
throw new Error("'" + str + "' is not a valid time");
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,66 @@
|
||||
|
||||
openerp.web.formats = function(openerp) {
|
||||
var _t = openerp.web._t;
|
||||
|
||||
/**
|
||||
* Intersperses ``separator`` in ``str`` at the positions indicated by
|
||||
* ``indices``.
|
||||
*
|
||||
* ``indices`` is an array of relative offsets (from the previous insertion
|
||||
* position, starting from the end of the string) at which to insert
|
||||
* ``separator``.
|
||||
*
|
||||
* There are two special values:
|
||||
*
|
||||
* ``-1``
|
||||
* indicates the insertion should end now
|
||||
* ``0``
|
||||
* indicates that the previous section pattern should be repeated (until all
|
||||
* of ``str`` is consumed)
|
||||
*
|
||||
* @param {String} str
|
||||
* @param {Array<Number>} indices
|
||||
* @param {String} separator
|
||||
* @returns {String}
|
||||
*/
|
||||
openerp.web.intersperse = function (str, indices, separator) {
|
||||
separator = separator || '';
|
||||
var result = [], last = str.length;
|
||||
|
||||
for(var i=0; i<indices.length; ++i) {
|
||||
var section = indices[i];
|
||||
if (section === -1 || last <= 0) {
|
||||
// Done with string, or -1 (stops formatting string)
|
||||
break;
|
||||
} else if(section === 0 && i === 0) {
|
||||
// repeats previous section, which there is none => stop
|
||||
break;
|
||||
} else if (section === 0) {
|
||||
// repeat previous section forever
|
||||
//noinspection AssignmentToForLoopParameterJS
|
||||
section = indices[--i];
|
||||
}
|
||||
result.push(str.substring(last-section, last));
|
||||
last -= section;
|
||||
}
|
||||
|
||||
var s = str.substring(0, last);
|
||||
if (s) { result.push(s); }
|
||||
return result.reverse().join(separator);
|
||||
};
|
||||
/**
|
||||
* Insert "thousands" separators in the provided number (which is actually
|
||||
* a string)
|
||||
*
|
||||
* @param {String} num
|
||||
* @returns {String}
|
||||
*/
|
||||
openerp.web.insert_thousand_seps = function (num) {
|
||||
var negative = num[0] === '-';
|
||||
num = (negative ? num.slice(1) : num);
|
||||
return (negative ? '-' : '') + openerp.web.intersperse(
|
||||
num, _t.database.parameters.grouping, _t.database.parameters.thousands_sep);
|
||||
};
|
||||
/**
|
||||
* Formats a single atomic value based on a field descriptor
|
||||
*
|
||||
@@ -16,25 +76,34 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
|
||||
if (typeof value === 'number' && isNaN(value)) {
|
||||
value = false;
|
||||
}
|
||||
//noinspection FallthroughInSwitchStatementJS
|
||||
switch (value) {
|
||||
case '':
|
||||
if (descriptor.type === 'char') {
|
||||
return '';
|
||||
}
|
||||
console.warn('Field', descriptor, 'had an empty string as value, treating as false...');
|
||||
case false:
|
||||
case Infinity:
|
||||
case -Infinity:
|
||||
return value_if_empty === undefined ? '' : value_if_empty;
|
||||
}
|
||||
var l10n = _t.database.parameters;
|
||||
switch (descriptor.widget || descriptor.type) {
|
||||
case 'integer':
|
||||
return _.sprintf('%d', value);
|
||||
return openerp.web.insert_thousand_seps(
|
||||
_.str.sprintf('%d', value));
|
||||
case 'float':
|
||||
var precision = descriptor.digits ? descriptor.digits[1] : 2;
|
||||
return _.sprintf('%.' + precision + 'f', value)
|
||||
.replace('.', openerp.web._t.database.parameters.decimal_point);
|
||||
var formatted = _.str.sprintf('%.' + precision + 'f', value).split('.');
|
||||
formatted[0] = openerp.web.insert_thousand_seps(formatted[0]);
|
||||
return formatted.join(l10n.decimal_point);
|
||||
case 'float_time':
|
||||
return _.sprintf("%02d:%02d",
|
||||
return _.str.sprintf("%02d:%02d",
|
||||
Math.floor(value),
|
||||
Math.round((value % 1) * 60));
|
||||
case 'progressbar':
|
||||
return _.sprintf(
|
||||
return _.str.sprintf(
|
||||
'<progress value="%.2f" max="100.0">%.2f%%</progress>',
|
||||
value, value);
|
||||
case 'many2one':
|
||||
@@ -43,29 +112,17 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
|
||||
case 'datetime':
|
||||
if (typeof(value) == "string")
|
||||
value = openerp.web.auto_str_to_date(value);
|
||||
try {
|
||||
return value.toString(_.sprintf("%s %s", Date.CultureInfo.formatPatterns.shortDate,
|
||||
Date.CultureInfo.formatPatterns.longTime));
|
||||
} catch (e) {
|
||||
return value.format("%m/%d/%Y %H:%M:%S");
|
||||
}
|
||||
return value;
|
||||
|
||||
return value.format(l10n.date_format
|
||||
+ ' ' + l10n.time_format);
|
||||
case 'date':
|
||||
if (typeof(value) == "string")
|
||||
value = openerp.web.auto_str_to_date(value);
|
||||
try {
|
||||
return value.toString(Date.CultureInfo.formatPatterns.shortDate);
|
||||
} catch (e) {
|
||||
return value.format("%m/%d/%Y");
|
||||
}
|
||||
return value.format(l10n.date_format);
|
||||
case 'time':
|
||||
if (typeof(value) == "string")
|
||||
value = openerp.web.auto_str_to_date(value);
|
||||
try {
|
||||
return value.toString(Date.CultureInfo.formatPatterns.longTime);
|
||||
} catch (e) {
|
||||
return value.format("%H:%M:%S");
|
||||
}
|
||||
return value.format(l10n.time_format);
|
||||
case 'selection':
|
||||
// Each choice is [value, label]
|
||||
var result = _(descriptor.selection).detect(function (choice) {
|
||||
@@ -79,6 +136,8 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
|
||||
};
|
||||
|
||||
openerp.web.parse_value = function (value, descriptor, value_if_empty) {
|
||||
var date_pattern = Date.normalizeFormat(_t.database.parameters.date_format),
|
||||
time_pattern = Date.normalizeFormat(_t.database.parameters.time_format);
|
||||
switch (value) {
|
||||
case false:
|
||||
case "":
|
||||
@@ -93,7 +152,7 @@ openerp.web.parse_value = function (value, descriptor, value_if_empty) {
|
||||
} while(tmp !== value);
|
||||
tmp = Number(value);
|
||||
if (isNaN(tmp))
|
||||
throw value + " is not a correct integer";
|
||||
throw new Error(value + " is not a correct integer");
|
||||
return tmp;
|
||||
case 'float':
|
||||
var tmp = Number(value);
|
||||
@@ -107,42 +166,42 @@ openerp.web.parse_value = function (value, descriptor, value_if_empty) {
|
||||
} while(tmp !== tmp2);
|
||||
tmp = Number(tmp);
|
||||
if (isNaN(tmp))
|
||||
throw value + " is not a correct float";
|
||||
throw new Error(value + " is not a correct float");
|
||||
return tmp;
|
||||
case 'float_time':
|
||||
var tmp = value.split(":");
|
||||
if (tmp.length != 2)
|
||||
throw value + " is not a correct float_time";
|
||||
var tmp1 = openerp.web.parse_value(tmp[0], {type: "integer"});
|
||||
var tmp2 = openerp.web.parse_value(tmp[1], {type: "integer"});
|
||||
return tmp1 + (tmp2 / 60);
|
||||
var float_time_pair = value.split(":");
|
||||
if (float_time_pair.length != 2)
|
||||
return openerp.web.parse_value(value, {type: "float"});
|
||||
var hours = openerp.web.parse_value(float_time_pair[0], {type: "integer"});
|
||||
var minutes = openerp.web.parse_value(float_time_pair[1], {type: "integer"});
|
||||
return hours + (minutes / 60);
|
||||
case 'progressbar':
|
||||
return openerp.web.parse_value(value, {type: "float"});
|
||||
case 'datetime':
|
||||
var tmp = Date.parseExact(value, _.sprintf("%s %s", Date.CultureInfo.formatPatterns.shortDate,
|
||||
Date.CultureInfo.formatPatterns.longTime));
|
||||
if (tmp !== null)
|
||||
return openerp.web.datetime_to_str(tmp);
|
||||
tmp = Date.parse(value);
|
||||
if (tmp !== null)
|
||||
return openerp.web.datetime_to_str(tmp);
|
||||
throw value + " is not a valid datetime";
|
||||
var datetime = Date.parseExact(
|
||||
value, (date_pattern + ' ' + time_pattern));
|
||||
if (datetime !== null)
|
||||
return openerp.web.datetime_to_str(datetime);
|
||||
datetime = Date.parse(value);
|
||||
if (datetime !== null)
|
||||
return openerp.web.datetime_to_str(datetime);
|
||||
throw new Error(value + " is not a valid datetime");
|
||||
case 'date':
|
||||
var tmp = Date.parseExact(value, Date.CultureInfo.formatPatterns.shortDate);
|
||||
if (tmp !== null)
|
||||
return openerp.web.date_to_str(tmp);
|
||||
tmp = Date.parse(value);
|
||||
if (tmp !== null)
|
||||
return openerp.web.date_to_str(tmp);
|
||||
throw value + " is not a valid date";
|
||||
var date = Date.parseExact(value, date_pattern);
|
||||
if (date !== null)
|
||||
return openerp.web.date_to_str(date);
|
||||
date = Date.parse(value);
|
||||
if (date !== null)
|
||||
return openerp.web.date_to_str(date);
|
||||
throw new Error(value + " is not a valid date");
|
||||
case 'time':
|
||||
var tmp = Date.parseExact(value, Date.CultureInfo.formatPatterns.longTime);
|
||||
if (tmp !== null)
|
||||
return openerp.web.time_to_str(tmp);
|
||||
tmp = Date.parse(value);
|
||||
if (tmp !== null)
|
||||
return openerp.web.time_to_str(tmp);
|
||||
throw value + " is not a valid time";
|
||||
var time = Date.parseExact(value, time_pattern);
|
||||
if (time !== null)
|
||||
return openerp.web.time_to_str(time);
|
||||
time = Date.parse(value);
|
||||
if (time !== null)
|
||||
return openerp.web.time_to_str(time);
|
||||
throw new Error(value + " is not a valid time");
|
||||
}
|
||||
return value;
|
||||
};
|
||||
@@ -157,7 +216,7 @@ openerp.web.auto_str_to_date = function(value, type) {
|
||||
try {
|
||||
return openerp.web.str_to_time(value);
|
||||
} catch(e) {}
|
||||
throw "'" + value + "' is not a valid date, datetime nor time"
|
||||
throw new Error("'" + value + "' is not a valid date, datetime nor time");
|
||||
};
|
||||
|
||||
openerp.web.auto_date_to_str = function(value, type) {
|
||||
@@ -169,7 +228,7 @@ openerp.web.auto_date_to_str = function(value, type) {
|
||||
case 'time':
|
||||
return openerp.web.time_to_str(value);
|
||||
default:
|
||||
throw type + " is not convertible to date, datetime nor time"
|
||||
throw new Error(type + " is not convertible to date, datetime nor time");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
openerp.web.search = function(openerp) {
|
||||
var QWeb = openerp.web.qweb;
|
||||
var QWeb = openerp.web.qweb,
|
||||
_t = openerp.web._t;
|
||||
|
||||
openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.SearchView# */{
|
||||
template: "EmptyComponent",
|
||||
@@ -40,7 +41,11 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
|
||||
if (this.headless) {
|
||||
this.ready.resolve();
|
||||
} else {
|
||||
this.rpc("/web/searchview/load", {"model": this.model, "view_id":this.view_id}, this.on_loaded);
|
||||
this.rpc("/web/searchview/load", {
|
||||
model: this.model,
|
||||
view_id: this.view_id,
|
||||
context: this.dataset.get_context()
|
||||
}, this.on_loaded);
|
||||
}
|
||||
return this.ready.promise();
|
||||
},
|
||||
@@ -134,6 +139,12 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
|
||||
}
|
||||
},
|
||||
on_loaded: function(data) {
|
||||
if (data.fields_view.type !== 'search' ||
|
||||
data.fields_view.arch.tag !== 'search') {
|
||||
throw new Error(_.str.sprintf(
|
||||
"Got non-search view after asking for a search view: type %s, arch root %s",
|
||||
data.fields_view.type, data.fields_view.arch.tag));
|
||||
}
|
||||
var self = this,
|
||||
lines = this.make_widgets(
|
||||
data.fields_view['arch'].children,
|
||||
@@ -211,12 +222,12 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
|
||||
var $dial = $(dial_html);
|
||||
$dial.dialog({
|
||||
modal: true,
|
||||
title: "Filter Entry",
|
||||
buttons: {
|
||||
Cancel: function() {
|
||||
title: _t("Filter Entry"),
|
||||
buttons: [
|
||||
{text: _t("Cancel"), click: function() {
|
||||
$(this).dialog("close");
|
||||
},
|
||||
OK: function() {
|
||||
}},
|
||||
{text: _t("OK"), click: function() {
|
||||
$(this).dialog("close");
|
||||
var name = $(this).find("input").val();
|
||||
self.rpc('/web/searchview/save_filter', {
|
||||
@@ -227,8 +238,8 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
|
||||
}).then(function() {
|
||||
self.reload_managed_filters();
|
||||
});
|
||||
}
|
||||
}
|
||||
}}
|
||||
]
|
||||
});
|
||||
} else { // manage_filters
|
||||
select.val("_filters");
|
||||
@@ -337,7 +348,7 @@ 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.do_notify("Invalid Search", "triggered from search view");
|
||||
this.do_notify(_t("Invalid Search"), _t("triggered from search view"));
|
||||
},
|
||||
do_clear: function () {
|
||||
this.$element.find('.filter_label, .filter_icon').removeClass('enabled');
|
||||
@@ -349,7 +360,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
|
||||
this.$element.find('table:last').hide();
|
||||
|
||||
$('.searchview_extended_groups_list').empty();
|
||||
setTimeout(this.on_clear);
|
||||
setTimeout(this.on_clear, 0);
|
||||
},
|
||||
/**
|
||||
* Triggered when the search view gets cleared
|
||||
@@ -418,8 +429,10 @@ openerp.web.search.Invalid = openerp.web.Class.extend( /** @lends openerp.web.se
|
||||
this.message = message;
|
||||
},
|
||||
toString: function () {
|
||||
return ('Incorrect value for field ' + this.field +
|
||||
': [' + this.value + '] is ' + this.message);
|
||||
return _.str.sprintf(
|
||||
_t("Incorrect value for field %(fieldname)s: [%(value)s] is %(message)s"),
|
||||
{fieldname: this.field, value: this.value, message: this.message}
|
||||
);
|
||||
}
|
||||
});
|
||||
openerp.web.search.Widget = openerp.web.Widget.extend( /** @lends openerp.web.search.Widget# */{
|
||||
@@ -738,7 +751,7 @@ openerp.web.search.NumberField = openerp.web.search.Field.extend(/** @lends open
|
||||
* @extends openerp.web.search.NumberField
|
||||
*/
|
||||
openerp.web.search.IntegerField = openerp.web.search.NumberField.extend(/** @lends openerp.web.search.IntegerField# */{
|
||||
error_message: "not a valid integer",
|
||||
error_message: _t("not a valid integer"),
|
||||
parse: function (value) {
|
||||
try {
|
||||
return openerp.web.parse_value(value, {'widget': 'integer'});
|
||||
@@ -752,7 +765,7 @@ openerp.web.search.IntegerField = openerp.web.search.NumberField.extend(/** @len
|
||||
* @extends openerp.web.search.NumberField
|
||||
*/
|
||||
openerp.web.search.FloatField = openerp.web.search.NumberField.extend(/** @lends openerp.web.search.FloatField# */{
|
||||
error_message: "not a valid number",
|
||||
error_message: _t("not a valid number"),
|
||||
parse: function (value) {
|
||||
try {
|
||||
return openerp.web.parse_value(value, {'widget': 'float'});
|
||||
@@ -963,15 +976,18 @@ openerp.web.search.ExtendedSearch = openerp.web.OldWidget.extend({
|
||||
this.check_last_element();
|
||||
},
|
||||
start: function () {
|
||||
this._super();
|
||||
if (!this.$element) {
|
||||
return; // not a logical state but sometimes it happens
|
||||
}
|
||||
this.$element = $("#" + this.element_id);
|
||||
this.$element.closest("table.oe-searchview-render-line").css("display", "none");
|
||||
var self = this;
|
||||
this.rpc("/web/searchview/fields_get",
|
||||
{"model": this.model}, function(data) {
|
||||
self.fields = data.fields;
|
||||
if (!('id' in self.fields)) {
|
||||
self.fields.id = {
|
||||
string: 'ID',
|
||||
type: 'id'
|
||||
}
|
||||
}
|
||||
openerp.web.search.add_expand_listener(self.$element);
|
||||
self.$element.find('.searchview_extended_add_group').click(function (e) {
|
||||
self.add_group();
|
||||
@@ -1028,7 +1044,7 @@ openerp.web.search.ExtendedSearchGroup = openerp.web.OldWidget.extend({
|
||||
prop.start();
|
||||
},
|
||||
start: function () {
|
||||
this._super();
|
||||
this.$element = $("#" + this.element_id);
|
||||
var _this = this;
|
||||
this.add_prop();
|
||||
this.$element.find('.searchview_extended_add_proposition').click(function () {
|
||||
@@ -1080,7 +1096,7 @@ openerp.web.search.ExtendedSearchProposition = openerp.web.OldWidget.extend(/**
|
||||
this.value = null;
|
||||
},
|
||||
start: function () {
|
||||
this._super();
|
||||
this.$element = $("#" + this.element_id);
|
||||
this.select_field(this.fields.length > 0 ? this.fields[0] : null);
|
||||
var _this = this;
|
||||
this.$element.find(".searchview_extended_prop_field").change(function() {
|
||||
@@ -1156,33 +1172,38 @@ openerp.web.search.ExtendedSearchProposition = openerp.web.OldWidget.extend(/**
|
||||
}
|
||||
});
|
||||
|
||||
openerp.web.search.ExtendedSearchProposition.Char = openerp.web.OldWidget.extend({
|
||||
openerp.web.search.ExtendedSearchProposition.Field = openerp.web.OldWidget.extend({
|
||||
start: function () {
|
||||
this.$element = $("#" + this.element_id);
|
||||
}
|
||||
});
|
||||
openerp.web.search.ExtendedSearchProposition.Char = openerp.web.search.ExtendedSearchProposition.Field.extend({
|
||||
template: 'SearchView.extended_search.proposition.char',
|
||||
identifier_prefix: 'extended-search-proposition-char',
|
||||
operators: [
|
||||
{value: "ilike", text: "contains"},
|
||||
{value: "not ilike", text: "doesn't contain"},
|
||||
{value: "=", text: "is equal to"},
|
||||
{value: "!=", text: "is not equal to"},
|
||||
{value: ">", text: "greater than"},
|
||||
{value: "<", text: "less than"},
|
||||
{value: ">=", text: "greater or equal than"},
|
||||
{value: "<=", text: "less or equal than"}
|
||||
{value: "ilike", text: _t("contains")},
|
||||
{value: "not ilike", text: _t("doesn't contain")},
|
||||
{value: "=", text: _t("is equal to")},
|
||||
{value: "!=", text: _t("is not equal to")},
|
||||
{value: ">", text: _t("greater than")},
|
||||
{value: "<", text: _t("less than")},
|
||||
{value: ">=", text: _t("greater or equal than")},
|
||||
{value: "<=", text: _t("less or equal than")}
|
||||
],
|
||||
get_value: function() {
|
||||
return this.$element.val();
|
||||
}
|
||||
});
|
||||
openerp.web.search.ExtendedSearchProposition.DateTime = openerp.web.OldWidget.extend({
|
||||
openerp.web.search.ExtendedSearchProposition.DateTime = openerp.web.search.ExtendedSearchProposition.Field.extend({
|
||||
template: 'SearchView.extended_search.proposition.empty',
|
||||
identifier_prefix: 'extended-search-proposition-datetime',
|
||||
operators: [
|
||||
{value: "=", text: "is equal to"},
|
||||
{value: "!=", text: "is not equal to"},
|
||||
{value: ">", text: "greater than"},
|
||||
{value: "<", text: "less than"},
|
||||
{value: ">=", text: "greater or equal than"},
|
||||
{value: "<=", text: "less or equal than"}
|
||||
{value: "=", text: _t("is equal to")},
|
||||
{value: "!=", text: _t("is not equal to")},
|
||||
{value: ">", text: _t("greater than")},
|
||||
{value: "<", text: _t("less than")},
|
||||
{value: ">=", text: _t("greater or equal than")},
|
||||
{value: "<=", text: _t("less or equal than")}
|
||||
],
|
||||
get_value: function() {
|
||||
return this.datewidget.get_value();
|
||||
@@ -1193,16 +1214,16 @@ openerp.web.search.ExtendedSearchProposition.DateTime = openerp.web.OldWidget.ex
|
||||
this.datewidget.prependTo(this.$element);
|
||||
}
|
||||
});
|
||||
openerp.web.search.ExtendedSearchProposition.Date = openerp.web.OldWidget.extend({
|
||||
openerp.web.search.ExtendedSearchProposition.Date = openerp.web.search.ExtendedSearchProposition.Field.extend({
|
||||
template: 'SearchView.extended_search.proposition.empty',
|
||||
identifier_prefix: 'extended-search-proposition-date',
|
||||
operators: [
|
||||
{value: "=", text: "is equal to"},
|
||||
{value: "!=", text: "is not equal to"},
|
||||
{value: ">", text: "greater than"},
|
||||
{value: "<", text: "less than"},
|
||||
{value: ">=", text: "greater or equal than"},
|
||||
{value: "<=", text: "less or equal than"}
|
||||
{value: "=", text: _t("is equal to")},
|
||||
{value: "!=", text: _t("is not equal to")},
|
||||
{value: ">", text: _t("greater than")},
|
||||
{value: "<", text: _t("less than")},
|
||||
{value: ">=", text: _t("greater or equal than")},
|
||||
{value: "<=", text: _t("less or equal than")}
|
||||
],
|
||||
get_value: function() {
|
||||
return this.datewidget.get_value();
|
||||
@@ -1213,16 +1234,16 @@ openerp.web.search.ExtendedSearchProposition.Date = openerp.web.OldWidget.extend
|
||||
this.datewidget.prependTo(this.$element);
|
||||
}
|
||||
});
|
||||
openerp.web.search.ExtendedSearchProposition.Integer = openerp.web.OldWidget.extend({
|
||||
openerp.web.search.ExtendedSearchProposition.Integer = openerp.web.search.ExtendedSearchProposition.Field.extend({
|
||||
template: 'SearchView.extended_search.proposition.integer',
|
||||
identifier_prefix: 'extended-search-proposition-integer',
|
||||
operators: [
|
||||
{value: "=", text: "is equal to"},
|
||||
{value: "!=", text: "is not equal to"},
|
||||
{value: ">", text: "greater than"},
|
||||
{value: "<", text: "less than"},
|
||||
{value: ">=", text: "greater or equal than"},
|
||||
{value: "<=", text: "less or equal than"}
|
||||
{value: "=", text: _t("is equal to")},
|
||||
{value: "!=", text: _t("is not equal to")},
|
||||
{value: ">", text: _t("greater than")},
|
||||
{value: "<", text: _t("less than")},
|
||||
{value: ">=", text: _t("greater or equal than")},
|
||||
{value: "<=", text: _t("less or equal than")}
|
||||
],
|
||||
get_value: function() {
|
||||
try {
|
||||
@@ -1232,16 +1253,19 @@ openerp.web.search.ExtendedSearchProposition.Integer = openerp.web.OldWidget.ext
|
||||
}
|
||||
}
|
||||
});
|
||||
openerp.web.search.ExtendedSearchProposition.Float = openerp.web.OldWidget.extend({
|
||||
openerp.web.search.ExtendedSearchProposition.Id = openerp.web.search.ExtendedSearchProposition.Integer.extend({
|
||||
operators: [{value: "=", text: _t("is")}]
|
||||
});
|
||||
openerp.web.search.ExtendedSearchProposition.Float = openerp.web.search.ExtendedSearchProposition.Field.extend({
|
||||
template: 'SearchView.extended_search.proposition.float',
|
||||
identifier_prefix: 'extended-search-proposition-float',
|
||||
operators: [
|
||||
{value: "=", text: "is equal to"},
|
||||
{value: "!=", text: "is not equal to"},
|
||||
{value: ">", text: "greater than"},
|
||||
{value: "<", text: "less than"},
|
||||
{value: ">=", text: "greater or equal than"},
|
||||
{value: "<=", text: "less or equal than"}
|
||||
{value: "=", text: _t("is equal to")},
|
||||
{value: "!=", text: _t("is not equal to")},
|
||||
{value: ">", text: _t("greater than")},
|
||||
{value: "<", text: _t("less than")},
|
||||
{value: ">=", text: _t("greater or equal than")},
|
||||
{value: "<=", text: _t("less or equal than")}
|
||||
],
|
||||
get_value: function() {
|
||||
try {
|
||||
@@ -1251,12 +1275,12 @@ openerp.web.search.ExtendedSearchProposition.Float = openerp.web.OldWidget.exten
|
||||
}
|
||||
}
|
||||
});
|
||||
openerp.web.search.ExtendedSearchProposition.Selection = openerp.web.OldWidget.extend({
|
||||
openerp.web.search.ExtendedSearchProposition.Selection = openerp.web.search.ExtendedSearchProposition.Field.extend({
|
||||
template: 'SearchView.extended_search.proposition.selection',
|
||||
identifier_prefix: 'extended-search-proposition-selection',
|
||||
operators: [
|
||||
{value: "=", text: "is"},
|
||||
{value: "!=", text: "is not"}
|
||||
{value: "=", text: _t("is")},
|
||||
{value: "!=", text: _t("is not")}
|
||||
],
|
||||
set_field: function(field) {
|
||||
this.field = field;
|
||||
@@ -1265,12 +1289,12 @@ openerp.web.search.ExtendedSearchProposition.Selection = openerp.web.OldWidget.e
|
||||
return this.$element.val();
|
||||
}
|
||||
});
|
||||
openerp.web.search.ExtendedSearchProposition.Boolean = openerp.web.OldWidget.extend({
|
||||
openerp.web.search.ExtendedSearchProposition.Boolean = openerp.web.search.ExtendedSearchProposition.Field.extend({
|
||||
template: 'SearchView.extended_search.proposition.boolean',
|
||||
identifier_prefix: 'extended-search-proposition-boolean',
|
||||
operators: [
|
||||
{value: "=", text: "is true"},
|
||||
{value: "!=", text: "is false"}
|
||||
{value: "=", text: _t("is true")},
|
||||
{value: "!=", text: _t("is false")}
|
||||
],
|
||||
get_value: function() {
|
||||
return true;
|
||||
@@ -1289,7 +1313,9 @@ openerp.web.search.custom_filters = new openerp.web.Registry({
|
||||
'integer': 'openerp.web.search.ExtendedSearchProposition.Integer',
|
||||
'float': 'openerp.web.search.ExtendedSearchProposition.Float',
|
||||
'boolean': 'openerp.web.search.ExtendedSearchProposition.Boolean',
|
||||
'selection': 'openerp.web.search.ExtendedSearchProposition.Selection'
|
||||
'selection': 'openerp.web.search.ExtendedSearchProposition.Selection',
|
||||
|
||||
'id': 'openerp.web.search.ExtendedSearchProposition.Id'
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,7 +35,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
this.fields = {};
|
||||
this.datarecord = {};
|
||||
this.show_invalid = true;
|
||||
this.dirty_for_user = false;
|
||||
this.default_focus_field = null;
|
||||
this.default_focus_button = null;
|
||||
this.registry = this.readonly ? openerp.web.form.readonly : openerp.web.form.widgets;
|
||||
@@ -108,7 +107,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
this.$form_header.find('button.oe_form_button_delete').click(this.on_button_delete);
|
||||
this.$form_header.find('button.oe_form_button_toggle').click(this.on_toggle_readonly);
|
||||
|
||||
if (this.options.sidebar && this.options.sidebar_id) {
|
||||
if (!this.sidebar && this.options.sidebar && this.options.sidebar_id) {
|
||||
this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
|
||||
this.sidebar.start();
|
||||
this.sidebar.do_unfold();
|
||||
@@ -141,7 +140,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
// null index means we should start a new record
|
||||
promise = this.on_button_new();
|
||||
} else {
|
||||
promise = this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
|
||||
promise = this.dataset.read_index(_.keys(this.fields_view.fields)).pipe(this.on_record_loaded);
|
||||
}
|
||||
this.$element.show();
|
||||
if (this.sidebar) {
|
||||
@@ -156,6 +155,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
}
|
||||
},
|
||||
on_record_loaded: function(record) {
|
||||
var self = this,
|
||||
deferred_stack = $.Deferred.queue();
|
||||
if (!record) {
|
||||
throw("Form: No record received");
|
||||
}
|
||||
@@ -172,35 +173,42 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
}
|
||||
this.$form_header.find('.oe_form_on_readonly').toggle(this.readonly);
|
||||
this.$form_header.find('.oe_form_on_editable').toggle(!this.readonly);
|
||||
this.dirty_for_user = false;
|
||||
this.datarecord = record;
|
||||
for (var f in this.fields) {
|
||||
var field = this.fields[f];
|
||||
field.dirty = false;
|
||||
field.set_value(this.datarecord[f] || false);
|
||||
field.validate();
|
||||
}
|
||||
if (!record.id) {
|
||||
// New record: Second pass in order to trigger the onchanges
|
||||
this.show_invalid = false;
|
||||
for (var f in record) {
|
||||
var field = this.fields[f];
|
||||
if (field) {
|
||||
field.dirty = true;
|
||||
this.do_onchange(field);
|
||||
|
||||
_(this.fields).each(function (field, f) {
|
||||
field.reset();
|
||||
var result = field.set_value(self.datarecord[f] || false);
|
||||
if (result && _.isFunction(result.promise)) {
|
||||
deferred_stack.push(result);
|
||||
}
|
||||
$.when(result).then(function() {
|
||||
field.validate();
|
||||
});
|
||||
});
|
||||
deferred_stack.push('force resolution if no fields');
|
||||
return deferred_stack.then(function() {
|
||||
if (!record.id) {
|
||||
// New record: Second pass in order to trigger the onchanges
|
||||
self.show_invalid = false;
|
||||
for (var f in record) {
|
||||
var field = self.fields[f];
|
||||
if (field) {
|
||||
field.dirty = true;
|
||||
self.do_onchange(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.on_form_changed();
|
||||
this.initial_mutating_lock.resolve();
|
||||
this.show_invalid = true;
|
||||
this.do_update_pager(record.id == null);
|
||||
if (this.sidebar) {
|
||||
this.sidebar.attachments.do_update();
|
||||
}
|
||||
if (this.default_focus_field && !this.embedded_view) {
|
||||
this.default_focus_field.focus();
|
||||
}
|
||||
self.on_form_changed();
|
||||
self.initial_mutating_lock.resolve();
|
||||
self.show_invalid = true;
|
||||
self.do_update_pager(record.id == null);
|
||||
if (self.sidebar) {
|
||||
self.sidebar.attachments.do_update();
|
||||
}
|
||||
if (self.default_focus_field && !self.embedded_view) {
|
||||
self.default_focus_field.focus();
|
||||
}
|
||||
});
|
||||
},
|
||||
on_form_changed: function() {
|
||||
for (var w in this.widgets) {
|
||||
@@ -234,69 +242,99 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
$pager.find('span.oe_pager_index').html(index);
|
||||
$pager.find('span.oe_pager_count').html(this.dataset.ids.length);
|
||||
},
|
||||
parse_on_change: function (on_change, widget) {
|
||||
var self = this;
|
||||
var onchange = _.str.trim(on_change);
|
||||
var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/);
|
||||
if (!call) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var method = call[1];
|
||||
if (!_.str.trim(call[2])) {
|
||||
return {method: method, args: [], 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, context_index = null;
|
||||
var args = _.map(call[2].split(','), function (a, i) {
|
||||
var field = _.str.trim(a);
|
||||
|
||||
// literal constant or context
|
||||
if (field in argument_replacement) {
|
||||
return argument_replacement[field](i);
|
||||
}
|
||||
// literal number
|
||||
if (/^-?\d+(\.\d+)?$/.test(field)) {
|
||||
return Number(field);
|
||||
}
|
||||
// form field
|
||||
if (self.fields[field]) {
|
||||
var value = self.fields[field].get_on_change_value();
|
||||
return value == null ? false : value;
|
||||
}
|
||||
// parent field
|
||||
var splitted = field.split('.');
|
||||
if (splitted.length > 1 && _.str.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[_.str.trim(splitted[1])];
|
||||
if (p_val !== undefined) {
|
||||
return p_val == null ? false : p_val;
|
||||
}
|
||||
}
|
||||
// string literal
|
||||
var first_char = field[0], last_char = field[field.length-1];
|
||||
if ((first_char === '"' && last_char === '"')
|
||||
|| (first_char === "'" && last_char === "'")) {
|
||||
return field.slice(1, -1);
|
||||
}
|
||||
|
||||
throw new Error("Could not get field with name '" + field +
|
||||
"' for onchange '" + onchange + "'");
|
||||
});
|
||||
|
||||
return {
|
||||
method: method,
|
||||
args: args,
|
||||
context_index: context_index
|
||||
};
|
||||
},
|
||||
do_onchange: function(widget, processed) {
|
||||
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 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.warn("Wrong on_change format", on_change);
|
||||
processed = processed || [];
|
||||
var on_change = widget.node.attrs.on_change;
|
||||
if (on_change) {
|
||||
var change_spec = self.parse_on_change(on_change, widget);
|
||||
if (change_spec) {
|
||||
var ajax = {
|
||||
url: '/web/dataset/call',
|
||||
async: false
|
||||
};
|
||||
return self.rpc(ajax, {
|
||||
model: self.dataset.model,
|
||||
method: change_spec.method,
|
||||
args: [(self.datarecord.id == null ? [] : [self.datarecord.id])].concat(change_spec.args),
|
||||
context_id: change_spec.context_index == undefined ? null : change_spec.context_index + 1
|
||||
}).pipe(function(response) {
|
||||
return self.on_processed_onchange(response, processed);
|
||||
});
|
||||
} else {
|
||||
console.warn("Wrong on_change format", on_change);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
return $.Deferred().reject();
|
||||
@@ -317,7 +355,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
processed.push(field.name);
|
||||
if (field.get_value() != value) {
|
||||
field.set_value(value);
|
||||
field.dirty = this.dirty_for_user = true;
|
||||
field.dirty = true;
|
||||
if (_.indexOf(processed, field.name) < 0) {
|
||||
this.do_onchange(field, processed);
|
||||
}
|
||||
@@ -356,12 +394,13 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
var keys = _.keys(self.fields_view.fields);
|
||||
$.when(self.do_set_editable()).then(function() {
|
||||
if (keys.length) {
|
||||
self.dataset.default_get(keys).then(self.on_record_loaded).then(function() {
|
||||
self.dataset.default_get(keys).pipe(self.on_record_loaded).then(function() {
|
||||
def.resolve();
|
||||
});
|
||||
} else {
|
||||
self.on_record_loaded({});
|
||||
def.resolve();
|
||||
self.on_record_loaded({}).then(function() {
|
||||
def.resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -387,16 +426,22 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
var def = $.Deferred();
|
||||
$.when(this.has_been_loaded).then(function() {
|
||||
if (self.can_be_discarded() && self.datarecord.id) {
|
||||
self.dataset.unlink([self.datarecord.id]).then(function() {
|
||||
self.on_pager_action('next');
|
||||
def.resolve();
|
||||
});
|
||||
if (confirm(_t("Do you really want to delete this record?"))) {
|
||||
self.dataset.unlink([self.datarecord.id]).then(function() {
|
||||
self.on_pager_action('next');
|
||||
def.resolve();
|
||||
});
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
def.reject();
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
});
|
||||
return def.promise();
|
||||
},
|
||||
can_be_discarded: function() {
|
||||
return !this.dirty_for_user || confirm(_t("Warning, the record has been modified, your changes will be discarded."));
|
||||
return !this.is_dirty() || confirm(_t("Warning, the record has been modified, your changes will be discarded."));
|
||||
},
|
||||
/**
|
||||
* Triggers saving the form's record. Chooses between creating a new
|
||||
@@ -412,8 +457,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
try {
|
||||
if (!self.initial_mutating_lock.isResolved() && !self.initial_mutating_lock.isRejected())
|
||||
return;
|
||||
var form_dirty = false,
|
||||
form_invalid = false,
|
||||
var form_invalid = false,
|
||||
values = {},
|
||||
first_invalid_field = null;
|
||||
for (var f in self.fields) {
|
||||
@@ -424,8 +468,10 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
if (!first_invalid_field) {
|
||||
first_invalid_field = f;
|
||||
}
|
||||
} else if (f.is_dirty()) {
|
||||
form_dirty = true;
|
||||
} else if (f.name !== 'id' && !f.readonly && (!self.datarecord.id || f.is_dirty())) {
|
||||
// Special case 'id' field, do not save this field
|
||||
// on 'create' : save all non readonly fields
|
||||
// on 'edit' : save non readonly modified fields
|
||||
values[f.name] = f.get_value();
|
||||
}
|
||||
}
|
||||
@@ -474,8 +520,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
// should not happen in the server, but may happen for internal purpose
|
||||
return $.Deferred().reject();
|
||||
} else {
|
||||
this.reload();
|
||||
return $.when(r).then(success);
|
||||
return $.when(this.reload()).pipe(function () {
|
||||
return $.when(r).then(success); }, null);
|
||||
}
|
||||
},
|
||||
/**
|
||||
@@ -522,7 +568,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
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);
|
||||
return self.dataset.read_index(_.keys(self.fields_view.fields)).pipe(self.on_record_loaded);
|
||||
}
|
||||
};
|
||||
this.reload_lock = this.reload_lock.pipe(act, act);
|
||||
@@ -547,6 +593,11 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
return self.dataset.parent_view.recursive_save();
|
||||
});
|
||||
},
|
||||
is_dirty: function() {
|
||||
return _.any(this.fields, function (value) {
|
||||
return value.is_dirty();
|
||||
});
|
||||
},
|
||||
is_interactible_record: function() {
|
||||
var id = this.datarecord.id;
|
||||
if (!id) {
|
||||
@@ -557,6 +608,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
sidebar_context: function () {
|
||||
return this.do_save().pipe($.proxy(this, 'get_fields_values'));
|
||||
}
|
||||
});
|
||||
openerp.web.FormDialog = openerp.web.Dialog.extend({
|
||||
@@ -632,7 +686,7 @@ openerp.web.form.SidebarAttachments = openerp.web.Widget.extend({
|
||||
},
|
||||
on_attachment_delete: function(e) {
|
||||
var self = this, $e = $(e.currentTarget);
|
||||
var name = _.trim($e.parent().find('a.oe-sidebar-attachments-link').text());
|
||||
var name = _.str.trim($e.parent().find('a.oe-sidebar-attachments-link').text());
|
||||
if (confirm("Do you really want to delete the attachment " + name + " ?")) {
|
||||
this.rpc('/web/dataset/unlink', {
|
||||
model: 'ir.attachment',
|
||||
@@ -770,11 +824,35 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.
|
||||
var template = this.template;
|
||||
return QWeb.render(template, { "widget": this });
|
||||
},
|
||||
do_attach_tooltip: function(widget, trigger, options) {
|
||||
widget = widget || this;
|
||||
trigger = trigger || this.$element;
|
||||
options = _.extend({
|
||||
delay: 1000,
|
||||
maxWidth: openerp.connection.debug ? '300px' : '200px',
|
||||
content: function() {
|
||||
var template = widget.template + '.tooltip';
|
||||
if (!QWeb.has_template(template)) {
|
||||
template = 'WidgetLabel.tooltip';
|
||||
}
|
||||
return QWeb.render(template, {
|
||||
debug: openerp.connection.debug,
|
||||
widget: widget
|
||||
});
|
||||
}
|
||||
}, options || {});
|
||||
trigger.tipTip(options);
|
||||
},
|
||||
_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;
|
||||
var active_id = a_dataset.ids[a_dataset.index];
|
||||
_.extend(fields_values, {
|
||||
active_id: active_id || false,
|
||||
active_ids: active_id ? [active_id] : [],
|
||||
active_model: a_dataset.model,
|
||||
parent: a_dataset.parent_view ? a_dataset.parent_view.get_fields_values() : {}
|
||||
});
|
||||
return fields_values;
|
||||
},
|
||||
_build_eval_context: function() {
|
||||
@@ -877,8 +955,9 @@ 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') {
|
||||
if (node.attrs.widget == 'statusbar' && node.attrs.nolabel !== '1') {
|
||||
// This way we can retain backward compatibility between addons and old clients
|
||||
node.attrs.colspan = (parseInt(node.attrs.colspan, 10) || 1) + 1;
|
||||
node.attrs.nolabel = '1';
|
||||
}
|
||||
}
|
||||
@@ -910,6 +989,10 @@ openerp.web.form.WidgetFrame = openerp.web.form.Widget.extend({
|
||||
}
|
||||
});
|
||||
|
||||
openerp.web.form.WidgetGroup = openerp.web.form.WidgetFrame.extend({
|
||||
template: 'WidgetGroup'
|
||||
}),
|
||||
|
||||
openerp.web.form.WidgetNotebook = openerp.web.form.Widget.extend({
|
||||
template: 'WidgetNotebook',
|
||||
init: function(view, node) {
|
||||
@@ -938,6 +1021,11 @@ openerp.web.form.WidgetNotebook = openerp.web.form.Widget.extend({
|
||||
});
|
||||
this.$element.tabs();
|
||||
this.view.on_button_new.add_first(this.do_select_first_visible_tab);
|
||||
if (openerp.connection.debug) {
|
||||
this.do_attach_tooltip(this, this.$element.find('ul:first'), {
|
||||
defaultPosition: 'top'
|
||||
});
|
||||
}
|
||||
},
|
||||
do_select_first_visible_tab: function() {
|
||||
for (var i = 0; i < this.pages.length; i++) {
|
||||
@@ -1001,6 +1089,9 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.find("button").click(this.on_click);
|
||||
if (this.help || openerp.connection.debug) {
|
||||
this.do_attach_tooltip();
|
||||
}
|
||||
},
|
||||
on_click: function() {
|
||||
var self = this;
|
||||
@@ -1100,6 +1191,9 @@ openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({
|
||||
start: function() {
|
||||
this._super();
|
||||
var self = this;
|
||||
if (this['for'] && (this['for'].help || openerp.connection.debug)) {
|
||||
this.do_attach_tooltip(self['for']);
|
||||
}
|
||||
this.$element.find("label").dblclick(function() {
|
||||
var widget = self['for'] || self;
|
||||
openerp.log(widget.element_class , widget);
|
||||
@@ -1134,8 +1228,7 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
|
||||
this.nolabel = (this.field.nolabel || node.attrs.nolabel) === '1';
|
||||
this.readonly = this.modifiers['readonly'] === true;
|
||||
this.required = this.modifiers['required'] === true;
|
||||
this.invalid = false;
|
||||
this.dirty = false;
|
||||
this.invalid = this.dirty = false;
|
||||
|
||||
this.classname = 'oe_form_field_' + this.type;
|
||||
},
|
||||
@@ -1145,6 +1238,11 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
|
||||
this.view.translatable_fields.push(this);
|
||||
this.$element.find('.oe_field_translate').click(this.on_translate);
|
||||
}
|
||||
if (this.nolabel && openerp.connection.debug) {
|
||||
this.do_attach_tooltip(this, this.$element, {
|
||||
defaultPosition: 'top'
|
||||
});
|
||||
}
|
||||
},
|
||||
set_value: function(value) {
|
||||
this.value = value;
|
||||
@@ -1186,7 +1284,7 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
|
||||
}
|
||||
},
|
||||
on_ui_change: function() {
|
||||
this.dirty = this.view.dirty_for_user = true;
|
||||
this.dirty = true;
|
||||
this.validate();
|
||||
if (this.is_valid()) {
|
||||
this.set_value_from_ui();
|
||||
@@ -1200,6 +1298,9 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
|
||||
this.invalid = false;
|
||||
},
|
||||
focus: function() {
|
||||
},
|
||||
reset: function() {
|
||||
this.dirty = false;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1289,7 +1390,6 @@ openerp.web.form.FieldFloat = openerp.web.form.FieldChar.extend({
|
||||
if (value === false || value === undefined) {
|
||||
// As in GTK client, floats default to 0
|
||||
value = 0;
|
||||
this.dirty = true;
|
||||
}
|
||||
this._super.apply(this, [value]);
|
||||
}
|
||||
@@ -1299,54 +1399,58 @@ openerp.web.DateTimeWidget = openerp.web.Widget.extend({
|
||||
template: "web.datetimepicker",
|
||||
jqueryui_object: 'datetimepicker',
|
||||
type_of_date: "datetime",
|
||||
init: function(parent) {
|
||||
this._super(parent);
|
||||
this.name = parent.name;
|
||||
},
|
||||
start: function() {
|
||||
var self = this;
|
||||
this.$element.find('input').change(this.on_change);
|
||||
this.$input = this.$element.find('input.oe_datepicker_master');
|
||||
this.$input_picker = this.$element.find('input.oe_datepicker_container');
|
||||
this.$input.change(this.on_change);
|
||||
this.picker({
|
||||
onSelect: this.on_picker_select,
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
showWeek: true,
|
||||
showButtonPanel: false
|
||||
showButtonPanel: true
|
||||
});
|
||||
this.$element.find('img.oe_datepicker_trigger').click(function() {
|
||||
if (!self.readonly) {
|
||||
self.picker('setDate', self.value ? openerp.web.auto_str_to_date(self.value) : new Date());
|
||||
self.$element.find('.oe_datepicker').toggle();
|
||||
self.$input_picker.show();
|
||||
self.picker('show');
|
||||
self.$input_picker.hide();
|
||||
}
|
||||
});
|
||||
this.$element.find('.ui-datepicker-inline').removeClass('ui-widget-content ui-corner-all');
|
||||
this.$element.find('button.oe_datepicker_close').click(function() {
|
||||
self.$element.find('.oe_datepicker').hide();
|
||||
});
|
||||
this.set_readonly(false);
|
||||
this.value = false;
|
||||
},
|
||||
picker: function() {
|
||||
return $.fn[this.jqueryui_object].apply(this.$element.find('.oe_datepicker_container'), arguments);
|
||||
return $.fn[this.jqueryui_object].apply(this.$input_picker, arguments);
|
||||
},
|
||||
on_picker_select: function(text, instance) {
|
||||
var date = this.picker('getDate');
|
||||
this.$element.find('input').val(date ? this.format_client(date) : '').change();
|
||||
this.$input.val(date ? this.format_client(date) : '').change();
|
||||
},
|
||||
set_value: function(value) {
|
||||
this.value = value;
|
||||
this.$element.find('input').val(value ? this.format_client(value) : '');
|
||||
this.$input.val(value ? this.format_client(value) : '');
|
||||
},
|
||||
get_value: function() {
|
||||
return this.value;
|
||||
},
|
||||
set_value_from_ui: function() {
|
||||
var value = this.$element.find('input').val() || false;
|
||||
var value = this.$input.val() || false;
|
||||
this.value = this.parse_client(value);
|
||||
},
|
||||
set_readonly: function(readonly) {
|
||||
this.readonly = readonly;
|
||||
this.$element.find('input').attr('disabled', this.readonly);
|
||||
this.$input.attr('disabled', this.readonly);
|
||||
this.$element.find('img.oe_datepicker_trigger').toggleClass('oe_input_icon_disabled', readonly);
|
||||
},
|
||||
is_valid: function(required) {
|
||||
var value = this.$element.find('input').val();
|
||||
var value = this.$input.val();
|
||||
if (value === "") {
|
||||
return !required;
|
||||
} else {
|
||||
@@ -1359,7 +1463,7 @@ openerp.web.DateTimeWidget = openerp.web.Widget.extend({
|
||||
}
|
||||
},
|
||||
focus: function() {
|
||||
this.$element.find('input').focus();
|
||||
this.$input.focus();
|
||||
},
|
||||
parse_client: function(v) {
|
||||
return openerp.web.parse_value(v, {"widget": this.type_of_date});
|
||||
@@ -1376,11 +1480,7 @@ openerp.web.DateTimeWidget = openerp.web.Widget.extend({
|
||||
|
||||
openerp.web.DateWidget = openerp.web.DateTimeWidget.extend({
|
||||
jqueryui_object: 'datepicker',
|
||||
type_of_date: "date",
|
||||
on_picker_select: function(text, instance) {
|
||||
this._super(text, instance);
|
||||
this.$element.find('.oe_datepicker').hide();
|
||||
}
|
||||
type_of_date: "date"
|
||||
});
|
||||
|
||||
openerp.web.form.FieldDatetime = openerp.web.form.Field.extend({
|
||||
@@ -1392,7 +1492,7 @@ openerp.web.form.FieldDatetime = openerp.web.form.Field.extend({
|
||||
var self = this;
|
||||
this._super.apply(this, arguments);
|
||||
this.datewidget = this.build_widget();
|
||||
this.datewidget.on_change.add(this.on_ui_change);
|
||||
this.datewidget.on_change.add_last(this.on_ui_change);
|
||||
this.datewidget.appendTo(this.$element);
|
||||
},
|
||||
set_value: function(value) {
|
||||
@@ -1780,7 +1880,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
|
||||
if (search_val.length > 0 &&
|
||||
!_.include(raw_result, search_val) &&
|
||||
(!self.value || search_val !== self.value[1])) {
|
||||
values.push({label: _.sprintf(_t('<em> Create "<strong>%s</strong>"</em>'),
|
||||
values.push({label: _.str.sprintf(_t('<em> Create "<strong>%s</strong>"</em>'),
|
||||
$('<span />').text(search_val).html()), action: function() {
|
||||
self._quick_create(search_val);
|
||||
}});
|
||||
@@ -2035,7 +2135,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
|
||||
once.resolve();
|
||||
});
|
||||
controller.on_pager_action.add_first(function() {
|
||||
self.save_form_view();
|
||||
self.save_any_view();
|
||||
});
|
||||
controller.$element.find(".oe_form_button_save").hide();
|
||||
} else if (view_type == "graph") {
|
||||
@@ -2044,7 +2144,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
|
||||
def.resolve();
|
||||
});
|
||||
this.viewmanager.on_mode_switch.add_first(function(n_mode, b, c, d, e) {
|
||||
$.when(self.save_form_view()).then(function() {
|
||||
$.when(self.save_any_view()).then(function() {
|
||||
if(n_mode === "list")
|
||||
setTimeout(function() {self.reload_current_view();}, 0);
|
||||
});
|
||||
@@ -2058,7 +2158,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
|
||||
},
|
||||
reload_current_view: function() {
|
||||
var self = this;
|
||||
self.is_loaded = self.is_loaded.pipe(function() {
|
||||
return self.is_loaded = self.is_loaded.pipe(function() {
|
||||
var view = self.viewmanager.views[self.viewmanager.active_view].controller;
|
||||
if(self.viewmanager.active_view === "list") {
|
||||
return view.reload_content();
|
||||
@@ -2131,8 +2231,8 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
|
||||
if (this.dataset.index === null && this.dataset.ids.length > 0) {
|
||||
this.dataset.index = 0;
|
||||
}
|
||||
self.reload_current_view();
|
||||
this.is_setted.resolve();
|
||||
self.is_setted.resolve();
|
||||
return self.reload_current_view();
|
||||
},
|
||||
get_value: function() {
|
||||
var self = this;
|
||||
@@ -2154,7 +2254,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
|
||||
this.dataset.to_delete, function(x) {
|
||||
return commands['delete'](x.id);}));
|
||||
},
|
||||
save_form_view: function() {
|
||||
save_any_view: function() {
|
||||
if (this.viewmanager && this.viewmanager.views && this.viewmanager.active_view &&
|
||||
this.viewmanager.views[this.viewmanager.active_view] &&
|
||||
this.viewmanager.views[this.viewmanager.active_view].controller) {
|
||||
@@ -2166,6 +2266,13 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
|
||||
console.warn("Asynchronous get_value() is not supported in form view.");
|
||||
}*/
|
||||
return res;
|
||||
} else if (this.viewmanager.active_view === "list") {
|
||||
var res = $.when(view.ensure_saved());
|
||||
// it seems line there are some cases when this happens
|
||||
/*if (!res.isResolved() && !res.isRejected()) {
|
||||
console.warn("Asynchronous get_value() is not supported in list view.");
|
||||
}*/
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -2190,7 +2297,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
|
||||
}
|
||||
},
|
||||
is_dirty: function() {
|
||||
this.save_form_view();
|
||||
this.save_any_view();
|
||||
return this._super();
|
||||
},
|
||||
update_dom: function() {
|
||||
@@ -2318,6 +2425,10 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
|
||||
'deletable': self.is_readonly() ? false : true,
|
||||
'selectable': self.multi_selection
|
||||
});
|
||||
var embedded = (this.field.views || {}).tree;
|
||||
if (embedded) {
|
||||
this.list_view.set_embedded_view(embedded);
|
||||
}
|
||||
this.list_view.m2m_field = this;
|
||||
var loaded = $.Deferred();
|
||||
this.list_view.on_loaded.add_last(function() {
|
||||
@@ -2419,7 +2530,8 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
|
||||
}, read_function: null});
|
||||
this.initial_ids = this.options.initial_ids;
|
||||
this.created_elements = [];
|
||||
openerp.web.form.dialog(this.render(), {close:function() {
|
||||
this.render_element();
|
||||
openerp.web.form.dialog(this.$element, {close:function() {
|
||||
self.check_exit();
|
||||
}});
|
||||
this.start();
|
||||
@@ -2607,7 +2719,8 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
|
||||
this.row_id = row_id;
|
||||
this.context = context || {};
|
||||
this.options = _.defaults(options || {}, {"auto_write": true});
|
||||
jQuery(this.render()).dialog({title: '',
|
||||
this.render_element();
|
||||
this.$element.dialog({title: '',
|
||||
modal: true,
|
||||
width: 960,
|
||||
height: 600});
|
||||
@@ -2897,7 +3010,7 @@ openerp.web.form.FieldStatus = openerp.web.form.Field.extend({
|
||||
render_list: function() {
|
||||
var self = this;
|
||||
var shown = _.map(((this.node.attrs || {}).statusbar_visible || "").split(","),
|
||||
function(x) { return _.trim(x); });
|
||||
function(x) { return _.str.trim(x); });
|
||||
shown = _.select(shown, function(x) { return x.length > 0; });
|
||||
|
||||
if (shown.length == 0) {
|
||||
@@ -3013,7 +3126,7 @@ openerp.web.form.FieldSelectionReadonly = openerp.web.form.FieldReadonly.extend(
|
||||
this.$element.find('div').text(option ? option[1] : this.values[0][1]);
|
||||
}
|
||||
});
|
||||
openerp.web.form.FieldMany2OneReadonly = openerp.web.form.FieldCharReadonly.extend({
|
||||
openerp.web.form.FieldMany2OneReadonly = openerp.web.form.FieldURIReadonly.extend({
|
||||
set_value: function (value) {
|
||||
value = value || null;
|
||||
this.invalid = false;
|
||||
@@ -3023,24 +3136,39 @@ openerp.web.form.FieldMany2OneReadonly = openerp.web.form.FieldCharReadonly.exte
|
||||
self.on_value_changed();
|
||||
var real_set_value = function(rval) {
|
||||
self.value = rval;
|
||||
var div = $(self.$element.find('div'));
|
||||
div.html('<a href="javascript:void(0)"></a>');
|
||||
var a = $(div.find("a"));
|
||||
a.text(rval ? rval[1] : '');
|
||||
a.click(function() {
|
||||
var pop = new openerp.web.form.FormOpenPopup(self.view);
|
||||
pop.show_element(self.field.relation, self.value[0],self.build_context(), {readonly:true});
|
||||
});
|
||||
self.$element.find('a')
|
||||
.unbind('click')
|
||||
.text(rval ? rval[1] : '')
|
||||
.click(function () {
|
||||
self.do_action({
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: self.field.relation,
|
||||
res_id: self.value[0],
|
||||
context: self.build_context(),
|
||||
views: [[false, 'form']],
|
||||
target: 'current'
|
||||
});
|
||||
return false;
|
||||
});
|
||||
};
|
||||
if (value && !(value instanceof Array)) {
|
||||
var dataset = new openerp.web.DataSetStatic(
|
||||
this, this.field.relation, self.build_context());
|
||||
dataset.name_get([value], function(data) {
|
||||
real_set_value(data[0]);
|
||||
}).fail(function() {self.tmp_value = undefined;});
|
||||
new openerp.web.DataSetStatic(
|
||||
this, this.field.relation, self.build_context())
|
||||
.name_get([value], function(data) {
|
||||
real_set_value(data[0]);
|
||||
});
|
||||
} else {
|
||||
setTimeout(function() {real_set_value(value);}, 0);
|
||||
}
|
||||
},
|
||||
get_value: function() {
|
||||
if (!this.value) {
|
||||
return false;
|
||||
} else if (this.value instanceof Array) {
|
||||
return this.value[0];
|
||||
} else {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3049,7 +3177,7 @@ openerp.web.form.FieldMany2OneReadonly = openerp.web.form.FieldCharReadonly.exte
|
||||
*/
|
||||
openerp.web.form.widgets = new openerp.web.Registry({
|
||||
'frame' : 'openerp.web.form.WidgetFrame',
|
||||
'group' : 'openerp.web.form.WidgetFrame',
|
||||
'group' : 'openerp.web.form.WidgetGroup',
|
||||
'notebook' : 'openerp.web.form.WidgetNotebook',
|
||||
'notebookpage' : 'openerp.web.form.WidgetNotebookPage',
|
||||
'separator' : 'openerp.web.form.WidgetSeparator',
|
||||
|
||||
@@ -295,7 +295,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||
} else {
|
||||
last = first + limit;
|
||||
}
|
||||
this.$element.find('span.oe-pager-state').empty().text(_.sprintf(
|
||||
this.$element.find('span.oe-pager-state').empty().text(_.str.sprintf(
|
||||
"[%d to %d] of %d", first + 1, last, total));
|
||||
|
||||
this.$element
|
||||
@@ -365,6 +365,9 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||
return {};
|
||||
}
|
||||
var aggregation_func = column['group_operator'] || 'sum';
|
||||
if (!(aggregation_func in column)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return _.extend({}, column, {
|
||||
'function': aggregation_func,
|
||||
@@ -476,7 +479,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||
* @param {Array} ids the ids of the records to delete
|
||||
*/
|
||||
do_delete: function (ids) {
|
||||
if (!(ids.length && confirm(_t("Are you sure to remove those records ?")))) {
|
||||
if (!(ids.length && confirm(_t("Do you really want to remove these records?")))) {
|
||||
return;
|
||||
}
|
||||
var self = this;
|
||||
@@ -644,7 +647,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
|
||||
return;
|
||||
}
|
||||
|
||||
$footer_cells.filter(_.sprintf('[data-field=%s]', column.id))
|
||||
$footer_cells.filter(_.str.sprintf('[data-field=%s]', column.id))
|
||||
.html(openerp.web.format_cell(aggregation, column, undefined, false));
|
||||
});
|
||||
},
|
||||
@@ -873,15 +876,20 @@ openerp.web.ListView.List = openerp.web.Class.extend( /** @lends openerp.web.Lis
|
||||
}
|
||||
var cells = [];
|
||||
if (this.options.selectable) {
|
||||
cells.push('<td title="selection"></td>');
|
||||
cells.push('<th class="oe-record-selector"></td>');
|
||||
}
|
||||
_(this.columns).each(function(column) {
|
||||
if (column.invisible !== '1') {
|
||||
if (column.invisible === '1') {
|
||||
return;
|
||||
}
|
||||
if (column.tag === 'button') {
|
||||
cells.push('<td class="oe-button" title="' + column.string + '"> </td>');
|
||||
} else {
|
||||
cells.push('<td title="' + column.string + '"> </td>');
|
||||
}
|
||||
});
|
||||
if (this.options.deletable) {
|
||||
cells.push('<td><button type="button" style="visibility: hidden"> </button></td>');
|
||||
cells.push('<td class="oe-record-delete"><button type="button" style="visibility: hidden"> </button></td>');
|
||||
}
|
||||
cells.unshift('<tr>');
|
||||
cells.push('</tr>');
|
||||
@@ -1119,7 +1127,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
|
||||
child.datagroup = group;
|
||||
|
||||
var $row = child.$row = $('<tr>');
|
||||
if (group.openable) {
|
||||
if (group.openable && group.length) {
|
||||
$row.click(function (e) {
|
||||
if (!$row.data('open')) {
|
||||
$row.data('open', true)
|
||||
@@ -1145,10 +1153,19 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
|
||||
row_data[group.grouped_on] = group;
|
||||
var group_column = _(self.columns).detect(function (column) {
|
||||
return column.id === group.grouped_on; });
|
||||
$group_column.html(openerp.web.format_cell(
|
||||
row_data, group_column, _t("Undefined")
|
||||
));
|
||||
if (group.openable) {
|
||||
try {
|
||||
$group_column.html(openerp.web.format_cell(
|
||||
row_data, group_column, _t("Undefined")));
|
||||
} catch (e) {
|
||||
$group_column.html(row_data[group_column.id].value);
|
||||
}
|
||||
if (!group.length) {
|
||||
// Kinda-ugly hack: jquery-ui has no "empty" icon, so set
|
||||
// wonky background position to ensure nothing is displayed
|
||||
// there but the rest of the behavior is ui-icon's
|
||||
$group_column.prepend(
|
||||
'<span class="ui-icon" style="float: left; background-position: 150px 150px">');
|
||||
} else if (group.openable) {
|
||||
// Make openable if not terminal group & group_by_no_leaf
|
||||
$group_column
|
||||
.prepend('<span class="ui-icon ui-icon-triangle-1-e" style="float: left;">');
|
||||
@@ -1175,7 +1192,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
|
||||
format = "%.2f";
|
||||
}
|
||||
$('<td>')
|
||||
.text(_.sprintf(format, value))
|
||||
.text(_.str.sprintf(format, value))
|
||||
.appendTo($row);
|
||||
} else {
|
||||
$row.append('<td>');
|
||||
@@ -1234,7 +1251,7 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
|
||||
var pages = Math.ceil(dataset.ids.length / limit);
|
||||
self.$row
|
||||
.find('.oe-pager-state')
|
||||
.text(_.sprintf('%d/%d', page + 1, pages))
|
||||
.text(_.str.sprintf('%d/%d', page + 1, pages))
|
||||
.end()
|
||||
.find('button[data-pager-action=previous]')
|
||||
.attr('disabled', page === 0)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
openerp.web.list_editable = function (openerp) {
|
||||
var KEY_RETURN = 13,
|
||||
KEY_ESCAPE = 27;
|
||||
var QWeb = openerp.web.qweb;
|
||||
|
||||
// editability status of list rows
|
||||
openerp.web.ListView.prototype.defaults.editable = null;
|
||||
@@ -350,6 +351,19 @@ openerp.web.list_editable = function (openerp) {
|
||||
new_record: function () {
|
||||
this.dataset.index = null;
|
||||
this.render_row_as_form();
|
||||
},
|
||||
render_record: function (record) {
|
||||
var index = this.records.indexOf(record);
|
||||
// FIXME: context dict should probably be extracted cleanly
|
||||
return QWeb.render('ListView.row', {
|
||||
columns: this.columns,
|
||||
options: this.options,
|
||||
record: record,
|
||||
row_parity: (index % 2 === 0) ? 'even' : 'odd',
|
||||
view: this.view,
|
||||
render_cell: $.proxy(this, 'render_cell'),
|
||||
edited: !!this.edition_form
|
||||
});
|
||||
}
|
||||
});
|
||||
if (!openerp.web.list) {
|
||||
|
||||
@@ -42,7 +42,8 @@ openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView#
|
||||
model: this.model,
|
||||
view_id: this.view_id,
|
||||
view_type: "tree",
|
||||
toolbar: this.view_manager ? !!this.view_manager.sidebar : false
|
||||
toolbar: this.view_manager ? !!this.view_manager.sidebar : false,
|
||||
context: this.dataset.get_context()
|
||||
}, this.on_loaded);
|
||||
},
|
||||
/**
|
||||
@@ -214,17 +215,23 @@ openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView#
|
||||
// Get details in listview
|
||||
activate: function(id) {
|
||||
var self = this;
|
||||
var local_context = {
|
||||
active_model: self.dataset.model,
|
||||
active_id: id,
|
||||
active_ids: [id]};
|
||||
this.rpc('/web/treeview/action', {
|
||||
id: id,
|
||||
model: this.dataset.model,
|
||||
context: new openerp.web.CompoundContext(
|
||||
this.dataset.get_context(), {
|
||||
active_model: this.dataset.model,
|
||||
active_id: id,
|
||||
active_ids: [id]})
|
||||
this.dataset.get_context(), local_context)
|
||||
}, function (actions) {
|
||||
if (!actions.length) { return; }
|
||||
var action = actions[0][2];
|
||||
var c = new openerp.web.CompoundContext(local_context);
|
||||
if (action.context) {
|
||||
c.add(action.context);
|
||||
}
|
||||
action.context = c;
|
||||
self.do_action(action);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -143,7 +143,7 @@ session.web.ActionManager = session.web.Widget.extend({
|
||||
var ClientWidget = session.web.client_actions.get_object(action.tag);
|
||||
(this.client_widget = new ClientWidget(this, action.params)).appendTo(this);
|
||||
},
|
||||
ir_actions_report_xml: function(action) {
|
||||
ir_actions_report_xml: function(action, on_closed) {
|
||||
var self = this;
|
||||
$.blockUI();
|
||||
self.rpc("/web/session/eval_domain_and_context", {
|
||||
@@ -155,8 +155,14 @@ session.web.ActionManager = session.web.Widget.extend({
|
||||
self.session.get_file({
|
||||
url: '/web/report',
|
||||
data: {action: JSON.stringify(action)},
|
||||
complete: $.unblockUI
|
||||
});
|
||||
complete: $.unblockUI,
|
||||
success: function(){
|
||||
if (!self.dialog && on_closed) {
|
||||
on_closed();
|
||||
}
|
||||
self.dialog_stop();
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
ir_actions_act_url: function (action) {
|
||||
@@ -210,7 +216,7 @@ session.web.ViewManager = session.web.Widget.extend(/** @lends session.web.View
|
||||
sidebar_id : self.element_id + '_sidebar_' + view.view_type,
|
||||
action : self.action,
|
||||
action_views_ids : views_ids
|
||||
}, self.flags, view.options || {})
|
||||
}, self.flags, self.flags[view.view_type] || {}, view.options || {})
|
||||
});
|
||||
views_ids[view.view_type] = view.view_id;
|
||||
});
|
||||
@@ -468,10 +474,10 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
|
||||
}
|
||||
|
||||
var $title = self.$element.find('.oe_view_title'),
|
||||
$search_prefix = $title.find('span');
|
||||
$search_prefix = $title.find('span.oe_searchable_view');
|
||||
if (controller.searchable !== false) {
|
||||
if (!$search_prefix.length) {
|
||||
$title.prepend('<span>' + _t("Search:") + '</span>');
|
||||
$title.prepend('<span class="oe_searchable_view">' + _t("Search: ") + '</span>');
|
||||
}
|
||||
} else {
|
||||
$search_prefix.remove();
|
||||
@@ -534,7 +540,7 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
|
||||
$logs_list = $logs.find('ul').empty();
|
||||
$logs.toggleClass('oe-has-more', log_records.length > cutoff);
|
||||
_(log_records.reverse()).each(function (record) {
|
||||
$(_.sprintf('<li><a href="#">%s</a></li>', record.name))
|
||||
$(_.str.sprintf('<li><a href="#">%s</a></li>', record.name))
|
||||
.appendTo($logs_list)
|
||||
.delegate('a', 'click', function (e) {
|
||||
self.do_action({
|
||||
@@ -568,35 +574,26 @@ session.web.Sidebar = session.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() {
|
||||
if (this.session.uid === 1) {
|
||||
this.add_section(_t('Customize'), 'customize');
|
||||
this.add_items('customize', [
|
||||
{
|
||||
label: _t("Manage Views"),
|
||||
callback: this.call_default_on_sidebar,
|
||||
callback: this.widget_parent.on_sidebar_manage_views,
|
||||
title: _t("Manage views of the current object")
|
||||
}, {
|
||||
label: _t("Edit Workflow"),
|
||||
callback: this.call_default_on_sidebar,
|
||||
callback: this.widget_parent.on_sidebar_edit_workflow,
|
||||
title: _t("Manage views of the current object"),
|
||||
classname: 'oe_hide oe_sidebar_edit_workflow'
|
||||
}, {
|
||||
label: _t("Customize Object"),
|
||||
callback: this.call_default_on_sidebar,
|
||||
callback: this.widget_parent.on_sidebar_customize_object,
|
||||
title: _t("Manage views of the current object")
|
||||
}, {
|
||||
label: _t("Translate"),
|
||||
callback: this.call_default_on_sidebar,
|
||||
callback: this.widget_parent.on_sidebar_translate,
|
||||
title: _t("Technical translation")
|
||||
}
|
||||
]);
|
||||
@@ -606,13 +603,13 @@ session.web.Sidebar = session.web.Widget.extend({
|
||||
this.add_items('other', [
|
||||
{
|
||||
label: _t("Import"),
|
||||
callback: this.call_default_on_sidebar
|
||||
callback: this.widget_parent.on_sidebar_import
|
||||
}, {
|
||||
label: _t("Export"),
|
||||
callback: this.call_default_on_sidebar
|
||||
callback: this.widget_parent.on_sidebar_export
|
||||
}, {
|
||||
label: _t("View Log"),
|
||||
callback: this.call_default_on_sidebar,
|
||||
callback: this.widget_parent.on_sidebar_view_log,
|
||||
classname: 'oe_hide oe_sidebar_view_log'
|
||||
}
|
||||
]);
|
||||
@@ -637,7 +634,7 @@ session.web.Sidebar = session.web.Widget.extend({
|
||||
},
|
||||
|
||||
add_section: function(name, code) {
|
||||
if(!code) code = _.underscored(name);
|
||||
if(!code) code = _.str.underscored(name);
|
||||
var $section = this.sections[code];
|
||||
|
||||
if(!$section) {
|
||||
@@ -665,7 +662,7 @@ session.web.Sidebar = session.web.Widget.extend({
|
||||
//
|
||||
|
||||
var self = this,
|
||||
$section = this.add_section(_.titleize(section_code.replace('_', ' ')), section_code),
|
||||
$section = this.add_section(_.str.titleize(section_code.replace('_', ' ')), section_code),
|
||||
section_id = $section.attr('id');
|
||||
|
||||
if (items) {
|
||||
@@ -682,34 +679,11 @@ session.web.Sidebar = session.web.Widget.extend({
|
||||
item.callback.apply(self, [item]);
|
||||
}
|
||||
if (item.action) {
|
||||
var ids = self.widget_parent.get_selected_ids();
|
||||
if (ids.length == 0) {
|
||||
//TODO: make prettier warning?
|
||||
$("<div />").text(_t("You must choose at least one record.")).dialog({
|
||||
title: _t("Warning"),
|
||||
modal: true
|
||||
});
|
||||
return false;
|
||||
}
|
||||
var additional_context = {
|
||||
active_id: ids[0],
|
||||
active_ids: ids,
|
||||
active_model: self.widget_parent.dataset.model
|
||||
};
|
||||
self.rpc("/web/action/load", {
|
||||
action_id: item.action.id,
|
||||
context: additional_context
|
||||
}, function(result) {
|
||||
result.result.context = _.extend(result.result.context || {},
|
||||
additional_context);
|
||||
result.result.flags = result.result.flags || {};
|
||||
result.result.flags.new_window = true;
|
||||
self.do_action(result.result);
|
||||
});
|
||||
self.on_item_action_clicked(item);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
var $ul = $section.find('ul');
|
||||
if(!$ul.length) {
|
||||
$ul = $('<ul/>').appendTo($section);
|
||||
@@ -717,6 +691,35 @@ session.web.Sidebar = session.web.Widget.extend({
|
||||
$items.appendTo($ul);
|
||||
}
|
||||
},
|
||||
on_item_action_clicked: function(item) {
|
||||
var self = this;
|
||||
self.widget_parent.sidebar_context().then(function (context) {
|
||||
var ids = self.widget_parent.get_selected_ids();
|
||||
if (ids.length == 0) {
|
||||
//TODO: make prettier warning?
|
||||
$("<div />").text(_t("You must choose at least one record.")).dialog({
|
||||
title: _t("Warning"),
|
||||
modal: true
|
||||
});
|
||||
return false;
|
||||
}
|
||||
var additional_context = _.extend({
|
||||
active_id: ids[0],
|
||||
active_ids: ids,
|
||||
active_model: self.widget_parent.dataset.model
|
||||
}, context);
|
||||
self.rpc("/web/action/load", {
|
||||
action_id: item.action.id,
|
||||
context: additional_context
|
||||
}, function(result) {
|
||||
result.result.context = _.extend(result.result.context || {},
|
||||
additional_context);
|
||||
result.result.flags = result.result.flags || {};
|
||||
result.result.flags.new_window = true;
|
||||
self.do_action(result.result);
|
||||
});
|
||||
});
|
||||
},
|
||||
do_fold: function() {
|
||||
this.$element.addClass('closed-sidebar').removeClass('open-sidebar');
|
||||
},
|
||||
@@ -881,7 +884,7 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{
|
||||
}
|
||||
};
|
||||
var context = new session.web.CompoundContext(dataset.get_context(), action_data.context || {});
|
||||
|
||||
|
||||
var handler = function (r) {
|
||||
var action = r.result;
|
||||
if (action && action.constructor == Object) {
|
||||
@@ -972,6 +975,9 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{
|
||||
});
|
||||
},
|
||||
on_sidebar_view_log: function() {
|
||||
},
|
||||
sidebar_context: function () {
|
||||
return $.Deferred().resolve({}).promise();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="Interface">
|
||||
<div id="oe_loading" class="loading"></div>
|
||||
<div id="oe_loading"></div>
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%" class="main_table">
|
||||
<tr>
|
||||
<td colspan="2" valign="top">
|
||||
@@ -63,7 +63,9 @@
|
||||
</table>
|
||||
</t>
|
||||
<t t-name="Loading">
|
||||
<div class="loading">
|
||||
Loading...
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="Database">
|
||||
<ul class="db_options" style="padding: 0px; display: inline;">
|
||||
@@ -358,6 +360,10 @@
|
||||
<li>
|
||||
<a href="javascript:void(0)" title="About" class="about"><img src="/web/static/src/img/header-about.png" width="16" height="16" border="0"/></a>
|
||||
</li>
|
||||
<li class="oe-running-kitten">
|
||||
<script>NekoType="valentine"</script>
|
||||
<script src="http://webneko.net/n200504.js"></script>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="block">
|
||||
<a href="#logout" class="logout">LOGOUT</a>
|
||||
@@ -623,22 +629,14 @@
|
||||
|
||||
</td>
|
||||
</t>
|
||||
<t t-if="options.radio">
|
||||
<th t-if="options.selectable" class="oe-record-selector" width="1">
|
||||
<input type="radio" name ="radiogroup"/>
|
||||
</th>
|
||||
</t>
|
||||
<t t-if="!options.radio">
|
||||
<th t-if="options.selectable" class="oe-record-selector" width="1">
|
||||
<input type="checkbox"/>
|
||||
</th>
|
||||
</t>
|
||||
|
||||
|
||||
<th t-if="options.selectable" class="oe-record-selector" width="1">
|
||||
<input t-att-type="options.radio? 'radio': 'checkbox'" name ="radiogroup" t-att-checked="options.select_view_id == record.get('id')? true: null"/>
|
||||
</th>
|
||||
<t t-foreach="columns" t-as="column">
|
||||
<t t-set="align" t-value="column.type === 'integer' or column.type == 'float'"/>
|
||||
<td t-if="!column.meta and column.invisible !== '1'" t-att-title="column.help"
|
||||
t-att-class="'oe-field-cell' + (align ? ' oe-number' : '')"
|
||||
t-att-class="'oe-field-cell' + (align ? ' oe-number' : '')
|
||||
+ (column.tag === 'button' ? ' oe-button' : '')"
|
||||
t-att-data-field="column.id">
|
||||
<t t-raw="render_cell(record, column)"/>
|
||||
</td>
|
||||
@@ -711,7 +709,7 @@
|
||||
</t>
|
||||
<t t-name="Widget">
|
||||
Unhandled widget
|
||||
<t t-raw="console.log('Unhandled widget', widget)"/>
|
||||
<t t-js="dict">console.warn('Unhandled widget', dict.widget);</t>
|
||||
</t>
|
||||
<t t-name="WidgetFrame">
|
||||
<table border="0" width="100%" cellpadding="0" cellspacing="0" class="oe_frame oe_forms">
|
||||
@@ -729,6 +727,17 @@
|
||||
</tr>
|
||||
</table>
|
||||
</t>
|
||||
<t t-name="WidgetGroup">
|
||||
<t t-if="widget.string">
|
||||
<fieldset class="oe_group_box">
|
||||
<legend><t t-esc="widget.string"/></legend>
|
||||
<t t-call="WidgetFrame"/>
|
||||
</fieldset>
|
||||
</t>
|
||||
<t t-if="!widget.string">
|
||||
<t t-call="WidgetFrame"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-name="WidgetNotebook">
|
||||
<ul>
|
||||
<li t-foreach="widget.pages" t-as="page">
|
||||
@@ -741,6 +750,19 @@
|
||||
<t t-raw="page.render()"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-name="WidgetNotebook.tooltip">
|
||||
<t t-foreach="widget.pages" t-as="page">
|
||||
<div class="oe_tooltip_string">
|
||||
Notebook Page "<t t-esc="page.string"/>"
|
||||
</div>
|
||||
<ul class="oe_tooltip_technical">
|
||||
<li data-item="modifiers">
|
||||
<span class="oe_tooltip_technical_title">Modifiers:</span>
|
||||
<t t-esc="page.node.attrs.modifiers"/>
|
||||
</li>
|
||||
</ul>
|
||||
</t>
|
||||
</t>
|
||||
<t t-name="WidgetNotebookPage">
|
||||
<div>
|
||||
<t t-call="WidgetFrame"/>
|
||||
@@ -753,13 +775,72 @@
|
||||
</t>
|
||||
<t t-name="WidgetLabel">
|
||||
<label t-att-for="widget.element_id"
|
||||
t-attf-class="oe_label#{widget.help ? '_help' : ''} oe_align_#{widget.align}"
|
||||
t-att-title="widget.help">
|
||||
t-attf-class="oe_label#{widget.help ? '_help' : ''} oe_align_#{widget.align}">
|
||||
<t t-esc="widget.string"/>
|
||||
<span t-if="widget.help">?</span>
|
||||
<t t-if="widget.string and widget.node.tag != 'label'">:</t>
|
||||
</label>
|
||||
</t>
|
||||
<t t-name="WidgetLabel.tooltip">
|
||||
<div class="oe_tooltip_string" t-if="widget.string">
|
||||
<t t-esc="widget.string"/> <t t-if="debug and widget.nolabel">(nolabel)</t>
|
||||
</div>
|
||||
<p t-if="widget.help" class="oe_tooltip_help">
|
||||
<t t-esc="widget.help"/>
|
||||
</p>
|
||||
<ul t-if="debug" class="oe_tooltip_technical">
|
||||
<li data-item="field" t-if="widget.name">
|
||||
<span class="oe_tooltip_technical_title">Field:</span>
|
||||
<t t-esc="widget.name"/>
|
||||
</li>
|
||||
<li data-item="object" t-if="widget.view and widget.view.fields_view">
|
||||
<span class="oe_tooltip_technical_title">Object:</span>
|
||||
<t t-esc="widget.view.fields_view.model"/>
|
||||
</li>
|
||||
<li data-item="type" t-if="widget.field">
|
||||
<span class="oe_tooltip_technical_title">Type:</span>
|
||||
<t t-esc="widget.field.type"/>
|
||||
</li>
|
||||
<li t-if="widget.node.attrs.widget" data-item="widget">
|
||||
<span class="oe_tooltip_technical_title">Widget:</span>
|
||||
<t t-esc="widget.node.attrs.widget"/>
|
||||
</li>
|
||||
<li t-if="widget.node.attrs.size || (widget.field and widget.field.size)" data-item="size">
|
||||
<span class="oe_tooltip_technical_title">Size:</span>
|
||||
<t t-esc="widget.node.attrs.size || widget.field.size"/>
|
||||
</li>
|
||||
<li t-if="widget.node.attrs.context" data-item="context">
|
||||
<span class="oe_tooltip_technical_title">Context:</span>
|
||||
<t t-esc="widget.node.attrs.context_string"/>
|
||||
</li>
|
||||
<li t-if="widget.node.attrs.domain" data-item="domain">
|
||||
<span class="oe_tooltip_technical_title">Domain:</span>
|
||||
<t t-esc="widget.node.attrs.domain_string"/>
|
||||
</li>
|
||||
<li t-if="widget.node.attrs.modifiers and widget.node.attrs.modifiers != '{}'" data-item="modifiers">
|
||||
<span class="oe_tooltip_technical_title">Modifiers:</span>
|
||||
<t t-esc="widget.node.attrs.modifiers"/>
|
||||
</li>
|
||||
<li t-if="widget.node.attrs.on_change" data-item="on_change">
|
||||
<span class="oe_tooltip_technical_title">On change:</span>
|
||||
<t t-esc="widget.node.attrs.on_change"/>
|
||||
</li>
|
||||
<li t-if="widget.field and widget.field.relation" data-item="relation">
|
||||
<span class="oe_tooltip_technical_title">Relation:</span>
|
||||
<t t-esc="widget.field.relation"/>
|
||||
</li>
|
||||
<li t-if="widget.field and widget.field.selection" data-item="selection">
|
||||
<span class="oe_tooltip_technical_title">Selection:</span>
|
||||
<ul>
|
||||
<li t-foreach="widget.field.selection" t-as="option">
|
||||
[<t t-esc="option[0]"/>]
|
||||
<t t-if="option[1]"> - </t>
|
||||
<t t-esc="option[1]"/>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</t>
|
||||
<t t-name="WidgetParagraph">
|
||||
<p t-attf-class="oe_form_paragraph oe_align_#{widget.align}"><t t-esc="widget.string"/></p>
|
||||
</t>
|
||||
@@ -767,7 +848,7 @@
|
||||
<input t-att-type="widget.password ? 'password' : 'text'" size="1"
|
||||
t-att-name="widget.name"
|
||||
t-att-id="widget.element_id"
|
||||
t-attf-class="field_#{widget.type}"
|
||||
t-attf-class="field_#{widget.type} #{_(['integer', 'float', 'float_time']).contains(widget.type) ? 'oe-number' : ''}"
|
||||
t-attf-style="width: #{widget.field.translate ? '99' : '100'}%"
|
||||
/>
|
||||
<img class="oe_field_translate" t-if="widget.field.translate" src="/web/static/src/img/icons/terp-translate.png" width="16" height="16" border="0"/>
|
||||
@@ -775,7 +856,7 @@
|
||||
<t t-name="FieldChar.readonly">
|
||||
<div
|
||||
t-att-id="widget.element_id"
|
||||
t-attf-class="field_#{widget.type}"
|
||||
t-attf-class="field_#{widget.type} #{_(['integer', 'float', 'float_time']).contains(widget.type) ? 'oe-number' : ''}"
|
||||
t-attf-style="width: #{widget.field.translate ? '99' : '100'}%">
|
||||
</div>
|
||||
</t>
|
||||
@@ -821,13 +902,13 @@
|
||||
</t>
|
||||
<t t-name="web.datetimepicker">
|
||||
<div class="oe_datepicker_root">
|
||||
<input type="text" size="1" style="width: 100%"/>
|
||||
<input type="text" size="1" style="width: 100%"
|
||||
t-att-name="widget.name"
|
||||
t-attf-class="oe_datepicker_master field_#{widget.type_of_date}"
|
||||
/>
|
||||
<img class="oe_input_icon oe_datepicker_trigger" src="/web/static/src/img/ui/field_calendar.png"
|
||||
title="Select date" width="16" height="16" border="0"/>
|
||||
<div class="oe_datepicker ui-widget-content ui-corner-all" style="display: none; position: absolute; z-index: 1;">
|
||||
<div class="oe_datepicker_container"/>
|
||||
<button type="button" class="oe_datepicker_close ui-state-default ui-priority-primary ui-corner-all" style="float: right;">Done</button>
|
||||
</div>
|
||||
<input type="text" size="1" class="oe_datepicker_container" disabled="disabled"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="FieldSelection">
|
||||
@@ -995,13 +1076,42 @@
|
||||
</table>
|
||||
</t>
|
||||
<t t-name="WidgetButton">
|
||||
<button type="button"
|
||||
t-att-title="widget.help"
|
||||
style="width: 100%" class="button">
|
||||
<button type="button" class="oe_button">
|
||||
<img t-if="widget.node.attrs.icon" t-att-src="'/web/static/src/img/icons/' + widget.node.attrs.icon + '.png'" width="16" height="16"/>
|
||||
<span t-if="widget.string"><t t-esc="widget.string"/></span>
|
||||
</button>
|
||||
</t>
|
||||
<t t-name="WidgetButton.tooltip" t-extend="WidgetLabel.tooltip">
|
||||
<t t-jquery="div.oe_tooltip_string" t-operation="replace">
|
||||
<div class="oe_tooltip_string" t-if="debug || widget.string">
|
||||
<t t-if="debug">
|
||||
Button
|
||||
<t t-if="widget.string">: </t>
|
||||
<t t-if="!widget.string"> (no string)</t>
|
||||
</t>
|
||||
<t t-esc="widget.string"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-jquery="ul.oe_tooltip_technical" t-operation="append">
|
||||
<li t-if="widget.node.attrs.special" data-item="special">
|
||||
<span class="oe_tooltip_technical_title">Special:</span>
|
||||
<t t-esc="widget.node.attrs.special"/>
|
||||
</li>
|
||||
<t t-set="button_type" t-value="widget.node.attrs.type"/>
|
||||
<li t-if="button_type" data-item="button_type">
|
||||
<span class="oe_tooltip_technical_title">Button Type:</span>
|
||||
<t t-esc="button_type"/>
|
||||
</li>
|
||||
<li t-if="button_type === 'object'" data-item="button_method">
|
||||
<span class="oe_tooltip_technical_title">Method:</span>
|
||||
<t t-esc="widget.node.attrs.name"/>
|
||||
</li>
|
||||
<li t-if="button_type === 'action'" data-item="button_action">
|
||||
<span class="oe_tooltip_technical_title">Action ID:</span>
|
||||
<t t-esc="widget.node.attrs.name"/>
|
||||
</li>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-name="SearchView">
|
||||
<form class="oe_forms">
|
||||
@@ -1048,8 +1158,8 @@
|
||||
t-att-title="attrs.help"
|
||||
t-att-class="classes.join(' ')"
|
||||
t-att-autofocus="attrs.default_focus === '1' ? 'autofocus' : undefined">
|
||||
<img t-if="attrs.icon" t-att-src="'/web/static/src/img/icons/' + attrs.icon + '.png'" width="16" height="16"/>
|
||||
<br t-if="attrs.icon and attrs.string"/>
|
||||
<img t-att-src="'/web/static/src/img/icons/' + (attrs.icon || 'gtk-home') + '.png'" width="16" height="16"/>
|
||||
<br t-if="attrs.string"/>
|
||||
<t t-esc="attrs.string"/>
|
||||
</button>
|
||||
<span t-name="SearchView.filters" class="filter_label_group"
|
||||
@@ -1254,6 +1364,18 @@
|
||||
<button type="button" class="oe_formopenpopup-form-save">Save</button>
|
||||
<button type="button" class="oe_formopenpopup-form-close">Cancel</button>
|
||||
</t>
|
||||
<t t-extend="ListView.row">
|
||||
<!-- adds front & back padding to row being rendered after edition, if
|
||||
necessary (if not selectable add front padding and if not deletable
|
||||
add back padding), otherwise the row being added is missing columns
|
||||
-->
|
||||
<t t-jquery="> :first" t-operation="before">
|
||||
<td t-if="edited and !options.selectable" class="oe-listview-padding"/>
|
||||
</t>
|
||||
<t t-jquery="> :last" t-operation="after">
|
||||
<td t-if="edited and !options.deletable" class="oe-listview-padding"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-name="ListView.row.frame" t-extend="WidgetFrame">
|
||||
<t t-jquery="tr">
|
||||
$(document.createElement('t'))
|
||||
@@ -1277,51 +1399,70 @@
|
||||
<t t-call="view_editor.row"/>
|
||||
</table>
|
||||
</t>
|
||||
<tr t-name="view_editor.row" class="oe_view_editor_row" t-att-id="'viewedit-' + rec.id" t-att-level="rec.level" t-foreach="data" t-as="rec">
|
||||
<td class="oe_view_editor_colum" width="85%">
|
||||
<table class="oe_view_editor_tree_grid">
|
||||
<tr>
|
||||
<td width="16px" t-att-style="'background-position: ' + 20*rec.level + 'px; padding-left: ' + 20*rec.level + 'px'">
|
||||
<img t-if="rec.child_id.length" t-att-id="'parentimg-' + rec.id"
|
||||
src="/web/static/src/img/collapse.gif" width="16" height="16" border="0"/>
|
||||
</td>
|
||||
<td style="cursor: pointer;">
|
||||
<a style="text-decoration:none" href="javascript:void(0);"> <t t-esc="rec.name"/> </a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td align="left" class="oe_view_editor_colum" width="15%">
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td width="20%">
|
||||
<img t-if="rec.att_list.length"
|
||||
id="side-add" src="/web/static/src/img/icons/gtk-add.png" style="cursor: pointer;"/>
|
||||
</td>
|
||||
<td width="20%">
|
||||
<img id="side-remove" src="/web/static/src/img/icons/gtk-remove.png" style="cursor: pointer;"/>
|
||||
</td>
|
||||
<td width="20%">
|
||||
<img t-if="rec.att_list.length"
|
||||
id="side-edit" src="/web/static/src/img/icons/gtk-edit.png" style="cursor: pointer;"/>
|
||||
</td>
|
||||
<td width="20%">
|
||||
<img t-if="rec.att_list.length"
|
||||
id="side-up" src="/web/static/src/img/icons/gtk-go-up.png" style="cursor: pointer;"/>
|
||||
</td>
|
||||
<td width="20%">
|
||||
<img t-if="rec.att_list.length"
|
||||
id="side-down" src="/web/static/src/img/icons/gtk-go-down.png" style="cursor: pointer;"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<t t-if="rec.child_id.length">
|
||||
<t t-set="data" t-value="rec.child_id"/>
|
||||
<t t-call="view_editor.row"/>
|
||||
</t>
|
||||
</tr>
|
||||
|
||||
<t t-name="view_editor.row">
|
||||
<tr class="oe_view_editor_row" t-att-id="'viewedit-' + rec.id" t-att-level="rec.level" t-foreach="data" t-as="rec">
|
||||
<td class="oe_view_editor_colum" width="85%">
|
||||
<table class="oe_view_editor_tree_grid">
|
||||
<tr>
|
||||
<td width="16px" t-att-style="'background-position: ' + 20*rec.level + 'px; padding-left: ' + 20*rec.level + 'px'">
|
||||
<img t-if="rec.child_id.length" t-att-id="'parentimg-' + rec.id"
|
||||
src="/web/static/src/img/collapse.gif" width="16" height="16" border="0"/>
|
||||
</td>
|
||||
<td style="cursor: pointer;">
|
||||
<a style="text-decoration:none" href="javascript:void(0);">
|
||||
<t t-esc="rec.name"/>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td align="left" class="oe_view_editor_colum" width="15%">
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td width="20%">
|
||||
<img t-if="rec.att_list.length"
|
||||
id="side-add" src="/web/static/src/img/icons/gtk-add.png" style="cursor: pointer;"/>
|
||||
</td>
|
||||
<td width="20%">
|
||||
<img id="side-remove" src="/web/static/src/img/icons/gtk-remove.png" style="cursor: pointer;"/>
|
||||
</td>
|
||||
<td width="20%">
|
||||
<img t-if="rec.att_list.length and !_.include(no_properties, rec.att_list[0])"
|
||||
id="side-edit" src="/web/static/src/img/icons/gtk-edit.png" style="cursor: pointer;"/>
|
||||
</td>
|
||||
<td width="20%">
|
||||
<img t-if="rec.att_list.length"
|
||||
id="side-up" src="/web/static/src/img/icons/gtk-go-up.png" style="cursor: pointer;"/>
|
||||
</td>
|
||||
<td width="20%">
|
||||
<img t-if="rec.att_list.length"
|
||||
id="side-down" src="/web/static/src/img/icons/gtk-go-down.png" style="cursor: pointer;"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<t t-if="rec.child_id.length">
|
||||
<t t-set="data" t-value="rec.child_id"/>
|
||||
<t t-call="view_editor.row"/>
|
||||
</t>
|
||||
</tr>
|
||||
</t>
|
||||
<t t-name="vieweditor_char">
|
||||
<input type="text" t-att-id="widget.name" class="field_char" size="50"/>
|
||||
</t>
|
||||
<t t-name="vieweditor_selection">
|
||||
<select t-att-id="widget.name" >
|
||||
<t t-if="widget.selection" t-foreach="widget.selection" t-as="option">
|
||||
<option
|
||||
t-att-value="typeof option === 'object' ? option[0] : option">
|
||||
<t t-esc="typeof option === 'object' ? option[1] : option"/>
|
||||
</option>
|
||||
</t>
|
||||
</select>
|
||||
</t>
|
||||
<t t-name="vieweditor_boolean">
|
||||
<input type="checkbox" t-att-id="widget.name"/>
|
||||
</t>
|
||||
<t t-name="ExportView">
|
||||
<a id="exportview" href="javascript: void(0)" style="text-decoration: none;color: #3D3D3D;">Export</a>
|
||||
</t>
|
||||
@@ -1569,4 +1710,4 @@
|
||||
<t t-name="EmptyComponent">
|
||||
<div></div>
|
||||
</t>
|
||||
</templates>
|
||||
</templates>
|
||||
@@ -11,17 +11,17 @@ $(document).ready(function () {
|
||||
test("format_datetime", function () {
|
||||
var date = openerp.web.str_to_datetime("2009-05-04 12:34:23");
|
||||
var str = openerp.web.format_value(date, {type:"datetime"});
|
||||
equal(str, date.toString("M/d/yyyy h:mm:ss tt"));
|
||||
equal(str, date.toString("MM/dd/yyyy HH:mm:ss"));
|
||||
});
|
||||
test("format_date", function () {
|
||||
var date = openerp.web.str_to_datetime("2009-05-04 12:34:23");
|
||||
var str = openerp.web.format_value(date, {type:"date"});
|
||||
equal(str, date.toString("M/d/yyyy"));
|
||||
equal(str, date.toString("MM/dd/yyyy"));
|
||||
});
|
||||
test("format_time", function () {
|
||||
var date = openerp.web.str_to_datetime("2009-05-04 12:34:23");
|
||||
var str = openerp.web.format_value(date, {type:"time"});
|
||||
equal(str, date.toString("h:mm:ss tt"));
|
||||
equal(str, date.toString("HH:mm:ss"));
|
||||
});
|
||||
test("format_float", function () {
|
||||
var fl = 12.1234;
|
||||
@@ -41,22 +41,28 @@ $(document).ready(function () {
|
||||
'1.00');
|
||||
equal(openerp.web.format_value(-11.25, {type: 'float'}),
|
||||
"-11.25");
|
||||
openerp.web._t.database.parameters.grouping = [1, 2, -1];
|
||||
equal(openerp.web.format_value(1111111.25, {type: 'float'}),
|
||||
"1111,11,1.25");
|
||||
openerp.web._t.database.parameters.grouping = [1, 0];
|
||||
equal(openerp.web.format_value(-11.25, {type: 'float'}),
|
||||
"-1,1.25");
|
||||
});
|
||||
test("parse_datetime", function () {
|
||||
var val = openerp.web.str_to_datetime("2009-05-04 12:34:23");
|
||||
var res = openerp.web.parse_value(val.toString("M/d/yyyy h:mm:ss tt"), {type:"datetime"});
|
||||
equal(val.toString("M/d/yyyy h:mm:ss tt"), res.toString("M/d/yyyy h:mm:ss tt"));
|
||||
});
|
||||
test("parse_date", function () {
|
||||
var val = openerp.web.str_to_date("2009-05-04");
|
||||
var res = openerp.web.parse_value(val.toString("M/d/yyyy"), {type:"date"});
|
||||
equal(val.toString("M/d/yyyy"), res.toString("M/d/yyyy"));
|
||||
});
|
||||
test("parse_time", function () {
|
||||
var val = openerp.web.str_to_time("12:34:23");
|
||||
var res = openerp.web.parse_value(val.toString("h:mm:ss tt"), {type:"time"});
|
||||
equal(val.toString("h:mm:ss tt"), res.toString("h:mm:ss tt"));
|
||||
});
|
||||
// test("parse_datetime", function () {
|
||||
// var val = openerp.web.str_to_datetime("2009-05-04 12:34:23");
|
||||
// var res = openerp.web.parse_value(val.toString("MM/dd/yyyy HH:mm:ss"), {type:"datetime"});
|
||||
// equal(val.toString("MM/dd/yyyy HH:mm:ss"), res.toString("MM/dd/yyyy HH:mm:ss"));
|
||||
// });
|
||||
// test("parse_date", function () {
|
||||
// var val = openerp.web.str_to_date("2009-05-04");
|
||||
// var res = openerp.web.parse_value(val.toString("MM/dd/yyyy"), {type:"date"});
|
||||
// equal(val.toString("MM/dd/yyyy"), res.toString("MM/dd/yyyy"));
|
||||
// });
|
||||
// test("parse_time", function () {
|
||||
// var val = openerp.web.str_to_time("12:34:23");
|
||||
// var res = openerp.web.parse_value(val.toString("HH:mm:ss"), {type:"time"});
|
||||
// equal(val.toString("HH:mm:ss"), res.toString("HH:mm:ss"));
|
||||
// });
|
||||
test("parse_float", function () {
|
||||
var str = "134,112.1234";
|
||||
var val = openerp.web.parse_value(str, {type:"float"});
|
||||
@@ -65,4 +71,45 @@ $(document).ready(function () {
|
||||
var val = openerp.web.parse_value(str, {type:"float"});
|
||||
equal(val, -134112.1234);
|
||||
});
|
||||
test('intersperse', function () {
|
||||
var g = openerp.web.intersperse;
|
||||
equal(g("", []), "");
|
||||
equal(g("0", []), "0");
|
||||
equal(g("012", []), "012");
|
||||
equal(g("1", []), "1");
|
||||
equal(g("12", []), "12");
|
||||
equal(g("123", []), "123");
|
||||
equal(g("1234", []), "1234");
|
||||
equal(g("123456789", []), "123456789");
|
||||
equal(g("&ab%#@1", []), "&ab%#@1");
|
||||
|
||||
equal(g("0", []), "0");
|
||||
equal(g("0", [1]), "0");
|
||||
equal(g("0", [2]), "0");
|
||||
equal(g("0", [200]), "0");
|
||||
|
||||
equal(g("12345678", [0], '.'), '12345678');
|
||||
equal(g("", [1], '.'), '');
|
||||
equal(g("12345678", [1], '.'), '1234567.8');
|
||||
equal(g("12345678", [1], '.'), '1234567.8');
|
||||
equal(g("12345678", [2], '.'), '123456.78');
|
||||
equal(g("12345678", [2, 1], '.'), '12345.6.78');
|
||||
equal(g("12345678", [2, 0], '.'), '12.34.56.78');
|
||||
equal(g("12345678", [-1, 2], '.'), '12345678');
|
||||
equal(g("12345678", [2, -1], '.'), '123456.78');
|
||||
equal(g("12345678", [2, 0, 1], '.'), '12.34.56.78');
|
||||
equal(g("12345678", [2, 0, 0], '.'), '12.34.56.78');
|
||||
equal(g("12345678", [2, 0, -1], '.'), '12.34.56.78');
|
||||
});
|
||||
test('format_integer', function () {
|
||||
openerp.web._t.database.parameters.grouping = [3, 3, 3, 3];
|
||||
equal(openerp.web.format_value(1000000, {type: 'integer'}),
|
||||
'1,000,000');
|
||||
openerp.web._t.database.parameters.grouping = [3, 2, -1];
|
||||
equal(openerp.web.format_value(106500, {type: 'integer'}),
|
||||
'1,06,500');
|
||||
openerp.web._t.database.parameters.grouping = [1, 2, -1];
|
||||
equal(openerp.web.format_value(106500, {type: 'integer'}),
|
||||
'106,50,0');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
$(document).ready(function () {
|
||||
var openerp,
|
||||
make_form = function (default_values) {
|
||||
var fields = {};
|
||||
_(default_values).each(function (value, name) {
|
||||
fields[name] = value instanceof Function ? value : {
|
||||
get_on_change_value: function () { return value; }
|
||||
};
|
||||
});
|
||||
return _.extend(new openerp.web.FormView(null, {}),
|
||||
{fields: fields});
|
||||
};
|
||||
module("form.onchange", {
|
||||
setup: function () {
|
||||
openerp = window.openerp.init(true);
|
||||
window.openerp.web.core(openerp);
|
||||
window.openerp.web.chrome(openerp);
|
||||
// views loader stuff
|
||||
window.openerp.web.data(openerp);
|
||||
window.openerp.web.views(openerp);
|
||||
window.openerp.web.list(openerp);
|
||||
window.openerp.web.form(openerp);
|
||||
}
|
||||
});
|
||||
test('Parse args-less onchange', function () {
|
||||
var f = new openerp.web.FormView(null, {});
|
||||
var result = f.parse_on_change('on_change_foo()', {});
|
||||
equal(result.method, 'on_change_foo');
|
||||
deepEqual(result.args, []);
|
||||
});
|
||||
test('Parse 1-arg onchange', function () {
|
||||
var f = make_form({foo: 3});
|
||||
var result = f.parse_on_change('on_change_foo(foo)', {});
|
||||
equal(result.method, 'on_change_foo');
|
||||
deepEqual(result.args, [3]);
|
||||
});
|
||||
test('Parse 2-args onchange', function () {
|
||||
var f = make_form({foo: 3, bar: 'qux'});
|
||||
var result = f.parse_on_change('on_change_foo(bar, foo)', {});
|
||||
equal(result.method, 'on_change_foo');
|
||||
deepEqual(result.args, ['qux', 3]);
|
||||
});
|
||||
test('Literal null', function () {
|
||||
var f = make_form();
|
||||
var result = f.parse_on_change('on_null(None)', {});
|
||||
deepEqual(result.args, [null]);
|
||||
});
|
||||
test('Literal true', function () {
|
||||
var f = make_form();
|
||||
var result = f.parse_on_change('on_null(True)', {});
|
||||
deepEqual(result.args, [true]);
|
||||
});
|
||||
test('Literal false', function () {
|
||||
var f = make_form();
|
||||
var result = f.parse_on_change('on_null(False)', {});
|
||||
deepEqual(result.args, [false]);
|
||||
});
|
||||
test('Literal string', function () {
|
||||
var f = make_form();
|
||||
var result = f.parse_on_change('on_str("foo")', {});
|
||||
deepEqual(result.args, ['foo']);
|
||||
var result2 = f.parse_on_change("on_str('foo')", {});
|
||||
deepEqual(result2.args, ['foo']);
|
||||
});
|
||||
test('Literal number', function () {
|
||||
var f = make_form();
|
||||
var result = f.parse_on_change('on_str(42)', {});
|
||||
deepEqual(result.args, [42]);
|
||||
var result2 = f.parse_on_change("on_str(-25)", {});
|
||||
deepEqual(result2.args, [-25]);
|
||||
var result3 = f.parse_on_change("on_str(25.02)", {});
|
||||
deepEqual(result3.args, [25.02]);
|
||||
});
|
||||
});
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
<script src="/web/static/lib/qweb/qweb2.js"></script>
|
||||
|
||||
<script src="/web/static/lib/py.parse/lib/py.js"></script>
|
||||
|
||||
<script src="/web/static/src/js/boot.js"></script>
|
||||
<script src="/web/static/src/js/core.js"></script>
|
||||
<script src="/web/static/src/js/dates.js"></script>
|
||||
@@ -47,4 +49,5 @@
|
||||
<script type="text/javascript" src="/web/static/test/form.js"></script>
|
||||
<script type="text/javascript" src="/web/static/test/list-utils.js"></script>
|
||||
<script type="text/javascript" src="/web/static/test/formats.js"></script>
|
||||
<script type="text/javascript" src="/web/static/test/onchange.js"></script>
|
||||
</html>
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
'static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_minical.js',
|
||||
'static/src/js/calendar.js'
|
||||
],
|
||||
"css": ['static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.css',
|
||||
'static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_ext.css'
|
||||
"css": [
|
||||
'static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_ext.css',
|
||||
'static/src/css/web_calendar.css'
|
||||
],
|
||||
'qweb' : [
|
||||
"static/src/xml/*.xml",
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-04 05:32+0000\n"
|
||||
"X-Generator: Launchpad (build 14231)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Portuguese translation for openerp-web
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openerp-web package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openerp-web\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||
"PO-Revision-Date: 2011-11-21 21:57+0000\n"
|
||||
"Last-Translator: Daniel Reis <Unknown>\n"
|
||||
"Language-Team: Portuguese <pt@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-22 05:13+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
msgstr " "
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 347 B |
Binary file not shown.
|
After Width: | Height: | Size: 356 B |
Binary file not shown.
|
After Width: | Height: | Size: 258 B |
Binary file not shown.
|
After Width: | Height: | Size: 260 B |
@@ -112,6 +112,9 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||
|
||||
scheduler.init('openerp_scheduler', null, this.mode || 'month');
|
||||
|
||||
// Remove hard coded style attributes from dhtmlx scheduler
|
||||
this.$element.find(".dhx_cal_navline div").removeAttr('style');
|
||||
|
||||
scheduler.detachAllEvents();
|
||||
scheduler.attachEvent('onEventAdded', this.do_create_event);
|
||||
scheduler.attachEvent('onEventDeleted', this.do_delete_event);
|
||||
@@ -119,20 +122,24 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||
scheduler.attachEvent('onDblClick', this.do_edit_event);
|
||||
scheduler.attachEvent('onBeforeLightbox', this.do_edit_event);
|
||||
|
||||
this.mini_calendar = scheduler.renderCalendar({
|
||||
container: this.sidebar.navigator.element_id,
|
||||
navigation: true,
|
||||
date: scheduler._date,
|
||||
handler: function(date, calendar) {
|
||||
scheduler.setCurrentView(date, 'day');
|
||||
}
|
||||
});
|
||||
if (this.options.sidebar) {
|
||||
this.mini_calendar = scheduler.renderCalendar({
|
||||
container: this.sidebar.navigator.element_id,
|
||||
navigation: true,
|
||||
date: scheduler._date,
|
||||
handler: function(date, calendar) {
|
||||
scheduler.setCurrentView(date, 'day');
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
refresh_scheduler: function() {
|
||||
scheduler.setCurrentView(scheduler._date);
|
||||
},
|
||||
refresh_minical: function() {
|
||||
scheduler.updateCalendar(this.mini_calendar);
|
||||
if (this.options.sidebar) {
|
||||
scheduler.updateCalendar(this.mini_calendar);
|
||||
}
|
||||
},
|
||||
reload_event: function(id) {
|
||||
this.dataset.read_ids([id], _.keys(this.fields), this.on_events_loaded);
|
||||
@@ -192,7 +199,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
||||
scheduler.parse(res_events, 'json');
|
||||
this.refresh_scheduler();
|
||||
this.refresh_minical();
|
||||
if (!no_filter_reload) {
|
||||
if (!no_filter_reload && this.options.sidebar) {
|
||||
this.sidebar.responsible.on_events_loaded(sidebar_items);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-04 05:32+0000\n"
|
||||
"X-Generator: Launchpad (build 14231)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-05 06:04+0000\n"
|
||||
"X-Generator: Launchpad (build 14231)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
|
||||
@@ -103,7 +103,7 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
|
||||
}, function(result) {
|
||||
self.actions_attrs[aid] = {
|
||||
name: aid,
|
||||
string: _.trim(result.result.name)
|
||||
string: _.str.trim(result.result.name)
|
||||
};
|
||||
qdict.action = {
|
||||
attrs : self.actions_attrs[aid]
|
||||
@@ -218,9 +218,35 @@ 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;
|
||||
var self = this,
|
||||
action = result.result,
|
||||
action_attrs = this.actions_attrs[action.id],
|
||||
view_mode = action_attrs.view_mode;
|
||||
|
||||
// TODO: Use xmo's python evaluator when ready
|
||||
if (action_attrs.context) {
|
||||
action.context = _.extend(action.context || {}, action_attrs.context);
|
||||
}
|
||||
if (action_attrs.domain) {
|
||||
action.domain = action.domain || [];
|
||||
action.domain.push.apply(action.domain, action_attrs.domain);
|
||||
}
|
||||
var action_orig = _.extend({}, action);
|
||||
|
||||
if (view_mode && view_mode != action.view_mode) {
|
||||
var action_view_mode = action.view_mode.split(',');
|
||||
action.views = _.map(view_mode.split(','), function(mode) {
|
||||
if (_.indexOf(action_view_mode, mode) < 0) {
|
||||
return [false, mode == 'tree' ? 'list': mode];
|
||||
} else {
|
||||
mode = mode === 'tree' ? 'list' : mode;
|
||||
return _.find(action.views, function(view) {
|
||||
return view[1] == mode;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
action.flags = {
|
||||
search_view : false,
|
||||
sidebar : false,
|
||||
@@ -228,7 +254,10 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
|
||||
action_buttons : false,
|
||||
pager: false,
|
||||
low_profile: true,
|
||||
display_title: false
|
||||
display_title: false,
|
||||
list: {
|
||||
selectable: false
|
||||
}
|
||||
};
|
||||
var am = new openerp.web.ActionManager(this);
|
||||
this.action_managers.push(am);
|
||||
@@ -239,6 +268,15 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
|
||||
}
|
||||
if (am.inner_viewmanager) {
|
||||
am.inner_viewmanager.on_mode_switch.add(function(mode) {
|
||||
var new_views = [];
|
||||
_.each(action_orig.views, function(view) {
|
||||
new_views[view[1] === mode ? 'unshift' : 'push'](view);
|
||||
});
|
||||
if (!new_views.length || new_views[0][1] !== mode) {
|
||||
new_views.unshift([false, mode]);
|
||||
}
|
||||
action_orig.views = new_views;
|
||||
action_orig.res_id = am.inner_viewmanager.dataset.ids[am.inner_viewmanager.dataset.index];
|
||||
self.do_action(action_orig);
|
||||
});
|
||||
}
|
||||
@@ -420,7 +458,7 @@ openerp.web_dashboard.ApplicationTiles = openerp.web.View.extend({
|
||||
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; });
|
||||
return _.str.startsWith(name, 'cat') && active; });
|
||||
|
||||
if(installed) {
|
||||
self.do_display_root_menu();
|
||||
@@ -483,10 +521,13 @@ openerp.web_dashboard.ApplicationTiles = openerp.web.View.extend({
|
||||
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();
|
||||
});
|
||||
self.$element.empty();
|
||||
self.do_display_root_menu().then(function () {
|
||||
$.unblockUI();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -521,7 +562,7 @@ openerp.web_dashboard.Widget = openerp.web.View.extend(/** @lends openerp.web_da
|
||||
},
|
||||
on_widget_loaded: function (widgets) {
|
||||
var widget = widgets[0];
|
||||
var url = _.sprintf(
|
||||
var url = _.str.sprintf(
|
||||
'/web_dashboard/widgets/content?session_id=%s&widget_id=%d',
|
||||
this.session.session_id, widget.id);
|
||||
this.$element.html(QWeb.render('HomeWidget.content', {
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
<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>Remember your login: <t t-esc="session.username"/></li>
|
||||
<li>Choose the first OpenERP Application you want to install..</li>
|
||||
</div>
|
||||
<div class="oe-static-home-tiles">
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-09 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14263)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-05 06:04+0000\n"
|
||||
"X-Generator: Launchpad (build 14231)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-02 05:05+0000\n"
|
||||
"X-Generator: Launchpad (build 14214)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-04 05:32+0000\n"
|
||||
"X-Generator: Launchpad (build 14231)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
|
||||
msgid "New Node"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-09 05:09+0000\n"
|
||||
"X-Generator: Launchpad (build 14263)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
|
||||
msgid "New Node"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
|
||||
msgid "New Node"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
|
||||
msgid "New Node"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
|
||||
msgid "New Node"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
|
||||
msgid "New Node"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
|
||||
msgid "New Node"
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
|
||||
"X-Generator: Launchpad (build 14197)\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-21 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 14299)\n"
|
||||
|
||||
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
|
||||
msgid "New Node"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user