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 ? mStorage->getMsg( idx ) : 0;
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   //kdDebug(5006) << "**DEBUG KMFolder::addMsg()" << endl;
00393   return mStorage->addMsg( msg, index_return );
00394 }
00395 
00396 int KMFolder::addMsgKeepUID( KMMessage* msg, int* index_return )
00397 {
00398   return mStorage->addMsgKeepUID( msg, index_return );
00399 }
00400 
00401 int KMFolder::addMsg( QPtrList<KMMessage>& list, QValueList<int>& index_return )
00402 {
00403   return mStorage->addMsg( list, index_return );
00404 }
00405 
00406 void KMFolder::emitMsgAddedSignals( int idx )
00407 {
00408   mStorage->emitMsgAddedSignals( idx );
00409 }
00410 
00411 void KMFolder::removeMsg( int i, bool imapQuiet )
00412 {
00413   mStorage->removeMsg( i, imapQuiet );
00414 }
00415 
00416 void KMFolder::removeMsg( QPtrList<KMMessage> msgList, bool imapQuiet ) // TODO const ref
00417 {
00418   mStorage->removeMsg( msgList, imapQuiet );
00419 }
00420 
00421 int KMFolder::expungeOldMsg( int days )
00422 {
00423   return mStorage->expungeOldMsg( days );
00424 }
00425 
00426 int KMFolder::moveMsg( KMMessage* msg, int* index_return )
00427 {
00428   return mStorage->moveMsg( msg, index_return );
00429 }
00430 
00431 int KMFolder::moveMsg(QPtrList<KMMessage> q, int* index_return )
00432 {
00433   return mStorage->moveMsg( q, index_return );
00434 }
00435 
00436 int KMFolder::find( const KMMsgBase* msg ) const
00437 {
00438   return mStorage ? mStorage->find( msg ) : -1;
00439 }
00440 
00441 int KMFolder::find( const KMMessage* msg ) const
00442 {
00443   return mStorage ? mStorage->find( msg ) : -1;
00444 }
00445 
00446 int KMFolder::count( bool cache ) const
00447 {
00448   return mStorage ? mStorage->count( cache ) : 0;
00449 }
00450 
00451 int KMFolder::countUnread()
00452 {
00453   return mStorage ? mStorage->countUnread() : 0;
00454 }
00455 
00456 int KMFolder::countUnreadRecursive()
00457 {
00458   KMFolder *folder;
00459   int count = countUnread();
00460   KMFolderDir *dir = child();
00461   if (!dir)
00462     return count;
00463 
00464   QPtrListIterator<KMFolderNode> it(*dir);
00465   for ( ; it.current(); ++it )
00466     if (!it.current()->isDir()) {
00467       folder = static_cast<KMFolder*>(it.current());
00468       count += folder->countUnreadRecursive();
00469     }
00470 
00471   return count;
00472 }
00473 
00474 void KMFolder::msgStatusChanged( const KMMsgStatus oldStatus,
00475                                  const KMMsgStatus newStatus, int idx )
00476 {
00477   mStorage->msgStatusChanged( oldStatus, newStatus, idx );
00478 }
00479 
00480 int KMFolder::open(const char *owner)
00481 {
00482   return mStorage->open(owner);
00483 }
00484 
00485 int KMFolder::canAccess()
00486 {
00487   return mStorage->canAccess();
00488 }
00489 
00490 void KMFolder::close( const char *owner, bool force )
00491 {
00492   // do not emit closed() in here - as this would regain too early
00493   mStorage->close( owner, force );
00494 }
00495 
00496 void KMFolder::sync()
00497 {
00498   mStorage->sync();
00499 }
00500 
00501 bool KMFolder::isOpened() const
00502 {
00503   return mStorage->isOpened();
00504 }
00505 
00506 void KMFolder::markNewAsUnread()
00507 {
00508   mStorage->markNewAsUnread();
00509 }
00510 
00511 void KMFolder::markUnreadAsRead()
00512 {
00513   mStorage->markUnreadAsRead();
00514 }
00515 
00516 void KMFolder::remove()
00517 {
00518   /* The storage needs to be open before remove is called, otherwise
00519      it will not unregister the corresponding serial numbers from
00520      the message dict, since its message list is empty, and the .ids
00521      file contents are not loaded. That can lead to lookups in the
00522      dict returning stale pointers to the folder later. */
00523   mStorage->open("kmfolder_remove");
00524   mStorage->remove();
00525 }
00526 
00527 int KMFolder::expunge()
00528 {
00529   return mStorage->expunge();
00530 }
00531 
00532 int KMFolder::rename( const QString& newName, KMFolderDir *aParent )
00533 {
00534   return mStorage->rename( newName, aParent );
00535 }
00536 
00537 bool KMFolder::dirty() const
00538 {
00539   return mStorage->dirty();
00540 }
00541 
00542 void KMFolder::setDirty( bool f )
00543 {
00544   mStorage->setDirty( f );
00545 }
00546 
00547 bool KMFolder::needsCompacting() const
00548 {
00549   return mStorage->needsCompacting();
00550 }
00551 
00552 void KMFolder::setNeedsCompacting( bool f )
00553 {
00554   mStorage->setNeedsCompacting( f );
00555 }
00556 
00557 void KMFolder::quiet( bool beQuiet )
00558 {
00559   mStorage->quiet( beQuiet );
00560 }
00561 
00562 bool KMFolder::isReadOnly() const
00563 {
00564   return mStorage->isReadOnly();
00565 }
00566 
00567 bool KMFolder::mailCheckInProgress() const
00568 {
00569   return mStorage->mailCheckInProgress();
00570 }
00571 
00572 bool KMFolder::isWritable() const
00573 {
00574   return !mStorage->isReadOnly() && mStorage->canDeleteMessages();
00575 }
00576 
00577 bool KMFolder::canDeleteMessages() const
00578 {
00579   return mStorage->canDeleteMessages();
00580 }
00581 
00582 QString KMFolder::label() const
00583 {
00584   if ( !mSystemLabel.isEmpty() )
00585      return mSystemLabel;
00586   if ( !mLabel.isEmpty() )
00587      return mLabel;
00588   if ( isSystemFolder() )
00589      return i18n( name().utf8() );
00590   return name();
00591 }
00592 
00593 //-----------------------------------------------------------------------------
00594 QString KMFolder::prettyURL() const
00595 {
00596   QString parentUrl;
00597   if ( parent() )
00598     parentUrl = parent()->prettyURL();
00599   if ( !parentUrl.isEmpty() )
00600     return parentUrl + '/' + label();
00601   else
00602     return label();
00603 }
00604 
00605 //--------------------------------------------------------------------------
00606 QString KMFolder::mailingListPostAddress() const
00607 {
00608   if ( mMailingList.features() & MailingList::Post ) {
00609     KURL::List::const_iterator it;
00610     KURL::List post = mMailingList.postURLS();
00611     for( it = post.begin(); it != post.end(); ++it ) {
00612       // We check for isEmpty because before 3.3 postAddress was just an
00613       // email@kde.org and that leaves protocol() field in the kurl class
00614       if ( (*it).protocol() == "mailto" || (*it).protocol().isEmpty() )
00615         return (*it).path();
00616     }
00617   }
00618   return QString::null;
00619 }
00620 
00621 void KMFolder::setMailingListEnabled( bool enabled )
00622 {
00623   mMailingListEnabled = enabled;
00624   mStorage->writeConfig();
00625 }
00626 
00627 void KMFolder::setMailingList( const MailingList& mlist )
00628 {
00629   mMailingList = mlist;
00630   mStorage->writeConfig();
00631 }
00632 
00633 void KMFolder::setIdentity( uint identity )
00634 {
00635   mIdentity = identity;
00636   kmkernel->slotRequestConfigSync();
00637 }
00638 
00639 uint KMFolder::identity() const
00640 {
00641   // if we don't have one set ourselves, check our account
00642   kdDebug() << "FOO: " << mIdentity << " :: " << mStorage << endl;
00643   if ( !mIdentity && mStorage )
00644     if ( KMAccount *act = mStorage->account() )
00645       return act->identityId();
00646   return mIdentity;
00647 }
00648 
00649 void KMFolder::setWhoField(const QString& aWhoField )
00650 {
00651   mWhoField = aWhoField;
00652 #if 0
00653   // This isn't saved in the config anyway
00654   mStorage->writeConfig();
00655 #endif
00656 }
00657 
00658 void KMFolder::setUserWhoField( const QString& whoField, bool writeConfig )
00659 {
00660   if ( mUserWhoField == whoField )
00661     return;
00662   if ( whoField.isEmpty() )
00663   {
00664     // default setting
00665     const KPIM::Identity & identity =
00666       kmkernel->identityManager()->identityForUoidOrDefault( mIdentity );
00667 
00668     if ( isSystemFolder() && folderType() != KMFolderTypeImap ) {
00669       // local system folders
00670       if ( this == kmkernel->inboxFolder() ||
00671            this == kmkernel->trashFolder() )
00672         mWhoField = "From";
00673       if ( this == kmkernel->outboxFolder() ||
00674            this == kmkernel->sentFolder() ||
00675            this == kmkernel->draftsFolder() ||
00676            this == kmkernel->templatesFolder() )
00677         mWhoField = "To";
00678     } else if ( identity.drafts() == idString() ||
00679                 identity.templates() == idString() ||
00680                 identity.fcc() == idString() )
00681       // drafts, templates or sent of the identity
00682       mWhoField = "To";
00683     else
00684       mWhoField = "From";
00685   } else if ( whoField == "From" || whoField == "To" )
00686     // set the whoField according to the user-setting
00687     mWhoField = whoField;
00688   else {
00689     // this should not happen...
00690     kdDebug(5006) << "Illegal setting " << whoField << " for userWhoField!"
00691                   << endl;
00692     return; // don't use the value
00693   }
00694   mUserWhoField = whoField;
00695 
00696   if (writeConfig)
00697     mStorage->writeConfig();
00698   emit viewConfigChanged();
00699 }
00700 
00701 void KMFolder::correctUnreadMsgsCount()
00702 {
00703   mStorage->correctUnreadMsgsCount();
00704 }
00705 
00706 QString KMFolder::idString() const
00707 {
00708   KMFolderNode* folderNode = parent();
00709   if (!folderNode)
00710     return "";
00711   while ( folderNode->parent() )
00712     folderNode = folderNode->parent();
00713   QString myPath = path();
00714   int pathLen = myPath.length() - folderNode->path().length();
00715   QString relativePath = myPath.right( pathLen );
00716   if (!relativePath.isEmpty())
00717     relativePath = relativePath.right( relativePath.length() - 1 ) + "/";
00718   QString escapedName = name();
00719   /* Escape [ and ] as they are disallowed for kconfig sections and that is
00720      what the idString is primarily used for. */
00721   escapedName.replace( "[", "%(" );
00722   escapedName.replace( "]", "%)" );
00723   return relativePath + escapedName;
00724 }
00725 
00726 void KMFolder::setAutoExpire( bool enabled )
00727 {
00728   if( enabled != mExpireMessages ) {
00729     mExpireMessages = enabled;
00730     mStorage->writeConfig();
00731   }
00732 }
00733 
00734 void KMFolder::setUnreadExpireAge( int age )
00735 {
00736   if( age >= 0 && age != mUnreadExpireAge ) {
00737     mUnreadExpireAge = age;
00738     mStorage->writeConfig();
00739   }
00740 }
00741 
00742 void KMFolder::setUnreadExpireUnits( ExpireUnits units )
00743 {
00744   if (units >= expireNever && units < expireMaxUnits)
00745     mUnreadExpireUnits = units;
00746     mStorage->writeConfig();
00747 }
00748 
00749 void KMFolder::setReadExpireAge( int age )
00750 {
00751   if( age >= 0 && age != mReadExpireAge ) {
00752     mReadExpireAge = age;
00753     mStorage->writeConfig();
00754   }
00755 }
00756 
00757 void KMFolder::setReadExpireUnits( ExpireUnits units )
00758 {
00759   if (units >= expireNever && units <= expireMaxUnits)
00760     mReadExpireUnits = units;
00761     mStorage->writeConfig();
00762 }
00763 
00764 
00765 void KMFolder::setExpireAction( ExpireAction a )
00766 {
00767   if ( a != mExpireAction ) {
00768     mExpireAction = a;
00769     mStorage->writeConfig();
00770   }
00771 }
00772 
00773 void KMFolder::setExpireToFolderId( const QString& id )
00774 {
00775   if ( id != mExpireToFolderId ) {
00776     mExpireToFolderId = id;
00777     mStorage->writeConfig();
00778   }
00779 }
00780 
00781 
00782 static int daysToExpire( int number, ExpireUnits units )
00783 {
00784   switch (units) {
00785   case expireDays: // Days
00786     return number;
00787   case expireWeeks: // Weeks
00788     return number * 7;
00789   case expireMonths: // Months - this could be better rather than assuming 31day months.
00790     return number * 31;
00791   default: // this avoids a compiler warning (not handled enumeration values)
00792     ;
00793   }
00794   return -1;
00795 }
00796 
00797 void KMFolder::daysToExpire(int& unreadDays, int& readDays) {
00798   unreadDays = ::daysToExpire( getUnreadExpireAge(), getUnreadExpireUnits() );
00799   readDays = ::daysToExpire( getReadExpireAge(), getReadExpireUnits() );
00800 }
00801 
00802 void KMFolder::expireOldMessages( bool immediate )
00803 {
00804   KMail::ScheduledExpireTask* task = new KMail::ScheduledExpireTask(this, immediate);
00805   kmkernel->jobScheduler()->registerTask( task );
00806   if ( immediate ) {
00807     // #82259: compact after expiring.
00808     compact( CompactLater );
00809   }
00810 }
00811 
00812 void KMFolder::compact( CompactOptions options )
00813 {
00814   if ( options == CompactLater ) {
00815     KMail::ScheduledCompactionTask* task = new KMail::ScheduledCompactionTask(this, false);
00816     kmkernel->jobScheduler()->registerTask( task );
00817   } else {
00818     mStorage->compact( options == CompactSilentlyNow );
00819   }
00820 }
00821 
00822 KMFolder* KMFolder::trashFolder() const
00823 {
00824   return mStorage ? mStorage->trashFolder() : 0;
00825 }
00826 
00827 int KMFolder::writeIndex( bool createEmptyIndex )
00828 {
00829   return mStorage->writeIndex( createEmptyIndex );
00830 }
00831 
00832 void KMFolder::setStatus( int idx, KMMsgStatus status, bool toggle )
00833 {
00834   mStorage->setStatus( idx, status, toggle );
00835 }
00836 
00837 void KMFolder::setStatus( QValueList<int>& ids, KMMsgStatus status,
00838                           bool toggle )
00839 {
00840   mStorage->setStatus( ids, status, toggle);
00841 }
00842 
00843 void KMFolder::setIconPaths( const QString &normalPath,
00844                              const QString &unreadPath )
00845 {
00846   mNormalIconPath = normalPath;
00847   mUnreadIconPath = unreadPath;
00848   mStorage->writeConfig();
00849   emit iconsChanged();
00850 }
00851 
00852 void KMFolder::removeJobs()
00853 {
00854   mStorage->removeJobs();
00855 }
00856 
00857 int KMFolder::updateIndex()
00858 {
00859   return mStorage->updateIndex();
00860 }
00861 
00862 void KMFolder::reallyAddMsg( KMMessage* aMsg )
00863 {
00864   mStorage->reallyAddMsg( aMsg );
00865 }
00866 
00867 void KMFolder::reallyAddCopyOfMsg( KMMessage* aMsg )
00868 {
00869   mStorage->reallyAddCopyOfMsg( aMsg );
00870 }
00871 
00872 void KMFolder::setShortcut( const KShortcut &sc )
00873 {
00874   if ( mShortcut != sc ) {
00875     mShortcut = sc;
00876     emit shortcutChanged( this );
00877   }
00878 }
00879 
00880 bool KMFolder::isMoveable() const
00881 {
00882   return !isSystemFolder();
00883 }
00884 
00885 void KMFolder::slotContentsTypeChanged( KMail::FolderContentsType type )
00886 {
00887   kmkernel->iCalIface().folderContentsTypeChanged( this, type );
00888   emit iconsChanged();
00889 }
00890 
00891 void KMFolder::slotFolderSizeChanged()
00892 {
00893   emit folderSizeChanged( this );
00894   KMFolder* papa = parent()->manager()->parentFolder( this );
00895   if ( papa && papa != this ) {
00896     papa->slotFolderSizeChanged();
00897   }
00898 }
00899 
00900 bool KMFolder::isValidName( const QString &folderName, QString &message )
00901 {
00902   KMFolderType fldType = folderType();
00903 
00904   // names of local folders must not contain a '/'
00905   if ( folderName.find( '/' ) != -1 &&
00906        fldType != KMFolderTypeImap &&
00907        fldType != KMFolderTypeCachedImap ) {
00908     message = i18n( "Folder names cannot contain the / (slash) character; please choose another folder name." );
00909     return false;
00910   }
00911 
00912   // folder names must not start with a '.'
00913   if ( folderName.startsWith( "." ) ) {
00914     message = i18n( "Folder names cannot start with a . (dot) character; please choose another folder name." );
00915     return false;
00916   }
00917 
00918   // names of IMAP folders must not contain the folder delimiter
00919   if ( fldType == KMFolderTypeImap || fldType == KMFolderTypeCachedImap ) {
00920     QString delimiter;
00921     if ( fldType == KMFolderTypeImap ) {
00922       KMAcctImap *ai = static_cast<KMFolderImap*>( mStorage )->account();
00923       if ( ai ) {
00924         delimiter = ai->delimiterForFolder( mStorage );
00925       }
00926     } else {
00927       KMAcctCachedImap *ai = static_cast<KMFolderCachedImap*>( mStorage )->account();
00928       if ( ai ) {
00929         delimiter = ai->delimiterForFolder( mStorage );
00930       }
00931     }
00932     if ( !delimiter.isEmpty() && folderName.find( delimiter ) != -1 ) {
00933       message = i18n( "Your IMAP server does not allow the character '%1'; please choose another folder name." ).arg( delimiter );
00934       return false;
00935     }
00936   }
00937   return true;
00938 }
00939 
00940 #include "kmfolder.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys