NS_IMETHODIMP nsMsgThreadedDBView::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; // Preset msg hdr cache size for performance reason. PRInt32 totalMessages, unreadMessages; nsCOMPtr <nsIDBFolderInfo> dbFolderInfo; PersistFolderInfo(getter_AddRefs(dbFolderInfo)); NS_ENSURE_SUCCESS(rv, rv); // save off sort type and order, view type and flags dbFolderInfo->GetNumUnreadMessages(&unreadMessages); dbFolderInfo->GetNumMessages(&totalMessages); if (m_viewFlags & nsMsgViewFlagsType::kUnreadOnly) { // Set unread msg size + extra entries to avoid reallocation on new mail. totalMessages = (PRUint32)unreadMessages+MSGHDR_CACHE_LOOK_AHEAD_SIZE; } else { if (totalMessages > MSGHDR_CACHE_MAX_SIZE) totalMessages = MSGHDR_CACHE_MAX_SIZE; // use max default else if (totalMessages > 0) totalMessages += MSGHDR_CACHE_LOOK_AHEAD_SIZE;// allocate extra entries to avoid reallocation on new mail. } // if total messages is 0, then we probably don't have any idea how many headers are in the db // so we have no business setting the cache size. if (totalMessages > 0) m_db->SetMsgHdrCacheSize((PRUint32)totalMessages); if (pCount) *pCount = 0; rv = InitThreadedView(pCount); // this is a hack, but we're trying to find a way to correct // incorrect total and unread msg counts w/o paying a big // performance penalty. So, if we're not threaded, just add // up the total and unread messages in the view and see if that // matches what the db totals say. Except ignored threads are // going to throw us off...hmm. Unless we just look at the // unread counts which is what mostly tweaks people anyway... PRInt32 unreadMsgsInView = 0; if (!(m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay)) { for (PRUint32 i = m_flags.Length(); i > 0; ) { if (!(m_flags[--i] & nsMsgMessageFlags::Read)) ++unreadMsgsInView; } if (unreadMessages != unreadMsgsInView) m_db->SyncCounts(); } m_db->SetMsgHdrCacheSize(MSGHDR_CACHE_DEFAULT_SIZE); return rv; }
NS_IMETHODIMP nsMsgQuickSearchDBView::Open(nsIMsgFolder *folder, nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder, nsMsgViewFlagsTypeValue viewFlags, int32_t *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 = nullptr; return InitThreadedView(pCount); }
NS_IMETHODIMP nsMsgThreadedDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder) { nsresult rv; PRInt32 rowCountBeforeSort = GetSize(); if (!rowCountBeforeSort) { // still need to setup our flags even when no articles - bug 98183. m_sortType = sortType; if (sortType == nsMsgViewSortType::byThread && ! (m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay)) SetViewFlags(m_viewFlags | nsMsgViewFlagsType::kThreadedDisplay); SaveSortInfo(sortType, sortOrder); return NS_OK; } // sort threads by sort order bool sortThreads = m_viewFlags & (nsMsgViewFlagsType::kThreadedDisplay | nsMsgViewFlagsType::kGroupBySort); // 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; nsMsgKey preservedKey; nsAutoTArray<nsMsgKey, 1> preservedSelection; SaveAndClearSelection(&preservedKey, preservedSelection); // if the client wants us to forget our cached id arrays, they // should build a new view. If this isn't good enough, we // need a method to do that. if (sortType != m_sortType || !m_sortValid || sortThreads) { SaveSortInfo(sortType, sortOrder); if (sortType == nsMsgViewSortType::byThread) { m_sortType = sortType; m_viewFlags |= nsMsgViewFlagsType::kThreadedDisplay; m_viewFlags &= nsMsgViewFlagsType::kGroupBySort; if ( m_havePrevView) { // restore saved id array and flags array m_keys = m_prevKeys; m_flags = m_prevFlags; m_levels = m_prevLevels; m_sortValid = true; // the sort may have changed the number of rows // before we restore the selection, tell the tree // do this before we call restore selection // this is safe when there is no selection. rv = AdjustRowCount(rowCountBeforeSort, GetSize()); RestoreSelection(preservedKey, preservedSelection); if (mTree) mTree->Invalidate(); return NS_OK; } else { // set sort info in anticipation of what Init will do. InitThreadedView(nsnull); // build up thread list. if (sortOrder != nsMsgViewSortOrder::ascending) Sort(sortType, sortOrder); // the sort may have changed the number of rows // before we update the selection, tell the tree // do this before we call restore selection // this is safe when there is no selection. rv = AdjustRowCount(rowCountBeforeSort, GetSize()); RestoreSelection(preservedKey, preservedSelection); if (mTree) mTree->Invalidate(); return NS_OK; } } else if (sortType != nsMsgViewSortType::byThread && (m_sortType == nsMsgViewSortType::byThread || sortThreads)/* && !m_havePrevView*/) { if (sortThreads) { SortThreads(sortType, sortOrder); sortType = nsMsgViewSortType::byThread; // hack so base class won't do anything } else { // going from SortByThread to non-thread sort - must build new key, level,and flags arrays m_prevKeys = m_keys; m_prevFlags = m_flags; m_prevLevels = m_levels; // do this before we sort, so that we'll use the cheap method // of expanding. m_viewFlags &= ~(nsMsgViewFlagsType::kThreadedDisplay | nsMsgViewFlagsType::kGroupBySort); ExpandAll(); // m_idArray.RemoveAll(); // m_flags.Clear(); m_havePrevView = true; } } } else if (m_sortOrder != sortOrder)// check for toggling the sort { nsMsgDBView::Sort(sortType, sortOrder); } if (!sortThreads) { // call the base class in case we're not sorting by thread rv = nsMsgDBView::Sort(sortType, sortOrder); SaveSortInfo(sortType, sortOrder); } // the sort may have changed the number of rows // before we restore the selection, tell the tree // do this before we call restore selection // this is safe when there is no selection. rv = AdjustRowCount(rowCountBeforeSort, GetSize()); RestoreSelection(preservedKey, preservedSelection); if (mTree) mTree->Invalidate(); NS_ENSURE_SUCCESS(rv,rv); return NS_OK; }