Thibault Delavallée (OpenERP) has proposed merging 
lp:~openerp-dev/openobject-addons/trunk-chatter-emailfrom-chm into 
lp:openobject-addons.

Requested reviews:
  OpenERP Core Team (openerp)

For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-chatter-emailfrom-chm/+merge/140910
-- 
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-chatter-emailfrom-chm/+merge/140910
Your team OpenERP R&D Team is subscribed to branch 
lp:~openerp-dev/openobject-addons/trunk-chatter-emailfrom-chm.
=== modified file 'mail/mail_thread.py'
--- mail/mail_thread.py	2012-12-19 18:18:35 +0000
+++ mail/mail_thread.py	2012-12-20 14:32:39 +0000
@@ -749,8 +749,8 @@
         return mail_message.create(cr, uid, values, context=context)
 
     def message_post_user_api(self, cr, uid, thread_id, body='', subject=False, parent_id=False,
-                                attachment_ids=None, context=None, content_subtype='plaintext',
-                                extra_email=[], **kwargs):
+                                attachment_ids=None, extra_email=[], 
+                                context=None, content_subtype='plaintext', **kwargs):
         """ Wrapper on message_post, used for user input :
             - mail gateway
             - quick reply in Chatter (refer to mail.js), not
@@ -771,13 +771,20 @@
         if content_subtype == 'plaintext':
             body = tools.plaintext2html(body)
 
+        partner_ids = kwargs.pop('partner_ids', [])
+        
         for partner in extra_email:
             part_ids = self.pool.get('res.partner').search(cr, uid, [('email', '=', partner)], context=context)
             if not part_ids:
                 part_ids = [self.pool.get('res.partner').name_create(cr, uid, partner, context=context)[0]]
             self.message_subscribe(cr, uid, [thread_id], part_ids, context=context)
 
-        partner_ids = kwargs.pop('partner_ids', [])
+            message_ids = mail_message.search(cr, uid, [('email_from', '=', partner)], context=context)
+            if part_ids and message_ids:
+                mail_message.write(cr, uid, message_ids, {'email_from': None, 'author_id': part_ids[0]}, context=context)
+
+            partner_ids = set(partner_ids) + set(part_ids)
+
         if parent_id:
             parent_message = self.pool.get('mail.message').browse(cr, uid, parent_id, context=context)
             partner_ids += [(4, partner.id) for partner in parent_message.partner_ids]
@@ -852,7 +859,11 @@
 
     def message_unsubscribe(self, cr, uid, ids, partner_ids, context=None):
         """ Remove partners from the records followers. """
-        self.check_access_rights(cr, uid, 'read')
+        user_pids = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id']
+        if set(partner_ids) == set(user_pids):
+            self.check_access_rights(cr, uid, 'read')
+        else:
+            self.check_access_rights(cr, uid, 'write')
         return self.write(cr, SUPERUSER_ID, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context)
 
     #------------------------------------------------------

=== modified file 'mail/res_users.py'
--- mail/res_users.py	2012-12-17 14:43:06 +0000
+++ mail/res_users.py	2012-12-20 14:32:39 +0000
@@ -116,8 +116,10 @@
         alias_pool.unlink(cr, uid, alias_ids, context=context)
         return res
 
+
     def message_post_user_api(self, cr, uid, thread_id, body='', subject=False, parent_id=False,
-                                attachment_ids=None, context=None, content_subtype='plaintext', **kwargs):
+                                attachment_ids=None, extra_email=[], 
+                                context=None, content_subtype='plaintext', **kwargs):
         """ Redirect the posting of message on res.users to the related partner.
             This is done because when giving the context of Chatter on the
             various mailboxes, we do not have access to the current partner_id.
@@ -128,8 +130,10 @@
         if isinstance(thread_id, (list, tuple)):
             thread_id = thread_id[0]
         partner_id = self.browse(cr, uid, thread_id).partner_id.id
-        return self.pool.get('res.partner').message_post_user_api(cr, uid, partner_id, body=body, subject=subject,
-            parent_id=parent_id, attachment_ids=attachment_ids, context=context, content_subtype=content_subtype, **kwargs)
+        return self.pool.get('res.partner').message_post_user_api(cr, uid, 
+            partner_id, body=body, subject=subject, parent_id=parent_id, 
+            attachment_ids=attachment_ids, extra_email=extra_email, 
+            context=context, content_subtype=content_subtype, **kwargs)
 
     def message_post(self, cr, uid, thread_id, context=None, **kwargs):
         """ Redirect the posting of message on res.users to the related partner.

=== modified file 'mail/static/src/css/mail.css'
--- mail/static/src/css/mail.css	2012-12-19 13:15:01 +0000
+++ mail/static/src/css/mail.css	2012-12-20 14:32:39 +0000
@@ -253,6 +253,14 @@
 .openerp .oe_mail .oe_msg_composer .oe_msg_attachment_list{
     display: block;
 }
+.openerp .oe_mail .oe_msg_composer .oe_emails_from label{
+    vertical-align: middle;
+    display: block;
+    line-height: 16px;
+}
+.openerp .oe_mail .oe_msg_composer .oe_emails_from input{
+    vertical-align: middle;
+}
 .openerp .oe_mail .oe_attachment{
     display: inline-block;
     width: 100px;
@@ -578,6 +586,11 @@
     margin-right:4px;
     border-radius: 2px;
 }
+.openerp .oe_followers .oe_remove_follower{
+    cursor: pointer;
+    float: right;
+
+}
 
 /* ---------------- MESSAGES BODY ------------------ */
 .openerp .oe_mail .oe_msg_content .oe_blockquote,

=== modified file 'mail/static/src/js/mail.js'
--- mail/static/src/js/mail.js	2012-12-17 09:35:01 +0000
+++ mail/static/src/js/mail.js	2012-12-20 14:32:39 +0000
@@ -369,6 +369,7 @@
             this._super(parent, datasets, options);
             this.show_compact_message = false;
             this.show_delete_attachment = true;
+            this.emails_from = [];
         },
 
         start: function () {
@@ -478,9 +479,11 @@
             this.$('.oe_cancel').on('click', _.bind( this.on_cancel, this) );
             this.$('.oe_post').on('click', _.bind( this.on_message_post, this) );
             this.$('.oe_full').on('click', _.bind( this.on_compose_fullmail, this, this.id ? 'reply' : 'comment') );
-
+        
             /* stack for don't close the compose form if the user click on a button */
-            this.$('.oe_msg_footer').on('mousedown', _.bind( function () { this.stay_open = true; }, this));
+            this.$('.oe_msg_left, .oe_msg_center').on('mousedown', _.bind( function () { this.stay_open = true; }, this));
+            this.$('.oe_msg_left, .oe_msg_content').on('mouseup', _.bind( function () { this.$('textarea').focus(); }, this));
+
             var ev_stay = {};
             ev_stay.mouseup = ev_stay.keydown = ev_stay.focus = function () { self.stay_open = false; };
             this.$('textarea:not(.oe_compact)').on(ev_stay);
@@ -491,6 +494,8 @@
 
             // event: delete child attachments off the oe_msg_attachment_list box
             this.$(".oe_msg_attachment_list").on('click', '.oe_delete', this.on_attachment_delete);
+
+            this.$(".oe_emails_from").on('change', 'input', this.on_checked_email_from);
         },
 
         on_compose_fullmail: function (default_composition_mode) {
@@ -568,21 +573,23 @@
 
             if (this.do_check_attachment_upload() && (this.attachment_ids.length || body.match(/\S+/))) {
                 //session.web.blockUI();
-                this.parent_thread.ds_thread.call('message_post_user_api', [
-                        this.context.default_res_id, 
-                        body, 
-                        false, 
-                        this.context.default_parent_id, 
-                        _.map(this.attachment_ids, function (file) {return file.id;}),
-                        this.parent_thread.context
-                    ]).done(function (record) {
+                var values = [
+                    this.context.default_res_id, //thread_id
+                    body, //body
+                    false, //subject
+                    this.context.default_parent_id, //parent_id
+                    _.map(this.attachment_ids, function (file) {return file.id;}), //attachment_ids
+                    _.map(_.filter(this.emails_from, function (f) {return f[1]}), function (f) {return f[0]}), //extra_email
+                    this.parent_thread.context, // context
+                ];
+                this.parent_thread.ds_thread.call('message_post_user_api', values).done(function (record) {
                         var thread = self.parent_thread;
                         var root = thread == self.options.root_thread;
                         if (self.options.display_indented_thread < self.thread_level && thread.parent_message) {
                             var thread = thread.parent_message.parent_thread;
                         }
                         // create object and attach to the thread object
-                        thread.message_fetch([['id', 'child_of', [self.id]]], false, [record], function (arg, data) {
+                        thread.message_fetch([["id", "=", record]], false, [record], function (arg, data) {
                             var message = thread.create_message_object( data[0] );
                             // insert the message on dom
                             thread.insert_message( message, root ? undefined : self.$el, root );
@@ -597,8 +604,8 @@
         /* convert the compact mode into the compose message
         */
         on_compose_expandable: function (event) {
-
-            if ((!this.stay_open || (event && event.type == 'click')) && (!this.show_composer || !this.$('textarea:not(.oe_compact)').val().match(/\S+/))) {
+            this.get_emails_from();
+            if ((!this.stay_open || (event && event.type == 'click')) && (!this.show_composer || !this.$('textarea:not(.oe_compact)').val().match(/\S+/) && !this.attachment_ids.length)) {
                 this.show_composer = !this.show_composer || this.stay_open;
                 this.reinit();
             }
@@ -620,6 +627,41 @@
             if (!this.show_composer) {
                 this.reinit();
             }
+        },
+
+        get_emails_from: function () {
+            var self = this;
+            var messages = [];
+
+            if (this.parent_thread.parent_message) {
+                // go to the parented message
+                var message = this.parent_thread.parent_message;
+                var parent_message = message.parent_id ? message.parent_thread.parent_message : message;
+                var messages = [parent_message].concat(parent_message.get_childs());
+            } else {
+                // get all wall messages
+                _.each(this.options.root_thread.messages, function (msg) {messages.push(msg); messages.concat(msg.get_childs());});
+            }
+            
+            var emails_from = _.map(_.filter(messages,
+                    function (thread) {return thread.author_id && !thread.author_id[0];}),
+                function (thread) {return thread.author_id[1];});
+
+            return _.each(emails_from, function (email_from) {
+                if (!_.find(self.emails_from, function (from) {return from[0] == email_from;})) {
+                    self.emails_from.push([email_from, true]);
+                }
+            });
+        },
+
+        on_checked_email_from: function (event) {
+            var $input = $(event.target);
+            var email = $input.attr("data");
+            _.each(this.emails_from, function (email_from) {
+                if (email_from[0] == email) {
+                    email_from[1] = $input.is(":checked");
+                }
+            });
         }
     });
 
@@ -1477,7 +1519,7 @@
             $(window).resize( _.bind(this.thread.on_scroll, this.thread) );
             this.$el.resize( _.bind(this.thread.on_scroll, this.thread) );
             window.setTimeout( _.bind(this.thread.on_scroll, this.thread), 500 );
-        }
+        },
     });
 
 

=== modified file 'mail/static/src/js/mail_followers.js'
--- mail/static/src/js/mail_followers.js	2012-11-20 16:24:34 +0000
+++ mail/static/src/js/mail_followers.js	2012-12-20 14:32:39 +0000
@@ -69,27 +69,38 @@
             // event: click on a subtype, that (un)subscribe for this subtype
             this.$el.on('click', '.oe_subtype_list input', self.do_update_subscription);
             // event: click on 'invite' button, that opens the invite wizard
-            this.$('.oe_invite').on('click', function (event) {
-                action = {
-                    type: 'ir.actions.act_window',
-                    res_model: 'mail.wizard.invite',
-                    view_mode: 'form',
-                    view_type: 'form',
-                    views: [[false, 'form']],
-                    target: 'new',
-                    context: {
-                        'default_res_model': self.view.dataset.model,
-                        'default_res_id': self.view.datarecord.id,
-                    },
-                }
-                self.do_action(action, {
-                    on_close: function() {
-                        self.read_value();
-                    },
-                });
+            this.$('.oe_invite').on('click', self.on_invite_follower);
+            this.$el.on('click', '.oe_remove_follower', self.on_remove_follower);
+        },
+
+        on_invite_follower: function (event) {
+            var self = this;
+            var action = {
+                type: 'ir.actions.act_window',
+                res_model: 'mail.wizard.invite',
+                view_mode: 'form',
+                view_type: 'form',
+                views: [[false, 'form']],
+                target: 'new',
+                context: {
+                    'default_res_model': this.view.dataset.model,
+                    'default_res_id': this.view.datarecord.id,
+                },
+            }
+            this.do_action(action, {
+                on_close: function() {
+                    self.read_value();
+                },
             });
         },
 
+        on_remove_follower: function (event) {
+            var partner_id = $(event.target).data('id');
+            var context = new session.web.CompoundContext(this.build_context(), {});
+            return this.ds_model.call('message_unsubscribe', [[this.view.datarecord.id], [partner_id], context])
+                .then(this.proxy('read_value'));
+        },
+
         read_value: function () {
             var self = this;
             return this.ds_model.read_ids([this.view.datarecord.id], ['message_follower_ids']).then(function (results) {
@@ -151,7 +162,7 @@
             var node_user_list = this.$('.oe_follower_list').empty();
             this.$('.oe_follower_title').html(this._format_followers(records.length));
             // truncate number of displayed followers
-            truncated = records.splice(0, this.displayed_nb);
+            var truncated = records.splice(0, this.displayed_nb);
             _(truncated).each(function (record) {
                 record.avatar_url = mail.ChatterUtils.get_image(self.session, 'res.partner', 'image_small', record.id);
                 $(session.web.qweb.render('mail.followers.partner', {'record': record})).appendTo(node_user_list);
@@ -196,18 +207,24 @@
             var subtype_list_ul = this.$('.oe_subtype_list');
             subtype_list_ul.empty();
             var records = data[this.view.datarecord.id || this.view.dataset.ids[0]].message_subtype_data;
-            _(records).each(function (record, record_name) {
-                record.name = record_name;
-                record.followed = record.followed || undefined;
-                $(session.web.qweb.render('mail.followers.subtype', {'record': record})).appendTo( self.$('.oe_subtype_list') );
-            });
+            if (records.length > 1) {
+                _(records).each(function (record, record_name) {
+                    record.name = record_name;
+                    record.followed = record.followed || undefined;
+                    $(session.web.qweb.render('mail.followers.subtype', {'record': record})).appendTo( self.$('.oe_subtype_list') );
+                });
+            }
         },
 
         do_follow: function () {
-            _(this.$('.oe_msg_subtype_check')).each(function (record) {
+            var context = new session.web.CompoundContext(this.build_context(), {});
+            this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], [this.session.uid], undefined, context])
+                .then(this.proxy('read_value'));
+
+            _.each(this.$('.oe_subtype_list input'), function (record) {
+                console.log(record);
                 $(record).attr('checked', 'checked');
             });
-            this.do_update_subscription();
         },
         
         do_unfollow: function () {
@@ -229,9 +246,13 @@
                 }
             });
 
-            var context = new session.web.CompoundContext(this.build_context(), {});
-            return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], [this.session.uid], this.message_is_follower ? checklist : undefined, context])
-                .then(this.proxy('read_value'));
+            if (!checklist.length) {
+                this.do_unfollow();
+            } else {
+                var context = new session.web.CompoundContext(this.build_context(), {});
+                return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], [this.session.uid], checklist, context])
+                    .then(this.proxy('read_value'));
+            }
         },
     });
 };

=== modified file 'mail/static/src/xml/mail.xml'
--- mail/static/src/xml/mail.xml	2012-12-17 08:41:16 +0000
+++ mail/static/src/xml/mail.xml	2012-12-20 14:32:39 +0000
@@ -27,6 +27,11 @@
             <div class="oe_msg_center">
                 <div class="oe_msg_content">
                     <t t-call="mail.thread.list_recipients"/>
+                    <div class="oe_emails_from" t-if="widget.emails_from.length">
+                        <t t-foreach='widget.emails_from' t-as='email_from'>
+                            <label><input type="checkbox" t-att-checked="email_from[1] ? 'checked' : undefind" t-att-data="email_from[0]"/> <t t-raw="email_from[0]"/></label>
+                        </t>
+                    </div>
                     <textarea class="field_text"></textarea>
                 </div>
                 <div class="oe_msg_footer">
@@ -79,7 +84,7 @@
                         <img t-att-src="'/mail/static/src/img/mimetypes/' + attachment.filetype + '.png'"></img>
                         <div class='oe_name'><t t-raw='attachment.name' /></div>
                     </a>
-                    <div class='oe_delete oe_e' title="Delete this attachment" t-attf-data-id="{attachment.id}">[</div>
+                    <div class='oe_delete oe_e' title="Delete this attachment" t-att-data-id="attachment.id">[</div>
                     <div class='oe_progress_bar'>
                         uploading
                     </div>
@@ -91,7 +96,7 @@
                         <img t-att-src="widget.attachments_resize_image(attachment.id, [100,80])"></img>
                         <div class='oe_name'><t t-raw='attachment.name' /></div>
                     </a>
-                    <div class='oe_delete oe_e'>[</div>
+                    <div class='oe_delete oe_e' title="Delete this attachment" t-att-data-id="attachment.id">[</div>
                     <div class='oe_progress_bar'>
                         uploading
                     </div>

=== modified file 'mail/static/src/xml/mail_followers.xml'
--- mail/static/src/xml/mail_followers.xml	2012-11-21 12:33:46 +0000
+++ mail/static/src/xml/mail_followers.xml	2012-12-20 14:32:39 +0000
@@ -31,6 +31,7 @@
     <div t-name="mail.followers.partner" class='oe_partner'>
         <img class="oe_mail_thumbnail oe_mail_frame" t-attf-src="{record.avatar_url}"/>
         <a t-attf-href="#model=res.partner&amp;id=#{record.id}"><t t-raw="record.name"/></a>
+        <span class="oe_remove_follower oe_e" title="Remove this follower" t-att-data-id="record.id">X</span>
     </div>
     
     <!--

=== modified file 'note/static/src/css/note.css'
--- note/static/src/css/note.css	2012-11-15 12:38:51 +0000
+++ note/static/src/css/note.css	2012-12-20 14:32:39 +0000
@@ -4,7 +4,7 @@
 }
 
 .openerp .oe_form .oe_form_field.oe_memo {
-  margin: 0 -16px 0 -16px;
+  margin: 0;
   padding: 0px;
   width: 100%;
   min-height: 200px;

=== modified file 'note/static/src/css/note.sass'
--- note/static/src/css/note.sass	2012-11-15 12:38:51 +0000
+++ note/static/src/css/note.sass	2012-12-20 14:32:39 +0000
@@ -18,7 +18,7 @@
 .openerp
   .oe_form
     .oe_form_field.oe_memo
-      margin: 0 -16px 0 -16px
+      margin: 0
       padding: 0px
       width: 100%
       min-height: 200px

_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to     : openerp-dev-gtk@lists.launchpad.net
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help   : https://help.launchpad.net/ListHelp

Reply via email to