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
00031
00032 #ifdef HAVE_CONFIG_H
00033 #include <config.h>
00034 #endif
00035
00036 #include "imapjob.h"
00037 #include "kmfolderimap.h"
00038 #include "kmfolder.h"
00039 #include "kmmsgpart.h"
00040 #include "progressmanager.h"
00041 using KPIM::ProgressManager;
00042 #include "util.h"
00043
00044 #include <qstylesheet.h>
00045 #include <kio/scheduler.h>
00046 #include <kdebug.h>
00047 #include <klocale.h>
00048 #include <mimelib/body.h>
00049 #include <mimelib/bodypart.h>
00050 #include <mimelib/string.h>
00051
00052
00053 namespace KMail {
00054
00055
00056 ImapJob::ImapJob( KMMessage *msg, JobType jt, KMFolderImap* folder,
00057 QString partSpecifier, const AttachmentStrategy *as )
00058 : FolderJob( msg, jt, folder? folder->folder() : 0, partSpecifier ),
00059 mAttachmentStrategy( as ), mParentProgressItem(0)
00060 {
00061 }
00062
00063
00064 ImapJob::ImapJob( QPtrList<KMMessage>& msgList, QString sets, JobType jt,
00065 KMFolderImap* folder )
00066 : FolderJob( msgList, sets, jt, folder? folder->folder() : 0 ),
00067 mAttachmentStrategy ( 0 ), mParentProgressItem(0)
00068 {
00069 }
00070
00071 void ImapJob::init( JobType jt, QString sets, KMFolderImap* folder,
00072 QPtrList<KMMessage>& msgList )
00073 {
00074 mJob = 0;
00075
00076 assert(jt == tGetMessage || folder);
00077 KMMessage* msg = msgList.first();
00078
00079 if ( !msg ) {
00080 deleteLater();
00081 return;
00082 }
00083 mType = jt;
00084 mDestFolder = folder? folder->folder() : 0;
00085
00086 if (folder) {
00087 folder->open();
00088 }
00089 KMFolder *msg_parent = msg->parent();
00090 if (msg_parent) {
00091 if (!folder || folder!= msg_parent->storage()) {
00092 msg_parent->open();
00093 }
00094 }
00095 mSrcFolder = msg_parent;
00096
00097
00098
00099
00100 KMAcctImap *account;
00101 if (folder) {
00102 account = folder->account();
00103 } else {
00104 account = static_cast<KMFolderImap*>(msg_parent->storage())->account();
00105 }
00106 if ( !account ||
00107 account->makeConnection() == ImapAccountBase::Error ) {
00108 deleteLater();
00109 return;
00110 }
00111 account->mJobList.append( this );
00112 if ( jt == tPutMessage )
00113 {
00114
00115 QPtrListIterator<KMMessage> it( msgList );
00116 KMMessage* curMsg;
00117 while ( ( curMsg = it.current() ) != 0 )
00118 {
00119 ++it;
00120 if ( mSrcFolder && !curMsg->isMessage() )
00121 {
00122 int idx = mSrcFolder->find( curMsg );
00123 curMsg = mSrcFolder->getMsg( idx );
00124 }
00125 KURL url = account->getUrl();
00126 QString flags = KMFolderImap::statusToFlags( curMsg->status() );
00127 url.setPath( folder->imapPath() + ";SECTION=" + flags );
00128 ImapAccountBase::jobData jd;
00129 jd.parent = 0; jd.offset = 0; jd.done = 0;
00130 jd.total = ( curMsg->msgSizeServer() > 0 ) ?
00131 curMsg->msgSizeServer() : curMsg->msgSize();
00132 jd.msgList.append( curMsg );
00133 QCString cstr( curMsg->asString() );
00134 int a = cstr.find("\nX-UID: ");
00135 int b = cstr.find('\n', a);
00136 if (a != -1 && b != -1 && cstr.find("\n\n") > a) cstr.remove(a, b-a);
00137 jd.data.resize( cstr.length() + cstr.contains( "\n" ) - cstr.contains( "\r\n" ) );
00138 unsigned int i = 0;
00139 char prevChar = '\0';
00140
00141 for ( char *ch = cstr.data(); *ch; ch++ )
00142 {
00143 if ( *ch == '\n' && (prevChar != '\r') ) {
00144 jd.data.at( i ) = '\r';
00145 i++;
00146 }
00147 jd.data.at( i ) = *ch;
00148 prevChar = *ch;
00149 i++;
00150 }
00151 jd.progressItem = ProgressManager::createProgressItem(
00152 mParentProgressItem,
00153 "ImapJobUploading"+ProgressManager::getUniqueID(),
00154 i18n("Uploading message data"),
00155 curMsg->subject(),
00156 true,
00157 account->useSSL() || account->useTLS() );
00158 jd.progressItem->setTotalItems( jd.total );
00159 connect ( jd.progressItem, SIGNAL( progressItemCanceled( KPIM::ProgressItem*)),
00160 account, SLOT( slotAbortRequested( KPIM::ProgressItem* ) ) );
00161 KIO::SimpleJob *job = KIO::put( url, 0, FALSE, FALSE, FALSE );
00162 KIO::Scheduler::assignJobToSlave( account->slave(), job );
00163 account->insertJob( job, jd );
00164 connect( job, SIGNAL(result(KIO::Job *)),
00165 SLOT(slotPutMessageResult(KIO::Job *)) );
00166 connect( job, SIGNAL(dataReq(KIO::Job *, QByteArray &)),
00167 SLOT(slotPutMessageDataReq(KIO::Job *, QByteArray &)) );
00168 connect( job, SIGNAL(infoMessage(KIO::Job *, const QString &)),
00169 SLOT(slotPutMessageInfoData(KIO::Job *, const QString &)) );
00170 connect( job, SIGNAL(processedSize(KIO::Job *, KIO::filesize_t)),
00171 SLOT(slotProcessedSize(KIO::Job *, KIO::filesize_t)));
00172 }
00173 }
00174 else if ( jt == tCopyMessage || jt == tMoveMessage )
00175 {
00176 KURL url = account->getUrl();
00177 KURL destUrl = account->getUrl();
00178 destUrl.setPath(folder->imapPath());
00179 KMFolderImap *imapDestFolder = static_cast<KMFolderImap*>(msg_parent->storage());
00180 url.setPath( imapDestFolder->imapPath() + ";UID=" + sets );
00181 ImapAccountBase::jobData jd;
00182 jd.parent = 0; jd.offset = 0;
00183 jd.total = 1; jd.done = 0;
00184 jd.msgList = msgList;
00185
00186 QByteArray packedArgs;
00187 QDataStream stream( packedArgs, IO_WriteOnly );
00188
00189 stream << (int) 'C' << url << destUrl;
00190 jd.progressItem = ProgressManager::createProgressItem(
00191 mParentProgressItem,
00192 "ImapJobCopyMove"+ProgressManager::getUniqueID(),
00193 i18n("Server operation"),
00194 i18n("Source folder: %1 - Destination folder: %2")
00195 .arg( msg_parent->prettyURL(),
00196 mDestFolder->prettyURL() ),
00197 true,
00198 account->useSSL() || account->useTLS() );
00199 jd.progressItem->setTotalItems( jd.total );
00200 connect ( jd.progressItem, SIGNAL(progressItemCanceled(KPIM::ProgressItem*)),
00201 account, SLOT( slotAbortRequested(KPIM::ProgressItem* ) ) );
00202 KIO::SimpleJob *simpleJob = KIO::special( url, packedArgs, FALSE );
00203 KIO::Scheduler::assignJobToSlave( account->slave(), simpleJob );
00204 mJob = simpleJob;
00205 account->insertJob( mJob, jd );
00206 connect( mJob, SIGNAL(result(KIO::Job *)),
00207 SLOT(slotCopyMessageResult(KIO::Job *)) );
00208 if ( jt == tMoveMessage )
00209 {
00210 connect( mJob, SIGNAL(infoMessage(KIO::Job *, const QString &)),
00211 SLOT(slotCopyMessageInfoData(KIO::Job *, const QString &)) );
00212 }
00213 }
00214 else {
00215 slotGetNextMessage();
00216 }
00217 }
00218
00219
00220
00221 ImapJob::~ImapJob()
00222 {
00223 if ( mDestFolder )
00224 {
00225 KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
00226 if ( account && mJob ) {
00227 ImapAccountBase::JobIterator it = account->findJob( mJob );
00228 if ( it != account->jobsEnd() ) {
00229 if( (*it).progressItem ) {
00230 (*it).progressItem->setComplete();
00231 (*it).progressItem = 0;
00232 }
00233 if ( !(*it).msgList.isEmpty() ) {
00234 for ( QPtrListIterator<KMMessage> mit( (*it).msgList ); mit.current(); ++mit )
00235 mit.current()->setTransferInProgress( false );
00236 }
00237 }
00238 account->removeJob( mJob );
00239 }
00240 account->mJobList.remove( this );
00241 mDestFolder->close();
00242 }
00243
00244 if ( mSrcFolder ) {
00245 if (!mDestFolder || mDestFolder != mSrcFolder) {
00246 if (! (mSrcFolder->folderType() == KMFolderTypeImap) ) return;
00247 KMAcctImap *account = static_cast<KMFolderImap*>(mSrcFolder->storage())->account();
00248 if ( account && mJob ) {
00249 ImapAccountBase::JobIterator it = account->findJob( mJob );
00250 if ( it != account->jobsEnd() ) {
00251 if( (*it).progressItem ) {
00252 (*it).progressItem->setComplete();
00253 (*it).progressItem = 0;
00254 }
00255 if ( !(*it).msgList.isEmpty() ) {
00256 for ( QPtrListIterator<KMMessage> mit( (*it).msgList ); mit.current(); ++mit )
00257 mit.current()->setTransferInProgress( false );
00258 }
00259 }
00260 account->removeJob( mJob );
00261 }
00262 account->mJobList.remove( this );
00263 }
00264 mSrcFolder->close();
00265 }
00266 }
00267
00268
00269
00270 void ImapJob::slotGetNextMessage()
00271 {
00272 KMMessage *msg = mMsgList.first();
00273 KMFolderImap *msgParent = static_cast<KMFolderImap*>(msg->storage());
00274 KMAcctImap *account = msgParent->account();
00275 if ( msg->UID() == 0 )
00276 {
00277
00278 emit messageRetrieved( 0 );
00279 deleteLater();
00280 return;
00281 }
00282 KURL url = account->getUrl();
00283 QString path = msgParent->imapPath() + ";UID=" + QString::number(msg->UID());
00284 ImapAccountBase::jobData jd;
00285 jd.parent = 0; jd.offset = 0;
00286 jd.total = 1; jd.done = 0;
00287 jd.msgList.append( msg );
00288 if ( !mPartSpecifier.isEmpty() )
00289 {
00290 if ( mPartSpecifier.find ("STRUCTURE", 0, false) != -1 ) {
00291 path += ";SECTION=STRUCTURE";
00292 } else if ( mPartSpecifier == "HEADER" ) {
00293 path += ";SECTION=HEADER";
00294 } else {
00295 path += ";SECTION=BODY.PEEK[" + mPartSpecifier + "]";
00296 DwBodyPart * part = msg->findDwBodyPart( msg->getFirstDwBodyPart(), mPartSpecifier );
00297 if (part)
00298 jd.total = part->BodySize();
00299 }
00300 } else {
00301 path += ";SECTION=BODY.PEEK[]";
00302 if (msg->msgSizeServer() > 0)
00303 jd.total = msg->msgSizeServer();
00304 }
00305 url.setPath( path );
00306
00307
00308 msg->setTransferInProgress( true );
00309 const QString escapedSubject = QStyleSheet::escape( msg->subject() );
00310 jd.progressItem = ProgressManager::createProgressItem(
00311 mParentProgressItem,
00312 "ImapJobDownloading"+ProgressManager::getUniqueID(),
00313 i18n("Downloading message data"),
00314 i18n("Message with subject: ") + escapedSubject,
00315 true,
00316 account->useSSL() || account->useTLS() );
00317 connect ( jd.progressItem, SIGNAL( progressItemCanceled( KPIM::ProgressItem*)),
00318 account, SLOT( slotAbortRequested( KPIM::ProgressItem* ) ) );
00319 jd.progressItem->setTotalItems( jd.total );
00320
00321 KIO::SimpleJob *simpleJob = KIO::get( url, FALSE, FALSE );
00322 KIO::Scheduler::assignJobToSlave( account->slave(), simpleJob );
00323 mJob = simpleJob;
00324 account->insertJob( mJob, jd );
00325 if ( mPartSpecifier.find( "STRUCTURE", 0, false ) != -1 )
00326 {
00327 connect( mJob, SIGNAL(result(KIO::Job *)),
00328 this, SLOT(slotGetBodyStructureResult(KIO::Job *)) );
00329 } else {
00330 connect( mJob, SIGNAL(result(KIO::Job *)),
00331 this, SLOT(slotGetMessageResult(KIO::Job *)) );
00332 }
00333 connect( mJob, SIGNAL(data(KIO::Job *, const QByteArray &)),
00334 msgParent, SLOT(slotSimpleData(KIO::Job *, const QByteArray &)) );
00335 if ( jd.total > 1 )
00336 {
00337 connect(mJob, SIGNAL(processedSize(KIO::Job *, KIO::filesize_t)),
00338 this, SLOT(slotProcessedSize(KIO::Job *, KIO::filesize_t)));
00339 }
00340 }
00341
00342
00343
00344 void ImapJob::slotGetMessageResult( KIO::Job * job )
00345 {
00346 KMMessage *msg = mMsgList.first();
00347 if (!msg || !msg->parent() || !job) {
00348 emit messageRetrieved( 0 );
00349 deleteLater();
00350 return;
00351 }
00352 KMFolderImap* parent = static_cast<KMFolderImap*>(msg->storage());
00353 if (msg->transferInProgress())
00354 msg->setTransferInProgress( false );
00355 KMAcctImap *account = parent->account();
00356 if ( !account ) {
00357 emit messageRetrieved( 0 );
00358 deleteLater();
00359 return;
00360 }
00361 ImapAccountBase::JobIterator it = account->findJob( job );
00362 if ( it == account->jobsEnd() ) return;
00363
00364 bool gotData = true;
00365 if (job->error())
00366 {
00367 QString errorStr = i18n( "Error while retrieving messages from the server." );
00368 if ( (*it).progressItem )
00369 (*it).progressItem->setStatus( errorStr );
00370 account->handleJobError( job, errorStr );
00371 return;
00372 } else {
00373 if ((*it).data.size() > 0)
00374 {
00375 kdDebug(5006) << "ImapJob::slotGetMessageResult - retrieved part " << mPartSpecifier << endl;
00376 if ( mPartSpecifier.isEmpty() ||
00377 mPartSpecifier == "HEADER" )
00378 {
00379 uint size = msg->msgSizeServer();
00380 if ( size > 0 && mPartSpecifier.isEmpty() )
00381 (*it).done = size;
00382 ulong uid = msg->UID();
00383
00384 if ( mPartSpecifier.isEmpty() )
00385 msg->setComplete( true );
00386 else
00387 msg->setReadyToShow( false );
00388
00389
00390 size_t dataSize = (*it).data.size();
00391 dataSize = Util::crlf2lf( (*it).data.data(), dataSize );
00392 (*it).data.resize( dataSize );
00393
00394
00395
00396
00397 msg->parent()->storage()->blockSignals( true );
00398 msg->fromByteArray( (*it).data );
00399
00400 msg->parent()->storage()->blockSignals( false );
00401 if ( size > 0 && msg->msgSizeServer() == 0 ) {
00402 msg->setMsgSizeServer(size);
00403 }
00404
00405 msg->setUID(uid);
00406
00407 } else {
00408
00409 size_t dataSize = (*it).data.size();
00410 dataSize = Util::crlf2lf( (*it).data.data(), dataSize );
00411 (*it).data.resize( dataSize );
00412
00413
00414 msg->updateBodyPart( mPartSpecifier, (*it).data );
00415 msg->setReadyToShow( true );
00416
00417
00418 if (msg->attachmentState() != KMMsgHasAttachment)
00419 msg->updateAttachmentState();
00420 }
00421 } else {
00422 kdDebug(5006) << "ImapJob::slotGetMessageResult - got no data for " << mPartSpecifier << endl;
00423 gotData = false;
00424 msg->setReadyToShow( true );
00425
00426 msg->notify();
00427 }
00428 }
00429 if (account->slave()) {
00430 account->removeJob(it);
00431 account->mJobList.remove(this);
00432 }
00433
00434
00435 if ( mPartSpecifier.isEmpty() ||
00436 mPartSpecifier == "HEADER" )
00437 {
00438 if ( gotData )
00439 emit messageRetrieved(msg);
00440 else
00441 {
00442
00443
00444 emit messageRetrieved( 0 );
00445 parent->ignoreJobsForMessage( msg );
00446 int idx = parent->find( msg );
00447 if (idx != -1) parent->removeMsg( idx, true );
00448
00449
00450 return;
00451 }
00452 } else {
00453 emit messageUpdated(msg, mPartSpecifier);
00454 }
00455 deleteLater();
00456 }
00457
00458
00459 void ImapJob::slotGetBodyStructureResult( KIO::Job * job )
00460 {
00461 KMMessage *msg = mMsgList.first();
00462 if (!msg || !msg->parent() || !job) {
00463 deleteLater();
00464 return;
00465 }
00466 KMFolderImap* parent = static_cast<KMFolderImap*>(msg->storage());
00467 if (msg->transferInProgress())
00468 msg->setTransferInProgress( false );
00469 KMAcctImap *account = parent->account();
00470 if ( !account ) {
00471 deleteLater();
00472 return;
00473 }
00474 ImapAccountBase::JobIterator it = account->findJob( job );
00475 if ( it == account->jobsEnd() ) return;
00476
00477
00478 if (job->error())
00479 {
00480 account->handleJobError( job, i18n( "Error while retrieving information on the structure of a message." ) );
00481 return;
00482 } else {
00483 if ((*it).data.size() > 0)
00484 {
00485 QDataStream stream( (*it).data, IO_ReadOnly );
00486 account->handleBodyStructure(stream, msg, mAttachmentStrategy);
00487 }
00488 }
00489 if (account->slave()) {
00490 account->removeJob(it);
00491 account->mJobList.remove(this);
00492 }
00493 deleteLater();
00494 }
00495
00496
00497 void ImapJob::slotPutMessageDataReq( KIO::Job *job, QByteArray &data )
00498 {
00499 KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
00500 ImapAccountBase::JobIterator it = account->findJob( job );
00501 if ( it == account->jobsEnd() ) return;
00502
00503 if ((*it).data.size() - (*it).offset > 0x8000)
00504 {
00505 data.duplicate((*it).data.data() + (*it).offset, 0x8000);
00506 (*it).offset += 0x8000;
00507 }
00508 else if ((*it).data.size() - (*it).offset > 0)
00509 {
00510 data.duplicate((*it).data.data() + (*it).offset, (*it).data.size() - (*it).offset);
00511 (*it).offset = (*it).data.size();
00512 } else data.resize(0);
00513 }
00514
00515
00516
00517 void ImapJob::slotPutMessageResult( KIO::Job *job )
00518 {
00519 KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
00520 ImapAccountBase::JobIterator it = account->findJob( job );
00521 if ( it == account->jobsEnd() ) return;
00522 bool deleteMe = false;
00523 if (job->error())
00524 {
00525 if ( (*it).progressItem )
00526 (*it).progressItem->setStatus( i18n("Uploading message data failed.") );
00527 account->handlePutError( job, *it, mDestFolder );
00528 return;
00529 } else {
00530 if ( (*it).progressItem )
00531 (*it).progressItem->setStatus( i18n("Uploading message data completed.") );
00532 if ( mParentProgressItem )
00533 {
00534 mParentProgressItem->incCompletedItems();
00535 mParentProgressItem->updateProgress();
00536 }
00537 KMMessage *msg = (*it).msgList.first();
00538 emit messageStored( msg );
00539 if ( msg == mMsgList.getLast() )
00540 {
00541 emit messageCopied( mMsgList );
00542 if (account->slave()) {
00543 account->mJobList.remove( this );
00544 }
00545 deleteMe = true;
00546 }
00547 }
00548 if (account->slave()) {
00549 account->removeJob( it );
00550 }
00551 if ( deleteMe )
00552 deleteLater();
00553 }
00554
00555
00556 void ImapJob::slotCopyMessageInfoData(KIO::Job * job, const QString & data)
00557 {
00558 KMFolderImap * imapFolder = static_cast<KMFolderImap*>(mDestFolder->storage());
00559 KMAcctImap *account = imapFolder->account();
00560 ImapAccountBase::JobIterator it = account->findJob( job );
00561 if ( it == account->jobsEnd() ) return;
00562
00563 if (data.find("UID") != -1)
00564 {
00565
00566 QString oldUid = data.section(' ', 1, 1);
00567 QString newUid = data.section(' ', 2, 2);
00568
00569
00570 QValueList<ulong> olduids = KMFolderImap::splitSets(oldUid);
00571 QValueList<ulong> newuids = KMFolderImap::splitSets(newUid);
00572
00573 int index = -1;
00574 KMMessage * msg;
00575 for ( msg = (*it).msgList.first(); msg; msg = (*it).msgList.next() )
00576 {
00577 ulong uid = msg->UID();
00578 index = olduids.findIndex(uid);
00579 if (index > -1)
00580 {
00581
00582 imapFolder->saveMsgMetaData( msg, newuids[index] );
00583 }
00584 }
00585 }
00586 }
00587
00588
00589 void ImapJob::slotPutMessageInfoData(KIO::Job *job, const QString &data)
00590 {
00591 KMFolderImap * imapFolder = static_cast<KMFolderImap*>(mDestFolder->storage());
00592 KMAcctImap *account = imapFolder->account();
00593 ImapAccountBase::JobIterator it = account->findJob( job );
00594 if ( it == account->jobsEnd() ) return;
00595
00596 if ( data.find("UID") != -1 )
00597 {
00598 ulong uid = ( data.right(data.length()-4) ).toInt();
00599 if ( !(*it).msgList.isEmpty() )
00600 {
00601 imapFolder->saveMsgMetaData( (*it).msgList.first(), uid );
00602 }
00603 }
00604 }
00605
00606
00607
00608 void ImapJob::slotCopyMessageResult( KIO::Job *job )
00609 {
00610 KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
00611 ImapAccountBase::JobIterator it = account->findJob( job );
00612 if ( it == account->jobsEnd() ) return;
00613
00614 if (job->error())
00615 {
00616 mErrorCode = job->error();
00617 QString errStr = i18n("Error while copying messages.");
00618 if ( (*it).progressItem )
00619 (*it).progressItem->setStatus( errStr );
00620 account->handleJobError( job, errStr );
00621 deleteLater();
00622 return;
00623 } else {
00624 if ( !(*it).msgList.isEmpty() )
00625 {
00626 emit messageCopied((*it).msgList);
00627 } else if (mMsgList.first()) {
00628 emit messageCopied(mMsgList.first());
00629 }
00630 }
00631 if (account->slave()) {
00632 account->removeJob(it);
00633 account->mJobList.remove(this);
00634 }
00635 deleteLater();
00636 }
00637
00638
00639 void ImapJob::execute()
00640 {
00641 init( mType, mSets, mDestFolder?
00642 dynamic_cast<KMFolderImap*>( mDestFolder->storage() ):0, mMsgList );
00643 }
00644
00645
00646 void ImapJob::setParentFolder( const KMFolderImap* parent )
00647 {
00648 mParentFolder = const_cast<KMFolderImap*>( parent );
00649 }
00650
00651
00652 void ImapJob::slotProcessedSize(KIO::Job * job, KIO::filesize_t processed)
00653 {
00654 KMMessage *msg = mMsgList.first();
00655 if (!msg || !job) {
00656 return;
00657 }
00658 KMFolderImap* parent = 0;
00659 if ( msg->parent() && msg->parent()->folderType() == KMFolderTypeImap )
00660 parent = static_cast<KMFolderImap*>(msg->parent()->storage());
00661 else if (mDestFolder)
00662 parent = static_cast<KMFolderImap*>(mDestFolder->storage());
00663 if (!parent) return;
00664 KMAcctImap *account = parent->account();
00665 if ( !account ) return;
00666 ImapAccountBase::JobIterator it = account->findJob( job );
00667 if ( it == account->jobsEnd() ) return;
00668 (*it).done = processed;
00669 if ( (*it).progressItem ) {
00670 (*it).progressItem->setCompletedItems( processed );
00671 (*it).progressItem->updateProgress();
00672 }
00673 emit progress( (*it).done, (*it).total );
00674 }
00675
00676 }
00677
00678 #include "imapjob.moc"