summaryrefslogtreecommitdiffstats
path: root/mailnews/local/src/nsLocalMailFolder.h
blob: 1ed964b1605f7c185166b5dec935440f0b625c28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
/* -*- 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/. */

/**
   Interface for representing Local Mail folders.
*/

#ifndef nsMsgLocalMailFolder_h__
#define nsMsgLocalMailFolder_h__

#include "mozilla/Attributes.h"
#include "nsMsgDBFolder.h" /* include the interface we are going to support */
#include "nsAutoPtr.h"
#include "nsICopyMessageListener.h"
#include "nsIFileStreams.h"
#include "nsIPop3IncomingServer.h"  // need this for an interface ID
#include "nsMsgTxn.h"
#include "nsIMsgMessageService.h"
#include "nsIMsgParseMailMsgState.h"
#include "nsITransactionManager.h"
#include "nsIMsgLocalMailFolder.h"
#include "nsISeekableStream.h"
#include "nsIMutableArray.h"
#include "nsLocalUndoTxn.h"

#define COPY_BUFFER_SIZE 16384

class nsParseMailMessageState;

struct nsLocalMailCopyState
{
  nsLocalMailCopyState();
  virtual ~nsLocalMailCopyState();
  
  nsCOMPtr <nsIOutputStream> m_fileStream;
  nsCOMPtr<nsIMsgPluggableStore> m_msgStore;
  nsCOMPtr<nsISupports> m_srcSupport;
  /// Source nsIMsgDBHdr instances.
  nsCOMPtr<nsIArray> m_messages;
  /// Destination nsIMsgDBHdr instances.
  nsCOMPtr<nsIMutableArray> m_destMessages;
  RefPtr<nsLocalMoveCopyMsgTxn> m_undoMsgTxn;
  nsCOMPtr<nsIMsgDBHdr> m_message; // current copy message
  nsMsgMessageFlagType m_flags; // current copy message flags
  RefPtr<nsParseMailMessageState> m_parseMsgState;
  nsCOMPtr<nsIMsgCopyServiceListener> m_listener;
  nsCOMPtr<nsIMsgWindow> m_msgWindow;
  nsCOMPtr<nsIMsgDatabase> m_destDB;

  // for displaying status;
  nsCOMPtr <nsIMsgStatusFeedback> m_statusFeedback;
  nsCOMPtr <nsIStringBundle> m_stringBundle;
  int64_t m_lastProgressTime;

  nsMsgKey m_curDstKey;
  uint32_t m_curCopyIndex;
  nsCOMPtr <nsIMsgMessageService> m_messageService;
  /// The number of messages in m_messages.
  uint32_t m_totalMsgCount;
  char *m_dataBuffer;
  uint32_t m_dataBufferSize;
  uint32_t m_leftOver;
  bool m_isMove;
  bool m_isFolder;   // isFolder move/copy
  bool m_dummyEnvelopeNeeded;
  bool m_copyingMultipleMessages;
  bool m_fromLineSeen;
  bool m_allowUndo;
  bool m_writeFailed;
  bool m_notifyFolderLoaded;
  bool m_wholeMsgInStream;
  nsCString    m_newMsgKeywords;
  nsCOMPtr <nsIMsgDBHdr> m_newHdr;
};

struct nsLocalFolderScanState
{
  nsLocalFolderScanState();
  ~nsLocalFolderScanState();

  nsCOMPtr<nsIInputStream> m_inputStream;
  nsCOMPtr<nsISeekableStream> m_seekableStream;
  nsCOMPtr<nsIMsgPluggableStore> m_msgStore;
  nsCString m_header;
  nsCString m_accountKey;
  const char *m_uidl; // memory is owned by m_header
  // false if we need a new input stream for each message
  bool m_streamReusable;
};

class nsMsgLocalMailFolder : public nsMsgDBFolder,
                             public nsIMsgLocalMailFolder,
                             public nsICopyMessageListener
{
public:
  nsMsgLocalMailFolder(void);
  NS_DECL_NSICOPYMESSAGELISTENER
  NS_DECL_NSIMSGLOCALMAILFOLDER
  NS_DECL_NSIJUNKMAILCLASSIFICATIONLISTENER
  NS_DECL_ISUPPORTS_INHERITED
  // nsIRDFResource methods:
  NS_IMETHOD Init(const char *aURI) override;

  // nsIUrlListener methods
  NS_IMETHOD OnStartRunningUrl(nsIURI * aUrl) override;
  NS_IMETHOD OnStopRunningUrl(nsIURI * aUrl, nsresult aExitCode) override;

  // nsIMsgFolder methods:
  NS_IMETHOD GetSubFolders(nsISimpleEnumerator* *aResult) override;
  NS_IMETHOD GetMsgDatabase(nsIMsgDatabase **aMsgDatabase) override;

  NS_IMETHOD OnAnnouncerGoingAway(nsIDBChangeAnnouncer *instigator) override;
  NS_IMETHOD GetMessages(nsISimpleEnumerator **result) override;
  NS_IMETHOD UpdateFolder(nsIMsgWindow *aWindow) override;

  NS_IMETHOD CreateSubfolder(const nsAString& folderName ,nsIMsgWindow *msgWindow) override;

  NS_IMETHOD Compact(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow) override;
  NS_IMETHOD CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, bool aCompactOfflineAlso) override;
  NS_IMETHOD EmptyTrash(nsIMsgWindow *msgWindow, nsIUrlListener *aListener) override;
  NS_IMETHOD DeleteSubFolders(nsIArray *folders, nsIMsgWindow *msgWindow) override;
  NS_IMETHOD CreateStorageIfMissing(nsIUrlListener* urlListener) override;
  NS_IMETHOD Rename (const nsAString& aNewName, nsIMsgWindow *msgWindow) override;
  NS_IMETHOD RenameSubFolders (nsIMsgWindow *msgWindow, nsIMsgFolder *oldFolder) override;

  NS_IMETHOD GetPrettyName(nsAString& prettyName) override; // Override of the base, for top-level mail folder
  NS_IMETHOD SetPrettyName(const nsAString& aName) override;

  NS_IMETHOD GetFolderURL(nsACString& url) override;

  NS_IMETHOD GetManyHeadersToDownload(bool *retval) override;

  NS_IMETHOD GetDeletable (bool *deletable) override;
  NS_IMETHOD GetSizeOnDisk(int64_t *size) override;

  NS_IMETHOD GetDBFolderInfoAndDB(nsIDBFolderInfo **folderInfo, nsIMsgDatabase **db) override;

  NS_IMETHOD DeleteMessages(nsIArray *messages, 
                      nsIMsgWindow *msgWindow, bool
                      deleteStorage, bool isMove,
                      nsIMsgCopyServiceListener* listener, bool allowUndo) override;
  NS_IMETHOD CopyMessages(nsIMsgFolder *srcFolder, nsIArray* messages,
                          bool isMove, nsIMsgWindow *msgWindow,
                          nsIMsgCopyServiceListener* listener, bool isFolder, bool allowUndo) override;
  NS_IMETHOD CopyFolder(nsIMsgFolder *srcFolder, bool isMoveFolder, nsIMsgWindow *msgWindow,
                          nsIMsgCopyServiceListener* listener) override;
  NS_IMETHOD CopyFileMessage(nsIFile* aFile, nsIMsgDBHdr* msgToReplace,
                             bool isDraftOrTemplate, 
                             uint32_t newMsgFlags,
                             const nsACString &aNewMsgKeywords,
                             nsIMsgWindow *msgWindow,
                             nsIMsgCopyServiceListener* listener) override;

  NS_IMETHOD AddMessageDispositionState(nsIMsgDBHdr *aMessage, nsMsgDispositionState aDispositionFlag) override;
  NS_IMETHOD MarkMessagesRead(nsIArray *aMessages, bool aMarkRead) override;
  NS_IMETHOD MarkMessagesFlagged(nsIArray *aMessages, bool aMarkFlagged) override;
  NS_IMETHOD MarkAllMessagesRead(nsIMsgWindow *aMsgWindow) override;
  NS_IMETHOD MarkThreadRead(nsIMsgThread *thread) override;
  NS_IMETHOD GetNewMessages(nsIMsgWindow *aWindow, nsIUrlListener *aListener) override;
  NS_IMETHOD NotifyCompactCompleted() override;
  NS_IMETHOD Shutdown(bool shutdownChildren) override;

  NS_IMETHOD WriteToFolderCacheElem(nsIMsgFolderCacheElement *element) override;
  NS_IMETHOD ReadFromFolderCacheElem(nsIMsgFolderCacheElement *element) override;

  NS_IMETHOD GetName(nsAString& aName) override;

  // Used when headers_only is TRUE
  NS_IMETHOD DownloadMessagesForOffline(nsIArray *aMessages, nsIMsgWindow *aWindow) override;
  NS_IMETHOD FetchMsgPreviewText(nsMsgKey *aKeysToFetch, uint32_t aNumKeys,
                                                 bool aLocalOnly, nsIUrlListener *aUrlListener, 
                                                 bool *aAsyncResults) override;
  NS_IMETHOD AddKeywordsToMessages(nsIArray *aMessages, const nsACString& aKeywords) override;
  NS_IMETHOD RemoveKeywordsFromMessages(nsIArray *aMessages, const nsACString& aKeywords) override;
  NS_IMETHOD GetIncomingServerType(nsACString& serverType) override;

protected:
  virtual ~nsMsgLocalMailFolder();
  nsresult CreateChildFromURI(const nsCString &uri, nsIMsgFolder **folder) override;
  nsresult CopyFolderAcrossServer(nsIMsgFolder *srcFolder, nsIMsgWindow *msgWindow,nsIMsgCopyServiceListener* listener);

  nsresult CreateSubFolders(nsIFile *path);
  nsresult GetTrashFolder(nsIMsgFolder** trashFolder);
  nsresult WriteStartOfNewMessage();

  // CreateSubfolder, but without the nsIMsgFolderListener notification
  nsresult CreateSubfolderInternal(const nsAString& folderName, nsIMsgWindow *msgWindow,
                                   nsIMsgFolder **aNewFolder);

  nsresult IsChildOfTrash(bool *result);
  nsresult RecursiveSetDeleteIsMoveTrash(bool bVal);
  nsresult ConfirmFolderDeletion(nsIMsgWindow *aMsgWindow, nsIMsgFolder *aFolder, bool *aResult);

  nsresult DeleteMessage(nsISupports *message, nsIMsgWindow *msgWindow,
                   bool deleteStorage, bool commit);
  nsresult GetDatabase() override;
  // this will set mDatabase, if successful. It will also create a .msf file
  // for an empty local mail folder. It will leave invalid DBs in place, and
  // return an error.
  nsresult OpenDatabase();

  // copy message helper
  nsresult DisplayMoveCopyStatusMsg();

  nsresult CopyMessageTo(nsISupports *message, nsIMsgFolder *dstFolder,
                         nsIMsgWindow *msgWindow, bool isMove);

  /**
   * Checks if there's room in the target folder to copy message(s) into.
   * If not, handles alerting the user, and sending the copy notifications.
   */
  bool CheckIfSpaceForCopy(nsIMsgWindow *msgWindow,
                             nsIMsgFolder *srcFolder,
                             nsISupports *srcSupports,
                             bool isMove,
                             int64_t totalMsgSize);

  // copy multiple messages at a time from this folder
  nsresult CopyMessagesTo(nsIArray *messages, nsTArray<nsMsgKey> &keyArray,
                                       nsIMsgWindow *aMsgWindow,
                                       nsIMsgFolder *dstFolder,
                                       bool isMove);
  nsresult InitCopyState(nsISupports* aSupport, nsIArray* messages,
                         bool isMove, nsIMsgCopyServiceListener* listener, nsIMsgWindow *msgWindow, bool isMoveFolder, bool allowUndo);
  nsresult InitCopyMsgHdrAndFileStream();
  // preserve message metadata when moving or copying messages
  void CopyPropertiesToMsgHdr(nsIMsgDBHdr *destHdr, nsIMsgDBHdr *srcHdr, bool isMove);
  virtual nsresult CreateBaseMessageURI(const nsACString& aURI) override;
  nsresult ChangeKeywordForMessages(nsIArray *aMessages, const nsACString& aKeyword, bool add);
  bool GetDeleteFromServerOnMove();
  void CopyHdrPropertiesWithSkipList(nsIMsgDBHdr *destHdr,
                                     nsIMsgDBHdr *srcHdr,
                                     const nsCString &skipList);
  nsresult FinishNewLocalMessage(nsIOutputStream *outputStream,
                                 nsIMsgDBHdr *newHdr,
                                 nsIMsgPluggableStore *msgStore,
                                 nsParseMailMessageState *parseMsgState);

protected:
  nsLocalMailCopyState *mCopyState; //We only allow one of these at a time
  nsCString mType;
  bool mHaveReadNameFromDB;
  bool mInitialized;
  bool mCheckForNewMessagesAfterParsing;
  bool m_parsingFolder;
  nsCOMPtr<nsIUrlListener> mReparseListener;
  nsTArray<nsMsgKey> mSpamKeysToMove;
  nsresult setSubfolderFlag(const nsAString& aFolderName, uint32_t flags);

  // state variables for DownloadMessagesForOffline

  // Do we notify the owning window of Delete's before or after
  // Adding the new msg?
#define DOWNLOAD_NOTIFY_FIRST 1
#define DOWNLOAD_NOTIFY_LAST  2

#ifndef DOWNLOAD_NOTIFY_STYLE
#define DOWNLOAD_NOTIFY_STYLE DOWNLOAD_NOTIFY_FIRST
#endif

  nsCOMArray<nsIMsgDBHdr> mDownloadMessages;
  nsCOMPtr<nsIMsgWindow> mDownloadWindow;
  nsMsgKey mDownloadSelectKey;
  uint32_t mDownloadState;
#define DOWNLOAD_STATE_NONE 0
#define DOWNLOAD_STATE_INITED 1
#define DOWNLOAD_STATE_GOTMSG 2
#define DOWNLOAD_STATE_DIDSEL 3

#if DOWNLOAD_NOTIFY_STYLE == DOWNLOAD_NOTIFY_LAST
  nsMsgKey mDownloadOldKey;
  nsMsgKey mDownloadOldParent;
  uint32_t mDownloadOldFlags;
#endif
};

#endif // nsMsgLocalMailFolder_h__