summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/base/src/nsMsgDBView.h
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mailnews/base/src/nsMsgDBView.h')
-rw-r--r--comm/mailnews/base/src/nsMsgDBView.h558
1 files changed, 558 insertions, 0 deletions
diff --git a/comm/mailnews/base/src/nsMsgDBView.h b/comm/mailnews/base/src/nsMsgDBView.h
new file mode 100644
index 0000000000..6033a490bc
--- /dev/null
+++ b/comm/mailnews/base/src/nsMsgDBView.h
@@ -0,0 +1,558 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _nsMsgDBView_H_
+#define _nsMsgDBView_H_
+
+#include "nsIMsgDBView.h"
+#include "nsIMsgWindow.h"
+#include "nsIMessenger.h"
+#include "nsIMsgDatabase.h"
+#include "nsIMsgHdr.h"
+#include "MailNewsTypes.h"
+#include "nsIDBChangeListener.h"
+#include "nsITreeView.h"
+#include "mozilla/dom/XULTreeElement.h"
+#include "nsITreeSelection.h"
+#include "nsIMsgFolder.h"
+#include "nsIMsgThread.h"
+#include "nsMsgUtils.h"
+#include "nsIImapIncomingServer.h"
+#include "nsIMsgFilterPlugin.h"
+#include "nsIStringBundle.h"
+#include "nsMsgTagService.h"
+#include "nsCOMArray.h"
+#include "nsTArray.h"
+#include "nsTHashtable.h"
+#include "nsHashKeys.h"
+#include "nsIMsgCustomColumnHandler.h"
+#include "nsIWeakReferenceUtils.h"
+#include "nsMsgEnumerator.h"
+
+#define MESSENGER_STRING_URL "chrome://messenger/locale/messenger.properties"
+
+typedef AutoTArray<nsMsgViewIndex, 1> nsMsgViewIndexArray;
+static_assert(nsMsgViewIndex(nsMsgViewIndexArray::NoIndex) ==
+ nsMsgViewIndex_None,
+ "These need to be the same value.");
+
+enum eFieldType { kCollationKey, kU32 };
+
+// This is used in an nsTArray<> to keep track of a multi-column sort.
+class MsgViewSortColumnInfo {
+ public:
+ MsgViewSortColumnInfo(const MsgViewSortColumnInfo& other);
+ MsgViewSortColumnInfo()
+ : mSortType(nsMsgViewSortType::byNone),
+ mSortOrder(nsMsgViewSortOrder::none) {}
+ bool operator==(const MsgViewSortColumnInfo& other) const;
+ nsMsgViewSortTypeValue mSortType;
+ nsMsgViewSortOrderValue mSortOrder;
+ // If mSortType == byCustom, info about the custom column sort.
+ nsString mCustomColumnName;
+ nsCOMPtr<nsIMsgCustomColumnHandler> mColHandler;
+};
+
+// Reserve some bits in the msg flags for the view-only flags.
+// NOTE: this bit space is shared by nsMsgMessageFlags (and labels).
+#define MSG_VIEW_FLAG_ISTHREAD 0x8000000
+#define MSG_VIEW_FLAG_DUMMY 0x20000000
+#define MSG_VIEW_FLAG_HASCHILDREN 0x40000000
+#define MSG_VIEW_FLAGS \
+ (MSG_VIEW_FLAG_HASCHILDREN | MSG_VIEW_FLAG_DUMMY | MSG_VIEW_FLAG_ISTHREAD)
+
+// Helper struct for sorting by numeric fields.
+// Associates a message with a key for ordering it in the view.
+struct IdUint32 {
+ nsMsgKey id;
+ uint32_t bits;
+ uint32_t dword; // The numeric key.
+ nsIMsgFolder* folder;
+};
+
+// Extends IdUint32 for sorting by a collation key field (eg subject).
+// (Also used as IdUint32 a couple of places to simplify the code, where
+// the overhead of an unused nsTArray isn't a big deal).
+struct IdKey : public IdUint32 {
+ nsTArray<uint8_t> key;
+};
+
+class nsMsgDBViewService final : public nsIMsgDBViewService {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIMSGDBVIEWSERVICE
+
+ nsMsgDBViewService(){};
+
+ protected:
+ ~nsMsgDBViewService(){};
+};
+
+// 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 {
+ public:
+ friend class nsMsgDBViewService;
+ nsMsgDBView();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIMSGDBVIEW
+ NS_DECL_NSIDBCHANGELISTENER
+ NS_DECL_NSITREEVIEW
+ NS_DECL_NSIJUNKMAILCLASSIFICATIONLISTENER
+
+ nsMsgViewIndex GetInsertIndexHelper(nsIMsgDBHdr* msgHdr,
+ nsTArray<nsMsgKey>& keys,
+ nsCOMArray<nsIMsgFolder>* folders,
+ nsMsgViewSortOrderValue sortOrder,
+ nsMsgViewSortTypeValue sortType);
+ int32_t SecondaryCompare(nsMsgKey key1, nsIMsgFolder* folder1, nsMsgKey key2,
+ nsIMsgFolder* folder2,
+ class viewSortInfo* comparisonContext);
+
+ protected:
+ virtual ~nsMsgDBView();
+
+ static nsString kHighestPriorityString;
+ static nsString kHighPriorityString;
+ static nsString kLowestPriorityString;
+ static nsString kLowPriorityString;
+ static nsString kNormalPriorityString;
+
+ static nsString kReadString;
+ static nsString kRepliedString;
+ static nsString kForwardedString;
+ static nsString kRedirectedString;
+ static nsString kNewString;
+
+ // Used for group views.
+ static nsString kTodayString;
+ static nsString kYesterdayString;
+ static nsString kLastWeekString;
+ static nsString kTwoWeeksAgoString;
+ static nsString kOldMailString;
+ static nsString kFutureDateString;
+
+ RefPtr<mozilla::dom::XULTreeElement> mTree;
+ nsCOMPtr<nsIMsgJSTree> mJSTree;
+ nsCOMPtr<nsITreeSelection> mTreeSelection;
+ // We cache this to determine when to push command status notifications.
+ uint32_t mNumSelectedRows;
+ // Set when the message pane is collapsed.
+ bool mSuppressMsgDisplay;
+ bool mSuppressCommandUpdating;
+ // Set when we're telling the outline a row is being removed. Used to
+ // suppress msg loading during delete/move operations.
+ bool mRemovingRow;
+ bool mCommandsNeedDisablingBecauseOfSelection;
+ bool mSuppressChangeNotification;
+
+ virtual const char* GetViewName(void) { return "MsgDBView"; }
+ nsresult FetchAuthor(nsIMsgDBHdr* aHdr, nsAString& aAuthorString);
+ nsresult FetchRecipients(nsIMsgDBHdr* aHdr, nsAString& aRecipientsString);
+ nsresult FetchSubject(nsIMsgDBHdr* aMsgHdr, uint32_t aFlags,
+ nsAString& aValue);
+ nsresult FetchDate(nsIMsgDBHdr* aHdr, nsAString& aDateString,
+ bool rcvDate = false);
+ nsresult FetchStatus(uint32_t aFlags, nsAString& aStatusString);
+ nsresult FetchSize(nsIMsgDBHdr* aHdr, nsAString& aSizeString);
+ nsresult FetchPriority(nsIMsgDBHdr* aHdr, nsAString& aPriorityString);
+ nsresult FetchLabel(nsIMsgDBHdr* aHdr, nsAString& aLabelString);
+ nsresult FetchTags(nsIMsgDBHdr* aHdr, nsAString& aTagString);
+ nsresult FetchKeywords(nsIMsgDBHdr* aHdr, nsACString& keywordString);
+ nsresult FetchRowKeywords(nsMsgViewIndex aRow, nsIMsgDBHdr* aHdr,
+ nsACString& keywordString);
+ nsresult FetchAccount(nsIMsgDBHdr* aHdr, nsAString& aAccount);
+ bool IsOutgoingMsg(nsIMsgDBHdr* aHdr);
+
+ // The default enumerator is over the db, but things like
+ // quick search views will enumerate just the displayed messages.
+ virtual nsresult GetMessageEnumerator(nsIMsgEnumerator** enumerator);
+ // this is a message enumerator that enumerates based on the view contents
+ virtual nsresult GetViewEnumerator(nsIMsgEnumerator** enumerator);
+
+ // Save and Restore Selection are a pair of routines you should
+ // use when performing an operation which is going to change the view
+ // and you want to remember the selection. (i.e. for sorting).
+ // Call SaveAndClearSelection and we'll give you an array of msg keys for
+ // the current selection. We also freeze and clear the selection.
+ // When you are done changing the view,
+ // call RestoreSelection passing in the same array
+ // and we'll restore the selection AND unfreeze selection in the UI.
+ nsresult SaveAndClearSelection(nsMsgKey* aCurrentMsgKey,
+ nsTArray<nsMsgKey>& aMsgKeyArray);
+ nsresult RestoreSelection(nsMsgKey aCurrentmsgKey,
+ nsTArray<nsMsgKey>& aMsgKeyArray);
+
+ // This is not safe to use when you have a selection.
+ // RowCountChanged() will call AdjustSelection().
+ // It should be called after SaveAndClearSelection() and before
+ // RestoreSelection().
+ nsresult AdjustRowCount(int32_t rowCountBeforeSort,
+ int32_t rowCountAfterSort);
+
+ nsresult GenerateURIForMsgKey(nsMsgKey aMsgKey, nsIMsgFolder* folder,
+ nsACString& aURI);
+
+ // Routines used in building up view.
+ virtual bool WantsThisThread(nsIMsgThread* thread);
+ virtual nsresult AddHdr(nsIMsgDBHdr* msgHdr,
+ nsMsgViewIndex* resultIndex = nullptr);
+ bool GetShowingIgnored() {
+ return (m_viewFlags & nsMsgViewFlagsType::kShowIgnored) != 0;
+ }
+ bool OperateOnMsgsInCollapsedThreads();
+
+ virtual nsresult OnNewHeader(nsIMsgDBHdr* aNewHdr, nsMsgKey parentKey,
+ bool ensureListed);
+ virtual nsMsgViewIndex GetInsertIndex(nsIMsgDBHdr* msgHdr);
+ nsMsgViewIndex GetIndexForThread(nsIMsgDBHdr* hdr);
+ nsMsgViewIndex GetThreadRootIndex(nsIMsgDBHdr* msgHdr);
+ virtual nsresult GetMsgHdrForViewIndex(nsMsgViewIndex index,
+ nsIMsgDBHdr** msgHdr);
+ // Given a view index, return the index of the top-level msg in the thread.
+ nsMsgViewIndex GetThreadIndex(nsMsgViewIndex msgIndex);
+
+ virtual void InsertMsgHdrAt(nsMsgViewIndex index, nsIMsgDBHdr* hdr,
+ nsMsgKey msgKey, uint32_t flags, uint32_t level);
+ virtual void SetMsgHdrAt(nsIMsgDBHdr* hdr, nsMsgViewIndex index,
+ nsMsgKey msgKey, uint32_t flags, uint32_t level);
+ virtual void InsertEmptyRows(nsMsgViewIndex viewIndex, int32_t numRows);
+ virtual void RemoveRows(nsMsgViewIndex viewIndex, int32_t numRows);
+ nsresult ToggleExpansion(nsMsgViewIndex index, uint32_t* numChanged);
+ nsresult ExpandByIndex(nsMsgViewIndex index, uint32_t* pNumExpanded);
+ nsresult CollapseByIndex(nsMsgViewIndex index, uint32_t* pNumCollapsed);
+ nsresult ExpandAll();
+ nsresult CollapseAll();
+ nsresult ExpandAndSelectThread();
+
+ // Helper routines for thread expanding and collapsing.
+ nsresult GetThreadCount(nsMsgViewIndex viewIndex, uint32_t* pThreadCount);
+ /**
+ * Retrieve the view index of the first displayed message in the given thread.
+ * @param threadHdr The thread you care about.
+ * @param allowDummy Should dummy headers be returned when the non-dummy
+ * header is available? If the root node of the thread is a dummy header
+ * and you pass false, then we will return the first child of the thread
+ * unless the thread is elided, in which case we will return the root.
+ * If you pass true, we will always return the root.
+ * @return the view index of the first message in the thread, if any.
+ */
+ nsMsgViewIndex GetIndexOfFirstDisplayedKeyInThread(nsIMsgThread* threadHdr,
+ bool allowDummy = false);
+ virtual nsresult GetFirstMessageHdrToDisplayInThread(nsIMsgThread* threadHdr,
+ nsIMsgDBHdr** result);
+ virtual nsMsgViewIndex ThreadIndexOfMsg(
+ nsMsgKey msgKey, nsMsgViewIndex msgIndex = nsMsgViewIndex_None,
+ int32_t* pThreadCount = nullptr, uint32_t* pFlags = nullptr);
+ nsMsgViewIndex ThreadIndexOfMsgHdr(
+ nsIMsgDBHdr* msgHdr, nsMsgViewIndex msgIndex = nsMsgViewIndex_None,
+ int32_t* pThreadCount = nullptr, uint32_t* pFlags = nullptr);
+ nsMsgKey GetKeyOfFirstMsgInThread(nsMsgKey key);
+ int32_t CountExpandedThread(nsMsgViewIndex index);
+ virtual nsresult ExpansionDelta(nsMsgViewIndex index,
+ int32_t* expansionDelta);
+ void ReverseSort();
+ void ReverseThreads();
+ nsresult SaveSortInfo(nsMsgViewSortTypeValue sortType,
+ nsMsgViewSortOrderValue sortOrder);
+ nsresult RestoreSortInfo();
+ nsresult PersistFolderInfo(nsIDBFolderInfo** dbFolderInfo);
+ void SetMRUTimeForFolder(nsIMsgFolder* folder);
+
+ nsMsgKey GetAt(nsMsgViewIndex index) {
+ return m_keys.SafeElementAt(index, nsMsgKey_None);
+ }
+
+ nsMsgViewIndex FindViewIndex(nsMsgKey key) { return FindKey(key, false); }
+ /**
+ * Find the message header if it is visible in this view. (Messages in
+ * threads/groups that are elided will not be
+ * @param msgHdr Message header to look for.
+ * @param startIndex The index to start looking from.
+ * @param allowDummy Are dummy headers acceptable? If yes, then for a group
+ * with a dummy header, we return the root of the thread (the dummy
+ * header), otherwise we return the actual "content" header for the
+ * message.
+ * @return The view index of the header found, if any.
+ */
+ virtual nsMsgViewIndex FindHdr(nsIMsgDBHdr* msgHdr,
+ nsMsgViewIndex startIndex = 0,
+ bool allowDummy = false);
+ virtual nsMsgViewIndex FindKey(nsMsgKey key, bool expand);
+ virtual nsresult GetDBForViewIndex(nsMsgViewIndex index, nsIMsgDatabase** db);
+ virtual nsCOMArray<nsIMsgFolder>* GetFolders();
+ virtual nsresult GetFolderFromMsgURI(const nsACString& aMsgURI,
+ nsIMsgFolder** aFolder);
+
+ virtual nsresult ListIdsInThread(nsIMsgThread* threadHdr,
+ nsMsgViewIndex viewIndex,
+ uint32_t* pNumListed);
+ nsresult ListUnreadIdsInThread(nsIMsgThread* threadHdr,
+ nsMsgViewIndex startOfThreadViewIndex,
+ uint32_t* pNumListed);
+ nsMsgViewIndex FindParentInThread(nsMsgKey parentKey,
+ nsMsgViewIndex startOfThreadViewIndex);
+ virtual nsresult ListIdsInThreadOrder(nsIMsgThread* threadHdr,
+ nsMsgKey parentKey, uint32_t level,
+ nsMsgViewIndex* viewIndex,
+ uint32_t* pNumListed);
+ uint32_t GetSize(void) { return (m_keys.Length()); }
+
+ // For commands.
+ virtual nsresult ApplyCommandToIndicesWithFolder(
+ nsMsgViewCommandTypeValue command,
+ nsTArray<nsMsgViewIndex> const& selection, nsIMsgFolder* destFolder);
+ virtual nsresult CopyMessages(nsIMsgWindow* window,
+ nsTArray<nsMsgViewIndex> const& selection,
+ bool isMove, nsIMsgFolder* destFolder);
+ virtual nsresult DeleteMessages(nsIMsgWindow* window,
+ nsTArray<nsMsgViewIndex> const& selection,
+ bool deleteStorage);
+ nsresult GetHeadersFromSelection(nsTArray<nsMsgViewIndex> const& selection,
+ nsTArray<RefPtr<nsIMsgDBHdr>>& hdrs);
+ // ListCollapsedChildren() adds to messageArray (rather than replacing it).
+ virtual nsresult ListCollapsedChildren(
+ nsMsgViewIndex viewIndex, nsTArray<RefPtr<nsIMsgDBHdr>>& messageArray);
+
+ nsresult SetMsgHdrJunkStatus(nsIJunkMailPlugin* aJunkPlugin,
+ nsIMsgDBHdr* aMsgHdr,
+ nsMsgJunkStatus aNewClassification);
+ nsresult ToggleReadByIndex(nsMsgViewIndex index);
+ nsresult SetReadByIndex(nsMsgViewIndex index, bool read);
+ nsresult SetThreadOfMsgReadByIndex(nsMsgViewIndex index,
+ nsTArray<nsMsgKey>& keysMarkedRead,
+ bool read);
+ nsresult SetFlaggedByIndex(nsMsgViewIndex index, bool mark);
+ nsresult OrExtraFlag(nsMsgViewIndex index, uint32_t orflag);
+ nsresult AndExtraFlag(nsMsgViewIndex index, uint32_t andflag);
+ nsresult SetExtraFlag(nsMsgViewIndex index, uint32_t extraflag);
+ virtual nsresult RemoveByIndex(nsMsgViewIndex index);
+ virtual void OnExtraFlagChanged(nsMsgViewIndex /*index*/,
+ uint32_t /*extraFlag*/) {}
+ virtual void OnHeaderAddedOrDeleted() {}
+ nsresult ToggleWatched(nsTArray<nsMsgViewIndex> const& selection);
+ nsresult SetThreadWatched(nsIMsgThread* thread, nsMsgViewIndex index,
+ bool watched);
+ nsresult SetThreadIgnored(nsIMsgThread* thread, nsMsgViewIndex threadIndex,
+ bool ignored);
+ nsresult SetSubthreadKilled(nsIMsgDBHdr* header, nsMsgViewIndex msgIndex,
+ bool ignored);
+ nsresult DownloadForOffline(nsIMsgWindow* window,
+ nsTArray<nsMsgViewIndex> const& selection);
+ nsresult DownloadFlaggedForOffline(nsIMsgWindow* window);
+ nsMsgViewIndex GetThreadFromMsgIndex(nsMsgViewIndex index,
+ nsIMsgThread** threadHdr);
+ /// Should junk commands be enabled for the current message in the view?
+ bool JunkControlsEnabled(nsMsgViewIndex aViewIndex);
+
+ // For sorting.
+ nsresult GetFieldTypeAndLenForSort(
+ nsMsgViewSortTypeValue sortType, uint16_t* pMaxLen,
+ eFieldType* pFieldType, nsIMsgCustomColumnHandler* colHandler = nullptr);
+ nsresult GetCollationKey(nsIMsgDBHdr* msgHdr, nsMsgViewSortTypeValue sortType,
+ nsTArray<uint8_t>& result,
+ nsIMsgCustomColumnHandler* colHandler = nullptr);
+ nsresult GetLongField(nsIMsgDBHdr* msgHdr, nsMsgViewSortTypeValue sortType,
+ uint32_t* result,
+ nsIMsgCustomColumnHandler* colHandler = nullptr);
+
+ static int FnSortIdKey(const IdKey* pItem1, const IdKey* pItem2,
+ viewSortInfo* sortInfo);
+ static int FnSortIdUint32(const IdUint32* pItem1, const IdUint32* pItem2,
+ viewSortInfo* sortInfo);
+
+ nsresult GetStatusSortValue(nsIMsgDBHdr* msgHdr, uint32_t* result);
+ nsresult GetLocationCollationKey(nsIMsgDBHdr* msgHdr,
+ nsTArray<uint8_t>& result);
+ 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, bool wrap);
+ nsresult FindNextFlagged(nsMsgViewIndex startIndex,
+ nsMsgViewIndex* pResultIndex);
+ nsresult FindFirstNew(nsMsgViewIndex* pResultIndex);
+ nsresult FindPrevUnread(nsMsgKey startKey, nsMsgKey* pResultKey,
+ nsMsgKey* resultThreadId);
+ nsresult FindFirstFlagged(nsMsgViewIndex* pResultIndex);
+ nsresult FindPrevFlagged(nsMsgViewIndex startIndex,
+ nsMsgViewIndex* pResultIndex);
+ nsresult MarkThreadOfMsgRead(nsMsgKey msgId, nsMsgViewIndex msgIndex,
+ nsTArray<nsMsgKey>& idsMarkedRead, bool bRead);
+ nsresult MarkThreadRead(nsIMsgThread* threadHdr, nsMsgViewIndex threadIndex,
+ nsTArray<nsMsgKey>& idsMarkedRead, bool bRead);
+ bool IsValidIndex(nsMsgViewIndex index);
+ nsresult ToggleIgnored(nsTArray<nsMsgViewIndex> const& selection,
+ nsMsgViewIndex* resultIndex, bool* resultToggleState);
+ nsresult ToggleMessageKilled(nsTArray<nsMsgViewIndex> const& selection,
+ nsMsgViewIndex* resultIndex,
+ bool* resultToggleState);
+ bool OfflineMsgSelected(nsTArray<nsMsgViewIndex> const& selection);
+ bool NonDummyMsgSelected(nsTArray<nsMsgViewIndex> const& selection);
+ static void GetString(const char16_t* aStringName, nsAString& aValue);
+ static nsresult GetPrefLocalizedString(const char* aPrefName,
+ nsString& aResult);
+ nsresult AppendKeywordProperties(const nsACString& keywords,
+ nsAString& properties, bool* tagAdded);
+ static nsresult InitLabelStrings(void);
+ nsresult CopyDBView(nsMsgDBView* aNewMsgDBView,
+ nsIMessenger* aMessengerInstance,
+ nsIMsgWindow* aMsgWindow,
+ nsIMsgDBViewCommandUpdater* aCmdUpdater);
+ static void InitializeLiterals();
+ virtual int32_t FindLevelInThread(nsIMsgDBHdr* msgHdr,
+ nsMsgViewIndex startOfThread,
+ nsMsgViewIndex viewIndex);
+ nsresult GetImapDeleteModel(nsIMsgFolder* folder);
+ nsresult UpdateDisplayMessage(nsMsgViewIndex viewPosition);
+ nsresult GetDBForHeader(nsIMsgDBHdr* msgHdr, nsIMsgDatabase** db);
+
+ bool AdjustReadFlag(nsIMsgDBHdr* msgHdr, uint32_t* msgFlags);
+ void FreeAll(nsTArray<void*>* ptrs);
+ void ClearHdrCache();
+
+ // The message held in each row.
+ nsTArray<nsMsgKey> m_keys;
+ // Flags for each row, combining nsMsgMessageFlags and MSG_VIEW_FLAGS.
+ nsTArray<uint32_t> m_flags;
+ // Threading level of each row (1=top)
+ nsTArray<uint8_t> m_levels;
+
+ nsMsgImapDeleteModel mDeleteModel;
+
+ // Cache the most recently asked for header and corresponding msgKey.
+ nsCOMPtr<nsIMsgDBHdr> m_cachedHdr;
+ nsMsgKey m_cachedMsgKey;
+
+ // We need to store the message key for the message we are currently
+ // displaying to ensure we don't try to redisplay the same message just
+ // because the selection changed (i.e. after a sort).
+ nsMsgKey m_currentlyDisplayedMsgKey;
+ nsCString m_currentlyDisplayedMsgUri;
+ nsMsgViewIndex m_currentlyDisplayedViewIndex;
+ // If we're deleting messages, we want to hold off loading messages on
+ // selection changed until the delete is done and we want to batch
+ // notifications.
+ bool m_deletingRows;
+ // For certain special folders and descendants of those folders
+ // (like the "Sent" folder, "Sent/Old Sent").
+ // The Sender column really shows recipients.
+
+ // Server types for this view's folder
+ bool mIsNews; // We have special icons for news.
+ bool mIsRss; // RSS affects enabling of junk commands.
+ bool mIsXFVirtual; // A virtual folder with multiple folders.
+
+ bool mShowSizeInLines; // For news we show lines instead of size when true.
+ bool mSortThreadsByRoot; // As opposed to by the newest message.
+ bool m_sortValid;
+ bool m_checkedCustomColumns;
+ bool mSelectionSummarized;
+ // We asked the front end to summarize the selection and it did not.
+ bool mSummarizeFailed;
+ uint8_t m_saveRestoreSelectionDepth;
+
+ nsCOMPtr<nsIMsgDatabase> m_db;
+ nsCOMPtr<nsIMsgFolder> m_folder;
+ // For virtual folders, the VF db.
+ nsCOMPtr<nsIMsgFolder> m_viewFolder;
+ nsString mMessageType;
+ nsTArray<MsgViewSortColumnInfo> m_sortColumns;
+ nsMsgViewSortTypeValue m_sortType;
+ nsMsgViewSortOrderValue m_sortOrder;
+ nsString m_curCustomColumn;
+ nsMsgViewSortTypeValue m_secondarySort;
+ nsMsgViewSortOrderValue m_secondarySortOrder;
+ nsString m_secondaryCustomColumn;
+ nsMsgViewFlagsTypeValue m_viewFlags;
+
+ // I18N date formatter service which we'll want to cache locally.
+ nsCOMPtr<nsIMsgTagService> mTagService;
+ nsWeakPtr mMessengerWeak;
+ nsWeakPtr mMsgWindowWeak;
+ // We push command update notifications to the UI from this.
+ nsWeakPtr mCommandUpdater;
+ static nsCOMPtr<nsIStringBundle> mMessengerStringBundle;
+
+ // Used to determine when to start and end junk plugin batches.
+ uint32_t mNumMessagesRemainingInBatch;
+
+ // These are the headers of the messages in the current
+ // batch/series of batches of messages manually marked
+ // as junk.
+ nsTArray<RefPtr<nsIMsgDBHdr>> mJunkHdrs;
+
+ nsTArray<uint32_t> mIndicesToNoteChange;
+
+ nsTHashtable<nsCStringHashKey> mEmails;
+
+ // The saved search views keep track of the XX most recently deleted msg ids,
+ // so that if the delete is undone, we can add the msg back to the search
+ // results, even if it no longer matches the search criteria (e.g., a saved
+ // search over unread messages). We use mRecentlyDeletedArrayIndex to treat
+ // the array as a list of the XX most recently deleted msgs.
+ nsTArray<nsCString> mRecentlyDeletedMsgIds;
+ uint32_t mRecentlyDeletedArrayIndex;
+ void RememberDeletedMsgHdr(nsIMsgDBHdr* msgHdr);
+ bool WasHdrRecentlyDeleted(nsIMsgDBHdr* msgHdr);
+
+ // These hold pointers (and IDs) for the nsIMsgCustomColumnHandler object
+ // that constitutes the custom column handler.
+ nsCOMArray<nsIMsgCustomColumnHandler> m_customColumnHandlers;
+ nsTArray<nsString> m_customColumnHandlerIDs;
+
+ nsIMsgCustomColumnHandler* GetColumnHandler(const nsAString& colID);
+ nsIMsgCustomColumnHandler* GetCurColumnHandler();
+ bool CustomColumnsInSortAndNotRegistered();
+ void EnsureCustomColumnsValid();
+
+#ifdef DEBUG_David_Bienvenu
+ void InitEntryInfoForIndex(nsMsgViewIndex i, IdKey& EntryInfo);
+ void ValidateSort();
+#endif
+
+ protected:
+ static nsresult InitDisplayFormats();
+
+ private:
+ static bool m_dateFormatsInitialized;
+ static nsDateFormatSelectorComm m_dateFormatDefault;
+ static nsDateFormatSelectorComm m_dateFormatThisWeek;
+ static nsDateFormatSelectorComm m_dateFormatToday;
+ static nsString m_connectorPattern;
+
+ bool ServerSupportsFilterAfterTheFact();
+
+ nsresult PerformActionsOnJunkMsgs(bool msgsAreJunk);
+ nsresult DetermineActionsForJunkChange(bool msgsAreJunk,
+ nsIMsgFolder* srcFolder,
+ bool& moveMessages,
+ bool& changeReadState,
+ nsIMsgFolder** targetFolder);
+
+ class nsMsgViewHdrEnumerator final : public nsBaseMsgEnumerator {
+ public:
+ explicit nsMsgViewHdrEnumerator(nsMsgDBView* view);
+
+ // nsIMsgEnumerator support.
+ NS_IMETHOD GetNext(nsIMsgDBHdr** aItem) override;
+ NS_IMETHOD HasMoreElements(bool* aResult) override;
+
+ RefPtr<nsMsgDBView> m_view;
+ nsMsgViewIndex m_curHdrIndex;
+
+ private:
+ virtual ~nsMsgViewHdrEnumerator() override;
+ };
+};
+
+#endif