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.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Oct 1 15:19:17 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003