off-by-one: when strlen == trim_at, we also don't want to print ...
[squirrelmail.git] / functions / mailbox_display.php
index 379bea5f6f9a27ce0141a808c60478bf54ab87a3..ae678a786ed8912b45619f933019d1f4c3672e3c 100644 (file)
@@ -3,7 +3,7 @@
 /**
  * mailbox_display.php
  *
- * Copyright (c) 1999-2002 The SquirrelMail Project Team
+ * Copyright (c) 1999-2003 The SquirrelMail Project Team
  * Licensed under the GNU GPL. For full terms see the file COPYING.
  *
  * This contains functions that display mailbox information, such as the
@@ -17,13 +17,31 @@ require_once(SM_PATH . 'functions/html.php');
 require_once(SM_PATH . 'class/html.class.php');
 require_once(SM_PATH . 'functions/imap_mailbox.php');
 
-/* Default value for page_selector_max. */
+/* Constants:
+ *   PG_SEL_MAX:   default value for page_selector_max
+ *   SUBJ_TRIM_AT: the length at which we trim off subjects
+ */
 define('PG_SEL_MAX', 10);
+define('SUBJ_TRIM_AT', 55);
+
+function elapsed($start)
+{
+   $end = microtime();
+   list($start2, $start1) = explode(" ", $start);
+   list($end2, $end1) = explode(" ", $end);
+  $diff1 = $end1 - $start1;
+   $diff2 = $end2 - $start2;
+   if( $diff2 < 0 ){
+       $diff1 -= 1;
+       $diff2 += 1.0;
+  }
+   return $diff2 + $diff1;
+}
 
 function printMessageInfo($imapConnection, $t, $not_last=true, $key, $mailbox,
                           $start_msg, $where, $what) {
     global $checkall,
-           $color, $msgs, $msort,
+           $color, $msgs, $msort, $td_str, $msg, 
            $default_use_priority,
            $message_highlight_list,
            $index_order,
@@ -58,27 +76,30 @@ function printMessageInfo($imapConnection, $t, $not_last=true, $key, $mailbox,
 
     if (handleAsSent($mailbox)) {
        $msg['FROM'] = $msg['TO'];
+    }
+    $msg['FROM'] = parseAddress($msg['FROM'],1);
+
        /*
         * This is done in case you're looking into Sent folders,
         * because you can have multiple receivers.
         */
-       $senderNames = explode(',', $msg['FROM']);
-       $senderName  = '';
-       if (sizeof($senderNames)){
-          foreach ($senderNames as $senderNames_part) {
+
+    $senderNames = $msg['FROM'];
+    $senderName  = '';
+    if (sizeof($senderNames)){
+        foreach ($senderNames as $senderNames_part) {
             if ($senderName != '') {
                 $senderName .= ', ';
             }
-            $senderName .= sqimap_find_displayable_name($senderNames_part);
-          }
-       }
-    } else {
-       $senderName = sqimap_find_displayable_name($msg['FROM']);
+            if ($senderNames_part[1]) {
+                $senderName .= decodeHeader($senderNames_part[1]);
+            } else {
+                $senderName .= htmlspecialchars($senderNames_part[0]);
+            }
+        }
     }
-
-    $subject = processSubject($msg['SUBJECT']);
-
-    echo html_tag( 'tr' ) . "\n";
+    $senderName = str_replace('&nbsp;',' ',$senderName);
+    echo html_tag( 'tr','','','','VALIGN="top"') . "\n";
 
     if (isset($msg['FLAG_FLAGGED']) && ($msg['FLAG_FLAGGED'] == true)) {
         $flag = "<font color=\"$color[2]\">";
@@ -114,25 +135,41 @@ function printMessageInfo($imapConnection, $t, $not_last=true, $key, $mailbox,
     } else {
         $searchstr = '';
     }
-    /**
-    * AAAAH! Make my eyes stop bleeding!
-    * Who wrote this?!
-    */
-    if (sizeof($message_highlight_list)){
+
+    if (is_array($message_highlight_list) && count($message_highlight_list)) {
+        $msg['TO'] = parseAddress($msg['TO']);
+        $msg['CC'] = parseAddress($msg['CC']);
         foreach ($message_highlight_list as $message_highlight_list_part) {
             if (trim($message_highlight_list_part['value']) != '') {
                 $high_val   = strtolower($message_highlight_list_part['value']);
                 $match_type = strtoupper($message_highlight_list_part['match_type']);
-                if ($match_type == 'TO_CC') {
-                    if (strstr('^^' . strtolower($msg['TO']), $high_val) ||
-                        strstr('^^' . strtolower($msg['CC']), $high_val)) {
-                        $hlt_color = $message_highlight_list_part['color'];
-                        continue;
-                    }
+                if($match_type == 'TO_CC') {
+                    $match = array('TO', 'CC');
                 } else {
-                    if (strstr('^^' . strtolower($msg[$match_type]), $high_val)) {
-                        $hlt_color = $message_highlight_list_part['color'];
-                        continue;
+                    $match = array($match_type);
+                }
+                foreach($match as $match_type) {
+                    switch($match_type) {
+                        case('TO'):
+                        case('CC'):
+                        case('FROM'):
+                            foreach ($msg[$match_type] as $address) {
+                                $address[0] = decodeHeader($address[0], true, false);
+                                $address[1] = decodeHeader($address[1], true, false);
+                                if (strstr('^^' . strtolower($address[0]), $high_val) ||
+                                    strstr('^^' . strtolower($address[1]), $high_val)) {
+                                    $hlt_color = $message_highlight_list_part['color'];
+                                    break 4;
+                                }
+                            }
+                            break;
+                        default:
+                            $headertest = strtolower(decodeHeader($msg[$match_type], true, false));
+                            if (strstr('^^' . $headertest, $high_val)) {
+                                $hlt_color = $message_highlight_list_part['color'];
+                                break 3; 
+                            }
+                            break;
                     }
                 }
             }
@@ -142,8 +179,11 @@ function printMessageInfo($imapConnection, $t, $not_last=true, $key, $mailbox,
     if (!isset($hlt_color)) {
         $hlt_color = $color_string;
     }
-    $checked = ($checkall == 1) ? true : false;
+    $checked = ($checkall == 1) ? ' CHECKED' : '';
     $col = 0;
+    $msg['SUBJECT'] = decodeHeader($msg['SUBJECT']);
+    $subject = processSubject($msg['SUBJECT'], $indent_array[$msg['ID']]);
+    $subject = str_replace('&nbsp;',' ',$subject);    
     if (sizeof($index_order)) {
         foreach ($index_order as $index_order_part) {
             switch ($index_order_part) {
@@ -161,8 +201,12 @@ function printMessageInfo($imapConnection, $t, $not_last=true, $key, $mailbox,
                                $hlt_color );
                 break;
             case 3: /* date */
+                $date_string = $msg['DATE_STRING'] . '';
+                if ($date_string == '') {
+                    $date_string = _("Unknown date");
+                }
                 echo html_tag( 'td',
-                               $bold . $flag . $fontstr . $msg['DATE_STRING'] .
+                               $bold . $flag . $fontstr . $date_string .
                                $fontstr_end . $flag_end . $bold_end,
                                'center',
                                $hlt_color,
@@ -171,14 +215,14 @@ function printMessageInfo($imapConnection, $t, $not_last=true, $key, $mailbox,
             case 4: /* subject */
                 $td_str = $bold;
                 if ($thread_sort_messages == 1) {
-                    if (isset($indent_array[$msg["ID"]])) {
+                    if (isset($indent_array[$msg['ID']])) {
                         $td_str .= str_repeat("&nbsp;&nbsp;&nbsp;&nbsp;",$indent_array[$msg['ID']]);
                     }
                 }
                 $td_str .= '<a href="read_body.php?mailbox='.$urlMailbox
                         .  '&amp;passed_id='. $msg["ID"]
                         .  '&amp;startMessage='.$start_msg.$searchstr.'"';
-                do_hook("subject_link");
+                $td_str .= ' ' .concat_hook_function('subject_link', array($start_msg, $searchstr));
                 if ($subject != $msg['SUBJECT']) {
                     $title = get_html_translation_table(HTML_SPECIALCHARS);
                     $title = array_flip($title);
@@ -218,6 +262,7 @@ function printMessageInfo($imapConnection, $t, $not_last=true, $key, $mailbox,
                 if (!$stuff) {
                     $td_str .= '&nbsp;';
                 }
+                do_hook("msg_envelope");
                 $td_str .= '</small></b>';
                 echo html_tag( 'td',
                                $td_str,
@@ -246,13 +291,7 @@ function printMessageInfo($imapConnection, $t, $not_last=true, $key, $mailbox,
 
 function getServerMessages($imapConnection, $start_msg, $show_num, $num_msgs, $id) {
     if ($id != 'no') {
-        if ($start_msg + ($show_num - 1) < $num_msgs) {
-            $end_msg = $start_msg + ($show_num-1);
-        } else {
-            $end_msg = $num_msgs;
-        }
-        $id = array_slice($id, ($start_msg-1), ($end_msg));
-
+        $id = array_slice($id, ($start_msg-1), $show_num);
         $end = $start_msg + $show_num - 1;
         if ($num_msgs < $show_num) {
             $end_loop = $num_msgs;
@@ -261,7 +300,7 @@ function getServerMessages($imapConnection, $start_msg, $show_num, $num_msgs, $i
         } else {
             $end_loop = $show_num;
         }
-        return fillMessageArray($imapConnection,$id,$end_loop);
+        return fillMessageArray($imapConnection,$id,$end_loop,$show_num);
     } else {
         return false;
     }
@@ -286,6 +325,9 @@ function getSelfSortMessages($imapConnection, $start_msg, $show_num,
         if ($sort < 6 ) {
             $end = $num_msgs;
             $end_loop = $end;
+           /* set shownum to 999999 to fool sqimap_get_small_header_list
+              and rebuild the msgs_str to 1:* */
+           $show_num = 999999;
         } else {
             /* if it's not sorted */
             if ($start_msg + ($show_num - 1) < $num_msgs) {
@@ -299,7 +341,7 @@ function getSelfSortMessages($imapConnection, $start_msg, $show_num,
                     $start_msg = 1;
                 }
             }
-            $id = array_slice(array_reverse($id), ($start_msg-1), ($end_msg));
+            $id = array_slice(array_reverse($id), ($start_msg-1), $show_num);
             $end = $start_msg + $show_num - 1;
             if ($num_msgs < $show_num) {
                 $end_loop = $num_msgs;
@@ -309,7 +351,7 @@ function getSelfSortMessages($imapConnection, $start_msg, $show_num,
                 $end_loop = $show_num;
             }
         }
-        $msgs = fillMessageArray($imapConnection,$id,$end_loop);
+        $msgs = fillMessageArray($imapConnection,$id,$end_loop, $show_num);
     }
     return $msgs;
 }
@@ -326,6 +368,21 @@ function showMessagesForMailbox($imapConnection, $mailbox, $num_msgs,
     global $msgs, $msort, $auto_expunge, $thread_sort_messages,
            $allow_server_sort, $server_sort_order;
 
+    /*
+     * For some reason, on PHP 4.3+, this being unset, and set in the session causes havoc
+     * so setting it to an empty array beforehand seems to clean up the issue, and stopping the
+     * "Your script possibly relies on a session side-effect which existed until PHP 4.2.3" error
+     */
+
+    if (!isset($msort)) {
+        $msort = array();
+    }
+
+    if (!isset($msgs)) {
+        $msgs = array();
+    }
+
+    //$start = microtime();
     /* If autoexpunge is turned on, then do it now. */
     $mbxresponse = sqimap_mailbox_select($imapConnection, $mailbox);
     $srt = $sort;
@@ -362,8 +419,12 @@ function showMessagesForMailbox($imapConnection, $mailbox, $num_msgs,
             $mode = '';
         }
 
-        sqsession_unregister('msort');
-        sqsession_unregister('msgs');
+       if ($use_cache) {
+           sqgetGlobalVar('msgs', $msgs, SQ_SESSION);
+           sqgetGlobalVar('msort', $msort, SQ_SESSION);
+       } else {
+           sqsession_unregister('msort');
+           sqsession_unregister('msgs');       }
         switch ($mode) {
             case 'thread':
                 $id   = get_thread_sort($imapConnection);
@@ -405,6 +466,7 @@ function showMessagesForMailbox($imapConnection, $mailbox, $num_msgs,
         } // switch
         sqsession_register($msort, 'msort');
         sqsession_register($msgs,  'msgs');
+
     } /* if exists > 0 */
 
     $res = getEndMessage($start_msg, $show_num, $num_msgs);
@@ -417,23 +479,30 @@ function showMessagesForMailbox($imapConnection, $mailbox, $num_msgs,
     $msg_cnt_str = get_msgcnt_str($start_msg, $end_msg, $num_msgs);
 
     do_hook('mailbox_index_before');
-
-    mail_message_listing_beginning($imapConnection, $mailbox, $sort,
-                                   $msg_cnt_str, $paginator_str, $start_msg);
-
-
-    echo '<table bgcolor="' . $color[0] . '" border="0" width="100%" cellpadding="1" cellspacing="0"><tr><td>';
+    echo '<table border="0" width="100%" cellpadding="0" cellspacing="0">';
+    echo '<tr><td>';
+
+    mail_message_listing_beginning($imapConnection, $mailbox, $sort, 
+                                  $msg_cnt_str, $paginator_str, $start_msg);
+    echo '</td></tr>';
+    /* line between the button area and the list */
+    echo '<tr><td HEIGHT="5" BGCOLOR="'.$color[4].'"></td></tr>';  
+
+    echo '<tr><td>';
+    echo '    <table width="100%" cellpadding="1" cellspacing="0" align="center"'.' border="0" bgcolor="'.$color[9].'">';
+    echo '     <tr><td>';
+    echo '       <table width="100%" cellpadding="1" cellspacing="0" align="center" border="0" bgcolor="'.$color[5].'">';
+    echo '<tr><td>';
     printHeader($mailbox, $srt, $color, !$thread_sort_messages);
 
-    displayMessageArray($imapConnection, $num_msgs, $start_msg,
-                        $msort, $mailbox, $sort, $color, $show_num, 0, 0);
+    displayMessageArray($imapConnection, $num_msgs, $start_msg, 
+                     $msort, $mailbox, $sort, $color, $show_num,0,0);
+    echo '</td></tr></table></td></tr></table>';
 
-    mail_message_listing_end($num_msgs, $paginator_str, $msg_cnt_str, $color);
+    mail_message_listing_end($num_msgs, $paginator_str, $msg_cnt_str, $color); 
     echo '</td></tr></table>';
-
-  /**
-   * TODO: Switch to using $_SESSION[] whenever we ditch the 4.0.x series.
-   */
+    //$t = elapsed($start);
+    //echo("elapsed time = $t seconds\n");
 }
 
 function calc_msort($msgs, $sort) {
@@ -446,12 +515,19 @@ function calc_msort($msgs, $sort) {
      * 4 = Subject (up)
      * 5 = Subject (dn)
      */
+
     if (($sort == 0) || ($sort == 1)) {
-        $msort = array_cleave ($msgs, 'TIME_STAMP');
+        foreach ($msgs as $item) {
+            $msort[] = $item['TIME_STAMP'];
+        }
     } elseif (($sort == 2) || ($sort == 3)) {
-        $msort = array_cleave ($msgs, 'FROM-SORT');
+        foreach ($msgs as $item) {
+            $msort[] = $item['FROM-SORT'];
+        }
     } elseif (($sort == 4) || ($sort == 5)) {
-        $msort = array_cleave ($msgs, 'SUBJECT-SORT');
+        foreach ($msgs as $item) {
+            $msort[] = $item['SUBJECT-SORT'];
+        }
     } else {
         $msort = $msgs;
     }
@@ -465,68 +541,8 @@ function calc_msort($msgs, $sort) {
     return $msort;
 }
 
-function fillMessageArray($imapConnection, $id, $count) {
-    $msgs_list = sqimap_get_small_header_list($imapConnection, $id);
-    $messages = array();
-    if (sizeof($msgs_list)) {
-        foreach ($msgs_list as $hdr) {
-            $unique_id[] = $hdr->uid;
-            $from[] = $hdr->from;
-            $date[] = $hdr->date;
-            $subject[] = $hdr->subject;
-            $to[] = $hdr->to;
-            $priority[] = $hdr->priority;
-            $cc[] = $hdr->cc;
-            $size[] = $hdr->size;
-            $type[] = $hdr->type0;
-            $flag_deleted[] = $hdr->flag_deleted;
-            $flag_answered[] = $hdr->flag_answered;
-            $flag_seen[] = $hdr->flag_seen;
-            $flag_flagged[] = $hdr->flag_flagged;
-        }
-    }
-
-    for($j = 0; $j < $count; ++$j) {
-        if (isset($date[$j])) {
-            $date[$j] = str_replace('  ', ' ', $date[$j]);
-            $tmpdate  = explode(' ', trim($date[$j]));
-        } else {
-            $tmpdate = $date = array('', '', '', '', '', '');
-        }
-        $messages[$j]['TIME_STAMP'] = getTimeStamp($tmpdate);
-        $messages[$j]['DATE_STRING'] =
-        getDateString($messages[$j]['TIME_STAMP']);
-        $messages[$j]['ID'] = $unique_id[$j];
-        $messages[$j]['FROM'] = decodeHeader($from[$j]);
-        $messages[$j]['FROM-SORT'] =
-        strtolower(sqimap_find_displayable_name(decodeHeader($from[$j])));
-        $messages[$j]['SUBJECT'] = decodeHeader($subject[$j]);
-        $messages[$j]['SUBJECT-SORT'] = strtolower(decodeHeader($subject[$j]));
-        $messages[$j]['TO'] = decodeHeader($to[$j]);
-        $messages[$j]['PRIORITY'] = $priority[$j];
-        $messages[$j]['CC'] = $cc[$j];
-        $messages[$j]['SIZE'] = $size[$j];
-        $messages[$j]['TYPE0'] = $type[$j];
-        $messages[$j]['FLAG_DELETED'] = $flag_deleted[$j];
-        $messages[$j]['FLAG_ANSWERED'] = $flag_answered[$j];
-        $messages[$j]['FLAG_SEEN'] = $flag_seen[$j];
-        $messages[$j]['FLAG_FLAGGED'] = $flag_flagged[$j];
-
-        /*
-         * fix SUBJECT-SORT to remove Re:
-         *     vedr|sv  (Danish)
-         *     re|aw (English)
-         *
-         * TODO: i18n should be incorporated here. E.g. we catch the ones
-         * we know about, but also define in i18n what the localized
-         * "Re: " is for this or that locale.
-         */
-        if (preg_match("/^(vedr|sv|re|aw):\s*(.*)$/si",
-            $messages[$j]['SUBJECT-SORT'], $matches)){
-            $messages[$j]['SUBJECT-SORT'] = $matches[2];
-        }
-    }
-    return $messages;
+function fillMessageArray($imapConnection, $id, $count, $show_num=false) {
+    return sqimap_get_small_header_list($imapConnection, $id, $show_num);
 }
 
 
@@ -534,8 +550,7 @@ function fillMessageArray($imapConnection, $id, $count) {
 function displayMessageArray($imapConnection, $num_msgs, $start_msg,
                              $msort, $mailbox, $sort, $color,
                              $show_num, $where=0, $what=0) {
-    global $imapServerAddress, $use_mailbox_cache,
-           $index_order, $checkall,
+    global $imapServerAddress, $use_mailbox_cache, $index_order,
            $indent_array, $thread_sort_messages, $allow_server_sort,
            $server_sort_order, $PHP_SELF;
 
@@ -546,7 +561,7 @@ function displayMessageArray($imapConnection, $num_msgs, $start_msg,
     $urlMailbox = urlencode($mailbox);
 
     /* get indent level for subject display */
-    if ($thread_sort_messages == 1 ) {
+    if ($thread_sort_messages == 1 && $num_msgs) {
         $indent_array = get_parent_level($imapConnection);
     }
 
@@ -570,7 +585,7 @@ function displayMessageArray($imapConnection, $num_msgs, $start_msg,
 
     /* messages display */
 
-    if ($num_msgs == 0) {
+    if (!$num_msgs) {
     /* if there's no messages in this folder */
         echo html_tag( 'tr',
                 html_tag( 'td',
@@ -616,7 +631,6 @@ function displayMessageArray($imapConnection, $num_msgs, $start_msg,
             next($msort);
         } while ($i && $i < $endVar);
     }
-    echo '</table>';
 }
 
 /*
@@ -655,49 +669,64 @@ function mail_message_listing_beginning ($imapConnection,
     if (!isset($msg)) {
         $msg = '';
     }
-    $moveURL = "move_messages.php?msg=$msg&amp;mailbox=$urlMailbox"
-             . "&amp;startMessage=$start_msg";
+    $moveFields = '<input type="hidden" name="msg" value="'.htmlspecialchars($msg).'">' .
+                 '<input type="hidden" name="mailbox" value="'.htmlspecialchars($mailbox).'">' .
+                 '<input type="hidden" name="startMessage" value="'.htmlspecialchars($start_msg).'">';
+
+//    $moveURL = "move_messages.php?msg=$msg&amp;mailbox=$urlMailbox"
+//             . "&amp;startMessage=$start_msg";
     /*
      * This is the beginning of the message list table.
      * It wraps around all messages
      */
-
-    echo "<FORM name=\"messageList\" method=post action=\"$moveURL\">\n"
-        . html_tag( 'table' ,'' , '', '', 'border="0" width="100%" cellpadding="1"  cellspacing="0"' ) .
+    $safe_name = preg_replace("/[^0-9A-Za-z_]/", '_', $mailbox);
+    $form_name = "FormMsgs" . $safe_name;
+    echo '<form name="' . $form_name . '" method="post" action="move_messages.php">' ."\n"
+       . $moveFields
+        . html_tag( 'table' ,
             html_tag( 'tr',
                 html_tag( 'td' ,
                     html_tag( 'table' ,
                         html_tag( 'tr',
                             html_tag( 'td', $paginator, 'left' ) .
-                            html_tag( 'td', $msg_cnt_str, 'right' )
+                            html_tag( 'td', $msg_cnt_str, 'right' ) 
                         )
-                    , '', $color[4], 'border="0" width="100%" cellpadding="2"  cellspacing="0"' )
+                    , '', $color[4], 'border="0" width="100%" cellpadding="1"  cellspacing="0"' ) 
                 , 'left', '', '' )
             , '', $color[0] )
-        . html_tag( 'tr' ) . "\n"
-        . html_tag( 'td' ,'' , 'left', $color[0], '' )
-        . html_tag( 'table' ,'' , '', $color[0], 'border="0" width="100%" cellpadding="0"  cellspacing="0"' )
+           , '', '', 'border="0" width="100%" cellpadding="1"  cellspacing="0"' );
+       /* line between header and button area */
+        echo '<tr><td HEIGHT="5" BGCOLOR="'.$color[4].'"></td></tr>';
+
+        echo '<tr><td>';
+        echo html_tag( 'tr' ) . "\n"
+        . html_tag( 'td' ,'' , 'left', '', '' )
+         . html_tag( 'table' ,'' , '', $color[9], 'border="0" width="100%" cellpadding="1"  cellspacing="0"' )
+         . '<tr><td>'
+           . html_tag( 'table' ,'' , '', $color[0], 'border="0" width="100%" cellpadding="1"  cellspacing="0"' )
             . html_tag( 'tr',
-                getSmallStringCell('&nbsp;' . _("Move Selected To"), 'left') .
-                getSmallStringCell(_("Transform Selected Messages"), 'right')
+               getSmallStringCell(_("Move Selected To"), 'left', 'nowrap') .
+               getSmallStringCell(_("Transform Selected Messages"), 'right')
             )
             . html_tag( 'tr' ) ."\n"
             . html_tag( 'td', '', 'left', '', 'valign="middle" nowrap' );
-            getMbxList($imapConnection);
-            echo getButton('SUBMIT', 'moveButton',_("Move")) . "\n";
-            echo getButton('SUBMIT', 'attache',_("Forward")) . "\n";
+            getMbxList($imapConnection);  
+            echo getButton('SUBMIT', 'moveButton',_("Move")) . "\n";   
+            echo getButton('SUBMIT', 'attache',_("Forward")) . "\n";   
 
-    echo "      </TD>\n"
+  echo "      </TD>\n"
          . html_tag( 'td', '', 'right', '', 'nowrap' );
 
+
+
     if (!$auto_expunge) {
         echo getButton('SUBMIT', 'expungeButton',_("Expunge"))
              .'&nbsp;' . _("mailbox") . "\n";
     }
-
+    do_hook('mailbox_display_buttons');
     echo getButton('SUBMIT', 'markRead',_("Read"));
     echo getButton('SUBMIT', 'markUnread',_("Unread"));
-    echo getButton('SUBMIT', 'delete',_("Delete")) ."&nbsp\n";
+    echo getButton('SUBMIT', 'delete',_("Delete")) ."&nbsp;\n";
     if (!strpos($php_self,'mailbox')) {
         $location = $php_self.'?mailbox=INBOX&amp;startMessage=1';
     } else {
@@ -726,15 +755,10 @@ function mail_message_listing_beginning ($imapConnection,
                  , '', '', '' );
     }
 
-    echo "</TABLE>\n";
-    echo "</table>\n";
+    echo "</TABLE></td></tr></table></td></tr>\n";
 
     do_hook('mailbox_form_before');
 
-    echo '</td></tr>'
-         . html_tag( 'tr' )
-         . html_tag( 'td' ,'' , '', $color[0], '' );
-
     /* if using server sort we highjack the
      * the $sort var and use $server_sort_order
      * instead. but here we reset sort for a bit
@@ -746,8 +770,12 @@ function mail_message_listing_beginning ($imapConnection,
 }
 
 function mail_message_listing_end($num_msgs, $paginator_str, $msg_cnt_str, $color) {
-    if ($num_msgs) {
-        echo html_tag( 'table',
+  if ($num_msgs) {
+    /* space between list and footer */
+    echo '<tr><td HEIGHT="5" BGCOLOR="'.$color[4].'" COLSPAN="1">';  
+
+    echo '</td></tr><tr><td>';
+    echo html_tag( 'table',
             html_tag( 'tr',
                 html_tag( 'td',
                     html_tag( 'table',
@@ -755,12 +783,12 @@ function mail_message_listing_end($num_msgs, $paginator_str, $msg_cnt_str, $colo
                             html_tag( 'td', $paginator_str ) .
                             html_tag( 'td', $msg_cnt_str, 'right' )
                         )
-                    , '', $color[4], 'width="100%" cellpadding="1" cellspacing="1"' )
+                    , '', $color[4], 'width="100%" border="0" cellpadding="1" cellspacing="0"' )
                 )
-            , '', $color[4] )
-        , '', $color[9], 'width="100%" cellpadding="1"  cellspacing="1"' );
-
-    }
+            )
+        , '', $color[9], 'width="100%" border="0" cellpadding="1"  cellspacing="0"' );
+    echo '</td></tr>';
+  }
     /* End of message-list table */
 
     do_hook('mailbox_index_after');
@@ -769,10 +797,18 @@ function mail_message_listing_end($num_msgs, $paginator_str, $msg_cnt_str, $colo
 
 function printHeader($mailbox, $sort, $color, $showsort=true) {
     global $index_order;
-    echo html_tag( 'table' ,'' , '', $color[4], 'border="0" width="100%" cellpadding="1" cellspacing="0"' );
     echo html_tag( 'tr' ,'' , 'center', $color[5] );
-    for ($i = 1; $i <= count($index_order); $i++) {
-        switch ($index_order[$i]) {
+
+    /* calculate the width of the subject column based on the
+     * widths of the other columns */
+    $widths = array(1=>1,2=>25,3=>5,4=>0,5=>1,6=>5);
+    $subjectwidth = 100;
+    foreach($index_order as $item) {
+        $subjectwidth -= $widths[$item]; 
+    }
+
+    foreach ($index_order as $item) {
+        switch ($item) {
         case 1: /* checkbox */
         case 5: /* flags */
             echo html_tag( 'td' ,'&nbsp;' , '', '', 'width="1%"' );
@@ -799,7 +835,7 @@ function printHeader($mailbox, $sort, $color, $showsort=true) {
             echo "</td>\n";
             break;
         case 4: /* subject */
-            echo html_tag( 'td' ,'' , 'left', '', '' )
+            echo html_tag( 'td' ,'' , 'left', '', 'width="'.$subjectwidth.'%"' )
                  . '<b>' . _("Subject") . '</b>';
             if ($showsort) {
                 ShowSortButton($sort, $mailbox, 4, 5);
@@ -807,7 +843,7 @@ function printHeader($mailbox, $sort, $color, $showsort=true) {
             echo "</td>\n";
             break;
         case 6: /* size */
-            echo html_tag( 'td', '<b>' . _("Size") . '</b>', 'center', '', 'width="5%"' );
+            echo html_tag( 'td', '<b>' . _("Size") . '</b>', 'center', '', 'width="5%" nowrap' );
             break;
         }
     }
@@ -851,18 +887,22 @@ function get_selectall_link($start_msg, $sort) {
 
     $result = '';
     if ($javascript_on) {
+        $safe_name = preg_replace("/[^0-9A-Za-z_]/", '_', $mailbox);
+        $func_name = "CheckAll" . $safe_name;
+        $form_name = "FormMsgs" . $safe_name;
         $result = '<script language="JavaScript" type="text/javascript">'
                 . "\n<!-- \n"
-                . "function CheckAll() {\n"
-                . "  for (var i = 0; i < document.messageList.elements.length; i++) {\n"
-                . "    if(document.messageList.elements[i].type == 'checkbox'){\n"
-                . "      document.messageList.elements[i].checked = "
-                . "        !(document.messageList.elements[i].checked);\n"
+                . "function " . $func_name . "() {\n"
+                . "  for (var i = 0; i < document." . $form_name . ".elements.length; i++) {\n"
+                . "    if(document." . $form_name . ".elements[i].type == 'checkbox'){\n"
+                . "      document." . $form_name . ".elements[i].checked = "
+                . "        !(document." . $form_name . ".elements[i].checked);\n"
                 . "    }\n"
                 . "  }\n"
                 . "}\n"
                 . "//-->\n"
-                . '</script><a href="#" onClick="CheckAll();">' . _("Toggle All")
+                . '</script><a href="javascript:void(0)" onClick="' . $func_name . '();">' . _("Toggle All")
+/*                . '</script><a href="javascript:' . $func_name . '()">' . _("Toggle All")*/
                 . "</a>\n";
     } else {
         if (strpos($PHP_SELF, "?")) {
@@ -1139,32 +1179,48 @@ function get_paginator_str($box, $start_msg, $end_msg, $num_msgs,
     return ($result);
 }
 
-function processSubject($subject) {
+function processSubject($subject, $threadlevel = 0) {
     global $languages, $squirrelmail_language;
     /* Shouldn't ever happen -- caught too many times in the IMAP functions */
-    if ($subject == '')
+    if ($subject == '') {
         return _("(no subject)");
+    }
+
+    $trim_at = SUBJ_TRIM_AT;
+
+    /* if this is threaded, subtract two chars per indentlevel */
+    if($threadlevel > 0 && $threadlevel <= 10) {
+        $trim_at -= (2*$threadlevel);
+    }
 
-    if (strlen($subject) <= 55)
+    if (strlen($subject) <= $trim_at) {
         return $subject;
+    }
 
-    $ent_strlen = strlen($subject);
-    $trim_val=50;
-    $ent_offset=0;
+    $ent_strlen = $orig_len = strlen($subject);
+    $trim_val = $trim_at - 5;
+    $ent_offset = 0;
     /*
      * see if this is entities-encoded string
      * If so, Iterate through the whole string, find out
      * the real number of characters, and if more
-     * than 55, substr with an updated trim value.
+     * than 55, substr with an updated trim value. 
      */
-    while ( (($ent_loc = strpos($subject, '&', $ent_offset)) !== false) &&
-            (($ent_loc_end = strpos($subject, ';', $ent_loc)) !== false) ) {
-        $trim_val   += ($ent_loc_end-$ent_loc)+1;
-        $ent_strlen -= $ent_loc_end-$ent_loc;
+    $step = $ent_loc = 0;
+    while ( $ent_loc < $trim_val && (($ent_loc = strpos($subject, '&', $ent_offset)) !== false) &&
+            (($ent_loc_end = strpos($subject, ';', $ent_loc+3)) !== false) ) {
+        $trim_val += ($ent_loc_end-$ent_loc);
         $ent_offset  = $ent_loc_end+1;
+        ++$step;
     }
-
-    if ($ent_strlen <= 55){
+    
+    if (($trim_val > 50) && (strlen($subject) > ($trim_val))&& (strpos($subject,';',$trim_val) < ($trim_val +6))) {
+        $i = strpos($subject,';',$trim_val);
+        if ($i) {
+            $trim_val = strpos($subject,';',$trim_val);
+        }
+    }
+    if ($ent_strlen <= $trim_at){
         return $subject;
     }
 
@@ -1173,27 +1229,18 @@ function processSubject($subject) {
         return $languages[$squirrelmail_language]['XTRA_CODE']('strimwidth', $subject, $trim_val);
     }
 
-    return substr($subject, 0, $trim_val) . '...';
+    // only print '...' when we're actually dropping part of the subject
+    if(strlen($subject) <= $trim_val) {
+        return $subject;
+    } else {
+        return substr($subject, 0, $trim_val) . '...';
+    }
 }
 
 function getMbxList($imapConnection) {
     global $lastTargetMailbox;
     echo  '         <small>&nbsp;<tt><select name="targetMailbox">';
-    $boxes = sqimap_mailbox_list($imapConnection);
-    foreach ($boxes as $boxes_part) {
-        if (!in_array('noselect', $boxes_part['flags'])) {
-            $box = $boxes_part['unformatted'];
-            $box2 = str_replace(' ', '&nbsp;', imap_utf7_decode_local($boxes_part['unformatted-disp']));
-            if($box2 == 'INBOX') {
-                $box2 = _("INBOX");
-            }
-            if ($lastTargetMailbox == $box) {
-                echo "       <OPTION VALUE=\"$box\" SELECTED>$box2</OPTION>\n";
-            } else {
-                echo "         <OPTION VALUE=\"$box\">$box2</OPTION>\n";
-            }
-        }
-    }
+    echo sqimap_mailbox_option_list($imapConnection, array(strtolower($lastTargetMailbox)) ); 
     echo '         </SELECT></TT>&nbsp;';
 }
 
@@ -1226,16 +1273,16 @@ function getEndMessage($start_msg, $show_num, $num_msgs) {
 }
 
 function handleAsSent($mailbox) {
-    global $sent_folder, $draft_folder, $handleAsSent_result;
-
+    global $handleAsSent_result;
     /* First check if this is the sent or draft folder. */
-    $handleAsSent_result = (($mailbox == $sent_folder)
-                             || ($mailbox == $draft_folder));
+    $handleAsSent_result = isSentMailbox($mailbox) || isDraftMailbox($mailbox);
 
     /* Then check the result of the handleAsSent hook. */
     do_hook('check_handleAsSent_result', $mailbox);
 
     /* And return the result. */
-    return ($handleAsSent_result);
+    return $handleAsSent_result;
 }
+
 ?>