00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <config.h>
00036
00037 #include "folderstorage.h"
00038 #include "kmfolder.h"
00039
00040 #include "kmfolderimap.h"
00041 #include "undostack.h"
00042 #include "kmmsgdict.h"
00043 #include "kmfoldermgr.h"
00044 #include "kmkernel.h"
00045 #include "kmcommands.h"
00046 #include "kmailicalifaceimpl.h"
00047
00048 #include <klocale.h>
00049 #include <kconfig.h>
00050 #include <kdebug.h>
00051
00052 #include <qfile.h>
00053 #include <qregexp.h>
00054
00055 #include <mimelib/mimepp.h>
00056 #include <errno.h>
00057 #include "globalsettings.h"
00058
00059
00060
00061 FolderStorage::FolderStorage( KMFolder* folder, const char* aName )
00062 : QObject( folder, aName ), mFolder( folder )
00063 {
00064 mOpenCount = 0;
00065 mQuiet = 0;
00066 mChanged = FALSE;
00067 mAutoCreateIndex= TRUE;
00068 folder->setType( "plain" );
00069 mAcctList = 0;
00070 mDirty = FALSE;
00071 mUnreadMsgs = -1;
00072 mGuessedUnreadMsgs = -1;
00073 mTotalMsgs = -1;
00074 needsCompact = FALSE;
00075 mConvertToUtf8 = FALSE;
00076 mCompactable = TRUE;
00077 mNoContent = FALSE;
00078 mNoChildren = FALSE;
00079 mRDict = 0;
00080 mDirtyTimer = new QTimer(this);
00081 connect(mDirtyTimer, SIGNAL(timeout()),
00082 this, SLOT(updateIndex()));
00083 mHasChildren = HasNoChildren;
00084 mContentsType = KMail::ContentsTypeMail;
00085 }
00086
00087
00088 FolderStorage::~FolderStorage()
00089 {
00090 delete mAcctList;
00091 mJobList.setAutoDelete( true );
00092 QObject::disconnect( SIGNAL(destroyed(QObject*)), this, 0 );
00093 mJobList.clear();
00094 KMMsgDict::deleteRentry(mRDict);
00095 }
00096
00097
00098
00099 QString FolderStorage::dotEscape(const QString& aStr)
00100 {
00101 if (aStr[0] != '.') return aStr;
00102 return aStr.left(aStr.find(QRegExp("[^\\.]"))) + aStr;
00103 }
00104
00105 void FolderStorage::addJob( FolderJob* job ) const
00106 {
00107 QObject::connect( job, SIGNAL(destroyed(QObject*)),
00108 SLOT(removeJob(QObject*)) );
00109 mJobList.append( job );
00110 }
00111
00112 void FolderStorage::removeJob( QObject* job )
00113 {
00114 mJobList.remove( static_cast<FolderJob*>( job ) );
00115 }
00116
00117
00118
00119 QString FolderStorage::location() const
00120 {
00121 QString sLocation(const_cast<FolderStorage*>(this)->folder()->path());
00122
00123 if (!sLocation.isEmpty()) sLocation += '/';
00124 sLocation += dotEscape(fileName());
00125
00126 return sLocation;
00127 }
00128
00129 QString FolderStorage::fileName() const
00130 {
00131 return mFolder->name();
00132 }
00133
00134
00135
00136
00137 void FolderStorage::setAutoCreateIndex(bool autoIndex)
00138 {
00139 mAutoCreateIndex = autoIndex;
00140 }
00141
00142
00143 void FolderStorage::setDirty(bool f)
00144 {
00145 mDirty = f;
00146 if (mDirty && mAutoCreateIndex)
00147 mDirtyTimer->changeInterval( mDirtyTimerInterval );
00148 else
00149 mDirtyTimer->stop();
00150 }
00151
00152
00153 void FolderStorage::markNewAsUnread()
00154 {
00155 KMMsgBase* msgBase;
00156 int i;
00157
00158 for (i=0; i< count(); ++i)
00159 {
00160 if (!(msgBase = getMsgBase(i))) continue;
00161 if (msgBase->isNew())
00162 {
00163 msgBase->setStatus(KMMsgStatusUnread);
00164 msgBase->setDirty(TRUE);
00165 }
00166 }
00167 }
00168
00169 void FolderStorage::markUnreadAsRead()
00170 {
00171 KMMsgBase* msgBase;
00172 SerNumList serNums;
00173
00174 for (int i=count()-1; i>=0; --i)
00175 {
00176 msgBase = getMsgBase(i);
00177 assert(msgBase);
00178 if (msgBase->isNew() || msgBase->isUnread())
00179 {
00180 serNums.append( msgBase->getMsgSerNum() );
00181 }
00182 }
00183 if (serNums.empty())
00184 return;
00185
00186 KMCommand *command = new KMSetStatusCommand( KMMsgStatusRead, serNums );
00187 command->start();
00188 }
00189
00190
00191 void FolderStorage::quiet(bool beQuiet)
00192 {
00193 if (beQuiet)
00194 mQuiet++;
00195 else {
00196 mQuiet--;
00197 if (mQuiet <= 0)
00198 {
00199 mQuiet = 0;
00200 if (mChanged)
00201 emit changed();
00202 mChanged = FALSE;
00203 }
00204 }
00205 }
00206
00207
00208
00209
00210
00212 int operator<( KMMsgBase & m1, KMMsgBase & m2 )
00213 {
00214 return (m1.date() < m2.date());
00215 }
00216
00218 int operator==( KMMsgBase & m1, KMMsgBase & m2 )
00219 {
00220 return (m1.date() == m2.date());
00221 }
00222
00223
00224
00225 int FolderStorage::expungeOldMsg(int days)
00226 {
00227 int i, msgnb=0;
00228 time_t msgTime, maxTime;
00229 const KMMsgBase* mb;
00230 QValueList<int> rmvMsgList;
00231
00232 maxTime = time(0) - days * 3600 * 24;
00233
00234 for (i=count()-1; i>=0; i--) {
00235 mb = getMsgBase(i);
00236 assert(mb);
00237 msgTime = mb->date();
00238
00239 if (msgTime < maxTime) {
00240
00241 removeMsg( i );
00242 msgnb++;
00243 }
00244 }
00245 return msgnb;
00246 }
00247
00248
00249 void FolderStorage::emitMsgAddedSignals(int idx)
00250 {
00251 Q_UINT32 serNum = kmkernel->msgDict()->getMsgSerNum( folder() , idx );
00252 if (!mQuiet) {
00253 emit msgAdded(idx);
00254 } else {
00255 mChanged=true;
00256 }
00257 emit msgAdded( folder(), serNum );
00258 }
00259
00260
00261 bool FolderStorage::canAddMsgNow(KMMessage* aMsg, int* aIndex_ret)
00262 {
00263 if (aIndex_ret) *aIndex_ret = -1;
00264 KMFolder *msgParent = aMsg->parent();
00265
00266
00267 if (aMsg->transferInProgress() && msgParent)
00268 return false;
00269 if (!aMsg->isComplete() && msgParent && msgParent->folderType() == KMFolderTypeImap)
00270 {
00271 FolderJob *job = msgParent->createJob(aMsg);
00272 connect(job, SIGNAL(messageRetrieved(KMMessage*)),
00273 SLOT(reallyAddMsg(KMMessage*)));
00274 job->start();
00275 aMsg->setTransferInProgress(TRUE);
00276 return FALSE;
00277 }
00278 return TRUE;
00279 }
00280
00281
00282
00283 void FolderStorage::reallyAddMsg(KMMessage* aMsg)
00284 {
00285 if (!aMsg)
00286 return;
00287 aMsg->setTransferInProgress(FALSE);
00288 KMFolder *aFolder = aMsg->parent();
00289 int index;
00290 ulong serNum = aMsg->getMsgSerNum();
00291 bool undo = aMsg->enableUndo();
00292 addMsg(aMsg, &index);
00293 if (index < 0) return;
00294 unGetMsg(index);
00295 if (undo)
00296 {
00297 kmkernel->undoStack()->pushSingleAction( serNum, aFolder, folder() );
00298 }
00299 }
00300
00301
00302
00303 void FolderStorage::reallyAddCopyOfMsg(KMMessage* aMsg)
00304 {
00305 aMsg->setParent( 0 );
00306 aMsg->setTransferInProgress( false );
00307 addMsg( aMsg );
00308 unGetMsg( count() - 1 );
00309 }
00310
00311 int FolderStorage::find( const KMMessage * msg ) const {
00312 return find( &msg->toMsgBase() );
00313 }
00314
00315
00316 void FolderStorage::removeMsg(const QPtrList<KMMsgBase>& msgList, bool imapQuiet)
00317 {
00318 for( QPtrListIterator<KMMsgBase> it( msgList ); *it; ++it )
00319 {
00320 int idx = find(it.current());
00321 assert( idx != -1);
00322 removeMsg(idx, imapQuiet);
00323 }
00324 }
00325
00326
00327 void FolderStorage::removeMsg(const QPtrList<KMMessage>& msgList, bool imapQuiet)
00328 {
00329 for( QPtrListIterator<KMMessage> it( msgList ); *it; ++it )
00330 {
00331 int idx = find(it.current());
00332 assert( idx != -1);
00333 removeMsg(idx, imapQuiet);
00334 }
00335 }
00336
00337
00338 void FolderStorage::removeMsg(int idx, bool)
00339 {
00340
00341 if(idx < 0)
00342 {
00343 kdDebug(5006) << "FolderStorage::removeMsg() : idx < 0\n" << endl;
00344 return;
00345 }
00346
00347 KMMsgBase* mb = getMsgBase(idx);
00348
00349 Q_UINT32 serNum = kmkernel->msgDict()->getMsgSerNum( folder(), idx );
00350 if (serNum != 0)
00351 emit msgRemoved( folder(), serNum );
00352 mb = takeIndexEntry( idx );
00353
00354 setDirty( true );
00355 needsCompact=true;
00356
00357 if (mb->isUnread() || mb->isNew() ||
00358 (folder() == kmkernel->outboxFolder())) {
00359 --mUnreadMsgs;
00360 emit numUnreadMsgsChanged( folder() );
00361 }
00362 --mTotalMsgs;
00363
00364 QString msgIdMD5 = mb->msgIdMD5();
00365 QString strippedSubjMD5 = mb->strippedSubjectMD5();
00366 if (strippedSubjMD5.isEmpty()) {
00367 mb->initStrippedSubjectMD5();
00368 strippedSubjMD5 = mb->strippedSubjectMD5();
00369 }
00370 emit msgRemoved(idx, msgIdMD5, strippedSubjMD5);
00371 emit msgRemoved( folder() );
00372 }
00373
00374
00375
00376 KMMessage* FolderStorage::take(int idx)
00377 {
00378 KMMsgBase* mb;
00379 KMMessage* msg;
00380
00381 assert(idx>=0 && idx<=count());
00382
00383 mb = getMsgBase(idx);
00384 if (!mb) return 0;
00385 if (!mb->isMessage()) readMsg(idx);
00386 Q_UINT32 serNum = kmkernel->msgDict()->getMsgSerNum( folder(), idx );
00387 emit msgRemoved( folder(), serNum );
00388
00389 msg = (KMMessage*)takeIndexEntry(idx);
00390
00391 if (msg->isUnread() || msg->isNew() ||
00392 ( folder() == kmkernel->outboxFolder() )) {
00393 --mUnreadMsgs;
00394 emit numUnreadMsgsChanged( folder() );
00395 }
00396 --mTotalMsgs;
00397 msg->setParent(0);
00398 setDirty( true );
00399 needsCompact=true;
00400 QString msgIdMD5 = msg->msgIdMD5();
00401 QString strippedSubjMD5 = msg->strippedSubjectMD5();
00402 if (strippedSubjMD5.isEmpty()) {
00403 msg->initStrippedSubjectMD5();
00404 strippedSubjMD5 = msg->strippedSubjectMD5();
00405 }
00406 emit msgRemoved(idx, msgIdMD5, strippedSubjMD5);
00407 emit msgRemoved( folder() );
00408
00409 return msg;
00410 }
00411
00412 void FolderStorage::take(QPtrList<KMMessage> msgList)
00413 {
00414 for ( KMMessage* msg = msgList.first(); msg; msg = msgList.next() )
00415 {
00416 if (msg->parent())
00417 {
00418 int idx = msg->parent()->find(msg);
00419 assert( idx != -1);
00420 FolderStorage::take(idx);
00421 }
00422 }
00423 }
00424
00425
00426
00427 KMMessage* FolderStorage::getMsg(int idx)
00428 {
00429 if(!(idx >= 0 && idx <= count()))
00430 return 0;
00431
00432 KMMsgBase* mb = getMsgBase(idx);
00433 if (!mb) return 0;
00434
00435 KMMessage *msg = 0;
00436 bool undo = mb->enableUndo();
00437 if (mb->isMessage()) {
00438 msg = ((KMMessage*)mb);
00439 } else {
00440 QString mbSubject = mb->subject();
00441 msg = readMsg(idx);
00442
00443 if (mCompactable && (!msg || (msg->subject().isEmpty() != mbSubject.isEmpty()))) {
00444 kdDebug(5006) << "Error: " << location() <<
00445 " Index file is inconsistent with folder file. This should never happen." << endl;
00446 mCompactable = FALSE;
00447 writeConfig();
00448 }
00449
00450 }
00451 msg->setEnableUndo(undo);
00452
00453
00454
00455 if (msg->getMsgSerNum() == 0) {
00456 msg->setMsgSerNum(kmkernel->msgDict()->insert(0, msg, idx));
00457 kdDebug(5006) << "Serial number generated for message in folder "
00458 << label() << endl;
00459 }
00460 msg->setComplete( true );
00461 return msg;
00462 }
00463
00464
00465 KMMessage* FolderStorage::readTemporaryMsg(int idx)
00466 {
00467 if(!(idx >= 0 && idx <= count()))
00468 return 0;
00469
00470 KMMsgBase* mb = getMsgBase(idx);
00471 if (!mb) return 0;
00472
00473 unsigned long sernum = mb->getMsgSerNum();
00474
00475 KMMessage *msg = 0;
00476 bool undo = mb->enableUndo();
00477 if (mb->isMessage()) {
00478
00479 msg = new KMMessage(*(KMMessage*)mb);
00480 msg->setMsgSerNum(sernum);
00481 } else {
00482
00483 msg = new KMMessage(*(KMMsgInfo*)mb);
00484 msg->setMsgSerNum(sernum);
00485 msg->fromDwString(getDwString(idx));
00486 }
00487 msg->setEnableUndo(undo);
00488 msg->setComplete( true );
00489 return msg;
00490 }
00491
00492
00493
00494 KMMsgInfo* FolderStorage::unGetMsg(int idx)
00495 {
00496 KMMsgBase* mb;
00497
00498 if(!(idx >= 0 && idx <= count()))
00499 return 0;
00500
00501 mb = getMsgBase(idx);
00502 if (!mb) return 0;
00503
00504
00505 if (mb->isMessage()) {
00506
00507
00508 KMMessage *msg = static_cast<KMMessage*>(mb);
00509 if ( msg->transferInProgress() ) return 0;
00510 ignoreJobsForMessage( msg );
00511 return setIndexEntry( idx, msg );
00512 }
00513
00514 return 0;
00515 }
00516
00517
00518
00519 bool FolderStorage::isMessage(int idx)
00520 {
00521 KMMsgBase* mb;
00522 if (!(idx >= 0 && idx <= count())) return FALSE;
00523 mb = getMsgBase(idx);
00524 return (mb && mb->isMessage());
00525 }
00526
00527
00528 FolderJob* FolderStorage::createJob( KMMessage *msg, FolderJob::JobType jt,
00529 KMFolder *folder, QString partSpecifier,
00530 const AttachmentStrategy *as ) const
00531 {
00532 FolderJob * job = doCreateJob( msg, jt, folder, partSpecifier, as );
00533 if ( job )
00534 addJob( job );
00535 return job;
00536 }
00537
00538
00539 FolderJob* FolderStorage::createJob( QPtrList<KMMessage>& msgList, const QString& sets,
00540 FolderJob::JobType jt, KMFolder *folder ) const
00541 {
00542 FolderJob * job = doCreateJob( msgList, sets, jt, folder );
00543 if ( job )
00544 addJob( job );
00545 return job;
00546 }
00547
00548
00549 int FolderStorage::moveMsg(KMMessage* aMsg, int* aIndex_ret)
00550 {
00551 assert(aMsg != 0);
00552 KMFolder* msgParent = aMsg->parent();
00553
00554 if (msgParent)
00555 msgParent->open();
00556
00557 open();
00558 int rc = addMsg(aMsg, aIndex_ret);
00559 close();
00560
00561 if (msgParent)
00562 msgParent->close();
00563
00564 return rc;
00565 }
00566
00567
00568 int FolderStorage::moveMsg(QPtrList<KMMessage> msglist, int* aIndex_ret)
00569 {
00570 KMMessage* aMsg = msglist.first();
00571 assert(aMsg != 0);
00572 KMFolder* msgParent = aMsg->parent();
00573
00574 if (msgParent)
00575 msgParent->open();
00576
00577 open();
00578
00579 int rc = static_cast<KMFolderImap*>(this)->addMsg(msglist, aIndex_ret);
00580 close();
00581
00582 if (msgParent)
00583 msgParent->close();
00584
00585 return rc;
00586 }
00587
00588
00589
00590 int FolderStorage::rename(const QString& newName, KMFolderDir *newParent)
00591 {
00592 QString oldLoc, oldIndexLoc, oldIdsLoc, newLoc, newIndexLoc, newIdsLoc;
00593 QString oldSubDirLoc, newSubDirLoc;
00594 QString oldName;
00595 int rc=0, openCount=mOpenCount;
00596 KMFolderDir *oldParent;
00597
00598 assert(!newName.isEmpty());
00599
00600 oldLoc = location();
00601 oldIndexLoc = indexLocation();
00602 oldSubDirLoc = folder()->subdirLocation();
00603 if (kmkernel->msgDict())
00604 oldIdsLoc = kmkernel->msgDict()->getFolderIdsLocation( folder() );
00605 QString oldConfigString = "Folder-" + folder()->idString();
00606
00607 close(TRUE);
00608
00609 oldName = folder()->fileName();
00610 oldParent = folder()->parent();
00611 if (newParent)
00612 folder()->setParent( newParent );
00613
00614 folder()->setName(newName);
00615 newLoc = location();
00616 newIndexLoc = indexLocation();
00617 newSubDirLoc = folder()->subdirLocation();
00618 if (kmkernel->msgDict())
00619 newIdsLoc = kmkernel->msgDict()->getFolderIdsLocation( folder() );
00620
00621 if (::rename(QFile::encodeName(oldLoc), QFile::encodeName(newLoc))) {
00622 folder()->setName(oldName);
00623 folder()->setParent(oldParent);
00624 rc = errno;
00625 }
00626 else {
00627
00628 if (!oldIndexLoc.isEmpty()) {
00629 ::rename(QFile::encodeName(oldIndexLoc), QFile::encodeName(newIndexLoc));
00630 ::rename(QFile::encodeName(oldIndexLoc) + ".sorted",
00631 QFile::encodeName(newIndexLoc) + ".sorted");
00632 }
00633
00634
00635 if (!oldIdsLoc.isEmpty())
00636 ::rename(QFile::encodeName(oldIdsLoc), QFile::encodeName(newIdsLoc));
00637
00638
00639 KMFolderDir* child = 0;
00640 if( folder() )
00641 child = folder()->child();
00642
00643 if (!::rename(QFile::encodeName(oldSubDirLoc), QFile::encodeName(newSubDirLoc) )) {
00644
00645
00646
00647 if( child && ( oldName != newName ) ) {
00648 child->setName( "." + QFile::encodeName(newName) + ".directory" );
00649 }
00650 }
00651
00652
00653
00654 if (newParent) {
00655 if (oldParent->findRef( folder() ) != -1)
00656 oldParent->take();
00657 newParent->inSort( folder() );
00658 if ( child ) {
00659 if ( child->parent()->findRef( child ) != -1 )
00660 child->parent()->take();
00661 newParent->inSort( child );
00662 child->setParent( newParent );
00663 }
00664 }
00665 }
00666
00667 if (openCount > 0)
00668 {
00669 open();
00670 mOpenCount = openCount;
00671 }
00672 writeConfig();
00673
00674
00675 KMKernel::config()->deleteGroup( oldConfigString );
00676
00677 emit locationChanged( oldLoc, newLoc );
00678 emit nameChanged();
00679 return rc;
00680 }
00681
00682
00683
00684 void FolderStorage::remove()
00685 {
00686 assert(!folder()->name().isEmpty());
00687
00688 clearIndex(true, true);
00689 close(TRUE);
00690
00691 if (kmkernel->msgDict()) kmkernel->msgDict()->removeFolderIds( folder() );
00692 unlink(QFile::encodeName(indexLocation()) + ".sorted");
00693 unlink(QFile::encodeName(indexLocation()));
00694
00695 int rc = removeContents();
00696
00697 needsCompact = false;
00698
00699
00700 KConfig* config = KMKernel::config();
00701 config->deleteGroup( "Folder-" + folder()->idString() );
00702
00703 emit removed(folder(), (rc ? false : true));
00704 }
00705
00706
00707
00708 int FolderStorage::expunge()
00709 {
00710 int openCount = mOpenCount;
00711
00712 assert(!folder()->name().isEmpty());
00713
00714 clearIndex(true, true);
00715 close(TRUE);
00716
00717 kmkernel->msgDict()->removeFolderIds( folder() );
00718 if (mAutoCreateIndex)
00719 truncateIndex();
00720 else unlink(QFile::encodeName(indexLocation()));
00721
00722 int rc = expungeContents();
00723 if (rc) return rc;
00724
00725 mDirty = FALSE;
00726 needsCompact = false;
00727
00728 if (openCount > 0)
00729 {
00730 open();
00731 mOpenCount = openCount;
00732 }
00733
00734 mUnreadMsgs = 0;
00735 mTotalMsgs = 0;
00736 emit numUnreadMsgsChanged( folder() );
00737 if (mAutoCreateIndex)
00738 writeConfig();
00739 emit changed();
00740 emit expunged( folder() );
00741
00742 return 0;
00743 }
00744
00745
00746
00747 const char* FolderStorage::type() const
00748 {
00749 if (mAcctList) return "In";
00750 return folder()->KMFolderNode::type();
00751 }
00752
00753
00754
00755 QString FolderStorage::label() const
00756 {
00757 return folder()->label();
00758 }
00759
00760 int FolderStorage::count(bool cache) const
00761 {
00762 if (cache && mTotalMsgs != -1)
00763 return mTotalMsgs;
00764 else
00765 return -1;
00766 }
00767
00768
00769 int FolderStorage::countUnread()
00770 {
00771 if (mGuessedUnreadMsgs > -1)
00772 return mGuessedUnreadMsgs;
00773 if (mUnreadMsgs > -1)
00774 return mUnreadMsgs;
00775
00776 readConfig();
00777
00778 if (mUnreadMsgs > -1)
00779 return mUnreadMsgs;
00780
00781 open();
00782 int unread = mUnreadMsgs;
00783 close();
00784 return (unread > 0) ? unread : 0;
00785 }
00786
00787
00788 void FolderStorage::msgStatusChanged(const KMMsgStatus oldStatus,
00789 const KMMsgStatus newStatus, int idx)
00790 {
00791 int oldUnread = 0;
00792 int newUnread = 0;
00793
00794 if (oldStatus & KMMsgStatusUnread || oldStatus & KMMsgStatusNew ||
00795 (folder() == kmkernel->outboxFolder()))
00796 oldUnread = 1;
00797 if (newStatus & KMMsgStatusUnread || newStatus & KMMsgStatusNew ||
00798 (folder() == kmkernel->outboxFolder()))
00799 newUnread = 1;
00800 int deltaUnread = newUnread - oldUnread;
00801
00802 mDirtyTimer->changeInterval(mDirtyTimerInterval);
00803 if (deltaUnread != 0) {
00804 if (mUnreadMsgs < 0) mUnreadMsgs = 0;
00805 mUnreadMsgs += deltaUnread;
00806 if ( !mQuiet )
00807 emit numUnreadMsgsChanged( folder() );
00808 else
00809 mChanged = true;
00810 Q_UINT32 serNum = kmkernel->msgDict()->getMsgSerNum(folder(), idx);
00811 emit msgChanged( folder(), serNum, deltaUnread );
00812 }
00813 }
00814
00815
00816 void FolderStorage::headerOfMsgChanged(const KMMsgBase* aMsg, int idx)
00817 {
00818 if (idx < 0)
00819 idx = aMsg->parent()->find( aMsg );
00820 if (idx >= 0 && !mQuiet)
00821 emit msgHeaderChanged(folder(), idx);
00822 else
00823 mChanged = true;
00824 }
00825
00826
00827 void FolderStorage::readConfig()
00828 {
00829
00830 KConfig* config = KMKernel::config();
00831 KConfigGroupSaver saver(config, "Folder-" + folder()->idString());
00832 if (mUnreadMsgs == -1)
00833 mUnreadMsgs = config->readNumEntry("UnreadMsgs", -1);
00834 if (mTotalMsgs == -1)
00835 mTotalMsgs = config->readNumEntry("TotalMsgs", -1);
00836 mCompactable = config->readBoolEntry("Compactable", TRUE);
00837
00838 int type = config->readNumEntry( "ContentsType", 0 );
00839 if ( type < 0 || type > KMail::ContentsTypeLast ) type = 0;
00840 setContentsType( static_cast<KMail::FolderContentsType>( type ) );
00841
00842 if( folder() ) folder()->readConfig( config );
00843 }
00844
00845
00846 void FolderStorage::writeConfig()
00847 {
00848 KConfig* config = KMKernel::config();
00849 KConfigGroupSaver saver(config, "Folder-" + folder()->idString());
00850 config->writeEntry("UnreadMsgs", mGuessedUnreadMsgs == -1 ? mUnreadMsgs : -1);
00851 config->writeEntry("TotalMsgs", mTotalMsgs);
00852 config->writeEntry("Compactable", mCompactable);
00853 config->writeEntry("ContentsType", mContentsType);
00854
00855
00856 if( folder() ) folder()->writeConfig( config );
00857
00858 GlobalSettings::self()->requestSync();
00859 }
00860
00861
00862 void FolderStorage::correctUnreadMsgsCount()
00863 {
00864 open();
00865 close();
00866 emit numUnreadMsgsChanged( folder() );
00867 }
00868
00869
00870 void FolderStorage::fillMsgDict(KMMsgDict *dict)
00871 {
00872 fillDictFromIndex(dict);
00873 }
00874
00875
00876 int FolderStorage::writeMsgDict(KMMsgDict *dict)
00877 {
00878 int ret = 0;
00879 if (!dict)
00880 dict = kmkernel->msgDict();
00881 if (dict)
00882 ret = dict->writeFolderIds(folder());
00883 return ret;
00884 }
00885
00886
00887 int FolderStorage::touchMsgDict()
00888 {
00889 int ret = 0;
00890 KMMsgDict *dict = kmkernel->msgDict();
00891 if (dict)
00892 ret = dict->touchFolderIds(folder());
00893 return ret;
00894 }
00895
00896
00897 int FolderStorage::appendtoMsgDict(int idx)
00898 {
00899 int ret = 0;
00900 KMMsgDict *dict = kmkernel->msgDict();
00901 if (dict) {
00902 if (count() == 1) {
00903 ret = dict->writeFolderIds(folder());
00904 } else {
00905 ret = dict->appendtoFolderIds(folder(), idx);
00906 }
00907 }
00908 return ret;
00909 }
00910
00911
00912 void FolderStorage::setStatus(int idx, KMMsgStatus status, bool toggle)
00913 {
00914 KMMsgBase *msg = getMsgBase(idx);
00915 if ( msg ) {
00916 if (toggle)
00917 msg->toggleStatus(status, idx);
00918 else
00919 msg->setStatus(status, idx);
00920 }
00921 }
00922
00923 void FolderStorage::setRDict(KMMsgDictREntry *rentry) {
00924 if (rentry == mRDict)
00925 return;
00926 KMMsgDict::deleteRentry(mRDict);
00927 mRDict = rentry;
00928 }
00929
00930
00931 void FolderStorage::setStatus(QValueList<int>& ids, KMMsgStatus status, bool toggle)
00932 {
00933 for ( QValueList<int>::Iterator it = ids.begin(); it != ids.end(); ++it )
00934 {
00935 FolderStorage::setStatus(*it, status, toggle);
00936 }
00937 }
00938
00939 void FolderStorage::ignoreJobsForMessage( KMMessage *msg )
00940 {
00941 if ( !msg || msg->transferInProgress() )
00942 return;
00943
00944 QPtrListIterator<FolderJob> it( mJobList );
00945 while ( it.current() )
00946 {
00947
00948
00949
00950 if ( it.current()->msgList().first() == msg )
00951 {
00952 FolderJob* job = it.current();
00953 mJobList.remove( job );
00954 delete job;
00955 } else
00956 ++it;
00957 }
00958 }
00959
00960
00961 void FolderStorage::removeJobs()
00962 {
00963 mJobList.setAutoDelete( true );
00964 mJobList.clear();
00965 mJobList.setAutoDelete( false );
00966 }
00967
00968
00969 size_t FolderStorage::crlf2lf( char* str, const size_t strLen )
00970 {
00971 if ( !str || strLen == 0 ) return 0;
00972
00973 const char* source = str;
00974 const char* sourceEnd = source + strLen;
00975
00976
00977 for ( ; source < sourceEnd - 1; ++source ) {
00978 if ( *source == '\r' && *( source + 1 ) == '\n' )
00979 break;
00980 }
00981
00982 if ( source == sourceEnd - 1 ) {
00983
00984 return strLen;
00985 }
00986
00987
00988 char* target = const_cast<char*>( source );
00989 ++source;
00990 for ( ; source < sourceEnd; ++source ) {
00991 if ( *source != '\r' || *( source + 1 ) != '\n' )
00992 *target++ = *source;
00993 }
00994 *target = '\0';
00995 return target - str;
00996 }
00997
00998
00999 void FolderStorage::updateChildrenState()
01000 {
01001 if ( folder() && folder()->child() )
01002 {
01003 if ( kmkernel->folderMgr()->folderCount( folder()->child() ) > 0 )
01004 setHasChildren( HasChildren );
01005 else
01006 setHasChildren( HasNoChildren );
01007 }
01008 }
01009
01010
01011 void FolderStorage::setNoChildren( bool aNoChildren )
01012 {
01013 mNoChildren = aNoChildren;
01014 if ( aNoChildren )
01015 setHasChildren( HasNoChildren );
01016 }
01017
01018
01019 void FolderStorage::setContentsType( KMail::FolderContentsType type, bool quiet )
01020 {
01021 if ( type != mContentsType ) {
01022 mContentsType = type;
01023 if ( !quiet )
01024 emit contentsTypeChanged( type );
01025 }
01026 }
01027
01028 #include "folderstorage.moc"