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(), TQ_SIGNAL(changed()),
68  this, TQ_SLOT(slotUpdateFolderList()));
69  connect(&mErrorTimer, TQ_SIGNAL(timeout()), TQ_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  TQ_SIGNAL( progressItemCanceled( KPIM::ProgressItem*) ),
308  this,
309  TQ_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, 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"); // will be closed in the folderSelected slot
346  // first get new headers before we select the folder
347  imapFolder->setSelected( true );
348  connect( imapFolder, TQ_SIGNAL( folderComplete( KMFolderImap*, bool ) ),
349  this, TQ_SLOT( slotFolderSelected( KMFolderImap*, bool) ) );
350  imapFolder->getFolder();
351  }
352  else {
353  connect(imapFolder, TQ_SIGNAL(numUnreadMsgsChanged(KMFolder*)),
354  this, TQ_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, TQ_SIGNAL(folderComplete(KMFolderImap*, bool)),
386  this, TQ_SLOT(postProcessNewMail(KMFolderImap*, bool)));
387  postProcessNewMail(static_cast<KMFolder*>(folder->folder()));
388 }
389 
390 void KMAcctImap::postProcessNewMail( KMFolder * folder )
391 {
392  disconnect( folder->storage(), TQ_SIGNAL(numUnreadMsgsChanged(KMFolder*)),
393  this, TQ_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, TQ_SIGNAL(filtered(TQ_UINT32)), this, TQ_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, TQ_SIGNAL(messageRetrieved(KMMessage*)),
473  TQ_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, TQ_SIGNAL( folderComplete( KMFolderImap*, bool ) ),
575  this, TQ_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"
The FolderStorage class is the bass class for the storage related aspects of a collection of mail (a ...
Definition: folderstorage.h:80
Mail folder.
Definition: kmfolder.h:69
int countUnread()
Number of new or unread messages in this folder.
Definition: kmfolder.cpp:450
TQString idString() const
Returns a string that can be used to identify this folder.
Definition: kmfolder.cpp:705
virtual TQString prettyURL() const
URL of the node for visualization purposes.
Definition: kmfolder.cpp:593
KMMsgInfo * unGetMsg(int idx)
Replace KMMessage with KMMsgInfo and delete KMMessage
Definition: kmfolder.cpp:326
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
KMMessage * getMsg(int idx)
Read message at given index.
Definition: kmfolder.cpp:321
bool noContent() const
Returns, if the folder can't contain mails, but only subfolder.
Definition: kmfolder.cpp:301
This is a Mime Message.
Definition: kmmessage.h:68
void setTransferInProgress(bool value, bool force=false)
Set that the message shall not be deleted because it is still required.
Definition: kmmessage.cpp:243
bool transferInProgress() const
Return, if the message should not be deleted.
Definition: kmmessage.cpp:236
bool isComplete() const
Return true if the complete message is available without referring to the backing store.
Definition: kmmessage.h:867
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
static const KMMsgDict * instance()
Access the globally unique MessageDict.
Definition: kmmsgdict.cpp:167
The account manager is responsible for creating accounts of various types via the factory method crea...
folderdiaquotatab.h
Definition: aboutdata.cpp:40