kmail Library API Documentation

kmacctcachedimap.cpp

00001 00032 #ifdef HAVE_CONFIG_H 00033 #include <config.h> 00034 #endif 00035 00036 #include "kmacctcachedimap.h" 00037 using KMail::SieveConfig; 00038 00039 #include "kmfoldertree.h" 00040 #include "kmfoldermgr.h" 00041 #include "kmfiltermgr.h" 00042 #include "kmfoldercachedimap.h" 00043 #include "kmmainwin.h" 00044 #include "kmmainwidget.h" 00045 #include "kmkernel.h" 00046 #include "kmacctmgr.h" 00047 #include "progressmanager.h" 00048 00049 #include <kio/passdlg.h> 00050 #include <kio/scheduler.h> 00051 #include <kio/slave.h> 00052 #include <kmessagebox.h> 00053 #include <kdebug.h> 00054 #include <kstandarddirs.h> 00055 #include <kapplication.h> 00056 #include <kconfig.h> 00057 00058 00059 KMAcctCachedImap::KMAcctCachedImap( KMAcctMgr* aOwner, 00060 const QString& aAccountName, uint id ) 00061 : KMail::ImapAccountBase( aOwner, aAccountName, id ), mFolder( 0 ), 00062 mProgressDialogEnabled( true ) 00063 { 00064 // Never EVER set this for the cached IMAP account 00065 mAutoExpunge = false; 00066 } 00067 00068 00069 //----------------------------------------------------------------------------- 00070 KMAcctCachedImap::~KMAcctCachedImap() 00071 { 00072 killAllJobs( true ); 00073 } 00074 00075 00076 //----------------------------------------------------------------------------- 00077 QString KMAcctCachedImap::type() const 00078 { 00079 return "cachedimap"; 00080 } 00081 00082 void KMAcctCachedImap::init() { 00083 ImapAccountBase::init(); 00084 00085 setProgressDialogEnabled( true ); 00086 } 00087 00088 //----------------------------------------------------------------------------- 00089 void KMAcctCachedImap::pseudoAssign( const KMAccount * a ) { 00090 killAllJobs( true ); 00091 if (mFolder) 00092 { 00093 mFolder->setContentState(KMFolderCachedImap::imapNoInformation); 00094 mFolder->setSubfolderState(KMFolderCachedImap::imapNoInformation); 00095 } 00096 00097 setProgressDialogEnabled(static_cast<const KMAcctCachedImap*>(a)->isProgressDialogEnabled()); 00098 00099 ImapAccountBase::pseudoAssign( a ); 00100 } 00101 00102 void KMAcctCachedImap::setPrefixHook() { 00103 if ( mFolder ) mFolder->setImapPath( prefix() ); 00104 } 00105 00106 //----------------------------------------------------------------------------- 00107 void KMAcctCachedImap::setImapFolder(KMFolderCachedImap *aFolder) 00108 { 00109 mFolder = aFolder; 00110 mFolder->setImapPath(mPrefix); 00111 mFolder->setAccount( this ); 00112 } 00113 00114 00115 //----------------------------------------------------------------------------- 00116 void KMAcctCachedImap::setAutoExpunge( bool /*aAutoExpunge*/ ) 00117 { 00118 // Never EVER set this for the cached IMAP account 00119 mAutoExpunge = false; 00120 } 00121 00122 //----------------------------------------------------------------------------- 00123 void KMAcctCachedImap::killAllJobs( bool disconnectSlave ) 00124 { 00125 //kdDebug(5006) << "killAllJobs: disconnectSlave=" << disconnectSlave << " " << mapJobData.count() << " jobs in map." << endl; 00126 // Make list of folders to reset. This must be done last, since folderComplete 00127 // can trigger the next queued mail check already. 00128 QValueList<KMFolderCachedImap*> folderList; 00129 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin(); 00130 for (; it != mapJobData.end(); ++it) { 00131 if ((*it).parent) 00132 folderList << static_cast<KMFolderCachedImap*>((*it).parent->storage()); 00133 // Kill the job - except if it's the one that already died and is calling us 00134 if ( !it.key()->error() && mSlave ) { 00135 it.key()->kill(); 00136 mSlave = 0; // killing a job, kills the slave 00137 } 00138 } 00139 mapJobData.clear(); 00140 00141 // Clear the joblist. Make SURE to stop the job emitting "finished" 00142 for( QPtrListIterator<CachedImapJob> it( mJobList ); it.current(); ++it ) 00143 it.current()->setPassiveDestructor( true ); 00144 KMAccount::deleteFolderJobs(); 00145 00146 if ( disconnectSlave && slave() ) { 00147 KIO::Scheduler::disconnectSlave( slave() ); 00148 mSlave = 0; 00149 } 00150 for( QValueList<KMFolderCachedImap*>::Iterator it = folderList.begin(); it != folderList.end(); ++it ) { 00151 KMFolderCachedImap *fld = *it; 00152 fld->resetSyncState(); 00153 fld->setContentState(KMFolderCachedImap::imapNoInformation); 00154 fld->setSubfolderState(KMFolderCachedImap::imapNoInformation); 00155 fld->sendFolderComplete(FALSE); 00156 } 00157 } 00158 00159 //----------------------------------------------------------------------------- 00160 void KMAcctCachedImap::cancelMailCheck() 00161 { 00162 // Make list of folders to reset, like in killAllJobs 00163 QValueList<KMFolderCachedImap*> folderList; 00164 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin(); 00165 for (; it != mapJobData.end(); ++it) { 00166 if ( (*it).cancellable && (*it).parent ) 00167 folderList << static_cast<KMFolderCachedImap*>((*it).parent->storage()); 00168 } 00169 // Kill jobs 00170 ImapAccountBase::cancelMailCheck(); 00171 // Reset sync states and emit folderComplete, this is important for 00172 // KMAccount::checkingMail() to be reset, in case we restart checking mail later. 00173 for( QValueList<KMFolderCachedImap*>::Iterator it = folderList.begin(); it != folderList.end(); ++it ) { 00174 KMFolderCachedImap *fld = *it; 00175 fld->resetSyncState(); 00176 fld->setContentState(KMFolderCachedImap::imapNoInformation); 00177 fld->setSubfolderState(KMFolderCachedImap::imapNoInformation); 00178 fld->sendFolderComplete(FALSE); 00179 } 00180 } 00181 00182 //----------------------------------------------------------------------------- 00183 void KMAcctCachedImap::killJobsForItem(KMFolderTreeItem * fti) 00184 { 00185 QMap<KIO::Job *, jobData>::Iterator it = mapJobData.begin(); 00186 while (it != mapJobData.end()) 00187 { 00188 if (it.data().parent == fti->folder()) 00189 { 00190 killAllJobs(); 00191 break; 00192 } 00193 else ++it; 00194 } 00195 } 00196 00197 // Reimplemented from ImapAccountBase because we only check one folder at a time 00198 void KMAcctCachedImap::slotCheckQueuedFolders() 00199 { 00200 mMailCheckFolders.clear(); 00201 mMailCheckFolders.append( mFoldersQueuedForChecking.front() ); 00202 mFoldersQueuedForChecking.pop_front(); 00203 if ( mFoldersQueuedForChecking.isEmpty() ) 00204 disconnect( this, SIGNAL( finishedCheck( bool, CheckStatus ) ), 00205 this, SLOT( slotCheckQueuedFolders() ) ); 00206 00207 kmkernel->acctMgr()->singleCheckMail(this, true); 00208 mMailCheckFolders.clear(); 00209 } 00210 00211 void KMAcctCachedImap::processNewMail( bool interactive ) 00212 { 00213 if ( !mFolder ) { // happens if this is a pseudo-account (from configuredialog) 00214 checkDone( false, CheckIgnored ); 00215 return; 00216 } 00217 if ( mMailCheckFolders.isEmpty() ) 00218 processNewMail( mFolder, interactive, true ); 00219 else { 00220 KMFolder* f = mMailCheckFolders.front(); 00221 mMailCheckFolders.pop_front(); 00222 processNewMail( static_cast<KMFolderCachedImap *>( f->storage() ), interactive, false ); 00223 } 00224 } 00225 00226 void KMAcctCachedImap::processNewMail( KMFolderCachedImap* folder, 00227 bool interactive, 00228 bool recurse ) 00229 { 00230 // This should never be set for a cached IMAP account 00231 mAutoExpunge = false; 00232 mCountLastUnread = 0; 00233 mUnreadBeforeCheck.clear(); 00234 // stop sending noops during sync, that will keep the connection open 00235 mNoopTimer.stop(); 00236 00237 if( interactive && isProgressDialogEnabled() ) { 00238 // Show progress dialog in all listeners. 00239 KPIM::ProgressManager::emitShowProgressDialog(); 00240 } 00241 00242 Q_ASSERT( !mMailCheckProgressItem ); 00243 mMailCheckProgressItem = KPIM::ProgressManager::createProgressItem( 00244 "MailCheck" + QString::number( id() ), 00245 folder->label(), // will be changed immediately in serverSync anyway 00246 QString::null, 00247 true, // can be cancelled 00248 useSSL() || useTLS() ); 00249 connect( mMailCheckProgressItem, SIGNAL( progressItemCanceled( ProgressItem* ) ), 00250 this, SLOT( slotProgressItemCanceled( ProgressItem* ) ) ); 00251 00252 folder->setAccount(this); 00253 connect(folder, SIGNAL(folderComplete(KMFolderCachedImap*, bool)), 00254 this, SLOT(postProcessNewMail(KMFolderCachedImap*, bool))); 00255 folder->serverSync( recurse ); 00256 } 00257 00258 void KMAcctCachedImap::postProcessNewMail( KMFolderCachedImap* folder, bool ) 00259 { 00260 mNoopTimer.start( 60000 ); // send a noop every minute to avoid "connection broken" errors 00261 disconnect(folder, SIGNAL(folderComplete(KMFolderCachedImap*, bool)), 00262 this, SLOT(postProcessNewMail(KMFolderCachedImap*, bool))); 00263 mMailCheckProgressItem->setComplete(); 00264 mMailCheckProgressItem = 0; 00265 00266 if ( folder == mFolder ) { 00267 // We remove everything from the deleted folders list after a full sync. 00268 // Even if it fails (no permission), because on the next sync we want the folder to reappear, 00269 // instead of the user being stuck with "can't delete" every time. 00270 // And we do it for _all_ deleted folders, even those that were deleted on the server in the first place (slotListResult). 00271 // Otherwise this might have side effects much later (e.g. when regaining permissions to a folder we could see before) 00272 mDeletedFolders.clear(); 00273 mPreviouslyDeletedFolders.clear(); 00274 } 00275 00276 KMail::ImapAccountBase::postProcessNewMail(); 00277 } 00278 00279 void KMAcctCachedImap::addUnreadMsgCount( const KMFolderCachedImap *folder, 00280 int countUnread ) 00281 { 00282 if ( folder->imapPath() != "/INBOX/" ) { 00283 // new mail in INBOX is processed with KMAccount::processNewMsg() and 00284 // therefore doesn't need to be counted here 00285 const QString folderId = folder->folder()->idString(); 00286 int newInFolder = countUnread; 00287 if ( mUnreadBeforeCheck.find( folderId ) != mUnreadBeforeCheck.end() ) 00288 newInFolder -= mUnreadBeforeCheck[folderId]; 00289 if ( newInFolder > 0 ) 00290 addToNewInFolder( folderId, newInFolder ); 00291 } 00292 mCountUnread += countUnread; 00293 } 00294 00295 void KMAcctCachedImap::addLastUnreadMsgCount( const KMFolderCachedImap *folder, 00296 int countLastUnread ) 00297 { 00298 mUnreadBeforeCheck[folder->folder()->idString()] = countLastUnread; 00299 mCountLastUnread += countLastUnread; 00300 } 00301 00302 // 00303 // 00304 // read/write config 00305 // 00306 // 00307 00308 void KMAcctCachedImap::readConfig( /*const*/ KConfig/*Base*/ & config ) { 00309 ImapAccountBase::readConfig( config ); 00310 setProgressDialogEnabled( config.readBoolEntry( "progressdialog", true ) ); 00311 // Apparently this method is only ever called once (from KMKernel::init) so this is ok 00312 mPreviouslyDeletedFolders = config.readListEntry( "deleted-folders" ); 00313 mDeletedFolders.clear(); // but just in case... 00314 const QStringList oldPaths = config.readListEntry( "renamed-folders-paths" ); 00315 const QStringList newNames = config.readListEntry( "renamed-folders-names" ); 00316 QStringList::const_iterator it = oldPaths.begin(); 00317 QStringList::const_iterator nameit = newNames.begin(); 00318 for( ; it != oldPaths.end() && nameit != newNames.end(); ++it, ++nameit ) { 00319 addRenamedFolder( *it, QString::null, *nameit ); 00320 } 00321 } 00322 00323 void KMAcctCachedImap::writeConfig( KConfig/*Base*/ & config ) /*const*/ { 00324 ImapAccountBase::writeConfig( config ); 00325 config.writeEntry( "progressdialog", isProgressDialogEnabled() ); 00326 config.writeEntry( "deleted-folders", mDeletedFolders + mPreviouslyDeletedFolders ); 00327 config.writeEntry( "renamed-folders-paths", mRenamedFolders.keys() ); 00328 const QValueList<RenamedFolder> values = mRenamedFolders.values(); 00329 QStringList lstNames; 00330 QValueList<RenamedFolder>::const_iterator it = values.begin(); 00331 for ( ; it != values.end() ; ++it ) 00332 lstNames.append( (*it).mNewName ); 00333 config.writeEntry( "renamed-folders-names", lstNames ); 00334 } 00335 00336 void KMAcctCachedImap::invalidateIMAPFolders() 00337 { 00338 invalidateIMAPFolders( mFolder ); 00339 } 00340 00341 void KMAcctCachedImap::invalidateIMAPFolders( KMFolderCachedImap* folder ) 00342 { 00343 if( !folder || !folder->folder() ) 00344 return; 00345 00346 folder->setAccount(this); 00347 00348 QStringList strList; 00349 QValueList<QGuardedPtr<KMFolder> > folderList; 00350 kmkernel->dimapFolderMgr()->createFolderList( &strList, &folderList, 00351 folder->folder()->child(), QString::null, 00352 false ); 00353 QValueList<QGuardedPtr<KMFolder> >::Iterator it; 00354 mCountLastUnread = 0; 00355 mUnreadBeforeCheck.clear(); 00356 00357 for( it = folderList.begin(); it != folderList.end(); ++it ) { 00358 KMFolder *f = *it; 00359 if( f && f->folderType() == KMFolderTypeCachedImap ) { 00360 KMFolderCachedImap *cfolder = static_cast<KMFolderCachedImap*>(f->storage()); 00361 // This invalidates the folder completely 00362 cfolder->setUidValidity("INVALID"); 00363 cfolder->writeUidCache(); 00364 processNewMailSingleFolder( f ); 00365 } 00366 } 00367 folder->setUidValidity("INVALID"); 00368 folder->writeUidCache(); 00369 00370 processNewMailSingleFolder( folder->folder() ); 00371 } 00372 00373 //----------------------------------------------------------------------------- 00374 void KMAcctCachedImap::addDeletedFolder( const QString& subFolderPath ) 00375 { 00376 mDeletedFolders.append( subFolderPath ); 00377 } 00378 00379 bool KMAcctCachedImap::isDeletedFolder( const QString& subFolderPath ) const 00380 { 00381 return mDeletedFolders.find( subFolderPath ) != mDeletedFolders.end(); 00382 } 00383 00384 bool KMAcctCachedImap::isPreviouslyDeletedFolder( const QString& subFolderPath ) const 00385 { 00386 return mPreviouslyDeletedFolders.find( subFolderPath ) != mPreviouslyDeletedFolders.end(); 00387 } 00388 00389 void KMAcctCachedImap::removeDeletedFolder( const QString& subFolderPath ) 00390 { 00391 mDeletedFolders.remove( subFolderPath ); 00392 mPreviouslyDeletedFolders.remove( subFolderPath ); 00393 } 00394 00395 void KMAcctCachedImap::addRenamedFolder( const QString& subFolderPath, const QString& oldLabel, const QString& newName ) 00396 { 00397 mRenamedFolders.insert( subFolderPath, RenamedFolder( oldLabel, newName ) ); 00398 } 00399 00400 void KMAcctCachedImap::removeRenamedFolder( const QString& subFolderPath ) 00401 { 00402 mRenamedFolders.remove( subFolderPath ); 00403 } 00404 00405 void KMAcctCachedImap::slotProgressItemCanceled( ProgressItem* ) 00406 { 00407 killAllJobs( false ); 00408 } 00409 00410 FolderStorage* const KMAcctCachedImap::rootFolder() const 00411 { 00412 return mFolder; 00413 } 00414 00415 00416 QString KMAcctCachedImap::renamedFolder( const QString& imapPath ) const 00417 { 00418 QMap<QString, RenamedFolder>::ConstIterator renit = mRenamedFolders.find( imapPath ); 00419 if ( renit != mRenamedFolders.end() ) 00420 return (*renit).mNewName; 00421 return QString::null; 00422 } 00423 00424 #include "kmacctcachedimap.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:18 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003