nsresult nsMsgThreadsWithUnreadDBView::AddMsgToThreadNotInView(nsIMsgThread *threadHdr, nsIMsgDBHdr *msgHdr, bool ensureListed) { nsresult rv = NS_OK; nsCOMPtr <nsIMsgDBHdr> parentHdr; PRUint32 msgFlags; msgHdr->GetFlags(&msgFlags); GetFirstMessageHdrToDisplayInThread(threadHdr, getter_AddRefs(parentHdr)); if (parentHdr && (ensureListed || !(msgFlags & nsMsgMessageFlags::Read))) { nsMsgKey key; PRUint32 numMsgsInThread; rv = AddHdr(parentHdr); threadHdr->GetNumChildren(&numMsgsInThread); if (numMsgsInThread > 1) { parentHdr->GetMessageKey(&key); nsMsgViewIndex viewIndex = FindViewIndex(key); if (viewIndex != nsMsgViewIndex_None) OrExtraFlag(viewIndex, nsMsgMessageFlags::Elided | MSG_VIEW_FLAG_HASCHILDREN); } m_totalUnwantedMessagesInView -= numMsgsInThread; } else m_totalUnwantedMessagesInView++; return rv; }
nsresult nsMsgQuickSearchDBView::SortThreads(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder) { // don't need to sort by threads for group view. if (m_viewFlags & nsMsgViewFlagsType::kGroupBySort) return NS_OK; // iterate over the messages in the view, getting the thread id's // sort m_keys so we can quickly find if a key is in the view. m_keys.Sort(); // array of the threads' root hdr keys. nsTArray<nsMsgKey> threadRootIds; nsCOMPtr <nsIMsgDBHdr> rootHdr; nsCOMPtr <nsIMsgDBHdr> msgHdr; nsCOMPtr <nsIMsgThread> threadHdr; for (uint32_t i = 0; i < m_keys.Length(); i++) { GetMsgHdrForViewIndex(i, getter_AddRefs(msgHdr)); m_db->GetThreadContainingMsgHdr(msgHdr, getter_AddRefs(threadHdr)); if (threadHdr) { nsMsgKey rootKey; threadHdr->GetChildKeyAt(0, &rootKey); nsMsgViewIndex threadRootIndex = threadRootIds.BinaryIndexOf(rootKey); // if we already have that id in top level threads, ignore this msg. if (threadRootIndex != nsMsgViewIndex_None) continue; // it would be nice if GetInsertIndexHelper always found the hdr, but it doesn't. threadHdr->GetChildHdrAt(0, getter_AddRefs(rootHdr)); if (!rootHdr) continue; threadRootIndex = GetInsertIndexHelper(rootHdr, threadRootIds, nullptr, nsMsgViewSortOrder::ascending, nsMsgViewSortType::byId); threadRootIds.InsertElementAt(threadRootIndex, rootKey); } } // need to sort the top level threads now by sort order, if it's not by id. if (sortType != nsMsgViewSortType::byId) { m_keys.SwapElements(threadRootIds); nsMsgDBView::Sort(sortType, sortOrder); threadRootIds.SwapElements(m_keys); } m_keys.Clear(); m_levels.Clear(); m_flags.Clear(); // 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. uint32_t numThreads = threadRootIds.Length(); for (uint32_t 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; uint32_t rootFlags; GetFirstMessageHdrToDisplayInThread(threadHdr, getter_AddRefs(displayRootHdr)); if (!displayRootHdr) continue; displayRootHdr->GetMessageKey(&rootKey); displayRootHdr->GetFlags(&rootFlags); rootFlags |= MSG_VIEW_FLAG_ISTHREAD; m_keys.AppendElement(rootKey); m_flags.AppendElement(rootFlags); m_levels.AppendElement(0); nsMsgViewIndex startOfThreadViewIndex = m_keys.Length(); nsMsgViewIndex rootIndex = startOfThreadViewIndex - 1; uint32_t numListed = 0; ListIdsInThreadOrder(threadHdr, rootKey, 1, &startOfThreadViewIndex, &numListed); if (numListed > 0) m_flags[rootIndex] = rootFlags | MSG_VIEW_FLAG_HASCHILDREN; } } } return NS_OK; }