diff options
author | Thomas Bruederli <thomas@roundcube.net> | 2012-10-17 22:42:35 +0200 |
---|---|---|
committer | Thomas Bruederli <thomas@roundcube.net> | 2012-10-17 22:42:35 +0200 |
commit | 271efe53e084779a8141228c29b5819d1acd2762 (patch) | |
tree | 9890424f3bb33281a70b91698631ebdfaf5c9f97 /program | |
parent | 5f6c71ae36b73e5f94543eec2f61874cf46e9c62 (diff) |
Add user settings to open message view and compose form in new windows. This natevely implements the compose_newwindow plugin functionslity and more
Diffstat (limited to 'program')
-rw-r--r-- | program/include/rcube_message.php | 9 | ||||
-rw-r--r-- | program/include/rcube_output_html.php | 11 | ||||
-rw-r--r-- | program/js/app.js | 144 | ||||
-rw-r--r-- | program/localization/en_US/labels.inc | 2 | ||||
-rw-r--r-- | program/steps/addressbook/func.inc | 1 | ||||
-rw-r--r-- | program/steps/addressbook/mailto.inc | 2 | ||||
-rw-r--r-- | program/steps/mail/compose.inc | 19 | ||||
-rw-r--r-- | program/steps/mail/func.inc | 17 | ||||
-rw-r--r-- | program/steps/mail/show.inc | 1 | ||||
-rw-r--r-- | program/steps/settings/func.inc | 24 | ||||
-rw-r--r-- | program/steps/settings/save_prefs.inc | 2 |
11 files changed, 170 insertions, 62 deletions
diff --git a/program/include/rcube_message.php b/program/include/rcube_message.php index 7bf95d1c5..c189df57d 100644 --- a/program/include/rcube_message.php +++ b/program/include/rcube_message.php @@ -210,15 +210,16 @@ class rcube_message 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 - $parent = $this->mime_parts[0]; + 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 6138e2a30..616ab3883 100644 --- a/program/include/rcube_output_html.php +++ b/program/include/rcube_output_html.php @@ -77,6 +77,9 @@ class rcube_output_html extends rcube_output $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'); @@ -274,6 +277,8 @@ class rcube_output_html extends rcube_output */ public function redirect($p = array(), $delay = 1) { + if ($this->env['extwin']) + $p['extwin'] = 1; $location = $this->app->url($p); header('Location: ' . $location); exit; @@ -974,7 +979,7 @@ class rcube_output_html extends rcube_output 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']; } } @@ -1319,6 +1324,10 @@ class rcube_output_html extends rcube_output $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 06eb9295c..7e55a3395 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -176,10 +176,10 @@ function rcube_webmail() } // 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 @@ function rcube_webmail() } } 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 @@ function rcube_webmail() 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('about:blank', 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 @@ function rcube_webmail() } 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(); } @@ -641,7 +662,7 @@ function rcube_webmail() 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); } @@ -670,7 +691,7 @@ function rcube_webmail() 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; @@ -863,47 +884,46 @@ function rcube_webmail() 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)); - 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]); + 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); + 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; + break; + } } else if (props) - url += '&_to='+urlencode(props); + url._to = props; - this.redirect(url); + this.open_compose_step(url); break; case 'spellcheck': @@ -978,7 +998,7 @@ function rcube_webmail() else if (command == 'reply-list') url._all = 'list'; - this.goto_url('compose', url, true); + this.open_compose_step(url); } break; @@ -988,7 +1008,7 @@ function rcube_webmail() 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; @@ -1562,7 +1582,7 @@ function rcube_webmail() 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); }; @@ -1644,6 +1664,21 @@ function rcube_webmail() 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); + extwin.moveTo(l,t); + window.setTimeout(function(){ extwin.focus(); }, 10); + + return wname; + }; + /*********************************************************/ /********* (message) list functionality *********/ @@ -1907,7 +1942,7 @@ function rcube_webmail() 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) @@ -1932,10 +1967,17 @@ function rcube_webmail() // 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) { @@ -2963,6 +3005,17 @@ function rcube_webmail() /********* 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() { @@ -2977,6 +3030,11 @@ function rcube_webmail() ac_fields = ['cc', 'bcc', 'replyto', 'followupto'], ac_props; + // copy contents from opener (after opening in a new window) + if (window.opener && opener.rcmail && opener.rcmail.env.action == 'compose') { + //opener.history.back(); + } + // configure parallel autocompletion if (this.env.autocomplete_threads > 0) { ac_props = { @@ -3631,8 +3689,16 @@ function rcube_webmail() 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/en_US/labels.inc b/program/localization/en_US/labels.inc index fbc154b88..fcf7fac19 100644 --- a/program/localization/en_US/labels.inc +++ b/program/localization/en_US/labels.inc @@ -383,6 +383,8 @@ $labels['timezone'] = 'Time zone'; $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/steps/addressbook/func.inc b/program/steps/addressbook/func.inc index 4ef4d1b51..3a0508025 100644 --- a/program/steps/addressbook/func.inc +++ b/program/steps/addressbook/func.inc @@ -87,6 +87,7 @@ if (!$RCMAIL->action && !$OUTPUT->ajax_call) { $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 3806c2c87..c3cbcadca 100644 --- a/program/steps/addressbook/mailto.inc +++ b/program/steps/addressbook/mailto.inc @@ -68,7 +68,7 @@ if (!empty($mailto)) $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 691eca2db..24cd5e425 100644 --- a/program/steps/mail/compose.inc +++ b/program/steps/mail/compose.inc @@ -130,6 +130,7 @@ $OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubj '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 @@ function rcmail_compose_editor_mode() $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 @@ function rcmail_receipt_checkbox($attrib) $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 @@ function rcmail_dsn_checkbox($attrib) $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 @@ function rcmail_store_target_selection($attrib) '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 c21202588..c18d2cd13 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -101,18 +101,11 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') { $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 029bc5f8d..f89660719 100644 --- a/program/steps/mail/show.inc +++ b/program/steps/mail/show.inc @@ -59,6 +59,7 @@ if ($uid = get_input_value('_uid', RCUBE_INPUT_GET)) { $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 c60d17f30..e94630635 100644 --- a/program/steps/settings/func.inc +++ b/program/steps/settings/func.inc @@ -129,8 +129,8 @@ function rcmail_user_prefs($current=null) $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')); @@ -414,6 +414,17 @@ function rcmail_user_prefs($current=null) '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'; @@ -483,6 +494,17 @@ function rcmail_user_prefs($current=null) '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 d1627ecea..db7b134c4 100644 --- a/program/steps/settings/save_prefs.inc +++ b/program/steps/settings/save_prefs.inc @@ -59,6 +59,7 @@ switch ($CURR_SECTION) 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 @@ switch ($CURR_SECTION) 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, |