00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <kdebug.h>
00031
00032 #ifdef HAVE_CONFIG_H
00033 #include <config.h>
00034 #endif
00035
00036 #include "actionscheduler.h"
00037
00038 #include "filterlog.h"
00039 #include "messageproperty.h"
00040 #include "kmfilter.h"
00041 #include "kmfolderindex.h"
00042 #include "kmfoldermgr.h"
00043 #include "kmmsgdict.h"
00044 #include "kmcommands.h"
00045 #include "kmheaders.h"
00046 #include "accountmanager.h"
00047 using KMail::AccountManager;
00048
00049 #include <qtimer.h>
00050 #include <kconfig.h>
00051 #include <kstandarddirs.h>
00052
00053 using namespace KMail;
00054 typedef QPtrList<KMMsgBase> KMMessageList;
00055
00056
00057 KMFolderMgr* ActionScheduler::tempFolderMgr = 0;
00058 int ActionScheduler::refCount = 0;
00059 int ActionScheduler::count = 0;
00060 QValueList<ActionScheduler*> *ActionScheduler::schedulerList = 0;
00061 bool ActionScheduler::sEnabled = false;
00062 bool ActionScheduler::sEnabledChecked = false;
00063
00064 ActionScheduler::ActionScheduler(KMFilterMgr::FilterSet set,
00065 QValueList<KMFilter*> filters,
00066 KMHeaders *headers,
00067 KMFolder *srcFolder)
00068 :mSet( set ), mHeaders( headers )
00069 {
00070 ++count;
00071 ++refCount;
00072 mExecuting = false;
00073 mExecutingLock = false;
00074 mFetchExecuting = false;
00075 mFiltersAreQueued = false;
00076 mResult = ResultOk;
00077 mIgnore = false;
00078 mAutoDestruct = false;
00079 mAlwaysMatch = false;
00080 mAccountId = 0;
00081 mAccount = false;
00082 lastCommand = 0;
00083 lastJob = 0;
00084 finishTimer = new QTimer( this, "finishTimer" );
00085 connect( finishTimer, SIGNAL(timeout()), this, SLOT(finish()));
00086 fetchMessageTimer = new QTimer( this, "fetchMessageTimer" );
00087 connect( fetchMessageTimer, SIGNAL(timeout()), this, SLOT(fetchMessage()));
00088 tempCloseFoldersTimer = new QTimer( this, "tempCloseFoldersTimer" );
00089 connect( tempCloseFoldersTimer, SIGNAL(timeout()), this, SLOT(tempCloseFolders()));
00090 processMessageTimer = new QTimer( this, "processMessageTimer" );
00091 connect( processMessageTimer, SIGNAL(timeout()), this, SLOT(processMessage()));
00092 filterMessageTimer = new QTimer( this, "filterMessageTimer" );
00093 connect( filterMessageTimer, SIGNAL(timeout()), this, SLOT(filterMessage()));
00094 timeOutTimer = new QTimer( this, "timeOutTimer" );
00095 connect( timeOutTimer, SIGNAL(timeout()), this, SLOT(timeOut()));
00096 fetchTimeOutTimer = new QTimer( this, "fetchTimeOutTimer" );
00097 connect( fetchTimeOutTimer, SIGNAL(timeout()), this, SLOT(fetchTimeOut()));
00098
00099 QValueList<KMFilter*>::Iterator it = filters.begin();
00100 for (; it != filters.end(); ++it)
00101 mFilters.append( **it );
00102 mDestFolder = 0;
00103 if (srcFolder) {
00104 mDeleteSrcFolder = false;
00105 setSourceFolder( srcFolder );
00106 } else {
00107 QString tmpName;
00108 tmpName.setNum( count );
00109 if (!tempFolderMgr)
00110 tempFolderMgr = new KMFolderMgr(locateLocal("data","kmail/filter"));
00111 KMFolder *tempFolder = tempFolderMgr->findOrCreate( tmpName );
00112 tempFolder->expunge();
00113 mDeleteSrcFolder = true;
00114 setSourceFolder( tempFolder );
00115 }
00116 if (!schedulerList)
00117 schedulerList = new QValueList<ActionScheduler*>;
00118 schedulerList->append( this );
00119 }
00120
00121 ActionScheduler::~ActionScheduler()
00122 {
00123 schedulerList->remove( this );
00124 tempCloseFolders();
00125 disconnect( mSrcFolder, SIGNAL(closed()),
00126 this, SLOT(folderClosedOrExpunged()) );
00127 disconnect( mSrcFolder, SIGNAL(expunged(KMFolder*)),
00128 this, SLOT(folderClosedOrExpunged()) );
00129 mSrcFolder->close("actionschedsrc");
00130
00131 if (mDeleteSrcFolder)
00132 tempFolderMgr->remove(mSrcFolder);
00133
00134 --refCount;
00135 if (refCount == 0) {
00136 delete tempFolderMgr;
00137 tempFolderMgr = 0;
00138 }
00139 }
00140
00141 void ActionScheduler::setAutoDestruct( bool autoDestruct )
00142 {
00143 mAutoDestruct = autoDestruct;
00144 }
00145
00146 void ActionScheduler::setAlwaysMatch( bool alwaysMatch )
00147 {
00148 mAlwaysMatch = alwaysMatch;
00149 }
00150
00151 void ActionScheduler::setDefaultDestinationFolder( KMFolder *destFolder )
00152 {
00153 mDestFolder = destFolder;
00154 }
00155
00156 void ActionScheduler::setSourceFolder( KMFolder *srcFolder )
00157 {
00158 srcFolder->open("actionschedsrc");
00159 if (mSrcFolder) {
00160 disconnect( mSrcFolder, SIGNAL(msgAdded(KMFolder*, Q_UINT32)),
00161 this, SLOT(msgAdded(KMFolder*, Q_UINT32)) );
00162 disconnect( mSrcFolder, SIGNAL(closed()),
00163 this, SLOT(folderClosedOrExpunged()) );
00164 disconnect( mSrcFolder, SIGNAL(expunged(KMFolder*)),
00165 this, SLOT(folderClosedOrExpunged()) );
00166 mSrcFolder->close("actionschedsrc");
00167 }
00168 mSrcFolder = srcFolder;
00169 int i = 0;
00170 for (i = 0; i < mSrcFolder->count(); ++i)
00171 enqueue( mSrcFolder->getMsgBase( i )->getMsgSerNum() );
00172 if (mSrcFolder) {
00173 connect( mSrcFolder, SIGNAL(msgAdded(KMFolder*, Q_UINT32)),
00174 this, SLOT(msgAdded(KMFolder*, Q_UINT32)) );
00175 connect( mSrcFolder, SIGNAL(closed()),
00176 this, SLOT(folderClosedOrExpunged()) );
00177 connect( mSrcFolder, SIGNAL(expunged(KMFolder*)),
00178 this, SLOT(folderClosedOrExpunged()) );
00179 }
00180 }
00181
00182 void ActionScheduler::setFilterList( QValueList<KMFilter*> filters )
00183 {
00184 mFiltersAreQueued = true;
00185 mQueuedFilters.clear();
00186
00187 QValueList<KMFilter*>::Iterator it = filters.begin();
00188 for (; it != filters.end(); ++it)
00189 mQueuedFilters.append( **it );
00190 if (!mExecuting) {
00191 mFilters = mQueuedFilters;
00192 mFiltersAreQueued = false;
00193 mQueuedFilters.clear();
00194 }
00195 }
00196
00197 void ActionScheduler::folderClosedOrExpunged()
00198 {
00199
00200 if ( mSrcFolder )
00201 {
00202 mSrcFolder->open( "actionsched" );
00203 }
00204 }
00205
00206 int ActionScheduler::tempOpenFolder( KMFolder* aFolder )
00207 {
00208 assert( aFolder );
00209 tempCloseFoldersTimer->stop();
00210 if ( aFolder == mSrcFolder.operator->() )
00211 return 0;
00212
00213 int rc = aFolder->open("actionsched");
00214 if (rc)
00215 return rc;
00216
00217 mOpenFolders.append( aFolder );
00218 return 0;
00219 }
00220
00221 void ActionScheduler::tempCloseFolders()
00222 {
00223
00224 QValueListConstIterator<QGuardedPtr<KMFolder> > it;
00225 for (it = mOpenFolders.begin(); it != mOpenFolders.end(); ++it) {
00226 KMFolder *folder = *it;
00227 if (folder)
00228 folder->close("actionsched");
00229 }
00230 mOpenFolders.clear();
00231 }
00232
00233 void ActionScheduler::execFilters(const QValueList<Q_UINT32> serNums)
00234 {
00235 QValueListConstIterator<Q_UINT32> it;
00236 for (it = serNums.begin(); it != serNums.end(); ++it)
00237 execFilters( *it );
00238 }
00239
00240 void ActionScheduler::execFilters(const QPtrList<KMMsgBase> msgList)
00241 {
00242 KMMsgBase *msgBase;
00243 QPtrList<KMMsgBase> list = msgList;
00244 for (msgBase = list.first(); msgBase; msgBase = list.next())
00245 execFilters( msgBase->getMsgSerNum() );
00246 }
00247
00248 void ActionScheduler::execFilters(KMMsgBase* msgBase)
00249 {
00250 execFilters( msgBase->getMsgSerNum() );
00251 }
00252
00253 void ActionScheduler::execFilters(Q_UINT32 serNum)
00254 {
00255 if (mResult != ResultOk) {
00256 if ((mResult != ResultCriticalError) &&
00257 !mExecuting && !mExecutingLock && !mFetchExecuting) {
00258 mResult = ResultOk;
00259 if (!mFetchSerNums.isEmpty()) {
00260 mFetchSerNums.push_back( mFetchSerNums.first() );
00261 mFetchSerNums.pop_front();
00262 }
00263 } else
00264 return;
00265 }
00266 if (MessageProperty::filtering( serNum )) {
00267
00268 mResult = ResultError;
00269 if (!mExecuting && !mFetchExecuting)
00270 finishTimer->start( 0, true );
00271 } else {
00272
00273 mFetchSerNums.append( serNum );
00274 if (!mFetchExecuting) {
00275
00276 mFetchExecuting = true;
00277 fetchMessageTimer->start( 0, true );
00278 }
00279 }
00280 }
00281
00282 KMMsgBase *ActionScheduler::messageBase(Q_UINT32 serNum)
00283 {
00284 int idx = -1;
00285 KMFolder *folder = 0;
00286 KMMsgBase *msg = 0;
00287 KMMsgDict::instance()->getLocation( serNum, &folder, &idx );
00288
00289
00290 if (folder && (idx != -1)) {
00291
00292 tempOpenFolder( folder );
00293 msg = folder->getMsgBase( idx );
00294 } else {
00295
00296 mResult = ResultError;
00297 finishTimer->start( 0, true );
00298 }
00299 return msg;
00300 }
00301
00302 KMMessage *ActionScheduler::message(Q_UINT32 serNum)
00303 {
00304 int idx = -1;
00305 KMFolder *folder = 0;
00306 KMMessage *msg = 0;
00307 KMMsgDict::instance()->getLocation( serNum, &folder, &idx );
00308
00309
00310 if (folder && (idx != -1)) {
00311
00312 msg = folder->getMsg( idx );
00313 tempOpenFolder( folder );
00314 } else {
00315
00316 mResult = ResultError;
00317 finishTimer->start( 0, true );
00318 }
00319 return msg;
00320 }
00321
00322 void ActionScheduler::finish()
00323 {
00324 if (mResult != ResultOk) {
00325
00326 emit result( mResult );
00327 return;
00328 }
00329
00330 if (!mExecuting) {
00331
00332 if (!mFetchSerNums.isEmpty()) {
00333
00334
00335
00336 fetchMessageTimer->start( 0, true );
00337 return;
00338 } else {
00339 mFetchExecuting = false;
00340 }
00341
00342 if (mSerNums.begin() != mSerNums.end()) {
00343 mExecuting = true;
00344 processMessageTimer->start( 0, true );
00345 return;
00346 }
00347
00348
00349
00350
00351
00352 if (!mDeleteSrcFolder && !mDestFolder.isNull() ) {
00353 while ( mSrcFolder->count() > 0 ) {
00354 KMMessage *msg = mSrcFolder->getMsg( 0 );
00355 mDestFolder->moveMsg( msg );
00356 }
00357
00358
00359
00360 tempCloseFoldersTimer->start( 60*1000, true );
00361 }
00362 mSerNums.clear();
00363 mFetchSerNums.clear();
00364
00365 if (mFiltersAreQueued)
00366 mFilters = mQueuedFilters;
00367 mQueuedFilters.clear();
00368 mFiltersAreQueued = false;
00369 ReturnCode aResult = mResult;
00370 mResult = ResultOk;
00371 mExecutingLock = false;
00372 emit result( aResult );
00373 if (mAutoDestruct)
00374 delete this;
00375 }
00376
00377
00378
00379 }
00380
00381 void ActionScheduler::fetchMessage()
00382 {
00383 QValueListIterator<Q_UINT32> mFetchMessageIt = mFetchSerNums.begin();
00384 while (mFetchMessageIt != mFetchSerNums.end()) {
00385 if (!MessageProperty::transferInProgress(*mFetchMessageIt))
00386 break;
00387 ++mFetchMessageIt;
00388 }
00389
00390
00391
00392
00393
00394 if (mFetchMessageIt == mFetchSerNums.end() && !mFetchSerNums.isEmpty()) {
00395 mResult = ResultError;
00396 }
00397 if ((mFetchMessageIt == mFetchSerNums.end()) || (mResult != ResultOk)) {
00398 mFetchExecuting = false;
00399 if (!mSrcFolder->count())
00400 mSrcFolder->expunge();
00401 finishTimer->start( 0, true );
00402 return;
00403 }
00404
00405
00406 KMMsgBase *msgBase = messageBase( *mFetchMessageIt );
00407
00408 if ((mResult != ResultOk) || (!msgBase)) {
00409 mFetchExecuting = false;
00410 return;
00411 }
00412 mFetchUnget = msgBase->isMessage();
00413 KMMessage *msg = message( *mFetchMessageIt );
00414 if (mResult != ResultOk) {
00415 mFetchExecuting = false;
00416 return;
00417 }
00418
00419 if (msg && msg->isComplete()) {
00420 messageFetched( msg );
00421 } else if (msg) {
00422 fetchTimeOutTime = QTime::currentTime();
00423 fetchTimeOutTimer->start( 60 * 1000, true );
00424 FolderJob *job = msg->parent()->createJob( msg );
00425 connect( job, SIGNAL(messageRetrieved( KMMessage* )),
00426 SLOT(messageFetched( KMMessage* )) );
00427 lastJob = job;
00428 job->start();
00429 } else {
00430 mFetchExecuting = false;
00431 mResult = ResultError;
00432 finishTimer->start( 0, true );
00433 return;
00434 }
00435 }
00436
00437 void ActionScheduler::messageFetched( KMMessage *msg )
00438 {
00439 fetchTimeOutTimer->stop();
00440 if (!msg) {
00441
00442 fetchMessageTimer->start( 0, true );
00443 return;
00444 }
00445
00446 mFetchSerNums.remove( msg->getMsgSerNum() );
00447
00448
00449
00450
00451 if ((mSet & KMFilterMgr::Explicit) ||
00452 (msg->headerField( "X-KMail-Filtered" ).isEmpty())) {
00453 QString serNumS;
00454 serNumS.setNum( msg->getMsgSerNum() );
00455 KMMessage *newMsg = new KMMessage;
00456 newMsg->fromString(msg->asString());
00457 newMsg->setStatus(msg->status());
00458 newMsg->setComplete(msg->isComplete());
00459 newMsg->setHeaderField( "X-KMail-Filtered", serNumS );
00460 mSrcFolder->addMsg( newMsg );
00461 } else {
00462 fetchMessageTimer->start( 0, true );
00463 }
00464 if (mFetchUnget && msg->parent())
00465 msg->parent()->unGetMsg( msg->parent()->find( msg ));
00466 return;
00467 }
00468
00469 void ActionScheduler::msgAdded( KMFolder*, Q_UINT32 serNum )
00470 {
00471 if (!mIgnore)
00472 enqueue( serNum );
00473 }
00474
00475 void ActionScheduler::enqueue(Q_UINT32 serNum)
00476 {
00477 if (mResult != ResultOk)
00478 return;
00479
00480 if (MessageProperty::filtering( serNum )) {
00481
00482 mResult = ResultError;
00483 if (!mExecuting && !mFetchExecuting)
00484 finishTimer->start( 0, true );
00485 } else {
00486
00487 mSerNums.append( serNum );
00488
00489 if (!mExecuting) {
00490
00491
00492 mExecuting = true;
00493 mMessageIt = mSerNums.begin();
00494 processMessageTimer->start( 0, true );
00495 }
00496 }
00497 }
00498
00499 void ActionScheduler::processMessage()
00500 {
00501 if (mExecutingLock)
00502 return;
00503 mExecutingLock = true;
00504 mMessageIt = mSerNums.begin();
00505 while (mMessageIt != mSerNums.end()) {
00506 if (!MessageProperty::transferInProgress(*mMessageIt))
00507 break;
00508 ++mMessageIt;
00509 }
00510
00511 if (mMessageIt == mSerNums.end() && !mSerNums.isEmpty()) {
00512 mExecuting = false;
00513 processMessageTimer->start( 600, true );
00514 }
00515
00516 if ((mMessageIt == mSerNums.end()) || (mResult != ResultOk)) {
00517 mExecutingLock = false;
00518 mExecuting = false;
00519 finishTimer->start( 0, true );
00520 return;
00521 }
00522
00523
00524 KMMsgBase *msgBase = messageBase( *mMessageIt );
00525 if (!msgBase || mResult != ResultOk) {
00526 mExecuting = false;
00527 return;
00528 }
00529
00530 MessageProperty::setFiltering( *mMessageIt, true );
00531 MessageProperty::setFilterHandler( *mMessageIt, this );
00532 MessageProperty::setFilterFolder( *mMessageIt, mDestFolder );
00533 if ( FilterLog::instance()->isLogging() ) {
00534 FilterLog::instance()->addSeparator();
00535 }
00536 mFilterIt = mFilters.begin();
00537
00538 mUnget = msgBase->isMessage();
00539 KMMessage *msg = message( *mMessageIt );
00540 if (mResult != ResultOk) {
00541 mExecuting = false;
00542 return;
00543 }
00544
00545 bool mdnEnabled = true;
00546 {
00547 KConfigGroup mdnConfig( kmkernel->config(), "MDN" );
00548 int mode = mdnConfig.readNumEntry( "default-policy", 0 );
00549 if (!mode || mode < 0 || mode > 3)
00550 mdnEnabled = false;
00551 }
00552 mdnEnabled = true;
00553
00554 if ((msg && msg->isComplete()) ||
00555 (msg && !(*mFilterIt).requiresBody(msg) && !mdnEnabled))
00556 {
00557
00558
00559
00560 msg->setTransferInProgress( true );
00561 filterMessageTimer->start( 0, true );
00562 return;
00563 }
00564 if (msg) {
00565 FolderJob *job = msg->parent()->createJob( msg );
00566 connect( job, SIGNAL(messageRetrieved( KMMessage* )),
00567 SLOT(messageRetrieved( KMMessage* )) );
00568 job->start();
00569 } else {
00570 mExecuting = false;
00571 mResult = ResultError;
00572 finishTimer->start( 0, true );
00573 return;
00574 }
00575 }
00576
00577 void ActionScheduler::messageRetrieved(KMMessage* msg)
00578 {
00579
00580 msg->setTransferInProgress( true );
00581 filterMessageTimer->start( 0, true );
00582 }
00583
00584 void ActionScheduler::filterMessage()
00585 {
00586 if (mFilterIt == mFilters.end()) {
00587 moveMessage();
00588 return;
00589 }
00590 if (((mSet & KMFilterMgr::Outbound) && (*mFilterIt).applyOnOutbound()) ||
00591 ((mSet & KMFilterMgr::Inbound) && (*mFilterIt).applyOnInbound() &&
00592 (!mAccount ||
00593 (mAccount && (*mFilterIt).applyOnAccount(mAccountId)))) ||
00594 ((mSet & KMFilterMgr::Explicit) && (*mFilterIt).applyOnExplicit())) {
00595
00596
00597 if ( FilterLog::instance()->isLogging() ) {
00598 QString logText( i18n( "<b>Evaluating filter rules:</b> " ) );
00599 logText.append( (*mFilterIt).pattern()->asString() );
00600 FilterLog::instance()->add( logText, FilterLog::patternDesc );
00601 }
00602 if (mAlwaysMatch ||
00603 (*mFilterIt).pattern()->matches( *mMessageIt )) {
00604 if ( FilterLog::instance()->isLogging() ) {
00605 FilterLog::instance()->add( i18n( "<b>Filter rules have matched.</b>" ),
00606 FilterLog::patternResult );
00607 }
00608 mFilterAction = (*mFilterIt).actions()->first();
00609 actionMessage();
00610 return;
00611 }
00612 }
00613 ++mFilterIt;
00614 filterMessageTimer->start( 0, true );
00615 }
00616
00617 void ActionScheduler::actionMessage(KMFilterAction::ReturnCode res)
00618 {
00619 if (res == KMFilterAction::CriticalError) {
00620 mResult = ResultCriticalError;
00621 finish();
00622 }
00623 if (mFilterAction) {
00624 KMMessage *msg = message( *mMessageIt );
00625 if (msg) {
00626 if ( FilterLog::instance()->isLogging() ) {
00627 QString logText( i18n( "<b>Applying filter action:</b> %1" )
00628 .arg( mFilterAction->displayString() ) );
00629 FilterLog::instance()->add( logText, FilterLog::appliedAction );
00630 }
00631 KMFilterAction *action = mFilterAction;
00632 mFilterAction = (*mFilterIt).actions()->next();
00633 action->processAsync( msg );
00634 }
00635 } else {
00636
00637 if ((*mFilterIt).stopProcessingHere())
00638 mFilterIt = mFilters.end();
00639 else
00640 ++mFilterIt;
00641 filterMessageTimer->start( 0, true );
00642 }
00643 }
00644
00645 void ActionScheduler::moveMessage()
00646 {
00647 KMMsgBase *msgBase = messageBase( *mMessageIt );
00648 if (!msgBase)
00649 return;
00650
00651 MessageProperty::setTransferInProgress( *mMessageIt, false, true );
00652 KMMessage *msg = message( *mMessageIt );
00653 KMFolder *folder = MessageProperty::filterFolder( *mMessageIt );
00654 QString serNumS = msg->headerField( "X-KMail-Filtered" );
00655 if (!serNumS.isEmpty())
00656 mOriginalSerNum = serNumS.toUInt();
00657 else
00658 mOriginalSerNum = 0;
00659 MessageProperty::setFilterHandler( *mMessageIt, 0 );
00660 MessageProperty::setFiltering( *mMessageIt, false );
00661 mSerNums.remove( *mMessageIt );
00662
00663 KMMessage *orgMsg = 0;
00664 ReturnCode mOldReturnCode = mResult;
00665 if (mOriginalSerNum)
00666 orgMsg = message( mOriginalSerNum );
00667 mResult = mOldReturnCode;
00668 if (!orgMsg || !orgMsg->parent()) {
00669
00670 mSrcFolder->removeMsg( mSrcFolder->find( msg ) );
00671 kdDebug(5006) << "The original serial number is missing. "
00672 << "Cannot complete the filtering." << endl;
00673 mExecutingLock = false;
00674 processMessageTimer->start( 0, true );
00675 return;
00676 } else {
00677 if (!folder)
00678 folder = orgMsg->parent();
00679 }
00680
00681 mIgnore = true;
00682 assert( msg->parent() == mSrcFolder.operator->() );
00683 mSrcFolder->take( mSrcFolder->find( msg ) );
00684 mSrcFolder->addMsg( msg );
00685 mIgnore = false;
00686
00687 if (msg && folder && kmkernel->folderIsTrash( folder ))
00688 KMFilterAction::sendMDN( msg, KMime::MDN::Deleted );
00689
00690 timeOutTime = QTime::currentTime();
00691 KMCommand *cmd = new KMMoveCommand( folder, msg );
00692 connect( cmd, SIGNAL( completed( KMCommand * ) ),
00693 this, SLOT( moveMessageFinished( KMCommand * ) ) );
00694 cmd->start();
00695
00696
00697 lastCommand = cmd;
00698 timeOutTimer->start( 60 * 1000, true );
00699 }
00700
00701 void ActionScheduler::moveMessageFinished( KMCommand *command )
00702 {
00703 timeOutTimer->stop();
00704 if ( command->result() != KMCommand::OK )
00705 mResult = ResultError;
00706
00707 if (!mSrcFolder->count())
00708 mSrcFolder->expunge();
00709
00710
00711 if ( mHeaders )
00712 mHeaders->clearSelectableAndAboutToBeDeleted( mOriginalSerNum );
00713 KMMessage *msg = 0;
00714 ReturnCode mOldReturnCode = mResult;
00715 if (mOriginalSerNum) {
00716 msg = message( mOriginalSerNum );
00717 emit filtered( mOriginalSerNum );
00718 }
00719
00720 mResult = mOldReturnCode;
00721 KMCommand *cmd = 0;
00722 if (msg && msg->parent()) {
00723 cmd = new KMMoveCommand( 0, msg );
00724
00725 }
00726
00727 if (mResult == ResultOk) {
00728 mExecutingLock = false;
00729 if (cmd)
00730 connect( cmd, SIGNAL( completed( KMCommand * ) ),
00731 this, SLOT( processMessage() ) );
00732 else
00733 processMessageTimer->start( 0, true );
00734 } else {
00735
00736
00737 if (cmd)
00738 connect( cmd, SIGNAL( completed( KMCommand * ) ),
00739 this, SLOT( finish() ) );
00740 else
00741 finishTimer->start( 0, true );
00742 }
00743 if (cmd)
00744 cmd->start();
00745
00746 }
00747
00748 void ActionScheduler::copyMessageFinished( KMCommand *command )
00749 {
00750 if ( command->result() != KMCommand::OK )
00751 actionMessage( KMFilterAction::ErrorButGoOn );
00752 else
00753 actionMessage();
00754 }
00755
00756 void ActionScheduler::timeOut()
00757 {
00758
00759 assert( lastCommand );
00760
00761 disconnect( lastCommand, SIGNAL( completed( KMCommand * ) ),
00762 this, SLOT( moveMessageFinished( KMCommand * ) ) );
00763 lastCommand = 0;
00764 mExecutingLock = false;
00765 mExecuting = false;
00766 finishTimer->start( 0, true );
00767 if (mOriginalSerNum)
00768 execFilters( mOriginalSerNum );
00769 }
00770
00771 void ActionScheduler::fetchTimeOut()
00772 {
00773
00774 assert( lastJob );
00775
00776 disconnect( lastJob, SIGNAL(messageRetrieved( KMMessage* )),
00777 this, SLOT(messageFetched( KMMessage* )) );
00778 lastJob->kill();
00779 lastJob = 0;
00780 fetchMessageTimer->start( 0, true );
00781 }
00782
00783 QString ActionScheduler::debug()
00784 {
00785 QString res;
00786 QValueList<ActionScheduler*>::iterator it;
00787 int i = 1;
00788 for ( it = schedulerList->begin(); it != schedulerList->end(); ++it ) {
00789 res.append( QString( "ActionScheduler #%1.\n" ).arg( i ) );
00790 if ((*it)->mAccount && kmkernel->find( (*it)->mAccountId )) {
00791 res.append( QString( "Account %1, Name %2.\n" )
00792 .arg( (*it)->mAccountId )
00793 .arg( kmkernel->acctMgr()->find( (*it)->mAccountId )->name() ) );
00794 }
00795 res.append( QString( "mExecuting %1, " ).arg( (*it)->mExecuting ? "true" : "false" ) );
00796 res.append( QString( "mExecutingLock %1, " ).arg( (*it)->mExecutingLock ? "true" : "false" ) );
00797 res.append( QString( "mFetchExecuting %1.\n" ).arg( (*it)->mFetchExecuting ? "true" : "false" ) );
00798 res.append( QString( "mOriginalSerNum %1.\n" ).arg( (*it)->mOriginalSerNum ) );
00799 res.append( QString( "mMessageIt %1.\n" ).arg( ((*it)->mMessageIt != 0) ? *(*it)->mMessageIt : 0 ) );
00800 res.append( QString( "mSerNums count %1, " ).arg( (*it)->mSerNums.count() ) );
00801 res.append( QString( "mFetchSerNums count %1.\n" ).arg( (*it)->mFetchSerNums.count() ) );
00802 res.append( QString( "mResult " ) );
00803 if ((*it)->mResult == ResultOk)
00804 res.append( QString( "ResultOk.\n" ) );
00805 else if ((*it)->mResult == ResultError)
00806 res.append( QString( "ResultError.\n" ) );
00807 else if ((*it)->mResult == ResultCriticalError)
00808 res.append( QString( "ResultCriticalError.\n" ) );
00809 else
00810 res.append( QString( "Unknown.\n" ) );
00811
00812 ++i;
00813 }
00814 return res;
00815 }
00816
00817 bool ActionScheduler::isEnabled()
00818 {
00819 if (sEnabledChecked)
00820 return sEnabled;
00821
00822 sEnabledChecked = true;
00823 KConfig* config = KMKernel::config();
00824 KConfigGroupSaver saver(config, "General");
00825 sEnabled = config->readBoolEntry("action-scheduler", false);
00826 return sEnabled;
00827 }
00828
00829 bool ActionScheduler::ignoreChanges( bool ignore )
00830 {
00831 bool oldValue = mIgnore;
00832 mIgnore = ignore;
00833 return oldValue;
00834 }
00835
00836 #include "actionscheduler.moc"