summaryrefslogtreecommitdiff
path: root/roundcubemail/program/steps
diff options
context:
space:
mode:
authorNathan Kinkade <nkinkade@nkinka.de>2009-03-05 20:48:46 +0000
committerNathan Kinkade <nkinkade@nkinka.de>2009-03-11 12:51:51 +0000
commit32ea464bdfe5f8a22f46bfac50dcdc26c36fc497 (patch)
tree50b13882e43a778a9e9dcec19f18d18bc8bb1aa9 /roundcubemail/program/steps
parent8013cb2424ca6912419dc7df73a9b8b77da7bdb0 (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.inc32
-rw-r--r--roundcubemail/program/steps/mail/func.inc64
-rw-r--r--roundcubemail/program/steps/mail/list.inc5
-rw-r--r--roundcubemail/program/steps/mail/move_del.inc11
-rw-r--r--roundcubemail/program/steps/mail/rss.inc2
-rw-r--r--roundcubemail/program/steps/mail/search.inc2
-rw-r--r--roundcubemail/program/steps/settings/func.inc2
-rw-r--r--roundcubemail/program/steps/settings/manage_folders.inc38
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\">&nbsp;</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">&nbsp</div>';
+ $tree .= $header->has_children?'<div id="rcmexpando' . $header->uid . '" class="collapsed">&nbsp;</div>':'<div class="leaf">&nbsp;</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', '&nbsp;');
$table->add_header('delete', '&nbsp;');
@@ -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 ? '&nbsp;&#x2022;' : '&nbsp;') :
$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']) {