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