kmail Library API Documentation

kmacctmgr.cpp

00001 // KMail Account Manager
00002 
00003 #ifdef HAVE_CONFIG_H
00004 #include <config.h>
00005 #endif
00006 
00007 #include "kmacctmgr.h"
00008 
00009 #include "kmacctmaildir.h"
00010 #include "kmacctlocal.h"
00011 #include "kmacctexppop.h"
00012 #include "kmacctimap.h"
00013 #include "networkaccount.h"
00014 using KMail::NetworkAccount;
00015 #include "kmacctcachedimap.h"
00016 #include "broadcaststatus.h"
00017 #include "kmfiltermgr.h"
00018 #include "globalsettings.h"
00019 
00020 #include <klocale.h>
00021 #include <kmessagebox.h>
00022 #include <kdebug.h>
00023 #include <kconfig.h>
00024 #include <kapplication.h>
00025 
00026 #include <qregexp.h>
00027 #include <qvaluelist.h>
00028 
00029 using KPIM::BroadcastStatus;
00030 
00031 //-----------------------------------------------------------------------------
00032 KMAcctMgr::KMAcctMgr(): QObject()
00033 {
00034   mAcctList.setAutoDelete(TRUE);
00035   mAcctChecking.clear();
00036   mAcctTodo.clear();
00037   mTotalNewMailsArrived=0;
00038   mDisplaySummary = false;
00039 }
00040 
00041 
00042 //-----------------------------------------------------------------------------
00043 KMAcctMgr::~KMAcctMgr()
00044 {
00045   writeConfig(FALSE);
00046 }
00047 
00048 
00049 //-----------------------------------------------------------------------------
00050 void KMAcctMgr::writeConfig(bool withSync)
00051 {
00052   KConfig* config = KMKernel::config();
00053   QString groupName;
00054 
00055   KConfigGroupSaver saver(config, "General");
00056   config->writeEntry("accounts", mAcctList.count());
00057 
00058   // first delete all account groups in the config file:
00059   QStringList accountGroups =
00060     config->groupList().grep( QRegExp( "Account \\d+" ) );
00061   for ( QStringList::Iterator it = accountGroups.begin() ;
00062     it != accountGroups.end() ; ++it )
00063     config->deleteGroup( *it );
00064 
00065   // now write new account groups:
00066   int i = 1;
00067   for ( QPtrListIterator<KMAccount> it(mAcctList) ;
00068     it.current() ; ++it, ++i ) {
00069     groupName.sprintf("Account %d", i);
00070     KConfigGroupSaver saver(config, groupName);
00071     (*it)->writeConfig(*config);
00072   }
00073   if (withSync) config->sync();
00074 }
00075 
00076 
00077 //-----------------------------------------------------------------------------
00078 void KMAcctMgr::readConfig(void)
00079 {
00080   KConfig* config = KMKernel::config();
00081   KMAccount* acct;
00082   QString acctType, acctName;
00083   QCString groupName;
00084   int i, num;
00085   uint id;
00086 
00087   mAcctList.clear();
00088 
00089   KConfigGroup general(config, "General");
00090   num = general.readNumEntry("accounts", 0);
00091 
00092   for (i=1; i<=num; i++)
00093   {
00094     groupName.sprintf("Account %d", i);
00095     KConfigGroupSaver saver(config, groupName);
00096     acctType = config->readEntry("Type");
00097     // Provide backwards compatibility
00098     if (acctType == "advanced pop" || acctType == "experimental pop")
00099       acctType = "pop";
00100     acctName = config->readEntry("Name");
00101     id = config->readUnsignedNumEntry("Id", 0);
00102     if (acctName.isEmpty()) acctName = i18n("Account %1").arg(i);
00103     acct = create(acctType, acctName, id);
00104     if (!acct) continue;
00105     add(acct);
00106     acct->readConfig(*config);
00107   }
00108 }
00109 
00110 
00111 //-----------------------------------------------------------------------------
00112 void KMAcctMgr::singleCheckMail(KMAccount *account, bool _interactive)
00113 {
00114   newMailArrived = false;
00115   interactive = _interactive;
00116 
00117   // queue the account
00118   mAcctTodo.append(account);
00119 
00120   if (account->checkingMail())
00121   {
00122     kdDebug(5006) << "account " << account->name() << " busy, queuing" << endl;
00123     return;
00124   }
00125 
00126   processNextCheck(false);
00127 }
00128 
00129 //-----------------------------------------------------------------------------
00130 void KMAcctMgr::processNextCheck(bool _newMail)
00131 {
00132   kdDebug(5006) << "processNextCheck, remaining " << mAcctTodo.count() << endl;
00133   KMAccount *curAccount = 0;
00134   newMailArrived |= _newMail;
00135 
00136   KMAccount* acct;
00137   for ( acct = mAcctChecking.first(); acct; acct = mAcctChecking.next() )
00138   {
00139     if ( !acct->checkingMail() )
00140     {
00141       // check done
00142       kdDebug(5006) << "account " << acct->name() << " finished check" << endl;
00143       mAcctChecking.removeRef( acct );
00144       kmkernel->filterMgr()->deref();
00145       disconnect( acct, SIGNAL( finishedCheck( bool, CheckStatus ) ),
00146                   this, SLOT( processNextCheck( bool ) ) );
00147       QString hostname = hostForAccount( acct );
00148       if ( !hostname.isEmpty() ) {
00149         if ( mServerConnections.find( hostname ) != mServerConnections.end() ) {
00150           mServerConnections[hostname] -= 1;
00151           kdDebug(5006) << "connections to server " << hostname
00152                         << " now " << mServerConnections[hostname] << endl;
00153         }
00154       }
00155     }
00156   }
00157   if (mAcctChecking.isEmpty())
00158   {
00159     // all checks finished, display summary
00160     if ( mDisplaySummary )
00161       BroadcastStatus::instance()->setStatusMsgTransmissionCompleted(
00162           mTotalNewMailsArrived );
00163     emit checkedMail( newMailArrived, interactive, mTotalNewInFolder );
00164     mTotalNewMailsArrived = 0;
00165     mTotalNewInFolder.clear();
00166     mDisplaySummary = false;
00167   }
00168   if (mAcctTodo.isEmpty()) return;
00169 
00170   QString accountHostName;
00171 
00172   curAccount = 0;
00173   KMAcctList::Iterator it ( mAcctTodo.begin() );
00174   KMAcctList::Iterator last ( mAcctTodo.end() );
00175   for ( ; it != last; it++ )
00176   {
00177     accountHostName = hostForAccount(*it);
00178     kdDebug(5006) << "for host " << accountHostName
00179                   << " current connections="
00180                   << (mServerConnections.find(accountHostName)==mServerConnections.end() ? 0 : mServerConnections[accountHostName])
00181                   << " and limit is " << GlobalSettings::maxConnectionsPerHost()
00182                   << endl;
00183     bool connectionLimitForHostReached =
00184       !accountHostName.isNull() &&
00185       GlobalSettings::maxConnectionsPerHost() > 0 &&
00186       mServerConnections.find( accountHostName ) != mServerConnections.end() &&
00187       mServerConnections[accountHostName] >= GlobalSettings::maxConnectionsPerHost();
00188     kdDebug(5006) << "connection limit reached: "
00189                   << connectionLimitForHostReached << endl;
00190     if ( !(*it)->checkingMail() && !connectionLimitForHostReached ) {
00191       curAccount = (*it);
00192       mAcctTodo.remove( curAccount );
00193       break;
00194     }
00195   }
00196   if ( !curAccount ) return; // no account or all of them are already checking
00197 
00198   if (curAccount->type() != "imap" && curAccount->type() != "cachedimap" &&
00199       curAccount->folder() == 0)
00200   {
00201     QString tmp = i18n("Account %1 has no mailbox defined:\n"
00202         "mail checking aborted;\n"
00203         "check your account settings.")
00204       .arg(curAccount->name());
00205     KMessageBox::information(0,tmp);
00206     emit checkedMail( false, interactive, mTotalNewInFolder );
00207     mTotalNewMailsArrived = 0;
00208     mTotalNewInFolder.clear();
00209     return;
00210   }
00211 
00212   connect( curAccount, SIGNAL( finishedCheck( bool, CheckStatus ) ),
00213        this, SLOT( processNextCheck( bool ) ) );
00214 
00215   BroadcastStatus::instance()->setStatusMsg(
00216       i18n("Checking account %1 for new mail").arg(curAccount->name()));
00217 
00218   kdDebug(5006) << "processing next mail check for " << curAccount->name() << endl;
00219 
00220   curAccount->setCheckingMail(true);
00221   mAcctChecking.append(curAccount);
00222   kmkernel->filterMgr()->ref();
00223   curAccount->processNewMail(interactive);
00224 
00225   if ( !accountHostName.isEmpty() ) {
00226     if ( mServerConnections.find( accountHostName ) != mServerConnections.end() )
00227       mServerConnections[accountHostName] += 1;
00228     else
00229       mServerConnections[accountHostName] = 1;
00230     kdDebug(5006) << "check mail started - connections for host "
00231                   << accountHostName << " now is "
00232                   << mServerConnections[accountHostName] << endl;
00233   }
00234 }
00235 
00236 //-----------------------------------------------------------------------------
00237 KMAccount* KMAcctMgr::create(const QString &aType, const QString &aName, uint id)
00238 {
00239   KMAccount* act = 0;
00240   if (id == 0)
00241     id = createId();
00242 
00243   if (aType == "local")
00244     act = new KMAcctLocal(this, aName, id);
00245 
00246   if (aType == "maildir")
00247     act = new KMAcctMaildir(this, aName, id);
00248 
00249   else if (aType == "pop")
00250     act = new KMAcctExpPop(this, aName, id);
00251 
00252   else if (aType == "imap")
00253     act = new KMAcctImap(this, aName, id);
00254 
00255   else if (aType == "cachedimap")
00256     act = new KMAcctCachedImap(this, aName, id);
00257 
00258   if (act)
00259   {
00260     if (aType != "imap" && aType != "cachedimap")
00261       act->setFolder(kmkernel->inboxFolder());
00262     connect( act, SIGNAL( newMailsProcessed( const QMap<QString, int> & ) ),
00263              this, SLOT( addToTotalNewMailCount( const QMap<QString, int> & ) ) );
00264   }
00265 
00266   return act;
00267 }
00268 
00269 
00270 //-----------------------------------------------------------------------------
00271 void KMAcctMgr::add(KMAccount *account)
00272 {
00273   if (account) {
00274     mAcctList.append( account );
00275     emit accountAdded( account );
00276   }
00277 }
00278 
00279 
00280 //-----------------------------------------------------------------------------
00281 KMAccount* KMAcctMgr::findByName(const QString &aName)
00282 {
00283   if (aName.isEmpty()) return 0;
00284 
00285   for ( QPtrListIterator<KMAccount> it(mAcctList) ; it.current() ; ++it )
00286   {
00287     if ((*it)->name() == aName) return (*it);
00288   }
00289 
00290   return 0;
00291 }
00292 
00293 
00294 //-----------------------------------------------------------------------------
00295 KMAccount* KMAcctMgr::find(const uint id)
00296 {
00297   if (id == 0) return 0;
00298 
00299   for ( QPtrListIterator<KMAccount> it(mAcctList) ; it.current() ; ++it )
00300   {
00301     if ((*it)->id() == id) return (*it);
00302   }
00303 
00304   return 0;
00305 }
00306 
00307 
00308 //-----------------------------------------------------------------------------
00309 KMAccount* KMAcctMgr::first(void)
00310 {
00311   return mAcctList.first();
00312 }
00313 
00314 
00315 //-----------------------------------------------------------------------------
00316 KMAccount* KMAcctMgr::next(void)
00317 {
00318   return mAcctList.next();
00319 }
00320 
00321 
00322 //-----------------------------------------------------------------------------
00323 bool KMAcctMgr::remove( KMAccount* acct )
00324 {
00325   if( !acct )
00326     return false;
00327   mAcctList.removeRef( acct );
00328   emit accountRemoved( acct );
00329   return true;
00330 }
00331 
00332 //-----------------------------------------------------------------------------
00333 void KMAcctMgr::checkMail(bool _interactive)
00334 {
00335   newMailArrived = false;
00336 
00337   if (mAcctList.isEmpty())
00338   {
00339     KMessageBox::information(0,i18n("You need to add an account in the network "
00340                     "section of the settings in order to "
00341                     "receive mail."));
00342     return;
00343   }
00344   mDisplaySummary = true;
00345 
00346   mTotalNewMailsArrived=0;
00347   mTotalNewInFolder.clear();
00348 
00349   for ( QPtrListIterator<KMAccount> it(mAcctList) ;
00350         it.current() ; ++it )
00351   {
00352     if (!it.current()->checkExclude())
00353       singleCheckMail(it.current(), _interactive);
00354   }
00355 }
00356 
00357 
00358 //-----------------------------------------------------------------------------
00359 void KMAcctMgr::singleInvalidateIMAPFolders(KMAccount *account) {
00360   account->invalidateIMAPFolders();
00361 }
00362 
00363 
00364 void KMAcctMgr::invalidateIMAPFolders()
00365 {
00366   if (mAcctList.isEmpty()) {
00367     KMessageBox::information(0,i18n("You need to add an account in the network "
00368                                    "section of the settings in order to "
00369                                    "receive mail."));
00370     return;
00371   }
00372 
00373   for ( QPtrListIterator<KMAccount> it(mAcctList) ; it.current() ; ++it )
00374     singleInvalidateIMAPFolders(it.current());
00375 }
00376 
00377 
00378 //-----------------------------------------------------------------------------
00379 QStringList  KMAcctMgr::getAccounts(bool noImap) {
00380 
00381   KMAccount *cur;
00382   QStringList strList;
00383   for (cur=mAcctList.first(); cur; cur=mAcctList.next()) {
00384     if (!noImap || cur->type() != "imap") strList.append(cur->name());
00385   }
00386 
00387   return strList;
00388 
00389 }
00390 
00391 //-----------------------------------------------------------------------------
00392 void KMAcctMgr::intCheckMail(int item, bool _interactive)
00393 {
00394   KMAccount* cur;
00395   newMailArrived = false;
00396 
00397   mTotalNewMailsArrived = 0;
00398   mTotalNewInFolder.clear();
00399   int x = 0;
00400   cur = mAcctList.first();
00401   while (cur)
00402   {
00403     x++;
00404     if (x > item) break;
00405     cur=mAcctList.next();
00406   }
00407   mDisplaySummary = false;
00408 
00409   singleCheckMail(cur, _interactive);
00410 }
00411 
00412 
00413 //-----------------------------------------------------------------------------
00414 void KMAcctMgr::addToTotalNewMailCount( const QMap<QString, int> & newInFolder )
00415 {
00416   for ( QMap<QString, int>::const_iterator it = newInFolder.begin();
00417         it != newInFolder.end();
00418         ++it )
00419   {
00420     mTotalNewMailsArrived += it.data();
00421     if ( mTotalNewInFolder.find( it.key() ) == mTotalNewInFolder.end() )
00422       mTotalNewInFolder[it.key()] = it.data();
00423     else
00424       mTotalNewInFolder[it.key()] += it.data();
00425   }
00426 }
00427 
00428 //-----------------------------------------------------------------------------
00429 uint KMAcctMgr::createId()
00430 {
00431   QValueList<uint> usedIds;
00432   for ( QPtrListIterator<KMAccount> it(mAcctList) ; it.current() ; ++it )
00433     usedIds << it.current()->id();
00434 
00435   usedIds << 0; // 0 is default for unknown
00436   int newId;
00437   do
00438   {
00439     newId = kapp->random();
00440   } while ( usedIds.find(newId) != usedIds.end() );
00441 
00442   return newId;
00443 }
00444 
00445 //-----------------------------------------------------------------------------
00446 void KMAcctMgr::cancelMailCheck()
00447 {
00448   for ( QPtrListIterator<KMAccount> it(mAcctList) ;
00449     it.current() ; ++it ) {
00450     it.current()->cancelMailCheck();
00451   }
00452 }
00453 
00454 //-----------------------------------------------------------------------------
00455 QString KMAcctMgr::hostForAccount( const KMAccount *acct ) const
00456 {
00457   const NetworkAccount *net_acct = dynamic_cast<const NetworkAccount*>( acct );
00458   return net_acct ? net_acct->host() : QString::null;
00459 }
00460 
00461 #include "kmacctmgr.moc"
KDE Logo
This file is part of the documentation for kmail Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 23 22:43:42 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003