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