зеркало из https://github.com/mozilla/gecko-dev.git
add threading to single folder virtual folders, views, and quick searches, sr=mscott 263180
This commit is contained in:
Родитель
002c9cc505
Коммит
5079273bb8
|
@ -852,6 +852,7 @@ function FolderPaneSelectionChange()
|
|||
var dbFolderInfo = msgDatabase.dBFolderInfo;
|
||||
sortType = dbFolderInfo.sortType;
|
||||
sortOrder = dbFolderInfo.sortOrder;
|
||||
viewFlags = dbFolderInfo.viewFlags;
|
||||
if (folderFlags & MSG_FOLDER_FLAG_VIRTUAL)
|
||||
{
|
||||
viewType = nsMsgViewType.eShowQuickSearchResults;
|
||||
|
|
|
@ -189,7 +189,7 @@ function createQuickSearchView()
|
|||
var saveViewSearchListener = gDBView.QueryInterface(Components.interfaces.nsIMsgSearchNotify);
|
||||
gSearchSession.unregisterListener(saveViewSearchListener);
|
||||
}
|
||||
CreateDBView(gDBView.msgFolder, (gXFVirtualFolderTerms) ? nsMsgViewType.eShowVirtualFolderResults : nsMsgViewType.eShowQuickSearchResults, nsMsgViewFlagsType.kNone, gDBView.sortType, gDBView.sortOrder);
|
||||
CreateDBView(gDBView.msgFolder, (gXFVirtualFolderTerms) ? nsMsgViewType.eShowVirtualFolderResults : nsMsgViewType.eShowQuickSearchResults, gDBView.viewFlags, gDBView.sortType, gDBView.sortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3706,22 +3706,22 @@ void nsMsgDBView::FreeAll(nsVoidArray *ptrs)
|
|||
|
||||
nsMsgViewIndex nsMsgDBView::GetIndexOfFirstDisplayedKeyInThread(nsIMsgThread *threadHdr)
|
||||
{
|
||||
nsMsgViewIndex retIndex = nsMsgViewIndex_None;
|
||||
PRUint32 childIndex = 0;
|
||||
// We could speed up the unreadOnly view by starting our search with the first
|
||||
// unread message in the thread. Sometimes, that will be wrong, however, so
|
||||
// let's skip it until we're sure it's necessary.
|
||||
// (m_viewFlags & nsMsgViewFlagsType::kUnreadOnly)
|
||||
// ? threadHdr->GetFirstUnreadKey(m_db) : threadHdr->GetChildAt(0);
|
||||
nsMsgViewIndex retIndex = nsMsgViewIndex_None;
|
||||
PRUint32 childIndex = 0;
|
||||
// We could speed up the unreadOnly view by starting our search with the first
|
||||
// unread message in the thread. Sometimes, that will be wrong, however, so
|
||||
// let's skip it until we're sure it's necessary.
|
||||
// (m_viewFlags & nsMsgViewFlagsType::kUnreadOnly)
|
||||
// ? threadHdr->GetFirstUnreadKey(m_db) : threadHdr->GetChildAt(0);
|
||||
PRUint32 numThreadChildren;
|
||||
threadHdr->GetNumChildren(&numThreadChildren);
|
||||
while (retIndex == nsMsgViewIndex_None && childIndex < numThreadChildren)
|
||||
{
|
||||
nsMsgKey childKey;
|
||||
while (retIndex == nsMsgViewIndex_None && childIndex < numThreadChildren)
|
||||
{
|
||||
nsMsgKey childKey;
|
||||
threadHdr->GetChildKeyAt(childIndex++, &childKey);
|
||||
retIndex = FindViewIndex(childKey);
|
||||
}
|
||||
return retIndex;
|
||||
retIndex = FindViewIndex(childKey);
|
||||
}
|
||||
return retIndex;
|
||||
}
|
||||
|
||||
nsresult nsMsgDBView::GetFirstMessageHdrToDisplayInThread(nsIMsgThread *threadHdr, nsIMsgDBHdr **result)
|
||||
|
@ -4245,12 +4245,10 @@ nsMsgViewIndex nsMsgDBView::GetInsertIndexHelper(nsIMsgDBHdr *msgHdr, nsMsgKeyAr
|
|||
comparisonContext = m_db.get();
|
||||
break;
|
||||
case kU32:
|
||||
if (sortType == nsMsgViewSortType::byId) {
|
||||
if (sortType == nsMsgViewSortType::byId)
|
||||
EntryInfo1.dword = EntryInfo1.id;
|
||||
}
|
||||
else {
|
||||
else
|
||||
GetLongField(msgHdr, sortType, &EntryInfo1.dword);
|
||||
}
|
||||
comparisonFun = FnSortIdDWord;
|
||||
break;
|
||||
default:
|
||||
|
@ -4323,7 +4321,8 @@ nsresult nsMsgDBView::AddHdr(nsIMsgDBHdr *msgHdr)
|
|||
NS_ASSERTION((int) m_keys.GetSize() == m_flags.GetSize() && (int) m_keys.GetSize() == m_levels.GetSize(), "view arrays out of sync!");
|
||||
#endif
|
||||
|
||||
if (!GetShowingIgnored()) {
|
||||
if (!GetShowingIgnored())
|
||||
{
|
||||
nsCOMPtr <nsIMsgThread> thread;
|
||||
m_db->GetThreadContainingMsgHdr(msgHdr, getter_AddRefs(thread));
|
||||
if (thread)
|
||||
|
@ -4471,7 +4470,7 @@ nsresult nsMsgDBView::ListIdsInThreadOrder(nsIMsgThread *threadHdr, nsMsgKey par
|
|||
return rv; // we don't want to return the rv from the enumerator when it reaches the end, do we?
|
||||
}
|
||||
|
||||
nsresult nsMsgDBView::ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex startOfThreadViewIndex, PRUint32 *pNumListed)
|
||||
nsresult nsMsgDBView::ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex startOfThreadViewIndex, PRUint32 *pNumListed)
|
||||
{
|
||||
NS_ENSURE_ARG(threadHdr);
|
||||
// these children ids should be in thread order.
|
||||
|
@ -4807,10 +4806,11 @@ NS_IMETHODIMP nsMsgDBView::SetViewFlags(nsMsgViewFlagsTypeValue aViewFlags)
|
|||
}
|
||||
m_viewFlags = aViewFlags;
|
||||
|
||||
if (m_folder)
|
||||
if (m_viewFolder)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDatabase> db;
|
||||
nsCOMPtr <nsIDBFolderInfo> folderInfo;
|
||||
nsresult rv = m_folder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(m_db));
|
||||
nsresult rv = m_viewFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(db));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
return folderInfo->SetViewFlags(aViewFlags);
|
||||
}
|
||||
|
@ -5419,8 +5419,8 @@ nsresult nsMsgDBView::ToggleIgnored(nsMsgViewIndex * indices, PRInt32 numIndices
|
|||
nsMsgViewIndex nsMsgDBView::GetThreadFromMsgIndex(nsMsgViewIndex index,
|
||||
nsIMsgThread **threadHdr)
|
||||
{
|
||||
nsMsgKey msgKey = GetAt(index);
|
||||
nsMsgViewIndex threadIndex;
|
||||
nsMsgKey msgKey = GetAt(index);
|
||||
nsMsgViewIndex threadIndex;
|
||||
|
||||
NS_ENSURE_ARG(threadHdr);
|
||||
nsresult rv = GetThreadContainingIndex(index, threadHdr);
|
||||
|
|
|
@ -213,7 +213,7 @@ protected:
|
|||
// helper routines for thread expanding and collapsing.
|
||||
nsresult GetThreadCount(nsMsgKey messageKey, PRUint32 *pThreadCount);
|
||||
nsMsgViewIndex GetIndexOfFirstDisplayedKeyInThread(nsIMsgThread *threadHdr);
|
||||
nsresult GetFirstMessageHdrToDisplayInThread(nsIMsgThread *threadHdr, nsIMsgDBHdr **result);
|
||||
virtual nsresult GetFirstMessageHdrToDisplayInThread(nsIMsgThread *threadHdr, nsIMsgDBHdr **result);
|
||||
virtual nsMsgViewIndex ThreadIndexOfMsg(nsMsgKey msgKey,
|
||||
nsMsgViewIndex msgIndex = nsMsgViewIndex_None,
|
||||
PRInt32 *pThreadCount = nsnull,
|
||||
|
@ -221,7 +221,7 @@ protected:
|
|||
virtual nsresult GetThreadContainingMsgHdr(nsIMsgDBHdr *msgHdr, nsIMsgThread **pThread);
|
||||
nsMsgKey GetKeyOfFirstMsgInThread(nsMsgKey key);
|
||||
PRInt32 CountExpandedThread(nsMsgViewIndex index);
|
||||
nsresult ExpansionDelta(nsMsgViewIndex index, PRInt32 *expansionDelta);
|
||||
virtual nsresult ExpansionDelta(nsMsgViewIndex index, PRInt32 *expansionDelta);
|
||||
nsresult ReverseSort();
|
||||
nsresult ReverseThreads();
|
||||
nsresult SaveSortInfo(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
|
||||
|
@ -236,7 +236,7 @@ protected:
|
|||
virtual nsresult GetFolders(nsISupportsArray **folders);
|
||||
virtual nsresult GetFolderFromMsgURI(const char *aMsgURI, nsIMsgFolder **aFolder);
|
||||
|
||||
nsresult ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex viewIndex, PRUint32 *pNumListed);
|
||||
virtual nsresult ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex viewIndex, PRUint32 *pNumListed);
|
||||
nsresult ListUnreadIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex startOfThreadViewIndex, PRUint32 *pNumListed);
|
||||
nsMsgViewIndex FindParentInThread(nsMsgKey parentKey, nsMsgViewIndex startOfThreadViewIndex);
|
||||
nsresult ListIdsInThreadOrder(nsIMsgThread *threadHdr, nsMsgKey parentKey, PRInt32 level, nsMsgViewIndex *viewIndex, PRUint32 *pNumListed);
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsMsgBaseCID.h"
|
||||
#include "nsIMsgImapMailFolder.h"
|
||||
#include "nsImapCore.h"
|
||||
#include "nsIMsgHdr.h"
|
||||
|
||||
nsMsgQuickSearchDBView::nsMsgQuickSearchDBView()
|
||||
{
|
||||
|
@ -55,6 +56,19 @@ nsMsgQuickSearchDBView::~nsMsgQuickSearchDBView()
|
|||
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(nsMsgQuickSearchDBView, nsMsgDBView, nsIMsgDBView, nsIMsgSearchNotify)
|
||||
|
||||
NS_IMETHODIMP nsMsgQuickSearchDBView::Open(nsIMsgFolder *folder, nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder, nsMsgViewFlagsTypeValue viewFlags, PRInt32 *pCount)
|
||||
{
|
||||
nsresult rv = nsMsgDBView::Open(folder, sortType, sortOrder, viewFlags, pCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!m_db)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if (pCount)
|
||||
*pCount = 0;
|
||||
m_viewFolder = nsnull;
|
||||
return InitThreadedView(pCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgQuickSearchDBView::DoCommand(nsMsgViewCommandTypeValue aCommand)
|
||||
{
|
||||
if (aCommand == nsMsgViewCommandType::markAllRead)
|
||||
|
@ -100,7 +114,7 @@ nsresult nsMsgQuickSearchDBView::OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aPare
|
|||
if (searchSession)
|
||||
searchSession->MatchHdr(newHdr, m_db, &match);
|
||||
if (match)
|
||||
AddHdr(newHdr); // do not add a new message if there isn't a match.
|
||||
nsMsgThreadedDBView::OnNewHeader(newHdr, aParentKey, ensureListed); // do not add a new message if there isn't a match.
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -163,20 +177,9 @@ NS_IMETHODIMP
|
|||
nsMsgQuickSearchDBView::OnSearchHit(nsIMsgDBHdr* aMsgHdr, nsIMsgFolder *folder)
|
||||
{
|
||||
NS_ENSURE_ARG(aMsgHdr);
|
||||
NS_ENSURE_ARG(folder);
|
||||
nsMsgKey msgKey;
|
||||
PRUint32 msgFlags;
|
||||
aMsgHdr->GetMessageKey(&msgKey);
|
||||
aMsgHdr->GetFlags(&msgFlags);
|
||||
m_keys.Add(msgKey);
|
||||
m_levels.Add(0);
|
||||
m_flags.Add(msgFlags);
|
||||
|
||||
// this needs to happen after we add the key, as RowCountChanged() will call our GetRowCount()
|
||||
if (mTree)
|
||||
mTree->RowCountChanged(GetSize() - 1, 1);
|
||||
|
||||
return NS_OK;
|
||||
if (!m_db)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
return AddHdr(aMsgHdr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -207,20 +210,196 @@ nsMsgQuickSearchDBView::OnNewSearch()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgQuickSearchDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder)
|
||||
nsresult nsMsgQuickSearchDBView::GetFirstMessageHdrToDisplayInThread(nsIMsgThread *threadHdr, nsIMsgDBHdr **result)
|
||||
{
|
||||
nsMsgKey preservedKey;
|
||||
nsMsgKeyArray preservedSelection;
|
||||
SaveAndClearSelection(&preservedKey, &preservedSelection);
|
||||
nsMsgDBView::Sort(sortType, sortOrder);
|
||||
RestoreSelection(preservedKey, &preservedSelection);
|
||||
if (mTree)
|
||||
mTree->Invalidate();
|
||||
PRUint32 numChildren;
|
||||
nsresult rv = NS_OK;
|
||||
PRUint8 minLevel = 0xff;
|
||||
nsMsgKey threadRootKey;
|
||||
|
||||
PRUint32 folderFlags;
|
||||
if (m_viewFolder && NS_SUCCEEDED(m_viewFolder->GetFlags(&folderFlags)) && folderFlags & MSG_FOLDER_FLAG_VIRTUAL)
|
||||
SaveSortInfo(sortType, sortOrder);
|
||||
threadHdr->GetNumChildren(&numChildren);
|
||||
threadHdr->GetThreadKey(&threadRootKey);
|
||||
if ((PRInt32) numChildren < 0)
|
||||
numChildren = 0;
|
||||
|
||||
nsCOMPtr <nsIMsgDBHdr> retHdr;
|
||||
|
||||
// iterate over thread, finding mgsHdr in view with the lowest level.
|
||||
for (PRUint32 childIndex = 0; childIndex < numChildren; childIndex++)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDBHdr> child;
|
||||
rv = threadHdr->GetChildHdrAt(childIndex, getter_AddRefs(child));
|
||||
if (NS_SUCCEEDED(rv) && child)
|
||||
{
|
||||
nsMsgKey msgKey;
|
||||
child->GetMessageKey(&msgKey);
|
||||
|
||||
// this works because we've already sorted m_keys by id.
|
||||
nsMsgViewIndex keyIndex = m_origKeys.IndexOfSorted(msgKey);
|
||||
if (keyIndex != kNotFound)
|
||||
{
|
||||
// this is the root, so it's the best we're going to do.
|
||||
if (msgKey == threadRootKey)
|
||||
{
|
||||
retHdr = child;
|
||||
break;
|
||||
}
|
||||
PRUint8 level = 0;
|
||||
nsMsgKey parentId;
|
||||
child->GetThreadParent(&parentId);
|
||||
nsCOMPtr <nsIMsgDBHdr> parent;
|
||||
// count number of ancestors - that's our level
|
||||
while (parentId != nsMsgKey_None)
|
||||
{
|
||||
rv = m_db->GetMsgHdrForKey(parentId, getter_AddRefs(parent));
|
||||
if (parent)
|
||||
{
|
||||
parent->GetThreadParent(&parentId);
|
||||
level++;
|
||||
}
|
||||
}
|
||||
if (level < minLevel)
|
||||
{
|
||||
minLevel = level;
|
||||
retHdr = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_IF_ADDREF(*result = retHdr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgQuickSearchDBView::SortThreads(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder)
|
||||
{
|
||||
// iterate over the messages in the view, getting the thread id's
|
||||
if (sortType == nsMsgViewSortType::byId)
|
||||
{
|
||||
// sort m_keys so we can quickly find if a key is in the view.
|
||||
m_keys.QuickSort();
|
||||
// array of the threads' root hdr keys.
|
||||
nsMsgKeyArray threadRootIds;
|
||||
nsCOMPtr <nsIMsgDBHdr> rootHdr;
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
nsCOMPtr <nsIMsgThread> threadHdr;
|
||||
for (PRUint32 i = 0; i < m_keys.GetSize(); i++)
|
||||
{
|
||||
GetMsgHdrForViewIndex(i, getter_AddRefs(msgHdr));
|
||||
m_db->GetThreadContainingMsgHdr(msgHdr, getter_AddRefs(threadHdr));
|
||||
if (threadHdr)
|
||||
{
|
||||
nsMsgKey rootKey;
|
||||
threadHdr->GetChildKeyAt(0, &rootKey);
|
||||
nsMsgViewIndex threadRootIndex = threadRootIds.IndexOfSorted(rootKey);
|
||||
// if we already have that id in top level threads, ignore this msg.
|
||||
if (threadRootIndex != kNotFound)
|
||||
continue;
|
||||
// it would be nice if GetInsertIndexHelper always found the hdr, but it doesn't.
|
||||
threadHdr->GetChildHdrAt(0, getter_AddRefs(rootHdr));
|
||||
threadRootIndex = GetInsertIndexHelper(rootHdr, &threadRootIds, nsMsgViewSortOrder::ascending, sortType);
|
||||
threadRootIds.InsertAt(threadRootIndex, rootKey);
|
||||
}
|
||||
}
|
||||
// now we've build up the list of thread ids - need to build the view
|
||||
// from that. So for each thread id, we need to list the messages in the thread.
|
||||
m_origKeys.CopyArray(m_keys);
|
||||
m_keys.RemoveAll();
|
||||
m_levels.RemoveAll();
|
||||
m_flags.RemoveAll();
|
||||
PRUint32 numThreads = threadRootIds.GetSize();
|
||||
for (PRUint32 threadIndex = 0; threadIndex < numThreads; threadIndex++)
|
||||
{
|
||||
m_db->GetMsgHdrForKey(threadRootIds[threadIndex], getter_AddRefs(rootHdr));
|
||||
if (rootHdr)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDBHdr> displayRootHdr;
|
||||
m_db->GetThreadContainingMsgHdr(rootHdr, getter_AddRefs(threadHdr));
|
||||
if (threadHdr)
|
||||
{
|
||||
nsMsgKey rootKey;
|
||||
PRUint32 rootFlags;
|
||||
GetFirstMessageHdrToDisplayInThread(threadHdr, getter_AddRefs(displayRootHdr));
|
||||
displayRootHdr->GetMessageKey(&rootKey);
|
||||
displayRootHdr->GetFlags(&rootFlags);
|
||||
rootFlags |= MSG_VIEW_FLAG_ISTHREAD;
|
||||
m_keys.Add(rootKey);
|
||||
m_flags.Add(rootFlags);
|
||||
m_levels.Add(0);
|
||||
|
||||
nsMsgViewIndex startOfThreadViewIndex = m_keys.GetSize() - 1;
|
||||
PRUint32 numListed;
|
||||
ListIdsInThread(threadHdr, startOfThreadViewIndex, &numListed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgQuickSearchDBView::ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex startOfThreadViewIndex, PRUint32 *pNumListed)
|
||||
{
|
||||
PRUint32 numChildren;
|
||||
threadHdr->GetNumChildren(&numChildren);
|
||||
PRUint32 i;
|
||||
PRUint32 viewIndex = startOfThreadViewIndex + 1;
|
||||
nsCOMPtr <nsIMsgDBHdr> rootHdr;
|
||||
nsMsgKey rootKey;
|
||||
PRUint32 rootFlags = m_flags[startOfThreadViewIndex];
|
||||
*pNumListed = 0;
|
||||
GetMsgHdrForViewIndex(startOfThreadViewIndex, getter_AddRefs(rootHdr));
|
||||
rootHdr->GetMessageKey(&rootKey);
|
||||
for (i = 0; i < numChildren; i++)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
threadHdr->GetChildHdrAt(i, getter_AddRefs(msgHdr));
|
||||
if (msgHdr != nsnull)
|
||||
{
|
||||
nsMsgKey msgKey;
|
||||
msgHdr->GetMessageKey(&msgKey);
|
||||
if (msgKey != rootKey)
|
||||
{
|
||||
nsMsgViewIndex threadRootIndex = m_origKeys.IndexOfSorted(msgKey);
|
||||
// if this hdr is in the original view, add it to new view.
|
||||
if (threadRootIndex != kNotFound)
|
||||
{
|
||||
PRUint32 childFlags;
|
||||
msgHdr->GetFlags(&childFlags);
|
||||
PRUint8 levelToAdd;
|
||||
m_keys.InsertAt(viewIndex, msgKey);
|
||||
m_flags.InsertAt(viewIndex, childFlags);
|
||||
if (! (rootFlags & MSG_VIEW_FLAG_HASCHILDREN))
|
||||
{
|
||||
rootFlags |= MSG_VIEW_FLAG_HASCHILDREN;
|
||||
m_flags.SetAt(startOfThreadViewIndex, rootFlags);
|
||||
}
|
||||
levelToAdd = FindLevelInThread(msgHdr, startOfThreadViewIndex, viewIndex);
|
||||
m_levels.InsertAt(viewIndex, levelToAdd);
|
||||
viewIndex++;
|
||||
(*pNumListed)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgQuickSearchDBView::ExpansionDelta(nsMsgViewIndex index, PRInt32 *expansionDelta)
|
||||
{
|
||||
*expansionDelta = 0;
|
||||
if ( index > ((nsMsgViewIndex) m_keys.GetSize()))
|
||||
return NS_MSG_MESSAGE_NOT_FOUND;
|
||||
|
||||
char flags = m_flags[index];
|
||||
|
||||
if (!(m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay))
|
||||
return NS_OK;
|
||||
|
||||
// The client can pass in the key of any message
|
||||
// in a thread and get the expansion delta for the thread.
|
||||
|
||||
PRInt32 numChildren = CountExpandedThread(index);
|
||||
|
||||
*expansionDelta = (flags & MSG_FLAG_ELIDED) ?
|
||||
numChildren - 1 : - (PRInt32) (numChildren - 1);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -39,11 +39,11 @@
|
|||
#ifndef _nsMsgQuickSearchDBViewsH_
|
||||
#define _nsMsgQuickSearchDBView_H_
|
||||
|
||||
#include "nsMsgDBView.h"
|
||||
#include "nsMsgThreadedDBView.h"
|
||||
#include "nsIMsgSearchNotify.h"
|
||||
#include "nsIMsgSearchSession.h"
|
||||
|
||||
class nsMsgQuickSearchDBView : public nsMsgDBView, public nsIMsgSearchNotify
|
||||
class nsMsgQuickSearchDBView : public nsMsgThreadedDBView, public nsIMsgSearchNotify
|
||||
{
|
||||
public:
|
||||
nsMsgQuickSearchDBView();
|
||||
|
@ -53,17 +53,24 @@ public:
|
|||
NS_DECL_NSIMSGSEARCHNOTIFY
|
||||
|
||||
virtual const char * GetViewName(void) {return "QuickSearchView"; }
|
||||
NS_IMETHOD Open(nsIMsgFolder *folder, nsMsgViewSortTypeValue sortType,
|
||||
nsMsgViewSortOrderValue sortOrder,
|
||||
nsMsgViewFlagsTypeValue viewFlags, PRInt32 *pCount);
|
||||
NS_IMETHOD DoCommand(nsMsgViewCommandTypeValue aCommand);
|
||||
NS_IMETHOD GetViewType(nsMsgViewTypeValue *aViewType);
|
||||
NS_IMETHOD SetSearchSession(nsIMsgSearchSession *aSearchSession);
|
||||
NS_IMETHOD GetSearchSession(nsIMsgSearchSession* *aSearchSession);
|
||||
NS_IMETHOD Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
|
||||
NS_IMETHOD OnHdrChange(nsIMsgDBHdr *aHdrChanged, PRUint32 aOldFlags,
|
||||
PRUint32 aNewFlags, nsIDBChangeListener *aInstigator);
|
||||
|
||||
protected:
|
||||
nsWeakPtr m_searchSession;
|
||||
nsMsgKeyArray m_origKeys;
|
||||
virtual nsresult OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, PRBool ensureListed);
|
||||
virtual nsresult SortThreads(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
|
||||
virtual nsresult GetFirstMessageHdrToDisplayInThread(nsIMsgThread *threadHdr, nsIMsgDBHdr **result);
|
||||
virtual nsresult ExpansionDelta(nsMsgViewIndex index, PRInt32 *expansionDelta);
|
||||
virtual nsresult ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex startOfThreadViewIndex, PRUint32 *pNumListed);
|
||||
void SavePreSearchInfo();
|
||||
void ClearPreSearchInfo();
|
||||
|
||||
|
|
|
@ -286,7 +286,7 @@ NS_IMETHODIMP nsMsgThreadedDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgVi
|
|||
// sort threads by sort order
|
||||
PRBool sortThreads = m_viewFlags & (nsMsgViewFlagsType::kThreadedDisplay | nsMsgViewFlagsType::kGroupBySort);
|
||||
|
||||
// if sort type is by thread, but we're not threaded, change sort type to byId
|
||||
// if sort type is by thread, and we're already threaded, change sort type to byId
|
||||
if (sortType == nsMsgViewSortType::byThread && (m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay) != 0)
|
||||
sortType = nsMsgViewSortType::byId;
|
||||
|
||||
|
@ -489,6 +489,10 @@ nsresult nsMsgThreadedDBView::ListThreadIds(nsMsgKey *startMsg, PRBool unreadOnl
|
|||
else
|
||||
{
|
||||
*startMsg = nsMsgKey_None;
|
||||
nsCOMPtr <nsIDBChangeListener> dbListener = do_QueryInterface(m_threadEnumerator);
|
||||
// this is needed to make the thread enumerator release its reference to the db.
|
||||
if (dbListener)
|
||||
dbListener->OnAnnouncerGoingAway(nsnull);
|
||||
m_threadEnumerator = nsnull;
|
||||
}
|
||||
*pNumListed = numListed;
|
||||
|
|
|
@ -67,7 +67,7 @@ protected:
|
|||
nsresult ListThreadIds(nsMsgKey *startMsg, PRBool unreadOnly, nsMsgKey *pOutput, PRInt32 *pFlags, char *pLevels,
|
||||
PRInt32 numToList, PRInt32 *pNumListed, PRInt32 *pTotalHeaders);
|
||||
nsresult InitSort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
|
||||
nsresult SortThreads(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
|
||||
virtual nsresult SortThreads(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
|
||||
virtual void OnExtraFlagChanged(nsMsgViewIndex index, PRUint32 extraFlag);
|
||||
virtual void OnHeaderAddedOrDeleted();
|
||||
void ClearPrevIdArray();
|
||||
|
|
|
@ -331,3 +331,24 @@ void nsUInt32Array::QuickSort (int (* PR_CALLBACK compare) (const void *elem1, c
|
|||
if (m_nSize > 1)
|
||||
NS_QuickSort(m_pData, m_nSize, sizeof(PRUint32), compare ? compare : CompareDWord, nsnull);
|
||||
}
|
||||
|
||||
// Does a binary search - assumes array is sorted in ascending order.
|
||||
PRUint32 nsUInt32Array::IndexOfSorted(PRUint32 element)
|
||||
{
|
||||
PRInt32 msgIndex = 0;
|
||||
PRInt32 hi = m_nSize - 1;
|
||||
PRInt32 lo = 0;
|
||||
|
||||
while (lo <= hi)
|
||||
{
|
||||
msgIndex = (lo + hi) / 2;
|
||||
if (m_pData[msgIndex] == element)
|
||||
return msgIndex;
|
||||
if (m_pData[msgIndex] > element)
|
||||
hi = msgIndex -1;
|
||||
else if (m_pData[msgIndex] < element)
|
||||
lo = msgIndex + 1;
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
PRUint32 *GetData();
|
||||
void SetAt(PRUint32 nIndex, PRUint32 newElement);
|
||||
PRUint32 IndexOf(PRUint32 element);
|
||||
PRUint32 IndexOfSorted(PRUint32 element);
|
||||
|
||||
// Insertion/deletion member functions
|
||||
PRUint32 Add(PRUint32 newElement);
|
||||
|
|
Загрузка…
Ссылка в новой задаче