/** * kmacctimap.cpp * * Copyright (c) 2000-2002 Michael Haeckel * * This file is based on kmacctexppop.cpp by Don Sanders * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include "kmacctimap.h" using KMail::SieveConfig; #include "kmbroadcaststatus.h" #include "kmfoldertree.h" #include "kmfoldermgr.h" #include "kmfolderimap.h" #include "kmmainwin.h" #include "imapjob.h" using KMail::ImapJob; #include #include #include #include //----------------------------------------------------------------------------- KMAcctImap::KMAcctImap(KMAcctMgr* aOwner, const QString& aAccountName): KMail::ImapAccountBase(aOwner, aAccountName) { mFolder = 0; mOpenFolders.setAutoDelete(true); connect(KMBroadcastStatus::instance(), SIGNAL(signalAbortRequested()), this, SLOT(slotAbortRequested())); connect(&mIdleTimer, SIGNAL(timeout()), SLOT(slotIdleTimeout())); KIO::Scheduler::connect( SIGNAL(slaveError(KIO::Slave *, int, const QString &)), this, SLOT(slotSlaveError(KIO::Slave *, int, const QString &))); connect(kmkernel->imapFolderMgr(), SIGNAL(changed()), this, SLOT(slotUpdateFolderList())); } //----------------------------------------------------------------------------- KMAcctImap::~KMAcctImap() { killAllJobs( true ); } //----------------------------------------------------------------------------- QString KMAcctImap::type() const { return "imap"; } //----------------------------------------------------------------------------- void KMAcctImap::pseudoAssign( const KMAccount * a ) { mIdleTimer.stop(); killAllJobs( true ); if (mFolder) { mFolder->setContentState(KMFolderImap::imapNoInformation); mFolder->setSubfolderState(KMFolderImap::imapNoInformation); } ImapAccountBase::pseudoAssign( a ); } //----------------------------------------------------------------------------- void KMAcctImap::setImapFolder(KMFolderImap *aFolder) { mFolder = aFolder; mFolder->setImapPath(mPrefix); } //----------------------------------------------------------------------------- void KMAcctImap::slotSlaveError(KIO::Slave *aSlave, int errorCode, const QString &errorMsg) { if (aSlave != mSlave) return; if (errorCode == KIO::ERR_SLAVE_DIED) slaveDied(); if (errorCode == KIO::ERR_COULD_NOT_LOGIN && !mStorePasswd) mAskAgain = TRUE; if (errorCode == KIO::ERR_DOES_NOT_EXIST) { // folder is gone, so reload the folderlist if (mFolder) mFolder->listDirectory(); return; } // killAllJobs needs to disconnect the slave explicitely if the connection // went down. killAllJobs( errorCode == KIO::ERR_CONNECTION_BROKEN ); // check if we still display an error if ( !mErrorDialogIsActive ) { mErrorDialogIsActive = true; KMessageBox::error(kmkernel->mainWin(), KIO::buildErrorString(errorCode, errorMsg)); mErrorDialogIsActive = false; } else kdDebug(5006) << "suppressing error:" << errorMsg << endl; } //----------------------------------------------------------------------------- void KMAcctImap::slotIdleTimeout() { if (mIdle) { if (mSlave) KIO::Scheduler::disconnectSlave(mSlave); mSlave = 0; mIdleTimer.stop(); } else { if (mSlave) { QByteArray packedArgs; QDataStream stream( packedArgs, IO_WriteOnly); stream << (int) 'N'; KIO::SimpleJob *job = KIO::special(getUrl(), packedArgs, FALSE); KIO::Scheduler::assignJobToSlave(mSlave, job); connect(job, SIGNAL(result(KIO::Job *)), this, SLOT(slotSimpleResult(KIO::Job *))); } else mIdleTimer.stop(); } } //----------------------------------------------------------------------------- void KMAcctImap::slotAbortRequested() { killAllJobs(); } //----------------------------------------------------------------------------- void KMAcctImap::killAllJobs( bool disconnectSlave ) { QMap::Iterator it = mapJobData.begin(); for (it = mapJobData.begin(); it != mapJobData.end(); ++it) if ((*it).parent) { // clear folder state KMFolderImap *fld = static_cast((*it).parent); fld->setCheckingValidity(false); fld->setContentState(KMFolderImap::imapNoInformation); fld->setSubfolderState(KMFolderImap::imapNoInformation); fld->sendFolderComplete(FALSE); fld->removeJobs(); } if (mSlave && mapJobData.begin() != mapJobData.end()) { mSlave->kill(); mSlave = 0; } // remove the jobs mapJobData.clear(); KMAccount::deleteFolderJobs(); // make sure that no new-mail-check is blocked if (mCountRemainChecks > 0) { checkDone(false, 0); mCountRemainChecks = 0; } displayProgress(); if ( disconnectSlave && slave() ) { KIO::Scheduler::disconnectSlave( slave() ); mSlave = 0; } } //----------------------------------------------------------------------------- void KMAcctImap::ignoreJobsForMessage( KMMessage* msg ) { if (!msg) return; QPtrListIterator it( mJobList ); while ( it.current() ) { ImapJob *job = it.current(); ++it; if ( job->msgList().findRef( msg ) != -1 ) { if ( job->mJob ) { job->mJob->disconnect(); removeJob( job->mJob ); } mJobList.remove( job ); delete job; } } } //----------------------------------------------------------------------------- void KMAcctImap::ignoreJobsForFolder( KMFolder* folder ) { QPtrListIterator it( mJobList ); while ( it.current() ) { ImapJob *job = it.current(); ++it; if ( job->msgList().first()->parent() == folder ) { if ( job->mJob ) { job->mJob->disconnect(); removeJob( job->mJob ); } mJobList.remove( job ); delete job; } } } //----------------------------------------------------------------------------- void KMAcctImap::slotSimpleResult(KIO::Job * job) { JobIterator it = findJob( job ); bool quiet = FALSE; if (it != mapJobData.end()) { quiet = (*it).quiet; removeJob(it); } if (job->error()) { if (!quiet) slotSlaveError(mSlave, job->error(), job->errorText() ); else if ( job->error() == KIO::ERR_CONNECTION_BROKEN && slave() ) { // make sure ERR_CONNECTION_BROKEN is properly handled and the slave // disconnected even when quiet() KIO::Scheduler::disconnectSlave( slave() ); mSlave = 0; } if (job->error() == KIO::ERR_SLAVE_DIED) slaveDied(); } displayProgress(); } //----------------------------------------------------------------------------- void KMAcctImap::processNewMail(bool interactive) { if (!mFolder || !mFolder->child() || !makeConnection()) { mCountRemainChecks = 0; checkDone(false, 0); return; } // if necessary then initialize the list of folders which should be checked if( mMailCheckFolders.isEmpty() ) { slotUpdateFolderList(); // if no folders should be checked then the check is finished if( mMailCheckFolders.isEmpty() ) { checkDone(false, 0); } } QValueList >::Iterator it; // first get the current count of unread-messages mCountRemainChecks = 0; mCountLastUnread = 0; for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); it++) { KMFolder *folder = *it; if (folder && !folder->noContent()) { mCountLastUnread += folder->countUnread(); } } // then check for new mails for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); it++) { KMFolder *folder = *it; if (folder && !folder->noContent()) { KMFolderImap *imapFolder = static_cast(folder); if (imapFolder->getContentState() != KMFolderImap::imapInProgress) { // connect the result-signals for new-mail-notification mCountRemainChecks++; if (imapFolder->isSelected()) { connect(imapFolder, SIGNAL(folderComplete(KMFolderImap*, bool)), this, SLOT(postProcessNewMail(KMFolderImap*, bool))); imapFolder->getFolder(); } else { connect(imapFolder, SIGNAL(numUnreadMsgsChanged(KMFolder*)), this, SLOT(postProcessNewMail(KMFolder*))); imapFolder->processNewMail(interactive); } } } } } //----------------------------------------------------------------------------- void KMAcctImap::postProcessNewMail(KMFolderImap* folder, bool) { disconnect(folder, SIGNAL(folderComplete(KMFolderImap*, bool)), this, SLOT(postProcessNewMail(KMFolderImap*, bool))); postProcessNewMail(static_cast(folder)); } //----------------------------------------------------------------------------- void KMAcctImap::slotUpdateFolderList() { if (!mFolder || !mFolder->child() || !makeConnection()) return; QStringList strList; mMailCheckFolders.clear(); kmkernel->imapFolderMgr()->createFolderList(&strList, &mMailCheckFolders, mFolder->child(), QString::null, false); // the new list QValueList > includedFolders; // check for excluded folders QValueList >::Iterator it; for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); it++) { KMFolderImap* folder = static_cast((KMFolder*)(*it)); if (folder->includeInMailCheck()) includedFolders.append(*it); } mMailCheckFolders = includedFolders; } //----------------------------------------------------------------------------- void KMAcctImap::listDirectory(QString path, bool onlySubscribed, bool secondStep, KMFolder* parent) { ImapAccountBase::listDirectory( path, onlySubscribed, secondStep, parent ); } //----------------------------------------------------------------------------- void KMAcctImap::listDirectory() { mFolder->listDirectory(); } //----------------------------------------------------------------------------- void KMAcctImap::setPrefixHook() { if ( mFolder ) mFolder->setImapPath( prefix() ); } //----------------------------------------------------------------------------- void KMAcctImap::readConfig(KConfig& config) { ImapAccountBase::readConfig( config ); if ( checkExclude() ) { disconnect(kmkernel->imapFolderMgr(), SIGNAL(changed()), this, SLOT(slotUpdateFolderList())); } } #include "kmacctimap.moc"