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::self()->maxConnectionsPerHost()
00182                   << endl;
00183     bool connectionLimitForHostReached =
00184       !accountHostName.isNull() &&
00185       GlobalSettings::self()->maxConnectionsPerHost() > 0 &&
00186       mServerConnections.find( accountHostName ) != mServerConnections.end() &&
00187       mServerConnections[accountHostName] >= GlobalSettings::self()->maxConnectionsPerHost();
00188     kdDebug(5006) << "connection limit reached: "
00189                   << connectionLimitForHostReached << endl;
00190     if ( !(*it)->checkingMail() && !connectionLimitForHostReached && !kmkernel->isOffline() ) {
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     account->installTimer();
00277   }
00278 }
00279 
00280 
00281 //-----------------------------------------------------------------------------
00282 KMAccount* KMAcctMgr::findByName(const QString &aName)
00283 {
00284   if (aName.isEmpty()) return 0;
00285 
00286   for ( QPtrListIterator<KMAccount> it(mAcctList) ; it.current() ; ++it )
00287   {
00288     if ((*it)->name() == aName) return (*it);
00289   }
00290 
00291   return 0;
00292 }
00293 
00294 
00295 //-----------------------------------------------------------------------------
00296 KMAccount* KMAcctMgr::find(const uint id)
00297 {
00298   if (id == 0) return 0;
00299 
00300   for ( QPtrListIterator<KMAccount> it(mAcctList) ; it.current() ; ++it )
00301   {
00302     if ((*it)->id() == id) return (*it);
00303   }
00304 
00305   return 0;
00306 }
00307 
00308 
00309 //-----------------------------------------------------------------------------
00310 KMAccount* KMAcctMgr::first(void)
00311 {
00312   return mAcctList.first();
00313 }
00314 
00315 
00316 //-----------------------------------------------------------------------------
00317 KMAccount* KMAcctMgr::next(void)
00318 {
00319   return mAcctList.next();
00320 }
00321 
00322 
00323 //-----------------------------------------------------------------------------
00324 bool KMAcctMgr::remove( KMAccount* acct )
00325 {
00326   if( !acct )
00327     return false;
00328   mAcctList.removeRef( acct );
00329   emit accountRemoved( acct );
00330   return true;
00331 }
00332 
00333 //-----------------------------------------------------------------------------
00334 void KMAcctMgr::checkMail(bool _interactive)
00335 {
00336   newMailArrived = false;
00337 
00338   if (mAcctList.isEmpty())
00339   {
00340     KMessageBox::information(0,i18n("You need to add an account in the network "
00341                     "section of the settings in order to "
00342                     "receive mail."));
00343     return;
00344   }
00345   mDisplaySummary = true;
00346 
00347   mTotalNewMailsArrived=0;
00348   mTotalNewInFolder.clear();
00349 
00350   for ( QPtrListIterator<KMAccount> it(mAcctList) ;
00351         it.current() ; ++it )
00352   {
00353     if (!it.current()->checkExclude())
00354       singleCheckMail(it.current(), _interactive);
00355   }
00356 }
00357 
00358 
00359 //-----------------------------------------------------------------------------
00360 void KMAcctMgr::singleInvalidateIMAPFolders(KMAccount *account) {
00361   account->invalidateIMAPFolders();
00362 }
00363 
00364 
00365 void KMAcctMgr::invalidateIMAPFolders()
00366 {
00367   if (mAcctList.isEmpty()) {
00368     KMessageBox::information(0,i18n("You need to add an account in the network "
00369                                    "section of the settings in order to "
00370                                    "receive mail."));
00371     return;
00372   }
00373 
00374   for ( QPtrListIterator<KMAccount> it(mAcctList) ; it.current() ; ++it )
00375     singleInvalidateIMAPFolders(it.current());
00376 }
00377 
00378 
00379 //-----------------------------------------------------------------------------
00380 QStringList  KMAcctMgr::getAccounts(bool noImap) {
00381 
00382   KMAccount *cur;
00383   QStringList strList;
00384   for (cur=mAcctList.first(); cur; cur=mAcctList.next()) {
00385     if (!noImap || cur->type() != "imap") strList.append(cur->name());
00386   }
00387 
00388   return strList;
00389 
00390 }
00391 
00392 //-----------------------------------------------------------------------------
00393 void KMAcctMgr::intCheckMail(int item, bool _interactive)
00394 {
00395   KMAccount* cur;
00396   newMailArrived = false;
00397 
00398   mTotalNewMailsArrived = 0;
00399   mTotalNewInFolder.clear();
00400   int x = 0;
00401   cur = mAcctList.first();
00402   while (cur)
00403   {
00404     x++;
00405     if (x > item) break;
00406     cur=mAcctList.next();
00407   }
00408   mDisplaySummary = false;
00409 
00410   singleCheckMail(cur, _interactive);
00411 }
00412 
00413 
00414 //-----------------------------------------------------------------------------
00415 void KMAcctMgr::addToTotalNewMailCount( const QMap<QString, int> & newInFolder )
00416 {
00417   for ( QMap<QString, int>::const_iterator it = newInFolder.begin();
00418         it != newInFolder.end();
00419         ++it )
00420   {
00421     mTotalNewMailsArrived += it.data();
00422     if ( mTotalNewInFolder.find( it.key() ) == mTotalNewInFolder.end() )
00423       mTotalNewInFolder[it.key()] = it.data();
00424     else
00425       mTotalNewInFolder[it.key()] += it.data();
00426   }
00427 }
00428 
00429 //-----------------------------------------------------------------------------
00430 uint KMAcctMgr::createId()
00431 {
00432   QValueList<uint> usedIds;
00433   for ( QPtrListIterator<KMAccount> it(mAcctList) ; it.current() ; ++it )
00434     usedIds << it.current()->id();
00435 
00436   usedIds << 0; // 0 is default for unknown
00437   int newId;
00438   do
00439   {
00440     newId = kapp->random();
00441   } while ( usedIds.find(newId) != usedIds.end() );
00442 
00443   return newId;
00444 }
00445 
00446 //-----------------------------------------------------------------------------
00447 void KMAcctMgr::cancelMailCheck()
00448 {
00449   for ( QPtrListIterator<KMAccount> it(mAcctList) ;
00450     it.current() ; ++it ) {
00451     it.current()->cancelMailCheck();
00452   }
00453 }
00454 
00455 //-----------------------------------------------------------------------------
00456 QString KMAcctMgr::hostForAccount( const KMAccount *acct ) const
00457 {
00458   const NetworkAccount *net_acct = dynamic_cast<const NetworkAccount*>( acct );
00459   return net_acct ? net_acct->host() : QString::null;
00460 }
00461 
00462 #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 Thu Aug 23 18:21:12 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003