You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
627 lines
20 KiB
627 lines
20 KiB
/** -*- c++ -*- |
|
* imapaccountbase.cpp |
|
* |
|
* Copyright (c) 2000-2002 Michael Haeckel <haeckel@kde.org> |
|
* Copyright (c) 2002 Marc Mutz <mutz@kde.org> |
|
* |
|
* This file is based on work on pop3 and imap account implementations |
|
* by Don Sanders <sanders@kde.org> and Michael Haeckel <haeckel@kde.org> |
|
* |
|
* This program is free software; you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation; version 2 of the License |
|
* |
|
* This program is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with this program; if not, write to the Free Software |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|
*/ |
|
|
|
#include "imapaccountbase.h" |
|
using KMail::SieveConfig; |
|
|
|
#include "kmacctmgr.h" |
|
#include "kmfolder.h" |
|
#include "kmbroadcaststatus.h" |
|
#include "kmmainwin.h" |
|
#include "kmfolderimap.h" |
|
#include "kmmainwidget.h" |
|
#include "kmmainwin.h" |
|
#include "kmmsgpart.h" |
|
#include "bodyvisitor.h" |
|
using KMail::BodyVisitor; |
|
#include "imapjob.h" |
|
using KMail::ImapJob; |
|
|
|
#include <kdebug.h> |
|
#include <kconfig.h> |
|
#include <klocale.h> |
|
#include <kmessagebox.h> |
|
using KIO::MetaData; |
|
#include <kio/passdlg.h> |
|
using KIO::PasswordDialog; |
|
#include <kio/scheduler.h> |
|
#include <mimelib/bodypart.h> |
|
#include <mimelib/body.h> |
|
#include <mimelib/headers.h> |
|
#include <mimelib/message.h> |
|
//using KIO::Scheduler; // use FQN below |
|
|
|
#include <qregexp.h> |
|
|
|
namespace KMail { |
|
|
|
static const unsigned short int imapDefaultPort = 143; |
|
|
|
// |
|
// |
|
// Ctor and Dtor |
|
// |
|
// |
|
|
|
ImapAccountBase::ImapAccountBase( KMAcctMgr * parent, const QString & name ) |
|
: NetworkAccount( parent, name ), |
|
mPrefix( "/" ), |
|
mTotal( 0 ), |
|
mCountUnread( 0 ), |
|
mCountLastUnread( 0 ), |
|
mCountRemainChecks( 0 ), |
|
mAutoExpunge( true ), |
|
mHiddenFolders( false ), |
|
mOnlySubscribedFolders( false ), |
|
mLoadOnDemand( true ), |
|
mProgressEnabled( false ), |
|
mIdle( true ), |
|
mErrorDialogIsActive( false ), |
|
mPasswordDialogIsActive( false ), |
|
mCreateInbox( false ) |
|
{ |
|
mPort = imapDefaultPort; |
|
mBodyPartList.setAutoDelete(true); |
|
KIO::Scheduler::connect(SIGNAL(slaveError(KIO::Slave *, int, const QString &)), |
|
this, SLOT(slotSchedulerSlaveError(KIO::Slave *, int, const QString &))); |
|
KIO::Scheduler::connect(SIGNAL(slaveConnected(KIO::Slave *)), |
|
this, SLOT(slotSchedulerSlaveConnected(KIO::Slave *))); |
|
} |
|
|
|
ImapAccountBase::~ImapAccountBase() { |
|
kdWarning( mSlave, 5006 ) |
|
<< "slave should have been destroyed by subclass!" << endl; |
|
} |
|
|
|
void ImapAccountBase::init() { |
|
mPrefix = '/'; |
|
mAutoExpunge = true; |
|
mHiddenFolders = false; |
|
mOnlySubscribedFolders = false; |
|
mLoadOnDemand = true; |
|
mProgressEnabled = false; |
|
} |
|
|
|
void ImapAccountBase::pseudoAssign( const KMAccount * a ) { |
|
NetworkAccount::pseudoAssign( a ); |
|
|
|
const ImapAccountBase * i = dynamic_cast<const ImapAccountBase*>( a ); |
|
if ( !i ) return; |
|
|
|
setPrefix( i->prefix() ); |
|
setAutoExpunge( i->autoExpunge() ); |
|
setHiddenFolders( i->hiddenFolders() ); |
|
setOnlySubscribedFolders( i->onlySubscribedFolders() ); |
|
setLoadOnDemand( i->loadOnDemand() ); |
|
} |
|
|
|
unsigned short int ImapAccountBase::defaultPort() const { |
|
return imapDefaultPort; |
|
} |
|
|
|
QString ImapAccountBase::protocol() const { |
|
return useSSL() ? "imaps" : "imap"; |
|
} |
|
|
|
// |
|
// |
|
// Getters and Setters |
|
// |
|
// |
|
|
|
void ImapAccountBase::setPrefix( const QString & prefix ) { |
|
mPrefix = prefix; |
|
mPrefix.remove( QRegExp( "[%*\"]" ) ); |
|
if ( mPrefix.isEmpty() || mPrefix[0] != '/' ) |
|
mPrefix.prepend( '/' ); |
|
if ( mPrefix[ mPrefix.length() - 1 ] != '/' ) |
|
mPrefix += '/'; |
|
#if 1 |
|
setPrefixHook(); // ### needed while KMFolderCachedImap exists |
|
#else |
|
if ( mFolder ) mFolder->setImapPath( mPrefix ); |
|
#endif |
|
} |
|
|
|
void ImapAccountBase::setAutoExpunge( bool expunge ) { |
|
mAutoExpunge = expunge; |
|
} |
|
|
|
void ImapAccountBase::setHiddenFolders( bool show ) { |
|
mHiddenFolders = show; |
|
} |
|
|
|
void ImapAccountBase::setOnlySubscribedFolders( bool show ) { |
|
mOnlySubscribedFolders = show; |
|
} |
|
|
|
void ImapAccountBase::setLoadOnDemand( bool load ) { |
|
mLoadOnDemand = load; |
|
} |
|
|
|
// |
|
// |
|
// read/write config |
|
// |
|
// |
|
|
|
void ImapAccountBase::readConfig( /*const*/ KConfig/*Base*/ & config ) { |
|
NetworkAccount::readConfig( config ); |
|
|
|
setPrefix( config.readEntry( "prefix", "/" ) ); |
|
setAutoExpunge( config.readBoolEntry( "auto-expunge", false ) ); |
|
setHiddenFolders( config.readBoolEntry( "hidden-folders", false ) ); |
|
setOnlySubscribedFolders( config.readBoolEntry( "subscribed-folders", false ) ); |
|
setLoadOnDemand( config.readBoolEntry( "loadondemand", false ) ); |
|
} |
|
|
|
void ImapAccountBase::writeConfig( KConfig/*Base*/ & config ) /*const*/ { |
|
NetworkAccount::writeConfig( config ); |
|
|
|
config.writeEntry( "prefix", prefix() ); |
|
config.writeEntry( "auto-expunge", autoExpunge() ); |
|
config.writeEntry( "hidden-folders", hiddenFolders() ); |
|
config.writeEntry( "subscribed-folders", onlySubscribedFolders() ); |
|
config.writeEntry( "loadondemand", loadOnDemand() ); |
|
} |
|
|
|
// |
|
// |
|
// Network processing |
|
// |
|
// |
|
|
|
MetaData ImapAccountBase::slaveConfig() const { |
|
MetaData m = NetworkAccount::slaveConfig(); |
|
|
|
m.insert( "auth", auth() ); |
|
if ( autoExpunge() ) |
|
m.insert( "expunge", "auto" ); |
|
|
|
return m; |
|
} |
|
|
|
ImapAccountBase::ConnectionState ImapAccountBase::makeConnection() { |
|
if ( mSlave ) return Connected; |
|
|
|
if ( mPasswordDialogIsActive ) return Connecting; |
|
if( mAskAgain || passwd().isEmpty() || login().isEmpty() ) { |
|
QString log = login(); |
|
QString pass = passwd(); |
|
// We init "store" to true to indicate that we want to have the |
|
// "keep password" checkbox. Then, we set [Passwords]Keep to |
|
// storePasswd(), so that the checkbox in the dialog will be |
|
// init'ed correctly: |
|
bool store = true; |
|
KConfigGroup passwords( KGlobal::config(), "Passwords" ); |
|
passwords.writeEntry( "Keep", storePasswd() ); |
|
QString msg = i18n("You need to supply a username and a password to " |
|
"access this mailbox."); |
|
mPasswordDialogIsActive = true; |
|
if ( PasswordDialog::getNameAndPassword( log, pass, &store, msg, false, |
|
QString::null, name(), |
|
i18n("Account:") ) |
|
!= QDialog::Accepted ) { |
|
checkDone(false, 0); |
|
mPasswordDialogIsActive = false; |
|
return Error; |
|
} |
|
mPasswordDialogIsActive = false; |
|
// The user has been given the chance to change login and |
|
// password, so copy both from the dialog: |
|
setPasswd( pass, store ); |
|
setLogin( log ); |
|
mAskAgain = false; // ### taken from kmacctexppop |
|
} |
|
|
|
mSlave = KIO::Scheduler::getConnectedSlave( getUrl(), slaveConfig() ); |
|
if ( !mSlave ) { |
|
KMessageBox::error(0, i18n("Could not start process for %1.") |
|
.arg( getUrl().protocol() ) ); |
|
return Error; |
|
} |
|
|
|
return Connecting; |
|
} |
|
|
|
void ImapAccountBase::postProcessNewMail( KMFolder * folder ) { |
|
|
|
disconnect( folder, SIGNAL(numUnreadMsgsChanged(KMFolder*)), |
|
this, SLOT(postProcessNewMail(KMFolder*)) ); |
|
|
|
mCountRemainChecks--; |
|
|
|
// count the unread messages |
|
mCountUnread += folder->countUnread(); |
|
if (mCountRemainChecks == 0) |
|
{ |
|
// all checks are done |
|
KMBroadcastStatus::instance()->setStatusMsgTransmissionCompleted( |
|
name(), mCountUnread ); |
|
if (mCountUnread > 0 && mCountUnread > mCountLastUnread) { |
|
checkDone(true, mCountUnread); |
|
mCountLastUnread = mCountUnread; |
|
} else { |
|
checkDone(false, 0); |
|
} |
|
setCheckingMail(false); |
|
mCountUnread = 0; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void ImapAccountBase::displayProgress() |
|
{ |
|
if (mProgressEnabled == mapJobData.isEmpty()) |
|
{ |
|
mProgressEnabled = !mapJobData.isEmpty(); |
|
KMBroadcastStatus::instance()->setStatusProgressEnable( "I" + mName, |
|
mProgressEnabled ); |
|
} |
|
mIdle = FALSE; |
|
if (mapJobData.isEmpty()) |
|
mIdleTimer.start(15000); |
|
else |
|
mIdleTimer.stop(); |
|
int total = 0, done = 0; |
|
for (QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin(); |
|
it != mapJobData.end(); ++it) |
|
{ |
|
total += (*it).total; |
|
done += (*it).done; |
|
} |
|
if (total == 0) |
|
{ |
|
mTotal = 0; |
|
return; |
|
} |
|
if (total > mTotal) mTotal = total; |
|
done += mTotal - total; |
|
KMBroadcastStatus::instance()->setStatusProgressPercent( "I" + mName, |
|
100*done / mTotal ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void ImapAccountBase::listDirectory(QString path, bool onlySubscribed, |
|
bool secondStep, KMFolder* parent) |
|
{ |
|
if (!makeConnection()) return; |
|
// create jobData |
|
jobData jd; |
|
jd.total = 1; jd.done = 0; |
|
jd.inboxOnly = !secondStep && prefix() != "/" |
|
&& path == prefix(); |
|
if (jd.inboxOnly) |
|
mHasInbox = false; // reset |
|
jd.onlySubscribed = onlySubscribed; |
|
if (parent) jd.parent = parent; |
|
if (!secondStep) mCreateInbox = FALSE; |
|
// make the URL |
|
KURL url = getUrl(); |
|
url.setPath(((jd.inboxOnly) ? QString("/") : path) |
|
+ ";TYPE=" + ((onlySubscribed) ? "LSUB" : "LIST")); |
|
mSubfolderNames.clear(); |
|
mSubfolderPaths.clear(); |
|
mSubfolderMimeTypes.clear(); |
|
// and go |
|
KIO::SimpleJob *job = KIO::listDir(url, FALSE); |
|
KIO::Scheduler::assignJobToSlave(mSlave, job); |
|
insertJob(job, jd); |
|
connect(job, SIGNAL(result(KIO::Job *)), |
|
this, SLOT(slotListResult(KIO::Job *))); |
|
connect(job, SIGNAL(entries(KIO::Job *, const KIO::UDSEntryList &)), |
|
this, SLOT(slotListEntries(KIO::Job *, const KIO::UDSEntryList &))); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void ImapAccountBase::slotListEntries(KIO::Job * job, const KIO::UDSEntryList & uds) |
|
{ |
|
JobIterator it = findJob( job ); |
|
if ( it == jobsEnd() ) return; |
|
QString name; |
|
KURL url; |
|
QString mimeType; |
|
for (KIO::UDSEntryList::ConstIterator udsIt = uds.begin(); |
|
udsIt != uds.end(); udsIt++) |
|
{ |
|
mimeType = QString::null; |
|
for (KIO::UDSEntry::ConstIterator eIt = (*udsIt).begin(); |
|
eIt != (*udsIt).end(); eIt++) |
|
{ |
|
// get the needed information |
|
if ((*eIt).m_uds == KIO::UDS_NAME) |
|
name = (*eIt).m_str; |
|
else if ((*eIt).m_uds == KIO::UDS_URL) |
|
url = KURL((*eIt).m_str, 106); // utf-8 |
|
else if ((*eIt).m_uds == KIO::UDS_MIME_TYPE) |
|
mimeType = (*eIt).m_str; |
|
} |
|
if ((mimeType == "inode/directory" || mimeType == "message/digest" |
|
|| mimeType == "message/directory") |
|
&& name != ".." && (hiddenFolders() || name.at(0) != '.') |
|
&& (!(*it).inboxOnly || name.upper() == "INBOX")) |
|
{ |
|
if (((*it).inboxOnly || |
|
url.path() == "/INBOX/") && name.upper() == "INBOX" && |
|
!mHasInbox) |
|
{ |
|
// our INBOX |
|
mCreateInbox = TRUE; |
|
mHasInbox = TRUE; |
|
} |
|
|
|
// Some servers send _lots_ of duplicates |
|
if (mSubfolderNames.findIndex(name) == -1) |
|
{ |
|
mSubfolderNames.append(name); |
|
mSubfolderPaths.append(url.path()); |
|
mSubfolderMimeTypes.append(mimeType); |
|
} |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void ImapAccountBase::slotListResult(KIO::Job * job) |
|
{ |
|
JobIterator it = findJob( job ); |
|
if ( it == jobsEnd() ) return; |
|
if (job->error()) |
|
{ |
|
slotSlaveError( mSlave, job->error(), |
|
job->errorString() ); |
|
} |
|
if (!job->error()) |
|
{ |
|
// transport the information, include the jobData |
|
emit receivedFolders(mSubfolderNames, mSubfolderPaths, |
|
mSubfolderMimeTypes, *it); |
|
} |
|
if (mSlave) removeJob(it); |
|
mSubfolderNames.clear(); |
|
mSubfolderPaths.clear(); |
|
mSubfolderMimeTypes.clear(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void ImapAccountBase::changeSubscription( bool subscribe, QString imapPath ) |
|
{ |
|
// change the subscription of the folder |
|
KURL url = getUrl(); |
|
url.setPath(imapPath); |
|
|
|
QByteArray packedArgs; |
|
QDataStream stream( packedArgs, IO_WriteOnly); |
|
|
|
if (subscribe) |
|
stream << (int) 'u' << url; |
|
else |
|
stream << (int) 'U' << url; |
|
|
|
// create the KIO-job |
|
if (!makeConnection()) return; |
|
KIO::SimpleJob *job = KIO::special(url, packedArgs, FALSE); |
|
KIO::Scheduler::assignJobToSlave(mSlave, job); |
|
jobData jd; |
|
jd.total = 1; jd.done = 0; jd.parent = NULL; |
|
// a bit of a hack to save one slot |
|
if (subscribe) jd.onlySubscribed = true; |
|
else jd.onlySubscribed = false; |
|
insertJob(job, jd); |
|
|
|
connect(job, SIGNAL(result(KIO::Job *)), |
|
SLOT(slotSubscriptionResult(KIO::Job *))); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void ImapAccountBase::slotSubscriptionResult( KIO::Job * job ) |
|
{ |
|
// result of a subscription-job |
|
JobIterator it = findJob( job ); |
|
if ( it == jobsEnd() ) return; |
|
if (job->error()) |
|
{ |
|
slotSlaveError( mSlave, job->error(), |
|
job->errorString() ); |
|
} else { |
|
emit subscriptionChanged( |
|
static_cast<KIO::SimpleJob*>(job)->url().path(), (*it).onlySubscribed ); |
|
} |
|
if (mSlave) removeJob(it); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void ImapAccountBase::slotSchedulerSlaveError(KIO::Slave *aSlave, int errorCode, |
|
const QString &errorMsg) |
|
{ |
|
if (aSlave != mSlave) return; |
|
slotSlaveError( aSlave, errorCode, errorMsg ); |
|
emit connectionResult( errorCode ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void ImapAccountBase::slotSchedulerSlaveConnected(KIO::Slave *aSlave) |
|
{ |
|
if (aSlave != mSlave) return; |
|
emit connectionResult( 0 ); // success |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void ImapAccountBase::slotSlaveError(KIO::Slave *aSlave, int errorCode, |
|
const QString &errorMsg) |
|
{ |
|
if (aSlave != mSlave) return; |
|
if (errorCode == KIO::ERR_SLAVE_DIED) slaveDied(); |
|
if (errorCode == KIO::ERR_COULD_NOT_LOGIN && !mStorePasswd) mAskAgain = TRUE; |
|
killAllJobs(); |
|
// check if we still display an error |
|
if ( !mErrorDialogIsActive ) |
|
{ |
|
mErrorDialogIsActive = true; |
|
KMessageBox::messageBox(kmkernel->mainWin(), KMessageBox::Error, |
|
KIO::buildErrorString(errorCode, errorMsg), |
|
i18n("Error")); |
|
mErrorDialogIsActive = false; |
|
} else |
|
kdDebug(5006) << "suppressing error:" << errorMsg << endl; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
QString ImapAccountBase::jobData::htmlURL() const |
|
{ |
|
KURL u( url ); |
|
return u.htmlURL(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void ImapAccountBase::processNewMailSingleFolder(KMFolder* folder) |
|
{ |
|
mFoldersQueuedForChecking.append(folder); |
|
if (checkingMail()) |
|
{ |
|
disconnect (this, SIGNAL(finishedCheck(bool)), |
|
this, SLOT(slotCheckQueuedFolders())); |
|
connect (this, SIGNAL(finishedCheck(bool)), |
|
this, SLOT(slotCheckQueuedFolders())); |
|
} else { |
|
slotCheckQueuedFolders(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void ImapAccountBase::slotCheckQueuedFolders() |
|
{ |
|
disconnect (this, SIGNAL(finishedCheck(bool)), |
|
this, SLOT(slotCheckQueuedFolders())); |
|
|
|
QValueList<QGuardedPtr<KMFolder> > mSaveList = mMailCheckFolders; |
|
mMailCheckFolders = mFoldersQueuedForChecking; |
|
kmkernel->acctMgr()->singleCheckMail(this, true); |
|
mMailCheckFolders = mSaveList; |
|
mFoldersQueuedForChecking.clear(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void ImapAccountBase::handleBodyStructure( QDataStream & stream, KMMessage * msg ) |
|
{ |
|
mBodyPartList.clear(); |
|
mCurrentMsg = msg; |
|
// make the parts and fill the mBodyPartList |
|
constructParts( stream, 1, 0, 0, msg->asDwMessage() ); |
|
if ( mBodyPartList.count() == 1 ) // we directly set the body later |
|
msg->deleteBodyParts(); |
|
|
|
// get the currently active reader window |
|
if ( !kmkernel->activeReaderWin() ) |
|
{ |
|
kdWarning(5006) << "ImapAccountBase::handleBodyStructure - found no readerwin!" << endl; |
|
return; |
|
} |
|
|
|
// download parts according to attachmentstrategy |
|
BodyVisitor *visitor = BodyVisitorFactory::getVisitor( |
|
kmkernel->activeReaderWin()->attachmentStrategy() ); |
|
visitor->visit( mBodyPartList ); |
|
QPtrList<KMMessagePart> parts = visitor->partsToLoad(); |
|
QPtrListIterator<KMMessagePart> it( parts ); |
|
KMMessagePart *part; |
|
while ( (part = it.current()) != 0 ) |
|
{ |
|
++it; |
|
kdDebug(5006) << "ImapAccountBase::handleBodyStructure - load " << part->partSpecifier() |
|
<< " (" << part->originalContentTypeStr() << ")" << endl; |
|
if ( part->loadHeaders() ) |
|
{ |
|
kdDebug(5006) << "load HEADER" << endl; |
|
FolderJob *job = msg->parent()->createJob( |
|
msg, FolderJob::tGetMessage, 0, part->partSpecifier()+".MIME" ); |
|
job->start(); |
|
} |
|
if ( part->loadPart() ) |
|
{ |
|
kdDebug(5006) << "load Part" << endl; |
|
FolderJob *job = msg->parent()->createJob( |
|
msg, FolderJob::tGetMessage, 0, part->partSpecifier() ); |
|
job->start(); |
|
} |
|
} |
|
delete visitor; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void ImapAccountBase::constructParts( QDataStream & stream, int count, KMMessagePart* parentKMPart, |
|
DwBodyPart * parent, const DwMessage * dwmsg ) |
|
{ |
|
int children; |
|
for (int i = 0; i < count; i++) |
|
{ |
|
stream >> children; |
|
KMMessagePart* part = new KMMessagePart( stream ); |
|
part->setParent( parentKMPart ); |
|
mBodyPartList.append( part ); |
|
kdDebug(5006) << "ImapAccountBase::constructParts - created id " << part->partSpecifier() |
|
<< " of type " << part->originalContentTypeStr() << endl; |
|
DwBodyPart *dwpart = mCurrentMsg->createDWBodyPart( part ); |
|
dwpart->Parse(); // also creates an encapsulated DwMessage if necessary |
|
|
|
// kdDebug(5006) << "constructed dwpart " << dwpart << ",dwmsg " << dwmsg << ",parent " << parent |
|
// << ",dwparts msg " << dwpart->Body().Message() << endl; |
|
|
|
if ( parent ) |
|
{ |
|
// add to parent body |
|
parent->Body().AddBodyPart( dwpart ); |
|
} else if ( part->partSpecifier() != "0" && |
|
!part->partSpecifier().endsWith(".HEADER") ) |
|
{ |
|
// add to message |
|
dwmsg->Body().AddBodyPart( dwpart ); |
|
} else |
|
dwpart = 0; |
|
|
|
if ( !parentKMPart ) |
|
parentKMPart = part; |
|
|
|
if (children > 0) |
|
{ |
|
DwBodyPart* newparent = dwpart; |
|
const DwMessage* newmsg = dwmsg; |
|
if ( part->originalContentTypeStr() == "MESSAGE/RFC822" && |
|
dwpart->Body().Message() ) |
|
{ |
|
// set the encapsulated message as new parent message |
|
newparent = 0; |
|
newmsg = dwpart->Body().Message(); |
|
} |
|
KMMessagePart* newParentKMPart = part; |
|
if ( part->partSpecifier().endsWith(".HEADER") ) // we don't want headers as parent |
|
newParentKMPart = parentKMPart; |
|
|
|
constructParts( stream, children, newParentKMPart, newparent, newmsg ); |
|
} |
|
} |
|
} |
|
|
|
} // namespace KMail |
|
|
|
#include "imapaccountbase.moc"
|
|
|