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