зеркало из https://github.com/mozilla/gecko-dev.git
#73840 fix crashers caused by a missing and addref on the db in one case, one extra one in another.
#72256 Msg selection needs to hold when expanding threads of other msgs #72264 sorting by thread doesn't restore selection properly #72284 Get Msg selects new message instead of leaving thread pane selection on current selected message #74068 scroll to selected message after the sort sr=bienvenu
This commit is contained in:
Родитель
ccc3c72626
Коммит
94deb79b59
|
@ -522,9 +522,6 @@ function CreateBareDBView(msgFolder, viewType, viewFlags, sortType, sortOrder)
|
|||
// news defaults to threaded mode
|
||||
viewFlags = nsMsgViewFlagsType.kThreadedDisplay;
|
||||
}
|
||||
else {
|
||||
viewFlags &= nsMsgViewFlagsType.kThreadedDisplay;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sortType) {
|
||||
|
|
|
@ -865,8 +865,10 @@ nsresult nsMsgDBView::GetFolderForViewIndex(nsMsgViewIndex index, nsIMsgFolder *
|
|||
nsresult nsMsgDBView::GetDBForViewIndex(nsMsgViewIndex index, nsIMsgDatabase **db)
|
||||
{
|
||||
*db = m_db;
|
||||
NS_IF_ADDREF(*db);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDBView::GetCellText(PRInt32 aRow, const PRUnichar * aColID, PRUnichar ** aValue)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
@ -2852,8 +2854,7 @@ nsMsgViewIndex nsMsgDBView::GetIndexForThread(nsIMsgDBHdr *hdr)
|
|||
// and put new header before found header, or at end.
|
||||
for (PRInt32 i = GetSize() - 1; i >= 0; i--)
|
||||
{
|
||||
char level = m_levels[i];
|
||||
if (level == 0)
|
||||
if (m_levels[i])
|
||||
{
|
||||
if (insertKey < m_keys.GetAt(i))
|
||||
prevInsertIndex = i;
|
||||
|
@ -2884,8 +2885,7 @@ nsMsgViewIndex nsMsgDBView::GetIndexForThread(nsIMsgDBHdr *hdr)
|
|||
// new header before found header, or at beginning.
|
||||
for (PRInt32 i = 0; i < GetSize(); i++)
|
||||
{
|
||||
char level = m_levels[i];
|
||||
if (level == 0)
|
||||
if (m_levels[i])
|
||||
{
|
||||
if (insertKey > m_keys.GetAt(i))
|
||||
{
|
||||
|
@ -3042,13 +3042,13 @@ nsMsgViewIndex nsMsgDBView::GetInsertIndex(nsIMsgDBHdr *msgHdr)
|
|||
|
||||
nsresult nsMsgDBView::AddHdr(nsIMsgDBHdr *msgHdr)
|
||||
{
|
||||
PRUint32 flags = 0;
|
||||
PRUint32 flags = 0;
|
||||
#ifdef DEBUG_bienvenu
|
||||
NS_ASSERTION((int) m_keys.GetSize() == m_flags.GetSize() && (int) m_keys.GetSize() == m_levels.GetSize(), "view arrays out of sync!");
|
||||
NS_ASSERTION((int) m_keys.GetSize() == m_flags.GetSize() && (int) m_keys.GetSize() == m_levels.GetSize(), "view arrays out of sync!");
|
||||
#endif
|
||||
msgHdr->GetFlags(&flags);
|
||||
if (flags & MSG_FLAG_IGNORED && !GetShowingIgnored())
|
||||
return NS_OK;
|
||||
if (flags & MSG_FLAG_IGNORED && !GetShowingIgnored())
|
||||
return NS_OK;
|
||||
|
||||
nsMsgKey msgKey, threadId;
|
||||
nsMsgKey threadParent;
|
||||
|
@ -3057,40 +3057,52 @@ nsresult nsMsgDBView::AddHdr(nsIMsgDBHdr *msgHdr)
|
|||
msgHdr->GetThreadParent(&threadParent);
|
||||
|
||||
// ### this isn't quite right, is it? Should be checking that our thread parent key is none?
|
||||
if (threadParent == nsMsgKey_None)
|
||||
flags |= MSG_VIEW_FLAG_ISTHREAD;
|
||||
nsMsgViewIndex insertIndex = GetInsertIndex(msgHdr);
|
||||
if (insertIndex == nsMsgViewIndex_None)
|
||||
{
|
||||
// if unreadonly, level is 0 because we must be the only msg in the thread.
|
||||
char levelToAdd = 0; // ### TODO ((m_viewFlags & nsMsgViewFlagsType::kUnreadOnly) != 0) ? 0 : msgHdr->GetLevel();
|
||||
if (threadParent == nsMsgKey_None)
|
||||
flags |= MSG_VIEW_FLAG_ISTHREAD;
|
||||
nsMsgViewIndex insertIndex = GetInsertIndex(msgHdr);
|
||||
if (insertIndex == nsMsgViewIndex_None)
|
||||
{
|
||||
// if unreadonly, level is 0 because we must be the only msg in the thread.
|
||||
PRInt32 levelToAdd = 0;
|
||||
#if 0
|
||||
if (!(m_viewFlags & nsMsgViewFlagsType::kUnreadOnly))
|
||||
{
|
||||
levelToAdd = FindLevelInThread(msgHdr, insertIndex);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_sortOrder == nsMsgViewSortOrder::ascending)
|
||||
{
|
||||
m_keys.Add(msgKey);
|
||||
m_flags.Add(flags);
|
||||
m_levels.Add(levelToAdd);
|
||||
NoteChange(m_keys.GetSize() - 1, 1, nsMsgViewNotificationCode::insertOrDelete);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_keys.InsertAt(0, msgKey);
|
||||
m_flags.InsertAt(0, flags);
|
||||
m_levels.InsertAt(0, levelToAdd);
|
||||
NoteChange(0, 1, nsMsgViewNotificationCode::insertOrDelete);
|
||||
}
|
||||
m_sortValid = PR_FALSE;
|
||||
{
|
||||
m_keys.Add(msgKey);
|
||||
m_flags.Add(flags);
|
||||
m_levels.Add(levelToAdd);
|
||||
NoteChange(m_keys.GetSize() - 1, 1, nsMsgViewNotificationCode::insertOrDelete);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_keys.InsertAt(insertIndex, msgKey);
|
||||
m_flags.InsertAt(insertIndex, flags);
|
||||
char level = 0; // ### TODO (m_sortType == nsMsgViewSortType::byThread) ? 0 : msgHdr->GetLevel();
|
||||
m_levels.InsertAt(insertIndex, level);
|
||||
NoteChange(insertIndex, 1, nsMsgViewNotificationCode::insertOrDelete);
|
||||
m_keys.InsertAt(0, msgKey);
|
||||
m_flags.InsertAt(0, flags);
|
||||
m_levels.InsertAt(0, levelToAdd);
|
||||
NoteChange(0, 1, nsMsgViewNotificationCode::insertOrDelete);
|
||||
}
|
||||
OnHeaderAddedOrDeleted();
|
||||
return NS_OK;
|
||||
m_sortValid = PR_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_keys.InsertAt(insertIndex, msgKey);
|
||||
m_flags.InsertAt(insertIndex, flags);
|
||||
PRInt32 level = 0;
|
||||
#if 0
|
||||
if (m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay)
|
||||
{
|
||||
level = FindLevelInThread(msgHdr, insertIndex);
|
||||
}
|
||||
#endif
|
||||
m_levels.InsertAt(insertIndex, level);
|
||||
NoteChange(insertIndex, 1, nsMsgViewNotificationCode::insertOrDelete);
|
||||
}
|
||||
OnHeaderAddedOrDeleted();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgDBView::InsertHdrAt(nsIMsgDBHdr *msgHdr, nsMsgViewIndex insertIndex)
|
||||
|
@ -3103,7 +3115,13 @@ nsresult nsMsgDBView::InsertHdrAt(nsIMsgDBHdr *msgHdr, nsMsgViewIndex insertInde
|
|||
NoteStartChange(insertIndex, 1, nsMsgViewNotificationCode::changed);
|
||||
m_keys.SetAt(insertIndex, msgKey);
|
||||
m_flags.SetAt(insertIndex, flags);
|
||||
char level = 0; // ### TODO (m_sortType == nsMsgViewSortType::byThread) ? 0 : msgHdr->GetLevel()
|
||||
PRInt32 level = 0;
|
||||
#if 0
|
||||
if (m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay)
|
||||
{
|
||||
level = FindLevelInThread(msgHdr, insertIndex);
|
||||
}
|
||||
#endif
|
||||
m_levels.SetAt(insertIndex, level);
|
||||
NoteEndChange(insertIndex, 1, nsMsgViewNotificationCode::changed);
|
||||
OnHeaderAddedOrDeleted();
|
||||
|
@ -3116,7 +3134,7 @@ PRBool nsMsgDBView::WantsThisThread(nsIMsgThread * /*threadHdr*/)
|
|||
return PR_TRUE; // default is to want all threads.
|
||||
}
|
||||
|
||||
PRInt32 nsMsgDBView::FindLevelInThread(nsIMsgDBHdr *msgHdr, nsMsgKey msgKey, nsMsgViewIndex startOfThreadViewIndex)
|
||||
PRInt32 nsMsgDBView::FindLevelInThread(nsIMsgDBHdr *msgHdr, nsMsgViewIndex startOfThreadViewIndex)
|
||||
{
|
||||
nsMsgKey threadParent;
|
||||
msgHdr->GetThreadParent(&threadParent);
|
||||
|
@ -3164,7 +3182,7 @@ nsresult nsMsgDBView::ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex st
|
|||
// ### TODO - how about hasChildren flag?
|
||||
m_flags.InsertAt(viewIndex, msgFlags & ~MSG_VIEW_FLAGS);
|
||||
// ### TODO this is going to be tricky - might use enumerators
|
||||
PRInt32 level = FindLevelInThread(msgHdr, msgKey, startOfThreadViewIndex);
|
||||
PRInt32 level = FindLevelInThread(msgHdr, startOfThreadViewIndex);
|
||||
m_levels.InsertAt(viewIndex, level);
|
||||
// turn off thread or elided bit if they got turned on (maybe from new only view?)
|
||||
if (i > 0)
|
||||
|
@ -3361,7 +3379,7 @@ NS_IMETHODIMP nsMsgDBView::OnAnnouncerGoingAway(nsIDBChangeAnnouncer *instigator
|
|||
// this will force the outliner to ask for the cell values
|
||||
// since we don't have a db and we don't have any keys,
|
||||
// the thread pane goes blank
|
||||
mOutliner->Invalidate();
|
||||
if (mOutliner) mOutliner->Invalidate();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -4256,3 +4274,14 @@ nsresult nsMsgDBView::GetFolders(nsISupportsArray **aFolders)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgDBView::AdjustRowCount(PRInt32 rowCountBeforeSort, PRInt32 rowCountAfterSort)
|
||||
{
|
||||
PRInt32 rowChange = rowCountBeforeSort - rowCountAfterSort;
|
||||
|
||||
if (rowChange) {
|
||||
// this is not safe to use when you have a selection
|
||||
// RowCountChanged() will call AdjustSelection()
|
||||
if (mOutliner) mOutliner->RowCountChanged(0, rowChange);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -126,6 +126,12 @@ protected:
|
|||
nsresult SaveSelection(nsMsgKeyArray * aMsgKeyArray);
|
||||
nsresult RestoreSelection(nsMsgKeyArray * aMsgKeyArray);
|
||||
|
||||
// this is not safe to use when you have a selection
|
||||
// RowCountChanged() will call AdjustSelection()
|
||||
// it should be called after SaveSelection() and before
|
||||
// RestoreSelection()
|
||||
nsresult AdjustRowCount(PRInt32 rowCountBeforeSort, PRInt32 rowCountAfterSort);
|
||||
|
||||
nsresult GetSelectedIndices(nsUInt32Array *selection);
|
||||
nsresult GenerateURIForMsgKey(nsMsgKey aMsgKey, nsIMsgFolder *folder, char ** aURI);
|
||||
// routines used in building up view
|
||||
|
@ -172,7 +178,7 @@ protected:
|
|||
|
||||
nsresult ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex viewIndex, PRUint32 *pNumListed);
|
||||
nsresult ListUnreadIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex startOfThreadViewIndex, PRUint32 *pNumListed);
|
||||
PRInt32 FindLevelInThread(nsIMsgDBHdr *msgHdr, nsMsgKey msgKey, nsMsgViewIndex startOfThreadViewIndex);
|
||||
PRInt32 FindLevelInThread(nsIMsgDBHdr *msgHdr, nsMsgViewIndex startOfThreadViewIndex);
|
||||
PRInt32 GetSize(void) {return(m_keys.GetSize());}
|
||||
|
||||
// notification api's
|
||||
|
|
|
@ -139,7 +139,7 @@ nsresult nsMsgSearchDBView::GetDBForViewIndex(nsMsgViewIndex index, nsIMsgDataba
|
|||
nsCOMPtr <nsIMsgFolder> aFolder;
|
||||
GetFolderForViewIndex(index, getter_AddRefs(aFolder));
|
||||
if (aFolder)
|
||||
return aFolder->GetMsgDatabase(nsnull, getter_AddRefs(db));
|
||||
return aFolder->GetMsgDatabase(nsnull, db);
|
||||
else
|
||||
return NS_MSG_INVALID_DBVIEW_INDEX;
|
||||
}
|
||||
|
@ -531,10 +531,9 @@ NS_IMETHODIMP nsMsgSearchDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgView
|
|||
|
||||
// the sort may have changed the number of rows
|
||||
// before we restore the selection, tell the outliner
|
||||
PRInt32 rowCountAfterSort = GetSize();
|
||||
if (rowCountBeforeSort != rowCountAfterSort) {
|
||||
mOutliner->RowCountChanged(rowCountBeforeSort, rowCountBeforeSort - rowCountAfterSort);
|
||||
}
|
||||
// do this before we call restore selection
|
||||
// this is safe when there is no selection.
|
||||
rv = AdjustRowCount(rowCountBeforeSort, GetSize());
|
||||
|
||||
RestoreSelection(&preservedSelection);
|
||||
if (mOutliner) mOutliner->Invalidate();
|
||||
|
|
|
@ -155,10 +155,9 @@ NS_IMETHODIMP nsMsgThreadedDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgVi
|
|||
|
||||
// the sort may have changed the number of rows
|
||||
// before we restore the selection, tell the outliner
|
||||
PRInt32 rowCountAfterSort = GetSize();
|
||||
if (rowCountBeforeSort != rowCountAfterSort) {
|
||||
mOutliner->RowCountChanged(rowCountBeforeSort, rowCountBeforeSort - rowCountAfterSort);
|
||||
}
|
||||
// do this before we call restore selection
|
||||
// this is safe when there is no selection.
|
||||
rv = AdjustRowCount(rowCountBeforeSort, GetSize());
|
||||
|
||||
RestoreSelection(&preservedSelection);
|
||||
if (mOutliner) mOutliner->Invalidate();
|
||||
|
@ -173,10 +172,9 @@ NS_IMETHODIMP nsMsgThreadedDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgVi
|
|||
|
||||
// the sort may have changed the number of rows
|
||||
// before we update the selection, tell the outliner
|
||||
PRInt32 rowCountAfterSort = GetSize();
|
||||
if (rowCountBeforeSort != rowCountAfterSort) {
|
||||
mOutliner->RowCountChanged(rowCountBeforeSort, rowCountBeforeSort - rowCountAfterSort);
|
||||
}
|
||||
// do this before we call restore selection
|
||||
// this is safe when there is no selection.
|
||||
rv = AdjustRowCount(rowCountBeforeSort, GetSize());
|
||||
|
||||
RestoreSelection(&preservedSelection);
|
||||
if (mOutliner) mOutliner->Invalidate();
|
||||
|
@ -204,10 +202,9 @@ NS_IMETHODIMP nsMsgThreadedDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgVi
|
|||
|
||||
// the sort may have changed the number of rows
|
||||
// before we restore the selection, tell the outliner
|
||||
PRInt32 rowCountAfterSort = GetSize();
|
||||
if (rowCountBeforeSort != rowCountAfterSort) {
|
||||
mOutliner->RowCountChanged(rowCountBeforeSort, rowCountBeforeSort - rowCountAfterSort);
|
||||
}
|
||||
// do this before we call restore selection
|
||||
// this is safe when there is no selection.
|
||||
rv = AdjustRowCount(rowCountBeforeSort, GetSize());
|
||||
|
||||
RestoreSelection(&preservedSelection);
|
||||
if (mOutliner) mOutliner->Invalidate();
|
||||
|
|
Загрузка…
Ссылка в новой задаче