Source code

Revision control

Copy as Markdown

Other Tools

/* -*- 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