[IMP]improve code,merge with main branch and fix first element append issue.

bzr revid: vme@tinyerp.com-20111114101721-sz2dym1oho9b1c8b
bzr revid: vme@tinyerp.com-20111115093836-bq4wcc7sdru2no4c
This commit is contained in:
Vidhin Mehta (OpenERP) 2011-11-15 15:08:36 +05:30
commit 5e398b0834
19 changed files with 2001 additions and 317 deletions

View File

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

View File

@ -307,7 +307,7 @@ class Database(openerpweb.Controller):
@openerpweb.httprequest
def restore(self, req, db_file, restore_pwd, new_db):
try:
data = base64.b64encode(db_file.file.read())
data = base64.b64encode(db_file.read())
req.session.proxy("db").restore(restore_pwd, new_db, data)
return ''
except xmlrpclib.Fault, e:
@ -935,10 +935,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):

683
addons/web/po/pt_BR.po Normal file
View File

@ -0,0 +1,683 @@
# Brazilian Portuguese translation for openerp-web
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
"PO-Revision-Date: 2011-11-12 18:57+0000\n"
"Last-Translator: Cristiano Gavião <Unknown>\n"
"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-13 05:56+0000\n"
"X-Generator: Launchpad (build 14277)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
"Warning, the record has been modified, your changes will be discarded."
msgstr "Aviso, o registro foi modificado, suas alterações serão descartadas."
#: addons/web/static/src/js/view_form.js:1659
msgid "<em>   Search More...</em>"
msgstr "<em>   Procurar Mais...</em>"
#: addons/web/static/src/js/view_form.js:1672
#, python-format
msgid "<em>   Create \"<strong>%s</strong>\"</em>"
msgstr ""
#: addons/web/static/src/js/view_form.js:1678
msgid "<em>   Create and Edit...</em>"
msgstr ""
#: addons/web/static/src/js/views.js:568
msgid "You must choose at least one record."
msgstr ""
#: addons/web/static/src/js/views.js:569
msgid "Warning"
msgstr ""
#: addons/web/static/src/js/views.js:609
msgid "Translations"
msgstr ""
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
msgid "Save"
msgstr ""
#: addons/web/static/src/js/views.js:615
msgid "Close"
msgstr "Fechar"
#: addons/web/static/src/xml/base.xml:0
msgid "x"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "#{title}"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "#{text}"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Powered by"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "openerp.com"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Loading..."
msgstr "Carregando..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create"
msgstr "Criar"
#: addons/web/static/src/xml/base.xml:0
msgid "Drop"
msgstr "Soltar"
#: addons/web/static/src/xml/base.xml:0
msgid "Backup"
msgstr "Cópia de Segurança"
#: addons/web/static/src/xml/base.xml:0
msgid "Restore"
msgstr "Restaurar"
#: addons/web/static/src/xml/base.xml:0
msgid "Password"
msgstr "Senha"
#: addons/web/static/src/xml/base.xml:0
msgid "Back to Login"
msgstr "Voltar ao Login"
#: addons/web/static/src/xml/base.xml:0
msgid "CREATE DATABASE"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Master password:"
msgstr "Senha mestre"
#: addons/web/static/src/xml/base.xml:0
msgid "New database name:"
msgstr "Nome da nova base de dados:"
#: addons/web/static/src/xml/base.xml:0
msgid "Load Demonstration data:"
msgstr "Carregar dados de demonstração:"
#: addons/web/static/src/xml/base.xml:0
msgid "Default language:"
msgstr "Idioma padrão:"
#: addons/web/static/src/xml/base.xml:0
msgid "Admin password:"
msgstr "Senha de Administrador"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm password:"
msgstr "Confirme a senha:"
#: addons/web/static/src/xml/base.xml:0
msgid "DROP DATABASE"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Database:"
msgstr "Base de dados:"
#: addons/web/static/src/xml/base.xml:0
msgid "Master Password:"
msgstr "Senha Mestre"
#: addons/web/static/src/xml/base.xml:0
msgid "BACKUP DATABASE"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "RESTORE DATABASE"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "File:"
msgstr "Arquivo:"
#: addons/web/static/src/xml/base.xml:0
msgid "CHANGE MASTER PASSWORD"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "New master password:"
msgstr "Nova senha mestre:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm new master password:"
msgstr "Confirme nova senha mestre"
#: addons/web/static/src/xml/base.xml:0
msgid "User:"
msgstr "Usuário:"
#: addons/web/static/src/xml/base.xml:0
msgid "Password:"
msgstr "Senha:"
#: addons/web/static/src/xml/base.xml:0
msgid "Database"
msgstr "Base de dados"
#: addons/web/static/src/xml/base.xml:0
msgid "Login"
msgstr "Autenticação"
#: addons/web/static/src/xml/base.xml:0
msgid "Bad username or password"
msgstr "Nome de usuário ou senha inválido"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"We think that daily job activities can be more intuitive, efficient, "
"automated, .. and even fun."
msgstr ""
"Pensamos que as atividades de trabalho diário pode ser mais intuitivas, "
"eficiente, automatizadas .. e até mesmo divertidas."
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP's vision to be:"
msgstr "OpenERP vislumbra ser:"
#: addons/web/static/src/xml/base.xml:0
msgid "Full featured"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Today's enterprise challenges are multiple. We provide one module for each "
"need."
msgstr ""
"Os desafios atuais da empresa são múltiplos. Nós fornecemos um módulo para "
"cada necessidade."
#: addons/web/static/src/xml/base.xml:0
msgid "Open Source"
msgstr "Código Aberto"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"To Build a great product, we rely on the knowledge of thousands of "
"contributors."
msgstr ""
"Para construir um grande produto, contamos com o conhecimento de milhares de "
"contribuintes."
#: addons/web/static/src/xml/base.xml:0
msgid "User Friendly"
msgstr "Uso Amigável"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"In order to be productive, people need clean and easy to use interface."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "("
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ")"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "LOGOUT"
msgstr "DESCONECTAR"
#: addons/web/static/src/xml/base.xml:0
msgid "&laquo;"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "oe_secondary_menu_item"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "oe_secondary_submenu_item"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Hide this tip"
msgstr "Esconder dica"
#: addons/web/static/src/xml/base.xml:0
msgid "Disable all tips"
msgstr "Desligar todas as dicas"
#: addons/web/static/src/xml/base.xml:0
msgid "View#"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Fields"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "View labels"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Sidebar Relates"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Field"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ":"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Translate view"
msgstr "Visão de Tradução"
#: addons/web/static/src/xml/base.xml:0
msgid "Translate sidebar"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Delete"
msgstr "Excluir"
#: addons/web/static/src/xml/base.xml:0
msgid "First"
msgstr "Primeiro"
#: addons/web/static/src/xml/base.xml:0
msgid "<"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ">"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Last"
msgstr "Último"
#: addons/web/static/src/xml/base.xml:0
msgid "♻"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Save & Edit"
msgstr "Salvar & Editar"
#: addons/web/static/src/xml/base.xml:0
msgid "Create & Edit"
msgstr "Criar & Editar"
#: addons/web/static/src/xml/base.xml:0
msgid "New"
msgstr "Novo"
#: addons/web/static/src/xml/base.xml:0
msgid "Duplicate"
msgstr "Duplicar"
#: addons/web/static/src/xml/base.xml:0
msgid "Readonly/Editable"
msgstr "Apenas Leitura/Editável"
#: addons/web/static/src/xml/base.xml:0
msgid "<<"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "0"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "/"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ">>"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Add"
msgstr "Adicionar"
#: addons/web/static/src/xml/base.xml:0
msgid "Unhandled widget"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "?"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "#"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Done"
msgstr "Concluído"
#: addons/web/static/src/xml/base.xml:0
msgid "Open..."
msgstr "Abrir..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create..."
msgstr "Criar..."
#: addons/web/static/src/xml/base.xml:0
msgid "Search..."
msgstr "Pesquisar..."
#: addons/web/static/src/xml/base.xml:0
msgid "..."
msgstr "..."
#: addons/web/static/src/xml/base.xml:0
msgid "Uploading ..."
msgstr "Transferindo ..."
#: addons/web/static/src/xml/base.xml:0
msgid "Select"
msgstr "Selecionar"
#: addons/web/static/src/xml/base.xml:0
msgid "Save As"
msgstr "Salvar como"
#: addons/web/static/src/xml/base.xml:0
msgid "Clear"
msgstr "Limpar"
#: addons/web/static/src/xml/base.xml:0
msgid "Advanced Filter"
msgstr "Filtro Avançado"
#: addons/web/static/src/xml/base.xml:0
msgid "-- Filters --"
msgstr "-- Filtros --"
#: addons/web/static/src/xml/base.xml:0
msgid "-- Actions --"
msgstr "-- Ações --"
#: addons/web/static/src/xml/base.xml:0
msgid "Save Filter"
msgstr "Salvar filtro"
#: addons/web/static/src/xml/base.xml:0
msgid "Manage Filters"
msgstr "Gerenciar Filtros"
#: addons/web/static/src/xml/base.xml:0
msgid "Filter Name:"
msgstr "Nome do Filtro"
#: addons/web/static/src/xml/base.xml:0
msgid "(Any existing filter with the same name will be replaced)"
msgstr "(Qualquer filtro existente com o mesmo nome será substituído)"
#: addons/web/static/src/xml/base.xml:0
msgid "Any of the following conditions must match"
msgstr "Qualquer das seguintes condições deve ser verdadeira"
#: addons/web/static/src/xml/base.xml:0
msgid "All the following conditions must match"
msgstr "Todas as seguintes condições devem ser verdadeiras"
#: addons/web/static/src/xml/base.xml:0
msgid "None of the following conditions must match"
msgstr "Nenhuma das seguintes condições deve ser verdadeira"
#: addons/web/static/src/xml/base.xml:0
msgid "Add condition"
msgstr "Adicionar condição"
#: addons/web/static/src/xml/base.xml:0
msgid "and"
msgstr "e"
#: addons/web/static/src/xml/base.xml:0
msgid "Cancel"
msgstr "Cancelar"
#: addons/web/static/src/xml/base.xml:0
msgid "Save & New"
msgstr "Salvar & Novo"
#: addons/web/static/src/xml/base.xml:0
msgid "Save & Close"
msgstr "Salvar & Fechar"
#: addons/web/static/src/xml/base.xml:0
msgid "Export"
msgstr "Exportar"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"This wizard will export all data that matches the current search criteria to "
"a CSV file.\n"
" You can export all data or only the fields that can be "
"reimported after modification."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Export Type:"
msgstr "Tipo de Exportação:"
#: addons/web/static/src/xml/base.xml:0
msgid "Import Compatible Export"
msgstr "Importar Exportação Compatível"
#: addons/web/static/src/xml/base.xml:0
msgid "Export all Data"
msgstr "Exportar todos os Dados"
#: addons/web/static/src/xml/base.xml:0
msgid "Export Formats"
msgstr "Formatos de Exportação"
#: addons/web/static/src/xml/base.xml:0
msgid "Available fields"
msgstr "Campos Disponíveis"
#: addons/web/static/src/xml/base.xml:0
msgid "Fields to export"
msgstr "Campos para exportar"
#: addons/web/static/src/xml/base.xml:0
msgid "Save fields list"
msgstr "Salvar lista de campos"
#: addons/web/static/src/xml/base.xml:0
msgid "Remove"
msgstr "Remover"
#: addons/web/static/src/xml/base.xml:0
msgid "Remove All"
msgstr "Remover Tudo"
#: addons/web/static/src/xml/base.xml:0
msgid "Name"
msgstr "Nome"
#: addons/web/static/src/xml/base.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
#: addons/web/static/src/xml/base.xml:0
msgid "Save as:"
msgstr "Salvar como:"
#: addons/web/static/src/xml/base.xml:0
msgid "Ok"
msgstr "Ok"
#: addons/web/static/src/xml/base.xml:0
msgid "Saved exports:"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Old Password:"
msgstr "Senha antiga"
#: addons/web/static/src/xml/base.xml:0
msgid "New Password:"
msgstr "Nova Senha:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm Password:"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Import"
msgstr "Importar"
#: addons/web/static/src/xml/base.xml:0
msgid "1. Import a .CSV file"
msgstr "Importar um arquivo CSV."
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Select a .CSV file to import. If you need a sample of file to import,\n"
" you should use the export tool with the \"Import Compatible\" option."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "CSV File:"
msgstr "Arquivo CSV."
#: addons/web/static/src/xml/base.xml:0
msgid "2. Check your file format"
msgstr "Verifique seu formato de arquivo"
#: addons/web/static/src/xml/base.xml:0
msgid "Import Options"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Does your file have titles?"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Separator:"
msgstr "Separador:"
#: addons/web/static/src/xml/base.xml:0
msgid "Delimiter:"
msgstr "Delimitador:"
#: addons/web/static/src/xml/base.xml:0
msgid "Encoding:"
msgstr "Codificação:"
#: addons/web/static/src/xml/base.xml:0
msgid "UTF-8"
msgstr "UTF-8"
#: addons/web/static/src/xml/base.xml:0
msgid "Latin 1"
msgstr "Latin 1"
#: addons/web/static/src/xml/base.xml:0
msgid "Lines to skip"
msgstr "Linhas para ignorar"
#: addons/web/static/src/xml/base.xml:0
msgid "The import failed due to:"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Here is a preview of the file we could not import:"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP Web"
msgstr "OpenERP Web"
#: addons/web/static/src/xml/base.xml:0
msgid "Version"
msgstr "Versão"
#: addons/web/static/src/xml/base.xml:0
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP is a trademark of the"
msgstr "OpenERP é uma marca de"
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP SA Company"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Licenced under the terms of"
msgstr "Licenciado sobre os termos de"
#: addons/web/static/src/xml/base.xml:0
msgid "GNU Affero General Public License"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "About OpenERP"
msgstr "Sobre OpenERP"
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP"
msgstr "OpenERP"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"is a free enterprise-scale software system that is designed to boost\n"
" productivity and profit through data integration. It connects, "
"improves and\n"
" manages business processes in areas such as sales, finance, "
"supply chain,\n"
" project management, production, services, CRM, etc..."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ""
"The system is platform-independent, and can be installed on Windows, Mac OS "
"X,\n"
" and various Linux and other Unix-based distributions. Its "
"architecture enables\n"
" new functionality to be rapidly created, modifications to be "
"made to a\n"
" production system and migration to a new version to be "
"straightforward."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Depending on your needs, OpenERP is available through a web or application "
"client."
msgstr ""

View File

@ -0,0 +1,34 @@
--- jquery.tipTip_old.js 2011-11-14 14:05:53.000000000 +0100
+++ jquery.tipTip.js 2011-11-14 14:41:34.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");

View File

@ -0,0 +1,188 @@
/*
* 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).fadeIn(opts.fadeIn); }, opts.delay);
}
function deactive_tiptip(){
opts.exit.call(this);
if (timeout){ clearTimeout(timeout); }
tiptip_holder.fadeOut(opts.fadeOut);
}
}
});
}
})(jQuery);

View File

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

View File

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

View File

@ -26,7 +26,7 @@ body.openerp, .openerp textarea, .openerp input, .openerp select, .openerp optio
margin: 0;
}
.openerp .oe-number {
.openerp .oe-listview .oe-number {
text-align: right !important;
}
.openerp .oe_hide {
@ -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;
}
@ -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;

View File

@ -993,7 +993,7 @@ openerp.web.TranslationDataBase = openerp.web.Class.extend(/** @lends openerp.we
this.parameters = {"direction": 'ltr',
"date_format": '%m/%d/%Y',
"time_format": '%H:%M:%S',
"grouping": "[]",
"grouping": [],
"decimal_point": ".",
"thousands_sep": ","};
},
@ -1009,6 +1009,8 @@ openerp.web.TranslationDataBase = openerp.web.Class.extend(/** @lends openerp.we
});
if (translation_bundle.lang_parameters) {
this.parameters = translation_bundle.lang_parameters;
this.parameters.grouping = py.eval(
this.parameters.grouping).toJSON();
}
},
add_module_translation: function(mod) {

View File

@ -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();

View File

@ -1,6 +1,66 @@
openerp.web.formats = function(openerp) {
var _t = openerp.web._t;
/**
* Intersperses ``separator`` in ``str`` at the positions indicated by
* ``indices``.
*
* ``indices`` is an array of relative offsets (from the previous insertion
* position, starting from the end of the string) at which to insert
* ``separator``.
*
* There are two special values:
*
* ``-1``
* indicates the insertion should end now
* ``0``
* indicates that the previous section pattern should be repeated (until all
* of ``str`` is consumed)
*
* @param {String} str
* @param {Array<Number>} indices
* @param {String} separator
* @returns {String}
*/
openerp.web.intersperse = function (str, indices, separator) {
separator = separator || '';
var result = [], last = str.length;
for(var i=0; i<indices.length; ++i) {
var section = indices[i];
if (section === -1 || last <= 0) {
// Done with string, or -1 (stops formatting string)
break;
} else if(section === 0 && i === 0) {
// repeats previous section, which there is none => stop
break;
} else if (section === 0) {
// repeat previous section forever
//noinspection AssignmentToForLoopParameterJS
section = indices[--i];
}
result.push(str.substring(last-section, last));
last -= section;
}
var s = str.substring(0, last);
if (s) { result.push(s); }
return result.reverse().join(separator);
};
/**
* Insert "thousands" separators in the provided number (which is actually
* a string)
*
* @param {String} num
* @returns {String}
*/
openerp.web.insert_thousand_seps = function (num) {
var negative = num[0] === '-';
num = (negative ? num.slice(1) : num);
return (negative ? '-' : '') + openerp.web.intersperse(
num, _t.database.parameters.grouping, _t.database.parameters.thousands_sep);
};
/**
* Formats a single atomic value based on a field descriptor
*
@ -22,13 +82,16 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
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(
_.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 = _.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",
Math.floor(value),
@ -43,29 +106,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 +130,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 "":
@ -119,8 +172,8 @@ openerp.web.parse_value = function (value, descriptor, value_if_empty) {
case 'progressbar':
return openerp.web.parse_value(value, {type: "float"});
case 'datetime':
var datetime = Date.parseExact(value, _.sprintf("%s %s", Date.CultureInfo.formatPatterns.shortDate,
Date.CultureInfo.formatPatterns.longTime));
var datetime = Date.parseExact(
value, (date_pattern + ' ' + time_pattern));
if (datetime !== null)
return openerp.web.datetime_to_str(datetime);
datetime = Date.parse(value);
@ -128,7 +181,7 @@ openerp.web.parse_value = function (value, descriptor, value_if_empty) {
return openerp.web.datetime_to_str(datetime);
throw new Error(value + " is not a valid datetime");
case 'date':
var date = Date.parseExact(value, Date.CultureInfo.formatPatterns.shortDate);
var date = Date.parseExact(value, date_pattern);
if (date !== null)
return openerp.web.date_to_str(date);
date = Date.parse(value);
@ -136,7 +189,7 @@ openerp.web.parse_value = function (value, descriptor, value_if_empty) {
return openerp.web.date_to_str(date);
throw new Error(value + " is not a valid date");
case 'time':
var time = Date.parseExact(value, Date.CultureInfo.formatPatterns.longTime);
var time = Date.parseExact(value, time_pattern);
if (time !== null)
return openerp.web.time_to_str(time);
time = Date.parse(value);

View File

@ -1,5 +1,6 @@
openerp.web.search = function(openerp) {
var QWeb = openerp.web.qweb;
var QWeb = openerp.web.qweb,
_t = openerp.web._t;
openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.SearchView# */{
template: "EmptyComponent",
@ -134,6 +135,12 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
}
},
on_loaded: function(data) {
if (data.fields_view.type !== 'search' ||
data.fields_view.arch.tag !== 'search') {
throw new Error(_.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 +218,12 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
var $dial = $(dial_html);
$dial.dialog({
modal: true,
title: "Filter Entry",
buttons: {
Cancel: function() {
title: _t("Filter Entry"),
buttons: [
{text: _t("Cancel"), click: function() {
$(this).dialog("close");
},
OK: function() {
}},
{text: _t("OK"), click: function() {
$(this).dialog("close");
var name = $(this).find("input").val();
self.rpc('/web/searchview/save_filter', {
@ -227,8 +234,8 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
}).then(function() {
self.reload_managed_filters();
});
}
}
}}
]
});
} else { // manage_filters
select.val("_filters");
@ -337,7 +344,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 +356,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
this.$element.find('table:last').hide();
$('.searchview_extended_groups_list').empty();
setTimeout(this.on_clear);
setTimeout(this.on_clear, 0);
},
/**
* Triggered when the search view gets cleared
@ -418,8 +425,10 @@ openerp.web.search.Invalid = openerp.web.Class.extend( /** @lends openerp.web.se
this.message = message;
},
toString: function () {
return ('Incorrect value for field ' + this.field +
': [' + this.value + '] is ' + this.message);
return _.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 +747,7 @@ openerp.web.search.NumberField = openerp.web.search.Field.extend(/** @lends open
* @extends openerp.web.search.NumberField
*/
openerp.web.search.IntegerField = openerp.web.search.NumberField.extend(/** @lends openerp.web.search.IntegerField# */{
error_message: "not a valid integer",
error_message: _t("not a valid integer"),
parse: function (value) {
try {
return openerp.web.parse_value(value, {'widget': 'integer'});
@ -752,7 +761,7 @@ openerp.web.search.IntegerField = openerp.web.search.NumberField.extend(/** @len
* @extends openerp.web.search.NumberField
*/
openerp.web.search.FloatField = openerp.web.search.NumberField.extend(/** @lends openerp.web.search.FloatField# */{
error_message: "not a valid number",
error_message: _t("not a valid number"),
parse: function (value) {
try {
return openerp.web.parse_value(value, {'widget': 'float'});
@ -969,6 +978,12 @@ openerp.web.search.ExtendedSearch = openerp.web.OldWidget.extend({
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();
@ -1153,73 +1168,78 @@ 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();
},
start: function() {
this.$element = $("#" + this.element_id);
this._super();
this.datewidget = new openerp.web.DateTimeWidget(this);
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();
},
start: function() {
this.$element = $("#" + this.element_id);
this._super();
this.datewidget = new openerp.web.DateWidget(this);
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 {
@ -1229,16 +1249,19 @@ openerp.web.search.ExtendedSearchProposition.Integer = openerp.web.OldWidget.ext
}
}
});
openerp.web.search.ExtendedSearchProposition.Float = openerp.web.OldWidget.extend({
openerp.web.search.ExtendedSearchProposition.Id = openerp.web.search.ExtendedSearchProposition.Integer.extend({
operators: [{value: "=", text: _t("is")}]
});
openerp.web.search.ExtendedSearchProposition.Float = openerp.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.float',
identifier_prefix: 'extended-search-proposition-float',
operators: [
{value: "=", text: "is equal to"},
{value: "!=", text: "is not equal to"},
{value: ">", text: "greater than"},
{value: "<", text: "less than"},
{value: ">=", text: "greater or equal than"},
{value: "<=", text: "less or equal than"}
{value: "=", text: _t("is equal to")},
{value: "!=", text: _t("is not equal to")},
{value: ">", text: _t("greater than")},
{value: "<", text: _t("less than")},
{value: ">=", text: _t("greater or equal than")},
{value: "<=", text: _t("less or equal than")}
],
get_value: function() {
try {
@ -1248,12 +1271,12 @@ openerp.web.search.ExtendedSearchProposition.Float = openerp.web.OldWidget.exten
}
}
});
openerp.web.search.ExtendedSearchProposition.Selection = openerp.web.OldWidget.extend({
openerp.web.search.ExtendedSearchProposition.Selection = openerp.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.selection',
identifier_prefix: 'extended-search-proposition-selection',
operators: [
{value: "=", text: "is"},
{value: "!=", text: "is not"}
{value: "=", text: _t("is")},
{value: "!=", text: _t("is not")}
],
set_field: function(field) {
this.field = field;
@ -1262,12 +1285,12 @@ openerp.web.search.ExtendedSearchProposition.Selection = openerp.web.OldWidget.e
return this.$element.val();
}
});
openerp.web.search.ExtendedSearchProposition.Boolean = openerp.web.OldWidget.extend({
openerp.web.search.ExtendedSearchProposition.Boolean = openerp.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.boolean',
identifier_prefix: 'extended-search-proposition-boolean',
operators: [
{value: "=", text: "is true"},
{value: "!=", text: "is false"}
{value: "=", text: _t("is true")},
{value: "!=", text: _t("is false")}
],
get_value: function() {
return true;
@ -1286,7 +1309,9 @@ openerp.web.search.custom_filters = new openerp.web.Registry({
'integer': 'openerp.web.search.ExtendedSearchProposition.Integer',
'float': 'openerp.web.search.ExtendedSearchProposition.Float',
'boolean': 'openerp.web.search.ExtendedSearchProposition.Boolean',
'selection': 'openerp.web.search.ExtendedSearchProposition.Selection'
'selection': 'openerp.web.search.ExtendedSearchProposition.Selection',
'id': 'openerp.web.search.ExtendedSearchProposition.Id'
});
};

View File

@ -1,4 +1,5 @@
openerp.web.view_editor = function(openerp) {
var _t = openerp.web._t;
var QWeb = openerp.web.qweb;
openerp.web.ViewEditor = openerp.web.Widget.extend({
init: function(parent, element_id, dataset, view, options) {
@ -43,22 +44,25 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
height: 500,
buttons: {
"Create": function(){
//to do
self.on_create_view();
},
"Edit": function(){
self.xml_element_id = 0;
self.get_arch();
},
"Remove": function(){
self.do_delete_view();
},
"Close": function(){
self.view_edit_dialog.close();
}
},
}).start().open();
this.main_view_id = this.parent.fields_view.view_id;
var action_manager = new openerp.web.ActionManager(this);
action_manager.appendTo(this.view_edit_dialog);
$.when(action_manager.do_action(action)).then(function() {
var viewmanager = action_manager.inner_viewmanager,
this.action_manager = new openerp.web.ActionManager(this);
this.action_manager.appendTo(this.view_edit_dialog);
$.when(this.action_manager.do_action(action)).then(function() {
var viewmanager = self.action_manager.inner_viewmanager,
controller = viewmanager.views[viewmanager.active_view].controller;
controller.on_loaded.add_last(function(){
$(controller.groups).bind({
@ -69,6 +73,99 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
});
});
},
on_create_view: function() {
var self = this;
this.create_view_dialog = new openerp.web.Dialog(this, {
modal: true,
title: _.sprintf("Create a view (%s)", self.model),
width: 500,
height: 400,
buttons: {
"Save": function(){
var view_values = {};
var warn = false;
_.each(self.create_view_widget, function(widget) {
if (widget.invalid) {
warn = true;
return false;
};
if (widget.dirty && !widget.invalid) {
view_values[widget.name] = widget.get_value();
}
});
if (warn) {
self.on_valid_create_view();
} else {
$.when(self.do_save_view(view_values)).then(function() {
self.create_view_dialog.close();
var controller = self.action_manager.inner_viewmanager.views[self.action_manager.inner_viewmanager.active_view].controller;
controller.reload_content();
});
}
},
"Cancel": function(){
self.create_view_dialog.close();
}
}
});
this.create_view_dialog.start().open();
var view_widget = [{'name': 'view_name', 'string':'View Name', 'type': 'char', 'required': true, 'value' : this.model + '.custom_' + Math.round(Math.random() * 1000)},
{'name': 'view_type', 'string': 'View Type', 'type': 'selection', 'required': true, 'value': 'Form', 'selection': [['',''],['tree', 'Tree'],['form', 'Form'],['graph', 'Graph'],['calendar', 'Calender']]},
{'name': 'proirity', 'string': 'Priority', 'type': 'char', 'required': true, 'value':'16'}];
this.create_view_dialog.$element.append('<table id="create_view" style="width:400px" class="oe_forms"></table>');
this.create_view_widget = [];
_.each(view_widget, function(widget) {
var type_widget = new (self.property.get_any([widget.type])) (self.create_view_dialog, widget.name);
if (widget.selection) {
type_widget.selection = widget.selection;
}
type_widget.required = widget.required;
self.create_view_dialog.$element.find('table[id=create_view]').append('<tr><td width="100px" align="right">' + widget.string + ':</td>' + type_widget.render()+'</tr>');
var value = null;
if (widget.value) {
value = widget.value;
type_widget.dirty = true;
}
type_widget.start();
type_widget.set_value(value)
self.create_view_widget.push(type_widget);
});
},
do_save_view: function(values) {
def = $.Deferred();
var field_dataset = new openerp.web.DataSetSearch(this, this.model, null, null);
var model_dataset = new openerp.web.DataSetSearch(this, 'ir.model', null, null);
var view_string = "", field_name = false, self = this;
field_dataset.call( 'fields_get', [], function(fields) {
_.each(['name', 'x_name'], function(value) {
if (_.include(_.keys(fields), value)) {
field_name = value;
return false;
}
});
if (field_name) {
model_dataset.read_slice(['name','field_id'], {"domain": [['model','=',self.model]]}, function(records) {
if (records) {view_string = records[0].name;}
var arch = _.sprintf("<?xml version='1.0'?>\n<%s string='%s'>\n\t<field name='%s'/>\n</%s>", values.view_type, view_string, field_name, values.view_type);
var vals = {'model': self.model, 'name': values.view_name, 'priority': values.priority, 'type': values.view_type, 'arch': arch};
self.dataset.create(vals, function(suc) {
def.resolve();
});
});
}
});
return def.promise();
},
on_valid_create_view: function() {
var msg = "<ul>";
_.each(self.create_view_widget, function(widget) {
if (widget.invalid) {
msg += "<li>" + widget.name + "</li>";
}
});
msg += "</ul>";
self.do_warn("The following fields are invalid :", msg);
},
add_node_name : function(node) {
if(node.tagName.toLowerCase() == "button" || node.tagName.toLowerCase() == "field"){
return (node.getAttribute('name'))?
@ -80,7 +177,16 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
_.sprintf( "<%s>",node.tagName.toLowerCase());
}
},
do_delete_view: function() {
var self = this;
if (confirm(_t("Do you really want to remove this view?"))) {
var controller = this.action_manager.inner_viewmanager.views[this.action_manager.inner_viewmanager.active_view].controller;
this.dataset.unlink([this.main_view_id]).then(function() {
controller.reload_content();
self.main_view_id = self.parent.fields_view.view_id;
});
}
},
create_View_Node: function(node){
var self = this;
ViewNode = {
@ -96,7 +202,6 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
});
return ViewNode;
},
append_child_object: function(main_object, parent_id, child_obj_list) {
var self = this;
if(main_object.id == parent_id){
@ -109,7 +214,6 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
});
}
},
convert_arch_to_obj: function(xml_Node, main_object, parent_id){
var self = this;
var child_obj_list = [];
@ -127,7 +231,6 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
});
return main_object;
},
parse_xml: function(arch, view_id) {
main_object = {
'level': 0,
@ -139,23 +242,26 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
var xml_arch = QWeb.load_xml(arch);
return [this.convert_arch_to_obj(xml_arch.childNodes, main_object, this.xml_element_id)];
},
get_arch: function() {
var self = this;
var view_arch_list = [];
this.dataset.read_ids([parseInt(self.main_view_id)], ['arch', 'type'], function(arch) {
var arch_object = self.parse_xml(arch[0].arch, self.main_view_id);
self.main_view_type = arch[0].type
view_arch_list.push({"view_id": self.main_view_id, "arch": arch[0].arch});
self.dataset.read_slice([], {domain: [['inherit_id','=', parseInt(self.main_view_id)]]}, function(result) {
_.each(result, function(res) {
view_arch_list.push({"view_id": res.id, "arch": res.arch});
self.inherit_view(arch_object, res);
if (arch.length) {
var arch_object = self.parse_xml(arch[0].arch, self.main_view_id);
self.main_view_type = arch[0].type
view_arch_list.push({"view_id": self.main_view_id, "arch": arch[0].arch});
self.dataset.read_slice([], {domain: [['inherit_id','=', parseInt(self.main_view_id)]]}, function(result) {
_.each(result, function(res) {
view_arch_list.push({"view_id": res.id, "arch": res.arch});
self.inherit_view(arch_object, res);
});
return self.edit_view({"main_object": arch_object,
"parent_child_id": self.parent_child_list(arch_object, []),
"arch": view_arch_list});
});
return self.edit_view({"main_object": arch_object,
"parent_child_id": self.parent_child_list(arch_object, []),
"arch": view_arch_list});
});
} else {
self.do_warn("Please select view in list :");
}
});
},
parent_child_list : function(one_object, parent_list) {
@ -168,7 +274,6 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
});
return parent_list;
},
inherit_view : function(arch_object, result) {
var self = this;
var xml_list = [];
@ -279,8 +384,6 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
sidebar: false,
views_switcher: false,
action_buttons: false,
search_view: false,
pager: false,
},
};
var action_manager = new openerp.web.ActionManager(self);
@ -291,7 +394,11 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
}
}
}).start().open();
this.edit_xml_dialog.$element.html(QWeb.render('view_editor', {'data': one_object['main_object']}));
var no_property_att = [];
_.each(_PROPERTIES, function(val, key) {
if (! val.length) no_property_att.push(key);
});
this.edit_xml_dialog.$element.html(QWeb.render('view_editor', {'data': one_object['main_object'], 'no_properties': no_property_att}));
this.edit_xml_dialog.$element.find("tr[id^='viewedit-']").click(function() {
self.edit_xml_dialog.$element.find("tr[id^='viewedit-']").removeClass('ui-selected');
$(this).addClass('ui-selected');
@ -451,8 +558,12 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
if (insert.length == check_list.length ) {return xml_child;}
});
}
return self.do_save_xml(arch.arch, obj[0].child_id[0], parseInt(clicked_tr_id), [], parseInt(clicked_tr_level),
parseInt(view_id), arch, move_direct, update_values);
arch_to_pass = _.filter($(arch.arch), function (child) {
return child.nodeType == 1;
});
return self.do_save_xml(arch_to_pass[0], obj[0].child_id[0],
parseInt(clicked_tr_id), [], parseInt(clicked_tr_level),
parseInt(view_id), arch, move_direct, update_values);
},
get_object_by_id: function(view_xml_id, one_object, result) {
var self = this;
@ -511,7 +622,8 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
}
}
var parent = $(arch1).parents();
var convert_to_utf = QWeb.tools.xml_node_to_string(parent[parent.length-1]);
var convert_to_utf = (parent.length != 0)?parent[parent.length-1]:arch1;
convert_to_utf = QWeb.tools.xml_node_to_string(convert_to_utf);
convert_to_utf = convert_to_utf.replace('xmlns="http://www.w3.org/1999/xhtml"', "");
convert_to_utf = '<?xml version="1.0"?>' + convert_to_utf;
arch.arch = convert_to_utf;
@ -564,8 +676,8 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
"Update": function(){
var update_values = [];
_.each(self.edit_widget, function(widget) {
if (widget.dirty) {
update_values.push(widget.get_value());
if (widget.dirty && !widget.invalid) {
update_values.push([widget.name, widget.get_value()]);
}
});
self.do_save_update_arch(obj, view_id, view_xml_id, clicked_tr_id, clicked_tr_level, "update_node", update_values);
@ -581,20 +693,20 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
var arch_val = self.get_object_by_id(clicked_tr_id,obj['main_object'], []);
this.edit_node_dialog.$element.append('<table id="rec_table" style="width:400px" class="oe_forms"></table>');
this.edit_widget = [];
_.each(properties, function(record) {
var id = record,
type_widget;
self.ready = $.when(self.on_groups(id)).then(function () {
if (_.include(widget,id)){
type_widget = new (self.property.get_any(['undefined' , id, arch_val[0]['att_list'][0]])) (self.edit_node_dialog, id);
_.each(properties, function(property) {
type_widget = false;
self.ready = $.when(self.on_groups(property)).then(function () {
if (_.include(widget, property)){
type_widget = new (self.property.get_any([property])) (self.edit_node_dialog, property);
} else {
type_widget = new openerp.web.ViewEditor.FieldChar (self.edit_node_dialog, id);
type_widget = new openerp.web.ViewEditor.FieldChar (self.edit_node_dialog, property);
}
var value = _.detect(arch_val[0]['att_list'],function(res) {
return _.include(res, id);
return _.include(res, property);
});
if (id == 'groups') type_widget.selection = self.groups;
self.edit_node_dialog.$element.find('table[id=rec_table]').append('<tr><td align="right">'+id+':</td><td>'+type_widget.render()+'</td></tr>');
value = value instanceof Array ? value[1] : value;
if (property == 'groups') type_widget.selection = self.groups;
self.edit_node_dialog.$element.find('table[id=rec_table]').append('<tr><td align="right">' + property + ':</td>' + type_widget.render() + '</tr>');
type_widget.start();
type_widget.set_value(value);
self.edit_widget.push(type_widget);
@ -602,10 +714,10 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
});
},
//for getting groups
on_groups: function(id){
on_groups: function(property){
var self = this,
def = $.Deferred();
if (id != 'groups') {
if (property != 'groups') {
self.groups = false;
return false;
}
@ -638,10 +750,11 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
var self = this;
var positions = ['After','Before','Inside'];
var render_list = [];
render_list.push(["node_type",(_.keys(_CHILDREN)).sort()]);
render_list.push(["position",positions]);
render_list.push(["Fields",fields]);
this.edit_widget = [];
var render_list =[{'name': 'node_type','selection': _.keys(_CHILDREN).sort(),
'value': 'field', 'string': 'Node Type'},
{'name': 'position','selection': positions, 'value': false, 'string': 'Position'},
{'name': 'field_value','selection': fields, 'value': false, 'string': ''}];
this.add_widget = [];
this.add_node_dialog = new openerp.web.Dialog(this,{
modal: true,
title: 'Properties',
@ -649,25 +762,23 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
height: 300,
buttons: {
"Update": function(){
var node_type,position,field_value;
var check_add_node = true;
_.each(self.edit_widget, function(widget) {
(widget.name == "node_type")?node_type = widget.get_value()[1]:false;
(widget.name == "position")?position = widget.get_value()[1]:false;
(widget.name == "Fields")?field_value = widget.get_value()[1]:false;
var values = {};
_.each(self.add_widget, function(widget) {
values[widget.name] = widget.get_value() || false;
});
(position == "Inside")?
check_add_node =(_.include(_CHILDREN[properties[0]],node_type))?true:false:
check_add_node =(_.include(_CHILDREN[properties[1]],node_type))?true:false;
if(node_type == "field" && check_add_node )
{check_add_node = (field_value != " ")?true:false;
(values.position == "Inside")?
check_add_node =(_.include(_CHILDREN[properties[0]],values.node_type))?true:false:
check_add_node =(_.include(_CHILDREN[properties[1]],values.node_type))?true:false;
if(values.node_type == "field" && check_add_node )
{check_add_node = (values.field_value != " ")?true:false;
}
if(check_add_node){
var tag = (node_type == "field")?
_.sprintf("<%s name='%s'> </%s>",node_type,field_value,node_type):
_.sprintf("<%s> </%s>",node_type,node_type);
var tag = (values.node_type == "field")?
_.sprintf("<%s name='%s'> </%s>",values.node_type,values.field_value,values.node_type):
_.sprintf("<%s> </%s>",values.node_type,values.node_type);
self.do_save_update_arch(one_object, view_id, view_xml_id,
clicked_tr_id, clicked_tr_level, "add_node", [tag, position]);
clicked_tr_id, clicked_tr_level, "add_node", [tag, values.position]);
}else{alert("Can't Update View");}
},
"Cancel": function(){
@ -679,15 +790,14 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
append('<table id="rec_table" style="width:400px" class="oe_forms"></table>');
var table_selector = self.add_node_dialog.$element.find('table[id=rec_table]');
_.each(render_list,function(node){
type_widget = new openerp.web.ViewEditor.FieldSelect (self.add_node_dialog, node[0]);
type_widget.selection = node[1];
if(node[0]=="Fields"){ node[0] = "";}
table_selector.append('<tr><td align="right">'+node[0]+'</td><td>'+type_widget.render()+'</td></tr>');
type_widget = new openerp.web.ViewEditor.FieldSelect (self.add_node_dialog, node.name);
type_widget.selection = node.selection;
table_selector.append('<tr><td align="right">' + node.string + ':</td>' + type_widget.render() + '</tr>');
type_widget.start();
self.edit_widget.push(type_widget);
type_widget.set_value(node.value);
self.add_widget.push(type_widget);
});
table_selector.append('<tr><td align="right"> <button id="new_field">New Field</button></td></tr>');
self.add_node_dialog.$element.find("select[id=node_type] option[value=field]").attr("selected",1);
self.add_node_dialog.$element.find('#new_field').click(function() {
model_data = new openerp.web.DataSetSearch(self,'ir.model', null, null);
model_data.read_slice([], {domain: [['model','=', self.model]]}, function(result) {
@ -704,77 +814,98 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
target: "new",
flags: {
action_buttons: true,
},
};
}
}
var action_manager = new openerp.web.ActionManager(self);
action_manager.do_action(action);
});
}
});
openerp.web.ViewEditor.Field = openerp.web.Class.extend({
init: function(view, id) {
init: function(view, name) {
this.$element = view.$element;
this.dirty = false;
this.name = id;
this.name = name;
this.required = false;
this.invalid = false;
},
start: function () {
this.update_dom();
},
update_dom: function() {
this.$element.find("td[id="+ this.name+"]").toggleClass('invalid', this.invalid);
this.$element.find("td[id="+ this.name+"]").toggleClass('required', this.required);
},
on_ui_change: function() {
var value = this.get_value();
value = value instanceof Array ? value[1] : value;
if (this.required && !value) {
this.invalid = true;
} else {
this.invalid = false;
}
this.dirty = true;
this.update_dom();
},
render: function() {
return QWeb.render(this.template, {widget: this});
return _.sprintf("<td id = %s>%s</td>", this.name, QWeb.render(this.template, {widget: this}))
},
});
openerp.web.ViewEditor.FieldBoolean = openerp.web.ViewEditor.Field.extend({
template : "vieweditor_boolean",
start: function() {
var self = this;
this._super();
this.$element.find("input[id="+ self.name+"]").change(function() {
self.on_ui_change();
});
},
set_value: function(value) {
if (value) {
this.$element.find("input[id=" + this.name+ "]").attr('checked', value[1]);
this.$element.find("input[id=" + this.name+ "]").attr('checked', true);
}
},
get_value: function() {
var value = this.$element.find("input[id=" + this.name + "]").is(':checked');
return value ? [this.name, value] : [this.name, null];
return this.$element.find("input[id=" + this.name + "]").is(':checked') || null;
}
});
openerp.web.ViewEditor.FieldChar = openerp.web.ViewEditor.Field.extend({
template : "vieweditor_char",
start: function () {
var self = this;
this._super();
this.$element.find("input[id="+ this.name+"]").css('width','100%').change(function() {
self.on_ui_change();
});
},
set_value: function(value) {
value ? this.$element.find("input[id=" + this.name + "]").val(value[1]): this.$element.find("tr[id=" + this.name + "] input").val();
this.$element.find("input[id=" + this.name + "]").val(value);
},
get_value: function() {
var value= this.$element.find("input[id=" + this.name + "]").val();
return value ? [this.name, value] : [this.name, ""];
return this.$element.find("input[id=" + this.name + "]").val();
}
});
openerp.web.ViewEditor.FieldSelect = openerp.web.ViewEditor.Field.extend({
template : "vieweditor_selection",
init: function(view, name) {
this._super(view, name);
this.selection = false;
},
start: function () {
var self = this;
this._super();
this.$element.find("select[id=" + this.name + "]").css('width', '100%').change(function() {
self.on_ui_change();
add_node = self.get_value();
if(add_node[0] == "node_type"){
if(add_node[1] == "field"){self.$element.find("select[id=Fields]").show();}
else{self.$element.find("select[id=Fields]").hide();}
if(self.name == "node_type"){
(self.get_value() == "field")?
self.$element.find("select[id=field_value]").show():
self.$element.find("select[id=field_value]").hide();
}
});
},
set_value: function(value) {
value = value === null ? false : value;
value = value instanceof Array ? value[1] : value;
var index = 0;
for (var i = 0, ii = this.selection.length; i < ii; i++) {
if ((this.selection[i] instanceof Array && this.selection[i][1] === value) || this.selection[i] === value) index = i;
@ -782,13 +913,12 @@ openerp.web.ViewEditor.FieldSelect = openerp.web.ViewEditor.Field.extend({
this.$element.find("select[id=" + this.name + "]")[0].selectedIndex = index;
},
get_value: function() {
var value = this.$element.find("select[id=" + this.name + "]").val();
return value ? [this.name, value] : [this.name, ""];
return this.$element.find("select[id=" + this.name + "]").val();
}
});
openerp.web.ViewEditor.WidgetProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, id) {
this._super(view, id);
init: function(view, name) {
this._super(view, name);
this.registry = openerp.web.form.widgets;
var values = _.keys(this.registry.map);
values.push('');
@ -797,46 +927,42 @@ openerp.web.ViewEditor.WidgetProperty = openerp.web.ViewEditor.FieldSelect.exten
},
});
openerp.web.ViewEditor.IconProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, id) {
this._super(view, id);
this.selection = icons;
init: function(view, name) {
this._super(view, name);
this.selection = _ICONS;
},
});
openerp.web.ViewEditor.ButtonTargetProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, id) {
this._super(view, id);
init: function(view, name) {
this._super(view, name);
this.selection = [['', ''], ['new', 'New Window']];
},
});
openerp.web.ViewEditor.ButtonTypeProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, id) {
this._super(view, id);
init: function(view, name) {
this._super(view, name);
this.selection = [['', ''], ['action', 'Action'], ['object', 'Object'], ['workflow', 'Workflow'], ['server_action', 'Server Action']];
},
});
openerp.web.ViewEditor.AlignProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, id) {
this._super(view, id);
init: function(view, name) {
this._super(view, name);
this.selection = [['', ''], ['0.0', 'Left'], ['0.5', 'Center'], ['1.0', 'Right']];
},
});
openerp.web.ViewEditor.ButtonSpecialProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, id) {
this._super(view, id);
init: function(view, name) {
this._super(view, name);
this.selection = [['',''],['save', 'Save Button'], ['cancel', 'Cancel Button'], ['open', 'Open Button']];
},
});
openerp.web.ViewEditor.PositionProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, id) {
this._super(view, id);
init: function(view, name) {
this._super(view, name);
this.selection = [['',''],['after', 'After'],['before', 'Before'],['inside', 'Inside'],['replace', 'Replace']];
},
});
openerp.web.ViewEditor.GroupsProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, id) {
this._super(view, id);
this.multiple = true;
},
start: function () {
this._super();
this.$element.find("select[id=" + this.name + "]").css('height', '100px').attr("multiple",true);
@ -846,7 +972,7 @@ openerp.web.ViewEditor.GroupsProperty = openerp.web.ViewEditor.FieldSelect.exten
self.$element.find("#groups option").attr("selected",false);
if (!value) return false;
_.each(this.selection, function(item) {
if (_.include(value[1].split(','), item[0])) {
if (_.include(value.split(','), item[0])) {
self.$element.find("select[id="+self.name+"] option[value='" + item[0] +"']").attr("selected",1)
}
});
@ -871,7 +997,7 @@ var _PROPERTIES = {
'graph' : ['string', 'type'],
'calendar' : ['string', 'date_start', 'date_stop', 'date_delay', 'day_length', 'color', 'mode'],
};
_CHILDREN = {
var _CHILDREN = {
'form': ['notebook', 'group', 'field', 'label', 'button','board', 'newline', 'separator'],
'tree': ['field'],
'graph': ['field'],
@ -922,11 +1048,13 @@ openerp.web.ViewEditor.property_widget = new openerp.web.Registry({
'completion' : 'openerp.web.ViewEditor.FieldBoolean',
'widget' : 'openerp.web.ViewEditor.WidgetProperty',
'groups' : 'openerp.web.ViewEditor.GroupsProperty',
'position': 'openerp.web.ViewEditor.PositionProperty',
'icon': 'openerp.web.ViewEditor.IconProperty',
'align': 'openerp.web.ViewEditor.AlignProperty',
'special': 'openerp.web.ViewEditor.ButtonSpecialProperty',
'type': 'openerp.web.ViewEditor.ButtonTypeProperty',
'target': 'openerp.web.ViewEditor.ButtonTargetProperty'
'position' : 'openerp.web.ViewEditor.PositionProperty',
'icon' : 'openerp.web.ViewEditor.IconProperty',
'align' : 'openerp.web.ViewEditor.AlignProperty',
'special' : 'openerp.web.ViewEditor.ButtonSpecialProperty',
'type' : 'openerp.web.ViewEditor.ButtonTypeProperty',
'target' : 'openerp.web.ViewEditor.ButtonTargetProperty',
'selection' : 'openerp.web.ViewEditor.FieldSelect',
'char' : 'openerp.web.ViewEditor.FieldChar',
});
};

View File

@ -776,6 +776,25 @@ 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();
@ -916,6 +935,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) {
@ -944,6 +967,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++) {
@ -1007,6 +1035,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;
@ -1106,6 +1137,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);
@ -1151,6 +1185,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;
@ -3083,7 +3122,7 @@ openerp.web.form.FieldMany2OneReadonly = openerp.web.form.FieldURIReadonly.exten
*/
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',

View File

@ -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,
@ -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 + '">&nbsp;</td>');
} else {
cells.push('<td title="' + column.string + '">&nbsp;</td>');
}
});
if (this.options.deletable) {
cells.push('<td><button type="button" style="visibility: hidden"> </button></td>');
cells.push('<td class="oe-record-delete"><button type="button" style="visibility: hidden"> </button></td>');
}
cells.unshift('<tr>');
cells.push('</tr>');

View File

@ -468,10 +468,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();
@ -568,35 +568,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 +597,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'
}
]);
@ -682,34 +673,17 @@ 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
if (self.widget_parent instanceof session.web.FormView) {
self.widget_parent.do_save(function() {
self.on_item_action_clicked(item);
});
return false;
} else {
self.on_item_action_clicked(item);
}
var additional_context = {
active_id: ids[0],
active_ids: ids,
active_model: self.widget_parent.dataset.model
};
self.rpc("/web/action/load", {
action_id: item.action.id,
context: additional_context
}, function(result) {
result.result.context = _.extend(result.result.context || {},
additional_context);
result.result.flags = result.result.flags || {};
result.result.flags.new_window = true;
self.do_action(result.result);
});
}
return false;
});
var $ul = $section.find('ul');
if(!$ul.length) {
$ul = $('<ul/>').appendTo($section);
@ -717,6 +691,33 @@ session.web.Sidebar = session.web.Widget.extend({
$items.appendTo($ul);
}
},
on_item_action_clicked: function(item) {
var self = this;
var ids = self.widget_parent.get_selected_ids();
if (ids.length == 0) {
//TODO: make prettier warning?
$("<div />").text(_t("You must choose at least one record.")).dialog({
title: _t("Warning"),
modal: true
});
return false;
}
var additional_context = {
active_id: ids[0],
active_ids: ids,
active_model: self.widget_parent.dataset.model
};
self.rpc("/web/action/load", {
action_id: item.action.id,
context: additional_context
}, function(result) {
result.result.context = _.extend(result.result.context || {},
additional_context);
result.result.flags = result.result.flags || {};
result.result.flags.new_window = true;
self.do_action(result.result);
});
},
do_fold: function() {
this.$element.addClass('closed-sidebar').removeClass('open-sidebar');
},

View File

@ -629,7 +629,8 @@
<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>
@ -720,6 +721,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">
@ -732,6 +744,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"/>
@ -744,13 +769,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>
@ -758,7 +842,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"/>
@ -766,7 +850,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>
@ -986,13 +1070,42 @@
</table>
</t>
<t t-name="WidgetButton">
<button type="button"
t-att-title="widget.help"
style="width: 100%" class="button">
<button type="button" style="width: 100%" class="button">
<img t-if="widget.node.attrs.icon" t-att-src="'/web/static/src/img/icons/' + widget.node.attrs.icon + '.png'" width="16" height="16"/>
<span t-if="widget.string"><t t-esc="widget.string"/></span>
</button>
</t>
<t t-name="WidgetButton.tooltip" t-extend="WidgetLabel.tooltip">
<t t-jquery="div.oe_tooltip_string" t-operation="replace">
<div class="oe_tooltip_string" t-if="debug || widget.string">
<t t-if="debug">
Button
<t t-if="widget.string">: </t>
<t t-if="!widget.string"> (no string)</t>
</t>
<t t-esc="widget.string"/>
</div>
</t>
<t t-jquery="ul.oe_tooltip_technical" t-operation="append">
<li t-if="widget.node.attrs.special" data-item="special">
<span class="oe_tooltip_technical_title">Special:</span>
<t t-esc="widget.node.attrs.special"/>
</li>
<t t-set="button_type" t-value="widget.node.attrs.type"/>
<li t-if="button_type" data-item="button_type">
<span class="oe_tooltip_technical_title">Button Type:</span>
<t t-esc="button_type"/>
</li>
<li t-if="button_type === 'object'" data-item="button_method">
<span class="oe_tooltip_technical_title">Method:</span>
<t t-esc="widget.node.attrs.name"/>
</li>
<li t-if="button_type === 'action'" data-item="button_action">
<span class="oe_tooltip_technical_title">Action ID:</span>
<t t-esc="widget.node.attrs.name"/>
</li>
</t>
</t>
<t t-name="SearchView">
<form class="oe_forms">
@ -1268,50 +1381,54 @@
<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>

View File

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

View File

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