kmail

headeritem.cpp

00001 /*******************************************************************************
00002 **
00003 ** Filename   : headeritem.cpp
00004 ** Created on : 28 November, 2004
00005 ** Copyright  : (c) 2004 Till Adam
00006 ** Email      : adam@kde.org
00007 **
00008 *******************************************************************************/
00009 
00010 /*******************************************************************************
00011 **
00012 **   This program is free software; you can redistribute it and/or modify
00013 **   it under the terms of the GNU General Public License as published by
00014 **   the Free Software Foundation; either version 2 of the License, or
00015 **   (at your option) any later version.
00016 **
00017 **   In addition, as a special exception, the copyright holders give
00018 **   permission to link the code of this program with any edition of
00019 **   the TQt library by Trolltech AS, Norway (or with modified versions
00020 **   of TQt that use the same license as TQt), and distribute linked
00021 **   combinations including the two.  You must obey the GNU General
00022 **   Public License in all respects for all of the code used other than
00023 **   TQt.  If you modify this file, you may extend this exception to
00024 **   your version of the file, but you are not obligated to do so.  If
00025 **   you do not wish to do so, delete this exception statement from
00026 **   your version.
00027 **
00028 *******************************************************************************/
00029 #include <klocale.h>
00030 #include <tqapplication.h>
00031 #include <tqregexp.h>
00032 #include <tqbitmap.h>
00033 #include <tqpainter.h>
00034 
00035 #include <kio/netaccess.h>
00036 
00037 #include "headeritem.h"
00038 #include "kmheaders.h"
00039 
00040 #include "kmfolder.h"
00041 
00042 using namespace KMail;
00043 
00044 // Constuction a new list view item with the given colors and pixmap
00045 HeaderItem::HeaderItem( TQListView* parent, int msgId, const TQString& key )
00046   : KListViewItem( parent ),
00047   mMsgId( msgId ),
00048   mKey( key ),
00049   mAboutToBeDeleted( false ),
00050   mSortCacheItem( 0 )
00051 {
00052   irefresh();
00053 }
00054 
00055 // Constuction a new list view item with the given parent, colors, & pixmap
00056 HeaderItem::HeaderItem( TQListViewItem* parent, int msgId, const TQString& key )
00057   : KListViewItem( parent ),
00058   mMsgId( msgId ),
00059   mKey( key ),
00060   mAboutToBeDeleted( false ),
00061   mSortCacheItem( 0 )
00062 {
00063   irefresh();
00064 }
00065 
00066 HeaderItem::~HeaderItem ()
00067 {
00068   delete mSortCacheItem;
00069 }
00070 
00071 // Update the msgId this item corresponds to.
00072 void HeaderItem::setMsgId( int aMsgId )
00073 {
00074   mMsgId = aMsgId;
00075 }
00076 
00077 // Profiling note: About 30% of the time taken to initialize the
00078 // listview is spent in this function. About 60% is spent in operator
00079 // new and TQListViewItem::TQListViewItem.
00080 void HeaderItem::irefresh()
00081 {
00082   KMHeaders *headers = static_cast<KMHeaders*>(listView());
00083   NestingPolicy threadingPolicy = headers->getNestingPolicy();
00084   if ((threadingPolicy == AlwaysOpen) ||
00085       (threadingPolicy == DefaultOpen)) {
00086     //Avoid opening items as TQListView is currently slow to do so.
00087     setOpen(true);
00088     return;
00089 
00090   }
00091   if (threadingPolicy == DefaultClosed)
00092     return; //default to closed
00093 
00094   // otherwise threadingPolicy == OpenUnread
00095   if (parent() && parent()->isOpen()) {
00096     setOpen(true);
00097     return;
00098   }
00099 
00100   KMMsgBase *mMsgBase = headers->folder()->getMsgBase( mMsgId );
00101   mSerNum = mMsgBase->getMsgSerNum();
00102   if (mMsgBase->isNew() || mMsgBase->isUnread()
00103       || mMsgBase->isImportant() || mMsgBase->isTodo() || mMsgBase->isWatched() ) {
00104     setOpen(true);
00105     HeaderItem * topOfThread = this;
00106     while(topOfThread->parent())
00107       topOfThread = (HeaderItem*)topOfThread->parent();
00108     topOfThread->setOpenRecursive(true);
00109   }
00110 }
00111 
00112 // Return the msgId of the message associated with this item
00113 int HeaderItem::msgId() const
00114 {
00115   return mMsgId;
00116 }
00117 
00118 TQString HeaderItem::to() const
00119 {
00120   KMHeaders * const headers = static_cast<KMHeaders*>( listView() );
00121   KMMsgBase * const msgBase = headers->folder()->getMsgBase( mMsgId );
00122   if ( msgBase ) {
00123     return msgBase->to();
00124   } else {
00125     return TQString();
00126   }
00127 }
00128 
00129 TQString HeaderItem::from() const
00130 {
00131   KMHeaders * const headers = static_cast<KMHeaders*>( listView() );
00132   KMMsgBase * const msgBase = headers->folder()->getMsgBase( mMsgId );
00133   if ( msgBase ) {
00134     return msgBase->from();
00135   } else {
00136     return TQString();
00137   }
00138 }
00139 
00140 // Return the serial number
00141 TQ_UINT32 HeaderItem::msgSerNum() const
00142 {
00143   return mSerNum;
00144 }
00145 
00146 // Update this item to summarise a new folder and message
00147 
00148 //Opens all children in the thread
00149 void HeaderItem::setOpenRecursive( bool open )
00150 {
00151   if (open){
00152     TQListViewItem * lvchild;
00153     lvchild = firstChild();
00154     while (lvchild){
00155       ((HeaderItem*)lvchild)->setOpenRecursive( true );
00156       lvchild = lvchild->nextSibling();
00157     }
00158     setOpen( true );
00159   } else {
00160     setOpen( false );
00161   }
00162 }
00163 
00164 TQString HeaderItem::text( int col) const
00165 {
00166   KMHeaders *headers = static_cast<KMHeaders*>(listView());
00167   KMMsgBase *mMsgBase = headers->folder()->getMsgBase( mMsgId );
00168   TQString tmp;
00169 
00170   if ( !mMsgBase )
00171     return TQString();
00172 
00173   if ( col == headers->paintInfo()->senderCol ) {
00174     if ( (headers->folder()->whoField().lower() == "to") && !headers->paintInfo()->showReceiver )
00175       tmp = mMsgBase->toStrip();
00176     else
00177       tmp = mMsgBase->fromStrip();
00178     if (tmp.isEmpty())
00179       tmp = i18n("Unknown");
00180     else
00181       tmp = tmp.simplifyWhiteSpace();
00182 
00183   } else if ( col == headers->paintInfo()->receiverCol ) {
00184     tmp = mMsgBase->toStrip();
00185     if (tmp.isEmpty())
00186       tmp = i18n("Unknown");
00187     else
00188       tmp = tmp.simplifyWhiteSpace();
00189 
00190   } else if(col == headers->paintInfo()->subCol) {
00191     tmp = mMsgBase->subject();
00192     if (tmp.isEmpty())
00193       tmp = i18n("No Subject");
00194     else
00195       tmp.remove(TQRegExp("[\r\n]"));
00196 
00197   } else if(col == headers->paintInfo()->dateCol) {
00198     tmp = headers->mDate.dateString( mMsgBase->date() );
00199   } else if(col == headers->paintInfo()->sizeCol
00200       && headers->paintInfo()->showSize) {
00201     if ( mMsgBase->parent()->folderType() == KMFolderTypeImap ) {
00202       tmp = KIO::convertSize( mMsgBase->msgSizeServer() );
00203     } else {
00204       tmp = KIO::convertSize( mMsgBase->msgSize() );
00205     }
00206   }
00207   return tmp;
00208 }
00209 
00210 void HeaderItem::setup()
00211 {
00212   widthChanged();
00213   const int ph = KMHeaders::pixNew->height();
00214   TQListView *v = listView();
00215   int h = TQMAX( v->fontMetrics().height(), ph ) + 2*v->itemMargin();
00216   h = TQMAX( h, TQApplication::globalStrut().height());
00217   if ( h % 2 > 0 )
00218     h++;
00219   setHeight( h );
00220 }
00221 
00222 typedef TQValueList<TQPixmap> PixmapList;
00223 
00224 TQPixmap HeaderItem::pixmapMerge( PixmapList pixmaps ) const
00225 {
00226   int width = 0;
00227   int height = 0;
00228   for ( PixmapList::ConstIterator it = pixmaps.begin();
00229       it != pixmaps.end(); ++it ) {
00230     width += (*it).width();
00231     height = TQMAX( height, (*it).height() );
00232   }
00233 
00234   TQPixmap res( width, height );
00235   TQBitmap mask( width, height, true );
00236 
00237   int x = 0;
00238   for ( PixmapList::ConstIterator it = pixmaps.begin();
00239       it != pixmaps.end(); ++it ) {
00240     bitBlt( &res, x, (height - (*it).height()) / 2, &(*it) );
00241     bitBlt( &mask, x, (height - (*it).height()) / 2, (*it).mask() );
00242     x += (*it).width();
00243   }
00244 
00245   res.setMask( mask );
00246   return res;
00247 }
00248 
00249 const TQPixmap *HeaderItem::cryptoIcon(KMMsgBase *msgBase) const
00250 {
00251   switch ( msgBase->encryptionState() )
00252   {
00253     case KMMsgFullyEncrypted        : return KMHeaders::pixFullyEncrypted;
00254     case KMMsgPartiallyEncrypted    : return KMHeaders::pixPartiallyEncrypted;
00255     case KMMsgEncryptionStateUnknown: return KMHeaders::pixUndefinedEncrypted;
00256     case KMMsgEncryptionProblematic : return KMHeaders::pixEncryptionProblematic;
00257     default                         : return 0;
00258   }
00259 }
00260 
00261 const TQPixmap *HeaderItem::signatureIcon(KMMsgBase *msgBase) const
00262 {
00263   switch ( msgBase->signatureState() )
00264   {
00265     case KMMsgFullySigned          : return KMHeaders::pixFullySigned;
00266     case KMMsgPartiallySigned      : return KMHeaders::pixPartiallySigned;
00267     case KMMsgSignatureStateUnknown: return KMHeaders::pixUndefinedSigned;
00268     case KMMsgSignatureProblematic : return KMHeaders::pixSignatureProblematic;
00269     default                        : return 0;
00270   }
00271 }
00272 
00273 const TQPixmap *HeaderItem::statusIcon(KMMsgBase *msgBase) const
00274 {
00275   // forwarded, replied have precedence over the other states
00276   if (  msgBase->isForwarded() && !msgBase->isReplied() ) return KMHeaders::pixReadFwd;
00277   if ( !msgBase->isForwarded() &&  msgBase->isReplied() ) return KMHeaders::pixReadReplied;
00278   if (  msgBase->isForwarded() &&  msgBase->isReplied() ) return KMHeaders::pixReadFwdReplied;
00279 
00280   // a queued or sent mail is usually also read
00281   if ( msgBase->isQueued() ) return KMHeaders::pixQueued;
00282   if ( msgBase->isSent()   ) return KMHeaders::pixSent;
00283 
00284   if ( msgBase->isNew()                      ) return KMHeaders::pixNew;
00285   if ( msgBase->isRead() || msgBase->isOld() ) return KMHeaders::pixRead;
00286   if ( msgBase->isUnread()                   ) return KMHeaders::pixUns;
00287   if ( msgBase->isDeleted()                  ) return KMHeaders::pixDel;
00288 
00289   return 0;
00290 }
00291 
00292 const TQPixmap *HeaderItem::pixmap(int col) const
00293 {
00294   KMHeaders *headers = static_cast<KMHeaders*>(listView());
00295   KMMsgBase *msgBase = headers->folder()->getMsgBase( mMsgId );
00296 
00297   if ( col == headers->paintInfo()->subCol ) {
00298 
00299     PixmapList pixmaps;
00300 
00301     if ( !headers->mPaintInfo.showSpamHam ) {
00302       // Have the spam/ham and watched/ignored icons first, I guess.
00303       if ( msgBase->isSpam() ) pixmaps << *KMHeaders::pixSpam;
00304       if ( msgBase->isHam()  ) pixmaps << *KMHeaders::pixHam;
00305     }
00306 
00307     if ( !headers->mPaintInfo.showWatchedIgnored ) {
00308       if ( msgBase->isIgnored() ) pixmaps << *KMHeaders::pixIgnored;
00309       if ( msgBase->isWatched() ) pixmaps << *KMHeaders::pixWatched;
00310     }
00311 
00312     if ( !headers->mPaintInfo.showStatus ) {
00313       const TQPixmap *pix = statusIcon(msgBase);
00314       if ( pix ) pixmaps << *pix;
00315     }
00316 
00317     // Only merge the attachment icon in if that is configured.
00318     if ( headers->paintInfo()->showAttachmentIcon &&
00319         !headers->paintInfo()->showAttachment &&
00320          msgBase->attachmentState() == KMMsgHasAttachment )
00321       pixmaps << *KMHeaders::pixAttachment;
00322 
00323     // Only merge the invitation icon in if that is configured.
00324     if ( headers->paintInfo()->showInvitationIcon &&
00325          msgBase->invitationState() == KMMsgHasInvitation )
00326       pixmaps << *KMHeaders::pixInvitation;
00327 
00328     // Only merge the crypto icons in if that is configured.
00329     if ( headers->paintInfo()->showCryptoIcons ) {
00330       const TQPixmap *pix;
00331 
00332       if ( !headers->paintInfo()->showCrypto )
00333         if ( (pix = cryptoIcon(msgBase))    ) pixmaps << *pix;
00334 
00335       if ( !headers->paintInfo()->showSigned )
00336         if ( (pix = signatureIcon(msgBase)) ) pixmaps << *pix;
00337     }
00338 
00339     if ( !headers->mPaintInfo.showImportant )
00340       if ( msgBase->isImportant() ) pixmaps << *KMHeaders::pixFlag;
00341 
00342     if ( !headers->mPaintInfo.showTodo )
00343       if ( msgBase->isTodo() ) pixmaps << *KMHeaders::pixTodo;
00344 
00345     static TQPixmap mergedpix;
00346     mergedpix = pixmapMerge( pixmaps );
00347     return &mergedpix;
00348   }
00349   else if ( col == headers->paintInfo()->statusCol ) {
00350     return statusIcon(msgBase);
00351   }
00352   else if ( col == headers->paintInfo()->attachmentCol ) {
00353     if ( msgBase->attachmentState() == KMMsgHasAttachment )
00354       return KMHeaders::pixAttachment;
00355   }
00356   else if ( col == headers->paintInfo()->invitationCol ) {
00357     if ( msgBase->invitationState() == KMMsgHasInvitation )
00358       return KMHeaders::pixInvitation;
00359   }
00360   else if ( col == headers->paintInfo()->importantCol ) {
00361     if ( msgBase->isImportant() )
00362       return KMHeaders::pixFlag;
00363   }
00364   else if ( col == headers->paintInfo()->todoCol ) {
00365     if ( msgBase->isTodo() )
00366       return KMHeaders::pixTodo;
00367   }
00368   else if ( col == headers->paintInfo()->spamHamCol ) {
00369     if ( msgBase->isSpam() ) return KMHeaders::pixSpam;
00370     if ( msgBase->isHam()  ) return KMHeaders::pixHam;
00371   }
00372   else if ( col == headers->paintInfo()->watchedIgnoredCol ) {
00373     if ( msgBase->isWatched() ) return KMHeaders::pixWatched;
00374     if ( msgBase->isIgnored() ) return KMHeaders::pixIgnored;
00375   }
00376   else if ( col == headers->paintInfo()->signedCol ) {
00377     return signatureIcon(msgBase);
00378   }
00379   else if ( col == headers->paintInfo()->cryptoCol ) {
00380     return cryptoIcon(msgBase);
00381   }
00382   return 0;
00383 }
00384 
00385 void HeaderItem::paintCell( TQPainter * p, const TQColorGroup & cg,
00386     int column, int width, int align )
00387 {
00388   KMHeaders *headers = static_cast<KMHeaders*>(listView());
00389   if (headers->noRepaint) return;
00390   if (!headers->folder()) return;
00391   KMMsgBase *mMsgBase = headers->folder()->getMsgBase( mMsgId );
00392   if (!mMsgBase) return;
00393 
00394   TQColorGroup _cg( cg );
00395   TQColor c = _cg.text();
00396   TQColor *color = const_cast<TQColor *>( &headers->paintInfo()->colFore );
00397   TQFont font = p->font();
00398   int weight = font.weight();
00399 
00400   // for color and font family "important" overrides "new" overrides "unread"
00401   // overrides "todo" for the weight we use the maximal weight
00402   if ( mMsgBase->isTodo() ) {
00403     color = const_cast<TQColor*>( &headers->paintInfo()->colTodo );
00404     font = headers->todoFont();
00405     weight = TQMAX( weight, font.weight() );
00406   }
00407   if ( mMsgBase->isUnread() ) {
00408     color = const_cast<TQColor*>( &headers->paintInfo()->colUnread );
00409     font = headers->unreadFont();
00410     weight = TQMAX( weight, font.weight() );
00411   }
00412   if ( mMsgBase->isNew() ) {
00413     color = const_cast<TQColor*>( &headers->paintInfo()->colNew );
00414     font = headers->newFont();
00415     weight = TQMAX( weight, font.weight() );
00416   }
00417 
00418   if ( mMsgBase->isImportant() ) {
00419     color = const_cast<TQColor*>( &headers->paintInfo()->colFlag );
00420     font = headers->importantFont();
00421     weight = TQMAX( weight, font.weight() );
00422   }
00423   if ( column == headers->paintInfo()->dateCol ) {
00424     font = headers->dateFont();
00425   }
00426 
00427   TQColor cdisabled = KGlobalSettings::inactiveTextColor();
00428   if ( headers->isMessageCut( msgSerNum() ) ) {
00429     font.setItalic( true );
00430     color = &cdisabled;
00431   }
00432 
00433   // set color and font
00434   _cg.setColor( TQColorGroup::Text, *color );
00435   font.setWeight( weight );
00436   p->setFont( font );
00437 
00438   KListViewItem::paintCell( p, _cg, column, width, align );
00439 
00440   if (aboutToBeDeleted()) {
00441     // strike through
00442     p->drawLine( 0, height()/2, width, height()/2);
00443   }
00444 
00445   // reset color
00446   _cg.setColor( TQColorGroup::Text, c );
00447 }
00448 
00449 TQString HeaderItem::generate_key( KMHeaders *headers,
00450     KMMsgBase *msg,
00451     const KPaintInfo *paintInfo,
00452     int sortOrder )
00453 {
00454   // It appears, that TQListView in TQt-3.0 asks for the key
00455   // in TQListView::clear(), which is called from
00456   // readSortOrder()
00457   if (!msg) return TQString();
00458 
00459   int column = sortOrder & ((1 << 5) - 1);
00460   TQString ret = TQChar( (char)sortOrder );
00461   TQString sortArrival = TQString( "%1" ).arg( msg->getMsgSerNum(), 0, 36 );
00462   while (sortArrival.length() < 7) sortArrival = '0' + sortArrival;
00463 
00464   if (column == paintInfo->dateCol) {
00465     if (paintInfo->orderOfArrival)
00466       return ret + sortArrival;
00467     else {
00468       TQString d = TQString::number(msg->date());
00469       while (d.length() <= 10) d = '0' + d;
00470       return ret + d + sortArrival;
00471     }
00472   } else if (column == paintInfo->senderCol) {
00473     TQString tmp;
00474     if ( (headers->folder()->whoField().lower() == "to") && !headers->paintInfo()->showReceiver )
00475       tmp = msg->toStrip();
00476     else
00477       tmp = msg->fromStrip();
00478     return ret + tmp.lower() + ' ' + sortArrival;
00479   } else if (column == paintInfo->receiverCol) {
00480     TQString tmp = msg->toStrip();
00481     return ret + tmp.lower() + ' ' + sortArrival;
00482   } else if (column == paintInfo->subCol) {
00483     TQString tmp;
00484     tmp = ret;
00485     if (paintInfo->status) {
00486       tmp += msg->statusToSortRank() + ' ';
00487     }
00488     tmp += KMMessage::stripOffPrefixes( msg->subject().lower() ) + ' ' + sortArrival;
00489     return tmp;
00490   }
00491   else if (column == paintInfo->sizeCol) {
00492     TQString len;
00493     if ( msg->parent()->folderType() == KMFolderTypeImap )
00494     {
00495       len = TQString::number( msg->msgSizeServer() );
00496     } else {
00497       len = TQString::number( msg->msgSize() );
00498     }
00499     while (len.length() < 9) len = '0' + len;
00500     return ret + len + sortArrival;
00501   }
00502   else if (column == paintInfo->statusCol) {
00503     TQString s;
00504     if      ( msg->isNew()                            ) s = "1";
00505     else if ( msg->isUnread()                         ) s = "2";
00506     else if (!msg->isForwarded() &&  msg->isReplied() ) s = "3";
00507     else if ( msg->isForwarded() &&  msg->isReplied() ) s = "4";
00508     else if ( msg->isForwarded() && !msg->isReplied() ) s = "5";
00509     else if ( msg->isRead() || msg->isOld()           ) s = "6";
00510     else if ( msg->isQueued()                         ) s = "7";
00511     else if ( msg->isSent()                           ) s = "8";
00512     else if ( msg->isDeleted()                        ) s = "9";
00513     return ret + s + sortArrival;
00514   }
00515   else if (column == paintInfo->attachmentCol) {
00516     TQString s(msg->attachmentState() == KMMsgHasAttachment ? "1" : "0");
00517     return ret + s + sortArrival;
00518   }
00519   else if (column == paintInfo->invitationCol) {
00520     TQString s(msg->invitationState() == KMMsgHasInvitation ? "1" : "0");
00521     return ret + s + sortArrival;
00522   }
00523   else if (column == paintInfo->importantCol) {
00524     TQString s(msg->isImportant() ? "1" : "0");
00525     return ret + s + sortArrival;
00526   }
00527   else if ( column == paintInfo->todoCol ) {
00528     TQString s( msg->isTodo() ? "1": "0" );
00529     return ret + s + sortArrival;
00530   }
00531   else if (column == paintInfo->spamHamCol) {
00532     TQString s((msg->isSpam() || msg->isHam()) ? "1" : "0");
00533     return ret + s + sortArrival;
00534   }
00535   else if (column == paintInfo->watchedIgnoredCol) {
00536     TQString s((msg->isWatched() || msg->isIgnored()) ? "1" : "0");
00537     return ret + s + sortArrival;
00538   }
00539   else if (column == paintInfo->signedCol) {
00540     TQString s;
00541     switch ( msg->signatureState() )
00542     {
00543       case KMMsgFullySigned          : s = "1"; break;
00544       case KMMsgPartiallySigned      : s = "2"; break;
00545       case KMMsgSignatureStateUnknown: s = "3"; break;
00546       case KMMsgSignatureProblematic : s = "4"; break;
00547       default                        : s = "5"; break;
00548     }
00549     return ret + s + sortArrival;
00550   }
00551   else if (column == paintInfo->cryptoCol) {
00552     TQString s;
00553     switch ( msg->encryptionState() )
00554     {
00555       case KMMsgFullyEncrypted        : s = "1"; break;
00556       case KMMsgPartiallyEncrypted    : s = "2"; break;
00557       case KMMsgEncryptionStateUnknown: s = "3"; break;
00558       case KMMsgEncryptionProblematic : s = "4"; break;
00559       default                         : s = "5"; break;
00560     }
00561     return ret + s + sortArrival;
00562   }
00563   return ret + "missing key"; //you forgot something!!
00564 }
00565 
00566 TQString HeaderItem::key( int column, bool /*ascending*/ ) const
00567 {
00568   KMHeaders *headers = static_cast<KMHeaders*>(listView());
00569   int sortOrder = column;
00570   if (headers->mPaintInfo.orderOfArrival)
00571     sortOrder |= (1 << 6);
00572   if (headers->mPaintInfo.status)
00573     sortOrder |= (1 << 5);
00574   //This code should stay pretty much like this, if you are adding new
00575   //columns put them in generate_key
00576   if(mKey.isEmpty() || mKey[0] != (char)sortOrder) {
00577     KMHeaders *headers = static_cast<KMHeaders*>(listView());
00578     KMMsgBase *msgBase = headers->folder()->getMsgBase( mMsgId );
00579     return ((HeaderItem *)this)->mKey =
00580       generate_key( headers, msgBase, headers->paintInfo(), sortOrder );
00581   }
00582   return mKey;
00583 }
00584 
00585 void HeaderItem::setTempKey( TQString key ) {
00586   mKey = key;
00587 }
00588 
00589 int HeaderItem::compare( TQListViewItem *i, int col, bool ascending ) const
00590 {
00591   int res = 0;
00592   KMHeaders *headers = static_cast<KMHeaders*>(listView());
00593   if ( ( col == headers->paintInfo()->statusCol         ) ||
00594       ( col == headers->paintInfo()->sizeCol           ) ||
00595       ( col == headers->paintInfo()->attachmentCol     ) ||
00596       ( col == headers->paintInfo()->invitationCol     ) ||
00597       ( col == headers->paintInfo()->importantCol      ) ||
00598       ( col == headers->paintInfo()->todoCol           ) ||
00599       ( col == headers->paintInfo()->spamHamCol        ) ||
00600       ( col == headers->paintInfo()->signedCol         ) ||
00601       ( col == headers->paintInfo()->cryptoCol         ) ||
00602       ( col == headers->paintInfo()->watchedIgnoredCol ) ) {
00603     res = key( col, ascending ).compare( i->key( col, ascending ) );
00604   } else if ( col == headers->paintInfo()->dateCol ) {
00605     res = key( col, ascending ).compare( i->key( col, ascending ) );
00606     if (i->parent() && !ascending)
00607       res = -res;
00608   } else if ( col == headers->paintInfo()->subCol ||
00609       col == headers->paintInfo()->senderCol ||
00610       col == headers->paintInfo()->receiverCol ) {
00611     res = key( col, ascending ).localeAwareCompare( i->key( col, ascending ) );
00612   }
00613   return res;
00614 }
00615 
00616 TQListViewItem* HeaderItem::firstChildNonConst() /* Non const! */
00617 {
00618   enforceSortOrder(); // Try not to rely on TQListView implementation details
00619   return firstChild();
00620 }
00621