[MERGE] from trunk

bzr revid: fva@openerp.com-20121005094140-q09ctke4nm7n2l4t
This commit is contained in:
Frédéric van der Essen
2012-10-05 11:41:40 +02:00
5 changed files with 158 additions and 94 deletions
+1 -1
View File
@@ -146,8 +146,8 @@ instance.web.Dialog = instance.web.Widget.extend({
this.$buttons = $('<div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" />');
this.$el.dialog("widget").append(this.$buttons);
}
var res = this.start();
this.dialog_inited = true;
var res = this.start();
return res;
},
close: function() {
+4 -3
View File
@@ -820,9 +820,10 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, {
* the action manager can be found amongst the ancestors of the current widget.
* If that's not the case this method will simply return `false`.
*/
do_action: function(action, on_finished) {
if (this.getParent()) {
return this.getParent().do_action(action, on_finished);
do_action: function() {
var parent = this.getParent();
if (parent) {
return parent.do_action.apply(parent, arguments);
}
return false;
},
+10 -8
View File
@@ -5,7 +5,15 @@ instance.web.DataExport = instance.web.Dialog.extend({
template: 'ExportTreeView',
dialog_title: {toString: function () { return _t("Export Data"); }},
init: function(parent, dataset) {
this._super(parent);
var self = this;
options = {
buttons : [
{text: _t("Close"), click: function() { self.close(); }},
{text: _t("Export To File"), click: function() { self.on_click_export_data(); }}
],
close: function(event, ui){ self.close();}
}
this._super(parent, options);
this.records = {};
this.dataset = dataset;
this.exports = new instance.web.DataSetSearch(
@@ -14,13 +22,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
start: function() {
var self = this;
this._super.apply(this, arguments);
this.open({
buttons : [
{text: _t("Close"), click: function() { self.close(); }},
{text: _t("Export To File"), click: function() { self.on_click_export_data(); }}
],
close: function(event, ui){ self.close();}
});
this.open();
self.$el.removeClass('ui-dialog-content ui-widget-content');
self.$el.find('#add_field').click(function() {
if ($('#field-tree-structure tr.ui-selected')) {
+122 -67
View File
@@ -30,7 +30,7 @@ instance.web.form.FieldManagerMixin = {
/**
* Must return the asked field as in fields_get.
*/
get_field: function(field_name) {},
get_field_desc: function(field_name) {},
/**
* Returns the current value of a field present in the view. See the get_value() method
* method in FieldInterface for further information.
@@ -44,6 +44,21 @@ instance.web.form.FieldManagerMixin = {
@return (Deferred) Is resolved after all the values are setted.
*/
set_values: function(values) {},
/**
Computes an OpenERP domain.
@param (list) expression An OpenERP domain.
@return (boolean) The computed value of the domain.
*/
compute_domain: function(expression) {},
/**
Builds an evaluation context for the resolution of the fields' contexts. Please note
the field are only supposed to use this context to evualuate their own, they should not
extend it.
@return (CompoundContext) An OpenERP context.
*/
build_eval_context: function() {},
};
instance.web.views.add('form', 'instance.web.FormView');
@@ -1085,7 +1100,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
field.on('focused', null, this.proxy('widgetFocused'))
.on('blurred', null, this.proxy('widgetBlurred'));
if (this.get_field(name).translate) {
if (this.get_field_desc(name).translate) {
this.translatable_fields.push(field);
}
field.on('changed_value', this, function() {
@@ -1103,12 +1118,34 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
}
});
},
get_field: function(field_name) {
get_field_desc: function(field_name) {
return this.fields_view.fields[field_name];
},
get_field_value: function(field_name) {
return this.fields[field_name].get_value();
},
compute_domain: function(expression) {
return instance.web.form.compute_domain(expression, this.fields);
},
_build_view_fields_values: function(blacklist) {
var a_dataset = this.dataset;
var fields_values = this.get_fields_values(blacklist);
var active_id = a_dataset.ids[a_dataset.index];
_.extend(fields_values, {
active_id: active_id || false,
active_ids: active_id ? [active_id] : [],
active_model: a_dataset.model,
parent: {}
});
if (a_dataset.parent_view) {
fields_values.parent = a_dataset.parent_view.get_fields_values([a_dataset.child_name]);
}
return fields_values;
},
build_eval_context: function(blacklist) {
var a_dataset = this.dataset;
return new instance.web.CompoundContext(a_dataset.get_context(), this._build_view_fields_values(blacklist));
},
});
/**
@@ -1528,6 +1565,48 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
},
});
/**
Welcome.
If you read this documentation, it probably means that you were asked to use a form view widget outside of
a form view. Before going further, you must understand that those fields were never really created for
that usage. Don't think that this class will hold the answer to all your problems, at best it will allow
you to hack the system with more style.
*/
instance.web.form.DefaultFieldManager = instance.web.Widget.extend({
init: function(parent, eval_context) {
this._super(parent);
this.field_descs = {};
this.eval_context = eval_context || {};
},
get_field_desc: function(field_name) {
if (this.field_descs[field_name] === undefined) {
this.field_descs[field_name] = {
string: field_name,
};
}
return this.field_descs[field_name];
},
extend_field_desc: function(fields) {
var self = this;
_.each(fields, function(v, k) {
_.extend(self.get_field_desc(k), v);
});
},
get_field_value: function(field_name) {
return false;
},
set_values: function(values) {
// nothing
},
compute_domain: function(expression) {
return instance.web.form.compute_domain(expression, {});
},
build_eval_context: function() {
return new instance.web.CompoundContext(this.eval_context);
},
});
instance.web.form.FormDialog = instance.web.Dialog.extend({
init: function(parent, options, view_id, dataset) {
this._super(parent, options);
@@ -1641,9 +1720,7 @@ instance.web.form.InvisibilityChangerMixin = {
this._ic_invisible_modifier = invisible_domain;
this._ic_field_manager.on("view_content_has_changed", this, function() {
var result = self._ic_invisible_modifier === undefined ? false :
instance.web.form.compute_domain(
self._ic_invisible_modifier,
self._ic_field_manager.fields);
self._ic_field_manager.compute_domain(self._ic_invisible_modifier);
self.set({"invisible": result});
});
this.set({invisible: this._ic_invisible_modifier === true, force_invisible: false});
@@ -1694,8 +1771,9 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi
*/
init: function(field_manager, node) {
this._super(field_manager);
this.view = field_manager;
this.field_manager = field_manager;
if (this.field_manager instanceof instance.web.FormView)
this.view = this.field_manager;
this.node = node;
this.modifiers = JSON.parse(this.node.attrs.modifiers || '{}');
instance.web.form.InvisibilityChangerMixin.init.call(this, this.field_manager, this.modifiers.invisible);
@@ -1737,12 +1815,11 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi
});
},
process_modifiers: function() {
var compute_domain = instance.web.form.compute_domain;
var to_set = {};
for (var a in this.modifiers) {
if (!this.modifiers.hasOwnProperty(a)) { continue; }
if (!_.include(["invisible"], a)) {
var val = compute_domain(this.modifiers[a], this.view.fields);
var val = this.field_manager.compute_domain(this.modifiers[a]);
to_set[a] = val;
}
}
@@ -1771,25 +1848,6 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi
}, options || {});
$(trigger).tipsy(options);
},
_build_view_fields_values: function(blacklist) {
var a_dataset = this.view.dataset;
var fields_values = this.view.get_fields_values(blacklist);
var active_id = a_dataset.ids[a_dataset.index];
_.extend(fields_values, {
active_id: active_id || false,
active_ids: active_id ? [active_id] : [],
active_model: a_dataset.model,
parent: {}
});
if (a_dataset.parent_view) {
fields_values.parent = a_dataset.parent_view.get_fields_values([a_dataset.child_name]);
}
return fields_values;
},
_build_eval_context: function(blacklist) {
var a_dataset = this.view.dataset;
return new instance.web.CompoundContext(a_dataset.get_context(), this._build_view_fields_values(blacklist));
},
/**
* Builds a new context usable for operations related to fields by merging
* the fields'context with the action's context.
@@ -1802,7 +1860,7 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi
}
if (v_context.__ref || true) { //TODO: remove true
var fields_values = this._build_eval_context(blacklist);
var fields_values = this.field_manager.build_eval_context(blacklist);
v_context = new instance.web.CompoundContext(v_context).set_eval_context(fields_values);
}
return v_context;
@@ -1813,7 +1871,7 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi
// if there is a domain on the node, overrides the model's domain
var final_domain = n_domain !== null ? n_domain : f_domain;
if (!(final_domain instanceof Array) || true) { //TODO: remove true
var fields_values = this._build_eval_context();
var fields_values = this.field_manager.build_eval_context();
final_domain = new instance.web.CompoundDomain(final_domain).set_eval_context(fields_values);
}
return final_domain;
@@ -2001,7 +2059,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
var self = this
this._super(field_manager, node);
this.name = this.node.attrs.name;
this.field = this.field_manager.get_field(this.name);
this.field = this.field_manager.get_field_desc(this.name);
this.widget = this.node.attrs.widget;
this.string = this.node.attrs.string || this.field.string || this.name;
this.options = JSON.parse(this.node.attrs.options || '{}');
@@ -2015,11 +2073,11 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
renderElement: function() {
var self = this;
this._super();
if (this.field.translate) {
if (this.field.translate && this.view) {
this.$el.addClass('oe_form_field_translatable');
this.$el.find('.oe_field_translate').click(this.on_translate);
}
this.$label = this.view.$el.find('label[for=' + this.id_for_label + ']');
this.$label = this.view ? this.view.$el.find('label[for=' + this.id_for_label + ']') : $();
if (instance.session.debug) {
this.do_attach_tooltip(this, this.$label[0] || this.$el);
this.$label.off('dblclick').on('dblclick', function() {
@@ -2884,7 +2942,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
self.focus();
return;
}
var pop = new instance.web.form.FormOpenPopup(self.view);
var pop = new instance.web.form.FormOpenPopup(self);
pop.show_element(
self.field.relation,
self.get("value"),
@@ -3479,7 +3537,7 @@ instance.web.form.One2ManyViewManager = instance.web.ViewManager.extend({
}
var self = this;
var id = self.o2m.dataset.index !== null ? self.o2m.dataset.ids[self.o2m.dataset.index] : null;
var pop = new instance.web.form.FormOpenPopup(self.o2m.view);
var pop = new instance.web.form.FormOpenPopup(this);
pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(), {
title: _t("Open: ") + self.o2m.string,
create_function: function(data) {
@@ -3595,7 +3653,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
},
do_activate_record: function(index, id) {
var self = this;
var pop = new instance.web.form.FormOpenPopup(self.o2m.view);
var pop = new instance.web.form.FormOpenPopup(self);
pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(), {
title: _t("Open: ") + self.o2m.string,
write_function: function(id, data) {
@@ -3623,7 +3681,10 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
var parent_form = this.o2m.view;
var self = this;
this.ensure_saved().pipe(function () {
return parent_form.do_save();
if (parent_form)
return parent_form.do_save();
else
return $.when();
}).then(function () {
self.handle_button(name, id, callback);
});
@@ -3879,7 +3940,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
},
render_value: function() {
var self = this;
var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.view.dataset.get_context());
var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context());
var values = self.get("value")
var handle_names = function(data) {
var indexed = {};
@@ -4149,7 +4210,7 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend(
});
} else {
var id = self.dataset.ids[self.dataset.index];
var pop = new instance.web.form.FormOpenPopup(self.view);
var pop = new instance.web.form.FormOpenPopup(this);
pop.show_element(self.field.relation, id, self.build_context(), {
title: _t("Open: ") + self.string,
write_function: function(id, data, options) {
@@ -4551,11 +4612,21 @@ instance.web.form.FieldReference = instance.web.form.AbstractField.extend(instan
},
initialize_content: function() {
var self = this;
this.selection = new instance.web.form.FieldSelection(this, { attrs: {
var fm = new instance.web.form.DefaultFieldManager(this);
fm.extend_field_desc({
"selection": {
selection: this.field_manager.get_field_desc(this.name).selection,
type: "selection",
},
"m2o": {
relation: null,
type: "many2one",
},
});
this.selection = new instance.web.form.FieldSelection(fm, { attrs: {
name: 'selection',
modifiers: JSON.stringify({readonly: this.get('effective_readonly')}),
}});
this.selection.view = this.view;
this.selection.on("change:value", this, this.on_selection_changed);
this.selection.setElement(this.$(".oe_form_view_reference_selection"));
this.selection.renderElement();
@@ -4564,11 +4635,10 @@ instance.web.form.FieldReference = instance.web.form.AbstractField.extend(instan
.on('focused', null, function () {self.trigger('focused')})
.on('blurred', null, function () {self.trigger('blurred')});
this.m2o = new instance.web.form.FieldMany2One(this, { attrs: {
this.m2o = new instance.web.form.FieldMany2One(fm, { attrs: {
name: 'm2o',
modifiers: JSON.stringify({readonly: this.get('effective_readonly')}),
}});
this.m2o.view = this.view;
this.m2o.on("change:value", this, this.data_changed);
this.m2o.setElement(this.$(".oe_form_view_reference_m2o"));
this.m2o.renderElement();
@@ -4608,20 +4678,6 @@ instance.web.form.FieldReference = instance.web.form.AbstractField.extend(instan
this.set({'value': false});
}
},
get_field: function(name) {
if (name === "selection") {
return {
selection: this.view.fields_view.fields[this.name].selection,
type: "selection",
};
} else if (name === "m2o") {
return {
relation: null,
type: "many2one",
};
}
throw Exception("Should not happen");
},
});
instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, {
@@ -4709,9 +4765,10 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance.
},
set_filename: function(value) {
var filename = this.node.attrs.filename;
if (this.view.fields[filename]) {
this.view.fields[filename].set_value(value);
this.view.fields[filename].on_ui_change();
if (filename) {
var tmp = {};
tmp[filename] = value;
this.field_manager.set_values(tmp);
}
},
on_clear: function() {
@@ -4753,7 +4810,9 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({
} else {
this.$el.find('a').show(!!this.get('value'));
if (this.get('value')) {
var show_value = _t("Download") + " " + (this.view.datarecord[this.node.attrs.filename] || '');
var show_value = _t("Download")
if (this.view)
show_value += " " + (this.view.datarecord[this.node.attrs.filename] || '');
this.$el.find('a').text(show_value);
}
}
@@ -4765,12 +4824,6 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({
this.$el.find('input').eq(0).val(show_value);
this.set_filename(name);
},
set_filename: function(value_) {
var filename = this.node.attrs.filename;
if (this.view.fields[filename]) {
this.view.fields[filename].set({value: value_});
}
},
on_clear: function() {
this._super.apply(this, arguments);
this.$el.find('input').eq(0).val('');
@@ -4819,10 +4872,12 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({
this.set({'value': file_base64});
this.binary_value = true;
this.render_value();
this.set_filename(name);
},
on_clear: function() {
this._super.apply(this, arguments);
this.render_value();
this.set_filename('');
}
});
+21 -15
View File
@@ -99,6 +99,10 @@ instance.web.ActionManager = instance.web.Widget.extend({
this.select_breadcrumb(index, subindex);
},
select_breadcrumb: function(index, subindex) {
var next_item = this.breadcrumbs[index + 1];
if (next_item && next_item.on_reverse_breadcrumb) {
next_item.on_reverse_breadcrumb(this.breadcrumbs[index].widget);
}
for (var i = this.breadcrumbs.length - 1; i >= 0; i--) {
if (i > index) {
if (this.remove_breadcrumb(i) === false) {
@@ -220,14 +224,14 @@ instance.web.ActionManager = instance.web.Widget.extend({
}
});
},
do_action: function(action, on_close, clear_breadcrumbs) {
do_action: function(action, on_close, clear_breadcrumbs, on_reverse_breadcrumb) {
if (_.isString(action) && instance.web.client_actions.contains(action)) {
var action_client = { type: "ir.actions.client", tag: action };
return this.do_action(action_client, on_close, clear_breadcrumbs);
return this.do_action(action_client, on_close, clear_breadcrumbs, on_reverse_breadcrumb);
} else if (_.isNumber(action) || _.isString(action)) {
var self = this;
return self.rpc("/web/action/load", { action_id: action }).pipe(function(result) {
return self.do_action(result.result, on_close, clear_breadcrumbs);
return self.do_action(result.result, on_close, clear_breadcrumbs, on_reverse_breadcrumb);
});
}
if (!action.type) {
@@ -249,7 +253,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
console.error("Action manager can't handle action of type " + action.type, action);
return $.Deferred().reject();
}
return this[type](action, on_close, clear_breadcrumbs);
return this[type](action, on_close, clear_breadcrumbs, on_reverse_breadcrumb);
},
null_action: function() {
this.dialog_stop();
@@ -300,24 +304,24 @@ instance.web.ActionManager = instance.web.Widget.extend({
return this.inner_widget.appendTo(this.$el);
}
},
ir_actions_act_window: function (action, on_close, clear_breadcrumbs) {
ir_actions_act_window: function (action, on_close, clear_breadcrumbs, on_reverse_breadcrumb) {
var self = this;
return this.ir_actions_common({
widget: function () { return new instance.web.ViewManagerAction(self, action); },
action: action,
klass: 'oe_act_window',
post_process: function (widget) { widget.add_breadcrumb(); }
}, on_close, clear_breadcrumbs);
post_process: function (widget) { widget.add_breadcrumb(on_reverse_breadcrumb); }
}, on_close, clear_breadcrumbs, on_reverse_breadcrumb);
},
ir_actions_client: function (action, on_close, clear_breadcrumbs) {
ir_actions_client: function (action, on_close, clear_breadcrumbs, on_reverse_breadcrumb) {
var self = this;
var ClientWidget = instance.web.client_actions.get_object(action.tag);
if (!(ClientWidget.prototype instanceof instance.web.Widget)) {
var next;
if (next = ClientWidget(this, action.params)) {
return this.do_action(next, on_close, clear_breadcrumbs);
return this.do_action(next, on_close, clear_breadcrumbs, on_reverse_breadcrumb);
}
return $.when();
}
@@ -329,13 +333,14 @@ instance.web.ActionManager = instance.web.Widget.extend({
post_process: function(widget) {
self.push_breadcrumb({
widget: widget,
title: action.name
title: action.name,
on_reverse_breadcrumb: on_reverse_breadcrumb,
});
if (action.tag !== 'reload') {
self.do_push_state({});
}
}
}, on_close, clear_breadcrumbs);
}, on_close, clear_breadcrumbs, on_reverse_breadcrumb);
},
ir_actions_act_window_close: function (action, on_closed) {
if (!this.dialog && on_closed) {
@@ -343,13 +348,13 @@ instance.web.ActionManager = instance.web.Widget.extend({
}
this.dialog_stop();
},
ir_actions_server: function (action, on_closed, clear_breadcrumbs) {
ir_actions_server: function (action, on_closed, clear_breadcrumbs, on_reverse_breadcrumb) {
var self = this;
this.rpc('/web/action/run', {
action_id: action.id,
context: action.context || {}
}).then(function (action) {
self.do_action(action, on_closed, clear_breadcrumbs)
self.do_action(action, on_closed, clear_breadcrumbs, on_reverse_breadcrumb)
});
},
ir_actions_report_xml: function(action, on_closed) {
@@ -544,7 +549,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
set_title: function(title) {
this.$el.find('.oe_view_title_text:first').text(title);
},
add_breadcrumb: function() {
add_breadcrumb: function(on_reverse_breadcrumb) {
var self = this;
var views = [this.active_view || this.views_src[0].view_type];
this.on_mode_switch.add(function(mode) {
@@ -589,7 +594,8 @@ instance.web.ViewManager = instance.web.Widget.extend({
titles.pop();
}
return titles;
}
},
on_reverse_breadcrumb: on_reverse_breadcrumb,
});
},
/**