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 <tdelocale.h> 00042 #include <tdeshortcut.h> 00043 #include <tdemessagebox.h> 00044 #include <tqfile.h> 00045 #include <tqfileinfo.h> 00046 00047 00048 KMFolder::KMFolder( KMFolderDir* aParent, const TQString& 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 TQFileInfo dirinfo; 00080 dirinfo.setFile( mStorage->location() ); 00081 if ( !dirinfo.exists() ) { 00082 int rc = mStorage->create(); 00083 TQString 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, TQT_SIGNAL( msgAdded( KMFolder*, TQ_UINT32 ) ), 00091 aParent->manager(), TQT_SIGNAL( msgAdded( KMFolder*, TQ_UINT32 ) ) ); 00092 connect( mStorage, TQT_SIGNAL( msgRemoved( KMFolder*, TQ_UINT32 ) ), 00093 parent()->manager(), TQT_SIGNAL( msgRemoved( KMFolder*, TQ_UINT32 ) ) ); 00094 connect( this, TQT_SIGNAL( msgChanged( KMFolder*, TQ_UINT32, int ) ), 00095 parent()->manager(), TQT_SIGNAL( msgChanged( KMFolder*, TQ_UINT32, int ) ) ); 00096 connect( this, TQT_SIGNAL( msgHeaderChanged( KMFolder*, int ) ), 00097 parent()->manager(), TQT_SIGNAL( msgHeaderChanged( KMFolder*, int ) ) ); 00098 connect( mStorage, TQT_SIGNAL( invalidated( KMFolder* ) ), 00099 parent()->manager(), TQT_SIGNAL( folderInvalidated( KMFolder* ) ) ); 00100 } 00101 00102 // Resend all mStorage signals 00103 connect( mStorage, TQT_SIGNAL( changed() ), TQT_SIGNAL( changed() ) ); 00104 connect( mStorage, TQT_SIGNAL( cleared() ), TQT_SIGNAL( cleared() ) ); 00105 connect( mStorage, TQT_SIGNAL( expunged( KMFolder* ) ), 00106 TQT_SIGNAL( expunged( KMFolder* ) ) ); 00107 connect( mStorage, TQT_SIGNAL( nameChanged() ), TQT_SIGNAL( nameChanged() ) ); 00108 connect( mStorage, TQT_SIGNAL( msgRemoved( KMFolder*, TQ_UINT32 ) ), 00109 TQT_SIGNAL( msgRemoved( KMFolder*, TQ_UINT32 ) ) ); 00110 connect( mStorage, TQT_SIGNAL( msgRemoved( int, TQString ) ), 00111 TQT_SIGNAL( msgRemoved( int, TQString ) ) ); 00112 connect( mStorage, TQT_SIGNAL( msgRemoved( KMFolder* ) ), 00113 TQT_SIGNAL( msgRemoved( KMFolder* ) ) ); 00114 connect( mStorage, TQT_SIGNAL( msgAdded( int ) ), TQT_SIGNAL( msgAdded( int ) ) ); 00115 connect( mStorage, TQT_SIGNAL( msgAdded( KMFolder*, TQ_UINT32 ) ), 00116 TQT_SIGNAL( msgAdded( KMFolder*, TQ_UINT32 ) ) ); 00117 connect( mStorage, TQT_SIGNAL( msgChanged( KMFolder*, TQ_UINT32 , int ) ), 00118 TQT_SIGNAL( msgChanged( KMFolder*, TQ_UINT32 , int ) ) ); 00119 connect( mStorage, TQT_SIGNAL( msgHeaderChanged( KMFolder*, int ) ), 00120 TQT_SIGNAL( msgHeaderChanged( KMFolder*, int ) ) ); 00121 connect( mStorage, TQT_SIGNAL( statusMsg( const TQString& ) ), 00122 TQT_SIGNAL( statusMsg( const TQString& ) ) ); 00123 connect( mStorage, TQT_SIGNAL( numUnreadMsgsChanged( KMFolder* ) ), 00124 TQT_SIGNAL( numUnreadMsgsChanged( KMFolder* ) ) ); 00125 connect( mStorage, TQT_SIGNAL( removed( KMFolder*, bool ) ), 00126 TQT_SIGNAL( removed( KMFolder*, bool ) ) ); 00127 connect( mStorage, TQT_SIGNAL(noContentChanged()), 00128 TQT_SIGNAL(noContentChanged()) ); 00129 connect( mStorage, TQT_SIGNAL(syncStateChanged()), 00130 TQT_SIGNAL(syncStateChanged()) ); 00131 00132 connect( mStorage, TQT_SIGNAL( contentsTypeChanged( KMail::FolderContentsType ) ), 00133 this, TQT_SLOT( slotContentsTypeChanged( KMail::FolderContentsType ) ) ); 00134 00135 connect( mStorage, TQT_SIGNAL( folderSizeChanged() ), 00136 this, TQT_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( TDEConfig* 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 TQString shortcut( config->readEntry( "Shortcut" ) ); 00194 if ( !shortcut.isEmpty() ) { 00195 TDEShortcut sc( shortcut ); 00196 setShortcut( sc ); 00197 } 00198 } 00199 00200 void KMFolder::writeConfig( TDEConfig* 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 TQString KMFolder::fileName() const 00239 { 00240 return mStorage ? mStorage->fileName() : TQString(); 00241 } 00242 00243 TQString KMFolder::location() const 00244 { 00245 return mStorage ? mStorage->location() : TQString(); 00246 } 00247 00248 TQString KMFolder::indexLocation() const 00249 { 00250 return mStorage ? mStorage->indexLocation() : TQString(); 00251 } 00252 00253 TQString KMFolder::subdirLocation() const 00254 { 00255 TQString 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 TQString childName = "." + fileName() + ".directory"; 00270 TQString childDir = path() + "/" + childName; 00271 if (access(TQFile::encodeName(childDir), W_OK) != 0) // Not there or not writable 00272 { 00273 if (mkdir(TQFile::encodeName(childDir), S_IRWXU) != 0 00274 && chmod(TQFile::encodeName(childDir), S_IRWXU) != 0) { 00275 TQString wmsg = TQString(" '%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, TQString partSpecifier, 00348 const AttachmentStrategy *as ) const 00349 { 00350 return mStorage->createJob( msg, jt, folder, partSpecifier, as ); 00351 } 00352 00353 FolderJob* KMFolder::createJob( TQPtrList<KMMessage>& msgList, 00354 const TQString& 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( TQPtrList<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( TQPtrList<KMMessage>& list, TQValueList<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( TQPtrList<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(TQPtrList<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 TQPtrListIterator<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 TQString& 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 TQString 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 TQString KMFolder::prettyURL() const 00594 { 00595 TQString 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 TQString 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 TQString(); 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 TQString& 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 TQString& 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 TQString KMFolder::idString() const 00706 { 00707 KMFolderNode* folderNode = parent(); 00708 if (!folderNode) 00709 return ""; 00710 while ( folderNode->parent() ) 00711 folderNode = folderNode->parent(); 00712 TQString myPath = path(); 00713 int pathLen = myPath.length() - folderNode->path().length(); 00714 TQString relativePath = myPath.right( pathLen ); 00715 if (!relativePath.isEmpty()) 00716 relativePath = relativePath.right( relativePath.length() - 1 ) + "/"; 00717 TQString escapedName = name(); 00718 /* Escape [ and ] as they are disallowed for tdeconfig 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 TQString& 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( TQValueList<int>& ids, KMMsgStatus status, 00837 bool toggle ) 00838 { 00839 mStorage->setStatus( ids, status, toggle); 00840 } 00841 00842 void KMFolder::setIconPaths( const TQString &normalPath, 00843 const TQString &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 TDEShortcut &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 TQString &folderName, TQString &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 TQString 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"