mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
add subject attribute, add threading fixes
This commit is contained in:
parent
35d805638d
commit
15edba34e6
@ -233,10 +233,11 @@ protected:
|
||||
nsresult GetBoolPref(const char *prefName, PRBool *result);
|
||||
// retrieval methods
|
||||
nsMsgThread * GetThreadForReference(nsString2 &msgID);
|
||||
nsMsgThread * GetThreadForSubject(const char * subject);
|
||||
nsMsgThread * GetThreadForSubject(nsString2 &subject);
|
||||
nsMsgThread * GetThreadForThreadId(nsMsgKey threadId);
|
||||
nsMsgHdr * GetMsgHdrForReference(nsString2 &reference);
|
||||
nsIMsgDBHdr * GetMsgHdrForMessageID(nsString2 &msgID);
|
||||
nsIMsgDBHdr * GetMsgHdrForSubject(nsString2 &msgID);
|
||||
nsMsgThread * GetThreadContainingMsgHdr(nsMsgHdr *msgHdr);
|
||||
// threading interfaces
|
||||
virtual nsresult CreateNewThread(nsMsgKey key, nsMsgThread **newThread);
|
||||
@ -308,6 +309,7 @@ protected:
|
||||
mdb_token m_threadChildrenColumnToken;
|
||||
mdb_token m_threadUnreadChildrenColumnToken;
|
||||
mdb_token m_messageThreadIdColumnToken;
|
||||
mdb_token m_threadSubjectColumnToken;
|
||||
mdb_token m_numReferencesColumnToken;
|
||||
mdb_token m_messageCharSetColumnToken;
|
||||
nsIMsgHeaderParser *m_HeaderParser;
|
||||
|
@ -40,6 +40,8 @@ public:
|
||||
NS_IMETHOD GetThreadKey(nsMsgKey *result);
|
||||
NS_IMETHOD GetFlags(PRUint32 *result);
|
||||
NS_IMETHOD SetFlags(PRUint32 flags);
|
||||
NS_IMETHOD SetSubject(char *subject);
|
||||
NS_IMETHOD GetSubject(char **result);
|
||||
NS_IMETHOD GetNumChildren(PRUint32 *result);
|
||||
NS_IMETHOD GetNumUnreadChildren (PRUint32 *result);
|
||||
NS_IMETHOD AddChild(nsIMsgDBHdr *child, PRBool threadInThread);
|
||||
@ -47,7 +49,7 @@ public:
|
||||
NS_IMETHOD GetChild(nsMsgKey msgKey, nsIMsgDBHdr **result);
|
||||
NS_IMETHOD GetChildHdrAt(PRInt32 index, nsIMsgDBHdr **result);
|
||||
NS_IMETHOD RemoveChildAt(PRInt32 index);
|
||||
NS_IMETHOD RemoveChild(nsMsgKey msgKey);
|
||||
NS_IMETHOD RemoveChildHdr(nsIMsgDBHdr *child);
|
||||
NS_IMETHOD MarkChildRead(PRBool bRead);
|
||||
NS_IMETHOD EnumerateMessages(nsMsgKey parent, nsIEnumerator* *result);
|
||||
|
||||
@ -63,6 +65,7 @@ protected:
|
||||
virtual nsresult InitCachedValues();
|
||||
nsresult ChangeChildCount(PRInt32 delta);
|
||||
nsresult ChangeUnreadChildCount(PRInt32 delta);
|
||||
nsresult RemoveChild(nsMsgKey msgKey);
|
||||
|
||||
nsMsgKey m_threadKey;
|
||||
PRUint32 m_numChildren;
|
||||
@ -72,8 +75,6 @@ protected:
|
||||
nsIMdbRow *m_metaRow;
|
||||
PRBool m_cachedValuesInitialized;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -312,6 +312,7 @@ nsMsgDatabase::nsMsgDatabase()
|
||||
m_threadIdColumnToken(0),
|
||||
m_threadChildrenColumnToken(0),
|
||||
m_threadUnreadChildrenColumnToken(0),
|
||||
m_threadSubjectColumnToken(0),
|
||||
m_messageThreadIdColumnToken(0),
|
||||
m_numReferencesColumnToken(0),
|
||||
m_messageCharSetColumnToken(0),
|
||||
@ -738,6 +739,7 @@ const char *kThreadFlagsColumnName = "threadFlags";
|
||||
const char *kThreadIdColumnName = "threadId";
|
||||
const char *kThreadChildrenColumnName = "children";
|
||||
const char *kThreadUnreadChildrenColumnName = "unreadChildren";
|
||||
const char *kThreadSubjectColumnName = "threadSubject";
|
||||
const char *kMessageCharSetColumnName = "msgCharSet";
|
||||
struct mdbOid gAllMsgHdrsTableOID;
|
||||
|
||||
@ -829,6 +831,7 @@ nsresult nsMsgDatabase::InitMDBInfo()
|
||||
GetStore()->StringToToken(GetEnv(), kThreadFlagsColumnName, &m_threadFlagsColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kThreadChildrenColumnName, &m_threadChildrenColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kThreadUnreadChildrenColumnName, &m_threadUnreadChildrenColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kThreadSubjectColumnName, &m_threadSubjectColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kNumReferencesColumnName, &m_numReferencesColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kMessageCharSetColumnName, &m_messageCharSetColumnToken);
|
||||
err = GetStore()->StringToToken(GetEnv(), kMsgHdrsTableKind, &m_hdrTableKindToken);
|
||||
@ -998,13 +1001,7 @@ nsresult nsMsgDatabase::RemoveHeaderFromDB(nsMsgHdr *msgHdr)
|
||||
nsCOMPtr <nsIMsgThread> thread ;
|
||||
ret = GetThreadContainingMsgHdr(msgHdr, getter_AddRefs(thread));
|
||||
if (NS_SUCCEEDED(ret))
|
||||
{
|
||||
nsMsgKey msgKey;
|
||||
|
||||
ret = msgHdr->GetMessageKey(&msgKey);
|
||||
if (NS_SUCCEEDED(ret))
|
||||
ret = thread->RemoveChild(msgKey);
|
||||
}
|
||||
ret = thread->RemoveChildHdr(msgHdr);
|
||||
else
|
||||
NS_ASSERTION(PR_FALSE, "couldn't find thread containing deleted message");
|
||||
// even if we couldn't find the thread,we should try to remove the header.
|
||||
@ -1762,7 +1759,8 @@ NS_IMETHODIMP nsMsgDBThreadEnumerator::Next(void)
|
||||
nsresult rv;
|
||||
nsIMdbTable *table = nsnull;
|
||||
|
||||
do {
|
||||
while (PR_TRUE)
|
||||
{
|
||||
NS_IF_RELEASE(mResultThread);
|
||||
mResultThread = nsnull;
|
||||
rv = mTableCursor->NextTable(mDB->GetEnv(), &table);
|
||||
@ -1782,8 +1780,19 @@ NS_IMETHODIMP nsMsgDBThreadEnumerator::Next(void)
|
||||
|
||||
mResultThread = new nsMsgThread(mDB, table);
|
||||
if(mResultThread)
|
||||
{
|
||||
PRUint32 numChildren = 0;
|
||||
NS_ADDREF(mResultThread);
|
||||
} while (mFilter && mFilter(mResultThread, mClosure) != NS_OK);
|
||||
mResultThread->GetNumChildren(&numChildren);
|
||||
// we've got empty thread; don't tell caller about it.
|
||||
if (numChildren == 0)
|
||||
continue;
|
||||
}
|
||||
if (mFilter && mFilter(mResultThread, mClosure) != NS_OK)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1900,13 +1909,19 @@ NS_IMETHODIMP nsMsgDatabase::CreateNewHdr(nsMsgKey key, nsIMsgDBHdr **pnewHdr)
|
||||
NS_IMETHODIMP nsMsgDatabase::AddNewHdrToDB(nsIMsgDBHdr *newHdr, PRBool notify)
|
||||
{
|
||||
nsMsgHdr* hdr = NS_STATIC_CAST(nsMsgHdr*, newHdr); // closed system, cast ok
|
||||
nsresult err = m_mdbAllMsgHeadersTable->AddRow(GetEnv(), hdr->GetMDBRow());
|
||||
PRBool newThread;
|
||||
|
||||
nsresult err = ThreadNewHdr(hdr, newThread);
|
||||
// we thread header before we add it to the all headers table
|
||||
// so that subject threading will work (otherwise, when we try
|
||||
// to find the first header with the same subject, we get the
|
||||
// new header!
|
||||
if (NS_SUCCEEDED(err))
|
||||
{
|
||||
nsMsgKey key;
|
||||
PRUint32 flags;
|
||||
|
||||
newHdr->GetMessageKey(&key);
|
||||
newHdr->GetMessageKey(&key);
|
||||
newHdr->GetFlags(&flags);
|
||||
if (flags & MSG_FLAG_NEW)
|
||||
{
|
||||
@ -1921,9 +1936,7 @@ NS_IMETHODIMP nsMsgDatabase::AddNewHdrToDB(nsIMsgDBHdr *newHdr, PRBool notify)
|
||||
if (! (flags & MSG_FLAG_READ))
|
||||
m_dbFolderInfo->ChangeNumNewMessages(1);
|
||||
}
|
||||
PRBool newThread;
|
||||
|
||||
err = ThreadNewHdr(hdr, newThread);
|
||||
err = m_mdbAllMsgHeadersTable->AddRow(GetEnv(), hdr->GetMDBRow());
|
||||
if (notify)
|
||||
{
|
||||
NotifyKeyAddedAll(key, flags, NULL);
|
||||
@ -2210,10 +2223,25 @@ nsMsgThread *nsMsgDatabase::GetThreadForReference(nsString2 &msgID)
|
||||
return thread;
|
||||
}
|
||||
|
||||
nsMsgThread * nsMsgDatabase::GetThreadForSubject(const char * subject)
|
||||
nsMsgThread * nsMsgDatabase::GetThreadForSubject(nsString2 &subject)
|
||||
{
|
||||
// NS_ASSERTION(PR_FALSE, "not implemented yet.");
|
||||
return nsnull;
|
||||
nsMsgThread *thread = NULL;
|
||||
|
||||
// just find some msg hdr with this subject and use it's thread
|
||||
// as the containng thread,
|
||||
nsIMsgDBHdr *msgHdr = GetMsgHdrForSubject(subject);
|
||||
if (msgHdr != NULL)
|
||||
{
|
||||
nsMsgKey threadId;
|
||||
if (NS_SUCCEEDED(msgHdr->GetThreadId(&threadId)))
|
||||
{
|
||||
// find thread header for header whose message id we matched.
|
||||
thread = GetThreadForThreadId(threadId);
|
||||
}
|
||||
msgHdr->Release();
|
||||
}
|
||||
return thread;
|
||||
}
|
||||
|
||||
nsresult nsMsgDatabase::ThreadNewHdr(nsMsgHdr* newHdr, PRBool &newThread)
|
||||
@ -2260,7 +2288,7 @@ nsresult nsMsgDatabase::ThreadNewHdr(nsMsgHdr* newHdr, PRBool &newThread)
|
||||
newHdr->GetSubject(subject);
|
||||
if ((ThreadBySubjectWithoutRe() || (newHdrFlags & MSG_FLAG_HAS_RE)) && (!thread))
|
||||
{
|
||||
thread = getter_AddRefs(GetThreadForSubject(subject.GetBuffer()));
|
||||
thread = getter_AddRefs(GetThreadForSubject(subject));
|
||||
if(thread)
|
||||
{
|
||||
thread->GetThreadKey(&threadId);
|
||||
@ -2326,6 +2354,34 @@ nsIMsgDBHdr *nsMsgDatabase::GetMsgHdrForMessageID(nsString2 &msgID)
|
||||
return msgHdr;
|
||||
}
|
||||
|
||||
nsIMsgDBHdr *nsMsgDatabase::GetMsgHdrForSubject(nsString2 &subject)
|
||||
{
|
||||
nsIMsgDBHdr *msgHdr = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
mdbYarn subjectYarn;
|
||||
|
||||
subjectYarn.mYarn_Buf = (void*)subject.GetBuffer();
|
||||
subjectYarn.mYarn_Fill = PL_strlen(subject.GetBuffer());
|
||||
subjectYarn.mYarn_Form = 0;
|
||||
subjectYarn.mYarn_Size = subjectYarn.mYarn_Fill;
|
||||
|
||||
nsIMdbRow *hdrRow;
|
||||
mdbOid outRowId;
|
||||
mdb_err result = GetStore()->FindRow(GetEnv(), m_hdrRowScopeToken,
|
||||
m_subjectColumnToken, &subjectYarn, &outRowId,
|
||||
&hdrRow);
|
||||
if (NS_SUCCEEDED(result) && hdrRow)
|
||||
{
|
||||
//Get key from row
|
||||
mdbOid outOid;
|
||||
nsMsgKey key=0;
|
||||
if (hdrRow->GetOid(GetEnv(), &outOid) == NS_OK)
|
||||
key = outOid.mOid_Id;
|
||||
rv = CreateMsgHdr(hdrRow, key, &msgHdr);
|
||||
}
|
||||
return msgHdr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDatabase::GetThreadContainingMsgHdr(nsIMsgDBHdr *msgHdr, nsIMsgThread **result)
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
@ -2338,7 +2394,7 @@ NS_IMETHODIMP nsMsgDatabase::GetThreadContainingMsgHdr(nsIMsgDBHdr *msgHdr, nsIM
|
||||
if (threadId != nsMsgKey_None)
|
||||
*result = GetThreadForThreadId(threadId);
|
||||
|
||||
return ret;
|
||||
return (*result) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -130,6 +130,17 @@ NS_IMETHODIMP nsMsgThread::SetFlags(PRUint32 flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgThread::SetSubject(char *subject)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgThread::GetSubject(char **result)
|
||||
{
|
||||
if (!result)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgThread::GetNumChildren(PRUint32 *result)
|
||||
{
|
||||
@ -249,7 +260,7 @@ NS_IMETHODIMP nsMsgThread::RemoveChildAt(PRInt32 aIndex)
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMsgThread::RemoveChild(nsMsgKey msgKey)
|
||||
nsresult nsMsgThread::RemoveChild(nsMsgKey msgKey)
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
mdbOid rowObjectId;
|
||||
@ -259,6 +270,22 @@ NS_IMETHODIMP nsMsgThread::RemoveChild(nsMsgKey msgKey)
|
||||
return ret;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgThread::RemoveChildHdr(nsIMsgDBHdr *child)
|
||||
{
|
||||
PRUint32 flags;
|
||||
nsMsgKey key;
|
||||
|
||||
if (!child)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
child->GetFlags(&flags);
|
||||
child->GetMessageKey(&key);
|
||||
|
||||
if (!(flags & MSG_FLAG_READ))
|
||||
ChangeUnreadChildCount(-1);
|
||||
ChangeChildCount(-1);
|
||||
return RemoveChild(key);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgThread::MarkChildRead(PRBool bRead)
|
||||
{
|
||||
@ -277,12 +304,15 @@ PRBool nsMsgThread::TryReferenceThreading(nsIMsgDBHdr *newHeader)
|
||||
for (int32 refIndex = newHeader->GetNumReferences() - 1; !done && refIndex >= 0; refIndex--)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDBHdr> refHdr;
|
||||
refHdr = messageDB->GetNeoMessageHdrForHashMessageID(newHeader->GetReferenceId(refIndex));
|
||||
nsString2 referenceStr;
|
||||
|
||||
newHeader->GetStringReference(refIndex, referenceStr);
|
||||
refHdr = m_mdbDB->GetMsgHdrForMessageID(referenceStr);
|
||||
if (refHdr)
|
||||
{
|
||||
// position iterator at child pos.
|
||||
childIterator.reset();
|
||||
while (TRUE)
|
||||
while (PR_TRUE)
|
||||
{
|
||||
MessageKey curMsgId = childIterator.currentID();
|
||||
if (curMsgId == 0)
|
||||
@ -391,6 +421,8 @@ nsMsgThreadEnumerator::nsMsgThreadEnumerator(nsMsgThread *thread, nsMsgKey start
|
||||
mResultHdr = nsnull;
|
||||
|
||||
}
|
||||
else
|
||||
NS_ASSERTION(PR_FALSE, "couldn't get child from thread");
|
||||
mChildIndex = 1;
|
||||
}
|
||||
NS_ADDREF(thread);
|
||||
@ -405,12 +437,14 @@ NS_IMPL_ISUPPORTS(nsMsgThreadEnumerator, nsIEnumerator::GetIID())
|
||||
|
||||
NS_IMETHODIMP nsMsgThreadEnumerator::First(void)
|
||||
{
|
||||
//nsresult rv = NS_OK;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!mThread)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
return Next();
|
||||
rv = Next();
|
||||
NS_ASSERTION(mCurKey != nsMsgKey_None || NS_SUCCEEDED(rv), "first failed, can't have that");
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgThreadEnumerator::Next(void)
|
||||
|
Loading…
Reference in New Issue
Block a user