00001
00022 #ifdef HAVE_CONFIG_H
00023 #include <config.h>
00024 #endif
00025
00026 #include "kmacctimap.h"
00027 using KMail::SieveConfig;
00028
00029 #include "kmbroadcaststatus.h"
00030 #include "kmfoldertree.h"
00031 #include "kmfoldermgr.h"
00032 #include "kmfolderimap.h"
00033 #include "kmmainwin.h"
00034 #include "imapjob.h"
00035 using KMail::ImapJob;
00036
00037 #include <kio/scheduler.h>
00038 #include <kio/slave.h>
00039 #include <kmessagebox.h>
00040 #include <kdebug.h>
00041
00042
00043
00044 KMAcctImap::KMAcctImap(KMAcctMgr* aOwner, const QString& aAccountName):
00045 KMail::ImapAccountBase(aOwner, aAccountName)
00046 {
00047 mFolder = 0;
00048 mOpenFolders.setAutoDelete(true);
00049 connect(KMBroadcastStatus::instance(), SIGNAL(signalAbortRequested()),
00050 this, SLOT(slotAbortRequested()));
00051 connect(&mIdleTimer, SIGNAL(timeout()), SLOT(slotIdleTimeout()));
00052 KIO::Scheduler::connect(
00053 SIGNAL(slaveError(KIO::Slave *, int, const QString &)),
00054 this, SLOT(slotSlaveError(KIO::Slave *, int, const QString &)));
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 mIdleTimer.stop();
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 void KMAcctImap::slotSlaveError(KIO::Slave *aSlave, int errorCode,
00095 const QString &errorMsg)
00096 {
00097 if (aSlave != mSlave) return;
00098 if (errorCode == KIO::ERR_SLAVE_DIED) slaveDied();
00099 if (errorCode == KIO::ERR_COULD_NOT_LOGIN && !mStorePasswd) mAskAgain = TRUE;
00100 if (errorCode == KIO::ERR_DOES_NOT_EXIST)
00101 {
00102
00103 if (mFolder) mFolder->listDirectory();
00104 return;
00105 }
00106
00107
00108 killAllJobs( errorCode == KIO::ERR_CONNECTION_BROKEN );
00109
00110 if ( !mErrorDialogIsActive )
00111 {
00112 mErrorDialogIsActive = true;
00113 KMessageBox::error(kmkernel->mainWin(),
00114 KIO::buildErrorString(errorCode, errorMsg));
00115 mErrorDialogIsActive = false;
00116 } else {
00117 kdDebug(5006) << "suppressing error:" << errorMsg << endl;
00118 }
00119 if ( errorCode == KIO::ERR_COULD_NOT_MKDIR ) {
00120
00121 if ( mFolder )
00122 mFolder->listDirectory( );
00123 }
00124 }
00125
00126
00127
00128 void KMAcctImap::slotIdleTimeout()
00129 {
00130 if (mIdle)
00131 {
00132 if (mSlave) KIO::Scheduler::disconnectSlave(mSlave);
00133 mSlave = 0;
00134 mIdleTimer.stop();
00135 } else {
00136 if (mSlave)
00137 {
00138 QByteArray packedArgs;
00139 QDataStream stream( packedArgs, IO_WriteOnly);
00140
00141 stream << (int) 'N';
00142
00143 KIO::SimpleJob *job = KIO::special(getUrl(), packedArgs, FALSE);
00144 KIO::Scheduler::assignJobToSlave(mSlave, job);
00145 connect(job, SIGNAL(result(KIO::Job *)),
00146 this, SLOT(slotSimpleResult(KIO::Job *)));
00147 }
00148 else mIdleTimer.stop();
00149 }
00150 }
00151
00152
00153
00154 void KMAcctImap::slotAbortRequested()
00155 {
00156 killAllJobs();
00157 }
00158
00159
00160
00161 void KMAcctImap::killAllJobs( bool disconnectSlave )
00162 {
00163 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin();
00164 for (it = mapJobData.begin(); it != mapJobData.end(); ++it)
00165 if ((*it).parent)
00166 {
00167
00168 KMFolderImap *fld = static_cast<KMFolderImap*>((*it).parent);
00169 fld->setCheckingValidity(false);
00170 fld->setContentState(KMFolderImap::imapNoInformation);
00171 fld->setSubfolderState(KMFolderImap::imapNoInformation);
00172 fld->sendFolderComplete(FALSE);
00173 fld->removeJobs();
00174 }
00175 if (mSlave && mapJobData.begin() != mapJobData.end())
00176 {
00177 mSlave->kill();
00178 mSlave = 0;
00179 }
00180
00181 mapJobData.clear();
00182 KMAccount::deleteFolderJobs();
00183
00184 if (mCountRemainChecks > 0)
00185 {
00186 checkDone(false, 0);
00187 mCountRemainChecks = 0;
00188 }
00189 displayProgress();
00190
00191 if ( disconnectSlave && slave() ) {
00192 KIO::Scheduler::disconnectSlave( slave() );
00193 mSlave = 0;
00194 }
00195 }
00196
00197
00198 void KMAcctImap::ignoreJobsForMessage( KMMessage* msg )
00199 {
00200 if (!msg) return;
00201 QPtrListIterator<ImapJob> it( mJobList );
00202 while ( it.current() )
00203 {
00204 ImapJob *job = it.current();
00205 ++it;
00206 if ( job->msgList().findRef( msg ) != -1 )
00207 {
00208 if ( job->mJob )
00209 removeJob( job->mJob );
00210 mJobList.remove( job );
00211 delete job;
00212 }
00213 }
00214 }
00215
00216
00217 void KMAcctImap::ignoreJobsForFolder( KMFolder* folder )
00218 {
00219 QPtrListIterator<ImapJob> it( mJobList );
00220 while ( it.current() )
00221 {
00222 ImapJob *job = it.current();
00223 ++it;
00224 if ( !job->msgList().isEmpty() && job->msgList().first()->parent() == folder )
00225 {
00226 if ( job->mJob )
00227 removeJob( job->mJob );
00228 mJobList.remove( job );
00229 delete job;
00230 }
00231 }
00232 }
00233
00234
00235 void KMAcctImap::removeSlaveJobsForFolder( KMFolder* folder )
00236 {
00237
00238 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin();
00239 while ( it != mapJobData.end() ) {
00240 QMap<KIO::Job*, jobData>::Iterator i = it;
00241 it++;
00242 if ( (*i).parent ) {
00243 if ( (*i).parent == folder ) {
00244 mapJobData.remove(i);
00245 }
00246 }
00247 }
00248 }
00249
00250
00251 void KMAcctImap::slotSimpleResult(KIO::Job * job)
00252 {
00253 JobIterator it = findJob( job );
00254 bool quiet = FALSE;
00255 if (it != mapJobData.end())
00256 {
00257 quiet = (*it).quiet;
00258 removeJob(it);
00259 }
00260 if (job->error())
00261 {
00262 if (!quiet)
00263 slotSlaveError(mSlave, job->error(), job->errorText() );
00264 else if ( job->error() == KIO::ERR_CONNECTION_BROKEN && slave() ) {
00265
00266
00267 KIO::Scheduler::disconnectSlave( slave() );
00268 mSlave = 0;
00269 }
00270 if (job->error() == KIO::ERR_SLAVE_DIED)
00271 slaveDied();
00272 }
00273 displayProgress();
00274 }
00275
00276
00277
00278 void KMAcctImap::processNewMail(bool interactive)
00279 {
00280 if (!mFolder || !mFolder->child() ||
00281 makeConnection() != ImapAccountBase::Connected)
00282 {
00283 mCountRemainChecks = 0;
00284 checkDone(false, 0);
00285 return;
00286 }
00287
00288 if( mMailCheckFolders.isEmpty() )
00289 {
00290 slotUpdateFolderList();
00291
00292 if( mMailCheckFolders.isEmpty() )
00293 {
00294 checkDone(false, 0);
00295 }
00296 }
00297 QValueList<QGuardedPtr<KMFolder> >::Iterator it;
00298
00299 mCountRemainChecks = 0;
00300 mCountLastUnread = 0;
00301 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); it++)
00302 {
00303 KMFolder *folder = *it;
00304 if (folder && !folder->noContent())
00305 {
00306 mCountLastUnread += folder->countUnread();
00307 }
00308 }
00309 bool gotError = false;
00310
00311 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); it++)
00312 {
00313 KMFolder *folder = *it;
00314 if (folder && !folder->noContent())
00315 {
00316 KMFolderImap *imapFolder = static_cast<KMFolderImap*>(folder);
00317 if (imapFolder->getContentState() != KMFolderImap::imapInProgress)
00318 {
00319
00320 mCountRemainChecks++;
00321 if (imapFolder->isSelected()) {
00322 connect(imapFolder, SIGNAL(folderComplete(KMFolderImap*, bool)),
00323 this, SLOT(postProcessNewMail(KMFolderImap*, bool)));
00324 imapFolder->getFolder();
00325 }
00326 else {
00327 connect(imapFolder, SIGNAL(numUnreadMsgsChanged(KMFolder*)),
00328 this, SLOT(postProcessNewMail(KMFolder*)));
00329 bool ok = imapFolder->processNewMail(interactive);
00330 if (!ok)
00331 {
00332
00333 mCountRemainChecks--;
00334 gotError = true;
00335 }
00336 }
00337 }
00338 }
00339 }
00340 if ( gotError )
00341 slotUpdateFolderList();
00342 }
00343
00344
00345 void KMAcctImap::postProcessNewMail(KMFolderImap* folder, bool)
00346 {
00347 disconnect(folder, SIGNAL(folderComplete(KMFolderImap*, bool)),
00348 this, SLOT(postProcessNewMail(KMFolderImap*, bool)));
00349 postProcessNewMail(static_cast<KMFolder*>(folder));
00350 }
00351
00352
00353 void KMAcctImap::slotUpdateFolderList()
00354 {
00355 if (!mFolder || !mFolder->child() ||
00356 makeConnection() != ImapAccountBase::Connected)
00357 return;
00358 QStringList strList;
00359 mMailCheckFolders.clear();
00360 kmkernel->imapFolderMgr()->createFolderList(&strList, &mMailCheckFolders,
00361 mFolder->child(), QString::null, false);
00362
00363 QValueList<QGuardedPtr<KMFolder> > includedFolders;
00364
00365 QValueList<QGuardedPtr<KMFolder> >::Iterator it;
00366 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); it++)
00367 {
00368 KMFolderImap* folder = static_cast<KMFolderImap*>((KMFolder*)(*it));
00369 if (folder->includeInMailCheck())
00370 includedFolders.append(*it);
00371 }
00372 mMailCheckFolders = includedFolders;
00373 }
00374
00375
00376 void KMAcctImap::listDirectory(QString path, bool onlySubscribed,
00377 bool secondStep, KMFolder* parent, bool reset)
00378 {
00379 ImapAccountBase::listDirectory( path, onlySubscribed, secondStep, parent, reset );
00380 }
00381
00382
00383 void KMAcctImap::listDirectory()
00384 {
00385 mFolder->listDirectory();
00386 }
00387
00388
00389 void KMAcctImap::setPrefixHook() {
00390 if ( mFolder ) mFolder->setImapPath( prefix() );
00391 }
00392
00393
00394 void KMAcctImap::readConfig(KConfig& config)
00395 {
00396 ImapAccountBase::readConfig( config );
00397 if ( checkExclude() ) {
00398 disconnect(kmkernel->imapFolderMgr(), SIGNAL(changed()),
00399 this, SLOT(slotUpdateFolderList()));
00400 }
00401 }
00402
00403 #include "kmacctimap.moc"