diff --git a/kmail/kmmsgbase.h b/kmail/kmmsgbase.h index 1bdedf54c9..0586f6f40f 100644 --- a/kmail/kmmsgbase.h +++ b/kmail/kmmsgbase.h @@ -1,297 +1,306 @@ /* Virtual base class for messages and message infos * Author: Stefan Taferner * This code is under GPL. */ #ifndef kmmsgbase_h #define kmmsgbase_h // for large file support flags #include #include #include #include class QCString; class QStringList; class QTextCodec; class KMFolder; class KMFolderIndex; typedef enum { KMMsgStatusUnknown=' ', KMMsgStatusNew='N', KMMsgStatusUnread='U', KMMsgStatusRead='R', KMMsgStatusOld='O', KMMsgStatusDeleted='D', KMMsgStatusReplied='A', KMMsgStatusForwarded='F', KMMsgStatusQueued='Q', KMMsgStatusSent='S', KMMsgStatusFlag='G' } KMMsgStatus; /** Flags for the encryption state. */ typedef enum { KMMsgEncryptionStateUnknown=' ', KMMsgNotEncrypted='N', KMMsgPartiallyEncrypted='P', KMMsgFullyEncrypted='F', KMMsgEncryptionProblematic='X' } KMMsgEncryptionState; /** Flags for the signature state. */ typedef enum { KMMsgSignatureStateUnknown=' ', KMMsgNotSigned='N', KMMsgPartiallySigned='P', KMMsgFullySigned='F', KMMsgSignatureProblematic='X' } KMMsgSignatureState; /** Flags for the "MDN sent" state. */ typedef enum { KMMsgMDNStateUnknown = ' ', KMMsgMDNNone = 'N', KMMsgMDNIgnore = 'I', KMMsgMDNDisplayed = 'R', KMMsgMDNDeleted = 'D', KMMsgMDNDispatched = 'F', KMMsgMDNProcessed = 'P', KMMsgMDNDenied = 'X', KMMsgMDNFailed = 'E' } KMMsgMDNSentState; /** Flags for the signature state. */ typedef enum { KMMsgDnDActionMOVE=0, KMMsgDnDActionCOPY=1, KMMsgDnDActionASK=2 } KMMsgDnDAction; class KMMsgBase { public: KMMsgBase(KMFolderIndex* p=0); virtual ~KMMsgBase(); /** Convert the given message status to a string. */ static const char* statusToStr(KMMsgStatus aStatus); /** Return owning folder. */ KMFolderIndex* parent(void) const { return mParent; } /** Set owning folder. */ void setParent(KMFolderIndex* p) { mParent=p; } /** Returns TRUE if object is a real message (not KMMsgInfo or KMMsgBase) */ virtual bool isMessage(void) const; /** Returns TRUE if status is new or unread. */ virtual bool isUnread(void) const; /** Returns TRUE if status is new. */ virtual bool isNew(void) const; /** Status of the message. */ virtual KMMsgStatus status(void) const = 0; /** 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); virtual void setStatus(const char* statusField, const char* xstatusField=0); /** Encryption status of the message. */ virtual KMMsgEncryptionState encryptionState() const = 0; /** Signature status of the message. */ virtual KMMsgSignatureState signatureState() const = 0; /** "MDN send" status of the message. */ virtual KMMsgMDNSentState mdnSentState() const = 0; /** Set "MDN sent" status of the message. */ virtual void setMDNSentState( KMMsgMDNSentState status, int idx=-1 ); /** Set encryption status of the message and mark dirty. Optional * optimization: @p idx may specify the index of this message within * the parent folder. */ virtual void setEncryptionState(const KMMsgEncryptionState, int idx = -1); /** Set signature status of the message and mark dirty. Optional * optimization: @p idx may specify the index of this message within * the parent folder. */ virtual void setSignatureState(const KMMsgSignatureState, int idx = -1); /** Set encryption status of the message and mark dirty. Optional * optimization: @p idx may specify the index of this message within * the parent folder. */ virtual void setEncryptionStateChar( QChar status, int idx = -1 ); /** Set signature status of the message and mark dirty. Optional * optimization: @p idx may specify the index of this message within * the parent folder. */ virtual void setSignatureStateChar( QChar status, int idx = -1 ); /** Important header fields of the message that are also kept in the index. */ virtual QString subject(void) const = 0; virtual QString fromStrip(void) const = 0; virtual QString toStrip(void) const = 0; virtual QString replyToIdMD5(void) const = 0; virtual QString msgIdMD5(void) const = 0; + virtual QString replyToAuxIdMD5(void) const = 0; + virtual QString strippedSubjectMD5(void) const = 0; + virtual bool subjectIsPrefixed(void) const = 0; virtual time_t date(void) const = 0; virtual QString dateStr(void) const; virtual QString xmark(void) const = 0; /** Set date. */ virtual void setDate(const QCString &aStrDate); virtual void setDate(time_t aUnixTime) = 0; /** Returns TRUE if changed since last folder-sync. */ virtual bool dirty(void) const { return mDirty; } /** Change dirty flag. */ void setDirty(bool b) { mDirty = b; } /** Set subject/from/date and xmark. */ virtual void setSubject(const QString&) = 0; virtual void setXMark(const QString&) = 0; + /** Calculate strippedSubject */ + virtual void initStrippedSubjectMD5() = 0; + /** Return contents as index string. This string is of indexStringLength() size */ const uchar *asIndexString(int &len) const; /** Get/set offset in mail folder. */ virtual off_t folderOffset(void) const = 0; virtual void setFolderOffset(off_t offs) = 0; /** Get/set msg filename */ virtual QString fileName(void) const = 0; virtual void setFileName(const QString& filename) = 0; /** Get/set size of message including the whole header in bytes. */ virtual size_t msgSize(void) const = 0; virtual void setMsgSize(size_t sz) = 0; /** offset into index file */ virtual void setIndexOffset(off_t off) { mIndexOffset = off; } virtual off_t indexOffset() const { return mIndexOffset; } /** size in index file */ virtual void setIndexLength(short len) { mIndexLength = len; } virtual short indexLength() const { return mIndexLength; } /** Skip leading keyword if keyword has given character at it's end * (e.g. ':' or ',') and skip the then following blanks (if any) too. * If keywordFound is specified it will be TRUE if a keyword was skipped * and FALSE otherwise. */ static QString skipKeyword(const QString& str, QChar sepChar=':', bool* keywordFound=0); /** Return a QTextCodec for the specified charset. * This function is a bit more tolerant, than QTextCodec::codecForName */ static QTextCodec* codecForName(const QCString& _str); /** Convert all non-ascii characters to question marks * If ok is non-null, *ok will be set to true if all characters * where ascii, *ok will be set to false otherwise */ static const QCString toUsAscii(const QString& _str, bool *ok=0); /** Return a list of the supported encodings */ static QStringList supportedEncodings(bool usAscii); /** Copy all values from other to this object. */ void assign(const KMMsgBase* other); /** Assignment operator that simply calls assign(). */ KMMsgBase& operator=(const KMMsgBase& other); /** Copy constructor that simply calls assign(). */ KMMsgBase( const KMMsgBase& other ); /** En-/decode given string to/from quoted-printable. */ static QCString decodeQuotedPrintable(const QCString& str); static QCString encodeQuotedPrintable(const QCString& str); /** En/-decode given string to/from Base64. */ static QCString decodeBase64(const QCString& str); static QCString encodeBase64(const QCString& str); /** Helper function for encodeRFC2047String */ static QCString encodeRFC2047Quoted(const QCString& aStr, bool base64); /** This function handles both encodings described in RFC2047: Base64 ("=?iso-8859-1?b?...?=") and quoted-printable */ static QString decodeRFC2047String(const QCString& aStr); /** Encode given string as described in RFC2047: using quoted-printable. */ static QCString encodeRFC2047String(const QString& aStr, const QCString& charset); /** Encode given string as described in RFC2231 (parameters in MIME headers) */ static QCString encodeRFC2231String(const QString& aStr, const QCString& charset); /** Decode given string as described in RFC2231 */ static QString decodeRFC2231String(const QCString& aStr); /** * Find out preferred charset for 'text'. * First @p encoding is tried and if that one is not suitable, * the encodings in @p encodingList are tried. */ static QCString autoDetectCharset(const QCString &encoding, const QStringList &encodingList, const QString &text); /** Returns the message serial number for the message. */ virtual unsigned long getMsgSerNum() const; /** If undo for this message should be enabled */ virtual bool enableUndo() { return mEnableUndo; } virtual void setEnableUndo( bool enable ) { mEnableUndo = enable; } protected: KMFolderIndex* mParent; bool mDirty; off_t mIndexOffset; short mIndexLength; bool mEnableUndo; public: enum MsgPartType { MsgNoPart = 0, //unicode strings MsgFromPart = 1, MsgSubjectPart = 2, MsgToPart = 3, MsgReplyToIdMD5Part = 4, MsgIdMD5Part = 5, MsgXMarkPart = 6, //unsigned long MsgOffsetPart = 7, MsgStatusPart = 8, MsgSizePart = 9, MsgDatePart = 10, MsgFilePart = 11, MsgCryptoStatePart = 12, - MsgMDNSentPart = 13 + MsgMDNSentPart = 13, + //another two unicode strings + MsgReplyToAuxIdMD5Part = 14, + MsgStrippedSubjectMD5Part = 15 }; /** access to long msgparts */ off_t getLongPart(MsgPartType) const; /** access to string msgparts */ QString getStringPart(MsgPartType) const; /** sync'ing just one KMMsgBase */ bool syncIndexString() const; }; #endif /*kmmsgbase_h*/ diff --git a/kmail/kmmsginfo.cpp b/kmail/kmmsginfo.cpp index 8e22e36206..d250d6ef85 100644 --- a/kmail/kmmsginfo.cpp +++ b/kmail/kmmsginfo.cpp @@ -1,529 +1,598 @@ // kmmsginfo.cpp #include "kmmsginfo.h" #include "kmmessage.h" #include "kmmsgpart.h" // for encode #include #include #include #include #include class KMMsgInfo::KMMsgInfoPrivate { public: enum { SUBJECT_SET = 0x01, TO_SET = 0x02, REPLYTO_SET = 0x04, MSGID_SET=0x08, DATE_SET = 0x10, OFFSET_SET = 0x20, SIZE_SET = 0x40, XMARK_SET=0x100, FROM_SET=0x200, FILE_SET=0x400, ENCRYPTION_SET=0x800, - SIGNATURE_SET=0x1000, MDN_SET=0x2000, + SIGNATURE_SET=0x1000, MDN_SET=0x2000, REPLYTOAUX_SET = 0x4000, + STRIPPEDSUBJECT_SET = 0x8000, ALL_SET = 0xFFFF, NONE_SET = 0x0000 }; - ushort modifiers; - QString subject, from, to, replyToIdMD5, msgIdMD5, xmark, file; + uint modifiers; + QString subject, from, to, replyToIdMD5, replyToAuxIdMD5, strippedSubjectMD5, msgIdMD5, xmark, file; off_t folderOffset; size_t msgSize; time_t date; KMMsgEncryptionState encryptionState; KMMsgSignatureState signatureState; KMMsgMDNSentState mdnSentState; KMMsgInfoPrivate() : modifiers(NONE_SET) { } KMMsgInfoPrivate& operator=(const KMMsgInfoPrivate& other) { modifiers = NONE_SET; if (other.modifiers & SUBJECT_SET) { modifiers |= SUBJECT_SET; subject = other.subject; } + if (other.modifiers & STRIPPEDSUBJECT_SET) { + modifiers |= STRIPPEDSUBJECT_SET; + strippedSubjectMD5 = other.strippedSubjectMD5; + } if (other.modifiers & FROM_SET) { modifiers |= FROM_SET; from = other.from; } if (other.modifiers & FILE_SET) { modifiers |= FILE_SET; file = other.from; } if (other.modifiers & TO_SET) { modifiers |= TO_SET; to = other.to; } if (other.modifiers & REPLYTO_SET) { modifiers |= REPLYTO_SET; replyToIdMD5 = other.replyToIdMD5; } + if (other.modifiers & REPLYTOAUX_SET) { + modifiers |= REPLYTOAUX_SET; + replyToAuxIdMD5 = other.replyToAuxIdMD5; + } + if(other.modifiers & MSGID_SET) { modifiers |= MSGID_SET; msgIdMD5 = other.msgIdMD5; } if(other.modifiers & XMARK_SET) { modifiers |= XMARK_SET; xmark = other.xmark; } if(other.modifiers & OFFSET_SET) { modifiers |= OFFSET_SET; folderOffset = other.folderOffset; } if(other.modifiers & SIZE_SET) { modifiers |= SIZE_SET; msgSize = other.msgSize; } if(other.modifiers & DATE_SET) { modifiers |= DATE_SET; date = other.date; } if(other.modifiers & ENCRYPTION_SET) { modifiers |= ENCRYPTION_SET; encryptionState = other.encryptionState; } if(other.modifiers & SIGNATURE_SET) { modifiers |= SIGNATURE_SET; signatureState = other.signatureState; } if(other.modifiers & ENCRYPTION_SET) { modifiers |= ENCRYPTION_SET; encryptionState = other.encryptionState; } if(other.modifiers & SIGNATURE_SET) { modifiers |= SIGNATURE_SET; signatureState = other.signatureState; } if(other.modifiers & MDN_SET) { modifiers |= MDN_SET; mdnSentState = other.mdnSentState; } return *this; } }; //----------------------------------------------------------------------------- KMMsgInfo::KMMsgInfo(KMFolderIndex* p, off_t off, short len) : KMMsgInfoInherited(p), mStatus(KMMsgStatusUnknown), kd(0) { setIndexOffset(off); setIndexLength(len); setEnableUndo(true); } //----------------------------------------------------------------------------- KMMsgInfo::~KMMsgInfo() { delete kd; } //----------------------------------------------------------------------------- KMMsgInfo& KMMsgInfo::operator=(const KMMsgInfo& other) { KMMsgInfoInherited::assign(&other); if(other.kd) { if(!kd) kd = new KMMsgInfoPrivate; *kd = *other.kd; } else { delete kd; kd = 0; } mStatus = other.status(); return *this; } //----------------------------------------------------------------------------- KMMsgInfo& KMMsgInfo::operator=(const KMMessage& msg) { KMMsgInfoInherited::assign(&msg); if(!kd) kd = new KMMsgInfoPrivate; kd->modifiers = KMMsgInfoPrivate::ALL_SET; kd->subject = msg.subject(); kd->from = msg.fromStrip(); kd->to = msg.toStrip(); kd->replyToIdMD5 = msg.replyToIdMD5(); + kd->replyToAuxIdMD5 = msg.replyToAuxIdMD5(); + kd->strippedSubjectMD5 = msg.strippedSubjectMD5(); kd->msgIdMD5 = msg.msgIdMD5(); kd->xmark = msg.xmark(); mStatus = msg.status(); kd->folderOffset = msg.folderOffset(); kd->msgSize = msg.msgSize(); kd->date = msg.date(); kd->file = msg.fileName(); kd->encryptionState = msg.encryptionState(); kd->signatureState = msg.signatureState(); kd->mdnSentState = msg.mdnSentState(); return *this; } //----------------------------------------------------------------------------- void KMMsgInfo::init(const QCString& aSubject, const QCString& aFrom, const QCString& aTo, time_t aDate, KMMsgStatus aStatus, const QCString& aXMark, - const QCString& replyToId, const QCString& msgId, + const QCString& replyToId, const QCString& replyToAuxId, + const QCString& msgId, KMMsgEncryptionState encryptionState, KMMsgSignatureState signatureState, KMMsgMDNSentState mdnSentState, off_t aFolderOffset, size_t aMsgSize) { mIndexOffset = 0; mIndexLength = 0; if(!kd) kd = new KMMsgInfoPrivate; kd->modifiers = KMMsgInfoPrivate::ALL_SET; kd->subject = decodeRFC2047String(aSubject); kd->from = KMMessage::stripEmailAddr( decodeRFC2047String(aFrom) ); kd->to = KMMessage::stripEmailAddr( decodeRFC2047String(aTo) ); kd->replyToIdMD5 = KMMessagePart::encodeBase64( replyToId ); + kd->replyToAuxIdMD5 = KMMessagePart::encodeBase64( replyToAuxId ); + kd->strippedSubjectMD5 = KMMessagePart::encodeBase64( KMMessage::stripOffPrefixes( kd->subject ) ); kd->msgIdMD5 = KMMessagePart::encodeBase64( msgId ); kd->xmark = aXMark; kd->folderOffset = aFolderOffset; mStatus = aStatus; kd->msgSize = aMsgSize; kd->date = aDate; kd->file = ""; kd->encryptionState = encryptionState; kd->signatureState = signatureState; kd->mdnSentState = mdnSentState; mDirty = FALSE; } void KMMsgInfo::init(const QCString& aSubject, const QCString& aFrom, const QCString& aTo, time_t aDate, KMMsgStatus aStatus, const QCString& aXMark, - const QCString& replyToId, const QCString& msgId, + const QCString& replyToId, const QCString& replyToAuxId, + const QCString& msgId, const QCString& aFileName, KMMsgEncryptionState encryptionState, KMMsgSignatureState signatureState, KMMsgMDNSentState mdnSentState, unsigned long aMsgSize) { // use the "normal" init for most stuff - init(aSubject, aFrom, aTo, aDate, aStatus, aXMark, replyToId, msgId, - encryptionState, signatureState, mdnSentState, (unsigned long)0, aMsgSize); + init(aSubject, aFrom, aTo, aDate, aStatus, aXMark, replyToId, replyToAuxId, + msgId, encryptionState, signatureState, mdnSentState, + (unsigned long)0, aMsgSize); kd->file = aFileName; } //----------------------------------------------------------------------------- QString KMMsgInfo::subject(void) const { if (kd && kd->modifiers & KMMsgInfoPrivate::SUBJECT_SET) return kd->subject; return getStringPart(MsgSubjectPart); } //----------------------------------------------------------------------------- QString KMMsgInfo::fromStrip(void) const { if (kd && kd->modifiers & KMMsgInfoPrivate::FROM_SET) return kd->from; return getStringPart(MsgFromPart); } //----------------------------------------------------------------------------- QString KMMsgInfo::fileName(void) const { if (kd && kd->modifiers & KMMsgInfoPrivate::FILE_SET) return kd->file; return getStringPart(MsgFilePart); } //----------------------------------------------------------------------------- QString KMMsgInfo::toStrip(void) const { if (kd && kd->modifiers & KMMsgInfoPrivate::TO_SET) return kd->to; return getStringPart(MsgToPart); } //----------------------------------------------------------------------------- QString KMMsgInfo::xmark(void) const { if (kd && kd->modifiers & KMMsgInfoPrivate::XMARK_SET) return kd->xmark; return getStringPart(MsgXMarkPart); } //----------------------------------------------------------------------------- QString KMMsgInfo::replyToIdMD5(void) const { if (kd && kd->modifiers & KMMsgInfoPrivate::REPLYTO_SET) return kd->replyToIdMD5; return getStringPart(MsgReplyToIdMD5Part); } +//----------------------------------------------------------------------------- +QString KMMsgInfo::replyToAuxIdMD5(void) const +{ + if (kd && kd->modifiers & KMMsgInfoPrivate::REPLYTOAUX_SET) + return kd->replyToAuxIdMD5; + return getStringPart(MsgReplyToAuxIdMD5Part); +} + +//----------------------------------------------------------------------------- +QString KMMsgInfo::strippedSubjectMD5(void) const +{ + if (kd && kd->modifiers & KMMsgInfoPrivate::STRIPPEDSUBJECT_SET) + return kd->strippedSubjectMD5; + return getStringPart(MsgStrippedSubjectMD5Part); +} + + +//----------------------------------------------------------------------------- +bool KMMsgInfo::subjectIsPrefixed(void) const +{ + return !(strippedSubjectMD5() == KMMessagePart::encodeBase64(subject())); +} //----------------------------------------------------------------------------- QString KMMsgInfo::msgIdMD5(void) const { if (kd && kd->modifiers & KMMsgInfoPrivate::MSGID_SET) return kd->msgIdMD5; return getStringPart(MsgIdMD5Part); } //----------------------------------------------------------------------------- void KMMsgInfo::setSubject(const QString& aSubject) { if(aSubject == subject()) return; if (!kd) kd = new KMMsgInfoPrivate; kd->modifiers |= KMMsgInfoPrivate::SUBJECT_SET; kd->subject = aSubject; mDirty = TRUE; } //----------------------------------------------------------------------------- void KMMsgInfo::setXMark(const QString& aXMark) { if (aXMark == xmark()) return; if (!kd) kd = new KMMsgInfoPrivate; kd->modifiers |= KMMsgInfoPrivate::XMARK_SET; kd->xmark = aXMark; mDirty = TRUE; } //----------------------------------------------------------------------------- void KMMsgInfo::setReplyToIdMD5(const QString& aReplyToIdMD5) { if (aReplyToIdMD5 == replyToIdMD5()) return; if (!kd) kd = new KMMsgInfoPrivate; kd->modifiers |= KMMsgInfoPrivate::REPLYTO_SET; kd->replyToIdMD5 = aReplyToIdMD5; mDirty = TRUE; } +//----------------------------------------------------------------------------- +void KMMsgInfo::setReplyToAuxIdMD5(const QString& aReplyToAuxIdMD5) +{ + if (aReplyToAuxIdMD5 == replyToAuxIdMD5()) + return; + + if (!kd) + kd = new KMMsgInfoPrivate; + kd->modifiers |= KMMsgInfoPrivate::REPLYTOAUX_SET; + kd->replyToAuxIdMD5 = aReplyToAuxIdMD5; + mDirty = TRUE; +} + + + +//----------------------------------------------------------------------------- +void KMMsgInfo::initStrippedSubjectMD5() +{ + if (kd && kd->modifiers & KMMsgInfoPrivate::STRIPPEDSUBJECT_SET) + return; + QString rawSubject = KMMessage::stripOffPrefixes(subject()); + QString subjectMD5 = KMMessagePart::encodeBase64(rawSubject); + if (!kd) + kd = new KMMsgInfoPrivate; + kd->modifiers |= KMMsgInfoPrivate::STRIPPEDSUBJECT_SET; + kd->strippedSubjectMD5 = subjectMD5; + mDirty = TRUE; +} + + //----------------------------------------------------------------------------- void KMMsgInfo::setMsgIdMD5(const QString& aMsgIdMD5) { if (aMsgIdMD5 == msgIdMD5()) return; if (!kd) kd = new KMMsgInfoPrivate; kd->modifiers |= KMMsgInfoPrivate::MSGID_SET; kd->msgIdMD5 = aMsgIdMD5; mDirty = TRUE; } //----------------------------------------------------------------------------- void KMMsgInfo::setEncryptionState( const KMMsgEncryptionState s, int idx ) { if (s == encryptionState()) return; if (!kd) kd = new KMMsgInfoPrivate; kd->modifiers |= KMMsgInfoPrivate::ENCRYPTION_SET; kd->encryptionState = s; KMMsgBase::setEncryptionState(s, idx); //base does more "stuff" mDirty = TRUE; } //----------------------------------------------------------------------------- void KMMsgInfo::setSignatureState( const KMMsgSignatureState s, int idx ) { if (s == signatureState()) return; if (!kd) kd = new KMMsgInfoPrivate; kd->modifiers |= KMMsgInfoPrivate::SIGNATURE_SET; kd->signatureState = s; KMMsgBase::setSignatureState(s, idx); //base does more "stuff" mDirty = TRUE; } //----------------------------------------------------------------------------- void KMMsgInfo::setMDNSentState( const KMMsgMDNSentState s, int idx ) { if (s == mdnSentState()) return; if (!kd) kd = new KMMsgInfoPrivate; kd->modifiers |= KMMsgInfoPrivate::MDN_SET; kd->mdnSentState = s; KMMsgBase::setMDNSentState(s, idx); //base does more "stuff" mDirty = TRUE; } //----------------------------------------------------------------------------- KMMsgStatus KMMsgInfo::status(void) const { if (mStatus == KMMsgStatusUnknown) ((KMMsgInfo *)this)->mStatus = (KMMsgStatus)getLongPart(MsgStatusPart); return mStatus; } //----------------------------------------------------------------------------- KMMsgEncryptionState KMMsgInfo::encryptionState() const { if (kd && kd->modifiers & KMMsgInfoPrivate::ENCRYPTION_SET) return kd->encryptionState; unsigned long encState = getLongPart(MsgCryptoStatePart) & 0x0000FFFF; return encState ? (KMMsgEncryptionState)encState : KMMsgEncryptionStateUnknown; } KMMsgSignatureState KMMsgInfo::signatureState() const { if (kd && kd->modifiers & KMMsgInfoPrivate::SIGNATURE_SET) return kd->signatureState; unsigned long sigState = getLongPart(MsgCryptoStatePart) >> 16; return sigState ? (KMMsgSignatureState)sigState : KMMsgSignatureStateUnknown; } KMMsgMDNSentState KMMsgInfo::mdnSentState() const { if (kd && kd->modifiers & KMMsgInfoPrivate::MDN_SET) return kd->mdnSentState; unsigned long mdnState = getLongPart(MsgMDNSentPart); return mdnState ? (KMMsgMDNSentState)mdnState : KMMsgMDNStateUnknown; } //----------------------------------------------------------------------------- off_t KMMsgInfo::folderOffset(void) const { if (kd && kd->modifiers & KMMsgInfoPrivate::OFFSET_SET) return kd->folderOffset; return getLongPart(MsgOffsetPart); } //----------------------------------------------------------------------------- size_t KMMsgInfo::msgSize(void) const { if (kd && kd->modifiers & KMMsgInfoPrivate::SIZE_SET) return kd->msgSize; return getLongPart(MsgSizePart); } //----------------------------------------------------------------------------- time_t KMMsgInfo::date(void) const { if (kd && kd->modifiers & KMMsgInfoPrivate::DATE_SET) return kd->date; return getLongPart(MsgDatePart); } //----------------------------------------------------------------------------- void KMMsgInfo::setMsgSize(size_t sz) { if (sz == msgSize()) return; if(!kd) kd = new KMMsgInfoPrivate; kd->modifiers |= KMMsgInfoPrivate::SIZE_SET; kd->msgSize = sz; mDirty = TRUE; } //----------------------------------------------------------------------------- void KMMsgInfo::setFolderOffset(off_t offs) { if (folderOffset() == offs) return; if (!kd) kd = new KMMsgInfoPrivate; kd->modifiers |= KMMsgInfoPrivate::OFFSET_SET; kd->folderOffset = offs; mDirty = TRUE; } //----------------------------------------------------------------------------- void KMMsgInfo::setFileName(const QString& file) { if (fileName() == file) return; if (!kd) kd = new KMMsgInfoPrivate; kd->modifiers |= KMMsgInfoPrivate::FILE_SET; kd->file = file; mDirty = TRUE; } //----------------------------------------------------------------------------- void KMMsgInfo::setStatus(const KMMsgStatus aStatus, int idx) { if(aStatus == status()) return; KMMsgBase::setStatus(aStatus, idx); //base does more "stuff" mStatus = aStatus; mDirty = TRUE; } //----------------------------------------------------------------------------- void KMMsgInfo::setDate(time_t aUnixTime) { if(aUnixTime == date()) return; if(!kd) kd = new KMMsgInfoPrivate; kd->modifiers |= KMMsgInfoPrivate::DATE_SET; kd->date = aUnixTime; mDirty = TRUE; } //--- For compatability with old index files void KMMsgInfo::compat_fromOldIndexString(const QCString& str, bool toUtf8) { char *start, *offset; if(!kd) kd = new KMMsgInfoPrivate; kd->modifiers = KMMsgInfoPrivate::ALL_SET; kd->xmark = str.mid(33, 3).stripWhiteSpace(); 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); if (toUtf8) { kd->subject = str.mid(37, 100).stripWhiteSpace(); kd->from = str.mid(138, 50).stripWhiteSpace(); kd->to = str.mid(189, 50).stripWhiteSpace(); } else { start = offset = str.data() + 37; while (*start == ' ' && start - offset < 100) start++; kd->subject = QString::fromUtf8(str.mid(start - str.data(), 100 - (start - offset)), 100 - (start - offset)); start = offset = str.data() + 138; while (*start == ' ' && start - offset < 50) start++; kd->from = QString::fromUtf8(str.mid(start - str.data(), 50 - (start - offset)), 50 - (start - offset)); start = offset = str.data() + 189; while (*start == ' ' && start - offset < 50) start++; kd->to = QString::fromUtf8(str.mid(start - str.data(), 50 - (start - offset)), 50 - (start - offset)); } kd->replyToIdMD5 = str.mid(240, 22).stripWhiteSpace(); kd->msgIdMD5 = str.mid(263, 22).stripWhiteSpace(); mDirty = FALSE; } bool KMMsgInfo::dirty(void) const { if(KMMsgBase::dirty()) return TRUE; return kd && kd->modifiers != KMMsgInfoPrivate::NONE_SET; } diff --git a/kmail/kmmsginfo.h b/kmail/kmmsginfo.h index 79c453536b..9a2567a5ac 100644 --- a/kmail/kmmsginfo.h +++ b/kmail/kmmsginfo.h @@ -1,95 +1,104 @@ /* Message info describing a messages in a folder * * Author: Stefan Taferner */ #ifndef kmmsginfo_h #define kmmsginfo_h #include #include #include "kmmsgbase.h" class KMMessage; #define KMMsgInfoInherited KMMsgBase class KMMsgInfo: public KMMsgBase { public: KMMsgInfo(KMFolderIndex* parent, off_t off=0, short len=0); virtual ~KMMsgInfo(); /** left for old style index files */ void compat_fromOldIndexString(const QCString& str, bool toUtf8); /** Initialize with given values and set dirty flag to FALSE. */ virtual void init(const QCString& subject, const QCString& from, const QCString& to, time_t date, KMMsgStatus status, const QCString& xmark, - const QCString& replyToId, const QCString& msgId, + const QCString& replyToId, + const QCString& replyToAuxId, + const QCString& msgId, KMMsgEncryptionState encryptionState, KMMsgSignatureState signatureState, KMMsgMDNSentState mdnSentState, off_t folderOffset=0, size_t msgSize=0); /** Initialize with given values and set dirty flag to FALSE. */ virtual void init(const QCString& subject, const QCString& from, const QCString& to, time_t date, KMMsgStatus status, const QCString& xmark, - const QCString& replyToId, const QCString& msgId, + const QCString& replyToId, + const QCString& replyToAuxId, + const QCString& msgId, const QCString& fileName, KMMsgEncryptionState encryptionState, KMMsgSignatureState signatureState, KMMsgMDNSentState mdnSentState, unsigned long msgSize=0); /** Inherited methods (see @ref KMMsgBase for description): */ virtual QString subject(void) const; virtual QString fromStrip(void) const; virtual QString toStrip(void) const; virtual QString xmark(void) const; virtual QString replyToIdMD5(void) const; + virtual QString replyToAuxIdMD5(void) const; + virtual QString strippedSubjectMD5(void) const; + virtual bool subjectIsPrefixed(void) const; virtual QString msgIdMD5(void) const; virtual QString fileName(void) const; virtual KMMsgStatus status(void) const; virtual KMMsgEncryptionState encryptionState() const; virtual KMMsgSignatureState signatureState() const; virtual KMMsgMDNSentState mdnSentState() const; virtual off_t folderOffset(void) const; virtual size_t msgSize(void) const; virtual time_t date(void) const; void setMsgSize(size_t sz); void setFolderOffset(off_t offs); void setFileName(const QString& file); virtual void setStatus(const KMMsgStatus status, int idx = -1); virtual void setDate(time_t aUnixTime); virtual void setSubject(const QString&); virtual void setXMark(const QString&); virtual void setReplyToIdMD5(const QString&); + virtual void setReplyToAuxIdMD5(const QString&); + virtual void initStrippedSubjectMD5(); virtual void setMsgIdMD5(const QString&); virtual void setEncryptionState( const KMMsgEncryptionState, int idx = -1 ); virtual void setSignatureState( const KMMsgSignatureState, int idx = -1 ); virtual void setMDNSentState( const KMMsgMDNSentState, int idx = -1 ); /** Grr.. c++! */ virtual void setStatus(const char* s1, const char* s2=0) { KMMsgBase::setStatus(s1, s2); } virtual void setDate(const char* s1) { KMMsgBase::setDate(s1); } virtual bool dirty(void) const; /** Copy operators. */ KMMsgInfo& operator=(const KMMessage&); KMMsgInfo& operator=(const KMMsgInfo&); private: // WARNING: Do not add new member variables to the class. Add them to kd KMMsgStatus mStatus; class KMMsgInfoPrivate; KMMsgInfoPrivate *kd; }; typedef KMMsgInfo* KMMsgInfoPtr; #endif /*kmmsginfo_h*/