Vidhin Mehta  (OpenERP) has proposed merging 
lp:~openerp-dev/openerp-web/trunk-list_editable-m2m-fix into 
lp:~openerp-dev/openerp-web/trunk-10-first-clicks-purchase-atp-invoice-nco.

Requested reviews:
  OpenERP R&D Team (openerp-dev)

For more details, see:
https://code.launchpad.net/~openerp-dev/openerp-web/trunk-list_editable-m2m-fix/+merge/133404
-- 
https://code.launchpad.net/~openerp-dev/openerp-web/trunk-list_editable-m2m-fix/+merge/133404
Your team OpenERP R&D Team is requested to review the proposed merge of 
lp:~openerp-dev/openerp-web/trunk-list_editable-m2m-fix into 
lp:~openerp-dev/openerp-web/trunk-10-first-clicks-purchase-atp-invoice-nco.
=== modified file 'addons/web/static/src/css/base.css'
--- addons/web/static/src/css/base.css	2012-11-06 23:05:28 +0000
+++ addons/web/static/src/css/base.css	2012-11-08 05:19:19 +0000
@@ -25,7 +25,6 @@
     display: none !important;
   }
 }
-
 .openerp.openerp_webclient_container {
   height: 100%;
 }
@@ -2566,7 +2565,7 @@
   background-color: #eeeeee;
 }
 .openerp .oe_list_editable .oe_list_content td.oe_list_field_cell {
-  padding: 4px 6px 3px 6px;
+  padding: 4px 6px 3px;
 }
 .openerp .oe_list.oe_list_editable.oe_editing .oe_edition .oe_list_field_cell:not(.oe_readonly) {
   color: transparent;
@@ -2647,6 +2646,9 @@
   margin: 0 !important;
   padding: 0;
 }
+.openerp .oe_list .oe_form .oe_form_field_boolean {
+  padding: 1px 6px 3px;
+}
 .openerp .oe_list .oe_list_content .oe_group_header {
   background-color: #fcfcfc;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#fcfcfc), to(#dedede));

=== modified file 'addons/web/static/src/css/base.sass'
--- addons/web/static/src/css/base.sass	2012-11-06 23:05:28 +0000
+++ addons/web/static/src/css/base.sass	2012-11-08 05:19:19 +0000
@@ -2030,10 +2030,8 @@
                     background-color: #eee
 
     $row-height: 27px
-    .oe_list_editable
-        .oe_list_content
-            td.oe_list_field_cell
-                padding: 4px 6px 3px 6px
+    .oe_list_editable .oe_list_content td.oe_list_field_cell
+        padding: 4px 6px 3px
     .oe_list.oe_list_editable.oe_editing
         .oe_edition .oe_list_field_cell:not(.oe_readonly)
             *
@@ -2106,6 +2104,10 @@
                 position: absolute
                 margin: 0 !important // dammit
                 padding: 0
+            .oe_form_field_boolean
+                // use padding similar to actual cell to correctly position the
+                // checkbox
+                padding: 1px 6px 3px
         .oe_list_content .oe_group_header
             @include vertical-gradient(#fcfcfc, #dedede)
 

=== modified file 'addons/web/static/src/js/view_form.js'
--- addons/web/static/src/js/view_form.js	2012-11-06 17:20:36 +0000
+++ addons/web/static/src/js/view_form.js	2012-11-08 05:19:19 +0000
@@ -2216,6 +2216,13 @@
     },
     focus: function() {
         this.$('input:first').focus();
+    },
+    set_dimensions: function (height, width) {
+        this._super(height, width);
+        this.$('input').css({
+            height: height,
+            width: width
+        });
     }
 });
 
@@ -2502,7 +2509,7 @@
         this.$textarea.focus();
     },
     set_dimensions: function (height, width) {
-        this._super();
+        this._super(height, width);
         this.$textarea.css({
             width: width,
             minHeight: height
@@ -2664,6 +2671,13 @@
     },
     focus: function() {
         this.$el.find('select:first').focus();
+    },
+    set_dimensions: function (height, width) {
+        this._super(height, width);
+        this.$('select').css({
+            height: height,
+            width: width
+        });
     }
 });
 
@@ -3146,6 +3160,62 @@
         this.ed_def.reject();
         return instance.web.form.CompletionFieldMixin._search_create_popup.apply(this, arguments);
     },
+    set_dimensions: function (height, width) {
+        this._super(height, width);
+        this.$input.css('height', height);
+    }
+});
+
+instance.web.form.Many2OneButton = instance.web.form.AbstractField.extend({
+    template: 'Many2OneButton',
+    init: function(field_manager, node) {
+        this._super.apply(this, arguments);
+    },
+    start: function() {
+        this._super.apply(this, arguments);
+        this.set_button();
+    },
+    set_button: function() {
+        var self = this;
+        if (this.$button) {
+            this.$button.remove();
+        }
+        var options = {};
+        try {
+            options = py.eval(this.node.attrs.options);
+        } catch (e) {}
+        if (options.label) {
+            this.string = this.get('value') ? _t(options.label.edit) : _t(options.label.create);
+        } else {
+            this.string = '';
+        }
+        this.node.attrs.icon = this.get('value') ? '/web/static/src/img/icons/gtk-yes.png' : '/web/static/src/img/icons/gtk-no.png';
+        this.$button = $(QWeb.render('WidgetButton', {'widget': this}));
+        this.$el.append(this.$button);
+        this.$button.on('click', self.on_click);
+    },
+    on_click: function(ev) {
+        var self = this;
+        this.popup =  new instance.web.form.FormOpenPopup(this);
+        this.popup.show_element(
+            this.field.relation,
+            this.get('value'),
+            this.build_context(),
+            {title: this.string}
+        );
+        this.popup.on('create_completed write_completed', self, function(r) {
+            self.set_value(r);
+        });
+    },
+    set_value: function(value_) {
+        var self = this;
+        if (value_ instanceof Array) {
+            value_ = value_[0];
+        }
+        value_ = value_ || false;
+        this.set('value', value_);
+        this.set_button();
+     },
 });
 
 /*
@@ -4858,10 +4928,6 @@
             instance.webclient.notification.warn(_t("Image"), _t("Could not display the selected image."));
         });
     },
-    on_file_change: function() {
-        this.render_value();
-        this._super.apply(this, arguments);
-    },
     on_file_uploaded_and_valid: function(size, name, content_type, file_base64) {
         this.internal_set_value(file_base64);
         this.binary_value = true;
@@ -5140,6 +5206,7 @@
     'datetime' : 'instance.web.form.FieldDatetime',
     'selection' : 'instance.web.form.FieldSelection',
     'many2one' : 'instance.web.form.FieldMany2One',
+    'many2onebutton' : 'instance.web.form.Many2OneButton',
     'many2many' : 'instance.web.form.FieldMany2Many',
     'many2many_tags' : 'instance.web.form.FieldMany2ManyTags',
     'many2many_kanban' : 'instance.web.form.FieldMany2ManyKanban',

=== modified file 'addons/web/static/src/js/view_list.js'
--- addons/web/static/src/js/view_list.js	2012-11-06 15:39:29 +0000
+++ addons/web/static/src/js/view_list.js	2012-11-08 05:19:19 +0000
@@ -1016,6 +1016,7 @@
                 }
                 new instance.web.Model(column.relation)
                     .call('name_get', [ids]).then(function (names) {
+                        record.set(column.id + '_many2many', value);
                         record.set(column.id, _(names).pluck(1).join(', '));
                     })
             }
@@ -2012,6 +2013,7 @@
     'field.progressbar': 'instance.web.list.ProgressBar',
     'field.handle': 'instance.web.list.Handle',
     'button': 'instance.web.list.Button',
+    'field.many2onebutton': 'instance.web.list.Many2OneButton',
 });
 instance.web.list.columns.for_ = function (id, field, node) {
     var description = _.extend({tag: node.tag}, field, node.attrs);
@@ -2199,5 +2201,11 @@
         return '<div class="oe_list_handle">';
     }
 });
+instance.web.list.Many2OneButton = instance.web.list.Column.extend({
+    _format: function (row_data, options) {
+        this.has_value = !!row_data[this.id].value;
+        return QWeb.render('Many2OneButton.cell', {'widget': this});
+    },
+});
 };
 // vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:

=== modified file 'addons/web/static/src/js/view_list_editable.js'
--- addons/web/static/src/js/view_list_editable.js	2012-10-31 14:07:18 +0000
+++ addons/web/static/src/js/view_list_editable.js	2012-11-08 05:19:19 +0000
@@ -720,6 +720,10 @@
             // TODO: specify sequence of edit calls
             var self = this;
             var form = self.form;
+            var m2m_field = this.get_many2many_field();
+            if(record && m2m_field.length !== 0){
+                record = this.set_many2many_record(m2m_field, record);
+            }
             var loaded = record
                 ? form.trigger('load_record', _.extend({}, record))
                 : form.load_defaults();
@@ -734,6 +738,19 @@
                 return form;
             });
         },
+        get_many2many_field:function(){
+            var parent = this.getParent();
+            return _.filter(parent.columns, function(field){
+                return field.type === "many2many";
+            });
+        },
+        set_many2many_record:function(m2m_field, record){
+            _.each(m2m_field, function(field){
+                record[field.name] = record[field.name + '_many2many'];
+                delete record[field.name + '_many2many'];
+            });
+            return record;
+        },
         save: function () {
             var self = this;
             return this.form

=== modified file 'addons/web/static/src/js/view_tree.js'
--- addons/web/static/src/js/view_tree.js	2012-10-03 12:28:36 +0000
+++ addons/web/static/src/js/view_tree.js	2012-11-08 05:19:19 +0000
@@ -45,7 +45,7 @@
             view_type: "tree",
             toolbar: this.view_manager ? !!this.view_manager.sidebar : false,
             context: this.dataset.get_context()
-        }).then(this.on_loaded);
+        }, this.on_loaded);
     },
     /**
      * Returns the list of fields needed to correctly read objects.
@@ -63,12 +63,6 @@
         }
         return fields;
     },
-    store_record:function(records){
-        var self = this;
-        _(records).each(function (record) {
-            self.records[record.id] = record;
-        });
-    },
     on_loaded: function (fields_view) {
         var self = this;
         var has_toolbar = !!fields_view.arch.attrs.toolbar;
@@ -93,19 +87,17 @@
         this.$el.addClass(this.fields_view.arch.attrs['class']);
 
         this.dataset.read_slice(this.fields_list()).then(function(records) {
-            self.store_record(records);
             if (!has_toolbar) {
                 // WARNING: will do a second read on the same ids, but only on
                 //          first load so not very important
-                self.render_data({'null':records})
-                self.getdata(_.pluck(records,"id"));
+                self.getdata(null, _(records).pluck('id'));
                 return;
             }
 
             var $select = self.$el.find('select')
                 .change(function () {
                     var $option = $(this).find(':selected');
-                    self.getdata($option.val());
+                    self.getdata($option.val(), $option.data('children'));
                 });
             _(records).each(function (record) {
                 self.records[record.id] = record;
@@ -120,12 +112,7 @@
                 $select.change();
             }
         });
-        this.$el.find("#tree_view_expand").click(function(){
-                self.expand_all();
-        });
-        this.$el.find("#tree_view_collapse").click(function(){
-            self.collpase_all();
-        });
+
         // TODO store open nodes in url ?...
         this.do_push_state({});
 
@@ -141,22 +128,6 @@
                 return [color, py.parse(py.tokenize(expr)), expr];
             }).value();
     },
-    expand_all: function(){
-        var self = this;
-        var tr = this.$el.find(".oe-treeview-table tbody tr[id^='treerow_']");
-        _.each(tr,function(rec){
-            self.showcontent($(rec).attr('data-id'),true);
-        });
-    },
-    collpase_all: function(){
-        var self = this;
-        var root_tr = this.$el.find(".oe-treeview-table tbody tr[data-level='"+1+"']");
-        _.each(root_tr,function(rec){
-            if($(rec).hasClass('oe_open')){
-                self.showcontent($(rec).attr('data-id'),false);
-            }
-        });
-    },
     /**
      * Returns the color for the provided record in the current view (from the
      * ``@colors`` attribute)
@@ -193,44 +164,50 @@
         });
 
         this.$el.delegate('.treeview-tr', 'click', function () {
-            var $this = $(this),
+            var is_loaded = 0,
+                $this = $(this),
                 record_id = $this.data('id'),
-                bool = $this.parent().hasClass('oe_open');
-                self.showcontent(record_id, !bool);
+                record = self.records[record_id],
+                children_ids = record[self.children_field];
+
+            _(children_ids).each(function(childid) {
+                if (self.$el.find('#treerow_' + childid).length) {
+                    if (self.$el.find('#treerow_' + childid).is(':hidden')) {
+                        is_loaded = -1;
+                    } else {
+                        is_loaded++;
+                    }
+                }
+            });
+            if (is_loaded === 0) {
+                if (!$this.parent().hasClass('oe_open')) {
+                    self.getdata(record_id, children_ids);
+                }
+            } else {
+                self.showcontent(record_id, is_loaded < 0);
+            }
         });
     },
     // get child data of selected value
-    getdata: function (id) {
-        var self = this;
-        var parent_child ={};
-        id = _.isArray(id)?id:parseInt(id); 
-        var ir_model_data = new instance.web.Model(this.model,self.dataset.get_context() || {},[['id','child_of',id]]).query();
-        ir_model_data._execute().then(function(records){
-              self.store_record(records);
-             _.each(records,function(rec){
-                 if(rec[self.children_field].length === 0)return;
-                 parent_child[rec.id] = [];
-                 _.each(rec[self.children_field],function(key){
-                     parent_child[rec.id].push(self.records[key]);
-                 });
-             })
-             self.render_data(parent_child);
-        });
-    },
-    render_data: function(groupby){
-        var self = this;
-        _.each(_.keys(groupby),function(key){
-            var $curr_node = self.$el.find('#treerow_' + key);
-            var record = groupby[key];
+    getdata: function (id, children_ids) {
+        var self = this;
+
+        self.dataset.read_ids(children_ids, this.fields_list()).then(function(records) {
+            _(records).each(function (record) {
+                self.records[record.id] = record;
+            });
+
+            var $curr_node = self.$el.find('#treerow_' + id);
             var children_rows = QWeb.render('TreeView.rows', {
-                'records': record,
+                'records': records,
                 'children_field': self.children_field,
                 'fields_view': self.fields_view.arch.children,
                 'fields': self.fields,
-                'level': ($curr_node.data('level') || 0) + 1,
+                'level': $curr_node.data('level') || 0,
                 'render': instance.web.format_value,
                 'color_for': self.color_for
             });
+
             if ($curr_node.length) {
                 $curr_node.addClass('oe_open');
                 $curr_node.after(children_rows);
@@ -238,10 +215,8 @@
                 self.$el.find('tbody').html(children_rows);
             }
         });
-        self.collpase_all();
     },
 
-
     // Get details in listview
     activate: function(id) {
         var self = this;
@@ -284,5 +259,13 @@
         }, this);
     },
 
+    do_show: function () {
+        this.$el.show();
+    },
+
+    do_hide: function () {
+        this.$el.hide();
+        this.hidden = true;
+    }
 });
 };

=== modified file 'addons/web/static/src/xml/base.xml'
--- addons/web/static/src/xml/base.xml	2012-11-02 10:46:28 +0000
+++ addons/web/static/src/xml/base.xml	2012-11-08 05:19:19 +0000
@@ -567,16 +567,14 @@
 </t>
 
 <t t-name="TreeView">
-    <div class = "tree_header">
-         <select t-if="toolbar" ></select>
-         <button id = "tree_view_collapse">Collapse All</button>
-         <button id = "tree_view_expand">Expand All</button>
-     </div>
-    <table class="oe-treeview-table">
+    <select t-if="toolbar" style="width: 30%">
+    </select>
+    <table class="oe_tree_table oe-treeview-table">
         <thead>
             <tr>
                 <th t-foreach="fields_view" t-as="field"
-                    t-if="!field.attrs.modifiers.tree_invisible">
+                    t-if="!field.attrs.modifiers.tree_invisible"
+                    class="treeview-header">
                     <t t-esc="field_value.attrs.string || fields[field.attrs.name].string" />
                 </th>
             </tr>
@@ -588,11 +586,11 @@
 <tr t-name="TreeView.rows"
         t-foreach="records" t-as="record"
         t-att-id="'treerow_' + record.id"
-        t-att-data-id="record.id" t-att-data-level="level">
+        t-att-data-id="record.id" t-att-data-level="level + 1">
     <t t-set="children" t-value="record[children_field]"/>
     <t t-set="class" t-value="children and children.length ? 'treeview-tr' : 'treeview-td'"/>
     <t t-set="rank" t-value="'oe-treeview-first'"/>
-    <t t-set="style" t-value="'background-position: ' + 19*(level-1) + 'px; padding-left: ' + (4 + 19*(level-1)) + 'px;'"/>
+    <t t-set="style" t-value="'background-position: ' + 19*(level) + 'px; padding-left: ' + (4 + 19*(level)) + 'px;'"/>
 
     <td t-foreach="fields_view" t-as="field"
         t-if="!field.attrs.modifiers.tree_invisible"
@@ -1029,6 +1027,13 @@
         </t>
     </span>
 </t>
+<t t-name="Many2OneButton">
+    <span class="oe_form_field">
+    </span>
+</t>
+<t t-name="Many2OneButton.cell"
+    ><img t-attf-src="#{_s}/web/static/src/img/icons/gtk-#{widget.has_value ? 'yes' : 'no'}.png" width="16" height="16"/>
+</t>
 <t t-name="FieldMany2ManyTags">
     <div class="oe_form_field oe_tags" t-att-style="widget.node.attrs.style">
         <t t-if="! widget.get('effective_readonly')">

_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help   : https://help.launchpad.net/ListHelp

Reply via email to