kmail Library API Documentation

kmacctimap.cpp

00001 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include "kmacctimap.h" 00027 using KMail::SieveConfig; 00028 00029 #include "broadcaststatus.h" 00030 using KPIM::BroadcastStatus; 00031 #include "kmfoldertree.h" 00032 #include "kmfoldermgr.h" 00033 #include "kmfolderimap.h" 00034 #include "kmmainwin.h" 00035 #include "folderstorage.h" 00036 #include "imapjob.h" 00037 using KMail::ImapJob; 00038 #include "progressmanager.h" 00039 using KPIM::ProgressItem; 00040 using KPIM::ProgressManager; 00041 #include <kio/scheduler.h> 00042 #include <kio/slave.h> 00043 #include <kmessagebox.h> 00044 #include <kdebug.h> 00045 00046 00047 //----------------------------------------------------------------------------- 00048 KMAcctImap::KMAcctImap(KMAcctMgr* aOwner, const QString& aAccountName, uint id): 00049 KMail::ImapAccountBase(aOwner, aAccountName, id), 00050 mCountRemainChecks( 0 ) 00051 { 00052 mFolder = 0; 00053 mNoopTimer.start( 60000 ); // // send a noop every minute 00054 mOpenFolders.setAutoDelete(true); 00055 connect(kmkernel->imapFolderMgr(), SIGNAL(changed()), 00056 this, SLOT(slotUpdateFolderList())); 00057 } 00058 00059 00060 //----------------------------------------------------------------------------- 00061 KMAcctImap::~KMAcctImap() 00062 { 00063 killAllJobs( true ); 00064 } 00065 00066 00067 //----------------------------------------------------------------------------- 00068 QString KMAcctImap::type() const 00069 { 00070 return "imap"; 00071 } 00072 00073 //----------------------------------------------------------------------------- 00074 void KMAcctImap::pseudoAssign( const KMAccount * a ) { 00075 killAllJobs( true ); 00076 if (mFolder) 00077 { 00078 mFolder->setContentState(KMFolderImap::imapNoInformation); 00079 mFolder->setSubfolderState(KMFolderImap::imapNoInformation); 00080 } 00081 ImapAccountBase::pseudoAssign( a ); 00082 } 00083 00084 //----------------------------------------------------------------------------- 00085 void KMAcctImap::setImapFolder(KMFolderImap *aFolder) 00086 { 00087 mFolder = aFolder; 00088 mFolder->setImapPath(mPrefix); 00089 } 00090 00091 00092 //----------------------------------------------------------------------------- 00093 00094 bool KMAcctImap::handleError( int errorCode, const QString &errorMsg, KIO::Job* job, const QString& context, bool abortSync ) 00095 { 00096 /* TODO check where to handle this one better. */ 00097 if ( errorCode == KIO::ERR_DOES_NOT_EXIST ) { 00098 // folder is gone, so reload the folderlist 00099 if ( mFolder ) 00100 mFolder->listDirectory(); 00101 return true; 00102 } 00103 return ImapAccountBase::handleError( errorCode, errorMsg, job, context, abortSync ); 00104 } 00105 00106 00107 //----------------------------------------------------------------------------- 00108 void KMAcctImap::killAllJobs( bool disconnectSlave ) 00109 { 00110 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin(); 00111 for ( ; it != mapJobData.end(); ++it) 00112 { 00113 QPtrList<KMMessage> msgList = (*it).msgList; 00114 QPtrList<KMMessage>::Iterator it2 = msgList.begin(); 00115 for ( ; it2 != msgList.end(); ++it2 ) { 00116 KMMessage *msg = *it2; 00117 if ( msg->transferInProgress() ) { 00118 kdDebug(5006) << "KMAcctImap::killAllJobs - resetting mail" << endl; 00119 msg->setTransferInProgress( false ); 00120 } 00121 } 00122 if ((*it).parent) 00123 { 00124 // clear folder state 00125 KMFolderImap *fld = static_cast<KMFolderImap*>((*it).parent->storage()); 00126 fld->setCheckingValidity(false); 00127 fld->setContentState(KMFolderImap::imapNoInformation); 00128 fld->setSubfolderState(KMFolderImap::imapNoInformation); 00129 fld->sendFolderComplete(FALSE); 00130 fld->removeJobs(); 00131 } 00132 if ( (*it).progressItem ) 00133 { 00134 (*it).progressItem->setComplete(); 00135 } 00136 } 00137 if (mSlave && mapJobData.begin() != mapJobData.end()) 00138 { 00139 mSlave->kill(); 00140 mSlave = 0; 00141 } 00142 // remove the jobs 00143 mapJobData.clear(); 00144 KMAccount::deleteFolderJobs(); 00145 // make sure that no new-mail-check is blocked 00146 if (mCountRemainChecks > 0) 00147 { 00148 checkDone( false, CheckOK ); // returned 0 new messages 00149 mCountRemainChecks = 0; 00150 } 00151 if ( disconnectSlave && slave() ) { 00152 KIO::Scheduler::disconnectSlave( slave() ); 00153 mSlave = 0; 00154 } 00155 } 00156 00157 //----------------------------------------------------------------------------- 00158 void KMAcctImap::ignoreJobsForMessage( KMMessage* msg ) 00159 { 00160 if (!msg) return; 00161 QPtrListIterator<ImapJob> it( mJobList ); 00162 while ( it.current() ) 00163 { 00164 ImapJob *job = it.current(); 00165 ++it; 00166 if ( job->msgList().findRef( msg ) != -1 ) 00167 { 00168 job->kill(); 00169 } 00170 } 00171 } 00172 00173 //----------------------------------------------------------------------------- 00174 void KMAcctImap::ignoreJobsForFolder( KMFolder* folder ) 00175 { 00176 QPtrListIterator<ImapJob> it( mJobList ); 00177 while ( it.current() ) 00178 { 00179 ImapJob *job = it.current(); 00180 ++it; 00181 if ( !job->msgList().isEmpty() && job->msgList().first()->parent() == folder ) 00182 { 00183 job->kill(); 00184 } 00185 } 00186 } 00187 00188 //----------------------------------------------------------------------------- 00189 void KMAcctImap::removeSlaveJobsForFolder( KMFolder* folder ) 00190 { 00191 // Make sure the folder is not referenced in any kio slave jobs 00192 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin(); 00193 while ( it != mapJobData.end() ) { 00194 QMap<KIO::Job*, jobData>::Iterator i = it; 00195 it++; 00196 if ( (*i).parent ) { 00197 if ( (*i).parent == folder ) { 00198 mapJobData.remove(i); 00199 } 00200 } 00201 } 00202 } 00203 00204 //----------------------------------------------------------------------------- 00205 void KMAcctImap::cancelMailCheck() 00206 { 00207 // Make list of folders to reset, like in killAllJobs 00208 QValueList<KMFolderImap*> folderList; 00209 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin(); 00210 for (; it != mapJobData.end(); ++it) { 00211 if ( (*it).cancellable && (*it).parent ) { 00212 folderList << static_cast<KMFolderImap*>((*it).parent->storage()); 00213 } 00214 } 00215 // Kill jobs 00216 // FIXME 00217 // ImapAccountBase::cancelMailCheck(); 00218 killAllJobs( true ); 00219 // emit folderComplete, this is important for 00220 // KMAccount::checkingMail() to be reset, in case we restart checking mail later. 00221 for( QValueList<KMFolderImap*>::Iterator it = folderList.begin(); it != folderList.end(); ++it ) { 00222 KMFolderImap *fld = *it; 00223 fld->sendFolderComplete(FALSE); 00224 } 00225 } 00226 00227 //----------------------------------------------------------------------------- 00228 void KMAcctImap::processNewMail(bool interactive) 00229 { 00230 if (!mFolder || !mFolder->folder() || !mFolder->folder()->child() || 00231 makeConnection() == ImapAccountBase::Error) 00232 { 00233 mCountRemainChecks = 0; 00234 checkDone( false, CheckError ); 00235 return; 00236 } 00237 // if necessary then initialize the list of folders which should be checked 00238 if( mMailCheckFolders.isEmpty() ) 00239 { 00240 slotUpdateFolderList(); 00241 // if no folders should be checked then the check is finished 00242 if( mMailCheckFolders.isEmpty() ) 00243 { 00244 checkDone( false, CheckOK ); 00245 return; 00246 } 00247 } 00248 // Ok, we're really checking, get a progress item; 00249 Q_ASSERT( !mMailCheckProgressItem ); 00250 mMailCheckProgressItem = 00251 ProgressManager::createProgressItem( 00252 "MailCheckAccount" + name(), 00253 i18n("Checking account: " ) + name(), 00254 QString::null, // status 00255 true, // can be canceled 00256 useSSL() || useTLS() ); 00257 00258 mMailCheckProgressItem->setTotalItems( mMailCheckFolders.count() ); 00259 connect ( mMailCheckProgressItem, 00260 SIGNAL( progressItemCanceled( ProgressItem*) ), 00261 this, 00262 SLOT( slotMailCheckCanceled() ) ); 00263 00264 QValueList<QGuardedPtr<KMFolder> >::Iterator it; 00265 // first get the current count of unread-messages 00266 mCountRemainChecks = 0; 00267 mCountUnread = 0; 00268 mUnreadBeforeCheck.clear(); 00269 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); it++) 00270 { 00271 KMFolder *folder = *it; 00272 if (folder && !folder->noContent()) 00273 { 00274 mUnreadBeforeCheck[folder->idString()] = folder->countUnread(); 00275 } 00276 } 00277 bool gotError = false; 00278 // then check for new mails 00279 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); it++) 00280 { 00281 KMFolder *folder = *it; 00282 if (folder && !folder->noContent()) 00283 { 00284 KMFolderImap *imapFolder = static_cast<KMFolderImap*>(folder->storage()); 00285 if (imapFolder->getContentState() != KMFolderImap::imapInProgress) 00286 { 00287 // connect the result-signals for new-mail-notification 00288 mCountRemainChecks++; 00289 if (imapFolder->isSelected()) { 00290 connect(imapFolder, SIGNAL(folderComplete(KMFolderImap*, bool)), 00291 this, SLOT(postProcessNewMail(KMFolderImap*, bool))); 00292 imapFolder->getFolder(); 00293 } 00294 else { 00295 connect(imapFolder, SIGNAL(numUnreadMsgsChanged(KMFolder*)), 00296 this, SLOT(postProcessNewMail(KMFolder*))); 00297 bool ok = imapFolder->processNewMail(interactive); 00298 if (!ok) 00299 { 00300 // there was an error so cancel 00301 mCountRemainChecks--; 00302 gotError = true; 00303 if ( mMailCheckProgressItem ) { 00304 mMailCheckProgressItem->incCompletedItems(); 00305 mMailCheckProgressItem->updateProgress(); 00306 } 00307 } 00308 } 00309 } 00310 } 00311 } // end for 00312 if ( gotError ) 00313 slotUpdateFolderList(); 00314 // for the case the account is down and all folders report errors 00315 if ( mCountRemainChecks == 0 ) 00316 { 00317 mCountLastUnread = 0; // => mCountUnread - mCountLastUnread == new count 00318 ImapAccountBase::postProcessNewMail(); 00319 mUnreadBeforeCheck.clear(); 00320 } 00321 } 00322 00323 //----------------------------------------------------------------------------- 00324 void KMAcctImap::postProcessNewMail(KMFolderImap* folder, bool) 00325 { 00326 disconnect(folder, SIGNAL(folderComplete(KMFolderImap*, bool)), 00327 this, SLOT(postProcessNewMail(KMFolderImap*, bool))); 00328 postProcessNewMail(static_cast<KMFolder*>(folder->folder())); 00329 } 00330 00331 void KMAcctImap::postProcessNewMail( KMFolder * folder ) { 00332 00333 disconnect( folder->storage(), SIGNAL(numUnreadMsgsChanged(KMFolder*)), 00334 this, SLOT(postProcessNewMail(KMFolder*)) ); 00335 00336 if ( mMailCheckProgressItem ) { 00337 mMailCheckProgressItem->incCompletedItems(); 00338 mMailCheckProgressItem->updateProgress(); 00339 mMailCheckProgressItem->setStatus( folder->prettyURL() + i18n(" completed") ); 00340 } 00341 mCountRemainChecks--; 00342 00343 // count the unread messages 00344 const QString folderId = folder->idString(); 00345 int newInFolder = folder->countUnread(); 00346 if ( mUnreadBeforeCheck.find( folderId ) != mUnreadBeforeCheck.end() ) 00347 newInFolder -= mUnreadBeforeCheck[folderId]; 00348 if ( newInFolder > 0 ) { 00349 addToNewInFolder( folderId, newInFolder ); 00350 mCountUnread += newInFolder; 00351 } 00352 if (mCountRemainChecks == 0) 00353 { 00354 // all checks are done 00355 mCountLastUnread = 0; // => mCountUnread - mCountLastUnread == new count 00356 ImapAccountBase::postProcessNewMail(); 00357 mUnreadBeforeCheck.clear(); 00358 } 00359 } 00360 00361 //----------------------------------------------------------------------------- 00362 void KMAcctImap::slotUpdateFolderList() 00363 { 00364 if ( !mFolder || !mFolder->folder() || !mFolder->folder()->child() ) 00365 { 00366 kdWarning(5006) << "KMAcctImap::slotUpdateFolderList return" << endl; 00367 return; 00368 } 00369 QStringList strList; 00370 mMailCheckFolders.clear(); 00371 kmkernel->imapFolderMgr()->createFolderList(&strList, &mMailCheckFolders, 00372 mFolder->folder()->child(), QString::null, false); 00373 // the new list 00374 QValueList<QGuardedPtr<KMFolder> > includedFolders; 00375 // check for excluded folders 00376 QValueList<QGuardedPtr<KMFolder> >::Iterator it; 00377 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); it++) 00378 { 00379 KMFolderImap* folder = static_cast<KMFolderImap*>(((KMFolder*)(*it))->storage()); 00380 if (folder->includeInMailCheck()) 00381 includedFolders.append(*it); 00382 } 00383 mMailCheckFolders = includedFolders; 00384 } 00385 00386 //----------------------------------------------------------------------------- 00387 void KMAcctImap::listDirectory() 00388 { 00389 mFolder->listDirectory(); 00390 } 00391 00392 //----------------------------------------------------------------------------- 00393 void KMAcctImap::setPrefixHook() { 00394 if ( mFolder ) mFolder->setImapPath( prefix() ); 00395 } 00396 00397 //----------------------------------------------------------------------------- 00398 void KMAcctImap::readConfig(KConfig& config) 00399 { 00400 ImapAccountBase::readConfig( config ); 00401 } 00402 00403 //----------------------------------------------------------------------------- 00404 void KMAcctImap::slotMailCheckCanceled() 00405 { 00406 if( mMailCheckProgressItem ) 00407 mMailCheckProgressItem->setComplete(); 00408 cancelMailCheck(); 00409 } 00410 00411 //----------------------------------------------------------------------------- 00412 FolderStorage* const KMAcctImap::rootFolder() const 00413 { 00414 return mFolder; 00415 } 00416 00417 #include "kmacctimap.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:19 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003