From 71fd433ec0948d936d24f992a412ef866b943eed Mon Sep 17 00:00:00 2001 From: Andreas Gungl Date: Wed, 26 Oct 2005 17:11:50 +0000 Subject: [PATCH] Move the message status implementation of KMail to libkdepim. The simple status variable has been replaced by a class which encapsulates the internal representation of the status flags as well as the logic to keep the integrity. svn path=/trunk/KDE/kdepim/; revision=474533 --- kmmessage.cpp | 7 +- kmmessage.h | 2 +- kmmsgbase.cpp | 221 ++++++++++++++++++++++++++++++-------------------- kmmsgbase.h | 44 +++------- kmmsginfo.cpp | 12 +-- 5 files changed, 153 insertions(+), 133 deletions(-) diff --git a/kmmessage.cpp b/kmmessage.cpp index 2fe0738e3..289369f91 100644 --- a/kmmessage.cpp +++ b/kmmessage.cpp @@ -121,7 +121,7 @@ KMMessage::KMMessage(KMMsgInfo& msgInfo): KMMsgBase() // now overwrite a few from the msgInfo mMsgSize = msgInfo.msgSize(); mFolderOffset = msgInfo.folderOffset(); - mStatus = msgInfo.status(); + mStatus = msgInfo.messageStatus(); mEncryptionState = msgInfo.encryptionState(); mSignatureState = msgInfo.signatureState(); mMDNSentState = msgInfo.mdnSentState(); @@ -152,7 +152,8 @@ void KMMessage::init() mMsgSize = 0; mMsgLength = 0; mFolderOffset = 0; - mStatus = KMMsgStatusNew; + mStatus.clear(); + mStatus.setNew(); mEncryptionState = KMMsgEncryptionStateUnknown; mSignatureState = KMMsgSignatureStateUnknown; mMDNSentState = KMMsgMDNStateUnknown; @@ -3871,7 +3872,7 @@ void KMMessage::setCharset(const Q3CString& bStr) //----------------------------------------------------------------------------- void KMMessage::setStatus(const KMMsgStatus aStatus, int idx) { - if (mStatus == aStatus) + if (mStatus.getStatus() == aStatus) return; KMMsgBase::setStatus(aStatus, idx); } diff --git a/kmmessage.h b/kmmessage.h index 7ae7a3cba..578ecd708 100644 --- a/kmmessage.h +++ b/kmmessage.h @@ -763,7 +763,7 @@ public: void setUID(ulong uid); /** Status of the message. */ - KMMsgStatus status() const { return mStatus; } + KMMsgStatus status() const { return mStatus.getStatus(); } /** Set status and mark dirty. */ void setStatus(const KMMsgStatus status, int idx = -1); void setStatus(const char* s1, const char* s2=0) { KMMsgBase::setStatus(s1, s2); } diff --git a/kmmsgbase.cpp b/kmmsgbase.cpp index 8b6070815..965ce1113 100644 --- a/kmmsgbase.cpp +++ b/kmmsgbase.cpp @@ -73,7 +73,7 @@ using KMail::MessageProperty; //----------------------------------------------------------------------------- KMMsgBase::KMMsgBase(KMFolder* aParentFolder) : mParent( aParentFolder ), mIndexOffset( 0 ), - mIndexLength( 0 ), mDirty( false ), mEnableUndo( false ), mStatus( KMMsgStatusUnknown ) + mIndexLength( 0 ), mDirty( false ), mEnableUndo( false ), mStatus() { } @@ -126,20 +126,85 @@ void KMMsgBase::toggleStatus(const KMMsgStatus aStatus, int idx) { mDirty = true; KMMsgStatus oldStatus = status(); - if ( status() & aStatus ) { - mStatus &= ~aStatus; - } else { - mStatus |= aStatus; - // Ignored and Watched are toggleable, yet mutually exclusive. - // That is an arbitrary restriction on my part. HAR HAR HAR :) -till - if (aStatus == KMMsgStatusWatched) - mStatus &= ~KMMsgStatusIgnored; - if (aStatus == KMMsgStatusIgnored) - mStatus &= ~KMMsgStatusWatched; - if (aStatus == KMMsgStatusSpam) - mStatus &= ~KMMsgStatusHam; - if (aStatus == KMMsgStatusHam) - mStatus &= ~KMMsgStatusSpam; + switch (aStatus) { + case KMMsgStatusRead: + if ( !mStatus.isRead() ) + mStatus.setRead(); + else + mStatus.setUnread(); + break; + + case KMMsgStatusUnread: + if ( !mStatus.isUnread() ) + mStatus.setUnread(); + else + mStatus.setRead(); + break; + + case KMMsgStatusOld: + if ( !mStatus.isOld() ) + mStatus.setOld(); + else + mStatus.setNew(); + break; + + case KMMsgStatusNew: + if ( !mStatus.isNew() ) + mStatus.setNew(); + else + mStatus.setOld(); + break; + + case KMMsgStatusDeleted: + mStatus.setDeleted( !mStatus.isDeleted() ); + break; + + case KMMsgStatusReplied: + mStatus.setReplied( !mStatus.isReplied() ); + break; + + case KMMsgStatusForwarded: + mStatus.setForwarded( !mStatus.isForwarded() ); + break; + + case KMMsgStatusQueued: + mStatus.setQueued( !mStatus.isQueued() ); + break; + + case KMMsgStatusTodo: + mStatus.setTodo( !mStatus.isTodo() ); + break; + + case KMMsgStatusSent: + mStatus.setSent( !mStatus.isSent() ); + break; + + case KMMsgStatusFlag: + mStatus.setImportant( !mStatus.isImportant() ); + break; + + // Watched and ignored are mutually exclusive + case KMMsgStatusWatched: + mStatus.setWatched( !mStatus.isWatched() ); + break; + + case KMMsgStatusIgnored: + mStatus.setIgnored( !mStatus.isIgnored() ); + break; + + // as are ham and spam + case KMMsgStatusSpam: + mStatus.setSpam( !mStatus.isSpam() ); + break; + + case KMMsgStatusHam: + mStatus.setHam( !mStatus.isHam() ); + break; + + case KMMsgStatusHasAttach: + case KMMsgStatusHasNoAttach: + mStatus.setHasAttachment( !mStatus.hasAttachment() ); + break; } if (storage()) { if (idx < 0) @@ -157,99 +222,81 @@ void KMMsgBase::setStatus(const KMMsgStatus aStatus, int idx) KMMsgStatus oldStatus = status(); switch (aStatus) { case KMMsgStatusRead: - // Unset unread and new, set read - mStatus &= ~KMMsgStatusUnread; - mStatus &= ~KMMsgStatusNew; - mStatus |= KMMsgStatusRead; + mStatus.setRead(); break; case KMMsgStatusUnread: - // unread overrides read - mStatus &= ~KMMsgStatusOld; - mStatus &= ~KMMsgStatusRead; - mStatus &= ~KMMsgStatusNew; - mStatus |= KMMsgStatusUnread; + mStatus.setUnread(); break; case KMMsgStatusOld: - // old can't be new or unread - mStatus &= ~KMMsgStatusNew; - mStatus &= ~KMMsgStatusUnread; - mStatus |= KMMsgStatusOld; + mStatus.setOld(); break; case KMMsgStatusNew: - // new overrides old and read - mStatus &= ~KMMsgStatusOld; - mStatus &= ~KMMsgStatusRead; - mStatus &= ~KMMsgStatusUnread; - mStatus |= KMMsgStatusNew; + mStatus.setNew(); break; case KMMsgStatusDeleted: - mStatus |= KMMsgStatusDeleted; + mStatus.setDeleted(); break; case KMMsgStatusReplied: - mStatus |= KMMsgStatusReplied; + mStatus.setReplied(); break; case KMMsgStatusForwarded: - mStatus |= KMMsgStatusForwarded; + mStatus.setForwarded(); break; case KMMsgStatusQueued: - mStatus |= KMMsgStatusQueued; + mStatus.setQueued(); break; case KMMsgStatusTodo: - mStatus |= KMMsgStatusTodo; + mStatus.setTodo(); break; case KMMsgStatusSent: - mStatus &= ~KMMsgStatusQueued; - mStatus &= ~KMMsgStatusUnread; - mStatus &= ~KMMsgStatusNew; - mStatus |= KMMsgStatusSent; + mStatus.setSent(); break; case KMMsgStatusFlag: - mStatus |= KMMsgStatusFlag; + mStatus.setImportant(); break; // Watched and ignored are mutually exclusive case KMMsgStatusWatched: - mStatus &= ~KMMsgStatusIgnored; - mStatus |= KMMsgStatusWatched; + mStatus.setWatched(); break; case KMMsgStatusIgnored: - mStatus &= ~KMMsgStatusWatched; - mStatus |= KMMsgStatusIgnored; + mStatus.setIgnored(); break; + // as are ham and spam case KMMsgStatusSpam: - mStatus &= ~KMMsgStatusHam; - mStatus |= KMMsgStatusSpam; + mStatus.setSpam(); break; + case KMMsgStatusHam: - mStatus &= ~KMMsgStatusSpam; - mStatus |= KMMsgStatusHam; + mStatus.setHam(); break; + case KMMsgStatusHasAttach: - mStatus &= ~KMMsgStatusHasNoAttach; - mStatus |= KMMsgStatusHasAttach; + mStatus.setHasAttachment(); break; + case KMMsgStatusHasNoAttach: - mStatus &= ~KMMsgStatusHasAttach; - mStatus |= KMMsgStatusHasNoAttach; + mStatus.setHasAttachment( false ); break; + default: - mStatus = aStatus; + mStatus.setStatus( aStatus ); break; } - if ( oldStatus != mStatus && storage() ) { + if ( oldStatus != mStatus.getStatus() && storage() ) { if (idx < 0) idx = storage()->find( this ); storage()->msgStatusChanged( oldStatus, status(), idx ); @@ -356,113 +403,109 @@ void KMMsgBase::setSignatureStateChar( QChar status, int idx ) //----------------------------------------------------------------------------- bool KMMsgBase::isUnread(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusUnread && !(st & KMMsgStatusIgnored)); + return mStatus.isUnread(); } //----------------------------------------------------------------------------- bool KMMsgBase::isNew(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusNew && !(st & KMMsgStatusIgnored)); + return mStatus.isIgnored(); } //----------------------------------------------------------------------------- bool KMMsgBase::isOfUnknownStatus(void) const { - KMMsgStatus st = status(); - return (st == KMMsgStatusUnknown); + return mStatus.isOfUnknownStatus(); } //----------------------------------------------------------------------------- bool KMMsgBase::isOld(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusOld); + return mStatus.isOld(); } //----------------------------------------------------------------------------- bool KMMsgBase::isRead(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusRead || st & KMMsgStatusIgnored); + return mStatus.isRead(); } //----------------------------------------------------------------------------- bool KMMsgBase::isDeleted(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusDeleted); + return mStatus.isDeleted(); } //----------------------------------------------------------------------------- bool KMMsgBase::isReplied(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusReplied); + return mStatus.isReplied(); } //----------------------------------------------------------------------------- bool KMMsgBase::isForwarded(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusForwarded); + return mStatus.isForwarded(); } //----------------------------------------------------------------------------- bool KMMsgBase::isQueued(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusQueued); + return mStatus.isQueued(); } //----------------------------------------------------------------------------- bool KMMsgBase::isTodo(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusTodo); + return mStatus.isTodo(); } //----------------------------------------------------------------------------- bool KMMsgBase::isSent(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusSent); + return mStatus.isSent(); } //----------------------------------------------------------------------------- bool KMMsgBase::isImportant(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusFlag); + return mStatus.isImportant(); } //----------------------------------------------------------------------------- bool KMMsgBase::isWatched(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusWatched); + return mStatus.isWatched(); } //----------------------------------------------------------------------------- bool KMMsgBase::isIgnored(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusIgnored); + return mStatus.isIgnored(); } //----------------------------------------------------------------------------- bool KMMsgBase::isSpam(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusSpam); + return mStatus.isSpam(); } //----------------------------------------------------------------------------- bool KMMsgBase::isHam(void) const { - KMMsgStatus st = status(); - return (st & KMMsgStatusHam); + return mStatus.isHam(); +} + +//----------------------------------------------------------------------------- +MessageStatus& KMMsgBase::messageStatus() +{ + return mStatus; +} + +//----------------------------------------------------------------------------- +const MessageStatus& KMMsgBase::getMessageStatus() const +{ + return mStatus; } //----------------------------------------------------------------------------- diff --git a/kmmsgbase.h b/kmmsgbase.h index 97b60271a..76d772ca6 100644 --- a/kmmsgbase.h +++ b/kmmsgbase.h @@ -20,6 +20,9 @@ #ifndef kmmsgbase_h #define kmmsgbase_h +#include "messagestatus.h" +using KPIM::MessageStatus; + // for large file support flags #include #include @@ -34,39 +37,8 @@ class QTextCodec; class KMFolder; class KMFolderIndex; -/** The new status format. These can be or'd together. - Note, that the KMMsgStatusIgnored implies the - status to be Read even if the flags are set - to Unread or New. This is done in KMMsgBase::isRead() - and related getters. So we can preserve the state - when switching a thread to Ignored and back. */ -enum MsgStatus -{ - KMMsgStatusUnknown = 0x00000000, - KMMsgStatusNew = 0x00000001, - KMMsgStatusUnread = 0x00000002, - KMMsgStatusRead = 0x00000004, - KMMsgStatusOld = 0x00000008, - KMMsgStatusDeleted = 0x00000010, - KMMsgStatusReplied = 0x00000020, - KMMsgStatusForwarded = 0x00000040, - KMMsgStatusQueued = 0x00000080, - KMMsgStatusSent = 0x00000100, - KMMsgStatusFlag = 0x00000200, // flag means important - KMMsgStatusWatched = 0x00000400, - KMMsgStatusIgnored = 0x00000800, // forces isRead() - KMMsgStatusTodo = 0x00001000, - KMMsgStatusSpam = 0x00002000, - KMMsgStatusHam = 0x00004000, - KMMsgStatusHasAttach = 0x00008000, - KMMsgStatusHasNoAttach = 0x00010000 -}; - -typedef uint KMMsgStatus; - /** The old status format, only one at a time possible. Needed for upgrade path purposes. */ - typedef enum { KMLegacyMsgStatusUnknown=' ', @@ -82,8 +54,6 @@ typedef enum KMLegacyMsgStatusFlag='G' } KMLegacyMsgStatus; - - /** Flags for the encryption state. */ typedef enum { @@ -211,6 +181,12 @@ public: /** Status of the message. */ virtual KMMsgStatus status(void) const = 0; + /** Status object of a message. */ + MessageStatus& messageStatus(); + + /** Const reference to a status object of a message. */ + const MessageStatus& getMessageStatus() const; + /** Set status and mark dirty. Optional optimization: @p idx may * specify the index of this message within the parent folder. */ virtual void setStatus(const KMMsgStatus status, int idx = -1); @@ -426,7 +402,7 @@ protected: short mIndexLength; bool mDirty; bool mEnableUndo; - mutable KMMsgStatus mStatus; + mutable MessageStatus mStatus; // This is kept to provide an upgrade path from the the old single status // to the new multiple status scheme. mutable KMLegacyMsgStatus mLegacyStatus; diff --git a/kmmsginfo.cpp b/kmmsginfo.cpp index 3f1becf1c..9abfdffe4 100644 --- a/kmmsginfo.cpp +++ b/kmmsginfo.cpp @@ -166,7 +166,7 @@ KMMsgInfo& KMMsgInfo::operator=(const KMMessage& msg) kd->strippedSubjectMD5 = msg.strippedSubjectMD5(); kd->msgIdMD5 = msg.msgIdMD5(); kd->xmark = msg.xmark(); - mStatus = msg.status(); + mStatus = msg.getMessageStatus(); kd->folderOffset = msg.folderOffset(); kd->msgSize = msg.msgSize(); kd->date = msg.date(); @@ -205,7 +205,7 @@ void KMMsgInfo::init(const Q3CString& aSubject, const Q3CString& aFrom, kd->msgIdMD5 = base64EncodedMD5( msgId ); kd->xmark = aXMark; kd->folderOffset = aFolderOffset; - mStatus = aStatus; + mStatus.setStatus( aStatus ); kd->msgSize = aMsgSize; kd->date = aDate; kd->file = ""; @@ -449,7 +449,7 @@ void KMMsgInfo::setMDNSentState( const KMMsgMDNSentState s, int idx ) //----------------------------------------------------------------------------- KMMsgStatus KMMsgInfo::status(void) const { - if (mStatus == KMMsgStatusUnknown) { + if ( mStatus.isOfUnknownStatus() ) { KMMsgStatus st = (KMMsgStatus)getLongPart(MsgStatusPart); if (!st) { // We are opening an old index for the first time, get the legacy @@ -495,9 +495,9 @@ KMMsgStatus KMMsgInfo::status(void) const } } - mStatus = st; + mStatus.setStatus( st ); } - return mStatus; + return mStatus.getStatus(); } @@ -668,7 +668,7 @@ void KMMsgInfo::compat_fromOldIndexString(const Q3CString& str, bool toUtf8) kd->folderOffset = str.mid(2,9).toULong(); kd->msgSize = str.mid(12,9).toULong(); kd->date = (time_t)str.mid(22,10).toULong(); - mStatus = (KMMsgStatus)str.at(0); + mStatus.setStatusFromStr( str ); if (toUtf8) { kd->subject = str.mid(37, 100).stripWhiteSpace(); kd->from = str.mid(138, 50).stripWhiteSpace();