// KMail Account #include "kmaccount.h" #include "accountmanager.h" using KMail::AccountManager; #include "kmacctfolder.h" #include "kmfoldermgr.h" #include "kmfiltermgr.h" #include "messagesender.h" #include "kmmessage.h" #include "broadcaststatus.h" using KPIM::BroadcastStatus; #include "kmfoldercachedimap.h" #include "progressmanager.h" using KPIM::ProgressItem; using KPIM::ProgressManager; #include #include using KMail::FolderJob; #include #include #include #include #include #include #include #include #include #include #include #include #include //---------------------- #include "kmaccount.moc" //----------------------------------------------------------------------------- KMPrecommand::KMPrecommand(const QString &precommand, QObject *parent) : QObject(parent), mPrecommand(precommand) { BroadcastStatus::instance()->setStatusMsg( i18n("Executing precommand %1", precommand )); mPrecommandProcess.setShellCommand(precommand); connect(&mPrecommandProcess, SIGNAL(processFinished(int, QProcess::ExitStatus)), SLOT(precommandExited(int, QProcess::ExitStatus))); } //----------------------------------------------------------------------------- KMPrecommand::~KMPrecommand() { } //----------------------------------------------------------------------------- bool KMPrecommand::start() { mPrecommandProcess.start(); const bool ok = mPrecommandProcess.waitForStarted(); if (!ok) KMessageBox::error(0, i18n("Could not execute precommand '%1'.", mPrecommand)); return ok; } //----------------------------------------------------------------------------- void KMPrecommand::precommandExited(int exitCode, QProcess::ExitStatus) { if (exitCode != 0) KMessageBox::error(0, i18n("The precommand exited with code %1:\n%2", exitCode, strerror(exitCode))); emit finished(exitCode == 0); } //----------------------------------------------------------------------------- KMAccount::KMAccount(AccountManager* aOwner, const QString& aName, uint id) : KAccount( id, aName ), mTrash(KMKernel::self()->trashFolder()->idString()), mOwner(aOwner), mFolder(0), mTimer(0), mInterval(0), mExclude(false), mCheckingMail(false), mPrecommandSuccess(true), mUseDefaultIdentity(true), mHasInbox(false), mMailCheckProgressItem(0) { assert(aOwner != 0); mIdentityId = kmkernel->identityManager()->defaultIdentity().uoid(); connect( kmkernel->identityManager(), SIGNAL( changed() ), this, SLOT( slotIdentitiesChanged() ) ); } void KMAccount::init() { mTrash = kmkernel->trashFolder()->idString(); mExclude = false; mInterval = 0; mNewInFolder.clear(); } //----------------------------------------------------------------------------- KMAccount::~KMAccount() { if ( (kmkernel && !kmkernel->shuttingDown()) && mFolder ) mFolder->removeAccount(this); if (mTimer) deinstallTimer(); } //----------------------------------------------------------------------------- void KMAccount::setName(const QString& aName) { mName = aName; } //----------------------------------------------------------------------------- void KMAccount::clearPasswd() { } //----------------------------------------------------------------------------- void KMAccount::setFolder(KMFolder* aFolder, bool addAccount) { if(!aFolder) { //kDebug(5006) <<"KMAccount::setFolder() : aFolder == 0"; mFolder = 0; return; } mFolder = (KMAcctFolder*)aFolder; if (addAccount) mFolder->addAccount(this); } //----------------------------------------------------------------------------- void KMAccount::readConfig(KConfigGroup& config) { QString folderName; mFolder = 0; folderName = config.readEntry("Folder"); setCheckInterval(config.readEntry("check-interval", 0 ) ); setTrash(config.readEntry("trash", kmkernel->trashFolder()->idString())); setCheckExclude(config.readEntry("check-exclude", false ) ); setPrecommand(config.readPathEntry("precommand", QString())); uint defaultIdentity = kmkernel->identityManager()->defaultIdentity().uoid(); setIdentityId( config.readEntry( "identity-id", defaultIdentity ) ); mUseDefaultIdentity = config.readEntry( "use-default-identity", true ); slotIdentitiesChanged(); if ( !folderName.isEmpty() ) { setFolder (kmkernel->folderMgr()->findIdString( folderName ), true ); } if (mInterval == 0) deinstallTimer(); else installTimer(); } //----------------------------------------------------------------------------- void KMAccount::writeConfig(KConfigGroup& config) { // ID, Name KAccount::writeConfig(config); config.writeEntry("Type", KAccount::nameForType( type() ) ); config.writeEntry("Folder", mFolder ? mFolder->idString() : QString()); config.writeEntry("check-interval", mInterval); config.writeEntry("check-exclude", mExclude); config.writePathEntry("precommand", mPrecommand); config.writeEntry("trash", mTrash); config.writeEntry( "use-default-identity", mUseDefaultIdentity ); config.writeEntry( "identity-id", mIdentityId ); } //----------------------------------------------------------------------------- void KMAccount::sendReceipt(KMMessage* aMsg) { bool sendReceipts; KConfigGroup cfg( KMKernel::config(), "General" ); sendReceipts = cfg.readEntry("send-receipts", false ); if (!sendReceipts) return; KMMessage *newMsg = aMsg->createDeliveryReceipt(); if (newMsg) { mReceipts.append(newMsg); QTimer::singleShot( 0, this, SLOT( sendReceipts() ) ); } } //----------------------------------------------------------------------------- bool KMAccount::processNewMsg(KMMessage* aMsg) { int rc, processResult; assert(aMsg != 0); // Save this one for readding KMFolderCachedImap* parent = 0; if( type() == KAccount::DImap ) parent = static_cast( aMsg->storage() ); // checks whether we should send delivery receipts // and sends them. sendReceipt(aMsg); // Set status of new messages that are marked as old to read, otherwise // the user won't see which messages newly arrived. // This is only valid for pop accounts and produces wrong stati for imap. if ( type() != KAccount::DImap && type() != KAccount::Imap ) { if ( aMsg->status().isOld() ) aMsg->setStatus( MessageStatus::statusUnread() ); // -sanders // aMsg->setStatus( MessageStatus::statusRead() ); else aMsg->setStatus( MessageStatus::statusNew() ); } /* QFile fileD0( "testdat_xx-kmaccount-0" ); if( fileD0.open( QIODevice::WriteOnly ) ) { QDataStream ds( &fileD0 ); ds.writeRawData( aMsg->asString(), aMsg->asString().length() ); fileD0.close(); // If data is 0 we just create a zero length file. } */ // 0==message moved; 1==processing ok, no move; 2==critical error, abort! processResult = kmkernel->filterMgr()->process(aMsg,KMFilterMgr::Inbound,true,id()); if (processResult == 2) { perror("Critical error: Unable to collect mail (out of space?)"); KMessageBox::information(0,(i18n("Critical error: " "Unable to collect mail: ")) + QString::fromLocal8Bit(strerror(errno))); return false; } else if (processResult == 1) { if( type() == KAccount::DImap ) ; // already done by caller: parent->addMsgInternal( aMsg, false ); else { // TODO: Perhaps it would be best, if this if was handled by a virtual // method, so the if( !dimap ) above could die? kmkernel->filterMgr()->tempOpenFolder(mFolder); rc = mFolder->addMsg(aMsg); /* QFile fileD0( "testdat_xx-kmaccount-1" ); if( fileD0.open( QIODevice::WriteOnly ) ) { QDataStream ds( &fileD0 ); ds.writeRawData( aMsg->asString(), aMsg->asString().length() ); fileD0.close(); // If data is 0 we just create a zero length file. } */ if (rc) { perror("failed to add message"); KMessageBox::information(0, i18n("Failed to add message:\n") + QString(strerror(rc))); return false; } int count = mFolder->count(); // If count == 1, the message is immediately displayed if (count != 1) mFolder->unGetMsg(count - 1); } } // Count number of new messages for each folder QString folderId; if ( processResult == 1 ) { folderId = ( type() == KAccount::DImap ) ? parent->folder()->idString() : mFolder->idString(); } else { folderId = aMsg->parent()->idString(); } addToNewInFolder( folderId, 1 ); return true; //Everything's fine - message has been added by filter } } //----------------------------------------------------------------------------- void KMAccount::setCheckInterval(int aInterval) { if (aInterval <= 0) mInterval = 0; else mInterval = aInterval; // Don't call installTimer from here! See #117935. } int KMAccount::checkInterval() const { if ( mInterval <= 0 ) return mInterval; return qMax( mInterval, GlobalSettings::self()->minimumCheckInterval() ); } //---------------------------------------------------------------------------- void KMAccount::deleteFolderJobs() { qDeleteAll( mJobList ); mJobList.clear(); } //---------------------------------------------------------------------------- void KMAccount::ignoreJobsForMessage( KMMessage* msg ) { //FIXME: remove, make folders handle those QList::iterator it; for( it = mJobList.begin(); it != mJobList.end(); ++it ) { if ( (*it)->msgList().first() == msg) { FolderJob *job = (*it); it = mJobList.erase( it ); delete job; break; } } } //----------------------------------------------------------------------------- void KMAccount::setCheckExclude(bool aExclude) { mExclude = aExclude; } //----------------------------------------------------------------------------- void KMAccount::installTimer() { if (mInterval <= 0) return; if(!mTimer) { mTimer = new QTimer(); connect(mTimer,SIGNAL(timeout()),SLOT(mailCheck())); } else { mTimer->stop(); } mTimer->start( checkInterval() * 60000 ); } //----------------------------------------------------------------------------- void KMAccount::deinstallTimer() { delete mTimer; mTimer = 0; } //----------------------------------------------------------------------------- bool KMAccount::runPrecommand(const QString &precommand) { // Run the pre command if there is one if ( precommand.isEmpty() ) return true; KMPrecommand precommandProcess(precommand, this); BroadcastStatus::instance()->setStatusMsg( i18n("Executing precommand %1", precommand )); connect(&precommandProcess, SIGNAL(finished(bool)), SLOT(precommandExited(bool))); kDebug(5006) <<"Running precommand" << precommand; if (!precommandProcess.start()) return false; QEventLoop ().exec(); return mPrecommandSuccess; } //----------------------------------------------------------------------------- void KMAccount::precommandExited(bool success) { mPrecommandSuccess = success; QEventLoop ().exit (); } void KMAccount::slotIdentitiesChanged() { // Fall back to the default identity if the one used currently is invalid if ( kmkernel->identityManager()->identityForUoid( mIdentityId ).isNull() ) { mIdentityId = kmkernel->identityManager()->defaultIdentity().uoid(); } } //----------------------------------------------------------------------------- void KMAccount::mailCheck() { if (mTimer) mTimer->stop(); if ( kmkernel ) { AccountManager *acctmgr = kmkernel->acctMgr(); if ( acctmgr ) { acctmgr->singleCheckMail( this, false ); } } } //----------------------------------------------------------------------------- void KMAccount::sendReceipts() { QList::Iterator it; for(it = mReceipts.begin(); it != mReceipts.end(); ++it) kmkernel->msgSender()->send(*it); //might process events mReceipts.clear(); } //----------------------------------------------------------------------------- QString KMAccount::importPassword(const QString &aStr) { unsigned int i, val; unsigned int len = aStr.length(); QByteArray result; result.resize(len); for (i=0; iname() ); setId( a->id() ); setCheckInterval( a->checkInterval() ); setCheckExclude( a->checkExclude() ); setFolder( a->folder() ); setPrecommand( a->precommand() ); setTrash( a->trash() ); setIdentityId( a->identityId() ); setUseDefaultIdentity( a->useDefaultIdentity() ); } //----------------------------------------------------------------------------- void KMAccount::checkDone( bool newmail, CheckStatus status ) { setCheckingMail( false ); // Reset the timeout for automatic mailchecking. The user might have // triggered the check manually. if (mTimer) mTimer->start( checkInterval() * 60000 ); if ( mMailCheckProgressItem ) { mMailCheckProgressItem->setComplete(); // that will delete it mMailCheckProgressItem = 0; } emit newMailsProcessed( mNewInFolder ); emit finishedCheck( newmail, status ); mNewInFolder.clear(); } uint KMAccount::identityId() const { if ( mUseDefaultIdentity ) return kmkernel->identityManager()->defaultIdentity().uoid(); else return mIdentityId; } //----------------------------------------------------------------------------- void KMAccount::addToNewInFolder( const QString &folderId, int num ) { if ( mNewInFolder.find( folderId ) == mNewInFolder.end() ) mNewInFolder[folderId] = num; else mNewInFolder[folderId] += num; }