00001
00024
#ifdef HAVE_CONFIG_H
00025
#include <config.h>
00026
#endif
00027
00028
#include "imapaccountbase.h"
00029
using KMail::SieveConfig;
00030
00031
#include "kmacctmgr.h"
00032
#include "kmfolder.h"
00033
#include "broadcaststatus.h"
00034
using KPIM::BroadcastStatus;
00035
#include "kmmainwin.h"
00036
#include "kmfolderimap.h"
00037
#include "kmmainwidget.h"
00038
#include "kmmainwin.h"
00039
#include "kmmsgpart.h"
00040
#include "acljobs.h"
00041
#include "kmfoldercachedimap.h"
00042
#include "bodyvisitor.h"
00043
using KMail::BodyVisitor;
00044
#include "imapjob.h"
00045
using KMail::ImapJob;
00046
#include "protocols.h"
00047
#include "progressmanager.h"
00048
using KPIM::ProgressManager;
00049
#include "kmfoldermgr.h"
00050
00051
#include <kapplication.h>
00052
#include <kdebug.h>
00053
#include <kconfig.h>
00054
#include <klocale.h>
00055
#include <kmessagebox.h>
00056
using KIO::MetaData;
00057
#include <kio/passdlg.h>
00058
using KIO::PasswordDialog;
00059
#include <kio/scheduler.h>
00060
#include <kio/slave.h>
00061
#include <mimelib/bodypart.h>
00062
#include <mimelib/body.h>
00063
#include <mimelib/headers.h>
00064
#include <mimelib/message.h>
00065
00066
00067
#include <qregexp.h>
00068
#include <qstylesheet.h>
00069
00070
namespace KMail {
00071
00072
static const unsigned short int imapDefaultPort = 143;
00073
00074
00075
00076
00077
00078
00079
00080 ImapAccountBase::ImapAccountBase( KMAcctMgr * parent,
const QString & name, uint
id )
00081 : NetworkAccount( parent, name, id ),
00082 mPrefix( "/" ),
00083 mTotal( 0 ),
00084 mCountUnread( 0 ),
00085 mCountLastUnread( 0 ),
00086 mAutoExpunge( true ),
00087 mHiddenFolders( false ),
00088 mOnlySubscribedFolders( false ),
00089 mLoadOnDemand( true ),
00090 mListOnlyOpenFolders( false ),
00091 mProgressEnabled( false ),
00092 mErrorDialogIsActive( false ),
00093 mPasswordDialogIsActive( false ),
00094 mACLSupport( true ),
00095 mSlaveConnected( false ),
00096 mListDirProgressItem( 0 )
00097 {
00098 mPort = imapDefaultPort;
00099 mBodyPartList.setAutoDelete(
true);
00100 KIO::Scheduler::connect(SIGNAL(slaveError(KIO::Slave *,
int,
const QString &)),
00101
this, SLOT(slotSchedulerSlaveError(KIO::Slave *,
int,
const QString &)));
00102 KIO::Scheduler::connect(SIGNAL(slaveConnected(KIO::Slave *)),
00103
this, SLOT(slotSchedulerSlaveConnected(KIO::Slave *)));
00104 connect(&mNoopTimer, SIGNAL(timeout()), SLOT(slotNoopTimeout()));
00105 connect(&mIdleTimer, SIGNAL(timeout()), SLOT(slotIdleTimeout()));
00106 }
00107
00108 ImapAccountBase::~ImapAccountBase() {
00109 kdWarning( mSlave, 5006 )
00110 <<
"slave should have been destroyed by subclass!" << endl;
00111 }
00112
00113
void ImapAccountBase::init() {
00114 mPrefix =
'/';
00115 mAutoExpunge =
true;
00116 mHiddenFolders =
false;
00117 mOnlySubscribedFolders =
false;
00118 mLoadOnDemand =
true;
00119 mListOnlyOpenFolders =
false;
00120 mProgressEnabled =
false;
00121 }
00122
00123
void ImapAccountBase::pseudoAssign(
const KMAccount * a ) {
00124 NetworkAccount::pseudoAssign( a );
00125
00126
const ImapAccountBase * i = dynamic_cast<const ImapAccountBase*>( a );
00127
if ( !i )
return;
00128
00129 setPrefix( i->prefix() );
00130 setAutoExpunge( i->autoExpunge() );
00131 setHiddenFolders( i->hiddenFolders() );
00132 setOnlySubscribedFolders( i->onlySubscribedFolders() );
00133 setLoadOnDemand( i->loadOnDemand() );
00134 setListOnlyOpenFolders( i->listOnlyOpenFolders() );
00135 }
00136
00137
unsigned short int ImapAccountBase::defaultPort()
const {
00138
return imapDefaultPort;
00139 }
00140
00141
QString ImapAccountBase::protocol()
const {
00142
return useSSL() ? IMAP_SSL_PROTOCOL : IMAP_PROTOCOL;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
void ImapAccountBase::setPrefix(
const QString & prefix ) {
00152 mPrefix = prefix;
00153 mPrefix.remove(
QRegExp(
"[%*\"]" ) );
00154
if ( mPrefix.isEmpty() || mPrefix[0] !=
'/' )
00155 mPrefix.prepend(
'/' );
00156
if ( mPrefix[ mPrefix.length() - 1 ] !=
'/' )
00157 mPrefix +=
'/';
00158
#if 1
00159
setPrefixHook();
00160
#else
00161
if ( mFolder ) mFolder->setImapPath( mPrefix );
00162
#endif
00163
}
00164
00165
void ImapAccountBase::setAutoExpunge(
bool expunge ) {
00166 mAutoExpunge = expunge;
00167 }
00168
00169
void ImapAccountBase::setHiddenFolders(
bool show ) {
00170 mHiddenFolders = show;
00171 }
00172
00173
void ImapAccountBase::setOnlySubscribedFolders(
bool show ) {
00174 mOnlySubscribedFolders = show;
00175 }
00176
00177
void ImapAccountBase::setLoadOnDemand(
bool load ) {
00178 mLoadOnDemand = load;
00179 }
00180
00181
void ImapAccountBase::setListOnlyOpenFolders(
bool only ) {
00182 mListOnlyOpenFolders = only;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
void ImapAccountBase::readConfig( KConfig & config ) {
00192 NetworkAccount::readConfig( config );
00193
00194 setPrefix( config.readEntry(
"prefix",
"/" ) );
00195 setAutoExpunge( config.readBoolEntry(
"auto-expunge",
false ) );
00196 setHiddenFolders( config.readBoolEntry(
"hidden-folders",
false ) );
00197 setOnlySubscribedFolders( config.readBoolEntry(
"subscribed-folders",
false ) );
00198 setLoadOnDemand( config.readBoolEntry(
"loadondemand",
false ) );
00199 setListOnlyOpenFolders( config.readBoolEntry(
"listOnlyOpenFolders",
false ) );
00200 }
00201
00202
void ImapAccountBase::writeConfig( KConfig & config ) {
00203 NetworkAccount::writeConfig( config );
00204
00205 config.writeEntry(
"prefix", prefix() );
00206 config.writeEntry(
"auto-expunge", autoExpunge() );
00207 config.writeEntry(
"hidden-folders", hiddenFolders() );
00208 config.writeEntry(
"subscribed-folders", onlySubscribedFolders() );
00209 config.writeEntry(
"loadondemand", loadOnDemand() );
00210 config.writeEntry(
"listOnlyOpenFolders", listOnlyOpenFolders() );
00211 }
00212
00213
00214
00215
00216
00217
00218
00219 MetaData ImapAccountBase::slaveConfig()
const {
00220 MetaData m = NetworkAccount::slaveConfig();
00221
00222 m.insert(
"auth", auth() );
00223
if ( autoExpunge() )
00224 m.insert(
"expunge",
"auto" );
00225
00226
return m;
00227 }
00228
00229 ImapAccountBase::ConnectionState ImapAccountBase::makeConnection() {
00230
00231
if ( mSlave && mSlaveConnected )
return Connected;
00232
if ( mPasswordDialogIsActive )
return Connecting;
00233
00234
if( mAskAgain || passwd().isEmpty() || login().isEmpty() ) {
00235 Q_ASSERT( !mSlave );
00236
QString log = login();
00237
QString pass = passwd();
00238
00239
00240
00241
00242
bool store =
true;
00243 KConfigGroup passwords( KGlobal::config(),
"Passwords" );
00244 passwords.writeEntry(
"Keep", storePasswd() );
00245
QString msg = i18n(
"You need to supply a username and a password to "
00246
"access this mailbox.");
00247 mPasswordDialogIsActive =
true;
00248
if ( PasswordDialog::getNameAndPassword( log, pass, &store, msg,
false,
00249 QString::null, name(),
00250 i18n(
"Account:") )
00251 != QDialog::Accepted ) {
00252 mPasswordDialogIsActive =
false;
00253 mAskAgain =
false;
00254 emit connectionResult( KIO::ERR_USER_CANCELED, QString::null );
00255
return Error;
00256 }
00257 mPasswordDialogIsActive =
false;
00258
00259
00260 setPasswd( pass, store );
00261 setLogin( log );
00262 mAskAgain =
false;
00263 }
00264
00265
if ( mSlave && !mSlaveConnected )
return Connecting;
00266
00267 mSlaveConnected =
false;
00268 mSlave = KIO::Scheduler::getConnectedSlave( getUrl(), slaveConfig() );
00269
if ( !mSlave ) {
00270 KMessageBox::error(0, i18n(
"Could not start process for %1.")
00271 .arg( getUrl().protocol() ) );
00272
return Error;
00273 }
00274
if ( mSlave->isConnected() ) {
00275 mSlaveConnected =
true;
00276
return Connected;
00277 }
00278
00279
return Connecting;
00280 }
00281
00282
bool ImapAccountBase::handleJobError( KIO::Job *job,
const QString& context,
bool abortSync )
00283 {
00284
return handleError( job->error(), job->errorText(), job, context, abortSync );
00285 }
00286
00287
00288
void ImapAccountBase::postProcessNewMail() {
00289 setCheckingMail(
false);
00290
int newMails = 0;
00291
if ( mCountUnread > 0 && mCountUnread > mCountLastUnread ) {
00292 newMails = mCountUnread - mCountLastUnread;
00293 mCountLastUnread = mCountUnread;
00294 mCountUnread = 0;
00295 checkDone(
true, CheckOK );
00296 }
else {
00297 mCountUnread = 0;
00298 checkDone(
false, CheckOK );
00299 }
00300 BroadcastStatus::instance()->setStatusMsgTransmissionCompleted(
00301 name(), newMails);
00302 }
00303
00304
00305
void ImapAccountBase::changeSubscription(
bool subscribe,
QString imapPath )
00306 {
00307
00308 KURL url = getUrl();
00309 url.setPath(imapPath);
00310
00311
QByteArray packedArgs;
00312
QDataStream stream( packedArgs, IO_WriteOnly);
00313
00314
if (subscribe)
00315 stream << (
int)
'u' << url;
00316
else
00317 stream << (
int)
'U' << url;
00318
00319
00320
if (makeConnection() != Connected)
00321
return;
00322 KIO::SimpleJob *job = KIO::special(url, packedArgs, FALSE);
00323 KIO::Scheduler::assignJobToSlave(mSlave, job);
00324 jobData jd( url.url(), NULL );
00325
00326
if (subscribe) jd.onlySubscribed =
true;
00327
else jd.onlySubscribed =
false;
00328 insertJob(job, jd);
00329
00330 connect(job, SIGNAL(result(KIO::Job *)),
00331 SLOT(slotSubscriptionResult(KIO::Job *)));
00332 }
00333
00334
00335
void ImapAccountBase::slotSubscriptionResult( KIO::Job * job )
00336 {
00337
00338 JobIterator it = findJob( job );
00339
if ( it == jobsEnd() )
return;
00340
bool onlySubscribed = (*it).onlySubscribed;
00341
QString path = static_cast<KIO::SimpleJob*>(job)->url().path();
00342
if (job->error())
00343 {
00344 handleJobError( job, i18n(
"Error while trying to subscribe to %1:" ).arg( path ) +
'\n' );
00345
00346 }
00347
else
00348 {
00349 emit subscriptionChanged( path, onlySubscribed );
00350
if (mSlave) removeJob(job);
00351 }
00352 }
00353
00354
00355
00356
void ImapAccountBase::getUserRights(
KMFolder* parent,
const QString& imapPath )
00357 {
00358
00359
00360
00361
00362
if ( imapPath ==
"/INBOX/" ) {
00363
if ( parent->
folderType() == KMFolderTypeImap )
00364 static_cast<KMFolderImap*>( parent->
storage() )->setUserRights( ACLJobs::All );
00365
else if ( parent->
folderType() == KMFolderTypeCachedImap )
00366 static_cast<KMFolderCachedImap*>( parent->
storage() )->setUserRights( ACLJobs::All );
00367 emit receivedUserRights( parent );
00368
return;
00369 }
00370
00371 KURL url = getUrl();
00372 url.setPath(imapPath);
00373
00374
ACLJobs::GetUserRightsJob* job = ACLJobs::getUserRights( mSlave, url );
00375
00376 jobData jd( url.url(), parent );
00377 jd.cancellable =
true;
00378 insertJob(job, jd);
00379
00380 connect(job, SIGNAL(result(KIO::Job *)),
00381 SLOT(slotGetUserRightsResult(KIO::Job *)));
00382 }
00383
00384
void ImapAccountBase::slotGetUserRightsResult( KIO::Job* _job )
00385 {
00386
ACLJobs::GetUserRightsJob* job = static_cast<ACLJobs::GetUserRightsJob *>( _job );
00387 JobIterator it = findJob( job );
00388
if ( it == jobsEnd() )
return;
00389
00390
KMFolder* folder = (*it).parent;
00391
if ( job->error() ) {
00392
if ( job->error() == KIO::ERR_UNSUPPORTED_ACTION )
00393 mACLSupport =
false;
00394
else
00395 kdWarning(5006) <<
"slotGetUserRightsResult: " << job->errorString() << endl;
00396 }
else {
00397
#ifndef NDEBUG
00398
00399
#endif
00400
00401
if ( folder->
folderType() == KMFolderTypeImap )
00402 static_cast<KMFolderImap*>( folder->
storage() )->setUserRights( job->
permissions() );
00403
else if ( folder->
folderType() == KMFolderTypeCachedImap )
00404 static_cast<KMFolderCachedImap*>( folder->
storage() )->setUserRights( job->
permissions() );
00405 }
00406
if (mSlave) removeJob(job);
00407 emit receivedUserRights( folder );
00408 }
00409
00410
00411
void ImapAccountBase::getACL(
KMFolder* parent,
const QString& imapPath )
00412 {
00413 KURL url = getUrl();
00414 url.setPath(imapPath);
00415
00416
ACLJobs::GetACLJob* job = ACLJobs::getACL( mSlave, url );
00417 jobData jd( url.url(), parent );
00418 jd.cancellable =
true;
00419 insertJob(job, jd);
00420
00421 connect(job, SIGNAL(result(KIO::Job *)),
00422 SLOT(slotGetACLResult(KIO::Job *)));
00423 }
00424
00425
void ImapAccountBase::slotGetACLResult( KIO::Job* _job )
00426 {
00427
ACLJobs::GetACLJob* job = static_cast<ACLJobs::GetACLJob *>( _job );
00428 JobIterator it = findJob( job );
00429
if ( it == jobsEnd() )
return;
00430
00431
KMFolder* folder = (*it).parent;
00432 emit receivedACL( folder, job, job->
entries() );
00433
if (mSlave) removeJob(job);
00434 }
00435
00436
00437
void ImapAccountBase::slotNoopTimeout()
00438 {
00439
if ( mSlave ) {
00440
QByteArray packedArgs;
00441
QDataStream stream( packedArgs, IO_WriteOnly );
00442
00443 stream << (
int )
'N';
00444
00445 KIO::SimpleJob *job = KIO::special( getUrl(), packedArgs,
false );
00446 KIO::Scheduler::assignJobToSlave(mSlave, job);
00447 connect( job, SIGNAL(result( KIO::Job * ) ),
00448
this, SLOT( slotSimpleResult( KIO::Job * ) ) );
00449 }
else {
00450
00451
00452 mNoopTimer.stop();
00453 }
00454 }
00455
00456
void ImapAccountBase::slotIdleTimeout()
00457 {
00458
if ( mSlave ) {
00459 KIO::Scheduler::disconnectSlave(mSlave);
00460 mSlave = 0;
00461 mSlaveConnected =
false;
00462
00463
00464 mIdleTimer.stop();
00465 }
00466 }
00467
00468
void ImapAccountBase::slotAbortRequested( KPIM::ProgressItem* item )
00469 {
00470
if ( item )
00471 item->setComplete();
00472 killAllJobs();
00473 }
00474
00475
00476
00477
void ImapAccountBase::slotSchedulerSlaveError(KIO::Slave *aSlave,
int errorCode,
00478
const QString &errorMsg)
00479 {
00480
if (aSlave != mSlave)
return;
00481 handleError( errorCode, errorMsg, 0, QString::null,
true );
00482
if ( mAskAgain )
00483 makeConnection();
00484
else
00485 emit connectionResult( errorCode, errorMsg );
00486 }
00487
00488
00489
void ImapAccountBase::slotSchedulerSlaveConnected(KIO::Slave *aSlave)
00490 {
00491
if (aSlave != mSlave)
return;
00492 mSlaveConnected =
true;
00493 emit connectionResult( 0, QString::null );
00494 }
00495
00496
00497
void ImapAccountBase::slotSimpleResult(KIO::Job * job)
00498 {
00499 JobIterator it = findJob( job );
00500
bool quiet =
false;
00501
if (it != mapJobData.end()) {
00502 quiet = (*it).quiet;
00503
if ( !(job->error() && !quiet) )
00504 removeJob(it);
00505 }
00506
if (job->error()) {
00507
if (!quiet)
00508 handleJobError(job, QString::null );
00509
else {
00510
if ( job->error() == KIO::ERR_CONNECTION_BROKEN && slave() ) {
00511
00512
00513 KIO::Scheduler::disconnectSlave( slave() );
00514 mSlave = 0;
00515 }
00516
if (job->error() == KIO::ERR_SLAVE_DIED)
00517 slaveDied();
00518 }
00519 }
00520 }
00521
00522
00523
bool ImapAccountBase::handlePutError( KIO::Job* job, jobData& jd,
KMFolder* folder )
00524 {
00525 Q_ASSERT( !jd.msgList.isEmpty() );
00526 KMMessage* msg = jd.msgList.first();
00527
00528
00529
const QString subject = msg->subject().isEmpty() ? i18n(
"<unknown>" ) :
QString("\"%1\"").arg( msg->subject() );
00530
const QString from = msg->from().isEmpty() ? i18n(
"<unknown>" ) : msg->from();
00531
QString myError =
"<p><b>" + i18n(
"Error while uploading message")
00532 +
"</b></p><p>"
00533 + i18n(
"Could not upload the message dated %1 from %2 with subject %3 on the server.").arg( msg->dateStr(), QStyleSheet::escape( from ), QStyleSheet::escape( subject ) )
00534 +
"</p><p>"
00535 + i18n(
"The destination folder was %1, which has the URL %2.").arg( QStyleSheet::escape( folder->
label() ), QStyleSheet::escape( jd.htmlURL() ) )
00536 +
"</p><p>"
00537 + i18n(
"The error message from the server communication is here:") +
"</p>";
00538
return handleJobError( job, myError );
00539 }
00540
00541
00542
bool ImapAccountBase::handleError(
int errorCode,
const QString &errorMsg, KIO::Job* job,
const QString& context,
bool abortSync )
00543 {
00544
00545
QStringList errors;
00546
if ( job && job->error() != KIO::ERR_SLAVE_DEFINED )
00547 errors = job->detailedErrorStrings();
00548
00549
bool jobsKilled =
true;
00550
switch( errorCode ) {
00551
case KIO::ERR_SLAVE_DIED: slaveDied(); killAllJobs(
true );
break;
00552
case KIO::ERR_COULD_NOT_LOGIN:
00553 mAskAgain =
true;
00554
00555
case KIO::ERR_CONNECTION_BROKEN:
00556
case KIO::ERR_COULD_NOT_CONNECT:
00557
00558 killAllJobs(
true );
00559
break;
00560
case KIO::ERR_USER_CANCELED:
00561 killAllJobs(
false );
00562
break;
00563
default:
00564
if ( abortSync )
00565 killAllJobs(
false );
00566
else
00567 jobsKilled =
false;
00568
break;
00569 }
00570
00571
00572
if ( !mErrorDialogIsActive && errorCode != KIO::ERR_USER_CANCELED )
00573 {
00574 mErrorDialogIsActive =
true;
00575
QString msg;
00576
QString caption;
00577
if ( errors.count() >= 3 ) {
00578 msg =
QString(
"<qt>") + context + errors[1] +
'\n' + errors[2];
00579 caption = errors[0];
00580 }
else {
00581 msg = context +
'\n' + KIO::buildErrorString( errorCode, errorMsg );
00582 caption = i18n(
"Error");
00583 }
00584
00585
if ( jobsKilled || errorCode == KIO::ERR_COULD_NOT_LOGIN )
00586 KMessageBox::error( kapp->activeWindow(), msg, caption );
00587
else
00588 {
00589
int ret = KMessageBox::warningContinueCancel( kapp->activeWindow(), msg, caption );
00590
if ( ret == KMessageBox::Cancel ) {
00591 jobsKilled =
true;
00592 killAllJobs(
false );
00593 }
00594 }
00595 mErrorDialogIsActive =
false;
00596 }
else
00597 kdDebug(5006) <<
"suppressing error:" << errorMsg << endl;
00598
00599
if ( job && !jobsKilled )
00600 removeJob( job );
00601
return !jobsKilled;
00602 }
00603
00604
00605
void ImapAccountBase::cancelMailCheck()
00606 {
00607
QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin();
00608
while ( it != mapJobData.end() ) {
00609 kdDebug(5006) <<
"cancelMailCheck: job is cancellable: " << (*it).cancellable << endl;
00610
if ( (*it).cancellable ) {
00611 it.key()->kill();
00612
QMap<KIO::Job*, jobData>::Iterator rmit = it;
00613 ++it;
00614 mapJobData.remove( rmit );
00615
00616 mSlave = 0;
00617 }
else
00618 ++it;
00619 }
00620
00621
for(
QPtrListIterator<FolderJob> it( mJobList ); it.current(); ++it ) {
00622
if ( it.current()->isCancellable() ) {
00623 FolderJob* job = it.current();
00624 job->setPassiveDestructor(
true );
00625 mJobList.remove( job );
00626
delete job;
00627 }
else
00628 ++it;
00629 }
00630 }
00631
00632
00633
00634
QString ImapAccountBase::jobData::htmlURL()
const
00635
{
00636 KURL u( url );
00637
return u.htmlURL();
00638 }
00639
00640
00641
void ImapAccountBase::processNewMailSingleFolder(
KMFolder* folder)
00642 {
00643 mFoldersQueuedForChecking.append(folder);
00644
if ( checkingMail() )
00645 {
00646 disconnect(
this, SIGNAL( finishedCheck(
bool, CheckStatus ) ),
00647
this, SLOT( slotCheckQueuedFolders() ) );
00648 connect(
this, SIGNAL( finishedCheck(
bool, CheckStatus ) ),
00649
this, SLOT( slotCheckQueuedFolders() ) );
00650 }
else {
00651 slotCheckQueuedFolders();
00652 }
00653 }
00654
00655
00656
void ImapAccountBase::slotCheckQueuedFolders()
00657 {
00658 disconnect(
this, SIGNAL( finishedCheck(
bool, CheckStatus ) ),
00659
this, SLOT( slotCheckQueuedFolders() ) );
00660
00661
QValueList<QGuardedPtr<KMFolder> > mSaveList = mMailCheckFolders;
00662 mMailCheckFolders = mFoldersQueuedForChecking;
00663 kmkernel->acctMgr()->singleCheckMail(
this,
true);
00664 mMailCheckFolders = mSaveList;
00665 mFoldersQueuedForChecking.clear();
00666 }
00667
00668
00669
bool ImapAccountBase::checkingMail(
KMFolder *folder )
00670 {
00671
if (checkingMail() && mFoldersQueuedForChecking.contains(folder))
00672
return true;
00673
return false;
00674 }
00675
00676
00677
void ImapAccountBase::handleBodyStructure(
QDataStream & stream, KMMessage * msg,
00678
const AttachmentStrategy *as )
00679 {
00680 mBodyPartList.clear();
00681 mCurrentMsg = msg;
00682
00683 constructParts( stream, 1, 0, 0, msg->asDwMessage() );
00684
if ( mBodyPartList.count() == 1 )
00685 msg->deleteBodyParts();
00686
00687
if ( !as )
00688 {
00689 kdWarning(5006) <<
"ImapAccountBase::handleBodyStructure - found no attachment strategy!" << endl;
00690
return;
00691 }
00692
00693
00694 BodyVisitor *visitor = BodyVisitorFactory::getVisitor( as );
00695 visitor->visit( mBodyPartList );
00696
QPtrList<KMMessagePart> parts = visitor->partsToLoad();
00697
QPtrListIterator<KMMessagePart> it( parts );
00698 KMMessagePart *part;
00699
while ( (part = it.current()) != 0 )
00700 {
00701 ++it;
00702 kdDebug(5006) <<
"ImapAccountBase::handleBodyStructure - load " << part->partSpecifier()
00703 <<
" (" << part->originalContentTypeStr() <<
")" << endl;
00704
if ( part->loadHeaders() )
00705 {
00706 kdDebug(5006) <<
"load HEADER" << endl;
00707 FolderJob *job = msg->parent()->createJob(
00708 msg, FolderJob::tGetMessage, 0, part->partSpecifier()+
".MIME" );
00709 job->start();
00710 }
00711
if ( part->loadPart() )
00712 {
00713 kdDebug(5006) <<
"load Part" << endl;
00714 FolderJob *job = msg->parent()->createJob(
00715 msg, FolderJob::tGetMessage, 0, part->partSpecifier() );
00716 job->start();
00717 }
00718 }
00719
delete visitor;
00720 }
00721
00722
00723
void ImapAccountBase::constructParts(
QDataStream & stream,
int count, KMMessagePart* parentKMPart,
00724 DwBodyPart * parent,
const DwMessage * dwmsg )
00725 {
00726
int children;
00727
for (
int i = 0; i < count; i++)
00728 {
00729 stream >> children;
00730 KMMessagePart* part =
new KMMessagePart( stream );
00731 part->setParent( parentKMPart );
00732 mBodyPartList.append( part );
00733 kdDebug(5006) <<
"ImapAccountBase::constructParts - created id " << part->partSpecifier()
00734 <<
" of type " << part->originalContentTypeStr() << endl;
00735 DwBodyPart *dwpart = mCurrentMsg->createDWBodyPart( part );
00736 dwpart->Parse();
00737
00738
00739
00740
00741
if ( parent )
00742 {
00743
00744 parent->Body().AddBodyPart( dwpart );
00745 }
else if ( part->partSpecifier() !=
"0" &&
00746 !part->partSpecifier().endsWith(
".HEADER") )
00747 {
00748
00749 dwmsg->Body().AddBodyPart( dwpart );
00750 }
else
00751 dwpart = 0;
00752
00753
if ( !parentKMPart )
00754 parentKMPart = part;
00755
00756
if (children > 0)
00757 {
00758 DwBodyPart* newparent = dwpart;
00759
const DwMessage* newmsg = dwmsg;
00760
if ( part->originalContentTypeStr() ==
"MESSAGE/RFC822" &&
00761 dwpart->Body().Message() )
00762 {
00763
00764 newparent = 0;
00765 newmsg = dwpart->Body().Message();
00766 }
00767 KMMessagePart* newParentKMPart = part;
00768
if ( part->partSpecifier().endsWith(
".HEADER") )
00769 newParentKMPart = parentKMPart;
00770
00771 constructParts( stream, children, newParentKMPart, newparent, newmsg );
00772 }
00773 }
00774 }
00775
00776
00777
void ImapAccountBase::setImapStatus(
KMFolder* folder,
const QString& path,
const QCString& flags )
00778 {
00779
00780 kdDebug(5006) <<
"setImapStatus path=" << path <<
" to: " << flags << endl;
00781 KURL url = getUrl();
00782 url.setPath(path);
00783
00784
QByteArray packedArgs;
00785
QDataStream stream( packedArgs, IO_WriteOnly);
00786
00787 stream << (
int)
'S' << url << flags;
00788
00789
if ( makeConnection() != ImapAccountBase::Connected )
00790
return;
00791
00792 KIO::SimpleJob *job = KIO::special(url, packedArgs, FALSE);
00793 KIO::Scheduler::assignJobToSlave(slave(), job);
00794 ImapAccountBase::jobData jd( url.url(), folder );
00795 jd.path = path;
00796 insertJob(job, jd);
00797 connect(job, SIGNAL(result(KIO::Job *)),
00798 SLOT(slotSetStatusResult(KIO::Job *)));
00799 }
00800
00801
void ImapAccountBase::slotSetStatusResult(KIO::Job * job)
00802 {
00803 ImapAccountBase::JobIterator it = findJob(job);
00804
if ( it == jobsEnd() )
return;
00805
int errorCode = job->error();
00806
if (errorCode && errorCode != KIO::ERR_CANNOT_OPEN_FOR_WRITING)
00807 {
00808
bool cont = handleJobError( job, i18n(
"Error while uploading status of messages to server: " ) +
'\n' );
00809 emit imapStatusChanged( (*it).parent, (*it).path, cont );
00810 }
00811
else
00812 {
00813 emit imapStatusChanged( (*it).parent, (*it).path,
true );
00814 removeJob(it);
00815 }
00816 }
00817
00818
00819
void ImapAccountBase::setFolder(
KMFolder* folder,
bool addAccount)
00820 {
00821
if (folder)
00822 {
00823 folder->
setSystemLabel(name());
00824 folder->setId(
id());
00825 }
00826 NetworkAccount::setFolder(folder, addAccount);
00827 }
00828
00829
00830
void ImapAccountBase::removeJob( JobIterator& it )
00831 {
00832
if( (*it).progressItem ) {
00833 (*it).progressItem->setComplete();
00834 (*it).progressItem = 0;
00835 }
00836 mapJobData.remove( it );
00837 }
00838
00839
00840 KPIM::ProgressItem* ImapAccountBase::listDirProgressItem()
00841 {
00842
if ( !mListDirProgressItem )
00843 {
00844 mListDirProgressItem = ProgressManager::createProgressItem(
00845
"ListDir" + name(),
00846 name(),
00847 i18n(
"retrieving folders"),
00848
true,
00849 useSSL() || useTLS() );
00850 connect ( mListDirProgressItem,
00851 SIGNAL( progressItemCanceled( ProgressItem* ) ),
00852
this,
00853 SLOT( slotAbortRequested( ProgressItem* ) ) );
00854
00855
00856
00857
unsigned int count = folderCount();
00858 mListDirProgressItem->setTotalItems( count + (
unsigned int)(count*0.05) );
00859 }
00860
return mListDirProgressItem;
00861 }
00862
00863
unsigned int ImapAccountBase::folderCount()
const
00864
{
00865
if ( !rootFolder() || !rootFolder()->folder() || !rootFolder()->folder()->child() )
00866
return 0;
00867
return kmkernel->imapFolderMgr()->folderCount( rootFolder()->folder()->child() );
00868 }
00869
00870 }
00871
00872
#include "imapaccountbase.moc"