1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef nsMsgDBFolder_h__ 7 #define nsMsgDBFolder_h__ 8 9 #include "mozilla/Attributes.h" 10 #include "msgCore.h" 11 #include "nsIMsgFolder.h" 12 #include "nsIDBFolderInfo.h" 13 #include "nsIMsgDatabase.h" 14 #include "nsIMsgIncomingServer.h" 15 #include "nsCOMPtr.h" 16 #include "nsIDBChangeListener.h" 17 #include "nsIMsgPluggableStore.h" 18 #include "nsIURL.h" 19 #include "nsIFile.h" 20 #include "nsWeakReference.h" 21 #include "nsIWeakReferenceUtils.h" 22 #include "nsIMsgFilterList.h" 23 #include "nsIUrlListener.h" 24 #include "nsIMsgHdr.h" 25 #include "nsIOutputStream.h" 26 #include "nsITransport.h" 27 #include "nsIStringBundle.h" 28 #include "nsTObserverArray.h" 29 #include "nsCOMArray.h" 30 #include "nsMsgKeySet.h" 31 #include "nsMsgMessageFlags.h" 32 #include "nsIMsgFilterPlugin.h" 33 34 // We declare strings for folder properties and events. 35 // Properties: 36 extern const nsLiteralCString kBiffState; 37 extern const nsLiteralCString kCanFileMessages; 38 extern const nsLiteralCString kDefaultServer; 39 extern const nsLiteralCString kFlagged; 40 extern const nsLiteralCString kFolderFlag; 41 extern const nsLiteralCString kFolderSize; 42 extern const nsLiteralCString kIsDeferred; 43 extern const nsLiteralCString kIsSecure; 44 extern const nsLiteralCString kJunkStatusChanged; 45 extern const nsLiteralCString kKeywords; 46 extern const nsLiteralCString kMRMTimeChanged; 47 extern const nsLiteralCString kMsgLoaded; 48 extern const nsLiteralCString kName; 49 extern const nsLiteralCString kNewMailReceived; 50 extern const nsLiteralCString kNewMessages; 51 extern const nsLiteralCString kOpen; 52 extern const nsLiteralCString kSortOrder; 53 extern const nsLiteralCString kStatus; 54 extern const nsLiteralCString kSynchronize; 55 extern const nsLiteralCString kTotalMessages; 56 extern const nsLiteralCString kTotalUnreadMessages; 57 58 // Events: 59 extern const nsLiteralCString kAboutToCompact; 60 extern const nsLiteralCString kCompactCompleted; 61 extern const nsLiteralCString kDeleteOrMoveMsgCompleted; 62 extern const nsLiteralCString kDeleteOrMoveMsgFailed; 63 extern const nsLiteralCString kFiltersApplied; 64 extern const nsLiteralCString kFolderCreateCompleted; 65 extern const nsLiteralCString kFolderCreateFailed; 66 extern const nsLiteralCString kFolderLoaded; 67 extern const nsLiteralCString kNumNewBiffMessages; 68 extern const nsLiteralCString kRenameCompleted; 69 70 class nsIMsgFolderCacheElement; 71 class nsICollation; 72 class nsMsgKeySetU; 73 74 class nsMsgFolderService final : public nsIMsgFolderService { 75 public: 76 NS_DECL_ISUPPORTS 77 NS_DECL_NSIMSGFOLDERSERVICE 78 nsMsgFolderService()79 nsMsgFolderService(){}; 80 81 protected: ~nsMsgFolderService()82 ~nsMsgFolderService(){}; 83 }; 84 85 /* 86 * nsMsgDBFolder 87 * class derived from nsMsgFolder for those folders that use an nsIMsgDatabase 88 */ 89 class nsMsgDBFolder : public nsSupportsWeakReference, 90 public nsIMsgFolder, 91 public nsIDBChangeListener, 92 public nsIUrlListener, 93 public nsIJunkMailClassificationListener, 94 public nsIMsgTraitClassificationListener { 95 public: 96 friend class nsMsgFolderService; 97 98 nsMsgDBFolder(void); 99 NS_DECL_THREADSAFE_ISUPPORTS 100 NS_DECL_NSIMSGFOLDER 101 NS_DECL_NSIDBCHANGELISTENER 102 NS_DECL_NSIURLLISTENER 103 NS_DECL_NSIJUNKMAILCLASSIFICATIONLISTENER 104 NS_DECL_NSIMSGTRAITCLASSIFICATIONLISTENER 105 106 NS_IMETHOD WriteToFolderCacheElem(nsIMsgFolderCacheElement* element); 107 NS_IMETHOD ReadFromFolderCacheElem(nsIMsgFolderCacheElement* element); 108 109 nsresult CreateDirectoryForFolder(nsIFile** result); 110 nsresult CreateBackupDirectory(nsIFile** result); 111 nsresult GetBackupSummaryFile(nsIFile** result, const nsACString& newName); 112 nsresult GetMsgPreviewTextFromStream(nsIMsgDBHdr* msgHdr, 113 nsIInputStream* stream); 114 nsresult HandleAutoCompactEvent(nsIMsgWindow* aMsgWindow); 115 116 protected: 117 virtual ~nsMsgDBFolder(); 118 119 virtual nsresult CreateBaseMessageURI(const nsACString& aURI); 120 121 void compressQuotesInMsgSnippet(const nsString& aMessageText, 122 nsAString& aCompressedQuotesStr); 123 void decodeMsgSnippet(const nsACString& aEncodingType, bool aIsComplete, 124 nsCString& aMsgSnippet); 125 126 // helper routine to parse the URI and update member variables 127 nsresult parseURI(bool needServer = false); 128 nsresult GetBaseStringBundle(nsIStringBundle** aBundle); 129 nsresult GetStringFromBundle(const char* msgName, nsString& aResult); 130 nsresult ThrowConfirmationPrompt(nsIMsgWindow* msgWindow, 131 const nsAString& confirmString, 132 bool* confirmed); 133 nsresult GetWarnFilterChanged(bool* aVal); 134 nsresult SetWarnFilterChanged(bool aVal); 135 nsresult CreateCollationKey(const nsString& aSource, uint8_t** aKey, 136 uint32_t* aLength); 137 138 // All children will override this to create the right class of object. 139 virtual nsresult CreateChildFromURI(const nsACString& uri, 140 nsIMsgFolder** folder) = 0; 141 virtual nsresult ReadDBFolderInfo(bool force); 142 virtual nsresult FlushToFolderCache(); 143 virtual nsresult GetDatabase() = 0; 144 virtual nsresult SendFlagNotifications(nsIMsgDBHdr* item, uint32_t oldFlags, 145 uint32_t newFlags); 146 nsresult CheckWithNewMessagesStatus(bool messageAdded); 147 void UpdateNewMessages(); 148 nsresult OnHdrAddedOrDeleted(nsIMsgDBHdr* hdrChanged, bool added); 149 nsresult CreateFileForDB(const nsAString& userLeafName, nsIFile* baseDir, 150 nsIFile** dbFile); 151 152 nsresult GetFolderCacheKey(nsIFile** aFile, bool createDBIfMissing = false); 153 nsresult GetFolderCacheElemFromFile(nsIFile* file, 154 nsIMsgFolderCacheElement** cacheElement); 155 nsresult AddDirectorySeparator(nsIFile* path); 156 nsresult CheckIfFolderExists(const nsAString& newFolderName, 157 nsIMsgFolder* parentFolder, 158 nsIMsgWindow* msgWindow); 159 bool ConfirmAutoFolderRename(nsIMsgWindow* aMsgWindow, 160 const nsString& aOldName, 161 const nsString& aNewName); 162 163 // Returns true if: a) there is no need to prompt or b) the user is already 164 // logged in or c) the user logged in successfully. 165 static bool PromptForMasterPasswordIfNecessary(); 166 167 // offline support methods. 168 nsresult StartNewOfflineMessage(); 169 nsresult WriteStartOfNewLocalMessage(); 170 nsresult EndNewOfflineMessage(); 171 nsresult CompactOfflineStore(nsIMsgWindow* inWindow, 172 nsIUrlListener* aUrlListener); 173 nsresult AutoCompact(nsIMsgWindow* aWindow); 174 // this is a helper routine that ignores whether nsMsgMessageFlags::Offline is 175 // set for the folder 176 nsresult MsgFitsDownloadCriteria(nsMsgKey msgKey, bool* result); 177 nsresult GetPromptPurgeThreshold(bool* aPrompt); 178 nsresult GetPurgeThreshold(int32_t* aThreshold); 179 nsresult ApplyRetentionSettings(bool deleteViaFolder); 180 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult AddMarkAllReadUndoAction( 181 nsIMsgWindow* msgWindow, nsMsgKey* thoseMarked, uint32_t numMarked); 182 183 nsresult PerformBiffNotifications( 184 void); // if there are new, non spam messages, do biff 185 nsresult CloseDBIfFolderNotOpen(); 186 187 // Helper function for Move code to call to update the MRU and MRM time. 188 void UpdateTimestamps(bool allowUndo); 189 void SetMRUTime(); 190 void SetMRMTime(); 191 /** 192 * Clear all processing flags, presumably because message keys are no longer 193 * valid. 194 */ 195 void ClearProcessingFlags(); 196 197 nsresult NotifyHdrsNotBeingClassified(); 198 static nsresult BuildFolderSortKey(nsIMsgFolder* aFolder, 199 nsTArray<uint8_t>& aKey); 200 /** 201 * Produce an array of messages ordered like the input keys. 202 */ 203 nsresult MessagesInKeyOrder(nsTArray<nsMsgKey> const& aKeyArray, 204 nsIMsgFolder* srcFolder, 205 nsTArray<RefPtr<nsIMsgDBHdr>>& messages); 206 nsCString mURI; 207 208 nsCOMPtr<nsIMsgDatabase> mDatabase; 209 nsCOMPtr<nsIMsgDatabase> mBackupDatabase; 210 bool mAddListener; 211 bool mNewMessages; 212 bool mGettingNewMessages; 213 nsMsgKey mLastMessageLoaded; 214 215 nsCOMPtr<nsIMsgDBHdr> m_offlineHeader; 216 int32_t m_numOfflineMsgLines; 217 int32_t m_bytesAddedToLocalMsg; 218 // this is currently used when we do a save as of an imap or news message.. 219 nsCOMPtr<nsIOutputStream> m_tempMessageStream; 220 221 nsCOMPtr<nsIMsgRetentionSettings> m_retentionSettings; 222 nsCOMPtr<nsIMsgDownloadSettings> m_downloadSettings; 223 static nsrefcnt mInstanceCount; 224 225 uint32_t mFlags; 226 nsWeakPtr mParent; // This won't be refcounted for ownership reasons. 227 int32_t mNumUnreadMessages; /* count of unread messages (-1 means unknown; -2 228 means unknown but we already tried to find 229 out.) */ 230 int32_t mNumTotalMessages; /* count of existing messages. */ 231 bool mNotifyCountChanges; 232 int64_t mExpungedBytes; 233 nsCOMArray<nsIMsgFolder> mSubFolders; 234 nsTObserverArray<nsCOMPtr<nsIFolderListener>> mListeners; 235 236 bool mInitializedFromCache; 237 nsISupports* mSemaphoreHolder; // set when the folder is being written to 238 // Due to ownership issues, this won't be 239 // AddRef'd. 240 241 nsWeakPtr mServer; 242 243 // These values are used for tricking the front end into thinking that we have 244 // more messages than are really in the DB. This is usually after and IMAP 245 // message copy where we don't want to do an expensive select until the user 246 // actually opens that folder 247 int32_t mNumPendingUnreadMessages; 248 int32_t mNumPendingTotalMessages; 249 int64_t mFolderSize; 250 251 int32_t mNumNewBiffMessages; 252 253 // these are previous set of new msgs, which we might 254 // want to run junk controls on. This is in addition to "new" hdrs 255 // in the db, which might get cleared because the user clicked away 256 // from the folder. 257 nsTArray<nsMsgKey> m_saveNewMsgs; 258 259 // These are the set of new messages for a folder who has had 260 // its db closed, without the user reading the folder. This 261 // happens with pop3 mail filtered to a different local folder. 262 nsTArray<nsMsgKey> m_newMsgs; 263 264 // 265 // stuff from the uri 266 // 267 bool mHaveParsedURI; // is the URI completely parsed? 268 bool mIsServerIsValid; 269 bool mIsServer; 270 nsString mName; 271 nsCOMPtr<nsIFile> mPath; 272 nsCString mBaseMessageURI; // The uri with the message scheme 273 274 // static stuff for cross-instance objects like atoms 275 static nsrefcnt gInstanceCount; 276 277 static nsresult initializeStrings(); 278 static nsresult createCollationKeyGenerator(); 279 280 static nsString kLocalizedInboxName; 281 static nsString kLocalizedTrashName; 282 static nsString kLocalizedSentName; 283 static nsString kLocalizedDraftsName; 284 static nsString kLocalizedTemplatesName; 285 static nsString kLocalizedUnsentName; 286 static nsString kLocalizedJunkName; 287 static nsString kLocalizedArchivesName; 288 289 static nsString kLocalizedBrandShortName; 290 291 static nsICollation* gCollationKeyGenerator; 292 static bool gInitializeStringsDone; 293 294 // store of keys that have a processing flag set 295 struct { 296 uint32_t bit; 297 nsMsgKeySetU* keys; 298 } mProcessingFlag[nsMsgProcessingFlags::NumberOfFlags]; 299 300 // list of nsIMsgDBHdrs for messages to process post-bayes 301 nsTArray<RefPtr<nsIMsgDBHdr>> mPostBayesMessagesToFilter; 302 303 /** 304 * The list of message keys that have been classified for msgsClassified 305 * batch notification purposes. We add to this list in OnMessageClassified 306 * when we are told about a classified message (a URI is provided), and we 307 * notify for the list and clear it when we are told all the messages in 308 * the batch were classified (a URI is not provided). 309 */ 310 nsTArray<nsMsgKey> mClassifiedMsgKeys; 311 // Is the current bayes filtering doing junk classification? 312 bool mBayesJunkClassifying; 313 // Is the current bayes filtering doing trait classification? 314 bool mBayesTraitClassifying; 315 }; 316 317 // This class is a kludge to allow nsMsgKeySet to be used with uint32_t keys 318 class nsMsgKeySetU { 319 public: 320 // Creates an empty set. 321 static nsMsgKeySetU* Create(); 322 ~nsMsgKeySetU(); 323 // IsMember() returns whether the given key is a member of this set. 324 bool IsMember(nsMsgKey key); 325 // Add() adds the given key to the set. (Returns 1 if a change was 326 // made, 0 if it was already there, and negative on error.) 327 int Add(nsMsgKey key); 328 // Remove() removes the given article from the set. 329 int Remove(nsMsgKey key); 330 // Add the keys in the set to aArray. 331 nsresult ToMsgKeyArray(nsTArray<nsMsgKey>& aArray); 332 333 protected: 334 nsMsgKeySetU(); 335 nsMsgKeySet* loKeySet; 336 nsMsgKeySet* hiKeySet; 337 }; 338 339 #endif 340