kmail

kmfolder.cpp

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