[MERGE] openerp-web.

bzr revid: vda@tinyerp.com-20110627102112-fdq1j7o7emt6en03
This commit is contained in:
Vaibhav (OpenERP)
2011-06-27 15:51:12 +05:30
11 changed files with 440 additions and 170 deletions
-5
View File
@@ -383,11 +383,6 @@ class DataSet(openerpweb.Controller):
reads = Model.read(ids, fields or False, context)
reads.sort(key=lambda obj: ids.index(obj['id']))
return reads
@openerpweb.jsonrequest
def read(self, request, model, ids, fields=False):
return self.do_search_read(request, model, ids, fields,
request.session.eval_context(request.context))
@openerpweb.jsonrequest
def get(self, request, model, ids, fields=False):
+4 -9
View File
@@ -48,7 +48,7 @@ var QWeb2 = {
if (o !== null && o !== undefined) {
if (o.constructor === Array) {
if (o[1] !== null && o[1] !== undefined) {
return ' ' + o[0] + '="' + this.html_escape(o[1]) + '"';
return ' ' + o[0] + '="' + this.html_escape(o[1], true) + '"';
}
} else if (typeof o === 'object') {
var r = '';
@@ -670,15 +670,10 @@ QWeb2.Element = (function() {
this.top("(function(" + value + ") {");
this.bottom("})(dict);");
this.indent();
if (this.children.length === 1) {
var lines = this.children[0].node.data.split(/\r?\n/);
for (var i = 0, ilen = lines.length; i < ilen; i++) {
this.top(lines[i]);
}
} else {
this.engine.tools.exception("'js' code block contains " + this.children.length + " nodes instead of 1");
var lines = this.engine.tools.xml_node_to_string(this.node, true).split(/\r?\n/);
for (var i = 0, ilen = lines.length; i < ilen; i++) {
this.top(lines[i]);
}
// Maybe I could handle the children ?
this.process_children = false;
},
compile_action_debug : function(value) {
+6 -17
View File
@@ -474,9 +474,10 @@ background: linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,
background: #AAAAAA;
}
.openerp .filter_icon {
height: 22px;
padding: 1px 2px 0 2px;
margin-left: 0;
margin-right: 0;
margin: 0;
vertical-align: bottom;
}
.openerp .filter_label {
font-weight: bold;
@@ -537,14 +538,6 @@ background: linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,
.openerp .searchview_group_content {
padding-left: 10px;
}
.openerp .searchview_group_content .oe-searchview-render-line {
width:0;
}
.openerp .oe-searchview-render-line {
width:100%;
}
.openerp .searchview_extended_group {
padding: 3px;
@@ -1055,18 +1048,14 @@ background: linear-gradient(top, #ffffff 0%,#ebe9e9 100%); /* W3C */
.openerp .oe-m2o-drop-down-button img,
.openerp .oe-m2o-cm-button img {
margin-bottom: -4px;
cursor: pointer;
}
.openerp .oe-m2o-disabled-cm {
color: grey;
}
.openerp .oe-dialog-warning {
.openerp .oe-dialog-warning p {
padding-left: 1em;
font-size: 1.2em;
font-weight: bold;
}
.openerp .oe-dialog-warning img {
float: left;
position: relative;
top: -0.5em;
margin:0 7px 7px 0;
}
+9 -3
View File
@@ -399,7 +399,6 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b
on_rpc_response: function() {
},
on_rpc_error: function(error) {
this.on_log(error.message, error.data.debug);
},
/**
* The session is validated either by login or by restoration of a previous session
@@ -830,8 +829,15 @@ openerp.base.CrashManager = openerp.base.Dialog.extend({
},
on_rpc_error: function(error) {
this.error = error;
if (error.code === 200) {
this.dialog_title = "OpenERP Warning";
if (error.data.fault_code) {
var split = error.data.fault_code.split('\n')[0].split(' -- ');
if (split.length > 1) {
error.type = split.shift();
error.data.fault_code = error.data.fault_code.substr(error.type.length + 4);
}
}
if (error.code === 200 && error.type) {
this.dialog_title = "OpenERP " + _.capitalize(error.type);
this.template = 'DialogWarning';
this.open({
width: 'auto',
+150 -4
View File
@@ -235,7 +235,7 @@ openerp.base.DataSet = openerp.base.Controller.extend( /** @lends openerp.base.
this._super(session);
this.model = model;
this.context = context || {};
this.index = 0;
this.index = null;
this.count = 0;
},
start: function() {
@@ -310,9 +310,10 @@ openerp.base.DataSet = openerp.base.Controller.extend( /** @lends openerp.base.
context: this.context
}, callback);
},
unlink: function(ids) {
// to implement in children
this.notification.notify("Unlink", ids);
unlink: function(ids, callback, error_callback) {
var self = this;
return this.call_and_eval("unlink", [ids, this.context], null, 1,
callback, error_callback);
},
call: function (method, args, callback, error_callback) {
return this.rpc('/base/dataset/call', {
@@ -356,15 +357,20 @@ openerp.base.DataSetStatic = openerp.base.DataSet.extend({
this.count = this.ids.length;
},
read_slice: function (fields, offset, limit, callback) {
var self = this;
offset = offset || 0;
var end_pos = limit && limit !== -1 ? offset + limit : undefined;
this.read_ids(this.ids.slice(offset, end_pos), fields, callback);
},
set_ids: function (ids) {
this.ids = ids;
this.count = this.ids.length;
this.index = this.index <= this.count - 1 ?
this.index : (this.count > 0 ? this.count - 1 : 0);
},
unlink: function(ids) {
this.on_unlink(ids);
return $.Deferred().resolve({result: true});
},
on_unlink: function(ids) {
this.set_ids(_.without.apply(null, [this.ids].concat(ids)));
@@ -438,9 +444,149 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
this._sort.unshift((reverse ? '-' : '') + field);
return undefined;
},
unlink: function(ids, callback, error_callback) {
var self = this;
return this._super(ids, function(result) {
self.ids = _.without.apply(_, [self.ids].concat(ids));
self.count = self.ids.length;
self.index = self.index <= self.count - 1 ?
self.index : (self.count > 0 ? self.count -1 : 0);
if (callback)
callback(result);
}, error_callback);
}
});
openerp.base.BufferedDataSet = openerp.base.DataSetStatic.extend({
virtual_id_prefix: "one2many_v_id_",
virtual_id_regex: /one2many_v_id_.*/,
debug_mode: true,
init: function() {
this._super.apply(this, arguments);
this.reset_ids([]);
},
create: function(data, callback, error_callback) {
var cached = {id:_.uniqueId(this.virtual_id_prefix), values: data};
this.to_create.push(cached);
this.cache.push(cached);
this.on_change();
var to_return = $.Deferred().then(callback);
setTimeout(function() {to_return.resolve({result: cached.id});}, 0);
return to_return.promise();
},
write: function (id, data, callback) {
var self = this;
var record = _.detect(this.to_create, function(x) {return x.id === id;});
record = record || _.detect(this.to_write, function(x) {return x.id === id;});
if (record) {
$.extend(record.values, data);
} else {
record = {id: id, values: data};
self.to_write.push(record);
}
var cached = _.detect(this.cache, function(x) {return x.id === id;});
$.extend(cached.values, record.values);
this.on_change();
var to_return = $.Deferred().then(callback);
setTimeout(function () {to_return.resolve({result: true});}, 0);
return to_return.promise();
},
unlink: function(ids, callback, error_callback) {
var self = this;
_.each(ids, function(id) {
if (! _.detect(self.to_create, function(x) { return x.id === id; })) {
self.to_delete.push({id: id})
}
});
this.to_create = _.reject(this.to_create, function(x) { return _.include(ids, x.id);});
this.to_write = _.reject(this.to_write, function(x) { return _.include(ids, x.id);});
this.cache = _.reject(this.cache, function(x) { return _.include(ids, x.id);});
this.set_ids(_.without.apply(_, [this.ids].concat(ids)));
this.on_change();
var to_return = $.Deferred().then(callback);
setTimeout(function () {to_return.resolve({result: true});}, 0);
return to_return.promise();
},
reset_ids: function(ids) {
this.set_ids(ids);
this.to_delete = [];
this.to_create = [];
this.to_write = [];
this.cache = [];
},
on_change: function() {},
read_ids: function (ids, fields, callback) {
var self = this;
var to_get = [];
_.each(ids, function(id) {
var cached = _.detect(self.cache, function(x) {return x.id === id;});
var created = _.detect(self.to_create, function(x) {return x.id === id;});
if (created) {
_.each(fields, function(x) {if (cached.values[x] === undefined) cached.values[x] = false;});
} else {
if (!cached || !_.all(fields, function(x) {return cached.values[x] !== undefined}))
to_get.push(id);
}
});
var completion = $.Deferred().then(callback);
var return_records = function() {
var records = _.map(ids, function(id) {
return _.extend({}, _.detect(self.cache, function(c) {return c.id === id;}).values, {"id": id});
});
if (self.debug_mode) {
if (_.include(records, undefined)) {
throw "Record not correctly loaded";
}
}
setTimeout(function () {completion.resolve(records);}, 0);
}
if(to_get.length > 0) {
var rpc_promise = this._super(to_get, fields, function(records) {
_.each(records, function(record, index) {
var id = to_get[index];
var cached = _.detect(self.cache, function(x) {return x.id === id;});
if (!cached) {
self.cache.push({id: id, values: record});
} else {
// I assume cache value is prioritary
_.defaults(cached.values, record);
}
});
return_records();
});
$.when(rpc_promise).fail(function() {completion.reject();});
} else {
return_records();
}
return completion.promise();
},
});
openerp.base.ReadOnlyDataSetSearch = openerp.base.DataSetSearch.extend({
create: function(data, callback, error_callback) {
this.on_create(data);
var to_return = $.Deferred().then(callback);
setTimeout(function () {to_return.resolve({"result": undefined});}, 0);
return to_return.promise();
},
on_create: function(data) {},
write: function (id, data, callback) {
this.on_write(id);
var to_return = $.Deferred().then(callback);
setTimeout(function () {to_return.resolve({"result": true});}, 0);
return to_return.promise();
},
on_write: function(id) {},
unlink: function(ids, callback, error_callback) {
this.on_unlink(ids);
var to_return = $.Deferred().then(callback);
setTimeout(function () {to_return.resolve({"result": true});}, 0);
return to_return.promise();
},
on_unlink: function(ids) {}
});
openerp.base.CompoundContext = function() {
this.__ref = "compound_context";
this.__contexts = [];
+180 -91
View File
@@ -36,6 +36,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
this.default_focus_button = null;
this.registry = openerp.base.form.widgets;
this.has_been_loaded = $.Deferred();
this.$form_header = null;
},
start: function() {
//this.log('Starting FormView '+this.model+this.view_id)
@@ -59,72 +60,80 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
_.each(this.widgets, function(w) {
w.start();
});
this.$element.find('div.oe_form_pager button[data-pager-action]').click(function() {
this.$form_header = this.$element.find('#' + this.element_id + '_header');
this.$form_header.find('div.oe_form_pager button[data-pager-action]').click(function() {
var action = $(this).data('pager-action');
self.on_pager_action(action);
});
this.$element.find('#' + this.element_id + '_header button.oe_form_button_save').click(this.do_save);
this.$element.find('#' + this.element_id + '_header button.oe_form_button_save_edit').click(this.do_save_edit);
this.$element.find('#' + this.element_id + '_header button.oe_form_button_cancel').click(this.do_cancel);
this.$element.find('#' + this.element_id + '_header button.oe_form_button_new').click(this.on_button_new);
this.$form_header.find('button.oe_form_button_save').click(this.do_save);
this.$form_header.find('button.oe_form_button_save_edit').click(this.do_save_edit);
this.$form_header.find('button.oe_form_button_cancel').click(this.do_cancel);
this.$form_header.find('button.oe_form_button_new').click(this.on_button_new);
this.view_manager.sidebar.set_toolbar(data.fields_view.toolbar);
this.has_been_loaded.resolve();
},
do_show: function () {
var self = this;
self.$element.show();
if (this.dataset.index === null || (this.dataset.index === 0 && this.dataset.ids.length == 0)) {
if (this.dataset.index === null) {
// null index means we should start a new record
// 0 index with empty ids means we called the form with empty dataset (wizards, switched to form from empty list, ...)
this.on_button_new();
} else {
this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
}
self.$element.show();
this.view_manager.sidebar.do_refresh(true);
},
do_hide: function () {
this.$element.hide();
},
on_record_loaded: function(record) {
if (!record) {
throw("Form: No record received");
}
if (!record.id) {
this.$form_header.find('.oe_form_on_create').show();
this.$form_header.find('.oe_form_on_update').hide();
this.$form_header.find('button.oe_form_button_new').hide();
} else {
this.$form_header.find('.oe_form_on_create').hide();
this.$form_header.find('.oe_form_on_update').show();
this.$form_header.find('button.oe_form_button_new').show();
}
this.touched = false;
if (record) {
this.datarecord = record;
for (var f in this.fields) {
this.datarecord = record;
for (var f in this.fields) {
var field = this.fields[f];
field.touched = false;
field.set_value(this.datarecord[f] || false);
field.validate();
}
if (!record.id) {
// New record: Second pass in order to trigger the onchanges
this.touched = true;
this.show_invalid = false;
for (var f in record) {
var field = this.fields[f];
field.touched = false;
field.set_value(this.datarecord[f] || false);
field.validate();
}
if (!record.id) {
// New record: Second pass in order to trigger the onchanges
this.touched = true;
this.show_invalid = false;
for (var f in record) {
this.on_form_changed(this.fields[f]);
if (field) {
field.touched = true;
this.do_onchange(field);
}
}
this.on_form_changed();
this.show_invalid = this.ready = true;
} else {
this.log("No record received");
}
this.on_form_changed();
this.show_invalid = this.ready = true;
this.do_update_pager(record.id == null);
this.do_update_sidebar();
if (this.default_focus_field) {
this.default_focus_field.focus();
}
},
on_form_changed: function(widget) {
if (widget && widget.node.attrs.on_change) {
this.do_onchange(widget);
} else {
for (var w in this.widgets) {
w = this.widgets[w];
w.process_attrs();
w.update_dom();
}
on_form_changed: function() {
for (var w in this.widgets) {
w = this.widgets[w];
w.process_attrs();
w.update_dom();
}
},
on_pager_action: function(action) {
@@ -157,6 +166,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
this.ready = false;
var onchange = _.trim(widget.node.attrs.on_change);
var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/);
console.log("Onchange triggered for field '%s' -> %s", widget.name, onchange);
if (call) {
var method = call[1], args = [];
var argument_replacement = {
@@ -195,12 +205,14 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
on_processed_onchange: function(response, processed) {
var result = response.result;
if (result.value) {
console.log(" |-> Onchange Response :", result.value);
for (var f in result.value) {
var field = this.fields[f];
if (field) {
var value = result.value[f];
processed.push(field.name);
if (field.get_value() != value) {
console.log(" |-> Onchange Action : change '%s' value from '%s' to '%s'", field.name, field.get_value(), value);
field.set_value(value);
if (_.indexOf(processed, field.name) < 0) {
this.do_onchange(field, processed);
@@ -252,18 +264,23 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
if (!this.ready) {
return false;
}
var invalid = false;
var values = {};
var invalid = false,
values = {},
first_invalid_field = null;
for (var f in this.fields) {
f = this.fields[f];
if (f.invalid) {
invalid = true;
f.update_dom();
if (!first_invalid_field) {
first_invalid_field = f;
}
} else if (f.touched) {
values[f.name] = f.get_value();
}
}
if (invalid) {
first_invalid_field.focus();
this.on_invalid();
return false;
} else {
@@ -360,12 +377,13 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
if (!this.datarecord.id) {
this.on_attachments_loaded([]);
} else {
this.rpc('/base/dataset/search_read', {
// TODO fme: modify this so it doesn't try to load attachments when there is not sidebar
/*this.rpc('/base/dataset/search_read', {
model: 'ir.attachment',
fields: ['name', 'url', 'type'],
domain: [['res_model', '=', this.dataset.model], ['res_id', '=', this.datarecord.id], ['type', 'in', ['binary', 'url']]],
context: this.dataset.context
}, this.on_attachments_loaded);
}, this.on_attachments_loaded);*/
}
},
on_attachments_loaded: function(attachments) {
@@ -553,7 +571,7 @@ openerp.base.form.WidgetFrame = openerp.base.form.Widget.extend({
var widget_type = node.attrs.widget || type.type || node.tag;
var widget = new (this.view.registry.get_object(widget_type)) (this.view, node);
if (node.tag == 'field') {
if (node.attrs.default_focus == '1') {
if (!this.view.default_focus_field || node.attrs.default_focus == '1') {
this.view.default_focus_field = widget;
}
if (node.attrs.nolabel != '1') {
@@ -718,7 +736,8 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
this.validate();
if (!this.invalid) {
this.set_value_from_ui();
this.view.on_form_changed(this);
this.view.do_onchange(this);
this.view.on_form_changed();
} else {
this.update_dom();
}
@@ -857,7 +876,7 @@ openerp.base.form.FieldDatetime = openerp.base.form.Field.extend({
}
},
validate: function() {
this.invalid = this.required && this.$element.find('input')[this.jqueryui_object]('getDate') === '';
this.invalid = this.required && !this.$element.find('input')[this.jqueryui_object]('getDate');
},
focus: function() {
this.$element.find('input').focus();
@@ -1074,6 +1093,7 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
this.value = null;
this.cm_id = _.uniqueId('m2o_cm_');
this.last_search = [];
this.tmp_value = undefined;
},
start: function() {
this._super();
@@ -1259,11 +1279,32 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
},
set_value_from_ui: function() {},
set_value: function(value) {
this._super(value);
this.original_value = value;
this._change_int_ext_value(value);
value = value || null;
var self = this;
var _super = this._super;
this.tmp_value = value;
var real_set_value = function(rval) {
this.tmp_value = undefined;
_super.apply(self, rval);
self.original_value = rval;
self._change_int_ext_value(rval);
};
if(typeof(value) === "number") {
var dataset = new openerp.base.DataSetStatic(this.session, this.field.relation, []);
dataset.call("name_get", [value], function(data) {
real_set_value(data.result[0]);
}).fail(function() {self.tmp_value = undefined;});
} else {
setTimeout(function() {real_set_value(value);}, 0);
}
},
get_value: function() {
if (this.tmp_value !== undefined) {
if (this.tmp_value instanceof Array) {
return this.tmp_value[0];
}
return this.tmp_value;
}
if (this.value === undefined)
throw "theorically unreachable state";
return this.value ? this.value[0] : false;
@@ -1276,23 +1317,29 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
}
});
/*
# Values: (0, 0, { fields }) create
# (1, ID, { fields }) update
# (2, ID) remove (delete)
# (3, ID) unlink one (target id or target of relation)
# (4, ID) link
# (5) unlink all (only valid for one2many)
*/
openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
init: function(view, node) {
this._super(view, node);
this.template = "FieldOne2Many";
this.is_started = $.Deferred();
this.is_setted = $.Deferred();
},
start: function() {
this._super.apply(this, arguments);
var self = this;
this.dataset = new openerp.base.DataSetStatic(this.session, this.field.relation);
this.dataset.on_unlink.add_last(function(ids) {
self.dataset.set_ids(_.without.apply(_, [self.dataset.ids].concat(ids)));
this.dataset = new openerp.base.BufferedDataSet(this.session, this.field.relation);
this.dataset.on_change.add_last(function() {
self.on_ui_change();
self.reload_current_view();
});
var modes = this.node.attrs.mode;
@@ -1328,14 +1375,6 @@ openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
self.is_started.resolve();
});
this.viewmanager.start();
$.when(this.is_started, this.is_setted).then(function() {
if (modes[0] == "tree") {
var view = self.viewmanager.views[self.viewmanager.active_view].controller;
view.reload_content();
}
// TODO niv: handle other types of views
});
},
reload_current_view: function() {
var self = this;
@@ -1343,18 +1382,61 @@ openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
if(self.viewmanager.active_view === "list") {
view.reload_content();
} else if (self.viewmanager.active_view === "form") {
// TODO niv: but fme did not implemented delete in form view anyway
// TODO niv: implement
}
},
set_value_from_ui: function() {},
set_value: function(value) {
if(value != false) {
this.dataset.set_ids(value);
this.is_setted.resolve();
value = value || [];
var self = this;
if(value.length >= 1 && value[0] instanceof Array) {
var ids = [];
_each(value, function(command) {
if(command[0] == 0) {
var obj = {id: _.uniqueId(self.dataset.virtual_id_prefix), values: command[2]};
self.dataset.to_create.push(obj);
self.dataset.cache.push(_.clone(obj));
ids.push(obj.id);
} else if(command[0] == 1) {
var obj = {id: command[1], values: command[2]};
self.dataset.to_write.push(obj);
self.dataset.cache.push(_.clone(obj));
ids.push(obj.id);
} else if(command[0] == 2) {
self.dataset.to_delete.push({id: command[1]});
} else if(command[0] == 4) {
ids.push(command[1]);
}
});
this._super(ids);
this.dataset.set_ids(ids);
} else {
this._super(value);
this.dataset.reset_ids(value);
}
$.when(this.is_started).then(function() {
self.reload_current_view();
});
},
get_value: function(value) {
//TODO niv
return [];
get_value: function() {
var self = this;
var val = _.map(this.dataset.ids, function(id) {
var alter_order = _.detect(self.dataset.to_create, function(x) {return x.id === id;});
if (alter_order) {
return [0, 0, alter_order.values];
}
alter_order = _.detect(self.dataset.to_write, function(x) {return x.id === id;});
if (alter_order) {
return [1, alter_order.id, alter_order.values];
}
return [4, id];
});
val = val.concat(_.map(this.dataset.to_delete, function(v, k) {return [2, x.id];}));
return val;
},
validate: function() {
this.invalid = false;
// TODO niv
}
});
@@ -1364,14 +1446,15 @@ openerp.base.form.One2ManyListView = openerp.base.ListView.extend({
var pop = new openerp.base.form.SelectCreatePopup(null, self.o2m.view.session);
pop.select_element(self.o2m.field.relation,{
initial_view: "form",
alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined
alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined,
auto_create: false
});
pop.on_select_elements.add(function(element_ids) {
var ids = self.o2m.dataset.ids;
_.each(element_ids, function(x) {if (!_.include(ids, x)) ids.push(x);});
self.o2m.dataset.set_ids(ids);
self.o2m.on_ui_change();
self.o2m.reload_current_view();
pop.on_create.add(function(data) {
self.o2m.dataset.create(data, function(r) {
self.o2m.dataset.set_ids(self.o2m.dataset.ids.concat([r.result]));
pop.stop();
self.o2m.reload_current_view();
});
});
}
});
@@ -1382,7 +1465,6 @@ openerp.base.form.FieldMany2Many = openerp.base.form.Field.extend({
this.template = "FieldMany2Many";
this.list_id = _.uniqueId("many2many");
this.is_started = $.Deferred();
this.is_setted = $.Deferred();
},
start: function() {
this._super.apply(this, arguments);
@@ -1392,8 +1474,7 @@ openerp.base.form.FieldMany2Many = openerp.base.form.Field.extend({
this.dataset = new openerp.base.DataSetStatic(
this.session, this.field.relation);
this.dataset.on_unlink.add_last(function(ids) {
self.list_view.reload_content();
//TODO niv: should check this for other cases
self.on_ui_change();
});
@@ -1406,15 +1487,18 @@ openerp.base.form.FieldMany2Many = openerp.base.form.Field.extend({
self.is_started.resolve();
});
this.list_view.start();
$.when(this.is_started, this.is_setted).then(function() {
self.list_view.reload_content();
});
},
set_value: function(value) {
if (value != false) {
this.dataset.set_ids(value);
this.is_setted.resolve();
value = value || [];
if (value.length >= 1 && value[0] instanceof Array) {
value = value[0][2];
}
this._super(value);
this.dataset.set_ids(value);
var self = this;
$.when(this.is_started).then(function() {
self.list_view.reload_content();
});
},
get_value: function() {
return [[6,false,this.dataset.ids]];
@@ -1459,12 +1543,13 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
* - initial_view: form or search (default search)
* - disable_multiple_selection
* - alternative_form_view
* - auto_create (default true)
*/
select_element: function(model, options, domain, context) {
this.model = model;
this.domain = domain || [];
this.context = context || {};
this.options = options || {};
this.options = _.defaults(options || {}, {"initial_view": "search", "auto_create": true});
this.initial_ids = this.options.initial_ids;
jQuery(this.render()).dialog({title: '',
modal: true,
@@ -1473,9 +1558,9 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
},
start: function() {
this._super();
this.dataset = new openerp.base.DataSetSearch(this.session, this.model,
this.dataset = new openerp.base.ReadOnlyDataSetSearch(this.session, this.model,
this.context, this.domain);
if ((this.options.initial_view || "search") == "search") {
if (this.options.initial_view == "search") {
this.setup_search_view();
} else { // "form"
this.new_object();
@@ -1514,7 +1599,7 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
$sbutton.click(function() {
self.on_select_elements(self.selected_ids);
});
self.view_list = new openerp.base.form.Many2XPopupListView( null, self.session,
self.view_list = new openerp.base.form.SelectCreateListView( null, self.session,
self.element_id + "_view_list", self.dataset, false,
{'deletable': false});
self.view_list.popup = self;
@@ -1525,6 +1610,15 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
});
this.searchview.start();
},
on_create: function(data) {
if (!this.options.auto_create)
return;
var self = this;
var wdataset = new openerp.base.DataSetSearch(this.session, this.model, this.context, this.domain);
wdataset.create(data, function(r) {
self.on_select_elements([r.result]);
});
},
on_select_elements: function(element_ids) {
},
on_click_element: function(ids) {
@@ -1562,17 +1656,12 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
self.stop();
});
});
this.view_form.on_created.add_last(function(r, success) {
if (r.result) {
var id = arguments[0].result;
self.on_select_elements([id]);
}
});
this.dataset.on_create.add(this.on_create);
this.view_form.do_show();
}
});
openerp.base.form.Many2XPopupListView = openerp.base.ListView.extend({
openerp.base.form.SelectCreateListView = openerp.base.ListView.extend({
do_add_record: function () {
this.popup.new_object();
},
+9 -6
View File
@@ -125,6 +125,15 @@ openerp.base.list.editable = function (openerp) {
'class': $(row).attr('class'),
click: function (e) {e.stopPropagation();}
})
.delegate('button.oe-edit-row-save', 'click', function () {
self.save_row();
})
.delegate('button.oe-edit-row-cancel', 'click', function () {
self.cancel_edition();
})
.delegate('button', 'keyup', function (e) {
e.stopImmediatePropagation();
})
.keyup(function (e) {
switch (e.which) {
case KEY_RETURN:
@@ -136,12 +145,6 @@ openerp.base.list.editable = function (openerp) {
default:
return;
}
})
.delegate('button.oe-edit-row-save', 'click', function () {
self.save_row();
})
.delegate('button.oe-edit-row-cancel', 'click', function () {
self.cancel_edition();
});
if (row) {
$new_row.replaceAll(row);
+2 -20
View File
@@ -336,25 +336,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
}
var self = this;
return $.when(this.dataset.unlink(ids)).then(function () {
_(self.rows).chain()
.map(function (row, index) {
return {
index: index,
id: row.data.id.value
};})
.filter(function (record) {
return _.contains(ids, record.id);
})
.sort(function (a, b) {
// sort in reverse index order, so we delete from the end
// and don't blow up the following indexes (leading to
// removing the wrong records from the visible list)
return b.index - a.index;
})
.each(function (record) {
self.rows.splice(record.index, 1);
});
// TODO only refresh modified rows
self.reload_content();
});
},
/**
@@ -895,7 +877,7 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
var d = new $.Deferred();
dataset.read_slice(
_.filter(_.pluck(this.columns, 'name'), _.identity),
_.filter(_.pluck(_.select(this.columns, function(x) {return x.tag == "field";}), 'name'), _.identity),
0, false,
function (records) {
var form_records = _(records).map(
+1
View File
@@ -377,6 +377,7 @@ openerp.base.search.FilterGroup = openerp.base.search.Widget.extend({
init: function (filters, view) {
this._super(view);
this.filters = filters;
this.length = filters.length;
},
start: function () {
this._super();
+58 -9
View File
@@ -113,7 +113,8 @@ openerp.base.ViewManager = openerp.base.Controller.extend({
* @returns {jQuery.Deferred} new view loading promise
*/
on_mode_switch: function(view_type) {
var view_promise;
var self = this,
view_promise;
this.active_view = view_type;
var view = this.views[view_type];
if (!view.controller) {
@@ -124,6 +125,16 @@ openerp.base.ViewManager = openerp.base.Controller.extend({
if (view.embedded_view) {
controller.set_embedded_view(view.embedded_view);
}
if (view_type === 'list' && this.flags.search_view === false && this.action && this.action['auto_search']) {
// In case the search view is not instanciated: manually call ListView#search
controller.on_loaded.add({
callback: function () {
controller.do_search([self.action.domain], [self.action.context], []);
},
position: 'last',
unique: true
});
}
view_promise = controller.start();
var self = this;
$.when(view_promise).then(function() {
@@ -132,6 +143,7 @@ openerp.base.ViewManager = openerp.base.Controller.extend({
this.views[view_type].controller = controller;
}
if (this.searchview) {
if (view.controller.searchable === false) {
this.searchview.hide();
@@ -261,16 +273,18 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
}
});
// init search view
var searchview_id = this.action.search_view_id && this.action.search_view_id[0];
if (this.flags.search_view !== false) {
// init search view
var searchview_id = this.action.search_view_id && this.action.search_view_id[0];
var searchview_loaded = this.setup_search_view(
searchview_id || false, search_defaults);
var searchview_loaded = this.setup_search_view(
searchview_id || false, search_defaults);
// schedule auto_search
if (searchview_loaded != null && this.action['auto_search']) {
$.when(searchview_loaded, inital_view_loaded)
.then(this.searchview.do_search);
// schedule auto_search
if (searchview_loaded != null && this.action['auto_search']) {
$.when(searchview_loaded, inital_view_loaded)
.then(this.searchview.do_search);
}
}
},
stop: function() {
@@ -455,6 +469,41 @@ openerp.base.ProcessView = openerp.base.Controller.extend({
openerp.base.HelpView = openerp.base.Controller.extend({
});
openerp.base.json_node_to_xml = function(node, single_quote, indent) {
// For debugging purpose, this function will convert a json node back to xml
// Maybe usefull for xml view editor
if (typeof(node.tag) !== 'string' || !node.children instanceof Array || !node.attrs instanceof Object) {
throw("Node a json node");
}
indent = indent || 0;
var sindent = Array(indent + 1).join('\t'),
r = sindent + '<' + node.tag;
for (var attr in node.attrs) {
var vattr = node.attrs[attr];
if (typeof(vattr) !== 'string') {
// domains, ...
vattr = JSON.stringify(vattr);
}
vattr = vattr.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
if (single_quote) {
vattr = vattr.replace(/&quot;/g, "'");
}
r += ' ' + attr + '="' + vattr + '"';
}
if (node.children.length) {
r += '>\n';
var childs = [];
for (var i = 0, ii = node.children.length; i < ii; i++) {
childs.push(openerp.base.json_node_to_xml(node.children[i], single_quote, indent + 1));
}
r += childs.join('\n');
r += '\n' + sindent + '</' + node.tag + '>';
return r;
} else {
return r + '/>';
}
}
};
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
+21 -6
View File
@@ -360,8 +360,14 @@
<h2 class="oe_view_title"><t t-esc="view.fields_view.arch.attrs.string"/></h2>
<div class="oe_form_header" t-att-id="view.element_id + '_header'">
<div class="oe_form_buttons" t-if="view.flags.action_buttons !== false">
<!--<button type="button" class="oe_form_button_save">Save</button>-->
<button type="button" class="oe_form_button_save_edit">Save &amp; Edit</button>
<!--<button type="button" class="oe_form_button_save">
<span class="oe_form_on_update">Save</span>
<span class="oe_form_on_create">Create</span>
</button>-->
<button type="button" class="oe_form_button_save_edit">
<span class="oe_form_on_update">Save &amp; Edit</span>
<span class="oe_form_on_create">Create &amp; Edit</span>
</button>
<!--<button type="button" class="oe_form_button_cancel">Cancel</button>-->
<button type="button" class="oe_form_button_new">New</button>
</div>
@@ -871,10 +877,19 @@
</div>
</t>
<t t-name="DialogWarning">
<p class="oe-dialog-warning">
<img src="/base/static/src/img/warning.png" class="oe-dialog-icon"/>
<t t-esc="error.data.fault_code.substr(18)"/>
</p>
<table cellspacing="0" cellpadding="0" border="0" class="oe-dialog-warning">
<tr>
<td><img src="/base/static/src/img/warning.png" class="oe-dialog-icon"/></td>
<td>
<p>
<t t-js="d">
d.html_error = context.engine.tools.html_escape(d.error.data.fault_code).replace(/\n/g, '<br/>');
</t>
<t t-raw="html_error"/>
</p>
</td>
</tr>
</table>
</t>
<t t-name="DialogTraceback">
<pre><t t-esc="error.message"/></pre>