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
48KMFolder::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
153KMFolder::~KMFolder()
154{
155 mStorage->close( "~KMFolder", true );
156 delete mAcctList;
157 if ( mHasIndex ) mStorage->deregisterFromMessageDict();
158 delete mStorage;
159}
160
161void 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
200void 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
233KMFolderType KMFolder::folderType() const
234{
235 return mStorage ? mStorage->folderType() : KMFolderTypeUnknown;
236}
237
238TQString KMFolder::fileName() const
239{
240 return mStorage ? mStorage->fileName() : TQString();
241}
242
243TQString KMFolder::location() const
244{
245 return mStorage ? mStorage->location() : TQString();
246}
247
249{
250 return mStorage ? mStorage->indexLocation() : TQString();
251}
252
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
306void KMFolder::setNoContent( bool aNoContent )
307{
308 mStorage->setNoContent( aNoContent );
309}
310
312{
313 return mStorage->noChildren();
314}
315
316void KMFolder::setNoChildren( bool aNoChildren )
317{
318 mStorage->setNoChildren( aNoChildren );
319}
320
322{
323 return mStorage->getMsg( idx );
324}
325
326KMMsgInfo* KMFolder::unGetMsg( int idx )
327{
328 return mStorage->unGetMsg( idx );
329}
330
331bool KMFolder::isMessage( int idx )
332{
333 return mStorage->isMessage( idx );
334}
335
336DwString KMFolder::getDwString( int idx )
337{
338 return mStorage->getDwString( idx );
339}
340
342{
343 mStorage->ignoreJobsForMessage( m );
344}
345
346FolderJob* 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
353FolderJob* 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
360const KMMsgBase* KMFolder::getMsgBase( int idx ) const
361{
362 return mStorage->getMsgBase( idx );
363}
364
365KMMsgBase* KMFolder::getMsgBase( int idx )
366{
367 return mStorage->getMsgBase( idx );
368}
369
370const KMMsgBase* KMFolder::operator[]( int idx ) const
371{
372 return mStorage->operator[]( idx );
373}
374
375KMMsgBase* KMFolder::operator[]( int idx )
376{
377 return mStorage->operator[]( idx );
378}
379
381{
382 return mStorage->take( idx );
383}
384
385void KMFolder::take( TQPtrList<KMMessage> msgList ) // TODO const ref
386{
387 mStorage->take( msgList );
388}
389
390int KMFolder::addMsg( KMMessage* msg, int* index_return )
391{
392 return mStorage->addMsg( msg, index_return );
393}
394
395int KMFolder::addMsgKeepUID( KMMessage* msg, int* index_return )
396{
397 return mStorage->addMsgKeepUID( msg, index_return );
398}
399
400int 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
410void KMFolder::removeMsg( int i, bool imapQuiet )
411{
412 mStorage->removeMsg( i, imapQuiet );
413}
414
415void KMFolder::removeMsg( TQPtrList<KMMessage> msgList, bool imapQuiet ) // TODO const ref
416{
417 mStorage->removeMsg( msgList, imapQuiet );
418}
419
421{
422 return mStorage->expungeOldMsg( days );
423}
424
425int KMFolder::moveMsg( KMMessage* msg, int* index_return )
426{
427 return mStorage->moveMsg( msg, index_return );
428}
429
430int KMFolder::moveMsg(TQPtrList<KMMessage> q, int* index_return )
431{
432 return mStorage->moveMsg( q, index_return );
433}
434
435int KMFolder::find( const KMMsgBase* msg ) const
436{
437 return mStorage ? mStorage->find( msg ) : -1;
438}
439
440int KMFolder::find( const KMMessage* msg ) const
441{
442 return mStorage ? mStorage->find( msg ) : -1;
443}
444
445int 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
473void KMFolder::msgStatusChanged( const KMMsgStatus oldStatus,
474 const KMMsgStatus newStatus, int idx )
475{
476 mStorage->msgStatusChanged( oldStatus, newStatus, idx );
477}
478
479int KMFolder::open(const char *owner)
480{
481 return mStorage->open(owner);
482}
483
485{
486 return mStorage->canAccess();
487}
488
489void 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
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
531int KMFolder::rename( const TQString& newName, KMFolderDir *aParent )
532{
533 return mStorage->rename( newName, aParent );
534}
535
536bool KMFolder::dirty() const
537{
538 return mStorage->dirty();
539}
540
541void KMFolder::setDirty( bool f )
542{
543 mStorage->setDirty( f );
544}
545
547{
548 return mStorage->needsCompacting();
549}
550
551void KMFolder::setNeedsCompacting( bool f )
552{
553 mStorage->setNeedsCompacting( f );
554}
555
556void KMFolder::quiet( bool beQuiet )
557{
558 mStorage->quiet( beQuiet );
559}
560
562{
563 return mStorage->isReadOnly();
564}
565
566bool 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
581TQString 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//-----------------------------------------------------------------------------
593TQString 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//--------------------------------------------------------------------------
605TQString 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
626void KMFolder::setMailingList( const MailingList& mlist )
627{
628 mMailingList = mlist;
629 mStorage->writeConfig();
630}
631
632void KMFolder::setIdentity( uint identity )
633{
634 mIdentity = identity;
635 kmkernel->slotRequestConfigSync();
636}
637
638uint 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
648void 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
657void 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
705TQString 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
725void 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
741void 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
756void KMFolder::setReadExpireUnits( ExpireUnits units )
757{
758 if (units >= expireNever && units <= expireMaxUnits)
759 mReadExpireUnits = units;
760 mStorage->writeConfig();
761}
762
763
764void KMFolder::setExpireAction( ExpireAction a )
765{
766 if ( a != mExpireAction ) {
767 mExpireAction = a;
768 mStorage->writeConfig();
769 }
770}
771
772void KMFolder::setExpireToFolderId( const TQString& id )
773{
774 if ( id != mExpireToFolderId ) {
775 mExpireToFolderId = id;
776 mStorage->writeConfig();
777 }
778}
779
780
781static 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
796void KMFolder::daysToExpire(int& unreadDays, int& readDays) {
797 unreadDays = ::daysToExpire( getUnreadExpireAge(), getUnreadExpireUnits() );
798 readDays = ::daysToExpire( getReadExpireAge(), getReadExpireUnits() );
799}
800
801void 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
811void 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
826int KMFolder::writeIndex( bool createEmptyIndex )
827{
828 return mStorage->writeIndex( createEmptyIndex );
829}
830
831void KMFolder::setStatus( int idx, KMMsgStatus status, bool toggle )
832{
833 mStorage->setStatus( idx, status, toggle );
834}
835
836void KMFolder::setStatus( TQValueList<int>& ids, KMMsgStatus status,
837 bool toggle )
838{
839 mStorage->setStatus( ids, status, toggle);
840}
841
842void KMFolder::setIconPaths( const TQString &normalPath,
843 const TQString &unreadPath )
844{
845 mNormalIconPath = normalPath;
846 mUnreadIconPath = unreadPath;
847 mStorage->writeConfig();
848 emit iconsChanged();
849}
850
851void 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
871void 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
884void KMFolder::slotContentsTypeChanged( KMail::FolderContentsType type )
885{
886 kmkernel->iCalIface().folderContentsTypeChanged( this, type );
887 emit iconsChanged();
888}
889
890void 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
899bool 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.
virtual KMFolder * trashFolder() const
If this folder has a special trash folder set, return it.
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 const KMMsgBase * getMsgBase(int idx) const =0
Provides access to the basic message fields that are also stored in the index.
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 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 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,...
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
KMFolderDir * child() const
Returns the folder directory associated with this node or 0 if no such directory exists.
Definition: kmfolder.h:157
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