From 460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kmail/kmaccount.cpp | 500 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 500 insertions(+) create mode 100644 kmail/kmaccount.cpp (limited to 'kmail/kmaccount.cpp') diff --git a/kmail/kmaccount.cpp b/kmail/kmaccount.cpp new file mode 100644 index 00000000..65222dd4 --- /dev/null +++ b/kmail/kmaccount.cpp @@ -0,0 +1,500 @@ +// KMail Account +#include + +#include "kmaccount.h" + +#include "accountmanager.h" +using KMail::AccountManager; +#include "globalsettings.h" +#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 "kmaccount.moc" + +//----------------------------------------------------------------------------- +KMPrecommand::KMPrecommand(const QString &precommand, QObject *parent) + : QObject(parent), mPrecommand(precommand) +{ + BroadcastStatus::instance()->setStatusMsg( + i18n("Executing precommand %1").arg(precommand )); + + mPrecommandProcess.setUseShell(true); + mPrecommandProcess << precommand; + + connect(&mPrecommandProcess, SIGNAL(processExited(KProcess *)), + SLOT(precommandExited(KProcess *))); +} + +//----------------------------------------------------------------------------- +KMPrecommand::~KMPrecommand() +{ +} + + +//----------------------------------------------------------------------------- +bool KMPrecommand::start() +{ + bool ok = mPrecommandProcess.start( KProcess::NotifyOnExit ); + if (!ok) KMessageBox::error(0, i18n("Could not execute precommand '%1'.") + .arg(mPrecommand)); + return ok; +} + + +//----------------------------------------------------------------------------- +void KMPrecommand::precommandExited(KProcess *p) +{ + int exitCode = p->normalExit() ? p->exitStatus() : -1; + if (exitCode) + KMessageBox::error(0, i18n("The precommand exited with code %1:\n%2") + .arg(exitCode).arg(strerror(exitCode))); + emit finished(!exitCode); +} + + +//----------------------------------------------------------------------------- +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), + mHasInbox(false), + mMailCheckProgressItem(0), + mIdentityId(0) +{ + assert(aOwner != 0); +} + +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) { + //kdDebug(5006) << "KMAccount::setFolder() : aFolder == 0" << endl; + mFolder = 0; + return; + } + mFolder = (KMAcctFolder*)aFolder; + if (addAccount) mFolder->addAccount(this); +} + + +//----------------------------------------------------------------------------- +void KMAccount::readConfig(KConfig& config) +{ + QString folderName; + mFolder = 0; + folderName = config.readEntry("Folder"); + setCheckInterval(config.readNumEntry("check-interval", 0)); + setTrash(config.readEntry("trash", kmkernel->trashFolder()->idString())); + setCheckExclude(config.readBoolEntry("check-exclude", false)); + setPrecommand(config.readPathEntry("precommand")); + setIdentityId(config.readNumEntry("identity-id", 0)); + if (!folderName.isEmpty()) + { + setFolder(kmkernel->folderMgr()->findIdString(folderName), true); + } + + if (mInterval == 0) + deinstallTimer(); + else + installTimer(); +} + +void KMAccount::readTimerConfig() +{ + // Re-reads and checks check-interval value and deinstalls timer incase check-interval + // for mail check is disabled. + // Or else, the mail sync goes into a infinite loop (kolab/issue2607) + if (mInterval == 0) + deinstallTimer(); + else + installTimer(); +} + +//----------------------------------------------------------------------------- +void KMAccount::writeConfig(KConfig& config) +{ + // ID, Name + KAccount::writeConfig(config); + + config.writeEntry("Type", type()); + config.writeEntry("Folder", mFolder ? mFolder->idString() : QString::null); + config.writeEntry("check-interval", mInterval); + config.writeEntry("check-exclude", mExclude); + config.writePathEntry("precommand", mPrecommand); + config.writeEntry("trash", mTrash); + if ( mIdentityId && mIdentityId != kmkernel->identityManager()->defaultIdentity().uoid() ) + config.writeEntry("identity-id", mIdentityId); + else + config.deleteEntry("identity-id"); +} + + +//----------------------------------------------------------------------------- +void KMAccount::sendReceipt(KMMessage* aMsg) +{ + KConfig* cfg = KMKernel::config(); + bool sendReceipts; + + KConfigGroupSaver saver(cfg, "General"); + + sendReceipts = cfg->readBoolEntry("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() == "cachedimap" ) + 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() != "cachedimap" && type() != "imap" ) { + if ( aMsg->isOld() ) + aMsg->setStatus(KMMsgStatusUnread); // -sanders + // aMsg->setStatus(KMMsgStatusRead); + else + aMsg->setStatus(KMMsgStatusNew); + } +/* +QFile fileD0( "testdat_xx-kmaccount-0" ); +if( fileD0.open( IO_WriteOnly ) ) { + QDataStream ds( &fileD0 ); + ds.writeRawBytes( 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() == "cachedimap" ) + ; // 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( IO_WriteOnly ) ) { + QDataStream ds( &fileD0 ); + ds.writeRawBytes( 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() == "cachedimap" ) ? 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() +{ + mJobList.setAutoDelete(true); + mJobList.clear(); + mJobList.setAutoDelete(false); +} + +//---------------------------------------------------------------------------- +void KMAccount::ignoreJobsForMessage( KMMessage* msg ) +{ + //FIXME: remove, make folders handle those + for( QPtrListIterator it(mJobList); it.current(); ++it ) { + if ( it.current()->msgList().first() == msg) { + FolderJob *job = it.current(); + mJobList.remove( job ); + delete job; + break; + } + } +} + +//----------------------------------------------------------------------------- +void KMAccount::setCheckExclude(bool aExclude) +{ + mExclude = aExclude; +} + + +//----------------------------------------------------------------------------- +void KMAccount::installTimer() +{ + if (mInterval <= 0) return; + if(!mTimer) + { + mTimer = new QTimer(0, "mTimer"); + 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").arg(precommand )); + + connect(&precommandProcess, SIGNAL(finished(bool)), + SLOT(precommandExited(bool))); + + kdDebug(5006) << "Running precommand " << precommand << endl; + if (!precommandProcess.start()) return false; + + kapp->eventLoop()->enterLoop(); + + return mPrecommandSuccess; +} + +//----------------------------------------------------------------------------- +void KMAccount::precommandExited(bool success) +{ + mPrecommandSuccess = success; + kapp->eventLoop()->exitLoop(); +} + +//----------------------------------------------------------------------------- +void KMAccount::mailCheck() +{ + if (mTimer) + mTimer->stop(); + + if ( kmkernel ) { + AccountManager *acctmgr = kmkernel->acctMgr(); + if ( acctmgr ) + acctmgr->singleCheckMail(this, false); + } +} + +//----------------------------------------------------------------------------- +void KMAccount::sendReceipts() +{ + QValueList::Iterator it; + for(it = mReceipts.begin(); it != mReceipts.end(); ++it) + kmkernel->msgSender()->send(*it); //might process events + mReceipts.clear(); +} + +//----------------------------------------------------------------------------- +QString KMAccount::encryptStr(const QString &aStr) +{ + QString result; + for (uint i = 0; i < aStr.length(); i++) + /* yes, no typo. can't encode ' ' or '!' because + they're the unicode BOM. stupid scrambling. stupid. */ + result += (aStr[i].unicode() <= 0x21 ) ? aStr[i] : + QChar(0x1001F - aStr[i].unicode()); + return result; +} + +//----------------------------------------------------------------------------- +QString KMAccount::importPassword(const QString &aStr) +{ + unsigned int i, val; + unsigned int len = aStr.length(); + QCString result; + result.resize(len+1); + + 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() ); +} + +//----------------------------------------------------------------------------- +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 ) { + // set mMailCheckProgressItem = 0 before calling setComplete() to prevent + // a race condition + ProgressItem *savedMailCheckProgressItem = mMailCheckProgressItem; + mMailCheckProgressItem = 0; + savedMailCheckProgressItem->setComplete(); // that will delete it + } + + emit newMailsProcessed( mNewInFolder ); + emit finishedCheck( newmail, status ); + mNewInFolder.clear(); +} + +//----------------------------------------------------------------------------- +void KMAccount::addToNewInFolder( QString folderId, int num ) +{ + if ( mNewInFolder.find( folderId ) == mNewInFolder.end() ) + mNewInFolder[folderId] = num; + else + mNewInFolder[folderId] += num; +} -- cgit v1.2.3