kmacctimap.cpp
00001 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include "kmacctimap.h" 00027 using KMail::SieveConfig; 00028 00029 #include "kmmessage.h" 00030 #include "broadcaststatus.h" 00031 using KPIM::BroadcastStatus; 00032 #include "kmfoldertree.h" 00033 #include "kmfoldermgr.h" 00034 #include "kmfolderimap.h" 00035 #include "kmmainwin.h" 00036 #include "kmmsgdict.h" 00037 #include "kmfilter.h" 00038 #include "kmfiltermgr.h" 00039 #include "folderstorage.h" 00040 #include "imapjob.h" 00041 #include "actionscheduler.h" 00042 using KMail::ActionScheduler; 00043 using KMail::ImapJob; 00044 using KMail::ImapAccountBase; 00045 #include "progressmanager.h" 00046 using KPIM::ProgressItem; 00047 using KPIM::ProgressManager; 00048 #include <kio/scheduler.h> 00049 #include <kio/slave.h> 00050 #include <kmessagebox.h> 00051 #include <kdebug.h> 00052 00053 #include <tqstylesheet.h> 00054 00055 #include <errno.h> 00056 00057 //----------------------------------------------------------------------------- 00058 KMAcctImap::KMAcctImap(AccountManager* aOwner, const TQString& aAccountName, uint id): 00059 KMail::ImapAccountBase(aOwner, aAccountName, id), 00060 mCountRemainChecks( 0 ), 00061 mErrorTimer( 0, "mErrorTimer" ) 00062 { 00063 mFolder = 0; 00064 mScheduler = 0; 00065 mNoopTimer.start( 60000 ); // // send a noop every minute 00066 mOpenFolders.setAutoDelete(true); 00067 connect(kmkernel->imapFolderMgr(), TQT_SIGNAL(changed()), 00068 this, TQT_SLOT(slotUpdateFolderList())); 00069 connect(&mErrorTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotResetConnectionError())); 00070 00071 TQString serNumUri = locateLocal( "data", "kmail/unfiltered." + 00072 TQString("%1").arg(KAccount::id()) ); 00073 KConfig config( serNumUri ); 00074 TQStringList serNums = config.readListEntry( "unfiltered" ); 00075 mFilterSerNumsToSave.setAutoDelete( false ); 00076 00077 for ( TQStringList::ConstIterator it = serNums.begin(); 00078 it != serNums.end(); ++it ) { 00079 mFilterSerNums.append( (*it).toUInt() ); 00080 mFilterSerNumsToSave.insert( *it, (const int *)1 ); 00081 } 00082 } 00083 00084 00085 //----------------------------------------------------------------------------- 00086 KMAcctImap::~KMAcctImap() 00087 { 00088 killAllJobs( true ); 00089 00090 TQString serNumUri = locateLocal( "data", "kmail/unfiltered." + 00091 TQString("%1").arg(KAccount::id()) ); 00092 KConfig config( serNumUri ); 00093 TQStringList serNums; 00094 TQDictIterator<int> it( mFilterSerNumsToSave ); 00095 for( ; it.current(); ++it ) 00096 serNums.append( it.currentKey() ); 00097 config.writeEntry( "unfiltered", serNums ); 00098 } 00099 00100 00101 //----------------------------------------------------------------------------- 00102 TQString KMAcctImap::type() const 00103 { 00104 return "imap"; 00105 } 00106 00107 //----------------------------------------------------------------------------- 00108 void KMAcctImap::pseudoAssign( const KMAccount * a ) { 00109 killAllJobs( true ); 00110 if (mFolder) 00111 { 00112 mFolder->setContentState(KMFolderImap::imapNoInformation); 00113 mFolder->setSubfolderState(KMFolderImap::imapNoInformation); 00114 } 00115 ImapAccountBase::pseudoAssign( a ); 00116 } 00117 00118 //----------------------------------------------------------------------------- 00119 void KMAcctImap::setImapFolder(KMFolderImap *aFolder) 00120 { 00121 mFolder = aFolder; 00122 mFolder->setImapPath( "/" ); 00123 } 00124 00125 00126 //----------------------------------------------------------------------------- 00127 00128 bool KMAcctImap::handleError( int errorCode, const TQString &errorMsg, KIO::Job* job, const TQString& context, bool abortSync ) 00129 { 00130 /* TODO check where to handle this one better. */ 00131 if ( errorCode == KIO::ERR_DOES_NOT_EXIST ) { 00132 // folder is gone, so reload the folderlist 00133 if ( mFolder ) 00134 mFolder->listDirectory(); 00135 return true; 00136 } 00137 return ImapAccountBase::handleError( errorCode, errorMsg, job, context, abortSync ); 00138 } 00139 00140 00141 //----------------------------------------------------------------------------- 00142 void KMAcctImap::killAllJobs( bool disconnectSlave ) 00143 { 00144 TQMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin(); 00145 for ( ; it != mapJobData.end(); ++it) 00146 { 00147 TQPtrList<KMMessage> msgList = (*it).msgList; 00148 TQPtrList<KMMessage>::Iterator it2 = msgList.begin(); 00149 for ( ; it2 != msgList.end(); ++it2 ) { 00150 KMMessage *msg = *it2; 00151 if ( msg->transferInProgress() ) { 00152 kdDebug(5006) << "KMAcctImap::killAllJobs - resetting mail" << endl; 00153 msg->setTransferInProgress( false ); 00154 } 00155 } 00156 if ((*it).parent) 00157 { 00158 // clear folder state 00159 KMFolderImap *fld = static_cast<KMFolderImap*>((*it).parent->storage()); 00160 fld->setCheckingValidity(false); 00161 fld->quiet(false); 00162 fld->setContentState(KMFolderImap::imapNoInformation); 00163 fld->setSubfolderState(KMFolderImap::imapNoInformation); 00164 fld->sendFolderComplete(FALSE); 00165 fld->removeJobs(); 00166 } 00167 if ( (*it).progressItem ) 00168 { 00169 (*it).progressItem->setComplete(); 00170 } 00171 } 00172 if (mSlave && mapJobData.begin() != mapJobData.end()) 00173 { 00174 mSlave->kill(); 00175 mSlave = 0; 00176 } 00177 // remove the jobs 00178 mapJobData.clear(); 00179 // KMAccount::deleteFolderJobs(); doesn't work here always, it deletes jobs from 00180 // its own mJobList instead of our mJobList... 00181 KMAccount::deleteFolderJobs(); 00182 TQPtrListIterator<ImapJob> it2( mJobList ); 00183 while ( it2.current() ) { 00184 ImapJob *job = it2.current(); 00185 ++it2; 00186 job->kill(); 00187 } 00188 mJobList.clear(); 00189 // make sure that no new-mail-check is blocked 00190 if (mCountRemainChecks > 0) 00191 { 00192 checkDone( false, CheckOK ); // returned 0 new messages 00193 mCountRemainChecks = 0; 00194 } 00195 if ( disconnectSlave && slave() ) { 00196 KIO::Scheduler::disconnectSlave( slave() ); 00197 mSlave = 0; 00198 } 00199 } 00200 00201 //----------------------------------------------------------------------------- 00202 void KMAcctImap::ignoreJobsForMessage( KMMessage* msg ) 00203 { 00204 if (!msg) return; 00205 TQPtrListIterator<ImapJob> it( mJobList ); 00206 while ( it.current() ) 00207 { 00208 ImapJob *job = it.current(); 00209 ++it; 00210 if ( job->msgList().first() == msg ) 00211 { 00212 job->kill(); 00213 } 00214 } 00215 } 00216 00217 //----------------------------------------------------------------------------- 00218 void KMAcctImap::ignoreJobsForFolder( KMFolder* folder ) 00219 { 00220 TQPtrListIterator<ImapJob> it( mJobList ); 00221 while ( it.current() ) 00222 { 00223 ImapJob *job = it.current(); 00224 ++it; 00225 if ( !job->msgList().isEmpty() && job->msgList().first()->parent() == folder ) 00226 { 00227 job->kill(); 00228 } 00229 } 00230 } 00231 00232 //----------------------------------------------------------------------------- 00233 void KMAcctImap::removeSlaveJobsForFolder( KMFolder* folder ) 00234 { 00235 // Make sure the folder is not referenced in any kio slave jobs 00236 TQMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin(); 00237 while ( it != mapJobData.end() ) { 00238 TQMap<KIO::Job*, jobData>::Iterator i = it; 00239 it++; 00240 if ( (*i).parent ) { 00241 if ( (*i).parent == folder ) { 00242 mapJobData.remove(i); 00243 } 00244 } 00245 } 00246 } 00247 00248 //----------------------------------------------------------------------------- 00249 void KMAcctImap::cancelMailCheck() 00250 { 00251 // Make list of folders to reset, like in killAllJobs 00252 TQValueList<KMFolderImap*> folderList; 00253 TQMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin(); 00254 for (; it != mapJobData.end(); ++it) { 00255 if ( (*it).cancellable && (*it).parent ) { 00256 folderList << static_cast<KMFolderImap*>((*it).parent->storage()); 00257 } 00258 } 00259 // Kill jobs 00260 // FIXME 00261 // ImapAccountBase::cancelMailCheck(); 00262 killAllJobs( true ); 00263 // emit folderComplete, this is important for 00264 // KMAccount::checkingMail() to be reset, in case we restart checking mail later. 00265 for( TQValueList<KMFolderImap*>::Iterator it = folderList.begin(); it != folderList.end(); ++it ) { 00266 KMFolderImap *fld = *it; 00267 fld->sendFolderComplete(FALSE); 00268 } 00269 } 00270 00271 //----------------------------------------------------------------------------- 00272 void KMAcctImap::processNewMail(bool interactive) 00273 { 00274 kdDebug() << "processNewMail " << mCheckingSingleFolder << ",status="<<makeConnection()<<endl; 00275 if (!mFolder || !mFolder->folder() || !mFolder->folder()->child() || 00276 makeConnection() == ImapAccountBase::Error) 00277 { 00278 mCountRemainChecks = 0; 00279 mCheckingSingleFolder = false; 00280 checkDone( false, CheckError ); 00281 return; 00282 } 00283 // if necessary then initialize the list of folders which should be checked 00284 if( mMailCheckFolders.isEmpty() ) 00285 { 00286 slotUpdateFolderList(); 00287 // if no folders should be checked then the check is finished 00288 if( mMailCheckFolders.isEmpty() ) 00289 { 00290 checkDone( false, CheckOK ); 00291 mCheckingSingleFolder = false; 00292 return; 00293 } 00294 } 00295 // Ok, we're really checking, get a progress item; 00296 Q_ASSERT( !mMailCheckProgressItem ); 00297 mMailCheckProgressItem = 00298 ProgressManager::createProgressItem( 00299 "MailCheckAccount" + name(), 00300 i18n("Checking account: %1" ).arg( TQStyleSheet::escape( name() ) ), 00301 TQString(), // status 00302 true, // can be canceled 00303 useSSL() || useTLS() ); 00304 00305 mMailCheckProgressItem->setTotalItems( mMailCheckFolders.count() ); 00306 connect ( mMailCheckProgressItem, 00307 TQT_SIGNAL( progressItemCanceled( KPIM::ProgressItem*) ), 00308 this, 00309 TQT_SLOT( slotMailCheckCanceled() ) ); 00310 00311 TQValueList<TQGuardedPtr<KMFolder> >::Iterator it; 00312 // first get the current count of unread-messages 00313 mCountRemainChecks = 0; 00314 mCountUnread = 0; 00315 mUnreadBeforeCheck.clear(); 00316 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); ++it) 00317 { 00318 KMFolder *folder = *it; 00319 if (folder && !folder->noContent()) 00320 { 00321 mUnreadBeforeCheck[folder->idString()] = folder->countUnread(); 00322 } 00323 } 00324 bool gotError = false; 00325 // then check for new mails 00326 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); ++it) 00327 { 00328 KMFolder *folder = *it; 00329 if (folder && !folder->noContent()) 00330 { 00331 KMFolderImap *imapFolder = static_cast<KMFolderImap*>(folder->storage()); 00332 if ( imapFolder->getContentState() != KMFolderImap::imapListingInProgress 00333 && imapFolder->getContentState() != KMFolderImap::imapDownloadInProgress ) 00334 { 00335 // connect the result-signals for new-mail-notification 00336 mCountRemainChecks++; 00337 00338 if (imapFolder->isSelected()) { 00339 connect(imapFolder, TQT_SIGNAL(folderComplete(KMFolderImap*, bool)), 00340 this, TQT_SLOT(postProcessNewMail(KMFolderImap*, bool))); 00341 imapFolder->getFolder(); 00342 } else if ( kmkernel->filterMgr()->atLeastOneIncomingFilterAppliesTo( id() ) && 00343 imapFolder->folder()->isSystemFolder() && 00344 imapFolder->imapPath() == "/INBOX/" ) { 00345 imapFolder->open("acctimap"); // will be closed in the folderSelected slot 00346 // first get new headers before we select the folder 00347 imapFolder->setSelected( true ); 00348 connect( imapFolder, TQT_SIGNAL( folderComplete( KMFolderImap*, bool ) ), 00349 this, TQT_SLOT( slotFolderSelected( KMFolderImap*, bool) ) ); 00350 imapFolder->getFolder(); 00351 } 00352 else { 00353 connect(imapFolder, TQT_SIGNAL(numUnreadMsgsChanged(KMFolder*)), 00354 this, TQT_SLOT(postProcessNewMail(KMFolder*))); 00355 bool ok = imapFolder->processNewMail(interactive); 00356 if (!ok) 00357 { 00358 // there was an error so cancel 00359 mCountRemainChecks--; 00360 gotError = true; 00361 if ( mMailCheckProgressItem ) { 00362 mMailCheckProgressItem->incCompletedItems(); 00363 mMailCheckProgressItem->updateProgress(); 00364 } 00365 } 00366 } 00367 } 00368 } 00369 } // end for 00370 if ( gotError ) 00371 slotUpdateFolderList(); 00372 // for the case the account is down and all folders report errors 00373 if ( mCountRemainChecks == 0 ) 00374 { 00375 mCountLastUnread = 0; // => mCountUnread - mCountLastUnread == new count 00376 ImapAccountBase::postProcessNewMail(); 00377 mUnreadBeforeCheck.clear(); 00378 mCheckingSingleFolder = false; 00379 } 00380 } 00381 00382 //----------------------------------------------------------------------------- 00383 void KMAcctImap::postProcessNewMail(KMFolderImap* folder, bool) 00384 { 00385 disconnect(folder, TQT_SIGNAL(folderComplete(KMFolderImap*, bool)), 00386 this, TQT_SLOT(postProcessNewMail(KMFolderImap*, bool))); 00387 postProcessNewMail(static_cast<KMFolder*>(folder->folder())); 00388 } 00389 00390 void KMAcctImap::postProcessNewMail( KMFolder * folder ) 00391 { 00392 disconnect( folder->storage(), TQT_SIGNAL(numUnreadMsgsChanged(KMFolder*)), 00393 this, TQT_SLOT(postProcessNewMail(KMFolder*)) ); 00394 00395 if ( mMailCheckProgressItem ) { 00396 mMailCheckProgressItem->incCompletedItems(); 00397 mMailCheckProgressItem->updateProgress(); 00398 mMailCheckProgressItem->setStatus( folder->prettyURL() + i18n(" completed") ); 00399 } 00400 mCountRemainChecks--; 00401 00402 // count the unread messages 00403 const TQString folderId = folder->idString(); 00404 int newInFolder = folder->countUnread(); 00405 if ( mUnreadBeforeCheck.find( folderId ) != mUnreadBeforeCheck.end() ) 00406 newInFolder -= mUnreadBeforeCheck[folderId]; 00407 if ( newInFolder > 0 ) { 00408 addToNewInFolder( folderId, newInFolder ); 00409 mCountUnread += newInFolder; 00410 } 00411 00412 // Filter messages 00413 TQValueListIterator<TQ_UINT32> filterIt = mFilterSerNums.begin(); 00414 TQValueList<TQ_UINT32> inTransit; 00415 00416 if (ActionScheduler::isEnabled() || 00417 kmkernel->filterMgr()->atLeastOneOnlineImapFolderTarget()) { 00418 KMFilterMgr::FilterSet set = KMFilterMgr::Inbound; 00419 TQValueList<KMFilter*> filters = kmkernel->filterMgr()->filters(); 00420 if (!mScheduler) { 00421 mScheduler = new KMail::ActionScheduler( set, filters ); 00422 mScheduler->setAccountId( id() ); 00423 connect( mScheduler, TQT_SIGNAL(filtered(TQ_UINT32)), this, TQT_SLOT(slotFiltered(TQ_UINT32)) ); 00424 } else { 00425 mScheduler->setFilterList( filters ); 00426 } 00427 } 00428 00429 while (filterIt != mFilterSerNums.end()) { 00430 int idx = -1; 00431 KMFolder *folder = 0; 00432 KMMessage *msg = 0; 00433 KMMsgDict::instance()->getLocation( *filterIt, &folder, &idx ); 00434 // It's possible that the message has been deleted or moved into a 00435 // different folder, or that the serNum is stale 00436 if ( !folder ) { 00437 mFilterSerNumsToSave.remove( TQString( "%1" ).arg( *filterIt ) ); 00438 ++filterIt; 00439 continue; 00440 } 00441 00442 KMFolderImap *imapFolder = dynamic_cast<KMFolderImap*>(folder->storage()); 00443 if (!imapFolder || 00444 !imapFolder->folder()->isSystemFolder() || 00445 !(imapFolder->imapPath() == "/INBOX/") ) { // sanity checking 00446 mFilterSerNumsToSave.remove( TQString( "%1" ).arg( *filterIt ) ); 00447 ++filterIt; 00448 continue; 00449 } 00450 00451 if (idx != -1) { 00452 00453 msg = folder->getMsg( idx ); 00454 if (!msg) { // sanity checking 00455 mFilterSerNumsToSave.remove( TQString( "%1" ).arg( *filterIt ) ); 00456 ++filterIt; 00457 continue; 00458 } 00459 00460 if (ActionScheduler::isEnabled() || 00461 kmkernel->filterMgr()->atLeastOneOnlineImapFolderTarget()) { 00462 mScheduler->execFilters( msg ); 00463 } else { 00464 if (msg->transferInProgress()) { 00465 inTransit.append( *filterIt ); 00466 ++filterIt; 00467 continue; 00468 } 00469 msg->setTransferInProgress(true); 00470 if ( !msg->isComplete() ) { 00471 FolderJob *job = folder->createJob(msg); 00472 connect(job, TQT_SIGNAL(messageRetrieved(KMMessage*)), 00473 TQT_SLOT(slotFilterMsg(KMMessage*))); 00474 job->start(); 00475 } else { 00476 mFilterSerNumsToSave.remove( TQString( "%1" ).arg( *filterIt ) ); 00477 if (slotFilterMsg(msg) == 2) break; 00478 } 00479 } 00480 } 00481 ++filterIt; 00482 } 00483 mFilterSerNums = inTransit; 00484 00485 if (mCountRemainChecks == 0) 00486 { 00487 // all checks are done 00488 mCountLastUnread = 0; // => mCountUnread - mCountLastUnread == new count 00489 // when we check only one folder (=selected) and we have new mails 00490 // then do not display a summary as the normal status message is better 00491 bool showStatus = ( mCheckingSingleFolder && mCountUnread > 0 ) ? false : true; 00492 ImapAccountBase::postProcessNewMail( showStatus ); 00493 mUnreadBeforeCheck.clear(); 00494 mCheckingSingleFolder = false; 00495 } 00496 } 00497 00498 //----------------------------------------------------------------------------- 00499 void KMAcctImap::slotFiltered(TQ_UINT32 serNum) 00500 { 00501 mFilterSerNumsToSave.remove( TQString( "%1" ).arg( serNum ) ); 00502 } 00503 00504 //----------------------------------------------------------------------------- 00505 void KMAcctImap::slotUpdateFolderList() 00506 { 00507 if ( !mFolder || !mFolder->folder() || !mFolder->folder()->child() ) 00508 { 00509 kdWarning(5006) << "KMAcctImap::slotUpdateFolderList return" << endl; 00510 return; 00511 } 00512 TQStringList strList; 00513 mMailCheckFolders.clear(); 00514 kmkernel->imapFolderMgr()->createFolderList(&strList, &mMailCheckFolders, 00515 mFolder->folder()->child(), TQString(), false); 00516 // the new list 00517 TQValueList<TQGuardedPtr<KMFolder> > includedFolders; 00518 // check for excluded folders 00519 TQValueList<TQGuardedPtr<KMFolder> >::Iterator it; 00520 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); ++it) 00521 { 00522 KMFolderImap* folder = static_cast<KMFolderImap*>(((KMFolder*)(*it))->storage()); 00523 if (folder->includeInMailCheck()) 00524 includedFolders.append(*it); 00525 } 00526 mMailCheckFolders = includedFolders; 00527 } 00528 00529 //----------------------------------------------------------------------------- 00530 void KMAcctImap::listDirectory() 00531 { 00532 mFolder->listDirectory(); 00533 } 00534 00535 //----------------------------------------------------------------------------- 00536 void KMAcctImap::readConfig(KConfig& config) 00537 { 00538 ImapAccountBase::readConfig( config ); 00539 } 00540 00541 //----------------------------------------------------------------------------- 00542 void KMAcctImap::slotMailCheckCanceled() 00543 { 00544 if( mMailCheckProgressItem ) 00545 mMailCheckProgressItem->setComplete(); 00546 cancelMailCheck(); 00547 } 00548 00549 //----------------------------------------------------------------------------- 00550 FolderStorage* KMAcctImap::rootFolder() const 00551 { 00552 return mFolder; 00553 } 00554 00555 ImapAccountBase::ConnectionState KMAcctImap::makeConnection() 00556 { 00557 if ( mSlaveConnectionError ) 00558 { 00559 mErrorTimer.start(100, true); // Clear error flag 00560 return Error; 00561 } 00562 return ImapAccountBase::makeConnection(); 00563 } 00564 00565 void KMAcctImap::slotResetConnectionError() 00566 { 00567 mSlaveConnectionError = false; 00568 kdDebug(5006) << k_funcinfo << endl; 00569 } 00570 00571 void KMAcctImap::slotFolderSelected( KMFolderImap* folder, bool ) 00572 { 00573 folder->setSelected( false ); 00574 disconnect( folder, TQT_SIGNAL( folderComplete( KMFolderImap*, bool ) ), 00575 this, TQT_SLOT( slotFolderSelected( KMFolderImap*, bool) ) ); 00576 postProcessNewMail( static_cast<KMFolder*>(folder->folder()) ); 00577 folder->close( "acctimap" ); 00578 } 00579 00580 void KMAcctImap::execFilters(TQ_UINT32 serNum) 00581 { 00582 if ( !kmkernel->filterMgr()->atLeastOneFilterAppliesTo( id() ) ) return; 00583 TQValueListIterator<TQ_UINT32> findIt = mFilterSerNums.find( serNum ); 00584 if ( findIt != mFilterSerNums.end() ) 00585 return; 00586 mFilterSerNums.append( serNum ); 00587 mFilterSerNumsToSave.insert( TQString( "%1" ).arg( serNum ), (const int *)1 ); 00588 } 00589 00590 int KMAcctImap::slotFilterMsg( KMMessage *msg ) 00591 { 00592 if ( !msg ) { 00593 // messageRetrieved(0) is always possible 00594 return -1; 00595 } 00596 msg->setTransferInProgress(false); 00597 TQ_UINT32 serNum = msg->getMsgSerNum(); 00598 if ( serNum ) 00599 mFilterSerNumsToSave.remove( TQString( "%1" ).arg( serNum ) ); 00600 00601 int filterResult = kmkernel->filterMgr()->process(msg, 00602 KMFilterMgr::Inbound, 00603 true, 00604 id() ); 00605 if (filterResult == 2) { 00606 // something went horribly wrong (out of space?) 00607 kmkernel->emergencyExit( i18n("Unable to process messages: " ) + TQString::fromLocal8Bit(strerror(errno))); 00608 return 2; 00609 } 00610 if (msg->parent()) { // unGet this msg 00611 int idx = -1; 00612 KMFolder * p = 0; 00613 KMMsgDict::instance()->getLocation( msg, &p, &idx ); 00614 assert( p == msg->parent() ); assert( idx >= 0 ); 00615 p->unGetMsg( idx ); 00616 } 00617 00618 return filterResult; 00619 } 00620 00621 #include "kmacctimap.moc"