kmail Library API Documentation

cachedimapjob.cpp

00001 /* -*- mode: C++; c-file-style: "gnu" -*- 00002 * 00003 * This file is part of KMail, the KDE mail client. 00004 * Copyright (c) 2002-2004 Bo Thorsen <bo@sonofthor.dk> 00005 * 2002-2003 Steffen Hansen <hansen@kde.org> 00006 * 2002-2003 Zack Rusin <zack@kde.org> 00007 * 00008 * KMail is free software; you can redistribute it and/or modify it 00009 * under the terms of the GNU General Public License, version 2, as 00010 * published by the Free Software Foundation. 00011 * 00012 * KMail is distributed in the hope that it will be useful, but 00013 * WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 * 00021 * In addition, as a special exception, the copyright holders give 00022 * permission to link the code of this program with any edition of 00023 * the Qt library by Trolltech AS, Norway (or with modified versions 00024 * of Qt that use the same license as Qt), and distribute linked 00025 * combinations including the two. You must obey the GNU General 00026 * Public License in all respects for all of the code used other than 00027 * Qt. If you modify this file, you may extend this exception to 00028 * your version of the file, but you are not obligated to do so. If 00029 * you do not wish to do so, delete this exception statement from 00030 * your version. 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 "kmacctcachedimap.h" 00044 #include "kmmsgdict.h" 00045 #include "maildirjob.h" 00046 00047 #include <kio/scheduler.h> 00048 #include <kio/job.h> 00049 00050 #include <kmessagebox.h> 00051 #include <klocale.h> 00052 #include <kdebug.h> 00053 00054 00055 namespace KMail { 00056 00057 // Get messages 00058 CachedImapJob::CachedImapJob( const QValueList<MsgForDownload>& msgs, 00059 JobType type, KMFolderCachedImap* folder ) 00060 : FolderJob( type ), mFolder( folder ), mMsgsForDownload( msgs ), 00061 mTotalBytes(0), mMsg(0), mParentFolder( 0 ) 00062 { 00063 QValueList<MsgForDownload>::ConstIterator it = msgs.begin(); 00064 for ( ; it != msgs.end() ; ++it ) 00065 mTotalBytes += (*it).size; 00066 } 00067 00068 // Put messages 00069 CachedImapJob::CachedImapJob( const QPtrList<KMMessage>& msgs, JobType type, 00070 KMFolderCachedImap* folder ) 00071 : FolderJob( msgs, QString::null, type, folder?folder->folder():0 ), mFolder( folder ), 00072 mTotalBytes( msgs.count() ), // we abuse it as "total number of messages" 00073 mMsg( 0 ), mParentFolder( 0 ) 00074 { 00075 } 00076 00077 CachedImapJob::CachedImapJob( const QValueList<unsigned long>& msgs, 00078 JobType type, KMFolderCachedImap* folder ) 00079 : FolderJob( QPtrList<KMMessage>(), QString::null, type, folder?folder->folder():0 ), 00080 mFolder( folder ), mSerNumMsgList( msgs ), mTotalBytes( msgs.count() ), mMsg( 0 ), 00081 mParentFolder ( 0 ) 00082 { 00083 } 00084 00085 // Add sub folders 00086 CachedImapJob::CachedImapJob( const QValueList<KMFolderCachedImap*>& fList, 00087 JobType type, KMFolderCachedImap* folder ) 00088 : FolderJob( type ), mFolder( folder ), mFolderList( fList ), mMsg( 0 ), 00089 mParentFolder ( 0 ) 00090 { 00091 } 00092 00093 // Delete message ; Rename folder 00094 CachedImapJob::CachedImapJob( const QString& uids, JobType type, 00095 KMFolderCachedImap* folder ) 00096 : FolderJob( type ), mFolder(folder), mMsg( 0 ), mString( uids ), 00097 mParentFolder ( 0 ) 00098 { 00099 assert( folder ); 00100 } 00101 00102 // Delete folders 00103 CachedImapJob::CachedImapJob( const QStringList& folderpaths, JobType type, 00104 KMFolderCachedImap* folder ) 00105 : FolderJob( type ), mFolder( folder ), mFolderPathList( folderpaths ), 00106 mMsg( 0 ), mParentFolder ( 0 ) 00107 { 00108 assert( folder ); 00109 } 00110 00111 // Other jobs (list messages,expunge folder, check uid validity) 00112 CachedImapJob::CachedImapJob( JobType type, KMFolderCachedImap* folder ) 00113 : FolderJob( type ), mFolder( folder ), mMsg( 0 ), mParentFolder ( 0 ) 00114 { 00115 assert( folder ); 00116 } 00117 00118 CachedImapJob::~CachedImapJob() 00119 { 00120 mAccount->mJobList.remove(this); 00121 } 00122 00123 void CachedImapJob::execute() 00124 { 00125 mSentBytes = 0; 00126 00127 if( !mFolder ) { 00128 if( !mMsgList.isEmpty() ) { 00129 mFolder = static_cast<KMFolderCachedImap*>(mMsgList.first()->storage()); 00130 } 00131 } 00132 assert( mFolder ); 00133 mAccount = mFolder->account(); 00134 assert( mAccount != 0 ); 00135 if( mAccount->makeConnection() != ImapAccountBase::Connected ) { 00136 // No connection to the IMAP server 00137 kdDebug(5006) << "mAccount->makeConnection() failed" << endl; 00138 mPassiveDestructor = true; 00139 delete this; 00140 return; 00141 } else 00142 mPassiveDestructor = false; 00143 00144 // All necessary conditions have been met. Register this job 00145 mAccount->mJobList.append(this); 00146 00147 switch( mType ) { 00148 case tGetMessage: slotGetNextMessage(); break; 00149 case tPutMessage: slotPutNextMessage(); break; 00150 case tDeleteMessage: deleteMessages(mString); break; 00151 case tExpungeFolder: expungeFolder(); break; 00152 case tAddSubfolders: slotAddNextSubfolder(); break; 00153 case tDeleteFolders: slotDeleteNextFolder(); break; 00154 case tCheckUidValidity: checkUidValidity(); break; 00155 case tRenameFolder: renameFolder(mString); break; 00156 case tListMessages: listMessages(); break; 00157 default: 00158 assert( 0 ); 00159 } 00160 } 00161 00162 void CachedImapJob::listMessages() 00163 { 00164 KURL url = mAccount->getUrl(); 00165 url.setPath( mFolder->imapPath() + ";UID=1:*;SECTION=FLAGS RFC822.SIZE"); 00166 00167 KIO::SimpleJob *job = KIO::get(url, false, false); 00168 KIO::Scheduler::assignJobToSlave( mAccount->slave(), job ); 00169 ImapAccountBase::jobData jd( url.url(), mFolder->folder() ); 00170 jd.cancellable = true; 00171 mAccount->insertJob( job, jd ); 00172 connect( job, SIGNAL( result(KIO::Job *) ), 00173 this, SLOT( slotListMessagesResult( KIO::Job* ) ) ); 00174 // send the data directly for KMFolderCachedImap 00175 connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), 00176 mFolder, SLOT( slotGetMessagesData( KIO::Job* , const QByteArray& ) ) ); 00177 } 00178 00179 void CachedImapJob::deleteMessages( const QString& uids ) 00180 { 00181 KURL url = mAccount->getUrl(); 00182 url.setPath( mFolder->imapPath() + 00183 QString::fromLatin1(";UID=%1").arg(uids) ); 00184 00185 KIO::SimpleJob *job = KIO::file_delete( url, false ); 00186 KIO::Scheduler::assignJobToSlave( mAccount->slave(), job ); 00187 ImapAccountBase::jobData jd( url.url(), mFolder->folder() ); 00188 mAccount->insertJob( job, jd ); 00189 connect( job, SIGNAL( result(KIO::Job *) ), 00190 this, SLOT( slotDeleteResult(KIO::Job *) ) ); 00191 } 00192 00193 void CachedImapJob::expungeFolder() 00194 { 00195 KURL url = mAccount->getUrl(); 00196 // Special URL that means EXPUNGE 00197 url.setPath( mFolder->imapPath() + QString::fromLatin1(";UID=*") ); 00198 00199 KIO::SimpleJob *job = KIO::file_delete( url, false ); 00200 KIO::Scheduler::assignJobToSlave( mAccount->slave(), job ); 00201 ImapAccountBase::jobData jd( url.url(), mFolder->folder() ); 00202 mAccount->insertJob( job, jd ); 00203 connect( job, SIGNAL( result(KIO::Job *) ), 00204 this, SLOT( slotDeleteResult(KIO::Job *) ) ); 00205 } 00206 00207 void CachedImapJob::slotDeleteResult( KIO::Job * job ) 00208 { 00209 KMAcctCachedImap::JobIterator it = mAccount->findJob(job); 00210 if ( it == mAccount->jobsEnd() ) { // Shouldn't happen 00211 delete this; 00212 return; 00213 } 00214 00215 if (job->error()) { 00216 mErrorCode = job->error(); 00217 mAccount->handleJobError( job, i18n( "Error while deleting messages on the server: " ) + '\n' ); 00218 } 00219 else 00220 mAccount->removeJob(it); 00221 00222 delete this; 00223 } 00224 00225 void CachedImapJob::slotGetNextMessage(KIO::Job * job) 00226 { 00227 if (job) { 00228 KMAcctCachedImap::JobIterator it = mAccount->findJob(job); 00229 if ( it == mAccount->jobsEnd() ) { // Shouldn't happen 00230 delete this; 00231 return; 00232 } 00233 00234 if (job->error()) { 00235 mErrorCode = job->error(); 00236 mAccount->handleJobError( job, i18n( "Error while retrieving message on the server: " ) + '\n' ); 00237 delete this; 00238 return; 00239 } 00240 00241 ulong size = 0; 00242 if ((*it).data.size() > 0) { 00243 ulong uid = mMsg->UID(); 00244 size = mMsg->msgSizeServer(); 00245 mMsg->setComplete( true ); 00246 mMsg->fromByteArray( (*it).data ); 00247 mMsg->setUID(uid); 00248 mMsg->setMsgSizeServer(size); 00249 mMsg->setTransferInProgress( false ); 00250 int index = 0; 00251 mFolder->addMsgInternal( mMsg, true, &index ); 00252 emit messageRetrieved( mMsg ); 00253 if ( index > 0 ) mFolder->unGetMsg( index ); 00254 } else { 00255 emit messageRetrieved( 0 ); 00256 } 00257 mMsg = 0; 00258 00259 mSentBytes += size; 00260 emit progress( mSentBytes, mTotalBytes ); 00261 mAccount->removeJob(it); 00262 } 00263 00264 if( mMsgsForDownload.isEmpty() ) { 00265 delete this; 00266 return; 00267 } 00268 00269 MsgForDownload mfd = mMsgsForDownload.front(); mMsgsForDownload.pop_front(); 00270 00271 mMsg = new KMMessage; 00272 mMsg->setUID(mfd.uid); 00273 mMsg->setMsgSizeServer(mfd.size); 00274 if( mfd.flags > 0 ) 00275 KMFolderImap::flagsToStatus(mMsg, mfd.flags); 00276 KURL url = mAccount->getUrl(); 00277 url.setPath(mFolder->imapPath() + QString(";UID=%1;SECTION=BODY.PEEK[]").arg(mfd.uid)); 00278 00279 ImapAccountBase::jobData jd( url.url(), mFolder->folder() ); 00280 jd.cancellable = true; 00281 mMsg->setTransferInProgress(true); 00282 KIO::SimpleJob *simpleJob = KIO::get(url, false, false); 00283 KIO::Scheduler::assignJobToSlave(mAccount->slave(), simpleJob); 00284 mAccount->insertJob(simpleJob, jd); 00285 connect(simpleJob, SIGNAL(processedSize(KIO::Job *, KIO::filesize_t)), 00286 this, SLOT(slotProcessedSize(KIO::Job *, KIO::filesize_t))); 00287 connect(simpleJob, SIGNAL(result(KIO::Job *)), 00288 this, SLOT(slotGetNextMessage(KIO::Job *))); 00289 connect(simpleJob, SIGNAL(data(KIO::Job *, const QByteArray &)), 00290 mFolder, SLOT(slotSimpleData(KIO::Job *, const QByteArray &))); 00291 } 00292 00293 void CachedImapJob::slotProcessedSize(KIO::Job *, KIO::filesize_t processed) 00294 { 00295 emit progress( mSentBytes + processed, mTotalBytes ); 00296 } 00297 00298 void CachedImapJob::slotPutNextMessage() 00299 { 00300 mMsg = 0; 00301 00302 // First try the message list 00303 if( !mMsgList.isEmpty() ) { 00304 mMsg = mMsgList.first(); 00305 mMsgList.removeFirst(); 00306 } 00307 00308 // Now try the serial number list 00309 while( mMsg == 0 && !mSerNumMsgList.isEmpty() ) { 00310 unsigned long serNum = mSerNumMsgList.first(); 00311 mSerNumMsgList.pop_front(); 00312 00313 // Find the message with this serial number 00314 int i = 0; 00315 KMFolder* aFolder = 0; 00316 kmkernel->msgDict()->getLocation( serNum, &aFolder, &i ); 00317 if( mFolder->folder() != aFolder ) 00318 // This message was moved or something 00319 continue; 00320 mMsg = mFolder->getMsg( i ); 00321 } 00322 00323 if( !mMsg ) { 00324 // No message found for upload 00325 delete this; 00326 return; 00327 } 00328 00329 KURL url = mAccount->getUrl(); 00330 QString flags = KMFolderImap::statusToFlags( mMsg->status() ); 00331 url.setPath( mFolder->imapPath() + ";SECTION=" + flags ); 00332 00333 ImapAccountBase::jobData jd( url.url(), mFolder->folder() ); 00334 00335 mMsg->setUID( 0 ); // for the index 00336 QCString cstr(mMsg->asString()); 00337 int a = cstr.find("\nX-UID: "); 00338 int b = cstr.find('\n', a); 00339 if (a != -1 && b != -1 && cstr.find("\n\n") > a) cstr.remove(a, b-a); 00340 QCString mData(cstr.length() + cstr.contains('\n')); 00341 unsigned int i = 0; 00342 for( char *ch = cstr.data(); *ch; ch++ ) { 00343 if ( *ch == '\n' ) { 00344 mData.at(i) = '\r'; 00345 i++; 00346 } 00347 mData.at(i) = *ch; i++; 00348 } 00349 jd.data = mData; 00350 jd.msgList.append( mMsg ); 00351 00352 mMsg->setTransferInProgress(true); 00353 KIO::SimpleJob *simpleJob = KIO::put(url, 0, false, false, false); 00354 KIO::Scheduler::assignJobToSlave(mAccount->slave(), simpleJob); 00355 mAccount->insertJob(simpleJob, jd); 00356 connect( simpleJob, SIGNAL( result(KIO::Job *) ), 00357 SLOT( slotPutMessageResult(KIO::Job *) ) ); 00358 connect( simpleJob, SIGNAL( dataReq(KIO::Job *, QByteArray &) ), 00359 SLOT( slotPutMessageDataReq(KIO::Job *, QByteArray &) ) ); 00360 connect( simpleJob, SIGNAL( data(KIO::Job *, const QByteArray &) ), 00361 mFolder, SLOT( slotSimpleData(KIO::Job *, const QByteArray &) ) ); 00362 connect( simpleJob, SIGNAL(infoMessage(KIO::Job *, const QString &)), 00363 SLOT(slotPutMessageInfoData(KIO::Job *, const QString &)) ); 00364 00365 } 00366 00367 //----------------------------------------------------------------------------- 00368 // TODO: port to KIO::StoredTransferJob once it's ok to require kdelibs-3.3 00369 void CachedImapJob::slotPutMessageDataReq(KIO::Job *job, QByteArray &data) 00370 { 00371 KMAcctCachedImap::JobIterator it = mAccount->findJob(job); 00372 if ( it == mAccount->jobsEnd() ) { // Shouldn't happen 00373 delete this; 00374 return; 00375 } 00376 if ((*it).data.size() - (*it).offset > 0x8000) { 00377 data.duplicate((*it).data.data() + (*it).offset, 0x8000); 00378 (*it).offset += 0x8000; 00379 } else if ((*it).data.size() - (*it).offset > 0) { 00380 data.duplicate((*it).data.data() + (*it).offset, 00381 (*it).data.size() - (*it).offset); 00382 (*it).offset = (*it).data.size(); 00383 } else 00384 data.resize(0); 00385 } 00386 00387 //---------------------------------------------------------------------------- 00388 void CachedImapJob::slotPutMessageInfoData(KIO::Job *job, const QString &data) 00389 { 00390 KMFolderCachedImap * imapFolder = static_cast<KMFolderCachedImap*>(mDestFolder->storage()); 00391 KMAcctCachedImap *account = imapFolder->account(); 00392 ImapAccountBase::JobIterator it = account->findJob( job ); 00393 if ( it == account->jobsEnd() ) return; 00394 00395 if (data.find("UID") != -1) 00396 { 00397 int uid = (data.right(data.length()-4)).toInt(); 00398 kdDebug( 5006 ) << k_funcinfo << "Server told us uid is: " << uid << endl; 00399 mMsg->setUID( uid ); 00400 } 00401 } 00402 00403 00404 //----------------------------------------------------------------------------- 00405 void CachedImapJob::slotPutMessageResult(KIO::Job *job) 00406 { 00407 KMAcctCachedImap::JobIterator it = mAccount->findJob(job); 00408 if ( it == mAccount->jobsEnd() ) { // Shouldn't happen 00409 delete this; 00410 return; 00411 } 00412 00413 if ( job->error() ) { 00414 bool cont = mAccount->handlePutError( job, *it, mFolder->folder() ); 00415 if ( !cont ) { 00416 delete this; 00417 } else { 00418 mMsg = 0; 00419 slotPutNextMessage(); 00420 } 00421 return; 00422 } 00423 00424 emit messageStored( mMsg ); 00425 00426 // we abuse those fields, the unit is the number of messages, here 00427 ++mSentBytes; 00428 emit progress( mSentBytes, mTotalBytes ); 00429 00430 int i; 00431 if( ( i = mFolder->find(mMsg) ) != -1 ) { 00432 /* 00433 * If we have aquired a uid during upload the server supports the uidnext 00434 * extension and there is no need to redownload this mail, we already have 00435 * it. Otherwise remove it, it will be redownloaded. 00436 */ 00437 if ( mMsg->UID() == 0 ) { 00438 mFolder->removeMsg(i); 00439 } else { 00440 mFolder->take( i ); 00441 mFolder->addMsgKeepUID( mMsg ); 00442 mMsg->setTransferInProgress( false ); 00443 } 00444 } 00445 mMsg = NULL; 00446 mAccount->removeJob( it ); 00447 slotPutNextMessage(); 00448 } 00449 00450 00451 void CachedImapJob::slotAddNextSubfolder( KIO::Job * job ) 00452 { 00453 if (job) { 00454 KMAcctCachedImap::JobIterator it = mAccount->findJob(job); 00455 if ( it == mAccount->jobsEnd() ) { // Shouldn't happen 00456 delete this; 00457 return; 00458 } 00459 00460 // make copy of setting, to reset it before potentially destroying 'it' 00461 bool silentUpload = static_cast<KMFolderCachedImap*>((*it).parent->storage())->silentUpload(); 00462 static_cast<KMFolderCachedImap*>((*it).parent->storage())->setSilentUpload( false ); 00463 00464 if ( job->error() && !silentUpload ) { 00465 QString myError = "<p><b>" + i18n("Error while uploading folder") 00466 + "</b></p><p>" + i18n("Could not make the folder <b>%1</b> on the server.").arg((*it).items[0]) 00467 + "</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>"; 00468 mAccount->handleJobError( job, myError ); 00469 } 00470 00471 if( job->error() ) { 00472 delete this; 00473 return; 00474 } 00475 mAccount->removeJob( it ); 00476 } 00477 00478 if (mFolderList.isEmpty()) { 00479 // No more folders to add 00480 delete this; 00481 return; 00482 } 00483 00484 KMFolderCachedImap *folder = mFolderList.front(); 00485 mFolderList.pop_front(); 00486 KURL url = mAccount->getUrl(); 00487 url.setPath(mFolder->imapPath() + folder->name()); 00488 00489 // Associate the jobData with the parent folder, not with the child 00490 // This is necessary in case of an error while creating the subfolder, 00491 // so that folderComplete is called on the parent (and the sync resetted). 00492 ImapAccountBase::jobData jd( url.url(), mFolder->folder() ); 00493 jd.items << folder->label(); // for the err msg 00494 KIO::SimpleJob *simpleJob = KIO::mkdir(url); 00495 KIO::Scheduler::assignJobToSlave(mAccount->slave(), simpleJob); 00496 mAccount->insertJob(simpleJob, jd); 00497 connect( simpleJob, SIGNAL(result(KIO::Job *)), 00498 this, SLOT(slotAddNextSubfolder(KIO::Job *)) ); 00499 } 00500 00501 00502 void CachedImapJob::slotDeleteNextFolder( KIO::Job *job ) 00503 { 00504 if (job) { 00505 KMAcctCachedImap::JobIterator it = mAccount->findJob(job); 00506 if ( it == mAccount->jobsEnd() ) { // Shouldn't happen 00507 delete this; 00508 return; 00509 } 00510 00511 if( job->error() ) { 00512 mAccount->handleJobError( job, i18n( "Error while deleting folder %1 on the server: " ).arg( (*it).path ) + '\n' ); 00513 delete this; 00514 return; 00515 } 00516 mAccount->removeJob(it); 00517 } 00518 00519 if( mFolderPathList.isEmpty() ) { 00520 // No more folders to delete 00521 delete this; 00522 return; 00523 } 00524 00525 QString folderPath = mFolderPathList.front(); mFolderPathList.pop_front(); 00526 KURL url = mAccount->getUrl(); 00527 url.setPath(folderPath); 00528 ImapAccountBase::jobData jd( url.url(), mFolder->folder() ); 00529 jd.path = url.path(); 00530 KIO::SimpleJob *simpleJob = KIO::file_delete(url, false); 00531 KIO::Scheduler::assignJobToSlave(mAccount->slave(), simpleJob); 00532 mAccount->insertJob(simpleJob, jd); 00533 connect( simpleJob, SIGNAL( result(KIO::Job *) ), 00534 SLOT( slotDeleteNextFolder(KIO::Job *) ) ); 00535 } 00536 00537 void CachedImapJob::checkUidValidity() 00538 { 00539 KURL url = mAccount->getUrl(); 00540 url.setPath( mFolder->imapPath() + ";UID=0:0" ); 00541 00542 ImapAccountBase::jobData jd( url.url(), mFolder->folder() ); 00543 jd.cancellable = true; 00544 00545 KIO::SimpleJob *job = KIO::get( url, false, false ); 00546 KIO::Scheduler::assignJobToSlave( mAccount->slave(), job ); 00547 mAccount->insertJob( job, jd ); 00548 connect( job, SIGNAL(result(KIO::Job *)), 00549 SLOT(slotCheckUidValidityResult(KIO::Job *)) ); 00550 connect( job, SIGNAL(data(KIO::Job *, const QByteArray &)), 00551 mFolder, SLOT(slotSimpleData(KIO::Job *, const QByteArray &))); 00552 } 00553 00554 void CachedImapJob::slotCheckUidValidityResult(KIO::Job * job) 00555 { 00556 KMAcctCachedImap::JobIterator it = mAccount->findJob(job); 00557 if ( it == mAccount->jobsEnd() ) { // Shouldn't happen 00558 delete this; 00559 return; 00560 } 00561 00562 if( job->error() ) { 00563 mErrorCode = job->error(); 00564 mAccount->handleJobError( job, i18n( "Error while reading folder %1 on the server: " ).arg( (*it).parent->label() ) + '\n' ); 00565 delete this; 00566 return; 00567 } 00568 00569 // Check the uidValidity 00570 QCString cstr((*it).data.data(), (*it).data.size() + 1); 00571 int a = cstr.find("X-uidValidity: "); 00572 if (a < 0) { 00573 // Something is seriously rotten here! 00574 // TODO: Tell the user that he has a problem 00575 kdDebug(5006) << "No uidvalidity available for folder " 00576 << mFolder->name() << endl; 00577 } 00578 else { 00579 int b = cstr.find("\r\n", a); 00580 if ( (b - a - 15) >= 0 ) { 00581 QString uidv = cstr.mid(a + 15, b - a - 15); 00582 // kdDebug(5006) << "New uidv = " << uidv << ", old uidv = " 00583 // << mFolder->uidValidity() << endl; 00584 if( !mFolder->uidValidity().isEmpty() && mFolder->uidValidity() != uidv ) { 00585 // kdDebug(5006) << "Expunging the mailbox " << mFolder->name() 00586 // << "!" << endl; 00587 mFolder->expunge(); 00588 mFolder->setLastUid( 0 ); 00589 } 00590 } else 00591 kdDebug(5006) << "No uidvalidity available for folder " 00592 << mFolder->name() << endl; 00593 } 00594 00595 mAccount->removeJob(it); 00596 delete this; 00597 } 00598 00599 00600 void CachedImapJob::renameFolder( const QString &newName ) 00601 { 00602 // Set the source URL 00603 KURL urlSrc = mAccount->getUrl(); 00604 urlSrc.setPath( mFolder->imapPath() ); 00605 00606 // Set the destination URL - this is a bit trickier 00607 KURL urlDst = mAccount->getUrl(); 00608 QString imapPath( mFolder->imapPath() ); 00609 // Destination url = old imappath - oldname + new name 00610 imapPath.truncate( imapPath.length() - mFolder->folder()->name().length() - 1); 00611 imapPath += newName + '/'; 00612 urlDst.setPath( imapPath ); 00613 00614 ImapAccountBase::jobData jd( newName, mFolder->folder() ); 00615 jd.path = imapPath; 00616 00617 KIO::SimpleJob *simpleJob = KIO::rename( urlSrc, urlDst, false ); 00618 KIO::Scheduler::assignJobToSlave( mAccount->slave(), simpleJob ); 00619 mAccount->insertJob( simpleJob, jd ); 00620 connect( simpleJob, SIGNAL(result(KIO::Job *)), 00621 SLOT(slotRenameFolderResult(KIO::Job *)) ); 00622 } 00623 00624 static void renameChildFolders( KMFolderDir* dir, const QString& oldPath, 00625 const QString& newPath ) 00626 { 00627 if( dir ) { 00628 KMFolderNode *node = dir->first(); 00629 while( node ) { 00630 if( !node->isDir() ) { 00631 KMFolderCachedImap* imapFolder = 00632 static_cast<KMFolderCachedImap*>(static_cast<KMFolder*>(node)->storage()); 00633 if ( !imapFolder->imapPath().isEmpty() ) 00634 // Only rename folders that have been accepted by the server 00635 if( imapFolder->imapPath().find( oldPath ) == 0 ) { 00636 QString p = imapFolder->imapPath(); 00637 p = p.mid( oldPath.length() ); 00638 p.prepend( newPath ); 00639 imapFolder->setImapPath( p ); 00640 renameChildFolders( imapFolder->folder()->child(), oldPath, newPath ); 00641 } 00642 } 00643 node = dir->next(); 00644 } 00645 } 00646 } 00647 00648 void CachedImapJob::slotRenameFolderResult( KIO::Job *job ) 00649 { 00650 KMAcctCachedImap::JobIterator it = mAccount->findJob(job); 00651 if ( it == mAccount->jobsEnd() ) { // Shouldn't happen 00652 delete this; 00653 return; 00654 } 00655 00656 00657 if( job->error() ) { 00658 // Error, revert label change 00659 QMap<QString, KMAcctCachedImap::RenamedFolder>::ConstIterator renit = mAccount->renamedFolders().find( mFolder->imapPath() ); 00660 Q_ASSERT( renit != mAccount->renamedFolders().end() ); 00661 if ( renit != mAccount->renamedFolders().end() ) { 00662 mFolder->folder()->setLabel( (*renit).mOldLabel ); 00663 mAccount->removeRenamedFolder( mFolder->imapPath() ); 00664 } 00665 mAccount->handleJobError( job, i18n( "Error while trying to rename folder %1" ).arg( mFolder->label() ) + '\n' ); 00666 } else { 00667 // Okay, the folder seems to be renamed on the server, 00668 // now rename it on disk 00669 QString oldName = mFolder->name(); 00670 QString oldPath = mFolder->imapPath(); 00671 mAccount->removeRenamedFolder( oldPath ); 00672 mFolder->setImapPath( (*it).path ); 00673 mFolder->FolderStorage::rename( (*it).url ); 00674 00675 if( oldPath.endsWith( "/" ) ) oldPath.truncate( oldPath.length() -1 ); 00676 QString newPath = mFolder->imapPath(); 00677 if( newPath.endsWith( "/" ) ) newPath.truncate( newPath.length() -1 ); 00678 renameChildFolders( mFolder->folder()->child(), oldPath, newPath ); 00679 kmkernel->dimapFolderMgr()->contentsChanged(); 00680 00681 mAccount->removeJob(it); 00682 } 00683 delete this; 00684 } 00685 00686 void CachedImapJob::slotListMessagesResult( KIO::Job * job ) 00687 { 00688 KMAcctCachedImap::JobIterator it = mAccount->findJob(job); 00689 if ( it == mAccount->jobsEnd() ) { // Shouldn't happen 00690 delete this; 00691 return; 00692 } 00693 00694 if (job->error()) { 00695 mErrorCode = job->error(); 00696 mAccount->handleJobError( job, i18n( "Error while deleting messages on the server: " ) + '\n' ); 00697 } 00698 else 00699 mAccount->removeJob(it); 00700 00701 delete this; 00702 } 00703 00704 //----------------------------------------------------------------------------- 00705 void CachedImapJob::setParentFolder( const KMFolderCachedImap* parent ) 00706 { 00707 mParentFolder = const_cast<KMFolderCachedImap*>( parent ); 00708 } 00709 00710 } 00711 00712 #include "cachedimapjob.moc"
KDE Logo
This file is part of the documentation for kmail Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 27 12:52:02 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003