diff options
| author | Nathan Kinkade <nkinkade@nkinka.de> | 2009-03-05 20:48:46 +0000 |
|---|---|---|
| committer | Nathan Kinkade <nkinkade@nkinka.de> | 2009-03-11 12:51:51 +0000 |
| commit | 32ea464bdfe5f8a22f46bfac50dcdc26c36fc497 (patch) | |
| tree | 50b13882e43a778a9e9dcec19f18d18bc8bb1aa9 /roundcubemail/program/steps | |
| parent | 8013cb2424ca6912419dc7df73a9b8b77da7bdb0 (diff) | |
Applied message threading patch from Chris January: http://www.atomice.com/blog/?p=33
Diffstat (limited to 'roundcubemail/program/steps')
| -rw-r--r-- | roundcubemail/program/steps/mail/check_recent.inc | 32 | ||||
| -rw-r--r-- | roundcubemail/program/steps/mail/func.inc | 64 | ||||
| -rw-r--r-- | roundcubemail/program/steps/mail/list.inc | 5 | ||||
| -rw-r--r-- | roundcubemail/program/steps/mail/move_del.inc | 11 | ||||
| -rw-r--r-- | roundcubemail/program/steps/mail/rss.inc | 2 | ||||
| -rw-r--r-- | roundcubemail/program/steps/mail/search.inc | 2 | ||||
| -rw-r--r-- | roundcubemail/program/steps/settings/func.inc | 2 | ||||
| -rw-r--r-- | roundcubemail/program/steps/settings/manage_folders.inc | 38 |
8 files changed, 115 insertions, 41 deletions
diff --git a/roundcubemail/program/steps/mail/check_recent.inc b/roundcubemail/program/steps/mail/check_recent.inc index a0668537d..d13eef163 100644 --- a/roundcubemail/program/steps/mail/check_recent.inc +++ b/roundcubemail/program/steps/mail/check_recent.inc @@ -28,9 +28,9 @@ foreach ($a_mailboxes as $mbox_name) { // refresh saved search set if (($search_request = get_input_value('_search', RCUBE_INPUT_GPC)) && isset($_SESSION['search'][$search_request])) { $_SESSION['search'][$search_request] = $IMAP->refresh_search(); - $all_count = $IMAP->messagecount(); + $all_count = $IMAP->messagecount(NULL, rcmail::get_instance()->imap->threading?'THREADS':'ALL'); } else { - $all_count = $IMAP->messagecount(NULL, 'ALL', TRUE); + $all_count = $IMAP->messagecount(NULL, rcmail::get_instance()->imap->threading?'THREADS':'ALL', TRUE); } $unread_count = $IMAP->messagecount(NULL, 'UNSEEN', TRUE); @@ -51,18 +51,24 @@ foreach ($a_mailboxes as $mbox_name) { if (empty($_GET['_list'])) continue; - // use SEARCH/SORT to find recent messages - $search_str = 'RECENT'; - if ($search_request) - $search_str .= ' '.$IMAP->search_string; - - $result = $IMAP->search($mbox_name, $search_str, NULL, 'date'); + if (rcmail::get_instance()->imap->threading) { + $OUTPUT->command('message_list.clear'); + $sort_col = isset($_SESSION['sort_col']) ? $_SESSION['sort_col'] : $CONFIG['message_sort_col']; + $sort_order = isset($_SESSION['sort_order']) ? $_SESSION['sort_order'] : $CONFIG['message_sort_order']; + $result_h = $IMAP->list_headers($mbox_name, NULL, $sort_col, $sort_order); + // add to the list + rcmail_js_message_list($result_h); + } else { + // use SEARCH/SORT to find recent messages + $search_str = 'RECENT'; + if ($search_request) + $search_str .= ' '.$IMAP->search_string; - if ($result) { - // get the headers - $result_h = $IMAP->list_headers($mbox_name, 1, 'date', 'DESC'); - // add to the list - rcmail_js_message_list($result_h, TRUE); + $result = $IMAP->search($mbox_name, $search_str, NULL, 'date'); + // get the headers + $result_h = $IMAP->list_headers($mbox_name, 1, 'date', 'DESC'); + // add to the list + rcmail_js_message_list($result_h, TRUE); } } } diff --git a/roundcubemail/program/steps/mail/func.inc b/roundcubemail/program/steps/mail/func.inc index 79e148d8a..bac49463e 100644 --- a/roundcubemail/program/steps/mail/func.inc +++ b/roundcubemail/program/steps/mail/func.inc @@ -44,6 +44,8 @@ if ($mbox = get_input_value('_mbox', RCUBE_INPUT_GPC)) $IMAP->set_mailbox(($_SESSION['mbox'] = $mbox)); else $_SESSION['mbox'] = $IMAP->get_mailbox_name(); +$a_message_threading = $RCMAIL->config->get('message_threading', array()); +rcmail::get_instance()->imap->threading = $a_message_threading[$_SESSION['mbox']]; if (!empty($_GET['_page'])) $IMAP->set_page(($_SESSION['page'] = intval($_GET['_page']))); @@ -80,7 +82,7 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') } // make sure the message count is refreshed (for default view) - $IMAP->messagecount($mbox_name, 'ALL', true); + $IMAP->messagecount($mbox_name, rcmail::get_instance()->imap->threading?'THREADS':'ALL', true); } // set current mailbox in client environment @@ -152,7 +154,6 @@ function rcmail_message_list($attrib) // add col definition $out .= '<colgroup>'; - $out .= '<col class="icon" />'; foreach ($a_show_cols as $col) $out .= ($col!='attachment') ? sprintf('<col class="%s" />', $col) : '<col class="icon" />'; @@ -160,7 +161,7 @@ function rcmail_message_list($attrib) $out .= "</colgroup>\n"; // add table title - $out .= "<thead><tr>\n<td class=\"icon\"> </td>\n"; + $out .= "<thead><tr>\n"; $javascript = ''; foreach ($a_show_cols as $col) @@ -257,9 +258,15 @@ function rcmail_message_list($attrib) $js_row_arr['forwarded'] = true; if ($header->flagged) $js_row_arr['flagged'] = true; + if ($header->has_children) + $js_row_arr['has_children'] = true; + $js_row_arr['depth'] = $header->depth; + $js_row_arr['unread_children'] = $header->unread_children; - // set message icon - if ($attrib['deletedicon'] && $header->deleted) + // set message icon + if ($header->seen && $attrib['unreadchildrenicon'] && $header->unread_children > 0) + $message_icon = $attrib['unreadchildrenicon']; + else if ($attrib['deletedicon'] && $header->deleted) $message_icon = $attrib['deletedicon']; else if ($attrib['repliedicon'] && $header->answered) { @@ -284,19 +291,28 @@ function rcmail_message_list($attrib) if ($attrib['attachmenticon'] && preg_match("/multipart\/m/i", $header->ctype)) $attach_icon = $attrib['attachmenticon']; - $out .= sprintf('<tr id="rcmrow%d" class="message%s%s%s%s">'."\n", + $out .= sprintf('<tr id="rcmrow%d" class="message%s%s%s%s"%s>'."\n", $header->uid, $header->seen ? '' : ' unread', $header->deleted ? ' deleted' : '', $header->flagged ? ' flagged' : '', - $zebra_class); + $zebra_class, + ($header->depth > 1) ? ' style="display: none"' : ''); - $out .= sprintf("<td class=\"icon\">%s</td>\n", $message_icon ? sprintf($image_tag, $skin_path, $message_icon, '') : ''); - + $tree = ''; + $depth = $header->depth; + if ($depth > 0) + { + for ($i=1;$i<$depth;$i++) + $tree .= '<div class="branch"> </div>'; + $tree .= $header->has_children?'<div id="rcmexpando' . $header->uid . '" class="collapsed"> </div>':'<div class="leaf"> </div>'; + } + $tree .= $message_icon ? sprintf($image_tag, $skin_path, $message_icon, '') : ''; $IMAP->set_charset(!empty($header->charset) ? $header->charset : $CONFIG['default_charset']); // format each col + $first = true; foreach ($a_show_cols as $col) { if ($col=='from' || $col=='to') @@ -318,6 +334,10 @@ function rcmail_message_list($attrib) else $cont = Q($header->$col); + if ($first) { + $first = false; + $cont = $tree . $cont; + } if ($col!='attachment') $out .= '<td class="'.$col.'">' . $cont . "</td>\n"; else @@ -333,7 +353,7 @@ function rcmail_message_list($attrib) // complete message table $out .= "</tbody></table>\n"; - $message_count = $IMAP->messagecount(); + $message_count = $IMAP->messagecount(NULL, rcmail::get_instance()->imap->threading?'THREADS':'ALL'); // set client env $OUTPUT->add_gui_object('mailcontframe', 'mailcontframe'); @@ -362,6 +382,8 @@ function rcmail_message_list($attrib) $OUTPUT->set_env('flaggedicon', $skin_path . $attrib['flaggedicon']); if ($attrib['unflaggedicon']) $OUTPUT->set_env('unflaggedicon', $skin_path . $attrib['unflaggedicon']); + if ($attrib['unreadchildrenicon']) + $OUTPUT->set_env('unreadchildrenicon', $skin_path . $attrib['unreadchildrenicon']); $OUTPUT->set_env('messages', $a_js_message_arr); $OUTPUT->set_env('coltypes', $a_show_cols); @@ -393,6 +415,12 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE) $OUTPUT->command('set_message_coltypes', $a_show_cols); + // remove 'attachment' and 'flag' columns, we don't need them here + if(($key = array_search('attachment', $a_show_cols)) !== FALSE) + unset($a_show_cols[$key]); + if(($key = array_search('flag', $a_show_cols)) !== FALSE) + unset($a_show_cols[$key]); + // loop through message headers foreach ($a_headers as $n => $header) { @@ -404,12 +432,6 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE) $IMAP->set_charset(!empty($header->charset) ? $header->charset : $CONFIG['default_charset']); - // remove 'attachment' and 'flag' columns, we don't need them here - if(($key = array_search('attachment', $a_show_cols)) !== FALSE) - unset($a_show_cols[$key]); - if(($key = array_search('flag', $a_show_cols)) !== FALSE) - unset($a_show_cols[$key]); - // format each col; similar as in rcmail_message_list() foreach ($a_show_cols as $col) { @@ -438,6 +460,9 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE) $a_msg_flags['replied'] = $header->answered ? 1 : 0; $a_msg_flags['forwarded'] = $header->forwarded ? 1 : 0; $a_msg_flags['flagged'] = $header->flagged ? 1 : 0; + $a_msg_flags['has_children'] = $header->has_children ? 1 : 0; + $a_msg_cols['depth'] = $header->depth; + $a_msg_cols['unread_children'] = $header->unread_children; $OUTPUT->command('add_message_row', $header->uid, @@ -446,6 +471,7 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE) preg_match("/multipart\/m/i", $header->ctype), $insert_top); } + $OUTPUT->command('expand_threads'); } @@ -569,19 +595,19 @@ function rcmail_get_messagecount_text($count=NULL, $page=NULL) { return rcube_label(array('name' => 'messagenrof', 'vars' => array('nr' => $MESSAGE->index+1, - 'count' => $count!==NULL ? $count : $IMAP->messagecount()))); + 'count' => $count!==NULL ? $count : $IMAP->messagecount(NULL, rcmail::get_instance()->imap->threading?'THREADS':'ALL')))); } if ($page===NULL) $page = $IMAP->list_page; $start_msg = ($page-1) * $IMAP->page_size + 1; - $max = $count!==NULL ? $count : $IMAP->messagecount(); + $max = $count!==NULL ? $count : $IMAP->messagecount(NULL, rcmail::get_instance()->imap->threading?'THREADS':'ALL'); if ($max==0) $out = rcube_label('mailboxempty'); else - $out = rcube_label(array('name' => 'messagesfromto', + $out = rcube_label(array('name' => rcmail::get_instance()->imap->threading?'threadsfromto':'messagesfromto', 'vars' => array('from' => $start_msg, 'to' => min($max, $start_msg + $IMAP->page_size - 1), 'count' => $max))); diff --git a/roundcubemail/program/steps/mail/list.inc b/roundcubemail/program/steps/mail/list.inc index 5cc2a574d..4d5169c29 100644 --- a/roundcubemail/program/steps/mail/list.inc +++ b/roundcubemail/program/steps/mail/list.inc @@ -53,10 +53,10 @@ if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL') // fetch message headers -if ($IMAP->messagecount($mbox_name, 'ALL', !empty($_REQUEST['_refresh']))) +if ($IMAP->messagecount($mbox_name, rcmail::get_instance()->imap->threading?'THREADS':'ALL', !empty($_REQUEST['_refresh']))) $a_headers = $IMAP->list_headers($mbox_name, NULL, $sort_col, $sort_order); -$count = $IMAP->messagecount($mbox_name); +$count = $IMAP->messagecount($mbox_name, rcmail::get_instance()->imap->threading?'THREADS':'ALL'); $unseen = $IMAP->messagecount($mbox_name, 'UNSEEN', !empty($_REQUEST['_refresh'])); // update message count display @@ -65,6 +65,7 @@ $OUTPUT->set_env('messagecount', $count); $OUTPUT->set_env('pagecount', $pages); $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($count)); $OUTPUT->command('set_mailboxname', rcmail_get_mailbox_name_text()); +$OUTPUT->command('set_threaded', rcmail::get_instance()->imap->threading); // add message rows if (isset($a_headers) && count($a_headers)) diff --git a/roundcubemail/program/steps/mail/move_del.inc b/roundcubemail/program/steps/mail/move_del.inc index 673bd800b..bf78429f1 100644 --- a/roundcubemail/program/steps/mail/move_del.inc +++ b/roundcubemail/program/steps/mail/move_del.inc @@ -20,7 +20,7 @@ */ // count messages before changing anything -$old_count = $IMAP->messagecount(); +$old_count = $IMAP->messagecount(NULL, rcmail::get_instance()->imap->threading?'THREADS':'ALL'); $old_pages = ceil($old_count / $IMAP->page_size); // move messages @@ -71,7 +71,7 @@ if (($search_request = get_input_value('_search', RCUBE_INPUT_GPC)) && $IMAP->se $_SESSION['search'][$search_request] = $IMAP->refresh_search(); } -$msg_count = $IMAP->messagecount(); +$msg_count = $IMAP->messagecount(NULL, rcmail::get_instance()->imap->threading?'THREADS':'ALL'); $pages = ceil($msg_count / $IMAP->page_size); $nextpage_count = $old_count - $IMAP->page_size * $IMAP->list_page; $remaining = $msg_count - $IMAP->page_size * ($IMAP->list_page - 1); @@ -90,7 +90,6 @@ $OUTPUT->set_env('current_page', $IMAP->list_page); $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($msg_count)); // update mailboxlist -$mbox = $IMAP->get_mailbox_name(); $OUTPUT->command('set_unread_count', $mbox, $IMAP->messagecount($mbox, 'UNSEEN'), ($mbox == 'INBOX')); if ($RCMAIL->action=='moveto' && $target) { @@ -106,7 +105,11 @@ if ($addrows && $_POST['_from']!='show' && ($jump_back || $nextpage_count > 0)) $a_headers = $IMAP->list_headers($mbox, NULL, $sort_col, $sort_order); if (!$jump_back) { - $a_headers = array_slice($a_headers, -$count, $count); + if ($_SESSION['threads']) + // TODO: count number of roots deleted and slice that many roots from the end of $a_headers + $OUTPUT->command('message_list.clear'); + else + $a_headers = array_slice($a_headers, -$count, $count); } rcmail_js_message_list($a_headers); } diff --git a/roundcubemail/program/steps/mail/rss.inc b/roundcubemail/program/steps/mail/rss.inc index 72317c68f..4e75811c9 100644 --- a/roundcubemail/program/steps/mail/rss.inc +++ b/roundcubemail/program/steps/mail/rss.inc @@ -42,7 +42,7 @@ if (dirname($_SERVER['SCRIPT_NAME']) != '/') $webmail_url .= '?_task=mail'; $messagecount_unread = $IMAP->messagecount('INBOX', 'UNSEEN', TRUE); -$messagecount = $IMAP->messagecount(); +$messagecount = $IMAP->messagecount(NULL, rcmail::get_instance()->imap->threading?'THREADS':'ALL'); $sort_col = 'date'; $sort_order = 'DESC'; diff --git a/roundcubemail/program/steps/mail/search.inc b/roundcubemail/program/steps/mail/search.inc index 95ca67a12..d74a23030 100644 --- a/roundcubemail/program/steps/mail/search.inc +++ b/roundcubemail/program/steps/mail/search.inc @@ -90,7 +90,7 @@ if ($search_str) // Get the headers $result_h = $IMAP->list_headers($mbox, 1, $_SESSION['sort_col'], $_SESSION['sort_order']); -$count = $IMAP->messagecount(); +$count = $IMAP->messagecount(NULL, rcmail::get_instance()->imap->threading?'THREADS':'ALL'); // save search results in session if (!is_array($_SESSION['search'])) diff --git a/roundcubemail/program/steps/settings/func.inc b/roundcubemail/program/steps/settings/func.inc index d0a3ae69c..6515ae4f6 100644 --- a/roundcubemail/program/steps/settings/func.inc +++ b/roundcubemail/program/steps/settings/func.inc @@ -168,6 +168,8 @@ function rcmail_user_prefs_block($part, $no_override, $attrib) case 'mailbox': $table = new html_table(array('cols' => 2)); + $RCMAIL->imap_init(true); + if (!isset($no_override['focus_on_new_message'])) { $field_id = 'rcmfd_focus_on_new_message'; $input_focus_on_new_message = new html_checkbox(array('name' => '_focus_on_new_message', 'id' => $field_id, 'value' => 1)); diff --git a/roundcubemail/program/steps/settings/manage_folders.inc b/roundcubemail/program/steps/settings/manage_folders.inc index 9affded98..80a6b7c65 100644 --- a/roundcubemail/program/steps/settings/manage_folders.inc +++ b/roundcubemail/program/steps/settings/manage_folders.inc @@ -38,6 +38,28 @@ else if ($RCMAIL->action=='unsubscribe') $IMAP->unsubscribe(array($mbox)); } +// enable threading for one or more mailboxes +else if ($RCMAIL->action=='enable-threading') + { + if ($mbox = get_input_value('_mbox', RCUBE_INPUT_POST, false, 'UTF-7')) + $a_user_prefs = $USER->get_prefs(); + if (!is_array($a_user_prefs['message_threading'])) + $a_user_prefs['message_threading'] = array(); + $a_user_prefs['message_threading'][$mbox] = true; + $USER->save_prefs($a_user_prefs); + } + +// enable threading for one or more mailboxes +else if ($RCMAIL->action=='disable-threading') + { + if ($mbox = get_input_value('_mbox', RCUBE_INPUT_POST, false, 'UTF-7')) + $a_user_prefs = $USER->get_prefs(); + if (!is_array($a_user_prefs['message_threading'])) + $a_user_prefs['message_threading'] = array(); + unset($a_user_prefs['message_threading'][$mbox]); + $USER->save_prefs($a_user_prefs); + } + // create a new mailbox else if ($RCMAIL->action=='create-folder') { @@ -162,6 +184,8 @@ function rcube_subscription_form($attrib) { global $IMAP, $CONFIG, $OUTPUT; + $threading_supported = $IMAP->get_capability('thread=references'); + list($form_start, $form_end) = get_form_tags($attrib, 'folders'); unset($attrib['form']); @@ -174,6 +198,8 @@ function rcube_subscription_form($attrib) $table->add_header('name', rcube_label('foldername')); $table->add_header('msgcount', rcube_label('messagecount')); $table->add_header('subscribed', rcube_label('subscribed')); + if ($threading_supported) + $table->add_header('threaded', rcube_label('threaded')); $table->add_header('rename', ' '); $table->add_header('delete', ' '); @@ -183,6 +209,7 @@ function rcube_subscription_form($attrib) $a_unsubscribed = $IMAP->list_unsubscribed(); $a_subscribed = $IMAP->list_mailboxes(); + $a_threaded =rcmail::get_instance()->config->get('message_threading', array()); $delimiter = $IMAP->get_hierarchy_delimiter(); $a_js_folders = $seen_folders = $list_folders = array(); @@ -212,6 +239,10 @@ function rcube_subscription_form($attrib) 'name' => '_subscribed[]', 'onclick' => JS_OBJECT_NAME.".command(this.checked?'subscribe':'unsubscribe',this.value)", )); + $checkbox_threaded = new html_checkbox(array( + 'name' => '_threaded[]', + 'onclick' => JS_OBJECT_NAME.".command(this.checked?'enable-threading':'disable-threading',this.value)", + )); if (!empty($attrib['deleteicon'])) $del_button = html::img(array('src' => $CONFIG['skin_path'] . $attrib['deleteicon'], 'alt' => rcube_label('delete'))); @@ -227,6 +258,7 @@ function rcube_subscription_form($attrib) foreach ($list_folders as $i => $folder) { $idx = $i + 1; $subscribed = in_array($folder['id'], $a_subscribed); + $threaded = $a_threaded[$folder['id']]; $protected = ($CONFIG['protect_default_folders'] == true && in_array($folder['id'], $CONFIG['default_imap_folders'])); $classes = array($i%2 ? 'even' : 'odd'); $folder_js = JQ($folder['id']); @@ -239,9 +271,13 @@ function rcube_subscription_form($attrib) $table->add_row(array('id' => 'rcmrow'.$idx, 'class' => join(' ', $classes))); $table->add('name', Q($display_folder)); - $table->add('msgcount', ($folder['virtual'] ? '' : $IMAP->messagecount($folder['id']))); + $table->add('msgcount', ($folder['virtual'] ? '' : $IMAP->messagecount($folder['id']))); // XXX: Use THREADS or ALL? $table->add('subscribed', ($protected || $folder['virtual']) ? ($subscribed ? ' •' : ' ') : $checkbox_subscribe->show(($subscribed ? $folder_utf8 : ''), array('value' => $folder_utf8))); + if ($IMAP->get_capability('thread=references')) { + $table->add('threaded', + $checkbox_threaded->show(($threaded ? $folder_utf8 : ''), array('value' => $folder_utf8))); + } // add rename and delete buttons if (!$protected && !$folder['virtual']) { |
