From 6dc5b8bdedfa6a1fabea03c7cb1ea377900bc2e3 Mon Sep 17 00:00:00 2001 From: "naving%netscape.com" Date: Sun, 17 Dec 2000 01:19:41 +0000 Subject: [PATCH] 43411 sr=bienvenu. Implementing expunge inbox on exit for imap servers. git-svn-id: svn://10.0.0.236/trunk@83776 18797224-902f-48f8-a5cc-f745e15eee43 --- .../base/public/nsIMsgAccountManager.idl | 4 + mozilla/mailnews/base/public/nsIMsgFolder.idl | 2 +- .../mailnews/base/src/nsMsgAccountManager.cpp | 117 +++++++++++++++++- .../mailnews/base/src/nsMsgAccountManager.h | 7 ++ .../mailnews/base/src/nsMsgMailSession.cpp | 1 + mozilla/mailnews/base/util/nsMsgFolder.cpp | 2 +- mozilla/mailnews/base/util/nsMsgFolder.h | 2 +- mozilla/mailnews/imap/src/nsImapMailFolder.h | 2 +- 8 files changed, 131 insertions(+), 6 deletions(-) diff --git a/mozilla/mailnews/base/public/nsIMsgAccountManager.idl b/mozilla/mailnews/base/public/nsIMsgAccountManager.idl index ad21594dc7b..e12693832be 100644 --- a/mozilla/mailnews/base/public/nsIMsgAccountManager.idl +++ b/mozilla/mailnews/base/public/nsIMsgAccountManager.idl @@ -144,6 +144,10 @@ interface nsIMsgAccountManager : nsISupports { void SetFolderDoingEmptyTrash(in nsIMsgFolder folder); boolean GetEmptyTrashInProgress(); + void CleanupInboxOnExit(); + void SetFolderDoingCleanupInbox(in nsIMsgFolder folder); + boolean GetCleanupInboxInProgress(); + void addRootFolderListener(in nsIFolderListener listener); void removeRootFolderListener(in nsIFolderListener listener); diff --git a/mozilla/mailnews/base/public/nsIMsgFolder.idl b/mozilla/mailnews/base/public/nsIMsgFolder.idl index cd0da87a187..ef65603050e 100644 --- a/mozilla/mailnews/base/public/nsIMsgFolder.idl +++ b/mozilla/mailnews/base/public/nsIMsgFolder.idl @@ -148,7 +148,7 @@ const nsMsgBiffState nsMsgBiffState_Unknown = 2; // We dunno whether there is ne */ void createStorageIfMissing(in nsIUrlListener urlListener); - void compact(); + void compact(in nsIUrlListener aListener); void emptyTrash(in nsIMsgWindow aMsgWindow, in nsIUrlListener aListener); /** diff --git a/mozilla/mailnews/base/src/nsMsgAccountManager.cpp b/mozilla/mailnews/base/src/nsMsgAccountManager.cpp index 301a4b29345..5799895c235 100644 --- a/mozilla/mailnews/base/src/nsMsgAccountManager.cpp +++ b/mozilla/mailnews/base/src/nsMsgAccountManager.cpp @@ -128,6 +128,7 @@ nsMsgAccountManager::nsMsgAccountManager() : m_accountsLoaded(PR_FALSE), m_defaultAccount(null_nsCOMPtr()), m_emptyTrashInProgress(PR_FALSE), + m_cleanupInboxInProgress(PR_FALSE), m_haveShutdown(PR_FALSE), m_shutdownInProgress(PR_FALSE), m_prefs(0) @@ -936,9 +937,92 @@ PRBool PR_CALLBACK nsMsgAccountManager::emptyTrashOnExit(nsHashKey *aKey, void * return PR_TRUE; } -// enumaration for closing cached connections. -PRBool nsMsgAccountManager::closeCachedConnections(nsHashKey *aKey, void *aData, +PRBool PR_CALLBACK nsMsgAccountManager::cleanupInboxOnExit(nsHashKey *aKey, void *aData, void *closure) +{ + nsCOMPtr root; + nsIMsgIncomingServer *msgserver = (nsIMsgIncomingServer*)aData; + msgserver->GetRootFolder(getter_AddRefs(root)); + nsXPIDLCString type; + msgserver->GetType(getter_Copies(type)); + if (root) + { + nsCOMPtr folder; + folder = do_QueryInterface(root); + if (folder) + { + nsXPIDLCString passwd; + PRBool isImap = (type ? PL_strcmp(type, "imap") == 0 :PR_FALSE); + if (isImap) + { + nsImapIncomingServer *imapserver = (nsImapIncomingServer*)aData; + PRBool cleanupInboxOnExit = PR_FALSE; + + imapserver->GetCleanupInboxOnExit(&cleanupInboxOnExit); + if (cleanupInboxOnExit) + { + msgserver->GetPassword(getter_Copies(passwd)); + if (isImap && passwd && nsCRT::strlen((const char*) passwd)) + { + nsresult rv; + nsCOMPtr inboxFolder; + nsCOMPtr aEnumerator; + folder->GetSubFolders(getter_AddRefs(aEnumerator)); + nsCOMPtr aSupport; + rv = aEnumerator->First(); + while (NS_SUCCEEDED(rv)) + { + rv = aEnumerator->CurrentItem(getter_AddRefs(aSupport)); + nsCOMPtrinboxFolder = do_QueryInterface(aSupport); + PRUnichar *folderName = nsnull; + inboxFolder->GetName(&folderName); + if (folderName && nsCRT::strcasecmp(folderName, "INBOX") ==0) + { + nsCOMPtr urlListener; + NS_WITH_SERVICE(nsIMsgAccountManager, accountManager, + kMsgAccountManagerCID, &rv); + if (NS_FAILED(rv)) return rv; + NS_WITH_SERVICE(nsIEventQueueService, pEventQService, + kEventQueueServiceCID, &rv); + + if (NS_FAILED(rv)) return rv; + nsCOMPtr eventQueue; + pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, + getter_AddRefs(eventQueue)); + + accountManager->SetFolderDoingCleanupInbox(inboxFolder); + urlListener = do_QueryInterface(accountManager, &rv); + + inboxFolder->Compact(urlListener); + if (NS_SUCCEEDED(rv) && isImap && urlListener) + { + PRBool inProgress = PR_FALSE; + accountManager->GetCleanupInboxInProgress(&inProgress); + while (inProgress) + { + accountManager->GetCleanupInboxInProgress(&inProgress); + PR_CEnterMonitor(inboxFolder); + PR_CWait(folder, 1000UL); + PR_CExitMonitor(inboxFolder); + if (eventQueue) + rv = eventQueue->ProcessPendingEvents(); + } + } + break; + } + else + rv = aEnumerator->Next(); + } + } + } + } + } + } + return PR_TRUE; +} + +// enumaration for closing cached connections. +PRBool nsMsgAccountManager::closeCachedConnections(nsHashKey *aKey, void *aData, void *closure) { nsIMsgIncomingServer *server = (nsIMsgIncomingServer*)aData; @@ -1307,6 +1391,13 @@ nsMsgAccountManager::EmptyTrashOnExit() return NS_OK; } +NS_IMETHODIMP +nsMsgAccountManager::CleanupInboxOnExit() +{ + m_incomingServers.Enumerate(cleanupInboxOnExit,nsnull); + return NS_OK; +} + NS_IMETHODIMP nsMsgAccountManager::WriteToFolderCache(nsIMsgFolderCache *folderCache) { @@ -1930,6 +2021,13 @@ nsMsgAccountManager::OnStopRunningUrl(nsIURI * aUrl, nsresult aExitCode) m_emptyTrashInProgress = PR_FALSE; PR_CExitMonitor(m_folderDoingEmptyTrash); } + else if (m_folderDoingCleanupInbox) + { + PR_CEnterMonitor(m_folderDoingCleanupInbox); + PR_CNotifyAll(m_folderDoingCleanupInbox); + m_cleanupInboxInProgress = PR_FALSE; + PR_CExitMonitor(m_folderDoingCleanupInbox); + } return NS_OK; } @@ -1949,6 +2047,21 @@ nsMsgAccountManager::GetEmptyTrashInProgress(PRBool *bVal) return NS_OK; } +NS_IMETHODIMP +nsMsgAccountManager::SetFolderDoingCleanupInbox(nsIMsgFolder *folder) +{ + m_folderDoingCleanupInbox = folder; + m_cleanupInboxInProgress = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP +nsMsgAccountManager::GetCleanupInboxInProgress(PRBool *bVal) +{ + NS_ENSURE_ARG_POINTER(bVal); + *bVal = m_cleanupInboxInProgress; + return NS_OK; +} nsresult nsMsgAccountManager::SetLastServerFound(nsIMsgIncomingServer *server, const char *hostname, const char *username, const char *type) { diff --git a/mozilla/mailnews/base/src/nsMsgAccountManager.h b/mozilla/mailnews/base/src/nsMsgAccountManager.h index caf9e7222dd..0aa73de8e82 100644 --- a/mozilla/mailnews/base/src/nsMsgAccountManager.h +++ b/mozilla/mailnews/base/src/nsMsgAccountManager.h @@ -37,6 +37,7 @@ #include "nsIObserver.h" #include "nsWeakReference.h" #include "nsIUrlListener.h" +#include "nsImapIncomingServer.h" class nsMsgAccountManager : public nsIMsgAccountManager, @@ -72,7 +73,9 @@ private: nsCOMPtr m_defaultAccount; nsCOMPtr m_incomingServerListeners; nsCOMPtr m_folderDoingEmptyTrash; + nsCOMPtr m_folderDoingCleanupInbox; PRBool m_emptyTrashInProgress; + PRBool m_cleanupInboxInProgress; nsCString mAccountKeyList; @@ -127,6 +130,10 @@ private: // empty trash on exit static PRBool PR_CALLBACK emptyTrashOnExit(nsHashKey *aKey, void *aData, void *closure); + + // cleanup inbox on exit + static PRBool PR_CALLBACK cleanupInboxOnExit(nsHashKey *aKey, void *aData, + void *closure); // // account enumerators // ("element" is always an account) diff --git a/mozilla/mailnews/base/src/nsMsgMailSession.cpp b/mozilla/mailnews/base/src/nsMsgMailSession.cpp index 480f12e7b60..bb4ae16db0d 100644 --- a/mozilla/mailnews/base/src/nsMsgMailSession.cpp +++ b/mozilla/mailnews/base/src/nsMsgMailSession.cpp @@ -349,6 +349,7 @@ NS_IMETHODIMP nsMsgMailSession::RemoveMsgWindow(nsIMsgWindow *msgWindow) NS_WITH_SERVICE(nsIMsgAccountManager, accountManager, kMsgAccountManagerCID, &rv); if (NS_FAILED(rv)) return rv; + accountManager->CleanupInboxOnExit(); accountManager->EmptyTrashOnExit(); } return NS_OK; diff --git a/mozilla/mailnews/base/util/nsMsgFolder.cpp b/mozilla/mailnews/base/util/nsMsgFolder.cpp index e297ffee9e0..6e4c3c13847 100644 --- a/mozilla/mailnews/base/util/nsMsgFolder.cpp +++ b/mozilla/mailnews/base/util/nsMsgFolder.cpp @@ -1162,7 +1162,7 @@ nsresult nsMsgFolder::AddSubfolder(nsAutoString *folderName, return NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP nsMsgFolder::Compact() +NS_IMETHODIMP nsMsgFolder::Compact(nsIUrlListener *aListener) { return NS_ERROR_NOT_IMPLEMENTED; } diff --git a/mozilla/mailnews/base/util/nsMsgFolder.h b/mozilla/mailnews/base/util/nsMsgFolder.h index 7c09a51d7ae..a3e955fbe47 100644 --- a/mozilla/mailnews/base/util/nsMsgFolder.h +++ b/mozilla/mailnews/base/util/nsMsgFolder.h @@ -95,7 +95,7 @@ public: NS_IMETHOD RecursiveDelete(PRBool deleteStorage); NS_IMETHOD CreateSubfolder(const PRUnichar *folderName, nsIMsgWindow *msgWindow); NS_IMETHOD AddSubfolder(nsAutoString *folderName, nsIMsgFolder **newFolder); - NS_IMETHOD Compact(void); + NS_IMETHOD Compact(nsIUrlListener *aListener); NS_IMETHOD EmptyTrash(nsIMsgWindow *msgWindow, nsIUrlListener *aListener); NS_IMETHOD Rename(const PRUnichar *name, nsIMsgWindow *msgWindow); NS_IMETHOD Adopt(nsIMsgFolder *srcFolder, PRUint32 *outPos); diff --git a/mozilla/mailnews/imap/src/nsImapMailFolder.h b/mozilla/mailnews/imap/src/nsImapMailFolder.h index 325e989cc86..813c6f96d6c 100644 --- a/mozilla/mailnews/imap/src/nsImapMailFolder.h +++ b/mozilla/mailnews/imap/src/nsImapMailFolder.h @@ -124,7 +124,7 @@ public: NS_IMETHOD AddSubfolderWithPath(nsAutoString *name, nsIFileSpec *dbPath, nsIMsgFolder **child); NS_IMETHODIMP CreateStorageIfMissing(nsIUrlListener* urlListener); - NS_IMETHOD Compact(); + NS_IMETHOD Compact(nsIUrlListener *aListener); NS_IMETHOD EmptyTrash(nsIMsgWindow *msgWindow, nsIUrlListener *aListener); NS_IMETHOD Delete (); NS_IMETHOD Rename (const PRUnichar *newName, nsIMsgWindow *msgWindow);