"};
+ var root_object = this.check_attr(root,tag,0);
+ obj.child_id = this.xml_node_create(arch, tag, [], this.xml_id-1, [root_object], [])
+ return [obj];
+ },
+ get_data: function() {
+ var self = this;
+ var view_arch_list = [];
+ self.main_view_id =((this.view_edit_dialog.$element.find("input[name='radiogroup']:checked").parent()).parent()).attr('data-id');
+ var ve_dataset = new openerp.web.DataSet(this, 'ir.ui.view');
+ ve_dataset.read_ids([parseInt(self.main_view_id)], ['arch', 'type'], function (arch) {
+ one_object = self.parse_xml(arch[0].arch,self.main_view_id);
+ self.main_view_type = arch[0].type
+ view_arch_list.push({"view_id" : self.main_view_id, "arch" : arch[0].arch});
+ dataset = new openerp.web.DataSetSearch(self, 'ir.ui.view', null, null);
+ dataset.read_slice([], {domain : [['inherit_id','=', parseInt(self.main_view_id)]]}, function (result) {
+ _.each(result, function(res) {
+ view_arch_list.push({"view_id":res.id,"arch":res.arch});
+ self.inherit_view(one_object, res);
+ });
+ return self.edit_view({"main_object": one_object,
+ "parent_child_id": self.parent_child_list(one_object, []),
+ "arch": view_arch_list});
+ });
+ });
+ },
+ parent_child_list : function(one_object, p_list) {
+ var self = this;
+ _.each(one_object , function(element){
+ if(element.child_id.length != 0){
+ p_list.push({"key":element.id,"value":_.pluck(element.child_id, 'id')});
+ self.parent_child_list(element.child_id, p_list);
+ }
+ });
+ return p_list;
+ },
+ inherit_view : function(one_object, result) {
+ var self = this;
+ var root = $(result.arch).filter('*');
+ var xml_list = [];
+ if (root[0].tagName.toLowerCase() == "data") {
+ xml_list = $(root[0]).children();
+ } else {
+ xml_list.push(root[0]);
+ }
+ _.each(xml_list , function(xml){
+ var parent_id;
+ var check_list = [];
+ var xpath_object = self.parse_xml(xml,result.id);
+ if (xml.tagName.toLowerCase() == "xpath" ) {
+ var part_expr = _.without($(xml).attr('expr').split("/"),"");
+ _.each(part_expr,function(part){
+ check_list.push(_.without($.trim(part.replace(/[^a-zA-Z 0-9 _]+/g,'!')).split("!"),""));
+ });
+ } else {
+ var temp = [];
+ _.each(xpath_object[0].child_id[0].att_list, function(list){
+ if(!_.include(list, "position")){
+ temp.push(list);
+ }
+ });
+ check_list = [_.flatten(temp)];
+ }
+ self.full_path_search(check_list ,one_object ,xpath_object);
+ });
+ },
+ full_path_search: function(check_list ,val ,xpath_object) {
+ var self = this;
+ if(xpath_object.length!=0){
+ var check = check_list[0];
+ var obj;
+ switch (check.length) {
+ case 2:
+ if(parseInt(check[1])){
+ var list_1 = _.select(val,function(element){
+ var main_list = _.flatten(element.att_list);
+ return _.include(main_list, check[0]);
+ });
+ obj = val[_.indexOf(val,list_1[parseInt(check[1])-1])];
+ } else {
+ obj = _.detect(val, function(element){
+ var main_list = _.flatten(element.att_list);
+ return _.include(main_list, check[0]);
+ });
+ }
+ break;
+ case 3:
+ obj = _.detect(val,function(element){
+ var main_list = _.flatten(element.att_list);
+ check = _.uniq(check);
+ var insert = _.intersection(main_list,check);
+ if(insert.length == check.length ){return element;}
+ });
+ break;
+ case 1:
+ var list_1 = _.select(val,function(element){
+ var main_list = _.flatten(element.att_list);
+ return _.include(main_list, check[0]);
+ });
+ if(list_1.length != 0){
+ (check_list.length == 1)? obj = list_1[0] : check_list.shift();
+ }
+ break;
+ }
+ if(obj) {
+ check_list.shift();
+ if (check_list.length !=0){
+ self.full_path_search(check_list ,obj.child_id ,xpath_object);
+ } else {
+ var level = obj.level+1;
+ self.increase_level(xpath_object[0], level)
+ obj.child_id.push(xpath_object[0]);
+ xpath_object.pop();
+ return;
+ }
+ }
+ else {
+ _.each(val,function(element){
+ self.full_path_search(check_list ,element.child_id ,xpath_object);
+ });
+ }
+ }
+ },
+ increase_level: function(val, level) {
+ var self = this;
+ val.level = level;
+ _.each(val.child_id, function(val, key) {
+ self.increase_level(val, level + 1);
+ });
+ },
+ edit_view: function(one_object) {
+ var self = this;
+ this.edit_xml_dialog = new openerp.web.Dialog(this,{
+ modal: true,
+ title: 'View Editor',
+ width: 750,
+ height: 500,
+ buttons: {
+ "Inherited View": function(){
+ //todo
+ },
+ "Preview": function(){
+ var action = {
+ context:self.session.user_context,
+ res_model : self.model,
+ views : [[self.main_view_id, self.main_view_type]],
+ type: 'ir.actions.act_window',
+ target: "new",
+ flags: {
+ sidebar: false,
+ views_switcher: false,
+ action_buttons:false,
+ search_view:false,
+ pager:false,
+ },
+ };
+ var action_manager = new openerp.web.ActionManager(self);
+ action_manager.do_action(action);
+ },
+ "Close": function(){
+ self.edit_xml_dialog.close();
+ }
+ }
+ });
+ this.edit_xml_dialog.start().open();
+ this.edit_xml_dialog.$element.html(QWeb.render('view_editor', {
+ 'data': one_object['main_object'],
+ }));
+ this.edit_xml_dialog.$element.find("tr[id^='viewedit-']").click(function() {
+ self.edit_xml_dialog.$element.find("tr[id^='viewedit-']").removeClass('ui-selected');
+ $(this).addClass('ui-selected');
+ });
+ this.edit_xml_dialog.$element.find("img[id^='parentimg-']").click(function() {
+ if ($(this).attr('src') == '/web/static/src/img/collapse.gif') {
+ $(this).attr('src', '/web/static/src/img/expand.gif');
+ self.on_expand(this);
+ } else {
+ $(this).attr('src', '/web/static/src/img/collapse.gif');
+ var id = this.id.split('-')[1];
+ self.on_collapse(this,one_object['parent_child_id'], one_object['main_object']);
+ }
+ });
+ this.edit_xml_dialog.$element.find("img[id^='side-']").click(function() {
+ var side = $(this).closest("tr[id^='viewedit-']")
+ var id_tr = (side.attr('id')).split('-')[1];
+ var img = side.find("img[id='parentimg-"+id_tr+"']").attr('src'); ;
+ var level = parseInt(side.attr('level'));
+ var list_shift =[];
+ var last_tr;
+ var cur_tr = side;
+ list_shift.push(side);
+ var next_tr;
+ var ls = side;
+ var view_id;
+ var view_xml_id;
+ while(1){
+ ls = ls.prev();
+ if((self.edit_xml_dialog.$element.find(ls).find('a').text()).search("view_id") != -1
+ && parseInt(ls.attr('level')) < level){
+ view_id = parseInt(($(ls).find('a').text()).replace(/[^0-9]+/g,''));
+ view_xml_id = (ls.attr('id')).split('-')[1];
+ break;
+ }
+ }
+ switch (this.id) {
+ case "side-add":
+ break;
+ case "side-remove":
+ break;
+ case "side-edit":
+ break;
+ case "side-up":
+ while (1) {
+ var prev_tr = cur_tr.prev();
+ if(level >= parseInt(prev_tr.attr('level')) || prev_tr.length == 0) {
+ last_tr = prev_tr;
+ break;
+ }
+ cur_tr = prev_tr;
+ }
+ if (img) {
+ while (1) {
+ next_tr = side.next();
+ if ( parseInt(next_tr.attr('level')) <= level || next_tr.length == 0) {
+ break;
+ } else {
+ list_shift.push(next_tr);
+ side = next_tr;
+ }
+ }
+ }
+ if (last_tr.length != 0 && parseInt(last_tr.attr('level')) == level &&
+ (self.edit_xml_dialog.$element.find(last_tr).find('a').text()).search("view_id") == -1) {
+ _.each(list_shift, function(rec) {
+ $(last_tr).before(rec);
+ });
+ self.save_move_arch(one_object, view_id, view_xml_id, id_tr, level, "up");
+ }
+ break;
+ case "side-down":
+ if (img) {
+ while (1) {
+ next_tr = cur_tr.next();
+ if ( parseInt(next_tr.attr('level')) <= level || next_tr.length == 0) {
+ last_tr = next_tr;
+ break;
+ } else {
+ list_shift.push(next_tr);
+ cur_tr = next_tr;
+ }
+ }
+ }
+ else {
+ last_tr = cur_tr.next();
+ }
+ if((self.edit_xml_dialog.$element.find(last_tr).find('a').text()).search("view_id") != -1){
+ return;
+ }
+ if (last_tr.length != 0 && parseInt(last_tr.attr('level')) == level) {
+ var last_tr_id = (last_tr.attr('id')).split('-')[1];
+ img = last_tr.find("img[id='parentimg-" + last_tr_id + "']").attr('src');
+ if (img) {
+ self.edit_xml_dialog.$element.find("img[id='parentimg-" + last_tr_id + "']").
+ attr('src', '/web/static/src/img/expand.gif');
+ while (1) {
+ var next_tr = last_tr.next();
+ if (next_tr.attr('level') <= level || next_tr.length == 0) break;
+ next_tr.hide();
+ last_tr = next_tr;
+ }
+ }
+ list_shift.reverse();
+ _.each(list_shift, function(rec) {
+ $(last_tr).after(rec);
+ });
+ self.save_move_arch(one_object, view_id, view_xml_id, id_tr, level, "down");
+ }
+ break;
+ }
+ });
+ },
+ save_move_arch: function(one_object, view_id, view_xml_id, id_tr, level, move_direct){
+ var self = this;
+ var arch = _.detect(one_object['arch'],function(element){
+ return element.view_id == view_id;
+ });
+ var obj = self.get_view_object(view_xml_id, one_object['main_object'], []);
+ if(($(arch.arch).filter("data")).length != 0 && view_xml_id != 0){
+ var check_list = _.flatten(obj[0].child_id[0].att_list);
+ arch.arch = _.detect($(arch.arch).children(), function(xml_child){
+ var temp_obj = self.check_attr(xml_child, xml_child.tagName.toLowerCase());
+ var main_list = _.flatten(temp_obj.att_list);
+ check_list = _.uniq(check_list);
+ var insert = _.intersection(main_list,check_list);
+ if(insert.length == check_list.length ){return xml_child;}
+ });
+ }
+ return self.get_node(arch.arch, obj[0].child_id[0], parseInt(id_tr), [], parseInt(level),
+ parseInt(view_id), arch, move_direct);
+ },
+
+ get_view_object: function(view_xml_id, one_object,result){
+ var self = this;
+ if(result.length==0){
+ var check = _.detect(one_object , function(obj){
+ return view_xml_id==obj.id;
+ });
+ if(check){result.push(check);};
+ _.each(one_object, function(obj){
+ self.get_view_object(view_xml_id, obj.child_id, result);
+ });
+ }
+ return result;
+ },
+ get_node: function(arch1, obj, id, child_list, level, view_id, arch, move_direct){
+ var self = this;
+ var children_list = $(arch1).children();
+ var list_obj_xml = _.zip(children_list,obj.child_id);
+ if (id) {
+ if (obj.id == id) {
+ var id;
+ var parent = $(arch1).parents();
+ var index = _.indexOf(child_list, obj)
+ var re_insert_obj = child_list.splice(index, 1);
+ if (move_direct == "down") {
+ var next = $(arch1).next();
+ $(next).after(arch1);
+ child_list.splice(index+1, 0, re_insert_obj[0]);
+ } else {
+ var prev = $(arch1).prev();
+ $(prev).before(arch1);
+ child_list.splice(index-1, 0, re_insert_obj[0]);
+ }
+ parent = parent[parent.length-1];
+ var convert_to_utf = self.xml2Str(parent);
+ if (convert_to_utf) {
+ convert_to_utf = convert_to_utf.replace('xmlns="http://www.w3.org/1999/xhtml"', "");
+ convert_to_utf = '' + convert_to_utf;
+ arch.arch = convert_to_utf;
+ dataset = new openerp.web.DataSet(this, 'ir.ui.view');
+ dataset.write(parseInt(view_id),{"arch":convert_to_utf}, function(r) {
+ });
+ }
+ }
+ if (obj.level <= level) {
+ _.each(list_obj_xml, function(child_node) {
+ self.get_node(child_node[0], child_node[1], id, obj.child_id, level, view_id, arch, move_direct);
+ });
+ }
+ }
+ },
+ xml2Str: function(xmlNode) {
+ try {
+ return (new XMLSerializer()).serializeToString(xmlNode);
+ }
+ catch (e) {
+ try {
+ return xmlNode.xml;
+ }
+ catch (e) {
+ return false;
+ }
+ }
+
+ },
+ on_expand: function(expand_img){
+ var level = parseInt($(expand_img).closest("tr[id^='viewedit-']").attr('level'));
+ var cur_tr = $(expand_img).closest("tr[id^='viewedit-']");
+ while (1) {
+ var nxt_tr = cur_tr.next();
+ if (parseInt(nxt_tr.attr('level')) > level){
+ cur_tr = nxt_tr;
+ nxt_tr.hide();
+ } else return nxt_tr;
+ }
+ },
+ on_collapse: function(collapse_img, parent_child_id, id, main_object) {
+ var self = this;
+ var id = collapse_img.id.split('-')[1];
+ var datas = _.detect(parent_child_id,function(res) {
+ return res.key == id;
+ });
+ _.each(datas.value, function(rec) {
+ var tr = self.edit_xml_dialog.$element.find("tr[id='viewedit-"+rec+"']");
+ tr.find("img[id='parentimg-"+rec+"']").attr('src','/web/static/src/img/expand.gif');
+ tr.show();
+ });
+ }
+
+});
+};
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 2946df7166c..603e2abb008 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -10,6 +10,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
* view should be displayed (if there is one active).
*/
searchable: false,
+ readonly : false,
form_template: "FormView",
identifier_prefix: 'formview-',
/**
@@ -37,7 +38,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.dirty_for_user = false;
this.default_focus_field = null;
this.default_focus_button = null;
- this.registry = openerp.web.form.widgets;
+ this.registry = this.readonly ? openerp.web.form.readonly : openerp.web.form.widgets;
this.has_been_loaded = $.Deferred();
this.$form_header = null;
this.translatable_fields = [];
@@ -89,7 +90,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.fields_view = data;
var frame = new (this.registry.get_object('frame'))(this, this.fields_view.arch);
- this.rendered = QWeb.render(this.form_template, { 'frame': frame, 'view': this });
+ this.rendered = QWeb.render(this.form_template, { 'frame': frame, 'widget': this });
}
this.$element.html(this.rendered);
_.each(this.widgets, function(w) {
@@ -101,21 +102,11 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
self.on_pager_action(action);
});
- this.$form_header.find('button.oe_form_button_save').click(this.do_save);
- this.$form_header.find('button.oe_form_button_cancel').click(this.do_cancel);
+ this.$form_header.find('button.oe_form_button_save').click(this.do_save_then_readonly);
this.$form_header.find('button.oe_form_button_new').click(this.on_button_new);
this.$form_header.find('button.oe_form_button_duplicate').click(this.on_button_duplicate);
- this.$form_header.find('button.oe_form_button_toggle').click(function () {
- self.translatable_fields = [];
- self.widgets = {};
- self.fields = {};
- self.$form_header.find('button').unbind('click');
- self.registry = self.registry === openerp.web.form.widgets
- ? openerp.web.form.readonly
- : openerp.web.form.widgets;
- self.on_loaded(self.fields_view);
- self.reload();
- });
+ this.$form_header.find('button.oe_form_button_delete').click(this.on_button_delete);
+ this.$form_header.find('button.oe_form_button_toggle').click(this.on_toggle_readonly);
if (this.options.sidebar && this.options.sidebar_id) {
this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
@@ -127,6 +118,23 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
this.has_been_loaded.resolve();
},
+ on_toggle_readonly: function() {
+ var self = this;
+ self.translatable_fields = [];
+ self.widgets = {};
+ self.fields = {};
+ self.$form_header.find('button').unbind('click');
+ self.readonly = !self.readonly;
+ self.registry = self.readonly ? openerp.web.form.readonly : openerp.web.form.widgets;
+ self.on_loaded(self.fields_view);
+ return self.reload();
+ },
+ do_set_readonly: function() {
+ return this.readonly ? $.Deferred().resolve() : this.on_toggle_readonly();
+ },
+ do_set_editable: function() {
+ return !this.readonly ? $.Deferred().resolve() : this.on_toggle_readonly();
+ },
do_show: function () {
var promise;
if (this.dataset.index === null) {
@@ -162,6 +170,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.$form_header.find('.oe_form_on_update').show();
this.$form_header.find('button.oe_form_button_new').show();
}
+ this.$form_header.find('.oe_form_on_readonly').toggle(this.readonly);
+ this.$form_header.find('.oe_form_on_editable').toggle(!this.readonly);
this.dirty_for_user = false;
this.datarecord = record;
for (var f in this.fields) {
@@ -342,14 +352,16 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
$.when(this.has_been_loaded).then(function() {
if (self.can_be_discarded()) {
var keys = _.keys(self.fields_view.fields);
- if (keys.length) {
- self.dataset.default_get(keys).then(self.on_record_loaded).then(function() {
+ $.when(self.do_set_editable()).then(function() {
+ if (keys.length) {
+ self.dataset.default_get(keys).then(self.on_record_loaded).then(function() {
+ def.resolve();
+ });
+ } else {
+ self.on_record_loaded({});
def.resolve();
- });
- } else {
- self.on_record_loaded({});
- def.resolve();
- }
+ }
+ });
}
});
return def.promise();
@@ -361,7 +373,20 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
if (self.can_be_discarded()) {
self.dataset.call('copy', [self.datarecord.id, {}, self.dataset.context]).then(function(new_id) {
return self.on_created({ result : new_id });
- }).then(function() {
+ }).then(self.do_set_editable).then(function() {
+ def.resolve();
+ });
+ }
+ });
+ return def.promise();
+ },
+ on_button_delete: function() {
+ var self = this;
+ var def = $.Deferred();
+ $.when(this.has_been_loaded).then(function() {
+ if (self.can_be_discarded() && self.datarecord.id) {
+ self.dataset.unlink([self.datarecord.id]).then(function() {
+ self.on_pager_action('next');
def.resolve();
});
}
@@ -379,6 +404,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
* @param {Function} success callback on save success
* @param {Boolean} [prepend_on_create=false] if ``do_save`` creates a new record, should that record be inserted at the start of the dataset (by default, records are added at the end)
*/
+ do_save_then_readonly: function(success, prepend_on_create) {
+ return this.do_save(success, prepend_on_create).then(this.do_set_readonly);
+ },
do_save: function(success, prepend_on_create) {
var self = this;
var action = function() {
@@ -426,10 +454,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.mutating_lock = this.mutating_lock.pipe(action, action);
return this.mutating_lock;
},
- switch_readonly: function() {
- },
- switch_editable: function() {
- },
on_invalid: function() {
var msg = "";
_.each(this.fields, function(f) {
@@ -487,9 +511,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
on_action: function (action) {
console.debug('Executing action', action);
},
- do_cancel: function () {
- console.debug("Cancelling form");
- },
reload: function() {
var self = this;
var act = function() {
@@ -715,6 +736,16 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.
this.invisible = this.modifiers['invisible'] === true;
this.classname = 'oe_form_' + this.type;
+ this.align = parseFloat(this.node.attrs.align);
+ if (isNaN(this.align) || this.align === 1) {
+ this.align = 'right';
+ } else if (this.align === 0) {
+ this.align = 'left';
+ } else {
+ this.align = 'center';
+ }
+
+
this.width = this.node.attrs.width;
},
start: function() {
@@ -1044,8 +1075,7 @@ openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({
this._super(view, node);
- // TODO fme: support for attrs.align
- if (this.node.tag == 'label' && (this.node.attrs.colspan || (this.string && this.string.length > 32))) {
+ if (this.node.tag == 'label' && (this.align === 'left' || this.node.attrs.colspan || (this.string && this.string.length > 32))) {
this.template = "WidgetParagraph";
this.colspan = parseInt(this.node.attrs.colspan || 1, 10);
} else {
@@ -1170,6 +1200,10 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
openerp.web.form.FieldChar = openerp.web.form.Field.extend({
template: 'FieldChar',
+ init: function (view, node) {
+ this._super(view, node);
+ this.password = this.node.attrs.password === 'True' || this.node.attrs.password === '1';
+ },
start: function() {
this._super.apply(this, arguments);
this.$element.find('input').change(this.on_ui_change);
@@ -1419,11 +1453,7 @@ openerp.web.form.FieldBoolean = openerp.web.form.Field.extend({
start: function() {
var self = this;
this._super.apply(this, arguments);
- this.$element.find('input').click(function() {
- if ($(this).is(':checked') != self.value) {
- self.on_ui_change();
- }
- });
+ this.$element.find('input').click(self.on_ui_change);
},
set_value: function(value) {
this._super.apply(this, arguments);
@@ -1632,6 +1662,11 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
} else {
$("#" + self.cm_id + " .oe_m2o_menu_item_mandatory").addClass("oe-m2o-disabled-cm");
}
+ if (!self.readonly) {
+ $("#" + self.cm_id + " .oe_m2o_menu_item_noreadonly").removeClass("oe-m2o-disabled-cm");
+ } else {
+ $("#" + self.cm_id + " .oe_m2o_menu_item_noreadonly").addClass("oe-m2o-disabled-cm");
+ }
return true;
}, menuStyle: {width: "200px"}
});
@@ -1651,6 +1686,8 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
}
});
this.$drop_down.click(function() {
+ if (self.readonly)
+ return;
if (self.$input.autocomplete("widget").is(":visible")) {
self.$input.autocomplete("close");
} else {
@@ -1811,7 +1848,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
self.original_value = undefined;
self._change_int_ext_value(rval);
};
- if(typeof(value) === "number") {
+ if (value && !(value instanceof Array)) {
var dataset = new openerp.web.DataSetStatic(this, this.field.relation, self.build_context());
dataset.name_get([value], function(data) {
real_set_value(data[0]);
@@ -1857,6 +1894,10 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
},
focus: function () {
this.$input.focus();
+ },
+ update_dom: function() {
+ this._super.apply(this, arguments);
+ this.$input.attr('disabled', this.readonly);
}
});
@@ -1910,7 +1951,8 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
multi_selection: false,
init: function(view, node) {
this._super(view, node);
- this.is_started = $.Deferred();
+ this.is_loaded = $.Deferred();
+ this.initial_is_loaded = this.is_loaded;
this.is_setted = $.Deferred();
this.form_last_update = $.Deferred();
this.init_form_last_update = this.form_last_update;
@@ -1928,8 +1970,18 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
self.on_ui_change();
});
+ this.is_setted.then(function() {
+ self.load_views();
+ });
+ },
+ is_readonly: function() {
+ return this.readonly || this.force_readonly;
+ },
+ load_views: function() {
+ var self = this;
+
var modes = this.node.attrs.mode;
- modes = !!modes ? modes.split(",") : ["tree", "form"];
+ modes = !!modes ? modes.split(",") : ["tree"];
var views = [];
_.each(modes, function(mode) {
var view = {
@@ -1942,25 +1994,38 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
}
if(view.view_type === "list") {
view.options.selectable = self.multi_selection;
+ if (self.is_readonly()) {
+ view.options.addable = null;
+ view.options.deletable = null;
+ }
} else if (view.view_type === "form") {
view.options.not_interactible_on_create = true;
}
views.push(view);
});
this.views = views;
-
+
this.viewmanager = new openerp.web.ViewManager(this, this.dataset, views);
this.viewmanager.registry = openerp.web.views.clone({
list: 'openerp.web.form.One2ManyListView',
- form: 'openerp.web.form.One2ManyFormView'
+ form: 'openerp.web.FormView'
});
var once = $.Deferred().then(function() {
self.init_form_last_update.resolve();
});
+ var def = $.Deferred().then(function() {
+ self.initial_is_loaded.resolve();
+ });
this.viewmanager.on_controller_inited.add_last(function(view_type, controller) {
if (view_type == "list") {
controller.o2m = self;
+ if (self.is_readonly())
+ controller.set_editable(false);
} else if (view_type == "form") {
+ if (self.is_readonly()) {
+ controller.on_toggle_readonly();
+ $(controller.$element.find(".oe_form_buttons")[0]).children().remove();
+ }
controller.on_record_loaded.add_last(function() {
once.resolve();
});
@@ -1971,33 +2036,40 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
} else if (view_type == "graph") {
self.reload_current_view()
}
- self.is_started.resolve();
+ def.resolve();
});
- this.viewmanager.on_mode_switch.add_first(function() {
- self.save_form_view();
+ this.viewmanager.on_mode_switch.add_first(function(n_mode, b, c, d, e) {
+ $.when(self.save_form_view()).then(function() {
+ if(n_mode === "list")
+ setTimeout(function() {self.reload_current_view();}, 0);
+ });
});
this.is_setted.then(function() {
setTimeout(function () {
self.viewmanager.appendTo(self.$element);
}, 0);
});
+ return def;
},
reload_current_view: function() {
var self = this;
- var view = self.viewmanager.views[self.viewmanager.active_view].controller;
- if(self.viewmanager.active_view === "list") {
- view.reload_content();
- } else if (self.viewmanager.active_view === "form") {
- if (this.dataset.index === null && this.dataset.ids.length >= 1) {
- this.dataset.index = 0;
+ self.is_loaded = self.is_loaded.pipe(function() {
+ var view = self.viewmanager.views[self.viewmanager.active_view].controller;
+ if(self.viewmanager.active_view === "list") {
+ return view.reload_content();
+ } else if (self.viewmanager.active_view === "form") {
+ if (self.dataset.index === null && self.dataset.ids.length >= 1) {
+ self.dataset.index = 0;
+ }
+ var act = function() {
+ return view.do_show();
+ }
+ self.form_last_update = self.form_last_update.pipe(act, act);
+ return self.form_last_update;
+ } else if (self.viewmanager.active_view === "graph") {
+ return view.do_search(self.build_domain(), self.dataset.get_context(), []);
}
- var act = function() {
- return view.do_show();
- }
- this.form_last_update = this.form_last_update.pipe(act, act);;
- } else if (self.viewmanager.active_view === "graph") {
- view.do_search(this.build_domain(), this.dataset.get_context(), []);
- }
+ });
},
set_value: function(value) {
value = value || [];
@@ -2054,9 +2126,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
if (this.dataset.index === null && this.dataset.ids.length > 0) {
this.dataset.index = 0;
}
- $.when(this.is_started).then(function() {
- self.reload_current_view();
- });
+ self.reload_current_view();
this.is_setted.resolve();
},
get_value: function() {
@@ -2120,7 +2190,18 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
},
update_dom: function() {
this._super.apply(this, arguments);
- this.$element.toggleClass('disabled', this.readonly);
+ var self = this;
+ if (this.previous_readonly !== this.readonly) {
+ this.previous_readonly = this.readonly;
+ if (this.viewmanager) {
+ this.is_loaded = this.is_loaded.pipe(function() {
+ self.viewmanager.stop();
+ return $.when(self.load_views()).then(function() {
+ self.reload_current_view();
+ });
+ });
+ }
+ }
}
});
@@ -2131,9 +2212,6 @@ openerp.web.form.One2ManyDataSet = openerp.web.BufferedDataSet.extend({
}
});
-openerp.web.form.One2ManyFormView = openerp.web.FormView.extend({
-});
-
openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
do_add_record: function () {
if (this.options.editable) {
@@ -2172,7 +2250,8 @@ openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
read_function: function() {
return self.o2m.dataset.read_ids.apply(self.o2m.dataset, arguments);
},
- form_view_options: {'not_interactible_on_create':true}
+ form_view_options: {'not_interactible_on_create':true},
+ readonly: self.o2m.is_readonly()
});
pop.on_write.add(function(id, data) {
self.o2m.dataset.write(id, data, {}, function(r) {
@@ -2188,7 +2267,9 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
init: function(view, node) {
this._super(view, node);
this.list_id = _.uniqueId("many2many");
- this.is_started = $.Deferred();
+ this.is_loaded = $.Deferred();
+ this.initial_is_loaded = this.is_loaded;
+ this.is_setted = $.Deferred();
},
start: function() {
this._super.apply(this, arguments);
@@ -2200,18 +2281,10 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
this.dataset.on_unlink.add_last(function(ids) {
self.on_ui_change();
});
-
- this.list_view = new openerp.web.form.Many2ManyListView(this, this.dataset, false, {
- 'addable': 'Add',
- 'selectable': self.multi_selection
- });
- this.list_view.m2m_field = this;
- this.list_view.on_loaded.add_last(function() {
- self.is_started.resolve();
+
+ this.is_setted.then(function() {
+ self.load_view();
});
- setTimeout(function () {
- self.list_view.appendTo($("#" + self.list_id));
- }, 0);
},
set_value: function(value) {
value = value || [];
@@ -2221,16 +2294,56 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
this._super(value);
this.dataset.set_ids(value);
var self = this;
- $.when(this.is_started).then(function() {
- self.list_view.reload_content();
- });
+ self.reload_content();
+ this.is_setted.resolve();
},
get_value: function() {
return [commands.replace_with(this.dataset.ids)];
},
validate: function() {
this.invalid = false;
- // TODO niv
+ },
+ is_readonly: function() {
+ return this.readonly || this.force_readonly;
+ },
+ load_view: function() {
+ var self = this;
+ this.list_view = new openerp.web.form.Many2ManyListView(this, this.dataset, false, {
+ 'addable': self.is_readonly() ? null : 'Add',
+ 'deletable': self.is_readonly() ? false : true,
+ 'selectable': self.multi_selection
+ });
+ this.list_view.m2m_field = this;
+ var loaded = $.Deferred();
+ this.list_view.on_loaded.add_last(function() {
+ self.initial_is_loaded.resolve();
+ loaded.resolve();
+ });
+ setTimeout(function () {
+ self.list_view.appendTo($("#" + self.list_id));
+ }, 0);
+ return loaded;
+ },
+ reload_content: function() {
+ var self = this;
+ this.is_loaded = this.is_loaded.pipe(function() {
+ return self.list_view.reload_content();
+ });
+ },
+ update_dom: function() {
+ this._super.apply(this, arguments);
+ var self = this;
+ if (this.previous_readonly !== this.readonly) {
+ this.previous_readonly = this.readonly;
+ if (this.list_view) {
+ this.is_loaded = this.is_loaded.pipe(function() {
+ self.list_view.stop();
+ return $.when(self.load_view()).then(function() {
+ self.reload_content();
+ });
+ });
+ }
+ }
}
});
@@ -2334,10 +2447,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
this.searchview.stop();
}
this.searchview = new openerp.web.SearchView(this,
- this.dataset, false, {
- "selectable": !this.options.disable_multiple_selection,
- "deletable": false
- });
+ this.dataset, false, {});
this.searchview.on_search.add(function(domains, contexts, groupbys) {
if (self.initial_ids) {
self.do_search(domains.concat([[["id", "in", self.initial_ids]], self.domain]),
@@ -2364,7 +2474,9 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
});
self.view_list = new openerp.web.form.SelectCreateListView(self,
self.dataset, false,
- _.extend({'deletable': false}, self.options.list_view_options || {}));
+ _.extend({'deletable': false,
+ 'selectable': !self.options.disable_multiple_selection
+ }, self.options.list_view_options || {}));
self.view_list.popup = self;
self.view_list.appendTo($("#" + self.element_id + "_view_list")).pipe(function() {
self.view_list.do_show();
@@ -2483,6 +2595,7 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
* - read_function
* - parent_view
* - form_view_options
+ * - readonly
*/
show_element: function(model, row_id, context, options) {
this.model = model;
@@ -2522,7 +2635,13 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
this.view_form.set_embedded_view(this.options.alternative_form_view);
}
this.view_form.appendTo(this.$element.find("#" + this.element_id + "_view_form"));
+ var once = $.Deferred().then(function() {
+ if (self.options.readonly) {
+ self.view_form.on_toggle_readonly();
+ }
+ });
this.view_form.on_loaded.add_last(function() {
+ once.resolve();
var $buttons = self.view_form.$element.find(".oe_form_buttons");
$buttons.html(QWeb.render("FormOpenPopup.form.buttons"));
var $nbutton = $buttons.find(".oe_formopenpopup-form-save");
@@ -2535,6 +2654,10 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
$cbutton.click(function() {
self.stop();
});
+ if (self.options.readonly) {
+ $nbutton.hide();
+ $cbutton.text(_t("Close"));
+ }
self.view_form.do_show();
});
this.dataset.on_write.add(this.on_write);
@@ -2817,17 +2940,21 @@ openerp.web.form.FieldStatus = openerp.web.form.Field.extend({
}
});
-openerp.web.form.WidgetNotebookReadonly = openerp.web.form.WidgetNotebook.extend({
- template: 'WidgetNotebook.readonly'
-});
openerp.web.form.FieldReadonly = openerp.web.form.Field.extend({
});
openerp.web.form.FieldCharReadonly = openerp.web.form.FieldReadonly.extend({
template: 'FieldChar.readonly',
+ init: function(view, node) {
+ this._super(view, node);
+ this.password = this.node.attrs.password === 'True' || this.node.attrs.password === '1';
+ },
set_value: function (value) {
this._super.apply(this, arguments);
var show_value = openerp.web.format_value(value, this, '');
+ if (this.password) {
+ show_value = new Array(show_value.length + 1).join('*');
+ }
this.$element.find('div').text(show_value);
return show_value;
}
@@ -2855,7 +2982,7 @@ openerp.web.form.FieldUrlReadonly = openerp.web.form.FieldURIReadonly.extend({
});
openerp.web.form.FieldBooleanReadonly = openerp.web.form.FieldCharReadonly.extend({
set_value: function (value) {
- this._super(value ? '\u2714' : '\u2718');
+ this._super(value ? '\u2611' : '\u2610');
}
});
openerp.web.form.FieldSelectionReadonly = openerp.web.form.FieldReadonly.extend({
@@ -2890,9 +3017,17 @@ openerp.web.form.FieldMany2OneReadonly = openerp.web.form.FieldCharReadonly.exte
self.update_dom();
self.on_value_changed();
var real_set_value = function(rval) {
- self.$element.find('div').text(rval ? rval[1] : '');
+ self.value = rval;
+ var div = $(self.$element.find('div'));
+ div.html('');
+ var a = $(div.find("a"));
+ a.text(rval ? rval[1] : '');
+ a.click(function() {
+ var pop = new openerp.web.form.FormOpenPopup(self.view);
+ pop.show_element(self.field.relation, self.value[0],self.build_context(), {readonly:true});
+ });
};
- if(typeof(value) === "number") {
+ if (value && !(value instanceof Array)) {
var dataset = new openerp.web.DataSetStatic(
this, this.field.relation, self.build_context());
dataset.name_get([value], function(data) {
@@ -2937,8 +3072,14 @@ openerp.web.form.widgets = new openerp.web.Registry({
'binary': 'openerp.web.form.FieldBinaryFile',
'statusbar': 'openerp.web.form.FieldStatus'
});
+
+openerp.web.form.FieldMany2ManyReadonly = openerp.web.form.FieldMany2Many.extend({
+ force_readonly: true
+});
+openerp.web.form.FieldOne2ManyReadonly = openerp.web.form.FieldOne2Many.extend({
+ force_readonly: true
+});
openerp.web.form.readonly = openerp.web.form.widgets.clone({
- 'notebook': 'openerp.web.form.WidgetNotebookReadonly',
'char': 'openerp.web.form.FieldCharReadonly',
'email': 'openerp.web.form.FieldEmailReadonly',
'url': 'openerp.web.form.FieldUrlReadonly',
@@ -2948,6 +3089,9 @@ openerp.web.form.readonly = openerp.web.form.widgets.clone({
'datetime': 'openerp.web.form.FieldCharReadonly',
'selection' : 'openerp.web.form.FieldSelectionReadonly',
'many2one': 'openerp.web.form.FieldMany2OneReadonly',
+ 'many2many' : 'openerp.web.form.FieldMany2ManyReadonly',
+ 'one2many' : 'openerp.web.form.FieldOne2ManyReadonly',
+ 'one2many_list' : 'openerp.web.form.FieldOne2ManyReadonly',
'boolean': 'openerp.web.form.FieldBooleanReadonly',
'float': 'openerp.web.form.FieldCharReadonly',
'integer': 'openerp.web.form.FieldCharReadonly',
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index d09ec1d3035..e891a6c7db7 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -11,7 +11,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
// whether the column headers should be displayed
'header': true,
// display addition button, with that label
- 'addable': _t("New"),
+ 'addable': _t("Create"),
// whether the list view can be sorted, note that once a view has been
// sorted it can not be reordered anymore
'sortable': true,
@@ -201,8 +201,15 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
this.setup_columns(this.fields_view.fields, grouped);
this.$element.html(QWeb.render("ListView", this));
-
// Head hook
+ this.$element.find('.all-record-selector').click(function(){
+ self.$element.find('.oe-record-selector input').prop('checked',
+ self.$element.find('.all-record-selector').prop('checked') || false);
+ var selection = self.groups.get_selection();
+ $(self.groups).trigger(
+ 'selected', [selection.ids, selection.records]);
+ });
+
this.$element.find('.oe-list-add')
.click(this.do_add_record)
.attr('disabled', grouped && this.options.editable);
@@ -424,10 +431,13 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
},
/**
* re-renders the content of the list view
+ *
+ * @returns {$.Deferred} promise to content reloading
*/
reload_content: function () {
var self = this;
this.records.reset();
+ var reloaded = $.Deferred();
this.$element.find('.oe-listview-content').append(
this.groups.render(function () {
if (self.dataset.index == null) {
@@ -438,7 +448,9 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
}
}
self.compute_aggregates();
+ reloaded.resolve();
}));
+ return reloaded.promise();
},
/**
* Handler for the result of eval_domain_and_context, actually perform the
@@ -512,6 +524,17 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
return field.name === name;
});
if (!action) { return; }
+
+ var c = new openerp.web.CompoundContext();
+ c.set_eval_context(_.extend({
+ active_id: id,
+ active_ids: [id],
+ active_model: this.dataset.model
+ }, this.records.get(id).toContext()));
+ if (action.context) {
+ c.add(action.context);
+ }
+ action.context = c;
this.do_execute_action(action, this.dataset, id, callback);
},
/**
@@ -1201,6 +1224,10 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
var options = { offset: page * limit, limit: limit };
//TODO xmo: investigate why we need to put the setTimeout
setTimeout(function() {dataset.read_slice(fields, options , function (records) {
+ // FIXME: ignominious hacks, parents (aka form view) should not send two ListView#reload_content concurrently
+ if (self.records.length) {
+ self.records.reset(null, {silent: true});
+ }
if (!self.datagroup.openable) {
view.configure_pager(dataset);
} else {
@@ -1430,6 +1457,25 @@ var Record = openerp.web.Class.extend(/** @lends Record# */{
}
return {data: form_data};
+ },
+ /**
+ * Converts the current record to a format expected by context evaluations
+ * (identical to record.attributes, except m2o fields are their integer
+ * value rather than a pair)
+ */
+ toContext: function () {
+ var output = {}, attrs = this.attributes;
+ for(var k in attrs) {
+ var val = attrs[k];
+ if (typeof val !== 'object') {
+ output[k] = val;
+ } else if (val instanceof Array) {
+ output[k] = val[0];
+ } else {
+ throw new Error("Can't convert value " + val + " to context");
+ }
+ }
+ return output;
}
});
Record.include(Events);
@@ -1541,7 +1587,8 @@ var Collection = openerp.web.Class.extend(/** @lends Collection# */{
* @param {Array} [records]
* @returns this
*/
- reset: function (records) {
+ reset: function (records, options) {
+ options = options || {};
_(this._proxies).each(function (proxy) {
proxy.reset();
});
@@ -1552,7 +1599,9 @@ var Collection = openerp.web.Class.extend(/** @lends Collection# */{
if (records) {
this.add(records);
}
- this.trigger('reset', this);
+ if (!options.silent) {
+ this.trigger('reset', this);
+ }
return this;
},
/**
diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js
index 4cc081a6266..dba0a1abba4 100644
--- a/addons/web/static/src/js/view_list_editable.js
+++ b/addons/web/static/src/js/view_list_editable.js
@@ -78,6 +78,17 @@ openerp.web.list_editable = function (openerp) {
// tree/@editable takes priority on everything else if present.
this.options.editable = data.arch.attrs.editable || this.options.editable;
return this._super(data, grouped);
+ },
+ /**
+ * Ensures the editable list is saved (saves any pending edition if
+ * needed, or tries to)
+ *
+ * Returns a deferred to the end of the saving.
+ *
+ * @returns {$.Deferred}
+ */
+ ensure_saved: function () {
+ return this.groups.ensure_saved();
}
});
@@ -86,6 +97,18 @@ openerp.web.list_editable = function (openerp) {
new_record: function () {
// TODO: handle multiple children
this.children[null].new_record();
+ },
+ /**
+ * Ensures descendant editable List instances are all saved if they have
+ * pending editions.
+ *
+ * @returns {$.Deferred}
+ */
+ ensure_saved: function () {
+ return $.when.apply(null,
+ _.invoke(
+ _.values(this.children),
+ 'ensure_saved'));
}
});
@@ -254,9 +277,11 @@ openerp.web.list_editable = function (openerp) {
* sibling if asked.
*
* @param {Boolean} [edit_next=false] should the next row become editable
+ * @returns {$.Deferred}
*/
save_row: function (edit_next) {
- var self = this;
+ //noinspection JSPotentiallyInvalidConstructorUsage
+ var self = this, done = $.Deferred();
this.edition_form.do_save(function (result) {
if (result.created && !self.edition_id) {
self.records.add({id: result.result},
@@ -267,28 +292,44 @@ openerp.web.list_editable = function (openerp) {
next_record = self.records.at(
self.records.indexOf(edited_record) + 1);
- self.handle_onwrite(self.edition_id);
- self.cancel_pending_edition().then(function () {
- $(self).trigger('saved', [self.dataset]);
- if (!edit_next) {
- return;
- }
- if (result.created) {
- self.new_record();
- return;
- }
- var next_record_id;
- if (next_record) {
- next_record_id = next_record.get('id');
- self.dataset.index = _(self.dataset.ids)
- .indexOf(next_record_id);
- } else {
- self.dataset.index = 0;
- next_record_id = self.records.at(0).get('id');
- }
- self.edit_record(next_record_id);
- });
- }, this.options.editable === 'top');
+ $.when(
+ self.handle_onwrite(self.edition_id),
+ self.cancel_pending_edition().then(function () {
+ $(self).trigger('saved', [self.dataset]);
+ if (!edit_next) {
+ return;
+ }
+ if (result.created) {
+ self.new_record();
+ return;
+ }
+ var next_record_id;
+ if (next_record) {
+ next_record_id = next_record.get('id');
+ self.dataset.index = _(self.dataset.ids)
+ .indexOf(next_record_id);
+ } else {
+ self.dataset.index = 0;
+ next_record_id = self.records.at(0).get('id');
+ }
+ self.edit_record(next_record_id);
+ })).then(function () {
+ done.resolve();
+ });
+ }, this.options.editable === 'top').fail(function () {
+ done.reject();
+ });
+ return done.promise();
+ },
+ /**
+ * If the current list is being edited, ensures it's saved
+ */
+ ensure_saved: function () {
+ if (this.edition) {
+ return this.save_row();
+ }
+ //noinspection JSPotentiallyInvalidConstructorUsage
+ return $.Deferred().resolve().promise();
},
/**
* Cancels the edition of the row for the current dataset index
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index f402a51bf7e..62928401492 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -2,21 +2,21 @@
* OpenERP web library
*---------------------------------------------------------*/
-openerp.web.views = function(db) {
+openerp.web.views = function(session) {
-var _t = db.web._t;
+var _t = session.web._t;
/**
* Registry for all the client actions key: tag value: widget
*/
-db.web.client_actions = new db.web.Registry();
+session.web.client_actions = new session.web.Registry();
/**
* Registry for all the main views
*/
-db.web.views = new db.web.Registry();
+session.web.views = new session.web.Registry();
-db.web.ActionManager = db.web.Widget.extend({
+session.web.ActionManager = session.web.Widget.extend({
identifier_prefix: "actionmanager",
init: function(parent) {
this._super(parent);
@@ -93,20 +93,20 @@ db.web.ActionManager = db.web.Widget.extend({
ir_actions_act_window: function (action, on_close) {
if (action.target === 'new') {
if (this.dialog == null) {
- this.dialog = new db.web.Dialog(this, { title: action.name, width: '80%' });
+ this.dialog = new session.web.Dialog(this, { title: action.name, width: '80%' });
if(on_close)
this.dialog.on_close.add(on_close);
this.dialog.start();
} else {
this.dialog_viewmanager.stop();
}
- this.dialog_viewmanager = new db.web.ViewManagerAction(this, action);
+ this.dialog_viewmanager = new session.web.ViewManagerAction(this, action);
this.dialog_viewmanager.appendTo(this.dialog.$element);
this.dialog.open();
} else {
this.dialog_stop();
this.content_stop();
- this.inner_viewmanager = new db.web.ViewManagerAction(this, action);
+ this.inner_viewmanager = new session.web.ViewManagerAction(this, action);
this.inner_viewmanager.appendTo(this.$element);
this.url_update(action);
}
@@ -124,7 +124,7 @@ db.web.ActionManager = db.web.Widget.extend({
if (this.dialog && action.context) {
var model = action.context.active_model;
if (model === 'base.module.upgrade' || model === 'base.setup.installer' || model === 'base.module.upgrade') {
- db.webclient.do_reload();
+ session.webclient.do_reload();
}
}
this.dialog_stop();
@@ -140,7 +140,7 @@ db.web.ActionManager = db.web.Widget.extend({
},
ir_actions_client: function (action) {
this.content_stop();
- var ClientWidget = db.web.client_actions.get_object(action.tag);
+ var ClientWidget = session.web.client_actions.get_object(action.tag);
(this.client_widget = new ClientWidget(this, action.params)).appendTo(this);
},
ir_actions_report_xml: function(action) {
@@ -164,12 +164,12 @@ db.web.ActionManager = db.web.Widget.extend({
}
});
-db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
+session.web.ViewManager = session.web.Widget.extend(/** @lends session.web.ViewManager# */{
identifier_prefix: "viewmanager",
template: "ViewManager",
/**
- * @constructs db.web.ViewManager
- * @extends db.web.Widget
+ * @constructs session.web.ViewManager
+ * @extends session.web.Widget
*
* @param parent
* @param dataset
@@ -185,10 +185,10 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
this.views_src = _.map(views, function(x) {return x instanceof Array? {view_id: x[0], view_type: x[1]} : x;});
this.views = {};
this.flags = this.flags || {};
- this.registry = db.web.views;
+ this.registry = session.web.views;
},
render: function() {
- return db.web.qweb.render(this.template, {
+ return session.web.qweb.render(this.template, {
self: this,
prefix: this.element_id,
views: this.views_src});
@@ -271,6 +271,10 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
}
}
}
+ $.when(view_promise).then(function () {
+ self.$element.find('.oe_view_title:first').text(
+ self.display_title());
+ });
return view_promise;
},
/**
@@ -284,7 +288,7 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
if (this.searchview) {
this.searchview.stop();
}
- this.searchview = new db.web.SearchView(
+ this.searchview = new session.web.SearchView(
this, this.dataset,
view_id, search_defaults, this.flags.search_view === false);
@@ -331,16 +335,24 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
/**
* Called by children view after executing an action
*/
- on_action_executed: function () {}
+ on_action_executed: function () {},
+ display_title: function () {
+ var view = this.views[this.active_view];
+ if (view) {
+ // ick
+ return view.controller.fields_view.arch.attrs.string;
+ }
+ return '';
+ }
});
-db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.ViewManagerAction# */{
+session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepnerp.web.ViewManagerAction# */{
template:"ViewManagerAction",
/**
- * @constructs db.web.ViewManagerAction
- * @extends db.web.ViewManager
+ * @constructs session.web.ViewManagerAction
+ * @extends session.web.ViewManager
*
- * @param {db.web.ActionManager} parent parent object/widget
+ * @param {session.web.ActionManager} parent parent object/widget
* @param {Object} action descriptor for the action this viewmanager needs to manage its views.
*/
init: function(parent, action) {
@@ -350,7 +362,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
this._super(parent, null, action.views);
this.session = parent.session;
this.action = action;
- var dataset = new db.web.DataSetSearch(this, action.res_model, action.context, action.domain);
+ var dataset = new session.web.DataSetSearch(this, action.res_model, action.context, action.domain);
if (action.res_id) {
dataset.ids.push(action.res_id);
dataset.index = 0;
@@ -400,12 +412,12 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
this.$element.find('.oe_get_xml_view').click(function () {
// TODO: add search view?
- $('
').text(db.web.json_node_to_xml(
+ $('').text(session.web.json_node_to_xml(
self.views[self.active_view].controller.fields_view.arch, true))
.dialog({ width: '95%'});
});
if (this.action.help && !this.flags.low_profile) {
- var Users = new db.web.DataSet(self, 'res.users'),
+ var Users = new session.web.DataSet(self, 'res.users'),
header = this.$element.find('.oe-view-manager-header');
header.delegate('blockquote button', 'click', function() {
var $this = $(this);
@@ -444,6 +456,16 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
if (!self.action.name && fvg) {
self.$element.find('.oe_view_title').text(fvg.arch.attrs.string || fvg.name);
}
+
+ var $title = self.$element.find('.oe_view_title'),
+ $search_prefix = $title.find('span');
+ if (controller.searchable !== false) {
+ if (!$search_prefix.length) {
+ $title.prepend('' + _t("Search:") + '');
+ }
+ } else {
+ $search_prefix.remove();
+ }
});
},
shortcut_check : function(view) {
@@ -451,7 +473,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
var grandparent = this.widget_parent && this.widget_parent.widget_parent;
// display shortcuts if on the first view for the action
var $shortcut_toggle = this.$element.find('.oe-shortcut-toggle');
- if (!(grandparent instanceof db.web.WebClient) ||
+ if (!(grandparent instanceof session.web.WebClient) ||
!(view.view_type === this.views_src[0].view_type
&& view.view_id === this.views_src[0].view_id)) {
$shortcut_toggle.hide();
@@ -488,7 +510,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
* Intercept do_action resolution from children views
*/
on_action_executed: function () {
- return new db.web.DataSet(this, 'res.log')
+ return new session.web.DataSet(this, 'res.log')
.call('get', [], this.do_display_log);
},
/**
@@ -512,10 +534,13 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
return false;
});
});
+ },
+ display_title: function () {
+ return this.action.name;
}
});
-db.web.Sidebar = db.web.Widget.extend({
+session.web.Sidebar = session.web.Widget.extend({
init: function(parent, element_id) {
this._super(parent, element_id);
this.items = {};
@@ -524,7 +549,7 @@ db.web.Sidebar = db.web.Widget.extend({
start: function() {
this._super(this);
var self = this;
- this.$element.html(db.web.qweb.render('Sidebar'));
+ this.$element.html(session.web.qweb.render('Sidebar'));
this.$element.find(".toggle-sidebar").click(function(e) {
self.do_toggle();
});
@@ -544,7 +569,7 @@ db.web.Sidebar = db.web.Widget.extend({
{
label: _t("Manage Views"),
callback: this.call_default_on_sidebar,
- title: _t("Manage views of the current object"),
+ title: _t("Manage views of the current object")
}, {
label: _t("Edit Workflow"),
callback: this.call_default_on_sidebar,
@@ -553,7 +578,7 @@ db.web.Sidebar = db.web.Widget.extend({
}, {
label: _t("Customize Object"),
callback: this.call_default_on_sidebar,
- title: _t("Manage views of the current object"),
+ title: _t("Manage views of the current object")
}
]);
@@ -561,10 +586,10 @@ db.web.Sidebar = db.web.Widget.extend({
this.add_items('other', [
{
label: _t("Import"),
- callback: this.call_default_on_sidebar,
+ callback: this.call_default_on_sidebar
}, {
label: _t("Export"),
- callback: this.call_default_on_sidebar,
+ callback: this.call_default_on_sidebar
}, {
label: _t("Translate"),
callback: this.call_default_on_sidebar,
@@ -601,10 +626,10 @@ db.web.Sidebar = db.web.Widget.extend({
if(!$section) {
section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
- var $section = $(db.web.qweb.render("Sidebar.section", {
+ var $section = $(session.web.qweb.render("Sidebar.section", {
section_id: section_id,
name: name,
- classname: 'oe_sidebar_' + code,
+ classname: 'oe_sidebar_' + code
}));
$section.appendTo(this.$element.find('div.sidebar-actions'));
this.sections[code] = $section;
@@ -633,7 +658,7 @@ db.web.Sidebar = db.web.Widget.extend({
this.items[items[i].element_id] = items[i];
}
- var $items = $(db.web.qweb.render("Sidebar.section.items", {items: items}));
+ var $items = $(session.web.qweb.render("Sidebar.section.items", {items: items}));
$items.find('a.oe_sidebar_action_a').click(function() {
var item = self.items[$(this).attr('id')];
@@ -687,7 +712,7 @@ db.web.Sidebar = db.web.Widget.extend({
}
});
-db.web.TranslateDialog = db.web.Dialog.extend({
+session.web.TranslateDialog = session.web.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
@@ -707,14 +732,14 @@ db.web.TranslateDialog = db.web.Dialog.extend({
this.translatable_fields_keys = _.map(this.view.translatable_fields || [], function(i) { return i.name });
this.languages = null;
this.languages_loaded = $.Deferred();
- (new db.web.DataSetSearch(this, 'res.lang', this.view.dataset.get_context(),
+ (new session.web.DataSetSearch(this, 'res.lang', this.view.dataset.get_context(),
[['translatable', '=', '1']])).read_slice(['code', 'name'], { sort: 'id' }, this.on_languages_loaded);
},
start: function() {
var self = this;
this._super();
$.when(this.languages_loaded).then(function() {
- self.$element.html(db.web.qweb.render('TranslateDialog', { widget: self }));
+ self.$element.html(session.web.qweb.render('TranslateDialog', { widget: self }));
self.$element.tabs();
if (!(self.view.translatable_fields && self.view.translatable_fields.length)) {
self.hide_tabs('fields');
@@ -819,7 +844,7 @@ db.web.TranslateDialog = db.web.Dialog.extend({
}
});
-db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
+session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{
template: "EmptyComponent",
set_default_options: function(options) {
this.options = options || {};
@@ -833,7 +858,7 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
},
open_translate_dialog: function(field) {
if (!this.translate_dialog) {
- this.translate_dialog = new db.web.TranslateDialog(this).start();
+ this.translate_dialog = new session.web.TranslateDialog(this).start();
}
this.translate_dialog.open(field);
},
@@ -845,7 +870,7 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
* @param {String} [action_data.special=null] special action handlers (currently: only ``'cancel'``)
* @param {String} [action_data.type='workflow'] the action type, if present, one of ``'object'``, ``'action'`` or ``'workflow'``
* @param {Object} [action_data.context=null] additional action context, to add to the current context
- * @param {db.web.DataSet} dataset a dataset object used to communicate with the server
+ * @param {session.web.DataSet} dataset a dataset object used to communicate with the server
* @param {Object} [record_id] the identifier of the object on which the action is to be applied
* @param {Function} on_closed callback to execute when dialog is closed or when the action does not generate any result (no new action)
*/
@@ -857,12 +882,12 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
return self.widget_parent.on_action_executed.apply(null, arguments);
}
};
- var context = new db.web.CompoundContext(dataset.get_context(), action_data.context || {});
+ var context = new session.web.CompoundContext(dataset.get_context(), action_data.context || {});
var handler = function (r) {
var action = r.result;
if (action && action.constructor == Object) {
- var ncontext = new db.web.CompoundContext(context);
+ var ncontext = new session.web.CompoundContext(context);
if (record_id) {
ncontext.add({
active_id: record_id,
@@ -899,7 +924,7 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
/**
* Directly set a view to use instead of calling fields_view_get. This method must
* be called before start(). When an embedded view is set, underlying implementations
- * of db.web.View must use the provided view instead of any other one.
+ * of session.web.View must use the provided view instead of any other one.
*
* @param embedded_view A view.
*/
@@ -917,7 +942,8 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
},
on_sidebar_manage_views: function() {
if (this.fields_view && this.fields_view.arch) {
- $('' + db.web.json_node_to_xml(this.fields_view.arch, true) + '').dialog({ width: '95%', height: 600});
+ var view_editor = new session.web.ViewEditor(this, this.$element, this.dataset, this.fields_view.arch);
+ view_editor.start();
} else {
this.do_warn("Manage Views", "Could not find current view declaration");
}
@@ -929,11 +955,11 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
console.log('Todo');
},
on_sidebar_import: function() {
- var import_view = new db.web.DataImport(this, this.dataset);
+ var import_view = new session.web.DataImport(this, this.dataset);
import_view.start();
},
on_sidebar_export: function() {
- var export_view = new db.web.DataExport(this, this.dataset);
+ var export_view = new session.web.DataExport(this, this.dataset);
export_view.start();
},
on_sidebar_translate: function() {
@@ -943,19 +969,19 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
}
});
-db.web.json_node_to_xml = function(node, single_quote, indent) {
+session.web.json_node_to_xml = function(node, human_readable, indent) {
// For debugging purpose, this function will convert a json node back to xml
// Maybe usefull for xml view editor
+ indent = indent || 0;
+ var sindent = (human_readable ? (new Array(indent + 1).join('\t')) : ''),
+ r = sindent + '<' + node.tag,
+ cr = human_readable ? '\n' : '';
if (typeof(node) === 'string') {
- return node;
- }
- else if (typeof(node.tag) !== 'string' || !node.children instanceof Array || !node.attrs instanceof Object) {
+ return sindent + node;
+ } else if (typeof(node.tag) !== 'string' || !node.children instanceof Array || !node.attrs instanceof Object) {
throw("Node a json node");
}
- indent = indent || 0;
- var sindent = new Array(indent + 1).join('\t'),
- r = sindent + '<' + node.tag;
for (var attr in node.attrs) {
var vattr = node.attrs[attr];
if (typeof(vattr) !== 'string') {
@@ -963,19 +989,19 @@ db.web.json_node_to_xml = function(node, single_quote, indent) {
vattr = JSON.stringify(vattr);
}
vattr = vattr.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"');
- if (single_quote) {
+ if (human_readable) {
vattr = vattr.replace(/"/g, "'");
}
r += ' ' + attr + '="' + vattr + '"';
}
if (node.children && node.children.length) {
- r += '>\n';
+ r += '>' + cr;
var childs = [];
for (var i = 0, ii = node.children.length; i < ii; i++) {
- childs.push(db.web.json_node_to_xml(node.children[i], single_quote, indent + 1));
+ childs.push(session.web.json_node_to_xml(node.children[i], human_readable, indent + 1));
}
- r += childs.join('\n');
- r += '\n' + sindent + '' + node.tag + '>';
+ r += childs.join(cr);
+ r += cr + sindent + '' + node.tag + '>';
return r;
} else {
return r + '/>';
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 7720ae2d38b..1fc98ba34ee 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -415,6 +415,9 @@
|
|
+
@@ -593,7 +578,8 @@
- |
+
+ |
@@ -612,8 +598,26 @@
| |
+
+
+
+
@@ -628,9 +632,18 @@
-
-
- |
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
|