[MERGE] merged trunk.

bzr revid: vmt@openerp.com-20120118101252-e81nlyzym2nkebf4
This commit is contained in:
Vo Minh Thu 2012-01-18 11:12:52 +01:00
commit 75b3fc0907
29 changed files with 567 additions and 616 deletions

View File

@ -1,7 +1,6 @@
import common
import controllers
import logging
import optparse
_logger = logging.getLogger(__name__)

View File

@ -328,6 +328,7 @@ def session_context(request, storage_path, session_cookie='sessionid'):
# Remove all OpenERPSession instances with no uid, they're generated
# either by login process or by HTTP requests without an OpenERP
# session id, and are generally noise
removed_sessions = []
for key, value in request.session.items():
if (isinstance(value, session.OpenERPSession)
and not value._uid
@ -335,6 +336,7 @@ def session_context(request, storage_path, session_cookie='sessionid'):
and value._creation_time + (60*5) < time.time() # FIXME do not use a fixed value
):
_logger.debug('remove session %s', key)
removed_sessions.append(key)
del request.session[key]
with session_lock:
@ -364,7 +366,7 @@ def session_context(request, storage_path, session_cookie='sessionid'):
# add missing keys
for k, v in in_store.iteritems():
if k not in request.session:
if k not in request.session and k not in removed_sessions:
request.session[k] = v
session_store.save(request.session)

View File

@ -8,7 +8,7 @@ import binascii
import hashlib
import simplejson.encoder
__all__ = ['Domain', 'Context', 'NonLiteralEncoder, non_literal_decoder', 'CompoundDomain', 'CompoundContext']
__all__ = ['Domain', 'Context', 'NonLiteralEncoder', 'non_literal_decoder', 'CompoundDomain', 'CompoundContext']
#: 48 bits should be sufficient to have almost no chance of collision
#: with a million hashes, according to hg@67081329d49a

View File

@ -4,35 +4,23 @@
#
# URL: http://code.google.com/p/xml2json-direct/
class Xml2Json(object):
@staticmethod
def convert_to_json(s):
return simplejson.dumps(
Xml2Json.convert_to_structure(s), sort_keys=True, indent=4)
@staticmethod
def convert_to_structure(s):
root = ElementTree.fromstring(s)
return Xml2Json.convert_element(root)
@staticmethod
def convert_element(el, preserve_whitespaces=False):
res = {}
if el.tag[0] == "{":
ns, name = el.tag.rsplit("}", 1)
res["tag"] = name
res["namespace"] = ns[1:]
else:
res["tag"] = el.tag
res["attrs"] = {}
for k, v in el.items():
res["attrs"][k] = v
kids = []
if el.text and (preserve_whitespaces or el.text.strip() != ''):
kids.append(el.text)
for kid in el:
kids.append(Xml2Json.convert_element(kid, preserve_whitespaces))
if kid.tail and (preserve_whitespaces or kid.tail.strip() != ''):
kids.append(kid.tail)
res["children"] = kids
return res
def from_elementtree(el, preserve_whitespaces=False):
res = {}
if el.tag[0] == "{":
ns, name = el.tag.rsplit("}", 1)
res["tag"] = name
res["namespace"] = ns[1:]
else:
res["tag"] = el.tag
res["attrs"] = {}
for k, v in el.items():
res["attrs"][k] = v
kids = []
if el.text and (preserve_whitespaces or el.text.strip() != ''):
kids.append(el.text)
for kid in el:
kids.append(from_elementtree(kid, preserve_whitespaces))
if kid.tail and (preserve_whitespaces or kid.tail.strip() != ''):
kids.append(kid.tail)
res["children"] = kids
return res

View File

@ -99,7 +99,7 @@ html_template = """<!DOCTYPE html>
});
</script>
</head>
<body></body>
<body class="openerp" id="oe"></body>
</html>
"""
@ -207,7 +207,7 @@ class WebClient(openerpweb.Controller):
'js': js,
'css': css,
'modules': simplejson.dumps(self.server_wide_modules(req)),
'init': 'new s.web.WebClient().replace($("body"));',
'init': 'new s.web.WebClient().start();',
}
return r
@ -933,7 +933,7 @@ class View(openerpweb.Controller):
xml = self.transform_view(arch, session, evaluation_context)
else:
xml = ElementTree.fromstring(arch)
fvg['arch'] = common.xml2json.Xml2Json.convert_element(xml, preserve_whitespaces)
fvg['arch'] = common.xml2json.from_elementtree(xml, preserve_whitespaces)
for field in fvg['fields'].itervalues():
if field.get('views'):

View File

@ -8,15 +8,14 @@ msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-12-20 18:48+0100\n"
"PO-Revision-Date: 2012-01-15 02:47+0000\n"
"Last-Translator: Renato Lima - http://www.akretion.com "
"<renatonlima@gmail.com>\n"
"PO-Revision-Date: 2012-01-16 13:38+0000\n"
"Last-Translator: Rafael Sales <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: 2012-01-16 05:27+0000\n"
"X-Generator: Launchpad (build 14664)\n"
"X-Launchpad-Export-Date: 2012-01-17 05:08+0000\n"
"X-Generator: Launchpad (build 14676)\n"
#: addons/web/static/src/js/chrome.js:162
#: addons/web/static/src/js/chrome.js:175
@ -626,7 +625,7 @@ msgstr "Visão de Depuração#"
#: addons/web/static/src/xml/base.xml:0
msgid "- Fields View Get"
msgstr ""
msgstr "- Fields View Get"
#: addons/web/static/src/xml/base.xml:0
msgid "- Edit"
@ -786,7 +785,7 @@ msgstr "Botão"
#: addons/web/static/src/xml/base.xml:0
msgid "(no string)"
msgstr ""
msgstr "(sem string)"
#: addons/web/static/src/xml/base.xml:0
msgid "Special:"
@ -875,6 +874,10 @@ msgid ""
" You can export all data or only the fields that can be "
"reimported after modification."
msgstr ""
"Este assistente irá exportar todos os dados que corresponda aos critérios de "
"pesquisa atual em um arquivo CSV.\n"
" Você pode exportar todos os dados ou apenas os campos que podem "
"ser reimportados após a modificação."
#: addons/web/static/src/xml/base.xml:0
msgid "Export Type:"
@ -945,6 +948,10 @@ 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 ""
"Selecionar um arquivo .CSV para importar. Se você precisar de uma amostra do "
"arquivo para importação,\n"
" você deve usar a ferramenta de exportação com a opção \"Importação "
"Compatível\"."
#: addons/web/static/src/xml/base.xml:0
msgid "CSV File:"
@ -1039,6 +1046,13 @@ msgid ""
"supply chain,\n"
" project management, production, services, CRM, etc..."
msgstr ""
"é um sistema de software livre de escala empresarial que é projetado para "
"aumentar\n"
" produtividade e lucro através da integração de dados. Ele se "
"conecta, melhora e\n"
" gerencia os processos de negócio em áreas como vendas, "
"finanças, supply chain,\n"
" gerenciamento de projetos, produção, serviços, CRM, etc .."
#: addons/web/static/src/xml/base.xml:0
msgid ""
@ -1051,6 +1065,14 @@ msgid ""
" production system and migration to a new version to be "
"straightforward."
msgstr ""
"É um sistema independente de plataforma, onde pode ser instalado em "
"ambientes Windows, Mac OS X,\n"
" e várias distribuições Linux ou baseadas em Unix. Sua "
"arquitetura permite que\n"
" novas funcionalidades sejam criadas rapidamente, e modificações "
"possam ser realizadas em um\n"
" sistema de produção e sua migração para uma nova versão de "
"forma simples."
#: addons/web/static/src/xml/base.xml:0
msgid ""

View File

@ -1,58 +0,0 @@
--- jquery.tipTip_old.js 2011-12-01 14:15:35.000000000 +0100
+++ jquery.tipTip.js 2011-12-07 12:32:32.000000000 +0100
@@ -20,6 +20,9 @@
*/
(function($){
+ $.tipTipClear = function() {
+ $("#tiptip_holder").remove();
+ }
$.fn.tipTip = function(options) {
var defaults = {
activation: "hover",
@@ -31,7 +34,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 +54,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 +97,8 @@
function active_tiptip(){
opts.enter.call(this);
+ var org_title = typeof opts.content === 'function' ? opts.content.call(org_elem, opts) : 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");
@@ -177,7 +177,12 @@
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);
+ timeout = setTimeout(function() {
+ tiptip_holder.stop(true,true);
+ if ($.contains(document.documentElement, org_elem[0])) {
+ tiptip_holder.fadeIn(opts.fadeIn);
+ }
+ }, opts.delay);
}
function deactive_tiptip(){

View File

@ -1,196 +1,325 @@
/*
* 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
*/
/*
* 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($){
$.tipTipClear = function() {
$("#tiptip_holder").remove();
(function ($) {
$.fn.tipTip = function (options) {
var defaults = {
activation: 'hover', // How to show (and hide) the tooltip. Can be: hover, focus, click and manual.
keepAlive: false, // When true the tooltip won't disapper when the mouse moves away from the element. Instead it will be hidden when it leaves the tooltip.
maxWidth: '200px', // The max-width to set on the tooltip. You may also use the option cssClass to set this.
edgeOffset: 0, // The offset between the tooltip arrow edge and the element that has the tooltip.
defaultPosition: 'bottom', // The position of the tooltip. Can be: top, right, bottom and left.
delay: 400, // The delay in msec to show a tooltip.
fadeIn: 200, // The length in msec of the fade in.
fadeOut: 200, // The length in msec of the fade out.
attribute: 'title', // The attribute to fetch the tooltip text if the option content is false.
content: false, // HTML or String or Function (that returns HTML or String) to fill TipTIp with
enter: function () { }, // Callback function before a tooltip is shown.
afterEnter: function () { }, // Callback function after a tooltip is shown.
exit: function () { }, // Callback function before a tooltip is hidden.
afterExit: function () { }, // Callback function after a tooltip is hidden.
cssClass: '', // CSS class that will be applied on the tooltip before showing only for this instance of tooltip.
detectTextDir: true // When false auto-detection for right-to-left text will be disable (When true affects a bit the performance).
};
// Setup tip tip elements and render them to the DOM
if ($('#tiptip_holder').length <= 0) {
var tiptip_inner_arrow = $('<div>', { id: 'tiptip_arrow_inner' }),
tiptip_arrow = $('<div>', { id: 'tiptip_arrow' }).append(tiptip_inner_arrow),
tiptip_content = $('<div>', { id: 'tiptip_content' }),
tiptip_holder = $('<div>', { id: 'tiptip_holder' }).append(tiptip_arrow).append(tiptip_content);
$('body').append(tiptip_holder);
} else {
var tiptip_holder = $('#tiptip_holder'),
tiptip_content = $('#tiptip_content'),
tiptip_arrow = $('#tiptip_arrow');
}
return this.each(function () {
var org_elem = $(this),
data = org_elem.data('tipTip'),
opts = data && data.options || $.extend({}, defaults, options),
callback_data = {
holder: tiptip_holder,
content: tiptip_content,
arrow: tiptip_arrow,
options: opts
};
if (data) {
switch (options) {
case 'show':
activate();
break;
case 'hide':
deactivate();
break;
case 'destroy':
org_elem.unbind('.tipTip').removeData('tipTip');
break;
case 'position':
position_tiptip();
}
} else {
var timeout = false;
org_elem.data('tipTip', { options: opts });
if (opts.activation == 'hover') {
org_elem.bind('mouseenter.tipTip', function () {
activate();
}).bind('mouseleave.tipTip', function () {
if (!opts.keepAlive) {
deactivate();
} else {
tiptip_holder.one('mouseleave.tipTip', function () {
deactivate();
});
}
});
} else if (opts.activation == 'focus') {
org_elem.bind('focus.tipTip', function () {
activate();
}).bind('blur.tipTip', function () {
deactivate();
});
} else if (opts.activation == 'click') {
org_elem.bind('click.tipTip', function (e) {
e.preventDefault();
activate();
return false;
}).bind('mouseleave.tipTip', function () {
if (!opts.keepAlive) {
deactivate();
} else {
tiptip_holder.one('mouseleave.tipTip', function () {
deactivate();
});
}
});
} else if (opts.activation == 'manual') {
// Nothing to register actually. We decide when to show or hide.
}
}
function activate() {
if (opts.enter.call(org_elem, callback_data) === false) {
return;
}
// Get the text and append it in the tiptip_content.
var org_title;
if (opts.content) {
org_title = $.isFunction(opts.content) ? opts.content.call(org_elem, callback_data) : opts.content;
} else {
org_title = opts.content = org_elem.attr(opts.attribute);
org_elem.removeAttr(opts.attribute); //remove original Attribute
}
if (!org_title) {
return; // don't show tip when no content.
}
tiptip_content.html(org_title);
tiptip_holder.hide().removeAttr('class').css({ 'max-width': opts.maxWidth });
if (opts.cssClass) {
tiptip_holder.addClass(opts.cssClass);
}
// Calculate the position of the tooltip.
position_tiptip();
// Show the tooltip.
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(function () {
tiptip_holder.stop(true, true).fadeIn(opts.fadeIn);
}, opts.delay);
$(window).bind('resize.tipTip scroll.tipTip', position_tiptip);
// Ensure clicking on anything makes tipTip deactivate
$(document).unbind("click.tipTip dblclick.tipTip").bind("click.tiptip dblclick.tiptip", deactivate);
org_elem.addClass('tiptip_visible'); // Add marker class to easily find the target element with visible tooltip. It will be remove later on deactivate().
opts.afterEnter.call(org_elem, callback_data);
}
function deactivate() {
if (opts.exit.call(org_elem, callback_data) === false) {
return;
}
if (timeout) {
clearTimeout(timeout);
}
tiptip_holder.fadeOut(opts.fadeOut);
$(window).unbind('resize.tipTip scroll.tipTip');
$(document).unbind("click.tipTip").unbind("dblclick.tipTip");
org_elem.removeClass('tiptip_visible');
opts.afterExit.call(org_elem, callback_data);
}
function position_tiptip() {
var org_offset = org_elem.offset(),
org_top = org_offset.top,
org_left = org_offset.left,
org_width = org_elem.outerWidth(),
org_height = org_elem.outerHeight(),
tip_top,
tip_left,
tip_width = tiptip_holder.outerWidth(),
tip_height = tiptip_holder.outerHeight(),
tip_class,
tip_classes = { top: 'tip_top', bottom: 'tip_bottom', left: 'tip_left', right: 'tip_right' },
arrow_top,
arrow_left,
arrow_width = 12, // tiptip_arrow.outerHeight() and tiptip_arrow.outerWidth() don't work because they need the element to be visible.
arrow_height = 12,
win = $(window),
win_top = win.scrollTop(),
win_left = win.scrollLeft(),
win_width = win.width(),
win_height = win.height(),
is_rtl = opts.detectTextDir && isRtlText(tiptip_content.text());
function moveTop() {
tip_class = tip_classes.top;
tip_top = org_top - tip_height - opts.edgeOffset - (arrow_height / 2);
tip_left = org_left + ((org_width - tip_width) / 2);
}
function moveBottom() {
tip_class = tip_classes.bottom;
tip_top = org_top + org_height + opts.edgeOffset + (arrow_height / 2);
tip_left = org_left + ((org_width - tip_width) / 2);
}
function moveLeft() {
tip_class = tip_classes.left;
tip_top = org_top + ((org_height - tip_height) / 2);
tip_left = org_left - tip_width - opts.edgeOffset - (arrow_width / 2);
}
function moveRight() {
tip_class = tip_classes.right;
tip_top = org_top + ((org_height - tip_height) / 2);
tip_left = org_left + org_width + opts.edgeOffset + (arrow_width / 2);
}
// Calculate the position of the tooltip.
if (opts.defaultPosition == 'bottom') {
moveBottom();
} else if (opts.defaultPosition == 'top') {
moveTop();
} else if (opts.defaultPosition == 'left' && !is_rtl) {
moveLeft();
} else if (opts.defaultPosition == 'left' && is_rtl) {
moveRight();
} else if (opts.defaultPosition == 'right' && !is_rtl) {
moveRight();
} else if (opts.defaultPosition == 'right' && is_rtl) {
moveLeft();
} else {
moveBottom();
}
// Flip the tooltip if off the window's viewport. (left <-> right and top <-> bottom).
if (tip_class == tip_classes.left && !is_rtl && tip_left < win_left) {
moveRight();
} else if (tip_class == tip_classes.left && is_rtl && tip_left - tip_width < win_left) {
moveRight();
} else if (tip_class == tip_classes.right && !is_rtl && tip_left > win_left + win_width) {
moveLeft();
} else if (tip_class == tip_classes.right && is_rtl && tip_left + tip_width > win_left + win_width) {
moveLeft();
} else if (tip_class == tip_classes.top && tip_top < win_top) {
moveBottom();
} else if (tip_class == tip_classes.bottom && tip_top > win_top + win_height) {
moveTop();
}
// Fix the vertical position if the tooltip is off the top or bottom sides of the window's viewport.
if (tip_class == tip_classes.left || tip_class == tip_classes.right) { // If positioned left or right check if the tooltip is off the top or bottom window's viewport.
if (tip_top + tip_height > win_height + win_top) { // If the bottom edge of the tooltip is off the bottom side of the window's viewport.
tip_top = org_top + org_height > win_height + win_top ? org_top + org_height - tip_height : win_height + win_top - tip_height; // Make 'bottom edge of the tooltip' == 'bottom side of the window's viewport'.
} else if (tip_top < win_top) { // If the top edge of the tooltip if off the top side of the window's viewport.
tip_top = org_top < win_top ? org_top : win_top; // Make 'top edge of the tooltip' == 'top side of the window's viewport'.
}
}
// Fix the horizontal position if the tooltip is off the right or left sides of the window's viewport.
if (tip_class == tip_classes.top || tip_class == tip_classes.bottom) {
if (tip_left + tip_width > win_width + win_left) { // If the right edge of the tooltip is off the right side of the window's viewport.
tip_left = org_left + org_width > win_width + win_left ? org_left + org_width - tip_width : win_width + win_left - tip_width; // Make 'right edge of the tooltip' == 'right side of the window's viewport'.
} else if (tip_left < win_left) { // If the left edge of the tooltip if off the left side of the window's viewport.
tip_left = org_left < win_left ? org_left : win_left; // Make 'left edge of the tooltip' == 'left side of the window's viewport'.
}
}
// Apply the new position.
tiptip_holder
.css({ left: Math.round(tip_left), top: Math.round(tip_top) })
.removeClass(tip_classes.top)
.removeClass(tip_classes.bottom)
.removeClass(tip_classes.left)
.removeClass(tip_classes.right)
.addClass(tip_class);
// Position the arrow
if (tip_class == tip_classes.top) {
arrow_top = tip_height; // Position the arrow vertically on the top of the tooltip.
arrow_left = org_left - tip_left + ((org_width - arrow_width) / 2); // Center the arrow horizontally on the center of the target element.
} else if (tip_class == tip_classes.bottom) {
arrow_top = -arrow_height; // Position the arrow vertically on the bottom of the tooltip.
arrow_left = org_left - tip_left + ((org_width - arrow_width) / 2); // Center the arrow horizontally on the center of the target element.
} else if (tip_class == tip_classes.left) {
arrow_top = org_top - tip_top + ((org_height - arrow_height) / 2); // Center the arrow vertically on the center of the target element.
arrow_left = tip_width; // Position the arrow vertically on the left of the tooltip.
} else if (tip_class == tip_classes.right) {
arrow_top = org_top - tip_top + ((org_height - arrow_height) / 2); // Center the arrow vertically on the center of the target element.
arrow_left = -arrow_width; // Position the arrow vertically on the right of the tooltip.
}
tiptip_arrow
.css({ left: Math.round(arrow_left), top: Math.round(arrow_top) });
}
});
}
$.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.call(org_elem, opts) : 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 ltrChars = 'A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF\u2C00-\uFB1C\uFDFE-\uFE6F\uFEFD-\uFFFF',
rtlChars = '\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC',
rtlDirCheckRe = new RegExp('^[^' + ltrChars + ']*[' + rtlChars + ']');
function isRtlText(text) {
return rtlDirCheckRe.test(text);
};
})(jQuery);
var top_compare = (top + org_height + opts.edgeOffset + tip_h + 8) > parseInt($(window).height() + $(window).scrollTop());
var bottom_compare = ((top + org_height) - (opts.edgeOffset + tip_h + 8)) < 0;
if(top_compare || (t_class == "_bottom" && top_compare) || (t_class == "_top" && !bottom_compare)){
if(t_class == "_top" || t_class == "_bottom"){
t_class = "_top";
} else {
t_class = t_class+"_top";
}
arrow_top = tip_h;
marg_top = Math.round(top - (tip_h + 5 + opts.edgeOffset));
} else if(bottom_compare | (t_class == "_top" && bottom_compare) || (t_class == "_bottom" && !top_compare)){
if(t_class == "_top" || t_class == "_bottom"){
t_class = "_bottom";
} else {
t_class = t_class+"_bottom";
}
arrow_top = -12;
marg_top = Math.round(top + org_height + opts.edgeOffset);
}
if(t_class == "_right_top" || t_class == "_left_top"){
marg_top = marg_top + 5;
} else if(t_class == "_right_bottom" || t_class == "_left_bottom"){
marg_top = marg_top - 5;
}
if(t_class == "_left_top" || t_class == "_left_bottom"){
marg_left = marg_left + 5;
}
tiptip_arrow.css({"margin-left": arrow_left+"px", "margin-top": arrow_top+"px"});
tiptip_holder.css({"margin-left": marg_left+"px", "margin-top": marg_top+"px"}).attr("class","tip"+t_class);
if (timeout){ clearTimeout(timeout); }
timeout = setTimeout(function() {
tiptip_holder.stop(true,true);
if ($.contains(document.documentElement, org_elem[0])) {
tiptip_holder.fadeIn(opts.fadeIn);
}
}, opts.delay);
}
function deactive_tiptip(){
opts.exit.call(this);
if (timeout){ clearTimeout(timeout); }
tiptip_holder.fadeOut(opts.fadeOut);
}
}
});
}
})(jQuery);

View File

@ -1,191 +0,0 @@
/*
* 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

@ -13,15 +13,15 @@
}
#tiptip_holder.tip_bottom {
padding-top: 5px;
padding-bottom: 5px;
}
#tiptip_holder.tip_right {
padding-left: 5px;
padding-right: 5px;
}
#tiptip_holder.tip_left {
padding-right: 5px;
padding-left: 5px;
}
#tiptip_content {
@ -110,4 +110,25 @@
#tiptip_holder.tip_top #tiptip_arrow_inner {
border-top-color: rgba(20,20,20,0.92);
}
}
/* Alternative theme for TipTip */
#tiptip_holder.alt.tip_top #tiptip_arrow_inner {
border-top-color: #444444;
}
#tiptip_holder.alt.tip_bottom #tiptip_arrow_inner {
border-bottom-color: #444444;
}
#tiptip_holder.alt.tip_right #tiptip_arrow_inner {
border-right-color: #444444;
}
#tiptip_holder.alt.tip_left #tiptip_arrow_inner {
border-left-color: #444444;
}
#tiptip_holder.alt #tiptip_content {
background-color: #444444; border: 1px solid White; border-radius: 3px; box-shadow: 0 0 3px #555555; color: #FFFFFF; font-size: 11px; padding: 4px 8px; text-shadow: 0 0 1px Black;
}

View File

@ -5,11 +5,25 @@
<script type="text/javascript" src="qweb.js"></script>
<script type="text/javascript" src="qweb2.js"></script>
<script type="text/javascript">
(function (c) {
if (c.time) { return; }
var d = {};
c.time = function (key) {
d[key] = Date.now();
};
c.timeEnd = function (key) {
var end = Date.now(),
origin = d[key];
delete d[key];
if (!origin) { return; }
console.log(key + ': ' + (end - origin) + 'ms');
};
})(window.console);
var dict = {
session : true,
testing : 'yes',
name : 'AGR'
}
};
console.time("Load template with QWeb");
QWeb.add_template("qweb-benchmark.xml");
console.timeEnd("Load template with QWeb");

View File

@ -1,6 +1,6 @@
<templates>
<t t-name="basic-callee">ok</t>
<t t-name="callee-printsbody"><t t-esc="0"/></t>
<t t-name="callee-printsbody"><t t-esc="__content__"/></t>
<t t-name="callee-uses-foo"><t t-esc="foo"/></t>
<t t-name="callee-sets-foo"><t t-set="foo" t-value="'ok'"/></t>

View File

@ -194,7 +194,7 @@ var QWeb2 = {
QWeb2.Engine = (function() {
function Engine() {
// TODO: handle prefix at template level : t-prefix="x"
// TODO: handle prefix at template level : t-prefix="x", don't forget to lowercase it
this.prefix = 't';
this.debug = false;
this.templates_resources = []; // TODO: implement this.reload()
@ -329,12 +329,12 @@ QWeb2.Engine = (function() {
" return r.join('');";
},
render : function(template, dict) {
var ndict = QWeb2.tools.extend({}, this.default_dict);
QWeb2.tools.extend(ndict, dict);
dict = dict || {};
QWeb2.tools.extend(dict, this.default_dict);
/*if (this.debug && window['console'] !== undefined) {
console.time("QWeb render template " + template);
}*/
var r = this._render(template, ndict);
var r = this._render(template, dict);
/*if (this.debug && window['console'] !== undefined) {
console.timeEnd("QWeb render template " + template);
}*/
@ -620,7 +620,7 @@ QWeb2.Element = (function() {
}
}
}
if (this.tag !== this.engine.prefix) {
if (this.tag.toLowerCase() !== this.engine.prefix) {
var tag = "<" + this.tag;
for (var a in this.attributes) {
tag += this.engine.tools.gen_attribute([a, this.attributes[a]]);

View File

@ -1,4 +1,5 @@
body.openerp {
body { padding: 0; margin: 0; }
.openerp {
padding: 0;
margin: 0;
height: 100%;
@ -7,7 +8,8 @@ body.openerp {
font-family: Ubuntu, Helvetica, sans-serif;
}
body.openerp, .openerp textarea, .openerp input, .openerp select, .openerp option, .openerp button, .openerp .ui-widget {
.openerp, .openerp textarea, .openerp input, .openerp select, .openerp option,
.openerp button, .openerp .ui-widget {
font-family: Ubuntu, Helvetica, sans-serif;
font-size:85%;
}
@ -1416,7 +1418,7 @@ label.error {
}
@-moz-document url-prefix() {
/* Strange firefox behaviour on width: 100% + white-space: nowrap */
.openerp .oe_forms .oe_button {
.openerp .oe_forms .oe_form_button .oe_button {
width: auto;
}
}
@ -1851,15 +1853,28 @@ label.error {
}
.openerp .oe-treeview-table {
width: 100%;
background-color : #FFFFFF;
border-spacing: 0;
}
.openerp .oe-treeview-table tr:hover{
color: blue;
background-color : #D8D8D8;
}
.treeview-tr, .treeview-td {
cursor: pointer;
vertical-align: top;
text-align: left;
border-bottom: 1px solid #CFCCCC;
}
.oe-number{
text-align: right !important;
}
.treeview-tr span, .treeview-td span {
font-size: 90%;
font-weight: normal;
white-space: nowrap;
display: block;
}
}
.treeview-tr:first-of-type {
background: transparent url(/web/static/src/img/expand.gif) 0 50% no-repeat;
}
@ -1872,8 +1887,11 @@ label.error {
}
.treeview-header {
text-align: left;
vertical-align: top;
background-color : #D8D8D8;
white-space: nowrap;
text-align: left;
padding: 4px 5px;
}
/* Shortcuts*/
.oe-shortcut-toggle {

View File

@ -205,7 +205,7 @@ openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
buttons: buttons
}).open();
dialog.$element.html(QWeb.render('CrashManagerError', {session: openerp.connection, error: error}));
},
}
});
openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading# */{
@ -280,6 +280,9 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
init: function(parent, element_id, option_id) {
this._super(parent, element_id);
this.unblockUIFunction = $.unblockUI;
$.validator.addMethod('matches', function (s, _, re) {
return new RegExp(re).test(s);
}, _t("Invalid database name"));
},
start: function() {
this.$option_id = $("#oe_db_options");
@ -646,7 +649,7 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
}
}
});
},
}
});
openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# */{
@ -1059,13 +1062,9 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
this._current_state = null;
},
render_element: function() {
this.$element = $('<body/>');
this.$element.attr("id", "oe");
this.$element.addClass("openerp");
},
start: function() {
var self = this;
this.$element = $(document.body);
if (jQuery.param != undefined && jQuery.deparam(jQuery.param.querystring()).kitten != undefined) {
this.$element.addClass("kitten-mode-activated");
this.$element.delegate('img.oe-record-edit-link-img', 'hover', function(e) {
@ -1089,7 +1088,7 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
self.bind_hashchange();
if (!self.session.openerp_entreprise) {
self.$element.find('.oe_footer_powered').append('<span> - <a href="http://www.openerp.com/support-or-publisher-warranty-contract" target="_blank">Unsupported/Community Version</a></span>');
$('title').html('OpenERP - Unsupported/Community Version');
document.title = _t("OpenERP - Unsupported/Community Version");
}
});
},
@ -1212,7 +1211,7 @@ openerp.web.EmbeddedClient = openerp.web.Widget.extend({
self.am.do_action(action);
});
},
}
});

View File

@ -491,7 +491,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(payload),
processData: false,
processData: false
}, url);
if (this.synch)
ajax.async = false;
@ -502,7 +502,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
// extracted from payload to set on the url
var data = {
session_id: this.session_id,
id: payload.id,
id: payload.id
};
url.url = this.get_url(url.url);
var ajax = _.extend({
@ -864,7 +864,7 @@ openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.
} finally {
this.synch = synch;
}
},
}
});
/**

View File

@ -829,9 +829,9 @@ openerp.web.Model = openerp.web.CallbackEnabled.extend({
model: this.model_name,
method: method,
args: args,
kwargs: kwargs,
kwargs: kwargs
});
},
}
});
openerp.web.CompoundContext = openerp.web.Class.extend({

View File

@ -364,9 +364,8 @@ openerp.web.DataExport = openerp.web.Dialog.extend({
on_click_export_data: function() {
var self = this;
var exported_fields = this.$element.find('#fields_list option').map(function () {
var name = self.records[this.value] || this.value
// DOM property is textContent, but IE8 only knows innerText
return {name: this.value,
return {name: self.records[this.value] || this.value,
label: this.textContent || this.innerText};
}).get();

View File

@ -806,7 +806,7 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
'widget' : {'name':'widget', 'string': 'widget', 'type': 'selection'},
'colors' : {'name':'colors', 'string': 'Colors', 'type': 'char'},
'editable' : {'name':'editable', 'string': 'Editable', 'type': 'selection', 'selection': [["",""],["top","Top"],["bottom", "Bottom"]]},
'groups' : {'name':'groups', 'string': 'Groups', 'type': 'seleciton_multi'},
'groups' : {'name':'groups', 'string': 'Groups', 'type': 'seleciton_multi'}
};
var arch_val = self.get_object_by_id(this.one_object.clicked_tr_id,this.one_object['main_object'], []);
this.edit_node_dialog.$element.append('<table id="rec_table" style="width:400px" class="oe_forms"></table>');
@ -928,7 +928,7 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
type: 'ir.actions.act_window',
target: "new",
flags: {
action_buttons: true,
action_buttons: true
}
}
var action_manager = new openerp.web.ActionManager(self);
@ -982,7 +982,7 @@ openerp.web.ViewEditor.Field = openerp.web.Class.extend({
},
render: function() {
return _.str.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",
@ -1084,7 +1084,7 @@ var _PROPERTIES = {
'action' : ['name', 'string', 'colspan', 'groups'],
'tree' : ['string', 'colors', 'editable', 'link', 'limit', 'min_rows'],
'graph' : ['string', 'type'],
'calendar' : ['string', 'date_start', 'date_stop', 'date_delay', 'day_length', 'color', 'mode'],
'calendar' : ['string', 'date_start', 'date_stop', 'date_delay', 'day_length', 'color', 'mode']
};
var _CHILDREN = {
'form': ['notebook', 'group', 'field', 'label', 'button','board', 'newline', 'separator'],
@ -1100,7 +1100,7 @@ var _CHILDREN = {
'label': [],
'button' : [],
'newline': [],
'separator': [],
'separator': []
};
var _ICONS = ['','STOCK_ABOUT', 'STOCK_ADD', 'STOCK_APPLY', 'STOCK_BOLD',
'STOCK_CANCEL', 'STOCK_CDROM', 'STOCK_CLEAR', 'STOCK_CLOSE', 'STOCK_COLOR_PICKER',
@ -1134,6 +1134,6 @@ openerp.web.ViewEditor.property_widget = new openerp.web.Registry({
'seleciton_multi' : 'openerp.web.ViewEditor.FieldSelectMulti',
'selection' : 'openerp.web.ViewEditor.FieldSelect',
'char' : 'openerp.web.ViewEditor.FieldChar',
'float' : 'openerp.web.ViewEditor.FieldFloat',
'float' : 'openerp.web.ViewEditor.FieldFloat'
});
};

View File

@ -40,7 +40,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.fields = {};
this.fields_order = [];
this.datarecord = {};
this.show_invalid = true;
this.default_focus_field = null;
this.default_focus_button = null;
this.registry = openerp.web.form.widgets;
@ -179,7 +178,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
});
return $.when.apply(null, set_values).pipe(function() {
if (!record.id) {
self.show_invalid = false;
// New record: Second pass in order to trigger the onchanges
// respecting the fields order defined in the view
_.each(self.fields_order, function(field_name) {
@ -192,7 +190,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
self.on_form_changed();
self.is_initialized.resolve();
self.show_invalid = true;
self.do_update_pager(record.id == null);
if (self.sidebar) {
self.sidebar.attachments.do_update();
@ -429,7 +426,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
f = self.fields[f];
if (!f.is_valid()) {
form_invalid = true;
f.update_dom();
f.update_dom(true);
if (!first_invalid_field) {
first_invalid_field = f;
}
@ -716,9 +713,11 @@ openerp.web.form.compute_domain = function(expr, fields) {
stack.push(field_value >= val);
break;
case 'in':
if (!_.isArray(val)) val = [val];
stack.push(_(val).contains(field_value));
break;
case 'not in':
if (!_.isArray(val)) val = [val];
stack.push(!_(val).contains(field_value));
break;
default:
@ -791,6 +790,11 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.
return QWeb.render(template, { "widget": this });
},
do_attach_tooltip: function(widget, trigger, options) {
if ($.browser.mozilla && parseInt($.browser.version.split('.')[0], 10) < 2) {
// Unknown bug in old version of firefox :
// input type=text onchange event not fired when tootip is shown
return;
}
widget = widget || this;
trigger = trigger || this.$element;
options = _.extend({
@ -1063,7 +1067,6 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
this.execute_action().always(function() {
self.force_disabled = false;
self.check_disable();
$.tipTipClear();
});
},
execute_action: function() {
@ -1075,17 +1078,17 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
title: _t('Confirm'),
modal: true,
buttons: [
{text: _t("Cancel"), click: function() {
def.resolve();
$(this).dialog("close");
}
},
{text: _t("Ok"), click: function() {
self.on_confirmed().then(function() {
def.resolve();
});
$(this).dialog("close");
}
},
{text: _t("Cancel"), click: function() {
def.resolve();
$(this).dialog("close");
}
}
]
});
@ -1116,7 +1119,7 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
});
},
update_dom: function() {
this._super();
this._super.apply(this, arguments);
this.check_disable();
},
check_disable: function() {
@ -1238,7 +1241,7 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
get_on_change_value: function() {
return this.get_value();
},
update_dom: function() {
update_dom: function(show_invalid) {
this._super.apply(this, arguments);
if (this.field.translate) {
this.$element.find('.oe_field_translate').toggle(!!this.view.datarecord.id);
@ -1246,7 +1249,7 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
if (!this.disable_utility_classes) {
this.$element.toggleClass('disabled', this.readonly);
this.$element.toggleClass('required', this.required);
if (this.view.show_invalid) {
if (show_invalid) {
this.$element.toggleClass('invalid', !this.is_valid());
}
}
@ -1259,7 +1262,7 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
this.view.do_onchange(this);
this.view.on_form_changed();
} else {
this.update_dom();
this.update_dom(true);
}
},
validate: function() {
@ -1281,7 +1284,7 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
this.definition_options = JSON.parse(str);
}
return this.definition_options;
},
}
});
openerp.web.form.FieldChar = openerp.web.form.Field.extend({
@ -2424,7 +2427,7 @@ openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
var self = this;
var def = $.Deferred().then(callback).then(function() {self.o2m.view.reload();});
return this._super(name, id, _.bind(def.resolve, def));
},
}
});
openerp.web.form.One2ManyFormView = openerp.web.FormView.extend({
@ -3214,7 +3217,6 @@ openerp.web.form.widgets = new openerp.web.Registry({
'email' : 'openerp.web.form.FieldEmail',
'url' : 'openerp.web.form.FieldUrl',
'text' : 'openerp.web.form.FieldText',
'text_wiki' : 'openerp.web.form.FieldText',
'date' : 'openerp.web.form.FieldDate',
'datetime' : 'openerp.web.form.FieldDatetime',
'selection' : 'openerp.web.form.FieldSelection',

View File

@ -1316,19 +1316,24 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
if (!self.datagroup.openable) {
view.configure_pager(dataset);
} else {
var pages = Math.ceil(dataset.ids.length / limit);
self.$row
.find('.oe-pager-state')
.text(_.str.sprintf(_t("%(page)d/%(page_count)d"), {
page: page + 1,
page_count: pages
}))
.end()
.find('button[data-pager-action=previous]')
.attr('disabled', page === 0)
.end()
.find('button[data-pager-action=next]')
.attr('disabled', page === pages - 1);
if (dataset.ids.length == records.length) {
// only one page
self.$row.find('td.oe-group-pagination').empty();
} else {
var pages = Math.ceil(dataset.ids.length / limit);
self.$row
.find('.oe-pager-state')
.text(_.str.sprintf(_t("%(page)d/%(page_count)d"), {
page: page + 1,
page_count: pages
}))
.end()
.find('button[data-pager-action=previous]')
.attr('disabled', page === 0)
.end()
.find('button[data-pager-action=next]')
.attr('disabled', page === pages - 1);
}
}
self.records.add(records, {silent: true});

View File

@ -241,7 +241,6 @@ openerp.web.page = function (openerp) {
'email': 'openerp.web.page.FieldEmailReadonly',
'url': 'openerp.web.page.FieldUrlReadonly',
'text': 'openerp.web.page.FieldCharReadonly',
'text_wiki' : 'openerp.web.page.FieldCharReadonly',
'date': 'openerp.web.page.FieldCharReadonly',
'datetime': 'openerp.web.page.FieldCharReadonly',
'selection' : 'openerp.web.page.FieldSelectionReadonly',

View File

@ -70,7 +70,8 @@
</tr>
<tr>
<td><label for="db_name">New database name:</label></td>
<td><input type="text" name="db_name" class="required"/></td>
<td><input type="text" name="db_name"
class="required" matches="^[a-zA-Z][a-zA-Z0-9_]+$"/></td>
</tr>
<tr>
<td><label for="demo_data">Load Demonstration data:</label></td>
@ -553,16 +554,21 @@
t-att-data-id="record.id" t-att-data-level="level + 1">
<t t-set="children" t-value="record[children_field]"/>
<t t-set="class" t-value="children and children.length ? 'treeview-tr' : 'treeview-td'"/>
<t t-set="style" t-value="'background-position: ' + 19*level + 'px; padding-left: ' + 19*level + 'px;'"/>
<td t-foreach="fields_view" t-as="field"
t-if="!field.attrs.modifiers.tree_invisible"
t-att-data-id="record.id"
t-att-style="color_for(record) + (!field_index ? 'background-position: ' + 19*level + 'px; padding-left: ' + 19*level + 'px;' : '')"
t-att-class="class">
<span t-if="!field.attrs.modifiers.invisible">
t-att-style="color_for(record) + style "
t-att-class="(fields[field.attrs.name].type === 'float') or (fields[field.attrs.name].type === 'integer')
? (class +' ' +'oe-number') : class">
<span t-if="!field.attrs.modifiers.invisible" >
<t t-esc="render(record[field.attrs.name], fields[field.attrs.name])" />
</span>
<t t-set="class" t-value="'treeview-td'"/>
<t t-set="style" t-value="''"/>
</td>
</tr>
@ -1717,32 +1723,18 @@
<t t-name="About-Page">
<div>
<a class="oe_activate_debug_mode" href="?debug">Debug mode</a>
<h1>OpenERP Web</h1>
<h3 style="padding:0 5px 5px">Version <t t-esc="version_info.version"/></h3>
<a class="oe_activate_debug_mode" href="?debug" style="float:right; font-size: 80%;">Activate the developper mode</a>
<h1 style="margin:0;">OpenERP</h1>
<h3 style="margin:15px 0;padding:0;">Version <t t-esc="version_info.version"/></h3>
<p>
Copyright © 2011-TODAY OpenERP SA. All Rights Reserved.<br />
Copyright © 2004-TODAY OpenERP SA. All Rights Reserved.<br />
OpenERP is a trademark of the <a target="_blank" href="http://openerp.com/" style="text-decoration: underline;">OpenERP SA Company</a>.
</p>
<p>
Licenced under the terms of <a target="_blank" href="http://www.gnu.org/licenses/agpl.html" style="text-decoration: underline;">GNU Affero General Public License</a>
</p>
<br />
<h1>About OpenERP</h1>
<p>
<a target="_blank" href="http://openerp.com/" style="text-decoration: underline;">OpenERP</a> is a free enterprise-scale software system that is designed to boost
productivity and profit through data integration. It connects, improves and
manages business processes in areas such as sales, finance, supply chain,
project management, production, services, CRM, etc...
</p>
<p>
The system is platform-independent, and can be installed on Windows, Mac OS X,
and various Linux and other Unix-based distributions. Its architecture enables
new functionality to be rapidly created, modifications to be made to a
production system and migration to a new version to be straightforward.
</p>
<p>
Depending on your needs, OpenERP is available through a web or application client.
For more information visit <a target="_blank" href="http://openerp.com/" style="text-decoration: underline;">OpenERP.com</a>
</p>
</div>
</t>

View File

@ -300,7 +300,6 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
this.dataset.index = null;
self.creating_event_id = event_id;
this.form_dialog.form.do_show().then(function() {
form.show_invalid = false;
_.each(['date_start', 'date_delay', 'date_stop'], function(field) {
var field_name = self[field];
if (field_name && form.fields[field_name]) {
@ -313,7 +312,6 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
});
}
});
form.show_invalid = true;
self.form_dialog.open();
});
},

View File

@ -8,34 +8,34 @@ msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-12-20 18:48+0100\n"
"PO-Revision-Date: 2012-01-14 15:57+0000\n"
"PO-Revision-Date: 2012-01-16 13:49+0000\n"
"Last-Translator: Rafael Sales <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: 2012-01-15 05:35+0000\n"
"X-Generator: Launchpad (build 14664)\n"
"X-Launchpad-Export-Date: 2012-01-17 05:08+0000\n"
"X-Generator: Launchpad (build 14676)\n"
#: addons/web_dashboard/static/src/js/dashboard.js:63
msgid "Edit Layout"
msgstr ""
msgstr "Editar Layout"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
msgstr ""
msgstr "Restaurar"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Change layout"
msgstr ""
msgstr "Mudar Layout"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "&nbsp;"
msgstr ""
msgstr "&nbsp;"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Create"
msgstr ""
msgstr "Criar"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Choose dashboard layout"
@ -43,34 +43,36 @@ msgstr "Escolha o Layout do Painel"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "progress:"
msgstr ""
msgstr "progresso:"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "%"
msgstr ""
msgstr "%"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid ""
"Click on the functionalites listed below to launch them and configure your "
"system"
msgstr ""
"Clique em alguma funcionalidade listada abaixo para ativa-lá e configurar no "
"seu sistema"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Welcome to OpenERP"
msgstr ""
msgstr "Bem Vindo ao OpenERP"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Remember to bookmark this page."
msgstr ""
msgstr "Lembre-se de adicionar esta página as seus favoritos."
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Remember your login:"
msgstr ""
msgstr "Lembre-se de seu login:"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Choose the first OpenERP Application you want to install.."
msgstr ""
msgstr "Escolha a primeira Aplicação OpenERP que você deseja instalar.."
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Please choose the first application to install."
msgstr ""
msgstr "Por favor, escolha a primeira aplicação para instalar."

View File

@ -106,7 +106,7 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
this.do_save_dashboard();
},
on_close_action: function(e) {
if (confirm("Are you sure you want to remove this item ?")) {
if (confirm(_t("Are you sure you want to remove this item ?"))) {
$(e.currentTarget).parents('.oe-dashboard-action:first').remove();
this.do_save_dashboard();
}

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-01-16 05:27+0000\n"
"X-Generator: Launchpad (build 14664)\n"
"X-Launchpad-Export-Date: 2012-01-17 05:08+0000\n"
"X-Generator: Launchpad (build 14676)\n"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Welcome to your new OpenERP instance."

View File

@ -389,27 +389,33 @@ openerp.web_graph.GraphView = openerp.web.View.extend({
// unconditionally nuke tooltips before switching view
$(".dhx_tooltip").remove('div');
id = id[this.abscissa];
if(this.fields[this.abscissa].type == "selection"){
id = _.detect(this.fields[this.abscissa].selection,function(select_value){
return _.include(select_value, id);
});
}
if (typeof id == 'object'){
id = id[0];
}
var record_id = this.abscissa;
var modes = ["list", "form", "graph"];
var views = [];
_.each(modes, function(mode) {
var view = [false, mode];
if (self.fields.views && self.fields.views[mode]) {
view.push(self.fields.views[mode]);
var views;
if (this.widget_parent.action) {
views = this.widget_parent.action.views;
if (!_(views).detect(function (view) {
return view[1] === 'list' })) {
views = [[false, 'list']].concat(views);
}
views.push(view);
});
} else {
views = _(["list", "form", "graph"]).map(function(mode) {
return [false, mode];
});
}
this.do_action({
"res_model" : this.dataset.model,
"domain" : [[record_id, '=', id], ['id','in',this.dataset.ids]],
"views" : views,
"type" : "ir.actions.act_window",
"view_type" : "list",
"view_mode" : "list"
res_model : this.dataset.model,
domain: [[this.abscissa, '=', id], ['id','in',this.dataset.ids]],
views: views,
type: "ir.actions.act_window",
flags: {default_view: 'list'}
});
},

View File

@ -162,7 +162,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
group_aggregates[value] = group.aggregates[key];
});
var dataset = new openerp.web.DataSetSearch(self, self.dataset.model, group.context, group.domain);
dataset.read_slice(self.fields_keys, {'domain': group.domain, 'context': group.context}).then(function(records) {
dataset.read_slice(self.fields_keys.concat(['__last_update']), {'domain': group.domain, 'context': group.context}).then(function(records) {
self.dataset.ids.push.apply(self.dataset.ids, dataset.ids);
groups_array[index] = new openerp.web_kanban.KanbanGroup(self, records, group_value, group_name, group_aggregates);
if (!remaining--) {
@ -175,7 +175,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
do_process_dataset: function(dataset) {
var self = this;
this.do_clear_groups();
this.dataset.read_slice(this.fields_keys).then(function(records) {
this.dataset.read_slice(this.fields_keys.concat(['__last_update'])).then(function(records) {
var groups = [];
while (records.length) {
for (var i = 0; i < self.default_nr_columns; i++) {
@ -491,7 +491,7 @@ openerp.web_kanban.KanbanRecord = openerp.web.Widget.extend({
},
do_reload: function() {
var self = this;
this.view.dataset.read_ids([this.id], this.view.fields_keys).then(function(records) {
this.view.dataset.read_ids([this.id], this.view.fields_keys.concat(['__last_update'])).then(function(records) {
if (records.length) {
self.set_record(records[0]);
self.do_render();
@ -531,7 +531,12 @@ openerp.web_kanban.KanbanRecord = openerp.web.Widget.extend({
},
kanban_image: function(model, field, id) {
id = id || '';
return openerp.connection.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id;
var url = openerp.connection.prefix + '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id;
if (this.record.__last_update && this.record.__last_update.raw_value) {
var time = openerp.web.str_to_datetime(this.record.__last_update.raw_value).getTime();
url += '&t=' + time;
}
return url;
},
kanban_text_ellipsis: function(s, size) {
size = size || 160;