29 #include <tdelocale.h>
30 #include <tqapplication.h>
33 #include <tqpainter.h>
35 #include <tdeio/netaccess.h>
37 #include "headeritem.h"
38 #include "kmheaders.h"
42 using namespace KMail;
45 HeaderItem::HeaderItem( TQListView* parent,
int msgId,
const TQString& key )
46 : TDEListViewItem( parent ),
49 mAboutToBeDeleted( false ),
56 HeaderItem::HeaderItem( TQListViewItem* parent,
int msgId,
const TQString& key )
57 : TDEListViewItem( parent ),
60 mAboutToBeDeleted( false ),
66 HeaderItem::~HeaderItem ()
68 delete mSortCacheItem;
80 void HeaderItem::irefresh()
83 NestingPolicy threadingPolicy = headers->getNestingPolicy();
84 if ((threadingPolicy == AlwaysOpen) ||
85 (threadingPolicy == DefaultOpen)) {
91 if (threadingPolicy == DefaultClosed)
95 if (parent() && parent()->isOpen()) {
101 mSerNum = mMsgBase->getMsgSerNum();
102 if (mMsgBase->isNew() || mMsgBase->isUnread()
103 || mMsgBase->isImportant() || mMsgBase->isTodo() || mMsgBase->isWatched() ) {
106 while(topOfThread->parent())
107 topOfThread = (
HeaderItem*)topOfThread->parent();
118 TQString HeaderItem::to()
const
123 return msgBase->to();
129 TQString HeaderItem::from()
const
134 return msgBase->from();
141 TQ_UINT32 HeaderItem::msgSerNum()
const
152 TQListViewItem * lvchild;
153 lvchild = firstChild();
155 ((
HeaderItem*)lvchild)->setOpenRecursive(
true );
156 lvchild = lvchild->nextSibling();
173 if ( col == headers->
paintInfo()->senderCol ) {
175 tmp = mMsgBase->toStrip();
177 tmp = mMsgBase->fromStrip();
179 tmp = i18n(
"Unknown");
181 tmp = tmp.simplifyWhiteSpace();
183 }
else if ( col == headers->
paintInfo()->receiverCol ) {
184 tmp = mMsgBase->toStrip();
186 tmp = i18n(
"Unknown");
188 tmp = tmp.simplifyWhiteSpace();
190 }
else if(col == headers->
paintInfo()->subCol) {
191 tmp = mMsgBase->subject();
193 tmp = i18n(
"No Subject");
195 tmp.remove(TQRegExp(
"[\r\n]"));
197 }
else if(col == headers->
paintInfo()->dateCol) {
198 tmp = headers->mDate.dateString( mMsgBase->date() );
199 }
else if(col == headers->
paintInfo()->sizeCol
201 if ( mMsgBase->parent()->folderType() == KMFolderTypeImap ) {
202 tmp = TDEIO::convertSize( mMsgBase->msgSizeServer() );
204 tmp = TDEIO::convertSize( mMsgBase->msgSize() );
210 void HeaderItem::setup()
213 const int ph = KMHeaders::pixNew->height();
214 TQListView *v = listView();
215 int h = TQMAX( v->fontMetrics().height(), ph ) + 2*v->itemMargin();
216 h = TQMAX( h, TQApplication::globalStrut().height());
222 typedef TQValueList<TQPixmap> PixmapList;
224 TQPixmap HeaderItem::pixmapMerge( PixmapList pixmaps )
const
228 for ( PixmapList::ConstIterator it = pixmaps.begin();
229 it != pixmaps.end(); ++it ) {
230 width += (*it).width();
231 height = TQMAX( height, (*it).height() );
234 TQPixmap res( width, height );
235 TQBitmap mask( width, height,
true );
238 for ( PixmapList::ConstIterator it = pixmaps.begin();
239 it != pixmaps.end(); ++it ) {
240 bitBlt( &res, x, (height - (*it).height()) / 2, &(*it) );
241 bitBlt( &mask, x, (height - (*it).height()) / 2, (*it).mask() );
249 const TQPixmap *HeaderItem::cryptoIcon(KMMsgBase *msgBase)
const
251 switch ( msgBase->encryptionState() )
253 case KMMsgFullyEncrypted :
return KMHeaders::pixFullyEncrypted;
254 case KMMsgPartiallyEncrypted :
return KMHeaders::pixPartiallyEncrypted;
255 case KMMsgEncryptionStateUnknown:
return KMHeaders::pixUndefinedEncrypted;
256 case KMMsgEncryptionProblematic :
return KMHeaders::pixEncryptionProblematic;
261 const TQPixmap *HeaderItem::signatureIcon(KMMsgBase *msgBase)
const
263 switch ( msgBase->signatureState() )
265 case KMMsgFullySigned :
return KMHeaders::pixFullySigned;
266 case KMMsgPartiallySigned :
return KMHeaders::pixPartiallySigned;
267 case KMMsgSignatureStateUnknown:
return KMHeaders::pixUndefinedSigned;
268 case KMMsgSignatureProblematic :
return KMHeaders::pixSignatureProblematic;
273 const TQPixmap *HeaderItem::statusIcon(KMMsgBase *msgBase)
const
276 if ( msgBase->isForwarded() && !msgBase->isReplied() )
return KMHeaders::pixReadFwd;
277 if ( !msgBase->isForwarded() && msgBase->isReplied() )
return KMHeaders::pixReadReplied;
278 if ( msgBase->isForwarded() && msgBase->isReplied() )
return KMHeaders::pixReadFwdReplied;
281 if ( msgBase->isQueued() )
return KMHeaders::pixQueued;
282 if ( msgBase->isSent() )
return KMHeaders::pixSent;
284 if ( msgBase->isNew() )
return KMHeaders::pixNew;
285 if ( msgBase->isRead() || msgBase->isOld() )
return KMHeaders::pixRead;
286 if ( msgBase->isUnread() )
return KMHeaders::pixUns;
287 if ( msgBase->isDeleted() )
return KMHeaders::pixDel;
292 const TQPixmap *HeaderItem::pixmap(
int col)
const
297 if ( col == headers->
paintInfo()->subCol ) {
301 if ( !headers->mPaintInfo.showSpamHam ) {
303 if ( msgBase->isSpam() ) pixmaps << *KMHeaders::pixSpam;
304 if ( msgBase->isHam() ) pixmaps << *KMHeaders::pixHam;
307 if ( !headers->mPaintInfo.showWatchedIgnored ) {
308 if ( msgBase->isIgnored() ) pixmaps << *KMHeaders::pixIgnored;
309 if ( msgBase->isWatched() ) pixmaps << *KMHeaders::pixWatched;
312 if ( !headers->mPaintInfo.showStatus ) {
313 const TQPixmap *pix = statusIcon(msgBase);
314 if ( pix ) pixmaps << *pix;
318 if ( headers->
paintInfo()->showAttachmentIcon &&
320 msgBase->attachmentState() == KMMsgHasAttachment )
321 pixmaps << *KMHeaders::pixAttachment;
324 if ( headers->
paintInfo()->showInvitationIcon &&
325 msgBase->invitationState() == KMMsgHasInvitation )
326 pixmaps << *KMHeaders::pixInvitation;
329 if ( headers->
paintInfo()->showCryptoIcons ) {
333 if ( (pix = cryptoIcon(msgBase)) ) pixmaps << *pix;
336 if ( (pix = signatureIcon(msgBase)) ) pixmaps << *pix;
339 if ( !headers->mPaintInfo.showImportant )
340 if ( msgBase->isImportant() ) pixmaps << *KMHeaders::pixFlag;
342 if ( !headers->mPaintInfo.showTodo )
343 if ( msgBase->isTodo() ) pixmaps << *KMHeaders::pixTodo;
345 static TQPixmap mergedpix;
346 mergedpix = pixmapMerge( pixmaps );
349 else if ( col == headers->
paintInfo()->statusCol ) {
350 return statusIcon(msgBase);
352 else if ( col == headers->
paintInfo()->attachmentCol ) {
353 if ( msgBase->attachmentState() == KMMsgHasAttachment )
354 return KMHeaders::pixAttachment;
356 else if ( col == headers->
paintInfo()->invitationCol ) {
357 if ( msgBase->invitationState() == KMMsgHasInvitation )
358 return KMHeaders::pixInvitation;
360 else if ( col == headers->
paintInfo()->importantCol ) {
361 if ( msgBase->isImportant() )
362 return KMHeaders::pixFlag;
364 else if ( col == headers->
paintInfo()->todoCol ) {
365 if ( msgBase->isTodo() )
366 return KMHeaders::pixTodo;
368 else if ( col == headers->
paintInfo()->spamHamCol ) {
369 if ( msgBase->isSpam() )
return KMHeaders::pixSpam;
370 if ( msgBase->isHam() )
return KMHeaders::pixHam;
372 else if ( col == headers->
paintInfo()->watchedIgnoredCol ) {
373 if ( msgBase->isWatched() )
return KMHeaders::pixWatched;
374 if ( msgBase->isIgnored() )
return KMHeaders::pixIgnored;
376 else if ( col == headers->
paintInfo()->signedCol ) {
377 return signatureIcon(msgBase);
379 else if ( col == headers->
paintInfo()->cryptoCol ) {
380 return cryptoIcon(msgBase);
385 void HeaderItem::paintCell( TQPainter * p,
const TQColorGroup & cg,
386 int column,
int width,
int align )
389 if (headers->noRepaint)
return;
390 if (!headers->
folder())
return;
392 if (!mMsgBase)
return;
394 TQColorGroup _cg( cg );
395 TQColor c = _cg.text();
396 TQColor *color =
const_cast<TQColor *
>( &headers->
paintInfo()->colFore );
397 TQFont font = p->font();
398 int weight = font.weight();
402 if ( mMsgBase->isTodo() ) {
403 color =
const_cast<TQColor*
>( &headers->
paintInfo()->colTodo );
404 font = headers->todoFont();
405 weight = TQMAX( weight, font.weight() );
407 if ( mMsgBase->isUnread() ) {
408 color =
const_cast<TQColor*
>( &headers->
paintInfo()->colUnread );
409 font = headers->unreadFont();
410 weight = TQMAX( weight, font.weight() );
412 if ( mMsgBase->isNew() ) {
413 color =
const_cast<TQColor*
>( &headers->
paintInfo()->colNew );
414 font = headers->newFont();
415 weight = TQMAX( weight, font.weight() );
418 if ( mMsgBase->isImportant() ) {
419 color =
const_cast<TQColor*
>( &headers->
paintInfo()->colFlag );
420 font = headers->importantFont();
421 weight = TQMAX( weight, font.weight() );
423 if ( column == headers->
paintInfo()->dateCol ) {
424 font = headers->dateFont();
427 TQColor cdisabled = TDEGlobalSettings::inactiveTextColor();
429 font.setItalic(
true );
434 _cg.setColor( TQColorGroup::Text, *color );
435 font.setWeight( weight );
438 TDEListViewItem::paintCell( p, _cg, column, width, align );
442 p->drawLine( 0, height()/2, width, height()/2);
446 _cg.setColor( TQColorGroup::Text, c );
449 TQString HeaderItem::generate_key(
KMHeaders *headers,
451 const KPaintInfo *paintInfo,
457 if (!msg)
return TQString();
459 int column = sortOrder & ((1 << 5) - 1);
460 TQString ret = TQChar( (
char)sortOrder );
461 TQString sortArrival = TQString(
"%1" ).arg( msg->getMsgSerNum(), 0, 36 );
462 while (sortArrival.length() < 7) sortArrival =
'0' + sortArrival;
464 if (column == paintInfo->dateCol) {
465 if (paintInfo->orderOfArrival)
466 return ret + sortArrival;
468 TQString d = TQString::number(msg->date());
469 while (d.length() <= 10) d =
'0' + d;
470 return ret + d + sortArrival;
472 }
else if (column == paintInfo->senderCol) {
475 tmp = msg->toStrip();
477 tmp = msg->fromStrip();
478 return ret + tmp.lower() +
' ' + sortArrival;
479 }
else if (column == paintInfo->receiverCol) {
480 TQString tmp = msg->toStrip();
481 return ret + tmp.lower() +
' ' + sortArrival;
482 }
else if (column == paintInfo->subCol) {
485 if (paintInfo->status) {
486 tmp += msg->statusToSortRank() +
' ';
488 tmp += KMMessage::stripOffPrefixes( msg->subject().lower() ) +
' ' + sortArrival;
491 else if (column == paintInfo->sizeCol) {
493 if ( msg->parent()->folderType() == KMFolderTypeImap )
495 len = TQString::number( msg->msgSizeServer() );
497 len = TQString::number( msg->msgSize() );
499 while (len.length() < 9) len =
'0' + len;
500 return ret + len + sortArrival;
502 else if (column == paintInfo->statusCol) {
504 if ( msg->isNew() ) s =
"1";
505 else if ( msg->isUnread() ) s =
"2";
506 else if (!msg->isForwarded() && msg->isReplied() ) s =
"3";
507 else if ( msg->isForwarded() && msg->isReplied() ) s =
"4";
508 else if ( msg->isForwarded() && !msg->isReplied() ) s =
"5";
509 else if ( msg->isRead() || msg->isOld() ) s =
"6";
510 else if ( msg->isQueued() ) s =
"7";
511 else if ( msg->isSent() ) s =
"8";
512 else if ( msg->isDeleted() ) s =
"9";
513 return ret + s + sortArrival;
515 else if (column == paintInfo->attachmentCol) {
516 TQString s(msg->attachmentState() == KMMsgHasAttachment ?
"1" :
"0");
517 return ret + s + sortArrival;
519 else if (column == paintInfo->invitationCol) {
520 TQString s(msg->invitationState() == KMMsgHasInvitation ?
"1" :
"0");
521 return ret + s + sortArrival;
523 else if (column == paintInfo->importantCol) {
524 TQString s(msg->isImportant() ?
"1" :
"0");
525 return ret + s + sortArrival;
527 else if ( column == paintInfo->todoCol ) {
528 TQString s( msg->isTodo() ?
"1":
"0" );
529 return ret + s + sortArrival;
531 else if (column == paintInfo->spamHamCol) {
532 TQString s((msg->isSpam() || msg->isHam()) ?
"1" :
"0");
533 return ret + s + sortArrival;
535 else if (column == paintInfo->watchedIgnoredCol) {
536 TQString s((msg->isWatched() || msg->isIgnored()) ?
"1" :
"0");
537 return ret + s + sortArrival;
539 else if (column == paintInfo->signedCol) {
541 switch ( msg->signatureState() )
543 case KMMsgFullySigned : s =
"1";
break;
544 case KMMsgPartiallySigned : s =
"2";
break;
545 case KMMsgSignatureStateUnknown: s =
"3";
break;
546 case KMMsgSignatureProblematic : s =
"4";
break;
547 default : s =
"5";
break;
549 return ret + s + sortArrival;
551 else if (column == paintInfo->cryptoCol) {
553 switch ( msg->encryptionState() )
555 case KMMsgFullyEncrypted : s =
"1";
break;
556 case KMMsgPartiallyEncrypted : s =
"2";
break;
557 case KMMsgEncryptionStateUnknown: s =
"3";
break;
558 case KMMsgEncryptionProblematic : s =
"4";
break;
559 default : s =
"5";
break;
561 return ret + s + sortArrival;
563 return ret +
"missing key";
566 TQString HeaderItem::key(
int column,
bool )
const
569 int sortOrder = column;
570 if (headers->mPaintInfo.orderOfArrival)
571 sortOrder |= (1 << 6);
572 if (headers->mPaintInfo.status)
573 sortOrder |= (1 << 5);
576 if(mKey.isEmpty() || mKey[0] != (char)sortOrder) {
580 generate_key( headers, msgBase, headers->
paintInfo(), sortOrder );
585 void HeaderItem::setTempKey( TQString key ) {
589 int HeaderItem::compare( TQListViewItem *i,
int col,
bool ascending )
const
593 if ( ( col == headers->
paintInfo()->statusCol ) ||
594 ( col == headers->
paintInfo()->sizeCol ) ||
595 ( col == headers->
paintInfo()->attachmentCol ) ||
596 ( col == headers->
paintInfo()->invitationCol ) ||
597 ( col == headers->
paintInfo()->importantCol ) ||
598 ( col == headers->
paintInfo()->todoCol ) ||
599 ( col == headers->
paintInfo()->spamHamCol ) ||
600 ( col == headers->
paintInfo()->signedCol ) ||
601 ( col == headers->
paintInfo()->cryptoCol ) ||
602 ( col == headers->
paintInfo()->watchedIgnoredCol ) ) {
603 res = key( col, ascending ).compare( i->key( col, ascending ) );
604 }
else if ( col == headers->
paintInfo()->dateCol ) {
605 res = key( col, ascending ).compare( i->key( col, ascending ) );
606 if (i->parent() && !ascending)
608 }
else if ( col == headers->
paintInfo()->subCol ||
609 col == headers->
paintInfo()->senderCol ||
610 col == headers->
paintInfo()->receiverCol ) {
611 res = key( col, ascending ).localeAwareCompare( i->key( col, ascending ) );
616 TQListViewItem* HeaderItem::firstChildNonConst()
TQString whoField() const
Get / set the name of the field that is used for the Sender/Receiver column in the headers (From/To)
const KMMsgBase * getMsgBase(int idx) const
Provides access to the basic message fields that are also stored in the index.