fix 303948, rebuild group sort by date when date changes, sr=mscott

This commit is contained in:
bienvenu%nventure.com 2005-08-17 17:02:12 +00:00
Родитель 743b627878
Коммит c710b8ce90
2 изменённых файлов: 79 добавлений и 9 удалений

Просмотреть файл

@ -65,6 +65,8 @@ nsMsgGroupView::nsMsgGroupView()
kTwoWeeksAgoString = GetString(NS_LITERAL_STRING("twoWeeksAgo").get()); kTwoWeeksAgoString = GetString(NS_LITERAL_STRING("twoWeeksAgo").get());
kOldMailString = GetString(NS_LITERAL_STRING("older").get()); kOldMailString = GetString(NS_LITERAL_STRING("older").get());
} }
m_dayChanged = PR_FALSE;
m_lastCurExplodedTime.tm_mday = 0;
} }
nsMsgGroupView::~nsMsgGroupView() nsMsgGroupView::~nsMsgGroupView()
@ -102,8 +104,7 @@ NS_IMETHODIMP nsMsgGroupView::Open(nsIMsgFolder *aFolder, nsMsgViewSortTypeValue
return kHashEnumerateNext; return kHashEnumerateNext;
} }
void nsMsgGroupView::InternalClose()
NS_IMETHODIMP nsMsgGroupView::Close()
{ {
if (m_db && m_sortType == nsMsgViewSortType::byDate) if (m_db && m_sortType == nsMsgViewSortType::byDate)
{ {
@ -132,7 +133,12 @@ NS_IMETHODIMP nsMsgGroupView::Close()
} }
} }
// enumerate m_groupsTable releasing the thread objects. // enumerate m_groupsTable releasing the thread objects.
m_groupsTable.Enumerate(ReleaseThread); m_groupsTable.Reset(ReleaseThread);
}
NS_IMETHODIMP nsMsgGroupView::Close()
{
InternalClose();
return nsMsgThreadedDBView::Close(); return nsMsgThreadedDBView::Close();
} }
@ -193,14 +199,19 @@ nsHashKey *nsMsgGroupView::AllocHashKeyForHdr(nsIMsgDBHdr *msgHdr)
nsresult rv = msgHdr->GetDate(&dateOfMsg); nsresult rv = msgHdr->GetDate(&dateOfMsg);
PRTime currentTime = PR_Now(); PRTime currentTime = PR_Now();
PRExplodedTime explodedCurrentTime; PRExplodedTime currentExplodedTime;
PR_ExplodeTime(currentTime, PR_LocalTimeParameters, &explodedCurrentTime); PR_ExplodeTime(currentTime, PR_LocalTimeParameters, &currentExplodedTime);
PRExplodedTime explodedMsgTime; PRExplodedTime explodedMsgTime;
PR_ExplodeTime(dateOfMsg, PR_LocalTimeParameters, &explodedMsgTime); PR_ExplodeTime(dateOfMsg, PR_LocalTimeParameters, &explodedMsgTime);
if (explodedCurrentTime.tm_year == explodedMsgTime.tm_year && if (m_lastCurExplodedTime.tm_mday &&
explodedCurrentTime.tm_month == explodedMsgTime.tm_month && m_lastCurExplodedTime.tm_mday != currentExplodedTime.tm_mday)
explodedCurrentTime.tm_mday == explodedMsgTime.tm_mday) m_dayChanged = PR_TRUE; // this will cause us to rebuild the view.
m_lastCurExplodedTime = currentExplodedTime;
if (currentExplodedTime.tm_year == explodedMsgTime.tm_year &&
currentExplodedTime.tm_month == explodedMsgTime.tm_month &&
currentExplodedTime.tm_mday == explodedMsgTime.tm_mday)
{ {
// same day... // same day...
ageBucket = 1; ageBucket = 1;
@ -234,7 +245,7 @@ nsHashKey *nsMsgGroupView::AllocHashKeyForHdr(nsIMsgDBHdr *msgHdr)
// setting the time variables to local time // setting the time variables to local time
PRInt64 GMTLocalTimeShift; PRInt64 GMTLocalTimeShift;
LL_ADD( GMTLocalTimeShift, explodedCurrentTime.tm_params.tp_gmt_offset, explodedCurrentTime.tm_params.tp_dst_offset ); LL_ADD( GMTLocalTimeShift, currentExplodedTime.tm_params.tp_gmt_offset, currentExplodedTime.tm_params.tp_dst_offset );
LL_MUL( GMTLocalTimeShift, GMTLocalTimeShift, microSecondsPerSecond ); LL_MUL( GMTLocalTimeShift, GMTLocalTimeShift, microSecondsPerSecond );
LL_ADD( currentTime, currentTime, GMTLocalTimeShift ); LL_ADD( currentTime, currentTime, GMTLocalTimeShift );
LL_ADD( dateOfMsg, dateOfMsg, GMTLocalTimeShift ); LL_ADD( dateOfMsg, dateOfMsg, GMTLocalTimeShift );
@ -397,8 +408,53 @@ NS_IMETHODIMP nsMsgGroupView::OpenWithHdrs(nsISimpleEnumerator *aHeaders, nsMsgV
return rv; return rv;
} }
// if the day has changed, we need to close and re-open the view.
nsresult nsMsgGroupView::HandleDayChange()
{
nsCOMPtr <nsISimpleEnumerator> headers;
if (NS_SUCCEEDED(m_db->EnumerateMessages(getter_AddRefs(headers))))
{
PRInt32 count;
m_dayChanged = PR_FALSE;
nsMsgKeyArray preservedSelection;
nsMsgKey curSelectedKey;
SaveAndClearSelection(&curSelectedKey, &preservedSelection);
InternalClose();
PRInt32 oldSize = GetSize();
// this is important, because the tree will ask us for our
// row count, which get determine from the number of keys.
m_keys.RemoveAll();
// be consistent
m_flags.RemoveAll();
m_levels.RemoveAll();
// this needs to happen after we remove all the keys, since RowCountChanged() will call our GetRowCount()
if (mTree)
mTree->RowCountChanged(0, -oldSize);
DisableChangeUpdates();
nsresult rv = OpenWithHdrs(headers, m_sortType, m_sortOrder, m_viewFlags, &count);
EnableChangeUpdates();
if (mTree)
mTree->RowCountChanged(0, GetSize());
NS_ENSURE_SUCCESS(rv,rv);
// now, restore our desired selection
nsMsgKeyArray keyArray;
keyArray.Add(curSelectedKey);
return RestoreSelection(curSelectedKey, &keyArray);
}
}
nsresult nsMsgGroupView::OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, PRBool /*ensureListed*/) nsresult nsMsgGroupView::OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, PRBool /*ensureListed*/)
{ {
// check if we're adding a header, and the current day has changed. If it has, we're just going to
// close and re-open the view so things will be correctly categorized.
if (m_dayChanged)
return HandleDayChange();
PRBool newThread; PRBool newThread;
nsMsgGroupThread *thread = AddHdrToThread(newHdr, &newThread); nsMsgGroupThread *thread = AddHdrToThread(newHdr, &newThread);
if (thread) if (thread)
@ -477,6 +533,11 @@ NS_IMETHODIMP nsMsgGroupView::OnHdrChange(nsIMsgDBHdr *aHdrChanged, PRUint32 aOl
{ {
nsCOMPtr <nsIMsgThread> thread; nsCOMPtr <nsIMsgThread> thread;
// check if we're adding a header, and the current day has changed. If it has, we're just going to
// close and re-open the view so things will be correctly categorized.
if (m_dayChanged)
return HandleDayChange();
nsresult rv = GetThreadContainingMsgHdr(aHdrChanged, getter_AddRefs(thread)); nsresult rv = GetThreadContainingMsgHdr(aHdrChanged, getter_AddRefs(thread));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
PRUint32 deltaFlags = (aOldFlags ^ aNewFlags); PRUint32 deltaFlags = (aOldFlags ^ aNewFlags);
@ -489,6 +550,11 @@ NS_IMETHODIMP nsMsgGroupView::OnHdrChange(nsIMsgDBHdr *aHdrChanged, PRUint32 aOl
NS_IMETHODIMP nsMsgGroupView::OnHdrDeleted(nsIMsgDBHdr *aHdrDeleted, nsMsgKey aParentKey, PRInt32 aFlags, NS_IMETHODIMP nsMsgGroupView::OnHdrDeleted(nsIMsgDBHdr *aHdrDeleted, nsMsgKey aParentKey, PRInt32 aFlags,
nsIDBChangeListener *aInstigator) nsIDBChangeListener *aInstigator)
{ {
// check if we're adding a header, and the current day has changed. If it has, we're just going to
// close and re-open the view so things will be correctly categorized.
if (m_dayChanged)
return HandleDayChange();
nsCOMPtr <nsIMsgThread> thread; nsCOMPtr <nsIMsgThread> thread;
nsMsgKey keyDeleted; nsMsgKey keyDeleted;
aHdrDeleted->GetMessageKey(&keyDeleted); aHdrDeleted->GetMessageKey(&keyDeleted);

Просмотреть файл

@ -63,6 +63,7 @@ public:
NS_IMETHOD GetCellText(PRInt32 aRow, nsITreeColumn* aCol, nsAString& aValue); NS_IMETHOD GetCellText(PRInt32 aRow, nsITreeColumn* aCol, nsAString& aValue);
protected: protected:
void InternalClose();
nsMsgGroupThread *AddHdrToThread(nsIMsgDBHdr *msgHdr, PRBool *pNewThread); nsMsgGroupThread *AddHdrToThread(nsIMsgDBHdr *msgHdr, PRBool *pNewThread);
nsHashKey *AllocHashKeyForHdr(nsIMsgDBHdr *msgHdr); // caller must delete nsHashKey *AllocHashKeyForHdr(nsIMsgDBHdr *msgHdr); // caller must delete
nsresult OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, PRBool /*ensureListed*/); nsresult OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, PRBool /*ensureListed*/);
@ -74,8 +75,11 @@ protected:
PRUint32 *pFlags = NULL); PRUint32 *pFlags = NULL);
PRBool GroupViewUsesDummyRow(); // returns true if we are grouped by a sort attribute that uses a dummy row PRBool GroupViewUsesDummyRow(); // returns true if we are grouped by a sort attribute that uses a dummy row
nsresult HandleDayChange();
nsHashtable m_groupsTable; nsHashtable m_groupsTable;
PRExplodedTime m_lastCurExplodedTime;
PRBool m_dayChanged;
static PRUnichar* kTodayString; static PRUnichar* kTodayString;
static PRUnichar* kYesterdayString; static PRUnichar* kYesterdayString;