kmail

kmacctimap.cpp
1 
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 
26 #include "kmacctimap.h"
27 using KMail::SieveConfig;
28 
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"
37 #include "kmfilter.h"
38 #include "kmfiltermgr.h"
39 #include "folderstorage.h"
40 #include "imapjob.h"
41 #include "actionscheduler.h"
42 using KMail::ActionScheduler;
43 using KMail::ImapJob;
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>
51 #include <kdebug.h>
52 
53 #include <tqstylesheet.h>
54 
55 #include <errno.h>
56 
57 //-----------------------------------------------------------------------------
58 KMAcctImap::KMAcctImap(AccountManager* aOwner, const TQString& aAccountName, uint id):
59  KMail::ImapAccountBase(aOwner, aAccountName, id),
60  mCountRemainChecks( 0 ),
61  mErrorTimer( 0, "mErrorTimer" )
62 {
63  mFolder = 0;
64  mScheduler = 0;
65  mNoopTimer.start( 60000 ); // // send a noop every minute
66  mOpenFolders.setAutoDelete(true);
67  connect(kmkernel->imapFolderMgr(), TQT_SIGNAL(changed()),
68  this, TQT_SLOT(slotUpdateFolderList()));
69  connect(&mErrorTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotResetConnectionError()));
70 
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 );
76 
77  for ( TQStringList::ConstIterator it = serNums.begin();
78  it != serNums.end(); ++it ) {
79  mFilterSerNums.append( (*it).toUInt() );
80  mFilterSerNumsToSave.insert( *it, (const int *)1 );
81  }
82 }
83 
84 
85 //-----------------------------------------------------------------------------
86 KMAcctImap::~KMAcctImap()
87 {
88  killAllJobs( true );
89 
90  TQString serNumUri = locateLocal( "data", "kmail/unfiltered." +
91  TQString("%1").arg(KAccount::id()) );
92  TDEConfig config( serNumUri );
93  TQStringList serNums;
94  TQDictIterator<int> it( mFilterSerNumsToSave );
95  for( ; it.current(); ++it )
96  serNums.append( it.currentKey() );
97  config.writeEntry( "unfiltered", serNums );
98 }
99 
100 
101 //-----------------------------------------------------------------------------
102 TQString KMAcctImap::type() const
103 {
104  return "imap";
105 }
106 
107 //-----------------------------------------------------------------------------
108 void KMAcctImap::pseudoAssign( const KMAccount * a ) {
109  killAllJobs( true );
110  if (mFolder)
111  {
112  mFolder->setContentState(KMFolderImap::imapNoInformation);
113  mFolder->setSubfolderState(KMFolderImap::imapNoInformation);
114  }
115  ImapAccountBase::pseudoAssign( a );
116 }
117 
118 //-----------------------------------------------------------------------------
119 void KMAcctImap::setImapFolder(KMFolderImap *aFolder)
120 {
121  mFolder = aFolder;
122  mFolder->setImapPath( "/" );
123 }
124 
125 
126 //-----------------------------------------------------------------------------
127 
128 bool KMAcctImap::handleError( int errorCode, const TQString &errorMsg, TDEIO::Job* job, const TQString& context, bool abortSync )
129 {
130  /* TODO check where to handle this one better. */
131  if ( errorCode == TDEIO::ERR_DOES_NOT_EXIST ) {
132  // folder is gone, so reload the folderlist
133  if ( mFolder )
134  mFolder->listDirectory();
135  return true;
136  }
137  return ImapAccountBase::handleError( errorCode, errorMsg, job, context, abortSync );
138 }
139 
140 
141 //-----------------------------------------------------------------------------
142 void KMAcctImap::killAllJobs( bool disconnectSlave )
143 {
144  TQMap<TDEIO::Job*, jobData>::Iterator it = mapJobData.begin();
145  for ( ; it != mapJobData.end(); ++it)
146  {
147  TQPtrList<KMMessage> msgList = (*it).msgList;
148  TQPtrList<KMMessage>::Iterator it2 = msgList.begin();
149  for ( ; it2 != msgList.end(); ++it2 ) {
150  KMMessage *msg = *it2;
151  if ( msg->transferInProgress() ) {
152  kdDebug(5006) << "KMAcctImap::killAllJobs - resetting mail" << endl;
153  msg->setTransferInProgress( false );
154  }
155  }
156  if ((*it).parent)
157  {
158  // clear folder state
159  KMFolderImap *fld = static_cast<KMFolderImap*>((*it).parent->storage());
160  fld->setCheckingValidity(false);
161  fld->quiet(false);
162  fld->setContentState(KMFolderImap::imapNoInformation);
163  fld->setSubfolderState(KMFolderImap::imapNoInformation);
164  fld->sendFolderComplete(FALSE);
165  fld->removeJobs();
166  }
167  if ( (*it).progressItem )
168  {
169  (*it).progressItem->setComplete();
170  }
171  }
172  if (mSlave && mapJobData.begin() != mapJobData.end())
173  {
174  mSlave->kill();
175  mSlave = 0;
176  }
177  // remove the jobs
178  mapJobData.clear();
179  // KMAccount::deleteFolderJobs(); doesn't work here always, it deletes jobs from
180  // its own mJobList instead of our mJobList...
181  KMAccount::deleteFolderJobs();
182  TQPtrListIterator<ImapJob> it2( mJobList );
183  while ( it2.current() ) {
184  ImapJob *job = it2.current();
185  ++it2;
186  job->kill();
187  }
188  mJobList.clear();
189  // make sure that no new-mail-check is blocked
190  if (mCountRemainChecks > 0)
191  {
192  checkDone( false, CheckOK ); // returned 0 new messages
193  mCountRemainChecks = 0;
194  }
195  if ( disconnectSlave && slave() ) {
196  TDEIO::Scheduler::disconnectSlave( slave() );
197  mSlave = 0;
198  }
199 }
200 
201 //-----------------------------------------------------------------------------
202 void KMAcctImap::ignoreJobsForMessage( KMMessage* msg )
203 {
204  if (!msg) return;
205  TQPtrListIterator<ImapJob> it( mJobList );
206  while ( it.current() )
207  {
208  ImapJob *job = it.current();
209  ++it;
210  if ( job->msgList().first() == msg )
211  {
212  job->kill();
213  }
214  }
215 }
216 
217 //-----------------------------------------------------------------------------
218 void KMAcctImap::ignoreJobsForFolder( KMFolder* folder )
219 {
220  TQPtrListIterator<ImapJob> it( mJobList );
221  while ( it.current() )
222  {
223  ImapJob *job = it.current();
224  ++it;
225  if ( !job->msgList().isEmpty() && job->msgList().first()->parent() == folder )
226  {
227  job->kill();
228  }
229  }
230 }
231 
232 //-----------------------------------------------------------------------------
233 void KMAcctImap::removeSlaveJobsForFolder( KMFolder* folder )
234 {
235  // Make sure the folder is not referenced in any tdeio slave jobs
236  TQMap<TDEIO::Job*, jobData>::Iterator it = mapJobData.begin();
237  while ( it != mapJobData.end() ) {
238  TQMap<TDEIO::Job*, jobData>::Iterator i = it;
239  it++;
240  if ( (*i).parent ) {
241  if ( (*i).parent == folder ) {
242  mapJobData.remove(i);
243  }
244  }
245  }
246 }
247 
248 //-----------------------------------------------------------------------------
249 void KMAcctImap::cancelMailCheck()
250 {
251  // Make list of folders to reset, like in killAllJobs
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());
257  }
258  }
259  // Kill jobs
260  // FIXME
261  // ImapAccountBase::cancelMailCheck();
262  killAllJobs( true );
263  // emit folderComplete, this is important for
264  // KMAccount::checkingMail() to be reset, in case we restart checking mail later.
265  for( TQValueList<KMFolderImap*>::Iterator it = folderList.begin(); it != folderList.end(); ++it ) {
266  KMFolderImap *fld = *it;
267  fld->sendFolderComplete(FALSE);
268  }
269 }
270 
271 //-----------------------------------------------------------------------------
272 void KMAcctImap::processNewMail(bool interactive)
273 {
274  kdDebug() << "processNewMail " << mCheckingSingleFolder << ",status="<<makeConnection()<<endl;
275  if (!mFolder || !mFolder->folder() || !mFolder->folder()->child() ||
276  makeConnection() == ImapAccountBase::Error)
277  {
278  mCountRemainChecks = 0;
279  mCheckingSingleFolder = false;
280  checkDone( false, CheckError );
281  return;
282  }
283  // if necessary then initialize the list of folders which should be checked
284  if( mMailCheckFolders.isEmpty() )
285  {
286  slotUpdateFolderList();
287  // if no folders should be checked then the check is finished
288  if( mMailCheckFolders.isEmpty() )
289  {
290  checkDone( false, CheckOK );
291  mCheckingSingleFolder = false;
292  return;
293  }
294  }
295  // Ok, we're really checking, get a progress item;
296  Q_ASSERT( !mMailCheckProgressItem );
297  mMailCheckProgressItem =
298  ProgressManager::createProgressItem(
299  "MailCheckAccount" + name(),
300  i18n("Checking account: %1" ).arg( TQStyleSheet::escape( name() ) ),
301  TQString(), // status
302  true, // can be canceled
303  useSSL() || useTLS() );
304 
305  mMailCheckProgressItem->setTotalItems( mMailCheckFolders.count() );
306  connect ( mMailCheckProgressItem,
307  TQT_SIGNAL( progressItemCanceled( KPIM::ProgressItem*) ),
308  this,
309  TQT_SLOT( slotMailCheckCanceled() ) );
310 
311  TQValueList<TQGuardedPtr<KMFolder> >::Iterator it;
312  // first get the current count of unread-messages
313  mCountRemainChecks = 0;
314  mCountUnread = 0;
315  mUnreadBeforeCheck.clear();
316  for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); ++it)
317  {
318  KMFolder *folder = *it;
319  if (folder && !folder->noContent())
320  {
321  mUnreadBeforeCheck[folder->idString()] = folder->countUnread();
322  }
323  }
324  bool gotError = false;
325  // then check for new mails
326  for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); ++it)
327  {
328  KMFolder *folder = *it;
329  if (folder && !folder->noContent())
330  {
331  KMFolderImap *imapFolder = static_cast<KMFolderImap*>(folder->storage());
332  if ( imapFolder->getContentState() != KMFolderImap::imapListingInProgress
333  && imapFolder->getContentState() != KMFolderImap::imapDownloadInProgress )
334  {
335  // connect the result-signals for new-mail-notification
336  mCountRemainChecks++;
337 
338  if (imapFolder->isSelected()) {
339  connect(imapFolder, TQT_SIGNAL(folderComplete(KMFolderImap*, bool)),
340  this, TQT_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"); // will be closed in the folderSelected slot
346  // first get new headers before we select the folder
347  imapFolder->setSelected( true );
348  connect( imapFolder, TQT_SIGNAL( folderComplete( KMFolderImap*, bool ) ),
349  this, TQT_SLOT( slotFolderSelected( KMFolderImap*, bool) ) );
350  imapFolder->getFolder();
351  }
352  else {
353  connect(imapFolder, TQT_SIGNAL(numUnreadMsgsChanged(KMFolder*)),
354  this, TQT_SLOT(postProcessNewMail(KMFolder*)));
355  bool ok = imapFolder->processNewMail(interactive);
356  if (!ok)
357  {
358  // there was an error so cancel
359  mCountRemainChecks--;
360  gotError = true;
361  if ( mMailCheckProgressItem ) {
362  mMailCheckProgressItem->incCompletedItems();
363  mMailCheckProgressItem->updateProgress();
364  }
365  }
366  }
367  }
368  }
369  } // end for
370  if ( gotError )
371  slotUpdateFolderList();
372  // for the case the account is down and all folders report errors
373  if ( mCountRemainChecks == 0 )
374  {
375  mCountLastUnread = 0; // => mCountUnread - mCountLastUnread == new count
376  ImapAccountBase::postProcessNewMail();
377  mUnreadBeforeCheck.clear();
378  mCheckingSingleFolder = false;
379  }
380 }
381 
382 //-----------------------------------------------------------------------------
383 void KMAcctImap::postProcessNewMail(KMFolderImap* folder, bool)
384 {
385  disconnect(folder, TQT_SIGNAL(folderComplete(KMFolderImap*, bool)),
386  this, TQT_SLOT(postProcessNewMail(KMFolderImap*, bool)));
387  postProcessNewMail(static_cast<KMFolder*>(folder->folder()));
388 }
389 
390 void KMAcctImap::postProcessNewMail( KMFolder * folder )
391 {
392  disconnect( folder->storage(), TQT_SIGNAL(numUnreadMsgsChanged(KMFolder*)),
393  this, TQT_SLOT(postProcessNewMail(KMFolder*)) );
394 
395  if ( mMailCheckProgressItem ) {
396  mMailCheckProgressItem->incCompletedItems();
397  mMailCheckProgressItem->updateProgress();
398  mMailCheckProgressItem->setStatus( folder->prettyURL() + i18n(" completed") );
399  }
400  mCountRemainChecks--;
401 
402  // count the unread messages
403  const TQString folderId = folder->idString();
404  int newInFolder = folder->countUnread();
405  if ( mUnreadBeforeCheck.find( folderId ) != mUnreadBeforeCheck.end() )
406  newInFolder -= mUnreadBeforeCheck[folderId];
407  if ( newInFolder > 0 ) {
408  addToNewInFolder( folderId, newInFolder );
409  mCountUnread += newInFolder;
410  }
411 
412  // Filter messages
413  TQValueListIterator<TQ_UINT32> filterIt = mFilterSerNums.begin();
414  TQValueList<TQ_UINT32> inTransit;
415 
416  if (ActionScheduler::isEnabled() ||
417  kmkernel->filterMgr()->atLeastOneOnlineImapFolderTarget()) {
418  KMFilterMgr::FilterSet set = KMFilterMgr::Inbound;
419  TQValueList<KMFilter*> filters = kmkernel->filterMgr()->filters();
420  if (!mScheduler) {
421  mScheduler = new KMail::ActionScheduler( set, filters );
422  mScheduler->setAccountId( id() );
423  connect( mScheduler, TQT_SIGNAL(filtered(TQ_UINT32)), this, TQT_SLOT(slotFiltered(TQ_UINT32)) );
424  } else {
425  mScheduler->setFilterList( filters );
426  }
427  }
428 
429  while (filterIt != mFilterSerNums.end()) {
430  int idx = -1;
431  KMFolder *folder = 0;
432  KMMessage *msg = 0;
433  KMMsgDict::instance()->getLocation( *filterIt, &folder, &idx );
434  // It's possible that the message has been deleted or moved into a
435  // different folder, or that the serNum is stale
436  if ( !folder ) {
437  mFilterSerNumsToSave.remove( TQString( "%1" ).arg( *filterIt ) );
438  ++filterIt;
439  continue;
440  }
441 
442  KMFolderImap *imapFolder = dynamic_cast<KMFolderImap*>(folder->storage());
443  if (!imapFolder ||
444  !imapFolder->folder()->isSystemFolder() ||
445  !(imapFolder->imapPath() == "/INBOX/") ) { // sanity checking
446  mFilterSerNumsToSave.remove( TQString( "%1" ).arg( *filterIt ) );
447  ++filterIt;
448  continue;
449  }
450 
451  if (idx != -1) {
452 
453  msg = folder->getMsg( idx );
454  if (!msg) { // sanity checking
455  mFilterSerNumsToSave.remove( TQString( "%1" ).arg( *filterIt ) );
456  ++filterIt;
457  continue;
458  }
459 
460  if (ActionScheduler::isEnabled() ||
461  kmkernel->filterMgr()->atLeastOneOnlineImapFolderTarget()) {
462  mScheduler->execFilters( msg );
463  } else {
464  if (msg->transferInProgress()) {
465  inTransit.append( *filterIt );
466  ++filterIt;
467  continue;
468  }
469  msg->setTransferInProgress(true);
470  if ( !msg->isComplete() ) {
471  FolderJob *job = folder->createJob(msg);
472  connect(job, TQT_SIGNAL(messageRetrieved(KMMessage*)),
473  TQT_SLOT(slotFilterMsg(KMMessage*)));
474  job->start();
475  } else {
476  mFilterSerNumsToSave.remove( TQString( "%1" ).arg( *filterIt ) );
477  if (slotFilterMsg(msg) == 2) break;
478  }
479  }
480  }
481  ++filterIt;
482  }
483  mFilterSerNums = inTransit;
484 
485  if (mCountRemainChecks == 0)
486  {
487  // all checks are done
488  mCountLastUnread = 0; // => mCountUnread - mCountLastUnread == new count
489  // when we check only one folder (=selected) and we have new mails
490  // then do not display a summary as the normal status message is better
491  bool showStatus = ( mCheckingSingleFolder && mCountUnread > 0 ) ? false : true;
492  ImapAccountBase::postProcessNewMail( showStatus );
493  mUnreadBeforeCheck.clear();
494  mCheckingSingleFolder = false;
495  }
496 }
497 
498 //-----------------------------------------------------------------------------
499 void KMAcctImap::slotFiltered(TQ_UINT32 serNum)
500 {
501  mFilterSerNumsToSave.remove( TQString( "%1" ).arg( serNum ) );
502 }
503 
504 //-----------------------------------------------------------------------------
505 void KMAcctImap::slotUpdateFolderList()
506 {
507  if ( !mFolder || !mFolder->folder() || !mFolder->folder()->child() )
508  {
509  kdWarning(5006) << "KMAcctImap::slotUpdateFolderList return" << endl;
510  return;
511  }
512  TQStringList strList;
513  mMailCheckFolders.clear();
514  kmkernel->imapFolderMgr()->createFolderList(&strList, &mMailCheckFolders,
515  mFolder->folder()->child(), TQString(), false);
516  // the new list
517  TQValueList<TQGuardedPtr<KMFolder> > includedFolders;
518  // check for excluded folders
519  TQValueList<TQGuardedPtr<KMFolder> >::Iterator it;
520  for (it = mMailCheckFolders.begin(); it != mMailCheckFolders.end(); ++it)
521  {
522  KMFolderImap* folder = static_cast<KMFolderImap*>(((KMFolder*)(*it))->storage());
523  if (folder->includeInMailCheck())
524  includedFolders.append(*it);
525  }
526  mMailCheckFolders = includedFolders;
527 }
528 
529 //-----------------------------------------------------------------------------
530 void KMAcctImap::listDirectory()
531 {
532  mFolder->listDirectory();
533 }
534 
535 //-----------------------------------------------------------------------------
536 void KMAcctImap::readConfig(TDEConfig& config)
537 {
538  ImapAccountBase::readConfig( config );
539 }
540 
541 //-----------------------------------------------------------------------------
542 void KMAcctImap::slotMailCheckCanceled()
543 {
544  if( mMailCheckProgressItem )
545  mMailCheckProgressItem->setComplete();
546  cancelMailCheck();
547 }
548 
549 //-----------------------------------------------------------------------------
550 FolderStorage* KMAcctImap::rootFolder() const
551 {
552  return mFolder;
553 }
554 
555 ImapAccountBase::ConnectionState KMAcctImap::makeConnection()
556 {
557  if ( mSlaveConnectionError )
558  {
559  mErrorTimer.start(100, true); // Clear error flag
560  return Error;
561  }
562  return ImapAccountBase::makeConnection();
563 }
564 
565 void KMAcctImap::slotResetConnectionError()
566 {
567  mSlaveConnectionError = false;
568  kdDebug(5006) << k_funcinfo << endl;
569 }
570 
571 void KMAcctImap::slotFolderSelected( KMFolderImap* folder, bool )
572 {
573  folder->setSelected( false );
574  disconnect( folder, TQT_SIGNAL( folderComplete( KMFolderImap*, bool ) ),
575  this, TQT_SLOT( slotFolderSelected( KMFolderImap*, bool) ) );
576  postProcessNewMail( static_cast<KMFolder*>(folder->folder()) );
577  folder->close( "acctimap" );
578 }
579 
580 void KMAcctImap::execFilters(TQ_UINT32 serNum)
581 {
582  if ( !kmkernel->filterMgr()->atLeastOneFilterAppliesTo( id() ) ) return;
583  TQValueListIterator<TQ_UINT32> findIt = mFilterSerNums.find( serNum );
584  if ( findIt != mFilterSerNums.end() )
585  return;
586  mFilterSerNums.append( serNum );
587  mFilterSerNumsToSave.insert( TQString( "%1" ).arg( serNum ), (const int *)1 );
588 }
589 
590 int KMAcctImap::slotFilterMsg( KMMessage *msg )
591 {
592  if ( !msg ) {
593  // messageRetrieved(0) is always possible
594  return -1;
595  }
596  msg->setTransferInProgress(false);
597  TQ_UINT32 serNum = msg->getMsgSerNum();
598  if ( serNum )
599  mFilterSerNumsToSave.remove( TQString( "%1" ).arg( serNum ) );
600 
601  int filterResult = kmkernel->filterMgr()->process(msg,
602  KMFilterMgr::Inbound,
603  true,
604  id() );
605  if (filterResult == 2) {
606  // something went horribly wrong (out of space?)
607  kmkernel->emergencyExit( i18n("Unable to process messages: " ) + TQString::fromLocal8Bit(strerror(errno)));
608  return 2;
609  }
610  if (msg->parent()) { // unGet this msg
611  int idx = -1;
612  KMFolder * p = 0;
613  KMMsgDict::instance()->getLocation( msg, &p, &idx );
614  assert( p == msg->parent() ); assert( idx >= 0 );
615  p->unGetMsg( idx );
616  }
617 
618  return filterResult;
619 }
620 
621 #include "kmacctimap.moc"
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)...
Definition: kmfolder.cpp:346
bool noContent() const
Returns, if the folder can&#39;t contain mails, but only subfolder.
Definition: kmfolder.cpp:301
virtual TQString prettyURL() const
URL of the node for visualization purposes.
Definition: kmfolder.cpp:593
static const KMMsgDict * instance()
Access the globally unique MessageDict.
Definition: kmmsgdict.cpp:167
int countUnread()
Number of new or unread messages in this folder.
Definition: kmfolder.cpp:450
void numUnreadMsgsChanged(KMFolder *)
Emitted when number of unread messages has changed.
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...
Definition: kmmsgdict.cpp:319
bool transferInProgress() const
Return, if the message should not be deleted.
Definition: kmmessage.cpp:238
TQString idString() const
Returns a string that can be used to identify this folder.
Definition: kmfolder.cpp:705
Mail folder.
Definition: kmfolder.h:68
bool isComplete() const
Return true if the complete message is available without referring to the backing store...
Definition: kmmessage.h:867
The FolderStorage class is the bass class for the storage related aspects of a collection of mail (a ...
Definition: folderstorage.h:79
KMMessage * getMsg(int idx)
Read message at given index.
Definition: kmfolder.cpp:321
folderdiaquotatab.h
Definition: aboutdata.cpp:40
void changed()
Emitted when the status, name, or associated accounts of this folder changed.
The account manager is responsible for creating accounts of various types via the factory method crea...
This is a Mime Message.
Definition: kmmessage.h:67
void setTransferInProgress(bool value, bool force=false)
Set that the message shall not be deleted because it is still required.
Definition: kmmessage.cpp:245
KMMsgInfo * unGetMsg(int idx)
Replace KMMessage with KMMsgInfo and delete KMMessage.
Definition: kmfolder.cpp:326