[MERGE] trunk

bzr revid: fme@openerp.com-20121107091047-uehws6qa3ouaa4fs
This commit is contained in:
Fabien Meghazi 2012-11-07 10:10:47 +01:00
commit f06b78dbf6
8 changed files with 153 additions and 122 deletions

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-07-02 09:06+0200\n"
"PO-Revision-Date: 2012-02-17 07:29+0000\n"
"Last-Translator: Jeff Wang <wjfonhand@hotmail.com>\n"
"PO-Revision-Date: 2012-11-06 04:40+0000\n"
"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
"Language-Team: Chinese (Simplified) <zh_CN@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-10-21 05:03+0000\n"
"X-Generator: Launchpad (build 16165)\n"
"X-Launchpad-Export-Date: 2012-11-07 04:55+0000\n"
"X-Generator: Launchpad (build 16232)\n"
#. openerp-web
#: addons/web/static/src/js/chrome.js:176
@ -129,56 +129,56 @@ msgstr "OpenERP社区支持版"
#. openerp-web
#: addons/web/static/src/js/coresetup.js:619
msgid "less than a minute ago"
msgstr ""
msgstr "一分钟内"
#. openerp-web
#: addons/web/static/src/js/coresetup.js:620
msgid "about a minute ago"
msgstr ""
msgstr "大约一分钟"
#. openerp-web
#: addons/web/static/src/js/coresetup.js:621
#, python-format
msgid "%d minutes ago"
msgstr ""
msgstr "%d 分钟之前"
#. openerp-web
#: addons/web/static/src/js/coresetup.js:622
msgid "about an hour ago"
msgstr ""
msgstr "大约一小时前"
#. openerp-web
#: addons/web/static/src/js/coresetup.js:623
#, python-format
msgid "%d hours ago"
msgstr ""
msgstr "%d 小时前"
#. openerp-web
#: addons/web/static/src/js/coresetup.js:624
msgid "a day ago"
msgstr ""
msgstr "一天前"
#. openerp-web
#: addons/web/static/src/js/coresetup.js:625
#, python-format
msgid "%d days ago"
msgstr ""
msgstr "%d 天前"
#. openerp-web
#: addons/web/static/src/js/coresetup.js:626
msgid "about a month ago"
msgstr ""
msgstr "大约一月前"
#. openerp-web
#: addons/web/static/src/js/coresetup.js:627
#, python-format
msgid "%d months ago"
msgstr ""
msgstr "%d 月前"
#. openerp-web
#: addons/web/static/src/js/coresetup.js:628
msgid "about a year ago"
msgstr ""
msgstr "大约一年前"
#. openerp-web
#: addons/web/static/src/js/coresetup.js:629
@ -247,13 +247,13 @@ msgstr ""
#. openerp-web
#: addons/web/static/src/js/data_import.js:386
msgid "*Required Fields are not selected :"
msgstr ""
msgstr "*没有选择必须的字段:"
#. openerp-web
#: addons/web/static/src/js/formats.js:139
#, python-format
msgid "(%d records)"
msgstr ""
msgstr "%d 条记录)"
#. openerp-web
#: addons/web/static/src/js/formats.js:325

View File

@ -25,6 +25,7 @@
display: none !important;
}
}
.openerp.openerp_webclient_container {
height: 100%;
}
@ -659,7 +660,7 @@
cursor: pointer;
}
.openerp .oe_dropdown_toggle {
color: rgba(0, 0, 0, 0.5);
color: rgba(0, 0, 0, 0.3);
font-weight: normal;
}
.openerp .oe_dropdown_hover:hover .oe_dropdown_menu, .openerp .oe_dropdown_menu.oe_opened {
@ -2777,6 +2778,9 @@
content: "}";
color: #e0e0e0;
}
.openerp .oe_list_content .oe_list_field_progressbar progress {
width: 100%;
}
.openerp .tree_header {
background-color: #f0f0f0;
border-bottom: 1px solid #cacaca;

View File

@ -569,7 +569,7 @@ $sheet-padding: 16px
position: relative
cursor: pointer
.oe_dropdown_toggle
color: rgba(0,0,0,0.5)
color: rgba(0,0,0,0.3)
font-weight: normal
.oe_dropdown_hover:hover .oe_dropdown_menu, .oe_dropdown_menu.oe_opened
display: block
@ -2193,6 +2193,8 @@ $sheet-padding: 16px
.oe_list_handle
@include text-to-entypo-icon("}",#E0E0E0,18px)
margin-right: 7px
.oe_list_field_progressbar progress
width: 100%
// }}}
// Tree view {{{
.tree_header

View File

@ -124,19 +124,10 @@ function assert(condition, message) {
}
my.InputView = instance.web.Widget.extend({
template: 'SearchView.InputView',
start: function () {
var p = this._super.apply(this, arguments);
this.$el.on('focus', this.proxy('onFocus'));
this.$el.on('blur', this.proxy('onBlur'));
this.$el.on('keydown', this.proxy('onKeydown'));
return p;
},
onFocus: function () {
this.trigger('focused', this);
},
onBlur: function () {
this.$el.text('');
this.trigger('blurred', this);
events: {
focus: function () { this.trigger('focused', this); },
blur: function () { this.$el.text(''); this.trigger('blurred', this); },
keydown: 'onKeydown'
},
getSelection: function () {
// get Text node
@ -212,6 +203,27 @@ my.InputView = instance.web.Widget.extend({
});
my.FacetView = instance.web.Widget.extend({
template: 'SearchView.FacetView',
events: {
'focus': function () { this.trigger('focused', this); },
'blur': function () { this.trigger('blurred', this); },
'click': function (e) {
if ($(e.target).is('.oe_facet_remove')) {
this.model.destroy();
return false;
}
this.$el.focus();
e.stopPropagation();
},
'keydown': function (e) {
var keys = $.ui.keyCode;
switch (e.which) {
case keys.BACKSPACE:
case keys.DELETE:
this.model.destroy();
return false;
}
}
},
init: function (parent, model) {
this._super(parent);
this.model = model;
@ -223,33 +235,11 @@ my.FacetView = instance.web.Widget.extend({
},
start: function () {
var self = this;
this.$el.on('focus', function () { self.trigger('focused', self); });
this.$el.on('blur', function () { self.trigger('blurred', self); });
this.$el.on('click', function (e) {
if ($(e.target).is('.oe_facet_remove')) {
self.model.destroy();
return false;
}
self.$el.focus();
e.stopPropagation();
});
this.$el.on('keydown', function (e) {
var keys = $.ui.keyCode;
switch (e.which) {
case keys.BACKSPACE:
case keys.DELETE:
self.model.destroy();
return false;
}
});
var $e = self.$el.find('> span:last-child');
var q = $.when(this._super());
return q.then(function () {
var values = self.model.values.map(function (value) {
var $e = this.$('> span:last-child');
return $.when(this._super()).then(function () {
return $.when.apply(null, self.model.values.map(function (value) {
return new my.FacetValueView(self, value).appendTo($e);
});
return $.when.apply(null, values);
}));
});
},
model_changed: function () {
@ -274,6 +264,48 @@ my.FacetValueView = instance.web.Widget.extend({
instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.SearchView# */{
template: "SearchView",
events: {
// focus last input if view itself is clicked
'click': function (e) {
if (e.target === this.$('.oe_searchview_facets')[0]) {
this.$('.oe_searchview_input:last').focus();
}
},
// when the completion list opens/refreshes, automatically select the
// first completion item so if the user just hits [RETURN] or [TAB] it
// automatically selects it
'autocompleteopen': function () {
var menu = this.$el.data('autocomplete').menu;
menu.activate(
$.Event({ type: "mouseenter" }),
menu.element.children().first());
},
// search button
'click button.oe_searchview_search': function (e) {
e.stopImmediatePropagation();
this.do_search();
},
'click .oe_searchview_clear': function (e) {
e.stopImmediatePropagation();
this.query.reset();
},
'click .oe_searchview_unfold_drawer': function (e) {
e.stopImmediatePropagation();
this.$el.toggleClass('oe_searchview_open_drawer');
},
'keydown .oe_searchview_input, .oe_searchview_facet': function (e) {
switch(e.which) {
case $.ui.keyCode.LEFT:
this.focusPreceding(this);
e.preventDefault();
break;
case $.ui.keyCode.RIGHT:
this.focusFollowing(this);
e.preventDefault();
break;
}
}
},
/**
* @constructs instance.web.SearchView
* @extends instance.web.Widget
@ -331,46 +363,11 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
});
}
// Launch a search on clicking the oe_searchview_search button
this.$el.on('click', 'button.oe_searchview_search', function (e) {
e.stopImmediatePropagation();
self.do_search();
});
this.$el.on('keydown',
'.oe_searchview_input, .oe_searchview_facet', function (e) {
switch(e.which) {
case $.ui.keyCode.LEFT:
self.focusPreceding(this);
e.preventDefault();
break;
case $.ui.keyCode.RIGHT:
self.focusFollowing(this);
e.preventDefault();
break;
}
});
this.$el.on('click', '.oe_searchview_clear', function (e) {
e.stopImmediatePropagation();
self.query.reset();
});
this.$el.on('click', '.oe_searchview_unfold_drawer', function (e) {
e.stopImmediatePropagation();
self.$el.toggleClass('oe_searchview_open_drawer');
});
instance.web.bus.on('click', this, function(ev) {
if ($(ev.target).parents('.oe_searchview').length === 0) {
self.$el.removeClass('oe_searchview_open_drawer');
}
});
// Focus last input if the view itself is clicked (empty section of
// facets element)
this.$el.on('click', function (e) {
if (e.target === self.$el.find('.oe_searchview_facets')[0]) {
self.$el.find('.oe_searchview_input:last').focus();
}
});
return $.when(p, this.ready);
},
@ -457,7 +454,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
});
},
_value: function() {
return self.$el.find('div.oe_searchview_input').text();
return self.$('div.oe_searchview_input').text();
},
});
},
@ -489,7 +486,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
var input_index = _(this.input_subviews).indexOf(
this.subviewForRoot(
this.$el.find('div.oe_searchview_input:focus')[0]));
this.$('div.oe_searchview_input:focus')[0]));
this.query.add(ui.item.facet, {at: input_index / 2});
},
childFocused: function () {
@ -518,7 +515,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
// _2: undefined if event=change, otherwise model
var self = this;
var started = [];
var $e = this.$el.find('div.oe_searchview_facets');
var $e = this.$('div.oe_searchview_facets');
_.invoke(this.input_subviews, 'destroy');
this.input_subviews = [];
@ -643,7 +640,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
// build drawer
var drawer_started = $.when.apply(
null, _(this.select_for_drawer()).invoke(
'appendTo', this.$el.find('.oe_searchview_drawer')));
'appendTo', this.$('.oe_searchview_drawer')));
// load defaults
var defaults_fetched = $.when.apply(null, _(this.inputs).invoke(
@ -715,6 +712,9 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
*
* If at least one field failed its validation, triggers
* :js:func:`instance.web.SearchView.on_invalid` instead.
*
* @param [_query]
* @param {Object} [options]
*/
do_search: function (_query, options) {
if (options && options.preventSearch) {
@ -940,7 +940,7 @@ instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends in
*/
search_change: function () {
var self = this;
var $filters = this.$el.find('> li').removeClass('oe_selected');
var $filters = this.$('> li').removeClass('oe_selected');
var facet = this.view.query.find(_.bind(this.match_facet, this));
if (!facet) { return; }
facet.values.each(function (v) {
@ -1491,7 +1491,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
}).then(this.proxy('set_filters'));
},
clear_selection: function () {
this.$el.find('li.oe_selected').removeClass('oe_selected');
this.$('li.oe_selected').removeClass('oe_selected');
},
append_filter: function (filter) {
var self = this;
@ -1503,7 +1503,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
} else {
var id = filter.id;
$filter = this.filters[key] = $('<li></li>')
.appendTo(this.$el.find('.oe_searchview_custom_list'))
.appendTo(this.$('.oe_searchview_custom_list'))
.addClass(filter.user_id ? 'oe_searchview_custom_private'
: 'oe_searchview_custom_public')
.text(filter.name);
@ -1538,8 +1538,8 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
},
save_current: function () {
var self = this;
var $name = this.$el.find('input:first');
var private_filter = !this.$el.find('input:last').prop('checked');
var $name = this.$('input:first');
var private_filter = !this.$('input:last').prop('checked');
var search = this.view.build_search_data();
this.rpc('/web/session/eval_domain_and_context', {
@ -1644,11 +1644,20 @@ instance.web.search.Advanced = instance.web.search.Input.extend({
});
},
append_proposition: function () {
var self = this;
return (new instance.web.search.ExtendedSearchProposition(this, this.fields))
.appendTo(this.$el.find('ul'));
.appendTo(this.$('ul')).done(function () {
self.$('button.oe_apply').prop('disabled', false);
});
},
remove_proposition: function (prop) {
// removing last proposition, disable apply button
if (this.getChildren().length <= 1) {
this.$('button.oe_apply').prop('disabled', true);
}
prop.destroy();
},
commit_search: function () {
var self = this;
// Get domain sections from all propositions
var children = this.getChildren();
var propositions = _.invoke(children, 'get_proposition');
@ -1678,6 +1687,13 @@ instance.web.search.Advanced = instance.web.search.Input.extend({
instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @lends instance.web.search.ExtendedSearchProposition# */{
template: 'SearchView.extended_search.proposition',
events: {
'change .searchview_extended_prop_field': 'changed',
'click .searchview_extended_delete_prop': function (e) {
e.stopPropagation();
this.getParent().remove_proposition(this);
}
},
/**
* @constructs instance.web.search.ExtendedSearchProposition
* @extends instance.web.Widget
@ -1695,17 +1711,10 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
this.value = null;
},
start: function () {
var _this = this;
this.$el.find(".searchview_extended_prop_field").change(function() {
_this.changed();
});
this.$el.find('.searchview_extended_delete_prop').click(function () {
_this.destroy();
});
this.changed();
return this._super().done(this.proxy('changed'));
},
changed: function() {
var nval = this.$el.find(".searchview_extended_prop_field").val();
var nval = this.$(".searchview_extended_prop_field").val();
if(this.attrs.selected == null || nval != this.attrs.selected.name) {
this.select_field(_.detect(this.fields, function(x) {return x.name == nval;}));
}
@ -1720,7 +1729,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
if(this.attrs.selected != null) {
this.value.destroy();
this.value = null;
this.$el.find('.searchview_extended_prop_op').html('');
this.$('.searchview_extended_prop_op').html('');
}
this.attrs.selected = field;
if(field == null) {
@ -1736,9 +1745,9 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
_.each(this.value.operators, function(operator) {
$('<option>', {value: operator.value})
.text(String(operator.text))
.appendTo(self.$el.find('.searchview_extended_prop_op'));
.appendTo(self.$('.searchview_extended_prop_op'));
});
var $value_loc = this.$el.find('.searchview_extended_prop_value').empty();
var $value_loc = this.$('.searchview_extended_prop_value').empty();
this.value.appendTo($value_loc);
},
@ -1746,7 +1755,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
if ( this.attrs.selected == null)
return null;
var field = this.attrs.selected;
var op = this.$el.find('.searchview_extended_prop_op')[0];
var op = this.$('.searchview_extended_prop_op')[0];
var operator = op.options[op.selectedIndex];
return {
label: _.str.sprintf(_t('%(field)s %(operator)s "%(value)s"'), {

View File

@ -3917,6 +3917,8 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context());
var values = self.get("value")
var handle_names = function(data) {
if (self.isDestroyed())
return;
var indexed = {};
_.each(data, function(el) {
indexed[el[0]] = el;
@ -4415,6 +4417,7 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
this.destroy();
},
destroy: function () {
this.trigger('closed');
if (this.$el.is(":data(dialog)")) {
this.$el.dialog('close');
}
@ -4820,6 +4823,7 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({
instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({
template: 'FieldBinaryImage',
placeholder: "/web/static/src/img/placeholder.png",
render_value: function() {
var self = this;
var url;
@ -4833,7 +4837,7 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({
url = '/web/binary/image?session_id=' + this.session.session_id + '&model=' +
this.view.dataset.model +'&id=' + id + '&field=' + field + '&t=' + (new Date().getTime());
} else {
url = "/web/static/src/img/placeholder.png";
url = this.placeholder;
}
var $img = $(QWeb.render("FieldBinaryImage-img", { widget: this, url: url }));
this.$el.find('> img').remove();
@ -4846,6 +4850,10 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({
$img.css("margin-left", "" + (self.options.size[0] - $img.width()) / 2 + "px");
$img.css("margin-top", "" + (self.options.size[1] - $img.height()) / 2 + "px");
});
$img.on('error', function() {
$img.attr('src', self.placeholder);
instance.webclient.notification.warn(_t("Image"), _t("Could not display the selected image."));
});
},
on_file_change: function() {
this.render_value();

View File

@ -970,7 +970,7 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web.
// set) a human-readable version. m2o does not have this issue
// because the non-human-readable is just a number, where the
// human-readable version is a pair
if (value && (ref_match = /([\w\.]+),(\d+)/.exec(value))) {
if (value && (ref_match = /^([\w\.]+),(\d+)$/.exec(value))) {
// reference values are in the shape "$model,$id" (as a
// string), we need to split and name_get this pair in order
// to get a correctly displayable value in the field
@ -1306,9 +1306,11 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
process_modifiers: false
});
} catch (e) {
group_label = row_data[group_column.id].value;
group_label = _.str.escapeHTML(row_data[group_column.id].value);
}
$group_column.text(_.str.sprintf("%s (%d)",
// group_label is html-clean (through format or explicit
// escaping if format failed), can inject straight into HTML
$group_column.html(_.str.sprintf("%s (%d)",
group_label, group.length));
if (group.length && group.openable) {

View File

@ -144,8 +144,13 @@
margin-left: 4px;
cursor: pointer;
position: relative;
}
.openerp .oe_kanban_view .oe_kanban_add {
top: -8px;
}
.openerp .oe_kanban_view .oe_kanban_header .oe_dropdown_toggle {
top: -2px;
}
.openerp .oe_kanban_view .oe_kanban_card, .openerp .oe_kanban_view .oe_dropdown_toggle {
cursor: pointer;
display: inline-block;
@ -481,7 +486,6 @@
}
.openerp .oe_kanban_view .oe_dropdown_kanban {
float: right;
clear: both;
cursor: pointer;
margin-top: -6px;
}

View File

@ -168,7 +168,10 @@
margin-left: 4px
cursor: pointer
position: relative
.oe_kanban_add
top: -8px
.oe_kanban_header .oe_dropdown_toggle
top: -2px
.oe_kanban_card, .oe_dropdown_toggle
cursor: pointer
display: inline-block
@ -414,7 +417,6 @@
// KanbanDropDown {{{
.oe_dropdown_kanban
float: right
clear: both
cursor: pointer
margin-top: -6px
&:hover