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 ), mInteractive( true )
00051 {
00052 mFolder = 0;
00053 mNoopTimer.start( 60000 );
00054 mOpenFolders.setAutoDelete(true);
00055 connect(kmkernel->imapFolderMgr(), SIGNAL(changed()),
00056 this, SLOT(slotUpdateFolderList()));
00057 connect(&mErrorTimer, SIGNAL(timeout()), SLOT(slotResetConnectionError()));
00058 }
00059
00060
00061
00062 KMAcctImap::~KMAcctImap()
00063 {
00064 killAllJobs( true );
00065 }
00066
00067
00068
00069 QString KMAcctImap::type() const
00070 {
00071 return "imap";
00072 }
00073
00074
00075 void KMAcctImap::pseudoAssign( const KMAccount * a ) {
00076 killAllJobs( true );
00077 if (mFolder)
00078 {
00079 mFolder->setContentState(KMFolderImap::imapNoInformation);
00080 mFolder->setSubfolderState(KMFolderImap::imapNoInformation);
00081 }
00082 ImapAccountBase::pseudoAssign( a );
00083 }
00084
00085
00086 void KMAcctImap::setImapFolder(KMFolderImap *aFolder)
00087 {
00088 mFolder = aFolder;
00089 mFolder->setImapPath(mPrefix);
00090 }
00091
00092
00093
00094
00095 bool KMAcctImap::handleError( int errorCode, const QString &errorMsg, KIO::Job* job, const QString& context, bool abortSync )
00096 {
00097
00098 if ( errorCode == KIO::ERR_DOES_NOT_EXIST ) {
00099
00100 if ( mFolder )
00101 mFolder->listDirectory();
00102 return true;
00103 }
00104 return ImapAccountBase::handleError( errorCode, errorMsg, job, context, abortSync );
00105 }
00106
00107
00108
00109 void KMAcctImap::killAllJobs( bool disconnectSlave )
00110 {
00111 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin();
00112 for ( ; it != mapJobData.end(); ++it)
00113 {
00114 QPtrList<KMMessage> msgList = (*it).msgList;
00115 QPtrList<KMMessage>::Iterator it2 = msgList.begin();
00116 for ( ; it2 != msgList.end(); ++it2 ) {
00117 KMMessage *msg = *it2;
00118 if ( msg->transferInProgress() ) {
00119 kdDebug(5006) << "KMAcctImap::killAllJobs - resetting mail" << endl;
00120 msg->setTransferInProgress( false );
00121 }
00122 }
00123 if ((*it).parent)
00124 {
00125
00126 KMFolderImap *fld = static_cast<KMFolderImap*>((*it).parent->storage());
00127 fld->setCheckingValidity(false);
00128 fld->setContentState(KMFolderImap::imapNoInformation);
00129 fld->setSubfolderState(KMFolderImap::imapNoInformation);
00130 fld->sendFolderComplete(FALSE);
00131 fld->removeJobs();
00132 }
00133 if ( (*it).progressItem )
00134 {
00135 (*it).progressItem->setComplete();
00136 }
00137 }
00138 if (mSlave && mapJobData.begin() != mapJobData.end())
00139 {
00140 mSlave->kill();
00141 mSlave = 0;
00142 }
00143
00144 mapJobData.clear();
00145 KMAccount::deleteFolderJobs();
00146
00147 if (mCountRemainChecks > 0)
00148 {
00149 checkDone( false, CheckOK );
00150 mCountRemainChecks = 0;
00151 }
00152 if ( disconnectSlave && slave() ) {
00153 KIO::Scheduler::disconnectSlave( slave() );
00154 mSlave = 0;
00155 }
00156 }
00157
00158
00159 void KMAcctImap::ignoreJobsForMessage( KMMessage* msg )
00160 {
00161 if (!msg) return;
00162 QPtrListIterator<ImapJob> it( mJobList );
00163 while ( it.current() )
00164 {
00165 ImapJob *job = it.current();
00166 ++it;
00167 if ( job->msgList().findRef( msg ) != -1 )
00168 {
00169 job->kill();
00170 }
00171 }
00172 }
00173
00174
00175 void KMAcctImap::ignoreJobsForFolder( KMFolder* folder )
00176 {
00177 QPtrListIterator<ImapJob> it( mJobList );
00178 while ( it.current() )
00179 {
00180 ImapJob *job = it.current();
00181 ++it;
00182 if ( !job->msgList().isEmpty() && job->msgList().first()->parent() == folder )
00183 {
00184 job->kill();
00185 }
00186 }
00187 }
00188
00189
00190 void KMAcctImap::removeSlaveJobsForFolder( KMFolder* folder )
00191 {
00192
00193 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin();
00194 while ( it != mapJobData.end() ) {
00195 QMap<KIO::Job*, jobData>::Iterator i = it;
00196 it++;
00197 if ( (*i).parent ) {
00198 if ( (*i).parent == folder ) {
00199 mapJobData.remove(i);
00200 }
00201 }
00202 }
00203 }
00204
00205
00206 void KMAcctImap::cancelMailCheck()
00207 {
00208
00209 QValueList<KMFolderImap*> folderList;
00210 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin();
00211 for (; it != mapJobData.end(); ++it) {
00212 if ( (*it).cancellable && (*it).parent ) {
00213 folderList << static_cast<KMFolderImap*>((*it).parent->storage());
00214 }
00215 }
00216
00217
00218
00219 killAllJobs( true );
00220
00221
00222 for( QValueList<KMFolderImap*>::Iterator it = folderList.begin(); it != folderList.end(); ++it ) {
00223 KMFolderImap *fld = *it;
00224 fld->sendFolderComplete(FALSE);
00225 }
00226 }
00227
00228
00229 void KMAcctImap::processNewMail(bool interactive)
00230 {
00231 if (!mFolder || !mFolder->folder() || !mFolder->folder()->child() ||
00232 makeConnection() == ImapAccountBase::Error)
00233 {
00234 mCountRemainChecks = 0;
00235 checkDone( false, CheckError );
00236 return;
00237 }
00238
00239 if( mMailCheckFolders.isEmpty() )
00240 {
00241 slotUpdateFolderList();
00242
00243 if( mMailCheckFolders.isEmpty() )
00244 {
00245 checkDone( false, CheckOK );
00246 return;
00247 }
00248 }
00249
00250 mInteractive = interactive;
00251
00252 if ( mMailCheckFolders.count() > 1 ) {
00253 connect( listDirProgressItem(), SIGNAL( progressItemCompleted( ProgressItem *) ),
00254 this, SLOT( slotContinueMailCheck() ) );
00255 listDirectory();
00256 } else{
00257 slotContinueMailCheck();
00258 }
00259 }
00260
00261 void KMAcctImap::slotContinueMailCheck()
00262 {
00263
00264 Q_ASSERT( !mMailCheckProgressItem );
00265 mMailCheckProgressItem =
00266 ProgressManager::createProgressItem(
00267 "MailCheckAccount" + name(),
00268 i18n("Checking account: " ) + name(),
00269 QString::null,
00270 true,
00271 useSSL() || useTLS() );
00272
00273 mMailCheckProgressItem->setTotalItems( mMailCheckFolders.count() );
00274 connect ( mMailCheckProgressItem,
00275 SIGNAL( progressItemCanceled( ProgressItem*) ),
00276 this,
00277 SLOT( slotMailCheckCanceled() ) );
00278
00279 QValueList<QGuardedPtr<KMFolder> >::Iterator it;
00280
00281 mCountRemainChecks = 0;
00282 mCountUnread = 0;
00283 mUnreadBeforeCheck.clear();
00284 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); it++)
00285 {
00286 KMFolder *folder = *it;
00287 if (folder && !folder->noContent())
00288 {
00289 mUnreadBeforeCheck[folder->idString()] = folder->countUnread();
00290 }
00291 }
00292 bool gotError = false;
00293
00294 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); it++)
00295 {
00296 KMFolder *folder = *it;
00297 if (folder && !folder->noContent())
00298 {
00299 KMFolderImap *imapFolder = static_cast<KMFolderImap*>(folder->storage());
00300 if (imapFolder->getContentState() != KMFolderImap::imapInProgress)
00301 {
00302
00303 mCountRemainChecks++;
00304 if (imapFolder->isSelected()) {
00305 connect(imapFolder, SIGNAL(folderComplete(KMFolderImap*, bool)),
00306 this, SLOT(postProcessNewMail(KMFolderImap*, bool)));
00307 imapFolder->getFolder();
00308 }
00309 else {
00310 connect(imapFolder, SIGNAL(numUnreadMsgsChanged(KMFolder*)),
00311 this, SLOT(postProcessNewMail(KMFolder*)));
00312 bool ok = imapFolder->processNewMail(mInteractive);
00313 if (!ok)
00314 {
00315
00316 mCountRemainChecks--;
00317 gotError = true;
00318 if ( mMailCheckProgressItem ) {
00319 mMailCheckProgressItem->incCompletedItems();
00320 mMailCheckProgressItem->updateProgress();
00321 }
00322 }
00323 }
00324 }
00325 }
00326 }
00327 if ( gotError )
00328 slotUpdateFolderList();
00329
00330 if ( mCountRemainChecks == 0 )
00331 {
00332 mCountLastUnread = 0;
00333 ImapAccountBase::postProcessNewMail();
00334 mUnreadBeforeCheck.clear();
00335 }
00336 }
00337
00338
00339 void KMAcctImap::postProcessNewMail(KMFolderImap* folder, bool)
00340 {
00341 disconnect(folder, SIGNAL(folderComplete(KMFolderImap*, bool)),
00342 this, SLOT(postProcessNewMail(KMFolderImap*, bool)));
00343 postProcessNewMail(static_cast<KMFolder*>(folder->folder()));
00344 }
00345
00346 void KMAcctImap::postProcessNewMail( KMFolder * folder ) {
00347
00348 disconnect( folder->storage(), SIGNAL(numUnreadMsgsChanged(KMFolder*)),
00349 this, SLOT(postProcessNewMail(KMFolder*)) );
00350
00351 if ( mMailCheckProgressItem ) {
00352 mMailCheckProgressItem->incCompletedItems();
00353 mMailCheckProgressItem->updateProgress();
00354 mMailCheckProgressItem->setStatus( folder->prettyURL() + i18n(" completed") );
00355 }
00356 mCountRemainChecks--;
00357
00358
00359 const QString folderId = folder->idString();
00360 int newInFolder = folder->countUnread();
00361 if ( mUnreadBeforeCheck.find( folderId ) != mUnreadBeforeCheck.end() )
00362 newInFolder -= mUnreadBeforeCheck[folderId];
00363 if ( newInFolder > 0 ) {
00364 addToNewInFolder( folderId, newInFolder );
00365 mCountUnread += newInFolder;
00366 }
00367 if (mCountRemainChecks == 0)
00368 {
00369
00370 mCountLastUnread = 0;
00371 ImapAccountBase::postProcessNewMail();
00372 mUnreadBeforeCheck.clear();
00373 }
00374 }
00375
00376
00377 void KMAcctImap::slotUpdateFolderList()
00378 {
00379 if ( !mFolder || !mFolder->folder() || !mFolder->folder()->child() )
00380 {
00381 kdWarning(5006) << "KMAcctImap::slotUpdateFolderList return" << endl;
00382 return;
00383 }
00384 QStringList strList;
00385 mMailCheckFolders.clear();
00386 kmkernel->imapFolderMgr()->createFolderList(&strList, &mMailCheckFolders,
00387 mFolder->folder()->child(), QString::null, false);
00388
00389 QValueList<QGuardedPtr<KMFolder> > includedFolders;
00390
00391 QValueList<QGuardedPtr<KMFolder> >::Iterator it;
00392 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); it++)
00393 {
00394 KMFolderImap* folder = static_cast<KMFolderImap*>(((KMFolder*)(*it))->storage());
00395 if (folder->includeInMailCheck())
00396 includedFolders.append(*it);
00397 }
00398 mMailCheckFolders = includedFolders;
00399 }
00400
00401
00402 void KMAcctImap::listDirectory()
00403 {
00404 mFolder->listDirectory();
00405 }
00406
00407
00408 void KMAcctImap::setPrefixHook() {
00409 if ( mFolder ) mFolder->setImapPath( prefix() );
00410 }
00411
00412
00413 void KMAcctImap::readConfig(KConfig& config)
00414 {
00415 ImapAccountBase::readConfig( config );
00416 }
00417
00418
00419 void KMAcctImap::slotMailCheckCanceled()
00420 {
00421 if( mMailCheckProgressItem )
00422 mMailCheckProgressItem->setComplete();
00423 cancelMailCheck();
00424 }
00425
00426
00427 FolderStorage* const KMAcctImap::rootFolder() const
00428 {
00429 return mFolder;
00430 }
00431
00432 ImapAccountBase::ConnectionState KMAcctImap::makeConnection()
00433 {
00434 if ( mSlaveConnectionError )
00435 {
00436 mErrorTimer.start(100, true);
00437 return Error;
00438 }
00439 return ImapAccountBase::makeConnection();
00440 }
00441
00442 void KMAcctImap::slotResetConnectionError()
00443 {
00444 mSlaveConnectionError = false;
00445 kdDebug(5006) << k_funcinfo << endl;
00446 }
00447
00448 #include "kmacctimap.moc"