kmail

kmfolder.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-file-style: "gnu" -*-
00002  * kmail: KDE mail client
00003  * Copyright (c) 1996-1998 Stefan Taferner <taferner@kde.org>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  */
00020 #include <config.h>
00021 
00022 #include "kmfolder.h"
00023 #include "kmfolderdir.h"
00024 #include "kmfoldermbox.h"
00025 #include "folderstorage.h"
00026 #include "kmfoldercachedimap.h"
00027 #include "kmfoldersearch.h"
00028 #include "kmfolderimap.h"
00029 #include "kmfoldermgr.h"
00030 #include <libkpimidentities/identitymanager.h>
00031 #include <libkpimidentities/identity.h>
00032 #include "expirejob.h"
00033 #include "compactionjob.h"
00034 #include "kmfoldertree.h"
00035 #include "kmailicalifaceimpl.h"
00036 #include "kmaccount.h"
00037 
00038 #include <errno.h>
00039 
00040 #include <kdebug.h>
00041 #include <klocale.h>
00042 #include <kshortcut.h>
00043 #include <kmessagebox.h>
00044 #include <qfile.h>
00045 #include <qfileinfo.h>
00046 
00047 
00048 KMFolder::KMFolder( KMFolderDir* aParent, const QString& aFolderName,
00049                              KMFolderType aFolderType, bool withIndex, bool exportedSernums )
00050   : KMFolderNode( aParent, aFolderName ), mStorage(0),
00051     mChild( 0 ),
00052     mIsSystemFolder( false ),
00053     mHasIndex( withIndex ),
00054     mExportsSernums( exportedSernums ),
00055     mMoveInProgress( false ),
00056     mExpireMessages( false ), mUnreadExpireAge( 28 ),
00057     mReadExpireAge( 14 ), mUnreadExpireUnits( expireNever ),
00058     mReadExpireUnits( expireNever ),
00059     mExpireAction( ExpireDelete ),
00060     mUseCustomIcons( false ), mMailingListEnabled( false ),
00061     mAcctList( 0 ),
00062     mIdentity( 0 ), // default identity
00063     mPutRepliesInSameFolder( false ),
00064     mIgnoreNewMail( false )
00065 {
00066   if( aFolderType == KMFolderTypeCachedImap )
00067     mStorage = new KMFolderCachedImap( this, aFolderName.latin1() );
00068   else if( aFolderType == KMFolderTypeImap )
00069     mStorage = new KMFolderImap( this, aFolderName.latin1() );
00070   else if( aFolderType == KMFolderTypeMaildir )
00071     mStorage = new KMFolderMaildir( this, aFolderName.latin1() );
00072   else if( aFolderType == KMFolderTypeSearch )
00073     mStorage = new KMFolderSearch( this, aFolderName.latin1() );
00074   else
00075     mStorage = new KMFolderMbox( this, aFolderName.latin1() );
00076 
00077   assert( mStorage );
00078 
00079   QFileInfo dirinfo;
00080   dirinfo.setFile( mStorage->location() );
00081   if ( !dirinfo.exists() ) {
00082     int rc = mStorage->create();
00083     QString msg = i18n("<qt>Error while creating file <b>%1</b>:<br>%2</qt>").arg(aFolderName).arg(strerror(rc));
00084     if ( rc ) {
00085       KMessageBox::information(0, msg);
00086     }
00087   }
00088 
00089   if ( aParent ) {
00090     connect( mStorage, SIGNAL( msgAdded( KMFolder*, Q_UINT32 ) ),
00091              aParent->manager(), SIGNAL( msgAdded( KMFolder*, Q_UINT32 ) ) );
00092     connect( mStorage, SIGNAL( msgRemoved( KMFolder*, Q_UINT32 ) ),
00093              parent()->manager(), SIGNAL( msgRemoved( KMFolder*, Q_UINT32 ) ) );
00094     connect( this, SIGNAL( msgChanged( KMFolder*, Q_UINT32, int ) ),
00095              parent()->manager(), SIGNAL( msgChanged( KMFolder*, Q_UINT32, int ) ) );
00096     connect( this, SIGNAL( msgHeaderChanged( KMFolder*,  int ) ),
00097              parent()->manager(), SIGNAL( msgHeaderChanged( KMFolder*, int ) ) );
00098     connect( mStorage, SIGNAL( invalidated( KMFolder* ) ),
00099              parent()->manager(), SIGNAL( folderInvalidated( KMFolder* ) ) );
00100   }
00101 
00102   // Resend all mStorage signals
00103   connect( mStorage, SIGNAL( changed() ), SIGNAL( changed() ) );
00104   connect( mStorage, SIGNAL( cleared() ), SIGNAL( cleared() ) );
00105   connect( mStorage, SIGNAL( expunged( KMFolder* ) ),
00106            SIGNAL( expunged( KMFolder* ) ) );
00107   connect( mStorage, SIGNAL( nameChanged() ), SIGNAL( nameChanged() ) );
00108   connect( mStorage, SIGNAL( msgRemoved( KMFolder*, Q_UINT32 ) ),
00109            SIGNAL( msgRemoved( KMFolder*, Q_UINT32 ) ) );
00110   connect( mStorage, SIGNAL( msgRemoved( int, QString ) ),
00111            SIGNAL( msgRemoved( int, QString ) ) );
00112   connect( mStorage, SIGNAL( msgRemoved( KMFolder* ) ),
00113            SIGNAL( msgRemoved( KMFolder* ) ) );
00114   connect( mStorage, SIGNAL( msgAdded( int ) ), SIGNAL( msgAdded( int ) ) );
00115   connect( mStorage, SIGNAL( msgAdded( KMFolder*, Q_UINT32 ) ),
00116            SIGNAL( msgAdded( KMFolder*, Q_UINT32 ) ) );
00117   connect( mStorage, SIGNAL( msgChanged( KMFolder*, Q_UINT32 , int ) ),
00118            SIGNAL( msgChanged( KMFolder*, Q_UINT32 , int ) ) );
00119   connect( mStorage, SIGNAL( msgHeaderChanged( KMFolder*, int ) ),
00120            SIGNAL( msgHeaderChanged( KMFolder*, int ) ) );
00121   connect( mStorage, SIGNAL( statusMsg( const QString& ) ),
00122            SIGNAL( statusMsg( const QString& ) ) );
00123   connect( mStorage, SIGNAL( numUnreadMsgsChanged( KMFolder* ) ),
00124            SIGNAL( numUnreadMsgsChanged( KMFolder* ) ) );
00125   connect( mStorage, SIGNAL( removed( KMFolder*, bool ) ),
00126            SIGNAL( removed( KMFolder*, bool ) ) );
00127 
00128   connect( mStorage, SIGNAL( contentsTypeChanged( KMail::FolderContentsType ) ),
00129                 this, SLOT( slotContentsTypeChanged( KMail::FolderContentsType ) ) );
00130 
00131   connect( mStorage, SIGNAL( folderSizeChanged() ),
00132            this, SLOT( slotFolderSizeChanged() ) );
00133 
00134   //FIXME: Centralize all the readConfig calls somehow - Zack
00135   // Meanwhile, readConfig must be done before registerWithMessageDict, since
00136   // that one can call writeConfig in some circumstances - David
00137   mStorage->readConfig();
00138 
00139    // trigger from here, since it needs a fully constructed FolderStorage
00140   if ( mExportsSernums )
00141     mStorage->registerWithMessageDict();
00142   if ( !mHasIndex )
00143     mStorage->setAutoCreateIndex( false );
00144 
00145   if ( mId == 0 && aParent )
00146     mId = aParent->manager()->createId();
00147 }
00148 
00149 KMFolder::~KMFolder()
00150 {
00151   mStorage->close( "~KMFolder", true );
00152   delete mAcctList;
00153   if ( mHasIndex ) mStorage->deregisterFromMessageDict();
00154   delete mStorage;
00155 }
00156 
00157 void KMFolder::readConfig( KConfig* config )
00158 {
00159   if ( !config->readEntry("SystemLabel").isEmpty() )
00160     mSystemLabel = config->readEntry("SystemLabel");
00161   mExpireMessages = config->readBoolEntry("ExpireMessages", false);
00162   mReadExpireAge = config->readNumEntry("ReadExpireAge", 3);
00163   mReadExpireUnits = (ExpireUnits)config->readNumEntry("ReadExpireUnits", expireMonths);
00164   mUnreadExpireAge = config->readNumEntry("UnreadExpireAge", 12);
00165   mUnreadExpireUnits = (ExpireUnits)config->readNumEntry("UnreadExpireUnits", expireNever);
00166   mExpireAction = config->readEntry("ExpireAction", "Delete") == "Move" ? ExpireMove : ExpireDelete;
00167   mExpireToFolderId = config->readEntry("ExpireToFolder");
00168 
00169   mUseCustomIcons = config->readBoolEntry("UseCustomIcons", false );
00170   mNormalIconPath = config->readEntry("NormalIconPath" );
00171   mUnreadIconPath = config->readEntry("UnreadIconPath" );
00172 
00173   mMailingListEnabled = config->readBoolEntry("MailingListEnabled");
00174   mMailingList.readConfig( config );
00175 
00176   mIdentity = config->readUnsignedNumEntry("Identity",0);
00177 
00178   setUserWhoField( config->readEntry("WhoField"), false );
00179   uint savedId = config->readUnsignedNumEntry("Id", 0);
00180   // make sure that we don't overwrite a valid id
00181   if ( savedId != 0 && mId == 0 )
00182     mId = savedId;
00183   mPutRepliesInSameFolder = config->readBoolEntry( "PutRepliesInSameFolder", false );
00184   mIgnoreNewMail = config->readBoolEntry( "IgnoreNewMail", false );
00185 
00186   if ( mUseCustomIcons )
00187     emit iconsChanged();
00188 
00189   QString shortcut( config->readEntry( "Shortcut" ) );
00190   if ( !shortcut.isEmpty() ) {
00191     KShortcut sc( shortcut );
00192     setShortcut( sc );
00193   }
00194 }
00195 
00196 void KMFolder::writeConfig( KConfig* config ) const
00197 {
00198   config->writeEntry("SystemLabel", mSystemLabel);
00199   config->writeEntry("ExpireMessages", mExpireMessages);
00200   config->writeEntry("ReadExpireAge", mReadExpireAge);
00201   config->writeEntry("ReadExpireUnits", mReadExpireUnits);
00202   config->writeEntry("UnreadExpireAge", mUnreadExpireAge);
00203   config->writeEntry("UnreadExpireUnits", mUnreadExpireUnits);
00204   config->writeEntry("ExpireAction", mExpireAction == ExpireDelete ? "Delete" : "Move");
00205   config->writeEntry("ExpireToFolder", mExpireToFolderId);
00206 
00207   config->writeEntry("UseCustomIcons", mUseCustomIcons);
00208   config->writeEntry("NormalIconPath", mNormalIconPath);
00209   config->writeEntry("UnreadIconPath", mUnreadIconPath);
00210 
00211   config->writeEntry("MailingListEnabled", mMailingListEnabled);
00212   mMailingList.writeConfig( config );
00213 
00214   if ( mIdentity != 0 && ( !mStorage || !mStorage->account() || mIdentity != mStorage->account()->identityId() ) )
00215       config->writeEntry("Identity", mIdentity);
00216   else
00217       config->deleteEntry("Identity");
00218 
00219   config->writeEntry("WhoField", mUserWhoField);
00220   config->writeEntry("Id", mId);
00221   config->writeEntry( "PutRepliesInSameFolder", mPutRepliesInSameFolder );
00222   config->writeEntry( "IgnoreNewMail", mIgnoreNewMail );
00223   if ( !mShortcut.isNull() )
00224     config->writeEntry( "Shortcut", mShortcut.toString() );
00225   else
00226     config->deleteEntry( "Shortcut" );
00227 }
00228 
00229 KMFolderType KMFolder::folderType() const
00230 {
00231   return mStorage ? mStorage->folderType() : KMFolderTypeUnknown;
00232 }
00233 
00234 QString KMFolder::fileName() const
00235 {
00236   return mStorage ? mStorage->fileName() : QString::null;
00237 }
00238 
00239 QString KMFolder::location() const
00240 {
00241   return mStorage ? mStorage->location() : QString::null;
00242 }
00243 
00244 QString KMFolder::indexLocation() const
00245 {
00246   return mStorage ? mStorage->indexLocation() : QString::null;
00247 }
00248 
00249 QString KMFolder::subdirLocation() const
00250 {
00251   QString sLocation( path() );
00252 
00253   if( !sLocation.isEmpty() )
00254     sLocation += '/';
00255   sLocation += '.' + FolderStorage::dotEscape( fileName() ) + ".directory";
00256 
00257   return sLocation;
00258 }
00259 
00260 KMFolderDir* KMFolder::createChildFolder()
00261 {
00262   if( mChild )
00263     return mChild;
00264 
00265   QString childName = "." + fileName() + ".directory";
00266   QString childDir = path() + "/" + childName;
00267   if (access(QFile::encodeName(childDir), W_OK) != 0) // Not there or not writable
00268   {
00269     if (mkdir(QFile::encodeName(childDir), S_IRWXU) != 0
00270       && chmod(QFile::encodeName(childDir), S_IRWXU) != 0) {
00271       QString wmsg = QString(" '%1': %2").arg(childDir).arg(strerror(errno));
00272       KMessageBox::information(0,i18n("Failed to create folder") + wmsg);
00273       return 0;
00274     }
00275   }
00276 
00277   KMFolderDirType newType = KMStandardDir;
00278   if( folderType() == KMFolderTypeCachedImap )
00279     newType = KMDImapDir;
00280   else if( folderType() == KMFolderTypeImap )
00281     newType = KMImapDir;
00282 
00283   mChild = new KMFolderDir( this, parent(), childName, newType );
00284   if( !mChild )
00285     return 0;
00286   mChild->reload();
00287   parent()->append( mChild );
00288   return mChild;
00289 }
00290 
00291 void KMFolder::setChild( KMFolderDir* aChild )
00292 {
00293   mChild = aChild;
00294   mStorage->updateChildrenState();
00295 }
00296 
00297 bool KMFolder::noContent() const
00298 {
00299   return mStorage ? mStorage->noContent() : true;
00300 }
00301 
00302 void KMFolder::setNoContent( bool aNoContent )
00303 {
00304   mStorage->setNoContent( aNoContent );
00305 }
00306 
00307 bool KMFolder::noChildren() const
00308 {
00309   return mStorage->noChildren();
00310 }
00311 
00312 void KMFolder::setNoChildren( bool aNoChildren )
00313 {
00314   mStorage->setNoChildren( aNoChildren );
00315 }
00316 
00317 KMMessage* KMFolder::getMsg( int idx )
00318 {
00319   return mStorage->getMsg( idx );
00320 }
00321 
00322 KMMsgInfo* KMFolder::unGetMsg( int idx )
00323 {
00324   return mStorage->unGetMsg( idx );
00325 }
00326 
00327 bool KMFolder::isMessage( int idx )
00328 {
00329   return mStorage->isMessage( idx );
00330 }
00331 
00332 DwString KMFolder::getDwString( int idx )
00333 {
00334   return mStorage->getDwString( idx );
00335 }
00336 
00337 void KMFolder::ignoreJobsForMessage( KMMessage* m )
00338 {
00339   mStorage->ignoreJobsForMessage( m );
00340 }
00341 
00342 FolderJob* KMFolder::createJob( KMMessage *msg, FolderJob::JobType jt,
00343                                 KMFolder *folder, QString partSpecifier,
00344                                 const AttachmentStrategy *as ) const
00345 {
00346   return mStorage->createJob( msg, jt, folder, partSpecifier, as );
00347 }
00348 
00349 FolderJob* KMFolder::createJob( QPtrList<KMMessage>& msgList,
00350                                 const QString& sets,
00351                                 FolderJob::JobType jt, KMFolder *folder ) const
00352 {
00353   return mStorage->createJob( msgList, sets, jt, folder );
00354 }
00355 
00356 const KMMsgBase* KMFolder::getMsgBase( int idx ) const
00357 {
00358   return mStorage->getMsgBase( idx );
00359 }
00360 
00361 KMMsgBase* KMFolder::getMsgBase( int idx )
00362 {
00363   return mStorage->getMsgBase( idx );
00364 }
00365 
00366 const KMMsgBase* KMFolder::operator[]( int idx ) const
00367 {
00368   return mStorage->operator[]( idx );
00369 }
00370 
00371 KMMsgBase* KMFolder::operator[]( int idx )
00372 {
00373   return mStorage->operator[]( idx );
00374 }
00375 
00376 KMMessage* KMFolder::take( int idx )
00377 {
00378   return mStorage->take( idx );
00379 }
00380 
00381 void KMFolder::take( QPtrList<KMMessage> msgList ) // TODO const ref
00382 {
00383   mStorage->take( msgList );
00384 }
00385 
00386 int KMFolder::addMsg( KMMessage* msg, int* index_return )
00387 {
00388   return mStorage->addMsg( msg, index_return );
00389 }
00390 
00391 int KMFolder::addMsgKeepUID( KMMessage* msg, int* index_return )
00392 {
00393   return mStorage->addMsgKeepUID( msg, index_return );
00394 }
00395 
00396 int KMFolder::addMsg( QPtrList<KMMessage>& list, QValueList<int>& index_return )
00397 {
00398   return mStorage->addMsg( list, index_return );
00399 }
00400 
00401 void KMFolder::emitMsgAddedSignals( int idx )
00402 {
00403   mStorage->emitMsgAddedSignals( idx );
00404 }
00405 
00406 void KMFolder::removeMsg( int i, bool imapQuiet )
00407 {
00408   mStorage->removeMsg( i, imapQuiet );
00409 }
00410 
00411 void KMFolder::removeMsg( QPtrList<KMMessage> msgList, bool imapQuiet ) // TODO const ref
00412 {
00413   mStorage->removeMsg( msgList, imapQuiet );
00414 }
00415 
00416 int KMFolder::expungeOldMsg( int days )
00417 {
00418   return mStorage->expungeOldMsg( days );
00419 }
00420 
00421 int KMFolder::moveMsg( KMMessage* msg, int* index_return )
00422 {
00423   return mStorage->moveMsg( msg, index_return );
00424 }
00425 
00426 int KMFolder::moveMsg(QPtrList<KMMessage> q, int* index_return )
00427 {
00428   return mStorage->moveMsg( q, index_return );
00429 }
00430 
00431 int KMFolder::find( const KMMsgBase* msg ) const
00432 {
00433   return mStorage ? mStorage->find( msg ) : -1;
00434 }
00435 
00436 int KMFolder::find( const KMMessage* msg ) const
00437 {
00438   return mStorage ? mStorage->find( msg ) : -1;
00439 }
00440 
00441 int KMFolder::count( bool cache ) const
00442 {
00443   return mStorage->count( cache );
00444 }
00445 
00446 int KMFolder::countUnread()
00447 {
00448   return mStorage->countUnread();
00449 }
00450 
00451 int KMFolder::countUnreadRecursive()
00452 {
00453   KMFolder *folder;
00454   int count = countUnread();
00455   KMFolderDir *dir = child();
00456   if (!dir)
00457     return count;
00458 
00459   QPtrListIterator<KMFolderNode> it(*dir);
00460   for ( ; it.current(); ++it )
00461     if (!it.current()->isDir()) {
00462       folder = static_cast<KMFolder*>(it.current());
00463       count += folder->countUnreadRecursive();
00464     }
00465 
00466   return count;
00467 }
00468 
00469 void KMFolder::msgStatusChanged( const KMMsgStatus oldStatus,
00470                                  const KMMsgStatus newStatus, int idx )
00471 {
00472   mStorage->msgStatusChanged( oldStatus, newStatus, idx );
00473 }
00474 
00475 int KMFolder::open(const char *owner)
00476 {
00477   return mStorage->open(owner);
00478 }
00479 
00480 int KMFolder::canAccess()
00481 {
00482   return mStorage->canAccess();
00483 }
00484 
00485 void KMFolder::close( const char *owner, bool force )
00486 {
00487   // do not emit closed() in here - as this would regain too early
00488   mStorage->close( owner, force );
00489 }
00490 
00491 void KMFolder::sync()
00492 {
00493   mStorage->sync();
00494 }
00495 
00496 bool KMFolder::isOpened() const
00497 {
00498   return mStorage->isOpened();
00499 }
00500 
00501 void KMFolder::markNewAsUnread()
00502 {
00503   mStorage->markNewAsUnread();
00504 }
00505 
00506 void KMFolder::markUnreadAsRead()
00507 {
00508   mStorage->markUnreadAsRead();
00509 }
00510 
00511 void KMFolder::remove()
00512 {
00513   /* The storage needs to be open before remove is called, otherwise
00514      it will not unregister the corresponding serial numbers from
00515      the message dict, since its message list is empty, and the .ids
00516      file contents are not loaded. That can lead to lookups in the
00517      dict returning stale pointers to the folder later. */
00518   mStorage->open("kmfolder_remove");
00519   mStorage->remove();
00520 }
00521 
00522 int KMFolder::expunge()
00523 {
00524   return mStorage->expunge();
00525 }
00526 
00527 int KMFolder::rename( const QString& newName, KMFolderDir *aParent )
00528 {
00529   return mStorage->rename( newName, aParent );
00530 }
00531 
00532 bool KMFolder::dirty() const
00533 {
00534   return mStorage->dirty();
00535 }
00536 
00537 void KMFolder::setDirty( bool f )
00538 {
00539   mStorage->setDirty( f );
00540 }
00541 
00542 bool KMFolder::needsCompacting() const
00543 {
00544   return mStorage->needsCompacting();
00545 }
00546 
00547 void KMFolder::setNeedsCompacting( bool f )
00548 {
00549   mStorage->setNeedsCompacting( f );
00550 }
00551 
00552 void KMFolder::quiet( bool beQuiet )
00553 {
00554   mStorage->quiet( beQuiet );
00555 }
00556 
00557 bool KMFolder::isReadOnly() const
00558 {
00559   return mStorage->isReadOnly();
00560 }
00561 
00562 QString KMFolder::label() const
00563 {
00564   if ( !mSystemLabel.isEmpty() )
00565      return mSystemLabel;
00566   if ( !mLabel.isEmpty() )
00567      return mLabel;
00568   if ( isSystemFolder() )
00569      return i18n( name().utf8() );
00570   return name();
00571 }
00572 
00573 //-----------------------------------------------------------------------------
00574 QString KMFolder::prettyURL() const
00575 {
00576   QString parentUrl;
00577   if ( parent() )
00578     parentUrl = parent()->prettyURL();
00579   if ( !parentUrl.isEmpty() )
00580     return parentUrl + '/' + label();
00581   else
00582     return label();
00583 }
00584 
00585 //--------------------------------------------------------------------------
00586 QString KMFolder::mailingListPostAddress() const
00587 {
00588   if ( mMailingList.features() & MailingList::Post ) {
00589     KURL::List::const_iterator it;
00590     KURL::List post = mMailingList.postURLS();
00591     for( it = post.begin(); it != post.end(); ++it ) {
00592       // We check for isEmpty because before 3.3 postAddress was just an
00593       // email@kde.org and that leaves protocol() field in the kurl class
00594       if ( (*it).protocol() == "mailto" || (*it).protocol().isEmpty() )
00595         return (*it).path();
00596     }
00597   }
00598   return QString::null;
00599 }
00600 
00601 void KMFolder::setMailingListEnabled( bool enabled )
00602 {
00603   mMailingListEnabled = enabled;
00604   mStorage->writeConfig();
00605 }
00606 
00607 void KMFolder::setMailingList( const MailingList& mlist )
00608 {
00609   mMailingList = mlist;
00610   mStorage->writeConfig();
00611 }
00612 
00613 void KMFolder::setIdentity( uint identity )
00614 {
00615   mIdentity = identity;
00616   kmkernel->slotRequestConfigSync();
00617 }
00618 
00619 uint KMFolder::identity() const
00620 {
00621   // if we don't have one set ourselves, check our account
00622   kdDebug() << "FOO: " << mIdentity << " :: " << mStorage << endl;
00623   if ( !mIdentity && mStorage )
00624     if ( KMAccount *act = mStorage->account() )
00625       return act->identityId();
00626   return mIdentity;
00627 }
00628 
00629 void KMFolder::setWhoField(const QString& aWhoField )
00630 {
00631   mWhoField = aWhoField;
00632 #if 0
00633   // This isn't saved in the config anyway
00634   mStorage->writeConfig();
00635 #endif
00636 }
00637 
00638 void KMFolder::setUserWhoField( const QString& whoField, bool writeConfig )
00639 {
00640   if ( mUserWhoField == whoField )
00641     return;
00642   if ( whoField.isEmpty() )
00643   {
00644     // default setting
00645     const KPIM::Identity & identity =
00646       kmkernel->identityManager()->identityForUoidOrDefault( mIdentity );
00647 
00648     if ( isSystemFolder() && folderType() != KMFolderTypeImap ) {
00649       // local system folders
00650       if ( this == kmkernel->inboxFolder() ||
00651            this == kmkernel->trashFolder() )
00652         mWhoField = "From";
00653       if ( this == kmkernel->outboxFolder() ||
00654            this == kmkernel->sentFolder() ||
00655            this == kmkernel->draftsFolder() ||
00656            this == kmkernel->templatesFolder() )
00657         mWhoField = "To";
00658     } else if ( identity.drafts() == idString() ||
00659                 identity.templates() == idString() ||
00660                 identity.fcc() == idString() )
00661       // drafts, templates or sent of the identity
00662       mWhoField = "To";
00663     else
00664       mWhoField = "From";
00665   } else if ( whoField == "From" || whoField == "To" )
00666     // set the whoField according to the user-setting
00667     mWhoField = whoField;
00668   else {
00669     // this should not happen...
00670     kdDebug(5006) << "Illegal setting " << whoField << " for userWhoField!"
00671                   << endl;
00672     return; // don't use the value
00673   }
00674   mUserWhoField = whoField;
00675 
00676   if (writeConfig)
00677     mStorage->writeConfig();
00678   emit viewConfigChanged();
00679 }
00680 
00681 void KMFolder::correctUnreadMsgsCount()
00682 {
00683   mStorage->correctUnreadMsgsCount();
00684 }
00685 
00686 QString KMFolder::idString() const
00687 {
00688   KMFolderNode* folderNode = parent();
00689   if (!folderNode)
00690     return "";
00691   while ( folderNode->parent() )
00692     folderNode = folderNode->parent();
00693   QString myPath = path();
00694   int pathLen = myPath.length() - folderNode->path().length();
00695   QString relativePath = myPath.right( pathLen );
00696   if (!relativePath.isEmpty())
00697     relativePath = relativePath.right( relativePath.length() - 1 ) + "/";
00698   QString escapedName = name();
00699   /* Escape [ and ] as they are disallowed for kconfig sections and that is
00700      what the idString is primarily used for. */
00701   escapedName.replace( "[", "%(" );
00702   escapedName.replace( "]", "%)" );
00703   return relativePath + escapedName;
00704 }
00705 
00706 void KMFolder::setAutoExpire( bool enabled )
00707 {
00708   if( enabled != mExpireMessages ) {
00709     mExpireMessages = enabled;
00710     mStorage->writeConfig();
00711   }
00712 }
00713 
00714 void KMFolder::setUnreadExpireAge( int age )
00715 {
00716   if( age >= 0 && age != mUnreadExpireAge ) {
00717     mUnreadExpireAge = age;
00718     mStorage->writeConfig();
00719   }
00720 }
00721 
00722 void KMFolder::setUnreadExpireUnits( ExpireUnits units )
00723 {
00724   if (units >= expireNever && units < expireMaxUnits)
00725     mUnreadExpireUnits = units;
00726     mStorage->writeConfig();
00727 }
00728 
00729 void KMFolder::setReadExpireAge( int age )
00730 {
00731   if( age >= 0 && age != mReadExpireAge ) {
00732     mReadExpireAge = age;
00733     mStorage->writeConfig();
00734   }
00735 }
00736 
00737 void KMFolder::setReadExpireUnits( ExpireUnits units )
00738 {
00739   if (units >= expireNever && units <= expireMaxUnits)
00740     mReadExpireUnits = units;
00741     mStorage->writeConfig();
00742 }
00743 
00744 
00745 void KMFolder::setExpireAction( ExpireAction a )
00746 {
00747   if ( a != mExpireAction ) {
00748     mExpireAction = a;
00749     mStorage->writeConfig();
00750   }
00751 }
00752 
00753 void KMFolder::setExpireToFolderId( const QString& id )
00754 {
00755   if ( id != mExpireToFolderId ) {
00756     mExpireToFolderId = id;
00757     mStorage->writeConfig();
00758   }
00759 }
00760 
00761 
00762 static int daysToExpire( int number, ExpireUnits units )
00763 {
00764   switch (units) {
00765   case expireDays: // Days
00766     return number;
00767   case expireWeeks: // Weeks
00768     return number * 7;
00769   case expireMonths: // Months - this could be better rather than assuming 31day months.
00770     return number * 31;
00771   default: // this avoids a compiler warning (not handled enumeration values)
00772     ;
00773   }
00774   return -1;
00775 }
00776 
00777 void KMFolder::daysToExpire(int& unreadDays, int& readDays) {
00778   unreadDays = ::daysToExpire( getUnreadExpireAge(), getUnreadExpireUnits() );
00779   readDays = ::daysToExpire( getReadExpireAge(), getReadExpireUnits() );
00780 }
00781 
00782 void KMFolder::expireOldMessages( bool immediate )
00783 {
00784   KMail::ScheduledExpireTask* task = new KMail::ScheduledExpireTask(this, immediate);
00785   kmkernel->jobScheduler()->registerTask( task );
00786   if ( immediate ) {
00787     // #82259: compact after expiring.
00788     compact( CompactLater );
00789   }
00790 }
00791 
00792 void KMFolder::compact( CompactOptions options )
00793 {
00794   if ( options == CompactLater ) {
00795     KMail::ScheduledCompactionTask* task = new KMail::ScheduledCompactionTask(this, false);
00796     kmkernel->jobScheduler()->registerTask( task );
00797   } else {
00798     mStorage->compact( options == CompactSilentlyNow );
00799   }
00800 }
00801 
00802 KMFolder* KMFolder::trashFolder() const
00803 {
00804   return mStorage ? mStorage->trashFolder() : 0;
00805 }
00806 
00807 int KMFolder::writeIndex( bool createEmptyIndex )
00808 {
00809   return mStorage->writeIndex( createEmptyIndex );
00810 }
00811 
00812 void KMFolder::setStatus( int idx, KMMsgStatus status, bool toggle )
00813 {
00814   mStorage->setStatus( idx, status, toggle );
00815 }
00816 
00817 void KMFolder::setStatus( QValueList<int>& ids, KMMsgStatus status,
00818                           bool toggle )
00819 {
00820   mStorage->setStatus( ids, status, toggle);
00821 }
00822 
00823 void KMFolder::setIconPaths( const QString &normalPath,
00824                              const QString &unreadPath )
00825 {
00826   mNormalIconPath = normalPath;
00827   mUnreadIconPath = unreadPath;
00828   mStorage->writeConfig();
00829   emit iconsChanged();
00830 }
00831 
00832 void KMFolder::removeJobs()
00833 {
00834   mStorage->removeJobs();
00835 }
00836 
00837 int KMFolder::updateIndex()
00838 {
00839   return mStorage->updateIndex();
00840 }
00841 
00842 void KMFolder::reallyAddMsg( KMMessage* aMsg )
00843 {
00844   mStorage->reallyAddMsg( aMsg );
00845 }
00846 
00847 void KMFolder::reallyAddCopyOfMsg( KMMessage* aMsg )
00848 {
00849   mStorage->reallyAddCopyOfMsg( aMsg );
00850 }
00851 
00852 void KMFolder::setShortcut( const KShortcut &sc )
00853 {
00854   if ( mShortcut != sc ) {
00855     mShortcut = sc;
00856     emit shortcutChanged( this );
00857   }
00858 }
00859 
00860 bool KMFolder::isMoveable() const
00861 {
00862   return !isSystemFolder();
00863 }
00864 
00865 void KMFolder::slotContentsTypeChanged( KMail::FolderContentsType type )
00866 {
00867   kmkernel->iCalIface().folderContentsTypeChanged( this, type );
00868   emit iconsChanged();
00869 }
00870 
00871 void KMFolder::slotFolderSizeChanged()
00872 {
00873   emit folderSizeChanged( this );
00874   KMFolder* papa = parent()->manager()->parentFolder( this );
00875   if ( papa && papa != this ) {
00876     papa->slotFolderSizeChanged();
00877   }
00878 }
00879 
00880 
00881 #include "kmfolder.moc"