Windows2003-3790/inetcore/outlookexpress/mailnews/store/msgtable.h
2020-09-30 16:53:55 +02:00

252 lines
14 KiB
C++

//--------------------------------------------------------------------------
// MsgTable.h
//--------------------------------------------------------------------------
#pragma once
//--------------------------------------------------------------------------
// Forward Decl.
//--------------------------------------------------------------------------
class CFindFolder;
class CMessageTable;
//--------------------------------------------------------------------------
// SafeReleaseRow
//--------------------------------------------------------------------------
#define SafeReleaseRow(_pTable, _pMessage) \
if (_pMessage) { \
_pTable->ReleaseRow(_pMessage); \
_pMessage = NULL; \
}
//--------------------------------------------------------------------------
// WALKTHREADFLAGS
//--------------------------------------------------------------------------
typedef DWORD WALKTHREADFLAGS;
#define WALK_THREAD_CURRENT 0x00000001
#define WALK_THREAD_BOTTOMUP 0x00000020
//--------------------------------------------------------------------------
// SORTCHANGEINFO
//--------------------------------------------------------------------------
typedef struct tagSORTCHANGEINFO {
BYTE fSort;
BYTE fThread;
BYTE fFilter;
BYTE fExpand;
} SORTCHANGEINFO, *LPSORTCHANGEINFO;
//--------------------------------------------------------------------------
// ROWINFO
//--------------------------------------------------------------------------
typedef struct tagROWINFO *LPROWINFO;
typedef struct tagROWINFO {
BYTE cRefs;
ROWSTATE dwState;
LPROWINFO pParent;
LPROWINFO pChild;
LPROWINFO pSibling;
WORD wHighlight;
unsigned fExpanded : 1; // A thread parent that is expanded
unsigned fVisible : 1; // Is displayed in the m_prgpView index
unsigned fFiltered : 1; // Filtered and won't be displayed until filter changes
unsigned fHidden : 1; // Hidden, but if row is changed it may become visible.
unsigned fDelayed : 1; // Delayed Insert
MESSAGEINFO Message;
} ROWINFO;
//--------------------------------------------------------------------------
// NOTIFYQUEUE
//--------------------------------------------------------------------------
typedef struct tagNOTIFYQUEUE {
BOOL fClean;
TRANSACTIONTYPE tyCurrent;
ROWINDEX iRowMin;
ROWINDEX iRowMax;
DWORD cUpdate;
DWORD cAllocated;
DWORD cRows;
BYTE fIsExpandCollapse;
LPROWINDEX prgiRow;
} NOTIFYQUEUE, *LPNOTIFYQUEUE;
//--------------------------------------------------------------------------
// PFWALKTHREADCALLBACK
//--------------------------------------------------------------------------
typedef HRESULT (APIENTRY *PFWALKTHREADCALLBACK)(CMessageTable *pThis,
LPROWINFO pRow, DWORD_PTR dwCookie);
//--------------------------------------------------------------------------
// PFNENUMREFS
//--------------------------------------------------------------------------
typedef HRESULT (APIENTRY *PFNENUMREFS)(LPCSTR pszMessageId, DWORD_PTR dwCookie,
BOOL *pfDone);
//--------------------------------------------------------------------------
// CMessageTable
//--------------------------------------------------------------------------
class CMessageTable : public IMessageTable,
public IDatabaseNotify,
public IServiceProvider,
public IOperationCancel
{
public:
//----------------------------------------------------------------------
// Construction
//----------------------------------------------------------------------
CMessageTable(void);
~CMessageTable(void);
//----------------------------------------------------------------------
// IUnknown Members
//----------------------------------------------------------------------
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
//----------------------------------------------------------------------
// IMessageTable Members
//----------------------------------------------------------------------
STDMETHODIMP Initialize(FOLDERID idFolder, IMessageServer *pServer, BOOL fFindTable, IStoreCallback *pCallback);
STDMETHODIMP StartFind(LPFINDINFO pCriteria, IStoreCallback *pCallback);
STDMETHODIMP SetOwner(IStoreCallback *pDefaultCallback);
STDMETHODIMP Close(void);
STDMETHODIMP Synchronize(SYNCFOLDERFLAGS dwFlags, DWORD cHeaders, IStoreCallback *pCallback);
STDMETHODIMP OnSynchronizeComplete(void);
STDMETHODIMP GetCount(GETCOUNTTYPE tyCount, DWORD *pdwCount);
STDMETHODIMP GetRow(ROWINDEX iRow, LPMESSAGEINFO *ppData);
STDMETHODIMP ReleaseRow(LPMESSAGEINFO pInfo);
STDMETHODIMP GetRelativeRow(ROWINDEX iRow, RELATIVEROWTYPE tyRelative, LPROWINDEX piRelative);
STDMETHODIMP GetIndentLevel(ROWINDEX iRow, LPDWORD pcIndent);
STDMETHODIMP Mark(LPROWINDEX prgiView, DWORD cRows, APPLYCHILDRENTYPE tyApply, MARK_TYPE mark, IStoreCallback *pCallback);
STDMETHODIMP GetSortInfo(LPFOLDERSORTINFO pSortInfo);
STDMETHODIMP SetSortInfo(LPFOLDERSORTINFO pSortInfo, IStoreCallback *pCallback);
STDMETHODIMP GetLanguage(ROWINDEX iRow, LPDWORD pdwCodePage);
STDMETHODIMP SetLanguage(DWORD cRows, LPROWINDEX prgiRow, DWORD dwCodePage);
STDMETHODIMP GetNextRow(ROWINDEX iCurrentRow, GETNEXTTYPE tyDirection, ROWMESSAGETYPE tyMessage, GETNEXTFLAGS dwFlags, LPROWINDEX piNewRow);
STDMETHODIMP GetRowState(ROWINDEX iRow, ROWSTATE dwStateMask, ROWSTATE *pdwState);
STDMETHODIMP GetSelectionState(DWORD cRows, LPROWINDEX prgiView, SELECTIONSTATE dwMask, BOOL fIncludeChildren, SELECTIONSTATE *pdwState);
STDMETHODIMP Expand(ROWINDEX iRow);
STDMETHODIMP Collapse(ROWINDEX iRow);
STDMETHODIMP OpenMessage(ROWINDEX iRow, OPENMESSAGEFLAGS dwFlags, IMimeMessage **ppMessage, IStoreCallback *pCallback);
STDMETHODIMP GetRowMessageId(ROWINDEX iRow, LPMESSAGEID pidMessage);
STDMETHODIMP GetRowIndex(MESSAGEID idMessage, LPROWINDEX piView);
STDMETHODIMP DeleteRows(DELETEMESSAGEFLAGS dwFlags, DWORD cRows, LPROWINDEX prgiView, BOOL fIncludeChildren, IStoreCallback *pCallback);
STDMETHODIMP CopyRows(FOLDERID idFolder, COPYMESSAGEFLAGS dwOptions, DWORD cRows, LPROWINDEX prgiView, LPADJUSTFLAGS pFlags, IStoreCallback *pCallback);
STDMETHODIMP RegisterNotify(REGISTERNOTIFYFLAGS dwFlags, IMessageTableNotify *pNotify);
STDMETHODIMP UnregisterNotify(IMessageTableNotify *pNotify);
STDMETHODIMP FindNextRow(ROWINDEX iStartRow, LPCTSTR pszFindString, FINDNEXTFLAGS dwFlags, BOOL fIncludeBody, ROWINDEX *piNextRow, BOOL *pfWrapped);
STDMETHODIMP GetRowFolderId(ROWINDEX iRow, LPFOLDERID pidFolder);
STDMETHODIMP GetMessageIdList(BOOL fRootsOnly, DWORD cRows, LPROWINDEX prgiView, LPMESSAGEIDLIST pIdList);
STDMETHODIMP ConnectionAddRef(void);
STDMETHODIMP ConnectionRelease(void);
STDMETHODIMP IsChild(ROWINDEX iRowParent, ROWINDEX iRowChild);
STDMETHODIMP GetAdBarUrl(IStoreCallback *pCallback);
//----------------------------------------------------------------------
// IDatabaseNotify
//----------------------------------------------------------------------
STDMETHODIMP OnTransaction(HTRANSACTION hTransaction, DWORD_PTR dwCookie, IDatabase *pDB);
//----------------------------------------------------------------------
// IServiceProvider
//----------------------------------------------------------------------
STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, LPVOID *ppvObject);
//----------------------------------------------------------------------
// IOperationCancel
//----------------------------------------------------------------------
STDMETHODIMP Cancel(CANCELTYPE tyCancel) { return(S_OK); }
private:
//----------------------------------------------------------------------
// Private Methods
//----------------------------------------------------------------------
HRESULT _CreateRow(LPMESSAGEINFO pMessage, LPROWINFO *ppRow);
HRESULT _InsertRowIntoThread(LPROWINFO pRow, BOOL fNotify);
HRESULT _DeleteRowFromThread(LPROWINFO pRow, BOOL fNotify);
HRESULT _FreeTable(void);
HRESULT _FreeTableElements(void);
HRESULT _BuildTable(IStoreCallback *pCallback);
HRESULT _WalkMessageThread(LPROWINFO pRow, WALKTHREADFLAGS dwFlags, DWORD_PTR dwCookie, PFWALKTHREADCALLBACK pfnCallback);
HRESULT _RowTableInsert(ROWORDINAL iOrdinal, LPMESSAGEINFO pMessage);
HRESULT _RowTableDelete(ROWORDINAL iOrdinal, LPMESSAGEINFO pMessage);
HRESULT _RowTableUpdate(ROWORDINAL iOrdinal, LPMESSAGEINFO pMessage);
HRESULT _GetRowFromIndex(ROWINDEX iRow, LPROWINFO *ppRow);
HRESULT _LinkRowIntoThread(LPROWINFO pParent, LPROWINFO pRow, BOOL fNotify);
HRESULT _GrowIdList(LPMESSAGEIDLIST pList, DWORD cNeeded);
HRESULT _ExpandThread(ROWINDEX iRow, BOOL fNotify, BOOL fReExpand);
HRESULT _ExpandSingleThread(LPROWINDEX piCurrent, LPROWINFO pParent, BOOL fNotify, BOOL fForceExpand);
HRESULT _CollapseThread(ROWINDEX iRow, BOOL fNotify);
HRESULT _CollapseSingleThread(LPROWINDEX piCurrent, LPROWINFO pParent, BOOL fNotify);
HRESULT _InsertIntoView(ROWINDEX iRow, LPROWINFO pRow);
HRESULT _DeleteFromView(ROWINDEX iRow, LPROWINFO pRow);
HRESULT _GetRowFromOrdinal(ROWORDINAL iOrdinal, LPMESSAGEINFO pExpected, LPROWINFO *ppRow);
HRESULT _AdjustUnreadCount(LPROWINFO pRow, LONG lCount);
HRESULT _GetThreadIndexRange(LPROWINFO pRow, BOOL fClearState, LPROWINDEX piMin, LPROWINDEX piMax);
HRESULT _IsThreadImportance(LPROWINFO pRow, MESSAGEFLAGS dwFlag, ROWSTATE dwState, ROWSTATE *pdwState);
HRESULT _QueueNotification(TRANSACTIONTYPE tyTransaction, ROWINDEX iRowMin, ROWINDEX iRowMax, BOOL fIsExpandCollapse=FALSE);
HRESULT _FlushNotificationQueue(BOOL fFinal);
HRESULT _GetSortChangeInfo(LPFOLDERSORTINFO pSortInfo, LPFOLDERUSERDATA pUserData, LPSORTCHANGEINFO pChange);
HRESULT _SortThreadFilterTable(LPSORTCHANGEINFO pChange, BOOL fApplyFilter);
HRESULT _SortAndThreadTable(BOOL fApplyFilter);
HRESULT _HideRow(LPROWINFO pRow, BOOL fNotify);
HRESULT _ShowRow(LPROWINFO pRow);
HRESULT _PruneToReplies(void);
HRESULT _FindThreadParentByRef(LPCSTR pszReferences, LPROWINFO *ppParent);
HRESULT _RefreshFilter(void);
//----------------------------------------------------------------------
// Utilities
//----------------------------------------------------------------------
VOID _SortView(LONG left, LONG right);
LONG _CompareMessages(LPMESSAGEINFO pMsg1, LPMESSAGEINFO pMsg2);
BOOL _FIsFiltered(LPROWINFO pRow);
BOOL _FIsHidden(LPROWINFO pRow);
LPROWINFO _PGetThreadRoot(LPROWINFO pRow);
//----------------------------------------------------------------------
// Friends
//----------------------------------------------------------------------
static HRESULT _WalkThreadGetSelectionState(CMessageTable *pThis, LPROWINFO pRow, DWORD_PTR dwCookie);
static HRESULT _WalkThreadGetIdList(CMessageTable *pThis, LPROWINFO pRow, DWORD_PTR dwCookie);
static HRESULT _WalkThreadGetState(CMessageTable *pThis, LPROWINFO pRow, DWORD_PTR dwCookie);
static HRESULT _WalkThreadClearState(CMessageTable *pThis, LPROWINFO pRow, DWORD_PTR dwCookie);
static HRESULT _WalkThreadIsFromMe(CMessageTable *pThis, LPROWINFO pRow, DWORD_PTR dwCookie);
static HRESULT _WalkThreadHide(CMessageTable *pThis, LPROWINFO pRow, DWORD_PTR dwCookie);
private:
//----------------------------------------------------------------------
// Private Data
//----------------------------------------------------------------------
LONG m_cRef; // Reference Counting
BOOL m_fSynching; // Are we synching a folder ?
DWORD m_cAllocated; // Allocated elements in m_prgRow and m_prgiView
DWORD m_cRows; // Rows...
DWORD m_cView; // Number of items in the listview
DWORD m_cFiltered; // Number of rows that were filtered
DWORD m_cUnread; // Number of unread rows in m_prgpRow
LPROWINFO *m_prgpRow; // Array of Pointers to Rows
LPROWINFO *m_prgpView; // Current View
FOLDERSORTINFO m_SortInfo; // Folder Sort Info
IMessageFolder *m_pFolder; // Base Folder
IDatabase *m_pDB; // The Database
CFindFolder *m_pFindFolder; // Find Folder
IMessageTableNotify *m_pNotify; // usually the message list
BYTE m_fRelNotify; // Release m_pNotify?
IDatabaseQuery *m_pQuery; // Query Object
NOTIFYQUEUE m_Notify; // Notify Queue
FOLDERINFO m_Folder; // Folder Information
DWORD m_cDelayed; // Number of news messages not insert into view
BYTE m_fRegistered; // Registered for Notifications
BYTE m_fLoaded; // The first load has completed.
WORD m_clrWatched; // Watched Color
LPSTR m_pszEmail; // Email Address to use for show replies filter
IHashTable *m_pThreadMsgId; // Message-ID Hash Table for Threading
IHashTable *m_pThreadSubject; // Message-ID Hash Table for Threading
};
//--------------------------------------------------------------------------
// Prototypes
//--------------------------------------------------------------------------
HRESULT EnumerateRefs(LPCSTR pszReferences, DWORD_PTR dwCookie, PFNENUMREFS pfnEnumRefs);