Index: CHANGELOG
===================================================================
--- CHANGELOG	(revision ac67db19802abd7d2a18c1bb804c3bfd887e9bdf)
+++ CHANGELOG	(revision 50f56d2046a28e7d8ae48e84ddd32dd022d9cf8d)
@@ -2,4 +2,5 @@
 ===========================
 
+- Allow inserting signatures above replied message body (#1484272) 
 - Managesieve 2.0: multi-script support
 - Fix imap_auth_type regression (#1486263)
Index: config/main.inc.php.dist
===================================================================
--- config/main.inc.php.dist	(revision f5d61d845f8cfce4c7b559a900df846947e45b00)
+++ config/main.inc.php.dist	(revision 50f56d2046a28e7d8ae48e84ddd32dd022d9cf8d)
@@ -451,4 +451,14 @@
 $rcmail_config['index_sort'] = TRUE;
 
+// When replying place cursor above original message (top posting)
+$rcmail_config['top_posting'] = FALSE;
+
+// Show signature:
+// 0 - Always
+// 1 - Never
+// 2 - New messages only
+// 3 - Forwards, Edits and Replies only
+$rcmail_config['show_sig'] = 0;
+
 // end of config file
 ?>
Index: program/js/app.js
===================================================================
--- program/js/app.js	(revision 06e07571b651f959620c31c0d030f1adf62b590f)
+++ program/js/app.js	(revision 50f56d2046a28e7d8ae48e84ddd32dd022d9cf8d)
@@ -473,4 +473,7 @@
     this.init_address_input_events($("[name='_cc']"));
     this.init_address_input_events($("[name='_bcc']"));
+
+    if (!html_mode)
+      this.set_caret_pos(input_message, this.env.top_posting ? 0 : $(input_message).val().length);
 
     // add signature according to selected identity
@@ -973,4 +976,8 @@
         break;
 
+      case 'insert-sig':
+        this.change_identity($("[name='_from']")[0], true);
+        break;
+
       case 'add-attachment':
         this.show_attachment_form(true);
@@ -2296,22 +2303,39 @@
     };
     
-  this.change_identity = function(obj)
+  this.change_identity = function(obj, show_sig)
     {
     if (!obj || !obj.options)
       return false;
 
+    if (!show_sig)
+      show_sig = this.env.show_sig;
+
     var id = obj.options[obj.selectedIndex].value;
-    var input_message = $("[name='_message']");
-    var message = input_message.val();
     var is_html = ($("input[name='_is_html']").val() == '1');
-    var sig, p, len;
+    var sig;
+
+    // enable manual signature insert
+    if (this.env.signatures && this.env.signatures[id])
+      this.enable_command('insert-sig', true);
+    else {
+      this.enable_command('insert-sig', false);
+      if (!this.env.signatures)
+        return true;
+      }
 
     if (!this.env.identity)
       this.env.identity = id
+
+    if (!show_sig)
+      return false;
   
     if (!is_html)
       {
+      var input_message = $("[name='_message']");
+      var message = input_message.val();
+      var pos, cursor_pos, p = -1;
+
       // remove the 'old' signature
-      if (this.env.identity && this.env.signatures && this.env.signatures[this.env.identity])
+      if (this.env.identity && this.env.signatures[this.env.identity])
         {
         if (this.env.signatures[this.env.identity]['is_html'])
@@ -2319,77 +2343,113 @@
         else
           sig = this.env.signatures[this.env.identity]['text'];
+
+	if (this.env.top_posting)
+          p = message.indexOf(sig);
+        else {
+	  if (sig.indexOf('-- ')!=0)
+            sig = '-- \n'+sig;
+          p = message.lastIndexOf(sig);
+	  }
+	  
+        if (p>=0)
+          message = message.substring(0, p) + message.substring(p+sig.length, message.length);
+	}
+
+      input_message.get(0).focus();
+
+      // add the new signature string
+      if (this.env.signatures[id])
+        {
+        if (this.env.signatures[id]['is_html'])
+          sig = this.env.signatures[id]['plain_text'];
+	else
+          sig = this.env.signatures[id]['text'];
+
+	if (this.env.top_posting) {
+	  if (p>=0) { // in place of removed signature
+	    message = message.substring(0, p) + sig + message.substring(p, message.length);
+	    cursor_pos = p - 1;
+	    }
+	  else if (pos = this.get_caret_pos(input_message.get(0))) { // at cursor position
+	    message = message.substring(0, pos) + '\n' + sig + '\n' + message.substring(pos, message.length);
+	    cursor_pos = pos;
+	    }
+	  else { // on top
+	    cursor_pos = 0;
+	    message = '\n\n' + sig + '\n' + message;
+	    }
+	  }
+	else {
+          message = message.replace(/[\r\n]+$/, '');
+
+          if (sig.indexOf('-- ')!=0)
+            sig = '-- \n'+sig;
+	  cursor_pos = message.length ? message.length+1 : 0;
+          message += '\n\n' + sig;
+	  }
+        }
+
+      input_message.val(message);
+
+      // move cursor before the signature
+      if (typeof(cursor_pos) != 'undefined')
+        this.set_caret_pos(input_message.get(0), cursor_pos);
+      }
+    // html
+    else
+      {
+      var editor = tinyMCE.get(this.env.composebody);
+      var sigElem = editor.dom.get('_rc_sig');
+
+      // Append the signature as a div within the body
+      if (!sigElem) {
+	var body = editor.getBody();
+	var doc = editor.getDoc();
         
-        if (sig.indexOf('-- ')!=0)
-          sig = '-- \n'+sig;
-
-        p = message.lastIndexOf(sig);
-        if (p>=0)
-          message = message.substring(0, p-1) + message.substring(p+sig.length, message.length);
-        }
-
-      message = message.replace(/[\r\n]+$/, '');
-      len = message.length;
-
-      // add the new signature string
-      if (this.env.signatures && this.env.signatures[id])
+	sigElem = doc.createElement('div');
+        sigElem.setAttribute('id', '_rc_sig');
+      
+        if (this.env.top_posting) {
+          // if no existing sig and top posting then insert at caret pos
+          editor.getWin().focus(); // correct focus in IE
+
+          var node = editor.selection.getNode();
+
+          if (node.nodeName == 'BODY') {
+            // no real focus, insert at start
+            body.insertBefore(sigElem, body.firstChild);
+            body.insertBefore(doc.createElement('br'), body.firstChild);
+            }
+          else {
+            body.insertBefore(sigElem, node.nextSibling);
+            body.insertBefore(doc.createElement('br'), node.nextSibling);
+            }
+	  }
+        else {
+	  if (bw.ie)
+            // add empty line before signature on IE
+            body.appendChild(doc.createElement('br'));
+
+          body.appendChild(sigElem);
+          }
+	}
+
+      if (this.env.signatures[id])
         {
-        sig = this.env.signatures[id]['text'];
-        if (this.env.signatures[id]['is_html'])
-          {
-          sig = this.env.signatures[id]['plain_text'];
+        if (this.env.signatures[id]['is_html']) {
+          sig = this.env.signatures[id]['text'];
+          if (!this.env.top_posting && this.env.signatures[id]['plain_text'].indexOf('-- ')!=0)
+            sig = '-- <br />' + sig;
+	  }
+	else {
+          sig = this.env.signatures[id]['text'];
+	  if (!this.env.top_posting && sig.indexOf('-- ')!=0)
+            sig = '-- \n' + sig;
+	  sig = '<pre>' + sig + '</pre>';
           }
-        if (sig.indexOf('-- ')!=0)
-          sig = '-- \n'+sig;
-        message += '\n\n'+sig;
-	if (len) len += 1;
-        }
-      }
-    else
-      {
-      var editor = tinyMCE.get(this.env.composebody);
-
-      if (this.env.signatures)
-        {
-        // Append the signature as a div within the body
-        var sigElem = editor.dom.get('_rc_sig');
-        var newsig = '';
-        var htmlsig = true;
-
-        if (!sigElem)
-          {
-          // add empty line before signature on IE
-          if (bw.ie)
-            editor.getBody().appendChild(editor.getDoc().createElement('br'));
-
-          sigElem = editor.getDoc().createElement('div');
-          sigElem.setAttribute('id', '_rc_sig');
-          editor.getBody().appendChild(sigElem);
-          }
-
-        if (this.env.signatures[id])
-        {
-          newsig = this.env.signatures[id]['text'];
-          htmlsig = this.env.signatures[id]['is_html'];
-
-          if (newsig) {
-            if (htmlsig && this.env.signatures[id]['plain_text'].indexOf('-- ')!=0)
-              newsig = '<p>-- </p>' + newsig;
-            else if (!htmlsig && newsig.indexOf('-- ')!=0)
-              newsig = '-- \n' + newsig;
-          }
-        }
-
-        if (htmlsig)
-          sigElem.innerHTML = newsig;
-        else
-          sigElem.innerHTML = '<pre>' + newsig + '</pre>';
-        }
-      }
-
-    input_message.val(message);
-
-    // move cursor before the signature
-    if (!is_html)
-      this.set_caret_pos(input_message.get(0), len);
+        
+        sigElem.innerHTML = sig;
+        }
+      }
 
     this.env.identity = id;
Index: program/localization/en_US/labels.inc
===================================================================
--- program/localization/en_US/labels.inc	(revision 1cead0cbf40468233f1f644ee6bf11835c74737a)
+++ program/localization/en_US/labels.inc	(revision 50f56d2046a28e7d8ae48e84ddd32dd022d9cf8d)
@@ -308,4 +308,9 @@
 $labels['displaynext'] = 'After message delete/move display the next message';
 $labels['indexsort'] = 'Use message index for sorting by date';
+$labels['top_posting'] = 'Start reply on top of the replied message body (not recommended)';
+$labels['auto_add_sig'] = 'Automatically add signature';
+$labels['new_msg_only'] = 'new messages only';
+$labels['reply_forward_only'] = 'edits, replies and forwards only';
+$labels['insertsig'] = 'Insert signature';
 $labels['mainoptions'] = 'Main Options';
 $labels['section'] = 'Section';
Index: program/localization/pl_PL/labels.inc
===================================================================
--- program/localization/pl_PL/labels.inc	(revision 1cead0cbf40468233f1f644ee6bf11835c74737a)
+++ program/localization/pl_PL/labels.inc	(revision 50f56d2046a28e7d8ae48e84ddd32dd022d9cf8d)
@@ -318,4 +318,9 @@
 $labels['newmessage'] = 'Nowa wiadomoÅÄ';
 $labels['listoptions'] = 'Opcje list';
+$labels['top_posting'] = 'Odpowiadaj powyÅŒej treÅci wiadomoÅci (niezalecane)';
+$labels['auto_add_sig'] = 'Automatycznie wstaw podpis';
+$labels['new_msg_only'] = 'tylko nowe wiadomoÅci';
+$labels['reply_forward_only'] = 'tylko dla edycji, przekazywania i odpowiedzi';
+$labels['insertsig'] = 'Wstaw podpis';
 
 ?>
Index: program/steps/mail/compose.inc
===================================================================
--- program/steps/mail/compose.inc	(revision 01ffe039089e08fd6faaf03f4170853defd41fc8)
+++ program/steps/mail/compose.inc	(revision 50f56d2046a28e7d8ae48e84ddd32dd022d9cf8d)
@@ -104,4 +104,5 @@
 // set current mailbox in client environment
 $OUTPUT->set_env('mailbox', $IMAP->get_mailbox_name());
+$OUTPUT->set_env('top_posting', $CONFIG['top_posting']);
 
 // get reference message and set compose mode
@@ -116,4 +117,11 @@
   $compose_mode = RCUBE_COMPOSE_DRAFT;
 }
+
+if (!$CONFIG['show_sig'])
+  $OUTPUT->set_env('show_sig', true);
+else if ($CONFIG['show_sig'] == 2 && empty($compose_mode))
+  $OUTPUT->set_env('show_sig', true);
+else if ($CONFIG['show_sig'] == 3 && ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD))
+  $OUTPUT->set_env('show_sig', true);
 
 if (!empty($msg_uid))
@@ -511,10 +519,12 @@
 function rcmail_create_reply_body($body, $bodyIsHtml)
 {
-  global $IMAP, $MESSAGE, $OUTPUT;
+  global $MESSAGE;
+  
+  $rcmail = rcmail::get_instance();
 
   if (! $bodyIsHtml)
   {
     // try to remove the signature
-    if (($sp = strrpos($body, '-- ')) !== false && ($sp == 0 || $body{$sp-1} == "\n"))
+    if (!$rcmail->config->get('top_posting') && ($sp = strrpos($body, '-- ')) !== false && ($sp == 0 || $body{$sp-1} == "\n"))
       {
       if ($body{$sp+3}==' ' || $body{$sp+3}=="\n" || $body{$sp+3}=="\r")
@@ -548,4 +558,7 @@
 
     $suffix = '';
+
+    if ($rcmail->config->get('top_posting'))
+      $prefix = "\n\n\n" . $prefix;
   }
   else
@@ -561,7 +574,14 @@
     $prefix = sprintf("On %s, %s wrote:<br />\n",
       $MESSAGE->headers->date,
-      htmlspecialchars(Q($MESSAGE->get_header('from'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset()));
+      htmlspecialchars(Q($MESSAGE->get_header('from'), 'replace'), ENT_COMPAT, $rcmail->output->get_charset()));
     $prefix .= '<blockquote type="cite" style="padding-left:5px; border-left:#1010ff 2px solid; margin-left:5px; width:100%">';
-    $suffix = "</blockquote><p></p>";
+
+    if ($rcmail->config->get('top_posting')) {
+	  $prefix = "<p></p>" . $prefix;
+	  $suffix = "</blockquote>";
+    }
+    else {
+      $suffix = "</blockquote><p></p>";
+    }
   }
 
Index: program/steps/settings/func.inc
===================================================================
--- program/steps/settings/func.inc	(revision 49771b1039b9beef6c78ecc1e52157384f8dcd8f)
+++ program/steps/settings/func.inc	(revision 50f56d2046a28e7d8ae48e84ddd32dd022d9cf8d)
@@ -449,4 +449,28 @@
       );
     }
+    
+    if (!isset($no_override['top_posting'])) {
+      $field_id = 'rcmfd_top_posting';
+      $input_topposting = new html_checkbox(array('name' => '_top_posting', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['top_posting'] = array(
+	'title' => html::label($field_id, Q(rcube_label('top_posting'))),
+	'content' => $input_topposting->show($config['top_posting']?1:0),
+      );
+    }
+
+    if (!isset($no_override['show_sig'])) {
+      $field_id = 'rcmfd_show_sig';
+      $select_show_sig = new html_select(array('name' => '_show_sig', 'id' => $field_id));
+      $select_show_sig->add(rcube_label('always'), 0);
+      $select_show_sig->add(rcube_label('never'), 1);
+      $select_show_sig->add(rcube_label('new_msg_only'), 2);
+      $select_show_sig->add(rcube_label('reply_forward_only'), 3);
+
+      $blocks['main']['options']['show_sig'] = array(
+	'title' => html::label($field_id, Q(rcube_label('auto_add_sig'))),
+        'content' => $select_show_sig->show(intval($config['show_sig'])),
+      );
+    }
 
     break;
Index: program/steps/settings/save_prefs.inc
===================================================================
--- program/steps/settings/save_prefs.inc	(revision 1cead0cbf40468233f1f644ee6bf11835c74737a)
+++ program/steps/settings/save_prefs.inc	(revision 50f56d2046a28e7d8ae48e84ddd32dd022d9cf8d)
@@ -63,4 +63,6 @@
       'draft_autosave'     => isset($_POST['_draft_autosave']) ? intval($_POST['_draft_autosave']) : 0,
       'mime_param_folding' => isset($_POST['_mime_param_folding']) ? intval($_POST['_mime_param_folding']) : 0,
+      'show_sig'           => isset($_POST['_show_sig']) ? intval($_POST['_show_sig']) : 0,
+      'top_posting'        => isset($_POST['_top_posting']) ? TRUE : FALSE,
     );
 
Index: skins/default/templates/compose.html
===================================================================
--- skins/default/templates/compose.html	(revision 09915f14307f179bb0744889c06147448d1ceb6f)
+++ skins/default/templates/compose.html	(revision 50f56d2046a28e7d8ae48e84ddd32dd022d9cf8d)
@@ -21,4 +21,5 @@
       <roundcube:button command="spellcheck" type="link" class="buttonPas spellcheck" classAct="button spellcheck" classSel="button spellcheckSel" title="checkspelling" content=" " />
       <roundcube:button command="add-attachment" type="link" class="buttonPas attach" classAct="button attach" classSel="button attachSel" title="addattachment" content=" " />
+      <roundcube:button command="insert-sig" type="link" class="buttonPas insertsig" classAct="button insertsig" classSel="button insertsigSel" title="insertsig" content=" " />
       <roundcube:button command="savedraft" type="link" class="buttonPas savedraft" classAct="button savedraft" classSel="button savedraftSel" title="savemessage" content=" " />
       <roundcube:container name="toolbar" id="compose-toolbar" />
