diff --git a/kmheaders.cpp b/kmheaders.cpp index bc407991b..aad602764 100644 --- a/kmheaders.cpp +++ b/kmheaders.cpp @@ -1412,48 +1412,59 @@ void KMHeaders::applyFiltersOnMsg() int contentX, contentY; HeaderItem *nextItem = prepareMove( &contentX, &contentY ); - KMMessageList* msgList = selectedMsgs(); - if (msgList->isEmpty()) + //prevent issues with stale message pointers by using serial numbers instead + QList serNums = KMMsgDict::serNumList( *selectedMsgs() ); + if ( serNums.isEmpty() ) return; - finalizeMove( nextItem, contentX, contentY ); + finalizeMove( nextItem, contentX, contentY ); CREATE_TIMER(filter); START_TIMER(filter); KCursorSaver busy( KBusyPtr::busy() ); int msgCount = 0; - int msgCountToFilter = msgList->count(); + int msgCountToFilter = serNums.count(); ProgressItem* progressItem = ProgressManager::createProgressItem ( "filter"+ProgressManager::getUniqueID(), i18n( "Filtering messages" ) ); progressItem->setTotalItems( msgCountToFilter ); - QList::const_iterator it; - for ( it = msgList->begin(); it != msgList->end(); it++ ) { - KMMsgBase* msgBase = (*it); - int diff = msgCountToFilter - ++msgCount; - if ( diff < 10 || !( msgCount % 10 ) || msgCount <= 10 ) { + + for ( QList::ConstIterator it = serNums.constBegin(); + it != serNums.constEnd(); ++it ) { + msgCount++; + if ( msgCountToFilter - msgCount < 10 || !( msgCount % 10 ) || msgCount <= 10 ) { progressItem->updateProgress(); QString statusMsg = i18n( "Filtering message %1 of %2", msgCount, msgCountToFilter ); KPIM::BroadcastStatus::instance()->setStatusMsg( statusMsg ); qApp->processEvents( QEventLoop::ExcludeUserInputEvents, 50 ); } - int idx = msgBase->parent()->find(msgBase); - assert(idx != -1); - KMMessage * msg = msgBase->parent()->getMsg(idx); - if (msg->transferInProgress()) continue; - msg->setTransferInProgress(true); - if ( !msg->isComplete() ) - { - FolderJob *job = mFolder->createJob(msg); - connect(job, SIGNAL(messageRetrieved(KMMessage*)), - SLOT(slotFilterMsg(KMMessage*))); - job->start(); + + KMFolder *folder = 0; + int idx; + KMMsgDict::instance()->getLocation( *it, &folder, &idx ); + KMMessage *msg = 0; + if (folder) + msg = folder->getMsg(idx); + if (msg) { + if (msg->transferInProgress()) + continue; + msg->setTransferInProgress(true); + if ( !msg->isComplete() ) { + FolderJob *job = mFolder->createJob(msg); + connect(job, SIGNAL(messageRetrieved(KMMessage*)), + this, SLOT(slotFilterMsg(KMMessage*))); + job->start(); + } else { + if (slotFilterMsg(msg) == 2) + break; + } } else { - if (slotFilterMsg(msg) == 2) break; + kDebug (5006) << "####### KMHeaders::applyFiltersOnMsg -" + " A message went missing during filtering " << endl; } - progressItem->incCompletedItems(); + progressItem->incCompletedItems(); } progressItem->setComplete(); progressItem = 0; diff --git a/kmmsgdict.cpp b/kmmsgdict.cpp index b010d01ce..877e7dc3c 100644 --- a/kmmsgdict.cpp +++ b/kmmsgdict.cpp @@ -353,6 +353,20 @@ unsigned long KMMsgDict::getMsgSerNum(KMFolder *folder, int index) const //----------------------------------------------------------------------------- +//static +QList KMMsgDict::serNumList(QList msgList) +{ + QList ret; + for ( unsigned int i = 0; i < msgList.count(); i++ ) { + unsigned long serNum = msgList.at(i)->getMsgSerNum(); + assert( serNum ); + ret.append( serNum ); + } + return ret; +} + +//----------------------------------------------------------------------------- + QString KMMsgDict::getFolderIdsLocation( const FolderStorage &storage ) { return storage.indexLocation() + ".ids"; diff --git a/kmmsgdict.h b/kmmsgdict.h index b7f697225..f2c61174f 100644 --- a/kmmsgdict.h +++ b/kmmsgdict.h @@ -20,6 +20,8 @@ #ifndef __KMMSGDICT #define __KMMSGDICT +#include + class KMFolder; class KMMsgBase; class KMMessage; @@ -67,6 +69,9 @@ class KMMsgDict * @return the message serial number or zero is no such message can be found */ unsigned long getMsgSerNum( KMFolder *folder, int index ) const; + /** Convert a list of KMMsgBase pointers to a list of serial numbers */ + static QList serNumList(QList msgList); + private: /* FIXME It would be better to do without these, they are the classes * involved in filling and maintaining the dict. The MsgList needs access