kmail Library API Documentation

kmacctimap.cpp

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     // folder is gone, so reload the folderlist
00103     if (mFolder) mFolder->listDirectory();
00104     return;
00105   }
00106   // killAllJobs needs to disconnect the slave explicitely if the connection
00107   // went down.
00108   killAllJobs( errorCode == KIO::ERR_CONNECTION_BROKEN );
00109   // check if we still display an error
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      // Creating a folder failed, remove it from the tree.
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       // clear folder state
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   // remove the jobs
00181   mapJobData.clear();
00182   KMAccount::deleteFolderJobs();
00183   // make sure that no new-mail-check is blocked
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   // Make sure the folder is not referenced in any kio slave jobs
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       // make sure ERR_CONNECTION_BROKEN is properly handled and the slave 
00266       // disconnected even when quiet()
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   // if necessary then initialize the list of folders which should be checked
00288   if( mMailCheckFolders.isEmpty() )
00289   {
00290     slotUpdateFolderList();
00291     // if no folders should be checked then the check is finished
00292     if( mMailCheckFolders.isEmpty() )
00293     {
00294       checkDone(false, 0);
00295     }
00296   }
00297   QValueList<QGuardedPtr<KMFolder> >::Iterator it;
00298   // first get the current count of unread-messages
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   // then check for new mails
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         // connect the result-signals for new-mail-notification
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             // there was an error so cancel
00333             mCountRemainChecks--;
00334             gotError = true;
00335           }
00336         }
00337       }
00338     }
00339   } // end for
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   // the new list
00363   QValueList<QGuardedPtr<KMFolder> > includedFolders;
00364   // check for excluded folders
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"
KDE Logo
This file is part of the documentation for kmail Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat May 1 11:37:19 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003