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
00065 mAutoExpunge = false;
00066 }
00067
00068
00069
00070 KMAcctCachedImap::~KMAcctCachedImap()
00071 {
00072 killAllJobsInternal( 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 )
00117 {
00118
00119 mAutoExpunge = false;
00120 }
00121
00122
00123 void KMAcctCachedImap::killAllJobs( bool disconnectSlave )
00124 {
00125
00126 QValueList<KMFolderCachedImap*> folderList = killAllJobsInternal( disconnectSlave );
00127 for( QValueList<KMFolderCachedImap*>::Iterator it = folderList.begin(); it != folderList.end(); ++it ) {
00128 KMFolderCachedImap *fld = *it;
00129 fld->resetSyncState();
00130 fld->setContentState(KMFolderCachedImap::imapNoInformation);
00131 fld->setSubfolderState(KMFolderCachedImap::imapNoInformation);
00132 fld->sendFolderComplete(FALSE);
00133 }
00134 }
00135
00136
00137
00138 QValueList<KMFolderCachedImap*> KMAcctCachedImap::killAllJobsInternal( bool disconnectSlave )
00139 {
00140
00141
00142 QValueList<KMFolderCachedImap*> folderList;
00143 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin();
00144 for (; it != mapJobData.end(); ++it) {
00145 if ((*it).parent)
00146 folderList << static_cast<KMFolderCachedImap*>((*it).parent->storage());
00147
00148 if ( !it.key()->error() && mSlave ) {
00149 it.key()->kill();
00150 mSlave = 0;
00151 }
00152 }
00153 mapJobData.clear();
00154
00155
00156 for( QPtrListIterator<CachedImapJob> it( mJobList ); it.current(); ++it )
00157 it.current()->setPassiveDestructor( true );
00158 KMAccount::deleteFolderJobs();
00159
00160 if ( disconnectSlave && mSlave ) {
00161 KIO::Scheduler::disconnectSlave( mSlave );
00162 mSlave = 0;
00163 }
00164 return folderList;
00165 }
00166
00167
00168 void KMAcctCachedImap::cancelMailCheck()
00169 {
00170
00171 QValueList<KMFolderCachedImap*> folderList;
00172 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin();
00173 for (; it != mapJobData.end(); ++it) {
00174 if ( (*it).cancellable && (*it).parent )
00175 folderList << static_cast<KMFolderCachedImap*>((*it).parent->storage());
00176 }
00177
00178 ImapAccountBase::cancelMailCheck();
00179
00180
00181 for( QValueList<KMFolderCachedImap*>::Iterator it = folderList.begin(); it != folderList.end(); ++it ) {
00182 KMFolderCachedImap *fld = *it;
00183 fld->resetSyncState();
00184 fld->setContentState(KMFolderCachedImap::imapNoInformation);
00185 fld->setSubfolderState(KMFolderCachedImap::imapNoInformation);
00186 fld->sendFolderComplete(FALSE);
00187 }
00188 }
00189
00190
00191 void KMAcctCachedImap::killJobsForItem(KMFolderTreeItem * fti)
00192 {
00193 QMap<KIO::Job *, jobData>::Iterator it = mapJobData.begin();
00194 while (it != mapJobData.end())
00195 {
00196 if (it.data().parent == fti->folder())
00197 {
00198 killAllJobs();
00199 break;
00200 }
00201 else ++it;
00202 }
00203 }
00204
00205
00206 void KMAcctCachedImap::slotCheckQueuedFolders()
00207 {
00208 mMailCheckFolders.clear();
00209 mMailCheckFolders.append( mFoldersQueuedForChecking.front() );
00210 mFoldersQueuedForChecking.pop_front();
00211 if ( mFoldersQueuedForChecking.isEmpty() )
00212 disconnect( this, SIGNAL( finishedCheck( bool, CheckStatus ) ),
00213 this, SLOT( slotCheckQueuedFolders() ) );
00214
00215 kmkernel->acctMgr()->singleCheckMail(this, true);
00216 mMailCheckFolders.clear();
00217 }
00218
00219 void KMAcctCachedImap::processNewMail( bool interactive )
00220 {
00221 if ( !mFolder ) {
00222 checkDone( false, CheckIgnored );
00223 return;
00224 }
00225 if ( mMailCheckFolders.isEmpty() )
00226 processNewMail( mFolder, interactive, true );
00227 else {
00228 KMFolder* f = mMailCheckFolders.front();
00229 mMailCheckFolders.pop_front();
00230 processNewMail( static_cast<KMFolderCachedImap *>( f->storage() ), interactive, false );
00231 }
00232 }
00233
00234 void KMAcctCachedImap::processNewMail( KMFolderCachedImap* folder,
00235 bool interactive,
00236 bool recurse )
00237 {
00238
00239 mAutoExpunge = false;
00240 mCountLastUnread = 0;
00241 mUnreadBeforeCheck.clear();
00242
00243 mNoopTimer.stop();
00244
00245 if( interactive && isProgressDialogEnabled() ) {
00246
00247 KPIM::ProgressManager::emitShowProgressDialog();
00248 }
00249
00250 Q_ASSERT( !mMailCheckProgressItem );
00251 mMailCheckProgressItem = KPIM::ProgressManager::createProgressItem(
00252 "MailCheck" + QString::number( id() ),
00253 folder->label(),
00254 QString::null,
00255 true,
00256 useSSL() || useTLS() );
00257 connect( mMailCheckProgressItem, SIGNAL( progressItemCanceled( ProgressItem* ) ),
00258 this, SLOT( slotProgressItemCanceled( ProgressItem* ) ) );
00259
00260 folder->setAccount(this);
00261 connect(folder, SIGNAL(folderComplete(KMFolderCachedImap*, bool)),
00262 this, SLOT(postProcessNewMail(KMFolderCachedImap*, bool)));
00263 folder->serverSync( recurse );
00264 }
00265
00266 void KMAcctCachedImap::postProcessNewMail( KMFolderCachedImap* folder, bool )
00267 {
00268 mNoopTimer.start( 60000 );
00269 disconnect(folder, SIGNAL(folderComplete(KMFolderCachedImap*, bool)),
00270 this, SLOT(postProcessNewMail(KMFolderCachedImap*, bool)));
00271 mMailCheckProgressItem->setComplete();
00272 mMailCheckProgressItem = 0;
00273
00274 if ( folder == mFolder ) {
00275
00276
00277
00278
00279
00280 mDeletedFolders.clear();
00281 mPreviouslyDeletedFolders.clear();
00282 }
00283
00284 KMail::ImapAccountBase::postProcessNewMail();
00285 }
00286
00287 void KMAcctCachedImap::addUnreadMsgCount( const KMFolderCachedImap *folder,
00288 int countUnread )
00289 {
00290 if ( folder->imapPath() != "/INBOX/" ) {
00291
00292
00293 const QString folderId = folder->folder()->idString();
00294 int newInFolder = countUnread;
00295 if ( mUnreadBeforeCheck.find( folderId ) != mUnreadBeforeCheck.end() )
00296 newInFolder -= mUnreadBeforeCheck[folderId];
00297 if ( newInFolder > 0 )
00298 addToNewInFolder( folderId, newInFolder );
00299 }
00300 mCountUnread += countUnread;
00301 }
00302
00303 void KMAcctCachedImap::addLastUnreadMsgCount( const KMFolderCachedImap *folder,
00304 int countLastUnread )
00305 {
00306 mUnreadBeforeCheck[folder->folder()->idString()] = countLastUnread;
00307 mCountLastUnread += countLastUnread;
00308 }
00309
00310
00311
00312
00313
00314
00315
00316 void KMAcctCachedImap::readConfig( KConfig & config ) {
00317 ImapAccountBase::readConfig( config );
00318 setProgressDialogEnabled( config.readBoolEntry( "progressdialog", true ) );
00319
00320 mPreviouslyDeletedFolders = config.readListEntry( "deleted-folders" );
00321 mDeletedFolders.clear();
00322 const QStringList oldPaths = config.readListEntry( "renamed-folders-paths" );
00323 const QStringList newNames = config.readListEntry( "renamed-folders-names" );
00324 QStringList::const_iterator it = oldPaths.begin();
00325 QStringList::const_iterator nameit = newNames.begin();
00326 for( ; it != oldPaths.end() && nameit != newNames.end(); ++it, ++nameit ) {
00327 addRenamedFolder( *it, QString::null, *nameit );
00328 }
00329 }
00330
00331 void KMAcctCachedImap::writeConfig( KConfig & config ) {
00332 ImapAccountBase::writeConfig( config );
00333 config.writeEntry( "progressdialog", isProgressDialogEnabled() );
00334 config.writeEntry( "deleted-folders", mDeletedFolders + mPreviouslyDeletedFolders );
00335 config.writeEntry( "renamed-folders-paths", mRenamedFolders.keys() );
00336 const QValueList<RenamedFolder> values = mRenamedFolders.values();
00337 QStringList lstNames;
00338 QValueList<RenamedFolder>::const_iterator it = values.begin();
00339 for ( ; it != values.end() ; ++it )
00340 lstNames.append( (*it).mNewName );
00341 config.writeEntry( "renamed-folders-names", lstNames );
00342 }
00343
00344 void KMAcctCachedImap::invalidateIMAPFolders()
00345 {
00346 invalidateIMAPFolders( mFolder );
00347 }
00348
00349 void KMAcctCachedImap::invalidateIMAPFolders( KMFolderCachedImap* folder )
00350 {
00351 if( !folder || !folder->folder() )
00352 return;
00353
00354 folder->setAccount(this);
00355
00356 QStringList strList;
00357 QValueList<QGuardedPtr<KMFolder> > folderList;
00358 kmkernel->dimapFolderMgr()->createFolderList( &strList, &folderList,
00359 folder->folder()->child(), QString::null,
00360 false );
00361 QValueList<QGuardedPtr<KMFolder> >::Iterator it;
00362 mCountLastUnread = 0;
00363 mUnreadBeforeCheck.clear();
00364
00365 for( it = folderList.begin(); it != folderList.end(); ++it ) {
00366 KMFolder *f = *it;
00367 if( f && f->folderType() == KMFolderTypeCachedImap ) {
00368 KMFolderCachedImap *cfolder = static_cast<KMFolderCachedImap*>(f->storage());
00369
00370 cfolder->setUidValidity("INVALID");
00371 cfolder->writeUidCache();
00372 processNewMailSingleFolder( f );
00373 }
00374 }
00375 folder->setUidValidity("INVALID");
00376 folder->writeUidCache();
00377
00378 processNewMailSingleFolder( folder->folder() );
00379 }
00380
00381
00382 void KMAcctCachedImap::addDeletedFolder( const QString& subFolderPath )
00383 {
00384 mDeletedFolders.append( subFolderPath );
00385 }
00386
00387 bool KMAcctCachedImap::isDeletedFolder( const QString& subFolderPath ) const
00388 {
00389 return mDeletedFolders.find( subFolderPath ) != mDeletedFolders.end();
00390 }
00391
00392 bool KMAcctCachedImap::isPreviouslyDeletedFolder( const QString& subFolderPath ) const
00393 {
00394 return mPreviouslyDeletedFolders.find( subFolderPath ) != mPreviouslyDeletedFolders.end();
00395 }
00396
00397 void KMAcctCachedImap::removeDeletedFolder( const QString& subFolderPath )
00398 {
00399 mDeletedFolders.remove( subFolderPath );
00400 mPreviouslyDeletedFolders.remove( subFolderPath );
00401 }
00402
00403 void KMAcctCachedImap::addRenamedFolder( const QString& subFolderPath, const QString& oldLabel, const QString& newName )
00404 {
00405 mRenamedFolders.insert( subFolderPath, RenamedFolder( oldLabel, newName ) );
00406 }
00407
00408 void KMAcctCachedImap::removeRenamedFolder( const QString& subFolderPath )
00409 {
00410 mRenamedFolders.remove( subFolderPath );
00411 }
00412
00413 void KMAcctCachedImap::slotProgressItemCanceled( ProgressItem* )
00414 {
00415 bool abortConnection = !mSlaveConnected;
00416 killAllJobs( abortConnection );
00417 if ( abortConnection ) {
00418
00419 emit connectionResult( KIO::ERR_USER_CANCELED, QString::null );
00420 }
00421 }
00422
00423 FolderStorage* const KMAcctCachedImap::rootFolder() const
00424 {
00425 return mFolder;
00426 }
00427
00428
00429 QString KMAcctCachedImap::renamedFolder( const QString& imapPath ) const
00430 {
00431 QMap<QString, RenamedFolder>::ConstIterator renit = mRenamedFolders.find( imapPath );
00432 if ( renit != mRenamedFolders.end() )
00433 return (*renit).mNewName;
00434 return QString::null;
00435 }
00436
00437 #include "kmacctcachedimap.moc"