зеркало из https://github.com/mozilla/pjs.git
379 строки
17 KiB
C++
379 строки
17 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 _MsgDB_H_
|
|
#define _MsgDB_H_
|
|
|
|
#include "msgcom.h"
|
|
#include "ptrarray.h"
|
|
#include "dberror.h"
|
|
#include "chngntfy.h"
|
|
#include "msgdbtyp.h"
|
|
|
|
class MessageDB;
|
|
class MsgDocument;
|
|
class DBFolderInfo;
|
|
class MailDB;
|
|
class NewsGroupDB;
|
|
class XPByteArray;
|
|
class msg_NewsArtSet;
|
|
class XPStringObj;
|
|
|
|
const int kMaxSubject = 160;
|
|
const int kMaxAuthor = 160;
|
|
const int kMaxRecipient = 80;
|
|
const int kMaxMsgIdLen = 80;
|
|
const int kMaxReferenceLen = 10 * kMaxMsgIdLen;
|
|
|
|
const MessageKey kIdNone = 0xffffffff;
|
|
const MessageKey kIdPending = 0xfffffffe;
|
|
const MessageKey kIdStartOfFake = 0xffffff80; // start of the fake message id
|
|
|
|
#include "idarray.h" // need MessageKey to be defined before including...
|
|
|
|
struct ListContext
|
|
{
|
|
MessageDB *m_pMessageDB;
|
|
int m_curMessageNum;
|
|
MSG_IteratorHandle m_iterator;
|
|
};
|
|
|
|
struct MessageHdrStruct
|
|
{
|
|
MessageKey m_threadId;
|
|
MessageKey m_messageKey;
|
|
char m_subject[kMaxSubject];
|
|
char m_author[kMaxAuthor];
|
|
char m_messageId[kMaxMsgIdLen];
|
|
char m_references[kMaxReferenceLen];
|
|
char m_recipients[kMaxRecipient];
|
|
time_t m_date;
|
|
uint32 m_messageSize; // lines for news articles, bytes for mail messages
|
|
uint32 m_flags;
|
|
uint16 m_numChildren; // for top-level threads
|
|
uint16 m_numNewChildren; // for top-level threads
|
|
char m_level; // indentation level
|
|
MSG_PRIORITY m_priority;
|
|
public:
|
|
void SetSubject(const char * subject);
|
|
void SetAuthor(const char * author);
|
|
void SetMessageID(const char * msgID);
|
|
void SetReferences(const char * referencesStr);
|
|
void SetDate(const char * date);
|
|
void SetLines(uint32 lines);
|
|
void SetSize(uint32 size);
|
|
const char *GetReference(const char *nextRef, char *reference);
|
|
static void StripMessageId(const char *msgID, char *outMsgId, int msgIdLen);
|
|
};
|
|
|
|
typedef int32 MsgFlags; // try to keep flags view is going to care about
|
|
// in the first byte, so we can copy the flags over directly
|
|
|
|
const int32 kIsRead = 0x1; // same as MSG_FLAG_READ
|
|
const int32 kReplied = 0x2; // same as MSG_FLAG_REPLIED
|
|
const int32 kMsgMarked = 0x4; // same as MSG_FLAG_MARKED - (kMarked collides with IMAP)
|
|
const int32 kHasChildren = 0x8; // no equivalent (shares space with FLAG_EXPUNGED)
|
|
const int32 kIsThread = 0x10; // !!shares space with MSG_FLAG_HAS_RE
|
|
const int32 kElided = 0x20; // same as MSG_FLAG_ELIDED
|
|
const int32 kExpired = 0x40; // same as MSG_FLAG_EXPIRED
|
|
const int32 kOffline = 0x80; // this message has been downloaded
|
|
const int32 kWatched = 0x100;
|
|
const int32 kSenderAuthed = 0x200; // same as MSG_FLAG_SENDER_AUTHED
|
|
const int32 kExpunged = 0x400; // NOT same value as MSG_FLAG_EXPUNGED
|
|
const int32 kHasRe = 0x800; // Not same values as MSG_FLAG_HAS_RE
|
|
const int32 kForwarded = 0x1000; // this message has been forward (mail only)
|
|
const int32 kIgnored = 0x2000; // this message is ignored
|
|
|
|
const int32 kMDNNeeded = 0x4000; // this message needs MDN report
|
|
const int32 kMDNSent = 0x8000; // MDN report has been Sent
|
|
|
|
const int32 kNew = 0x10000; // used for status, never stored in db.
|
|
const int32 kAdded = 0x20000; // Just added to db - used in
|
|
// notifications, never set in msgHdr.
|
|
|
|
const int32 kTemplate = 0x40000; // this message is a template
|
|
|
|
const int32 kDirty = 0x80000;
|
|
const int32 kPartial = 0x100000; // NOT same value as MSG_FLAG_PARTIAL
|
|
const int32 kIMAPdeleted = 0x200000; // same value as MSG_FLAG_IMAP_DELETED
|
|
const int32 kHasAttachment = 0x10000000; // message has attachments
|
|
|
|
const int32 kSameAsMSG_FLAG = kHasAttachment|kIsRead|kMsgMarked|kExpired|kElided|kSenderAuthed|kReplied|kOffline|kForwarded|kWatched|kIMAPdeleted;
|
|
const int32 kMozillaSameAsMSG_FLAG = kIsRead|kMsgMarked|kExpired|kElided|kSenderAuthed|kReplied|kOffline|kForwarded|kWatched|kIMAPdeleted;
|
|
const int32 kExtraFlags = 0xFF;
|
|
|
|
|
|
class MessageDBArray : public XPPtrArray
|
|
{
|
|
public:
|
|
MessageDBArray();
|
|
|
|
// overrides with proper types to avoid casting
|
|
MessageDB* GetAt(int nIndex) const {return((MessageDB*)XPPtrArray::GetAt(nIndex));}
|
|
void* operator[](int nIndex) const {return((MessageDB*)XPPtrArray::operator[](nIndex));}
|
|
};
|
|
|
|
|
|
#include "msghdr.h"
|
|
|
|
class DBThreadMessageHdr;
|
|
class DBMessageHdr;
|
|
|
|
typedef XP_Bool
|
|
HdrCompareFunc (DBMessageHdr *hdr);
|
|
|
|
// the DB doing threading, partly because we want it to be persistent,
|
|
// to avoid rethreading everytime a group is opened.
|
|
class MessageDB : public ChangeAnnouncer
|
|
{
|
|
friend class MessageDBView;
|
|
friend class DBThreadMessageHdr;
|
|
public:
|
|
MessageDB();
|
|
virtual ~MessageDB();
|
|
virtual MsgERR OpenDB(const char *dbFileName, XP_Bool create);
|
|
virtual MsgERR MessageDBOpen(const char * dbName, XP_Bool create);
|
|
|
|
virtual MsgERR Close();
|
|
virtual MsgERR ForceClosed();
|
|
virtual MsgERR CloseDB();
|
|
virtual MsgERR OnNewPath (const char * /*path*/) ;
|
|
static MsgERR RenameDB(const char *sourceName, const char *destName);
|
|
virtual MsgERR SetSummaryValid(XP_Bool valid = TRUE);
|
|
|
|
virtual MsgERR Commit(XP_Bool compress = FALSE);
|
|
|
|
virtual MsgERR GetMessageHdr(MessageKey messageNum, MessageHdrStruct *);
|
|
virtual MsgERR GetShortMessageHdr(MessageKey messageNum, MSG_MessageLine *msgHdr);
|
|
|
|
virtual XP_Bool KeyToAddExists(MessageKey messageKey);
|
|
|
|
virtual MsgERR AddHeaderToArray(DBMessageHdr *header);
|
|
virtual MsgERR AddHdr(DBMessageHdr *hdr);
|
|
virtual MsgERR AddHdrToDB(DBMessageHdr *newHdr, XP_Bool *newThread,
|
|
XP_Bool notify = FALSE);
|
|
virtual MsgERR AddThread(DBMessageHdr *msgHdr);
|
|
virtual DBThreadMessageHdr *GetDBThreadHdrForSubject(DBMessageHdr *msgHdr);
|
|
virtual DBThreadMessageHdr *GetDBMsgHdrForReference(const char * msgID);
|
|
virtual DBMessageHdr * GetDBMessageHdrForID(const char * msgID);
|
|
virtual MsgERR GetHeaderFromHandle(MSG_HeaderHandle headerHandle, DBMessageHdr **pResult);
|
|
DBThreadMessageHdr *GetThreadHeaderFromHandle(MSG_ThreadHandle handle);
|
|
|
|
virtual MessageKey GetMessageKeyForID(const char *msgID);
|
|
virtual DBThreadMessageHdr *GetDBThreadHdrForMsgID(MessageKey messageKey);
|
|
virtual MessageKey GetThreadIdForMsgId(MessageKey messageKey);
|
|
virtual MsgERR AddToThread(DBMessageHdr *reply, DBThreadMessageHdr *threadHdr, XP_Bool threadInThread);
|
|
// we've finished receiving new headers - clean up any temporary info.
|
|
virtual MsgERR FinishAddingHeaders();
|
|
// given an array of thread ids, return list header information for each thread
|
|
MsgERR ListHeaders(MessageKey *pMessageNums, int numToList, MessageHdrStruct *pOutput, int *pNumListed);
|
|
MsgERR ListHeadersShort(MessageKey *pMessageNums, int numToList, MSG_MessageLine *pOutput, int *pNumListed);
|
|
// list the headers of the top-level thread ids
|
|
virtual MsgERR ListThreadIds(MessageKey *startMsg, XP_Bool unreadOnly, MessageKey *pOutput, int32 *pFlags,
|
|
char *pLevels, int numToList, int *numListed, MessageDBView *view, int32 *pTotalHeaders);
|
|
virtual MsgERR ListThreadIds(ListContext *context, MessageKey *pOutput, int numToList, int *numListed);
|
|
// Info about a given thread
|
|
virtual MsgERR GetThreadCount(MessageKey messageKey, int32 *pThreadCount);
|
|
virtual MsgERR GetThreadCount(DBThreadMessageHdr *threadHdr, int32 *pThreadCount);
|
|
virtual MsgERR GetDBThreadListContext(MessageKey threadId, MessageKey startMsg, DBThreadMessageHdr **pThreadHdr, uint16 *pThreadIndex);
|
|
virtual MsgERR GetDBThreadListContext(DBMessageHdr *msgHdr, MessageKey startMsg, DBThreadMessageHdr **pThreadHdr, uint16 *pThreadIndex);
|
|
virtual DBThreadMessageHdr * GetDBThreadHdrForThreadID(MessageKey messageID);
|
|
virtual DBMessageHdr *GetDBHdrForKey(MessageKey messageKey);
|
|
virtual DBThreadMessageHdr *GetDBThreadHdrForMsgHdr(DBMessageHdr *msgHdr);
|
|
virtual MessageKey GetKeyOfFirstMsgInThread(MessageKey key);
|
|
|
|
// return a flat list of ids (no threading)
|
|
MsgERR ListAllIds(IDArray &outputIds);
|
|
MsgERR ListAllIds(IDArray *outputIds);
|
|
// iterate through message headers, in no particular order (currently, id order).
|
|
// Caller must unrefer return DBMessageHdr when done with it.
|
|
// eDBEndOfList will be returned when return DBMessageHdr * is NULL.
|
|
// Caller must call ListDone to free up the context.
|
|
// ListLast will produce a reverse iterator that starts at the end and moves towards the start
|
|
MsgERR ListFirst(ListContext **pContext, DBMessageHdr **pResult);
|
|
MsgERR ListLast(ListContext **pContext, DBMessageHdr **pResult);
|
|
MsgERR ListNext(ListContext *pContext, DBMessageHdr **pResult);
|
|
MsgERR ListDone(ListContext *pContext);
|
|
|
|
MessageKey ListHighwaterMark(); // returns the biggest key, kIdNone if none found.
|
|
// return the list header information for the documents in a thread.
|
|
virtual MsgERR ListIdsInThread(MessageKey threadId, MessageKey *startMsg, int numToList, MessageKey *pOutput, char *pFlags, char *pLevels, int *pNumListed);
|
|
virtual MsgERR ListIdsInThread(DBMessageHdr *msgHdr, MessageKey *startMsg, int numToList, MessageKey *pOutput, char *pFlags, char *pLevels, int *pNumListed);
|
|
virtual MsgERR ListIdsInThread(DBThreadMessageHdr *threadHdr, uint16 threadIndex, MessageKey *startMsg, int numToList, MessageKey *pOutput, char *pFlags, char *pLevels, int *pNumListed);
|
|
virtual MsgERR ListUnreadIdsInThread(MessageKey threadId, MessageKey *startMsg, XPByteArray &levelStack, int numToList, MessageKey *pOutput, char *pFlags, char *pLevels, int *pNumListed);
|
|
virtual MsgERR ListNextUnread(ListContext **pContext, DBMessageHdr **pResult);
|
|
|
|
static XP_Bool MatchFlaggedNotOffline(DBMessageHdr *hdr);
|
|
virtual void ListMatchingKeys(HdrCompareFunc *compareFunc, IDArray &matchingKeys);
|
|
MsgERR Purge();
|
|
|
|
// MDN support
|
|
virtual MsgERR MarkMDNNeeded(MessageKey messageKey, XP_Bool bNeeded,
|
|
ChangeListener *instigator = NULL);
|
|
// MarkMDNneeded only used when mail server is a POP3 server
|
|
// or when the IMAP server does not support user defined
|
|
// PERMANENTFLAGS
|
|
virtual MsgERR IsMDNNeeded(MessageKey messageKey, XP_Bool *isNeeded);
|
|
|
|
virtual MsgERR MarkMDNSent(MessageKey messageKey, XP_Bool bNeeded,
|
|
ChangeListener *instigator = NULL);
|
|
virtual MsgERR IsMDNSent(MessageKey messageKey, XP_Bool *isSent);
|
|
|
|
// methods to get and set docsets for ids.
|
|
virtual MsgERR MarkRead(MessageKey messageKey, XP_Bool bRead,
|
|
ChangeListener *instigator = NULL);
|
|
|
|
virtual MsgERR MarkReplied(MessageKey messageKey, XP_Bool bReplied,
|
|
ChangeListener *instigator = NULL);
|
|
|
|
virtual MsgERR MarkForwarded(MessageKey messageKey, XP_Bool bForwarded,
|
|
ChangeListener *instigator = NULL);
|
|
|
|
virtual MsgERR MarkHasAttachments(MessageKey messageKey, XP_Bool bHasAttachments,
|
|
ChangeListener *instigator = NULL);
|
|
|
|
virtual MsgERR MarkThreadIgnored(DBThreadMessageHdr *thread, MessageKey threadKey, XP_Bool bIgnored,
|
|
ChangeListener *instigator = NULL);
|
|
virtual MsgERR MarkThreadWatched(DBThreadMessageHdr *thread, MessageKey threadKey, XP_Bool bWatched,
|
|
ChangeListener *instigator = NULL);
|
|
virtual MsgERR IsRead(MessageKey messageKey, XP_Bool *pRead);
|
|
virtual MsgERR IsIgnored(MessageKey messageKey, XP_Bool *pIgnored);
|
|
virtual MsgERR IsMarked(MessageKey messageKey, XP_Bool *pMarked);
|
|
virtual MsgERR HasAttachments(MessageKey messageKey, XP_Bool *pHasThem);
|
|
virtual MsgERR DeleteMessages(IDArray &messageKeys, ChangeListener *instigator);
|
|
virtual MsgERR DeleteMessage(MessageKey messageKey,
|
|
ChangeListener *instigator = NULL,
|
|
XP_Bool commit = TRUE);
|
|
virtual MsgERR DeleteHeader(DBMessageHdr *msgHdr, ChangeListener *instigator, XP_Bool commit, XP_Bool onlyRemoveFromThread = FALSE);
|
|
virtual MsgERR UndoDelete(DBMessageHdr *msgHdr);
|
|
virtual MsgERR MarkLater(MessageKey messageKey, time_t until);
|
|
virtual MsgERR MarkMarked(MessageKey messageKey, XP_Bool mark,
|
|
ChangeListener *instigator = NULL);
|
|
virtual MsgERR MarkOffline(MessageKey messageKey, XP_Bool offline,
|
|
ChangeListener *instigator);
|
|
virtual XP_Bool AllMessageKeysImapDeleted(const IDArray &keys);
|
|
virtual MsgERR MarkImapDeleted(MessageKey messageKey, XP_Bool deleted,
|
|
ChangeListener *instigator);
|
|
|
|
virtual void RemoveHeaderFromDB(DBMessageHdr *msgHdr);
|
|
|
|
virtual MsgERR GetUnreadKeyInThread(MessageKey threadId,
|
|
MessageKey *resultKey,
|
|
MessageKey *resultThreadId);
|
|
|
|
virtual MsgERR MarkReadByDate (time_t startDate, time_t endDate, MWContext *context, IDArray *markedIds);
|
|
virtual MsgERR MarkAllRead(MWContext *context, IDArray *thoseMarked = NULL);
|
|
virtual XP_Bool SetPriority(MessageKey messageKey, MSG_PRIORITY priority);
|
|
virtual XP_Bool SetPriority(DBMessageHdr *msgHdr, MSG_PRIORITY priority);
|
|
|
|
void SetSortInfo(SortType, SortOrder);
|
|
MsgERR GetSortInfo(SortType *, SortOrder *);
|
|
|
|
virtual void HandleLatered(); // mark latered documents unread
|
|
|
|
// methods to handle new message support
|
|
MessageKey GetFirstNew();
|
|
void AddToNewList(MessageKey key);
|
|
XP_Bool HasNew();
|
|
void ClearNewList(XP_Bool notify = FALSE);
|
|
|
|
MessageKey GetUnusedFakeId();
|
|
|
|
DBFolderInfo *m_dbFolderInfo;
|
|
MSG_DBHandle GetDB() {return m_dbHandle;}
|
|
|
|
// typesafe downcasts for db's
|
|
virtual MailDB *GetMailDB(); // returns NULL if not a mail db
|
|
virtual NewsGroupDB *GetNewsDB(); // returns NULL if not a news db
|
|
|
|
virtual MSG_FolderInfo *GetFolderInfo();
|
|
void SetFolderInfo(MSG_FolderInfo *info) {m_folderInfo = info;}
|
|
|
|
virtual int GetCurVersion() {return 0;}
|
|
DBFolderInfo *GetDBFolderInfo() {return m_dbFolderInfo;}
|
|
int AddUseCount() {return ++m_useCount;}
|
|
|
|
static void ConvertDBFlagsToPublicFlags(uint32 *flags);
|
|
static void ConvertPublicFlagsToDBFlags(uint32 *flags);
|
|
|
|
static MessageDB* FindInCache(const char * pDBName);
|
|
static void CopyFullHdrToShortHdr(MSG_MessageLine *msgHdr,
|
|
MessageHdrStruct *fullHdr);
|
|
static void CleanupCache();
|
|
#ifdef DEBUG
|
|
static int GetNumInCache(void) {return(GetDBCache()->GetSize());}
|
|
static void DumpCache();
|
|
#endif
|
|
ViewType GetViewType();
|
|
void SetViewType(ViewType viewType);
|
|
uint32 GetStatusFlags(DBMessageHdr *msgHdr);
|
|
#ifdef DEBUG_bienvenu
|
|
void Verify();
|
|
#endif
|
|
virtual MsgERR MarkHdrRead(DBMessageHdr *msgHdr, XP_Bool bRead,
|
|
ChangeListener *instigator);
|
|
|
|
virtual MsgERR GetCachedPassword(XPStringObj &cachedPassword);
|
|
virtual MsgERR SetCachedPassword(const char *password);
|
|
virtual XP_Bool HasCachedPassword();
|
|
protected:
|
|
virtual MsgERR SetKeyFlag(MessageKey messageKey, XP_Bool set, int32 flag,
|
|
ChangeListener *instigator /* = NULL */);
|
|
virtual void SetHdrFlag(DBMessageHdr *, XP_Bool bSet, MsgFlags flag);
|
|
virtual void MarkHdrReadInDB(DBMessageHdr *msgHdr, XP_Bool bRead,
|
|
ChangeListener *instigator);
|
|
|
|
virtual DBFolderInfo *CreateFolderInfo(MSG_DBFolderInfoHandle handle);
|
|
virtual MsgERR IsHeaderRead(DBMessageHdr *hdr, XP_Bool *pRead);
|
|
|
|
XP_Bool MatchDbName(const char * dbName); // returns TRUE if they match
|
|
DBFolderInfo *AddNewFolderInfoToDB();
|
|
// helper function for creating iterators;
|
|
MsgERR CreateListIterator(XP_Bool forward, ListContext **pContext, DBMessageHdr **pResult);
|
|
MsgERR GetMessageIndexInThread(DBThreadMessageHdr *threadHdr, MessageKey startMsg, uint16 *pThreadIndex);
|
|
protected:
|
|
MSG_DBHandle m_dbHandle;
|
|
MSG_DBFolderInfoHandle m_dbFolderInfoHandle;
|
|
MSG_IteratorHandle m_threadIterator;
|
|
char *m_dbName;
|
|
int m_useCount;
|
|
MSG_FolderInfo *m_folderInfo;
|
|
XPPtrArray m_newHeaders; // array of DBMessageHdr *
|
|
int m_headerIndex; // index of last header added to m_newHeaders
|
|
int32 m_addCount; // how many added since last commit
|
|
int32 m_commitChunk; // how many to add before committing
|
|
|
|
IDArray m_lockedKeys;
|
|
msg_NewsArtSet *m_newSet; // new messages since last open.
|
|
// static message db cache functions - perhaps overlaps with URL caching
|
|
// since we can open message dbs without opening a UI on the message db,
|
|
// or have two ui widgets open the same db.
|
|
static MessageDBArray *m_dbCache; // array of messageDB's
|
|
static XP_Bool m_cacheEnabled;
|
|
|
|
static void AddToCache(MessageDB* pMessageDB)
|
|
{GetDBCache()->Add(pMessageDB);}
|
|
static void RemoveFromCache(MessageDB* pMessageDB);
|
|
static int FindInCache(MessageDB* pMessageDB);
|
|
static XP_Bool EnableCache(XP_Bool enable);
|
|
static XP_Bool IsCacheEnabled(void) {return(m_cacheEnabled);}
|
|
static MessageDBArray* GetDBCache();
|
|
};
|
|
|
|
#endif
|