26 #include "kmacctimap.h"
27 using KMail::SieveConfig;
29 #include "kmmessage.h"
30 #include "broadcaststatus.h"
31 using KPIM::BroadcastStatus;
32 #include "kmfoldertree.h"
33 #include "kmfoldermgr.h"
34 #include "kmfolderimap.h"
35 #include "kmmainwin.h"
36 #include "kmmsgdict.h"
38 #include "kmfiltermgr.h"
39 #include "folderstorage.h"
41 #include "actionscheduler.h"
42 using KMail::ActionScheduler;
44 using KMail::ImapAccountBase;
45 #include "progressmanager.h"
46 using KPIM::ProgressItem;
47 using KPIM::ProgressManager;
48 #include <tdeio/scheduler.h>
49 #include <tdeio/slave.h>
50 #include <tdemessagebox.h>
53 #include <tqstylesheet.h>
58 KMAcctImap::KMAcctImap(
AccountManager* aOwner,
const TQString& aAccountName, uint
id):
59 KMail::ImapAccountBase(aOwner, aAccountName, id),
60 mCountRemainChecks( 0 ),
61 mErrorTimer( 0,
"mErrorTimer" )
65 mNoopTimer.start( 60000 );
66 mOpenFolders.setAutoDelete(
true);
67 connect(kmkernel->imapFolderMgr(), TQ_SIGNAL(changed()),
68 this, TQ_SLOT(slotUpdateFolderList()));
69 connect(&mErrorTimer, TQ_SIGNAL(timeout()), TQ_SLOT(slotResetConnectionError()));
71 TQString serNumUri = locateLocal(
"data",
"kmail/unfiltered." +
72 TQString(
"%1").arg(KAccount::id()) );
73 TDEConfig config( serNumUri );
74 TQStringList serNums = config.readListEntry(
"unfiltered" );
75 mFilterSerNumsToSave.setAutoDelete(
false );
77 for ( TQStringList::ConstIterator it = serNums.begin();
78 it != serNums.end(); ++it ) {
79 mFilterSerNums.append( (*it).toUInt() );
80 mFilterSerNumsToSave.insert( *it, (
const int *)1 );
86 KMAcctImap::~KMAcctImap()
90 TQString serNumUri = locateLocal(
"data",
"kmail/unfiltered." +
91 TQString(
"%1").arg(KAccount::id()) );
92 TDEConfig config( serNumUri );
94 TQDictIterator<int> it( mFilterSerNumsToSave );
95 for( ; it.current(); ++it )
96 serNums.append( it.currentKey() );
97 config.writeEntry(
"unfiltered", serNums );
102 TQString KMAcctImap::type()
const
108 void KMAcctImap::pseudoAssign(
const KMAccount * a ) {
112 mFolder->setContentState(KMFolderImap::imapNoInformation);
113 mFolder->setSubfolderState(KMFolderImap::imapNoInformation);
115 ImapAccountBase::pseudoAssign( a );
119 void KMAcctImap::setImapFolder(KMFolderImap *aFolder)
122 mFolder->setImapPath(
"/" );
128 bool KMAcctImap::handleError(
int errorCode,
const TQString &errorMsg, TDEIO::Job* job,
const TQString& context,
bool abortSync )
131 if ( errorCode == TDEIO::ERR_DOES_NOT_EXIST ) {
134 mFolder->listDirectory();
137 return ImapAccountBase::handleError( errorCode, errorMsg, job, context, abortSync );
142 void KMAcctImap::killAllJobs(
bool disconnectSlave )
144 TQMap<TDEIO::Job*, jobData>::Iterator it = mapJobData.begin();
145 for ( ; it != mapJobData.end(); ++it)
147 TQPtrList<KMMessage> msgList = (*it).msgList;
148 TQPtrList<KMMessage>::Iterator it2 = msgList.begin();
149 for ( ; it2 != msgList.end(); ++it2 ) {
152 kdDebug(5006) <<
"KMAcctImap::killAllJobs - resetting mail" << endl;
159 KMFolderImap *fld =
static_cast<KMFolderImap*
>((*it).parent->storage());
160 fld->setCheckingValidity(
false);
162 fld->setContentState(KMFolderImap::imapNoInformation);
163 fld->setSubfolderState(KMFolderImap::imapNoInformation);
164 fld->sendFolderComplete(FALSE);
167 if ( (*it).progressItem )
169 (*it).progressItem->setComplete();
172 if (mSlave && mapJobData.begin() != mapJobData.end())
181 KMAccount::deleteFolderJobs();
182 TQPtrListIterator<ImapJob> it2( mJobList );
183 while ( it2.current() ) {
184 ImapJob *job = it2.current();
190 if (mCountRemainChecks > 0)
192 checkDone(
false, CheckOK );
193 mCountRemainChecks = 0;
195 if ( disconnectSlave && slave() ) {
196 TDEIO::Scheduler::disconnectSlave( slave() );
202 void KMAcctImap::ignoreJobsForMessage(
KMMessage* msg )
205 TQPtrListIterator<ImapJob> it( mJobList );
206 while ( it.current() )
208 ImapJob *job = it.current();
210 if ( job->msgList().first() == msg )
218 void KMAcctImap::ignoreJobsForFolder(
KMFolder* folder )
220 TQPtrListIterator<ImapJob> it( mJobList );
221 while ( it.current() )
223 ImapJob *job = it.current();
225 if ( !job->msgList().isEmpty() && job->msgList().first()->parent() == folder )
233 void KMAcctImap::removeSlaveJobsForFolder(
KMFolder* folder )
236 TQMap<TDEIO::Job*, jobData>::Iterator it = mapJobData.begin();
237 while ( it != mapJobData.end() ) {
238 TQMap<TDEIO::Job*, jobData>::Iterator i = it;
241 if ( (*i).parent == folder ) {
242 mapJobData.remove(i);
249 void KMAcctImap::cancelMailCheck()
252 TQValueList<KMFolderImap*> folderList;
253 TQMap<TDEIO::Job*, jobData>::Iterator it = mapJobData.begin();
254 for (; it != mapJobData.end(); ++it) {
255 if ( (*it).cancellable && (*it).parent ) {
256 folderList << static_cast<KMFolderImap*>((*it).parent->storage());
265 for( TQValueList<KMFolderImap*>::Iterator it = folderList.begin(); it != folderList.end(); ++it ) {
266 KMFolderImap *fld = *it;
267 fld->sendFolderComplete(FALSE);
272 void KMAcctImap::processNewMail(
bool interactive)
274 kdDebug() <<
"processNewMail " << mCheckingSingleFolder <<
",status="<<makeConnection()<<endl;
275 if (!mFolder || !mFolder->folder() || !mFolder->folder()->child() ||
276 makeConnection() == ImapAccountBase::Error)
278 mCountRemainChecks = 0;
279 mCheckingSingleFolder =
false;
280 checkDone(
false, CheckError );
284 if( mMailCheckFolders.isEmpty() )
286 slotUpdateFolderList();
288 if( mMailCheckFolders.isEmpty() )
290 checkDone(
false, CheckOK );
291 mCheckingSingleFolder =
false;
296 Q_ASSERT( !mMailCheckProgressItem );
297 mMailCheckProgressItem =
298 ProgressManager::createProgressItem(
299 "MailCheckAccount" + name(),
300 i18n(
"Checking account: %1" ).arg( TQStyleSheet::escape( name() ) ),
303 useSSL() || useTLS() );
305 mMailCheckProgressItem->setTotalItems( mMailCheckFolders.count() );
306 connect ( mMailCheckProgressItem,
307 TQ_SIGNAL( progressItemCanceled( KPIM::ProgressItem*) ),
309 TQ_SLOT( slotMailCheckCanceled() ) );
311 TQValueList<TQGuardedPtr<KMFolder> >::Iterator it;
313 mCountRemainChecks = 0;
315 mUnreadBeforeCheck.clear();
316 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); ++it)
324 bool gotError =
false;
326 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); ++it)
331 KMFolderImap *imapFolder =
static_cast<KMFolderImap*
>(folder->storage());
332 if ( imapFolder->getContentState() != KMFolderImap::imapListingInProgress
333 && imapFolder->getContentState() != KMFolderImap::imapDownloadInProgress )
336 mCountRemainChecks++;
338 if (imapFolder->isSelected()) {
339 connect(imapFolder, TQ_SIGNAL(folderComplete(KMFolderImap*,
bool)),
340 this, TQ_SLOT(postProcessNewMail(KMFolderImap*,
bool)));
341 imapFolder->getFolder();
342 }
else if ( kmkernel->filterMgr()->atLeastOneIncomingFilterAppliesTo(
id() ) &&
343 imapFolder->folder()->isSystemFolder() &&
344 imapFolder->imapPath() ==
"/INBOX/" ) {
345 imapFolder->open(
"acctimap");
347 imapFolder->setSelected(
true );
348 connect( imapFolder, TQ_SIGNAL( folderComplete( KMFolderImap*,
bool ) ),
349 this, TQ_SLOT( slotFolderSelected( KMFolderImap*,
bool) ) );
350 imapFolder->getFolder();
353 connect(imapFolder, TQ_SIGNAL(numUnreadMsgsChanged(
KMFolder*)),
354 this, TQ_SLOT(postProcessNewMail(
KMFolder*)));
355 bool ok = imapFolder->processNewMail(interactive);
359 mCountRemainChecks--;
361 if ( mMailCheckProgressItem ) {
362 mMailCheckProgressItem->incCompletedItems();
363 mMailCheckProgressItem->updateProgress();
371 slotUpdateFolderList();
373 if ( mCountRemainChecks == 0 )
375 mCountLastUnread = 0;
376 ImapAccountBase::postProcessNewMail();
377 mUnreadBeforeCheck.clear();
378 mCheckingSingleFolder =
false;
383 void KMAcctImap::postProcessNewMail(KMFolderImap* folder,
bool)
385 disconnect(folder, TQ_SIGNAL(folderComplete(KMFolderImap*,
bool)),
386 this, TQ_SLOT(postProcessNewMail(KMFolderImap*,
bool)));
387 postProcessNewMail(
static_cast<KMFolder*
>(folder->folder()));
390 void KMAcctImap::postProcessNewMail(
KMFolder * folder )
392 disconnect( folder->storage(), TQ_SIGNAL(numUnreadMsgsChanged(
KMFolder*)),
393 this, TQ_SLOT(postProcessNewMail(
KMFolder*)) );
395 if ( mMailCheckProgressItem ) {
396 mMailCheckProgressItem->incCompletedItems();
397 mMailCheckProgressItem->updateProgress();
398 mMailCheckProgressItem->setStatus( folder->
prettyURL() + i18n(
" completed") );
400 mCountRemainChecks--;
403 const TQString folderId = folder->
idString();
405 if ( mUnreadBeforeCheck.find( folderId ) != mUnreadBeforeCheck.end() )
406 newInFolder -= mUnreadBeforeCheck[folderId];
407 if ( newInFolder > 0 ) {
408 addToNewInFolder( folderId, newInFolder );
409 mCountUnread += newInFolder;
413 TQValueListIterator<TQ_UINT32> filterIt = mFilterSerNums.begin();
414 TQValueList<TQ_UINT32> inTransit;
416 if (ActionScheduler::isEnabled() ||
417 kmkernel->filterMgr()->atLeastOneOnlineImapFolderTarget()) {
418 KMFilterMgr::FilterSet set = KMFilterMgr::Inbound;
419 TQValueList<KMFilter*> filters = kmkernel->filterMgr()->filters();
421 mScheduler =
new KMail::ActionScheduler( set, filters );
422 mScheduler->setAccountId(
id() );
423 connect( mScheduler, TQ_SIGNAL(filtered(TQ_UINT32)),
this, TQ_SLOT(slotFiltered(TQ_UINT32)) );
425 mScheduler->setFilterList( filters );
429 while (filterIt != mFilterSerNums.end()) {
437 mFilterSerNumsToSave.remove( TQString(
"%1" ).arg( *filterIt ) );
442 KMFolderImap *imapFolder =
dynamic_cast<KMFolderImap*
>(folder->storage());
444 !imapFolder->folder()->isSystemFolder() ||
445 !(imapFolder->imapPath() ==
"/INBOX/") ) {
446 mFilterSerNumsToSave.remove( TQString(
"%1" ).arg( *filterIt ) );
453 msg = folder->
getMsg( idx );
455 mFilterSerNumsToSave.remove( TQString(
"%1" ).arg( *filterIt ) );
460 if (ActionScheduler::isEnabled() ||
461 kmkernel->filterMgr()->atLeastOneOnlineImapFolderTarget()) {
462 mScheduler->execFilters( msg );
465 inTransit.append( *filterIt );
472 connect(job, TQ_SIGNAL(messageRetrieved(
KMMessage*)),
476 mFilterSerNumsToSave.remove( TQString(
"%1" ).arg( *filterIt ) );
477 if (slotFilterMsg(msg) == 2)
break;
483 mFilterSerNums = inTransit;
485 if (mCountRemainChecks == 0)
488 mCountLastUnread = 0;
491 bool showStatus = ( mCheckingSingleFolder && mCountUnread > 0 ) ?
false :
true;
492 ImapAccountBase::postProcessNewMail( showStatus );
493 mUnreadBeforeCheck.clear();
494 mCheckingSingleFolder =
false;
499 void KMAcctImap::slotFiltered(TQ_UINT32 serNum)
501 mFilterSerNumsToSave.remove( TQString(
"%1" ).arg( serNum ) );
505 void KMAcctImap::slotUpdateFolderList()
507 if ( !mFolder || !mFolder->folder() || !mFolder->folder()->child() )
509 kdWarning(5006) <<
"KMAcctImap::slotUpdateFolderList return" << endl;
512 TQStringList strList;
513 mMailCheckFolders.clear();
514 kmkernel->imapFolderMgr()->createFolderList(&strList, &mMailCheckFolders,
515 mFolder->folder()->child(), TQString(),
false);
517 TQValueList<TQGuardedPtr<KMFolder> > includedFolders;
519 TQValueList<TQGuardedPtr<KMFolder> >::Iterator it;
520 for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); ++it)
522 KMFolderImap* folder =
static_cast<KMFolderImap*
>(((
KMFolder*)(*it))->storage());
523 if (folder->includeInMailCheck())
524 includedFolders.append(*it);
526 mMailCheckFolders = includedFolders;
530 void KMAcctImap::listDirectory()
532 mFolder->listDirectory();
536 void KMAcctImap::readConfig(TDEConfig& config)
538 ImapAccountBase::readConfig( config );
542 void KMAcctImap::slotMailCheckCanceled()
544 if( mMailCheckProgressItem )
545 mMailCheckProgressItem->setComplete();
555 ImapAccountBase::ConnectionState KMAcctImap::makeConnection()
557 if ( mSlaveConnectionError )
559 mErrorTimer.start(100,
true);
562 return ImapAccountBase::makeConnection();
565 void KMAcctImap::slotResetConnectionError()
567 mSlaveConnectionError =
false;
568 kdDebug(5006) << k_funcinfo << endl;
571 void KMAcctImap::slotFolderSelected( KMFolderImap* folder,
bool )
573 folder->setSelected(
false );
574 disconnect( folder, TQ_SIGNAL( folderComplete( KMFolderImap*,
bool ) ),
575 this, TQ_SLOT( slotFolderSelected( KMFolderImap*,
bool) ) );
576 postProcessNewMail(
static_cast<KMFolder*
>(folder->folder()) );
577 folder->close(
"acctimap" );
580 void KMAcctImap::execFilters(TQ_UINT32 serNum)
582 if ( !kmkernel->filterMgr()->atLeastOneFilterAppliesTo(
id() ) )
return;
583 TQValueListIterator<TQ_UINT32> findIt = mFilterSerNums.find( serNum );
584 if ( findIt != mFilterSerNums.end() )
586 mFilterSerNums.append( serNum );
587 mFilterSerNumsToSave.insert( TQString(
"%1" ).arg( serNum ), (
const int *)1 );
590 int KMAcctImap::slotFilterMsg(
KMMessage *msg )
597 TQ_UINT32 serNum = msg->getMsgSerNum();
599 mFilterSerNumsToSave.remove( TQString(
"%1" ).arg( serNum ) );
601 int filterResult = kmkernel->filterMgr()->process(msg,
602 KMFilterMgr::Inbound,
605 if (filterResult == 2) {
607 kmkernel->emergencyExit( i18n(
"Unable to process messages: " ) + TQString::fromLocal8Bit(strerror(errno)));
614 assert( p == msg->parent() ); assert( idx >= 0 );
621 #include "kmacctimap.moc"
The FolderStorage class is the bass class for the storage related aspects of a collection of mail (a ...
int countUnread()
Number of new or unread messages in this folder.
TQString idString() const
Returns a string that can be used to identify this folder.
virtual TQString prettyURL() const
URL of the node for visualization purposes.
KMMsgInfo * unGetMsg(int idx)
Replace KMMessage with KMMsgInfo and delete KMMessage
FolderJob * createJob(KMMessage *msg, FolderJob::JobType jt=FolderJob::tGetMessage, KMFolder *folder=0, TQString partSpecifier=TQString(), const AttachmentStrategy *as=0) const
These methods create respective FolderJob (You should derive FolderJob for each derived KMFolder).
KMMessage * getMsg(int idx)
Read message at given index.
bool noContent() const
Returns, if the folder can't contain mails, but only subfolder.
void setTransferInProgress(bool value, bool force=false)
Set that the message shall not be deleted because it is still required.
bool transferInProgress() const
Return, if the message should not be deleted.
bool isComplete() const
Return true if the complete message is available without referring to the backing store.
void getLocation(unsigned long key, KMFolder **retFolder, int *retIndex) const
Returns the folder the message represented by the serial number key is in and the index in that folde...
static const KMMsgDict * instance()
Access the globally unique MessageDict.
The account manager is responsible for creating accounts of various types via the factory method crea...