kmail

kmfolder.cpp
1 /*
2  * kmail: KDE mail client
3  * Copyright (c) 1996-1998 Stefan Taferner <taferner@kde.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  */
20 #include <config.h>
21 
22 #include "kmfolder.h"
23 #include "kmfolderdir.h"
24 #include "kmfoldermbox.h"
25 #include "folderstorage.h"
26 #include "kmfoldercachedimap.h"
27 #include "kmfoldersearch.h"
28 #include "kmfolderimap.h"
29 #include "kmfoldermgr.h"
30 #include <libkpimidentities/identitymanager.h>
31 #include <libkpimidentities/identity.h>
32 #include "expirejob.h"
33 #include "compactionjob.h"
34 #include "kmfoldertree.h"
35 #include "kmailicalifaceimpl.h"
36 #include "kmaccount.h"
37 
38 #include <errno.h>
39 
40 #include <kdebug.h>
41 #include <tdelocale.h>
42 #include <tdeshortcut.h>
43 #include <tdemessagebox.h>
44 #include <tqfile.h>
45 #include <tqfileinfo.h>
46 
47 
48 KMFolder::KMFolder( KMFolderDir* aParent, const TQString& aFolderName,
49  KMFolderType aFolderType, bool withIndex, bool exportedSernums )
50  : KMFolderNode( aParent, aFolderName ), mStorage(0),
51  mChild( 0 ),
52  mIsSystemFolder( false ),
53  mHasIndex( withIndex ),
54  mExportsSernums( exportedSernums ),
55  mMoveInProgress( false ),
56  mExpireMessages( false ), mUnreadExpireAge( 28 ),
57  mReadExpireAge( 14 ), mUnreadExpireUnits( expireNever ),
58  mReadExpireUnits( expireNever ),
59  mExpireAction( ExpireDelete ),
60  mUseCustomIcons( false ), mMailingListEnabled( false ),
61  mAcctList( 0 ),
62  mIdentity( 0 ), // default identity
63  mPutRepliesInSameFolder( false ),
64  mIgnoreNewMail( false )
65 {
66  if( aFolderType == KMFolderTypeCachedImap )
67  mStorage = new KMFolderCachedImap( this, aFolderName.latin1() );
68  else if( aFolderType == KMFolderTypeImap )
69  mStorage = new KMFolderImap( this, aFolderName.latin1() );
70  else if( aFolderType == KMFolderTypeMaildir )
71  mStorage = new KMFolderMaildir( this, aFolderName.latin1() );
72  else if( aFolderType == KMFolderTypeSearch )
73  mStorage = new KMFolderSearch( this, aFolderName.latin1() );
74  else
75  mStorage = new KMFolderMbox( this, aFolderName.latin1() );
76 
77  assert( mStorage );
78 
79  TQFileInfo dirinfo;
80  dirinfo.setFile( mStorage->location() );
81  if ( !dirinfo.exists() ) {
82  int rc = mStorage->create();
83  TQString msg = i18n("<qt>Error while creating file <b>%1</b>:<br>%2</qt>").arg(aFolderName).arg(strerror(rc));
84  if ( rc ) {
85  KMessageBox::information(0, msg);
86  }
87  }
88 
89  if ( aParent ) {
90  connect( mStorage, TQ_SIGNAL( msgAdded( KMFolder*, TQ_UINT32 ) ),
91  aParent->manager(), TQ_SIGNAL( msgAdded( KMFolder*, TQ_UINT32 ) ) );
92  connect( mStorage, TQ_SIGNAL( msgRemoved( KMFolder*, TQ_UINT32 ) ),
93  parent()->manager(), TQ_SIGNAL( msgRemoved( KMFolder*, TQ_UINT32 ) ) );
94  connect( this, TQ_SIGNAL( msgChanged( KMFolder*, TQ_UINT32, int ) ),
95  parent()->manager(), TQ_SIGNAL( msgChanged( KMFolder*, TQ_UINT32, int ) ) );
96  connect( this, TQ_SIGNAL( msgHeaderChanged( KMFolder*, int ) ),
97  parent()->manager(), TQ_SIGNAL( msgHeaderChanged( KMFolder*, int ) ) );
98  connect( mStorage, TQ_SIGNAL( invalidated( KMFolder* ) ),
99  parent()->manager(), TQ_SIGNAL( folderInvalidated( KMFolder* ) ) );
100  }
101 
102  // Resend all mStorage signals
103  connect( mStorage, TQ_SIGNAL( changed() ), TQ_SIGNAL( changed() ) );
104  connect( mStorage, TQ_SIGNAL( cleared() ), TQ_SIGNAL( cleared() ) );
105  connect( mStorage, TQ_SIGNAL( expunged( KMFolder* ) ),
106  TQ_SIGNAL( expunged( KMFolder* ) ) );
107  connect( mStorage, TQ_SIGNAL( nameChanged() ), TQ_SIGNAL( nameChanged() ) );
108  connect( mStorage, TQ_SIGNAL( msgRemoved( KMFolder*, TQ_UINT32 ) ),
109  TQ_SIGNAL( msgRemoved( KMFolder*, TQ_UINT32 ) ) );
110  connect( mStorage, TQ_SIGNAL( msgRemoved( int, TQString ) ),
111  TQ_SIGNAL( msgRemoved( int, TQString ) ) );
112  connect( mStorage, TQ_SIGNAL( msgRemoved( KMFolder* ) ),
113  TQ_SIGNAL( msgRemoved( KMFolder* ) ) );
114  connect( mStorage, TQ_SIGNAL( msgAdded( int ) ), TQ_SIGNAL( msgAdded( int ) ) );
115  connect( mStorage, TQ_SIGNAL( msgAdded( KMFolder*, TQ_UINT32 ) ),
116  TQ_SIGNAL( msgAdded( KMFolder*, TQ_UINT32 ) ) );
117  connect( mStorage, TQ_SIGNAL( msgChanged( KMFolder*, TQ_UINT32 , int ) ),
118  TQ_SIGNAL( msgChanged( KMFolder*, TQ_UINT32 , int ) ) );
119  connect( mStorage, TQ_SIGNAL( msgHeaderChanged( KMFolder*, int ) ),
120  TQ_SIGNAL( msgHeaderChanged( KMFolder*, int ) ) );
121  connect( mStorage, TQ_SIGNAL( statusMsg( const TQString& ) ),
122  TQ_SIGNAL( statusMsg( const TQString& ) ) );
123  connect( mStorage, TQ_SIGNAL( numUnreadMsgsChanged( KMFolder* ) ),
124  TQ_SIGNAL( numUnreadMsgsChanged( KMFolder* ) ) );
125  connect( mStorage, TQ_SIGNAL( removed( KMFolder*, bool ) ),
126  TQ_SIGNAL( removed( KMFolder*, bool ) ) );
127  connect( mStorage, TQ_SIGNAL(noContentChanged()),
128  TQ_SIGNAL(noContentChanged()) );
129  connect( mStorage, TQ_SIGNAL(syncStateChanged()),
130  TQ_SIGNAL(syncStateChanged()) );
131 
132  connect( mStorage, TQ_SIGNAL( contentsTypeChanged( KMail::FolderContentsType ) ),
133  this, TQ_SLOT( slotContentsTypeChanged( KMail::FolderContentsType ) ) );
134 
135  connect( mStorage, TQ_SIGNAL( folderSizeChanged() ),
136  this, TQ_SLOT( slotFolderSizeChanged() ) );
137 
138  //FIXME: Centralize all the readConfig calls somehow - Zack
139  // Meanwhile, readConfig must be done before registerWithMessageDict, since
140  // that one can call writeConfig in some circumstances - David
141  mStorage->readConfig();
142 
143  // trigger from here, since it needs a fully constructed FolderStorage
144  if ( mExportsSernums )
145  mStorage->registerWithMessageDict();
146  if ( !mHasIndex )
147  mStorage->setAutoCreateIndex( false );
148 
149  if ( mId == 0 && aParent )
150  mId = aParent->manager()->createId();
151 }
152 
153 KMFolder::~KMFolder()
154 {
155  mStorage->close( "~KMFolder", true );
156  delete mAcctList;
157  if ( mHasIndex ) mStorage->deregisterFromMessageDict();
158  delete mStorage;
159 }
160 
161 void KMFolder::readConfig( TDEConfig* config )
162 {
163  if ( !config->readEntry("SystemLabel").isEmpty() )
164  mSystemLabel = config->readEntry("SystemLabel");
165  mExpireMessages = config->readBoolEntry("ExpireMessages", false);
166  mReadExpireAge = config->readNumEntry("ReadExpireAge", 3);
167  mReadExpireUnits = (ExpireUnits)config->readNumEntry("ReadExpireUnits", expireMonths);
168  mUnreadExpireAge = config->readNumEntry("UnreadExpireAge", 12);
169  mUnreadExpireUnits = (ExpireUnits)config->readNumEntry("UnreadExpireUnits", expireNever);
170  mExpireAction = config->readEntry("ExpireAction", "Delete") == "Move" ? ExpireMove : ExpireDelete;
171  mExpireToFolderId = config->readEntry("ExpireToFolder");
172 
173  mUseCustomIcons = config->readBoolEntry("UseCustomIcons", false );
174  mNormalIconPath = config->readEntry("NormalIconPath" );
175  mUnreadIconPath = config->readEntry("UnreadIconPath" );
176 
177  mMailingListEnabled = config->readBoolEntry("MailingListEnabled");
178  mMailingList.readConfig( config );
179 
180  mIdentity = config->readUnsignedNumEntry("Identity",0);
181 
182  setUserWhoField( config->readEntry("WhoField"), false );
183  uint savedId = config->readUnsignedNumEntry("Id", 0);
184  // make sure that we don't overwrite a valid id
185  if ( savedId != 0 && mId == 0 )
186  mId = savedId;
187  mPutRepliesInSameFolder = config->readBoolEntry( "PutRepliesInSameFolder", false );
188  mIgnoreNewMail = config->readBoolEntry( "IgnoreNewMail", false );
189 
190  if ( mUseCustomIcons )
191  emit iconsChanged();
192 
193  TQString shortcut( config->readEntry( "Shortcut" ) );
194  if ( !shortcut.isEmpty() ) {
195  TDEShortcut sc( shortcut );
196  setShortcut( sc );
197  }
198 }
199 
200 void KMFolder::writeConfig( TDEConfig* config ) const
201 {
202  config->writeEntry("SystemLabel", mSystemLabel);
203  config->writeEntry("ExpireMessages", mExpireMessages);
204  config->writeEntry("ReadExpireAge", mReadExpireAge);
205  config->writeEntry("ReadExpireUnits", mReadExpireUnits);
206  config->writeEntry("UnreadExpireAge", mUnreadExpireAge);
207  config->writeEntry("UnreadExpireUnits", mUnreadExpireUnits);
208  config->writeEntry("ExpireAction", mExpireAction == ExpireDelete ? "Delete" : "Move");
209  config->writeEntry("ExpireToFolder", mExpireToFolderId);
210 
211  config->writeEntry("UseCustomIcons", mUseCustomIcons);
212  config->writeEntry("NormalIconPath", mNormalIconPath);
213  config->writeEntry("UnreadIconPath", mUnreadIconPath);
214 
215  config->writeEntry("MailingListEnabled", mMailingListEnabled);
216  mMailingList.writeConfig( config );
217 
218  if ( mIdentity != 0 && ( !mStorage || !mStorage->account() || mIdentity != mStorage->account()->identityId() ) )
219  config->writeEntry("Identity", mIdentity);
220  else
221  config->deleteEntry("Identity");
222 
223  config->writeEntry("WhoField", mUserWhoField);
224  config->writeEntry("Id", mId);
225  config->writeEntry( "PutRepliesInSameFolder", mPutRepliesInSameFolder );
226  config->writeEntry( "IgnoreNewMail", mIgnoreNewMail );
227  if ( !mShortcut.isNull() )
228  config->writeEntry( "Shortcut", mShortcut.toString() );
229  else
230  config->deleteEntry( "Shortcut" );
231 }
232 
233 KMFolderType KMFolder::folderType() const
234 {
235  return mStorage ? mStorage->folderType() : KMFolderTypeUnknown;
236 }
237 
238 TQString KMFolder::fileName() const
239 {
240  return mStorage ? mStorage->fileName() : TQString();
241 }
242 
243 TQString KMFolder::location() const
244 {
245  return mStorage ? mStorage->location() : TQString();
246 }
247 
248 TQString KMFolder::indexLocation() const
249 {
250  return mStorage ? mStorage->indexLocation() : TQString();
251 }
252 
253 TQString KMFolder::subdirLocation() const
254 {
255  TQString sLocation( path() );
256 
257  if( !sLocation.isEmpty() )
258  sLocation += '/';
259  sLocation += '.' + FolderStorage::dotEscape( fileName() ) + ".directory";
260 
261  return sLocation;
262 }
263 
265 {
266  if( mChild )
267  return mChild;
268 
269  TQString childName = "." + fileName() + ".directory";
270  TQString childDir = path() + "/" + childName;
271  if (access(TQFile::encodeName(childDir), W_OK) != 0) // Not there or not writable
272  {
273  if (mkdir(TQFile::encodeName(childDir), S_IRWXU) != 0
274  && chmod(TQFile::encodeName(childDir), S_IRWXU) != 0) {
275  TQString wmsg = TQString(" '%1': %2").arg(childDir).arg(strerror(errno));
276  KMessageBox::information(0,i18n("Failed to create folder") + wmsg);
277  return 0;
278  }
279  }
280 
281  KMFolderDirType newType = KMStandardDir;
282  if( folderType() == KMFolderTypeCachedImap )
283  newType = KMDImapDir;
284  else if( folderType() == KMFolderTypeImap )
285  newType = KMImapDir;
286 
287  mChild = new KMFolderDir( this, parent(), childName, newType );
288  if( !mChild )
289  return 0;
290  mChild->reload();
291  parent()->append( mChild );
292  return mChild;
293 }
294 
296 {
297  mChild = aChild;
298  mStorage->updateChildrenState();
299 }
300 
302 {
303  return mStorage ? mStorage->noContent() : true;
304 }
305 
306 void KMFolder::setNoContent( bool aNoContent )
307 {
308  mStorage->setNoContent( aNoContent );
309 }
310 
312 {
313  return mStorage->noChildren();
314 }
315 
316 void KMFolder::setNoChildren( bool aNoChildren )
317 {
318  mStorage->setNoChildren( aNoChildren );
319 }
320 
322 {
323  return mStorage->getMsg( idx );
324 }
325 
326 KMMsgInfo* KMFolder::unGetMsg( int idx )
327 {
328  return mStorage->unGetMsg( idx );
329 }
330 
331 bool KMFolder::isMessage( int idx )
332 {
333  return mStorage->isMessage( idx );
334 }
335 
336 DwString KMFolder::getDwString( int idx )
337 {
338  return mStorage->getDwString( idx );
339 }
340 
342 {
343  mStorage->ignoreJobsForMessage( m );
344 }
345 
346 FolderJob* KMFolder::createJob( KMMessage *msg, FolderJob::JobType jt,
347  KMFolder *folder, TQString partSpecifier,
348  const AttachmentStrategy *as ) const
349 {
350  return mStorage->createJob( msg, jt, folder, partSpecifier, as );
351 }
352 
353 FolderJob* KMFolder::createJob( TQPtrList<KMMessage>& msgList,
354  const TQString& sets,
355  FolderJob::JobType jt, KMFolder *folder ) const
356 {
357  return mStorage->createJob( msgList, sets, jt, folder );
358 }
359 
360 const KMMsgBase* KMFolder::getMsgBase( int idx ) const
361 {
362  return mStorage->getMsgBase( idx );
363 }
364 
365 KMMsgBase* KMFolder::getMsgBase( int idx )
366 {
367  return mStorage->getMsgBase( idx );
368 }
369 
370 const KMMsgBase* KMFolder::operator[]( int idx ) const
371 {
372  return mStorage->operator[]( idx );
373 }
374 
375 KMMsgBase* KMFolder::operator[]( int idx )
376 {
377  return mStorage->operator[]( idx );
378 }
379 
381 {
382  return mStorage->take( idx );
383 }
384 
385 void KMFolder::take( TQPtrList<KMMessage> msgList ) // TODO const ref
386 {
387  mStorage->take( msgList );
388 }
389 
390 int KMFolder::addMsg( KMMessage* msg, int* index_return )
391 {
392  return mStorage->addMsg( msg, index_return );
393 }
394 
395 int KMFolder::addMsgKeepUID( KMMessage* msg, int* index_return )
396 {
397  return mStorage->addMsgKeepUID( msg, index_return );
398 }
399 
400 int KMFolder::addMsg( TQPtrList<KMMessage>& list, TQValueList<int>& index_return )
401 {
402  return mStorage->addMsg( list, index_return );
403 }
404 
406 {
407  mStorage->emitMsgAddedSignals( idx );
408 }
409 
410 void KMFolder::removeMsg( int i, bool imapQuiet )
411 {
412  mStorage->removeMsg( i, imapQuiet );
413 }
414 
415 void KMFolder::removeMsg( TQPtrList<KMMessage> msgList, bool imapQuiet ) // TODO const ref
416 {
417  mStorage->removeMsg( msgList, imapQuiet );
418 }
419 
420 int KMFolder::expungeOldMsg( int days )
421 {
422  return mStorage->expungeOldMsg( days );
423 }
424 
425 int KMFolder::moveMsg( KMMessage* msg, int* index_return )
426 {
427  return mStorage->moveMsg( msg, index_return );
428 }
429 
430 int KMFolder::moveMsg(TQPtrList<KMMessage> q, int* index_return )
431 {
432  return mStorage->moveMsg( q, index_return );
433 }
434 
435 int KMFolder::find( const KMMsgBase* msg ) const
436 {
437  return mStorage ? mStorage->find( msg ) : -1;
438 }
439 
440 int KMFolder::find( const KMMessage* msg ) const
441 {
442  return mStorage ? mStorage->find( msg ) : -1;
443 }
444 
445 int KMFolder::count( bool cache ) const
446 {
447  return mStorage->count( cache );
448 }
449 
451 {
452  return mStorage->countUnread();
453 }
454 
456 {
457  KMFolder *folder;
458  int count = countUnread();
459  KMFolderDir *dir = child();
460  if (!dir)
461  return count;
462 
463  TQPtrListIterator<KMFolderNode> it(*dir);
464  for ( ; it.current(); ++it )
465  if (!it.current()->isDir()) {
466  folder = static_cast<KMFolder*>(it.current());
467  count += folder->countUnreadRecursive();
468  }
469 
470  return count;
471 }
472 
473 void KMFolder::msgStatusChanged( const KMMsgStatus oldStatus,
474  const KMMsgStatus newStatus, int idx )
475 {
476  mStorage->msgStatusChanged( oldStatus, newStatus, idx );
477 }
478 
479 int KMFolder::open(const char *owner)
480 {
481  return mStorage->open(owner);
482 }
483 
485 {
486  return mStorage->canAccess();
487 }
488 
489 void KMFolder::close( const char *owner, bool force )
490 {
491  // do not emit closed() in here - as this would regain too early
492  mStorage->close( owner, force );
493 }
494 
496 {
497  mStorage->sync();
498 }
499 
500 bool KMFolder::isOpened() const
501 {
502  return mStorage->isOpened();
503 }
504 
506 {
507  mStorage->markNewAsUnread();
508 }
509 
511 {
512  mStorage->markUnreadAsRead();
513 }
514 
516 {
517  /* The storage needs to be open before remove is called, otherwise
518  it will not unregister the corresponding serial numbers from
519  the message dict, since its message list is empty, and the .ids
520  file contents are not loaded. That can lead to lookups in the
521  dict returning stale pointers to the folder later. */
522  mStorage->open("kmfolder_remove");
523  mStorage->remove();
524 }
525 
527 {
528  return mStorage->expunge();
529 }
530 
531 int KMFolder::rename( const TQString& newName, KMFolderDir *aParent )
532 {
533  return mStorage->rename( newName, aParent );
534 }
535 
536 bool KMFolder::dirty() const
537 {
538  return mStorage->dirty();
539 }
540 
541 void KMFolder::setDirty( bool f )
542 {
543  mStorage->setDirty( f );
544 }
545 
547 {
548  return mStorage->needsCompacting();
549 }
550 
551 void KMFolder::setNeedsCompacting( bool f )
552 {
553  mStorage->setNeedsCompacting( f );
554 }
555 
556 void KMFolder::quiet( bool beQuiet )
557 {
558  mStorage->quiet( beQuiet );
559 }
560 
562 {
563  return mStorage->isReadOnly();
564 }
565 
566 bool KMFolder::mailCheckInProgress() const
567 {
568  return mStorage->mailCheckInProgress();
569 }
570 
572 {
573  return !mStorage->isReadOnly() && mStorage->canDeleteMessages();
574 }
575 
577 {
578  return mStorage->canDeleteMessages();
579 }
580 
581 TQString KMFolder::label() const
582 {
583  if ( !mSystemLabel.isEmpty() )
584  return mSystemLabel;
585  if ( !mLabel.isEmpty() )
586  return mLabel;
587  if ( isSystemFolder() )
588  return i18n( name().utf8() );
589  return name();
590 }
591 
592 //-----------------------------------------------------------------------------
593 TQString KMFolder::prettyURL() const
594 {
595  TQString parentUrl;
596  if ( parent() )
597  parentUrl = parent()->prettyURL();
598  if ( !parentUrl.isEmpty() )
599  return parentUrl + '/' + label();
600  else
601  return label();
602 }
603 
604 //--------------------------------------------------------------------------
605 TQString KMFolder::mailingListPostAddress() const
606 {
607  if ( mMailingList.features() & MailingList::Post ) {
608  KURL::List::const_iterator it;
609  KURL::List post = mMailingList.postURLS();
610  for( it = post.begin(); it != post.end(); ++it ) {
611  // We check for isEmpty because before 3.3 postAddress was just an
612  // email@kde.org and that leaves protocol() field in the kurl class
613  if ( (*it).protocol() == "mailto" || (*it).protocol().isEmpty() )
614  return (*it).path();
615  }
616  }
617  return TQString();
618 }
619 
621 {
622  mMailingListEnabled = enabled;
623  mStorage->writeConfig();
624 }
625 
626 void KMFolder::setMailingList( const MailingList& mlist )
627 {
628  mMailingList = mlist;
629  mStorage->writeConfig();
630 }
631 
632 void KMFolder::setIdentity( uint identity )
633 {
634  mIdentity = identity;
635  kmkernel->slotRequestConfigSync();
636 }
637 
638 uint KMFolder::identity() const
639 {
640  // if we don't have one set ourselves, check our account
641  kdDebug() << "FOO: " << mIdentity << " :: " << mStorage << endl;
642  if ( !mIdentity && mStorage )
643  if ( KMAccount *act = mStorage->account() )
644  return act->identityId();
645  return mIdentity;
646 }
647 
648 void KMFolder::setWhoField(const TQString& aWhoField )
649 {
650  mWhoField = aWhoField;
651 #if 0
652  // This isn't saved in the config anyway
653  mStorage->writeConfig();
654 #endif
655 }
656 
657 void KMFolder::setUserWhoField( const TQString& whoField, bool writeConfig )
658 {
659  if ( mUserWhoField == whoField )
660  return;
661  if ( whoField.isEmpty() )
662  {
663  // default setting
664  const KPIM::Identity & identity =
665  kmkernel->identityManager()->identityForUoidOrDefault( mIdentity );
666 
667  if ( isSystemFolder() && folderType() != KMFolderTypeImap ) {
668  // local system folders
669  if ( this == kmkernel->inboxFolder() ||
670  this == kmkernel->trashFolder() )
671  mWhoField = "From";
672  if ( this == kmkernel->outboxFolder() ||
673  this == kmkernel->sentFolder() ||
674  this == kmkernel->draftsFolder() ||
675  this == kmkernel->templatesFolder() )
676  mWhoField = "To";
677  } else if ( identity.drafts() == idString() ||
678  identity.templates() == idString() ||
679  identity.fcc() == idString() )
680  // drafts, templates or sent of the identity
681  mWhoField = "To";
682  else
683  mWhoField = "From";
684  } else if ( whoField == "From" || whoField == "To" )
685  // set the whoField according to the user-setting
686  mWhoField = whoField;
687  else {
688  // this should not happen...
689  kdDebug(5006) << "Illegal setting " << whoField << " for userWhoField!"
690  << endl;
691  return; // don't use the value
692  }
693  mUserWhoField = whoField;
694 
695  if (writeConfig)
696  mStorage->writeConfig();
697  emit viewConfigChanged();
698 }
699 
701 {
702  mStorage->correctUnreadMsgsCount();
703 }
704 
705 TQString KMFolder::idString() const
706 {
707  KMFolderNode* folderNode = parent();
708  if (!folderNode)
709  return "";
710  while ( folderNode->parent() )
711  folderNode = folderNode->parent();
712  TQString myPath = path();
713  int pathLen = myPath.length() - folderNode->path().length();
714  TQString relativePath = myPath.right( pathLen );
715  if (!relativePath.isEmpty())
716  relativePath = relativePath.right( relativePath.length() - 1 ) + "/";
717  TQString escapedName = name();
718  /* Escape [ and ] as they are disallowed for tdeconfig sections and that is
719  what the idString is primarily used for. */
720  escapedName.replace( "[", "%(" );
721  escapedName.replace( "]", "%)" );
722  return relativePath + escapedName;
723 }
724 
725 void KMFolder::setAutoExpire( bool enabled )
726 {
727  if( enabled != mExpireMessages ) {
728  mExpireMessages = enabled;
729  mStorage->writeConfig();
730  }
731 }
732 
734 {
735  if( age >= 0 && age != mUnreadExpireAge ) {
736  mUnreadExpireAge = age;
737  mStorage->writeConfig();
738  }
739 }
740 
741 void KMFolder::setUnreadExpireUnits( ExpireUnits units )
742 {
743  if (units >= expireNever && units < expireMaxUnits)
744  mUnreadExpireUnits = units;
745  mStorage->writeConfig();
746 }
747 
749 {
750  if( age >= 0 && age != mReadExpireAge ) {
751  mReadExpireAge = age;
752  mStorage->writeConfig();
753  }
754 }
755 
756 void KMFolder::setReadExpireUnits( ExpireUnits units )
757 {
758  if (units >= expireNever && units <= expireMaxUnits)
759  mReadExpireUnits = units;
760  mStorage->writeConfig();
761 }
762 
763 
764 void KMFolder::setExpireAction( ExpireAction a )
765 {
766  if ( a != mExpireAction ) {
767  mExpireAction = a;
768  mStorage->writeConfig();
769  }
770 }
771 
772 void KMFolder::setExpireToFolderId( const TQString& id )
773 {
774  if ( id != mExpireToFolderId ) {
775  mExpireToFolderId = id;
776  mStorage->writeConfig();
777  }
778 }
779 
780 
781 static int daysToExpire( int number, ExpireUnits units )
782 {
783  switch (units) {
784  case expireDays: // Days
785  return number;
786  case expireWeeks: // Weeks
787  return number * 7;
788  case expireMonths: // Months - this could be better rather than assuming 31day months.
789  return number * 31;
790  default: // this avoids a compiler warning (not handled enumeration values)
791  ;
792  }
793  return -1;
794 }
795 
796 void KMFolder::daysToExpire(int& unreadDays, int& readDays) {
797  unreadDays = ::daysToExpire( getUnreadExpireAge(), getUnreadExpireUnits() );
798  readDays = ::daysToExpire( getReadExpireAge(), getReadExpireUnits() );
799 }
800 
801 void KMFolder::expireOldMessages( bool immediate )
802 {
803  KMail::ScheduledExpireTask* task = new KMail::ScheduledExpireTask(this, immediate);
804  kmkernel->jobScheduler()->registerTask( task );
805  if ( immediate ) {
806  // #82259: compact after expiring.
807  compact( CompactLater );
808  }
809 }
810 
811 void KMFolder::compact( CompactOptions options )
812 {
813  if ( options == CompactLater ) {
815  kmkernel->jobScheduler()->registerTask( task );
816  } else {
817  mStorage->compact( options == CompactSilentlyNow );
818  }
819 }
820 
822 {
823  return mStorage ? mStorage->trashFolder() : 0;
824 }
825 
826 int KMFolder::writeIndex( bool createEmptyIndex )
827 {
828  return mStorage->writeIndex( createEmptyIndex );
829 }
830 
831 void KMFolder::setStatus( int idx, KMMsgStatus status, bool toggle )
832 {
833  mStorage->setStatus( idx, status, toggle );
834 }
835 
836 void KMFolder::setStatus( TQValueList<int>& ids, KMMsgStatus status,
837  bool toggle )
838 {
839  mStorage->setStatus( ids, status, toggle);
840 }
841 
842 void KMFolder::setIconPaths( const TQString &normalPath,
843  const TQString &unreadPath )
844 {
845  mNormalIconPath = normalPath;
846  mUnreadIconPath = unreadPath;
847  mStorage->writeConfig();
848  emit iconsChanged();
849 }
850 
851 void KMFolder::removeJobs()
852 {
853  mStorage->removeJobs();
854 }
855 
857 {
858  return mStorage->updateIndex();
859 }
860 
862 {
863  mStorage->reallyAddMsg( aMsg );
864 }
865 
867 {
868  mStorage->reallyAddCopyOfMsg( aMsg );
869 }
870 
871 void KMFolder::setShortcut( const TDEShortcut &sc )
872 {
873  if ( mShortcut != sc ) {
874  mShortcut = sc;
875  emit shortcutChanged( this );
876  }
877 }
878 
880 {
881  return !isSystemFolder();
882 }
883 
884 void KMFolder::slotContentsTypeChanged( KMail::FolderContentsType type )
885 {
886  kmkernel->iCalIface().folderContentsTypeChanged( this, type );
887  emit iconsChanged();
888 }
889 
890 void KMFolder::slotFolderSizeChanged()
891 {
892  emit folderSizeChanged( this );
893  KMFolder* papa = parent()->manager()->parentFolder( this );
894  if ( papa && papa != this ) {
895  papa->slotFolderSizeChanged();
896  }
897 }
898 
899 bool KMFolder::isValidName( const TQString &folderName, TQString &message )
900 {
901  KMFolderType fldType = folderType();
902 
903  // names of local folders must not contain a '/'
904  if ( folderName.find( '/' ) != -1 &&
905  fldType != KMFolderTypeImap &&
906  fldType != KMFolderTypeCachedImap ) {
907  message = i18n( "Folder names cannot contain the / (slash) character; please choose another folder name." );
908  return false;
909  }
910 
911  // folder names must not start with a '.'
912  if ( folderName.startsWith( "." ) ) {
913  message = i18n( "Folder names cannot start with a . (dot) character; please choose another folder name." );
914  return false;
915  }
916 
917  // names of IMAP folders must not contain the folder delimiter
918  if ( fldType == KMFolderTypeImap || fldType == KMFolderTypeCachedImap ) {
919  TQString delimiter;
920  if ( fldType == KMFolderTypeImap ) {
921  KMAcctImap *ai = static_cast<KMFolderImap*>( mStorage )->account();
922  if ( ai ) {
923  delimiter = ai->delimiterForFolder( mStorage );
924  }
925  } else {
926  KMAcctCachedImap *ai = static_cast<KMFolderCachedImap*>( mStorage )->account();
927  if ( ai ) {
928  delimiter = ai->delimiterForFolder( mStorage );
929  }
930  }
931  if ( !delimiter.isEmpty() && folderName.find( delimiter ) != -1 ) {
932  message = i18n( "Your IMAP server does not allow the character '%1'; please choose another folder name." ).arg( delimiter );
933  return false;
934  }
935  }
936  return true;
937 }
938 
939 #include "kmfolder.moc"
virtual bool isMessage(int idx)
Checks if the message is already "gotten" with getMsg.
virtual int countUnread()
Number of new or unread messages in this folder.
virtual int create()=0
Create a new folder with the name of this object and open it.
virtual void ignoreJobsForMessage(KMMessage *)
Removes and deletes all jobs associated with the particular message.
virtual DwString getDwString(int idx)=0
Read a message and returns a DwString.
virtual void markNewAsUnread()
Mark all new messages as unread.
virtual int open(const char *owner)=0
Open folder for access.
virtual TQString indexLocation() const =0
Returns full path to index file.
virtual KMMessage * take(int idx)
Detach message from this folder.
virtual int count(bool cache=false) const
Number of messages in this folder.
virtual bool noChildren() const
Returns, if the folder can't have children.
void emitMsgAddedSignals(int idx)
Called by derived classes implementation of addMsg.
virtual int updateIndex()=0
Incrementally update the index if possible else call writeIndex.
virtual int expungeOldMsg(int days)
Delete messages in the folder that are older than days.
virtual int rename(const TQString &newName, KMFolderDir *aParent=0)
Physically rename the folder.
bool isOpened() const
Test if folder is opened, i.e.
virtual void msgStatusChanged(const KMMsgStatus oldStatus, const KMMsgStatus newStatus, int idx)
Called by KMMsgBase::setStatus when status of a message has changed required to keep the number unrea...
void registerWithMessageDict()
Triggers registration with the message dict, which will cause the dict to ask the FolderStorage to fi...
virtual TQString fileName() const
Returns the filename of the folder (reimplemented in KMFolderImap)
virtual int find(const KMMsgBase *msg) const =0
Returns the index of the given message or -1 if not found.
virtual void reallyAddMsg(KMMessage *aMsg)
Add the message to the folder after it has been retrieved from an IMAP server.
bool needsCompacting() const
Returns TRUE if the folder contains deleted messages.
virtual 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).
virtual void readConfig()
Read the config file.
virtual int addMsgKeepUID(KMMessage *msg, int *index_return=0)
(Note(bo): This needs to be fixed better at a later point.) This is overridden by dIMAP because addMs...
static TQString dotEscape(const TQString &)
Escape a leading dot.
virtual void markUnreadAsRead()
Mark all new and unread messages as read.
virtual void setStatus(int idx, KMMsgStatus status, bool toggle=false)
Set the status of the message at index idx to status.
virtual int expunge()
Delete entire folder.
virtual KMFolder * trashFolder() const
If this folder has a special trash folder set, return it.
virtual void correctUnreadMsgsCount()
A cludge to help make sure the count of unread messges is kept in sync.
virtual void reallyAddCopyOfMsg(KMMessage *aMsg)
Add a copy of the message to the folder after it has been retrieved from an IMAP server.
virtual KMFolderType folderType() const
Returns the type of this folder.
Definition: folderstorage.h:96
virtual void updateChildrenState()
Updates the hasChildren() state.
virtual void removeMsg(int i, bool imapQuiet=false)
Remove (first occurrence of) given message from the folder.
void setDirty(bool f)
Change the dirty flag.
virtual void remove()
Removes the folder physically from disk and empties the contents of the folder in memory.
virtual bool canDeleteMessages() const
Can messages in this folder be deleted?
void close(const char *owner, bool force=false)
Close folder.
virtual KMMsgInfo * unGetMsg(int idx)
Replace KMMessage with KMMsgInfo and delete KMMessage
virtual void writeConfig()
Write the config file.
virtual int moveMsg(KMMessage *msg, int *index_return=0)
Detaches the given message from it's current folder and adds it to this folder.
virtual void sync()=0
fsync buffers to disk
virtual int addMsg(KMMessage *msg, int *index_return=0)=0
Add the given message to the folder.
bool dirty() const
Returns TRUE if the table of contents is dirty.
virtual int canAccess()=0
Check folder for permissions Returns zero if readable and writable.
virtual void setAutoCreateIndex(bool)
Allow/disallow automatic creation of a table of contents file.
virtual bool noContent() const
Returns, if the folder can't contain mails, but only subfolder.
virtual void setNoChildren(bool aNoChildren)
Specify, that the folder can't have children.
TQString location() const
Returns full path to folder file.
virtual bool isReadOnly() const =0
Is the folder read-only?
virtual KMMessage * getMsg(int idx)
Read message at given index.
virtual const KMMsgBase * getMsgBase(int idx) const =0
Provides access to the basic message fields that are also stored in the index.
virtual int writeIndex(bool createEmptyIndex=false)=0
Write index to index-file.
virtual int compact(bool silent)=0
Remove deleted messages from the folder.
virtual void quiet(bool beQuiet)
If set to quiet the folder will not emit msgAdded(idx) signal.
void deregisterFromMessageDict()
Triggers deregistration from the message dict, which will cause the dict to ask the FolderStorage to ...
virtual void setNoContent(bool aNoContent)
Specify, that the folder can't contain mails.
KMail list that manages the contents of one directory that may contain folders and/or other directori...
Definition: kmfolderdir.h:16
virtual bool reload()
Read contents of directory.
virtual KMFolderMgr * manager() const
Returns the folder manager that manages this folder.
Mail folder.
Definition: kmfolder.h:69
int getUnreadExpireAge() const
Get the age at which unread messages are expired.
Definition: kmfolder.h:449
bool isOpened() const
Test if folder is opened.
Definition: kmfolder.cpp:500
void sync()
fsync buffers to disk
Definition: kmfolder.cpp:495
void setNoChildren(bool aNoChildren)
Specify, that the folder can't have children.
Definition: kmfolder.cpp:316
void viewConfigChanged()
Emitted when the variables for the config of the view have changed.
int countUnread()
Number of new or unread messages in this folder.
Definition: kmfolder.cpp:450
TQString subdirLocation() const
Returns full path to sub directory file.
Definition: kmfolder.cpp:253
KMFolder * trashFolder() const
If this folder has a special trash folder set, return it.
Definition: kmfolder.cpp:821
void emitMsgAddedSignals(int idx)
Called by derived classes implementation of addMsg.
Definition: kmfolder.cpp:405
int updateIndex()
Incrementally update the index if possible else call writeIndex.
Definition: kmfolder.cpp:856
int moveMsg(KMMessage *msg, int *index_return=0)
Detaches the given message from it's current folder and adds it to this folder.
Definition: kmfolder.cpp:425
int addMsgKeepUID(KMMessage *msg, int *index_return=0)
(Note(bo): This needs to be fixed better at a later point.) This is overridden by dIMAP because addMs...
Definition: kmfolder.cpp:395
void removed(KMFolder *, bool)
Emitted when a folder was removed.
void correctUnreadMsgsCount()
A cludge to help make sure the count of unread messges is kept in sync.
Definition: kmfolder.cpp:700
void setReadExpireUnits(ExpireUnits units)
Set units to use for expiry of read messages.
Definition: kmfolder.cpp:756
KMFolder(KMFolderDir *parent, const TQString &name, KMFolderType aFolderType, bool withIndex=true, bool exportedSernums=true)
Constructs a new Folder object.
Definition: kmfolder.cpp:48
TQString idString() const
Returns a string that can be used to identify this folder.
Definition: kmfolder.cpp:705
void changed()
Emitted when the status, name, or associated accounts of this folder changed.
void msgStatusChanged(const KMMsgStatus oldStatus, const KMMsgStatus newStatus, int idx)
Called by KMMsgBase::setStatus when status of a message has changed required to keep the number unrea...
Definition: kmfolder.cpp:473
virtual TQString prettyURL() const
URL of the node for visualization purposes.
Definition: kmfolder.cpp:593
void shortcutChanged(KMFolder *)
Emitted when the shortcut associated with this folder changes.
void reallyAddCopyOfMsg(KMMessage *aMsg)
Add a copy of the message to the folder after it has been retrieved from an IMAP server.
Definition: kmfolder.cpp:866
int writeIndex(bool createEmptyIndex=false)
Write index to index-file.
Definition: kmfolder.cpp:826
void ignoreJobsForMessage(KMMessage *)
Removes and deletes all jobs associated with the particular message.
Definition: kmfolder.cpp:341
virtual TQString label() const
Returns the label of the folder for visualization.
Definition: kmfolder.cpp:581
void cleared()
Emitted when the contents of a folder have been cleared (new search in a search folder,...
KMFolderDir * child() const
Returns the folder directory associated with this node or 0 if no such directory exists.
Definition: kmfolder.h:157
bool noChildren() const
Returns, if the folder can't have children.
Definition: kmfolder.cpp:311
void numUnreadMsgsChanged(KMFolder *)
Emitted when number of unread messages has changed.
ExpireUnits getReadExpireUnits() const
Units getReadExpireAge() is returned in.
Definition: kmfolder.h:467
void expunged(KMFolder *)
Emitted after an expunge.
void noContentChanged()
Emitted when the no content state changed.
void markNewAsUnread()
Mark all new messages as unread.
Definition: kmfolder.cpp:505
bool isValidName(const TQString &folderName, TQString &message)
Returns true if the name is valid for a child of this folder.
Definition: kmfolder.cpp:899
TQString fileName() const
Returns the filename of the folder (reimplemented in KMFolderImap)
Definition: kmfolder.cpp:238
void msgRemoved(KMFolder *, TQ_UINT32 sernum)
Emitted before a message is removed from the folder.
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
int canAccess()
Check folder for permissions Returns zero if readable and writable.
Definition: kmfolder.cpp:484
int addMsg(KMMessage *msg, int *index_return=0)
Add the given message to the folder.
Definition: kmfolder.cpp:390
bool canDeleteMessages() const
Can messages in this folder be deleted?
Definition: kmfolder.cpp:576
TQString whoField() const
Get / set the name of the field that is used for the Sender/Receiver column in the headers (From/To)
Definition: kmfolder.h:396
void msgAdded(int idx)
Emitted when a message is added from the folder.
int getReadExpireAge() const
Get the age at which read messages are expired.
Definition: kmfolder.h:455
bool isMessage(int idx)
Checks if the message is already "gotten" with getMsg.
Definition: kmfolder.cpp:331
void markUnreadAsRead()
Mark all new and unread messages as read.
Definition: kmfolder.cpp:510
void msgHeaderChanged(KMFolder *, int)
Emitted when a field of the header of a specific message changed.
DwString getDwString(int idx)
Read a message and returns a DwString.
Definition: kmfolder.cpp:336
bool needsCompacting() const
Returns true if the folder contains deleted messages.
Definition: kmfolder.cpp:546
void setUnreadExpireAge(int age)
Set the maximum age for unread messages in this folder.
Definition: kmfolder.cpp:733
KMMessage * take(int idx)
Detach message from this folder.
Definition: kmfolder.cpp:380
int expunge()
Delete entire folder.
Definition: kmfolder.cpp:526
int expungeOldMsg(int days)
Delete messages in the folder that are older than days.
Definition: kmfolder.cpp:420
bool isSystemFolder() const
Returns true if the folder is a kmail system folder.
Definition: kmfolder.h:369
void close(const char *owner, bool force=false)
Close folder.
Definition: kmfolder.cpp:489
void setDirty(bool f)
Change the dirty flag.
Definition: kmfolder.cpp:541
void setAutoExpire(bool enabled)
Set whether this folder automatically expires messages.
Definition: kmfolder.cpp:725
int rename(const TQString &newName, KMFolderDir *aParent=0)
Physically rename the folder.
Definition: kmfolder.cpp:531
KMFolderDir * createChildFolder()
Create a child folder directory and associates it with this folder.
Definition: kmfolder.cpp:264
void readConfig(TDEConfig *config)
This is used by the storage to read the folder specific configuration.
Definition: kmfolder.cpp:161
void expireOldMessages(bool immediate)
Expire old messages in this folder.
Definition: kmfolder.cpp:801
void setNoContent(bool aNoContent)
Specify, that the folder can't contain mails.
Definition: kmfolder.cpp:306
void nameChanged()
Emitted when the name of the folder changes.
KMMessage * getMsg(int idx)
Read message at given index.
Definition: kmfolder.cpp:321
const KMMsgBase * getMsgBase(int idx) const
Provides access to the basic message fields that are also stored in the index.
Definition: kmfolder.cpp:360
KMFolderType folderType() const
Returns the type of this folder.
Definition: kmfolder.cpp:233
bool isMoveable() const
Returns true if this folder can be moved.
Definition: kmfolder.cpp:879
void folderSizeChanged(KMFolder *)
Emitted when the folder's size changes.
void setStatus(int idx, KMMsgStatus status, bool toggle=false)
Set the status of the message at index idx to status.
Definition: kmfolder.cpp:831
void setMailingListEnabled(bool enabled)
Returns true if this folder is associated with a mailing-list.
Definition: kmfolder.cpp:620
int count(bool cache=false) const
Number of messages in this folder.
Definition: kmfolder.cpp:445
const KMMsgBase * operator[](int idx) const
Same as getMsgBase(int).
Definition: kmfolder.cpp:370
TQString indexLocation() const
Returns full path to index file.
Definition: kmfolder.cpp:248
int open(const char *owner)
Open folder for access.
Definition: kmfolder.cpp:479
int countUnreadRecursive()
Number of new or unread messages in this folder and all folders contained by this folder.
Definition: kmfolder.cpp:455
bool isWritable() const
Can we write into and delete from this folder (on IMAP that's not necessarily !isReadOnly())
Definition: kmfolder.cpp:571
void remove()
Removes the folder physically from disk and empties the contents of the folder in memory.
Definition: kmfolder.cpp:515
void compact(CompactOptions options)
Compact this folder.
Definition: kmfolder.cpp:811
TQString location() const
Returns full path to folder file.
Definition: kmfolder.cpp:243
bool noContent() const
Returns, if the folder can't contain mails, but only subfolder.
Definition: kmfolder.cpp:301
void statusMsg(const TQString &)
Emmited to display a message somewhere in a status line.
void setUnreadExpireUnits(ExpireUnits units)
Set units to use for expiry of unread messages.
Definition: kmfolder.cpp:741
void setReadExpireAge(int age)
Set the maximum age for read messages in this folder.
Definition: kmfolder.cpp:748
void writeConfig(TDEConfig *config) const
This is used by the storage to save the folder specific configuration.
Definition: kmfolder.cpp:200
void removeMsg(int i, bool imapQuiet=false)
Remove (first occurrence of) given message from the folder.
Definition: kmfolder.cpp:410
void quiet(bool beQuiet)
If set to quiet the folder will not emit msgAdded(idx) signal.
Definition: kmfolder.cpp:556
ExpireUnits getUnreadExpireUnits() const
Units getUnreadExpireAge() is returned in.
Definition: kmfolder.h:461
bool dirty() const
Returns true if the table of contents is dirty.
Definition: kmfolder.cpp:536
int find(const KMMsgBase *msg) const
Returns the index of the given message or -1 if not found.
Definition: kmfolder.cpp:435
void setChild(KMFolderDir *aChild)
Set the folder directory associated with this node.
Definition: kmfolder.cpp:295
void reallyAddMsg(KMMessage *aMsg)
Add the message to the folder after it has been retrieved from an IMAP server.
Definition: kmfolder.cpp:861
bool isReadOnly() const
Is the folder read-only?
Definition: kmfolder.cpp:561
void msgChanged(KMFolder *, TQ_UINT32 sernum, int delta)
Emitted, when the status of a message is changed.
void syncStateChanged()
Emiitted when the sync state, i.e.
void iconsChanged()
Emitted when the icon paths are set.
This is a Mime Message.
Definition: kmmessage.h:68
Class is used for all Mailing List handling inside KMail.
A scheduled "compact mails in this folder" task.
A scheduled "expire mails in this folder" task.
Definition: expirejob.h:66