pjs/lib/libmsg/msgdbvw.h

306 строки
13 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _MsgView_H_
#define _MsgView_H_
typedef uint32 MSG_ViewIndex;
const uint32 kViewIndexNone = MSG_VIEWINDEXNONE;
#include "msg.h"
#include "msgdb.h"
#include "idarray.h"
#include "bytearr.h"
#include "errcode.h"
#include "chngntfy.h"
#include "abcom.h"
class XPStringObj;
class ViewChangeListener : public ChangeListener
{
public:
ViewChangeListener(MessageDBView *view);
virtual ~ViewChangeListener();
virtual void OnViewChange(MSG_ViewIndex startIndex, int32 numChanged,
MSG_NOTIFY_CODE changeType,
ChangeListener *instigator);
virtual void OnViewStartChange(MSG_ViewIndex startIndex, int32 numChanged,
MSG_NOTIFY_CODE changeType,
ChangeListener *instigator);
virtual void OnViewEndChange(MSG_ViewIndex startIndex, int32 numChanged,
MSG_NOTIFY_CODE changeType,
ChangeListener *instigator);
virtual void OnKeyChange(MessageKey keyChanged, int32 flags,
ChangeListener *instigator);
virtual void OnAnnouncerGoingAway (ChangeAnnouncer *instigator);
protected:
MessageDBView *m_dbView;
};
typedef int32 ViewFlags;
// flags for GetViewFlags
const int kOutlineDisplay = 0x1;
const int kFlatDisplay = 0x2;
const int kShowIgnored = 0x8;
const int kUnreadOnly = 0x10;
class MessageDBView : public ChangeAnnouncer
{
friend class ViewChangeListener;
public:
MessageDBView();
// Open and close methods
static MsgERR OpenURL(const char * url, MSG_Master *master,
ViewType viewType, MessageDBView **view, XP_Bool openInForeground);
static MsgERR OpenViewOnDB(MessageDB *msgDB, ViewType viewType,
MessageDBView ** pRetView,
XP_Bool runInForeground = TRUE);
virtual MsgERR Open(MessageDB *messageDB, ViewType viewType,
uint32* pCount, XP_Bool runInForeground = TRUE);
virtual MsgERR Close();
virtual MsgERR Init(uint32 *pCount, XP_Bool runInForeground = TRUE);
virtual MsgERR InitSort(SortType sortType, SortOrder sortOrder);
virtual int32 AddKeys(MessageKey *pOutput, int32 *pFlags, char *pLevels, SortType sortType, int numListed);
// Methods dealing with adding headers
// this is for background loading and indicates to the view that no
// more headers are coming. For example, the view of only threads with
// new documents could throw away all threads not having new at this point,
// and whatever data structures it no longer needs
virtual MsgERR FinishedAddingHeaders();
// this tells the view that we've added a chunk and we need to add them to
// the db and view. For threaded views, we want to do threading in chunks.
virtual MsgERR AddNewMessages() = 0;
// for news, xover line, potentially, for IMAP, imap line...
virtual MsgERR AddHdrFromServerLine(char *line, MessageKey *msgId) = 0;
virtual MsgERR AddHdr(DBMessageHdr *msgHdr);
virtual MsgERR InsertHdrAt(DBMessageHdr *msgHdr, MSG_ViewIndex index);
virtual MsgERR OnNewHeader(MessageKey newKey, XP_Bool ensureListed);
virtual XP_Bool WantsThisThread(DBThreadMessageHdr *threadHdr);
public:
// accessors
virtual ViewType GetViewType(void) {return m_viewType;}
XP_Bool GetShowingIgnored();
void SetShowingIgnored(XP_Bool bShowIgnored);
MessageDB *GetDB() {return m_messageDB;}
virtual void SetInitialSortState(void) = 0;
virtual const char * GetViewName(void) = 0;
MsgERR ListThreads(MessageKey *pMessageNums, int numToList,
MessageHdrStruct *pOutput, int *pNumListed);
MsgERR ListThreadsShort(MessageKey *pMessageNums, int numToList,
MSG_MessageLine *pOutput, int *pNumListed);
// list the headers of the top-level thread ids
MsgERR ListThreadIds(MessageKey *startMsg, MessageKey *pOutput,
int numToList, int *numListed);
MsgERR ListThreadIds(ListContext *context, MessageKey *pOutput,
int numToList, int *numListed);
// return the list header information for the documents in a thread.
MsgERR ListThread(MessageKey threadId, MessageKey startMsg,
int numToList, MessageHdrStruct *pOutput,
int *pNumListed);
MsgERR ListThreadShort(MessageKey threadId, MessageKey startMsg,
int numToList, MSG_MessageLine *pOutput,
int *pNumListed);
// list headers by index
virtual MsgERR ListShortMsgHdrByIndex(MSG_ViewIndex startIndex,
int numToList,
MSG_MessageLine *pOutput,
int *pNumListed);
virtual MsgERR ListMsgHdrByIndex(MSG_ViewIndex startIndex,
int numToList, MessageHdrStruct *pOutput,
int *pNumListed);
MsgERR GetMsgLevelByIndex(MSG_ViewIndex index, int &level);
// view modification by index.
MsgERR ToggleIgnored(MSG_ViewIndex* indices, int32 numIndices, XP_Bool *resultToggleState);
MsgERR ToggleWatched(MSG_ViewIndex* indices, int32 numIndices);
MsgERR ExpansionDelta(MSG_ViewIndex index, int32 *expansionDelta);
MsgERR ToggleExpansion(MSG_ViewIndex index, uint32 *numChanged);
MsgERR ExpandByIndex(MSG_ViewIndex index, uint32 *numExpanded);
MsgERR CollapseByIndex(MSG_ViewIndex index, uint32 *numCollapsed);
MsgERR ExpandAll();
MsgERR CollapseAll();
// navigation routines
// This can cause a thread to be expanded. Maybe caller doesn't care...
// But we'll return the index of any expanded thread, if asked, and the
// index where we landed..
MsgERR Navigate(MSG_ViewIndex startIndex, MSG_MotionType motion,
MessageKey *pResultKey, MSG_ViewIndex *resultIndex,
MSG_ViewIndex *pThreadIndex, XP_Bool wrap = TRUE);
// Data navigate has no side effects - could be used to see if navigate
// is valid...
MsgERR DataNavigate(MessageKey startKey, MSG_MotionType motion,
MessageKey *pResultKey, MessageKey *pThreadKey);
MsgERR GetNavigateStatus(MSG_MotionType motion, MSG_ViewIndex index,
XP_Bool *selectable_p,
const char **display_string);
MsgERR FindNextUnread(MessageKey startId, MessageKey *resultId,
MessageKey *resultThreadId);
MsgERR FindPrevUnread(MessageKey startKey, MessageKey *pResultKey,
MessageKey *resultThreadId = NULL);
MsgERR FindFirstFlagged(MSG_ViewIndex * pResultIndex);
MsgERR FindPrevFlagged(MSG_ViewIndex startIndex, MSG_ViewIndex *pResultIndex);
MsgERR FindNextFlagged(MSG_ViewIndex startIndex, MSG_ViewIndex *pResultIndex);
MsgERR FindFirstNew(MSG_ViewIndex *pResultIndex);
// view modifications methods by index
MsgERR ToggleReadByIndex(MSG_ViewIndex index);
MsgERR SetReadByIndex(MSG_ViewIndex index, XP_Bool read);
MsgERR SetThreadOfMsgReadByIndex(MSG_ViewIndex index, XP_Bool read);
MsgERR ToggleThreadIgnored(DBThreadMessageHdr *thread, MSG_ViewIndex index);
MsgERR SetThreadIgnored(DBThreadMessageHdr *thread, MSG_ViewIndex index,
XP_Bool ignored);
MsgERR MarkMarkedByIndex(MSG_ViewIndex index, XP_Bool mark);
MsgERR ToggleThreadWatched(DBThreadMessageHdr *thread, MSG_ViewIndex index);
MsgERR SetThreadWatched(DBThreadMessageHdr *thread, MSG_ViewIndex index,
XP_Bool watched);
MsgERR SetKeyByIndex(MSG_ViewIndex index, MessageKey id);
virtual MsgERR RemoveByIndex(MSG_ViewIndex index);
MsgERR InsertByIndex(MSG_ViewIndex index, MessageKey id);
MsgERR DeleteMessagesByIndex(MSG_ViewIndex *indices, int32 numIndices, XP_Bool removeFromDB);
virtual MsgERR DeleteMsgByIndex(MSG_ViewIndex index, XP_Bool removeFromDB);
/* these are the old methods....delete these once everyone in Nova is using the new address book */
MsgERR AddSenderToABByIndex(MWContext* context, MSG_ViewIndex index, XP_Bool lastOneToAdd, XP_Bool displayRecip);
MsgERR AddAllToABByIndex(MWContext* context, MSG_ViewIndex index, XP_Bool lastOneToAdd);
/* new address book APIs require a destination container */
MsgERR AddSenderToABByIndex(MSG_Pane * pane, MWContext* context, MSG_ViewIndex index, XP_Bool lastOneToAdd, XP_Bool displayRecip, AB_ContainerInfo * destAB);
MsgERR AddAllToABByIndex(MSG_Pane * pane, MWContext* context, MSG_ViewIndex index, XP_Bool lastOneToAdd, AB_ContainerInfo * destAB);
// view modifications methods by ID - returned index can be useful to
// caller.
MsgERR SetReadByID(MessageKey id, XP_Bool read, MSG_ViewIndex* pIndex);
MsgERR InsertByID(MessageKey id, MessageKey newId, MSG_ViewIndex* pIndex);
// make sure the passed key is "in" the view (e.g., for a threaded sort, this
// may just mean the parent thread is in the view).
virtual void EnsureListed(MessageKey key);
void EnableChangeUpdates();
void DisableChangeUpdates();
void NoteChange(MSG_ViewIndex firstlineChanged, int numChanged,
MSG_NOTIFY_CODE changeType);
void NoteStartChange(MSG_ViewIndex firstlineChanged, int numChanged,
MSG_NOTIFY_CODE changeType);
void NoteEndChange(MSG_ViewIndex firstlineChanged, int numChanged,
MSG_NOTIFY_CODE changeType);
// array accessors
MessageKey GetAt(MSG_ViewIndex index) ;
MSG_ViewIndex FindViewIndex(MessageKey key)
{return (MSG_ViewIndex) (m_idArray.FindIndex(key));}
virtual MSG_ViewIndex FindKey(MessageKey key, XP_Bool expand);
int GetSize(void) {return(m_idArray.GetSize());}
virtual MsgViewIndex GetThreadFromMsgIndex(MsgViewIndex index,
DBThreadMessageHdr **threadHdr);
virtual MSG_ViewIndex ThreadIndexOfMsg(MessageKey msgKey,
MSG_ViewIndex msgIndex = kViewIndexNone,
int32 *pThreadCount = NULL,
uint32 *pFlags = NULL);
// public methods dealing with sorting
virtual MsgERR Sort(SortType sortType, SortOrder sortOrder);
virtual MsgERR ExternalSort(SortType sort_key,
XP_Bool sort_forward_p);
SortType GetSortType(void) {return(m_sortType);}
SortOrder GetSortOrder(void) {return m_sortOrder;}
enum eFieldType {
kString,
kU16,
kU32
};
MSG_ViewIndex GetInsertIndex(DBMessageHdr *msgHdr);
// methods dealing with view flags
virtual MsgERR OrExtraFlag(MSG_ViewIndex index, char orflag);
virtual MsgERR AndExtraFlag(MSG_ViewIndex index, char andflag);
virtual MsgERR SetExtraFlag(MSG_ViewIndex index, char setflag);
virtual MsgERR GetExtraFlag(MSG_ViewIndex, char *extraFlag);
virtual void SetExtraFlagsFromDBFlags(uint32 messageFlags,
MSG_ViewIndex index);
static void CopyExtraFlagsToDBFlags(char flags,
uint32 *messageFlags);
static void CopyDBFlagsToExtraFlags(uint32 messageFlags,
char *extraFlags);
static void CopyExtraFlagsToPublicFlags(char flags,
uint32 *messageFlags);
virtual XPByteArray *GetFlagsArray() {return &m_flags;}
int32 AddReference ();
protected:
static void InitNavigateCommands();
virtual void OnHeaderAddedOrDeleted() {}
virtual void OnExtraFlagChanged(MSG_ViewIndex /*index*/, char /*extraFlag*/) {}
virtual XP_Bool IsValidIndex(MSG_ViewIndex index);
virtual MSG_ViewIndex GetIndexOfFirstDisplayedKeyInThread(DBThreadMessageHdr *threadHdr);
virtual DBMessageHdr *GetFirstDisplayedHdrInThread(DBThreadMessageHdr *threadHdr);
virtual DBMessageHdr *GetFirstMessageHdrToDisplayInThread(DBThreadMessageHdr *threadHdr);
virtual int32 CountExpandedThread(MSG_ViewIndex index);
virtual MsgERR MarkThreadOfMsgRead(MessageKey msgId, MSG_ViewIndex msgIndex,
XP_Bool bRead);
virtual MsgERR MarkThreadRead(DBThreadMessageHdr *threadHdr,
MSG_ViewIndex threadIndex, XP_Bool bRead);
virtual MsgERR SortInternal(SortType sortType, SortOrder sortOrder);
void ReverseSort();
virtual MsgERR ReverseThreads();
// helper routines for internal sort
char *GetStringField(DBMessageHdr *msgHdr, SortType sortType, int16 csid, XPStringObj &string);
uint32 GetLongField(DBMessageHdr *msgHdr, SortType sortType);
eFieldType GetFieldTypeAndLenForSort(SortType sortType, uint16 *pMaxLen);
uint32 GetStatusSortValue(DBMessageHdr *msgHdr);
static MessageDBView *CacheLookup (MessageDB *, ViewType);
static XP_List *m_viewCache;
void CacheAdd ();
void CacheRemove ();
virtual ~MessageDBView();
int32 m_refCount;
protected:
static uint32 m_publicEquivOfExtraFlags;
SortType m_sortType;
SortOrder m_sortOrder;
ViewType m_viewType;
ViewFlags m_viewFlags;
IDArray m_idArray;
XPByteArray m_flags;
XPByteArray m_levels;
MessageDB *m_messageDB;
ViewChangeListener m_changeListener;
XP_Bool m_sortValid; // has id array been added to since we sorted?
} ;
#endif