flesh out secondary sort support, sr=mscott, 57898, NPOTB for Firefox

git-svn-id: svn://10.0.0.236/trunk@231251 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bienvenu%nventure.com
2007-08-02 00:59:55 +00:00
parent 17ecc742c2
commit 0c27a705e1
2 changed files with 231 additions and 79 deletions

View File

@@ -114,6 +114,8 @@ nsDateFormatSelector nsMsgDBView::m_dateFormatDefault = kDateFormatShort;
nsDateFormatSelector nsMsgDBView::m_dateFormatThisWeek = kDateFormatShort;
nsDateFormatSelector nsMsgDBView::m_dateFormatToday = kDateFormatNone;
static const PRUint32 kMaxNumSortColumns = 2;
// this is passed into NS_QuickSort as custom data.
class viewSortInfo
{
@@ -121,6 +123,7 @@ public:
nsMsgDBView *view;
nsIMsgDatabase *db;
PRBool isSecondarySort;
PRBool ascendingSort;
};
@@ -142,6 +145,7 @@ nsMsgDBView::nsMsgDBView()
m_sortOrder = nsMsgViewSortOrder::none;
m_viewFlags = nsMsgViewFlagsType::kNone;
m_secondarySort = nsMsgViewSortType::byId;
m_secondarySortOrder = nsMsgViewSortOrder::ascending;
m_cachedMsgKey = nsMsgKey_None;
m_currentlyDisplayedMsgKey = nsMsgKey_None;
m_currentlyDisplayedViewIndex = nsMsgViewIndex_None;
@@ -1567,7 +1571,6 @@ PRBool nsMsgDBView::WasHdrRecentlyDeleted(nsIMsgDBHdr *msgHdr)
{
nsCString messageId;
msgHdr->GetMessageId(getter_Copies(messageId));
PRInt32 arrayCount;
for (PRInt32 i = 0; i < mRecentlyDeletedMsgIds.Count(); i++)
{
if (messageId.Equals(*(mRecentlyDeletedMsgIds[i])))
@@ -1597,7 +1600,15 @@ NS_IMETHODIMP nsMsgDBView::AddColumnHandler(const nsAString& column, nsIMsgCusto
m_customColumnHandlers.ReplaceObjectAt(handler, index);
}
// Check if the column name matches any of the columns in
// m_sortColumns, and if so, set m_sortColumns[i].mColHandler
for (PRUint32 i = 0; i < m_sortColumns.Length(); i++)
{
MsgViewSortColumnInfo &sortInfo = m_sortColumns[i];
if (sortInfo.mSortType == nsMsgViewSortType::byCustom &&
sortInfo.mCustomColumnName.Equals(column))
sortInfo.mColHandler = handler;
}
return NS_OK;
}
@@ -1605,12 +1616,23 @@ NS_IMETHODIMP nsMsgDBView::AddColumnHandler(const nsAString& column, nsIMsgCusto
NS_IMETHODIMP nsMsgDBView::RemoveColumnHandler(const nsAString& aColID)
{
// here we should check if the column name matches any of the columns in
// m_sortColumns, and if so, clear m_sortColumns[i].mColHandler
PRInt32 index = m_customColumnHandlerIDs.IndexOf(aColID);
if (index != -1)
{
m_customColumnHandlerIDs.RemoveStringAt(index);
m_customColumnHandlers.RemoveObjectAt(index);
// Check if the column name matches any of the columns in
// m_sortColumns, and if so, clear m_sortColumns[i].mColHandler
for (PRUint32 i = 0; i < m_sortColumns.Length(); i++)
{
MsgViewSortColumnInfo &sortInfo = m_sortColumns[i];
if (sortInfo.mSortType == nsMsgViewSortType::byCustom &&
sortInfo.mCustomColumnName.Equals(aColID))
sortInfo.mColHandler = nsnull;
}
return NS_OK;
}
@@ -1621,24 +1643,26 @@ NS_IMETHODIMP nsMsgDBView::RemoveColumnHandler(const nsAString& aColID)
//TODO: NS_ENSURE_SUCCESS
nsIMsgCustomColumnHandler* nsMsgDBView::GetCurColumnHandlerFromDBInfo()
{
if (!m_db)
return nsnull;
nsresult rv;
nsCOMPtr<nsIDBFolderInfo> dbInfo;
m_db->GetDBFolderInfo(getter_AddRefs(dbInfo));
if (!dbInfo)
return nsnull;
nsAutoString colID;
rv = dbInfo->GetProperty("customSortCol", colID);
GetCurCustomColumn(colID);
return GetColumnHandler(colID.get());
}
void nsMsgDBView::GetCurCustomColumn(nsString &colID)
{
if (!m_db)
return;
nsCOMPtr<nsIDBFolderInfo> dbInfo;
m_db->GetDBFolderInfo(getter_AddRefs(dbInfo));
if (!dbInfo)
return;
dbInfo->GetProperty("customSortCol", colID);
}
nsIMsgCustomColumnHandler* nsMsgDBView::GetColumnHandler(const PRUnichar *colID)
{
nsIMsgCustomColumnHandler* columnHandler = nsnull;
@@ -1651,6 +1675,7 @@ nsIMsgCustomColumnHandler* nsMsgDBView::GetColumnHandler(const PRUnichar *colID)
return columnHandler;
}
NS_IMETHODIMP nsMsgDBView::GetColumnHandler(const nsAString& aColID, nsIMsgCustomColumnHandler** aHandler)
{
NS_ENSURE_ARG_POINTER(aHandler);
@@ -1923,6 +1948,10 @@ NS_IMETHODIMP nsMsgDBView::Open(nsIMsgFolder *folder, nsMsgViewSortTypeValue sor
SetMRUTimeForFolder(m_folder);
// restore m_sortColumns from db
nsString sortColumnsString;
folderInfo->GetProperty("sortColumns", sortColumnsString);
DecodeColumnSort(sortColumnsString);
// determine if we are in a news folder or not.
// if yes, we'll show lines instead of size, and special icons in the thread pane
nsCOMPtr <nsIMsgIncomingServer> server;
@@ -3226,7 +3255,7 @@ struct IdKeyPtr : public IdDWord
};
int PR_CALLBACK
FnSortIdKey(const void *pItem1, const void *pItem2, void *privateData)
nsMsgDBView::FnSortIdKey(const void *pItem1, const void *pItem2, void *privateData)
{
PRInt32 retVal = 0;
nsresult rv;
@@ -3240,53 +3269,57 @@ FnSortIdKey(const void *pItem1, const void *pItem2, void *privateData)
rv = db->CompareCollationKeys((*p1)->key, (*p1)->dword, (*p2)->key, (*p2)->dword, &retVal);
NS_ASSERTION(NS_SUCCEEDED(rv),"compare failed");
if (retVal != 0)
return(retVal);
if (retVal)
return sortInfo->ascendingSort ? retVal : ~retVal;
if (sortInfo->view->m_secondarySort == nsMsgViewSortType::byId)
return ((*p1)->id >= (*p2)->id) ? 1 : -1;
return (sortInfo->view->m_secondarySortOrder == nsMsgViewSortOrder::ascending &&
(*p1)->id >= (*p2)->id) ? 1 : -1;
else
return sortInfo->view->SecondarySort((*p1)->id, (*p1)->folder, (*p2)->id, (*p2)->folder, sortInfo);
// here we'd use the secondary sort
}
int PR_CALLBACK
FnSortIdKeyPtr(const void *pItem1, const void *pItem2, void *privateData)
nsMsgDBView::FnSortIdKeyPtr(const void *pItem1, const void *pItem2, void *privateData)
{
PRInt32 retVal = 0;
nsresult rv;
PRInt32 retVal = 0;
nsresult rv;
IdKeyPtr** p1 = (IdKeyPtr**)pItem1;
IdKeyPtr** p2 = (IdKeyPtr**)pItem2;
IdKeyPtr** p1 = (IdKeyPtr**)pItem1;
IdKeyPtr** p2 = (IdKeyPtr**)pItem2;
viewSortInfo* sortInfo = (viewSortInfo *) privateData;
nsIMsgDatabase *db = ((viewSortInfo *)privateData)->db;
nsIMsgDatabase *db = sortInfo->db;
rv = db->CompareCollationKeys((*p1)->key, (*p1)->dword, (*p2)->key, (*p2)->dword, &retVal);
NS_ASSERTION(NS_SUCCEEDED(rv),"compare failed");
rv = db->CompareCollationKeys((*p1)->key, (*p1)->dword, (*p2)->key, (*p2)->dword, &retVal);
NS_ASSERTION(NS_SUCCEEDED(rv),"compare failed");
if (retVal != 0)
return(retVal);
// here we'd use the secondary sort
if ((*p1)->id >= (*p2)->id)
return(1);
else
return(-1);
if (retVal)
return sortInfo->ascendingSort ? retVal : ~retVal;
if (sortInfo->view->m_secondarySort == nsMsgViewSortType::byId)
return (sortInfo->view->m_secondarySortOrder == nsMsgViewSortOrder::ascending &&
(*p1)->id >= (*p2)->id) ? 1 : -1;
else
return sortInfo->view->SecondarySort((*p1)->id, (*p1)->folder, (*p2)->id, (*p2)->folder, sortInfo);
}
int PR_CALLBACK
FnSortIdDWord(const void *pItem1, const void *pItem2, void *privateData)
nsMsgDBView::FnSortIdDWord(const void *pItem1, const void *pItem2, void *privateData)
{
IdDWord** p1 = (IdDWord**)pItem1;
IdDWord** p2 = (IdDWord**)pItem2;
IdDWord** p1 = (IdDWord**)pItem1;
IdDWord** p2 = (IdDWord**)pItem2;
viewSortInfo* sortInfo = (viewSortInfo *) privateData;
if ((*p1)->dword > (*p2)->dword)
return(1);
else if ((*p1)->dword < (*p2)->dword)
return(-1);
// here we'd use the secondary sort
else if ((*p1)->id >= (*p2)->id)
return(1);
else
return(-1);
if ((*p1)->dword > (*p2)->dword)
return (sortInfo->ascendingSort) ? 1 : -1;
else if ((*p1)->dword < (*p2)->dword)
return (sortInfo->ascendingSort) ? -1 : 1;
if (sortInfo->view->m_secondarySort == nsMsgViewSortType::byId)
return (sortInfo->view->m_secondarySortOrder == nsMsgViewSortOrder::ascending &&
(*p1)->id >= (*p2)->id) ? 1 : -1;
else
return sortInfo->view->SecondarySort((*p1)->id, (*p1)->folder, (*p2)->id, (*p2)->folder, sortInfo);
}
@@ -3495,6 +3528,70 @@ nsresult nsMsgDBView::GetLongField(nsIMsgDBHdr *msgHdr, nsMsgViewSortTypeValue s
return NS_OK;
}
MsgViewSortColumnInfo::MsgViewSortColumnInfo(const MsgViewSortColumnInfo &other)
{
mSortType = other.mSortType;
mSortOrder = other.mSortOrder;
mCustomColumnName = other.mCustomColumnName;
mColHandler = other.mColHandler;
}
PRBool MsgViewSortColumnInfo::operator== (const MsgViewSortColumnInfo& other) const
{
return (mSortType == nsMsgViewSortType::byCustom) ?
mCustomColumnName.Equals(other.mCustomColumnName) : mSortType == other.mSortType;
}
nsresult nsMsgDBView::EncodeColumnSort(nsString &columnSortString)
{
for (PRUint32 i = 0; i < m_sortColumns.Length(); i++)
{
MsgViewSortColumnInfo &sortInfo = m_sortColumns[i];
columnSortString.Append((char) sortInfo.mSortType);
columnSortString.Append((char) sortInfo.mSortOrder + '0');
if (sortInfo.mSortType == nsMsgViewSortType::byCustom)
{
columnSortString.Append(sortInfo.mCustomColumnName);
columnSortString.Append((PRUnichar) '\r');
}
}
return NS_OK;
}
nsresult nsMsgDBView::DecodeColumnSort(nsString &columnSortString)
{
const PRUnichar *stringPtr = columnSortString.BeginReading();
while (*stringPtr)
{
MsgViewSortColumnInfo sortColumnInfo;
sortColumnInfo.mSortType = (nsMsgViewSortTypeValue) *stringPtr++;
sortColumnInfo.mSortOrder = (nsMsgViewSortOrderValue) (*stringPtr++) - '0';
if (sortColumnInfo.mSortType == nsMsgViewSortType::byCustom)
{
while (*stringPtr && *stringPtr != '\r')
sortColumnInfo.mCustomColumnName.Append(*stringPtr++);
sortColumnInfo.mColHandler = GetColumnHandler(sortColumnInfo.mCustomColumnName.get());
if (*stringPtr) // advance past '\r'
stringPtr++;
}
m_sortColumns.AppendElement(sortColumnInfo);
}
return NS_OK;
}
void nsMsgDBView::PushSort(const MsgViewSortColumnInfo &newSort)
{
// no sense in keeping secondary sorts if primary sort is date or id
if (newSort.mSortType == nsMsgViewSortType::byDate || newSort.mSortType == nsMsgViewSortType::byId)
m_sortColumns.Clear();
PRInt32 sortIndex = m_sortColumns.IndexOf(newSort, 0);
if (sortIndex != kNotFound)
m_sortColumns. RemoveElementAt(sortIndex);
m_sortColumns.InsertElementAt(0, newSort);
if (m_sortColumns.Length() > kMaxNumSortColumns)
m_sortColumns.RemoveElementAt(kMaxNumSortColumns);
}
nsresult
nsMsgDBView::GetCollationKey(nsIMsgDBHdr *msgHdr, nsMsgViewSortTypeValue sortType, PRUint8 **result, PRUint32 *len, nsIMsgCustomColumnHandler* colHandler)
{
@@ -3597,6 +3694,11 @@ nsresult nsMsgDBView::SaveSortInfo(nsMsgViewSortTypeValue sortType, nsMsgViewSor
// save off sort type and order, view type and flags
folderInfo->SetSortType(sortType);
folderInfo->SetSortOrder(sortOrder);
nsString sortColumnsString;
rv = EncodeColumnSort(sortColumnsString);
NS_ENSURE_SUCCESS(rv, rv);
folderInfo->SetProperty("sortColumns", sortColumnsString);
}
}
return NS_OK;
@@ -3625,6 +3727,7 @@ PRInt32 nsMsgDBView::SecondarySort(nsMsgKey key1, nsISupports *supports1, nsMsg
PRUint16 maxLen;
eFieldType fieldType;
nsMsgViewSortTypeValue sortType = comparisonContext->view->m_secondarySort;
nsMsgViewSortOrderValue sortOrder = comparisonContext->view->m_secondarySortOrder;
rv = GetFieldTypeAndLenForSort(sortType, &maxLen, &fieldType);
const void *pValue1 = &EntryInfo1, *pValue2 = &EntryInfo2;
@@ -3637,6 +3740,9 @@ PRInt32 nsMsgDBView::SecondarySort(nsMsgKey key1, nsISupports *supports1, nsMsg
//to either GetCollationKey or GetLongField - we need the custom column handler for
// the previous sort, if any.
nsIMsgCustomColumnHandler* colHandler = nsnull; // GetCurColumnHandlerFromDBInfo();
if (sortType == nsMsgViewSortType::byCustom)
colHandler = comparisonContext->view->m_sortColumns[1].mColHandler;
switch (fieldType)
{
@@ -3655,8 +3761,9 @@ PRInt32 nsMsgDBView::SecondarySort(nsMsgKey key1, nsISupports *supports1, nsMsg
default:
return 0;
}
PRBool saveAscendingSort = comparisonContext->ascendingSort;
comparisonContext->isSecondarySort = PR_TRUE;
comparisonContext->ascendingSort = (sortOrder == nsMsgViewSortOrder::ascending);
if (fieldType == kCollationKey)
{
PR_FREEIF(EntryInfo2.key);
@@ -3673,6 +3780,8 @@ PRInt32 nsMsgDBView::SecondarySort(nsMsgKey key1, nsISupports *supports1, nsMsg
retStatus = (*comparisonFun)(&pValue1, &pValue2, comparisonContext);
comparisonContext->isSecondarySort = PR_FALSE;
comparisonContext->ascendingSort = saveAscendingSort;
return retStatus;
}
@@ -3680,37 +3789,55 @@ PRInt32 nsMsgDBView::SecondarySort(nsMsgKey key1, nsISupports *supports1, nsMsg
NS_IMETHODIMP nsMsgDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder)
{
nsresult rv;
if (m_sortType == sortType && m_sortValid && sortType != nsMsgViewSortType::byCustom)
// if we're doing a stable sort, we can't just reverse the messages.
// And the custom column we're sorting on might have changed, so to be
// on the safe side, resort.
if (m_sortType == sortType && m_sortValid && sortType != nsMsgViewSortType::byCustom
&& m_sortColumns.Length() < 2)
{
// same as it ever was. do nothing
if (m_sortOrder == sortOrder)
{
// same as it ever was. do nothing
return NS_OK;
// for secondary sort, remember the sort order on a per column basis.
m_sortColumns[0].mSortOrder = sortOrder;
SaveSortInfo(sortType, sortOrder);
if (! (m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay))
{
(void ) ReverseSort(); // doesn't fail.
}
else
{
SaveSortInfo(sortType, sortOrder);
if (! (m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay))
{
(void ) ReverseSort(); // doesn't fail.
}
else
{
rv = ReverseThreads();
NS_ENSURE_SUCCESS(rv,rv);
}
m_sortOrder = sortOrder;
// we just reversed the sort order...we still need to invalidate the view
return NS_OK;
rv = ReverseThreads();
NS_ENSURE_SUCCESS(rv,rv);
}
m_sortOrder = sortOrder;
// we just reversed the sort order...we still need to invalidate the view
return NS_OK;
}
if (sortType == nsMsgViewSortType::byThread)
return NS_OK;
if (m_sortType != sortType)
m_secondarySort = m_sortType;
{
MsgViewSortColumnInfo sortColumnInfo;
sortColumnInfo.mSortType = sortType;
sortColumnInfo.mSortOrder = sortOrder;
if (sortType == nsMsgViewSortType::byCustom)
{
GetCurCustomColumn(sortColumnInfo.mCustomColumnName);
sortColumnInfo.mColHandler = GetCurColumnHandlerFromDBInfo();
}
PushSort(sortColumnInfo);
if (m_sortColumns.Length() > 1)
{
m_secondarySort = m_sortColumns[1].mSortType;
m_secondarySortOrder = m_sortColumns[1].mSortOrder;
}
}
SaveSortInfo(sortType, sortOrder);
// figure out how much memory we'll need, and the malloc it
@@ -3854,6 +3981,8 @@ NS_IMETHODIMP nsMsgDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOr
viewSortInfo qsPrivateData;
qsPrivateData.view = this;
qsPrivateData.isSecondarySort = PR_FALSE;
qsPrivateData.ascendingSort = (sortOrder == nsMsgViewSortOrder::ascending);
// do the sort
switch (fieldType)
{
@@ -3895,7 +4024,7 @@ NS_IMETHODIMP nsMsgDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOr
if (sortOrder == nsMsgViewSortOrder::descending)
{
rv = ReverseSort();
// rv = ReverseSort();
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to reverse sort");
}
@@ -4459,14 +4588,15 @@ nsMsgViewIndex nsMsgDBView::GetInsertIndexHelper(nsIMsgDBHdr *msgHdr, nsMsgKeyAr
viewSortInfo comparisonContext;
comparisonContext.view = this;
comparisonContext.isSecondarySort = PR_FALSE;
comparisonContext.ascendingSort = (sortOrder == nsMsgViewSortOrder::ascending);
comparisonContext.db = m_db.get();
switch (fieldType)
{
case kCollationKey:
rv = GetCollationKey(msgHdr, sortType, &EntryInfo1.key, &EntryInfo1.dword, colHandler);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to create collation key");
comparisonFun = FnSortIdKeyPtr;
comparisonContext.db = m_db.get();
break;
case kU32:
if (sortType == nsMsgViewSortType::byId)
@@ -4510,8 +4640,6 @@ nsMsgViewIndex nsMsgDBView::GetInsertIndexHelper(nsIMsgDBHdr *msgHdr, nsMsgKeyAr
highIndex = tryIndex;
break;
}
if (sortOrder == nsMsgViewSortOrder::descending) //switch retStatus based on sort order
retStatus = ~retStatus;
if (retStatus < 0)
{

View File

@@ -65,6 +65,8 @@
#include "nsIStringBundle.h"
#include "nsMsgTagService.h"
#include "nsCOMArray.h"
#include "nsTArray.h"
#include "nsIMsgCustomColumnHandler.h"
#define MESSENGER_STRING_URL "chrome://messenger/locale/messenger.properties"
@@ -73,6 +75,20 @@ enum eFieldType {
kU32
};
// this is used in an nsTArray<> to keep track of a multi-column sort
class MsgViewSortColumnInfo
{
public:
MsgViewSortColumnInfo(const MsgViewSortColumnInfo &other);
MsgViewSortColumnInfo() {}
PRBool operator == (const MsgViewSortColumnInfo &other) const;
nsMsgViewSortTypeValue mSortType;
nsMsgViewSortOrderValue mSortOrder;
// if mSortType == byCustom, info about the custom column sort
nsString mCustomColumnName;
nsCOMPtr <nsIMsgCustomColumnHandler> mColHandler;
} ;
// reserve the top 8 bits in the msg flags for the view-only flags.
#define MSG_VIEW_FLAGS 0xEE000000
#define MSG_VIEW_FLAG_HASCHILDREN 0x40000000
@@ -87,9 +103,8 @@ enum eFieldType {
#define LABEL_COLOR_STRING "lc-"
#define LABEL_COLOR_WHITE_STRING "#FFFFFF"
// I think this will be an abstract implementation class.
// The classes that implement the tree support will probably
// inherit from this class.
// This is an abstract implementation class.
// The actual view objects will be instances of sub-classes of this class
class nsMsgDBView : public nsIMsgDBView, public nsIDBChangeListener,
public nsITreeView,
public nsIJunkMailClassificationListener
@@ -108,8 +123,7 @@ public:
nsMsgViewSortOrderValue sortOrder,
nsMsgViewSortTypeValue sortType);
PRInt32 SecondarySort(nsMsgKey key1, nsISupports *folder1, nsMsgKey key2, nsISupports *folder2,
struct viewSortInfo *comparisonContext);
nsMsgViewSortTypeValue m_secondarySort;
class viewSortInfo *comparisonContext);
protected:
static nsrefcnt gInstanceCount;
// atoms used for styling the view. we're going to have a lot of
@@ -280,9 +294,9 @@ protected:
nsresult OrExtraFlag(nsMsgViewIndex index, PRUint32 orflag);
nsresult AndExtraFlag(nsMsgViewIndex index, PRUint32 andflag);
nsresult SetExtraFlag(nsMsgViewIndex index, PRUint32 extraflag);
virtual nsresult RemoveByIndex(nsMsgViewIndex index);
virtual void OnExtraFlagChanged(nsMsgViewIndex /*index*/, PRUint32 /*extraFlag*/) {}
virtual void OnHeaderAddedOrDeleted() {}
virtual nsresult RemoveByIndex(nsMsgViewIndex index);
virtual void OnExtraFlagChanged(nsMsgViewIndex /*index*/, PRUint32 /*extraFlag*/) {}
virtual void OnHeaderAddedOrDeleted() {}
nsresult ToggleWatched( nsMsgViewIndex* indices, PRInt32 numIndices);
nsresult SetThreadWatched(nsIMsgThread *thread, nsMsgViewIndex index, PRBool watched);
nsresult SetThreadIgnored(nsIMsgThread *thread, nsMsgViewIndex threadIndex, PRBool ignored);
@@ -296,9 +310,15 @@ protected:
PRUint32 *len, nsIMsgCustomColumnHandler* colHandler = nsnull);
nsresult GetLongField(nsIMsgDBHdr *msgHdr, nsMsgViewSortTypeValue sortType, PRUint32 *result,
nsIMsgCustomColumnHandler* colHandler = nsnull);
static int PR_CALLBACK FnSortIdKey(const void *pItem1, const void *pItem2, void *privateData);
static int PR_CALLBACK FnSortIdKeyPtr(const void *pItem1, const void *pItem2, void *privateData);
static int PR_CALLBACK FnSortIdDWord(const void *pItem1, const void *pItem2, void *privateData);
nsresult GetStatusSortValue(nsIMsgDBHdr *msgHdr, PRUint32 *result);
nsresult GetLocationCollationKey(nsIMsgDBHdr *msgHdr, PRUint8 **result, PRUint32 *len);
void PushSort(const MsgViewSortColumnInfo &newSort);
nsresult EncodeColumnSort(nsString &columnSortString);
nsresult DecodeColumnSort(nsString &columnSortString);
// for view navigation
nsresult NavigateFromPos(nsMsgNavigationTypeValue motion, nsMsgViewIndex startIndex, nsMsgKey *pResultKey,
nsMsgViewIndex *pResultIndex, nsMsgViewIndex *pThreadIndex, PRBool wrap);
@@ -358,8 +378,11 @@ protected:
nsCOMPtr <nsIMsgFolder> m_viewFolder; // for virtual folders, the VF db.
nsCOMPtr <nsIAtom> mRedirectorTypeAtom;
nsCOMPtr <nsIAtom> mMessageTypeAtom; // news, rss, mail, etc.
nsTArray <MsgViewSortColumnInfo> m_sortColumns;
nsMsgViewSortTypeValue m_sortType;
nsMsgViewSortOrderValue m_sortOrder;
nsMsgViewSortTypeValue m_secondarySort;
nsMsgViewSortOrderValue m_secondarySortOrder;
nsMsgViewFlagsTypeValue m_viewFlags;
// I18N date formater service which we'll want to cache locally.
@@ -407,6 +430,7 @@ protected:
nsIMsgCustomColumnHandler* GetColumnHandler(const PRUnichar*);
nsIMsgCustomColumnHandler* GetCurColumnHandlerFromDBInfo();
void GetCurCustomColumn(nsString &colID);
protected:
static nsresult InitDisplayFormats();