diff --git a/mailnews/imap/public/nsIImapService.idl b/mailnews/imap/public/nsIImapService.idl index 5f5b9c561616..b2b29dfe91d8 100644 --- a/mailnews/imap/public/nsIImapService.idl +++ b/mailnews/imap/public/nsIImapService.idl @@ -173,6 +173,8 @@ interface nsIImapService : nsISupports out nsIURI aURL, in nsISupports aCopyState); + void downloadMessagesForOffline(in string aMessageIds, in nsIMsgFolder aSrcFolder, + in nsIMsgWindow aMsgWindow); nsIURI moveFolder(in nsIEventQueue aClientEventQueue, in nsIMsgFolder aSrcFolder, in nsIMsgFolder aDstFolder, diff --git a/mailnews/imap/src/nsImapMailFolder.cpp b/mailnews/imap/src/nsImapMailFolder.cpp index 6c158e432ab0..4a7f1dad3547 100644 --- a/mailnews/imap/src/nsImapMailFolder.cpp +++ b/mailnews/imap/src/nsImapMailFolder.cpp @@ -138,6 +138,7 @@ NS_IMPL_QUERY_HEAD(nsImapMailFolder) NS_IMPL_QUERY_BODY(nsIImapMiscellaneousSink) NS_IMPL_QUERY_BODY(nsIUrlListener) NS_IMPL_QUERY_BODY(nsIMsgFilterHitNotify) + NS_IMPL_QUERY_BODY(nsIStreamListener) NS_IMPL_QUERY_TAIL_INHERITING(nsMsgDBFolder) @@ -2942,7 +2943,17 @@ nsImapMailFolder::SetupMsgWriteStream(const char * aNativeString, PRBool addDumm NS_IMETHODIMP nsImapMailFolder::DownloadMessagesForOffline(nsISupportsArray *messages) { - return NS_OK; + nsCAutoString messageIds; + nsMsgKeyArray srcKeyArray; + + nsresult rv = BuildIdsAndKeyArray(messages, messageIds, srcKeyArray); + if (NS_FAILED(rv)) return rv; + NS_WITH_SERVICE(nsIImapService, imapService, kCImapService, &rv); + if (NS_FAILED(rv)) return rv; + + SetNotifyDownloadedLines(PR_TRUE); // ### TODO need to clear this when we've finished + rv = imapService->DownloadMessagesForOffline(messageIds, this, nsnull); + return rv; } NS_IMETHODIMP @@ -3041,16 +3052,16 @@ nsImapMailFolder::NormalEndMsgWriteStream(nsMsgKey uidOfMessage, PRBool markRead if (m_offlineHeader) { - PRUint32 newFlags; - nsCOMPtr randomStore; PRInt32 curStorePos; PRUint32 messageOffset; + nsMsgKey messageKey; - if (m_offlineHeader) + m_offlineHeader->GetMessageKey(&messageKey); + if (m_tempMessageStream) randomStore = do_QueryInterface(m_tempMessageStream); - m_offlineHeader->OrFlags(MSG_FLAG_OFFLINE, &newFlags); + mDatabase->MarkOffline(messageKey, PR_TRUE, nsnull); if (randomStore) { m_tempMessageStream->Flush(); @@ -3456,6 +3467,26 @@ nsImapMailFolder::SetContentModified(nsIImapUrl *aImapUrl, nsImapContentModified return aImapUrl->SetContentModified(modified); } +// we provide this interface (nsIStreamListener) because the nsImapProtocol wants us to, in order +// to hook up the mock channel and other stuff when downloading messages for offline use. +// But we don't really need to do anything with these notifications because we use +// the nsIImapMesageSink interfaces ParseAdoptedMessageLine and NormalEndMsgWriteStream +NS_IMETHODIMP nsImapMailFolder::OnDataAvailable(nsIChannel * /* aChannel */, nsISupports *ctxt, nsIInputStream *aIStream, PRUint32 sourceOffset, PRUint32 aLength) +{ + nsresult rv = NS_OK; + return rv; +} + +NS_IMETHODIMP nsImapMailFolder::OnStartRequest(nsIChannel * aChannel, nsISupports *ctxt) +{ + return NS_OK; +} + +NS_IMETHODIMP nsImapMailFolder::OnStopRequest(nsIChannel * aChannel, nsISupports *ctxt, nsresult aStatus, const PRUnichar *aMsg) +{ + return NS_OK; +} + NS_IMETHODIMP nsImapMailFolder::OnStartRunningUrl(nsIURI *aUrl) { diff --git a/mailnews/imap/src/nsImapMailFolder.h b/mailnews/imap/src/nsImapMailFolder.h index 832a7213225f..325e989cc868 100644 --- a/mailnews/imap/src/nsImapMailFolder.h +++ b/mailnews/imap/src/nsImapMailFolder.h @@ -44,7 +44,7 @@ #include "nsIMsgImapMailFolder.h" #include "nsIImapMailFolderSink.h" #include "nsIImapServerSink.h" - +#include "nsIStreamListener.h" class nsImapMoveCoalescer; @@ -99,7 +99,8 @@ class nsImapMailFolder : public nsMsgDBFolder, public nsIImapExtensionSink, public nsIImapMiscellaneousSink, public nsICopyMessageListener, - public nsIMsgFilterHitNotify + public nsIMsgFilterHitNotify, + public nsIStreamListener { public: nsImapMailFolder(); @@ -195,6 +196,9 @@ public: //nsICopyMessageListener NS_DECL_NSICOPYMESSAGELISTENER + NS_DECL_NSISTREAMOBSERVER + + NS_DECL_NSISTREAMLISTENER // nsIUrlListener methods NS_IMETHOD OnStartRunningUrl(nsIURI * aUrl); NS_IMETHOD OnStopRunningUrl(nsIURI * aUrl, nsresult aExitCode); diff --git a/mailnews/imap/src/nsImapService.cpp b/mailnews/imap/src/nsImapService.cpp index 832e92f5d354..738db6a176d3 100644 --- a/mailnews/imap/src/nsImapService.cpp +++ b/mailnews/imap/src/nsImapService.cpp @@ -878,7 +878,7 @@ NS_IMETHODIMP nsImapService::SaveMessageToDisk(const char *aMessageURI, msgUrl->SetAddDummyEnvelope(aAddDummyEnvelope); msgUrl->SetCanonicalLineEnding(canonicalLineEnding); - return FetchMessage(imapUrl, nsIImapUrl::nsImapSaveMessageToDisk, folder, imapMessageSink, aMsgWindow, aURL, imapMessageSink, msgKey, PR_TRUE); + return FetchMessage(imapUrl, nsIImapUrl::nsImapSaveMessageToDisk, folder, imapMessageSink, aMsgWindow, aURL, nsnull, msgKey, PR_TRUE); } return rv; @@ -3149,3 +3149,29 @@ nsImapService::UnsubscribeFolder(nsIEventQueue* eventQueue, } return rv; } + +NS_IMETHODIMP +nsImapService::DownloadMessagesForOffline(const char *messageIds, nsIMsgFolder *aFolder, nsIMsgWindow *aMsgWindow) +{ + NS_ENSURE_ARG_POINTER(aFolder); + NS_ENSURE_ARG_POINTER(messageIds); + + nsCOMPtr imapUrl; + nsCAutoString urlSpec; + nsresult rv; + PRUnichar hierarchySeparator = GetHierarchyDelimiter(aFolder); + rv = CreateStartOfImapUrl(nsnull, getter_AddRefs(imapUrl), aFolder, nsnull, + urlSpec, hierarchySeparator); + if (NS_SUCCEEDED(rv) && imapUrl) + { + if (NS_SUCCEEDED(rv)) + { + // need to pass in stream listener in order to get the channel created correctly + nsCOMPtr imapMessageSink(do_QueryInterface(aFolder, &rv)); + nsCOMPtr folderStreamListener(do_QueryInterface(aFolder, &rv)); + rv = FetchMessage(imapUrl, nsImapUrl::nsImapMsgFetch,aFolder, imapMessageSink, + aMsgWindow, nsnull, folderStreamListener, messageIds, PR_TRUE); + } + } + return rv; +}