summaryrefslogtreecommitdiffstats
path: root/kmail/accountmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmail/accountmanager.cpp')
-rw-r--r--kmail/accountmanager.cpp415
1 files changed, 415 insertions, 0 deletions
diff --git a/kmail/accountmanager.cpp b/kmail/accountmanager.cpp
new file mode 100644
index 000000000..c27432ae4
--- /dev/null
+++ b/kmail/accountmanager.cpp
@@ -0,0 +1,415 @@
+// KMail Account Manager
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "accountmanager.h"
+
+#include "kmaccount.h"
+#include "kmacctfolder.h"
+#include "kmacctmaildir.h"
+#include "kmacctlocal.h"
+#include "popaccount.h"
+#include "kmacctimap.h"
+#include "networkaccount.h"
+#include "kmacctcachedimap.h"
+#include "broadcaststatus.h"
+#include "kmfiltermgr.h"
+#include "globalsettings.h"
+
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <kconfig.h>
+#include <kapplication.h>
+
+#include <qregexp.h>
+#include <qvaluelist.h>
+
+using namespace KMail;
+
+//-----------------------------------------------------------------------------
+AccountManager::AccountManager()
+ :QObject(), mNewMailArrived( false ), mInteractive( false ),
+ mTotalNewMailsArrived( 0 ), mDisplaySummary( false )
+{
+ mAcctChecking.clear();
+ mAcctTodo.clear();
+}
+
+//-----------------------------------------------------------------------------
+AccountManager::~AccountManager()
+{
+ writeConfig( false );
+}
+
+
+//-----------------------------------------------------------------------------
+void AccountManager::writeConfig( bool withSync )
+{
+ KConfig* config = KMKernel::config();
+ QString groupName;
+
+ KConfigGroupSaver saver(config, "General");
+ config->writeEntry("accounts", mAcctList.count());
+
+ // first delete all account groups in the config file:
+ QStringList accountGroups =
+ config->groupList().grep( QRegExp( "Account \\d+" ) );
+ for ( QStringList::Iterator it = accountGroups.begin() ;
+ it != accountGroups.end() ; ++it )
+ config->deleteGroup( *it );
+
+ // now write new account groups:
+ int i = 1;
+ for ( AccountList::ConstIterator it( mAcctList.begin() ), end( mAcctList.end() ); it != end; ++it, ++i ) {
+ groupName.sprintf("Account %d", i);
+ KConfigGroupSaver saver(config, groupName);
+ (*it)->writeConfig(*config);
+ }
+ if (withSync) config->sync();
+}
+
+
+//-----------------------------------------------------------------------------
+void AccountManager::readConfig(void)
+{
+ KConfig* config = KMKernel::config();
+ KMAccount* acct;
+ QString acctType, acctName;
+ QCString groupName;
+ int i, num;
+ uint id;
+
+ for ( AccountList::Iterator it( mAcctList.begin() ), end( mAcctList.end() ); it != end; ++it )
+ delete *it;
+ mAcctList.clear();
+
+ KConfigGroup general(config, "General");
+ num = general.readNumEntry("accounts", 0);
+
+ for (i=1; i<=num; i++)
+ {
+ groupName.sprintf("Account %d", i);
+ KConfigGroupSaver saver(config, groupName);
+ acctType = config->readEntry("Type");
+ // Provide backwards compatibility
+ if (acctType == "advanced pop" || acctType == "experimental pop")
+ acctType = "pop";
+ acctName = config->readEntry("Name");
+ id = config->readUnsignedNumEntry("Id", 0);
+ if (acctName.isEmpty()) acctName = i18n("Account %1").arg(i);
+ acct = create(acctType, acctName, id);
+ if (!acct) continue;
+ add(acct);
+ acct->readConfig(*config);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+void AccountManager::singleCheckMail(KMAccount *account, bool interactive)
+{
+ mNewMailArrived = false;
+ mInteractive = interactive;
+
+ // if sync has been requested by the user then check if check-interval was disabled by user, if yes, then
+ // de-install the timer
+ // Safe guard against an infinite sync loop (kolab/issue2607)
+ if ( mInteractive )
+ account->readTimerConfig();
+
+ // queue the account
+ mAcctTodo.append(account);
+
+ if (account->checkingMail())
+ {
+ kdDebug(5006) << "account " << account->name() << " busy, queuing" << endl;
+ return;
+ }
+
+ processNextCheck(false);
+}
+
+//-----------------------------------------------------------------------------
+void AccountManager::processNextCheck( bool _newMail )
+{
+ kdDebug(5006) << "processNextCheck, remaining " << mAcctTodo.count() << endl;
+ if ( _newMail )
+ mNewMailArrived = true;
+
+ for ( AccountList::Iterator it( mAcctChecking.begin() ), end( mAcctChecking.end() ); it != end; ) {
+ KMAccount* acct = *it;
+ ++it;
+ if ( acct->checkingMail() )
+ continue;
+ // check done
+ kdDebug(5006) << "account " << acct->name() << " finished check" << endl;
+ mAcctChecking.remove( acct );
+ kmkernel->filterMgr()->deref();
+ disconnect( acct, SIGNAL( finishedCheck( bool, CheckStatus ) ),
+ this, SLOT( processNextCheck( bool ) ) );
+ }
+ if ( mAcctChecking.isEmpty() ) {
+ // all checks finished, display summary
+ if ( mDisplaySummary )
+ KPIM::BroadcastStatus::instance()->setStatusMsgTransmissionCompleted(
+ mTotalNewMailsArrived );
+ emit checkedMail( mNewMailArrived, mInteractive, mTotalNewInFolder );
+ mTotalNewMailsArrived = 0;
+ mTotalNewInFolder.clear();
+ mDisplaySummary = false;
+ }
+ if ( mAcctTodo.isEmpty() ) return;
+
+ QString accountHostName;
+
+ KMAccount *curAccount = 0;
+ for ( AccountList::Iterator it ( mAcctTodo.begin() ), last ( mAcctTodo.end() ); it != last; ) {
+ KMAccount *acct = *it;
+ ++it;
+ if ( !acct->checkingMail() && acct->mailCheckCanProceed() ) {
+ curAccount = acct;
+ mAcctTodo.remove( acct );
+ break;
+ }
+ }
+ if ( !curAccount ) return; // no account or all of them are already checking
+
+ if ( curAccount->type() != "imap" && curAccount->type() != "cachedimap" &&
+ curAccount->folder() == 0 ) {
+ QString tmp = i18n("Account %1 has no mailbox defined:\n"
+ "mail checking aborted;\n"
+ "check your account settings.")
+ .arg(curAccount->name());
+ KMessageBox::information(0,tmp);
+ emit checkedMail( false, mInteractive, mTotalNewInFolder );
+ mTotalNewMailsArrived = 0;
+ mTotalNewInFolder.clear();
+ return;
+ }
+
+ connect( curAccount, SIGNAL( finishedCheck( bool, CheckStatus ) ),
+ this, SLOT( processNextCheck( bool ) ) );
+
+ KPIM::BroadcastStatus::instance()->setStatusMsg(
+ i18n("Checking account %1 for new mail").arg(curAccount->name()));
+
+ kdDebug(5006) << "processing next mail check for " << curAccount->name() << endl;
+
+ curAccount->setCheckingMail( true );
+ mAcctChecking.append( curAccount );
+ kmkernel->filterMgr()->ref();
+ curAccount->processNewMail( mInteractive );
+}
+
+//-----------------------------------------------------------------------------
+KMAccount* AccountManager::create( const QString &aType, const QString &aName, uint id )
+{
+ KMAccount* act = 0;
+ if ( id == 0 )
+ id = createId();
+
+ if ( aType == "local" ) {
+ act = new KMAcctLocal(this, aName.isEmpty() ? i18n("Local Account") : aName, id);
+ act->setFolder( kmkernel->inboxFolder() );
+ } else if ( aType == "maildir" ) {
+ act = new KMAcctMaildir(this, aName.isEmpty() ? i18n("Local Account") : aName, id);
+ act->setFolder( kmkernel->inboxFolder() );
+ } else if ( aType == "pop" ) {
+ act = new KMail::PopAccount(this, aName.isEmpty() ? i18n("POP Account") : aName, id);
+ act->setFolder( kmkernel->inboxFolder() );
+ } else if ( aType == "imap" ) {
+ act = new KMAcctImap(this, aName.isEmpty() ? i18n("IMAP Account") : aName, id);
+ } else if (aType == "cachedimap") {
+ act = new KMAcctCachedImap(this, aName.isEmpty() ? i18n("IMAP Account") : aName, id);
+ }
+ if ( !act ) {
+ kdWarning(5006) << "Attempt to instantiate a non-existing account type!" << endl;
+ return 0;
+ }
+ connect( act, SIGNAL( newMailsProcessed( const QMap<QString, int> & ) ),
+ this, SLOT( addToTotalNewMailCount( const QMap<QString, int> & ) ) );
+ return act;
+}
+
+
+//-----------------------------------------------------------------------------
+void AccountManager::add( KMAccount *account )
+{
+ if ( account ) {
+ mAcctList.append( account );
+ // init folder's account list
+ KMAcctFolder *folder = static_cast<KMAcctFolder*>( account->folder() );
+ if ( folder && !folder->hasAccounts() ) {
+ folder->addAccount( account );
+ }
+ emit accountAdded( account );
+ account->installTimer();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+KMAccount* AccountManager::findByName(const QString &aName) const
+{
+ if ( aName.isEmpty() ) return 0;
+
+ for ( AccountList::ConstIterator it( mAcctList.begin() ), end( mAcctList.end() ); it != end; ++it ) {
+ if ( (*it)->name() == aName ) return (*it);
+ }
+ return 0;
+}
+
+
+//-----------------------------------------------------------------------------
+KMAccount* AccountManager::find( const uint id ) const
+{
+ if (id == 0) return 0;
+ for ( AccountList::ConstIterator it( mAcctList.begin() ), end( mAcctList.end() ); it != end; ++it ) {
+ if ( (*it)->id() == id ) return (*it);
+ }
+ return 0;
+}
+
+
+//-----------------------------------------------------------------------------
+KMAccount* AccountManager::first()
+{
+ if ( !mAcctList.empty() ) {
+ mPtrListInterfaceProxyIterator = mAcctList.begin();
+ return *mPtrListInterfaceProxyIterator;
+ } else {
+ return 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+KMAccount* AccountManager::next()
+{
+ ++mPtrListInterfaceProxyIterator;
+ if ( mPtrListInterfaceProxyIterator == mAcctList.end() )
+ return 0;
+ else
+ return *mPtrListInterfaceProxyIterator;
+}
+
+//-----------------------------------------------------------------------------
+bool AccountManager::remove( KMAccount* acct )
+{
+ if( !acct )
+ return false;
+ mAcctList.remove( acct );
+ emit accountRemoved( acct );
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+void AccountManager::checkMail( bool _interactive )
+{
+ mNewMailArrived = false;
+
+ if ( mAcctList.isEmpty() ) {
+ KMessageBox::information( 0,i18n("You need to add an account in the network "
+ "section of the settings in order to receive mail.") );
+ return;
+ }
+ mDisplaySummary = true;
+
+ mTotalNewMailsArrived=0;
+ mTotalNewInFolder.clear();
+
+ for ( AccountList::Iterator it( mAcctList.begin() ), end( mAcctList.end() ); it != end; ++it ) {
+ if ( !(*it)->checkExclude() )
+ singleCheckMail( (*it), _interactive);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+void AccountManager::singleInvalidateIMAPFolders(KMAccount *account) {
+ account->invalidateIMAPFolders();
+}
+
+
+void AccountManager::invalidateIMAPFolders()
+{
+ for ( AccountList::ConstIterator it( mAcctList.begin() ), end( mAcctList.end() ); it != end; ++it )
+ singleInvalidateIMAPFolders( *it );
+}
+
+
+//-----------------------------------------------------------------------------
+QStringList AccountManager::getAccounts() const
+{
+ QStringList strList;
+ for ( AccountList::ConstIterator it( mAcctList.begin() ), end( mAcctList.end() ); it != end; ++it ) {
+ strList.append( (*it)->name() );
+ }
+ return strList;
+}
+
+//-----------------------------------------------------------------------------
+void AccountManager::intCheckMail(int item, bool _interactive)
+{
+ mNewMailArrived = false;
+ mTotalNewMailsArrived = 0;
+ mTotalNewInFolder.clear();
+ if ( KMAccount *acct = mAcctList[ item ] )
+ singleCheckMail( acct, _interactive );
+ mDisplaySummary = false;
+}
+
+
+//-----------------------------------------------------------------------------
+void AccountManager::addToTotalNewMailCount( const QMap<QString, int> & newInFolder )
+{
+ for ( QMap<QString, int>::const_iterator it = newInFolder.begin();
+ it != newInFolder.end(); ++it ) {
+ mTotalNewMailsArrived += it.data();
+ if ( mTotalNewInFolder.find( it.key() ) == mTotalNewInFolder.end() )
+ mTotalNewInFolder[it.key()] = it.data();
+ else
+ mTotalNewInFolder[it.key()] += it.data();
+ }
+}
+
+//-----------------------------------------------------------------------------
+uint AccountManager::createId()
+{
+ QValueList<uint> usedIds;
+ for ( AccountList::ConstIterator it( mAcctList.begin() ), end( mAcctList.end() ); it != end; ++it ) {
+ usedIds << (*it)->id();
+ }
+
+ usedIds << 0; // 0 is default for unknown
+ int newId;
+ do
+ {
+ newId = kapp->random();
+ } while ( usedIds.find(newId) != usedIds.end() );
+
+ return newId;
+}
+
+//-----------------------------------------------------------------------------
+void AccountManager::cancelMailCheck()
+{
+ for ( AccountList::ConstIterator it( mAcctList.begin() ), end( mAcctList.end() ); it != end; ++it ) {
+ (*it)->cancelMailCheck();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+void AccountManager::readPasswords()
+{
+ for ( AccountList::ConstIterator it( mAcctList.begin() ), end( mAcctList.end() ); it != end; ++it ) {
+ NetworkAccount *acct = dynamic_cast<NetworkAccount*>( (*it) );
+ if ( acct )
+ acct->readPassword();
+ }
+}
+
+#include "accountmanager.moc"