[MERGE] Merged trunk.

bzr revid: jra@tinyerp.com-20121025093537-rua2i3iqg2wisa5v
This commit is contained in:
Jiten (OpenERP) 2012-10-25 15:05:37 +05:30
commit 2354633823
18 changed files with 3247 additions and 2700 deletions

View File

@ -128,10 +128,9 @@ class JsonRequest(WebRequest):
"id": null}
"""
def dispatch(self, controller, method):
def dispatch(self, method):
""" Calls the method asked for by the JSON-RPC2 or JSONP request
:param controller: the instance of the controller which received the request
:param method: the method which received the request
:returns: an utf8 encoded JSON-RPC2 or JSONP reply
@ -170,9 +169,9 @@ class JsonRequest(WebRequest):
self.jsonrequest = simplejson.loads(request, object_hook=nonliterals.non_literal_decoder)
self.init(self.jsonrequest.get("params", {}))
if _logger.isEnabledFor(logging.DEBUG):
_logger.debug("--> %s.%s\n%s", controller.__class__.__name__, method.__name__, pprint.pformat(self.jsonrequest))
_logger.debug("--> %s.%s\n%s", method.im_class.__name__, method.__name__, pprint.pformat(self.jsonrequest))
response['id'] = self.jsonrequest.get('id')
response["result"] = method(controller, self, **self.params)
response["result"] = method(self, **self.params)
except session.AuthenticationError:
error = {
'code': 100,
@ -230,16 +229,13 @@ def jsonrequest(f):
the ``session_id``, ``context`` and ``debug`` keys (which are stripped out
beforehand)
"""
@functools.wraps(f)
def json_handler(controller, request):
return JsonRequest(request).dispatch(controller, f)
json_handler.exposed = True
return json_handler
f.exposed = 'json'
return f
class HttpRequest(WebRequest):
""" Regular GET/POST request
"""
def dispatch(self, controller, method):
def dispatch(self, method):
params = dict(self.httprequest.args)
params.update(self.httprequest.form)
params.update(self.httprequest.files)
@ -250,9 +246,9 @@ class HttpRequest(WebRequest):
akw[key] = value
else:
akw[key] = type(value)
_logger.debug("%s --> %s.%s %r", self.httprequest.method, controller.__class__.__name__, method.__name__, akw)
_logger.debug("%s --> %s.%s %r", self.httprequest.method, method.im_class.__name__, method.__name__, akw)
try:
r = method(controller, self, **self.params)
r = method(self, **self.params)
except xmlrpclib.Fault, e:
r = werkzeug.exceptions.InternalServerError(cgi.escape(simplejson.dumps({
'code': 200,
@ -317,11 +313,8 @@ def httprequest(f):
merged in the same dictionary), apart from the ``session_id``, ``context``
and ``debug`` keys (which are stripped out beforehand)
"""
@functools.wraps(f)
def http_handler(controller, request):
return HttpRequest(request).dispatch(controller, f)
http_handler.exposed = True
return http_handler
f.exposed = 'http'
return f
#----------------------------------------------------------
# Controller registration with a metaclass
@ -538,16 +531,21 @@ class Root(object):
"""
if l:
ps = '/' + '/'.join(l)
meth = 'index'
method_name = 'index'
while ps:
c = controllers_path.get(ps)
if c:
m = getattr(c, meth, None)
if m and getattr(m, 'exposed', False):
_logger.debug("Dispatching to %s %s %s", ps, c, meth)
return m
ps, _slash, meth = ps.rpartition('/')
if not ps and meth:
method = getattr(c, method_name, None)
if method:
exposed = getattr(method, 'exposed', False)
if exposed == 'json':
_logger.debug("Dispatch json to %s %s %s", ps, c, method_name)
return lambda request: JsonRequest(request).dispatch(method)
elif exposed == 'http':
_logger.debug("Dispatch http to %s %s %s", ps, c, method_name)
return lambda request: HttpRequest(request).dispatch(method)
ps, _slash, method_name = ps.rpartition('/')
if not ps and method_name:
ps = '/'
return None

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-20 07:27+0000\n"
"Last-Translator: Aleksei Motsik <Unknown>\n"
"PO-Revision-Date: 2012-10-23 14:30+0000\n"
"Last-Translator: Chertykov Denis <chertykov@gmail.com>\n"
"Language-Team: Russian <ru@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:02+0000\n"
"X-Generator: Launchpad (build 16165)\n"
"X-Launchpad-Export-Date: 2012-10-24 05:20+0000\n"
"X-Generator: Launchpad (build 16179)\n"
#. openerp-web
#: addons/web/static/src/js/chrome.js:176
@ -129,62 +129,62 @@ msgstr "OpenERP - Не поддерживаемая/Community Версия"
#. 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
#, python-format
msgid "%d years ago"
msgstr ""
msgstr "%d лет назад"
#. openerp-web
#: addons/web/static/src/js/data_export.js:6
@ -290,18 +290,18 @@ msgstr ""
#: addons/web/static/src/js/search.js:948
#, python-format
msgid "Filter on: %s"
msgstr ""
msgstr "Фильтр по: %s"
#. openerp-web
#: addons/web/static/src/js/search.js:999
msgid "Filter"
msgstr ""
msgstr "Фильтр"
#. openerp-web
#: addons/web/static/src/js/search.js:1108
#, python-format
msgid "Group by: %s"
msgstr ""
msgstr "Группировать по: %s"
#. openerp-web
#: addons/web/static/src/js/search.js:1132
@ -312,7 +312,7 @@ msgstr ""
#: addons/web/static/src/js/search.js:1267
#, python-format
msgid "Search %(field)s for: %(value)s"
msgstr ""
msgstr "Искать %(field)s для: %(value)s"
#. openerp-web
#: addons/web/static/src/js/search.js:869
@ -339,7 +339,7 @@ msgstr "Нет"
#: addons/web/static/src/js/search.js:1416
#, python-format
msgid "Search %(field)s at: %(value)s"
msgstr ""
msgstr "Искать %(field)s в: %(value)s"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1286
@ -349,13 +349,13 @@ msgstr "Фильтры"
#. openerp-web
#: addons/web/static/src/js/search.js:1762
msgid "Advanced"
msgstr ""
msgstr "Расширенный"
#. openerp-web
#: addons/web/static/src/js/search.js:1853
#, python-format
msgid "%(field)s %(operator)s \"%(value)s\""
msgstr ""
msgstr "%(field)s %(operator)s \"%(value)s\""
#. openerp-web
#: addons/web/static/src/js/search.js:1341
@ -633,12 +633,12 @@ msgstr "Добавить: "
#. openerp-web
#: addons/web/static/src/js/view_form.js:4230
msgid "Save As..."
msgstr ""
msgstr "Сохранить как..."
#. openerp-web
#: addons/web/static/src/js/view_form.js:4230
msgid "The field is empty, there's nothing to save !"
msgstr ""
msgstr "Поле пусто, нечего сохранять !"
#. openerp-web
#: addons/web/static/src/js/view_list.js:8
@ -680,7 +680,7 @@ msgstr "Внимание"
#. openerp-web
#: addons/web/static/src/js/view_list.js:716
msgid "You must select at least one record."
msgstr ""
msgstr "Вы должны выбрать хотя бы одну запись ."
#. openerp-web
#: addons/web/static/src/js/view_list.js:1243
@ -728,17 +728,17 @@ msgstr "Не удалось найти определение текущего
#. openerp-web
#: addons/web/static/src/js/views.js:716
msgid "Print"
msgstr ""
msgstr "Печать"
#. openerp-web
#: addons/web/static/src/js/views.js:717
msgid "Attachment"
msgstr ""
msgstr "Вложение"
#. openerp-web
#: addons/web/static/src/js/views.js:718 addons/web/static/src/xml/base.xml:276
msgid "More"
msgstr ""
msgstr "Еще"
#. openerp-web
#: addons/web/static/src/js/views.js:810
@ -758,12 +758,12 @@ msgstr "Вы должны выбрать хотя бы одну запись."
#. openerp-web
#: addons/web/static/src/js/views.js:875
msgid "Uploading..."
msgstr ""
msgstr "Загрузка..."
#. openerp-web
#: addons/web/static/src/js/views.js:885
msgid "Do you really want to delete this attachment ?"
msgstr ""
msgstr "Вы действительно хотите удалить это вложение?"
#. openerp-web
#: addons/web/static/src/js/views.js:962
@ -913,7 +913,7 @@ msgstr "Пароль Администратора:"
#. openerp-web
#: addons/web/static/src/xml/base.xml:95
msgid "Confirm password:"
msgstr "Подтверждение пароля:"
msgstr "Подтвердите пароль:"
#. openerp-web
#: addons/web/static/src/xml/base.xml:109
@ -960,17 +960,17 @@ msgstr "Подтвердить мастер-пароль:"
#. openerp-web
#: addons/web/static/src/xml/base.xml:325
msgid "About OpenERP"
msgstr ""
msgstr "Об OpenERP"
#. openerp-web
#: addons/web/static/src/xml/base.xml:327
msgid "Log out"
msgstr ""
msgstr "Выход"
#. openerp-web
#: addons/web/static/src/xml/base.xml:333
msgid "Activate the developer mode"
msgstr ""
msgstr "Включить режим разработчика"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1820
@ -1030,12 +1030,12 @@ msgstr "Пароль ещё раз:"
#. openerp-web
#: addons/web/static/src/xml/base.xml:390
msgid "Open"
msgstr ""
msgstr "Открыть"
#. openerp-web
#: addons/web/static/src/xml/base.xml:390
msgid "ERP"
msgstr ""
msgstr "ERP"
#. openerp-web
#: addons/web/static/src/xml/base.xml:477
@ -1050,7 +1050,7 @@ msgstr "Просмотр Лога (доступ на чтение)"
#. openerp-web
#: addons/web/static/src/xml/base.xml:450
msgid "Toggle Form Layout Outline"
msgstr ""
msgstr "Переключить структуры макета формы"
#. openerp-web
#: addons/web/static/src/xml/base.xml:479
@ -1115,28 +1115,28 @@ msgstr "Дата изменения:"
#. openerp-web
#: addons/web/static/src/xml/base.xml:518
msgid "Delete this attachment"
msgstr ""
msgstr "Удалить вложение"
#. openerp-web
#: addons/web/static/src/xml/base.xml:523
msgid "/web/binary/upload_attachment"
msgstr ""
msgstr "/web/binary/upload_attachment"
#. openerp-web
#: addons/web/static/src/xml/base.xml:527
msgid "Add..."
msgstr ""
msgstr "Добавить..."
#. openerp-web
#: addons/web/static/src/xml/base.xml:622
#: addons/web/static/src/xml/base.xml:687
msgid "or"
msgstr ""
msgstr "или"
#. openerp-web
#: addons/web/static/src/xml/base.xml:687
msgid "Discard"
msgstr ""
msgstr "Отменить"
#. openerp-web
#: addons/web/static/src/xml/base.xml:806
@ -1242,13 +1242,13 @@ msgstr "Выбрать дату"
#. openerp-web
#: addons/web/static/src/xml/base.xml:948
msgid "Open Resource"
msgstr ""
msgstr "Открыть ресурс"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1162
#: addons/web/static/src/xml/base.xml:1205
msgid "Set Image"
msgstr "Назначить изображение"
msgstr "Установить изображение"
#. openerp-web
#: addons/web/static/src/js/view_form.js:1623
@ -1263,12 +1263,12 @@ msgstr "Очистить"
#: addons/web/static/src/xml/base.xml:1179
#: addons/web/static/src/xml/base.xml:1230
msgid "Uploading ..."
msgstr "Загружаю ..."
msgstr "Загружается ..."
#. openerp-web
#: addons/web/static/src/xml/base.xml:1066
msgid "width: 83px;"
msgstr ""
msgstr "ширина: 83px ;"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1207
@ -1320,7 +1320,7 @@ msgstr "Поле"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1205
msgid "Advanced Search..."
msgstr ""
msgstr "Расширенный поиск..."
#. openerp-web
#: addons/web/static/src/xml/base.xml:1287
@ -1355,22 +1355,22 @@ msgstr "(Имеющийся фильтр с таким же имененем б
#. openerp-web
#: addons/web/static/src/xml/base.xml:1376
msgid "Custom Filters"
msgstr ""
msgstr "Настраиваемые фильтры"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1379
msgid "Save current filter"
msgstr ""
msgstr "Сохранить текущий фильтр"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1381
msgid "Filter name"
msgstr ""
msgstr "Название фильтра"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1383
msgid "Share with all users"
msgstr ""
msgstr "Совместно со всеми пользователями"
#. openerp-web
#: addons/web/static/src/js/search.js:298
@ -1381,32 +1381,32 @@ msgstr "Добавить на Панель"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1394
msgid "Title of new Dashboard item"
msgstr ""
msgstr "Название нового элемента панели"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1395
msgid "save"
msgstr ""
msgstr "сохранить"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1399
msgid "Select Dashboard to add this filter to"
msgstr ""
msgstr "Выберите панель, чтобы добавить этот фильтр"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1406
msgid "Advanced Search"
msgstr ""
msgstr "Расширенный поиск"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1411
msgid "Add a condition"
msgstr ""
msgstr "Добавить условие"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1412
msgid "Apply"
msgstr ""
msgstr "Применить"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1509
@ -1426,9 +1426,9 @@ msgid ""
" You can export all data or only the fields that can be "
"reimported after modification."
msgstr ""
"Этот мастер экспортирует все найденные данные в CSV файл.\n"
" Вы можете экспортровать все данные либо только те поля которые "
"могут быть в последствии импортированны."
"Этот мастер экспортирует все найденные данные в CSV-файл.\n"
" Вы можете экспортировать все данные, либо только те поля которые "
"должны быть в последствии импортированы после изменений."
#. openerp-web
#: addons/web/static/src/xml/base.xml:1624
@ -1562,7 +1562,7 @@ msgstr ""
#. openerp-web
#: addons/web/static/src/xml/base.xml:1713
msgid "--- Don't Import ---"
msgstr ""
msgstr "--- Не импортировать ---"
#. openerp-web
#: addons/web/static/src/xml/base.xml:1809

File diff suppressed because it is too large Load Diff

View File

@ -1547,7 +1547,9 @@ $sheet-max-width: 860px
padding: 100px 0 0 137px
min-height: 327px
margin-left: -15px
.oe_view.oe_cannot_create
.oe_view_nocontent_create
display: none
// }}}
// FormView.base and dynamic tags {{{
.oe_formview
@ -2081,6 +2083,14 @@ $sheet-max-width: 860px
visibility: visible
.oe_list
&.oe_cannot_edit
.oe_list_header_handle, .oe_list_field_handle
display: none !important
padding: 0 !important
&.oe_cannot_delete
.oe_list_record_delete
display: none !important
.oe_form
.oe_form_nosheet
margin: 0 // FIXME: either class or border should not be by default
@ -2178,16 +2188,6 @@ $sheet-max-width: 860px
.oe_list_handle
@include text-to-entypo-icon("}",#E0E0E0,18px)
margin-right: 7px
.oe_list_cannot_create
.oe_view_nocontent_create
display: none
.oe_list_cannot_edit
.oe_list_header_handle, .oe_list_field_handle
display: none !important
padding: 0 !important
.oe_list_cannot_delete
.oe_list_record_delete
display: none !important
// }}}
// Tree view {{{
.tree_header

View File

@ -1128,6 +1128,7 @@ instance.web.WebClient = instance.web.Client.extend({
}
return $.when(self.action_manager.do_action(action, {
clear_breadcrumbs: true,
action_menu_id: self.menu.current_menu,
})).fail(function() {
self.menu.open_menu(options.previous_menu_id);
});

View File

@ -1590,37 +1590,6 @@ instance.web.form.DefaultFieldManager = instance.web.Widget.extend({
},
});
instance.web.form.FormDialog = instance.web.Dialog.extend({
init: function(parent, options, view_id, dataset) {
this._super(parent, options);
this.dataset = dataset;
this.view_id = view_id;
return this;
},
start: function() {
var self = this;
this._super();
this.form = new instance.web.FormView(this, this.dataset, this.view_id, {
pager: false
});
this.form.appendTo(this.$el);
this.form.on('record_created', self, this.on_form_dialog_saved);
this.form.on('record_saved', this, this.on_form_dialog_saved);
return this;
},
select_id: function(id) {
if (this.form.dataset.select_id(id)) {
return this.form.do_show();
} else {
this.do_warn("Could not find id in dataset");
return $.Deferred().reject();
}
},
on_form_dialog_saved: function(r) {
this.close();
}
});
instance.web.form.compute_domain = function(expr, fields) {
if (! (expr instanceof Array))
return !! expr;
@ -3987,9 +3956,12 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
},
});
/*
* TODO niv: clean those deferred stuff, it could be better
*/
/**
widget options:
- reload_on_button: Reload the whole form view if click on a button in a list view.
If you see this options, do not use it, it's basically a dirty hack to make one
precise o2m to behave the way we want.
*/
instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({
multi_selection: false,
disable_utility_classes: true,
@ -4118,7 +4090,20 @@ instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends in
readonly: this.getParent().get("effective_readonly")
});
pop.on('write_completed', self, self.reload_content);
}
},
do_button_action: function(name, id, callback) {
var self = this;
var _sup = _.bind(this._super, this);
if (! this.m2m_field.options.reload_on_button) {
return _sup(name, id, callback);
} else {
return this.m2m_field.view.save().pipe(function() {
return _sup(name, id, function() {
self.m2m_field.view.reload();
});
});
}
},
});
instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend(instance.web.form.CompletionFieldMixin, {
@ -4551,6 +4536,10 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
self.select_elements(self.selected_ids);
self.destroy();
});
var $cbutton = self.$buttonpane.find(".oe_selectcreatepopup-search-create");
$cbutton.click(function() {
self.new_object();
});
});
});
this.searchview.appendTo($(".oe_popup_search", self.$el));
@ -4605,16 +4594,6 @@ instance.web.form.FieldReference = instance.web.form.AbstractField.extend(instan
this._super(field_manager, node);
this.reference_ready = true;
},
on_nop: function() {
},
on_selection_changed: function() {
if (this.reference_ready) {
var sel = this.selection.get_value();
this.m2o.field.relation = sel;
this.m2o.set_value(false);
this.m2o.$el.toggle(sel !== false);
}
},
destroy_content: function() {
if (this.fm) {
this.fm.destroy();
@ -4655,33 +4634,38 @@ instance.web.form.FieldReference = instance.web.form.AbstractField.extend(instan
.on('focused', null, function () {self.trigger('focused')})
.on('blurred', null, function () {self.trigger('blurred')});
},
is_false: function() {
return typeof(this.get_value()) !== 'string';
on_selection_changed: function() {
if (this.reference_ready) {
this.internal_set_value([this.selection.get_value(), false]);
this.render_value();
}
},
data_changed: function() {
if (this.reference_ready) {
this.internal_set_value([this.selection.get_value(), this.m2o.get_value()]);
}
},
set_value: function(val) {
if (val) {
val = val.split(',');
val[0] = val[0] || false;
val[1] = val[0] ? (val[1] ? parseInt(val[1], 10) : val[1]) : false;
}
this._super(val || [false, false]);
},
get_value: function() {
return this.get('value')[0] && this.get('value')[1] ? (this.get('value')[0] + ',' + this.get('value')[1]) : false;
},
render_value: function() {
this.reference_ready = false;
var vals = [], sel_val, m2o_val;
if (typeof(this.get('value')) === 'string') {
vals = this.get('value').split(',');
}
sel_val = vals[0] || false;
m2o_val = vals[1] ? parseInt(vals[1], 10) : vals[1];
if (!this.get("effective_readonly")) {
this.selection.set_value(sel_val);
this.selection.set_value(this.get('value')[0]);
}
this.m2o.field.relation = sel_val;
this.m2o.set_value(m2o_val);
this.m2o.field.relation = this.get('value')[0];
this.m2o.set_value(this.get('value')[1]);
this.m2o.$el.toggle(!!this.get('value')[0]);
this.reference_ready = true;
},
data_changed: function() {
var model = this.selection.get_value(),
id = this.m2o.get_value();
if (typeof(model) === 'string' && typeof(id) === 'number') {
this.internal_set_value(model + ',' + id);
} else {
this.internal_set_value(false);
}
},
});
instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, {

View File

@ -22,6 +22,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
'reorderable': true,
'action_buttons': true,
},
view_type: 'tree',
/**
* Core class for list-type displays.
*
@ -83,7 +84,8 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
});
this.no_leaf = false;
this.on('view_load', self, self.load_list);
this.grouped = false;
this.on('view_loaded', self, self.load_list);
},
set_default_options: function (options) {
this._super(options);
@ -145,7 +147,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
*/
start: function() {
this.$el.addClass('oe_list');
return this.reload_view(null, null, true);
return this._super();
},
/**
* Returns the style for the provided record in the current view (from the
@ -219,7 +221,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
* @param {Object} data.fields_view.arch current list view descriptor
* @param {Boolean} grouped Is the list view grouped
*/
load_list: function(data, grouped) {
load_list: function(data) {
var self = this;
this.fields_view = data;
this.name = "" + this.fields_view.arch.attrs.string;
@ -245,16 +247,11 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
}).value();
}
this.setup_columns(this.fields_view.fields, grouped);
this.setup_columns(this.fields_view.fields, this.grouped);
this.$el.html(QWeb.render(this._template, this));
this.$el.addClass(this.fields_view.arch.attrs['class']);
// add css classes that reflect the (absence of) access rights
this.$el.toggleClass('oe_list_cannot_create', !this.is_action_enabled('create'))
.toggleClass('oe_list_cannot_edit', !this.is_action_enabled('edit'))
.toggleClass('oe_list_cannot_delete', !this.is_action_enabled('delete'));
// Head hook
// Selecting records
this.$el.find('.oe_list_record_selector').click(function(){
@ -290,7 +287,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
}
this.$buttons.find('.oe_list_add')
.click(this.proxy('do_add_record'))
.prop('disabled', grouped);
.prop('disabled', this.grouped);
}
// Pager
@ -359,7 +356,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
this.sidebar.add_toolbar(this.fields_view.toolbar);
this.sidebar.$el.hide();
}
this.trigger('list_view_loaded', data, grouped);
this.trigger('list_view_loaded', data, this.grouped);
},
/**
* Configures the ListView pager based on the provided dataset's information
@ -377,7 +374,10 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
var total = dataset.size();
var limit = this.limit() || total;
this.$pager.toggle(total !== 0);
if (total == 0)
this.$pager.hide();
else
this.$pager.css("display", "");
this.$pager.toggleClass('oe_list_pager_single_page', (total <= limit));
var spager = '-';
if (total) {
@ -464,25 +464,12 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
/**
* Reloads the list view based on the current settings (dataset & al)
*
* @deprecated
* @param {Boolean} [grouped] Should the list be displayed grouped
* @param {Object} [context] context to send the server while loading the view
*/
reload_view: function (grouped, context, initial) {
var self = this;
var callback = function (field_view_get) {
self.load_list(field_view_get, grouped);
};
if (this.embedded_view) {
return $.Deferred().then(callback).resolve(this.embedded_view);
} else {
return this.rpc('/web/view/load', {
model: this.model,
view_id: this.view_id,
view_type: "tree",
context: this.dataset.get_context(context),
toolbar: !!this.options.$sidebar
}).then(callback);
}
return this.load_view(context);
},
/**
* re-renders the content of the list view
@ -564,8 +551,9 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
group_by = null;
}
this.no_leaf = !!context['group_by_no_leaf'];
this.grouped = !!group_by;
this.reload_view(!!group_by, context).then(
return this.load_view(context).pipe(
this.proxy('reload_content'));
},
/**

View File

@ -150,7 +150,7 @@ openerp.web.list_editable = function (instance) {
if (!id && done.created) {
id = done.record.get('id');
}
self.handle_button.call(self, name, id, callback);
self.handle_button(name, id, callback);
});
},
/**

View File

@ -174,6 +174,9 @@ instance.web.ActionManager = instance.web.Widget.extend({
if(this.inner_action.type == 'ir.actions.act_window') {
state['model'] = this.inner_action.res_model;
}
if (this.inner_action.menu_id) {
state['menu_id'] = this.inner_action.menu_id;
}
if (this.inner_action.id) {
state['action'] = this.inner_action.id;
} else if (this.inner_action.type == 'ir.actions.client') {
@ -241,6 +244,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
clear_breadcrumbs: false,
on_reverse_breadcrumb: function() {},
on_close: function() {},
action_menu_id: null,
});
if (_.isString(action) && instance.web.client_actions.contains(action)) {
var action_client = { type: "ir.actions.client", tag: action };
@ -266,6 +270,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
pager : !popup && !inline,
display_title : !popup
}, action.flags || {});
action.menu_id = options.action_menu_id;
if (!(type in this)) {
console.error("Action manager can't handle action of type " + action.type, action);
return $.Deferred().reject();
@ -895,9 +900,7 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
var self = this;
return $.when(this._super.apply(this, arguments)).then(function () {
var controller = self.views[self.active_view].controller,
fvg = controller.fields_view,
view_id = (fvg && fvg.view_id) || '--';
var controller = self.views[self.active_view].controller;
self.$el.find('.oe_debug_view').html(QWeb.render('ViewManagerDebug', {
view: controller,
view_manager: self
@ -1142,28 +1145,33 @@ instance.web.View = instance.web.Widget.extend({
start: function () {
return this.load_view();
},
load_view: function() {
load_view: function(context) {
var self = this;
var view_loaded;
if (this.embedded_view) {
var def = $.Deferred();
$.async_when().then(function() {def.resolve(self.embedded_view);});
return def.pipe(function(r) {
self.trigger('view_loaded', r);
view_loaded = $.Deferred();
$.async_when().then(function() {
view_loaded.resolve(self.embedded_view);
});
} else {
var context = new instance.web.CompoundContext(this.dataset.get_context());
if (! this.view_type)
console.warn("view_type is not defined", this);
return this.rpc("/web/view/load", {
view_loaded = this.rpc("/web/view/load", {
"model": this.dataset.model,
"view_id": this.view_id,
"view_type": this.view_type,
toolbar: !!this.options.$sidebar,
context: context
}).pipe(function(r) {
self.trigger('view_loaded', r);
context: this.dataset.get_context(context)
});
}
return view_loaded.pipe(function(r) {
self.trigger('view_loaded', r);
// add css classes that reflect the (absence of) access rights
self.$el.addClass('oe_view')
.toggleClass('oe_cannot_create', !self.is_action_enabled('create'))
.toggleClass('oe_cannot_edit', !self.is_action_enabled('edit'))
.toggleClass('oe_cannot_delete', !self.is_action_enabled('delete'));
});
},
set_default_options: function(options) {
this.options = options || {};
@ -1273,11 +1281,9 @@ instance.web.View = instance.web.Widget.extend({
},
/**
* Switches to a specific view type
*
* @param {String} view view type to switch to
*/
do_switch_view: function(view) {
this.trigger('switch_mode',view);
do_switch_view: function() {
this.trigger.apply(this, ['switch_mode'].concat(_.toArray(arguments)));
},
/**
* Cancels the switch to the current view, switches to the previous one

View File

@ -1236,9 +1236,9 @@
<t t-name="SelectCreatePopup.search.buttons">
<t t-if="! widget.options.disable_multiple_selection">
<button type="button" class="oe_button oe_selectcreatepopup-search-select" disabled="disabled">Select</button>
or
</t>
<a class="oe_button oe_selectcreatepopup-search-close oe_bold oe_form_button_cancel" href="javascript:void(0)">Cancel</a>
<button type="button" class="oe_button oe_selectcreatepopup-search-create">Create</button>
or <a class="oe_button oe_selectcreatepopup-search-close oe_bold oe_form_button_cancel" href="javascript:void(0)">Cancel</a>
</t>
<t t-name="AbstractFormPopup.buttons">
<t t-if="! readonly">

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-01-13 11:40+0000\n"
"Last-Translator: Aleksei Motsik <Unknown>\n"
"PO-Revision-Date: 2012-10-23 14:08+0000\n"
"Last-Translator: Chertykov Denis <chertykov@gmail.com>\n"
"Language-Team: Russian <ru@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-10-24 05:20+0000\n"
"X-Generator: Launchpad (build 16179)\n"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:11
@ -25,114 +25,114 @@ msgstr "Календарь"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:70
msgid "Filter"
msgstr ""
msgstr "Фильтр"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:144
msgid "Today"
msgstr ""
msgstr "Сегодня"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:145
msgid "Day"
msgstr ""
msgstr "День"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:146
msgid "Week"
msgstr ""
msgstr "Неделя"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:147
msgid "Month"
msgstr ""
msgstr "Месяц"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:148
msgid "New event"
msgstr ""
msgstr "Новое событие"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:149
msgid "Save"
msgstr ""
msgstr "Сохранить"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:150
msgid "Cancel"
msgstr ""
msgstr "Отмена"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:151
msgid "Details"
msgstr ""
msgstr "Подробности"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:152
msgid "Edit"
msgstr ""
msgstr "Изменить"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:153
msgid "Delete"
msgstr ""
msgstr "Удалить"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:155
msgid "Event will be deleted permanently, are you sure?"
msgstr ""
msgstr "Событие будет удалено навсегда, вы уверены?"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:156
#: addons/web_calendar/static/src/js/calendar.js:169
msgid "Description"
msgstr ""
msgstr "Описание"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:157
msgid "Time period"
msgstr ""
msgstr "Промежуток времени"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:158
msgid "Full day"
msgstr ""
msgstr "Полный день"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:161
msgid "Do you want to edit the whole set of repeated events?"
msgstr ""
msgstr "Вы хотите, изменить все повторяющиеся события?"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:162
msgid "Repeat event"
msgstr ""
msgstr "Повтор события"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:163
msgid "Disabled"
msgstr ""
msgstr "Отключено"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:164
msgid "Enabled"
msgstr ""
msgstr "Включено"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:167
#: addons/web_calendar/static/src/js/calendar.js:175
msgid "Agenda"
msgstr ""
msgstr "Повестка дня"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:168
msgid "Date"
msgstr ""
msgstr "Дата"
#. openerp-web
#: addons/web_calendar/static/src/js/calendar.js:172
msgid "Year"
msgstr ""
msgstr "Год"
#. openerp-web
#: addons/web_calendar/static/src/xml/web_calendar.xml:5

View File

@ -395,9 +395,7 @@ instance.web_calendar.CalendarView = instance.web.View.extend({
}
},
get_event_data: function(event_obj) {
var data = {
name: event_obj.text
};
var data = {};
data[this.date_start] = instance.web.datetime_to_str(event_obj.start_date);
if (this.date_stop) {
data[this.date_stop] = instance.web.datetime_to_str(event_obj.end_date);

View File

@ -1 +0,0 @@
import controllers

View File

@ -1 +0,0 @@
import graph

View File

@ -1,92 +0,0 @@
# -*- coding: utf-8 -*-
import openerp
from lxml import etree
class GraphView(openerp.addons.web.controllers.main.View):
_cp_path = '/web_graph/graph'
@openerp.addons.web.http.jsonrequest
def data_get(self, req, model=None, domain=[], context={}, group_by=[], view_id=False, orientation=False, stacked=False, mode="bar", **kwargs):
obj = req.session.model(model)
res = obj.fields_view_get(view_id, 'graph')
fields = res['fields']
toload = filter(lambda x: x not in fields, group_by)
if toload:
fields.update( obj.fields_get(toload, context) )
tree = etree.fromstring(res['arch'])
pos = 0
xaxis = group_by or []
yaxis = []
for field in tree.iter(tag='field'):
if (field.tag != 'field') or (not field.get('name')):
continue
assert field.get('name'), "This <field> tag must have a 'name' attribute."
if (not group_by) and ((not pos) or field.get('group')):
xaxis.append(field.get('name'))
if pos and not field.get('group'):
yaxis.append(field.get('name'))
pos += 1
assert len(xaxis), "No field for the X axis!"
assert len(yaxis), "No field for the Y axis!"
# Convert a field's data into a displayable string
ticks = {}
def _convert_key(field, data):
if fields[field]['type']=='many2one':
data = data and data[0]
return data
def _convert(field, data, tick=True):
if fields[field]['type']=='many2one':
data = data and data[1]
elif (fields[field]['type']=='selection') and (type(fields[field]['selection']) in (list, tuple)):
d = dict(fields[field]['selection'])
data = d[data]
if tick:
return ticks.setdefault(data, len(ticks))
return data or 0
def _orientation(x, y):
if not orientation:
return (x,y)
return (y,x)
result = []
if mode=="pie":
res = obj.read_group(domain, yaxis+[xaxis[0]], [xaxis[0]], context=context)
for record in res:
result.append( {
'data': [(_convert(xaxis[0], record[xaxis[0]]), record[yaxis[0]])],
'label': _convert(xaxis[0], record[xaxis[0]], tick=False)
})
elif (not stacked) or (len(xaxis)<2):
for x in xaxis:
res = obj.read_group(domain, yaxis+[x], [x], context=context)
result.append( {
'data': map(lambda record: _orientation(_convert(x, record[x]), record[yaxis[0]] or 0), res),
'label': fields[x]['string']
})
else:
xaxis.reverse()
axis = obj.read_group(domain, yaxis+xaxis[0:1], xaxis[0:1], context=context)
for x in axis:
key = x[xaxis[0]]
res = obj.read_group(domain+[(xaxis[0],'=',_convert_key(xaxis[0], key))], yaxis+xaxis[1:2], xaxis[1:2], context=context)
result.append( {
'data': map(lambda record: _orientation(_convert(xaxis[1], record[xaxis[1]]), record[yaxis[0]] or 0), res),
'label': _convert(xaxis[0], key, tick=False)
})
res = {
'data': result,
'ticks': map(lambda x: (x[1], x[0]), ticks.items())
}
return res

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-01-13 11:41+0000\n"
"Last-Translator: Aleksei Motsik <Unknown>\n"
"PO-Revision-Date: 2012-10-23 14:06+0000\n"
"Last-Translator: Chertykov Denis <chertykov@gmail.com>\n"
"Language-Team: Russian <ru@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-10-24 05:20+0000\n"
"X-Generator: Launchpad (build 16179)\n"
#. openerp-web
#: addons/web_graph/static/src/js/graph.js:19
@ -25,74 +25,74 @@ msgstr "График"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:5
msgid "Graph Options"
msgstr ""
msgstr "Параметры графика"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:7
msgid "Graph Mode"
msgstr ""
msgstr "Графический вид"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:11
msgid "Pie"
msgstr ""
msgstr "Круговая диаграмма"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:12
msgid "Bars"
msgstr ""
msgstr "Линейчатая"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:14
msgid "Lines"
msgstr ""
msgstr "Строчная"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:15
msgid "Areas"
msgstr ""
msgstr "Области"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:18
msgid "Radar"
msgstr ""
msgstr "Радар"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:20
msgid "Legend"
msgstr ""
msgstr "Обозначения"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:24
msgid "Hidden"
msgstr ""
msgstr "Скрытый"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:25
msgid "Inside"
msgstr ""
msgstr "Внутри"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:26
msgid "Top"
msgstr ""
msgstr "Сверху"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:28
msgid "Actions"
msgstr ""
msgstr "Действия"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:32
msgid "Switch Axis"
msgstr ""
msgstr "Переключение осей"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:33
msgid "Show Data"
msgstr ""
msgstr "Показать данные"
#. openerp-web
#: addons/web_graph/static/src/xml/web_graph.xml:34
msgid "Download as PNG"
msgstr ""
msgstr "Скачать как PNG"

View File

@ -228,15 +228,140 @@ instance.web_graph.GraphView = instance.web.View.extend({
},
graph_get_data: function () {
return this.rpc('/web_graph/graph/data_get', {
model: this.dataset.model,
domain: this.domain,
context: this.context,
group_by: this.group_by,
view_id: this.view_id,
mode: this.mode,
orientation: this.orientation,
stacked: this.stacked
var model = this.dataset.model,
domain = new instance.web.CompoundDomain(this.domain || []),
context = new instance.web.CompoundContext(this.context || {}),
group_by = this.group_by || [],
view_id = this.view_id || false,
mode = this.mode || 'bar',
orientation = this.orientation || false,
stacked = this.stacked || false;
var obj = new instance.web.Model(model);
var view_get;
var fields;
var result = [];
var ticks = {};
return obj.call("fields_view_get", [view_id, 'graph']).pipe(function(tmp) {
view_get = tmp;
fields = view_get['fields'];
var toload = _.select(group_by, function(x) { return fields[x] === undefined });
if (toload.length >= 1)
return obj.call("fields_get", [toload, context]);
else
return $.when([]);
}).pipe(function (fields_to_add) {
_.extend(fields, fields_to_add);
var tree = $($.parseXML(view_get['arch']));
var pos = 0;
var xaxis = group_by || [];
var yaxis = [];
tree.find("field").each(function() {
var field = $(this);
if (! field.attr("name"))
return;
if ((group_by.length == 0) && ((! pos) || field.attr('group'))) {
xaxis.push(field.attr('name'));
}
if (pos && ! field.attr('group')) {
yaxis.push(field.attr('name'));
}
pos += 1;
});
if (xaxis.length === 0)
throw new Error("No field for the X axis!");
if (yaxis.length === 0)
throw new Error("No field for the Y axis!");
// Convert a field's data into a displayable string
function _convert_key(field, data) {
if (fields[field]['type'] === 'many2one')
data = data && data[0];
return data;
}
function _convert(field, data, tick) {
tick = tick === undefined ? true : false;
data = instance.web.format_value(data, fields[field]);
if (tick) {
if (ticks[data] === undefined)
ticks[data] = _.size(ticks);
return ticks[data];
}
return data || 0;
}
function _orientation(x, y) {
if (! orientation)
return [x, y]
return [y, x]
}
if (mode === "pie") {
return obj.call("read_group", [domain, yaxis.concat([xaxis[0]]), [xaxis[0]]], {context: context}).pipe(function(res) {
_.each(res, function(record) {
result.push({
'data': [[_convert(xaxis[0], record[xaxis[0]]), record[yaxis[0]]]],
'label': _convert(xaxis[0], record[xaxis[0]], false)
});
});
});
} else if ((! stacked) || (xaxis.length < 2)) {
var defs = [];
_.each(xaxis, function(x) {
defs.push(obj.call("read_group", [domain, yaxis.concat([x]), [x]], {context: context}).pipe(function(res) {
return [x, res];
}));
});
return $.when.apply($, defs).pipe(function() {
_.each(_.toArray(arguments), function(res) {
var x = res[0];
res = res[1];
result.push({
'data': _.map(res, function(record) {
return _orientation(_convert(x, record[x]), record[yaxis[0]] || 0);
}),
'label': fields[x]['string']
});
});
});
} else {
xaxis.reverse();
return obj.call("read_group", [domain, yaxis.concat(xaxis.slice(0, 1)), xaxis.slice(0, 1)], {context: context}).pipe(function(axis) {
var defs = [];
_.each(axis, function(x) {
var key = x[xaxis[0]]
defs.push(obj.call("read_group", [new instance.web.CompoundDomain(domain, [[xaxis[0], '=' ,_convert_key(xaxis[0], key)]]),
yaxis.concat(xaxis.slice(1, 2)), xaxis.slice(1, 2)], {context: context}).pipe(function(res) {
return [x, key, res];
}));
});
return $.when.apply($, defs).pipe(function() {
_.each(_.toArray(arguments), function(res) {
var x = res[0];
var key = res[1];
res = res[2];
result.push({
'data': _.map(res, function(record) {
return _orientation(_convert(xaxis[1], record[xaxis[1]]), record[yaxis[0]] || 0);
}),
'label': _convert(xaxis[0], key, false)
})
});
});
});
}
}).pipe(function() {
var res = {
'data': result,
'ticks': _.map(ticks, function(el, key) { return [el, key] })
};
return res;
});
},

View File

@ -826,7 +826,7 @@ instance.web_kanban.KanbanRecord = instance.web.Widget.extend({
type = $action.data('type') || 'button',
method = 'do_action_' + (type === 'action' ? 'object' : type);
if ((type === 'edit' || type === 'delete') && ! self.view.is_action_enabled(type)) {
self.view.open_record(self.id);
self.view.open_record(self.id, true);
} else if (_.str.startsWith(type, 'switch_')) {
self.view.do_switch_view(type.substr(7));
} else if (typeof self[method] === 'function') {