TDE personal information management applications
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

622 lines
20KB

  1. /**
  2. * kmacctimap.cpp
  3. *
  4. * Copyright (c) 2000-2002 Michael Haeckel <haeckel@kde.org>
  5. *
  6. * This file is based on popaccount.cpp by Don Sanders
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; version 2 of the License
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include "kmacctimap.h"
  25. using KMail::SieveConfig;
  26. #include "kmmessage.h"
  27. #include "broadcaststatus.h"
  28. using KPIM::BroadcastStatus;
  29. #include "kmfoldertree.h"
  30. #include "kmfoldermgr.h"
  31. #include "kmfolderimap.h"
  32. #include "kmmainwin.h"
  33. #include "kmmsgdict.h"
  34. #include "kmfilter.h"
  35. #include "kmfiltermgr.h"
  36. #include "folderstorage.h"
  37. #include "imapjob.h"
  38. #include "actionscheduler.h"
  39. using KMail::ActionScheduler;
  40. using KMail::ImapJob;
  41. using KMail::ImapAccountBase;
  42. #include "progressmanager.h"
  43. using KPIM::ProgressItem;
  44. using KPIM::ProgressManager;
  45. #include <tdeio/scheduler.h>
  46. #include <tdeio/slave.h>
  47. #include <tdemessagebox.h>
  48. #include <kdebug.h>
  49. #include <tqstylesheet.h>
  50. #include <errno.h>
  51. //-----------------------------------------------------------------------------
  52. KMAcctImap::KMAcctImap(AccountManager* aOwner, const TQString& aAccountName, uint id):
  53. KMail::ImapAccountBase(aOwner, aAccountName, id),
  54. mCountRemainChecks( 0 ),
  55. mErrorTimer( 0, "mErrorTimer" )
  56. {
  57. mFolder = 0;
  58. mScheduler = 0;
  59. mNoopTimer.start( 60000 ); // // send a noop every minute
  60. mOpenFolders.setAutoDelete(true);
  61. connect(kmkernel->imapFolderMgr(), TQT_SIGNAL(changed()),
  62. this, TQT_SLOT(slotUpdateFolderList()));
  63. connect(&mErrorTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotResetConnectionError()));
  64. TQString serNumUri = locateLocal( "data", "kmail/unfiltered." +
  65. TQString("%1").arg(KAccount::id()) );
  66. TDEConfig config( serNumUri );
  67. TQStringList serNums = config.readListEntry( "unfiltered" );
  68. mFilterSerNumsToSave.setAutoDelete( false );
  69. for ( TQStringList::ConstIterator it = serNums.begin();
  70. it != serNums.end(); ++it ) {
  71. mFilterSerNums.append( (*it).toUInt() );
  72. mFilterSerNumsToSave.insert( *it, (const int *)1 );
  73. }
  74. }
  75. //-----------------------------------------------------------------------------
  76. KMAcctImap::~KMAcctImap()
  77. {
  78. killAllJobs( true );
  79. TQString serNumUri = locateLocal( "data", "kmail/unfiltered." +
  80. TQString("%1").arg(KAccount::id()) );
  81. TDEConfig config( serNumUri );
  82. TQStringList serNums;
  83. TQDictIterator<int> it( mFilterSerNumsToSave );
  84. for( ; it.current(); ++it )
  85. serNums.append( it.currentKey() );
  86. config.writeEntry( "unfiltered", serNums );
  87. }
  88. //-----------------------------------------------------------------------------
  89. TQString KMAcctImap::type() const
  90. {
  91. return "imap";
  92. }
  93. //-----------------------------------------------------------------------------
  94. void KMAcctImap::pseudoAssign( const KMAccount * a ) {
  95. killAllJobs( true );
  96. if (mFolder)
  97. {
  98. mFolder->setContentState(KMFolderImap::imapNoInformation);
  99. mFolder->setSubfolderState(KMFolderImap::imapNoInformation);
  100. }
  101. ImapAccountBase::pseudoAssign( a );
  102. }
  103. //-----------------------------------------------------------------------------
  104. void KMAcctImap::setImapFolder(KMFolderImap *aFolder)
  105. {
  106. mFolder = aFolder;
  107. mFolder->setImapPath( "/" );
  108. }
  109. //-----------------------------------------------------------------------------
  110. bool KMAcctImap::handleError( int errorCode, const TQString &errorMsg, TDEIO::Job* job, const TQString& context, bool abortSync )
  111. {
  112. /* TODO check where to handle this one better. */
  113. if ( errorCode == TDEIO::ERR_DOES_NOT_EXIST ) {
  114. // folder is gone, so reload the folderlist
  115. if ( mFolder )
  116. mFolder->listDirectory();
  117. return true;
  118. }
  119. return ImapAccountBase::handleError( errorCode, errorMsg, job, context, abortSync );
  120. }
  121. //-----------------------------------------------------------------------------
  122. void KMAcctImap::killAllJobs( bool disconnectSlave )
  123. {
  124. TQMap<TDEIO::Job*, jobData>::Iterator it = mapJobData.begin();
  125. for ( ; it != mapJobData.end(); ++it)
  126. {
  127. TQPtrList<KMMessage> msgList = (*it).msgList;
  128. TQPtrList<KMMessage>::Iterator it2 = msgList.begin();
  129. for ( ; it2 != msgList.end(); ++it2 ) {
  130. KMMessage *msg = *it2;
  131. if ( msg->transferInProgress() ) {
  132. kdDebug(5006) << "KMAcctImap::killAllJobs - resetting mail" << endl;
  133. msg->setTransferInProgress( false );
  134. }
  135. }
  136. if ((*it).parent)
  137. {
  138. // clear folder state
  139. KMFolderImap *fld = static_cast<KMFolderImap*>((*it).parent->storage());
  140. fld->setCheckingValidity(false);
  141. fld->quiet(false);
  142. fld->setContentState(KMFolderImap::imapNoInformation);
  143. fld->setSubfolderState(KMFolderImap::imapNoInformation);
  144. fld->sendFolderComplete(FALSE);
  145. fld->removeJobs();
  146. }
  147. if ( (*it).progressItem )
  148. {
  149. (*it).progressItem->setComplete();
  150. }
  151. }
  152. if (mSlave && mapJobData.begin() != mapJobData.end())
  153. {
  154. mSlave->kill();
  155. mSlave = 0;
  156. }
  157. // remove the jobs
  158. mapJobData.clear();
  159. // KMAccount::deleteFolderJobs(); doesn't work here always, it deletes jobs from
  160. // its own mJobList instead of our mJobList...
  161. KMAccount::deleteFolderJobs();
  162. TQPtrListIterator<ImapJob> it2( mJobList );
  163. while ( it2.current() ) {
  164. ImapJob *job = it2.current();
  165. ++it2;
  166. job->kill();
  167. }
  168. mJobList.clear();
  169. // make sure that no new-mail-check is blocked
  170. if (mCountRemainChecks > 0)
  171. {
  172. checkDone( false, CheckOK ); // returned 0 new messages
  173. mCountRemainChecks = 0;
  174. }
  175. if ( disconnectSlave && slave() ) {
  176. TDEIO::Scheduler::disconnectSlave( slave() );
  177. mSlave = 0;
  178. }
  179. }
  180. //-----------------------------------------------------------------------------
  181. void KMAcctImap::ignoreJobsForMessage( KMMessage* msg )
  182. {
  183. if (!msg) return;
  184. TQPtrListIterator<ImapJob> it( mJobList );
  185. while ( it.current() )
  186. {
  187. ImapJob *job = it.current();
  188. ++it;
  189. if ( job->msgList().first() == msg )
  190. {
  191. job->kill();
  192. }
  193. }
  194. }
  195. //-----------------------------------------------------------------------------
  196. void KMAcctImap::ignoreJobsForFolder( KMFolder* folder )
  197. {
  198. TQPtrListIterator<ImapJob> it( mJobList );
  199. while ( it.current() )
  200. {
  201. ImapJob *job = it.current();
  202. ++it;
  203. if ( !job->msgList().isEmpty() && job->msgList().first()->parent() == folder )
  204. {
  205. job->kill();
  206. }
  207. }
  208. }
  209. //-----------------------------------------------------------------------------
  210. void KMAcctImap::removeSlaveJobsForFolder( KMFolder* folder )
  211. {
  212. // Make sure the folder is not referenced in any tdeio slave jobs
  213. TQMap<TDEIO::Job*, jobData>::Iterator it = mapJobData.begin();
  214. while ( it != mapJobData.end() ) {
  215. TQMap<TDEIO::Job*, jobData>::Iterator i = it;
  216. it++;
  217. if ( (*i).parent ) {
  218. if ( (*i).parent == folder ) {
  219. mapJobData.remove(i);
  220. }
  221. }
  222. }
  223. }
  224. //-----------------------------------------------------------------------------
  225. void KMAcctImap::cancelMailCheck()
  226. {
  227. // Make list of folders to reset, like in killAllJobs
  228. TQValueList<KMFolderImap*> folderList;
  229. TQMap<TDEIO::Job*, jobData>::Iterator it = mapJobData.begin();
  230. for (; it != mapJobData.end(); ++it) {
  231. if ( (*it).cancellable && (*it).parent ) {
  232. folderList << static_cast<KMFolderImap*>((*it).parent->storage());
  233. }
  234. }
  235. // Kill jobs
  236. // FIXME
  237. // ImapAccountBase::cancelMailCheck();
  238. killAllJobs( true );
  239. // emit folderComplete, this is important for
  240. // KMAccount::checkingMail() to be reset, in case we restart checking mail later.
  241. for( TQValueList<KMFolderImap*>::Iterator it = folderList.begin(); it != folderList.end(); ++it ) {
  242. KMFolderImap *fld = *it;
  243. fld->sendFolderComplete(FALSE);
  244. }
  245. }
  246. //-----------------------------------------------------------------------------
  247. void KMAcctImap::processNewMail(bool interactive)
  248. {
  249. kdDebug() << "processNewMail " << mCheckingSingleFolder << ",status="<<makeConnection()<<endl;
  250. if (!mFolder || !mFolder->folder() || !mFolder->folder()->child() ||
  251. makeConnection() == ImapAccountBase::Error)
  252. {
  253. mCountRemainChecks = 0;
  254. mCheckingSingleFolder = false;
  255. checkDone( false, CheckError );
  256. return;
  257. }
  258. // if necessary then initialize the list of folders which should be checked
  259. if( mMailCheckFolders.isEmpty() )
  260. {
  261. slotUpdateFolderList();
  262. // if no folders should be checked then the check is finished
  263. if( mMailCheckFolders.isEmpty() )
  264. {
  265. checkDone( false, CheckOK );
  266. mCheckingSingleFolder = false;
  267. return;
  268. }
  269. }
  270. // Ok, we're really checking, get a progress item;
  271. Q_ASSERT( !mMailCheckProgressItem );
  272. mMailCheckProgressItem =
  273. ProgressManager::createProgressItem(
  274. "MailCheckAccount" + name(),
  275. i18n("Checking account: %1" ).arg( TQStyleSheet::escape( name() ) ),
  276. TQString(), // status
  277. true, // can be canceled
  278. useSSL() || useTLS() );
  279. mMailCheckProgressItem->setTotalItems( mMailCheckFolders.count() );
  280. connect ( mMailCheckProgressItem,
  281. TQT_SIGNAL( progressItemCanceled( KPIM::ProgressItem*) ),
  282. this,
  283. TQT_SLOT( slotMailCheckCanceled() ) );
  284. TQValueList<TQGuardedPtr<KMFolder> >::Iterator it;
  285. // first get the current count of unread-messages
  286. mCountRemainChecks = 0;
  287. mCountUnread = 0;
  288. mUnreadBeforeCheck.clear();
  289. for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); ++it)
  290. {
  291. KMFolder *folder = *it;
  292. if (folder && !folder->noContent())
  293. {
  294. mUnreadBeforeCheck[folder->idString()] = folder->countUnread();
  295. }
  296. }
  297. bool gotError = false;
  298. // then check for new mails
  299. for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); ++it)
  300. {
  301. KMFolder *folder = *it;
  302. if (folder && !folder->noContent())
  303. {
  304. KMFolderImap *imapFolder = static_cast<KMFolderImap*>(folder->storage());
  305. if ( imapFolder->getContentState() != KMFolderImap::imapListingInProgress
  306. && imapFolder->getContentState() != KMFolderImap::imapDownloadInProgress )
  307. {
  308. // connect the result-signals for new-mail-notification
  309. mCountRemainChecks++;
  310. if (imapFolder->isSelected()) {
  311. connect(imapFolder, TQT_SIGNAL(folderComplete(KMFolderImap*, bool)),
  312. this, TQT_SLOT(postProcessNewMail(KMFolderImap*, bool)));
  313. imapFolder->getFolder();
  314. } else if ( kmkernel->filterMgr()->atLeastOneIncomingFilterAppliesTo( id() ) &&
  315. imapFolder->folder()->isSystemFolder() &&
  316. imapFolder->imapPath() == "/INBOX/" ) {
  317. imapFolder->open("acctimap"); // will be closed in the folderSelected slot
  318. // first get new headers before we select the folder
  319. imapFolder->setSelected( true );
  320. connect( imapFolder, TQT_SIGNAL( folderComplete( KMFolderImap*, bool ) ),
  321. this, TQT_SLOT( slotFolderSelected( KMFolderImap*, bool) ) );
  322. imapFolder->getFolder();
  323. }
  324. else {
  325. connect(imapFolder, TQT_SIGNAL(numUnreadMsgsChanged(KMFolder*)),
  326. this, TQT_SLOT(postProcessNewMail(KMFolder*)));
  327. bool ok = imapFolder->processNewMail(interactive);
  328. if (!ok)
  329. {
  330. // there was an error so cancel
  331. mCountRemainChecks--;
  332. gotError = true;
  333. if ( mMailCheckProgressItem ) {
  334. mMailCheckProgressItem->incCompletedItems();
  335. mMailCheckProgressItem->updateProgress();
  336. }
  337. }
  338. }
  339. }
  340. }
  341. } // end for
  342. if ( gotError )
  343. slotUpdateFolderList();
  344. // for the case the account is down and all folders report errors
  345. if ( mCountRemainChecks == 0 )
  346. {
  347. mCountLastUnread = 0; // => mCountUnread - mCountLastUnread == new count
  348. ImapAccountBase::postProcessNewMail();
  349. mUnreadBeforeCheck.clear();
  350. mCheckingSingleFolder = false;
  351. }
  352. }
  353. //-----------------------------------------------------------------------------
  354. void KMAcctImap::postProcessNewMail(KMFolderImap* folder, bool)
  355. {
  356. disconnect(folder, TQT_SIGNAL(folderComplete(KMFolderImap*, bool)),
  357. this, TQT_SLOT(postProcessNewMail(KMFolderImap*, bool)));
  358. postProcessNewMail(static_cast<KMFolder*>(folder->folder()));
  359. }
  360. void KMAcctImap::postProcessNewMail( KMFolder * folder )
  361. {
  362. disconnect( folder->storage(), TQT_SIGNAL(numUnreadMsgsChanged(KMFolder*)),
  363. this, TQT_SLOT(postProcessNewMail(KMFolder*)) );
  364. if ( mMailCheckProgressItem ) {
  365. mMailCheckProgressItem->incCompletedItems();
  366. mMailCheckProgressItem->updateProgress();
  367. mMailCheckProgressItem->setStatus( folder->prettyURL() + i18n(" completed") );
  368. }
  369. mCountRemainChecks--;
  370. // count the unread messages
  371. const TQString folderId = folder->idString();
  372. int newInFolder = folder->countUnread();
  373. if ( mUnreadBeforeCheck.find( folderId ) != mUnreadBeforeCheck.end() )
  374. newInFolder -= mUnreadBeforeCheck[folderId];
  375. if ( newInFolder > 0 ) {
  376. addToNewInFolder( folderId, newInFolder );
  377. mCountUnread += newInFolder;
  378. }
  379. // Filter messages
  380. TQValueListIterator<TQ_UINT32> filterIt = mFilterSerNums.begin();
  381. TQValueList<TQ_UINT32> inTransit;
  382. if (ActionScheduler::isEnabled() ||
  383. kmkernel->filterMgr()->atLeastOneOnlineImapFolderTarget()) {
  384. KMFilterMgr::FilterSet set = KMFilterMgr::Inbound;
  385. TQValueList<KMFilter*> filters = kmkernel->filterMgr()->filters();
  386. if (!mScheduler) {
  387. mScheduler = new KMail::ActionScheduler( set, filters );
  388. mScheduler->setAccountId( id() );
  389. connect( mScheduler, TQT_SIGNAL(filtered(TQ_UINT32)), this, TQT_SLOT(slotFiltered(TQ_UINT32)) );
  390. } else {
  391. mScheduler->setFilterList( filters );
  392. }
  393. }
  394. while (filterIt != mFilterSerNums.end()) {
  395. int idx = -1;
  396. KMFolder *folder = 0;
  397. KMMessage *msg = 0;
  398. KMMsgDict::instance()->getLocation( *filterIt, &folder, &idx );
  399. // It's possible that the message has been deleted or moved into a
  400. // different folder, or that the serNum is stale
  401. if ( !folder ) {
  402. mFilterSerNumsToSave.remove( TQString( "%1" ).arg( *filterIt ) );
  403. ++filterIt;
  404. continue;
  405. }
  406. KMFolderImap *imapFolder = dynamic_cast<KMFolderImap*>(folder->storage());
  407. if (!imapFolder ||
  408. !imapFolder->folder()->isSystemFolder() ||
  409. !(imapFolder->imapPath() == "/INBOX/") ) { // sanity checking
  410. mFilterSerNumsToSave.remove( TQString( "%1" ).arg( *filterIt ) );
  411. ++filterIt;
  412. continue;
  413. }
  414. if (idx != -1) {
  415. msg = folder->getMsg( idx );
  416. if (!msg) { // sanity checking
  417. mFilterSerNumsToSave.remove( TQString( "%1" ).arg( *filterIt ) );
  418. ++filterIt;
  419. continue;
  420. }
  421. if (ActionScheduler::isEnabled() ||
  422. kmkernel->filterMgr()->atLeastOneOnlineImapFolderTarget()) {
  423. mScheduler->execFilters( msg );
  424. } else {
  425. if (msg->transferInProgress()) {
  426. inTransit.append( *filterIt );
  427. ++filterIt;
  428. continue;
  429. }
  430. msg->setTransferInProgress(true);
  431. if ( !msg->isComplete() ) {
  432. FolderJob *job = folder->createJob(msg);
  433. connect(job, TQT_SIGNAL(messageRetrieved(KMMessage*)),
  434. TQT_SLOT(slotFilterMsg(KMMessage*)));
  435. job->start();
  436. } else {
  437. mFilterSerNumsToSave.remove( TQString( "%1" ).arg( *filterIt ) );
  438. if (slotFilterMsg(msg) == 2) break;
  439. }
  440. }
  441. }
  442. ++filterIt;
  443. }
  444. mFilterSerNums = inTransit;
  445. if (mCountRemainChecks == 0)
  446. {
  447. // all checks are done
  448. mCountLastUnread = 0; // => mCountUnread - mCountLastUnread == new count
  449. // when we check only one folder (=selected) and we have new mails
  450. // then do not display a summary as the normal status message is better
  451. bool showStatus = ( mCheckingSingleFolder && mCountUnread > 0 ) ? false : true;
  452. ImapAccountBase::postProcessNewMail( showStatus );
  453. mUnreadBeforeCheck.clear();
  454. mCheckingSingleFolder = false;
  455. }
  456. }
  457. //-----------------------------------------------------------------------------
  458. void KMAcctImap::slotFiltered(TQ_UINT32 serNum)
  459. {
  460. mFilterSerNumsToSave.remove( TQString( "%1" ).arg( serNum ) );
  461. }
  462. //-----------------------------------------------------------------------------
  463. void KMAcctImap::slotUpdateFolderList()
  464. {
  465. if ( !mFolder || !mFolder->folder() || !mFolder->folder()->child() )
  466. {
  467. kdWarning(5006) << "KMAcctImap::slotUpdateFolderList return" << endl;
  468. return;
  469. }
  470. TQStringList strList;
  471. mMailCheckFolders.clear();
  472. kmkernel->imapFolderMgr()->createFolderList(&strList, &mMailCheckFolders,
  473. mFolder->folder()->child(), TQString(), false);
  474. // the new list
  475. TQValueList<TQGuardedPtr<KMFolder> > includedFolders;
  476. // check for excluded folders
  477. TQValueList<TQGuardedPtr<KMFolder> >::Iterator it;
  478. for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); ++it)
  479. {
  480. KMFolderImap* folder = static_cast<KMFolderImap*>(((KMFolder*)(*it))->storage());
  481. if (folder->includeInMailCheck())
  482. includedFolders.append(*it);
  483. }
  484. mMailCheckFolders = includedFolders;
  485. }
  486. //-----------------------------------------------------------------------------
  487. void KMAcctImap::listDirectory()
  488. {
  489. mFolder->listDirectory();
  490. }
  491. //-----------------------------------------------------------------------------
  492. void KMAcctImap::readConfig(TDEConfig& config)
  493. {
  494. ImapAccountBase::readConfig( config );
  495. }
  496. //-----------------------------------------------------------------------------
  497. void KMAcctImap::slotMailCheckCanceled()
  498. {
  499. if( mMailCheckProgressItem )
  500. mMailCheckProgressItem->setComplete();
  501. cancelMailCheck();
  502. }
  503. //-----------------------------------------------------------------------------
  504. FolderStorage* KMAcctImap::rootFolder() const
  505. {
  506. return mFolder;
  507. }
  508. ImapAccountBase::ConnectionState KMAcctImap::makeConnection()
  509. {
  510. if ( mSlaveConnectionError )
  511. {
  512. mErrorTimer.start(100, true); // Clear error flag
  513. return Error;
  514. }
  515. return ImapAccountBase::makeConnection();
  516. }
  517. void KMAcctImap::slotResetConnectionError()
  518. {
  519. mSlaveConnectionError = false;
  520. kdDebug(5006) << k_funcinfo << endl;
  521. }
  522. void KMAcctImap::slotFolderSelected( KMFolderImap* folder, bool )
  523. {
  524. folder->setSelected( false );
  525. disconnect( folder, TQT_SIGNAL( folderComplete( KMFolderImap*, bool ) ),
  526. this, TQT_SLOT( slotFolderSelected( KMFolderImap*, bool) ) );
  527. postProcessNewMail( static_cast<KMFolder*>(folder->folder()) );
  528. folder->close( "acctimap" );
  529. }
  530. void KMAcctImap::execFilters(TQ_UINT32 serNum)
  531. {
  532. if ( !kmkernel->filterMgr()->atLeastOneFilterAppliesTo( id() ) ) return;
  533. TQValueListIterator<TQ_UINT32> findIt = mFilterSerNums.find( serNum );
  534. if ( findIt != mFilterSerNums.end() )
  535. return;
  536. mFilterSerNums.append( serNum );
  537. mFilterSerNumsToSave.insert( TQString( "%1" ).arg( serNum ), (const int *)1 );
  538. }
  539. int KMAcctImap::slotFilterMsg( KMMessage *msg )
  540. {
  541. if ( !msg ) {
  542. // messageRetrieved(0) is always possible
  543. return -1;
  544. }
  545. msg->setTransferInProgress(false);
  546. TQ_UINT32 serNum = msg->getMsgSerNum();
  547. if ( serNum )
  548. mFilterSerNumsToSave.remove( TQString( "%1" ).arg( serNum ) );
  549. int filterResult = kmkernel->filterMgr()->process(msg,
  550. KMFilterMgr::Inbound,
  551. true,
  552. id() );
  553. if (filterResult == 2) {
  554. // something went horribly wrong (out of space?)
  555. kmkernel->emergencyExit( i18n("Unable to process messages: " ) + TQString::fromLocal8Bit(strerror(errno)));
  556. return 2;
  557. }
  558. if (msg->parent()) { // unGet this msg
  559. int idx = -1;
  560. KMFolder * p = 0;
  561. KMMsgDict::instance()->getLocation( msg, &p, &idx );
  562. assert( p == msg->parent() ); assert( idx >= 0 );
  563. p->unGetMsg( idx );
  564. }
  565. return filterResult;
  566. }
  567. #include "kmacctimap.moc"