Fixing bug 387712 Add a helper function to nsIMessenger to allow easy listening to attachment saving. r/sr=bienvenu. Tbird trunk only.

git-svn-id: svn://10.0.0.236/trunk@229753 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
nick.kreeger%park.edu 2007-07-11 22:16:04 +00:00
parent 42b5bf378d
commit 71b9537a1f
3 changed files with 101 additions and 83 deletions

View File

@ -47,8 +47,10 @@ interface nsIMsgDBHdr;
interface nsIDOMWindowInternal; interface nsIDOMWindowInternal;
interface nsITransactionManager; interface nsITransactionManager;
interface nsIMsgMessageService; interface nsIMsgMessageService;
interface nsIFile;
interface nsIUrlListener;
[scriptable, uuid(3CFFB7E3-D7C6-4335-8941-7B94BBAFB607)] [scriptable, uuid(BE8C45B1-F810-4B7E-BB44-790B53631D52)]
interface nsIMessenger : nsISupports { interface nsIMessenger : nsISupports {
const long eUnknown = 0; const long eUnknown = 0;
@ -107,6 +109,10 @@ interface nsIMessenger : nsISupports {
void saveAllAttachments(in unsigned long count, [array, size_is(count)] in string contentTypeArray, void saveAllAttachments(in unsigned long count, [array, size_is(count)] in string contentTypeArray,
[array, size_is(count)] in string urlArray, [array, size_is(count)] in string displayNameArray, [array, size_is(count)] in string urlArray, [array, size_is(count)] in string displayNameArray,
[array, size_is(count)] in string messageUriArray); [array, size_is(count)] in string messageUriArray);
void saveAttachmentToFile(in nsIFile aFile, in ACString aUrl, in ACString aMessageUri,
in ACString aContentType, in nsIUrlListener aListener);
void detachAttachment(in string contentTpe, in string url, in string displayName, in string messageUri, in boolean saveFirst); void detachAttachment(in string contentTpe, in string url, in string displayName, in string messageUri, in boolean saveFirst);
void detachAllAttachments(in unsigned long count, [array, size_is(count)] in string contentTypeArray, void detachAllAttachments(in unsigned long count, [array, size_is(count)] in string contentTypeArray,
[array, size_is(count)] in string urlArray, [array, size_is(count)] in string displayNameArray, [array, size_is(count)] in string urlArray, [array, size_is(count)] in string displayNameArray,

View File

@ -238,7 +238,7 @@ class nsSaveMsgListener : public nsIUrlListener,
public nsICancelable public nsICancelable
{ {
public: public:
nsSaveMsgListener(nsIFile* file, nsMessenger* aMessenger); nsSaveMsgListener(nsIFile *file, nsMessenger *aMessenger, nsIUrlListener *aListener);
virtual ~nsSaveMsgListener(); virtual ~nsSaveMsgListener();
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@ -270,6 +270,7 @@ public:
nsCString m_contentType; // used only when saving attachment nsCString m_contentType; // used only when saving attachment
nsCOMPtr<nsITransfer> mTransfer; nsCOMPtr<nsITransfer> mTransfer;
nsCOMPtr<nsIUrlListener> mListener;
PRInt32 mProgress; PRInt32 mProgress;
PRInt32 mContentLength; PRInt32 mContentLength;
PRBool mCanceled; PRBool mCanceled;
@ -680,12 +681,21 @@ nsMessenger::LoadURL(nsIDOMWindowInternal *aWin, const nsACString& aURL)
return mDocShell->LoadURI(uri, loadInfo, 0, PR_TRUE); return mDocShell->LoadURI(uri, loadInfo, 0, PR_TRUE);
} }
nsresult NS_IMETHODIMP nsMessenger::SaveAttachmentToFile(nsIFile *aFile,
nsMessenger::SaveAttachment(nsIFile * aFile, const nsACString &aURL,
const nsACString& aURL, const nsACString &aMessageUri,
const nsACString& aMessageUri, const nsACString &aContentType,
const nsACString& aContentType, nsIUrlListener *aListener)
void *closure) {
return SaveAttachment(aFile, aURL, aMessageUri, aContentType, nsnull, aListener);
}
NS_IMETHODIMP nsMessenger::SaveAttachment(nsIFile *aFile,
const nsACString &aURL,
const nsACString &aMessageUri,
const nsACString &aContentType,
void *closure,
nsIUrlListener *aListener)
{ {
nsIMsgMessageService * messageService = nsnull; nsIMsgMessageService * messageService = nsnull;
nsSaveAllAttachmentsState *saveState= (nsSaveAllAttachmentsState*) closure; nsSaveAllAttachmentsState *saveState= (nsSaveAllAttachmentsState*) closure;
@ -697,7 +707,7 @@ nsMessenger::SaveAttachment(nsIFile * aFile,
// XXX todo // XXX todo
// document the ownership model of saveListener // document the ownership model of saveListener
// whacky ref counting here...what's the deal? when does saveListener get released? it's not clear. // whacky ref counting here...what's the deal? when does saveListener get released? it's not clear.
nsSaveMsgListener *saveListener = new nsSaveMsgListener(aFile, this); nsSaveMsgListener *saveListener = new nsSaveMsgListener(aFile, this, aListener);
if (!saveListener) if (!saveListener)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
@ -771,7 +781,7 @@ nsMessenger::SaveAttachment(nsIFile * aFile,
} }
#endif #endif
if (fetchService) if (fetchService)
rv = fetchService->FetchMimePart(URL, fullMessageUri.get(), convertedListener, mMsgWindow, nsnull,nsnull); rv = fetchService->FetchMimePart(URL, fullMessageUri.get(), convertedListener, mMsgWindow, nsnull, nsnull);
else else
rv = messageService->DisplayMessage(fullMessageUri.get(), convertedListener, mMsgWindow, nsnull, nsnull, nsnull); rv = messageService->DisplayMessage(fullMessageUri.get(), convertedListener, mMsgWindow, nsnull, nsnull, nsnull);
} // if we got a message service } // if we got a message service
@ -828,7 +838,7 @@ nsMessenger::SaveAttachmentToFolder(const nsACString& contentType, const nsACStr
rv = attachmentDestination->AppendNative(unescapedFileName); rv = attachmentDestination->AppendNative(unescapedFileName);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = SaveAttachment(attachmentDestination, url, messageUri, contentType, nsnull); rv = SaveAttachment(attachmentDestination, url, messageUri, contentType, nsnull, nsnull);
attachmentDestination.swap(*aOutFile); attachmentDestination.swap(*aOutFile);
return rv; return rv;
} }
@ -875,7 +885,7 @@ nsMessenger::SaveAttachment(const nsACString& aContentType, const nsACString& aU
SetLastSaveDirectory(localFile); SetLastSaveDirectory(localFile);
rv = SaveAttachment(localFile, aURL, aMessageUri, aContentType, nsnull); rv = SaveAttachment(localFile, aURL, aMessageUri, aContentType, nsnull, nsnull);
return rv; return rv;
} }
@ -948,7 +958,7 @@ nsMessenger::SaveAllAttachments(PRUint32 count,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = SaveAttachment(localFile, nsDependentCString(urlArray[0]), nsDependentCString(messageUriArray[0]), rv = SaveAttachment(localFile, nsDependentCString(urlArray[0]), nsDependentCString(messageUriArray[0]),
nsDependentCString(contentTypeArray[0]), (void *)saveState); nsDependentCString(contentTypeArray[0]), (void *)saveState, nsnull);
return rv; return rv;
} }
@ -1108,7 +1118,7 @@ nsMessenger::SaveAs(const nsACString& aURI, PRBool aAsFile, nsIMsgIdentity *aIde
// XXX todo // XXX todo
// document the ownership model of saveListener // document the ownership model of saveListener
saveListener = new nsSaveMsgListener(localFile, this); saveListener = new nsSaveMsgListener(localFile, this, nsnull);
if (!saveListener) { if (!saveListener) {
rv = NS_ERROR_OUT_OF_MEMORY; rv = NS_ERROR_OUT_OF_MEMORY;
goto done; goto done;
@ -1197,7 +1207,7 @@ nsMessenger::SaveAs(const nsACString& aURI, PRBool aAsFile, nsIMsgIdentity *aIde
// XXX todo // XXX todo
// document the ownership model of saveListener // document the ownership model of saveListener
saveListener = new nsSaveMsgListener(tmpFile, this); saveListener = new nsSaveMsgListener(tmpFile, this, nsnull);
if (!saveListener) { if (!saveListener) {
rv = NS_ERROR_OUT_OF_MEMORY; rv = NS_ERROR_OUT_OF_MEMORY;
goto done; goto done;
@ -1710,10 +1720,11 @@ nsMessenger::SendUnsentMessages(nsIMsgIdentity *aIdentity, nsIMsgWindow *aMsgWin
return NS_OK; return NS_OK;
} }
nsSaveMsgListener::nsSaveMsgListener(nsIFile* aFile, nsMessenger *aMessenger) nsSaveMsgListener::nsSaveMsgListener(nsIFile* aFile, nsMessenger *aMessenger, nsIUrlListener *aListener)
{ {
m_file = do_QueryInterface(aFile); m_file = do_QueryInterface(aFile);
m_messenger = aMessenger; m_messenger = aMessenger;
mListener = aListener;
// rhp: for charset handling // rhp: for charset handling
m_doCharsetConversion = PR_FALSE; m_doCharsetConversion = PR_FALSE;
@ -1751,6 +1762,7 @@ nsSaveMsgListener::Cancel(nsresult status)
NS_IMETHODIMP NS_IMETHODIMP
nsSaveMsgListener::OnStartRunningUrl(nsIURI* url) nsSaveMsgListener::OnStartRunningUrl(nsIURI* url)
{ {
mListener->OnStartRunningUrl(url);
return NS_OK; return NS_OK;
} }
@ -1793,6 +1805,7 @@ done:
if (killSelf) if (killSelf)
Release(); // no more work needs to be done; kill ourself Release(); // no more work needs to be done; kill ourself
mListener->OnStopRunningUrl(url, exitCode);
return rv; return rv;
} }
@ -1923,13 +1936,12 @@ nsSaveMsgListener::OnStartRequest(nsIRequest* request, nsISupports* aSupport)
if (m_messenger) if (m_messenger)
m_messenger->Alert("saveAttachmentFailed"); m_messenger->Alert("saveAttachmentFailed");
} }
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsSaveMsgListener::OnStopRequest(nsIRequest* request, nsISupports* aSupport, nsSaveMsgListener::OnStopRequest(nsIRequest* request, nsISupports* aSupport,
nsresult status) nsresult status)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
@ -1973,56 +1985,55 @@ nsSaveMsgListener::OnStopRequest(nsIRequest* request, nsISupports* aSupport,
if (m_saveAllAttachmentsState) if (m_saveAllAttachmentsState)
{ {
m_saveAllAttachmentsState->m_curIndex++; m_saveAllAttachmentsState->m_curIndex++;
if (!mCanceled && m_saveAllAttachmentsState->m_curIndex < if (!mCanceled && m_saveAllAttachmentsState->m_curIndex < m_saveAllAttachmentsState->m_count)
m_saveAllAttachmentsState->m_count) {
{ nsSaveAllAttachmentsState *state = m_saveAllAttachmentsState;
nsSaveAllAttachmentsState *state = m_saveAllAttachmentsState; PRUint32 i = state->m_curIndex;
PRUint32 i = state->m_curIndex; nsCString unescapedName;
nsCString unescapedName; nsCOMPtr<nsILocalFile> localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
nsCOMPtr<nsILocalFile> localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv); if (NS_FAILED(rv)) goto done;
if (NS_FAILED(rv)) goto done; rv = localFile->InitWithNativePath(nsDependentCString(state->m_directoryName));
rv = localFile->InitWithNativePath(nsDependentCString(state->m_directoryName));
if (NS_FAILED(rv)) goto done; if (NS_FAILED(rv)) goto done;
rv = ConvertAndSanitizeFileName(state->m_displayNameArray[i], nsnull, rv = ConvertAndSanitizeFileName(state->m_displayNameArray[i], nsnull,
getter_Copies(unescapedName)); getter_Copies(unescapedName));
if (NS_FAILED(rv)) if (NS_FAILED(rv))
goto done; goto done;
localFile->AppendNative(unescapedName); localFile->AppendNative(unescapedName);
rv = m_messenger->PromptIfFileExists(localFile); rv = m_messenger->PromptIfFileExists(localFile);
if (NS_FAILED(rv)) goto done; if (NS_FAILED(rv)) goto done;
rv = m_messenger->SaveAttachment(localFile, rv = m_messenger->SaveAttachment(localFile,
nsDependentCString(state->m_urlArray[i]), nsDependentCString(state->m_urlArray[i]),
nsDependentCString(state->m_messageUriArray[i]), nsDependentCString(state->m_messageUriArray[i]),
nsDependentCString(state->m_contentTypeArray[i]), nsDependentCString(state->m_contentTypeArray[i]),
(void *)state); (void *)state, nsnull);
done: done:
if (NS_FAILED(rv)) if (NS_FAILED(rv))
{
delete state;
m_saveAllAttachmentsState = nsnull;
}
}
else
{
// check if we're saving attachments prior to detaching them.
if (m_saveAllAttachmentsState->m_detachingAttachments && !mCanceled)
{ {
nsSaveAllAttachmentsState *state = m_saveAllAttachmentsState; delete state;
m_messenger->DetachAttachments(state->m_count, m_saveAllAttachmentsState = nsnull;
(const char **) state->m_contentTypeArray,
(const char **) state->m_urlArray,
(const char **) state->m_displayNameArray,
(const char **) state->m_messageUriArray,
&state->m_savedFiles);
} }
}
delete m_saveAllAttachmentsState; else
m_saveAllAttachmentsState = nsnull; {
// check if we're saving attachments prior to detaching them.
if (m_saveAllAttachmentsState->m_detachingAttachments && !mCanceled)
{
nsSaveAllAttachmentsState *state = m_saveAllAttachmentsState;
m_messenger->DetachAttachments(state->m_count,
(const char **) state->m_contentTypeArray,
(const char **) state->m_urlArray,
(const char **) state->m_displayNameArray,
(const char **) state->m_messageUriArray,
&state->m_savedFiles);
} }
delete m_saveAllAttachmentsState;
m_saveAllAttachmentsState = nsnull;
}
} }
if(mTransfer) if(mTransfer)

View File

@ -63,22 +63,23 @@ public:
NS_DECL_NSIFOLDERLISTENER NS_DECL_NSIFOLDERLISTENER
nsresult Alert(const char * stringName); nsresult Alert(const char * stringName);
nsresult SaveAttachment(nsIFile *file, const nsACString& unescapedUrl, nsresult SaveAttachment(nsIFile *file, const nsACString& unescapedUrl,
const nsACString& messageUri, const nsACString& contentType, const nsACString& messageUri, const nsACString& contentType,
void *closure); void *closure, nsIUrlListener *aListener);
nsresult PromptIfFileExists(nsILocalFile *file); nsresult PromptIfFileExists(nsILocalFile *file);
nsresult DetachAttachments(PRUint32 aCount, nsresult DetachAttachments(PRUint32 aCount,
const char ** aContentTypeArray, const char ** aContentTypeArray,
const char ** aUrlArray, const char ** aUrlArray,
const char ** aDisplayNameArray, const char ** aDisplayNameArray,
const char ** aMessageUriArray, const char ** aMessageUriArray,
nsCStringArray *saveFileUris); nsCStringArray *saveFileUris);
nsresult SaveAllAttachments(PRUint32 count, nsresult SaveAllAttachments(PRUint32 count,
const char **contentTypeArray, const char **contentTypeArray,
const char **urlArray, const char **urlArray,
const char **displayNameArray, const char **displayNameArray,
const char **messageUriArray, const char **messageUriArray,
PRBool detaching); PRBool detaching);
protected: protected:
nsresult DoDelete(nsIRDFCompositeDataSource* db, nsISupportsArray *srcArray, nsresult DoDelete(nsIRDFCompositeDataSource* db, nsISupportsArray *srcArray,