[prev in list] [next in list] [prev in thread] [next in thread]
List: kmail-devel
Subject: Re: [Patch] Improved threading (by references and subject)
From: Till Adam <till () adam-lilienthal ! de>
Date: 2003-03-09 9:11:39
[Download RAW message or body]
On Sunday 09 March 2003 09:38, Till Adam wrote:
> Do you want me to regenerate a patch with this in, no tabs, and p, or can
> you manage with what you have?
What the hell. Attached. :)
Till
["ImprovedThreadingRC1.diff" (text/x-diff)]
Index: kmfoldermaildir.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmfoldermaildir.cpp,v
retrieving revision 1.50
diff -u -3 -p -w -r1.50 kmfoldermaildir.cpp
--- kmfoldermaildir.cpp 27 Feb 2003 10:39:48 -0000 1.50
+++ kmfoldermaildir.cpp 9 Mar 2003 08:58:50 -0000
@@ -558,7 +558,7 @@ void KMFolderMaildir::readFileHeaderInte
QCString dateStr, fromStr, toStr, subjStr;
QCString xmarkStr, replyToIdStr, msgIdStr, referencesStr;
- QCString statusStr;
+ QCString statusStr, replyToAuxIdStr;
// iterate through this file until done
while (!atEof)
@@ -574,7 +574,10 @@ void KMFolderMaildir::readFileHeaderInte
if ((replyToIdStr.isEmpty() || (replyToIdStr[0] != '<')) &&
!referencesStr.isEmpty() && referencesStr[0] == '<')
{
- replyToIdStr = referencesStr;
+ // use the last reference, instead of missing In-Reply-To
+ int leftAngle = referencesStr.findRev( '<' );
+ if (leftAngle != -1)
+ replyToIdStr = referencesStr.mid(leftAngle);
}
if (!statusStr.isEmpty())
@@ -594,8 +597,9 @@ void KMFolderMaildir::readFileHeaderInte
KMMsgInfo *mi = new KMMsgInfo(this);
mi->init(subjStr, fromStr, toStr, 0, status, xmarkStr, replyToIdStr,
- msgIdStr, file.local8Bit(), KMMsgEncryptionStateUnknown,
- KMMsgSignatureStateUnknown, KMMsgMDNStateUnknown, f.size());
+ replyToAuxIdStr, msgIdStr, file.local8Bit(),
+ KMMsgEncryptionStateUnknown, KMMsgSignatureStateUnknown,
+ KMMsgMDNStateUnknown, f.size());
if (!dateStr.isEmpty())
mi->setDate(dateStr);
mi->setDirty(false);
@@ -658,12 +662,21 @@ void KMFolderMaildir::readFileHeaderInte
referencesStr = QCString(line+12);
leftAngle = referencesStr.findRev('<');
+ leftAngle = referencesStr.findRev( '<', leftAngle-1);
if (leftAngle != -1)
referencesStr = referencesStr.mid(leftAngle);
+ rightAngle = referencesStr.findRev( '>' );
+ if (rightAngle != -1)
+ referencesStr.truncate( rightAngle + 1 );
+ // Store the second to last reference in the replyToAuxIdStr
+ // It is a good candidate for threading the message below if the
+ // message In-Reply-To points to is not kept in this folder,
+ // but e.g. in an Outbox
+ replyToAuxIdStr = referencesStr;
rightAngle = referencesStr.find('>');
if (rightAngle != -1)
- referencesStr.truncate(rightAngle + 1);
+ replyToAuxIdStr.truncate( rightAngle + 1 );
}
else if (strncasecmp(line, "Message-Id:", 11) == 0 && isblank(line[11]))
{
Index: kmfoldermbox.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmfoldermbox.cpp,v
retrieving revision 1.57
diff -u -3 -p -w -r1.57 kmfoldermbox.cpp
--- kmfoldermbox.cpp 26 Feb 2003 13:14:01 -0000 1.57
+++ kmfoldermbox.cpp 9 Mar 2003 08:58:52 -0000
@@ -527,7 +527,7 @@ int KMFolderMbox::createIndexFromContent
char line[MAX_LINE];
char status[8], xstatus[8];
QCString subjStr, dateStr, fromStr, toStr, xmarkStr, *lastStr=0;
- QCString replyToIdStr, referencesStr, msgIdStr;
+ QCString replyToIdStr, replyToAuxIdStr, referencesStr, msgIdStr;
bool atEof = FALSE;
bool inHeader = TRUE;
KMMsgInfo* mi;
@@ -554,6 +554,8 @@ int KMFolderMbox::createIndexFromContent
*xstatus = '\0';
xmarkStr = "";
replyToIdStr = "";
+ replyToAuxIdStr = "";
+ referencesStr = "";
msgIdStr = "";
needStatus = 3;
@@ -583,10 +585,15 @@ int KMFolderMbox::createIndexFromContent
{
if ((replyToIdStr.isEmpty() || (replyToIdStr[0] != '<')) &&
!referencesStr.isEmpty() && referencesStr[0] == '<') {
- replyToIdStr = referencesStr;
+ // use the last reference, instead of missing In-Reply-To
+ int leftAngle = referencesStr.findRev( '<' );
+ if (leftAngle != -1)
+ replyToIdStr = referencesStr.mid(leftAngle);
}
+
mi = new KMMsgInfo(this);
- mi->init(subjStr, fromStr, toStr, 0, KMMsgStatusNew, xmarkStr, replyToIdStr, \
msgIdStr, + mi->init(subjStr, fromStr, toStr, 0, KMMsgStatusNew, xmarkStr,
+ replyToIdStr, replyToAuxIdStr, msgIdStr,
KMMsgEncryptionStateUnknown, KMMsgSignatureStateUnknown,
KMMsgMDNStateUnknown, offs, size);
mi->setStatus("RO","O");
@@ -599,6 +606,7 @@ int KMFolderMbox::createIndexFromContent
needStatus = 3;
xmarkStr = "";
replyToIdStr = "";
+ replyToAuxIdStr = "";
referencesStr = "";
msgIdStr = "";
dateStr = "";
@@ -658,11 +666,22 @@ int KMFolderMbox::createIndexFromContent
int leftAngle, rightAngle;
referencesStr = QCString(line+12);
leftAngle = referencesStr.findRev( '<' );
+ leftAngle = referencesStr.findRev( '<', leftAngle-1);
if (leftAngle != -1)
referencesStr = referencesStr.mid( leftAngle );
- rightAngle = referencesStr.find( '>' );
+ rightAngle = referencesStr.findRev( '>' );
if (rightAngle != -1)
referencesStr.truncate( rightAngle + 1 );
+
+ // Store the second to last reference in the replyToAuxIdStr
+ // It is a good candidate for threading the message below if the
+ // message In-Reply-To points to is not kept in this folder,
+ // but e.g. in an Outbox
+ replyToAuxIdStr = referencesStr;
+ rightAngle = referencesStr.find( '>' );
+ if (rightAngle != -1)
+ replyToAuxIdStr.truncate( rightAngle + 1 );
+
}
else if (strncasecmp(line,"Message-Id:",11)==0 && isblank(line[11])) {
int rightAngle;
Index: kmheaders.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmheaders.cpp,v
retrieving revision 1.484
diff -u -3 -p -w -r1.484 kmheaders.cpp
--- kmheaders.cpp 26 Feb 2003 13:14:01 -0000 1.484
+++ kmheaders.cpp 9 Mar 2003 08:58:57 -0000
@@ -2300,7 +2300,7 @@ void KMHeaders::setSorting( int column,
}
//Flatten the list and write it to disk
-#define KMAIL_SORT_VERSION 1011
+#define KMAIL_SORT_VERSION 1012
#define KMAIL_SORT_FILE(x) x->indexLocation() + ".sorted"
#define KMAIL_SORT_HEADER "## KMail Sort V%04d\n\t"
#define KMAIL_MAGIC_HEADER_OFFSET 21 //strlen(KMAIL_SORT_HEADER)
@@ -2385,32 +2385,77 @@ bool KMHeaders::writeSortOrder()
}
}
}
- KMMsgBase *kmb;
- while(KMHeaderItem *i = items.pop()) {
- kmb = mFolder->getMsgBase( i->mMsgId );
- QString replymd5 = kmb->replyToIdMD5();
- int parent_id = -2; //no parent, top level
- if(!replymd5.isEmpty()) {
if(mIdTree.isEmpty()) {
- QString md5;
for(int x = 0; x < mFolder->count(); x++) {
+ QString md5;
if(mItems[x]) {
- md5 = mFolder->getMsgBase(x)->msgIdMD5();
- if(md5.isEmpty()) continue;
- if(mIdTree[md5])
- ;
- else
+ KMMsgBase *mb = mFolder->getMsgBase(x);
+ md5 = mb->msgIdMD5();
+ if (!md5.isEmpty() && !mIdTree[md5])
mIdTree.insert(md5, mItems[x]);
}
}
}
- KMHeaderItem *p = mIdTree[replymd5];
- if(p)
+ QDict<KMHeaderItem> msgSubjects(mFolder->count()*2);
+ for(int x = 0; x < mFolder->count(); x++) {
+ if(mItems[x]) {
+ QString subjMD5;
+ KMMsgBase *mb = mFolder->getMsgBase(x);
+ subjMD5 = mb->strippedSubjectMD5();
+ if (subjMD5.isEmpty()) {
+ mb->initStrippedSubjectMD5();
+ subjMD5 = mb->strippedSubjectMD5();
+ }
+ if( !subjMD5.isEmpty() && !msgSubjects.find(subjMD5) ) {
+ QString replyToIdMD5 = mb->replyToIdMD5();
+ QString replyToAuxIdMD5 = mb->replyToAuxIdMD5();
+ if ( (replyToIdMD5.isEmpty() || !mIdTree[replyToIdMD5])
+ && (replyToAuxIdMD5.isEmpty() || !mIdTree[replyToAuxIdMD5]) )
+ msgSubjects.insert(subjMD5, mItems[x]);
+ }
+ }
+ }
+
+ KMMsgBase *kmb;
+ while(KMHeaderItem *i = items.pop()) {
+ kmb = mFolder->getMsgBase( i->mMsgId );
+
+ QString replymd5 = kmb->replyToIdMD5();
+ int parent_id = -2; //no parent, top level
+ KMHeaderItem *p = NULL;
+ if(!replymd5.isEmpty())
+ p = mIdTree[replymd5];
+
+ if (!p) {
+ // If we dont have a replyToId, or if we have one and the
+ // corresponding message is not in this folder, as happens
+ // if you keep your outgoing messages in an OUTBOX, for
+ // example, try the list of references, because the second
+ // to last will likely be in this folder. replyToAuxIdMD5 ontains
+ // the second to last one.
+ QString ref = kmb->replyToAuxIdMD5();
+ if (!ref.isEmpty())
+ p = mIdTree[ref];
+ }
+ // still no parent, let's try by subject
+ // Force unprefixed subjects that would be threaded by subject
+ // to the top level.
+ if (!p && kmb->subjectIsPrefixed()) {
+
+ QString subjMD5 = kmb->strippedSubjectMD5();
+ if (!subjMD5.isEmpty()) {
+ p = msgSubjects[subjMD5];
+ }
+ }
+ if( p) {
parent_id = p->mMsgId;
- else
+ if (parent_id == i->mMsgId)
parent_id = -1;
}
+ else
+ parent_id = -1;
+
internalWriteItem(sortStream, mFolder, i->mMsgId, parent_id,
i->key(mSortCol, !mSortDescending), FALSE);
//double check for magic headers
@@ -2440,7 +2485,6 @@ bool KMHeaders::writeSortOrder()
return TRUE;
}
-
void KMHeaders::appendUnsortedItem(KMHeaderItem *khi)
{
QString sortFile = KMAIL_SORT_FILE(mFolder);
@@ -2565,6 +2609,8 @@ static int compare_KMSortCacheItem(const
return ret;
}
+
+
bool KMHeaders::readSortOrder(bool set_selection)
{
//all cases
@@ -2768,20 +2814,72 @@ bool KMHeaders::readSortOrder(bool set_s
if (appended && threaded && !unparented.isEmpty()) {
CREATE_TIMER(reparent);
START_TIMER(reparent);
- KMSortCacheItem *i;
+ // Build two dictionaries, one with all messages and their ids, and
+ // one with the md5 hashes of the subject stripped of prefixes such as
+ // Re: or similar.
QDict<KMSortCacheItem> msgs(mFolder->count() * 2);
+ QDict<KMSortCacheItem> msgSubjects(mFolder->count() * 2);
for(int x = 0; x < mFolder->count(); x++) {
- QString md5 = mFolder->getMsgBase(x)->msgIdMD5();
- if(md5.isEmpty()) continue;
+ KMMsgBase *mi = mFolder->getMsgBase(x);
+ QString md5 = mi->msgIdMD5();
+ if(!md5.isEmpty())
msgs.insert(md5, sortCache[x]);
}
+ for(int x = 0; x < mFolder->count(); x++) {
+ KMMsgBase *mi = mFolder->getMsgBase(x);
+ QString subjMD5 = mi->strippedSubjectMD5();
+ if (subjMD5.isEmpty()) {
+ mFolder->getMsgBase(x)->initStrippedSubjectMD5();
+ subjMD5 = mFolder->getMsgBase(x)->strippedSubjectMD5();
+ }
+ // The first message with a certain subject is where we want to
+ // thread the other messages with the same suject below. Only keep
+ // that in the dict. Also only accept messages which would not
+ // otherwise be threaded by IDs as top level messages to avoid
+ // circular threading.
+ if( !subjMD5.isEmpty() && !msgSubjects.find(subjMD5) ) {
+ QString replyToIdMD5 = mi->replyToIdMD5();
+ QString replyToAuxIdMD5 = mi->replyToAuxIdMD5();
+ if ( (replyToIdMD5.isEmpty() || !msgs.find(replyToIdMD5))
+ && (replyToAuxIdMD5.isEmpty() || !msgs.find(replyToAuxIdMD5)) )
+ msgSubjects.insert(subjMD5, sortCache[x]);
+ }
+ }
for(QPtrListIterator<KMSortCacheItem> it(unparented); it.current(); ++it) {
- replyToIdMD5 = mFolder->getMsgBase((*it)->id())->replyToIdMD5();
- if(!replyToIdMD5.isEmpty() && (i = msgs[replyToIdMD5])) {
- i->addUnsortedChild((*it));
+ KMSortCacheItem *parent=NULL;
+ KMMsgBase *msg = mFolder->getMsgBase((*it)->id());
+ QString replyToIdMD5 = msg->replyToIdMD5();
+ if(!replyToIdMD5.isEmpty())
+ parent = msgs[replyToIdMD5];
+ if (!parent) {
+ // If we dont have a replyToId, or if we have one and the
+ // corresponding message is not in this folder, as happens
+ // if you keep your outgoing messages in an OUTBOX, for
+ // example, try the list of references, because the second
+ // to last will likely be in this folder. replyToAuxIdMD5
+ // contains the second to last one.
+ QString ref = msg->replyToAuxIdMD5();
+ if (!ref.isEmpty())
+ parent = msgs[ref];
+ }
+ if (!parent msg->subjectIsPrefixed()) {
+ // Still no parent, let's try by subject, but only if the
+ // subhect is prefixed. This is necessary to make for
+ // example cvs commit mailing lists work as expected without
+ // having to turn threading off alltogether.
+ // If we have a parent, make sure it's not ourselves
+ QString subjMD5 = msg->strippedSubjectMD5();
+ if (!subjMD5.isEmpty()) {
+ parent = msgSubjects[subjMD5];
+ }
+ }
+ // If we have a parent, make sure it's not ourselves.
+ if ( parent && (parent != (*it)) ) {
+ parent->addUnsortedChild((*it));
if(sortStream)
(*it)->updateSortFile(sortStream, mFolder);
- } else { //oh well we tried, to the root with you!
+ } else {
+ //oh well we tried, to the root with you!
root.addUnsortedChild((*it));
}
}
@@ -2845,7 +2943,6 @@ bool KMHeaders::readSortOrder(bool set_s
for (KMHeaderItem *khi=static_cast<KMHeaderItem*>(firstChild()); \
khi!=0;khi=static_cast<KMHeaderItem*>(khi->nextSibling())) khi->setOpen(true);
-
END_TIMER(header_creation);
SHOW_TIMER(header_creation);
@@ -2911,6 +3008,7 @@ bool KMHeaders::readSortOrder(bool set_s
fclose(sortStream);
return TRUE;
}
+
//-----------------------------------------------------------------------------
Index: kmkernel.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmkernel.cpp,v
retrieving revision 1.164
diff -u -3 -p -w -r1.164 kmkernel.cpp
--- kmkernel.cpp 28 Feb 2003 04:42:49 -0000 1.164
+++ kmkernel.cpp 9 Mar 2003 08:59:00 -0000
@@ -691,13 +691,14 @@ void KMKernel::init()
the_popFilterMgr = new KMFilterMgr(true);
the_filterActionDict = new KMFilterActionDict;
+ // moved up here because KMMessage::stripOffPrefixes is used below -ta
+ KMMessage::readConfig();
initFolders(cfg);
the_acctMgr->readConfig();
the_filterMgr->readConfig();
the_popFilterMgr->readConfig();
cleanupImapFolders();
- KMMessage::readConfig();
the_msgSender = new KMSender;
the_server_is_ready = true;
Index: kmmessage.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmmessage.cpp,v
retrieving revision 1.377
diff -u -3 -p -w -r1.377 kmmessage.cpp
--- kmmessage.cpp 26 Feb 2003 14:58:33 -0000 1.377
+++ kmmessage.cpp 9 Mar 2003 08:59:06 -0000
@@ -2136,6 +2136,54 @@ QString KMMessage::replyToIdMD5(void) co
return result;
}
+//-----------------------------------------------------------------------------
+QString KMMessage::references(void) const
+{
+ int leftAngle, rightAngle;
+ QString references = headerField("References");
+
+ // keep the last two entries for threading
+ leftAngle = references.findRev( '<' );
+ leftAngle = references.findRev( '<', leftAngle-1 );
+ if (leftAngle != -1)
+ references = references.mid( leftAngle );
+ rightAngle = references.findRev( '>' );
+ if (rightAngle != -1)
+ references.truncate( rightAngle + 1 );
+
+ if (!references.isEmpty() && references[0] == '<')
+ return references;
+ else
+ return "";
+}
+
+//-----------------------------------------------------------------------------
+QString KMMessage::replyToAuxIdMD5(void) const
+{
+ int rightAngle;
+ QString result = references();
+ // references contains two items, use the first one
+ // (the second to last reference)
+ rightAngle = result.find( '>' );
+ if (rightAngle != -1)
+ result.truncate (rightAngle+1);
+
+ return KMMessagePart::encodeBase64( result );
+}
+
+//-----------------------------------------------------------------------------
+QString KMMessage::strippedSubjectMD5(void) const
+{
+ QString result = stripOffPrefixes(subject());
+ return KMMessagePart::encodeBase64( result );
+}
+
+//-----------------------------------------------------------------------------
+bool KMMessage::subjectIsPrefixed(void) const
+{
+ return !(strippedSubjectMD5() == KMMessagePart::encodeBase64(subject()));
+
+}
//-----------------------------------------------------------------------------
void KMMessage::setReplyToId(const QString& aStr)
Index: kmmessage.h
===================================================================
RCS file: /home/kde/kdepim/kmail/kmmessage.h,v
retrieving revision 1.128
diff -u -3 -p -w -r1.128 kmmessage.h
--- kmmessage.h 23 Feb 2003 19:12:09 -0000 1.128
+++ kmmessage.h 9 Mar 2003 08:59:08 -0000
@@ -333,6 +333,9 @@ public:
virtual QString subject(void) const;
virtual void setSubject(const QString& aStr);
+ /** Calculate strippedSubject */
+ virtual void initStrippedSubjectMD5() {};
+
/** Check for prefixes @p prefixRegExps in @p str. If none
is found, @p newPrefix + ' ' is prepended to @p str and the
resulting string is returned. If @p replace is true, any
@@ -352,7 +355,7 @@ public:
is found, @p newPrefix + ' ' is prepended to the subject and the
resulting string is returned. If @p replace is true, any
sequence of whitespace-delimited prefixes at the beginning of
- @ref #subject() is replaced by @p newPrefix.
+ @ref #subject() is replaced by @p newPrefix
**/
QString cleanSubject(const QStringList& prefixRegExps, bool replace,
const QString& newPrefix) const;
@@ -376,12 +379,38 @@ public:
virtual void setReplyToId(const QString& aStr);
virtual QString replyToIdMD5(void) const;
+ /** Get the second to last id from the References header
+ field. If outgoing messages are not kept in the same
+ folder as incoming ones, this will be a good place to
+ thread the message beneath.
+ bob <- second to last reference points to this
+ |_kmailuser <- not in our folder, but Outbox
+ |_bob <- In-Reply-To points to our mail above
+
+ Thread like this:
+ bob
+ |_bob
+
+ using replyToAuxIdMD5
+ */
+ virtual QString replyToAuxIdMD5(void) const;
+
+ /**
+ Get a hash of the subject with all prefixes such as Re: removed.
+ Used for threading.
+ */
+ virtual QString strippedSubjectMD5(void) const;
+
+ /** Is the subject prefixed by Re: or similar? */
+ virtual bool subjectIsPrefixed(void) const;
+
/** Get or set the 'Message-Id' header field */
virtual QString msgId(void) const;
virtual void setMsgId(const QString& aStr);
virtual QString msgIdMD5(void) const;
- /** Set the references for this message */
+ /** Get or set the references for this message */
+ virtual QString references(void) const;
virtual void setReferences(const QCString& aStr);
/** Returns the message ID, useful for followups */
Index: kmmsgbase.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmmsgbase.cpp,v
retrieving revision 1.137
diff -u -3 -p -w -r1.137 kmmsgbase.cpp
--- kmmsgbase.cpp 18 Feb 2003 03:26:17 -0000 1.137
+++ kmmsgbase.cpp 9 Mar 2003 08:59:10 -0000
@@ -1047,6 +1047,13 @@ const uchar *KMMsgBase::asIndexString(in
STORE_DATA(MsgCryptoStatePart, tmp);
tmp = mdnSentState();
STORE_DATA(MsgMDNSentPart, tmp);
+
+ tmp_str = replyToAuxIdMD5().stripWhiteSpace();
+ STORE_DATA_LEN(MsgReplyToAuxIdMD5Part, tmp_str.unicode(), tmp_str.length() * 2, true);
+
+ tmp_str = strippedSubjectMD5().stripWhiteSpace();
+ STORE_DATA_LEN(MsgStrippedSubjectMD5Part, tmp_str.unicode(), tmp_str.length() * 2, true);
+
#undef STORE_DATA_LEN
return ret;
}
Index: kmmsgbase.h
===================================================================
RCS file: /home/kde/kdepim/kmail/kmmsgbase.h,v
retrieving revision 1.52
diff -u -3 -p -w -r1.52 kmmsgbase.h
--- kmmsgbase.h 26 Dec 2002 10:18:15 -0000 1.52
+++ kmmsgbase.h 9 Mar 2003 08:59:10 -0000
@@ -148,6 +148,9 @@ public:
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;
@@ -166,6 +169,9 @@ public:
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;
@@ -284,7 +290,10 @@ public:
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;
Index: kmmsginfo.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmmsginfo.cpp,v
retrieving revision 1.43
diff -u -3 -p -w -r1.43 kmmsginfo.cpp
--- kmmsginfo.cpp 26 Dec 2002 10:18:15 -0000 1.43
+++ kmmsginfo.cpp 9 Mar 2003 08:59:12 -0000
@@ -17,12 +17,13 @@ public:
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;
@@ -37,6 +38,10 @@ public:
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;
@@ -53,6 +58,11 @@ public:
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;
@@ -143,6 +153,8 @@ KMMsgInfo& KMMsgInfo::operator=(const KM
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();
@@ -161,7 +173,8 @@ KMMsgInfo& KMMsgInfo::operator=(const KM
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,
@@ -176,6 +189,8 @@ void KMMsgInfo::init(const QCString& aSu
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;
@@ -192,7 +207,8 @@ void KMMsgInfo::init(const QCString& aSu
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,
@@ -200,8 +216,9 @@ void KMMsgInfo::init(const QCString& aSu
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;
}
@@ -257,6 +274,28 @@ QString KMMsgInfo::replyToIdMD5(void) co
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
@@ -307,6 +346,36 @@ void KMMsgInfo::setReplyToIdMD5(const QS
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;
+}
+
//-----------------------------------------------------------------------------
Index: kmmsginfo.h
===================================================================
RCS file: /home/kde/kdepim/kmail/kmmsginfo.h,v
retrieving revision 1.30
diff -u -3 -p -w -r1.30 kmmsginfo.h
--- kmmsginfo.h 26 Dec 2002 10:18:15 -0000 1.30
+++ kmmsginfo.h 9 Mar 2003 08:59:12 -0000
@@ -27,7 +27,9 @@ public:
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,
@@ -37,7 +39,9 @@ public:
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,
@@ -50,6 +54,9 @@ public:
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;
@@ -67,6 +74,8 @@ public:
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 );
_______________________________________________
KMail Developers mailing list
kmail@mail.kde.org
http://mail.kde.org/mailman/listinfo/kmail
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic