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 "listjob.h"
00047 using KMail::ListJob;
00048 #include "kmailicalifaceimpl.h"
00049
00050 #include <klocale.h>
00051 #include <kconfig.h>
00052 #include <kdebug.h>
00053
00054 #include <qfile.h>
00055 #include <qregexp.h>
00056
00057 #include <mimelib/mimepp.h>
00058 #include <errno.h>
00059
00060
00061
00062 FolderStorage::FolderStorage( KMFolder* folder, const char* aName )
00063 : QObject( folder, aName ), mFolder( folder )
00064 {
00065 mOpenCount = 0;
00066 mQuiet = 0;
00067 mChanged = FALSE;
00068 mAutoCreateIndex= TRUE;
00069 folder->setType( "plain" );
00070 mAcctList = 0;
00071 mDirty = FALSE;
00072 mUnreadMsgs = -1;
00073 mGuessedUnreadMsgs = -1;
00074 mTotalMsgs = -1;
00075 needsCompact = FALSE;
00076 mConvertToUtf8 = FALSE;
00077 mCompactable = TRUE;
00078 mNoContent = FALSE;
00079 mNoChildren = FALSE;
00080 mRDict = 0;
00081 mDirtyTimer = new QTimer(this);
00082 connect(mDirtyTimer, SIGNAL(timeout()),
00083 this, SLOT(updateIndex()));
00084 mHasChildren = HasNoChildren;
00085 mContentsType = KMail::ContentsTypeMail;
00086 }
00087
00088
00089 FolderStorage::~FolderStorage()
00090 {
00091 delete mAcctList;
00092 mJobList.setAutoDelete( true );
00093 QObject::disconnect( SIGNAL(destroyed(QObject*)), this, 0 );
00094 mJobList.clear();
00095 KMMsgDict::deleteRentry(mRDict);
00096 }
00097
00098
00099
00100 QString FolderStorage::dotEscape(const QString& aStr)
00101 {
00102 if (aStr[0] != '.') return aStr;
00103 return aStr.left(aStr.find(QRegExp("[^\\.]"))) + aStr;
00104 }
00105
00106 void FolderStorage::addJob( FolderJob* job ) const
00107 {
00108 QObject::connect( job, SIGNAL(destroyed(QObject*)),
00109 SLOT(removeJob(QObject*)) );
00110 mJobList.append( job );
00111 }
00112
00113 void FolderStorage::removeJob( QObject* job )
00114 {
00115 mJobList.remove( static_cast<FolderJob*>( job ) );
00116 }
00117
00118
00119
00120 QString FolderStorage::location() const
00121 {
00122 QString sLocation(const_cast<FolderStorage*>(this)->folder()->path());
00123
00124 if (!sLocation.isEmpty()) sLocation += '/';
00125 sLocation += dotEscape(fileName());
00126
00127 return sLocation;
00128 }
00129
00130 QString FolderStorage::fileName() const
00131 {
00132 return mFolder->name();
00133 }
00134
00135
00136
00137
00138 void FolderStorage::setAutoCreateIndex(bool autoIndex)
00139 {
00140 mAutoCreateIndex = autoIndex;
00141 }
00142
00143
00144 void FolderStorage::setDirty(bool f)
00145 {
00146 mDirty = f;
00147 if (mDirty && mAutoCreateIndex)
00148 mDirtyTimer->changeInterval( mDirtyTimerInterval );
00149 else
00150 mDirtyTimer->stop();
00151 }
00152
00153
00154 void FolderStorage::markNewAsUnread()
00155 {
00156 KMMsgBase* msgBase;
00157 int i;
00158
00159 for (i=0; i< count(); ++i)
00160 {
00161 if (!(msgBase = getMsgBase(i))) continue;
00162 if (msgBase->isNew())
00163 {
00164 msgBase->setStatus(KMMsgStatusUnread);
00165 msgBase->setDirty(TRUE);
00166 }
00167 }
00168 }
00169
00170 void FolderStorage::markUnreadAsRead()
00171 {
00172 KMMsgBase* msgBase;
00173 SerNumList serNums;
00174
00175 for (int i=count()-1; i>=0; --i)
00176 {
00177 msgBase = getMsgBase(i);
00178 assert(msgBase);
00179 if (msgBase->isNew() || msgBase->isUnread())
00180 {
00181 serNums.append( msgBase->getMsgSerNum() );
00182 }
00183 }
00184 if (serNums.empty())
00185 return;
00186
00187 KMCommand *command = new KMSetStatusCommand( KMMsgStatusRead, serNums );
00188 command->start();
00189 }
00190
00191
00192 void FolderStorage::quiet(bool beQuiet)
00193 {
00194 if (beQuiet)
00195 mQuiet++;
00196 else {
00197 mQuiet--;
00198 if (mQuiet <= 0)
00199 {
00200 mQuiet = 0;
00201 if (mChanged)
00202 emit changed();
00203 mChanged = FALSE;
00204 }
00205 }
00206 }
00207
00208
00209
00210
00211
00213 int operator<( KMMsgBase & m1, KMMsgBase & m2 )
00214 {
00215 return (m1.date() < m2.date());
00216 }
00217
00219 int operator==( KMMsgBase & m1, KMMsgBase & m2 )
00220 {
00221 return (m1.date() == m2.date());
00222 }
00223
00224
00225
00226 int FolderStorage::expungeOldMsg(int days)
00227 {
00228 int i, msgnb=0;
00229 time_t msgTime, maxTime;
00230 const KMMsgBase* mb;
00231 QValueList<int> rmvMsgList;
00232
00233 maxTime = time(0) - days * 3600 * 24;
00234
00235 for (i=count()-1; i>=0; i--) {
00236 mb = getMsgBase(i);
00237 assert(mb);
00238 msgTime = mb->date();
00239
00240 if (msgTime < maxTime) {
00241
00242 removeMsg( i );
00243 msgnb++;
00244 }
00245 }
00246 return msgnb;
00247 }
00248
00249
00250 void FolderStorage::emitMsgAddedSignals(int idx)
00251 {
00252 Q_UINT32 serNum = kmkernel->msgDict()->getMsgSerNum( folder() , idx );
00253 if (!mQuiet) {
00254 emit msgAdded(idx);
00255 } else {
00256 mChanged=true;
00257 }
00258 emit msgAdded( folder(), serNum );
00259 }
00260
00261
00262 bool FolderStorage::canAddMsgNow(KMMessage* aMsg, int* aIndex_ret)
00263 {
00264 if (aIndex_ret) *aIndex_ret = -1;
00265 KMFolder *msgParent = aMsg->parent();
00266
00267
00268 if (aMsg->transferInProgress() && msgParent)
00269 return false;
00270 if (!aMsg->isComplete() && msgParent && msgParent->folderType() == KMFolderTypeImap)
00271 {
00272 FolderJob *job = msgParent->createJob(aMsg);
00273 connect(job, SIGNAL(messageRetrieved(KMMessage*)),
00274 SLOT(reallyAddMsg(KMMessage*)));
00275 job->start();
00276 aMsg->setTransferInProgress(TRUE);
00277 return FALSE;
00278 }
00279 return TRUE;
00280 }
00281
00282
00283
00284 void FolderStorage::reallyAddMsg(KMMessage* aMsg)
00285 {
00286 if (!aMsg)
00287 return;
00288 aMsg->setTransferInProgress(FALSE);
00289 KMFolder *aFolder = aMsg->parent();
00290 int index;
00291 ulong serNum = aMsg->getMsgSerNum();
00292 bool undo = aMsg->enableUndo();
00293 addMsg(aMsg, &index);
00294 if (index < 0) return;
00295 unGetMsg(index);
00296 if (undo)
00297 {
00298 kmkernel->undoStack()->pushSingleAction( serNum, aFolder, folder() );
00299 }
00300 }
00301
00302
00303
00304 void FolderStorage::reallyAddCopyOfMsg(KMMessage* aMsg)
00305 {
00306 aMsg->setParent( 0 );
00307 aMsg->setTransferInProgress( false );
00308 addMsg( aMsg );
00309 unGetMsg( count() - 1 );
00310 }
00311
00312 int FolderStorage::find( const KMMessage * msg ) const {
00313 return find( &msg->toMsgBase() );
00314 }
00315
00316
00317 void FolderStorage::removeMsg(const QPtrList<KMMsgBase>& msgList, bool imapQuiet)
00318 {
00319 for( QPtrListIterator<KMMsgBase> it( msgList ); *it; ++it )
00320 {
00321 int idx = find(it.current());
00322 assert( idx != -1);
00323 removeMsg(idx, imapQuiet);
00324 }
00325 }
00326
00327
00328 void FolderStorage::removeMsg(const QPtrList<KMMessage>& msgList, bool imapQuiet)
00329 {
00330 for( QPtrListIterator<KMMessage> it( msgList ); *it; ++it )
00331 {
00332 int idx = find(it.current());
00333 assert( idx != -1);
00334 removeMsg(idx, imapQuiet);
00335 }
00336 }
00337
00338
00339 void FolderStorage::removeMsg(int idx, bool)
00340 {
00341
00342 if(idx < 0)
00343 {
00344 kdDebug(5006) << "FolderStorage::removeMsg() : idx < 0\n" << endl;
00345 return;
00346 }
00347
00348 KMMsgBase* mb = getMsgBase(idx);
00349
00350 Q_UINT32 serNum = kmkernel->msgDict()->getMsgSerNum( folder(), idx );
00351 if (serNum != 0)
00352 emit msgRemoved( folder(), serNum );
00353 mb = takeIndexEntry( idx );
00354
00355 setDirty( true );
00356 needsCompact=true;
00357
00358 if (mb->isUnread() || mb->isNew() ||
00359 (folder() == kmkernel->outboxFolder())) {
00360 --mUnreadMsgs;
00361 emit numUnreadMsgsChanged( folder() );
00362 }
00363 --mTotalMsgs;
00364
00365 QString msgIdMD5 = mb->msgIdMD5();
00366 QString strippedSubjMD5 = mb->strippedSubjectMD5();
00367 if (strippedSubjMD5.isEmpty()) {
00368 mb->initStrippedSubjectMD5();
00369 strippedSubjMD5 = mb->strippedSubjectMD5();
00370 }
00371 emit msgRemoved(idx, msgIdMD5, strippedSubjMD5);
00372 emit msgRemoved( folder() );
00373 }
00374
00375
00376
00377 KMMessage* FolderStorage::take(int idx)
00378 {
00379 KMMsgBase* mb;
00380 KMMessage* msg;
00381
00382 assert(idx>=0 && idx<=count());
00383
00384 mb = getMsgBase(idx);
00385 if (!mb) return 0;
00386 if (!mb->isMessage()) readMsg(idx);
00387 Q_UINT32 serNum = kmkernel->msgDict()->getMsgSerNum( folder(), idx );
00388 emit msgRemoved( folder(), serNum );
00389
00390 msg = (KMMessage*)takeIndexEntry(idx);
00391
00392 if (msg->isUnread() || msg->isNew() ||
00393 ( folder() == kmkernel->outboxFolder() )) {
00394 --mUnreadMsgs;
00395 emit numUnreadMsgsChanged( folder() );
00396 }
00397 --mTotalMsgs;
00398 msg->setParent(0);
00399 setDirty( true );
00400 needsCompact=true;
00401 QString msgIdMD5 = msg->msgIdMD5();
00402 QString strippedSubjMD5 = msg->strippedSubjectMD5();
00403 if (strippedSubjMD5.isEmpty()) {
00404 msg->initStrippedSubjectMD5();
00405 strippedSubjMD5 = msg->strippedSubjectMD5();
00406 }
00407 emit msgRemoved(idx, msgIdMD5, strippedSubjMD5);
00408 emit msgRemoved( folder() );
00409
00410 return msg;
00411 }
00412
00413 void FolderStorage::take(QPtrList<KMMessage> msgList)
00414 {
00415 for ( KMMessage* msg = msgList.first(); msg; msg = msgList.next() )
00416 {
00417 if (msg->parent())
00418 {
00419 int idx = msg->parent()->find(msg);
00420 assert( idx != -1);
00421 FolderStorage::take(idx);
00422 }
00423 }
00424 }
00425
00426
00427
00428 KMMessage* FolderStorage::getMsg(int idx)
00429 {
00430 if(!(idx >= 0 && idx <= count()))
00431 return 0;
00432
00433 KMMsgBase* mb = getMsgBase(idx);
00434 if (!mb) return 0;
00435
00436 KMMessage *msg = 0;
00437 bool undo = mb->enableUndo();
00438 if (mb->isMessage()) {
00439 msg = ((KMMessage*)mb);
00440 } else {
00441 QString mbSubject = mb->subject();
00442 msg = readMsg(idx);
00443
00444 if (mCompactable && (!msg || (msg->subject().isEmpty() != mbSubject.isEmpty()))) {
00445 kdDebug(5006) << "Error: " << location() <<
00446 " Index file is inconsistent with folder file. This should never happen." << endl;
00447 mCompactable = FALSE;
00448 writeConfig();
00449 }
00450
00451 }
00452 msg->setEnableUndo(undo);
00453
00454
00455
00456 if (msg->getMsgSerNum() == 0) {
00457 msg->setMsgSerNum(kmkernel->msgDict()->insert(0, msg, idx));
00458 kdDebug(5006) << "Serial number generated for message in folder "
00459 << label() << endl;
00460 }
00461 msg->setComplete( true );
00462 return msg;
00463 }
00464
00465
00466 KMMessage* FolderStorage::readTemporaryMsg(int idx)
00467 {
00468 if(!(idx >= 0 && idx <= count()))
00469 return 0;
00470
00471 KMMsgBase* mb = getMsgBase(idx);
00472 if (!mb) return 0;
00473
00474 unsigned long sernum = mb->getMsgSerNum();
00475
00476 KMMessage *msg = 0;
00477 bool undo = mb->enableUndo();
00478 if (mb->isMessage()) {
00479
00480 msg = new KMMessage(*(KMMessage*)mb);
00481 msg->setMsgSerNum(sernum);
00482 } else {
00483
00484 msg = new KMMessage(*(KMMsgInfo*)mb);
00485 msg->setMsgSerNum(sernum);
00486 msg->fromDwString(getDwString(idx));
00487 }
00488 msg->setEnableUndo(undo);
00489 msg->setComplete( true );
00490 return msg;
00491 }
00492
00493
00494
00495 KMMsgInfo* FolderStorage::unGetMsg(int idx)
00496 {
00497 KMMsgBase* mb;
00498
00499 if(!(idx >= 0 && idx <= count()))
00500 return 0;
00501
00502 mb = getMsgBase(idx);
00503 if (!mb) return 0;
00504
00505
00506 if (mb->isMessage()) {
00507
00508
00509 KMMessage *msg = static_cast<KMMessage*>(mb);
00510 if ( msg->transferInProgress() ) return 0;
00511 ignoreJobsForMessage( msg );
00512 return setIndexEntry( idx, msg );
00513 }
00514
00515 return 0;
00516 }
00517
00518
00519
00520 bool FolderStorage::isMessage(int idx)
00521 {
00522 KMMsgBase* mb;
00523 if (!(idx >= 0 && idx <= count())) return FALSE;
00524 mb = getMsgBase(idx);
00525 return (mb && mb->isMessage());
00526 }
00527
00528
00529 FolderJob* FolderStorage::createJob( KMMessage *msg, FolderJob::JobType jt,
00530 KMFolder *folder, QString partSpecifier,
00531 const AttachmentStrategy *as ) const
00532 {
00533 FolderJob * job = doCreateJob( msg, jt, folder, partSpecifier, as );
00534 if ( job )
00535 addJob( job );
00536 return job;
00537 }
00538
00539
00540 FolderJob* FolderStorage::createJob( QPtrList<KMMessage>& msgList, const QString& sets,
00541 FolderJob::JobType jt, KMFolder *folder ) const
00542 {
00543 FolderJob * job = doCreateJob( msgList, sets, jt, folder );
00544 if ( job )
00545 addJob( job );
00546 return job;
00547 }
00548
00549
00550 int FolderStorage::moveMsg(KMMessage* aMsg, int* aIndex_ret)
00551 {
00552 assert(aMsg != 0);
00553 KMFolder* msgParent = aMsg->parent();
00554
00555 if (msgParent)
00556 msgParent->open();
00557
00558 open();
00559 int rc = addMsg(aMsg, aIndex_ret);
00560 close();
00561
00562 if (msgParent)
00563 msgParent->close();
00564
00565 return rc;
00566 }
00567
00568
00569 int FolderStorage::moveMsg(QPtrList<KMMessage> msglist, int* aIndex_ret)
00570 {
00571 KMMessage* aMsg = msglist.first();
00572 assert(aMsg != 0);
00573 KMFolder* msgParent = aMsg->parent();
00574
00575 if (msgParent)
00576 msgParent->open();
00577
00578 open();
00579
00580 int rc = static_cast<KMFolderImap*>(this)->addMsg(msglist, aIndex_ret);
00581 close();
00582
00583 if (msgParent)
00584 msgParent->close();
00585
00586 return rc;
00587 }
00588
00589
00590
00591 int FolderStorage::rename(const QString& newName, KMFolderDir *newParent)
00592 {
00593 QString oldLoc, oldIndexLoc, oldIdsLoc, newLoc, newIndexLoc, newIdsLoc;
00594 QString oldSubDirLoc, newSubDirLoc;
00595 QString oldName;
00596 int rc=0, openCount=mOpenCount;
00597 KMFolderDir *oldParent;
00598
00599 assert(!newName.isEmpty());
00600
00601 oldLoc = location();
00602 oldIndexLoc = indexLocation();
00603 oldSubDirLoc = folder()->subdirLocation();
00604 if (kmkernel->msgDict())
00605 oldIdsLoc = kmkernel->msgDict()->getFolderIdsLocation( folder() );
00606 QString oldConfigString = "Folder-" + folder()->idString();
00607
00608 close(TRUE);
00609
00610 oldName = folder()->fileName();
00611 oldParent = folder()->parent();
00612 if (newParent)
00613 folder()->setParent( newParent );
00614
00615 folder()->setName(newName);
00616 newLoc = location();
00617 newIndexLoc = indexLocation();
00618 newSubDirLoc = folder()->subdirLocation();
00619 if (kmkernel->msgDict())
00620 newIdsLoc = kmkernel->msgDict()->getFolderIdsLocation( folder() );
00621
00622 if (::rename(QFile::encodeName(oldLoc), QFile::encodeName(newLoc))) {
00623 folder()->setName(oldName);
00624 folder()->setParent(oldParent);
00625 rc = errno;
00626 }
00627 else {
00628
00629 if (!oldIndexLoc.isEmpty()) {
00630 ::rename(QFile::encodeName(oldIndexLoc), QFile::encodeName(newIndexLoc));
00631 ::rename(QFile::encodeName(oldIndexLoc) + ".sorted",
00632 QFile::encodeName(newIndexLoc) + ".sorted");
00633 }
00634
00635
00636 if (!oldIdsLoc.isEmpty())
00637 ::rename(QFile::encodeName(oldIdsLoc), QFile::encodeName(newIdsLoc));
00638
00639
00640 KMFolderDir* child = 0;
00641 if( folder() )
00642 child = folder()->child();
00643
00644 if (!::rename(QFile::encodeName(oldSubDirLoc), QFile::encodeName(newSubDirLoc) )) {
00645
00646
00647
00648 if( child && ( oldName != newName ) ) {
00649 child->setName( "." + QFile::encodeName(newName) + ".directory" );
00650 }
00651 }
00652
00653
00654
00655 if (newParent) {
00656 if (oldParent->findRef( folder() ) != -1)
00657 oldParent->take();
00658 newParent->inSort( folder() );
00659 if ( child ) {
00660 if ( child->parent()->findRef( child ) != -1 )
00661 child->parent()->take();
00662 newParent->inSort( child );
00663 child->setParent( newParent );
00664 }
00665 }
00666 }
00667
00668 if (openCount > 0)
00669 {
00670 open();
00671 mOpenCount = openCount;
00672 }
00673 writeConfig();
00674
00675
00676 KMKernel::config()->deleteGroup( oldConfigString );
00677
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
00859
00860 void FolderStorage::correctUnreadMsgsCount()
00861 {
00862 open();
00863 close();
00864 emit numUnreadMsgsChanged( folder() );
00865 }
00866
00867
00868 void FolderStorage::fillMsgDict(KMMsgDict *dict)
00869 {
00870 fillDictFromIndex(dict);
00871 }
00872
00873
00874 int FolderStorage::writeMsgDict(KMMsgDict *dict)
00875 {
00876 int ret = 0;
00877 if (!dict)
00878 dict = kmkernel->msgDict();
00879 if (dict)
00880 ret = dict->writeFolderIds(folder());
00881 return ret;
00882 }
00883
00884
00885 int FolderStorage::touchMsgDict()
00886 {
00887 int ret = 0;
00888 KMMsgDict *dict = kmkernel->msgDict();
00889 if (dict)
00890 ret = dict->touchFolderIds(folder());
00891 return ret;
00892 }
00893
00894
00895 int FolderStorage::appendtoMsgDict(int idx)
00896 {
00897 int ret = 0;
00898 KMMsgDict *dict = kmkernel->msgDict();
00899 if (dict) {
00900 if (count() == 1) {
00901 ret = dict->writeFolderIds(folder());
00902 } else {
00903 ret = dict->appendtoFolderIds(folder(), idx);
00904 }
00905 }
00906 return ret;
00907 }
00908
00909
00910 void FolderStorage::setStatus(int idx, KMMsgStatus status, bool toggle)
00911 {
00912 KMMsgBase *msg = getMsgBase(idx);
00913 if ( msg ) {
00914 if (toggle)
00915 msg->toggleStatus(status, idx);
00916 else
00917 msg->setStatus(status, idx);
00918 }
00919 }
00920
00921 void FolderStorage::setRDict(KMMsgDictREntry *rentry) {
00922 if (rentry == mRDict)
00923 return;
00924 KMMsgDict::deleteRentry(mRDict);
00925 mRDict = rentry;
00926 }
00927
00928
00929 void FolderStorage::setStatus(QValueList<int>& ids, KMMsgStatus status, bool toggle)
00930 {
00931 for ( QValueList<int>::Iterator it = ids.begin(); it != ids.end(); ++it )
00932 {
00933 FolderStorage::setStatus(*it, status, toggle);
00934 }
00935 }
00936
00937 void FolderStorage::ignoreJobsForMessage( KMMessage *msg )
00938 {
00939 if ( !msg || msg->transferInProgress() )
00940 return;
00941
00942 QPtrListIterator<FolderJob> it( mJobList );
00943 while ( it.current() )
00944 {
00945
00946
00947
00948 if ( it.current()->msgList().first() == msg )
00949 {
00950 FolderJob* job = it.current();
00951 mJobList.remove( job );
00952 delete job;
00953 } else
00954 ++it;
00955 }
00956 }
00957
00958
00959 void FolderStorage::removeJobs()
00960 {
00961 mJobList.setAutoDelete( true );
00962 mJobList.clear();
00963 mJobList.setAutoDelete( false );
00964 }
00965
00966
00967 size_t FolderStorage::crlf2lf( char* str, const size_t strLen )
00968 {
00969 if ( !str || strLen == 0 ) return 0;
00970
00971 const char* source = str;
00972 const char* sourceEnd = source + strLen;
00973
00974
00975 for ( ; source < sourceEnd - 1; ++source ) {
00976 if ( *source == '\r' && *( source + 1 ) == '\n' )
00977 break;
00978 }
00979
00980 if ( source == sourceEnd - 1 ) {
00981
00982 return strLen;
00983 }
00984
00985
00986 char* target = const_cast<char*>( source );
00987 ++source;
00988 for ( ; source < sourceEnd; ++source ) {
00989 if ( *source != '\r' || *( source + 1 ) != '\n' )
00990 *target++ = *source;
00991 }
00992 *target = '\0';
00993 return target - str;
00994 }
00995
00996
00997 void FolderStorage::updateChildrenState()
00998 {
00999 if ( folder() && folder()->child() )
01000 {
01001 if ( kmkernel->folderMgr()->folderCount( folder()->child() ) > 0 )
01002 setHasChildren( HasChildren );
01003 else
01004 setHasChildren( HasNoChildren );
01005 }
01006 }
01007
01008
01009 void FolderStorage::setNoChildren( bool aNoChildren )
01010 {
01011 mNoChildren = aNoChildren;
01012 if ( aNoChildren )
01013 setHasChildren( HasNoChildren );
01014 }
01015
01016
01017 void FolderStorage::setContentsType( KMail::FolderContentsType type )
01018 {
01019 if ( type != mContentsType ) {
01020 mContentsType = type;
01021 kmkernel->iCalIface().folderContentsTypeChanged( folder(), type );
01022 }
01023 }
01024
01025 #include "folderstorage.moc"