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