From 7b789e0287ddfed155c2eea61620cdbb55706ae0 Mon Sep 17 00:00:00 2001 From: "bienvenu%netscape.com" Date: Sun, 20 Jun 1999 15:35:10 +0000 Subject: [PATCH] run url queue from mozilla thread, more work on imap filters --- mailnews/imap/public/nsIIMAPHostSessionList.h | 6 + .../imap/public/nsIImapMiscellaneousSink.h | 4 + mailnews/imap/src/nsIMAPHostSessionList.cpp | 23 ++++ mailnews/imap/src/nsIMAPHostSessionList.h | 6 + mailnews/imap/src/nsImapIncomingServer.cpp | 2 + mailnews/imap/src/nsImapMailFolder.cpp | 116 ++++++++++++++---- mailnews/imap/src/nsImapMailFolder.h | 4 +- mailnews/imap/src/nsImapProtocol.cpp | 23 ++-- mailnews/imap/src/nsImapProxyEvent.cpp | 50 ++++++++ mailnews/imap/src/nsImapProxyEvent.h | 15 ++- 10 files changed, 215 insertions(+), 34 deletions(-) diff --git a/mailnews/imap/public/nsIIMAPHostSessionList.h b/mailnews/imap/public/nsIIMAPHostSessionList.h index 218906ac1b4..20d039bc0c0 100644 --- a/mailnews/imap/public/nsIIMAPHostSessionList.h +++ b/mailnews/imap/public/nsIIMAPHostSessionList.h @@ -70,6 +70,12 @@ public: NS_IMETHOD SetDeleteIsMoveToTrashForHost(const char *hostName, const char *userName, PRBool isMoveToTrash) = 0; + NS_IMETHOD GetShowDeletedMessagesForHost(const char *hostName, + const char *userName, PRBool &result) = 0; + + NS_IMETHOD SetShowDeletedMessagesForHost(const char *hostName, const char + *userName, PRBool showDeletedMessages) + = 0; // Get namespaces NS_IMETHOD GetGotNamespacesForHost(const char *hostName, const char diff --git a/mailnews/imap/public/nsIImapMiscellaneousSink.h b/mailnews/imap/public/nsIImapMiscellaneousSink.h index 9b83fea36d2..ce3690b3f59 100644 --- a/mailnews/imap/public/nsIImapMiscellaneousSink.h +++ b/mailnews/imap/public/nsIImapMiscellaneousSink.h @@ -24,6 +24,8 @@ #include "nsIImapProtocol.h" #include "MailNewsTypes.h" +class nsIImapIncomingServer; + /* 22e3e664-e789-11d2-af83-001083002da8 */ #define NS_IIMAPMISCELLANEOUSSINK_IID \ @@ -78,6 +80,8 @@ public: msg_line_info* aInfo) = 0; NS_IMETHOD ProcessTunnel(nsIImapProtocol* aProtocol, TunnelInfo *aInfo) = 0; + NS_IMETHOD LoadNextQueuedUrl(nsIImapProtocol* aProtocol, + nsIImapIncomingServer *incomingServer) = 0; }; diff --git a/mailnews/imap/src/nsIMAPHostSessionList.cpp b/mailnews/imap/src/nsIMAPHostSessionList.cpp index 9dde8e49853..e81766a8525 100644 --- a/mailnews/imap/src/nsIMAPHostSessionList.cpp +++ b/mailnews/imap/src/nsIMAPHostSessionList.cpp @@ -45,6 +45,7 @@ nsIMAPHostInfo::nsIMAPHostInfo(const char *hostName, const char *userName) fShellCache = nsIMAPBodyShellCache::Create(); fPasswordVerifiedOnline = PR_FALSE; fDeleteIsMoveToTrash = PR_TRUE; + fShowDeletedMessages = PR_FALSE; fGotNamespaces = PR_FALSE; fNamespacesOverridable = PR_TRUE; } @@ -257,6 +258,17 @@ NS_IMETHODIMP nsIMAPHostSessionList::GetDeleteIsMoveToTrashForHost( return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK; } +NS_IMETHODIMP nsIMAPHostSessionList::GetShowDeletedMessagesForHost( + const char *hostName, const char *userName, PRBool &result) +{ + PR_EnterMonitor(gCachedHostInfoMonitor); + nsIMAPHostInfo *host = FindHost(hostName, userName); + if (host) + result = host->fShowDeletedMessages; + PR_ExitMonitor(gCachedHostInfoMonitor); + return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK; +} + NS_IMETHODIMP nsIMAPHostSessionList::SetDeleteIsMoveToTrashForHost( const char *hostName, const char *userName, PRBool isMoveToTrash) { @@ -268,6 +280,17 @@ NS_IMETHODIMP nsIMAPHostSessionList::SetDeleteIsMoveToTrashForHost( return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK; } +NS_IMETHODIMP nsIMAPHostSessionList::SetShowDeletedMessagesForHost( + const char *hostName, const char *userName, PRBool showDeletedMessages) +{ + PR_EnterMonitor(gCachedHostInfoMonitor); + nsIMAPHostInfo *host = FindHost(hostName, userName); + if (host) + host->fShowDeletedMessages = showDeletedMessages; + PR_ExitMonitor(gCachedHostInfoMonitor); + return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK; +} + NS_IMETHODIMP nsIMAPHostSessionList::GetGotNamespacesForHost( const char *hostName, const char *userName, PRBool &result) { diff --git a/mailnews/imap/src/nsIMAPHostSessionList.h b/mailnews/imap/src/nsIMAPHostSessionList.h index 127bc77040f..f060503155a 100644 --- a/mailnews/imap/src/nsIMAPHostSessionList.h +++ b/mailnews/imap/src/nsIMAPHostSessionList.h @@ -50,6 +50,7 @@ protected: PRBool fHaveAdminURL; PRBool fPasswordVerifiedOnline; PRBool fDeleteIsMoveToTrash; + PRBool fShowDeletedMessages; PRBool fGotNamespaces; nsIMAPBodyShellCache *fShellCache; }; @@ -93,6 +94,11 @@ public: *userName, PRBool &result); NS_IMETHOD SetDeleteIsMoveToTrashForHost(const char *hostName, const char *userName, PRBool isMoveToTrash); + // imap delete model (or not) + NS_IMETHOD GetShowDeletedMessagesForHost(const char *hostName, + const char *userName, PRBool &result); + NS_IMETHOD SetShowDeletedMessagesForHost(const char *hostName, const char + *userName, PRBool showDeletedMessages); // Get namespaces NS_IMETHOD GetGotNamespacesForHost(const char *hostName, const char diff --git a/mailnews/imap/src/nsImapIncomingServer.cpp b/mailnews/imap/src/nsImapIncomingServer.cpp index cda586fe667..4ec0198c350 100644 --- a/mailnews/imap/src/nsImapIncomingServer.cpp +++ b/mailnews/imap/src/nsImapIncomingServer.cpp @@ -202,6 +202,8 @@ nsImapIncomingServer::GetImapConnectionAndLoadUrl(nsIEventQueue* return rv; } +// checks to see if there are any queued urls on this incoming server, +// and if so, tries to run the oldest one. NS_IMETHODIMP nsImapIncomingServer::LoadNextQueuedUrl() { diff --git a/mailnews/imap/src/nsImapMailFolder.cpp b/mailnews/imap/src/nsImapMailFolder.cpp index 1680b89fe80..bb7a2d4df11 100644 --- a/mailnews/imap/src/nsImapMailFolder.cpp +++ b/mailnews/imap/src/nsImapMailFolder.cpp @@ -39,6 +39,7 @@ #include "nsMsgBaseCID.h" #include "nsMsgLocalCID.h" #include "nsImapUndoTxn.h" +#include "nsIImapHostSessionList.h" #ifdef DOING_FILTERS #include "nsIMsgFilter.h" @@ -60,6 +61,7 @@ static NS_DEFINE_CID(kCImapService, NS_IMAPSERVICE_CID); static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kMsgMailSessionCID, NS_MSGMAILSESSION_CID); static NS_DEFINE_CID(kParseMailMsgStateCID, NS_PARSEMAILMSGSTATE_CID); +static NS_DEFINE_CID(kCImapHostSessionList, NS_IIMAPHOSTSESSIONLIST_CID); //////////////////////////////////////////////////////////////////////////////// // for temp message hack @@ -772,7 +774,7 @@ NS_IMETHODIMP nsImapMailFolder::GetHostName(char** hostName) { nsresult rv = NS_ERROR_NULL_POINTER; - NS_PRECONDITION (hostName, "Oops ... null userName pointer"); + NS_PRECONDITION (hostName, "Oops ... null hostName pointer"); if (!hostName) return rv; else @@ -1508,6 +1510,7 @@ NS_IMETHODIMP nsImapMailFolder::ApplyFilterHit(nsIMsgFilter *filter, PRBool *app { PRUint32 msgFlags; nsMsgKey msgKey; + nsString trashNameVal(eOneByte); msgHdr->GetFlags(&msgFlags); msgHdr->GetMessageKey(&msgKey); @@ -1516,35 +1519,39 @@ NS_IMETHODIMP nsImapMailFolder::ApplyFilterHit(nsIMsgFilter *filter, PRBool *app { case nsMsgFilterActionDelete: { -#ifdef DOING_DELETE - MSG_IMAPFolderInfoMail *imapFolder = m_folder->GetIMAPFolderInfoMail(); - PRBool serverIsImap = GetMaster()->GetPrefs()->GetMailServerIsIMAP4(); - PRBool deleteToTrash = !imapFolder || imapFolder->DeleteIsMoveToTrash(); - PRBool showDeletedMessages = (!imapFolder) || imapFolder->ShowDeletedMessages(); - if (deleteToTrash || !serverIsImap) + PRBool deleteToTrash = DeleteIsMoveToTrash(); + PRBool showDeletedMessages = ShowDeletedMessages(); + if (deleteToTrash) { // set value to trash folder - MSG_FolderInfoMail *mailTrash = GetTrashFolder(); - if (mailTrash) - value = (void *) mailTrash->GetPathname(); + nsCOMPtr mailTrash; + rv = GetTrashFolder(getter_AddRefs(mailTrash));; + if (NS_SUCCEEDED(rv) && mailTrash) + { + // this sucks - but we need value to live past this scope + // so we use an nsString from above. + char *folderName = nsnull; + rv = mailTrash->GetName(&folderName); + trashNameVal = folderName; + PR_FREEIF(folderName); + value = (void *) trashNameVal.GetBuffer(); + } - msgHdr->OrFlags(MSG_FLAG_READ); // mark read in trash. + msgHdr->OrFlags(MSG_FLAG_READ, &newFlags); // mark read in trash. } - else // (!deleteToTrash && serverIsImap) + else // (!deleteToTrash) { - msgHdr->OrFlags(MSG_FLAG_READ | MSG_FLAG_IMAP_DELETED); + msgHdr->OrFlags(MSG_FLAG_READ | MSG_FLAG_IMAP_DELETED, &newFlags); nsMsgKeyArray keysToFlag; - keysToFlag.Add(msgHdr->GetMessageKey()); - if (imapFolder) - imapFolder->StoreImapFlags(m_pane, kImapMsgSeenFlag | kImapMsgDeletedFlag, TRUE, keysToFlag, ((ParseIMAPMailboxState *) this)->GetFilterUrlQueue()); - if (!showDeletedMessages) - msgMoved = TRUE; // this will prevent us from adding the header to the db. + keysToFlag.Add(msgKey); + StoreImapFlags(kImapMsgSeenFlag | kImapMsgDeletedFlag, TRUE, keysToFlag); +// if (!showDeletedMessages) +// msgMoved = TRUE; // this will prevent us from adding the header to the db. } - *applyMore = PR_FALSE; -#endif // DOING_DELETE } + // note that delete falls through to move. case nsMsgFilterActionMoveToFolder: { // if moving to a different file, do it. @@ -1741,7 +1748,7 @@ nsresult nsImapMailFolder::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, if (sourceDB && msgFolder) { - PRBool imapDeleteIsMoveToTrash = PR_TRUE /* ### DMB m_host->GetDeleteIsMoveToTrash() */; + PRBool imapDeleteIsMoveToTrash = DeleteIsMoveToTrash(); m_moveCoalescer->AddMove (msgFolder, keyToFilter); // For each folder, we need to keep track of the ids we want to move to that @@ -1780,7 +1787,7 @@ nsresult nsImapMailFolder::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, // both of these algorithms assume that key arrays and flag states are sorted by increasing key. void nsImapMailFolder::FindKeysToDelete(const nsMsgKeyArray &existingKeys, nsMsgKeyArray &keysToDelete, nsImapFlagAndUidState *flagState) { - PRBool imapDeleteIsMoveToTrash = /* DeleteIsMoveToTrash() */ PR_TRUE; + PRBool imapDeleteIsMoveToTrash = DeleteIsMoveToTrash(); PRUint32 total = existingKeys.GetSize(); PRInt32 messageIndex; @@ -1819,7 +1826,7 @@ void nsImapMailFolder::FindKeysToDelete(const nsMsgKeyArray &existingKeys, nsMsg void nsImapMailFolder::FindKeysToAdd(const nsMsgKeyArray &existingKeys, nsMsgKeyArray &keysToFetch, nsImapFlagAndUidState *flagState) { - PRBool showDeletedMessages = PR_FALSE /* ShowDeletedMessages() */; + PRBool showDeletedMessages = ShowDeletedMessages(); int dbIndex=0; // current index into existingKeys PRInt32 existTotal, numberOfKnownKeys; @@ -2132,11 +2139,65 @@ nsImapMailFolder::NotifyMessageDeleted(nsIImapProtocol* aProtocol, PRBool nsImapMailFolder::ShowDeletedMessages() { + nsresult err; // return (m_host->GetIMAPDeleteModel() == MSG_IMAPDeleteIsIMAPDelete); - return PR_FALSE; + NS_WITH_SERVICE(nsIImapHostSessionList, hostSession, + kCImapHostSessionList, &err); + PRBool rv = PR_FALSE; + + if (NS_SUCCEEDED(err) && hostSession) + { + char *hostName = nsnull; + char *userName = nsnull; + GetHostName(&hostName); + GetUsersName(&userName); + err = hostSession->GetShowDeletedMessagesForHost(hostName, userName, rv); + PR_FREEIF(hostName); + PR_FREEIF(userName); + } + return rv; } +PRBool nsImapMailFolder::DeleteIsMoveToTrash() +{ +// return (m_host->GetIMAPDeleteModel() == MSG_IMAPDeleteIsIMAPDelete); + nsresult err; + NS_WITH_SERVICE(nsIImapHostSessionList, hostSession, + kCImapHostSessionList, &err); + PRBool rv = PR_TRUE; + + if (NS_SUCCEEDED(err) && hostSession) + { + char *hostName = nsnull; + char *userName = nsnull; + GetHostName(&hostName); + GetUsersName(&userName); + nsresult err = hostSession->GetDeleteIsMoveToTrashForHost(hostName, userName, rv); + PR_FREEIF(hostName); + PR_FREEIF(userName); + } + return rv; +} + +nsresult nsImapMailFolder::GetTrashFolder(nsIMsgFolder **pTrashFolder) +{ + if (!pTrashFolder) + return NS_ERROR_NULL_POINTER; + + nsIMsgFolder *foundTrash = NULL; + nsCOMPtr rootFolder; + nsresult rv = GetRootFolder(getter_AddRefs(rootFolder)); + if(NS_SUCCEEDED(rv)) + { + PRUint32 numFolders; + rv = rootFolder->GetFoldersWithFlag(MSG_FOLDER_FLAG_TRASH, pTrashFolder, 1, &numFolders); + if (*pTrashFolder) + NS_ADDREF(*pTrashFolder); + } + return rv; +} + void nsImapMailFolder::ParseUidString(char *uidString, nsMsgKeyArray &keys) { // This is in the form ,, or : @@ -2469,6 +2530,13 @@ nsImapMailFolder::ProcessTunnel(nsIImapProtocol* aProtocol, return NS_ERROR_FAILURE; } +NS_IMETHODIMP +nsImapMailFolder::LoadNextQueuedUrl(nsIImapProtocol* aProtocol, + nsIImapIncomingServer *incomingServer) +{ + return incomingServer->LoadNextQueuedUrl(); +} + nsresult nsImapMailFolder::CreateDirectoryForFolder(nsFileSpec &path) //** dup { diff --git a/mailnews/imap/src/nsImapMailFolder.h b/mailnews/imap/src/nsImapMailFolder.h index d05a55b922d..6ff91e971b4 100644 --- a/mailnews/imap/src/nsImapMailFolder.h +++ b/mailnews/imap/src/nsImapMailFolder.h @@ -248,6 +248,7 @@ public: msg_line_info* aInfo); NS_IMETHOD ProcessTunnel(nsIImapProtocol* aProtocol, TunnelInfo *aInfo); + NS_IMETHOD LoadNextQueuedUrl(nsIImapProtocol* aProtocol, nsIImapIncomingServer *aInfo); #ifdef DOING_FILTERS // nsIMsgFilterHitNotification method(s) @@ -272,8 +273,9 @@ protected: void SetIMAPDeletedFlag(nsIMsgDatabase *mailDB, const nsMsgKeyArray &msgids, PRBool markDeleted); virtual PRBool ShowDeletedMessages(); - + virtual PRBool DeleteIsMoveToTrash(); void ParseUidString(char *uidString, nsMsgKeyArray &keys); + nsresult GetTrashFolder(nsIMsgFolder **pTrashFolder); nsresult AddDirectorySeparator(nsFileSpec &path); nsresult CreateDirectoryForFolder(nsFileSpec &path); diff --git a/mailnews/imap/src/nsImapProtocol.cpp b/mailnews/imap/src/nsImapProtocol.cpp index 69c4347d515..87fc0ee19b9 100644 --- a/mailnews/imap/src/nsImapProtocol.cpp +++ b/mailnews/imap/src/nsImapProtocol.cpp @@ -871,14 +871,6 @@ void nsImapProtocol::ProcessCurrentURL() } else { - if (m_server) - { - nsresult rv; - nsCOMPtr - aImapServer(do_QueryInterface(m_server, &rv)); - if (NS_SUCCEEDED(rv)) - aImapServer->LoadNextQueuedUrl(); - } } } else if (!logonFailed) @@ -889,6 +881,21 @@ void nsImapProtocol::ProcessCurrentURL() m_lastActiveTime = PR_Now(); // ** jt -- is this the best place for time stamp PseudoInterrupt(FALSE); // clear this, because we must be done interrupting? + // release this by hand so that we can load the next queued url without thinking + // this connection is busy running a url. + m_runningUrl = null_nsCOMPtr(); + + // now try queued urls, now that we've released this connection. + if (m_server && m_imapMiscellaneousSink) + { + nsresult rv; + nsCOMPtr + aImapServer(do_QueryInterface(m_server, &rv)); + if (NS_SUCCEEDED(rv)) + { + rv = m_imapMiscellaneousSink->LoadNextQueuedUrl(this, aImapServer); + } + } // release the url as we are done with it... ReleaseUrlState(); } diff --git a/mailnews/imap/src/nsImapProxyEvent.cpp b/mailnews/imap/src/nsImapProxyEvent.cpp index b3338379261..b7c0a4f00df 100644 --- a/mailnews/imap/src/nsImapProxyEvent.cpp +++ b/mailnews/imap/src/nsImapProxyEvent.cpp @@ -1716,6 +1716,32 @@ nsImapMiscellaneousSinkProxy::ProcessTunnel(nsIImapProtocol* aProtocol, return res; } +NS_IMETHODIMP +nsImapMiscellaneousSinkProxy::LoadNextQueuedUrl(nsIImapProtocol* aProtocol, + nsIImapIncomingServer *aInfo) +{ + nsresult res = NS_OK; + NS_PRECONDITION (aInfo, "Oops... null aInfo"); + if(!aInfo) + return NS_ERROR_NULL_POINTER; + NS_ASSERTION (m_protocol == aProtocol, "Ooh ooh, wrong protocol"); + + if (PR_GetCurrentThread() == m_thread) + { + LoadNextQueuedUrlProxyEvent *ev = + new LoadNextQueuedUrlProxyEvent(this, aInfo); + if(nsnull == ev) + res = NS_ERROR_OUT_OF_MEMORY; + else + ev->PostEvent(m_eventQueue); + } + else + { + res = m_realImapMiscellaneousSink->LoadNextQueuedUrl(aProtocol, aInfo); + } + return res; +} + nsImapMailFolderSinkProxyEvent::nsImapMailFolderSinkProxyEvent(nsImapMailFolderSinkProxy* aProxy) { @@ -3437,3 +3463,27 @@ ProcessTunnelProxyEvent::HandleEvent() m_proxy->m_protocol->NotifyFEEventCompletion(); return res; } + +LoadNextQueuedUrlProxyEvent::LoadNextQueuedUrlProxyEvent( + nsImapMiscellaneousSinkProxy* aProxy, nsIImapIncomingServer *aInfo) : + nsImapMiscellaneousSinkProxyEvent(aProxy) +{ + NS_ASSERTION (aInfo, "Oops... a null nsImapIncomingServer info"); + // potential ownership/lifetime problem here, but incoming server + // shouldn't be deleted while urls are running. + m_imapIncomingServer = aInfo; +} + +LoadNextQueuedUrlProxyEvent::~LoadNextQueuedUrlProxyEvent() +{ +} + +NS_IMETHODIMP +LoadNextQueuedUrlProxyEvent::HandleEvent() +{ + nsresult res = m_proxy->m_realImapMiscellaneousSink->LoadNextQueuedUrl( + m_proxy->m_protocol, m_imapIncomingServer); + if (m_notifyCompletion) + m_proxy->m_protocol->NotifyFEEventCompletion(); + return res; +} diff --git a/mailnews/imap/src/nsImapProxyEvent.h b/mailnews/imap/src/nsImapProxyEvent.h index 24df335411b..cd4bf932a7d 100644 --- a/mailnews/imap/src/nsImapProxyEvent.h +++ b/mailnews/imap/src/nsImapProxyEvent.h @@ -28,7 +28,8 @@ #include "nsIImapMessageSink.h" #include "nsIImapExtensionSink.h" #include "nsIImapMiscellaneousSink.h" - +#include "nsIImapIncomingServer.h" +#include "nsCOMPtr.h" class nsImapProxyBase { public: @@ -237,6 +238,8 @@ public: NS_IMETHOD ProcessTunnel(nsIImapProtocol* aProtocol, TunnelInfo *aInfo); + NS_IMETHOD LoadNextQueuedUrl(nsIImapProtocol* aProtocol, + nsIImapIncomingServer *aInfo); nsIImapMiscellaneousSink* m_realImapMiscellaneousSink; }; @@ -774,4 +777,14 @@ struct ProcessTunnelProxyEvent : public nsImapMiscellaneousSinkProxyEvent TunnelInfo m_tunnelInfo; }; +struct LoadNextQueuedUrlProxyEvent : public nsImapMiscellaneousSinkProxyEvent +{ + LoadNextQueuedUrlProxyEvent(nsImapMiscellaneousSinkProxy* aProxy, + nsIImapIncomingServer *aInfo); + virtual ~LoadNextQueuedUrlProxyEvent(); + NS_IMETHOD HandleEvent(); + nsCOMPtr m_imapIncomingServer; +}; + + #endif