From e25a357d956c263c90f1c816395418ef4dbc2939 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Mon, 04 Oct 2010 08:27:06 -0400
Subject: [PATCH] - Add Reply-to-List feature (#1484252) - Add Mail-Followup-To/Mail-Reply-To support (#1485547)

---
 skins/default/common.css                 |   25 ++++
 CHANGELOG                                |    2 
 program/steps/mail/compose.inc           |   95 ++++++++++++++----
 skins/default/mail.css                   |    8 +
 program/steps/mail/show.inc              |    2 
 program/include/rcube_message.php        |    6 +
 skins/default/templates/message.html     |    3 
 program/steps/mail/sendmail.inc          |    5 +
 skins/default/includes/replyallmenu.html |    7 +
 skins/default/templates/mail.html        |    3 
 program/steps/mail/func.inc              |   36 +++++-
 program/localization/en_US/labels.inc    |   10 +
 skins/default/functions.js               |   14 +-
 skins/default/images/dbutton.png         |    0 
 skins/default/templates/compose.html     |   26 ++++-
 program/include/rcube_imap_generic.php   |    3 
 program/js/app.js                        |   35 +++++-
 17 files changed, 222 insertions(+), 58 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 4ad6024..b34b21c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,6 +17,8 @@
 - Fix "Server Error! (Not Found)" when using utils/save-pref action (#1487023)
 - Fix handling of Thunderbird's vCards (#1487024)
 - Fix mailto optional params in plain text messages aren't handled (#1487026)
+- Add Reply-to-List feature (#1484252)
+- Add Mail-Followup-To/Mail-Reply-To support (#1485547)
 
 RELEASE 0.4.1
 -------------
diff --git a/program/include/rcube_imap_generic.php b/program/include/rcube_imap_generic.php
index 160c154..95e1180 100644
--- a/program/include/rcube_imap_generic.php
+++ b/program/include/rcube_imap_generic.php
@@ -1071,7 +1071,8 @@
 	    $request .= "(DATE FROM TO SUBJECT REPLY-TO IN-REPLY-TO CC BCC ";
 	    $request .= "CONTENT-TRANSFER-ENCODING CONTENT-TYPE MESSAGE-ID ";
 	    $request .= "REFERENCES DISPOSITION-NOTIFICATION-TO X-PRIORITY ";
-	    $request .= "X-DRAFT-INFO".$add.")])";
+	    $request .= "X-DRAFT-INFO LIST-POST MAIL-FOLLOWUP-TO MAIL-REPLY-TO ";
+        $request .= "RETURN-PATH".$add.")])";
 
 	    if (!$this->putLine($request)) {
 		    return false;
diff --git a/program/include/rcube_message.php b/program/include/rcube_message.php
index 4351f17..6a6186d 100644
--- a/program/include/rcube_message.php
+++ b/program/include/rcube_message.php
@@ -115,7 +115,11 @@
      */
     public function get_header($name, $raw = false)
     {
-        $value = $this->headers->$name;
+        if ($this->headers->$name)
+            $value = $this->headers->$name;
+        else if ($this->headers->others[$name])
+            $value = $this->headers->others[$name];
+
         return $raw ? $value : $this->imap->decode_header($value);
     }
 
diff --git a/program/js/app.js b/program/js/app.js
index f4e8e2f..4388c50 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -199,11 +199,13 @@
         if (this.env.trash_mailbox && this.env.mailbox != this.env.trash_mailbox)
           this.set_alttext('delete', 'movemessagetotrash');
 
-        this.env.message_commands = ['show', 'reply', 'reply-all', 'forward', 'moveto', 'copy', 'delete',
-          'open', 'mark', 'edit', 'viewsource', 'download', 'print', 'load-attachment', 'load-headers'];
+        this.env.message_commands = ['show', 'reply', 'reply-all', 'reply-list', 'forward',
+          'moveto', 'copy', 'delete', 'open', 'mark', 'edit', 'viewsource', 'download',
+          'print', 'load-attachment', 'load-headers'];
 
         if (this.env.action=='show' || this.env.action=='preview') {
           this.enable_command(this.env.message_commands, this.env.uid);
+          this.enable_command('reply-list', this.env.list_post);
 
           if (this.env.next_uid) {
             this.enable_command('nextmessage', 'lastmessage', true);
@@ -882,10 +884,19 @@
         break;
 
       case 'reply-all':
+      case 'reply-list':
       case 'reply':
         var uid;
-        if (uid = this.get_single_uid())
-          this.goto_url('compose', '_reply_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(command=='reply-all' ? '&_all=1' : ''), true);
+        if (uid = this.get_single_uid()) {
+          var url = '_reply_uid='+uid+'&_mbox='+urlencode(this.env.mailbox);
+          if (command == 'reply-all')
+            // do reply-list, when list is detected and popup menu wasn't used 
+            url += '&_all=' + (!props && this.commands['reply-list'] ? 'list' : 'all');
+          else if (command == 'reply-list')
+            url += '&_all=list';
+
+          this.goto_url('compose', url, true);
+        }
         break;
 
       case 'forward':
@@ -1366,9 +1377,16 @@
     var selected = list.get_single_selection() != null;
 
     this.enable_command(this.env.message_commands, selected);
-    // Hide certain command buttons when Drafts folder is selected
-    if (selected && this.env.mailbox == this.env.drafts_mailbox) {
-      this.enable_command('reply', 'reply-all', 'forward', false);
+    if (selected) {
+      // Hide certain command buttons when Drafts folder is selected
+      if (this.env.mailbox == this.env.drafts_mailbox)
+        this.enable_command('reply', 'reply-all', 'reply-list', 'forward', false);
+      // Disable reply-list when List-Post header is not set
+      else {
+        var msg = this.env.messages[list.get_single_selection()];
+        if (!msg.ml)
+          this.enable_command('reply-list', false);
+      }
     }
     // Multi-message commands
     this.enable_command('delete', 'moveto', 'copy', 'mark', (list.selection.length > 0 ? true : false));
@@ -1546,6 +1564,7 @@
       unread_children: flags.unread_children?flags.unread_children:0,
       parent_uid: flags.parent_uid?flags.parent_uid:0,
       selected: this.select_all_mode || this.message_list.in_selection(uid),
+      ml: flags.ml?1:0,
       // flags from plugins
       flags: flags.extra_flags
     });
@@ -5015,6 +5034,8 @@
         if (this.env.action == 'show') {
           // re-enable commands on move/delete error
           this.enable_command(this.env.message_commands, true);
+          if (!this.env.list_post)
+            this.enable_command('reply-list', false);
         }
         else if (this.task == 'addressbook') {
           this.triggerEvent('listupdate', { folder:this.env.source, rowcount:this.contact_list.rowcount });
diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc
index 5287f8b..4de0515 100644
--- a/program/localization/en_US/labels.inc
+++ b/program/localization/en_US/labels.inc
@@ -46,6 +46,8 @@
 $labels['cc']      = 'Copy';
 $labels['bcc']     = 'Bcc';
 $labels['replyto'] = 'Reply-To';
+$labels['mailreplyto'] = 'Mail-Reply-To';
+$labels['mailfollowupto'] = 'Mail-Followup-To';
 $labels['date']    = 'Date';
 $labels['size']    = 'Size';
 $labels['priority'] = 'Priority';
@@ -53,6 +55,8 @@
 
 // aliases
 $labels['reply-to'] = $labels['replyto'];
+$labels['mailreply-to'] = $labels['mailreplyto'];
+$labels['mailfollowup-to'] = $labels['mailfollowupto'];
 
 $labels['mailboxlist'] = 'Folders';
 $labels['messagesfromto'] = 'Messages $from to $to of $count';
@@ -121,7 +125,9 @@
 $labels['checkmail']        = 'Check for new messages';
 $labels['writenewmessage']  = 'Create a new message';
 $labels['replytomessage']   = 'Reply to sender';
-$labels['replytoallmessage'] = 'Reply to sender and all recipients';
+$labels['replytoallmessage'] = 'Reply to list or to sender and all recipients';
+$labels['replyall']         = 'Reply all';
+$labels['replylist']        = 'Reply list';
 $labels['forwardmessage']   = 'Forward the message';
 $labels['deletemessage']    = 'Delete message';
 $labels['movemessagetotrash'] = 'Move message to trash';
@@ -233,6 +239,8 @@
 $labels['addcc'] = 'Add Cc';
 $labels['addbcc'] = 'Add Bcc';
 $labels['addreplyto'] = 'Add Reply-To';
+$labels['addmailreplyto'] = 'Add Mail-Reply-To';
+$labels['addmailfollowupto'] = 'Add Mail-Followup-To';
 
 // mdn
 $labels['mdnrequest'] = 'The sender of this message has asked to be notified when you read this message. Do you wish to notify the sender?';
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index b9594a0..c69a0a1 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -166,7 +166,7 @@
     $_SESSION['compose']['references']  = trim($MESSAGE->headers->references . " " . $MESSAGE->headers->messageID);
 
     if (!empty($_SESSION['compose']['param']['all']))
-      $MESSAGE->reply_all = 1;
+      $MESSAGE->reply_all = $_SESSION['compose']['param']['all'];
 
     $OUTPUT->set_env('compose_mode', 'reply');
   }
@@ -245,6 +245,24 @@
     case 'reply-to':
       $fname = '_replyto';
       $param = 'replyto';
+      $header = 'reply-to';
+
+    case 'mailreplyto':
+    case 'mailreply-to':
+      if (!$fname) {
+        $fname = '_mailreplyto';
+        $param = 'mailreplyto';
+        $header = 'mailreply-to';
+      }
+
+    case 'mailfollowupto':
+    case 'mailfollowup-to':
+      if (!$fname) {
+        $fname = '_mailfollowupto';
+        $param = 'mailfollowupto';
+        $header = 'mailfollowup-to';
+      }
+
       $allow_attrib = array('id', 'class', 'style', 'size', 'tabindex');
       $field_type = 'html_inputfield';
       break;
@@ -258,15 +276,26 @@
   }
   else if ($header && $compose_mode == RCUBE_COMPOSE_REPLY) {
     // get recipent address(es) out of the message headers
-    if ($header=='to' && !empty($MESSAGE->headers->replyto))
-      $fvalue = $MESSAGE->headers->replyto;
-    else if ($header=='to' && !empty($MESSAGE->headers->from))
-      $fvalue = $MESSAGE->headers->from;
+    if ($header == 'to') {
+      $mailfollowup = $MESSAGE->headers->others['mail-followup-to'];
+      $mailreplyto  = $MESSAGE->headers->others['mail-reply-to'];
+
+      if ($MESSAGE->reply_all == 'list' && $mailfollowup)
+        $fvalue = $mailfollowup;
+      else if ($MESSAGE->reply_all == 'list'
+        && preg_match('/<mailto:([^>]+)>/i', $MESSAGE->headers->others['list-post'], $m))
+        $fvalue = $m[1];
+      else if ($mailreplyto)
+        $fvalue = $mailreplyto;
+      else if (!empty($MESSAGE->headers->replyto))
+        $fvalue = $MESSAGE->headers->replyto;
+      else if (!empty($MESSAGE->headers->from))
+        $fvalue = $MESSAGE->headers->from;
+    }
     // add recipent of original message if reply to all
-    else if ($header=='cc' && !empty($MESSAGE->reply_all)) {
+    else if ($header == 'cc' && !empty($MESSAGE->reply_all) && $MESSAGE->reply_all != 'list') {
       if ($v = $MESSAGE->headers->to)
         $fvalue .= $v;
-
       if ($v = $MESSAGE->headers->cc)
         $fvalue .= (!empty($fvalue) ? ', ' : '') . $v;
     }
@@ -305,6 +334,12 @@
       $fvalue = $MESSAGE->get_header('cc');
     else if ($header=='bcc' && !empty($MESSAGE->headers->bcc))
       $fvalue = $MESSAGE->get_header('bcc');
+    else if ($header=='reply-to' && !empty($MESSAGE->headers->replyto))
+      $fvalue = $MESSAGE->get_header('reply-to');
+    else if ($header=='mail-reply-to' && !empty($MESSAGE->headers->others['mail-reply-to']))
+      $fvalue = $MESSAGE->get_header('followup-to');
+    else if ($header=='mail-followup-to' && !empty($MESSAGE->headers->others['mail-followup-to']))
+      $fvalue = $MESSAGE->get_header('mail-followup-to');
 
     $addresses = $IMAP->decode_address_list($fvalue);
     $fvalue = '';
@@ -364,7 +399,7 @@
     foreach ($a_to as $addr)
     {
       if (!empty($addr['mailto']))
-        $a_recipients[] = mb_strtolower(idn_to_utf8($addr['mailto']));
+        $a_recipients[] = strtolower($addr['mailto']);
     }
 
     if (!empty($MESSAGE->headers->cc))
@@ -373,7 +408,7 @@
       foreach ($a_cc as $addr)
       {
         if (!empty($addr['mailto']))
-          $a_recipients[] = mb_strtolower(idn_to_utf8($addr['mailto']));
+          $a_recipients[] = strtolower($addr['mailto']);
       }
     }
   }
@@ -383,17 +418,17 @@
 
   if (count($user_identities))
   {
-    $from_id = 0;
     $a_signatures = array();
 
     $field_attrib['onchange'] = JS_OBJECT_NAME.".change_identity(this)";
     $select_from = new html_select($field_attrib);
 
+    // create SELECT element
     foreach ($user_identities as $sql_arr)
     {
-      $sql_arr['email'] = mb_strtolower(idn_to_utf8($sql_arr['email']));
+      $email = mb_strtolower(idn_to_utf8($sql_arr['email']));
       $identity_id = $sql_arr['identity_id'];
-      $select_from->add(format_email_recipient($sql_arr['email'], $sql_arr['name']), $identity_id);
+      $select_from->add(format_email_recipient($email, $sql_arr['name']), $identity_id);
 
       // add signature to array
       if (!empty($sql_arr['signature']) && empty($_SESSION['compose']['param']['nosig']))
@@ -408,24 +443,38 @@
       }
 
       if ($compose_mode == RCUBE_COMPOSE_REPLY && is_array($MESSAGE->compose_from))
-        $MESSAGE->compose_from[] = $sql_arr['email'];
-
-      if (empty($_POST['_from']) && empty($_SESSION['compose']['param']['from']))
-      {
-        // set draft's identity
-        if ($compose_mode == RCUBE_COMPOSE_DRAFT && strstr($MESSAGE->headers->from, $sql_arr['email']))
-          $from_id = $sql_arr['identity_id'];
-        // set identity if it's one of the reply-message recipients (with prio for default identity)
-        else if (in_array($sql_arr['email'], $a_recipients) && (empty($from_id) || $sql_arr['standard']))
-          $from_id = $sql_arr['identity_id'];
-      }
+        $MESSAGE->compose_from[] = $email;
     }
+
+    $from_id = 0;
 
     // overwrite identity selection with post parameter
     if (!empty($_POST['_from']))
       $from_id = get_input_value('_from', RCUBE_INPUT_POST);
     else if (!empty($_SESSION['compose']['param']['from']))
       $from_id = $_SESSION['compose']['param']['from'];
+    else {
+      $return_path = $MESSAGE->headers->others['return-path'];
+
+      // Set identity
+      foreach ($user_identities as $sql_arr) {
+        // set draft's identity
+        if ($compose_mode == RCUBE_COMPOSE_DRAFT) {
+          if (strstr($MESSAGE->headers->from, $sql_arr['email']))
+            $from_id = $sql_arr['identity_id'];
+            break;
+        }
+        // set identity if it's one of the reply-message recipients (with prio for default identity)
+        else if (in_array($sql_arr['email'], $a_recipients) && (empty($from_id) || $sql_arr['standard']))
+          $from_id = $sql_arr['identity_id'];
+        // set identity when replying to mailing list
+        else if (strpos($return_path, str_replace('@', '=', $sql_arr['email']).'@') !== false)
+          $from_id = $sql_arr['identity_id'];
+
+        if ($from_id)
+          break;
+      }
+    }
 
     $out = $select_from->show($from_id);
 
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 2bb2dc8..aad127c 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -338,6 +338,8 @@
       $a_msg_flags['forwarded'] = 1;
     if ($header->flagged)
       $a_msg_flags['flagged'] = 1;
+    if ($header->others['list-post'])
+      $a_msg_flags['ml'] = 1;
     if (preg_match("/(application\/|multipart\/m)/i", $header->ctype))
       $a_msg_flags['attachment'] = 1;
     $a_msg_flags['mbox'] = $mbox;
@@ -942,33 +944,49 @@
     $headers = is_object($MESSAGE->headers) ? get_object_vars($MESSAGE->headers) : $MESSAGE->headers;
 
   // show these headers
-  $standard_headers = array('subject', 'from', 'to', 'cc', 'bcc', 'replyto', 'date');
+  $standard_headers = array('subject', 'from', 'to', 'cc', 'bcc', 'replyto',
+    'mail-reply-to', 'mail-followup-to', 'date');
   $output_headers = array();
 
   foreach ($standard_headers as $hkey) {
-    if (!$headers[$hkey])
+    if ($headers[$hkey])
+      $value = $headers[$hkey];
+    else if ($headers['others'][$hkey])
+      $value = $headers['others'][$hkey];
+    else
       continue;
 
     if ($hkey == 'date') {
       if ($PRINT_MODE)
-        $header_value = format_date($headers[$hkey], $RCMAIL->config->get('date_long', 'x'));
+        $header_value = format_date($value, $RCMAIL->config->get('date_long', 'x'));
       else
-        $header_value = format_date($headers[$hkey]);
+        $header_value = format_date($value);
     }
     else if ($hkey == 'replyto') {
       if ($headers['replyto'] != $headers['from'])
-        $header_value = rcmail_address_string($headers['replyto'], null, true, $attrib['addicon']);
+        $header_value = rcmail_address_string($value, null, true, $attrib['addicon']);
       else
         continue;
     }
+    else if ($hkey == 'mail-reply-to') {
+      if ($headers['mail-replyto'] != $headers['reply-to']
+        && $headers['reply-to'] != $headers['from']
+      )
+        $header_value = rcmail_address_string($value, null, true, $attrib['addicon']);
+      else
+        continue;
+    }
+    else if ($hkey == 'mail-followup-to') {
+      $header_value = rcmail_address_string($value, null, true, $attrib['addicon']);
+    }
     else if (in_array($hkey, array('from', 'to', 'cc', 'bcc')))
-      $header_value = rcmail_address_string($headers[$hkey], null, true, $attrib['addicon']);
-    else if ($hkey == 'subject' && empty($headers[$hkey]))
+      $header_value = rcmail_address_string($value, null, true, $attrib['addicon']);
+    else if ($hkey == 'subject' && empty($value))
       $header_value = rcube_label('nosubject');
     else
-      $header_value = trim($IMAP->decode_header($headers[$hkey]));
+      $header_value = trim($IMAP->decode_header($value));
 
-    $output_headers[$hkey] = array('title' => rcube_label($hkey), 'value' => $header_value, 'raw' => $headers[$hkey]);
+    $output_headers[$hkey] = array('title' => rcube_label($hkey), 'value' => $header_value, 'raw' => $value);
   }
 
   $plugin = $RCMAIL->plugins->exec_hook('message_headers_output', array('output' => $output_headers, 'headers' => $MESSAGE->headers));
diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index 45afa04..a9ecf2e 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -314,6 +314,11 @@
 else if (!empty($identity_arr['reply-to']))
   $headers['Reply-To'] = rcmail_email_input_format($identity_arr['reply-to'], false, true);
 
+if (!empty($_POST['_mailfollowupto']))
+  $headers['Mail-Followup-To'] = rcmail_email_input_format(get_input_value('_mailfollowupto', RCUBE_INPUT_POST, TRUE, $message_charset));
+if (!empty($_POST['_mailreplyto']))
+  $headers['Mail-Reply-To'] = rcmail_email_input_format(get_input_value('_mailreplyto', RCUBE_INPUT_POST, TRUE, $message_charset));
+
 if (!empty($_SESSION['compose']['reply_msgid']))
   $headers['In-Reply-To'] = $_SESSION['compose']['reply_msgid'];
 
diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc
index bc208ab..3b357ac 100644
--- a/program/steps/mail/show.inc
+++ b/program/steps/mail/show.inc
@@ -61,6 +61,8 @@
     $OUTPUT->set_env('skip_deleted', true);
   if ($CONFIG['display_next'])
     $OUTPUT->set_env('display_next', true);
+  if ($MESSAGE->headers->others['list-post'])
+    $OUTPUT->set_env('list_post', true);
 
   if (!$OUTPUT->ajax_call)
     $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash', 'movingmessage');
diff --git a/skins/default/common.css b/skins/default/common.css
index 4a91552..c068ca2 100644
--- a/skins/default/common.css
+++ b/skins/default/common.css
@@ -462,6 +462,30 @@
   background-color: #F2F2F2 !important;
 }
 
+.dropbutton,
+.dropbutton span
+{
+  float: left;
+  height: 32px;
+}
+
+.dropbutton:hover
+{
+  background: url(images/dbutton.png) 0 0 no-repeat transparent;
+}
+
+.dropbutton span
+{
+  width: 9px;
+  background: url(images/dbutton.png) -53px 0 no-repeat transparent;
+}
+
+.dropbutton span:hover
+{
+  cursor: pointer;
+  background-position: -64px 0;
+}
+
 
 /***** common table settings ******/
 
@@ -752,4 +776,3 @@
 {
   font-weight: bold;
 }
-  
\ No newline at end of file
diff --git a/skins/default/functions.js b/skins/default/functions.js
index 4615a46..64a6d99 100644
--- a/skins/default/functions.js
+++ b/skins/default/functions.js
@@ -29,6 +29,7 @@
 {
   this.popups = {
     markmenu:       {id:'markmessagemenu'},
+    replyallmenu:   {id:'replyallmenu'},
     searchmenu:     {id:'searchmenu', editable:1},
     messagemenu:    {id:'messagemenu'},
     listmenu:       {id:'listmenu', editable:1},
@@ -293,16 +294,15 @@
 /* Message composing */
 init_compose_form: function()
 {
-  var cc_field = document.getElementById('_cc'),
-    bcc_field = document.getElementById('_bcc'),
+  var f, field, fields = ['cc', 'bcc', 'replyto', 'mailreplyto', 'mailfollowupto'],
     div = document.getElementById('compose-div'),
     headers_div = document.getElementById('compose-headers-div');
 
-  if (cc_field && cc_field.value != '')
-    rcmail_ui.show_header_form('cc');
-
-  if (bcc_field && bcc_field.value != '')
-    rcmail_ui.show_header_form('bcc');
+  // Show input elements with non-empty value
+  for (f=0; f<fields.length; f++) {
+    if ((field = $('#_'+fields[f])) && field.length && field.val() != '')
+      rcmail_ui.show_header_form(fields[f]);
+  }
 
   // prevent from form data loss when pressing ESC key in IE
   if (bw.ie) {
diff --git a/skins/default/images/dbutton.png b/skins/default/images/dbutton.png
new file mode 100644
index 0000000..31f9d63
--- /dev/null
+++ b/skins/default/images/dbutton.png
Binary files differ
diff --git a/skins/default/includes/replyallmenu.html b/skins/default/includes/replyallmenu.html
new file mode 100644
index 0000000..5cf1236
--- /dev/null
+++ b/skins/default/includes/replyallmenu.html
@@ -0,0 +1,7 @@
+<div id="replyallmenu" class="popupmenu">
+    <ul>
+        <li><roundcube:button command="reply-all" label="replyall" prop="sub" classAct="replyalllink active" class="replyalllink" /></li>
+        <li><roundcube:button command="reply-list" label="replylist" prop="sub" classAct="replylistlink active" class="replylistlink" /></li>
+        <roundcube:container name="replyallmenu" id="replyallmenu" />
+    </ul>
+</div>
diff --git a/skins/default/mail.css b/skins/default/mail.css
index 8baf836..84313a8 100644
--- a/skins/default/mail.css
+++ b/skins/default/mail.css
@@ -13,7 +13,7 @@
 /*  border: 1px solid #cccccc; */
 }
 
-#messagetoolbar > a
+#messagetoolbar a
 {
   display: block;
   float: left;
@@ -27,7 +27,7 @@
   width: 32px;
   height: 32px;
   padding: 0;
-  margin-right: 10px;
+  margin: 0 5px;
   overflow: hidden;
   background: url(images/mail_toolbar.png) 0 0 no-repeat transparent;
   opacity: 0.99; /* this is needed to make buttons appear correctly in Chrome */
@@ -1228,7 +1228,9 @@
 
 #compose-cc,
 #compose-bcc,
-#compose-replyto
+#compose-replyto,
+#compose-mailreplyto,
+#compose-mailfollowupto
 {
   display: none;
 }
diff --git a/skins/default/templates/compose.html b/skins/default/templates/compose.html
index 2e08b86..f99afdd 100644
--- a/skins/default/templates/compose.html
+++ b/skins/default/templates/compose.html
@@ -78,6 +78,18 @@
                 <label for="_replyto"><roundcube:label name="replyto" /></label>
             </td>
             <td class="editfield"><roundcube:object name="composeHeaders" part="replyto" form="form" id="_replyto" size="70" tabindex="5" /></td>
+        </tr><tr id="compose-mailreplyto">
+            <td class="title top">
+                <a href="#mailreplyto" onclick="return rcmail_ui.hide_header_form('mailreplyto');"><img src="/images/icons/minus.gif" alt="" title="<roundcube:label name='delete' />" /></a>
+                <label for="_mailreplyto"><roundcube:label name="mailreplyto" /></label>
+            </td>
+            <td class="editfield"><roundcube:object name="composeHeaders" part="mailreplyto" form="form" id="_mailreplyto" size="70" tabindex="6" /></td>
+        </tr><tr id="compose-mailfollowupto">
+            <td class="title top">
+                <a href="#mailfollowupto" onclick="return rcmail_ui.hide_header_form('mailfollowupto');"><img src="/images/icons/minus.gif" alt="" title="<roundcube:label name='delete' />" /></a>
+                <label for="_mailfollowupto"><roundcube:label name="mailfollowupto" /></label>
+            </td>
+            <td class="editfield"><roundcube:object name="composeHeaders" part="mailfollowupto" form="form" id="_mailfollowupto" size="70" tabindex="7" /></td>
         </tr><tr>
             <td></td>
             <td class="formlinks">
@@ -86,27 +98,31 @@
                 <a href="#bcc" onclick="return rcmail_ui.show_header_form('bcc')" id="bcc-link"><roundcube:label name="addbcc" /></a>
                 <span class="separator">|</span>
                 <a href="#reply-to" onclick="return rcmail_ui.show_header_form('replyto')" id="replyto-link"><roundcube:label name="addreplyto" /></a>
+                <span class="separator">|</span>
+                <a href="#mailreply-to" onclick="return rcmail_ui.show_header_form('mailreplyto')" id="mailreplyto-link"><roundcube:label name="addmailreplyto" /></a>
+                <span class="separator">|</span>
+                <a href="#mailfollowup-to" onclick="return rcmail_ui.show_header_form('mailfollowupto')" id="mailfollowupto-link"><roundcube:label name="addmailfollowupto" /></a>
             </td>
         </tr><tr>
             <td class="title"><label for="compose-subject"><roundcube:label name="subject" /></label></td>
-            <td class="editfield"><roundcube:object name="composeSubject" id="compose-subject" form="form" tabindex="6" /></td>
+            <td class="editfield"><roundcube:object name="composeSubject" id="compose-subject" form="form" tabindex="8" /></td>
         </tr>
         </table>
     </div>
     <div id="compose-div">
         <div class="boxlistcontent" style="overflow: hidden; top: 0">
-            <roundcube:object name="composeBody" id="compose-body" form="form" cols="70" rows="20" tabindex="7" />
+            <roundcube:object name="composeBody" id="compose-body" form="form" cols="70" rows="20" tabindex="9" />
         </div>
         <div class="boxfooter">
             <div id="compose-buttons">
-                <roundcube:button type="input" command="send" class="button mainaction" label="sendmessage" tabindex="8" />
-                <roundcube:button type="input" command="list" class="button" label="cancel" tabindex="9" />
+                <roundcube:button type="input" command="send" class="button mainaction" label="sendmessage" tabindex="10" />
+                <roundcube:button type="input" command="list" class="button" label="cancel" tabindex="11" />
             </div>
             <div id="compose-editorfooter">
                 <span id="spellcheck-control" style="margin-right:10px"></span>
                 <span>
                     <label><roundcube:label name="editortype" /></label>
-                    <roundcube:object name="editorSelector" editorid="compose-body" tabindex="10" />
+                    <roundcube:object name="editorSelector" editorid="compose-body" tabindex="12" />
                 </span>
             </div>
         </div>
diff --git a/skins/default/templates/mail.html b/skins/default/templates/mail.html
index 55fbc73..a084728 100644
--- a/skins/default/templates/mail.html
+++ b/skins/default/templates/mail.html
@@ -120,7 +120,9 @@
 <roundcube:button command="checkmail" type="link" class="button checkmail" classAct="button checkmail" classSel="button checkmailSel" title="checkmail" content=" " />
 <roundcube:button command="compose" type="link" class="button compose" classAct="button compose" classSel="button composeSel" title="writenewmessage" content=" " />
 <roundcube:button command="reply" type="link" class="buttonPas reply" classAct="button reply" classSel="button replySel" title="replytomessage" content=" " />
+<span class="dropbutton">
 <roundcube:button command="reply-all" type="link" class="buttonPas replyAll" classAct="button replyAll" classSel="button replyAllSel" title="replytoallmessage" content=" " />
+<span id="replyallmenulink" onclick="rcmail_ui.show_popup('replyallmenu');return false"></span></span>
 <roundcube:button command="forward" type="link" class="buttonPas forward" classAct="button forward" classSel="button forwardSel" title="forwardmessage" content=" " />
 <roundcube:button command="delete" type="link" class="buttonPas delete" classAct="button delete" classSel="button deleteSel" title="deletemessage" content=" " />
 <roundcube:container name="toolbar" id="messagetoolbar" />
@@ -138,6 +140,7 @@
   </ul>
 </div>
 
+<roundcube:include file="/includes/replyallmenu.html" />
 <roundcube:include file="/includes/messagemenu.html" />
 
 <div id="searchmenu" class="popupmenu">
diff --git a/skins/default/templates/message.html b/skins/default/templates/message.html
index 6bc1e29..809da33 100644
--- a/skins/default/templates/message.html
+++ b/skins/default/templates/message.html
@@ -21,7 +21,9 @@
 <roundcube:button command="list" type="link" class="button back" classAct="button back" classSel="button backSel" title="backtolist" content=" " />
 <roundcube:button command="compose" type="link" class="button compose" classAct="button compose" classSel="button composeSel" title="writenewmessage" content=" " />
 <roundcube:button command="reply" type="link" class="buttonPas reply" classAct="button reply" classSel="button replySel" title="replytomessage" content=" " />
+<span class="dropbutton">
 <roundcube:button command="reply-all" type="link" class="buttonPas replyAll" classAct="button replyAll" classSel="button replyAllSel" title="replytoallmessage" content=" " />
+<span id="replyallmenulink" onclick="rcmail_ui.show_popup('replyallmenu');return false"></span></span>
 <roundcube:button command="forward" type="link" class="buttonPas forward" classAct="button forward" classSel="button forwardSel" title="forwardmessage" content=" " />
 <roundcube:button command="delete" type="link" class="buttonPas delete" classAct="button delete" classSel="button deleteSel" title="deletemessage" content=" " />
 <roundcube:container name="toolbar" id="messagetoolbar" />
@@ -29,6 +31,7 @@
 <roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('moveto', this.options[this.selectedIndex].value)" class="mboxlist" />
 </div>
 
+<roundcube:include file="/includes/replyallmenu.html" />
 <roundcube:include file="/includes/messagemenu.html" />
 
 <div id="mainscreen">

--
Gitblit v1.9.1