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::canDeleteMessages() const
00565 {
00566   return mStorage->canDeleteMessages();
00567 }
00568 
00569 QString KMFolder::label() const
00570 {
00571   if ( !mSystemLabel.isEmpty() )
00572      return mSystemLabel;
00573   if ( !mLabel.isEmpty() )
00574      return mLabel;
00575   if ( isSystemFolder() )
00576      return i18n( name().utf8() );
00577   return name();
00578 }
00579 
00580 //-----------------------------------------------------------------------------
00581 QString KMFolder::prettyURL() const
00582 {
00583   QString parentUrl;
00584   if ( parent() )
00585     parentUrl = parent()->prettyURL();
00586   if ( !parentUrl.isEmpty() )
00587     return parentUrl + '/' + label();
00588   else
00589     return label();
00590 }
00591 
00592 //--------------------------------------------------------------------------
00593 QString KMFolder::mailingListPostAddress() const
00594 {
00595   if ( mMailingList.features() & MailingList::Post ) {
00596     KURL::List::const_iterator it;
00597     KURL::List post = mMailingList.postURLS();
00598     for( it = post.begin(); it != post.end(); ++it ) {
00599       // We check for isEmpty because before 3.3 postAddress was just an
00600       // email@kde.org and that leaves protocol() field in the kurl class
00601       if ( (*it).protocol() == "mailto" || (*it).protocol().isEmpty() )
00602         return (*it).path();
00603     }
00604   }
00605   return QString::null;
00606 }
00607 
00608 void KMFolder::setMailingListEnabled( bool enabled )
00609 {
00610   mMailingListEnabled = enabled;
00611   mStorage->writeConfig();
00612 }
00613 
00614 void KMFolder::setMailingList( const MailingList& mlist )
00615 {
00616   mMailingList = mlist;
00617   mStorage->writeConfig();
00618 }
00619 
00620 void KMFolder::setIdentity( uint identity )
00621 {
00622   mIdentity = identity;
00623   kmkernel->slotRequestConfigSync();
00624 }
00625 
00626 uint KMFolder::identity() const
00627 {
00628   // if we don't have one set ourselves, check our account
00629   kdDebug() << "FOO: " << mIdentity << " :: " << mStorage << endl;
00630   if ( !mIdentity && mStorage )
00631     if ( KMAccount *act = mStorage->account() )
00632       return act->identityId();
00633   return mIdentity;
00634 }
00635 
00636 void KMFolder::setWhoField(const QString& aWhoField )
00637 {
00638   mWhoField = aWhoField;
00639 #if 0
00640   // This isn't saved in the config anyway
00641   mStorage->writeConfig();
00642 #endif
00643 }
00644 
00645 void KMFolder::setUserWhoField( const QString& whoField, bool writeConfig )
00646 {
00647   if ( mUserWhoField == whoField )
00648     return;
00649   if ( whoField.isEmpty() )
00650   {
00651     // default setting
00652     const KPIM::Identity & identity =
00653       kmkernel->identityManager()->identityForUoidOrDefault( mIdentity );
00654 
00655     if ( isSystemFolder() && folderType() != KMFolderTypeImap ) {
00656       // local system folders
00657       if ( this == kmkernel->inboxFolder() ||
00658            this == kmkernel->trashFolder() )
00659         mWhoField = "From";
00660       if ( this == kmkernel->outboxFolder() ||
00661            this == kmkernel->sentFolder() ||
00662            this == kmkernel->draftsFolder() ||
00663            this == kmkernel->templatesFolder() )
00664         mWhoField = "To";
00665     } else if ( identity.drafts() == idString() ||
00666                 identity.templates() == idString() ||
00667                 identity.fcc() == idString() )
00668       // drafts, templates or sent of the identity
00669       mWhoField = "To";
00670     else
00671       mWhoField = "From";
00672   } else if ( whoField == "From" || whoField == "To" )
00673     // set the whoField according to the user-setting
00674     mWhoField = whoField;
00675   else {
00676     // this should not happen...
00677     kdDebug(5006) << "Illegal setting " << whoField << " for userWhoField!"
00678                   << endl;
00679     return; // don't use the value
00680   }
00681   mUserWhoField = whoField;
00682 
00683   if (writeConfig)
00684     mStorage->writeConfig();
00685   emit viewConfigChanged();
00686 }
00687 
00688 void KMFolder::correctUnreadMsgsCount()
00689 {
00690   mStorage->correctUnreadMsgsCount();
00691 }
00692 
00693 QString KMFolder::idString() const
00694 {
00695   KMFolderNode* folderNode = parent();
00696   if (!folderNode)
00697     return "";
00698   while ( folderNode->parent() )
00699     folderNode = folderNode->parent();
00700   QString myPath = path();
00701   int pathLen = myPath.length() - folderNode->path().length();
00702   QString relativePath = myPath.right( pathLen );
00703   if (!relativePath.isEmpty())
00704     relativePath = relativePath.right( relativePath.length() - 1 ) + "/";
00705   QString escapedName = name();
00706   /* Escape [ and ] as they are disallowed for kconfig sections and that is
00707      what the idString is primarily used for. */
00708   escapedName.replace( "[", "%(" );
00709   escapedName.replace( "]", "%)" );
00710   return relativePath + escapedName;
00711 }
00712 
00713 void KMFolder::setAutoExpire( bool enabled )
00714 {
00715   if( enabled != mExpireMessages ) {
00716     mExpireMessages = enabled;
00717     mStorage->writeConfig();
00718   }
00719 }
00720 
00721 void KMFolder::setUnreadExpireAge( int age )
00722 {
00723   if( age >= 0 && age != mUnreadExpireAge ) {
00724     mUnreadExpireAge = age;
00725     mStorage->writeConfig();
00726   }
00727 }
00728 
00729 void KMFolder::setUnreadExpireUnits( ExpireUnits units )
00730 {
00731   if (units >= expireNever && units < expireMaxUnits)
00732     mUnreadExpireUnits = units;
00733     mStorage->writeConfig();
00734 }
00735 
00736 void KMFolder::setReadExpireAge( int age )
00737 {
00738   if( age >= 0 && age != mReadExpireAge ) {
00739     mReadExpireAge = age;
00740     mStorage->writeConfig();
00741   }
00742 }
00743 
00744 void KMFolder::setReadExpireUnits( ExpireUnits units )
00745 {
00746   if (units >= expireNever && units <= expireMaxUnits)
00747     mReadExpireUnits = units;
00748     mStorage->writeConfig();
00749 }
00750 
00751 
00752 void KMFolder::setExpireAction( ExpireAction a )
00753 {
00754   if ( a != mExpireAction ) {
00755     mExpireAction = a;
00756     mStorage->writeConfig();
00757   }
00758 }
00759 
00760 void KMFolder::setExpireToFolderId( const QString& id )
00761 {
00762   if ( id != mExpireToFolderId ) {
00763     mExpireToFolderId = id;
00764     mStorage->writeConfig();
00765   }
00766 }
00767 
00768 
00769 static int daysToExpire( int number, ExpireUnits units )
00770 {
00771   switch (units) {
00772   case expireDays: // Days
00773     return number;
00774   case expireWeeks: // Weeks
00775     return number * 7;
00776   case expireMonths: // Months - this could be better rather than assuming 31day months.
00777     return number * 31;
00778   default: // this avoids a compiler warning (not handled enumeration values)
00779     ;
00780   }
00781   return -1;
00782 }
00783 
00784 void KMFolder::daysToExpire(int& unreadDays, int& readDays) {
00785   unreadDays = ::daysToExpire( getUnreadExpireAge(), getUnreadExpireUnits() );
00786   readDays = ::daysToExpire( getReadExpireAge(), getReadExpireUnits() );
00787 }
00788 
00789 void KMFolder::expireOldMessages( bool immediate )
00790 {
00791   KMail::ScheduledExpireTask* task = new KMail::ScheduledExpireTask(this, immediate);
00792   kmkernel->jobScheduler()->registerTask( task );
00793   if ( immediate ) {
00794     // #82259: compact after expiring.
00795     compact( CompactLater );
00796   }
00797 }
00798 
00799 void KMFolder::compact( CompactOptions options )
00800 {
00801   if ( options == CompactLater ) {
00802     KMail::ScheduledCompactionTask* task = new KMail::ScheduledCompactionTask(this, false);
00803     kmkernel->jobScheduler()->registerTask( task );
00804   } else {
00805     mStorage->compact( options == CompactSilentlyNow );
00806   }
00807 }
00808 
00809 KMFolder* KMFolder::trashFolder() const
00810 {
00811   return mStorage ? mStorage->trashFolder() : 0;
00812 }
00813 
00814 int KMFolder::writeIndex( bool createEmptyIndex )
00815 {
00816   return mStorage->writeIndex( createEmptyIndex );
00817 }
00818 
00819 void KMFolder::setStatus( int idx, KMMsgStatus status, bool toggle )
00820 {
00821   mStorage->setStatus( idx, status, toggle );
00822 }
00823 
00824 void KMFolder::setStatus( QValueList<int>& ids, KMMsgStatus status,
00825                           bool toggle )
00826 {
00827   mStorage->setStatus( ids, status, toggle);
00828 }
00829 
00830 void KMFolder::setIconPaths( const QString &normalPath,
00831                              const QString &unreadPath )
00832 {
00833   mNormalIconPath = normalPath;
00834   mUnreadIconPath = unreadPath;
00835   mStorage->writeConfig();
00836   emit iconsChanged();
00837 }
00838 
00839 void KMFolder::removeJobs()
00840 {
00841   mStorage->removeJobs();
00842 }
00843 
00844 int KMFolder::updateIndex()
00845 {
00846   return mStorage->updateIndex();
00847 }
00848 
00849 void KMFolder::reallyAddMsg( KMMessage* aMsg )
00850 {
00851   mStorage->reallyAddMsg( aMsg );
00852 }
00853 
00854 void KMFolder::reallyAddCopyOfMsg( KMMessage* aMsg )
00855 {
00856   mStorage->reallyAddCopyOfMsg( aMsg );
00857 }
00858 
00859 void KMFolder::setShortcut( const KShortcut &sc )
00860 {
00861   if ( mShortcut != sc ) {
00862     mShortcut = sc;
00863     emit shortcutChanged( this );
00864   }
00865 }
00866 
00867 bool KMFolder::isMoveable() const
00868 {
00869   return !isSystemFolder();
00870 }
00871 
00872 void KMFolder::slotContentsTypeChanged( KMail::FolderContentsType type )
00873 {
00874   kmkernel->iCalIface().folderContentsTypeChanged( this, type );
00875   emit iconsChanged();
00876 }
00877 
00878 void KMFolder::slotFolderSizeChanged()
00879 {
00880   emit folderSizeChanged( this );
00881   KMFolder* papa = parent()->manager()->parentFolder( this );
00882   if ( papa && papa != this ) {
00883     papa->slotFolderSizeChanged();
00884   }
00885 }
00886 
00887 
00888 #include "kmfolder.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys