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
00033 #ifdef HAVE_CONFIG_H
00034 #include <config.h>
00035 #endif
00036
00037 #include "cachedimapjob.h"
00038 #include "imapaccountbase.h"
00039
00040 #include "kmfoldermgr.h"
00041 #include "kmfolder.h"
00042 #include "kmfoldercachedimap.h"
00043 #include "kmailicalifaceimpl.h"
00044 #include "kmacctcachedimap.h"
00045 #include "kmmsgdict.h"
00046 #include "maildirjob.h"
00047 #include "scalix.h"
00048 #include "util.h"
00049
00050 #include <kio/scheduler.h>
00051 #include <kio/job.h>
00052
00053 #include <klocale.h>
00054 #include <kdebug.h>
00055
00056
00057 namespace KMail {
00058
00059
00060 CachedImapJob::CachedImapJob( const QValueList<MsgForDownload>& msgs,
00061 JobType type, KMFolderCachedImap* folder )
00062 : FolderJob( type ), mFolder( folder ), mMsgsForDownload( msgs ),
00063 mTotalBytes(0), mMsg(0), mParentFolder( 0 )
00064 {
00065 QValueList<MsgForDownload>::ConstIterator it = msgs.begin();
00066 for ( ; it != msgs.end() ; ++it )
00067 mTotalBytes += (*it).size;
00068 }
00069
00070
00071 CachedImapJob::CachedImapJob( const QPtrList<KMMessage>& msgs, JobType type,
00072 KMFolderCachedImap* folder )
00073 : FolderJob( msgs, QString::null, type, folder?folder->folder():0 ), mFolder( folder ),
00074 mTotalBytes( msgs.count() ),
00075 mMsg( 0 ), mParentFolder( 0 )
00076 {
00077 }
00078
00079 CachedImapJob::CachedImapJob( const QValueList<unsigned long>& msgs,
00080 JobType type, KMFolderCachedImap* folder )
00081 : FolderJob( QPtrList<KMMessage>(), QString::null, type, folder?folder->folder():0 ),
00082 mFolder( folder ), mSerNumMsgList( msgs ), mTotalBytes( msgs.count() ), mMsg( 0 ),
00083 mParentFolder ( 0 )
00084 {
00085 }
00086
00087
00088 CachedImapJob::CachedImapJob( const QValueList<KMFolderCachedImap*>& fList,
00089 JobType type, KMFolderCachedImap* folder )
00090 : FolderJob( type ), mFolder( folder ), mFolderList( fList ), mMsg( 0 ),
00091 mParentFolder ( 0 )
00092 {
00093 }
00094
00095
00096 CachedImapJob::CachedImapJob( const QString& string1, JobType type,
00097 KMFolderCachedImap* folder )
00098 : FolderJob( type ), mFolder(folder), mMsg( 0 ), mString( string1 ),
00099 mParentFolder ( 0 )
00100 {
00101 assert( folder );
00102 assert( type != tDeleteMessage );
00103 }
00104
00105
00106 CachedImapJob::CachedImapJob( const QStringList& foldersOrMsgs, JobType type,
00107 KMFolderCachedImap* folder )
00108 : FolderJob( type ), mFolder( folder ), mFoldersOrMessages( foldersOrMsgs ),
00109 mMsg( 0 ), mParentFolder( 0 )
00110 {
00111 assert( folder );
00112 }
00113
00114
00115 CachedImapJob::CachedImapJob( JobType type, KMFolderCachedImap* folder )
00116 : FolderJob( type ), mFolder( folder ), mMsg( 0 ), mParentFolder ( 0 )
00117 {
00118 assert( folder );
00119 }
00120
00121 CachedImapJob::~CachedImapJob()
00122 {
00123 mAccount->mJobList.remove(this);
00124 }
00125
00126 void CachedImapJob::execute()
00127 {
00128 mSentBytes = 0;
00129
00130 if( !mFolder ) {
00131 if( !mMsgList.isEmpty() ) {
00132 mFolder = static_cast<KMFolderCachedImap*>(mMsgList.first()->storage());
00133 }
00134 }
00135 assert( mFolder );
00136 mAccount = mFolder->account();
00137 assert( mAccount != 0 );
00138 if( mAccount->makeConnection() != ImapAccountBase::Connected ) {
00139
00140 kdDebug(5006) << "mAccount->makeConnection() failed" << endl;
00141 mPassiveDestructor = true;
00142 delete this;
00143 return;
00144 } else
00145 mPassiveDestructor = false;
00146
00147
00148 mAccount->mJobList.append(this);
00149
00156 if ( mAccount->groupwareType() == KMAcctCachedImap::GroupwareScalix ) {
00157 if ( !mAccount->sentCustomLoginCommand() ) {
00158 QByteArray packedArgs;
00159 QDataStream stream( packedArgs, IO_WriteOnly );
00160
00161 const QString command = QString( "X-SCALIX-ID " );
00162 const QString argument = QString( "(\"name\" \"Evolution\" \"version\" \"2.10.0\")" );
00163
00164 stream << (int) 'X' << 'N' << command << argument;
00165
00166 const KURL url = mAccount->getUrl();
00167
00168 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00169 jd.items << mFolder->label();
00170 KIO::SimpleJob *simpleJob = KIO::special( url.url(), packedArgs, false );
00171 KIO::Scheduler::assignJobToSlave(mAccount->slave(), simpleJob);
00172 mAccount->insertJob(simpleJob, jd);
00173
00174 mAccount->setSentCustomLoginCommand( true );
00175 }
00176 }
00177
00178 switch( mType ) {
00179 case tGetMessage: slotGetNextMessage(); break;
00180 case tPutMessage: slotPutNextMessage(); break;
00181 case tDeleteMessage: slotDeleteNextMessages(); break;
00182 case tExpungeFolder: expungeFolder(); break;
00183 case tAddSubfolders: slotAddNextSubfolder(); break;
00184 case tDeleteFolders: slotDeleteNextFolder(); break;
00185 case tCheckUidValidity: checkUidValidity(); break;
00186 case tRenameFolder: renameFolder(mString); break;
00187 case tListMessages: listMessages(); break;
00188 default:
00189 assert( 0 );
00190 }
00191 }
00192
00193 void CachedImapJob::listMessages()
00194 {
00195 KURL url = mAccount->getUrl();
00196 url.setPath( mFolder->imapPath() + ";UID=1:*;SECTION=FLAGS RFC822.SIZE");
00197
00198 KIO::SimpleJob *job = KIO::get(url, false, false);
00199 KIO::Scheduler::assignJobToSlave( mAccount->slave(), job );
00200 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00201 jd.cancellable = true;
00202 mAccount->insertJob( job, jd );
00203 connect( job, SIGNAL( result(KIO::Job *) ),
00204 this, SLOT( slotListMessagesResult( KIO::Job* ) ) );
00205
00206 connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00207 mFolder, SLOT( slotGetMessagesData( KIO::Job* , const QByteArray& ) ) );
00208 }
00209
00210 void CachedImapJob::slotDeleteNextMessages( KIO::Job* job )
00211 {
00212 if (job) {
00213 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00214 if ( it == mAccount->jobsEnd() ) {
00215 delete this;
00216 return;
00217 }
00218
00219 if( job->error() ) {
00220 mAccount->handleJobError( job, i18n( "Error while deleting messages on the server: " ) + '\n' );
00221 delete this;
00222 return;
00223 }
00224 mAccount->removeJob(it);
00225 }
00226
00227 if( mFoldersOrMessages.isEmpty() ) {
00228
00229 delete this;
00230 return;
00231 }
00232
00233 QString uids = mFoldersOrMessages.front(); mFoldersOrMessages.pop_front();
00234
00235 KURL url = mAccount->getUrl();
00236 url.setPath( mFolder->imapPath() +
00237 QString::fromLatin1(";UID=%1").arg(uids) );
00238
00239 KIO::SimpleJob *simpleJob = KIO::file_delete( url, false );
00240 KIO::Scheduler::assignJobToSlave( mAccount->slave(), simpleJob );
00241 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00242 mAccount->insertJob( simpleJob, jd );
00243 connect( simpleJob, SIGNAL( result(KIO::Job *) ),
00244 this, SLOT( slotDeleteNextMessages(KIO::Job *) ) );
00245 }
00246
00247 void CachedImapJob::expungeFolder()
00248 {
00249 KURL url = mAccount->getUrl();
00250
00251 url.setPath( mFolder->imapPath() + QString::fromLatin1(";UID=*") );
00252
00253 KIO::SimpleJob *job = KIO::file_delete( url, false );
00254 KIO::Scheduler::assignJobToSlave( mAccount->slave(), job );
00255 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00256 mAccount->insertJob( job, jd );
00257 connect( job, SIGNAL( result(KIO::Job *) ),
00258 this, SLOT( slotExpungeResult(KIO::Job *) ) );
00259 }
00260
00261 void CachedImapJob::slotExpungeResult( KIO::Job * job )
00262 {
00263 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00264 if ( it == mAccount->jobsEnd() ) {
00265 delete this;
00266 return;
00267 }
00268
00269 if (job->error()) {
00270 mErrorCode = job->error();
00271 mAccount->handleJobError( job, i18n( "Error while deleting messages on the server: " ) + '\n' );
00272 }
00273 else
00274 mAccount->removeJob(it);
00275
00276 delete this;
00277 }
00278
00279 void CachedImapJob::slotGetNextMessage(KIO::Job * job)
00280 {
00281 if (job) {
00282 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00283 if ( it == mAccount->jobsEnd() ) {
00284 delete this;
00285 return;
00286 }
00287
00288 if (job->error()) {
00289 mErrorCode = job->error();
00290 mAccount->handleJobError( job, i18n( "Error while retrieving message on the server: " ) + '\n' );
00291 delete this;
00292 return;
00293 }
00294
00295 ulong size = 0;
00296 if ((*it).data.size() > 0) {
00297 ulong uid = mMsg->UID();
00298 size = mMsg->msgSizeServer();
00299
00300
00301 size_t dataSize = (*it).data.size();
00302 dataSize = Util::crlf2lf( (*it).data.data(), dataSize );
00303 (*it).data.resize( dataSize );
00304
00305 mMsg->setComplete( true );
00306 mMsg->fromByteArray( (*it).data );
00307 mMsg->setUID(uid);
00308 mMsg->setMsgSizeServer(size);
00309 mMsg->setTransferInProgress( false );
00310 int index = 0;
00311 mFolder->addMsgInternal( mMsg, true, &index );
00312
00313 if ( kmkernel->iCalIface().isResourceFolder( mFolder->folder() ) ) {
00314 mFolder->setStatus( index, KMMsgStatusRead, false );
00315 }
00316
00317 emit messageRetrieved( mMsg );
00318 if ( index > 0 ) mFolder->unGetMsg( index );
00319 } else {
00320 emit messageRetrieved( 0 );
00321 }
00322 mMsg = 0;
00323
00324 mSentBytes += size;
00325 emit progress( mSentBytes, mTotalBytes );
00326 mAccount->removeJob(it);
00327 } else
00328 mFolder->quiet( true );
00329
00330 if( mMsgsForDownload.isEmpty() ) {
00331 mFolder->quiet( false );
00332 delete this;
00333 return;
00334 }
00335
00336 MsgForDownload mfd = mMsgsForDownload.front(); mMsgsForDownload.pop_front();
00337
00338 mMsg = new KMMessage;
00339 mMsg->setUID(mfd.uid);
00340 mMsg->setMsgSizeServer(mfd.size);
00341 if( mfd.flags > 0 )
00342 KMFolderImap::flagsToStatus(mMsg, mfd.flags, true, GlobalSettings::allowLocalFlags() ? mFolder->permanentFlags() : INT_MAX);
00343 KURL url = mAccount->getUrl();
00344 url.setPath(mFolder->imapPath() + QString(";UID=%1;SECTION=BODY.PEEK[]").arg(mfd.uid));
00345
00346 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00347 jd.cancellable = true;
00348 mMsg->setTransferInProgress(true);
00349 KIO::SimpleJob *simpleJob = KIO::get(url, false, false);
00350 KIO::Scheduler::assignJobToSlave(mAccount->slave(), simpleJob);
00351 mAccount->insertJob(simpleJob, jd);
00352 connect(simpleJob, SIGNAL(processedSize(KIO::Job *, KIO::filesize_t)),
00353 this, SLOT(slotProcessedSize(KIO::Job *, KIO::filesize_t)));
00354 connect(simpleJob, SIGNAL(result(KIO::Job *)),
00355 this, SLOT(slotGetNextMessage(KIO::Job *)));
00356 connect(simpleJob, SIGNAL(data(KIO::Job *, const QByteArray &)),
00357 mFolder, SLOT(slotSimpleData(KIO::Job *, const QByteArray &)));
00358 }
00359
00360 void CachedImapJob::slotProcessedSize(KIO::Job *, KIO::filesize_t processed)
00361 {
00362 emit progress( mSentBytes + processed, mTotalBytes );
00363 }
00364
00365 void CachedImapJob::slotPutNextMessage()
00366 {
00367 mMsg = 0;
00368
00369
00370 if( !mMsgList.isEmpty() ) {
00371 mMsg = mMsgList.first();
00372 mMsgList.removeFirst();
00373 }
00374
00375
00376 while( mMsg == 0 && !mSerNumMsgList.isEmpty() ) {
00377 unsigned long serNum = mSerNumMsgList.first();
00378 mSerNumMsgList.pop_front();
00379
00380
00381 int i = 0;
00382 KMFolder* aFolder = 0;
00383 KMMsgDict::instance()->getLocation( serNum, &aFolder, &i );
00384 if( mFolder->folder() != aFolder )
00385
00386 continue;
00387 mMsg = mFolder->getMsg( i );
00388 }
00389
00390 if( !mMsg ) {
00391
00392 delete this;
00393 return;
00394 }
00395
00396 KURL url = mAccount->getUrl();
00397 QString flags = KMFolderImap::statusToFlags( mMsg->status(), mFolder->permanentFlags() );
00398 url.setPath( mFolder->imapPath() + ";SECTION=" + flags );
00399
00400 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00401
00402 mMsg->setUID( 0 );
00403 QCString cstr(mMsg->asString());
00404 int a = cstr.find("\nX-UID: ");
00405 int b = cstr.find('\n', a);
00406 if (a != -1 && b != -1 && cstr.find("\n\n") > a) cstr.remove(a, b-a);
00407 QCString mData(cstr.length() + cstr.contains('\n'));
00408 unsigned int i = 0;
00409 for( char *ch = cstr.data(); *ch; ch++ ) {
00410 if ( *ch == '\n' ) {
00411 mData.at(i) = '\r';
00412 i++;
00413 }
00414 mData.at(i) = *ch; i++;
00415 }
00416 jd.data = mData;
00417 jd.msgList.append( mMsg );
00418
00419 mMsg->setTransferInProgress(true);
00420 KIO::SimpleJob *simpleJob = KIO::put(url, 0, false, false, false);
00421 KIO::Scheduler::assignJobToSlave(mAccount->slave(), simpleJob);
00422 mAccount->insertJob(simpleJob, jd);
00423 connect( simpleJob, SIGNAL( result(KIO::Job *) ),
00424 SLOT( slotPutMessageResult(KIO::Job *) ) );
00425 connect( simpleJob, SIGNAL( dataReq(KIO::Job *, QByteArray &) ),
00426 SLOT( slotPutMessageDataReq(KIO::Job *, QByteArray &) ) );
00427 connect( simpleJob, SIGNAL( data(KIO::Job *, const QByteArray &) ),
00428 mFolder, SLOT( slotSimpleData(KIO::Job *, const QByteArray &) ) );
00429 connect( simpleJob, SIGNAL(infoMessage(KIO::Job *, const QString &)),
00430 SLOT(slotPutMessageInfoData(KIO::Job *, const QString &)) );
00431
00432 }
00433
00434
00435
00436 void CachedImapJob::slotPutMessageDataReq(KIO::Job *job, QByteArray &data)
00437 {
00438 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00439 if ( it == mAccount->jobsEnd() ) {
00440 delete this;
00441 return;
00442 }
00443 if ((*it).data.size() - (*it).offset > 0x8000) {
00444 data.duplicate((*it).data.data() + (*it).offset, 0x8000);
00445 (*it).offset += 0x8000;
00446 } else if ((*it).data.size() - (*it).offset > 0) {
00447 data.duplicate((*it).data.data() + (*it).offset,
00448 (*it).data.size() - (*it).offset);
00449 (*it).offset = (*it).data.size();
00450 } else
00451 data.resize(0);
00452 }
00453
00454
00455 void CachedImapJob::slotPutMessageInfoData(KIO::Job *job, const QString &data)
00456 {
00457 KMFolderCachedImap * imapFolder = static_cast<KMFolderCachedImap*>(mDestFolder->storage());
00458 KMAcctCachedImap *account = imapFolder->account();
00459 ImapAccountBase::JobIterator it = account->findJob( job );
00460 if ( it == account->jobsEnd() ) return;
00461
00462 if ( data.find("UID") != -1 && mMsg )
00463 {
00464 int uid = (data.right(data.length()-4)).toInt();
00465 kdDebug( 5006 ) << k_funcinfo << "Server told us uid is: " << uid << endl;
00466 mMsg->setUID( uid );
00467 }
00468 }
00469
00470
00471
00472 void CachedImapJob::slotPutMessageResult(KIO::Job *job)
00473 {
00474 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00475 if ( it == mAccount->jobsEnd() ) {
00476 delete this;
00477 return;
00478 }
00479
00480 if ( job->error() ) {
00481 bool cont = mAccount->handlePutError( job, *it, mFolder->folder() );
00482 if ( !cont ) {
00483 delete this;
00484 } else {
00485 mMsg = 0;
00486 slotPutNextMessage();
00487 }
00488 return;
00489 }
00490
00491 emit messageStored( mMsg );
00492
00493
00494 ++mSentBytes;
00495 emit progress( mSentBytes, mTotalBytes );
00496
00497 int i;
00498 if( ( i = mFolder->find(mMsg) ) != -1 ) {
00499
00500
00501
00502
00503
00504 if ( mMsg->UID() == 0 ) {
00505 mFolder->removeMsg(i);
00506 } else {
00507
00508 bool b = kmkernel->iCalIface().isResourceQuiet();
00509 kmkernel->iCalIface().setResourceQuiet( true );
00510
00511 mFolder->takeTemporarily( i );
00512 mFolder->addMsgKeepUID( mMsg );
00513 mMsg->setTransferInProgress( false );
00514
00515 kmkernel->iCalIface().setResourceQuiet( b );
00516 }
00517 }
00518 mMsg = NULL;
00519 mAccount->removeJob( it );
00520 slotPutNextMessage();
00521 }
00522
00523
00524 void CachedImapJob::slotAddNextSubfolder( KIO::Job * job )
00525 {
00526 if (job) {
00527 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00528 if ( it == mAccount->jobsEnd() ) {
00529 delete this;
00530 return;
00531 }
00532
00533
00534 bool silentUpload = static_cast<KMFolderCachedImap*>((*it).parent->storage())->silentUpload();
00535 static_cast<KMFolderCachedImap*>((*it).parent->storage())->setSilentUpload( false );
00536
00537 if ( job->error() && !silentUpload ) {
00538 QString myError = "<p><b>" + i18n("Error while uploading folder")
00539 + "</b></p><p>" + i18n("Could not make the folder <b>%1</b> on the server.").arg((*it).items[0])
00540 + "</p><p>" + i18n("This could be because you do not have permission to do this, or because the folder is already present on the server; the error message from the server communication is here:") + "</p>";
00541 mAccount->handleJobError( job, myError );
00542 }
00543
00544 if( job->error() ) {
00545 delete this;
00546 return;
00547 } else {
00548 KMFolderCachedImap* storage = static_cast<KMFolderCachedImap*>( (*it).current->storage() );
00549 KMFolderCachedImap* parentStorage = static_cast<KMFolderCachedImap*>( (*it).parent->storage() );
00550 Q_ASSERT( storage );
00551 Q_ASSERT( parentStorage );
00552 if ( storage->imapPath().isEmpty() ) {
00553 QString path = mAccount->createImapPath( parentStorage->imapPath(), storage->folder()->name() );
00554 if ( !storage->imapPathForCreation().isEmpty() )
00555 path = storage->imapPathForCreation();
00556 storage->setImapPath( path );
00557 storage->writeConfig();
00558 }
00559 }
00560 mAccount->removeJob( it );
00561 }
00562
00563 if (mFolderList.isEmpty()) {
00564
00565 delete this;
00566 return;
00567 }
00568
00569 KMFolderCachedImap *folder = mFolderList.front();
00570 mFolderList.pop_front();
00571 KURL url = mAccount->getUrl();
00572 QString path = mAccount->createImapPath( mFolder->imapPath(),
00573 folder->folder()->name() );
00574 if ( !folder->imapPathForCreation().isEmpty() ) {
00575
00576 path = folder->imapPathForCreation();
00577 }
00578 url.setPath( path );
00579
00580 if ( mAccount->groupwareType() != KMAcctCachedImap::GroupwareScalix ) {
00581
00582
00583
00584 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00585 jd.items << folder->label();
00586 jd.current = folder->folder();
00587 KIO::SimpleJob *simpleJob = KIO::mkdir(url);
00588 KIO::Scheduler::assignJobToSlave(mAccount->slave(), simpleJob);
00589 mAccount->insertJob(simpleJob, jd);
00590 connect( simpleJob, SIGNAL(result(KIO::Job *)),
00591 this, SLOT(slotAddNextSubfolder(KIO::Job *)) );
00592 } else {
00593 QByteArray packedArgs;
00594 QDataStream stream( packedArgs, IO_WriteOnly );
00595
00596 const QString command = QString( "X-CREATE-SPECIAL" );
00597 const QString argument = QString( "%1 %2" ).arg( Scalix::Utils::contentsTypeToScalixId( folder->contentsType() ) )
00598 .arg( path );
00599
00600 stream << (int) 'X' << 'N' << command << argument;
00601
00602 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00603 jd.items << folder->label();
00604 jd.current = folder->folder();
00605 KIO::SimpleJob *simpleJob = KIO::special( url.url(), packedArgs, false );
00606 KIO::Scheduler::assignJobToSlave(mAccount->slave(), simpleJob);
00607 mAccount->insertJob(simpleJob, jd);
00608 connect( simpleJob, SIGNAL(result(KIO::Job *)),
00609 this, SLOT(slotAddNextSubfolder(KIO::Job *)) );
00610 }
00611 }
00612
00613
00614 void CachedImapJob::slotDeleteNextFolder( KIO::Job *job )
00615 {
00616 if (job) {
00617 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00618 if ( it == mAccount->jobsEnd() ) {
00619 delete this;
00620 return;
00621 }
00622
00623 mAccount->removeDeletedFolder( (*it).path );
00624
00625 if( job->error() ) {
00626 mAccount->handleJobError( job, i18n( "Error while deleting folder %1 on the server: " ).arg( (*it).path ) + '\n' );
00627 delete this;
00628 return;
00629 }
00630 mAccount->removeJob(it);
00631 }
00632
00633 if( mFoldersOrMessages.isEmpty() ) {
00634
00635 delete this;
00636 return;
00637 }
00638
00639 QString folderPath = mFoldersOrMessages.front();
00640 mFoldersOrMessages.pop_front();
00641 KURL url = mAccount->getUrl();
00642 url.setPath(folderPath);
00643 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00644 jd.path = url.path();
00645 KIO::SimpleJob *simpleJob = KIO::file_delete(url, false);
00646 KIO::Scheduler::assignJobToSlave(mAccount->slave(), simpleJob);
00647 mAccount->insertJob(simpleJob, jd);
00648 connect( simpleJob, SIGNAL( result(KIO::Job *) ),
00649 SLOT( slotDeleteNextFolder(KIO::Job *) ) );
00650 }
00651
00652 void CachedImapJob::checkUidValidity()
00653 {
00654 KURL url = mAccount->getUrl();
00655 url.setPath( mFolder->imapPath() + ";UID=0:0" );
00656
00657 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00658 jd.cancellable = true;
00659
00660 KIO::SimpleJob *job = KIO::get( url, false, false );
00661 KIO::Scheduler::assignJobToSlave( mAccount->slave(), job );
00662 mAccount->insertJob( job, jd );
00663 connect( job, SIGNAL(result(KIO::Job *)),
00664 SLOT(slotCheckUidValidityResult(KIO::Job *)) );
00665 connect( job, SIGNAL(data(KIO::Job *, const QByteArray &)),
00666 mFolder, SLOT(slotSimpleData(KIO::Job *, const QByteArray &)));
00667 }
00668
00669 void CachedImapJob::slotCheckUidValidityResult(KIO::Job * job)
00670 {
00671 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00672 if ( it == mAccount->jobsEnd() ) {
00673 delete this;
00674 return;
00675 }
00676
00677 if( job->error() ) {
00678 mErrorCode = job->error();
00679 mAccount->handleJobError( job, i18n( "Error while reading folder %1 on the server: " ).arg( (*it).parent->label() ) + '\n' );
00680 delete this;
00681 return;
00682 }
00683
00684
00685 QCString cstr((*it).data.data(), (*it).data.size() + 1);
00686 int a = cstr.find("X-uidValidity: ");
00687 if (a < 0) {
00688
00689
00690 kdDebug(5006) << "No uidvalidity available for folder "
00691 << mFolder->name() << endl;
00692 }
00693 else {
00694 int b = cstr.find("\r\n", a);
00695 if ( (b - a - 15) >= 0 ) {
00696 QString uidv = cstr.mid(a + 15, b - a - 15);
00697
00698
00699 if( !mFolder->uidValidity().isEmpty() && mFolder->uidValidity() != uidv ) {
00700
00701
00702 mFolder->expunge();
00703 mFolder->setLastUid( 0 );
00704 mFolder->clearUidMap();
00705 }
00706 } else
00707 kdDebug(5006) << "No uidvalidity available for folder "
00708 << mFolder->name() << endl;
00709 }
00710
00711 a = cstr.find( "X-PermanentFlags: " );
00712 if ( a < 0 ) {
00713 kdDebug(5006) << "no PERMANENTFLAGS response? assumming custom flags are not available" << endl;
00714 } else {
00715 int b = cstr.find( "\r\n", a );
00716 if ( (b - a - 18) >= 0 ) {
00717 int flags = cstr.mid( a + 18, b - a - 18 ).toInt();
00718 emit permanentFlags( flags );
00719 } else {
00720 kdDebug(5006) << "PERMANENTFLAGS response broken, assumming custom flags are not available" << endl;
00721 }
00722 }
00723
00724 mAccount->removeJob(it);
00725 delete this;
00726 }
00727
00728
00729 void CachedImapJob::renameFolder( const QString &newName )
00730 {
00731
00732 KURL urlSrc = mAccount->getUrl();
00733 urlSrc.setPath( mFolder->imapPath() );
00734
00735
00736 KURL urlDst = mAccount->getUrl();
00737 QString imapPath( mFolder->imapPath() );
00738
00739 imapPath.truncate( imapPath.length() - mFolder->folder()->name().length() - 1);
00740 imapPath += newName + '/';
00741 urlDst.setPath( imapPath );
00742
00743 ImapAccountBase::jobData jd( newName, mFolder->folder() );
00744 jd.path = imapPath;
00745
00746 KIO::SimpleJob *simpleJob = KIO::rename( urlSrc, urlDst, false );
00747 KIO::Scheduler::assignJobToSlave( mAccount->slave(), simpleJob );
00748 mAccount->insertJob( simpleJob, jd );
00749 connect( simpleJob, SIGNAL(result(KIO::Job *)),
00750 SLOT(slotRenameFolderResult(KIO::Job *)) );
00751 }
00752
00753 static void renameChildFolders( KMFolderDir* dir, const QString& oldPath,
00754 const QString& newPath )
00755 {
00756 if( dir ) {
00757 KMFolderNode *node = dir->first();
00758 while( node ) {
00759 if( !node->isDir() ) {
00760 KMFolderCachedImap* imapFolder =
00761 static_cast<KMFolderCachedImap*>(static_cast<KMFolder*>(node)->storage());
00762 if ( !imapFolder->imapPath().isEmpty() )
00763
00764 if( imapFolder->imapPath().find( oldPath ) == 0 ) {
00765 QString p = imapFolder->imapPath();
00766 p = p.mid( oldPath.length() );
00767 p.prepend( newPath );
00768 imapFolder->setImapPath( p );
00769 renameChildFolders( imapFolder->folder()->child(), oldPath, newPath );
00770 }
00771 }
00772 node = dir->next();
00773 }
00774 }
00775 }
00776
00777 void CachedImapJob::slotRenameFolderResult( KIO::Job *job )
00778 {
00779 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00780 if ( it == mAccount->jobsEnd() ) {
00781 delete this;
00782 return;
00783 }
00784
00785
00786 if( job->error() ) {
00787
00788 QMap<QString, KMAcctCachedImap::RenamedFolder>::ConstIterator renit = mAccount->renamedFolders().find( mFolder->imapPath() );
00789 Q_ASSERT( renit != mAccount->renamedFolders().end() );
00790 if ( renit != mAccount->renamedFolders().end() ) {
00791 mFolder->folder()->setLabel( (*renit).mOldLabel );
00792 mAccount->removeRenamedFolder( mFolder->imapPath() );
00793 }
00794 mAccount->handleJobError( job, i18n( "Error while trying to rename folder %1" ).arg( mFolder->label() ) + '\n' );
00795 } else {
00796
00797
00798 QString oldName = mFolder->name();
00799 QString oldPath = mFolder->imapPath();
00800 mAccount->removeRenamedFolder( oldPath );
00801 mFolder->setImapPath( (*it).path );
00802 mFolder->FolderStorage::rename( (*it).url );
00803
00804 if( oldPath.endsWith( "/" ) ) oldPath.truncate( oldPath.length() -1 );
00805 QString newPath = mFolder->imapPath();
00806 if( newPath.endsWith( "/" ) ) newPath.truncate( newPath.length() -1 );
00807 renameChildFolders( mFolder->folder()->child(), oldPath, newPath );
00808 kmkernel->dimapFolderMgr()->contentsChanged();
00809
00810 mAccount->removeJob(it);
00811 }
00812 delete this;
00813 }
00814
00815 void CachedImapJob::slotListMessagesResult( KIO::Job * job )
00816 {
00817 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00818 if ( it == mAccount->jobsEnd() ) {
00819 delete this;
00820 return;
00821 }
00822
00823 if (job->error()) {
00824 mErrorCode = job->error();
00825 mAccount->handleJobError( job, i18n( "Error while deleting messages on the server: " ) + '\n' );
00826 }
00827 else
00828 mAccount->removeJob(it);
00829
00830 delete this;
00831 }
00832
00833
00834 void CachedImapJob::setParentFolder( const KMFolderCachedImap* parent )
00835 {
00836 mParentFolder = const_cast<KMFolderCachedImap*>( parent );
00837 }
00838
00839 }
00840
00841 #include "cachedimapjob.moc"