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