From ddafe4e4109a8d6d412c3c138412ee2ca3d58dbf Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Sat, 27 Oct 2012 10:12:37 -0400
Subject: [PATCH] Merge branch 'dev-compose-newwindow'

---
 program/steps/mail/compose.inc              |   19 +
 program/steps/addressbook/mailto.inc        |    2 
 skins/classic/common.css                    |    5 
 program/steps/mail/show.inc                 |    1 
 skins/larry/ie7hacks.css                    |    4 
 program/localization/de_CH/labels.inc       |    5 
 program/localization/es_ES/labels.inc       |    1 
 program/localization/it_IT/labels.inc       |    1 
 skins/larry/templates/messagepreview.html   |    4 
 program/localization/de_DE/labels.inc       |    5 
 skins/classic/mail.css                      |   19 +
 program/localization/pt_BR/labels.inc       |    1 
 program/steps/mail/func.inc                 |   17 -
 program/steps/settings/func.inc             |   24 ++
 skins/classic/templates/message.html        |    7 
 program/localization/ru_RU/labels.inc       |    1 
 skins/larry/includes/header.html            |   10 
 skins/larry/templates/compose.html          |  110 +++++----
 skins/larry/templates/message.html          |   12 
 program/steps/addressbook/func.inc          |    1 
 skins/classic/templates/compose.html        |   10 
 skins/larry/svggradients.css                |    2 
 config/main.inc.php.dist                    |    6 
 program/include/rcube_message.php           |   20 -
 program/localization/nl_NL/labels.inc       |    1 
 program/steps/settings/save_prefs.inc       |    2 
 skins/larry/iehacks.css                     |    6 
 program/include/rcube_output_html.php       |   11 
 program/localization/en_US/labels.inc       |    5 
 skins/larry/styles.css                      |   25 ++
 skins/larry/images/buttons.png              |    0 
 program/js/app.js                           |  153 ++++++++++---
 skins/larry/mail.css                        |  106 +++++---
 skins/classic/includes/messagetoolbar.html  |    6 
 skins/classic/templates/messagepreview.html |    2 
 skins/larry/ui.js                           |   20 +
 36 files changed, 421 insertions(+), 203 deletions(-)

diff --git a/config/main.inc.php.dist b/config/main.inc.php.dist
index 2ee4ccd..dafee72 100644
--- a/config/main.inc.php.dist
+++ b/config/main.inc.php.dist
@@ -730,6 +730,12 @@
 // 2 - Always show inline images
 $rcmail_config['show_images'] = 0;
 
+// open messages in new window
+$rcmail_config['message_extwin'] = false;
+
+// open message compose form in new window
+$rcmail_config['compose_extwin'] = false;
+
 // compose html formatted messages by default
 // 0 - never, 1 - always, 2 - on reply to HTML message, 3 - on forward or reply to HTML message
 $rcmail_config['htmleditor'] = 0;
diff --git a/program/include/rcube_message.php b/program/include/rcube_message.php
index d15cc75..38d1817 100644
--- a/program/include/rcube_message.php
+++ b/program/include/rcube_message.php
@@ -210,26 +210,16 @@
                 if (!$recursive) {
                     $level = explode('.', $part->mime_id);
 
-                    // Level too high
-                    if (count($level) > 2) {
+                    // Skip if level too deep or part has a file name
+                    if (count($level) > 2 || $part->filename) {
                         continue;
                     }
 
                     // HTML part can be on the lower level, if not...
                     if (count($level) > 1) {
-                        // It can be an alternative or related message part
-                        // find parent part
-                        $parent = null;
-                        foreach ($this->mime_parts as $part) {
-                            if ($part->mime_id == $level[0]) {
-                                $parent = $part;
-                            }
-                        }
-
-                        if (!$parent) {
-                            continue;
-                        }
-
+                        array_pop($level);
+                        $parent = $this->mime_parts[join('.', $level)];
+                        // ... parent isn't multipart/alternative or related
                         if ($parent->mimetype != 'multipart/alternative' && $parent->mimetype != 'multipart/related') {
                             continue;
                         }
diff --git a/program/include/rcube_output_html.php b/program/include/rcube_output_html.php
index 2e3cd50..d421718 100644
--- a/program/include/rcube_output_html.php
+++ b/program/include/rcube_output_html.php
@@ -77,6 +77,9 @@
         $this->set_skin($skin);
         $this->set_env('skin', $skin);
 
+        if (!empty($_REQUEST['_extwin']))
+          $this->set_env('extwin', 1);
+
         // add common javascripts
         $this->add_script('var '.rcmail::JS_OBJECT_NAME.' = new rcube_webmail();', 'head_top');
 
@@ -298,6 +301,8 @@
      */
     public function redirect($p = array(), $delay = 1)
     {
+        if ($this->env['extwin'])
+            $p['extwin'] = 1;
         $location = $this->app->url($p);
         header('Location: ' . $location);
         exit;
@@ -1068,7 +1073,7 @@
             else if (in_array($attrib['command'], $a_static_commands)) {
                 $attrib['href'] = $this->app->url(array('action' => $attrib['command']));
             }
-            else if ($attrib['command'] == 'permaurl' && !empty($this->env['permaurl'])) {
+            else if (($attrib['command'] == 'permaurl' || $attrib['command'] == 'extwin') && !empty($this->env['permaurl'])) {
               $attrib['href'] = $this->env['permaurl'];
             }
         }
@@ -1380,6 +1385,10 @@
         $hiddenfield = new html_hiddenfield(array('name' => '_framed', 'value' => '1'));
         $hidden = $hiddenfield->show();
       }
+      if ($this->env['extwin']) {
+        $hiddenfield = new html_hiddenfield(array('name' => '_extwin', 'value' => '1'));
+        $hidden = $hiddenfield->show();
+      }
 
       if (!$content)
         $attrib['noclose'] = true;
diff --git a/program/js/app.js b/program/js/app.js
index 8296400..783936c 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -176,10 +176,10 @@
     }
 
     // enable general commands
-    this.enable_command('logout', 'mail', 'addressbook', 'settings', 'save-pref', 'compose', 'undo', 'about', 'switch-task', true);
+    this.enable_command('close', 'logout', 'mail', 'addressbook', 'settings', 'save-pref', 'compose', 'undo', 'about', 'switch-task', true);
 
     if (this.env.permaurl)
-      this.enable_command('permaurl', true);
+      this.enable_command('permaurl', 'extwin', true);
 
     switch (this.task) {
 
@@ -249,7 +249,7 @@
           }
         }
         else if (this.env.action == 'compose') {
-          this.env.compose_commands = ['send-attachment', 'remove-attachment', 'send', 'cancel', 'toggle-editor', 'list-adresses'];
+          this.env.compose_commands = ['send-attachment', 'remove-attachment', 'send', 'cancel', 'toggle-editor', 'list-adresses', 'extwin'];
 
           if (this.env.drafts_mailbox)
             this.env.compose_commands.push('savedraft')
@@ -570,6 +570,19 @@
           parent.location.href = this.env.permaurl;
         break;
 
+      case 'extwin':
+        if (this.env.action == 'compose') {
+          var prevstate = this.env.compose_extwin;
+          $("input[name='_action']", this.gui_objects.messageform).val('compose');
+          this.gui_objects.messageform.action = this.url('mail/compose', { _id: this.env.compose_id, _extwin: 1 });
+          this.gui_objects.messageform.target = this.open_window('', 1150, 900);
+          this.gui_objects.messageform.submit();
+        }
+        else {
+          this.open_window(this.env.permaurl, 1000, 1200);
+        }
+        break;
+
       case 'menu-open':
       case 'menu-save':
         this.triggerEvent(command, {props:props});
@@ -582,10 +595,18 @@
         }
         break;
 
+      case 'close':
+        if (this.env.extwin)
+          window.close();
+        break;
+
       case 'list':
         if (props && props != '')
           this.reset_qsearch();
-        if (this.task == 'mail') {
+        if (this.env.action == 'compose' && this.env.extwin) {
+          window.close();
+        }
+        else if (this.task == 'mail') {
           this.list_mailbox(props);
           this.set_button_titles();
         }
@@ -640,7 +661,7 @@
           uid = this.get_single_uid();
           if (uid && (!this.env.uid || uid != this.env.uid)) {
             if (this.env.mailbox == this.env.drafts_mailbox)
-              this.goto_url('compose', { _draft_uid: uid, _mbox: this.env.mailbox }, true);
+              this.open_compose_step({ _draft_uid: uid, _mbox: this.env.mailbox });
             else
               this.show_message(uid);
           }
@@ -669,7 +690,7 @@
         else if (this.task == 'mail' && (cid = this.get_single_uid())) {
           url = { _mbox: this.env.mailbox };
           url[this.env.mailbox == this.env.drafts_mailbox && props != 'new' ? '_draft_uid' : '_uid'] = cid;
-          this.goto_url('compose', url, true);
+          this.open_compose_step(url);
         }
         break;
 
@@ -862,47 +883,46 @@
         break;
 
       case 'compose':
-        url = this.url('mail/compose');
+        url = {};
 
         if (this.task == 'mail') {
-          url += '&_mbox='+urlencode(this.env.mailbox);
+          url._mbox = this.env.mailbox;
           if (props)
-             url += '&_to='+urlencode(props);
+             url._to = props;
           // also send search request so we can go back to search result after message is sent
           if (this.env.search_request)
-            url += '&_search='+this.env.search_request;
+            url._search = this.env.search_request;
         }
         // modify url if we're in addressbook
         else if (this.task == 'addressbook') {
           // switch to mail compose step directly
           if (props && props.indexOf('@') > 0) {
-            url = this.get_task_url('mail', url);
-            this.redirect(url + '&_to='+urlencode(props));
+            url._to = props;
+          }
+          else {
+            // use contact_id passed as command parameter
+            var n, len, a_cids = [];
+            if (props)
+              a_cids.push(props);
+            // get selected contacts
+            else if (this.contact_list) {
+              var selection = this.contact_list.get_selection();
+              for (n=0, len=selection.length; n<len; n++)
+                a_cids.push(selection[n]);
+            }
+
+            if (a_cids.length)
+              this.http_post('mailto', { _cid: a_cids.join(','), _source: this.env.source, }, true);
+            else if (this.env.group)
+              this.http_post('mailto', { _gid: this.env.group, _source: this.env.source }, true);
+
             break;
           }
-
-          // use contact_id passed as command parameter
-          var n, len, a_cids = [];
-          if (props)
-            a_cids.push(props);
-          // get selected contacts
-          else if (this.contact_list) {
-            var selection = this.contact_list.get_selection();
-            for (n=0, len=selection.length; n<len; n++)
-              a_cids.push(selection[n]);
-          }
-
-          if (a_cids.length)
-            this.http_post('mailto', { _cid: a_cids.join(','), _source: this.env.source}, true);
-          else if (this.env.group)
-            this.http_post('mailto', { _gid: this.env.group, _source: this.env.source}, true);
-
-          break;
         }
         else if (props)
-          url += '&_to='+urlencode(props);
+          url._to = props;
 
-        this.redirect(url);
+        this.open_compose_step(url);
         break;
 
       case 'spellcheck':
@@ -977,7 +997,7 @@
           else if (command == 'reply-list')
             url._all = 'list';
 
-          this.goto_url('compose', url, true);
+          this.open_compose_step(url);
         }
         break;
 
@@ -987,7 +1007,7 @@
           url = { _forward_uid: uid, _mbox: this.env.mailbox };
           if (command == 'forward-attachment' || (!props && this.env.forward_attachment))
             url._attachment = 1;
-          this.goto_url('compose', url, true);
+          this.open_compose_step(url);
         }
         break;
 
@@ -1561,7 +1581,7 @@
 
     var uid = list.get_single_selection();
     if (uid && this.env.mailbox == this.env.drafts_mailbox)
-      this.goto_url('compose', { _draft_uid: uid, _mbox: this.env.mailbox }, true);
+      this.open_compose_step({ _draft_uid: uid, _mbox: this.env.mailbox });
     else if (uid)
       this.show_message(uid, false, false);
   };
@@ -1641,6 +1661,28 @@
     }
 
     return allow ? (copy ? 2 : 1) : 0;
+  };
+
+  this.open_window = function(url, width, height)
+  {
+    var w = Math.min(width, screen.width - 10),
+      h = Math.min(height, screen.height - 100),
+      l = (screen.width - w) / 2 + (screen.left || 0),
+      t = Math.max(0, (screen.height - h) / 2 + (screen.top || 0) - 20);
+
+    var wname = 'rcmextwin' + new Date().getTime(),
+      extwin = window.open(url + '&_extwin=1', wname, 'width='+w+',height='+h+',top='+t+',left='+l+',resizable=yes,toolbar=no,status=no');
+    extwin.moveTo(l,t);
+
+    // write loading... message to empty windows
+    if (!url && extwin.document) {
+      extwin.document.write('<html><body>' + this.get_label('loading') + '</body></html>');
+    }
+
+    // focus window, delayed to bring to front
+    window.setTimeout(function(){ extwin.focus(); }, 10);
+
+    return wname;
   };
 
 
@@ -1906,7 +1948,7 @@
       this.list_mailbox('', '', sort_col+'_'+sort_order, post_data);
   };
 
-  // when user doble-clicks on a row
+  // when user double-clicks on a row
   this.show_message = function(id, safe, preview)
   {
     if (!id)
@@ -1931,10 +1973,17 @@
     // add browser capabilities, so we can properly handle attachments
     url += '&_caps='+urlencode(this.browser_capabilities());
 
-    if (preview && String(target.location.href).indexOf(url) >= 0)
+    if (this.env.extwin)
+      url += '&_extwin=1';
+
+    if (preview && String(target.location.href).indexOf(url) >= 0) {
       this.show_contentframe(true);
+    }
     else {
-      this.location_href(this.env.comm_path+url, target, true);
+      if (!preview && this.env.message_extwin && !this.env.extwin)
+        this.open_window(this.env.comm_path+url, 1000, 1200);
+      else
+        this.location_href(this.env.comm_path+url, target, true);
 
       // mark as read and change mbox unread counter
       if (preview && this.message_list && this.message_list.rows[id] && this.message_list.rows[id].unread && this.env.preview_pane_mark_read >= 0) {
@@ -2962,6 +3011,17 @@
   /*********        message compose methods        *********/
   /*********************************************************/
 
+  this.open_compose_step = function(p)
+  {
+    var url = this.url('mail/compose', p);
+
+    // open new compose window
+    if (this.env.compose_extwin)
+      this.open_window(url, 1150, 900);
+    else
+      this.redirect(url);
+  };
+
   // init message compose form: set focus and eventhandlers
   this.init_messageform = function()
   {
@@ -2975,6 +3035,11 @@
       html_mode = $("input[name='_is_html']").val() == '1',
       ac_fields = ['cc', 'bcc', 'replyto', 'followupto'],
       ac_props;
+
+    // close compose step in opener
+    if (window.opener && opener.rcmail && opener.rcmail.env.action == 'compose') {
+      setTimeout(function(){ opener.history.back(); }, 100);
+    }
 
     // configure parallel autocompletion
     if (this.env.autocomplete_threads > 0) {
@@ -3630,8 +3695,16 @@
   this.sent_successfully = function(type, msg)
   {
     this.display_message(msg, type);
-    // before redirect we need to wait some time for Chrome (#1486177)
-    setTimeout(function(){ ref.list_mailbox(); }, 500);
+
+    if (this.env.extwin && window.opener && opener.rcmail) {
+      this.lock_form(this.gui_objects.messageform);
+      opener.rcmail.display_message(msg, type);
+      setTimeout(function(){ window.close() }, 1000);
+    }
+    else {
+      // before redirect we need to wait some time for Chrome (#1486177)
+      setTimeout(function(){ ref.list_mailbox(); }, 500);
+    }
   };
 
 
diff --git a/program/localization/de_CH/labels.inc b/program/localization/de_CH/labels.inc
index 4164e03..f9f9531 100644
--- a/program/localization/de_CH/labels.inc
+++ b/program/localization/de_CH/labels.inc
@@ -169,8 +169,9 @@
 $labels['openinextwin'] = 'In neuem Fenster öffnen';
 $labels['emlsave'] = 'Herunterladen (.eml)';
 $labels['editasnew'] = 'Als neue Nachricht öffnen';
-$labels['savemessage'] = 'Nachricht speichern';
+$labels['send'] = 'Senden';
 $labels['sendmessage'] = 'Nachricht jetzt senden';
+$labels['savemessage'] = 'Nachricht speichern';
 $labels['addattachment'] = 'Datei anfügen';
 $labels['charset'] = 'Zeichensatz';
 $labels['editortype'] = 'Editor-Typ';
@@ -323,6 +324,8 @@
 $labels['pagesize'] = 'Einträge pro Seite';
 $labels['signature'] = 'Signatur';
 $labels['dstactive'] = 'Sommerzeit';
+$labels['showinextwin'] = 'Nachrichten in neuem Fenster öffnen';
+$labels['composeextwin'] = 'Nachrichten in neuem Fenster verfassen';
 $labels['htmleditor'] = 'HTML-Nachrichten verfassen';
 $labels['htmlonreply'] = 'nur Antworten auf HTML-Nachrichten';
 $labels['htmlsignature'] = 'HTML-Signatur';
diff --git a/program/localization/de_DE/labels.inc b/program/localization/de_DE/labels.inc
index 71d5b80..5c63034 100644
--- a/program/localization/de_DE/labels.inc
+++ b/program/localization/de_DE/labels.inc
@@ -169,8 +169,9 @@
 $labels['openinextwin'] = 'In neuem Fenster öffnen';
 $labels['emlsave'] = 'Lokal speichern (.eml)';
 $labels['editasnew'] = 'Als neue Nachricht öffnen';
-$labels['savemessage'] = 'Nachricht speichern';
+$labels['send'] = 'Senden';
 $labels['sendmessage'] = 'Nachricht jetzt senden';
+$labels['savemessage'] = 'Nachricht speichern';
 $labels['addattachment'] = 'Datei anfügen';
 $labels['charset'] = 'Zeichensatz';
 $labels['editortype'] = 'Editor Typ';
@@ -323,6 +324,8 @@
 $labels['pagesize'] = 'Einträge pro Seite';
 $labels['signature'] = 'Signatur';
 $labels['dstactive'] = 'Sommerzeit';
+$labels['showinextwin'] = 'Nachrichten in neuem Fenster öffnen';
+$labels['composeextwin'] = 'Nachrichten in neuem Fenster verfassen';
 $labels['htmleditor'] = 'HTML-Nachrichten verfassen';
 $labels['htmlonreply'] = 'nur Antworten auf HTML-Nachrichten';
 $labels['htmlsignature'] = 'HTML-Signatur';
diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc
index fbc154b..2b1397f 100644
--- a/program/localization/en_US/labels.inc
+++ b/program/localization/en_US/labels.inc
@@ -203,8 +203,9 @@
 
 // message compose
 $labels['editasnew']      = 'Edit as new';
-$labels['savemessage']    = 'Save as draft';
+$labels['send']           = 'Send';
 $labels['sendmessage']    = 'Send message';
+$labels['savemessage']    = 'Save as draft';
 $labels['addattachment']  = 'Attach a file';
 $labels['charset']        = 'Charset';
 $labels['editortype']     = 'Editor type';
@@ -383,6 +384,8 @@
 $labels['pagesize']  = 'Rows per page';
 $labels['signature'] = 'Signature';
 $labels['dstactive']  = 'Daylight saving time';
+$labels['showinextwin'] = 'Open message in a new window';
+$labels['composeextwin'] = 'Compose in a new window';
 $labels['htmleditor'] = 'Compose HTML messages';
 $labels['htmlonreply'] = 'on reply to HTML message';
 $labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
diff --git a/program/localization/es_ES/labels.inc b/program/localization/es_ES/labels.inc
index 7425dd7..d47bd0f 100644
--- a/program/localization/es_ES/labels.inc
+++ b/program/localization/es_ES/labels.inc
@@ -323,6 +323,7 @@
 $labels['pagesize'] = 'Filas por página';
 $labels['signature'] = 'Firma';
 $labels['dstactive'] = 'Cambio de horario';
+$labels['composeextwin'] = 'Redactar en una ventana nueva';
 $labels['htmleditor'] = 'Componer mensaje en HTML';
 $labels['htmlonreply'] = 'sólo en respuesta a un mensaje HTML';
 $labels['htmlsignature'] = 'Firma HTML';
diff --git a/program/localization/it_IT/labels.inc b/program/localization/it_IT/labels.inc
index 4d61ace..61b48b0 100644
--- a/program/localization/it_IT/labels.inc
+++ b/program/localization/it_IT/labels.inc
@@ -323,6 +323,7 @@
 $labels['pagesize'] = 'Righe per pagina';
 $labels['signature'] = 'Firma';
 $labels['dstactive'] = 'Gestione ora legale';
+$labels['composeextwin'] = 'Componi in nuova finestra';
 $labels['htmleditor'] = 'Scrivi i messaggi in HTML';
 $labels['htmlonreply'] = 'solo in risposta a messaggi HTML';
 $labels['htmlsignature'] = 'Firma in HTML';
diff --git a/program/localization/nl_NL/labels.inc b/program/localization/nl_NL/labels.inc
index 93537c5..bb93004 100644
--- a/program/localization/nl_NL/labels.inc
+++ b/program/localization/nl_NL/labels.inc
@@ -323,6 +323,7 @@
 $labels['pagesize'] = 'Aantal berichten per pagina';
 $labels['signature'] = 'Ondertekening';
 $labels['dstactive'] = 'Zomertijd';
+$labels['composeextwin'] = 'Berichten in nieuw venster';
 $labels['htmleditor'] = 'Berichten opstellen in HTML-opmaak';
 $labels['htmlonreply'] = 'alleen bij beantwoorden van HTML-berichten';
 $labels['htmlsignature'] = 'HTML-ondertekening';
diff --git a/program/localization/pt_BR/labels.inc b/program/localization/pt_BR/labels.inc
index 5abdf20..ffb8cd2 100644
--- a/program/localization/pt_BR/labels.inc
+++ b/program/localization/pt_BR/labels.inc
@@ -323,6 +323,7 @@
 $labels['pagesize'] = 'Mensagens por página';
 $labels['signature'] = 'Assinatura';
 $labels['dstactive'] = 'Horário de verão';
+$labels['composeextwin'] = 'Escrever em nova janela';
 $labels['htmleditor'] = 'Criar mensagens em HTML';
 $labels['htmlonreply'] = 'em resposta à mensagem em HTML somente';
 $labels['htmlsignature'] = 'Assinatura em HTML';
diff --git a/program/localization/ru_RU/labels.inc b/program/localization/ru_RU/labels.inc
index 8b69d22..33cb1e4 100644
--- a/program/localization/ru_RU/labels.inc
+++ b/program/localization/ru_RU/labels.inc
@@ -323,6 +323,7 @@
 $labels['pagesize'] = 'Строк на странице';
 $labels['signature'] = 'Подпись';
 $labels['dstactive'] = 'Летнее время';
+$labels['composeextwin'] = 'Написать сообщение в новом окне';
 $labels['htmleditor'] = 'Создавать сообщения в HTML';
 $labels['htmlonreply'] = 'только в ответ на сообщение в HTML';
 $labels['htmlsignature'] = 'Подпись в HTML';
diff --git a/program/steps/addressbook/func.inc b/program/steps/addressbook/func.inc
index 4ef4d1b..3a05080 100644
--- a/program/steps/addressbook/func.inc
+++ b/program/steps/addressbook/func.inc
@@ -87,6 +87,7 @@
     $OUTPUT->set_env('search_mods', $search_mods);
     $OUTPUT->set_env('address_sources', $js_list);
     $OUTPUT->set_env('writable_source', $writeable);
+    $OUTPUT->set_env('compose_extwin', $RCMAIL->config->get('compose_extwin',false));
 
     $OUTPUT->set_pagetitle(rcube_label('addressbook'));
     $_SESSION['addressbooks_count'] = $count;
diff --git a/program/steps/addressbook/mailto.inc b/program/steps/addressbook/mailto.inc
index 3806c2c..c3cbcad 100644
--- a/program/steps/addressbook/mailto.inc
+++ b/program/steps/addressbook/mailto.inc
@@ -68,7 +68,7 @@
     $mailto_str = join(', ', $mailto);
     $mailto_id = substr(md5($mailto_str), 0, 16);
     $_SESSION['mailto'][$mailto_id] = urlencode($mailto_str);
-    $OUTPUT->redirect(array('task' => 'mail', '_action' => 'compose', '_mailto' => $mailto_id));
+    $OUTPUT->command('open_compose_step', array('_mailto' => $mailto_id));
 }
 else {
     $OUTPUT->show_message('nocontactsfound', 'warning');
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index 7ac9a8d..2d45105 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -130,6 +130,7 @@
     'fileuploaderror', 'sendmessage');
 
 $OUTPUT->set_env('compose_id', $COMPOSE['id']);
+$OUTPUT->set_pagetitle(rcube_label('compose'));
 
 // add config parameters to client script
 if (!empty($CONFIG['drafts_mbox'])) {
@@ -606,7 +607,10 @@
 
   $html_editor = intval($RCMAIL->config->get('htmleditor'));
 
-  if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) {
+  if (isset($_POST['_is_html'])) {
+    $useHtml = !empty($_POST['_is_html']);
+  }
+  else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) {
     $useHtml = $MESSAGE->has_html_part(false);
   }
   else if ($compose_mode == RCUBE_COMPOSE_REPLY) {
@@ -1445,7 +1449,9 @@
   $attrib['value'] = '1';
   $checkbox = new html_checkbox($attrib);
 
-  if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT)))
+  if (isset($_POST['_receipt']))
+    $mdn_default = $_POST['_receipt'];
+  else if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT)))
     $mdn_default = (bool) $MESSAGE->headers->mdn_to;
   else
     $mdn_default = $RCMAIL->config->get('mdn_default');
@@ -1472,8 +1478,13 @@
   $attrib['value'] = '1';
   $checkbox = new html_checkbox($attrib);
 
+  if (isset($_POST['_dsn']))
+    $dsn_value = $_POST['_dsn'];
+  else
+    $dsn_value = $RCMAIL->config->get('dsn_default');
+
   $out = $form_start ? "$form_start\n" : '';
-  $out .= $checkbox->show($RCMAIL->config->get('dsn_default'));
+  $out .= $checkbox->show($dsn_value);
   $out .= $form_end ? "\n$form_end" : '';
 
   return $out;
@@ -1520,7 +1531,7 @@
     'folder_filter' => 'mail',
     'folder_rights' => 'w',
   )));
-  return $select->show($COMPOSE['param']['sent_mbox'], $attrib);
+  return $select->show(isset($_POST['_store_target']) ? $_POST['_store_target'] : $COMPOSE['param']['sent_mbox'], $attrib);
 }
 
 
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 4302bf9..47d1a48 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -101,18 +101,11 @@
     $OUTPUT->set_env('quota', true);
   }
 
-  if ($CONFIG['delete_junk'])
-    $OUTPUT->set_env('delete_junk', true);
-  if ($CONFIG['flag_for_deletion'])
-    $OUTPUT->set_env('flag_for_deletion', true);
-  if ($CONFIG['read_when_deleted'])
-    $OUTPUT->set_env('read_when_deleted', true);
-  if ($CONFIG['skip_deleted'])
-    $OUTPUT->set_env('skip_deleted', true);
-  if ($CONFIG['display_next'])
-    $OUTPUT->set_env('display_next', true);
-  if ($CONFIG['forward_attachment'])
-    $OUTPUT->set_env('forward_attachment', true);
+  foreach (array('delete_junk','flag_for_deletion','read_when_deleted','skip_deleted','display_next','message_extwin','compose_extwin','forward_attachment') as $prop) {
+    if ($CONFIG[$prop])
+      $OUTPUT->set_env($prop, true);
+  }
+
   if ($CONFIG['trash_mbox'])
     $OUTPUT->set_env('trash_mailbox', $CONFIG['trash_mbox']);
   if ($CONFIG['drafts_mbox'])
diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc
index 029bc5f..f896607 100644
--- a/program/steps/mail/show.inc
+++ b/program/steps/mail/show.inc
@@ -59,6 +59,7 @@
   $OUTPUT->set_env('permaurl', rcmail_url('show', array('_uid' => $MESSAGE->uid, '_mbox' => $mbox_name)));
   $OUTPUT->set_env('delimiter', $RCMAIL->storage->get_hierarchy_delimiter());
   $OUTPUT->set_env('mailbox', $mbox_name);
+  $OUTPUT->set_env('compose_extwin', $RCMAIL->config->get('compose_extwin',false));
 
   // mimetypes supported by the browser (default settings)
   $mimetypes = $RCMAIL->config->get('client_mimetypes', 'text/plain,text/html,text/xml,image/jpeg,image/gif,image/png,image/bmp,image/tiff,application/x-javascript,application/pdf,application/x-shockwave-flash');
diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc
index ba42e81..d5ccbb2 100644
--- a/program/steps/settings/func.inc
+++ b/program/steps/settings/func.inc
@@ -129,8 +129,8 @@
 
   $sections['general'] = array('id' => 'general', 'section' => rcube_label('uisettings'));
   $sections['mailbox'] = array('id' => 'mailbox', 'section' => rcube_label('mailboxview'));
-  $sections['compose'] = array('id' => 'compose', 'section' => rcube_label('messagescomposition'));
   $sections['mailview'] = array('id' => 'mailview','section' => rcube_label('messagesdisplaying'));
+  $sections['compose'] = array('id' => 'compose', 'section' => rcube_label('messagescomposition'));
   $sections['addressbook'] = array('id' => 'addressbook','section' => rcube_label('addressbook'));
   $sections['folders'] = array('id' => 'folders', 'section' => rcube_label('specialfolders'));
   $sections['server'] = array('id' => 'server',  'section' => rcube_label('serversettings'));
@@ -411,6 +411,17 @@
       'main' => array('name' => Q(rcube_label('mainoptions'))),
     );
 
+    // show checkbox to open message view in new window
+    if (!isset($no_override['message_extwin'])) {
+      $field_id = 'rcmfd_message_extwin';
+      $input_msgextwin = new html_checkbox(array('name' => '_message_extwin', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['message_extwin'] = array(
+        'title' => html::label($field_id, Q(rcube_label('showinextwin'))),
+        'content' => $input_msgextwin->show($config['message_extwin']?1:0),
+      );
+    }
+
     // show checkbox for HTML/plaintext messages
     if (!isset($no_override['prefer_html'])) {
       $field_id = 'rcmfd_htmlmsg';
@@ -480,6 +491,17 @@
       'sig'        => array('name' => Q(rcube_label('signatureoptions'))),
     );
 
+    // show checkbox to compose messages in a new window
+    if (!isset($no_override['compose_extwin'])) {
+      $field_id = 'rcmfdcompose_extwin';
+      $input_compextwin = new html_checkbox(array('name' => '_compose_extwin', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['compose_extwin'] = array(
+        'title' => html::label($field_id, Q(rcube_label('composeextwin'))),
+        'content' => $input_compextwin->show($config['compose_extwin']?1:0),
+      );
+    }
+
     if (!isset($no_override['htmleditor'])) {
       $field_id = 'rcmfd_htmleditor';
       $select_htmleditor = new html_select(array('name' => '_htmleditor', 'id' => $field_id));
diff --git a/program/steps/settings/save_prefs.inc b/program/steps/settings/save_prefs.inc
index d1627ec..db7b134 100644
--- a/program/steps/settings/save_prefs.inc
+++ b/program/steps/settings/save_prefs.inc
@@ -59,6 +59,7 @@
 
   case 'mailview':
     $a_user_prefs = array(
+      'message_extwin'  => intval($_POST['_message_extwin']),
       'prefer_html'     => isset($_POST['_prefer_html']) ? TRUE : FALSE,
       'inline_images'   => isset($_POST['_inline_images']) ? TRUE : FALSE,
       'show_images'     => isset($_POST['_show_images']) ? intval($_POST['_show_images']) : 0,
@@ -70,6 +71,7 @@
 
   case 'compose':
     $a_user_prefs = array(
+      'compose_extwin'     => intval($_POST['_compose_extwin']),
       'htmleditor'         => intval($_POST['_htmleditor']),
       '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,
diff --git a/skins/classic/common.css b/skins/classic/common.css
index 735a736..8f5daee 100644
--- a/skins/classic/common.css
+++ b/skins/classic/common.css
@@ -156,6 +156,11 @@
   left: 20px;
 }
 
+.extwin #mainscreen
+{
+  top: 43px;
+}
+
 body > #logo
 {
   margin-left: 12px;
diff --git a/skins/classic/includes/messagetoolbar.html b/skins/classic/includes/messagetoolbar.html
index 302e950..eebb557 100644
--- a/skins/classic/includes/messagetoolbar.html
+++ b/skins/classic/includes/messagetoolbar.html
@@ -1,10 +1,12 @@
 <div id="messagetoolbar">
-<roundcube:if condition="template:name == 'message'" />
+<roundcube:if condition="template:name == 'message' && env:extwin" />
+<roundcube:button command="close" type="link" class="button back" classAct="button back" classSel="button backSel" title="close" content=" " />
+<roundcube:elseif condition="template:name == 'message'" />
 <roundcube:button command="list" type="link" class="button back" classAct="button back" classSel="button backSel" title="backtolist" content=" " />
 <roundcube:else />
 <roundcube:button command="checkmail" type="link" class="button checkmail" classAct="button checkmail" classSel="button checkmailSel" title="checkmail" content=" " />
-<roundcube:endif />
 <roundcube:button command="compose" type="link" class="button compose" classAct="button compose" classSel="button composeSel" title="writenewmessage" content=" " />
+<roundcube:endif />
 <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=" " />
diff --git a/skins/classic/mail.css b/skins/classic/mail.css
index f899dbd..7408d49 100644
--- a/skins/classic/mail.css
+++ b/skins/classic/mail.css
@@ -13,6 +13,12 @@
 /*  border: 1px solid #cccccc; */
 }
 
+.extwin #messagetoolbar
+{
+  top: 5px;
+  left: 20px;
+}
+
 #messagetoolbar a,
 #messagetoolbar select
 {
@@ -1039,6 +1045,11 @@
   z-index: 1;
 }
 
+.extwin #messageframe
+{
+	left: 0;
+}
+
 div.messageheaderbox
 {
   margin: -14px 8px 0px 8px;
@@ -1243,7 +1254,7 @@
   color: #333333;
 }
 
-#messageviewlink
+#openextwinlink
 {
   position: absolute;
   top: 8px;
@@ -1253,6 +1264,12 @@
   border: 0;
 }
 
+#compose-headers #openextwinlink
+{
+	top: 4px;
+	right: 2px;
+}
+
 #full-headers
 {
   color: #666666;
diff --git a/skins/classic/templates/compose.html b/skins/classic/templates/compose.html
index 23998ee..e216465 100644
--- a/skins/classic/templates/compose.html
+++ b/skins/classic/templates/compose.html
@@ -15,15 +15,22 @@
 }
 </style>
 </head>
+<roundcube:if condition="env:extwin" />
+<body class="extwin" onload="rcube_init_mail_ui()">
+<roundcube:else />
 <body onload="rcube_init_mail_ui()">
-
 <roundcube:include file="/includes/taskbar.html" />
 <roundcube:include file="/includes/header.html" />
+<roundcube:endif />
 
 <form name="form" action="./" method="post">
 
 <div id="messagetoolbar">
+<roundcube:if condition="env:extwin" />
+    <roundcube:button command="close" type="link" class="button back" classAct="button back" classSel="button backSel" title="close" content=" " />
+<roundcube:else />
     <roundcube:button command="list" type="link" class="button back" classAct="button back" classSel="button backSel" title="backtolist" content=" " />
+<roundcube:endif />
     <roundcube:button command="send" type="link" class="buttonPas send" classAct="button send" classSel="button sendSel" title="sendmessage" content=" " />
 <roundcube:if condition="config:enable_spellcheck" />
     <span class="dropbutton">
@@ -64,6 +71,7 @@
             <td class="editfield formlinks">
                 <roundcube:object name="composeHeaders" part="from" form="form" id="_from" tabindex="1" />
                 <a href="#identities" onclick="return rcmail.command('identities')"><roundcube:label name="editidents" /></a>
+                <roundcube:button command="extwin" image="/images/icons/extwin.png" width="15" height="15" title="openinextwin" id="openextwinlink" condition="!env:extwin" />
             </td>
         </tr><tr>
             <td class="title top"><label for="_to"><roundcube:label name="to" /></label></td>
diff --git a/skins/classic/templates/message.html b/skins/classic/templates/message.html
index c03376e..9b7cb9f 100644
--- a/skins/classic/templates/message.html
+++ b/skins/classic/templates/message.html
@@ -12,13 +12,19 @@
 }
 </style>
 </head>
+<roundcube:if condition="env:extwin" />
+<body class="extwin" onload="rcube_init_mail_ui()">
+<roundcube:else />
 <body onload="rcube_init_mail_ui()">
 
 <roundcube:include file="/includes/taskbar.html" />
 <roundcube:include file="/includes/header.html" />
+<roundcube:endif />
+
 <roundcube:include file="/includes/messagetoolbar.html" />
 
 <div id="mainscreen">
+<roundcube:if condition="!env:extwin" />
 <div id="mailleftcontainer">
 <div id="mailboxlist-container">
 <div id="mailboxlist-title" class="boxtitle"><roundcube:label name="mailboxlist" /></div>
@@ -28,6 +34,7 @@
 <div class="boxfooter"></div>
 </div>
 </div>
+<roundcube:endif />
 
 <div id="messageframe">
 <div class="boxlistcontent" style="top:0; overflow-x:auto">
diff --git a/skins/classic/templates/messagepreview.html b/skins/classic/templates/messagepreview.html
index a606311..78b2306 100644
--- a/skins/classic/templates/messagepreview.html
+++ b/skins/classic/templates/messagepreview.html
@@ -7,7 +7,7 @@
 <body class="iframe">
 
 <div class="messageheaderbox">
-<roundcube:button command="permaurl" image="/images/icons/extwin.png" width="15" height="15" title="openinextwin" id="messageviewlink" target="_blank" />
+<roundcube:button command="extwin" image="/images/icons/extwin.png" width="15" height="15" title="openinextwin" id="openextwinlink" />
 <roundcube:object name="messageHeaders" class="headers-table" cellspacing="0" cellpadding="2" addicon="/images/icons/silhouette.png" summary="Message headers" />
 <roundcube:object name="messageFullHeaders" id="full-headers" />
 <roundcube:object name="messageAttachments" id="attachment-list" />
diff --git a/skins/larry/ie7hacks.css b/skins/larry/ie7hacks.css
index 893ffdf..f07d79a 100644
--- a/skins/larry/ie7hacks.css
+++ b/skins/larry/ie7hacks.css
@@ -151,10 +151,6 @@
 	bottom: 0;
 }
 
-#composeoptionsbox {
-	padding-top: 2px;
-}
-
 #composeoptionstoggle {
 	display: inline;
 	top: 3px;
diff --git a/skins/larry/iehacks.css b/skins/larry/iehacks.css
index 93f483c..83ea946 100644
--- a/skins/larry/iehacks.css
+++ b/skins/larry/iehacks.css
@@ -147,12 +147,8 @@
 	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f0f0f0', GradientType=0);
 }
 
-#previewheaderstoggle {
+.moreheaderstoggle {
 	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbfbfb', endColorstr='#e9e9e9', GradientType=1);
-}
-
-#composeoptionsbox {
-	border-top: 1px solid #999;
 }
 
 #messagelist tbody tr td span.branch div {
diff --git a/skins/larry/images/buttons.png b/skins/larry/images/buttons.png
index 0d3b5cc..c70a960 100644
--- a/skins/larry/images/buttons.png
+++ b/skins/larry/images/buttons.png
Binary files differ
diff --git a/skins/larry/includes/header.html b/skins/larry/includes/header.html
index 9187c6f..25bcc0b 100644
--- a/skins/larry/includes/header.html
+++ b/skins/larry/includes/header.html
@@ -7,11 +7,16 @@
 		<roundcube:endif />
 	</div>
 	<div class="topright">
-	<span class="username"><roundcube:object name="username" /></span>
-	<roundcube:button command="logout" label="logout" class="button-logout" />
+	<roundcube:if condition="!env:extwin" />
+		<span class="username"><roundcube:object name="username" /></span>
+		<roundcube:button command="logout" label="logout" class="button-logout" />
+	<roundcube:else />
+		<roundcube:button command="close" label="close" class="closelink" />
+	<roundcube:endif />
 	</div>
 </div>
 
+<roundcube:if condition="!env:extwin" />
 <div id="topnav">
 	<div id="taskbar" class="topright">
 	<roundcube:button command="mail" label="mail" class="button-mail" classSel="button-mail button-selected" innerClass="button-inner" />
@@ -21,6 +26,7 @@
 	</div>
 	<roundcube:object name="logo" src="/images/roundcube_logo.png" id="toplogo" border="0" alt="Logo" onclick="rcmail.command('switch-task','mail');return false;" />
 </div>
+<roundcube:endif />
 
 <br style="clear:both" />
 </div>
diff --git a/skins/larry/mail.css b/skins/larry/mail.css
index 76ca4ed..20a13f6 100644
--- a/skins/larry/mail.css
+++ b/skins/larry/mail.css
@@ -30,6 +30,10 @@
 	z-index: 3;
 }
 
+#mailview-right.fullwidth {
+	left: 0;
+}
+
 #mailview-top {
 	position: absolute;
 	top: 42px;
@@ -47,7 +51,9 @@
 	left: 0;
 	bottom: 0;
 	width: 100%;
-	height: 26px;
+	height: 27px;
+	border-radius: 0 0 4px 4px;
+	border-top: none;
 }
 
 #folderlist-header {
@@ -795,7 +801,7 @@
 	padding-right: 18px;
 }
 
-#previewheaderstoggle {
+.moreheaderstoggle {
 	display: block;
 	position: absolute;
 	top: 0;
@@ -814,7 +820,7 @@
 	border-radius: 3px 0 0 0; /* for Opera */
 }
 
-#previewheaderstoggle .iconlink {
+.moreheaderstoggle .iconlink {
 	display: inline-block;
 	position: absolute;
 	top: 8px;
@@ -824,7 +830,7 @@
 	background: url(images/buttons.png) -27px -242px no-repeat;
 }
 
-#previewheaderstoggle.remove .iconlink {
+.moreheaderstoggle.remove .iconlink {
 	top: auto;
 	bottom: 5px;
 	background-position: -5px -242px;
@@ -841,11 +847,11 @@
 	width: 12px;
 	height: 10px;
 	cursor: pointer;
-	background: url(images/buttons.png) center -1619px no-repeat;
+	background: url(images/buttons.png) center -1579px no-repeat;
 }
 
 div.hide-headers {
-	background-position: center -1629px;
+	background-position: center -1589px;
 }
 
 #all-headers {
@@ -1151,47 +1157,48 @@
 	background-position: 6px -1627px;
 }
 
-
 #compose-content {
 	position: absolute;
 	top: 42px;
 	left: 0;
 	width: 100%;
 	bottom: 28px;
-	border-bottom-left-radius: 0;
-	border-bottom-right-radius: 0;
+	border-radius: 4px 4px 0 0;
+	border-bottom: none;
 	overflow: hidden;
 }
 
 #composeheaders {
 	border-radius: 4px 4px 0 0;
-	-webkit-box-shadow: 0 2px 3px 0 #999;
-	-moz-box-shadow: 0 2px 3px 0 #999;
-	box-shadow: 0 2px 3px 0 #999;
-	border-bottom: 0;
+	padding-left: 19px;
 }
 
 #composebuttons {
 	position: absolute;
-	top: 8px;
-	right: 8px;
+	top: 6px;
+	right: 6px;
 	width: auto;
 	white-space: nowrap;
 	z-index: 100;
 }
 
+#composebuttons a.button.extwin {
+	padding: 2px 3px;
+}
+
 .compose-headers {
 	width: 99%;
-	margin: 4px 0;
+	margin-bottom: 2px;
 }
 
 .compose-headers td {
-	padding: 4px 4px 4px 8px;
+	padding: 2px 4px;
 }
 
 .compose-headers td.title {
 	width: 11%;
 	white-space: nowrap;
+	padding-left: 6px;
 }
 
 .compose-headers td.title label {
@@ -1235,49 +1242,35 @@
 	display: none;
 }
 
-#composeoptionsbox {
-	padding: 4px 8px 0 8px;
-	background: #d2d2d2;
-	border-bottom: 1px solid #e8e8e8;
-	-webkit-box-shadow: 0 2px 3px 0 #999;
-	-moz-box-shadow: 0 2px 3px 0 #999;
-	box-shadow: 0 2px 3px 0 #999;
-	white-space: nowrap;
-}
-
 #composeoptions {
 	display: none;
-	padding: 2px 0;
+	padding: 2px 0 0 8px;
 	white-space: normal;
+	border-top: 1px solid #dfdfdf;
+	box-shadow: inset 0 1px 0 0 #fff;
+	-o-box-shadow: inset 0 1px 0 0 #fff;
+	-webkit-box-shadow: inset 0 1px 0 0 #fff;
+	-moz-box-shadow: inset 0 1px 0 0 #fff;
+
 }
 
 .composeoption {
+	color: #666;
 	padding-right: 22px;
 	white-space: nowrap;
 }
 
 #composeoptions .composeoption {
 	display: inline-block;
-	padding: 4px 28px 4px 0;
+	padding: 4px 22px 4px 0;
 }
 
 #composeoptions .composeoption:last-child {
 	padding-right: 4px;
 }
 
-#composeoptionstoggle {
-	display: inline-block;
-	position: relative;
-	top: -1px;
-	left: 6px;
-	width: 20px;
-	height: 18px;
-	background: url(images/buttons.png) -3px -1640px no-repeat;
-	text-decoration: none;
-}
-
-#composeoptionstoggle.enabled {
-	background-position: -28px -1640px;
+.mozilla .composeoption input {
+	vertical-align: -3px;
 }
 
 #composeview-bottom {
@@ -1294,6 +1287,10 @@
 	bottom: 0;
 }
 
+#composebodycontainer.buttons {
+	bottom: 42px;
+}
+
 #composebody {
 	position: absolute;
 	top: 1px;
@@ -1303,15 +1300,22 @@
 	border: 0;
 	border-radius: 0;
 	padding: 8px 0 8px 8px;
-	box-shadow: none;
 	resize: none;
 	font-family: monospace;
 	font-size: 9pt;
 	outline: none;
+	box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.2);
+	-moz-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.2);
+	-webkit-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.2);
+	-o-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.2);
 }
 
 #composebody:active,
 #composebody:focus {
+	box-shadow: inset 0 0 3px 2px rgba(71,135,177, 0.9);
+	-moz-box-shadow: inset 0 0 3px 2px rgba(71,135,177, 0.9);
+	-webkit-box-shadow: inset 0 0 3px 2px rgba(71,135,177, 0.9);
+	-o-box-shadow: inset 0 0 3px 2px rgba(71,135,177, 0.9);
 }
 
 #compose-attachments {
@@ -1351,11 +1355,27 @@
 	-o-box-shadow: 0 0 5px 2px rgba(71,135,177, 0.9);
 }
 
+#composeview-bottom .formbuttons.floating {
+	position: absolute;
+	width: auto;
+	right: 260px;
+	z-index: 200;
+	padding-bottom: 8px;
+}
+
 .defaultSkin table.mceLayout,
 .defaultSkin table.mceLayout tr.mceLast td {
 	border: 0 !important;
 }
 
+.defaultSkin td.mceToolbar {
+	border: 0 !important;
+}
+
+.defaultSkin table.mceLayout tr.mceFirst td {
+	background: #f0f0f0;
+}
+
 #composebody_toolbargroup {
 	border-bottom: 1px solid #ddd;
 }
diff --git a/skins/larry/styles.css b/skins/larry/styles.css
index 3406880..9127fbe 100644
--- a/skins/larry/styles.css
+++ b/skins/larry/styles.css
@@ -637,6 +637,10 @@
 	bottom: 20px;
 }
 
+.extwin #mainscreen {
+	top: 40px;
+}
+
 #mainscreen.offset {
 	top: 130px;
 }
@@ -1084,7 +1088,8 @@
 	z-index: 100;
 }
 
-body.iframe .footerleft.floating {
+body.iframe .footerleft.floating,
+#composeview-bottom .formbuttons.floating {
 	position: fixed;
 	left: 0;
 	bottom: 0;
@@ -1095,7 +1100,8 @@
 	padding-bottom: 12px;
 }
 
-body.iframe .footerleft.floating:before {
+body.iframe .footerleft.floating:before,
+#composeview-bottom .formbuttons.floating:before {
 	content: " ";
 	position: absolute;
 	top: -6px;
@@ -1476,7 +1482,7 @@
 }
 
 .toolbar a.button.spellcheck.selected {
-	background-position: left -1580px;
+	background-position: left -1620px;
 	color: #1978a1;
 }
 
@@ -1496,6 +1502,19 @@
 	background-position: center -1054px;
 }
 
+.toolbar a.button.send {
+	background-position: center -1660px;
+}
+
+.toolbar a.button.savedraft {
+	background-position: center -1700px;
+}
+
+.toolbar a.button.close {
+	background-position: 0 -1745px;
+}
+
+
 a.menuselector {
 	display: inline-block;
 	border: 1px solid #ababab;
diff --git a/skins/larry/svggradients.css b/skins/larry/svggradients.css
index 5b3fedb..06c6f47 100644
--- a/skins/larry/svggradients.css
+++ b/skins/larry/svggradients.css
@@ -137,7 +137,7 @@
 	background-image: url(svggradient.php?c=ffffff;f0f0f0);
 }
 
-#previewheaderstoggle {
+.moreheaderstoggle {
 	background-image: url(svggradient.php?c=fbfbfb;e9e9e9&h=1);
 }
 
diff --git a/skins/larry/templates/compose.html b/skins/larry/templates/compose.html
index ef49ece..de3b5bf 100644
--- a/skins/larry/templates/compose.html
+++ b/skins/larry/templates/compose.html
@@ -7,12 +7,32 @@
 <link rel="stylesheet" type="text/css" href="/googiespell.css" />
 <roundcube:endif />
 </head>
-<body>
+<roundcube:if condition="env:extwin" /><body class="extwin"><roundcube:else /><body><roundcube:endif />
 
-<div class="minwidth">
 <roundcube:include file="/includes/header.html" />
 
 <div id="mainscreen">
+
+<!-- toolbar -->
+<div id="messagetoolbar" class="fullwidth">
+<div id="mailtoolbar" class="toolbar">
+	<roundcube:button command="list" type="link" class="button back disabled" classAct="button back" classSel="button back pressed" label="cancel" condition="!env:extwin" />
+	<roundcube:button command="close" type="link" class="button close disabled" classAct="button close" classSel="button close pressed" label="cancel" condition="env:extwin" />
+	<span class="spacer"></span>
+	<roundcube:button command="send" type="link" class="button send" classAct="button send" classSel="button send pressed" label="send" title="sendmessage" />
+	<roundcube:button command="savedraft" type="link" class="button savedraft" classAct="button savedraft" classSel="button savedraft pressed" label="save" title="savemessage" />
+	<span class="spacer"></span>
+	<roundcube:if condition="config:enable_spellcheck" />
+	<span class="dropbutton">
+		<roundcube:button command="spellcheck" type="link" class="button spellcheck disabled" classAct="button spellcheck" classSel="button spellcheck pressed" label="spellcheck" title="checkspelling" />
+		<span class="dropbuttontip" id="spellmenulink" onclick="UI.show_popup('spellmenu');return false"></span>
+	</span>
+	<roundcube:endif />
+	<roundcube:button name="addattachment" type="link" class="button attach" classAct="button attach" classSel="button attach pressed" label="attach" title="addattachment" onclick="UI.show_uploadform();return false" />
+	<roundcube:button command="insert-sig" type="link" class="button insertsig disabled" classAct="button insertsig" classSel="button insertsig pressed" label="signature" title="insertsignature" />
+	<roundcube:container name="toolbar" id="compose-toolbar" />
+</div>
+</div>
 
 <div id="composeview-left">
 
@@ -38,25 +58,11 @@
 
 <div id="composeview-right">
 
-<!-- toolbar -->
-<div id="messagetoolbar" class="fullwidth">
-<div id="mailtoolbar" class="toolbar">
-	<roundcube:if condition="config:enable_spellcheck" />
-	<span class="dropbutton">
-		<roundcube:button command="spellcheck" type="link" class="button spellcheck disabled" classAct="button spellcheck" classSel="button spellcheck pressed" label="spellcheck" title="checkspelling" />
-		<span class="dropbuttontip" id="spellmenulink" onclick="UI.show_popup('spellmenu');return false"></span>
-	</span>
-	<roundcube:endif />
-	<roundcube:button name="addattachment" type="link" class="button attach" classAct="button attach" classSel="button attach pressed" label="attach" title="addattachment" onclick="UI.show_uploadform();return false" />
-	<roundcube:button command="insert-sig" type="link" class="button insertsig disabled" classAct="button insertsig" classSel="button insertsig pressed" label="signature" title="insertsignature" />
-	<roundcube:container name="toolbar" id="compose-toolbar" />
-</div>
-</div>
-
 <form name="form" action="./" method="post" id="compose-content" class="uibox">
 
 <!-- message headers -->
 <div id="composeheaders">
+<a href="#options" id="composeoptionstoggle" class="moreheaderstoggle"><span class="iconlink" title="<roundcube:label name='options' />"></span></a>
 
 <table class="headers-table compose-headers">
 <tbody>
@@ -108,45 +114,36 @@
 </tbody>
 </table>
 
-<div id="composebuttons" class="formbuttons">
-	<roundcube:button type="input" command="send" class="button mainaction" label="sendmessage" tabindex="11" />
-	<roundcube:button type="input" command="savedraft" class="button" label="savemessage" tabindex="12" />
-	<roundcube:button type="input" command="list" class="button" label="cancel" tabindex="13" />
-</div>
-
+<div id="composebuttons" class="pagenav formbuttons">
+	<roundcube:button command="extwin" type="link" class="button extwin" classSel="button extwin pressed" innerClass="inner" title="openinextwin" content="[]" condition="!env:extwin" />
 </div>
 
 <!-- (collapsable) message options -->
-<div id="composeoptionsbox">
+<div id="composeoptions">
+	<roundcube:if condition="!in_array('htmleditor', (array)config:dont_override)" />
 	<span class="composeoption">
-		<label><roundcube:label name="options" />
-			<a href="#options" id="composeoptionstoggle">&nbsp;</a></label>
+		<label><roundcube:label name="editortype" />
+			<roundcube:object name="editorSelector" editorid="composebody" tabindex="14" /></label>
 	</span>
-	
-	<div id="composeoptions">
-		<roundcube:if condition="!in_array('htmleditor', (array)config:dont_override)" />
-		<span class="composeoption">
-			<label><roundcube:label name="editortype" />
-				<roundcube:object name="editorSelector" editorid="composebody" tabindex="14" /></label>
-		</span>
-		<roundcube:endif />
-		<span class="composeoption">
-			<label for="rcmcomposepriority"><roundcube:label name="priority" />
-				<roundcube:object name="prioritySelector" form="form" id="rcmcomposepriority" /></label>
-		</span>
-		<span class="composeoption">
-			<label><roundcube:object name="receiptCheckBox" form="form" id="rcmcomposereceipt" /> <roundcube:label name="returnreceipt" /></label>
-		</span>
-		<span class="composeoption">
-			<label><roundcube:object name="dsnCheckBox" form="form" id="rcmcomposedsn" /> <roundcube:label name="dsn" /></label>
-		</span>
-                <roundcube:if condition="!config:no_save_sent_messages" />
-		<span class="composeoption">
-			<label><roundcube:label name="savesentmessagein" /> <roundcube:object name="storetarget" maxlength="30" style="max-width:12em" /></label>
-		</span>
-                <roundcube:endif />
-		<roundcube:container name="composeoptions" id="composeoptions" />
-	</div>
+	<roundcube:endif />
+	<span class="composeoption">
+		<label for="rcmcomposepriority"><roundcube:label name="priority" />
+			<roundcube:object name="prioritySelector" form="form" id="rcmcomposepriority" /></label>
+	</span>
+	<span class="composeoption">
+		<label><roundcube:object name="receiptCheckBox" form="form" id="rcmcomposereceipt" /> <roundcube:label name="returnreceipt" /></label>
+	</span>
+	<span class="composeoption">
+		<label><roundcube:object name="dsnCheckBox" form="form" id="rcmcomposedsn" /> <roundcube:label name="dsn" /></label>
+	</span>
+	<roundcube:if condition="!config:no_save_sent_messages" />
+	<span class="composeoption">
+		<label><roundcube:label name="savesentmessagein" /> <roundcube:object name="storetarget" maxlength="30" style="max-width:12em" /></label>
+	</span>
+	<roundcube:endif />
+	<roundcube:container name="composeoptions" id="composeoptions" />
+</div>
+
 </div>
 
 <!-- message compose body -->
@@ -156,11 +153,18 @@
 	</div>
 	<div id="compose-attachments" class="rightcol">
 		<div style="text-align:center; margin-bottom:20px">
-			<roundcube:button name="addattachment" type="input" class="button" classSel="button pressed" label="addattachment" onclick="UI.show_uploadform();return false" tabindex="10" />
+			<roundcube:button name="addattachment" type="input" class="button" classSel="button pressed" label="addattachment" onclick="UI.show_uploadform();return false" />
 		</div>
 		<roundcube:object name="composeAttachmentList" id="attachment-list" class="attachmentslist" />
 		<roundcube:object name="fileDropArea" id="compose-attachments" />
 	</div>
+<!--
+	<div id="composeformbuttons" class="footerleft formbuttons floating">
+		<roundcube:button type="input" command="send" class="button mainaction" label="sendmessage" tabindex="11" />
+		<roundcube:button type="input" command="savedraft" class="button" label="savemessage" tabindex="12" />
+		<roundcube:button type="input" command="list" class="button" label="cancel" tabindex="13" />
+	</div>
+-->
 </div>
 
 </form>
@@ -172,8 +176,6 @@
 </div><!-- end mailview-right -->
 
 </div><!-- end mainscreen -->
-
-</div><!-- end minwidth -->
 
 <div id="upload-dialog" class="propform popupdialog" title="<roundcube:label name='addattachment' />">
 	<roundcube:object name="composeAttachmentForm" id="uploadform" attachmentFieldSize="40" buttons="no" />
diff --git a/skins/larry/templates/message.html b/skins/larry/templates/message.html
index e99f206..f7e188f 100644
--- a/skins/larry/templates/message.html
+++ b/skins/larry/templates/message.html
@@ -4,7 +4,7 @@
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
 </head>
-<body class="noscroll">
+<roundcube:if condition="env:extwin" /><body class="noscroll extwin"><roundcube:else /><body class="noscroll"><roundcube:endif />
 
 <roundcube:include file="/includes/header.html" />
 
@@ -12,13 +12,17 @@
 
 <!-- toolbar -->
 <div id="messagetoolbar" class="toolbar fullwidth">
+<roundcube:if condition="!env:extwin" />
 	<roundcube:button command="list" type="link" class="button back disabled" classAct="button back" classSel="button back pressed" label="back" />
 	<span class="spacer"></span>
+<roundcube:endif />
 	<roundcube:include file="/includes/mailtoolbar.html" />
 	<div class="toolbarselect">
 		<roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('moveto', this.options[this.selectedIndex].value)" class="mailboxlist decorated" folder_filter="mail" />
 	</div>
 </div>
+
+<roundcube:if condition="!env:extwin" />
 
 <div id="mailview-left">
 
@@ -32,9 +36,13 @@
 </div>
 
 <div id="mailview-right" class="offset uibox">
+<roundcube:else />
+
+<div id="mailview-right" class="offset fullwidth uibox">
+<roundcube:endif />
 
 <div id="messageheader">
-<span id="previewheaderstoggle"></span>
+<span class="moreheaderstoggle"></span>
 
 <h2 class="subject"><roundcube:object name="messageHeaders" valueOf="subject" /></h2>
 <roundcube:object name="messageHeaders" class="headers-table" addicon="/images/addcontact.png" exclude="subject" max="20" />
diff --git a/skins/larry/templates/messagepreview.html b/skins/larry/templates/messagepreview.html
index de02b05..9eb4d1e 100644
--- a/skins/larry/templates/messagepreview.html
+++ b/skins/larry/templates/messagepreview.html
@@ -9,7 +9,7 @@
 <div id="messageheader" class="previewheader">
 <h3 class="subject"><roundcube:object name="messageHeaders" valueOf="subject" /></h3>
 
-<a href="#details" id="previewheaderstoggle"><span class="iconlink" title="<roundcube:label name='togglemoreheaders' />"></span></a>
+<a href="#details" id="previewheaderstoggle" class="moreheaderstoggle"><span class="iconlink" title="<roundcube:label name='togglemoreheaders' />"></span></a>
 <div id="contactphoto"><roundcube:object name="contactphoto" /></div>
 
 <table class="headers-table" id="preview-shortheaders"><tbody><tr>
@@ -36,7 +36,7 @@
 	<roundcube:button command="forward" type="link" class="button forward" classSel="button forward pressed" innerClass="inner" title="forwardmessage" content="-&gt;" />
 	&nbsp;
 <roundcube:endif />
-	<roundcube:button command="permaurl" type="link" class="button extwin" classSel="button extwin pressed" innerClass="inner" title="openinextwin" content="[]" target="_blank" />
+	<roundcube:button command="extwin" type="link" class="button extwin" classSel="button extwin pressed" innerClass="inner" title="openinextwin" content="[]" />
 </div>
 
 </div>
diff --git a/skins/larry/ui.js b/skins/larry/ui.js
index 42d5237..da4f230 100644
--- a/skins/larry/ui.js
+++ b/skins/larry/ui.js
@@ -21,7 +21,6 @@
     dragmessagemenu:    { sticky:1 },
     groupmenu:          { above:1 },
     mailboxmenu:        { above:1 },
-    composeoptionsmenu: { editable:1, overlap:1 },
     spellmenu:          { callback: spellmenu },
     // toggle: #1486823, #1486930
     'attachment-form':  { editable:1, above:1, toggle:!bw.ie&&!bw.linux },
@@ -90,12 +89,16 @@
             show_header_row(fields[f], true);
         }
 
-        $('#composeoptionstoggle').parent().click(function(){
-          $('#composeoptionstoggle').toggleClass('enabled');
+        $('#composeoptionstoggle').click(function(){
+          $('#composeoptionstoggle').toggleClass('remove');
           $('#composeoptions').toggle();
           layout_composeview();
           return false;
         }).css('cursor', 'pointer');
+
+        // toggle compose options if opened in new window and they were visible before
+        if (window.opener && opener.rcmail && opener.rcmail.env.action == 'compose' && $('#composeoptionstoggle', opener.document).hasClass('remove'))
+          $('#composeoptionstoggle').click();
 
         new rcube_splitter({ id:'composesplitterv', p1:'#composeview-left', p2:'#composeview-right',
           orientation:'v', relative:true, start:248, min:170, size:12, render:layout_composeview }).init();
@@ -354,9 +357,14 @@
     var body = $('#composebody'),
       form = $('#compose-content'),
       bottom = $('#composeview-bottom'),
-      w, h;
+      w, h, bh, ovflw, btns = 0,
+      minheight = 300,
 
-    bottom.css('height', (form.height() - bottom.position().top) + 'px');
+    bh = (form.height() - bottom.position().top);
+    ovflw = minheight - bh;
+    btns = ovflw > -100 ? 0 : 40;
+    bottom.css('height', Math.max(minheight, bh) + 'px');
+    form.css('overflow', ovflw > 0 ? 'auto' : 'hidden');
 
     w = body.parent().width() - 5;
     h = body.parent().height() - 16;
@@ -365,6 +373,8 @@
     $('#composebody_tbl').width((w+8)+'px').height('').css('margin-top', '1px');
     $('#composebody_ifr').width((w+8)+'px').height((h-40)+'px');
     $('#googie_edit_layer').height(h+'px');
+//    $('#composebodycontainer')[(btns ? 'addClass' : 'removeClass')]('buttons');
+//    $('#composeformbuttons')[(btns ? 'show' : 'hide')]();
 
     var abooks = $('#directorylist');
     $('#compose-contacts .scroller').css('top', abooks.position().top + abooks.outerHeight());

--
Gitblit v1.9.1