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 if ( imapFolder ) {
00459 KMAcctCachedImap *account = imapFolder->account();
00460 ImapAccountBase::JobIterator it = account->findJob( job );
00461 if ( it == account->jobsEnd() ) {
00462 return;
00463 }
00464
00465 if ( data.find( "UID" ) != -1 && mMsg ) {
00466 int uid = ( data.right( data.length() - 4 ) ).toInt();
00467 kdDebug( 5006 ) << k_funcinfo << "Server told us uid is: " << uid << endl;
00468 mMsg->setUID( uid );
00469 }
00470 }
00471 }
00472
00473
00474
00475 void CachedImapJob::slotPutMessageResult(KIO::Job *job)
00476 {
00477 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00478 if ( it == mAccount->jobsEnd() ) {
00479 delete this;
00480 return;
00481 }
00482
00483 if ( job->error() ) {
00484 bool cont = mAccount->handlePutError( job, *it, mFolder->folder() );
00485 if ( !cont ) {
00486 delete this;
00487 } else {
00488 mMsg = 0;
00489 slotPutNextMessage();
00490 }
00491 return;
00492 }
00493
00494 emit messageStored( mMsg );
00495
00496
00497 ++mSentBytes;
00498 emit progress( mSentBytes, mTotalBytes );
00499
00500 int i;
00501 if( ( i = mFolder->find(mMsg) ) != -1 ) {
00502
00503
00504
00505
00506
00507 if ( mMsg->UID() == 0 ) {
00508 mFolder->removeMsg(i);
00509 } else {
00510
00511 bool b = kmkernel->iCalIface().isResourceQuiet();
00512 kmkernel->iCalIface().setResourceQuiet( true );
00513
00514 mFolder->takeTemporarily( i );
00515 mFolder->addMsgKeepUID( mMsg );
00516 mMsg->setTransferInProgress( false );
00517
00518 kmkernel->iCalIface().setResourceQuiet( b );
00519 }
00520 }
00521 mMsg = NULL;
00522 mAccount->removeJob( it );
00523 slotPutNextMessage();
00524 }
00525
00526
00527 void CachedImapJob::slotAddNextSubfolder( KIO::Job * job )
00528 {
00529 if (job) {
00530 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00531 if ( it == mAccount->jobsEnd() ) {
00532 delete this;
00533 return;
00534 }
00535
00536
00537 bool silentUpload = static_cast<KMFolderCachedImap*>((*it).parent->storage())->silentUpload();
00538 static_cast<KMFolderCachedImap*>((*it).parent->storage())->setSilentUpload( false );
00539
00540 if ( job->error() && !silentUpload ) {
00541 QString myError = "<p><b>" + i18n("Error while uploading folder")
00542 + "</b></p><p>" + i18n("Could not make the folder <b>%1</b> on the server.").arg((*it).items[0])
00543 + "</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>";
00544 mAccount->handleJobError( job, myError );
00545 }
00546
00547 if( job->error() ) {
00548 delete this;
00549 return;
00550 } else {
00551 KMFolderCachedImap* storage = static_cast<KMFolderCachedImap*>( (*it).current->storage() );
00552 KMFolderCachedImap* parentStorage = static_cast<KMFolderCachedImap*>( (*it).parent->storage() );
00553 Q_ASSERT( storage );
00554 Q_ASSERT( parentStorage );
00555 if ( storage->imapPath().isEmpty() ) {
00556 QString path = mAccount->createImapPath( parentStorage->imapPath(), storage->folder()->name() );
00557 if ( !storage->imapPathForCreation().isEmpty() )
00558 path = storage->imapPathForCreation();
00559 storage->setImapPath( path );
00560 storage->writeConfig();
00561 }
00562 }
00563 mAccount->removeJob( it );
00564 }
00565
00566 if (mFolderList.isEmpty()) {
00567
00568 delete this;
00569 return;
00570 }
00571
00572 KMFolderCachedImap *folder = mFolderList.front();
00573 mFolderList.pop_front();
00574 KURL url = mAccount->getUrl();
00575 QString path = mAccount->createImapPath( mFolder->imapPath(),
00576 folder->folder()->name() );
00577 if ( !folder->imapPathForCreation().isEmpty() ) {
00578
00579 path = folder->imapPathForCreation();
00580 }
00581 url.setPath( path );
00582
00583 if ( mAccount->groupwareType() != KMAcctCachedImap::GroupwareScalix ) {
00584
00585
00586
00587 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00588 jd.items << folder->label();
00589 jd.current = folder->folder();
00590 KIO::SimpleJob *simpleJob = KIO::mkdir(url);
00591 KIO::Scheduler::assignJobToSlave(mAccount->slave(), simpleJob);
00592 mAccount->insertJob(simpleJob, jd);
00593 connect( simpleJob, SIGNAL(result(KIO::Job *)),
00594 this, SLOT(slotAddNextSubfolder(KIO::Job *)) );
00595 } else {
00596 QByteArray packedArgs;
00597 QDataStream stream( packedArgs, IO_WriteOnly );
00598
00599 const QString command = QString( "X-CREATE-SPECIAL" );
00600 const QString argument = QString( "%1 %2" ).arg( Scalix::Utils::contentsTypeToScalixId( folder->contentsType() ) )
00601 .arg( path );
00602
00603 stream << (int) 'X' << 'N' << command << argument;
00604
00605 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00606 jd.items << folder->label();
00607 jd.current = folder->folder();
00608 KIO::SimpleJob *simpleJob = KIO::special( url.url(), packedArgs, false );
00609 KIO::Scheduler::assignJobToSlave(mAccount->slave(), simpleJob);
00610 mAccount->insertJob(simpleJob, jd);
00611 connect( simpleJob, SIGNAL(result(KIO::Job *)),
00612 this, SLOT(slotAddNextSubfolder(KIO::Job *)) );
00613 }
00614 }
00615
00616
00617 void CachedImapJob::slotDeleteNextFolder( KIO::Job *job )
00618 {
00619 if (job) {
00620 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00621 if ( it == mAccount->jobsEnd() ) {
00622 delete this;
00623 return;
00624 }
00625
00626 mAccount->removeDeletedFolder( (*it).path );
00627
00628 if( job->error() ) {
00629 mAccount->handleJobError( job, i18n( "Error while deleting folder %1 on the server: " ).arg( (*it).path ) + '\n' );
00630 delete this;
00631 return;
00632 }
00633 mAccount->removeJob(it);
00634 }
00635
00636 if( mFoldersOrMessages.isEmpty() ) {
00637
00638 delete this;
00639 return;
00640 }
00641
00642 QString folderPath = mFoldersOrMessages.front();
00643 mFoldersOrMessages.pop_front();
00644 KURL url = mAccount->getUrl();
00645 url.setPath(folderPath);
00646 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00647 jd.path = url.path();
00648 KIO::SimpleJob *simpleJob = KIO::file_delete(url, false);
00649 KIO::Scheduler::assignJobToSlave(mAccount->slave(), simpleJob);
00650 mAccount->insertJob(simpleJob, jd);
00651 connect( simpleJob, SIGNAL( result(KIO::Job *) ),
00652 SLOT( slotDeleteNextFolder(KIO::Job *) ) );
00653 }
00654
00655 void CachedImapJob::checkUidValidity()
00656 {
00657 KURL url = mAccount->getUrl();
00658 url.setPath( mFolder->imapPath() + ";UID=0:0" );
00659
00660 ImapAccountBase::jobData jd( url.url(), mFolder->folder() );
00661 jd.cancellable = true;
00662
00663 KIO::SimpleJob *job = KIO::get( url, false, false );
00664 KIO::Scheduler::assignJobToSlave( mAccount->slave(), job );
00665 mAccount->insertJob( job, jd );
00666 connect( job, SIGNAL(result(KIO::Job *)),
00667 SLOT(slotCheckUidValidityResult(KIO::Job *)) );
00668 connect( job, SIGNAL(data(KIO::Job *, const QByteArray &)),
00669 mFolder, SLOT(slotSimpleData(KIO::Job *, const QByteArray &)));
00670 }
00671
00672 void CachedImapJob::slotCheckUidValidityResult(KIO::Job * job)
00673 {
00674 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00675 if ( it == mAccount->jobsEnd() ) {
00676 delete this;
00677 return;
00678 }
00679
00680 if( job->error() ) {
00681 mErrorCode = job->error();
00682 mAccount->handleJobError( job, i18n( "Error while reading folder %1 on the server: " ).arg( (*it).parent->label() ) + '\n' );
00683 delete this;
00684 return;
00685 }
00686
00687
00688 QCString cstr((*it).data.data(), (*it).data.size() + 1);
00689 int a = cstr.find("X-uidValidity: ");
00690 if (a < 0) {
00691
00692
00693 kdDebug(5006) << "No uidvalidity available for folder "
00694 << mFolder->name() << endl;
00695 }
00696 else {
00697 int b = cstr.find("\r\n", a);
00698 if ( (b - a - 15) >= 0 ) {
00699 QString uidv = cstr.mid(a + 15, b - a - 15);
00700
00701
00702 if( !mFolder->uidValidity().isEmpty() && mFolder->uidValidity() != uidv ) {
00703
00704
00705 mFolder->expunge();
00706 mFolder->setLastUid( 0 );
00707 mFolder->clearUidMap();
00708 }
00709 } else
00710 kdDebug(5006) << "No uidvalidity available for folder "
00711 << mFolder->name() << endl;
00712 }
00713
00714 a = cstr.find( "X-PermanentFlags: " );
00715 if ( a < 0 ) {
00716 kdDebug(5006) << "no PERMANENTFLAGS response? assumming custom flags are not available" << endl;
00717 } else {
00718 int b = cstr.find( "\r\n", a );
00719 if ( (b - a - 18) >= 0 ) {
00720 int flags = cstr.mid( a + 18, b - a - 18 ).toInt();
00721 emit permanentFlags( flags );
00722 } else {
00723 kdDebug(5006) << "PERMANENTFLAGS response broken, assumming custom flags are not available" << endl;
00724 }
00725 }
00726
00727 mAccount->removeJob(it);
00728 delete this;
00729 }
00730
00731
00732 void CachedImapJob::renameFolder( const QString &newName )
00733 {
00734 mNewName = newName;
00735
00736
00737 KURL urlSrc = mAccount->getUrl();
00738 mOldImapPath = mFolder->imapPath();
00739 urlSrc.setPath( mOldImapPath );
00740
00741
00742 KURL urlDst = mAccount->getUrl();
00743 mNewImapPath = mFolder->imapPath();
00744
00745 mNewImapPath.truncate( mNewImapPath.length() - mFolder->folder()->name().length() - 1);
00746 mNewImapPath += newName + '/';
00747 urlDst.setPath( mNewImapPath );
00748
00749 ImapAccountBase::jobData jd( newName, mFolder->folder() );
00750 jd.path = mNewImapPath;
00751
00752 KIO::SimpleJob *simpleJob = KIO::rename( urlSrc, urlDst, false );
00753 KIO::Scheduler::assignJobToSlave( mAccount->slave(), simpleJob );
00754 mAccount->insertJob( simpleJob, jd );
00755 connect( simpleJob, SIGNAL(result(KIO::Job *)),
00756 SLOT(slotRenameFolderResult(KIO::Job *)) );
00757 }
00758
00759 static void renameChildFolders( KMFolderDir* dir, const QString& oldPath,
00760 const QString& newPath )
00761 {
00762 if( dir ) {
00763 KMFolderNode *node = dir->first();
00764 while( node ) {
00765 if( !node->isDir() ) {
00766 KMFolderCachedImap* imapFolder =
00767 static_cast<KMFolderCachedImap*>(static_cast<KMFolder*>(node)->storage());
00768 if ( !imapFolder->imapPath().isEmpty() )
00769
00770 if( imapFolder->imapPath().find( oldPath ) == 0 ) {
00771 QString p = imapFolder->imapPath();
00772 p = p.mid( oldPath.length() );
00773 p.prepend( newPath );
00774 imapFolder->setImapPath( p );
00775 renameChildFolders( imapFolder->folder()->child(), oldPath, newPath );
00776 }
00777 }
00778 node = dir->next();
00779 }
00780 }
00781 }
00782
00783 void CachedImapJob::revertLabelChange()
00784 {
00785 QMap<QString, KMAcctCachedImap::RenamedFolder>::ConstIterator renit = mAccount->renamedFolders().find( mFolder->imapPath() );
00786 Q_ASSERT( renit != mAccount->renamedFolders().end() );
00787 if ( renit != mAccount->renamedFolders().end() ) {
00788 mFolder->folder()->setLabel( (*renit).mOldLabel );
00789 mAccount->removeRenamedFolder( mFolder->imapPath() );
00790 kmkernel->dimapFolderMgr()->contentsChanged();
00791 }
00792 }
00793
00794 void CachedImapJob::renameOnDisk()
00795 {
00796 QString oldName = mFolder->name();
00797 QString oldPath = mFolder->imapPath();
00798 mAccount->removeRenamedFolder( oldPath );
00799 mFolder->setImapPath( mNewImapPath );
00800 mFolder->FolderStorage::rename( mNewName );
00801
00802 if( oldPath.endsWith( "/" ) ) oldPath.truncate( oldPath.length() -1 );
00803 QString newPath = mFolder->imapPath();
00804 if( newPath.endsWith( "/" ) ) newPath.truncate( newPath.length() -1 );
00805 renameChildFolders( mFolder->folder()->child(), oldPath, newPath );
00806 kmkernel->dimapFolderMgr()->contentsChanged();
00807 }
00808
00809 void CachedImapJob::slotSubscribtionChange1Failed( const QString &errorMessage )
00810 {
00811 KMessageBox::sorry( 0, i18n( "Error while trying to subscribe to the renamed folder %1.\n"
00812 "Renaming itself was successful, but the renamed folder might disappear "
00813 "from the folder list after the next sync since it is unsubscribed on the server.\n"
00814 "You can try to manually subscribe to the folder yourself.\n\n"
00815 "%2" )
00816 .arg( mFolder->label() ).arg( errorMessage ) );
00817 delete this;
00818 }
00819
00820 void CachedImapJob::slotSubscribtionChange2Failed( const QString &errorMessage )
00821 {
00822 kdWarning(5006) << k_funcinfo << errorMessage << endl;
00823
00824 delete this;
00825 }
00826
00827 void CachedImapJob::slotSubscribtionChange1Done( const QString&, bool )
00828 {
00829 disconnect( mAccount, SIGNAL( subscriptionChanged( const QString&, bool ) ),
00830 this, SLOT( slotSubscribtionChange1Done( const QString&, bool ) ) );
00831 connect( mAccount, SIGNAL( subscriptionChanged( const QString&, bool ) ),
00832 this, SLOT( slotSubscribtionChange2Done( const QString&, bool ) ) );
00833 disconnect( mAccount, SIGNAL( subscriptionChangeFailed( const QString& ) ),
00834 this, SLOT( slotSubscribtionChange1Failed( const QString& ) ) );
00835 connect( mAccount, SIGNAL( subscriptionChangeFailed( const QString& ) ),
00836 this, SLOT( slotSubscribtionChange2Failed( const QString& ) ) );
00837
00838 mAccount->changeSubscription( false, mOldImapPath, true );
00839 }
00840
00841 void CachedImapJob::slotSubscribtionChange2Done( const QString&, bool )
00842 {
00843
00844 delete this;
00845 }
00846
00847 void CachedImapJob::slotRenameFolderResult( KIO::Job *job )
00848 {
00849 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00850 if ( it == mAccount->jobsEnd() ) {
00851 delete this;
00852 return;
00853 }
00854
00855 if( job->error() ) {
00856 revertLabelChange();
00857 const QString errorMessage = i18n( "Error while trying to rename folder %1" ).arg( mFolder->label() );
00858 mAccount->handleJobError( job, errorMessage );
00859 delete this;
00860 } else {
00861
00862 mAccount->removeJob( it );
00863 renameOnDisk();
00864
00865
00866
00867
00868 connect( mAccount, SIGNAL( subscriptionChangeFailed( const QString& ) ),
00869 this, SLOT( slotSubscribtionChange1Failed( const QString& ) ) );
00870 connect( mAccount, SIGNAL( subscriptionChanged( const QString&, bool ) ),
00871 this, SLOT( slotSubscribtionChange1Done( const QString&, bool ) ) );
00872 mAccount->changeSubscription( true, mNewImapPath, true );
00873 }
00874 }
00875
00876 void CachedImapJob::slotListMessagesResult( KIO::Job * job )
00877 {
00878 KMAcctCachedImap::JobIterator it = mAccount->findJob(job);
00879 if ( it == mAccount->jobsEnd() ) {
00880 delete this;
00881 return;
00882 }
00883
00884 if (job->error()) {
00885 mErrorCode = job->error();
00886 mAccount->handleJobError( job, i18n( "Error while deleting messages on the server: " ) + '\n' );
00887 }
00888 else
00889 mAccount->removeJob(it);
00890
00891 delete this;
00892 }
00893
00894
00895 void CachedImapJob::setParentFolder( const KMFolderCachedImap* parent )
00896 {
00897 mParentFolder = const_cast<KMFolderCachedImap*>( parent );
00898 }
00899
00900 }
00901
00902 #include "cachedimapjob.moc"