summaryrefslogtreecommitdiff
path: root/addons/base/static/src
diff options
context:
space:
mode:
authorsma (Tiny) <sma@tinyerp.com>2011-08-31 16:09:21 +0530
committersma (Tiny) <sma@tinyerp.com>2011-08-31 16:09:21 +0530
commitfde5d6a1486ea9843d54b72ae2f31cd2bea18a59 (patch)
tree15958b2d1f7f7c04a88077c23d305aaa214c1831 /addons/base/static/src
parente629395daa3bd050f075a6012619d7c61ce0d801 (diff)
parent5b8ad8068bac7f124071249899e91822f11f194f (diff)
[MERGE]
bzr revid: sma@tinyerp.com-20110831103921-fdpmikied597o2kk
Diffstat (limited to 'addons/base/static/src')
-rw-r--r--addons/base/static/src/css/base.css20
-rw-r--r--addons/base/static/src/js/boot.js4
-rw-r--r--addons/base/static/src/js/chrome.js49
-rw-r--r--addons/base/static/src/js/core.js4
-rw-r--r--addons/base/static/src/js/data.js15
-rw-r--r--addons/base/static/src/js/form.js227
-rw-r--r--addons/base/static/src/js/formats.js30
-rw-r--r--addons/base/static/src/js/list.js59
-rw-r--r--addons/base/static/src/js/search.js2
-rw-r--r--addons/base/static/src/js/views.js123
-rw-r--r--addons/base/static/src/xml/base.xml43
11 files changed, 348 insertions, 228 deletions
diff --git a/addons/base/static/src/css/base.css b/addons/base/static/src/css/base.css
index cd420ea8c0d..4133a9c8623 100644
--- a/addons/base/static/src/css/base.css
+++ b/addons/base/static/src/css/base.css
@@ -597,13 +597,13 @@ label.error {
background-color: #ccc;
}
.openerp .searchview_group.folded .searchview_group_string {
- background: url("../img/ui/group-folded.png") no-repeat scroll 0 50%;
+ background: url("/base/static/src/img/ui/group-folded.png") no-repeat scroll 0 50%;
}
.openerp .searchview_group.folded .searchview_group_content {
display: none;
}
.openerp .searchview_group.expanded .searchview_group_string {
- background: url("../img/ui/group-expanded.png") no-repeat scroll 0 50%;
+ background: url("/base/static/src/img/ui/group-expanded.png") no-repeat scroll 0 50%;
}
.openerp .searchview_group.expanded .searchview_group_content {
display: block;
@@ -635,13 +635,13 @@ label.error {
}
.openerp .oe_search-view-custom-filter-btn span {
- background: url(../img/icons/gtk-add.png) repeat-y;
+ background: url(/base/static/src/img/icons/gtk-add.png) repeat-y;
padding-left: 18px;
}
.openerp .searchview_extended_add_proposition span {
font-size: 0.9em;
- background: url(../img/icons/gtk-add.png) repeat-y;
+ background: url(/base/static/src/img/icons/gtk-add.png) repeat-y;
padding-left: 18px;
}
@@ -657,7 +657,7 @@ label.error {
.openerp .searchview_extended_delete_group span,
.openerp .searchview_extended_delete_prop span {
font-size: 0.9em;
- background: url(../img/icons/gtk-close.png) repeat-y;
+ background: url(/base/static/src/img/icons/gtk-close.png) repeat-y;
padding-left: 18px;
}
/* List */
@@ -870,6 +870,9 @@ label.error {
.openerp .oe_forms input[type="text"], .openerp .oe_forms input[type="password"], .openerp .oe_forms select, .openerp .oe_forms .button {
height: 22px;
}
+.openerp .oe_forms input.field_datetime {
+ min-width: 11em;
+}
.openerp .oe_forms .button {
color: #4c4c4c;
white-space: nowrap;
@@ -892,6 +895,9 @@ label.error {
position: relative;
top: 4px;
}
+.openerp .oe_trad_field.touched {
+ border: 1px solid green !important;
+}
/* http://www.quirksmode.org/dom/inputfile.html
* http://stackoverflow.com/questions/2855589/replace-input-type-file-by-an-image
@@ -1085,7 +1091,7 @@ label.error {
cursor: pointer;
border: 1px solid #D2CFCF;
display: block;
- background: url(../img/toggle-a-bg.png);
+ background: url(/base/static/src/img/toggle-a-bg.png);
width: 21px;
height: 21px;
z-index: 10;
@@ -1100,7 +1106,7 @@ label.error {
}
.openerp li.oe_sidebar_print {
padding-left: 20px;
- background: 1px 3px url(../img/icons/gtk-print.png) no-repeat;
+ background: 1px 3px url(/base/static/src/img/icons/gtk-print.png) no-repeat;
}
.openerp.kitten-mode-activated .main_table {
diff --git a/addons/base/static/src/js/boot.js b/addons/base/static/src/js/boot.js
index 0dd8dcdc980..8fe62d2e5a4 100644
--- a/addons/base/static/src/js/boot.js
+++ b/addons/base/static/src/js/boot.js
@@ -50,7 +50,9 @@
openerp.base = function(instance) {
openerp.base.core(instance);
- openerp.base.dates(instance);
+ if (openerp.base.dates) {
+ openerp.base.dates(instance);
+ }
openerp.base.formats(instance);
openerp.base.chrome(instance);
openerp.base.data(instance);
diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js
index 954e2024965..720bc38d54a 100644
--- a/addons/base/static/src/js/chrome.js
+++ b/addons/base/static/src/js/chrome.js
@@ -479,8 +479,6 @@ openerp.base.Login = openerp.base.Widget.extend({
this.selected_login = localStorage.getItem('last_login_login_success');
}
if (jQuery.deparam(jQuery.param.querystring()).debug != undefined) {
- this.selected_db = this.selected_db || "trunk";
- this.selected_login = this.selected_login || "admin";
this.selected_password = this.selected_password || "a";
}
},
@@ -564,22 +562,25 @@ openerp.base.Login = openerp.base.Widget.extend({
});
openerp.base.Header = openerp.base.Widget.extend({
- init: function(parent, element_id) {
- this._super(parent, element_id);
- if (jQuery.deparam(jQuery.param.querystring()).debug !== undefined) {
- this.qs = '?debug'
- } else {
- this.qs = ''
- }
+ template: "Header",
+ identifier_prefix: 'oe-app-header-',
+ init: function(parent) {
+ this._super(parent);
+ this.qs = "?" + jQuery.param.querystring();
+ this.$content = $();
},
start: function() {
- return this.do_update();
+ this._super();
},
do_update: function () {
- this.$element.html(QWeb.render("Header", this));
+ this.$content = $(QWeb.render("Header-content", {widget: this}));
+ this.$content.appendTo(this.$element);
this.$element.find(".logout").click(this.on_logout);
return this.shortcut_load();
},
+ do_reset: function() {
+ this.$content.remove();
+ },
shortcut_load :function(){
var self = this,
sc = self.session.shortcuts,
@@ -590,22 +591,27 @@ openerp.base.Header = openerp.base.Widget.extend({
sc.binding = {};
$(sc.binding).bind({
'add': function (e, attrs) {
- var $shortcut = $('<li>', {
+ shortcuts_ds.create(attrs, function (out) {
+ $('<li>', {
+ 'data-shortcut-id':out.result,
'data-id': attrs.res_id
}).text(attrs.name)
- .appendTo(self.$element.find('.oe-shortcuts ul'));
- shortcuts_ds.create(attrs, function (out) {
- $shortcut.data('shortcut-id', out.result);
+ .appendTo(self.$element.find('.oe-shortcuts ul'));
+ attrs.id = out.result;
+ sc.push(attrs);
});
},
'remove-current': function () {
var menu_id = self.session.active_id;
var $shortcut = self.$element
- .find('.oe-shortcuts li[data-id=' + menu_id + ']');
+ .find('.oe-shortcuts li[data-id=' + menu_id + ']');
var shortcut_id = $shortcut.data('shortcut-id');
$shortcut.remove();
shortcuts_ds.unlink([shortcut_id]);
- }
+ var sc_new = _.reject(sc, function(shortcut){ return shortcut_id === shortcut.id});
+ sc.splice(0, sc.length);
+ sc.push.apply(sc, sc_new);
+ }
});
}
return this.rpc('/base/session/sc_list', {}, function(shortcuts) {
@@ -615,6 +621,7 @@ openerp.base.Header = openerp.base.Widget.extend({
self.$element.find('.oe-shortcuts')
.html(QWeb.render('Shortcuts', {'shortcuts': shortcuts}))
.undelegate('li', 'click')
+
.delegate('li', 'click', function(e) {
e.stopPropagation();
var id = $(this).data('id');
@@ -743,21 +750,23 @@ openerp.base.WebClient = openerp.base.Widget.extend({
// Do you autorize this ? will be replaced by notify() in controller
openerp.base.Widget.prototype.notification = new openerp.base.Notification(this, "oe_notification");
- this.header = new openerp.base.Header(this, "oe_header");
+
+ this.header = new openerp.base.Header(this);
this.login = new openerp.base.Login(this, "oe_login");
this.header.on_logout.add(this.login.on_logout);
+ this.header.on_action.add(this.on_menu_action);
this.session.on_session_invalid.add(this.login.do_ask_login);
this.session.on_session_valid.add_last(this.header.do_update);
+ this.session.on_session_invalid.add_last(this.header.do_reset);
this.session.on_session_valid.add_last(this.on_logged);
this.menu = new openerp.base.Menu(this, "oe_menu", "oe_secondary_menu");
this.menu.on_action.add(this.on_menu_action);
- this.header.on_action.add(this.on_menu_action);
},
start: function() {
+ this.header.appendTo($("#oe_header"));
this.session.start();
- this.header.start();
this.login.start();
this.menu.start();
this.notification.notify("OpenERP Client", "The openerp client has been initialized.");
diff --git a/addons/base/static/src/js/core.js b/addons/base/static/src/js/core.js
index e872ced1f0d..4cd46504a69 100644
--- a/addons/base/static/src/js/core.js
+++ b/addons/base/static/src/js/core.js
@@ -567,8 +567,8 @@ openerp.base.Session = openerp.base.CallbackEnabled.extend( /** @lends openerp.b
self.do_load_js(file_list.concat(files));
});
} else {
- self.do_load_css(file_list.concat(["/base/webclient/css?mods="+modules]));
- self.do_load_js(["/base/webclient/js?mods="+modules]);
+ self.do_load_css(["/base/webclient/css?mods="+modules]);
+ self.do_load_js(file_list.concat(["/base/webclient/js?mods="+modules]));
}
openerp._modules_loaded = true;
});
diff --git a/addons/base/static/src/js/data.js b/addons/base/static/src/js/data.js
index 04c23224806..e95adaf8870 100644
--- a/addons/base/static/src/js/data.js
+++ b/addons/base/static/src/js/data.js
@@ -355,12 +355,13 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data
* @param {Function} error_callback function called in case of write error
* @returns {$.Deferred}
*/
- write: function (id, data, callback, error_callback) {
+ write: function (id, data, options, callback, error_callback) {
+ var options = options || {};
return this.rpc('/base/dataset/save', {
model: this.model,
id: id,
data: data,
- context: this.get_context()
+ context: this.get_context(options.context)
}, callback, error_callback);
},
/**
@@ -396,18 +397,18 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data
*
* @param {String} method
* @param {Array} [args]
- * @param {Number} [domain_id] index of a domain to evaluate in the args array
- * @param {Number} [context_id] index of a context to evaluate in the args array
+ * @param {Number} [domain_index] index of a domain to evaluate in the args array
+ * @param {Number} [context_index] index of a context to evaluate in the args array
* @param {Function} callback
* @param {Function }error_callback
* @returns {$.Deferred}
*/
- call_and_eval: function (method, args, domain_id, context_id, callback, error_callback) {
+ call_and_eval: function (method, args, domain_index, context_index, callback, error_callback) {
return this.rpc('/base/dataset/call', {
model: this.model,
method: method,
- domain_id: domain_id || null,
- context_id: context_id || null,
+ domain_id: domain_index || null,
+ context_id: context_index || null,
args: args || []
}, callback, error_callback);
},
diff --git a/addons/base/static/src/js/form.js b/addons/base/static/src/js/form.js
index 7a4d3c92d89..e2a99e9b8c5 100644
--- a/addons/base/static/src/js/form.js
+++ b/addons/base/static/src/js/form.js
@@ -157,6 +157,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormVi
this.do_update_pager(record.id == null);
if (this.sidebar) {
this.sidebar.attachments.do_update();
+ this.sidebar.$element.find('.oe_sidebar_translate').toggleClass('oe_hide', !record.id);
}
if (this.default_focus_field && !this.embedded_view) {
this.default_focus_field.focus();
@@ -342,7 +343,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormVi
self.on_created(r, success, prepend_on_create);
});
} else {
- return this.dataset.write(this.datarecord.id, values, function(r) {
+ return this.dataset.write(this.datarecord.id, values, {}, function(r) {
self.on_saved(r, success);
});
}
@@ -441,6 +442,10 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormVi
values[key] = val;
});
return values;
+ },
+ get_selected_ids: function() {
+ var id = this.dataset.ids[this.dataset.index];
+ return id ? [id] : [];
}
});
@@ -875,6 +880,9 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
},
update_dom: function() {
this._super.apply(this, arguments);
+ if (this.field.translate) {
+ this.$element.find('.oe_field_translate').toggle(!!this.view.datarecord.id);
+ }
if (!this.disable_utility_classes) {
this.$element.toggleClass('disabled', this.readonly);
this.$element.toggleClass('required', this.required);
@@ -949,7 +957,7 @@ openerp.base.form.FieldChar = openerp.base.form.Field.extend({
},
set_value: function(value) {
this._super.apply(this, arguments);
- var show_value = (value != null && value !== false) ? value : '';
+ var show_value = openerp.base.format_value(value, this, '');
this.$element.find('input').val(show_value);
},
update_dom: function() {
@@ -957,16 +965,16 @@ openerp.base.form.FieldChar = openerp.base.form.Field.extend({
this.$element.find('input').attr('disabled', this.readonly);
},
set_value_from_ui: function() {
- this.value = this.$element.find('input').val();
+ this.value = openerp.base.parse_value(this.$element.find('input').val(), this);
this._super();
},
validate: function() {
this.invalid = false;
- var value = this.$element.find('input').val();
- if (value === "") {
- this.invalid = this.required;
- } else if (this.validation_regex) {
- this.invalid = !this.validation_regex.test(value);
+ try {
+ var value = openerp.base.parse_value(this.$element.find('input').val(), this, '');
+ this.invalid = this.required && value === '';
+ } catch(e) {
+ this.invalid = true;
}
},
focus: function() {
@@ -978,7 +986,6 @@ openerp.base.form.FieldEmail = openerp.base.form.FieldChar.extend({
init: function(view, node) {
this._super(view, node);
this.template = "FieldEmail";
- this.validation_regex = /@/;
},
start: function() {
this._super.apply(this, arguments);
@@ -993,8 +1000,7 @@ openerp.base.form.FieldEmail = openerp.base.form.FieldChar.extend({
},
set_value: function(value) {
this._super.apply(this, arguments);
- var show_value = (value != null && value !== false) ? value : '';
- this.$element.find('a').attr('href', 'mailto:' + show_value);
+ this.$element.find('a').attr('href', 'mailto:' + this.$element.find('input').val());
}
});
@@ -1017,44 +1023,13 @@ openerp.base.form.FieldUrl = openerp.base.form.FieldChar.extend({
});
openerp.base.form.FieldFloat = openerp.base.form.FieldChar.extend({
- init: function(view, node) {
- this._super(view, node);
- this.validation_regex = /^-?\d+(\.\d+)?$/;
- },
set_value: function(value) {
- this._super.apply(this, [value]);
if (value === false || value === undefined) {
// As in GTK client, floats default to 0
value = 0;
this.dirty = true;
}
- var show_value = value.toFixed(2);
- this.$element.find('input').val(show_value);
- },
- set_value_from_ui: function() {
- this.value = Number(this.$element.find('input').val().replace(/,/g, '.'));
- this._super();
- }
-});
-
-openerp.base.form.FieldInteger = openerp.base.form.FieldFloat.extend({
- init: function(view, node) {
- this._super(view, node);
- this.validation_regex = /^-?\d+$/;
- },
- set_value: function(value) {
this._super.apply(this, [value]);
- if (value === false || value === undefined) {
- // TODO fme: check if GTK client default integers to 0 (like it does with floats)
- value = 0;
- this.dirty = true;
- }
- var show_value = parseInt(value, 10);
- this.$element.find('input').val(show_value);
- },
- set_value_from_ui: function() {
- this.value = Number(this.$element.find('input').val());
- this._super();
}
});
@@ -1063,7 +1038,6 @@ openerp.base.form.FieldDatetime = openerp.base.form.Field.extend({
this._super(view, node);
this.template = "FieldDate";
this.jqueryui_object = 'datetimepicker';
- this.validation_regex = /^\d+-\d+-\d+( \d+:\d+(:\d+)?)?$/;
},
start: function() {
this._super.apply(this, arguments);
@@ -1103,8 +1077,6 @@ openerp.base.form.FieldDatetime = openerp.base.form.Field.extend({
var value = this.$element.find('input').val();
if (value === "") {
this.invalid = this.required;
- } else if (this.validation_regex) {
- this.invalid = !this.validation_regex.test(value);
} else {
this.invalid = !this.$element.find('input')[this.jqueryui_object]('getDate');
}
@@ -1120,39 +1092,15 @@ openerp.base.form.FieldDate = openerp.base.form.FieldDatetime.extend({
init: function(view, node) {
this._super(view, node);
this.jqueryui_object = 'datepicker';
- this.validation_regex = /^\d+-\d+-\d+$/;
},
parse: openerp.base.str_to_date,
format: openerp.base.date_to_str
});
-openerp.base.form.FieldFloatTime = openerp.base.form.FieldChar.extend({
- init: function(view, node) {
- this._super(view, node);
- this.validation_regex = /^\d+:\d+$/;
- },
- set_value: function(value) {
- this._super.apply(this, [value]);
- if (value === false || value === undefined) {
- // As in GTK client, floats default to 0
- value = 0;
- this.dirty = true;
- }
- var show_value = _.sprintf("%02d:%02d", Math.floor(value), Math.round((value % 1) * 60));
- this.$element.find('input').val(show_value);
- },
- set_value_from_ui: function() {
- var time = this.$element.find('input').val().split(':');
- this.set_value(parseInt(time[0], 10) + parseInt(time[1], 10) / 60);
- this._super();
- }
-});
-
openerp.base.form.FieldText = openerp.base.form.Field.extend({
init: function(view, node) {
this._super(view, node);
this.template = "FieldText";
- this.validation_regex = null;
},
start: function() {
this._super.apply(this, arguments);
@@ -1160,7 +1108,7 @@ openerp.base.form.FieldText = openerp.base.form.Field.extend({
},
set_value: function(value) {
this._super.apply(this, arguments);
- var show_value = (value != null && value !== false) ? value : '';
+ var show_value = openerp.base.format_value(value, this, '');
this.$element.find('textarea').val(show_value);
},
update_dom: function() {
@@ -1168,16 +1116,16 @@ openerp.base.form.FieldText = openerp.base.form.Field.extend({
this.$element.find('textarea').attr('disabled', this.readonly);
},
set_value_from_ui: function() {
- this.value = this.$element.find('textarea').val();
+ this.value = openerp.base.parse_value(this.$element.find('textarea').val(), this);
this._super();
},
validate: function() {
this.invalid = false;
- var value = this.$element.find('textarea').val();
- if (value === "") {
- this.invalid = this.required;
- } else if (this.validation_regex) {
- this.invalid = !this.validation_regex.test(value);
+ try {
+ var value = openerp.base.parse_value(this.$element.find('textarea').val(), this, '');
+ this.invalid = this.required && value === '';
+ } catch(e) {
+ this.invalid = true;
}
},
focus: function() {
@@ -1366,36 +1314,56 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
this.$input = this.$element.find("input");
this.$drop_down = this.$element.find(".oe-m2o-drop-down-button");
this.$menu_btn = this.$element.find(".oe-m2o-cm-button");
-
+
// context menu
- var bindings = {};
- bindings[this.cm_id + "_search"] = function() {
- self._search_create_popup("search");
- };
- bindings[this.cm_id + "_create"] = function() {
- self._search_create_popup("form");
- };
- bindings[this.cm_id + "_open"] = function() {
- if (!self.value) {
- return;
- }
- var pop = new openerp.base.form.FormOpenPopup(self.view);
- pop.show_element(self.field.relation, self.value[0],self.build_context(), {});
- pop.on_write_completed.add_last(function() {
- self.set_value(self.value[0]);
+ var init_context_menu_def = $.Deferred().then(function(e) {
+ var rdataset = new openerp.base.DataSetStatic(self, "ir.values", self.build_context());
+ rdataset.call("get", ['action', 'client_action_relate',
+ [[self.field.relation, false]], false, rdataset.get_context()], false, 0)
+ .then(function(result) {
+ self.related_entries = result;
+
+ var $cmenu = $("#" + self.cm_id);
+ $cmenu.append(QWeb.render("FieldMany2One.context_menu", {widget: self}));
+ var bindings = {};
+ bindings[self.cm_id + "_search"] = function() {
+ self._search_create_popup("search");
+ };
+ bindings[self.cm_id + "_create"] = function() {
+ self._search_create_popup("form");
+ };
+ bindings[self.cm_id + "_open"] = function() {
+ if (!self.value) {
+ return;
+ }
+ var pop = new openerp.base.form.FormOpenPopup(self.view);
+ pop.show_element(self.field.relation, self.value[0],self.build_context(), {});
+ pop.on_write_completed.add_last(function() {
+ self.set_value(self.value[0]);
+ });
+ };
+ _.each(_.range(self.related_entries.length), function(i) {
+ bindings[self.cm_id + "_related_" + i] = function() {
+ self.open_related(self.related_entries[i]);
+ };
+ });
+ var cmenu = self.$menu_btn.contextMenu(self.cm_id, {'leftClickToo': true,
+ bindings: bindings, itemStyle: {"color": ""},
+ onContextMenu: function() {
+ if(self.value) {
+ $("#" + self.cm_id + " .oe_m2o_menu_item_mandatory").removeClass("oe-m2o-disabled-cm");
+ } else {
+ $("#" + self.cm_id + " .oe_m2o_menu_item_mandatory").addClass("oe-m2o-disabled-cm");
+ }
+ return true;
+ }, menuStyle: {width: "200px"}
+ });
+ setTimeout(function() {self.$menu_btn.trigger(e);}, 0);
});
- };
- var cmenu = this.$menu_btn.contextMenu(this.cm_id, {'leftClickToo': true,
- bindings: bindings, itemStyle: {"color": ""},
- onContextMenu: function() {
- if(self.value) {
- $("#" + self.cm_id + "_open").removeClass("oe-m2o-disabled-cm");
- } else {
- $("#" + self.cm_id + "_open").addClass("oe-m2o-disabled-cm");
- }
- return true;
- }
});
+ var ctx_callback = function(e) {init_context_menu_def.resolve(e); e.preventDefault()};
+ this.$menu_btn.bind('contextmenu', ctx_callback);
+ this.$menu_btn.click(ctx_callback);
// some behavior for input
this.$input.keyup(function() {
@@ -1555,12 +1523,14 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
},
set_value: function(value) {
value = value || null;
+ this.invalid = false;
var self = this;
- var _super = this._super;
this.tmp_value = value;
+ self.update_dom();
+ self.on_value_changed();
var real_set_value = function(rval) {
self.tmp_value = undefined;
- _super.apply(self, rval);
+ self.value = rval;
self.original_value = undefined;
self._change_int_ext_value(rval);
};
@@ -1586,9 +1556,27 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
},
validate: function() {
this.invalid = false;
- if (this.value === null) {
+ var val = this.tmp_value !== undefined ? this.tmp_value : this.value;
+ if (val === null) {
this.invalid = this.required;
}
+ },
+ open_related: function(related) {
+ var self = this;
+ if (!self.value)
+ return;
+ var additional_context = {
+ active_id: self.value[0],
+ active_ids: [self.value[0]],
+ active_model: self.field.relation
+ };
+ self.rpc("/base/action/load", {
+ action_id: related[2].id,
+ context: additional_context
+ }, function(result) {
+ result.result.context = _.extend(result.result.context || {}, additional_context);
+ self.do_action(result.result);
+ });
}
});
@@ -1884,10 +1872,13 @@ openerp.base.form.One2ManyListView = openerp.base.ListView.extend({
pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(),{
auto_write: false,
alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined,
- parent_view: self.o2m.view
+ parent_view: self.o2m.view,
+ read_function: function() {
+ return self.o2m.dataset.read_ids.apply(self.o2m.dataset, arguments);
+ }
});
pop.on_write.add(function(id, data) {
- self.o2m.dataset.write(id, data, function(r) {
+ self.o2m.dataset.write(id, data, {}, function(r) {
self.o2m.reload_current_view();
});
});
@@ -2156,6 +2147,7 @@ openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({
* options:
* - alternative_form_view
* - auto_write (default true)
+ * - read_function
* - parent_view
*/
show_element: function(model, row_id, context, options) {
@@ -2171,7 +2163,8 @@ openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({
},
start: function() {
this._super();
- this.dataset = new openerp.base.ReadOnlyDataSetSearch(this, this.model, this.context);
+ this.dataset = new openerp.base.form.FormOpenDataset(this, this.model, this.context);
+ this.dataset.fop = this;
this.dataset.ids = [this.row_id];
this.dataset.index = 0;
this.dataset.parent_view = this.options.parent_view;
@@ -2184,7 +2177,7 @@ openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({
var self = this;
var wdataset = new openerp.base.DataSetSearch(this, this.model, this.context, this.domain);
wdataset.parent_view = this.options.parent_view;
- wdataset.write(id, data, function(r) {
+ wdataset.write(id, data, {}, function(r) {
self.on_write_completed();
});
},
@@ -2213,6 +2206,16 @@ openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({
}
});
+openerp.base.form.FormOpenDataset = openerp.base.ReadOnlyDataSetSearch.extend({
+ read_ids: function() {
+ if (this.fop.options.read_function) {
+ return this.fop.options.read_function.apply(null, arguments);
+ } else {
+ return this._super.apply(this, arguments);
+ }
+ }
+});
+
openerp.base.form.FieldReference = openerp.base.form.Field.extend({
init: function(view, node) {
this._super(view, node);
@@ -2440,9 +2443,9 @@ openerp.base.form.widgets = new openerp.base.Registry({
'reference' : 'openerp.base.form.FieldReference',
'boolean' : 'openerp.base.form.FieldBoolean',
'float' : 'openerp.base.form.FieldFloat',
- 'integer': 'openerp.base.form.FieldInteger',
+ 'integer': 'openerp.base.form.FieldFloat',
+ 'float_time': 'openerp.base.form.FieldFloat',
'progressbar': 'openerp.base.form.FieldProgressBar',
- 'float_time': 'openerp.base.form.FieldFloatTime',
'image': 'openerp.base.form.FieldBinaryImage',
'binary': 'openerp.base.form.FieldBinaryFile'
});
diff --git a/addons/base/static/src/js/formats.js b/addons/base/static/src/js/formats.js
index c141aad908c..bf54290bf45 100644
--- a/addons/base/static/src/js/formats.js
+++ b/addons/base/static/src/js/formats.js
@@ -28,8 +28,10 @@ openerp.base.format_value = function (value, descriptor, value_if_empty) {
case 'float':
var precision = descriptor.digits ? descriptor.digits[1] : 2;
var int_part = Math.floor(value);
- var dec_part = Math.floor((value % 1) * Math.pow(10, precision));
- return _.sprintf('%d' + openerp.base._t.database.parameters.decimal_point + '%d', int_part, dec_part);
+ var dec_part = Math.abs(Math.floor((value % 1) * Math.pow(10, precision)));
+ return _.sprintf('%d%s%d',
+ int_part,
+ openerp.base._t.database.parameters.decimal_point, dec_part);
case 'float_time':
return _.sprintf("%02d:%02d",
Math.floor(value),
@@ -45,8 +47,8 @@ openerp.base.format_value = function (value, descriptor, value_if_empty) {
if (typeof(value) == "string")
value = openerp.base.str_to_datetime(value);
try {
- return value.format(_.sprintf("%s %s", openerp.base._t.database.parameters.date_format,
- openerp.base._t.database.parameters.time_format));
+ return value.toString(_.sprintf("%s %s", Date.CultureInfo.formatPatterns.shortDate,
+ Date.CultureInfo.formatPatterns.longTime));
} catch (e) {
return value.format("%m/%d/%Y %H:%M:%S");
}
@@ -55,7 +57,7 @@ openerp.base.format_value = function (value, descriptor, value_if_empty) {
if (typeof(value) == "string")
value = openerp.base.str_to_date(value);
try {
- return value.format(openerp.base._t.database.parameters.date_format);
+ return value.toString(Date.CultureInfo.formatPatterns.shortDate);
} catch (e) {
return value.format("%m/%d/%Y");
}
@@ -63,7 +65,7 @@ openerp.base.format_value = function (value, descriptor, value_if_empty) {
if (typeof(value) == "string")
value = openerp.base.str_to_time(value);
try {
- return value.format(openerp.base._t.database.parameters.time_format);
+ return value.toString(Date.CultureInfo.formatPatterns.longTime);
} catch (e) {
return value.format("%H:%M:%S");
}
@@ -108,17 +110,27 @@ openerp.base.parse_value = function (value, descriptor, value_if_empty) {
case 'progressbar':
return openerp.base.parse_value(value, {type: "float"});
case 'datetime':
- var tmp = Date.parse(value);
+ var tmp = Date.parseExact(value, _.sprintf("%s %s", Date.CultureInfo.formatPatterns.shortDate,
+ Date.CultureInfo.formatPatterns.longTime));
+ if (tmp !== null)
+ return tmp;
+ tmp = Date.parse(value);
if (tmp !== null)
return tmp;
throw value + " is not a valid datetime";
case 'date':
- var tmp = Date.parse(value);
+ var tmp = Date.parseExact(value, Date.CultureInfo.formatPatterns.shortDate);
+ if (tmp !== null)
+ return tmp;
+ tmp = Date.parse(value);
if (tmp !== null)
return tmp;
throw value + " is not a valid date";
case 'time':
- var tmp = Date.parse(value);
+ var tmp = Date.parseExact(value, Date.CultureInfo.formatPatterns.longTime);
+ if (tmp !== null)
+ return tmp;
+ tmp = Date.parse(value);
if (tmp !== null)
return tmp;
throw value + " is not a valid time";
diff --git a/addons/base/static/src/js/list.js b/addons/base/static/src/js/list.js
index 9797b5dff99..786c8cb2068 100644
--- a/addons/base/static/src/js/list.js
+++ b/addons/base/static/src/js/list.js
@@ -365,7 +365,6 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
reload_view: function (grouped, context, initial) {
var self = this;
var callback = function (field_view_get) {
- console.log('loaded', initial ? 'initial' : 'subsequent');
self.on_loaded(field_view_get, grouped);
};
if (this.embedded_view) {
@@ -383,10 +382,19 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
* re-renders the content of the list view
*/
reload_content: function () {
+ var self = this;
this.records.reset();
this.$element.find('.oe-listview-content').append(
- this.groups.render(
- $.proxy(this, 'compute_aggregates')));
+ this.groups.render(function () {
+ if (self.dataset.index == null) {
+ var has_one = false;
+ self.records.each(function () { has_one = true; });
+ if (has_one) {
+ self.dataset.index = 0;
+ }
+ }
+ self.compute_aggregates();
+ }));
},
/**
* Event handler for a search, asks for the computation/folding of domains
@@ -399,8 +407,8 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
*/
do_search: function (domains, contexts, groupbys) {
return this.rpc('/base/session/eval_domain_and_context', {
- domains: domains,
- contexts: contexts,
+ domains: [this.dataset.get_domain()].concat(domains),
+ contexts: [this.dataset.get_context()].concat(contexts),
group_by_seq: groupbys
}, $.proxy(this, 'do_actual_search'));
},
@@ -589,8 +597,11 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
$footer_cells.filter(_.sprintf('[data-field=%s]', column.id))
.html(openerp.base.format_cell(aggregation, column));
});
+ },
+ get_selected_ids: function() {
+ var ids = this.groups.get_selection().ids;
+ return ids;
}
- // TODO: implement reorder (drag and drop rows)
});
openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.ListView.List# */{
/**
@@ -1040,25 +1051,25 @@ openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.bas
var fields = _.pluck(_.select(this.columns, function(x) {return x.tag == "field"}), 'name');
var options = { offset: page * limit, limit: limit };
dataset.read_slice(fields, options , function (records) {
- if (!self.datagroup.openable) {
- view.configure_pager(dataset);
- } else {
- var pages = Math.ceil(dataset.ids.length / limit);
- self.$row
- .find('.oe-pager-state')
- .text(_.sprintf('%d/%d', page + 1, 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 (!self.datagroup.openable) {
+ view.configure_pager(dataset);
+ } else {
+ var pages = Math.ceil(dataset.ids.length / limit);
+ self.$row
+ .find('.oe-pager-state')
+ .text(_.sprintf('%d/%d', page + 1, 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});
- list.render();
- d.resolve(list);
- });
+ self.records.add(records, {silent: true});
+ list.render();
+ d.resolve(list);
+ });
return d.promise();
},
setup_resequence_rows: function (list, dataset) {
diff --git a/addons/base/static/src/js/search.js b/addons/base/static/src/js/search.js
index 99f07784160..e3d51e2b439 100644
--- a/addons/base/static/src/js/search.js
+++ b/addons/base/static/src/js/search.js
@@ -801,6 +801,8 @@ openerp.base.search.ManyToOneField = openerp.base.search.CharField.extend({
render: function (defaults) {
if (defaults[this.attrs.name]) {
this.id = defaults[this.attrs.name];
+ if (this.id instanceof Array)
+ this.id = this.id[0];
// TODO: maybe this should not be completely removed
delete defaults[this.attrs.name];
this.dataset.name_get([this.id], $.proxy(this, 'on_name_get'));
diff --git a/addons/base/static/src/js/views.js b/addons/base/static/src/js/views.js
index 7320d09d251..11b45cbfeb0 100644
--- a/addons/base/static/src/js/views.js
+++ b/addons/base/static/src/js/views.js
@@ -123,6 +123,14 @@ openerp.base.ActionManager = openerp.base.Widget.extend({
this.content_stop();
var ClientWidget = openerp.base.client_actions.get_object(action.tag);
(this.client_widget = new ClientWidget(this, action.params)).appendTo(this);
+ },
+ ir_actions_report_xml: function(action) {
+ this.rpc('/base/report/get_report', {
+ action: action,
+ context: {}
+ }).then(function(result) {
+ debugger;
+ });
}
});
@@ -350,20 +358,22 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
shortcut_add_remove: function() {
var self = this;
var $shortcut_toggle = this.$element.find('.oe-shortcut-toggle');
- $shortcut_toggle.click(function() {
- if ($shortcut_toggle.hasClass("oe-shortcut-remove")) {
- $(self.session.shortcuts.binding).trigger('remove-current');
- $shortcut_toggle.removeClass("oe-shortcut-remove");
- } else {
- $(self.session.shortcuts.binding).trigger('add', {
- 'user_id': self.session.uid,
- 'res_id': self.session.active_id,
- 'resource': 'ir.ui.menu',
- 'name': self.action.name
- });
- $shortcut_toggle.addClass("oe-shortcut-remove");
- }
- });
+ $shortcut_toggle
+ .unbind("click")
+ .click(function() {
+ if ($shortcut_toggle.hasClass("oe-shortcut-remove")) {
+ $(self.session.shortcuts.binding).trigger('remove-current');
+ $shortcut_toggle.removeClass("oe-shortcut-remove");
+ } else {
+ $(self.session.shortcuts.binding).trigger('add', {
+ 'user_id': self.session.uid,
+ 'res_id': self.session.active_id,
+ 'resource': 'ir.ui.menu',
+ 'name': self.action.name
+ });
+ $shortcut_toggle.addClass("oe-shortcut-remove");
+ }
+ });
}
});
@@ -374,8 +384,8 @@ openerp.base.Sidebar = openerp.base.Widget.extend({
this.sections = {};
},
start: function() {
+ this._super(this);
var self = this;
- this._super(this, arguments);
this.$element.html(QWeb.render('Sidebar'));
this.$element.find(".toggle-sidebar").click(function(e) {
self.do_toggle();
@@ -431,9 +441,26 @@ openerp.base.Sidebar = openerp.base.Widget.extend({
item.callback();
}
if (item.action) {
- item.action.flags = item.action.flags || {};
- item.action.flags.new_window = true;
- self.do_action(item.action);
+ var ids = self.widget_parent.get_selected_ids();
+ if (ids.length == 0) {
+ //TODO niv: maybe show a warning?
+ return false;
+ }
+ var additional_context = {
+ active_id: ids[0],
+ active_ids: ids,
+ active_model: self.widget_parent.dataset.model
+ };
+ self.rpc("/base/action/load", {
+ action_id: item.action.id,
+ context: additional_context
+ }, function(result) {
+ result.result.context = _.extend(result.result.context || {},
+ additional_context);
+ result.result.flags = result.result.flags || {};
+ result.result.flags.new_window = true;
+ self.do_action(result.result);
+ });
}
return false;
});
@@ -456,6 +483,9 @@ openerp.base.Sidebar = openerp.base.Widget.extend({
openerp.base.TranslateDialog = openerp.base.Dialog.extend({
dialog_title: _t("Translations"),
init: function(view) {
+ // TODO fme: should add the language to fields_view_get because between the fields view get
+ // and the moment the user opens the translation dialog, the user language could have been changed
+ this.view_language = view.session.user_context.lang;
this['on_button' + _t("Save")] = this.on_button_Save;
this['on_button' + _t("Close")] = this.on_button_Close;
this._super(view, {
@@ -484,6 +514,9 @@ openerp.base.TranslateDialog = openerp.base.Dialog.extend({
self.select_tab('view');
}
self.$fields_form = self.$element.find('.oe_translation_form');
+ self.$fields_form.find('.oe_trad_field').change(function() {
+ $(this).toggleClass('touched', ($(this).val() != $(this).attr('data-value')));
+ });
});
return this;
},
@@ -498,19 +531,27 @@ openerp.base.TranslateDialog = openerp.base.Dialog.extend({
_.each(self.languages, function(lg) {
var deff = $.Deferred();
deffered.push(deff);
- self.rpc('/base/dataset/get', {
- model: self.view.dataset.model,
- ids: [self.view.datarecord.id],
- fields: self.translatable_fields_keys,
- context: self.view.dataset.get_context({
- 'lang': lg.code
- })
- }, function(values) {
+ var callback = function(values) {
_.each(self.translatable_fields_keys, function(f) {
- self.$fields_form.find('.oe_trad_field[name="' + lg.code + '-' + f + '"]').val(values[0][f] || '');
+ self.$fields_form.find('.oe_trad_field[name="' + lg.code + '-' + f + '"]').val(values[0][f] || '').attr('data-value', values[0][f] || '');
});
deff.resolve();
- });
+ }
+ if (lg.code === self.view_language) {
+ var values = {};
+ _.each(self.translatable_fields_keys, function(field) {
+ values[field] = self.view.fields[field].get_value();
+ });
+ callback([values]);
+ } else {
+ self.rpc('/base/dataset/get', {
+ model: self.view.dataset.model,
+ ids: [self.view.datarecord.id],
+ fields: self.translatable_fields_keys,
+ context: self.view.dataset.get_context({
+ 'lang': lg.code
+ })}, callback);
+ }
});
$.when.apply(null, deffered).then(callback);
},
@@ -531,21 +572,39 @@ openerp.base.TranslateDialog = openerp.base.Dialog.extend({
},
open: function(field) {
var self = this,
- super = this._super;
+ sup = this._super;
$.when(this.languages_loaded).then(function() {
if (self.view.translatable_fields && self.view.translatable_fields.length) {
self.do_load_fields_values(function() {
- super.call(self);
+ sup.call(self);
if (field) {
// TODO: focus and scroll to field
}
});
} else {
- super.call(self);
+ sup.call(self);
}
});
},
on_button_Save: function() {
+ var trads = {},
+ self = this;
+ self.$fields_form.find('.oe_trad_field.touched').each(function() {
+ var field = $(this).attr('name').split('-');
+ if (!trads[field[0]]) {
+ trads[field[0]] = {};
+ }
+ trads[field[0]][field[1]] = $(this).val();
+ });
+ _.each(trads, function(data, code) {
+ if (code === self.view_language) {
+ _.each(data, function(value, field) {
+ self.view.fields[field].set_value(value);
+ });
+ } else {
+ self.view.dataset.write(self.view.datarecord.id, data, { 'lang': code });
+ }
+ });
this.close();
},
on_button_Close: function() {
@@ -651,7 +710,7 @@ openerp.base.View = openerp.base.Widget.extend({
}, {
label: "Translate",
callback: this.on_sidebar_translate,
- classname: 'oe_sidebar_translate'
+ classname: 'oe_sidebar_translate oe_hide'
}, {
label: "View Log",
callback: this.on_sidebar_view_log,
diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml
index 69aac831386..c6bd9a1ee19 100644
--- a/addons/base/static/src/xml/base.xml
+++ b/addons/base/static/src/xml/base.xml
@@ -326,15 +326,19 @@
</div>
</t>
<t t-name="Header">
- <a t-att-href="'/' + qs" class="company_logo_link">
- <div class="company_logo" />
- </a>
- <h1 class="header_title" t-if="session.session_is_valid()">
- <span class="database"><t t-esc="session.db"/></span> - <t t-esc="session.login"/> <br/>
- <small class="username">rpc_session_id: <t t-esc="session.session_id"/></small>
+ <div>
+ <a t-att-href="'/' + widget.qs" class="company_logo_link">
+ <div class="company_logo" />
+ </a>
+ </div>
+</t>
+<t t-name="Header-content">
+ <h1 class="header_title">
+ <span class="database"><t t-esc="widget.session.db"/></span> - <t t-esc="widget.session.login"/> <br/>
+ <small class="username">rpc_session_id: <t t-esc="widget.session.session_id"/></small>
</h1>
<div class="header_corner">
- <ul class="block" t-if="session.session_is_valid()">
+ <ul class="block">
<li>
<a href="#home" title="Home" class="home"><img src="/base/static/src/img/header-home.png" width="16" height="16" border="0"/></a>
</li>
@@ -474,8 +478,8 @@
<label class="oe_form_label"><t t-esc="field.string"/>:</label>
</td>
<td t-foreach="widget.languages" t-as="lg" class="oe_form_frame_cell">
- <input t-if="field.type == 'char'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" class="oe_trad_field" style="width: 100%"/>
- <textarea t-if="field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" class="oe_trad_field" style="width: 100%"></textarea>
+ <input t-if="field.type == 'char'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field" style="width: 100%"/>
+ <textarea t-if="field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" style="width: 100%"></textarea>
</td>
</tr>
</table>
@@ -805,13 +809,24 @@
<img src="/base/static/src/img/down-arrow.png" /></span>
<span class="oe-m2o-cm-button" t-att-id="widget.name + '_open'">
<img src="/base/static/src/img/icons/gtk-index.png"/></span>
- <div t-att-id="widget.cm_id" class="contextMenu" style="display:none"><ul>
- <li t-att-id="widget.cm_id + '_open'" style="color:grey">Open...</li>
- <li t-att-id="widget.cm_id + '_create'">Create...</li>
- <li t-att-id="widget.cm_id + '_search'">Search...</li>
- </ul></div>
+ <div t-att-id="widget.cm_id" class="contextMenu" style="display:none">
+ </div>
</div>
</t>
+<t t-name="FieldMany2One.context_menu">
+ <ul>
+ <li t-att-id="widget.cm_id + '_open'" style="color:grey">Open...</li>
+ <li t-att-id="widget.cm_id + '_create'">Create...</li>
+ <li t-att-id="widget.cm_id + '_search'" class="oe_m2o_menu_item_mandatory">Search...</li>
+ <t t-set="i" t-value="0"/>
+ <t t-foreach="widget.related_entries" t-as="entry">
+ <li t-att-id="widget.cm_id + '_related_' + i" style="color:grey" class="oe_m2o_menu_item_mandatory">
+ ... <t t-esc="(entry[2] || {})['name'] || ''"/>
+ </li>
+ <t t-set="i" t-value="i+1"/>
+ </t>
+ </ul>
+</t>
<t t-name="FieldOne2Many">
<div t-att-id="widget.element_id">
</div>