6 #include "headeritem.h"
9 #include "kcursorsaver.h"
10 #include "kmcommands.h"
11 #include "kmmainwidget.h"
12 #include "kmfiltermgr.h"
13 #include "undostack.h"
14 #include "kmmsgdict.h"
16 #include "kmfoldertree.h"
17 #include "folderjob.h"
18 using KMail::FolderJob;
19 #include "actionscheduler.h"
20 using KMail::ActionScheduler;
21 #include "messagecopyhelper.h"
23 #include "broadcaststatus.h"
24 using KPIM::BroadcastStatus;
25 #include "progressmanager.h"
26 using KPIM::ProgressManager;
27 using KPIM::ProgressItem;
28 #include <maillistdrag.h>
29 #include "globalsettings.h"
31 #include "messageactions.h"
33 #include <tdeapplication.h>
34 #include <tdeaccelmanager.h>
35 #include <tdeglobalsettings.h>
36 #include <tdemessagebox.h>
37 #include <kiconloader.h>
38 #include <tdepopupmenu.h>
40 #include <tdeconfig.h>
41 #include <tdelocale.h>
45 #include <tqeventloop.h>
48 #include <tqptrstack.h>
49 #include <tqptrqueue.h>
50 #include <tqpainter.h>
51 #include <tqtextcodec.h>
53 #include <tqlistview.h>
55 #include <mimelib/enum.h>
56 #include <mimelib/field.h>
57 #include <mimelib/mimepp.h>
62 #include "textsource.h"
64 TQPixmap* KMHeaders::pixNew = 0;
65 TQPixmap* KMHeaders::pixUns = 0;
66 TQPixmap* KMHeaders::pixDel = 0;
67 TQPixmap* KMHeaders::pixRead = 0;
68 TQPixmap* KMHeaders::pixRep = 0;
69 TQPixmap* KMHeaders::pixQueued = 0;
70 TQPixmap* KMHeaders::pixTodo = 0;
71 TQPixmap* KMHeaders::pixSent = 0;
72 TQPixmap* KMHeaders::pixFwd = 0;
73 TQPixmap* KMHeaders::pixFlag = 0;
74 TQPixmap* KMHeaders::pixWatched = 0;
75 TQPixmap* KMHeaders::pixIgnored = 0;
76 TQPixmap* KMHeaders::pixSpam = 0;
77 TQPixmap* KMHeaders::pixHam = 0;
78 TQPixmap* KMHeaders::pixFullySigned = 0;
79 TQPixmap* KMHeaders::pixPartiallySigned = 0;
80 TQPixmap* KMHeaders::pixUndefinedSigned = 0;
81 TQPixmap* KMHeaders::pixFullyEncrypted = 0;
82 TQPixmap* KMHeaders::pixPartiallyEncrypted = 0;
83 TQPixmap* KMHeaders::pixUndefinedEncrypted = 0;
84 TQPixmap* KMHeaders::pixEncryptionProblematic = 0;
85 TQPixmap* KMHeaders::pixSignatureProblematic = 0;
86 TQPixmap* KMHeaders::pixAttachment = 0;
87 TQPixmap* KMHeaders::pixInvitation = 0;
88 TQPixmap* KMHeaders::pixReadFwd = 0;
89 TQPixmap* KMHeaders::pixReadReplied = 0;
90 TQPixmap* KMHeaders::pixReadFwdReplied = 0;
94 KMHeaders::KMHeaders(KMMainWidget *aOwner, TQWidget *parent,
96 TDEListView( parent, name ),
97 mIgnoreSortOrderChanges( false )
99 static bool pixmapsLoaded =
false;
101 KImageIO::registerFormats();
107 setSelectionMode( TQListView::Extended );
108 setAllColumnsShowFocus(
true );
110 nestingPolicy = OpenUnread;
111 mNestedOverride =
false;
112 mSubjThreading =
true;
113 mMousePressed =
false;
114 mSortInfo.dirty =
true;
115 mSortInfo.fakeSort = 0;
116 mSortInfo.removed = 0;
117 mSortInfo.column = 0;
119 mSortDescending =
false;
120 mSortInfo.ascending =
false;
121 mReaderWindowActive =
false;
124 setStyleDependantFrameWidth();
126 header()->setClickEnabled(
true);
127 header()->installEventFilter(
this);
128 mPopup =
new TDEPopupMenu(
this);
129 mPopup->insertTitle(i18n(
"View Columns"));
130 mPopup->setCheckable(
true);
131 mPopup->insertItem(i18n(
"Status"), KPaintInfo::COL_STATUS);
132 mPopup->insertItem(i18n(
"Important"), KPaintInfo::COL_IMPORTANT);
133 mPopup->insertItem(i18n(
"Action Item"), KPaintInfo::COL_TODO);
134 mPopup->insertItem(i18n(
"Attachment"), KPaintInfo::COL_ATTACHMENT);
135 mPopup->insertItem(i18n(
"Invitation"), KPaintInfo::COL_INVITATION);
136 mPopup->insertItem(i18n(
"Spam/Ham"), KPaintInfo::COL_SPAM_HAM);
137 mPopup->insertItem(i18n(
"Watched/Ignored"), KPaintInfo::COL_WATCHED_IGNORED);
138 mPopup->insertItem(i18n(
"Signature"), KPaintInfo::COL_SIGNED);
139 mPopup->insertItem(i18n(
"Encryption"), KPaintInfo::COL_CRYPTO);
140 mPopup->insertItem(i18n(
"Size"), KPaintInfo::COL_SIZE);
141 mPopup->insertItem(i18n(
"Receiver"), KPaintInfo::COL_RECEIVER);
143 connect(mPopup, TQ_SIGNAL(activated(
int)),
this, TQ_SLOT(slotToggleColumn(
int)));
145 setShowSortIndicator(
true);
146 setFocusPolicy( TQWidget::WheelFocus );
150 pixmapsLoaded =
true;
151 pixNew =
new TQPixmap( UserIcon(
"kmmsgnew" ) );
152 pixUns =
new TQPixmap( UserIcon(
"kmmsgunseen" ) );
153 pixDel =
new TQPixmap( UserIcon(
"kmmsgdel" ) );
154 pixRead =
new TQPixmap( UserIcon(
"kmmsgread" ) );
155 pixRep =
new TQPixmap( UserIcon(
"kmmsgreplied" ) );
156 pixQueued =
new TQPixmap( UserIcon(
"kmmsgqueued" ) );
157 pixTodo =
new TQPixmap( UserIcon(
"kmmsgtodo" ) );
158 pixSent =
new TQPixmap( UserIcon(
"kmmsgsent" ) );
159 pixFwd =
new TQPixmap( UserIcon(
"kmmsgforwarded" ) );
160 pixFlag =
new TQPixmap( UserIcon(
"kmmsgflag" ) );
161 pixWatched =
new TQPixmap( UserIcon(
"kmmsgwatched" ) );
162 pixIgnored =
new TQPixmap( UserIcon(
"kmmsgignored" ) );
163 pixSpam =
new TQPixmap( UserIcon(
"kmmsgspam" ) );
164 pixHam =
new TQPixmap( UserIcon(
"kmmsgham" ) );
165 pixFullySigned =
new TQPixmap( UserIcon(
"kmmsgfullysigned" ) );
166 pixPartiallySigned =
new TQPixmap( UserIcon(
"kmmsgpartiallysigned" ) );
167 pixUndefinedSigned =
new TQPixmap( UserIcon(
"kmmsgundefinedsigned" ) );
168 pixFullyEncrypted =
new TQPixmap( UserIcon(
"kmmsgfullyencrypted" ) );
169 pixPartiallyEncrypted =
new TQPixmap( UserIcon(
"kmmsgpartiallyencrypted" ) );
170 pixUndefinedEncrypted =
new TQPixmap( UserIcon(
"kmmsgundefinedencrypted" ) );
171 pixEncryptionProblematic =
new TQPixmap( UserIcon(
"kmmsgencryptionproblematic" ) );
172 pixSignatureProblematic =
new TQPixmap( UserIcon(
"kmmsgsignatureproblematic" ) );
173 pixAttachment =
new TQPixmap( UserIcon(
"kmmsgattachment" ) );
174 pixInvitation =
new TQPixmap( UserIcon(
"kmmsginvitation" ) );
175 pixReadFwd =
new TQPixmap( UserIcon(
"kmmsgread_fwd" ) );
176 pixReadReplied =
new TQPixmap( UserIcon(
"kmmsgread_replied" ) );
177 pixReadFwdReplied =
new TQPixmap( UserIcon(
"kmmsgread_fwd_replied" ) );
180 header()->setStretchEnabled(
false );
181 header()->setResizeEnabled(
false );
183 mPaintInfo.subCol = addColumn( i18n(
"Subject"), 310 );
184 mPaintInfo.senderCol = addColumn( i18n(
"Sender"), 170 );
185 mPaintInfo.dateCol = addColumn( i18n(
"Date"), 170 );
186 mPaintInfo.sizeCol = addColumn( i18n(
"Size"), 0 );
187 mPaintInfo.receiverCol = addColumn( i18n(
"Receiver"), 0 );
189 mPaintInfo.statusCol = addColumn( *pixNew ,
"", 0 );
190 mPaintInfo.importantCol = addColumn( *pixFlag ,
"", 0 );
191 mPaintInfo.todoCol = addColumn( *pixTodo ,
"", 0 );
192 mPaintInfo.attachmentCol = addColumn( *pixAttachment ,
"", 0 );
193 mPaintInfo.invitationCol = addColumn( *pixInvitation ,
"", 0 );
194 mPaintInfo.spamHamCol = addColumn( *pixSpam ,
"", 0 );
195 mPaintInfo.watchedIgnoredCol = addColumn( *pixWatched ,
"", 0 );
196 mPaintInfo.signedCol = addColumn( *pixFullySigned ,
"", 0 );
197 mPaintInfo.cryptoCol = addColumn( *pixFullyEncrypted,
"", 0 );
199 setResizeMode( TQListView::NoColumn );
202 header()->setResizeEnabled(
true, mPaintInfo.subCol );
203 header()->setResizeEnabled(
true, mPaintInfo.senderCol );
204 header()->setResizeEnabled(
true, mPaintInfo.dateCol );
206 connect(
this, TQ_SIGNAL( contextMenuRequested( TQListViewItem*,
const TQPoint &,
int )),
207 this, TQ_SLOT( rightButtonPressed( TQListViewItem*,
const TQPoint &,
int )));
208 connect(
this, TQ_SIGNAL(doubleClicked(TQListViewItem*)),
209 this,TQ_SLOT(selectMessage(TQListViewItem*)));
210 connect(
this,TQ_SIGNAL(currentChanged(TQListViewItem*)),
211 this,TQ_SLOT(highlightMessage(TQListViewItem*)));
214 mSubjectLists.setAutoDelete(
true );
216 mMoveMessages =
false;
217 connect(
this, TQ_SIGNAL(selectionChanged()), TQ_SLOT(updateActions()) );
222 KMHeaders::~KMHeaders ()
228 mFolder->close(
"kmheaders");
235 bool KMHeaders::eventFilter ( TQObject *o, TQEvent *e )
237 if ( e->type() == TQEvent::MouseButtonPress &&
238 static_cast<TQMouseEvent*
>(e)->button() == TQt::RightButton &&
243 if ( mPaintInfo.showReceiver )
244 mPopup->changeItem(KPaintInfo::COL_RECEIVER, i18n(
"Receiver"));
246 if ( mFolder && (mFolder->whoField().lower() ==
"to") )
247 mPopup->changeItem(KPaintInfo::COL_RECEIVER, i18n(
"Sender"));
249 mPopup->changeItem(KPaintInfo::COL_RECEIVER, i18n(
"Receiver"));
251 mPopup->popup(
static_cast<TQMouseEvent*
>(e)->globalPos() );
254 return TDEListView::eventFilter(o, e);
266 switch (
static_cast<KPaintInfo::ColumnIds
>(
id) )
268 case KPaintInfo::COL_SIZE:
270 show = &mPaintInfo.showSize;
271 col = &mPaintInfo.sizeCol;
275 case KPaintInfo::COL_ATTACHMENT:
277 show = &mPaintInfo.showAttachment;
278 col = &mPaintInfo.attachmentCol;
279 width = pixAttachment->width() + 8;
280 if ( *col == header()->mapToIndex( *col ) )
284 case KPaintInfo::COL_INVITATION:
286 show = &mPaintInfo.showInvitation;
287 col = &mPaintInfo.invitationCol;
288 width = pixAttachment->width() + 8;
289 if ( *col == header()->mapToIndex( *col ) )
293 case KPaintInfo::COL_IMPORTANT:
295 show = &mPaintInfo.showImportant;
296 col = &mPaintInfo.importantCol;
297 width = pixFlag->width() + 8;
298 if ( *col == header()->mapToIndex( *col ) )
302 case KPaintInfo::COL_TODO:
304 show = &mPaintInfo.showTodo;
305 col = &mPaintInfo.todoCol;
306 width = pixTodo->width() + 8;
307 if ( *col == header()->mapToIndex( *col ) )
311 case KPaintInfo::COL_SPAM_HAM:
313 show = &mPaintInfo.showSpamHam;
314 col = &mPaintInfo.spamHamCol;
315 width = pixSpam->width() + 8;
316 if ( *col == header()->mapToIndex( *col ) )
320 case KPaintInfo::COL_WATCHED_IGNORED:
322 show = &mPaintInfo.showWatchedIgnored;
323 col = &mPaintInfo.watchedIgnoredCol;
324 width = pixWatched->width() + 8;
325 if ( *col == header()->mapToIndex( *col ) )
329 case KPaintInfo::COL_STATUS:
331 show = &mPaintInfo.showStatus;
332 col = &mPaintInfo.statusCol;
333 width = pixNew->width() + 8;
334 if ( *col == header()->mapToIndex( *col ) )
338 case KPaintInfo::COL_SIGNED:
340 show = &mPaintInfo.showSigned;
341 col = &mPaintInfo.signedCol;
342 width = pixFullySigned->width() + 8;
343 if ( *col == header()->mapToIndex( *col ) )
347 case KPaintInfo::COL_CRYPTO:
349 show = &mPaintInfo.showCrypto;
350 col = &mPaintInfo.cryptoCol;
351 width = pixFullyEncrypted->width() + 8;
352 if ( *col == header()->mapToIndex( *col ) )
356 case KPaintInfo::COL_RECEIVER:
358 show = &mPaintInfo.showReceiver;
359 col = &mPaintInfo.receiverCol;
363 case KPaintInfo::COL_SCORE: ;
374 mPopup->setItemChecked(
id, *show);
377 header()->setResizeEnabled(
true, *col);
378 setColumnWidth(*col, width);
379 if ( moveToCol >= 0 )
380 header()->moveSection( *col, moveToCol );
383 header()->setResizeEnabled(
false, *col);
384 header()->setStretchEnabled(
false, *col);
390 if (
static_cast<KPaintInfo::ColumnIds
>(
id) == KPaintInfo::COL_RECEIVER ) {
391 TQString colText = i18n(
"Sender" );
392 if ( mFolder && (mFolder->whoField().lower() ==
"to") && !mPaintInfo.showReceiver)
393 colText = i18n(
"Receiver" );
394 setColumnText( mPaintInfo.senderCol, colText );
405 if (mPaintInfo.pixmapOn)
406 p->drawTiledPixmap( rect.left(), rect.top(), rect.width(), rect.height(),
408 rect.left() + contentsX(),
409 rect.top() + contentsY() );
411 p->fillRect( rect, colorGroup().base() );
416 bool result = TDEListView::event(e);
417 if (e->type() == TQEvent::ApplicationPaletteChange)
428 TDEConfig* config = KMKernel::config();
430 TDEConfigGroupSaver saver(config,
"Reader");
431 TQColor c1=TQColor(kapp->palette().active().text());
432 TQColor c2=TQColor(
"red");
433 TQColor c3=TQColor(
"blue");
434 TQColor c4=TQColor(kapp->palette().active().base());
435 TQColor c5=TQColor(0,0x7F,0);
436 TQColor c6=TQColor(0,0x98,0);
437 TQColor c7=TDEGlobalSettings::alternateBackgroundColor();
439 if (!config->readBoolEntry(
"defaultColors",
true)) {
440 mPaintInfo.colFore = config->readColorEntry(
"ForegroundColor",&c1);
441 mPaintInfo.colBack = config->readColorEntry(
"BackgroundColor",&c4);
442 TQPalette newPal = kapp->palette();
443 newPal.setColor( TQColorGroup::Base, mPaintInfo.colBack );
444 newPal.setColor( TQColorGroup::Text, mPaintInfo.colFore );
445 setPalette( newPal );
446 mPaintInfo.colNew = config->readColorEntry(
"NewMessage",&c2);
447 mPaintInfo.colUnread = config->readColorEntry(
"UnreadMessage",&c3);
448 mPaintInfo.colFlag = config->readColorEntry(
"FlagMessage",&c5);
449 mPaintInfo.colTodo = config->readColorEntry(
"TodoMessage",&c6);
450 c7 = config->readColorEntry(
"AltBackgroundColor",&c7);
453 mPaintInfo.colFore = c1;
454 mPaintInfo.colBack = c4;
455 TQPalette newPal = kapp->palette();
456 newPal.setColor( TQColorGroup::Base, c4 );
457 newPal.setColor( TQColorGroup::Text, c1 );
458 setPalette( newPal );
459 mPaintInfo.colNew = c2;
460 mPaintInfo.colUnread = c3;
461 mPaintInfo.colFlag = c5;
462 mPaintInfo.colTodo = c6;
464 setAlternateBackground(c7);
470 TDEConfig* config = KMKernel::config();
474 TDEConfigGroupSaver saver(config,
"Pixmaps");
475 TQString pixmapFile = config->readEntry(
"Headers");
476 mPaintInfo.pixmapOn =
false;
477 if (!pixmapFile.isEmpty()) {
478 mPaintInfo.pixmapOn =
true;
479 mPaintInfo.pixmap = TQPixmap( pixmapFile );
484 TDEConfigGroupSaver saver(config,
"General");
485 bool show = config->readBoolEntry(
"showMessageSize");
488 show = config->readBoolEntry(
"showAttachmentColumn");
491 show = config->readBoolEntry(
"showInvitationColumn");
494 show = config->readBoolEntry(
"showImportantColumn");
497 show = config->readBoolEntry(
"showTodoColumn");
500 show = config->readBoolEntry(
"showSpamHamColumn");
503 show = config->readBoolEntry(
"showWatchedIgnoredColumn");
506 show = config->readBoolEntry(
"showStatusColumn");
509 show = config->readBoolEntry(
"showSignedColumn");
512 show = config->readBoolEntry(
"showCryptoColumn");
515 show = config->readBoolEntry(
"showReceiverColumn");
518 mPaintInfo.showCryptoIcons = config->readBoolEntry(
"showCryptoIcons",
false );
519 mPaintInfo.showAttachmentIcon = config->readBoolEntry(
"showAttachmentIcon",
true );
520 mPaintInfo.showInvitationIcon = config->readBoolEntry(
"showInvitationIcon",
false );
522 KMime::DateFormatter::FormatType t =
523 (KMime::DateFormatter::FormatType) config->readNumEntry(
"dateFormat", KMime::DateFormatter::Fancy ) ;
524 mDate.setCustomFormat( config->readEntry(
"customDateFormat") );
525 mDate.setFormat( t );
532 TDEConfigGroupSaver saver(config,
"Fonts");
533 if (!(config->readBoolEntry(
"defaultFonts",
true)))
535 TQFont listFont( TDEGlobalSettings::generalFont() );
536 listFont = config->readFontEntry(
"list-font", &listFont );
538 mNewFont = config->readFontEntry(
"list-new-font", &listFont );
539 mUnreadFont = config->readFontEntry(
"list-unread-font", &listFont );
540 mImportantFont = config->readFontEntry(
"list-important-font", &listFont );
541 mTodoFont = config->readFontEntry(
"list-todo-font", &listFont );
542 mDateFont = TDEGlobalSettings::fixedFont();
543 mDateFont = config->readFontEntry(
"list-date-font", &mDateFont );
545 mNewFont= mUnreadFont = mImportantFont = mDateFont = mTodoFont =
546 TDEGlobalSettings::generalFont();
547 setFont( mDateFont );
553 TDEConfigGroupSaver saver(config,
"Geometry");
554 mReaderWindowActive = config->readEntry(
"readerWindowMode",
"below" ) !=
"hide";
564 mIgnoreSortOrderChanges =
true;
565 restoreLayout( config, group );
566 mIgnoreSortOrderChanges =
false;
576 TQString colText = i18n(
"Sender" );
577 if ( mFolder && (mFolder->whoField().lower() ==
"to") && !mPaintInfo.showReceiver)
578 colText = i18n(
"Receiver" );
579 setColumnText( mPaintInfo.senderCol, colText );
585 ensureCurrentItemVisible();
592 NestingPolicy oldNestPolicy = nestingPolicy;
593 TDEConfig* config = KMKernel::config();
594 TDEConfigGroupSaver saver(config,
"Geometry");
595 mNested = config->readBoolEntry(
"nestedMessages",
false );
597 nestingPolicy = (NestingPolicy)config->readNumEntry(
"nestingPolicy", OpenUnread );
598 if ((nestingPolicy != oldNestPolicy) ||
601 setRootIsDecorated( nestingPolicy != AlwaysOpen &&
isThreaded() );
610 if (!mFolder)
return;
611 TDEConfig* config = KMKernel::config();
613 TDEConfigGroupSaver saver(config,
"Folder-" + mFolder->idString());
614 mNestedOverride = config->readBoolEntry(
"threadMessagesOverride",
false );
615 mSortCol = config->readNumEntry(
"SortColumn", mSortCol+1 );
616 mSortDescending = (mSortCol < 0);
617 mSortCol = abs(mSortCol) - 1;
619 mTopItem = config->readNumEntry(
"Top", 0);
620 mCurrentItem = config->readNumEntry(
"Current", 0);
621 mCurrentItemSerNum = config->readNumEntry(
"CurrentSerialNum", 0);
623 mPaintInfo.orderOfArrival = config->readBoolEntry(
"OrderOfArrival",
false );
624 mPaintInfo.status = config->readBoolEntry(
"Status",
false );
627 TDEConfigGroupSaver saver(config,
"Geometry");
628 mNested = config->readBoolEntry(
"nestedMessages",
false );
629 nestingPolicy = (NestingPolicy)config->readNumEntry(
"nestingPolicy", OpenUnread );
632 setRootIsDecorated( nestingPolicy != AlwaysOpen &&
isThreaded() );
633 mSubjThreading = config->readBoolEntry(
"threadMessagesBySubject",
true );
640 if (!mFolder)
return;
641 TDEConfig* config = KMKernel::config();
642 int mSortColAdj = mSortCol + 1;
644 TDEConfigGroupSaver saver(config,
"Folder-" + mFolder->idString());
645 config->writeEntry(
"SortColumn", (mSortDescending ? -mSortColAdj : mSortColAdj));
650 if ( current && mFolder->getMsgBase( current->
msgId() ) )
651 sernum = mFolder->getMsgBase( current->
msgId() )->getMsgSerNum();
652 config->writeEntry(
"CurrentSerialNum", sernum);
654 config->writeEntry(
"OrderOfArrival", mPaintInfo.orderOfArrival);
655 config->writeEntry(
"Status", mPaintInfo.status);
661 TDEConfig* config = KMKernel::config();
662 saveLayout(config,
"Header-Geometry");
663 TDEConfigGroupSaver saver(config,
"General");
664 config->writeEntry(
"showMessageSize" , mPaintInfo.showSize);
665 config->writeEntry(
"showAttachmentColumn" , mPaintInfo.showAttachment);
666 config->writeEntry(
"showInvitationColumn" , mPaintInfo.showInvitation);
667 config->writeEntry(
"showImportantColumn" , mPaintInfo.showImportant);
668 config->writeEntry(
"showTodoColumn" , mPaintInfo.showTodo);
669 config->writeEntry(
"showSpamHamColumn" , mPaintInfo.showSpamHam);
670 config->writeEntry(
"showWatchedIgnoredColumn", mPaintInfo.showWatchedIgnored);
671 config->writeEntry(
"showStatusColumn" , mPaintInfo.showStatus);
672 config->writeEntry(
"showSignedColumn" , mPaintInfo.showSigned);
673 config->writeEntry(
"showCryptoColumn" , mPaintInfo.showCrypto);
674 config->writeEntry(
"showReceiverColumn" , mPaintInfo.showReceiver);
680 CREATE_TIMER(set_folder);
681 START_TIMER(set_folder);
686 mSortInfo.fakeSort = 0;
687 if ( mFolder &&
static_cast<KMFolder*
>(mFolder) == aFolder ) {
699 highlightMessage(0,
false);
701 disconnect(mFolder, TQ_SIGNAL(numUnreadMsgsChanged(
KMFolder*)),
704 mFolder->markNewAsUnread();
708 disconnect(mFolder, TQ_SIGNAL(
msgAdded(
int)),
710 disconnect(mFolder, TQ_SIGNAL(
msgRemoved(
int, TQString ) ),
711 this, TQ_SLOT(
msgRemoved(
int, TQString ) ) );
712 disconnect(mFolder, TQ_SIGNAL(changed()),
714 disconnect(mFolder, TQ_SIGNAL(cleared()),
716 disconnect(mFolder, TQ_SIGNAL(expunged(
KMFolder* )),
718 disconnect(mFolder, TQ_SIGNAL(closed()),
720 disconnect( mFolder, TQ_SIGNAL( statusMsg(
const TQString& ) ),
721 BroadcastStatus::instance(), TQ_SLOT( setStatusMsg(
const TQString& ) ) );
722 disconnect(mFolder, TQ_SIGNAL(viewConfigChanged()),
this, TQ_SLOT(
reset()));
724 mFolder->close(
"kmheaders");
727 if (mFolder->dirty()) mFolder->writeIndex();
730 mSortInfo.removed = 0;
732 mSortInfo.dirty =
true;
734 mOwner->useAction()->setEnabled( mFolder ?
735 ( kmkernel->folderIsTemplates( mFolder ) ) :
false );
736 mOwner->messageActions()->replyListAction()->setEnabled( mFolder ?
737 mFolder->isMailingListEnabled() :
false );
741 connect(mFolder, TQ_SIGNAL(
msgAdded(
int)),
743 connect(mFolder, TQ_SIGNAL(
msgRemoved(
int,TQString)),
745 connect(mFolder, TQ_SIGNAL(changed()),
747 connect(mFolder, TQ_SIGNAL(cleared()),
749 connect(mFolder, TQ_SIGNAL(expunged(
KMFolder* )),
751 connect(mFolder, TQ_SIGNAL(closed()),
753 connect(mFolder, TQ_SIGNAL(statusMsg(
const TQString&)),
754 BroadcastStatus::instance(), TQ_SLOT( setStatusMsg(
const TQString& ) ) );
755 connect(mFolder, TQ_SIGNAL(numUnreadMsgsChanged(
KMFolder*)),
757 connect(mFolder, TQ_SIGNAL(viewConfigChanged()),
this, TQ_SLOT(
reset()));
771 CREATE_TIMER(kmfolder_open);
772 START_TIMER(kmfolder_open);
773 mFolder->open(
"kmheaders");
774 END_TIMER(kmfolder_open);
775 SHOW_TIMER(kmfolder_open);
785 CREATE_TIMER(updateMsg);
786 START_TIMER(updateMsg);
787 updateMessageList(
true, forceJumpToUnread);
788 END_TIMER(updateMsg);
789 SHOW_TIMER(updateMsg);
793 TQString colText = i18n(
"Sender" );
794 if (mFolder && (mFolder->whoField().lower() ==
"to") && !mPaintInfo.showReceiver)
795 colText = i18n(
"Receiver");
796 setColumnText( mPaintInfo.senderCol, colText);
798 colText = i18n(
"Date" );
799 if (mPaintInfo.orderOfArrival)
800 colText = i18n(
"Order of Arrival" );
801 setColumnText( mPaintInfo.dateCol, colText);
803 colText = i18n(
"Subject" );
804 if (mPaintInfo.status)
805 colText = colText + i18n(
" (Status)" );
806 setColumnText( mPaintInfo.subCol, colText);
811 END_TIMER(set_folder);
812 SHOW_TIMER(set_folder);
818 if (mFolder->count() == 0) {
823 if (!isUpdatesEnabled())
return;
828 const bool scrollbarAtTop = verticalScrollBar() &&
829 verticalScrollBar()->value() == verticalScrollBar()->minValue();
830 const bool scrollbarAtBottom = verticalScrollBar() &&
831 verticalScrollBar()->value() == verticalScrollBar()->maxValue();
832 const HeaderItem *
const oldFirstVisibleItem =
dynamic_cast<HeaderItem*
>( itemAt( TQPoint( 0, 0 ) ) );
833 const int oldOffsetOfFirstVisibleItem = itemRect( oldFirstVisibleItem ).y();
834 const uint oldSerNumOfFirstVisibleItem = oldFirstVisibleItem ? oldFirstVisibleItem->msgSerNum() : 0;
837 TQListViewItem *item = currentItem();
841 KMMsgBase *mb = mFolder->getMsgBase(hi->
msgId());
843 msgIdMD5 = mb->msgIdMD5();
847 disconnect(
this,TQ_SIGNAL(currentChanged(TQListViewItem*)),
848 this,TQ_SLOT(highlightMessage(TQListViewItem*)));
855 if ( scrollbarAtTop ) {
856 setContentsPos( 0, 0 );
857 }
else if ( scrollbarAtBottom ) {
858 setContentsPos( 0, contentsHeight() );
859 }
else if ( oldSerNumOfFirstVisibleItem > 0 ) {
860 for ( uint i = 0; i < mItems.size(); ++i ) {
861 const KMMsgBase *
const mMsgBase = mFolder->getMsgBase( i );
862 if ( mMsgBase->getMsgSerNum() == oldSerNumOfFirstVisibleItem ) {
863 setContentsPos( 0, itemPos( mItems[i] ) - oldOffsetOfFirstVisibleItem );
869 connect(
this,TQ_SIGNAL(currentChanged(TQListViewItem*)),
870 this,TQ_SLOT(highlightMessage(TQListViewItem*)));
879 item = currentItem();
882 KMMsgBase *mb = mFolder->getMsgBase(hi->
msgId());
884 if (msgIdMD5.isEmpty() || (msgIdMD5 != mb->msgIdMD5()))
898 if (!isUpdatesEnabled())
return;
903 assert( mFolder->getMsgBase(
id ) );
910 if (mSortCacheItems.count() == (uint)mFolder->count()
911 || mSortCacheItems.count() == 0) {
912 kdDebug (5006) <<
"KMHeaders::msgAdded - Resizing id and subject trees of " << mFolder->label()
913 <<
": before=" << mSortCacheItems.count() <<
" ,after=" << (mFolder->count()*2) << endl;
914 mSortCacheItems.resize(mFolder->count()*2);
915 mSubjectLists.resize(mFolder->count()*2);
917 TQString msgId = mFolder->getMsgBase(
id)->msgIdMD5();
920 TQString replyToId = mFolder->getMsgBase(
id)->replyToIdMD5();
923 if (!parent && mSubjThreading) {
924 parent = findParentBySubject( sci );
930 if (msgId == mFolder->getMsgBase(parent->
item()->
msgId())->replyToIdMD5()
931 || msgId == mFolder->getMsgBase(parent->
item()->
msgId())->replyToAuxIdMD5())
936 if (parent && mFolder->getMsgBase(parent->id())->isWatched())
937 mFolder->getMsgBase(
id)->setStatus( KMMsgStatusWatched );
938 else if (parent && mFolder->getMsgBase(parent->id())->isIgnored())
939 mFolder->getMsgBase(
id)->setStatus( KMMsgStatusIgnored );
950 mItems.resize( mFolder->count() );
953 if ( !msgId.isEmpty() )
954 mSortCacheItems.replace(msgId, sci);
957 if (mSubjThreading && parent) {
958 TQString subjMD5 = mFolder->getMsgBase(
id)->strippedSubjectMD5();
959 if (subjMD5.isEmpty()) {
960 mFolder->getMsgBase(
id)->initStrippedSubjectMD5();
961 subjMD5 = mFolder->getMsgBase(
id)->strippedSubjectMD5();
963 if( !subjMD5.isEmpty()) {
964 if ( !mSubjectLists.find(subjMD5) )
965 mSubjectLists.insert(subjMD5,
new TQPtrList<SortCacheItem>());
968 for (TQPtrListIterator<SortCacheItem> it(*mSubjectLists[subjMD5]);
969 it.current(); ++it) {
970 KMMsgBase *mb = mFolder->getMsgBase((*it)->id());
971 if ( mb->date() < mFolder->getMsgBase(
id)->date())
975 mSubjectLists[subjMD5]->insert( p, sci);
985 disconnect(
this, TQ_SIGNAL(currentChanged(TQListViewItem*)),
986 this, TQ_SLOT(highlightMessage(TQListViewItem*)));
988 if ( !msgId.isEmpty() ) {
989 TQPtrListIterator<HeaderItem> it(mImperfectlyThreadedList);
991 while ( (cur = it.current()) ) {
993 int tryMe = cur->
msgId();
997 bool perfectParent =
true;
998 KMMsgBase *otherMsg = mFolder->getMsgBase(tryMe);
1000 kdDebug(5006) <<
"otherMsg is NULL !!! tryMe: " << tryMe << endl;
1003 TQString otherId = otherMsg->replyToIdMD5();
1004 if (msgId != otherId) {
1005 if (msgId != otherMsg->replyToAuxIdMD5())
1008 if (!otherId.isEmpty() && mSortCacheItems.find(otherId))
1013 perfectParent =
false;
1016 TQListViewItem *newParent = mItems[id];
1017 TQListViewItem *msg = mItems[tryMe];
1020 msg->parent()->takeItem(msg);
1023 newParent->insertItem(msg);
1029 if (perfectParent) {
1030 mImperfectlyThreadedList.removeRef (mItems[tryMe]);
1033 TQString sortFile = KMAIL_SORT_FILE(mFolder);
1034 FILE *sortStream = fopen(TQFile::encodeName(sortFile),
"r+");
1036 mItems[tryMe]->sortCacheItem()->updateSortFile( sortStream, mFolder );
1037 fclose (sortStream);
1044 mImperfectlyThreadedList.append(hi);
1048 mItems.resize( mFolder->count() );
1054 if (mSortInfo.fakeSort) {
1055 TQObject::disconnect(header(), TQ_SIGNAL(clicked(
int)),
this, TQ_SLOT(
dirtySortOrder(
int)));
1056 TDEListView::setSorting(mSortCol, !mSortDescending );
1057 mSortInfo.fakeSort = 0;
1059 appendItemToSortFile(hi);
1063 if ((childCount() == 1) && hi) {
1065 setCurrentItem( firstChild() );
1066 setSelectionAnchor( currentItem() );
1067 highlightMessage( currentItem() );
1071 connect(
this, TQ_SIGNAL(currentChanged(TQListViewItem*)),
1072 this, TQ_SLOT(highlightMessage(TQListViewItem*)));
1083 if (!isUpdatesEnabled())
return;
1085 if ((
id < 0) || (
id >= (
int)mItems.size()))
1092 disconnect(
this, TQ_SIGNAL(currentChanged(TQListViewItem*)),
1093 this, TQ_SLOT(highlightMessage(TQListViewItem*)));
1096 if (!removedItem)
return;
1099 for (
int i =
id; i < (int)mItems.size() - 1; ++i) {
1100 mItems[i] = mItems[i+1];
1101 mItems[i]->setMsgId( i );
1102 mItems[i]->sortCacheItem()->setId( i );
1105 mItems.resize( mItems.size() - 1 );
1108 if ( !msgId.isEmpty() && mSortCacheItems[msgId] ) {
1110 mSortCacheItems.remove(msgId);
1118 TQListViewItem *myParent = removedItem;
1119 TQListViewItem *myChild = myParent->firstChild();
1120 TQListViewItem *threadRoot = myParent;
1121 while (threadRoot->parent())
1122 threadRoot = threadRoot->parent();
1123 TQString key =
static_cast<HeaderItem*
>(threadRoot)->key(mSortCol, !mSortDescending);
1125 TQPtrList<TQListViewItem> childList;
1130 childList.append(myChild);
1132 myChild = myChild->nextSibling();
1134 myParent->takeItem( item );
1138 item->setTempKey( key + item->key( mSortCol, !mSortDescending ));
1139 if (mSortInfo.fakeSort) {
1140 TQObject::disconnect(header(), TQ_SIGNAL(clicked(
int)),
this, TQ_SLOT(
dirtySortOrder(
int)));
1141 TDEListView::setSorting(mSortCol, !mSortDescending );
1142 mSortInfo.fakeSort = 0;
1146 for (TQPtrListIterator<TQListViewItem> it(childList); it.current() ; ++it ) {
1147 TQListViewItem *lvi = *it;
1151 if ( !parent && mSubjThreading )
1152 parent = findParentBySubject( sci );
1154 Q_ASSERT( !parent || parent->
item() != removedItem );
1155 myParent->takeItem(lvi);
1156 if ( parent && parent->
item() != item && parent->
item() != removedItem ) {
1157 parent->
item()->insertItem(lvi);
1165 && !mImperfectlyThreadedList.containsRef(item))
1166 mImperfectlyThreadedList.append(item);
1169 && mImperfectlyThreadedList.containsRef(item))
1170 mImperfectlyThreadedList.removeRef(item);
1174 if (!mFolder->count())
1177 mImperfectlyThreadedList.removeRef( removedItem );
1180 while ( mImperfectlyThreadedList.findRef( removedItem ) != -1 ) {
1181 mImperfectlyThreadedList.remove();
1182 kdDebug(5006) <<
"Remove doubled item from mImperfectlyThreadedList: " << removedItem << endl;
1188 if ( curItem != removedItem ) {
1189 setCurrentItem( curItem );
1190 setSelectionAnchor( currentItem() );
1198 int contentX, contentY;
1199 HeaderItem *nextItem = prepareMove( &contentX, &contentY );
1200 finalizeMove( nextItem, contentX, contentY );
1204 connect(
this, TQ_SIGNAL(currentChanged(TQListViewItem*)),
1205 this, TQ_SLOT(highlightMessage(TQListViewItem*)));
1212 if (msgId<0 || msgId >= (
int)mItems.size() || !isUpdatesEnabled())
return;
1226 if (serNums.empty())
1229 KMCommand *command =
new KMSeStatusCommand( status, serNums, toggle );
1236 if (!mFolder)
return TQPtrList<TQListViewItem>();
1239 TQListViewItem *curItem = currentItem();
1240 if (!curItem)
return TQPtrList<TQListViewItem>();
1243 TQListViewItem *topOfThread = curItem;
1244 while ( topOfThread->parent() )
1245 topOfThread = topOfThread->parent();
1248 TQPtrList<TQListViewItem> list;
1249 TQListViewItem *topOfNextThread = topOfThread->nextSibling();
1250 for ( TQListViewItemIterator it( topOfThread ) ;
1251 it.current() && it.current() != topOfNextThread ; ++it )
1252 list.append( it.current() );
1258 TQPtrList<TQListViewItem> curThread;
1261 TQPtrList<TQListViewItem> topOfThreads;
1264 for (TQListViewItem *item = firstChild(); item; item = item->itemBelow())
1265 if (item->isSelected() ) {
1267 TQListViewItem *top = item;
1268 while ( top->parent() )
1269 top = top->parent();
1270 if (!topOfThreads.contains(top)) {
1271 topOfThreads.append(top);
1276 for ( TQPtrListIterator<TQListViewItem> it( topOfThreads ) ;
1277 it.current() ; ++ it ) {
1278 TQListViewItem *top = *it;
1281 TQListViewItem *topOfNextThread = top->nextSibling();
1282 for ( TQListViewItemIterator it( top ) ;
1283 it.current() && it.current() != topOfNextThread ; ++it )
1284 curThread.append( it.current() );
1288 TQPtrListIterator<TQListViewItem> it( curThread );
1291 for ( it.toFirst() ; it.current() ; ++it ) {
1293 KMMsgBase *msgBase = mFolder->getMsgBase(
id );
1294 serNums.append( msgBase->getMsgSerNum() );
1297 if (serNums.empty())
1300 KMCommand *command =
new KMSeStatusCommand( status, serNums, toggle );
1307 if ( !msg )
return 2;
1309 int filterResult = kmkernel->filterMgr()->process(msg,KMFilterMgr::Explicit);
1310 if (filterResult == 2) {
1312 kmkernel->emergencyExit( i18n(
"Unable to process messages: " ) + TQString::fromLocal8Bit(strerror(errno)));
1315 if (msg->parent()) {
1319 assert( p == msg->parent() ); assert( idx >= 0 );
1323 return filterResult;
1331 TQListViewItem *item = currentItem();
1332 if ( !item )
return;
1334 item->setSelected(
true );
1335 while ( item->parent() )
1336 item = item->parent();
1341 ensureItemVisible( currentItem() );
1348 TQListViewItem * item = currentItem();
1351 item->setSelected(
true );
1354 for ( TQListViewItem *item = firstChild() ;
1355 item ; item = item->nextSibling() )
1356 static_cast<HeaderItem*
>(item)->setOpenRecursive( expand );
1358 TQListViewItem * item = currentItem();
1360 while ( item->parent() )
1361 item = item->parent();
1365 ensureItemVisible( currentItem() );
1373 if( style().isA(
"KeramikStyle") )
1374 frameWidth = style().pixelMetric( TQStyle::PM_DefaultFrameWidth ) - 1;
1376 frameWidth = style().pixelMetric( TQStyle::PM_DefaultFrameWidth );
1377 if ( frameWidth < 0 )
1379 if ( frameWidth != lineWidth() )
1380 setLineWidth( frameWidth );
1387 TDEListView::styleChange( oldStyle );
1393 if ( !mFolder )
return;
1395 const int unread = mFolder->countUnread();
1396 if (
static_cast<KMFolder*
>(mFolder) == kmkernel->outboxFolder() )
1397 str = unread ? i18n(
"1 unsent",
"%n unsent", unread ) : i18n(
"0 unsent" );
1399 str = unread ? i18n(
"1 unread",
"%n unread", unread ) : i18n(
"0 unread" );
1400 const int count = mFolder->count();
1401 str = count ? i18n(
"1 message, %1.",
"%n messages, %1.", count ).arg( str )
1402 : i18n(
"0 messages" );
1403 if ( mFolder->isReadOnly() )
1404 str = i18n(
"%1 = n messages, m unread.",
"%1 Folder is read-only.").arg( str );
1405 BroadcastStatus::instance()->setStatusMsg(str);
1409 void KMHeaders::applyFiltersOnMsg()
1411 if (ActionScheduler::isEnabled() ||
1412 kmkernel->filterMgr()->atLeastOneOnlineImapFolderTarget()) {
1414 KMFilterMgr::FilterSet set = KMFilterMgr::Explicit;
1415 TQValueList<KMFilter*> filters = kmkernel->filterMgr()->filters();
1416 ActionScheduler *scheduler =
new ActionScheduler( set, filters,
this );
1417 scheduler->setAutoDestruct(
true );
1419 int contentX, contentY;
1420 HeaderItem *nextItem = prepareMove( &contentX, &contentY );
1422 finalizeMove( nextItem, contentX, contentY );
1424 for (KMMsgBase *msg = msgList.first(); msg; msg = msgList.next())
1425 scheduler->execFilters( msg );
1427 int contentX, contentY;
1428 HeaderItem *nextItem = prepareMove( &contentX, &contentY );
1432 if ( serNums.isEmpty() )
1435 finalizeMove( nextItem, contentX, contentY );
1436 CREATE_TIMER(filter);
1437 START_TIMER(filter);
1441 int msgCountToFilter = serNums.count();
1442 ProgressItem* progressItem =
1443 ProgressManager::createProgressItem(
"filter"+ProgressManager::getUniqueID(),
1444 i18n(
"Filtering messages" ) );
1445 progressItem->setTotalItems( msgCountToFilter );
1447 for ( TQValueList<unsigned long>::ConstIterator it = serNums.constBegin();
1448 it != serNums.constEnd(); ++it ) {
1450 if ( msgCountToFilter - msgCount < 10 || !( msgCount % 20 ) || msgCount <= 10 ) {
1451 progressItem->updateProgress();
1452 TQString statusMsg = i18n(
"Filtering message %1 of %2");
1453 statusMsg = statusMsg.arg( msgCount ).arg( msgCountToFilter );
1454 KPIM::BroadcastStatus::instance()->setStatusMsg( statusMsg );
1455 TDEApplication::kApplication()->eventLoop()->processEvents( TQEventLoop::ExcludeUserInput, 50 );
1469 FolderJob *job = mFolder->createJob(msg);
1470 connect(job, TQ_SIGNAL(messageRetrieved(
KMMessage*)),
1478 kdDebug (5006) <<
"####### KMHeaders::applyFiltersOnMsg -"
1479 " A message went missing during filtering " << endl;
1481 progressItem->incCompletedItems();
1483 progressItem->setComplete();
1492 void KMHeaders::setMsgRead (
int msgId)
1494 KMMsgBase *msgBase = mFolder->getMsgBase( msgId );
1499 if (msgBase->isNew() || msgBase->isUnread()) {
1500 serNums.append( msgBase->getMsgSerNum() );
1503 KMCommand *command =
new KMSeStatusCommand( KMMsgStatusRead, serNums );
1509 void KMHeaders::deleteMsg ()
1515 int contentX, contentY;
1516 HeaderItem *nextItem = prepareMove( &contentX, &contentY );
1518 finalizeMove( nextItem, contentX, contentY );
1520 KMCommand *command =
new KMDeleteMsgCommand( mFolder, msgList );
1521 connect( command, TQ_SIGNAL( completed( KMCommand * ) ),
1522 this, TQ_SLOT( slotMoveCompleted( KMCommand * ) ) );
1525 BroadcastStatus::instance()->setStatusMsg(
"");
1533 if (mMenuToFolder[menuId])
1538 HeaderItem* KMHeaders::prepareMove(
int *contentX,
int *contentY )
1543 disconnect(
this, TQ_SIGNAL(currentChanged(TQListViewItem*)),
1544 this, TQ_SLOT(highlightMessage(TQListViewItem*)));
1546 TQListViewItem *curItem;
1548 curItem = currentItem();
1549 while (curItem && curItem->isSelected() && curItem->itemBelow())
1550 curItem = curItem->itemBelow();
1551 while (curItem && curItem->isSelected() && curItem->itemAbove())
1552 curItem = curItem->itemAbove();
1555 *contentX = contentsX();
1556 *contentY = contentsY();
1558 if (item && !item->isSelected())
1565 void KMHeaders::finalizeMove(
HeaderItem *item,
int contentX,
int contentY )
1571 setCurrentItem( item );
1573 setSelectionAnchor( currentItem() );
1575 highlightMessage( item,
false);
1578 setContentsPos( contentX, contentY );
1580 connect(
this, TQ_SIGNAL(currentChanged(TQListViewItem*)),
1581 this, TQ_SLOT(highlightMessage(TQListViewItem*)));
1588 if ( destFolder == mFolder )
return;
1589 if ( mFolder->isReadOnly() )
return;
1592 if ( msgList.isEmpty() )
return;
1593 if ( !destFolder && askForConfirmation &&
1594 KMessageBox::warningContinueCancel(
this,
1595 i18n(
"<qt>Do you really want to delete the selected message?<br>"
1596 "Once deleted, it cannot be restored.</qt>",
1597 "<qt>Do you really want to delete the %n selected messages?<br>"
1598 "Once deleted, they cannot be restored.</qt>", msgList.count() ),
1599 msgList.count()>1 ? i18n(
"Delete Messages") : i18n(
"Delete Message"), KStdGuiItem::del(),
1600 "NoConfirmDelete") == KMessageBox::Cancel )
1604 int contentX, contentY;
1605 HeaderItem *nextItem = prepareMove( &contentX, &contentY );
1607 finalizeMove( nextItem, contentX, contentY );
1609 KMCommand *command =
new KMMoveCommand( destFolder, msgList );
1610 connect( command, TQ_SIGNAL( completed( KMCommand * ) ),
1611 this, TQ_SLOT( slotMoveCompleted( KMCommand * ) ) );
1615 void KMHeaders::slotMoveCompleted( KMCommand *command )
1617 kdDebug(5006) << k_funcinfo << command->result() << endl;
1618 bool deleted =
static_cast<KMMoveCommand *
>( command )->destFolder() == 0;
1619 if ( command->result() == KMCommand::OK ) {
1622 BroadcastStatus::instance()->setStatusMsg(
1623 deleted ? i18n(
"Messages deleted successfully.") : i18n(
"Messages moved successfully") );
1631 for (TQListViewItemIterator it(
this); it.current(); it++) {
1635 item->setSelectable (
true );
1636 KMMsgBase *msgBase = mFolder->getMsgBase(item->
msgId());
1637 if ( msgBase->isMessage() ) {
1644 if ( command->result() == KMCommand::Failed )
1645 BroadcastStatus::instance()->setStatusMsg(
1646 deleted ? i18n(
"Deleting messages failed.") : i18n(
"Moving messages failed.") );
1648 BroadcastStatus::instance()->setStatusMsg(
1649 deleted ? i18n(
"Deleting messages canceled.") : i18n(
"Moving messages canceled.") );
1651 mOwner->updateMessageActions();
1654 bool KMHeaders::canUndo()
const
1656 return ( kmkernel->undoStack()->size() > 0 );
1660 void KMHeaders::undo()
1662 kmkernel->undoStack()->undo();
1668 if (mMenuToFolder[menuId])
1679 KMCommand * command = 0;
1681 command =
new KMCopyCommand( destFolder, aMsg );
1684 command =
new KMCopyCommand( destFolder, msgList );
1694 if (!mFolder)
return;
1695 if (cur >= mFolder->count()) cur = mFolder->count() - 1;
1696 if ((cur >= 0) && (cur < (
int)mItems.size())) {
1698 setCurrentItem( mItems[cur] );
1700 setSelectionAnchor( currentItem() );
1712 if ( item->isVisible() )
1713 TDEListView::setSelected( item,
selected );
1717 if (
isThreaded() && !item->isOpen() && item->firstChild() ) {
1718 TQListViewItem *nextRoot = item->itemBelow();
1719 TQListViewItemIterator it( item->firstChild() );
1720 for( ; (*it) != nextRoot; ++it ) {
1721 if ( (*it)->isVisible() )
1729 for ( TQValueList<int>::Iterator it = items.begin(); it != items.end(); ++it )
1731 if ( ((*it) >= 0) && ((*it) < (
int)mItems.size()) )
1741 for (TQListViewItemIterator it(
this); it.current(); it++) {
1744 KMMsgBase *msgBase = mFolder->getMsgBase( item->
msgId() );
1745 if ( serNum == msgBase->getMsgSerNum() ) {
1747 item->setSelectable (
true );
1757 mSelMsgBaseList.clear();
1758 for (TQListViewItemIterator it(
this); it.current(); it++) {
1759 if ( it.current()->isSelected() && it.current()->isVisible() ) {
1765 item->setSelectable (
false );
1767 KMMsgBase *msgBase = mFolder->getMsgBase(item->
msgId());
1768 mSelMsgBaseList.append(msgBase);
1772 return &mSelMsgBaseList;
1778 TQValueList<int> items;
1779 for ( TQListViewItemIterator it(
this); it.current(); it++ )
1781 if ( it.current()->isSelected() && it.current()->isVisible() )
1784 items.append( item->
msgId() );
1793 int selectedMsg = -1;
1794 TQListViewItem *item;
1795 for (item = firstChild(); item; item = item->itemBelow())
1796 if (item->isSelected()) {
1806 TQListViewItem *lvi = currentItem();
1807 if (lvi && lvi->itemBelow()) {
1811 setSelectionAnchor( currentItem() );
1812 ensureCurrentItemVisible();
1819 if ( cm && cm->isBeingParsed() )
1821 TQListViewItem *lvi = currentItem();
1823 TQListViewItem *below = lvi->itemBelow();
1824 TQListViewItem *temp = lvi;
1825 if (lvi && below ) {
1828 temp = temp->parent();
1833 setCurrentItem(below);
1843 TQListViewItem *lvi = currentItem();
1844 if (lvi && lvi->itemAbove()) {
1848 setSelectionAnchor( currentItem() );
1849 ensureCurrentItemVisible();
1856 if ( cm && cm->isBeingParsed() )
1858 TQListViewItem *lvi = currentItem();
1860 TQListViewItem *above = lvi->itemAbove();
1861 TQListViewItem *temp = lvi;
1866 temp = temp->parent();
1871 setCurrentItem(above);
1882 if ( cm && cm->isBeingParsed() )
1884 TQListViewItem *lvi = currentItem();
1885 if ( lvi && lvi->itemBelow() ) {
1887 disconnect(
this,TQ_SIGNAL(currentChanged(TQListViewItem*)),
1888 this,TQ_SLOT(highlightMessage(TQListViewItem*)));
1889 setCurrentItem( lvi->itemBelow() );
1890 ensureCurrentItemVisible();
1892 connect(
this,TQ_SIGNAL(currentChanged(TQListViewItem*)),
1893 this,TQ_SLOT(highlightMessage(TQListViewItem*)));
1900 if ( cm && cm->isBeingParsed() )
1902 TQListViewItem *lvi = currentItem();
1903 if ( lvi && lvi->itemAbove() ) {
1904 disconnect(
this,TQ_SIGNAL(currentChanged(TQListViewItem*)),
1905 this,TQ_SLOT(highlightMessage(TQListViewItem*)));
1906 setCurrentItem( lvi->itemAbove() );
1907 ensureCurrentItemVisible();
1909 connect(
this,TQ_SIGNAL(currentChanged(TQListViewItem*)),
1910 this,TQ_SLOT(highlightMessage(TQListViewItem*)));
1917 highlightMessage( currentItem() );
1922 bool & foundUnreadMessage,
1926 KMMsgBase* msgBase = 0;
1932 msgBase = mFolder->getMsgBase(item->
msgId());
1933 if (!msgBase)
continue;
1934 if (msgBase->isUnread() || msgBase->isNew())
1935 foundUnreadMessage =
true;
1937 if (!onlyNew && (msgBase->isUnread() || msgBase->isNew()))
break;
1938 if (onlyNew && msgBase->isNew())
break;
1939 item =
static_cast<HeaderItem*
>(item->itemBelow());
1945 msgBase = mFolder->getMsgBase(newItem->
msgId());
1946 if (!msgBase)
continue;
1947 if (msgBase->isUnread() || msgBase->isNew())
1948 foundUnreadMessage =
true;
1949 if ( ( !onlyNew && (msgBase->isUnread() || msgBase->isNew()) )
1950 || ( onlyNew && msgBase->isNew() ) )
1951 lastUnread = newItem;
1952 if (newItem == item)
break;
1953 newItem =
static_cast<HeaderItem*
>(newItem->itemBelow());
1963 bool foundUnreadMessage =
false;
1965 if (!mFolder)
return -1;
1966 if (mFolder->count() <= 0)
return -1;
1968 if ((aStartAt >= 0) && (aStartAt < (
int)mItems.size()))
1969 item = mItems[aStartAt];
1974 item =
static_cast<HeaderItem*
>(firstChild());
1976 item =
static_cast<HeaderItem*
>(lastChild());
1981 if ( !acceptCurrent ) {
1983 item =
static_cast<HeaderItem*
>(item->itemBelow());
1986 item =
static_cast<HeaderItem*
>(item->itemAbove());
1993 findUnreadAux( item, foundUnreadMessage, onlyNew, aDirNext );
2001 TQListViewItem *next = item;
2002 while (next->parent())
2003 next = next->parent();
2004 next =
static_cast<HeaderItem*
>(next)->firstChildNonConst();
2005 while (next && (next != item))
2006 if (
static_cast<HeaderItem*
>(next)->firstChildNonConst())
2007 next = next->firstChild();
2008 else if (next->nextSibling())
2009 next = next->nextSibling();
2011 while (next && (next != item)) {
2012 next = next->parent();
2015 if (next && next->nextSibling()) {
2016 next = next->nextSibling();
2025 findUnreadAux( item, foundUnreadMessage, onlyNew, aDirNext );
2027 return item->
msgId();
2031 int unread = mFolder->countUnread();
2032 if (((unread == 0) && foundUnreadMessage) ||
2033 ((unread > 0) && !foundUnreadMessage)) {
2034 mFolder->correctUnreadMsgsCount();
2042 if ( !mFolder || !mFolder->countUnread() )
return false;
2043 int i =
findUnread(
true, -1,
false, acceptCurrent);
2044 if ( i < 0 && GlobalSettings::self()->loopOnGotoUnread() !=
2045 GlobalSettings::EnumLoopOnGotoUnread::DontLoop )
2054 ensureCurrentItemVisible();
2058 void KMHeaders::ensureCurrentItemVisible()
2061 if ((i >= 0) && (i < (
int)mItems.size()))
2062 center( contentsX(), itemPos(mItems[i]), 0, 9.0 );
2068 if ( !mFolder || !mFolder->countUnread() )
return false;
2070 if ( i < 0 && GlobalSettings::self()->loopOnGotoUnread() !=
2071 GlobalSettings::EnumLoopOnGotoUnread::DontLoop )
2080 ensureCurrentItemVisible();
2101 ensureItemVisible( currentItem() );
2105 void KMHeaders::highlightMessage(TQListViewItem* lvi,
bool markitread)
2108 if (lvi && !lvi->isSelectable())
return;
2111 if (lvi != mPrevCurrent) {
2112 if (mPrevCurrent && mFolder)
2115 if (prevMsg && mReaderWindowActive)
2117 mFolder->ignoreJobsForMessage(prevMsg);
2119 mFolder->unGetMsg(mPrevCurrent->
msgId());
2122 mPrevCurrent = item;
2129 int idx = item->
msgId();
2131 if (mReaderWindowActive && !msg) {
2137 BroadcastStatus::instance()->setStatusMsg(
"");
2138 if (markitread && idx >= 0) setMsgRead(idx);
2139 mItems[idx]->irefresh();
2140 mItems[idx]->repaint();
2145 void KMHeaders::highlightCurrentThread()
2148 TQPtrListIterator<TQListViewItem> it( curThread );
2150 for ( it.toFirst() ; it.current() ; ++it ) {
2151 TQListViewItem *lvi = *it;
2152 lvi->setSelected(
true );
2161 TQTimer::singleShot( ( 60-TQTime::currentTime().second() ) * 1000,
2172 int idx = item->
msgId();
2185 void KMHeaders::updateMessageList(
bool set_selection,
bool forceJumpToUnread )
2192 TDEListView::setSorting( mSortCol, !mSortDescending );
2197 readSortOrder( set_selection, forceJumpToUnread );
2218 void KMHeaders::keyPressEvent( TQKeyEvent * e )
2220 bool cntrl = (e->state() & ControlButton );
2221 bool shft = (e->state() & ShiftButton );
2222 TQListViewItem *cur = currentItem();
2224 if (!e || !firstChild())
2229 setCurrentItem( firstChild() );
2230 setSelectionAnchor( currentItem() );
2235 if (cur->isSelectable() && e->ascii() ==
' ' ) {
2237 highlightMessage( cur,
false);
2243 disconnect(
this,TQ_SIGNAL(currentChanged(TQListViewItem*)),
2244 this,TQ_SLOT(highlightMessage(TQListViewItem*)));
2253 TDEListView::keyPressEvent( e );
2256 connect(
this,TQ_SIGNAL(currentChanged(TQListViewItem*)),
2257 this,TQ_SLOT(highlightMessage(TQListViewItem*)));
2268 if (!(lvi->isSelected())) {
2278 mPressPos = e->pos();
2279 TQListViewItem *lvi = itemAt( contentsToViewport( e->pos() ));
2280 bool wasSelected =
false;
2281 bool rootDecoClicked =
false;
2283 wasSelected = lvi->isSelected();
2285 ( mPressPos.x() <= header()->cellPos( header()->mapToActual( 0 ) ) +
2286 treeStepSize() * ( lvi->depth() + ( rootIsDecorated() ? 1 : 0 ) ) + itemMargin() )
2287 && ( mPressPos.x() >= header()->cellPos( header()->mapToActual( 0 ) ) );
2289 if ( rootDecoClicked ) {
2294 if ( !lvi->isOpen() && lvi->firstChild() ) {
2295 TQListViewItem *nextRoot = lvi->itemBelow();
2296 TQListViewItemIterator it( lvi->firstChild() );
2297 for( ; (*it) != nextRoot; ++it )
2298 (*it)->setSelected(
false );
2304 TDEListView::contentsMousePressEvent(e);
2308 if ( e->state() & ShiftButton ) {
2309 TQListViewItemIterator it(
this, TQListViewItemIterator::Invisible );
2310 while ( it.current() ) {
2311 it.current()->setSelected(
false );
2316 if ( rootDecoClicked ) {
2318 if ( lvi && !lvi->isOpen() && lvi->isSelected() )
2322 if ( lvi && !rootDecoClicked ) {
2323 if ( lvi != currentItem() )
2324 highlightMessage( lvi );
2329 if ( !( e->state() & ControlButton ) && !wasSelected )
2332 if ( e->state() & ControlButton )
2335 if ((e->button() == TQt::LeftButton) )
2336 mMousePressed =
true;
2340 if ( lvi && e->button() == TQt::LeftButton && !( e->state() & (ShiftButton | ControlButton | AltButton | MetaButton) ) ) {
2341 bool flagsToggleable = GlobalSettings::self()->allowLocalFlags() || !(mFolder ? mFolder->isReadOnly() :
true);
2342 int section = header()->sectionAt( e->pos().x() );
2344 KMMsgBase *msg = mFolder->getMsgBase(item->
msgId());
2345 if ( section == mPaintInfo.flagCol && flagsToggleable ) {
2347 }
else if ( section == mPaintInfo.importantCol && flagsToggleable ) {
2349 }
else if ( section == mPaintInfo.todoCol && flagsToggleable ) {
2351 }
else if ( section == mPaintInfo.watchedIgnoredCol && flagsToggleable ) {
2352 if ( msg->isWatched() || msg->isIgnored() )
2356 }
else if ( section == mPaintInfo.statusCol ) {
2357 if ( msg->isUnread() || msg->isNew() )
2366 void KMHeaders::contentsMouseReleaseEvent(TQMouseEvent* e)
2368 if (e->button() != TQt::RightButton)
2369 TDEListView::contentsMouseReleaseEvent(e);
2371 mMousePressed =
false;
2377 if (mMousePressed &&
2378 (e->pos() - mPressPos).manhattanLength() > TDEGlobalSettings::dndEventDelay()) {
2379 mMousePressed =
false;
2380 TQListViewItem *item = itemAt( contentsToViewport(mPressPos) );
2383 unsigned int count = 0;
2384 for( TQListViewItemIterator it(
this); it.current(); it++ )
2385 if( it.current()->isSelected() ) {
2387 KMMsgBase *msg = mFolder->getMsgBase(item->
msgId());
2390 MailSummary mailSummary( msg->getMsgSerNum(), msg->msgIdMD5(),
2391 msg->subject(), msg->fromStrip(),
2392 msg->toStrip(), msg->date() );
2393 mailList.append( mailSummary );
2396 MailListDrag *d =
new MailListDrag( mailList, viewport(),
new KMTextSource );
2401 pixmap = TQPixmap( DesktopIcon(
"message", TDEIcon::SizeSmall) );
2403 pixmap = TQPixmap( DesktopIcon(
"application-vnd.tde.tdemultiple", TDEIcon::SizeSmall) );
2406 if( !pixmap.isNull() ) {
2407 TQPoint hotspot( pixmap.width() / 2, pixmap.height() / 2 );
2408 d->setPixmap( pixmap, hotspot );
2410 if ( mFolder->isReadOnly() )
2418 void KMHeaders::highlightMessage(TQListViewItem* i)
2420 highlightMessage( i,
false );
2426 if (!topLevelWidget())
return;
2427 mOwner->updateMessageActions();
2430 TQListViewItem *item = itemAt( viewport()->mapFromGlobal( TQCursor::pos() ) );
2432 int section = header()->sectionAt( viewportToContents( viewport()->mapFromGlobal( TQCursor::pos() ) ).x() );
2433 if ( section == mPaintInfo.flagCol || section == mPaintInfo.importantCol
2434 || section == mPaintInfo.todoCol || section == mPaintInfo.statusCol ) {
2435 mOwner->statusMenu()->popup( TQCursor::pos() );
2438 if ( section == mPaintInfo.watchedIgnoredCol ) {
2439 mOwner->threadStatusMenu()->popup( TQCursor::pos() );
2444 TQPopupMenu *menu =
new TQPopupMenu(
this);
2446 mMenuToFolder.clear();
2448 mOwner->updateMessageMenu();
2450 bool out_folder = kmkernel->folderIsDraftOrOutbox( mFolder );
2451 bool tem_folder = kmkernel->folderIsTemplates( mFolder );
2453 mOwner->useAction()->plug( menu );
2456 mOwner->messageActions()->replyMenu()->plug( menu );
2457 mOwner->forwardMenu()->plug( menu );
2458 if( mOwner->sendAgainAction()->isEnabled() ) {
2459 mOwner->sendAgainAction()->plug( menu );
2461 mOwner->editAction()->plug( menu );
2464 menu->insertSeparator();
2466 TQPopupMenu *msgCopyMenu =
new TQPopupMenu(menu);
2467 mOwner->folderTree()->folderToPopupMenu( KMFolderTree::CopyMessage,
this,
2468 &mMenuToFolder, msgCopyMenu );
2469 menu->insertItem(i18n(
"&Copy To"), msgCopyMenu);
2471 if ( !mFolder->canDeleteMessages() ) {
2472 int id = menu->insertItem( i18n(
"&Move To") );
2473 menu->setItemEnabled(
id,
false );
2475 TQPopupMenu *msgMoveMenu =
new TQPopupMenu(menu);
2476 mOwner->folderTree()->folderToPopupMenu( KMFolderTree::MoveMessage,
this,
2477 &mMenuToFolder, msgMoveMenu );
2478 menu->insertItem(i18n(
"&Move To"), msgMoveMenu);
2480 menu->insertSeparator();
2481 mOwner->statusMenu()->plug( menu );
2482 if ( mOwner->threadStatusMenu()->isEnabled() ) {
2483 mOwner->threadStatusMenu()->plug( menu );
2486 if ( !out_folder && !tem_folder ) {
2487 menu->insertSeparator();
2488 mOwner->filterMenu()->plug( menu );
2489 mOwner->action(
"apply_filter_actions" )->plug( menu );
2492 menu->insertSeparator();
2493 mOwner->printAction()->plug(menu);
2494 mOwner->saveAsAction()->plug(menu);
2495 mOwner->saveAttachmentsAction()->plug(menu);
2496 menu->insertSeparator();
2497 if ( mFolder->isTrash() ) {
2498 mOwner->deleteAction()->plug(menu);
2499 if ( mOwner->trashThreadAction()->isEnabled() )
2500 mOwner->deleteThreadAction()->plug(menu);
2502 mOwner->trashAction()->plug(menu);
2503 if ( mOwner->trashThreadAction()->isEnabled() )
2504 mOwner->trashThreadAction()->plug(menu);
2506 menu->insertSeparator();
2507 mOwner->messageActions()->createTodoAction()->plug( menu );
2509 TDEAcceleratorManager::manage(menu);
2510 kmkernel->setContextMenuShown(
true );
2511 menu->exec(TQCursor::pos(), 0);
2512 kmkernel->setContextMenuShown(
false );
2523 return mFolder->getMsg(hi->
msgId());
2529 return static_cast<HeaderItem*
>(currentItem());
2537 return item->
msgId();
2545 if (!mFolder->isOpened())
setFolder(mFolder);
2547 if ((msgIdx >= 0) && (msgIdx < (
int)mItems.size())) {
2549 bool unchanged = (currentItem() == mItems[msgIdx]);
2550 setCurrentItem( mItems[msgIdx] );
2552 setSelectionAnchor( currentItem() );
2554 highlightMessage( mItems[msgIdx],
false);
2564 return item->
msgId();
2572 if ( aMsgIdx < 0 ||
static_cast<unsigned int>( aMsgIdx ) >= mItems.size() )
2574 const TQListViewItem *
const item = mItems[aMsgIdx];
2576 setContentsPos( 0, itemPos( item ) );
2580 void KMHeaders::setNestedOverride(
bool override )
2582 mSortInfo.dirty =
true;
2583 mNestedOverride =
override;
2584 setRootIsDecorated( nestingPolicy != AlwaysOpen
2586 TQString sortFile = mFolder->indexLocation() +
".sorted";
2587 unlink(TQFile::encodeName(sortFile));
2592 void KMHeaders::setSubjectThreading(
bool aSubjThreading )
2594 mSortInfo.dirty =
true;
2595 mSubjThreading = aSubjThreading;
2596 TQString sortFile = mFolder->indexLocation() +
".sorted";
2597 unlink(TQFile::encodeName(sortFile));
2604 if ((nestingPolicy != AlwaysOpen)|| open)
2605 ((
HeaderItem*)item)->setOpenRecursive( open );
2612 return mFolder->getMsgBase( hi->
msgId() );
2618 if ( mIgnoreSortOrderChanges )
2625 if(mSortInfo.dirty || column != mSortInfo.column || ascending != mSortInfo.ascending) {
2626 TQObject::disconnect(header(), TQ_SIGNAL(clicked(
int)),
this, TQ_SLOT(
dirtySortOrder(
int)));
2627 mSortInfo.dirty =
true;
2630 assert(column >= 0);
2632 mSortDescending = !ascending;
2634 if (!ascending && (column == mPaintInfo.dateCol))
2635 mPaintInfo.orderOfArrival = !mPaintInfo.orderOfArrival;
2637 if (!ascending && (column == mPaintInfo.subCol))
2638 mPaintInfo.status = !mPaintInfo.status;
2640 TQString colText = i18n(
"Date" );
2641 if (mPaintInfo.orderOfArrival)
2642 colText = i18n(
"Order of Arrival" );
2643 setColumnText( mPaintInfo.dateCol, colText);
2645 colText = i18n(
"Subject" );
2646 if (mPaintInfo.status)
2647 colText = colText + i18n(
" (Status)" );
2648 setColumnText( mPaintInfo.subCol, colText);
2650 TDEListView::setSorting( column, ascending );
2651 ensureCurrentItemVisible();
2661 static void internalWriteItem(FILE *sortStream,
KMFolder *folder,
int msgid,
2662 int parent_id, TQString key,
2663 bool update_discover=
true)
2665 unsigned long msgSerNum;
2666 unsigned long parentSerNum;
2671 parentSerNum = (
unsigned long)(parent_id + KMAIL_RESERVED);
2673 fwrite(&msgSerNum,
sizeof(msgSerNum), 1, sortStream);
2674 fwrite(&parentSerNum,
sizeof(parentSerNum), 1, sortStream);
2675 TQ_INT32 len = key.length() *
sizeof(TQChar);
2676 fwrite(&len,
sizeof(len), 1, sortStream);
2678 fwrite(key.unicode(), TQMIN(len, KMAIL_MAX_KEY_LEN), 1, sortStream);
2680 if (update_discover) {
2682 TQ_INT32 discovered_count = 0;
2683 fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 20, SEEK_SET);
2684 fread(&discovered_count,
sizeof(discovered_count), 1, sortStream);
2686 fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 20, SEEK_SET);
2687 fwrite(&discovered_count,
sizeof(discovered_count), 1, sortStream);
2693 mSortCacheItems.clear();
2694 mSubjectLists.clear();
2695 mImperfectlyThreadedList.clear();
2703 if ( mFolder->open(
"kmheaders" ) == 0 )
2704 updateMessageList();
2709 bool KMHeaders::writeSortOrder()
2711 TQString sortFile = KMAIL_SORT_FILE(mFolder);
2713 if (!mSortInfo.dirty) {
2714 struct stat stat_tmp;
2715 if(stat(TQFile::encodeName(sortFile), &stat_tmp) == -1) {
2716 mSortInfo.dirty =
true;
2719 if (mSortInfo.dirty) {
2720 if (!mFolder->count()) {
2722 unlink(TQFile::encodeName(sortFile));
2725 TQString tempName = sortFile +
".temp";
2726 unlink(TQFile::encodeName(tempName));
2727 FILE *sortStream = fopen(TQFile::encodeName(tempName),
"w");
2731 mSortInfo.ascending = !mSortDescending;
2732 mSortInfo.dirty =
false;
2733 mSortInfo.column = mSortCol;
2734 fprintf(sortStream, KMAIL_SORT_HEADER, KMAIL_SORT_VERSION);
2736 TQ_INT32 byteOrder = 0x12345678;
2737 TQ_INT32 column = mSortCol;
2738 TQ_INT32 ascending= !mSortDescending;
2740 TQ_INT32 appended=0;
2741 TQ_INT32 discovered_count = 0;
2742 TQ_INT32 sorted_count=0;
2743 fwrite(&byteOrder,
sizeof(byteOrder), 1, sortStream);
2744 fwrite(&column,
sizeof(column), 1, sortStream);
2745 fwrite(&ascending,
sizeof(ascending), 1, sortStream);
2746 fwrite(&threaded,
sizeof(threaded), 1, sortStream);
2747 fwrite(&appended,
sizeof(appended), 1, sortStream);
2748 fwrite(&discovered_count,
sizeof(discovered_count), 1, sortStream);
2749 fwrite(&sorted_count,
sizeof(sorted_count), 1, sortStream);
2751 TQPtrStack<HeaderItem> items;
2753 TQPtrStack<TQListViewItem> s;
2754 for (TQListViewItem * i = firstChild(); i; ) {
2756 if ( i->firstChild() ) {
2758 i = i->firstChild();
2759 }
else if( i->nextSibling()) {
2760 i = i->nextSibling();
2762 for(i=0; !i && s.count(); i = s.pop()->nextSibling())
2772 kmb = mFolder->getMsgBase( i->
msgId() );
2776 TQString replymd5 = kmb->replyToIdMD5();
2777 TQString replyToAuxId = kmb->replyToAuxIdMD5();
2779 if(!replymd5.isEmpty())
2780 p = mSortCacheItems[replymd5];
2783 parent_id = p->id();
2789 if (replymd5.isEmpty()
2790 && replyToAuxId.isEmpty()
2791 && !kmb->subjectIsPrefixed() )
2797 internalWriteItem(sortStream, mFolder, i->
msgId(), parent_id,
2798 i->key(mSortCol, !mSortDescending),
false);
2804 fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET, SEEK_SET);
2805 fwrite(&byteOrder,
sizeof(byteOrder), 1, sortStream);
2806 fwrite(&column,
sizeof(column), 1, sortStream);
2807 fwrite(&ascending,
sizeof(ascending), 1, sortStream);
2808 fwrite(&threaded,
sizeof(threaded), 1, sortStream);
2809 fwrite(&appended,
sizeof(appended), 1, sortStream);
2810 fwrite(&discovered_count,
sizeof(discovered_count), 1, sortStream);
2811 fwrite(&sorted_count,
sizeof(sorted_count), 1, sortStream);
2812 if (sortStream && ferror(sortStream)) {
2814 unlink(TQFile::encodeName(sortFile));
2815 kdWarning(5006) <<
"Error: Failure modifying " << sortFile <<
" (No space left on device?)" << endl;
2816 kdWarning(5006) << __FILE__ <<
":" << __LINE__ << endl;
2817 kmkernel->emergencyExit( i18n(
"Failure modifying %1\n(No space left on device?)").arg( sortFile ));
2820 ::rename(TQFile::encodeName(tempName), TQFile::encodeName(sortFile));
2826 void KMHeaders::appendItemToSortFile(
HeaderItem *khi)
2828 TQString sortFile = KMAIL_SORT_FILE(mFolder);
2829 if(FILE *sortStream = fopen(TQFile::encodeName(sortFile),
"r+")) {
2834 KMMsgBase *kmb = mFolder->getMsgBase( khi->
msgId() );
2836 parent_id = sci->
parent()->id();
2837 else if(kmb->replyToIdMD5().isEmpty()
2838 && kmb->replyToAuxIdMD5().isEmpty()
2839 && !kmb->subjectIsPrefixed())
2843 internalWriteItem(sortStream, mFolder, khi->
msgId(), parent_id,
2844 khi->key(mSortCol, !mSortDescending),
false);
2847 TQ_INT32 appended = 1;
2848 fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 16, SEEK_SET);
2849 fwrite(&appended,
sizeof(appended), 1, sortStream);
2850 fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 16, SEEK_SET);
2852 if (sortStream && ferror(sortStream)) {
2854 unlink(TQFile::encodeName(sortFile));
2855 kdWarning(5006) <<
"Error: Failure modifying " << sortFile <<
" (No space left on device?)" << endl;
2856 kdWarning(5006) << __FILE__ <<
":" << __LINE__ << endl;
2857 kmkernel->emergencyExit( i18n(
"Failure modifying %1\n(No space left on device?)").arg( sortFile ));
2861 mSortInfo.dirty =
true;
2867 mSortInfo.dirty =
true;
2868 TQObject::disconnect(header(), TQ_SIGNAL(clicked(
int)),
this, TQ_SLOT(
dirtySortOrder(
int)));
2869 setSorting(column, mSortInfo.column == column ? !mSortInfo.ascending :
true);
2873 void SortCacheItem::updateSortFile( FILE *sortStream,
KMFolder *folder,
2874 bool waiting_for_parent,
bool update_discover)
2876 if(mSortOffset == -1) {
2877 fseek(sortStream, 0, SEEK_END);
2878 mSortOffset = ftell(sortStream);
2880 fseek(sortStream, mSortOffset, SEEK_SET);
2884 if(!waiting_for_parent) {
2886 parent_id = mParent->id();
2888 internalWriteItem(sortStream, folder, mId, parent_id, mKey, update_discover);
2891 static bool compare_ascending =
false;
2892 static bool compare_toplevel =
true;
2893 static int compare_SortCacheItem(
const void *s1,
const void *s2)
2899 int ret = (*b1)->key().compare((*b2)->key());
2900 if(compare_ascending || !compare_toplevel)
2906 void KMHeaders::printSubjectThreadingTree()
2908 TQDictIterator< TQPtrList< SortCacheItem > > it ( mSubjectLists );
2909 kdDebug(5006) <<
"SubjectThreading tree: " << endl;
2910 for( ; it.current(); ++it ) {
2911 TQPtrList<SortCacheItem> list = *( it.current() );
2912 TQPtrListIterator<SortCacheItem> it2( list ) ;
2913 kdDebug(5006) <<
"Subject MD5: " << it.currentKey() <<
" list: " << endl;
2914 for( ; it2.current(); ++it2 ) {
2916 kdDebug(5006) <<
" item:" << sci <<
" sci id: " << sci->id() << endl;
2919 kdDebug(5006) << endl;
2922 void KMHeaders::printThreadingTree()
2924 kdDebug(5006) <<
"Threading tree: " << endl;
2925 TQDictIterator<SortCacheItem> it( mSortCacheItems );
2926 kdDebug(5006) << endl;
2927 for( ; it.current(); ++it ) {
2929 kdDebug(5006) <<
"MsgId MD5: " << it.currentKey() <<
" message id: " << sci->id() << endl;
2931 for (
int i = 0; i < (int)mItems.size(); ++i) {
2934 kdDebug( 5006 ) <<
"SortCacheItem: " << item->
sortCacheItem()->id() <<
" parent: " << parentCacheId << endl;
2937 kdDebug(5006) << endl;
2942 void KMHeaders::buildThreadingTree( TQMemArray<SortCacheItem *> sortCache )
2944 mSortCacheItems.clear();
2945 mSortCacheItems.resize( mFolder->count() * 2 );
2948 for(
int x = 0; x < mFolder->count(); x++) {
2949 KMMsgBase *mi = mFolder->getMsgBase(x);
2950 TQString md5 = mi->msgIdMD5();
2952 mSortCacheItems.replace(md5, sortCache[x]);
2957 void KMHeaders::buildSubjectThreadingTree( TQMemArray<SortCacheItem *> sortCache )
2959 mSubjectLists.clear();
2960 mSubjectLists.resize( mFolder->count() * 2 );
2962 for(
int x = 0; x < mFolder->count(); x++) {
2964 if ( sortCache[x]->parent()
2965 && sortCache[x]->parent()->
id() != -666 )
continue;
2966 KMMsgBase *mi = mFolder->getMsgBase(x);
2967 TQString subjMD5 = mi->strippedSubjectMD5();
2968 if (subjMD5.isEmpty()) {
2969 mFolder->getMsgBase(x)->initStrippedSubjectMD5();
2970 subjMD5 = mFolder->getMsgBase(x)->strippedSubjectMD5();
2972 if( subjMD5.isEmpty() )
continue;
2976 if (!mSubjectLists.find(subjMD5))
2977 mSubjectLists.insert(subjMD5,
new TQPtrList<SortCacheItem>());
2983 for (TQPtrListIterator<SortCacheItem> it(*mSubjectLists[subjMD5]);
2984 it.current(); ++it) {
2985 KMMsgBase *mb = mFolder->getMsgBase((*it)->id());
2986 if ( mb->date() < mi->date())
2990 mSubjectLists[subjMD5]->insert( p, sortCache[x]);
2999 if (!item)
return parent;
3000 KMMsgBase *msg = mFolder->getMsgBase(item->id());
3001 TQString replyToIdMD5 = msg->replyToIdMD5();
3005 if(!replyToIdMD5.isEmpty()) {
3006 parent = mSortCacheItems[replyToIdMD5];
3017 TQString ref = msg->replyToAuxIdMD5();
3019 parent = mSortCacheItems[ref];
3027 if (!item)
return parent;
3029 KMMsgBase *msg = mFolder->getMsgBase(item->id());
3034 if (!msg->subjectIsPrefixed())
3037 TQString replyToIdMD5 = msg->replyToIdMD5();
3038 TQString subjMD5 = msg->strippedSubjectMD5();
3039 if (!subjMD5.isEmpty() && mSubjectLists[subjMD5]) {
3042 for (TQPtrListIterator<SortCacheItem> it2(*mSubjectLists[subjMD5]);
3043 it2.current(); ++it2) {
3044 KMMsgBase *mb = mFolder->getMsgBase((*it2)->id());
3045 if ( !mb )
return parent;
3047 if ( item == (*it2) )
continue;
3048 int delta = msg->date() - mb->date();
3053 if (delta < 3628899)
3062 bool KMHeaders::readSortOrder(
bool set_selection,
bool forceJumpToUnread )
3064 if (!mFolder->isOpened()) mFolder->open(
"kmheaders");
3067 TQ_INT32 column, ascending, threaded, discovered_count, sorted_count, appended;
3068 TQ_INT32 deleted_count = 0;
3069 bool unread_exists =
false;
3070 bool jumpToUnread = (GlobalSettings::self()->actionEnterFolder() ==
3071 GlobalSettings::EnumActionEnterFolder::SelectFirstUnreadNew) ||
3075 TQMemArray<SortCacheItem *> sortCache(mFolder->count());
3079 TQPtrList<SortCacheItem> unparented;
3080 mImperfectlyThreadedList.clear();
3083 mItems.fill( 0, mFolder->count() );
3084 sortCache.fill( 0 );
3086 mRoot->clearChildren();
3088 TQString sortFile = KMAIL_SORT_FILE(mFolder);
3089 FILE *sortStream = fopen(TQFile::encodeName(sortFile),
"r+");
3090 mSortInfo.fakeSort = 0;
3093 mSortInfo.fakeSort = 1;
3095 if (fscanf(sortStream, KMAIL_SORT_HEADER, &version) != 1)
3097 if(version == KMAIL_SORT_VERSION) {
3098 TQ_INT32 byteOrder = 0;
3099 fread(&byteOrder,
sizeof(byteOrder), 1, sortStream);
3100 if (byteOrder == 0x12345678)
3102 fread(&column,
sizeof(column), 1, sortStream);
3103 fread(&ascending,
sizeof(ascending), 1, sortStream);
3104 fread(&threaded,
sizeof(threaded), 1, sortStream);
3105 fread(&appended,
sizeof(appended), 1, sortStream);
3106 fread(&discovered_count,
sizeof(discovered_count), 1, sortStream);
3107 fread(&sorted_count,
sizeof(sorted_count), 1, sortStream);
3110 TDEListView::setSorting(-1);
3111 header()->setSortIndicator(column, ascending);
3112 TQObject::connect(header(), TQ_SIGNAL(clicked(
int)),
this, TQ_SLOT(dirtySortOrder(
int)));
3114 mSortInfo.dirty =
false;
3115 mSortInfo.column = (short)column;
3116 mSortInfo.ascending = (compare_ascending = ascending);
3119 unsigned long serNum, parentSerNum;
3120 int id, len, parent, x;
3121 TQChar *tmp_qchar = 0;
3122 int tmp_qchar_len = 0;
3123 const int mFolderCount = mFolder->count();
3126 CREATE_TIMER(parse);
3128 for(x = 0; !feof(sortStream) && !error; x++) {
3129 off_t offset = ftell(sortStream);
3132 if(!fread(&serNum,
sizeof(serNum), 1, sortStream) ||
3133 !fread(&parentSerNum,
sizeof(parentSerNum), 1, sortStream) ||
3134 !fread(&len,
sizeof(len), 1, sortStream)) {
3137 if ((len < 0) || (len > KMAIL_MAX_KEY_LEN)) {
3138 kdDebug(5006) <<
"Whoa.2! len " << len <<
" " << __FILE__ <<
":" << __LINE__ << endl;
3143 if(len > tmp_qchar_len) {
3144 tmp_qchar = (TQChar *)realloc(tmp_qchar, len);
3145 tmp_qchar_len = len;
3147 if(!fread(tmp_qchar, len, 1, sortStream))
3149 key = TQString(tmp_qchar, len / 2);
3155 if (folder != mFolder) {
3159 if (parentSerNum < KMAIL_RESERVED) {
3160 parent = (int)parentSerNum - KMAIL_RESERVED;
3163 if (folder != mFolder)
3166 if ((
id < 0) || (
id >= mFolderCount) ||
3167 (parent < -2) || (parent >= mFolderCount)) {
3168 kdDebug(5006) <<
"Whoa.1! " << __FILE__ <<
":" << __LINE__ << endl;
3173 if ((item=sortCache[
id])) {
3174 if (item->id() != -1) {
3175 kdDebug(5006) <<
"Whoa.3! " << __FILE__ <<
":" << __LINE__ << endl;
3181 item->setOffset(offset);
3185 if (threaded && parent != -2) {
3187 unparented.append(item);
3188 mRoot->addUnsortedChild(item);
3190 if( ! sortCache[parent] ) {
3196 if(x < sorted_count )
3197 mRoot->addSortedChild(item);
3199 mRoot->addUnsortedChild(item);
3203 if (error || (x != sorted_count + discovered_count)) {
3204 kdDebug(5006) << endl <<
"Whoa: x " << x <<
", sorted_count " << sorted_count <<
", discovered_count " << discovered_count <<
", count " << mFolder->count() << endl << endl;
3225 mSortInfo.dirty =
true;
3226 mSortInfo.column = column = mSortCol;
3227 mSortInfo.ascending = ascending = !mSortDescending;
3228 threaded = (isThreaded());
3229 sorted_count = discovered_count = appended = 0;
3230 TDEListView::setSorting( mSortCol, !mSortDescending );
3233 if((sorted_count + discovered_count - deleted_count) < mFolder->count()) {
3234 CREATE_TIMER(holes);
3237 for(
int x = 0; x < mFolder->count(); x++) {
3238 if((!sortCache[x] || (sortCache[x]->
id() < 0)) && (msg=mFolder->getMsgBase(x))) {
3239 int sortOrder = column;
3240 if (mPaintInfo.orderOfArrival)
3241 sortOrder |= (1 << 6);
3242 if (mPaintInfo.status)
3243 sortOrder |= (1 << 5);
3245 x, HeaderItem::generate_key(
this, msg, &mPaintInfo, sortOrder ));
3247 unparented.append(sortCache[x]);
3249 mRoot->addUnsortedChild(sortCache[x]);
3251 sortCache[x]->updateSortFile(sortStream, mFolder,
true,
true);
3262 if (threaded) buildThreadingTree( sortCache );
3263 TQPtrList<SortCacheItem> toBeSubjThreaded;
3265 if (threaded && !unparented.isEmpty()) {
3266 CREATE_TIMER(reparent);
3267 START_TIMER(reparent);
3269 for(TQPtrListIterator<SortCacheItem> it(unparented); it.current(); ++it) {
3273 if ( parent && (parent != (*it)) ) {
3276 (*it)->updateSortFile(sortStream, mFolder);
3281 toBeSubjThreaded.append((*it));
3283 mRoot->addUnsortedChild((*it));
3287 if (mSubjThreading) {
3288 buildSubjectThreadingTree( sortCache );
3289 for(TQPtrListIterator<SortCacheItem> it(toBeSubjThreaded); it.current(); ++it) {
3296 (*it)->updateSortFile(sortStream, mFolder);
3299 mRoot->addUnsortedChild((*it));
3303 END_TIMER(reparent);
3304 SHOW_TIMER(reparent);
3307 CREATE_TIMER(header_creation);
3308 START_TIMER(header_creation);
3311 TQPtrQueue<SortCacheItem> s;
3313 compare_toplevel =
true;
3317 int unsorted_count, unsorted_off=0;
3321 compare_SortCacheItem);
3327 for(TQPtrListIterator<SortCacheItem> it(*sorted);
3328 (unsorted && unsorted_off < unsorted_count) || it.current(); ) {
3335 ( !unsorted || unsorted_off >= unsorted_count
3337 ( ( !ascending || (ascending && !compare_toplevel) )
3338 && (*it)->key() < unsorted[unsorted_off]->
key() )
3340 ( ascending && (*it)->key() >= unsorted[unsorted_off]->
key() )
3348 new_kci = unsorted[unsorted_off++];
3350 if(new_kci->
item() || new_kci->
parent() != i)
3353 if(threaded && i->
item()) {
3356 if (mFolder->getMsgBase(i->id())->isWatched())
3357 mFolder->getMsgBase(new_kci->id())->setStatus(KMMsgStatusWatched);
3358 if (mFolder->getMsgBase(i->id())->isIgnored())
3359 mFolder->getMsgBase(new_kci->id())->setStatus(KMMsgStatusIgnored);
3364 new_kci->
setItem(mItems[new_kci->id()] = khi);
3369 if ( ( mFolder->getMsgBase(new_kci->id())->isNew() &&
3370 GlobalSettings::self()->actionEnterFolder() ==
3371 GlobalSettings::EnumActionEnterFolder::SelectFirstNew ) ||
3372 ( ( mFolder->getMsgBase(new_kci->id())->isNew() ||
3373 mFolder->getMsgBase(new_kci->id())->isUnread() ) &&
3376 unread_exists =
true;
3379 if ( !oldestItem || mFolder->getMsgBase( oldestItem->
msgId() )->date() >
3380 mFolder->getMsgBase( new_kci->id() )->date() ) {
3384 if ( !newestItem || mFolder->getMsgBase( newestItem->
msgId() )->date() <
3385 mFolder->getMsgBase( new_kci->id() )->date() ) {
3392 if (mSortCol == paintInfo()->dateCol)
3393 compare_toplevel =
false;
3394 }
while(!s.isEmpty());
3396 for(
int x = 0; x < mFolder->count(); x++) {
3397 if (!sortCache[x]) {
3401 if (!sortCache[x]->item()) {
3402 kdDebug(5006) <<
"KMHeaders::readSortOrder - msg could not be threaded. "
3403 << endl <<
"Please talk to your threading counselor asap. " << endl;
3404 khi =
new HeaderItem(
this, sortCache[x]->
id(), sortCache[x]->key());
3405 sortCache[x]->setItem(mItems[sortCache[x]->
id()] = khi);
3410 if (threaded && sortCache[x]->isImperfectlyThreaded()) {
3411 mImperfectlyThreadedList.append(sortCache[x]->item());
3415 sortCache[x]->item()->setSortCacheItem(sortCache[x]);
3418 if (getNestingPolicy()<2)
3422 END_TIMER(header_creation);
3423 SHOW_TIMER(header_creation);
3427 if( discovered_count * discovered_count > sorted_count - deleted_count ) {
3428 mSortInfo.dirty =
true;
3432 fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 16, SEEK_SET);
3433 fwrite(&appended,
sizeof(appended), 1, sortStream);
3438 CREATE_TIMER(selection);
3439 START_TIMER(selection);
3443 int first_unread = -1;
3444 if (unread_exists) {
3447 if ( ( mFolder->getMsgBase(item->
msgId())->isNew() &&
3448 GlobalSettings::self()->actionEnterFolder() ==
3449 GlobalSettings::EnumActionEnterFolder::SelectFirstNew ) ||
3450 ( ( mFolder->getMsgBase(item->
msgId())->isNew() ||
3451 mFolder->getMsgBase(item->
msgId())->isUnread() ) &&
3454 first_unread = item->
msgId();
3457 item =
static_cast<HeaderItem*
>(item->itemBelow());
3462 if(first_unread == -1 ) {
3463 setTopItemByIndex( mTopItem );
3465 if ( GlobalSettings::self()->actionEnterFolder() ==
3466 GlobalSettings::EnumActionEnterFolder::SelectNewest && newestItem != 0 ) {
3467 setCurrentItemByIndex( newestItem->
msgId() );
3469 else if ( GlobalSettings::self()->actionEnterFolder() ==
3470 GlobalSettings::EnumActionEnterFolder::SelectOldest && oldestItem != 0 ) {
3471 setCurrentItemByIndex( oldestItem->
msgId() );
3473 else if ( mCurrentItem >= 0 )
3474 setCurrentItemByIndex( mCurrentItem );
3475 else if ( mCurrentItemSerNum > 0 )
3476 setCurrentItemBySerialNum( mCurrentItemSerNum );
3478 setCurrentItemByIndex( 0 );
3482 setCurrentItemByIndex(first_unread);
3483 makeHeaderVisible();
3484 center( contentsX(), itemPos(mItems[first_unread]), 0, 9.0 );
3490 if (mCurrentItem <= 0) {
3491 setTopItemByIndex(mTopItem);
3492 setCurrentItemByIndex(0);
3495 END_TIMER(selection);
3496 SHOW_TIMER(selection);
3497 if (error || (sortStream && ferror(sortStream))) {
3500 unlink(TQFile::encodeName(sortFile));
3501 kdWarning(5006) <<
"Error: Failure modifying " << sortFile <<
" (No space left on device?)" << endl;
3502 kdWarning(5006) << __FILE__ <<
":" << __LINE__ << endl;
3518 for (
int i = 0; i < (int)mItems.size() - 1; ++i) {
3519 KMMsgBase *mMsgBase = mFolder->getMsgBase( i );
3520 if ( mMsgBase->getMsgSerNum() == serialNum ) {
3521 bool unchanged = (currentItem() == mItems[i]);
3522 setCurrentItem( mItems[i] );
3523 setSelected( mItems[i],
true );
3524 setSelectionAnchor( currentItem() );
3526 highlightMessage( currentItem(),
false );
3527 ensureCurrentItemVisible();
3532 kdDebug(5006) <<
"KMHeaders::setCurrentItem item with serial number " << serialNum <<
" NOT FOUND" << endl;
3535 void KMHeaders::copyMessages()
3537 mCopiedMessages.clear();
3538 KMMessageList* list = selectedMsgs();
3539 for ( uint i = 0; i < list->count(); ++ i )
3540 mCopiedMessages << list->at( i )->getMsgSerNum();
3541 mMoveMessages =
false;
3546 void KMHeaders::cutMessages()
3548 mCopiedMessages.clear();
3549 KMMessageList* list = selectedMsgs();
3550 for ( uint i = 0; i < list->count(); ++ i )
3551 mCopiedMessages << list->at( i )->getMsgSerNum();
3552 mMoveMessages =
true;
3557 void KMHeaders::pasteMessages()
3560 if ( mMoveMessages ) {
3561 mCopiedMessages.clear();
3566 void KMHeaders::updateActions()
3568 TDEAction *copy = owner()->action(
"copy_messages" );
3569 TDEAction *cut = owner()->action(
"cut_messages" );
3570 TDEAction *paste = owner()->action(
"paste_messages" );
3572 if ( selectedItems().isEmpty() ) {
3573 copy->setEnabled(
false );
3574 cut->setEnabled(
false );
3576 copy->setEnabled(
true );
3577 if ( folder() && !folder()->canDeleteMessages() )
3578 cut->setEnabled(
false );
3580 cut->setEnabled(
true );
3583 if ( mCopiedMessages.isEmpty() || !folder() || folder()->isReadOnly() )
3584 paste->setEnabled(
false );
3586 paste->setEnabled(
true );
3591 mCopiedMessages = msgs;
3592 mMoveMessages = move;
3598 return mMoveMessages && mCopiedMessages.contains( serNum );
3603 TQValueList<TQ_UINT32> list;
3604 for ( TQListViewItemIterator it(
this); it.current(); it++ ) {
3605 if ( it.current()->isSelected() && it.current()->isVisible() ) {
3607 KMMsgBase *msgBase = mFolder->getMsgBase( item->
msgId() );
3609 list.append( msgBase->getMsgSerNum() );
3618 TQValueList<TQ_UINT32> list;
3619 TQListViewItemIterator it(
this, TQListViewItemIterator::Selected|TQListViewItemIterator::Visible);
3620 while( it.current() ) {
3621 if ( it.current()->isSelected() && it.current()->isVisible() ) {
3622 if ( it.current()->parent() && ( !it.current()->parent()->isOpen() ) ) {
3624 TQListViewItem * lastAncestorWithSiblings = it.current()->parent();
3626 while ( ( lastAncestorWithSiblings->depth() > 0 ) && !lastAncestorWithSiblings->nextSibling() )
3627 lastAncestorWithSiblings = lastAncestorWithSiblings->parent();
3629 it = TQListViewItemIterator( lastAncestorWithSiblings->nextSibling() );
3633 KMMsgBase *msgBase = mFolder->getMsgBase( item->
msgId() );
3635 list.append( msgBase->getMsgSerNum() );
3644 #include "kmheaders.moc"
sets a cursor and makes sure it's restored on destruction Create a KCursorSaver object when you want ...
KMMsgInfo * unGetMsg(int idx)
Replace KMMessage with KMMsgInfo and delete KMMessage
KMMessage * getMsg(int idx)
Read message at given index.
void setTransferInProgress(bool value, bool force=false)
Set that the message shall not be deleted because it is still required.
bool transferInProgress() const
Return, if the message should not be deleted.
bool isComplete() const
Return true if the complete message is available without referring to the backing store.
unsigned long getMsgSerNum(KMFolder *folder, int index) const
Find the message serial number for the message located at index index in folder folder.
static TQValueList< unsigned long > serNumList(TQPtrList< KMMsgBase > msgList)
Convert a list of KMMsgBase pointers to a list of serial numbers.
void getLocation(unsigned long key, KMFolder **retFolder, int *retIndex) const
Returns the folder the message represented by the serial number key is in and the index in that folde...
static const KMMsgDict * instance()
Access the globally unique MessageDict.
Helper class to copy/move a set of messages defined by their serial numbers from arbitrary folders in...
Represents an item in the set of mails to be displayed but only as far as sorting,...
bool isImperfectlyThreaded() const
Returs whether the item is so far imperfectly threaded.
SortCacheItem * parent() const
The parent node of the item in the threading hierarchy.
const TQPtrList< SortCacheItem > * sortedChildren() const
The sorted children are an array of sortcache items we know are below the current one and are already...
void addUnsortedChild(SortCacheItem *i)
Add an item to this itme's list of unsorted children.
TQPtrList< SortCacheItem > * subjectThreadingList() const
The list of mails with a certain subject that this item is on.
const TQString & key() const
sort key as used by the listview
void addSortedChild(SortCacheItem *i)
Add an item to this itme's list of already sorted children.
void setImperfectlyThreaded(bool val)
Set whether the item is currently imperfectly threaded (by References or Subject, not by In-Reply-To)...
bool hasChildren() const
Returns whether the item has other items below it.
void setSubjectThreadingList(TQPtrList< SortCacheItem > *list)
Set the list of mails with a certain subject that this item is on.
HeaderItem * item() const
The corresponding KMail::HeaderItem.
void setItem(HeaderItem *i)
Set the corresponding KMail::HeaderItem.
SortCacheItem ** unsortedChildren(int &count) const
The unsorted children are an array of sortcache items we know are below the current one,...
void setKey(const TQString &key)
Set the sort key used by the list view.