Okay, at long last here is the patch. I believe this is the final version (containing all of your helpful suggestions)
There are three new options:
read_when_deleted = TRUE by default (emulating Thunderbird) if true messages will be marked as read when they are deleted. if set to false messages will preserver their read/unread status
flag_for_deletion = TRUE by default. If set to true messages will be flagged for deletion rather than deleted outright IF AND ONLY IF there is no Trash folder present
javascript_config = array('read_when_deleted', 'flag_for_deletion') This is an array of options that will be available in javascript. To reference them in Javascript simply call: this.env.flag_for_deletion (for instance)
Deleting messages will now behave thusly: If you have a Trash folder: Messages will always go into the Trash folder and will maintain their read/unread status
If you do not have a Trash Folder: If you are not in the Trash folder AND flag_for_deletion = TRUE Messages will be flagged for deletion If read_when_deleted = TRUE message will be set to SEEN If you are in the Trash folder OR flag_for_deletion = FALSE Messages will be deleted immediately.
I think that's about it! Let me know if you have any problems with the patch.
-Charles
? delete.patch ? log ? config/db.inc.php ? config/main.inc.php ? logs/error.log ? program/js/DP_Debug.js ? program/js/diff.patch ? temp/733216469445435dd61a9e ? temp/894471295445435a64469d ? temp/ae8f4077551837a4ccf4a06f9ea3d3d3 Index: index.php =================================================================== RCS file: /cvsroot/roundcubemail/roundcubemail/index.php,v retrieving revision 1.38 diff -b -B -c -r1.38 index.php Index: config/main.inc.php.dist =================================================================== RCS file: /cvsroot/roundcubemail/roundcubemail/config/main.inc.php.dist,v retrieving revision 1.28 diff -b -B -c -r1.28 main.inc.php.dist *** config/main.inc.php.dist 13 Apr 2006 18:23:48 -0000 1.28 --- config/main.inc.php.dist 1 May 2006 15:38:15 -0000
*** 132,137 **** --- 132,146 ---- // This will make the application run slower $rcmail_config['skip_deleted'] = FALSE;
*** 180,185 **** --- 189,196 ---- // default sort order $rcmail_config['message_sort_order'] = 'DESC';
// list of configuration option names that need to be available in Javascript.
$rcmail_config['javascript_config'] = array('read_when_deleted', 'flag_for_deletion');
/***** try to load host-specific configuration *****/
RCS file: /cvsroot/roundcubemail/roundcubemail/program/include/main.inc,v retrieving revision 1.50 diff -b -B -c -r1.50 main.inc *** program/include/main.inc 13 Apr 2006 18:23:44 -0000 1.50 --- program/include/main.inc 1 May 2006 15:38:15 -0000
*** 317,322 **** --- 314,323 ---- $javascript = "var $JS_OBJECT_NAME = new rcube_webmail();\n"; $javascript .= "$JS_OBJECT_NAME.set_env('comm_path', '$COMM_PATH');\n";
$javascript .= "$JS_OBJECT_NAME.set_env('$js_config_var', '" . $CONFIG[$js_config_var] . "');\n";
RCS file: /cvsroot/roundcubemail/roundcubemail/program/include/rcube_imap.inc,v retrieving revision 1.34 diff -b -B -c -r1.34 rcube_imap.inc *** program/include/rcube_imap.inc 27 Mar 2006 19:07:13 -0000 1.34 --- program/include/rcube_imap.inc 1 May 2006 15:38:15 -0000
*** 934,951 ****
// set message flag to one or several messages
! // possible flgs are: SEEN, DELETED, RECENT, ANSWERED, DRAFT function set_flag($uids, $flag) { $flag = strtoupper($flag); $msg_ids = array(); if (!is_array($uids)) ! $uids = array($uids);
! foreach ($uids as $uid) $msg_ids[$uid] = $this->_uid2id($uid);
! if ($flag=='UNSEEN') $result = iil_C_Unseen($this->conn, $this->mailbox, join(',', array_values($msg_ids))); else $result = iil_C_Flag($this->conn, $this->mailbox, join(',', array_values($msg_ids)), $flag); --- 934,954 ----
// set message flag to one or several messages
! // possible flags are: SEEN, UNDELETED, DELETED, RECENT, ANSWERED, DRAFT function set_flag($uids, $flag) { $flag = strtoupper($flag); $msg_ids = array(); if (!is_array($uids)) ! $uids = explode(',',$uids);
! foreach ($uids as $uid) { $msg_ids[$uid] = $this->_uid2id($uid);
}
! if ($flag=='UNDELETED') ! $result = iil_C_Undelete($this->conn, $this->mailbox, join(',', array_values($msg_ids))); ! else if ($flag=='UNSEEN') $result = iil_C_Unseen($this->conn, $this->mailbox, join(',', array_values($msg_ids))); else $result = iil_C_Flag($this->conn, $this->mailbox, join(',', array_values($msg_ids)), $flag); Index: program/js/app.js =================================================================== RCS file: /cvsroot/roundcubemail/roundcubemail/program/js/app.js,v retrieving revision 1.40 diff -b -B -c -r1.40 app.js *** program/js/app.js 24 Apr 2006 16:15:16 -0000 1.40 --- program/js/app.js 1 May 2006 15:38:16 -0000
*** 29,34 **** --- 28,34 ---- this.gui_objects = new Object(); this.commands = new Object(); this.selection = new Array();
this.last_selected = 0;
// create public reference to myself rcube_webmail_client = this;
*** 118,124 **** { msg_list_frame.onmousedown = function(e){return rcube_webmail_client.click_on_list(e);}; this.init_messagelist(msg_list); ! this.enable_command('markread', true); }
// enable mail commands
--- 118,124 ---- { msg_list_frame.onmousedown = function(e){return rcube_webmail_client.click_on_list(e);}; this.init_messagelist(msg_list); ! this.enable_command('toggle_status', true); }
// enable mail commands
*** 288,313 ****
this.use_arrow_key = function(keyCode, mod_key, msg_list_frame) {
var scroll_to = 0;
var last_selected_row = this.list_rows[this.last_selected];
if (keyCode == 40) { // down arrow key pressed
! var new_row = last_selected_row.obj.nextSibling;
! while (new_row && new_row.nodeType != 1) {
! new_row = new_row.nextSibling;
! }
if (!new_row) return false;
scroll_to = (Number(new_row.offsetTop) + Number(new_row.offsetHeight)) - Number(msg_list_frame.offsetHeight);
} else if (keyCode == 38) { // up arrow key pressed
! var new_row = last_selected_row.obj.previousSibling;
! while (new_row && new_row.nodeType != 1) {
! new_row = new_row.previousSibling;
! }
if (!new_row) return false;
scroll_to = new_row.offsetTop;
} else {return true;}
! if (mod_key != CONTROL_KEY)
! this.select_row(new_row.uid,mod_key);
if (((Number(new_row.offsetTop)) < (Number(msg_list_frame.scrollTop))) ||
((Number(new_row.offsetTop) + Number(new_row.offsetHeight)) > (Number(msg_list_frame.scrollTop) + Number(msg_list_frame.offsetHeight)))) {
--- 288,304 ----
this.use_arrow_key = function(keyCode, mod_key, msg_list_frame) {
var scroll_to = 0;
if (keyCode == 40) { // down arrow key pressed
! new_row = this.get_next_row();
if (!new_row) return false;
scroll_to = (Number(new_row.offsetTop) + Number(new_row.offsetHeight)) - Number(msg_list_frame.offsetHeight);
} else if (keyCode == 38) { // up arrow key pressed
! new_row = this.get_prev_row();
if (!new_row) return false;
scroll_to = new_row.offsetTop;
} else {return true;}
! this.select_row(new_row.uid,mod_key,true);
if (((Number(new_row.offsetTop)) < (Number(msg_list_frame.scrollTop))) ||
((Number(new_row.offsetTop) + Number(new_row.offsetHeight)) > (Number(msg_list_frame.scrollTop) + Number(msg_list_frame.offsetHeight)))) {
*** 355,360 **** --- 346,352 ----
this.message_rows[uid] = {id:row.id, obj:row,
classname:row.className,
deleted:this.env.messages[uid] ? this.env.messages[uid].deleted : null,
unread:this.env.messages[uid] ? this.env.messages[uid].unread : null,
replied:this.env.messages[uid] ? this.env.messages[uid].replied : null};
*** 370,376 ****
{
msg_icon.id = 'msgicn_'+uid;
msg_icon._row = row;
! msg_icon.onmousedown = function(e) { rcube_webmail_client.command('markread', this); };
// get message icon and save original icon src
this.message_rows[uid].icon = msg_icon;
--- 362,368 ----
{
msg_icon.id = 'msgicn_'+uid;
msg_icon._row = row;
! msg_icon.onmousedown = function(e) { rcube_webmail_client.command('toggle_status', this); };
// get message icon and save original icon src
this.message_rows[uid].icon = msg_icon;
*** 731,739 ****
case 'delete':
// mail task
! if (this.task=='mail' && this.env.trash_mailbox && String(this.env.mailbox).toLowerCase()!=String(this.env.trash_mailbox).toLowerCase()) ! this.move_messages(this.env.trash_mailbox); ! else if (this.task=='mail') this.delete_messages(); // addressbook task else if (this.task=='addressbook') --- 723,729 ----
case 'delete':
// mail task
! if (this.task=='mail') this.delete_messages(); // addressbook task else if (this.task=='addressbook')
*** 750,756 **** this.move_messages(props); break;
! case 'markread': if (props && !props._row) break;
--- 740,746 ---- this.move_messages(props); break;
! case 'toggle_status': if (props && !props._row) break;
*** 761,769 **** { uid = props._row.uid; this.dont_select = true;
// toggle read/unread
! if (!this.message_rows[uid].unread) flag = 'unread'; }
--- 751,760 ---- { uid = props._row.uid; this.dont_select = true; // toggle read/unread ! if (this.message_rows[uid].deleted) { ! flag = 'undelete'; ! } else if (!this.message_rows[uid].unread) flag = 'unread'; }
*** 1111,1117 **** if (!this.in_selection_before) { var mod_key = this.get_modifier(e); ! this.select_row(id,mod_key); }
if (this.selection.length)
--- 1102,1108 ---- if (!this.in_selection_before) { var mod_key = this.get_modifier(e); ! this.select_row(id,mod_key,false); }
if (this.selection.length)
*** 1139,1145 ****
// unselects currently selected row
if (!this.drag_active && this.in_selection_before==id)
! this.select_row(id,mod_key);
this.drag_start = false;
this.in_selection_before = false;
--- 1130,1136 ----
// unselects currently selected row
if (!this.drag_active && this.in_selection_before==id)
! this.select_row(id,mod_key,false);
this.drag_start = false;
this.in_selection_before = false;
*** 1213,1218 **** --- 1204,1228 ---- /********* (message) list functionality *********/ /*********************************************************/
var last_selected_row = this.list_rows[this.last_selected];
var new_row = last_selected_row.obj.nextSibling;
while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none')) {
new_row = new_row.nextSibling;
}
return new_row;
var last_selected_row = this.list_rows[this.last_selected];
var new_row = last_selected_row.obj.previousSibling;
while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none')) {
new_row = new_row.previousSibling;
}
return new_row;
*** 1259,1265 ****
// selects or unselects the proper row depending on the modifier key pressed ! this.select_row = function(id,mod_key) { if (!mod_key) { this.shift_start = id; this.highlight_row(id, false); --- 1269,1275 ----
// selects or unselects the proper row depending on the modifier key pressed ! this.select_row = function(id,mod_key,with_mouse) { if (!mod_key) { this.shift_start = id; this.highlight_row(id, false);
*** 1270,1275 **** --- 1280,1286 ---- break; } case CONTROL_KEY: { this.shift_start = id;
if (!with_mouse)
this.highlight_row(id, true);
break;
}
*** 1283,1289 **** --- 1294,1302 ---- } } }
if (this.last_selected != 0) { this.set_classname(this.list_rows[this.last_selected].obj, 'focused', false);} this.last_selected = id;
this.set_classname(this.list_rows[id].obj, 'focused', true);
};
this.shift_select = function(id, control) {
*** 1388,1393 **** --- 1401,1407 ---- // list messages of a specific mailbox this.list_mailbox = function(mbox, page, sort) {
this.last_selected = 0;
var add_url = '';
var target = window;
*** 1526,1531 **** --- 1540,1549 ---- if (this.message_rows[id].obj) this.message_rows[id].obj.style.display = 'none'; }
next_row = this.get_next_row();
prev_row = this.get_prev_row();
new_row = (next_row) ? next_row : prev_row;
this.select_row(new_row.uid,false,false);
}
var lock = false;
*** 1541,1550 **** this.http_request('moveto', '_uid='+a_uids.join(',')+'&_mbox='+escape(this.env.mailbox)+'&_target_mbox='+escape(mbox)+'&_from='+(this.env.action ? this.env.action : ''), lock); };
! ! // delete selected messages from the current mailbox ! this.delete_messages = function() ! { // exit if no mailbox specified or if selection is empty if (!(this.selection.length || this.env.uid)) return; --- 1559,1565 ---- this.http_request('moveto', '_uid='+a_uids.join(',')+'&_mbox='+escape(this.env.mailbox)+'&_target_mbox='+escape(mbox)+'&_from='+(this.env.action ? this.env.action : ''), lock); };
! this.permanently_remove_messages = function() { // exit if no mailbox specified or if selection is empty if (!(this.selection.length || this.env.uid)) return;
*** 1566,1574 **** --- 1581,1620 ---- this.message_rows[id].obj.style.display = 'none'; } }
next_row = this.get_next_row();
prev_row = this.get_prev_row();
new_row = (next_row) ? next_row : prev_row;
this.select_row(new_row.uid,false,false);
// send request to server
this.http_request('delete', '_uid='+a_uids.join(',')+'&_mbox='+escape(this.env.mailbox)+'&_from='+(this.env.action ? this.env.action : ''));
}
// delete selected messages from the current mailbox
this.delete_messages = function()
{
// exit if no mailbox specified or if selection is empty
if (!(this.selection.length || this.env.uid))
return;
// if there is a trash mailbox defined and we're not currently in it:
if (this.env.trash_mailbox && String(this.env.mailbox).toLowerCase()!=String(this.env.trash_mailbox).toLowerCase())
this.move_messages(this.env.trash_mailbox);
// if there is a trash mailbox defined but we *are* in it:
else if (this.env.trash_mailbox && String(this.env.mailbox).toLowerCase() == String(this.env.trash_mailbox).toLowerCase())
this.permanently_remove_messages();
// if there isn't a defined trash mailbox and the config is set to flag for deletion
else if (!this.env.trash_mailbox && this.env.flag_for_deletion) {
this.mark_message('delete');
next_row = this.get_next_row();
prev_row = this.get_prev_row();
new_row = (next_row) ? next_row : prev_row;
this.select_row(new_row.uid,false,false);
// if there isn't a defined trash mailbox and the config is set NOT to flag for deletion
}else if (!this.env.trash_mailbox && !this.env.flag_for_deletion) {
this.permanently_remove_messages();
}
return;
};
*** 1588,1600 **** { id = this.selection[n]; a_uids[a_uids.length] = id;
// 'remove' message row from list (just hide it)
if (this.message_rows[id].obj)
this.message_rows[id].obj.style.display = 'none';
}
}
// mark all message rows as read/unread
var icn_src;
for (var i=0; i<a_uids.length; i++)
--- 1634,1657 ---- { id = this.selection[n]; a_uids[a_uids.length] = id; } }
switch (flag) {
case 'read':
case 'unread':
this.toggle_read_status(flag,a_uids);
break;
case 'delete':
case 'undelete':
this.toggle_delete_status(flag,a_uids);
break;
}
// send request to server
this.http_request('mark', '_uid='+a_uids.join(',')+'&_flag='+flag);
};
// set class to read/unread
this.toggle_read_status = function(flag, a_uids) { // mark all message rows as read/unread var icn_src; for (var i=0; i<a_uids.length; i++)
*** 1627,1637 **** this.message_rows[uid].icon.src = icn_src; } }
! // send request to server ! this.http_request('mark', '_uid='+a_uids.join(',')+'&_flag='+flag); ! };
/*********************************************************/
--- 1684,1731 ---- this.message_rows[uid].icon.src = icn_src; } }
! // mark all message rows as deleted/undeleted
! this.toggle_delete_status = function(flag, a_uids) {
! if (this.env.read_when_deleted) {
! this.toggle_read_status('read',a_uids);
! }
!
! var icn_src;
! for (var i=0; i<a_uids.length; i++)
! {
! uid = a_uids[i];
! if (this.message_rows[uid])
! {
! this.message_rows[uid].deleted = (flag=='undelete' ? false : true);
!
! if (this.message_rows[uid].classname.indexOf('deleted')<0 && this.message_rows[uid].deleted)
! {
! this.message_rows[uid].classname += ' deleted';
! this.set_classname(this.message_rows[uid].obj, 'deleted', true);
!
! if (this.env.deletedicon)
! icn_src = this.env.deletedicon;
! }
! else if (!this.message_rows[uid].deleted)
! {
! this.message_rows[uid].classname = this.message_rows[uid].classname.replace(/\s*deleted/, '');
! this.set_classname(this.message_rows[uid].obj, 'deleted', false);
!
! if (this.message_rows[uid].unread && this.env.unreadicon)
! icn_src = this.env.unreadicon;
! else if (this.message_rows[uid].replied && this.env.repliedicon)
! icn_src = this.env.repliedicon;
! else if (this.env.messageicon)
! icn_src = this.env.messageicon;
! }
if (this.message_rows[uid].icon && icn_src)
this.message_rows[uid].icon.src = icn_src;
}
}
}
/*********************************************************/
*** 2656,2662 **** var rowcount = tbody.rows.length; var even = rowcount%2;
! this.env.messages[uid] = {replied:flags.replied?1:0, unread:flags.unread?1:0};
var row = document.createElement('TR');
--- 2750,2757 ---- var rowcount = tbody.rows.length; var even = rowcount%2;
! this.env.messages[uid] = {deleted:flags.deleted?1:0, ! replied:flags.replied?1:0, unread:flags.unread?1:0};
var row = document.createElement('TR');
*** 2666,2673 **** if (this.in_selection(uid)) row.className += ' selected';
! var icon = flags.unread && this.env.unreadicon ? this.env.unreadicon : ! (flags.replied && this.env.repliedicon ? this.env.repliedicon : this.env.messageicon);
var col = document.createElement('TD');
col.className = 'icon';
--- 2761,2769 ---- if (this.in_selection(uid)) row.className += ' selected';
! var icon = flags.deleted && this.env.deletedicon ? this.env.deletedicon: ! (flags.unread && this.env.unreadicon ? this.env.unreadicon : ! (flags.replied && this.env.repliedicon ? this.env.repliedicon : this.env.messageicon));
var col = document.createElement('TD');
col.className = 'icon';
RCS file: /cvsroot/roundcubemail/roundcubemail/program/js/common.js,v retrieving revision 1.7 diff -b -B -c -r1.7 common.js Index: program/lib/imap.inc =================================================================== RCS file: /cvsroot/roundcubemail/roundcubemail/program/lib/imap.inc,v retrieving revision 1.18 diff -b -B -c -r1.18 imap.inc *** program/lib/imap.inc 27 Mar 2006 19:06:30 -0000 1.18 --- program/lib/imap.inc 1 May 2006 15:38:17 -0000
*** 1468,1474 ****
function iil_C_ModFlag(&$conn, $mailbox, $messages, $flag, $mod){ if ($mod!="+" && $mod!="-") return -1;
--- 1468,1473 ---- Index: program/steps/mail/func.inc =================================================================== RCS file: /cvsroot/roundcubemail/roundcubemail/program/steps/mail/func.inc,v retrieving revision 1.32 diff -b -B -c -r1.32 func.inc *** program/steps/mail/func.inc 6 Apr 2006 17:35:04 -0000 1.32 --- program/steps/mail/func.inc 1 May 2006 15:38:22 -0000
*** 390,395 **** --- 390,397 ---- $zebra_class = $i%2 ? 'even' : 'odd';
// set messag attributes to javascript array
if ($header->deleted)
$js_row_arr['deleted'] = true;
if (!$header->seen)
$js_row_arr['unread'] = true;
if ($header->answered)
*** 394,402 **** $js_row_arr['unread'] = true; if ($header->answered) $js_row_arr['replied'] = true;
! if ($attrib['unreadicon'] && !$header->seen)
$message_icon = $attrib['unreadicon'];
else if ($attrib['repliedicon'] && $header->answered)
$message_icon = $attrib['repliedicon'];
--- 396,405 ----
$js_row_arr['unread'] = true;
if ($header->answered)
$js_row_arr['replied'] = true;
// set message icon
! if ($attrib['deletedicon'] && $header->deleted)
! $message_icon = $attrib['deletedicon'];
! else if ($attrib['unreadicon'] && !$header->seen)
$message_icon = $attrib['unreadicon'];
else if ($attrib['repliedicon'] && $header->answered)
$message_icon = $attrib['repliedicon'];
*** 456,461 **** --- 459,466 ----
if ($attrib['messageicon'])
$javascript .= sprintf("%s.set_env('messageicon', '%s%s');\n", $JS_OBJECT_NAME, $skin_path, $attrib['messageicon']);
$javascript .= sprintf("%s.set_env('deletedicon', '%s%s');\n", $JS_OBJECT_NAME, $skin_path, $attrib['deletedicon']);
if ($attrib['unreadicon'])
$javascript .= sprintf("%s.set_env('unreadicon', '%s%s');\n", $JS_OBJECT_NAME, $skin_path, $attrib['unreadicon']);
if ($attrib['repliedicon'])*** 510,521 **** $a_msg_cols[$col] = $cont; }
$a_msg_flags['unread'] = $header->seen ? 0 : 1;
$a_msg_flags['replied'] = $header->answered ? 1 : 0;
if ($header->deleted)
$a_msg_flags['deleted'] = 1;
--- 515,523 ---- $a_msg_cols[$col] = $cont; }
$a_msg_flags['deleted'] = $header->deleted ? 1 : 0;
$a_msg_flags['unread'] = $header->seen ? 0 : 1;
$a_msg_flags['replied'] = $header->answered ? 1 : 0;
$commands .= sprintf("this.add_message_row(%s, %s, %s, %b, %b);\n",
$header->uid,
array2js($a_msg_cols),
RCS file: /cvsroot/roundcubemail/roundcubemail/program/steps/mail/mark.inc,v retrieving revision 1.2 diff -b -B -c -r1.2 mark.inc *** program/steps/mail/mark.inc 28 Sep 2005 22:28:04 -0000 1.2 --- program/steps/mail/mark.inc 1 May 2006 15:38:22 -0000
*** 21,35 ****
$REMOTE_REQUEST = TRUE;
! $a_flags_map = array('read' => 'SEEN', 'unread' => 'UNSEEN');
if ($_GET['_uid'] && $_GET['_flag'])
{
$flag = $a_flags_map[$_GET['_flag']] ? $a_flags_map[$_GET['_flag']] : strtoupper($_GET['_flag']);
$marked = $IMAP->set_flag($_GET['_uid'], $flag);
!
! if ($marked)
{
$mbox = $IMAP->get_mailbox_name();
$commands = sprintf("this.set_unread_count('%s', %d);\n", $mbox, $IMAP->messagecount($mbox, 'UNSEEN'));
--- 21,36 ----
$REMOTE_REQUEST = TRUE;
! $a_flags_map = array('undelete' => 'UNDELETED', ! 'delete' => 'DELETED', ! 'read' => 'SEEN', 'unread' => 'UNSEEN');
if ($_GET['_uid'] && $_GET['_flag']) { $flag = $a_flags_map[$_GET['_flag']] ? $a_flags_map[$_GET['_flag']] : strtoupper($_GET['_flag']); $marked = $IMAP->set_flag($_GET['_uid'], $flag); ! if ($marked != -1) { $mbox = $IMAP->get_mailbox_name(); $commands = sprintf("this.set_unread_count('%s', %d);\n", $mbox, $IMAP->messagecount($mbox, 'UNSEEN')); Index: skins/default/mail.css =================================================================== RCS file: /cvsroot/roundcubemail/roundcubemail/skins/default/mail.css,v retrieving revision 1.19 diff -b -B -c -r1.19 mail.css *** skins/default/mail.css 4 Apr 2006 21:41:22 -0000 1.19 --- skins/default/mail.css 1 May 2006 15:38:22 -0000
*** 446,451 **** --- 446,457 ---- background-color: #CC3333; }
RCS file: /cvsroot/roundcubemail/roundcubemail/skins/default/templates/mail.html,v retrieving revision 1.11 diff -b -B -c -r1.11 mail.html *** skins/default/templates/mail.html 23 Mar 2006 22:32:47 -0000 1.11 --- skins/default/templates/mail.html 1 May 2006 15:38:23 -0000
*** 46,51 **** --- 46,52 ---- summary="Message list" messageIcon="/images/icons/dot.png" unreadIcon="/images/icons/unread.png"
</div>