00001
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include "imapaccountbase.h"
00029 using KMail::SieveConfig;
00030
00031 #include "accountmanager.h"
00032 using KMail::AccountManager;
00033 #include "kmfolder.h"
00034 #include "broadcaststatus.h"
00035 using KPIM::BroadcastStatus;
00036 #include "kmmainwin.h"
00037 #include "kmfolderimap.h"
00038 #include "kmmainwidget.h"
00039 #include "kmmainwin.h"
00040 #include "kmmsgpart.h"
00041 #include "acljobs.h"
00042 #include "kmfoldercachedimap.h"
00043 #include "bodyvisitor.h"
00044 using KMail::BodyVisitor;
00045 #include "imapjob.h"
00046 using KMail::ImapJob;
00047 #include "protocols.h"
00048 #include "progressmanager.h"
00049 using KPIM::ProgressManager;
00050 #include "kmfoldermgr.h"
00051 #include "listjob.h"
00052
00053 #include <kapplication.h>
00054 #include <kdebug.h>
00055 #include <kconfig.h>
00056 #include <klocale.h>
00057 #include <kmessagebox.h>
00058 using KIO::MetaData;
00059 #include <kio/passdlg.h>
00060 using KIO::PasswordDialog;
00061 #include <kio/scheduler.h>
00062 #include <kio/slave.h>
00063 #include <mimelib/bodypart.h>
00064 #include <mimelib/body.h>
00065 #include <mimelib/headers.h>
00066 #include <mimelib/message.h>
00067
00068
00069 #include <qregexp.h>
00070 #include <qstylesheet.h>
00071
00072 namespace KMail {
00073
00074 static const unsigned short int imapDefaultPort = 143;
00075
00076
00077
00078
00079
00080
00081
00082 ImapAccountBase::ImapAccountBase( AccountManager * parent, const QString & name, uint id )
00083 : NetworkAccount( parent, name, id ),
00084 mTotal( 0 ),
00085 mCountUnread( 0 ),
00086 mCountLastUnread( 0 ),
00087 mAutoExpunge( true ),
00088 mHiddenFolders( false ),
00089 mOnlySubscribedFolders( false ),
00090 mOnlyLocallySubscribedFolders( false ),
00091 mLoadOnDemand( true ),
00092 mListOnlyOpenFolders( false ),
00093 mProgressEnabled( false ),
00094 mErrorDialogIsActive( false ),
00095 mPasswordDialogIsActive( false ),
00096 mACLSupport( true ),
00097 mAnnotationSupport( true ),
00098 mQuotaSupport( true ),
00099 mSlaveConnected( false ),
00100 mSlaveConnectionError( false ),
00101 mCheckingSingleFolder( false ),
00102 mListDirProgressItem( 0 )
00103 {
00104 mPort = imapDefaultPort;
00105 mBodyPartList.setAutoDelete(true);
00106 KIO::Scheduler::connect(SIGNAL(slaveError(KIO::Slave *, int, const QString &)),
00107 this, SLOT(slotSchedulerSlaveError(KIO::Slave *, int, const QString &)));
00108 KIO::Scheduler::connect(SIGNAL(slaveConnected(KIO::Slave *)),
00109 this, SLOT(slotSchedulerSlaveConnected(KIO::Slave *)));
00110 connect(&mNoopTimer, SIGNAL(timeout()), SLOT(slotNoopTimeout()));
00111 connect(&mIdleTimer, SIGNAL(timeout()), SLOT(slotIdleTimeout()));
00112 }
00113
00114 ImapAccountBase::~ImapAccountBase() {
00115 kdWarning( mSlave, 5006 )
00116 << "slave should have been destroyed by subclass!" << endl;
00117 }
00118
00119 void ImapAccountBase::init() {
00120 mAutoExpunge = true;
00121 mHiddenFolders = false;
00122 mOnlySubscribedFolders = false;
00123 mOnlyLocallySubscribedFolders = false;
00124 mLoadOnDemand = true;
00125 mListOnlyOpenFolders = false;
00126 mProgressEnabled = false;
00127 }
00128
00129 void ImapAccountBase::pseudoAssign( const KMAccount * a ) {
00130 NetworkAccount::pseudoAssign( a );
00131
00132 const ImapAccountBase * i = dynamic_cast<const ImapAccountBase*>( a );
00133 if ( !i ) return;
00134
00135 setAutoExpunge( i->autoExpunge() );
00136 setHiddenFolders( i->hiddenFolders() );
00137 setOnlySubscribedFolders( i->onlySubscribedFolders() );
00138 setOnlyLocallySubscribedFolders( i->onlyLocallySubscribedFolders() );
00139 setLoadOnDemand( i->loadOnDemand() );
00140 setListOnlyOpenFolders( i->listOnlyOpenFolders() );
00141 setNamespaces( i->namespaces() );
00142 setNamespaceToDelimiter( i->namespaceToDelimiter() );
00143 localBlacklistFromStringList( i->locallyBlacklistedFolders() );
00144 }
00145
00146 unsigned short int ImapAccountBase::defaultPort() const {
00147 return imapDefaultPort;
00148 }
00149
00150 QString ImapAccountBase::protocol() const {
00151 return useSSL() ? IMAP_SSL_PROTOCOL : IMAP_PROTOCOL;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160 void ImapAccountBase::setAutoExpunge( bool expunge ) {
00161 mAutoExpunge = expunge;
00162 }
00163
00164 void ImapAccountBase::setHiddenFolders( bool show ) {
00165 mHiddenFolders = show;
00166 }
00167
00168 void ImapAccountBase::setOnlySubscribedFolders( bool show ) {
00169 mOnlySubscribedFolders = show;
00170 }
00171
00172 void ImapAccountBase::setOnlyLocallySubscribedFolders( bool show ) {
00173 mOnlyLocallySubscribedFolders = show;
00174 }
00175
00176 void ImapAccountBase::setLoadOnDemand( bool load ) {
00177 mLoadOnDemand = load;
00178 }
00179
00180 void ImapAccountBase::setListOnlyOpenFolders( bool only ) {
00181 mListOnlyOpenFolders = only;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190 void ImapAccountBase::readConfig( KConfig & config ) {
00191 NetworkAccount::readConfig( config );
00192
00193 setAutoExpunge( config.readBoolEntry( "auto-expunge", false ) );
00194 setHiddenFolders( config.readBoolEntry( "hidden-folders", false ) );
00195 setOnlySubscribedFolders( config.readBoolEntry( "subscribed-folders", false ) );
00196 setOnlyLocallySubscribedFolders( config.readBoolEntry( "locally-subscribed-folders", false ) );
00197 setLoadOnDemand( config.readBoolEntry( "loadondemand", false ) );
00198 setListOnlyOpenFolders( config.readBoolEntry( "listOnlyOpenFolders", false ) );
00199
00200 nsMap map;
00201 QStringList list = config.readListEntry( QString::number( PersonalNS ) );
00202 if ( !list.isEmpty() )
00203 map[PersonalNS] = list.gres( "\"", "" );
00204 list = config.readListEntry( QString::number( OtherUsersNS ) );
00205 if ( !list.isEmpty() )
00206 map[OtherUsersNS] = list.gres( "\"", "" );
00207 list = config.readListEntry( QString::number( SharedNS ) );
00208 if ( !list.isEmpty() )
00209 map[SharedNS] = list.gres( "\"", "" );
00210 setNamespaces( map );
00211
00212 namespaceDelim entries = config.entryMap( config.group() );
00213 namespaceDelim namespaceToDelimiter;
00214 for ( namespaceDelim::ConstIterator it = entries.begin();
00215 it != entries.end(); ++it ) {
00216 if ( it.key().startsWith( "Namespace:" ) ) {
00217 QString key = it.key().right( it.key().length() - 10 );
00218 namespaceToDelimiter[key] = it.data();
00219 }
00220 }
00221 setNamespaceToDelimiter( namespaceToDelimiter );
00222 mOldPrefix = config.readEntry( "prefix" );
00223 if ( !mOldPrefix.isEmpty() ) {
00224 makeConnection();
00225 }
00226 localBlacklistFromStringList( config.readListEntry( "locallyUnsubscribedFolders" ) );
00227 }
00228
00229 void ImapAccountBase::writeConfig( KConfig & config ) {
00230 NetworkAccount::writeConfig( config );
00231
00232 config.writeEntry( "auto-expunge", autoExpunge() );
00233 config.writeEntry( "hidden-folders", hiddenFolders() );
00234 config.writeEntry( "subscribed-folders", onlySubscribedFolders() );
00235 config.writeEntry( "locally-subscribed-folders", onlyLocallySubscribedFolders() );
00236 config.writeEntry( "loadondemand", loadOnDemand() );
00237 config.writeEntry( "listOnlyOpenFolders", listOnlyOpenFolders() );
00238 QString data;
00239 for ( nsMap::Iterator it = mNamespaces.begin(); it != mNamespaces.end(); ++it ) {
00240 if ( !it.data().isEmpty() ) {
00241 data = "\"" + it.data().join("\",\"") + "\"";
00242 config.writeEntry( QString::number( it.key() ), data );
00243 }
00244 }
00245 QString key;
00246 for ( namespaceDelim::ConstIterator it = mNamespaceToDelimiter.begin();
00247 it != mNamespaceToDelimiter.end(); ++it ) {
00248 key = "Namespace:" + it.key();
00249 config.writeEntry( key, it.data() );
00250 }
00251 config.writeEntry( "locallyUnsubscribedFolders", locallyBlacklistedFolders() );
00252 }
00253
00254
00255
00256
00257
00258
00259
00260 MetaData ImapAccountBase::slaveConfig() const {
00261 MetaData m = NetworkAccount::slaveConfig();
00262
00263 m.insert( "auth", auth() );
00264 if ( autoExpunge() )
00265 m.insert( "expunge", "auto" );
00266
00267 return m;
00268 }
00269
00270 ImapAccountBase::ConnectionState ImapAccountBase::makeConnection()
00271 {
00272 if ( mSlave && mSlaveConnected ) {
00273 return Connected;
00274 }
00275 if ( mPasswordDialogIsActive ) return Connecting;
00276
00277 if( mAskAgain || ( ( passwd().isEmpty() || login().isEmpty() ) &&
00278 auth() != "GSSAPI" ) ) {
00279
00280 Q_ASSERT( !mSlave );
00281 QString log = login();
00282 QString pass = passwd();
00283
00284
00285
00286
00287 KConfigGroup passwords( KGlobal::config(), "Passwords" );
00288 passwords.writeEntry( "Keep", storePasswd() );
00289 QString msg = i18n("You need to supply a username and a password to "
00290 "access this mailbox.");
00291 mPasswordDialogIsActive = true;
00292
00293 PasswordDialog dlg( msg, log, true , true, KMKernel::self()->mainWin() );
00294 dlg.setPlainCaption( i18n("Authorization Dialog") );
00295 dlg.addCommentLine( i18n("Account:"), name() );
00296 int ret = dlg.exec();
00297 if (ret != QDialog::Accepted ) {
00298 mPasswordDialogIsActive = false;
00299 mAskAgain = false;
00300 emit connectionResult( KIO::ERR_USER_CANCELED, QString::null );
00301 return Error;
00302 }
00303 mPasswordDialogIsActive = false;
00304
00305
00306 setPasswd( dlg.password(), dlg.keepPassword() );
00307 setLogin( dlg.username() );
00308 mAskAgain = false;
00309 }
00310
00311 if ( mSlave && !mSlaveConnected ) return Connecting;
00312
00313 mSlaveConnected = false;
00314 mSlave = KIO::Scheduler::getConnectedSlave( getUrl(), slaveConfig() );
00315 if ( !mSlave ) {
00316 KMessageBox::error(0, i18n("Could not start process for %1.")
00317 .arg( getUrl().protocol() ) );
00318 return Error;
00319 }
00320 if ( mSlave->isConnected() ) {
00321 slotSchedulerSlaveConnected( mSlave );
00322 return Connected;
00323 }
00324
00325 return Connecting;
00326 }
00327
00328 bool ImapAccountBase::handleJobError( KIO::Job *job, const QString& context, bool abortSync )
00329 {
00330 JobIterator it = findJob( job );
00331 if ( it != jobsEnd() && (*it).progressItem )
00332 {
00333 (*it).progressItem->setComplete();
00334 (*it).progressItem = 0;
00335 }
00336 return handleError( job->error(), job->errorText(), job, context, abortSync );
00337 }
00338
00339
00340 void ImapAccountBase::postProcessNewMail( bool showStatusMsg ) {
00341 setCheckingMail(false);
00342 int newMails = 0;
00343 if ( mCountUnread > 0 && mCountUnread > mCountLastUnread ) {
00344 newMails = mCountUnread - mCountLastUnread;
00345 mCountLastUnread = mCountUnread;
00346 mCountUnread = 0;
00347 checkDone( true, CheckOK );
00348 } else {
00349 mCountUnread = 0;
00350 checkDone( false, CheckOK );
00351 }
00352 if ( showStatusMsg )
00353 BroadcastStatus::instance()->setStatusMsgTransmissionCompleted(
00354 name(), newMails);
00355 }
00356
00357
00358 void ImapAccountBase::changeSubscription( bool subscribe, const QString& imapPath )
00359 {
00360
00361 KURL url = getUrl();
00362 url.setPath(imapPath);
00363
00364 QByteArray packedArgs;
00365 QDataStream stream( packedArgs, IO_WriteOnly);
00366
00367 if (subscribe)
00368 stream << (int) 'u' << url;
00369 else
00370 stream << (int) 'U' << url;
00371
00372
00373 if ( makeConnection() != Connected )
00374 return;
00375 KIO::SimpleJob *job = KIO::special(url, packedArgs, FALSE);
00376 KIO::Scheduler::assignJobToSlave(mSlave, job);
00377 jobData jd( url.url(), NULL );
00378
00379 if (subscribe) jd.onlySubscribed = true;
00380 else jd.onlySubscribed = false;
00381 insertJob(job, jd);
00382
00383 connect(job, SIGNAL(result(KIO::Job *)),
00384 SLOT(slotSubscriptionResult(KIO::Job *)));
00385 }
00386
00387
00388 void ImapAccountBase::slotSubscriptionResult( KIO::Job * job )
00389 {
00390
00391 JobIterator it = findJob( job );
00392 if ( it == jobsEnd() ) return;
00393 bool onlySubscribed = (*it).onlySubscribed;
00394 QString path = static_cast<KIO::SimpleJob*>(job)->url().path();
00395 if (job->error())
00396 {
00397 handleJobError( job, i18n( "Error while trying to subscribe to %1:" ).arg( path ) + '\n' );
00398
00399 }
00400 else
00401 {
00402 emit subscriptionChanged( path, onlySubscribed );
00403 if (mSlave) removeJob(job);
00404 }
00405 }
00406
00407
00408
00409 void ImapAccountBase::getUserRights( KMFolder* parent, const QString& imapPath )
00410 {
00411
00412
00413
00414
00415 if ( imapPath == "/INBOX/" ) {
00416 if ( parent->folderType() == KMFolderTypeImap )
00417 static_cast<KMFolderImap*>( parent->storage() )->setUserRights( ACLJobs::All );
00418 else if ( parent->folderType() == KMFolderTypeCachedImap )
00419 static_cast<KMFolderCachedImap*>( parent->storage() )->setUserRights( ACLJobs::All );
00420 emit receivedUserRights( parent );
00421 return;
00422 }
00423
00424 KURL url = getUrl();
00425 url.setPath(imapPath);
00426
00427 ACLJobs::GetUserRightsJob* job = ACLJobs::getUserRights( mSlave, url );
00428
00429 jobData jd( url.url(), parent );
00430 jd.cancellable = true;
00431 insertJob(job, jd);
00432
00433 connect(job, SIGNAL(result(KIO::Job *)),
00434 SLOT(slotGetUserRightsResult(KIO::Job *)));
00435 }
00436
00437 void ImapAccountBase::slotGetUserRightsResult( KIO::Job* _job )
00438 {
00439 ACLJobs::GetUserRightsJob* job = static_cast<ACLJobs::GetUserRightsJob *>( _job );
00440 JobIterator it = findJob( job );
00441 if ( it == jobsEnd() ) return;
00442
00443 KMFolder* folder = (*it).parent;
00444 if ( job->error() ) {
00445 if ( job->error() == KIO::ERR_UNSUPPORTED_ACTION )
00446 mACLSupport = false;
00447 else
00448 kdWarning(5006) << "slotGetUserRightsResult: " << job->errorString() << endl;
00449 } else {
00450 #ifndef NDEBUG
00451
00452 #endif
00453
00454 if ( folder->folderType() == KMFolderTypeImap )
00455 static_cast<KMFolderImap*>( folder->storage() )->setUserRights( job->permissions() );
00456 else if ( folder->folderType() == KMFolderTypeCachedImap )
00457 static_cast<KMFolderCachedImap*>( folder->storage() )->setUserRights( job->permissions() );
00458 }
00459 if (mSlave) removeJob(job);
00460 emit receivedUserRights( folder );
00461 }
00462
00463
00464 void ImapAccountBase::getACL( KMFolder* parent, const QString& imapPath )
00465 {
00466 KURL url = getUrl();
00467 url.setPath(imapPath);
00468
00469 ACLJobs::GetACLJob* job = ACLJobs::getACL( mSlave, url );
00470 jobData jd( url.url(), parent );
00471 jd.cancellable = true;
00472 insertJob(job, jd);
00473
00474 connect(job, SIGNAL(result(KIO::Job *)),
00475 SLOT(slotGetACLResult(KIO::Job *)));
00476 }
00477
00478 void ImapAccountBase::slotGetACLResult( KIO::Job* _job )
00479 {
00480 ACLJobs::GetACLJob* job = static_cast<ACLJobs::GetACLJob *>( _job );
00481 JobIterator it = findJob( job );
00482 if ( it == jobsEnd() ) return;
00483
00484 KMFolder* folder = (*it).parent;
00485 emit receivedACL( folder, job, job->entries() );
00486 if (mSlave) removeJob(job);
00487 }
00488
00489
00490
00491 void ImapAccountBase::getStorageQuotaInfo( KMFolder* parent, const QString& imapPath )
00492 {
00493 if ( !mSlave ) return;
00494 KURL url = getUrl();
00495 url.setPath(imapPath);
00496
00497 QuotaJobs::GetStorageQuotaJob* job = QuotaJobs::getStorageQuota( mSlave, url );
00498 jobData jd( url.url(), parent );
00499 jd.cancellable = true;
00500 insertJob(job, jd);
00501
00502 connect(job, SIGNAL(result(KIO::Job *)),
00503 SLOT(slotGetStorageQuotaInfoResult(KIO::Job *)));
00504 }
00505
00506 void ImapAccountBase::slotGetStorageQuotaInfoResult( KIO::Job* _job )
00507 {
00508 QuotaJobs::GetStorageQuotaJob* job = static_cast<QuotaJobs::GetStorageQuotaJob *>( _job );
00509 JobIterator it = findJob( job );
00510 if ( it == jobsEnd() ) return;
00511 if ( job->error() && job->error() == KIO::ERR_UNSUPPORTED_ACTION )
00512 setHasNoQuotaSupport();
00513
00514 KMFolder* folder = (*it).parent;
00515 emit receivedStorageQuotaInfo( folder, job, job->storageQuotaInfo() );
00516 if (mSlave) removeJob(job);
00517 }
00518
00519 void ImapAccountBase::slotNoopTimeout()
00520 {
00521 if ( mSlave ) {
00522 QByteArray packedArgs;
00523 QDataStream stream( packedArgs, IO_WriteOnly );
00524
00525 stream << ( int ) 'N';
00526
00527 KIO::SimpleJob *job = KIO::special( getUrl(), packedArgs, false );
00528 KIO::Scheduler::assignJobToSlave(mSlave, job);
00529 connect( job, SIGNAL(result( KIO::Job * ) ),
00530 this, SLOT( slotSimpleResult( KIO::Job * ) ) );
00531 } else {
00532
00533
00534 mNoopTimer.stop();
00535 }
00536 }
00537
00538 void ImapAccountBase::slotIdleTimeout()
00539 {
00540 if ( mSlave ) {
00541 KIO::Scheduler::disconnectSlave(mSlave);
00542 mSlave = 0;
00543 mSlaveConnected = false;
00544
00545
00546 mIdleTimer.stop();
00547 }
00548 }
00549
00550 void ImapAccountBase::slotAbortRequested( KPIM::ProgressItem* item )
00551 {
00552 if ( item )
00553 item->setComplete();
00554 killAllJobs();
00555 }
00556
00557
00558
00559 void ImapAccountBase::slotSchedulerSlaveError(KIO::Slave *aSlave, int errorCode,
00560 const QString &errorMsg)
00561 {
00562 if (aSlave != mSlave) return;
00563 handleError( errorCode, errorMsg, 0, QString::null, true );
00564 if ( mAskAgain )
00565 if ( makeConnection() != ImapAccountBase::Error )
00566 return;
00567
00568 if ( !mSlaveConnected ) {
00569 mSlaveConnectionError = true;
00570 resetConnectionList( this );
00571 if ( mSlave )
00572 {
00573 KIO::Scheduler::disconnectSlave( slave() );
00574 mSlave = 0;
00575 }
00576 }
00577 emit connectionResult( errorCode, errorMsg );
00578 }
00579
00580
00581 void ImapAccountBase::slotSchedulerSlaveConnected(KIO::Slave *aSlave)
00582 {
00583 if (aSlave != mSlave) return;
00584 mSlaveConnected = true;
00585 mNoopTimer.start( 60000 );
00586 emit connectionResult( 0, QString::null );
00587
00588 if ( mNamespaces.isEmpty() || mNamespaceToDelimiter.isEmpty() ) {
00589 connect( this, SIGNAL( namespacesFetched( const ImapAccountBase::nsDelimMap& ) ),
00590 this, SLOT( slotSaveNamespaces( const ImapAccountBase::nsDelimMap& ) ) );
00591 getNamespaces();
00592 }
00593
00594
00595 QByteArray packedArgs;
00596 QDataStream stream( packedArgs, IO_WriteOnly);
00597 stream << (int) 'c';
00598 KIO::SimpleJob *job = KIO::special( getUrl(), packedArgs, false );
00599 KIO::Scheduler::assignJobToSlave( mSlave, job );
00600 connect( job, SIGNAL(infoMessage(KIO::Job*, const QString&)),
00601 SLOT(slotCapabilitiesResult(KIO::Job*, const QString&)) );
00602 }
00603
00604
00605 void ImapAccountBase::slotCapabilitiesResult( KIO::Job*, const QString& result )
00606 {
00607 mCapabilities = QStringList::split(' ', result.lower() );
00608 kdDebug(5006) << "capabilities:" << mCapabilities << endl;
00609 }
00610
00611
00612 void ImapAccountBase::getNamespaces()
00613 {
00614 disconnect( this, SIGNAL( connectionResult(int, const QString&) ),
00615 this, SLOT( getNamespaces() ) );
00616 if ( makeConnection() != Connected || !mSlave ) {
00617 kdDebug(5006) << "getNamespaces - wait for connection" << endl;
00618 if ( mNamespaces.isEmpty() || mNamespaceToDelimiter.isEmpty() ) {
00619
00620 } else {
00621
00622 connect( this, SIGNAL( connectionResult(int, const QString&) ),
00623 this, SLOT( getNamespaces() ) );
00624 }
00625 return;
00626 }
00627
00628 QByteArray packedArgs;
00629 QDataStream stream( packedArgs, IO_WriteOnly);
00630 stream << (int) 'n';
00631 jobData jd;
00632 jd.total = 1; jd.done = 0; jd.cancellable = true;
00633 jd.progressItem = ProgressManager::createProgressItem(
00634 ProgressManager::getUniqueID(),
00635 i18n("Retrieving Namespaces"),
00636 QString::null, true, useSSL() || useTLS() );
00637 jd.progressItem->setTotalItems( 1 );
00638 connect ( jd.progressItem,
00639 SIGNAL( progressItemCanceled( KPIM::ProgressItem* ) ),
00640 this,
00641 SLOT( slotAbortRequested( KPIM::ProgressItem* ) ) );
00642 KIO::SimpleJob *job = KIO::special( getUrl(), packedArgs, false );
00643 KIO::Scheduler::assignJobToSlave( mSlave, job );
00644 insertJob( job, jd );
00645 connect( job, SIGNAL( infoMessage(KIO::Job*, const QString&) ),
00646 SLOT( slotNamespaceResult(KIO::Job*, const QString&) ) );
00647 }
00648
00649
00650 void ImapAccountBase::slotNamespaceResult( KIO::Job* job, const QString& str )
00651 {
00652 JobIterator it = findJob( job );
00653 if ( it == jobsEnd() ) return;
00654
00655 nsDelimMap map;
00656 namespaceDelim nsDelim;
00657 QStringList ns = QStringList::split( ",", str );
00658 for ( QStringList::Iterator it = ns.begin(); it != ns.end(); ++it ) {
00659
00660 QStringList parts = QStringList::split( "=", *it, true );
00661 imapNamespace section = imapNamespace( parts[0].toInt() );
00662 if ( map.contains( section ) ) {
00663 nsDelim = map[section];
00664 } else {
00665 nsDelim.clear();
00666 }
00667
00668 nsDelim[parts[1]] = parts[2];
00669 map[section] = nsDelim;
00670 }
00671 removeJob(it);
00672
00673 kdDebug(5006) << "namespaces fetched" << endl;
00674 emit namespacesFetched( map );
00675 }
00676
00677
00678 void ImapAccountBase::slotSaveNamespaces( const ImapAccountBase::nsDelimMap& map )
00679 {
00680 kdDebug(5006) << "slotSaveNamespaces " << name() << endl;
00681
00682 mNamespaces.clear();
00683 mNamespaceToDelimiter.clear();
00684 for ( uint i = 0; i < 3; ++i ) {
00685 imapNamespace section = imapNamespace( i );
00686 namespaceDelim ns = map[ section ];
00687 namespaceDelim::ConstIterator it;
00688 QStringList list;
00689 for ( it = ns.begin(); it != ns.end(); ++it ) {
00690 list += it.key();
00691 mNamespaceToDelimiter[ it.key() ] = it.data();
00692 }
00693 if ( !list.isEmpty() ) {
00694 mNamespaces[section] = list;
00695 }
00696 }
00697
00698 if ( !mOldPrefix.isEmpty() ) {
00699 migratePrefix();
00700 }
00701 emit namespacesFetched();
00702 }
00703
00704
00705 void ImapAccountBase::migratePrefix()
00706 {
00707 if ( !mOldPrefix.isEmpty() && mOldPrefix != "/" ) {
00708
00709 if ( mOldPrefix.startsWith("/") ) {
00710 mOldPrefix = mOldPrefix.right( mOldPrefix.length()-1 );
00711 }
00712 if ( mOldPrefix.endsWith("/") ) {
00713 mOldPrefix = mOldPrefix.left( mOldPrefix.length()-1 );
00714 }
00715 QStringList list = mNamespaces[PersonalNS];
00716 bool done = false;
00717 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
00718 if ( (*it).startsWith( mOldPrefix ) ) {
00719
00720 done = true;
00721 kdDebug(5006) << "migratePrefix - no migration needed" << endl;
00722 break;
00723 }
00724 }
00725 if ( !done ) {
00726 QString msg = i18n("KMail has detected a prefix entry in the "
00727 "configuration of the account \"%1\" which is obsolete with the "
00728 "support of IMAP namespaces.").arg( name() );
00729 if ( list.contains( "" ) ) {
00730
00731 list.remove( "" );
00732 list += mOldPrefix;
00733 mNamespaces[PersonalNS] = list;
00734 if ( mNamespaceToDelimiter.contains( "" ) ) {
00735 QString delim = mNamespaceToDelimiter[""];
00736 mNamespaceToDelimiter.remove( "" );
00737 mNamespaceToDelimiter[mOldPrefix] = delim;
00738 }
00739 kdDebug(5006) << "migratePrefix - replaced empty with " << mOldPrefix << endl;
00740 msg += i18n("The configuration was automatically migrated but you should check "
00741 "your account configuration.");
00742 } else if ( list.count() == 1 ) {
00743
00744 QString old = list.first();
00745 list.clear();
00746 list += mOldPrefix;
00747 mNamespaces[PersonalNS] = list;
00748 if ( mNamespaceToDelimiter.contains( old ) ) {
00749 QString delim = mNamespaceToDelimiter[old];
00750 mNamespaceToDelimiter.remove( old );
00751 mNamespaceToDelimiter[mOldPrefix] = delim;
00752 }
00753 kdDebug(5006) << "migratePrefix - replaced single with " << mOldPrefix << endl;
00754 msg += i18n("The configuration was automatically migrated but you should check "
00755 "your account configuration.");
00756 } else {
00757 kdDebug(5006) << "migratePrefix - migration failed" << endl;
00758 msg += i18n("It was not possible to migrate your configuration automatically "
00759 "so please check your account configuration.");
00760 }
00761 KMessageBox::information( kmkernel->getKMMainWidget(), msg );
00762 }
00763 } else
00764 {
00765 kdDebug(5006) << "migratePrefix - no migration needed" << endl;
00766 }
00767 mOldPrefix = "";
00768 }
00769
00770
00771 QString ImapAccountBase::namespaceForFolder( FolderStorage* storage )
00772 {
00773 QString path;
00774 if ( storage->folderType() == KMFolderTypeImap ) {
00775 path = static_cast<KMFolderImap*>( storage )->imapPath();
00776 } else if ( storage->folderType() == KMFolderTypeCachedImap ) {
00777 path = static_cast<KMFolderCachedImap*>( storage )->imapPath();
00778 }
00779
00780 nsMap::Iterator it;
00781 for ( it = mNamespaces.begin(); it != mNamespaces.end(); ++it )
00782 {
00783 QStringList::Iterator strit;
00784 for ( strit = it.data().begin(); strit != it.data().end(); ++strit )
00785 {
00786 QString ns = *strit;
00787 if ( ns.endsWith("/") || ns.endsWith(".") ) {
00788
00789 ns = ns.left( ns.length()-1 );
00790 }
00791
00792 if ( !ns.isEmpty() && path.find( ns ) != -1 ) {
00793 return (*strit);
00794 }
00795 }
00796 }
00797 return QString::null;
00798 }
00799
00800
00801 QString ImapAccountBase::delimiterForNamespace( const QString& prefix )
00802 {
00803 kdDebug(5006) << "delimiterForNamespace " << prefix << endl;
00804
00805 if ( mNamespaceToDelimiter.contains(prefix) ) {
00806 return mNamespaceToDelimiter[prefix];
00807 }
00808
00809
00810
00811 for ( namespaceDelim::ConstIterator it = mNamespaceToDelimiter.begin();
00812 it != mNamespaceToDelimiter.end(); ++it ) {
00813
00814
00815 QString stripped = it.key().left( it.key().length() - 1 );
00816 if ( !it.key().isEmpty() &&
00817 ( prefix.contains( it.key() ) || prefix.contains( stripped ) ) ) {
00818 return it.data();
00819 }
00820 }
00821
00822
00823 if ( mNamespaceToDelimiter.contains( "" ) ) {
00824 return mNamespaceToDelimiter[""];
00825 }
00826
00827 kdDebug(5006) << "delimiterForNamespace - not found" << endl;
00828 return QString::null;
00829 }
00830
00831
00832 QString ImapAccountBase::delimiterForFolder( FolderStorage* storage )
00833 {
00834 QString prefix = namespaceForFolder( storage );
00835 QString delim = delimiterForNamespace( prefix );
00836 return delim;
00837 }
00838
00839
00840 void ImapAccountBase::slotSimpleResult(KIO::Job * job)
00841 {
00842 JobIterator it = findJob( job );
00843 bool quiet = false;
00844 if (it != mapJobData.end()) {
00845 quiet = (*it).quiet;
00846 if ( !(job->error() && !quiet) )
00847 removeJob(it);
00848 }
00849 if (job->error()) {
00850 if (!quiet)
00851 handleJobError(job, QString::null );
00852 else {
00853 if ( job->error() == KIO::ERR_CONNECTION_BROKEN && slave() ) {
00854
00855
00856 KIO::Scheduler::disconnectSlave( slave() );
00857 mSlave = 0;
00858 }
00859 if (job->error() == KIO::ERR_SLAVE_DIED)
00860 slaveDied();
00861 }
00862 }
00863 }
00864
00865
00866 bool ImapAccountBase::handlePutError( KIO::Job* job, jobData& jd, KMFolder* folder )
00867 {
00868 Q_ASSERT( !jd.msgList.isEmpty() );
00869 KMMessage* msg = jd.msgList.first();
00870
00871
00872 const QString subject = msg->subject().isEmpty() ? i18n( "<unknown>" ) : QString("\"%1\"").arg( msg->subject() );
00873 const QString from = msg->from().isEmpty() ? i18n( "<unknown>" ) : msg->from();
00874 QString myError = "<p><b>" + i18n("Error while uploading message")
00875 + "</b></p><p>"
00876 + 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 ) )
00877 + "</p><p>"
00878 + i18n("The destination folder was %1, which has the URL %2.").arg( QStyleSheet::escape( folder->label() ), QStyleSheet::escape( jd.htmlURL() ) )
00879 + "</p><p>"
00880 + i18n("The error message from the server communication is here:") + "</p>";
00881 return handleJobError( job, myError );
00882 }
00883
00884
00885 bool ImapAccountBase::handleError( int errorCode, const QString &errorMsg, KIO::Job* job, const QString& context, bool abortSync )
00886 {
00887
00888 QStringList errors;
00889 if ( job && job->error() != KIO::ERR_SLAVE_DEFINED )
00890 errors = job->detailedErrorStrings();
00891
00892 bool jobsKilled = true;
00893 switch( errorCode ) {
00894 case KIO::ERR_SLAVE_DIED: slaveDied(); killAllJobs( true ); break;
00895 case KIO::ERR_COULD_NOT_AUTHENTICATE:
00896 mAskAgain = true;
00897
00898 case KIO::ERR_CONNECTION_BROKEN:
00899 case KIO::ERR_COULD_NOT_CONNECT:
00900 case KIO::ERR_SERVER_TIMEOUT:
00901
00902 killAllJobs( true );
00903 break;
00904 case KIO::ERR_COULD_NOT_LOGIN:
00905 case KIO::ERR_USER_CANCELED:
00906 killAllJobs( false );
00907 break;
00908 default:
00909 if ( abortSync )
00910 killAllJobs( false );
00911 else
00912 jobsKilled = false;
00913 break;
00914 }
00915
00916
00917 if ( !mErrorDialogIsActive && errorCode != KIO::ERR_USER_CANCELED ) {
00918 mErrorDialogIsActive = true;
00919 QString msg = context + '\n' + KIO::buildErrorString( errorCode, errorMsg );
00920 QString caption = i18n("Error");
00921
00922 if ( jobsKilled || errorCode == KIO::ERR_COULD_NOT_LOGIN ) {
00923 if ( errorCode == KIO::ERR_SERVER_TIMEOUT || errorCode == KIO::ERR_CONNECTION_BROKEN ) {
00924 msg = i18n("The connection to the server %1 was unexpectedly closed or timed out. It will be re-established automatically if possible.").
00925 arg( name() );
00926 KMessageBox::information( kapp->activeWindow(), msg, caption, "kmailConnectionBrokenErrorDialog" );
00927
00928 if ( errorCode == KIO::ERR_CONNECTION_BROKEN )
00929 KPIM::BroadcastStatus::instance()->setStatusMsg(
00930 i18n( "The connection to account %1 was broken." ).arg( name() ) );
00931 else if ( errorCode == KIO::ERR_SERVER_TIMEOUT )
00932 KPIM::BroadcastStatus::instance()->setStatusMsg(
00933 i18n( "The connection to account %1 timed out." ).arg( name() ) );
00934 } else {
00935 if ( !errors.isEmpty() )
00936 KMessageBox::detailedError( kapp->activeWindow(), msg, errors.join("\n").prepend("<qt>"), caption );
00937 else
00938 KMessageBox::error( kapp->activeWindow(), msg, caption );
00939 }
00940 }
00941 else {
00942 if ( errors.count() >= 3 ) {
00943 msg = QString( "<qt>") + context + errors[1] + '\n' + errors[2];
00944 caption = errors[0];
00945 }
00946 int ret = KMessageBox::warningContinueCancel( kapp->activeWindow(), msg, caption );
00947 if ( ret == KMessageBox::Cancel ) {
00948 jobsKilled = true;
00949 killAllJobs( false );
00950 }
00951 }
00952 mErrorDialogIsActive = false;
00953 } else {
00954 if ( mErrorDialogIsActive )
00955 kdDebug(5006) << "suppressing error:" << errorMsg << endl;
00956 }
00957 if ( job && !jobsKilled )
00958 removeJob( job );
00959 return !jobsKilled;
00960 }
00961
00962
00963 void ImapAccountBase::cancelMailCheck()
00964 {
00965 QMap<KIO::Job*, jobData>::Iterator it = mapJobData.begin();
00966 while ( it != mapJobData.end() ) {
00967 kdDebug(5006) << "cancelMailCheck: job is cancellable: " << (*it).cancellable << endl;
00968 if ( (*it).cancellable ) {
00969 it.key()->kill();
00970 QMap<KIO::Job*, jobData>::Iterator rmit = it;
00971 ++it;
00972 mapJobData.remove( rmit );
00973
00974 mSlave = 0;
00975 } else
00976 ++it;
00977 }
00978
00979 for( QPtrListIterator<FolderJob> it( mJobList ); it.current(); ++it ) {
00980 if ( it.current()->isCancellable() ) {
00981 FolderJob* job = it.current();
00982 job->setPassiveDestructor( true );
00983 mJobList.remove( job );
00984 delete job;
00985 } else
00986 ++it;
00987 }
00988 }
00989
00990
00991
00992 QString ImapAccountBase::jobData::htmlURL() const
00993 {
00994 KURL u( url );
00995 return u.htmlURL();
00996 }
00997
00998
00999 void ImapAccountBase::processNewMailSingleFolder(KMFolder* folder)
01000 {
01001 mFoldersQueuedForChecking.append(folder);
01002 mCheckingSingleFolder = true;
01003 if ( checkingMail() )
01004 {
01005 disconnect( this, SIGNAL( finishedCheck( bool, CheckStatus ) ),
01006 this, SLOT( slotCheckQueuedFolders() ) );
01007 connect( this, SIGNAL( finishedCheck( bool, CheckStatus ) ),
01008 this, SLOT( slotCheckQueuedFolders() ) );
01009 } else {
01010 slotCheckQueuedFolders();
01011 }
01012 }
01013
01014
01015 void ImapAccountBase::slotCheckQueuedFolders()
01016 {
01017 disconnect( this, SIGNAL( finishedCheck( bool, CheckStatus ) ),
01018 this, SLOT( slotCheckQueuedFolders() ) );
01019
01020 QValueList<QGuardedPtr<KMFolder> > mSaveList = mMailCheckFolders;
01021 mMailCheckFolders = mFoldersQueuedForChecking;
01022 if ( kmkernel->acctMgr() )
01023 kmkernel->acctMgr()->singleCheckMail(this, true);
01024 mMailCheckFolders = mSaveList;
01025 mFoldersQueuedForChecking.clear();
01026 }
01027
01028
01029 bool ImapAccountBase::checkingMail( KMFolder *folder )
01030 {
01031 if (checkingMail() && mFoldersQueuedForChecking.contains(folder))
01032 return true;
01033 return false;
01034 }
01035
01036
01037 void ImapAccountBase::handleBodyStructure( QDataStream & stream, KMMessage * msg,
01038 const AttachmentStrategy *as )
01039 {
01040 mBodyPartList.clear();
01041 mCurrentMsg = msg;
01042
01043 msg->deleteBodyParts();
01044
01045 constructParts( stream, 1, 0, 0, msg->asDwMessage() );
01046 if ( mBodyPartList.count() == 1 )
01047 msg->deleteBodyParts();
01048
01049 if ( !as )
01050 {
01051 kdWarning(5006) << k_funcinfo << " - found no attachment strategy!" << endl;
01052 return;
01053 }
01054
01055
01056 BodyVisitor *visitor = BodyVisitorFactory::getVisitor( as );
01057 visitor->visit( mBodyPartList );
01058 QPtrList<KMMessagePart> parts = visitor->partsToLoad();
01059 delete visitor;
01060 QPtrListIterator<KMMessagePart> it( parts );
01061 KMMessagePart *part;
01062 int partsToLoad = 0;
01063
01064 while ( (part = it.current()) != 0 )
01065 {
01066 ++it;
01067 if ( part->loadPart() )
01068 {
01069 ++partsToLoad;
01070 }
01071 }
01072
01073
01074
01075 if ( mBodyPartList.count() == 1 && partsToLoad == 0 )
01076 partsToLoad = 1;
01077
01078 if ( (mBodyPartList.count() * 0.5) < partsToLoad )
01079 {
01080
01081
01082 kdDebug(5006) << "Falling back to normal mode" << endl;
01083 FolderJob *job = msg->parent()->createJob(
01084 msg, FolderJob::tGetMessage, 0, "TEXT" );
01085 job->start();
01086 return;
01087 }
01088 it.toFirst();
01089 while ( (part = it.current()) != 0 )
01090 {
01091 ++it;
01092 kdDebug(5006) << "ImapAccountBase::handleBodyStructure - load " << part->partSpecifier()
01093 << " (" << part->originalContentTypeStr() << ")" << endl;
01094 if ( part->loadHeaders() )
01095 {
01096 kdDebug(5006) << "load HEADER" << endl;
01097 FolderJob *job = msg->parent()->createJob(
01098 msg, FolderJob::tGetMessage, 0, part->partSpecifier()+".MIME" );
01099 job->start();
01100 }
01101 if ( part->loadPart() )
01102 {
01103 kdDebug(5006) << "load Part" << endl;
01104 FolderJob *job = msg->parent()->createJob(
01105 msg, FolderJob::tGetMessage, 0, part->partSpecifier() );
01106 job->start();
01107 }
01108 }
01109 }
01110
01111
01112 void ImapAccountBase::constructParts( QDataStream & stream, int count, KMMessagePart* parentKMPart,
01113 DwBodyPart * parent, const DwMessage * dwmsg )
01114 {
01115 int children;
01116 for (int i = 0; i < count; i++)
01117 {
01118 stream >> children;
01119 KMMessagePart* part = new KMMessagePart( stream );
01120 part->setParent( parentKMPart );
01121 mBodyPartList.append( part );
01122 kdDebug(5006) << "ImapAccountBase::constructParts - created id " << part->partSpecifier()
01123 << " of type " << part->originalContentTypeStr() << endl;
01124 DwBodyPart *dwpart = mCurrentMsg->createDWBodyPart( part );
01125
01126 if ( parent )
01127 {
01128
01129 parent->Body().AddBodyPart( dwpart );
01130 dwpart->Parse();
01131
01132
01133 } else if ( part->partSpecifier() != "0" &&
01134 !part->partSpecifier().endsWith(".HEADER") )
01135 {
01136
01137 dwmsg->Body().AddBodyPart( dwpart );
01138 dwpart->Parse();
01139
01140
01141 } else
01142 dwpart = 0;
01143
01144 if ( !parentKMPart )
01145 parentKMPart = part;
01146
01147 if (children > 0)
01148 {
01149 DwBodyPart* newparent = dwpart;
01150 const DwMessage* newmsg = dwmsg;
01151 if ( part->originalContentTypeStr() == "MESSAGE/RFC822" && dwpart &&
01152 dwpart->Body().Message() )
01153 {
01154
01155 newparent = 0;
01156 newmsg = dwpart->Body().Message();
01157 }
01158 KMMessagePart* newParentKMPart = part;
01159 if ( part->partSpecifier().endsWith(".HEADER") )
01160 newParentKMPart = parentKMPart;
01161
01162 constructParts( stream, children, newParentKMPart, newparent, newmsg );
01163 }
01164 }
01165 }
01166
01167
01168 void ImapAccountBase::setImapStatus( KMFolder* folder, const QString& path, const QCString& flags )
01169 {
01170
01171 kdDebug(5006) << "setImapStatus path=" << path << " to: " << flags << endl;
01172 KURL url = getUrl();
01173 url.setPath(path);
01174
01175 QByteArray packedArgs;
01176 QDataStream stream( packedArgs, IO_WriteOnly);
01177
01178 stream << (int) 'S' << url << flags;
01179
01180 if ( makeConnection() != Connected )
01181 return;
01182
01183 KIO::SimpleJob *job = KIO::special(url, packedArgs, FALSE);
01184 KIO::Scheduler::assignJobToSlave(slave(), job);
01185 ImapAccountBase::jobData jd( url.url(), folder );
01186 jd.path = path;
01187 insertJob(job, jd);
01188 connect(job, SIGNAL(result(KIO::Job *)),
01189 SLOT(slotSetStatusResult(KIO::Job *)));
01190 }
01191
01192 void ImapAccountBase::slotSetStatusResult(KIO::Job * job)
01193 {
01194 ImapAccountBase::JobIterator it = findJob(job);
01195 if ( it == jobsEnd() ) return;
01196 int errorCode = job->error();
01197 KMFolder * const parent = (*it).parent;
01198 const QString path = (*it).path;
01199 if (errorCode && errorCode != KIO::ERR_CANNOT_OPEN_FOR_WRITING)
01200 {
01201 bool cont = handleJobError( job, i18n( "Error while uploading status of messages to server: " ) + '\n' );
01202 emit imapStatusChanged( parent, path, cont );
01203 }
01204 else
01205 {
01206 emit imapStatusChanged( parent, path, true );
01207 removeJob(it);
01208 }
01209 }
01210
01211
01212 void ImapAccountBase::setFolder(KMFolder* folder, bool addAccount)
01213 {
01214 if (folder)
01215 {
01216 folder->setSystemLabel(name());
01217 folder->setId(id());
01218 }
01219 NetworkAccount::setFolder(folder, addAccount);
01220 }
01221
01222
01223 void ImapAccountBase::removeJob( JobIterator& it )
01224 {
01225 if( (*it).progressItem ) {
01226 (*it).progressItem->setComplete();
01227 (*it).progressItem = 0;
01228 }
01229 mapJobData.remove( it );
01230 }
01231
01232
01233 void KMail::ImapAccountBase::removeJob( KIO::Job* job )
01234 {
01235 mapJobData.remove( job );
01236 }
01237
01238
01239 KPIM::ProgressItem* ImapAccountBase::listDirProgressItem()
01240 {
01241 if ( !mListDirProgressItem )
01242 {
01243 mListDirProgressItem = ProgressManager::createProgressItem(
01244 "ListDir" + name(),
01245 QStyleSheet::escape( name() ),
01246 i18n("retrieving folders"),
01247 true,
01248 useSSL() || useTLS() );
01249 connect ( mListDirProgressItem,
01250 SIGNAL( progressItemCanceled( KPIM::ProgressItem* ) ),
01251 this,
01252 SLOT( slotAbortRequested( KPIM::ProgressItem* ) ) );
01253
01254
01255
01256 unsigned int count = folderCount();
01257 mListDirProgressItem->setTotalItems( count + (unsigned int)(count*0.05) );
01258 }
01259 return mListDirProgressItem;
01260 }
01261
01262
01263 unsigned int ImapAccountBase::folderCount() const
01264 {
01265 if ( !rootFolder() || !rootFolder()->folder() || !rootFolder()->folder()->child() )
01266 return 0;
01267 return kmkernel->imapFolderMgr()->folderCount( rootFolder()->folder()->child() );
01268 }
01269
01270
01271 QString ImapAccountBase::addPathToNamespace( const QString& prefix )
01272 {
01273 QString myPrefix = prefix;
01274 if ( !myPrefix.startsWith( "/" ) ) {
01275 myPrefix = "/" + myPrefix;
01276 }
01277 if ( !myPrefix.endsWith( "/" ) ) {
01278 myPrefix += "/";
01279 }
01280
01281 return myPrefix;
01282 }
01283
01284
01285 bool ImapAccountBase::isNamespaceFolder( QString& name )
01286 {
01287 QStringList ns = mNamespaces[OtherUsersNS];
01288 ns += mNamespaces[SharedNS];
01289 ns += mNamespaces[PersonalNS];
01290 QString nameWithDelimiter;
01291 for ( QStringList::Iterator it = ns.begin(); it != ns.end(); ++it )
01292 {
01293 nameWithDelimiter = name + delimiterForNamespace( *it );
01294 if ( *it == name || *it == nameWithDelimiter )
01295 return true;
01296 }
01297 return false;
01298 }
01299
01300
01301 ImapAccountBase::nsDelimMap ImapAccountBase::namespacesWithDelimiter()
01302 {
01303 nsDelimMap map;
01304 nsMap::ConstIterator it;
01305 for ( uint i = 0; i < 3; ++i )
01306 {
01307 imapNamespace section = imapNamespace( i );
01308 QStringList namespaces = mNamespaces[section];
01309 namespaceDelim nsDelim;
01310 QStringList::Iterator lit;
01311 for ( lit = namespaces.begin(); lit != namespaces.end(); ++lit )
01312 {
01313 nsDelim[*lit] = delimiterForNamespace( *lit );
01314 }
01315 map[section] = nsDelim;
01316 }
01317 return map;
01318 }
01319
01320
01321 QString ImapAccountBase::createImapPath( const QString& parent,
01322 const QString& folderName )
01323 {
01324 kdDebug(5006) << "createImapPath parent="<<parent<<", folderName="<<folderName<<endl;
01325 QString newName = parent;
01326
01327 if ( newName.endsWith("/") ) {
01328 newName = newName.left( newName.length() - 1 );
01329 }
01330
01331 QString delim = delimiterForNamespace( newName );
01332
01333 if ( delim.isEmpty() ) {
01334 delim = "/";
01335 }
01336 if ( !newName.isEmpty() &&
01337 !newName.endsWith( delim ) && !folderName.startsWith( delim ) ) {
01338 newName = newName + delim;
01339 }
01340 newName = newName + folderName;
01341
01342 if ( !newName.endsWith("/") ) {
01343 newName = newName + "/";
01344 }
01345
01346 return newName;
01347 }
01348
01349
01350 QString ImapAccountBase::createImapPath( FolderStorage* parent,
01351 const QString& folderName )
01352 {
01353 QString path;
01354 if ( parent->folderType() == KMFolderTypeImap ) {
01355 path = static_cast<KMFolderImap*>( parent )->imapPath();
01356 } else if ( parent->folderType() == KMFolderTypeCachedImap ) {
01357 path = static_cast<KMFolderCachedImap*>( parent )->imapPath();
01358 } else {
01359
01360 return path;
01361 }
01362
01363 return createImapPath( path, folderName );
01364 }
01365
01366
01367 bool ImapAccountBase::locallySubscribedTo( const QString& imapPath )
01368 {
01369 return mLocalSubscriptionBlackList.find( imapPath ) == mLocalSubscriptionBlackList.end();
01370 }
01371
01372 void ImapAccountBase::changeLocalSubscription( const QString& imapPath, bool subscribe )
01373 {
01374 if ( subscribe ) {
01375
01376 mLocalSubscriptionBlackList.erase( imapPath );
01377 } else {
01378
01379 mLocalSubscriptionBlackList.insert( imapPath );
01380 }
01381 }
01382
01383
01384 QStringList ImapAccountBase::locallyBlacklistedFolders() const
01385 {
01386 QStringList list;
01387 std::set<QString>::const_iterator it = mLocalSubscriptionBlackList.begin();
01388 std::set<QString>::const_iterator end = mLocalSubscriptionBlackList.end();
01389 for ( ; it != end ; ++it )
01390 list.append( *it );
01391 return list;
01392 }
01393
01394 void ImapAccountBase::localBlacklistFromStringList( const QStringList &list )
01395 {
01396 for( QStringList::ConstIterator it = list.constBegin( ); it != list.constEnd( ); ++it )
01397 mLocalSubscriptionBlackList.insert( *it );
01398 }
01399
01400 }
01401
01402 #include "imapaccountbase.moc"