Bug 290648 make nsITransfer::init take an nsICancelable, and remove the observer attribute

r=bz sr=darin a=asa


git-svn-id: svn://10.0.0.236/trunk@172674 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
cbiesinger%web.de
2005-04-24 21:16:28 +00:00
parent 357b714eaf
commit 75f2a6ce48
24 changed files with 264 additions and 560 deletions

View File

@@ -371,11 +371,13 @@ nsresult nsHeaderSniffer::InitiateDownload(nsISupports* inSourceData, nsString&
nsCOMPtr<nsIDownload> downloader = do_CreateInstance(NS_TRANSFER_CONTRACTID);
// dlListener attaches to its progress dialog here, which gains ownership
rv = downloader->Init(inOriginalURI, destURI, inFileName.get(), nsnull, timeNow, webPersist);
rv = downloader->Init(inOriginalURI, destURI, inFileName, nsnull, timeNow, webPersist);
if (NS_FAILED(rv)) return rv;
PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
webPersist->SetPersistFlags(flags);
webPersist->SetProgressListener(downloader);
if (sourceURI)
{

View File

@@ -80,10 +80,8 @@ public:
private:
// These two are mutually exclusive
nsCOMPtr<nsIWebBrowserPersist> mWebPersist; // Our web persist object.
nsCOMPtr<nsIHelperAppLauncher> mHelperAppLauncher; // If we're talking to uriloader
nsCOMPtr<nsICancelable> mCancelable; // Object to cancel the download
nsCOMPtr<nsIURI> mURI; // The URI of our source file. Null if we're saving a complete document.
nsCOMPtr<nsIURI> mDestination; // Our destination URL.
nsCOMPtr<nsILocalFile> mDestinationFile; // Our destination file.

View File

@@ -40,7 +40,6 @@
#import "NSString+Utils.h"
#include "nsDownloadListener.h"
#include "nsIObserver.h"
#include "nsIWebProgress.h"
#include "nsIRequest.h"
@@ -69,10 +68,10 @@ NS_IMPL_ISUPPORTS_INHERITED4(nsDownloadListener, CHDownloader, nsIDownload,
#pragma mark -
/* void init (in nsIURI aSource, in nsIURI aTarget, in wstring aDisplayName, in wstring openingWith, in long long startTime, in nsIWebBrowserPersist aPersist); */
/* void init (in nsIURI aSource, in nsIURI aTarget, in AString aDisplayName, in wstring openingWith, in long long startTime, in nsICancelable aCancelable); */
NS_IMETHODIMP
nsDownloadListener::Init(nsIURI *aSource, nsIURI *aTarget, const PRUnichar *aDisplayName,
nsIMIMEInfo* aMIMEInfo, PRInt64 startTime, nsIWebBrowserPersist *aPersist)
nsDownloadListener::Init(nsIURI *aSource, nsIURI *aTarget, const nsAString &aDisplayName,
nsIMIMEInfo* aMIMEInfo, PRInt64 startTime, nsICancelable* aCancelable)
{
// get the local file corresponding to the given target URI
nsCOMPtr<nsILocalFile> targetFile;
@@ -89,23 +88,19 @@ nsDownloadListener::Init(nsIURI *aSource, nsIURI *aTarget, const PRUnichar *aDis
NS_ENSURE_TRUE(targetFile, NS_ERROR_INVALID_ARG);
CreateDownloadDisplay(); // call the base class to make the download UI
if (aPersist) // only true for File->Save As.
{
mWebPersist = aPersist;
mWebPersist->SetProgressListener(this); // we form a cycle here, since we're a listener.
// we'll break this cycle in DownloadDone()
}
SetIsFileSave(aPersist != NULL);
// Note: This forms a cycle, which will be broken in DownloadDone
mCancelable = aCancelable;
// This is a file save if the cancelable object is a webbrowserpersist
nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(aCancelable));
SetIsFileSave(persist != NULL);
mDestination = aTarget;
mDestinationFile = targetFile;
mURI = aSource;
mStartTime = startTime;
mHelperAppLauncher = nsnull;
InitDialog();
return NS_OK;
}
@@ -128,12 +123,12 @@ nsDownloadListener::GetTarget(nsIURI * *aTarget)
return NS_OK;
}
/* readonly attribute nsIWebBrowserPersist persist; */
/* readonly attribute nsICancelable cancelable; */
NS_IMETHODIMP
nsDownloadListener::GetPersist(nsIWebBrowserPersist * *aPersist)
nsDownloadListener::GetCancelable(nsICancelable * *aCancelable)
{
NS_ENSURE_ARG_POINTER(aPersist);
NS_IF_ADDREF(*aPersist = mWebPersist);
NS_ENSURE_ARG_POINTER(aCancelable);
NS_IF_ADDREF(*aCancelable = mCancelable);
return NS_OK;
}
@@ -182,21 +177,6 @@ nsDownloadListener::GetMIMEInfo(nsIMIMEInfo * *aMIMEInfo)
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute nsIObserver observer; */
NS_IMETHODIMP
nsDownloadListener::GetObserver(nsIObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDownloadListener::SetObserver(nsIObserver * aObserver)
{
if (aObserver)
mHelperAppLauncher = do_QueryInterface(aObserver);
return NS_OK;
}
NS_IMETHODIMP
nsDownloadListener::GetTargetFile(nsILocalFile ** aTargetFile)
{
@@ -344,10 +324,8 @@ nsDownloadListener::CancelDownload()
if (!mSentCancel)
{
if (mWebPersist)
mWebPersist->CancelSave();
else if (mHelperAppLauncher)
mHelperAppLauncher->Cancel(NS_BINDING_ABORTED);
if (mCancelable)
mCancelable->Cancel(NS_BINDING_ABORTED);
mSentCancel = PR_TRUE;
}
@@ -361,12 +339,8 @@ nsDownloadListener::CancelDownload()
void
nsDownloadListener::DownloadDone(nsresult aStatus)
{
// break the reference cycle by removing ourselves as a listener
if (mWebPersist)
{
mWebPersist->SetProgressListener(nsnull);
mWebPersist = nsnull;
}
// break the reference cycle
mCancelable = nsnull;
mHelperAppLauncher = nsnull;
mDownloadStatus = aStatus;

View File

@@ -341,8 +341,10 @@ nsresult nsHeaderSniffer::InitiateDownload(nsISupports* inSourceData, nsString&
nsCOMPtr<nsIDownload> downloader = do_CreateInstance(NS_TRANSFER_CONTRACTID);
// dlListener attaches to its progress dialog here, which gains ownership
rv = downloader->Init(inOriginalURI, destFile, inFileName.get(), nsnull, timeNow, webPersist);
rv = downloader->Init(inOriginalURI, destFile, inFileName, nsnull, timeNow, webPersist);
if (NS_FAILED(rv)) return rv;
webPersist->SetProgressListener(downloader);
PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION |
nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;

View File

@@ -64,21 +64,19 @@ NS_IMPL_ISUPPORTS_INHERITED4(nsDownloadListener, CHDownloader, nsIDownload,
#pragma mark -
/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in wstring openingWith, in long long startTime, in nsIWebBrowserPersist aPersist); */
/* void init (in nsIURI aSource, in nsILocalFile aTarget, in AString aDisplayName, in wstring openingWith, in long long startTime, in nsICancelable aCancelable); */
NS_IMETHODIMP
nsDownloadListener::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName,
nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsIWebBrowserPersist *aPersist)
nsDownloadListener::Init(nsIURI *aSource, nsILocalFile *aTarget, const nsAString &aDisplayName,
nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsICancelable* aCancelable)
{
CreateDownloadDisplay(); // call the base class to make the download UI
if (aPersist) // only true for File->Save As.
{
mWebPersist = aPersist;
mWebPersist->SetProgressListener(this); // we form a cycle here, since we're a listener.
// we'll break this cycle in DownloadDone()
}
SetIsFileSave(aPersist != NULL);
// Note: This forms a cycle, which will be broken in DownloadDone
mCancelable = aCancelable;
// This is a file save if the cancelable object is a webbrowserpersist
nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(aCancelable));
SetIsFileSave(persist != NULL);
mDestination = aTarget;
mURI = aSource;
@@ -106,12 +104,12 @@ nsDownloadListener::GetTarget(nsILocalFile * *aTarget)
return NS_OK;
}
/* readonly attribute nsIWebBrowserPersist persist; */
/* readonly attribute nsICancelable cancelable; */
NS_IMETHODIMP
nsDownloadListener::GetPersist(nsIWebBrowserPersist * *aPersist)
nsDownloadListener::GetCancelable(nsICancelable * *aCancelable)
{
NS_ENSURE_ARG_POINTER(aPersist);
NS_IF_ADDREF(*aPersist = mWebPersist);
NS_ENSURE_ARG_POINTER(aCancelable);
NS_IF_ADDREF(*aCancelable = mCancelable);
return NS_OK;
}
@@ -174,19 +172,6 @@ nsDownloadListener::SetListener(nsIWebProgressListener * aListener)
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute nsIObserver observer; */
NS_IMETHODIMP
nsDownloadListener::GetObserver(nsIObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDownloadListener::SetObserver(nsIObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
#pragma mark -
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */

View File

@@ -44,7 +44,6 @@
#include "nsDirectoryServiceUtils.h"
#include "nsIRequest.h"
#include "netCore.h"
#include "nsIObserver.h"
#include "UDownloadDisplay.h"
#include "UMacUnicode.h"
@@ -76,20 +75,16 @@ NS_IMPL_ISUPPORTS4(CDownload, nsIDownload, nsITransfer,
#pragma mark -
#pragma mark [CDownload::nsIDownload]
/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in nsIMIMEInfo aMIMEInfo, in long long startTime, in nsIWebBrowserPersist aPersist); */
NS_IMETHODIMP CDownload::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName, nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsIWebBrowserPersist *aPersist)
/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in nsIMIMEInfo aMIMEInfo, in long long startTime, in nsICancelable aCancelable); */
NS_IMETHODIMP CDownload::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName, nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsICancelable* aCancelable)
{
try {
mSource = aSource;
mDestination = aTarget;
mStartTime = startTime;
mPercentComplete = 0;
if (aPersist) {
mWebPersist = aPersist;
// We have to break this circular ref when the download is done -
// until nsIWebBrowserPersist supports weak refs - bug #163889.
aPersist->SetProgressListener(this);
}
// We have to break this circular ref when the download is done
mCancelable = aCancelable;
EnsureProgressView();
sProgressView->AddDownloadItem(this);
}
@@ -115,11 +110,11 @@ NS_IMETHODIMP CDownload::GetTarget(nsILocalFile * *aTarget)
return NS_OK;
}
/* readonly attribute nsIWebBrowserPersist persist; */
NS_IMETHODIMP CDownload::GetPersist(nsIWebBrowserPersist * *aPersist)
/* readonly attribute nsICancelable cancelable; */
NS_IMETHODIMP CDownload::GetCancelable(nsIWebBrowserCancelable * *aCancelable)
{
NS_ENSURE_ARG_POINTER(aPersist);
NS_IF_ADDREF(*aPersist = mWebPersist);
NS_ENSURE_ARG_POINTER(aCancelable);
NS_IF_ADDREF(*aCancelable = mCancelable);
return NS_OK;
}
@@ -151,19 +146,6 @@ NS_IMETHODIMP CDownload::GetMIMEInfo(nsIMIMEInfo * *aMIMEInfo)
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute nsIObserver observer; */
NS_IMETHODIMP CDownload::GetObserver(nsIObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP CDownload::SetObserver(nsIObserver * aObserver)
{
if (aObserver)
aObserver->QueryInterface(NS_GET_IID(nsIHelperAppLauncher), getter_AddRefs(mHelperAppLauncher));
return NS_OK;
}
#pragma mark -
#pragma mark [CDownload::nsIWebProgressListener]
@@ -183,11 +165,7 @@ NS_IMETHODIMP CDownload::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest
// We will get this even in the event of a cancel,
if ((aStateFlags & STATE_STOP) && (!mIsNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) {
if (mWebPersist) {
mWebPersist->SetProgressListener(nsnull);
mWebPersist = nsnull;
}
mHelperAppLauncher = nsnull;
mCancelable = nsnull;
BroadcastMessage(msg_OnDLComplete, this);
}
@@ -198,10 +176,7 @@ NS_IMETHODIMP CDownload::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest
NS_IMETHODIMP CDownload::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
{
if (mUserCanceled) {
if (mHelperAppLauncher)
mHelperAppLauncher->Cancel(NS_BINDING_ABORTED);
else if (aRequest)
aRequest->Cancel(NS_BINDING_ABORTED);
mCancelable->Cancel(NS_BINDING_ABORTED);
mUserCanceled = false;
}
if (aMaxTotalProgress == -1)
@@ -251,8 +226,7 @@ void CDownload::Cancel()
mUserCanceled = true;
// nsWebBrowserPersist does the right thing: After canceling, next time through
// OnStateChange(), aStatus != NS_OK. This isn't the case with nsExternalHelperAppService.
if (!mWebPersist)
mStatus = NS_ERROR_ABORT;
mStatus = NS_ERROR_ABORT;
}
void CDownload::CreateProgressView()

View File

@@ -117,9 +117,7 @@ protected:
bool mUserCanceled;
nsresult mStatus;
// These two are mutually exclusive.
nsCOMPtr<nsIWebBrowserPersist> mWebPersist;
nsCOMPtr<nsIHelperAppLauncher> mHelperAppLauncher;
nsCOMPtr<nsICancelable> mCancelable;
static ADownloadProgressView *sProgressView;
};

View File

@@ -40,6 +40,7 @@
#include "nsIDownload.idl"
interface nsIDOMWindow;
interface nsIObserver;
/* nsIProgressDialog
*
@@ -62,7 +63,7 @@ interface nsIDOMWindow;
* not need to hold a reference to it.
*/
[scriptable, uuid(80183bd3-b9e8-45a6-a2ee-1449bc0d4253)]
[scriptable, uuid(20e790a2-76c6-462d-851a-22ab6cbbe48b)]
interface nsIProgressDialog : nsIDownload {
/**
* Open the dialog
@@ -80,6 +81,15 @@ interface nsIProgressDialog : nsIDownload {
*/
attribute PRBool cancelDownloadOnClose;
/**
* Observer for this dialog. If set, receives the following topics:
* oncancel - observer should cancel the transfer
* onpause - observer should suspend the transfer
* onresume - observer should resume the suspended transfer
* For each of those, the subject will be the nsIProgressDialog.
*/
attribute nsIObserver observer;
/**
* The dialog object itself. This might be null if the dialog isn't
* open yet, or has been closed.

View File

@@ -498,7 +498,8 @@ nsProgressDialog.prototype = {
// Cancel the download, if not completed.
if ( !this.completed ) {
if ( this.operation ) {
this.operation.cancelSave();
const NS_BINDING_ABORTED = 0x804b0002;
this.operation.cancel(NS_BINDING_ABORTED);
// XXX We're supposed to clean up files/directories.
}
if ( this.observer ) {

View File

@@ -253,7 +253,7 @@ class nsSaveAllAttachmentsState;
class nsSaveMsgListener : public nsIUrlListener,
public nsIMsgCopyServiceListener,
public nsIStreamListener,
public nsIObserver
public nsICancelable
{
public:
nsSaveMsgListener(nsIFileSpec* fileSpec, nsMessenger* aMessenger);
@@ -265,7 +265,7 @@ public:
NS_DECL_NSIMSGCOPYSERVICELISTENER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSIOBSERVER
NS_DECL_NSICANCELABLE
nsCOMPtr<nsIFileSpec> m_fileSpec;
nsCOMPtr<nsIOutputStream> m_outputStream;
@@ -1714,15 +1714,13 @@ nsSaveMsgListener::~nsSaveMsgListener()
//
// nsISupports
//
NS_IMPL_ISUPPORTS4(nsSaveMsgListener, nsIUrlListener, nsIMsgCopyServiceListener, nsIStreamListener, nsIObserver)
NS_IMPL_ISUPPORTS4(nsSaveMsgListener, nsIUrlListener, nsIMsgCopyServiceListener, nsIStreamListener, nsICancelable)
NS_IMETHODIMP
nsSaveMsgListener::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
nsSaveMsgListener::Cancel(nsresult status)
{
if (!nsCRT::strcmp(aTopic, "oncancel"))
mCanceled = PR_TRUE;
mCanceled = PR_TRUE;
return NS_OK;
}
@@ -1862,9 +1860,8 @@ nsresult nsSaveMsgListener::InitializeDownload(nsIRequest * aRequest, PRInt32 aB
nsCOMPtr<nsIURI> url;
channel->GetURI(getter_AddRefs(url));
rv = tr->Init(url, outputURI, nsnull, mimeinfo, timeDownloadStarted, nsnull);
rv = tr->Init(url, outputURI, EmptyString(), mimeinfo, timeDownloadStarted, this);
tr->SetObserver(this);
// now store the web progresslistener
mTransfer = tr;
}

View File

@@ -45,13 +45,13 @@ interface nsIDOMWindow;
interface nsIURI;
interface nsILocalFile;
interface nsIDownload;
interface nsIWebBrowserPersist;
interface nsICancelable;
interface nsIMIMEInfo;
interface nsIRDFDataSource;
interface nsIDownloadProgressListener;
interface nsISupportsArray;
[scriptable, uuid(9be66cc0-1dd1-11b2-8617-e3a3ed26e3b0)]
[scriptable, uuid(31e8cfdc-52c7-4a36-b1c2-8038a12c271d)]
interface nsIDownloadManager : nsISupports {
// Download States
const short DOWNLOAD_NOTSTARTED = -1;
@@ -68,30 +68,32 @@ interface nsIDownloadManager : nsISupports {
/**
* Creates an nsIDownload and adds it to be managed by the download manager.
*
* @param aSource The source (nsIURI) of the download.
* @param aSource The source URI of the transfer. Must not be null.
*
* @param aTarget The local file to which the download is being saved.
* @param aTarget The target URI of the transfer. Must not be null.
*
* @param aDisplayName The user-readable description of the download.
* @param aDisplayName The user-readable description of the transfer.
* Can be empty.
*
* @param aPersist The "persist" used to transfer the download. If set,
* the manager will set its listener to the download item
* and use it for cancellation. If not set, the client
* is expected to set the download item as the listener on
* whatever transfer component is being used, and to
* set an observer on the download item that listens for
* the "oncancel" topic and cancels the download.
* @param aMIMEInfo The MIME info associated with the target,
* including MIME type and helper app when appropriate.
* This parameter is optional.
*
* @param startTime Time when the download started
*
* @param aCancelable An object that can be used to abort the download.
* Must not be null.
*
* @return The newly created download item with the passed-in properties.
*/
nsIDownload addDownload(in short aDownloadType,
in nsIURI aSource,
in nsIURI aTarget,
in wstring aDisplayName,
in wstring aIconURL,
in AString aDisplayName,
in AString aIconURL,
in nsIMIMEInfo aMIMEInfo,
in long long aStartTime,
in nsIWebBrowserPersist aPersist);
in PRTime aStartTime,
in nsICancelable aCancelable);
/**
* Retrieves an in-progress download managed by the download manager.
@@ -108,11 +110,8 @@ interface nsIDownloadManager : nsISupports {
/**
* Cancels the download with the specified persistent descriptor if it's
* currently in progress. If a "persist" was specified for the download,
* nsIWebBrowserPersist::CancelSave will be called. If an observer was set
* on the nsIDownload, it will be notified with the "oncancel" topic. Clients
* that don't provide a "persist" must listen for this topic and cancel the
* download.
* currently in progress. This calls cancel(NS_BINDING_ABORTED) on the
* nsICancelable provided for the download.
*
* @param aPersistentDescriptor The persistent descriptor of the download to
* be cancelled.

View File

@@ -495,11 +495,11 @@ NS_IMETHODIMP
nsDownloadManager::AddDownload(DownloadType aDownloadType,
nsIURI* aSource,
nsIURI* aTarget,
const PRUnichar* aDisplayName,
const PRUnichar* aIconURL,
const nsAString& aDisplayName,
const nsAString& aIconURL,
nsIMIMEInfo *aMIMEInfo,
PRInt64 aStartTime,
nsIWebBrowserPersist* aPersist,
PRTime aStartTime,
nsICancelable* aCancelable,
nsIDownload** aDownload)
{
NS_ENSURE_ARG_POINTER(aSource);
@@ -610,10 +610,9 @@ nsDownloadManager::AddDownload(DownloadType aDownloadType,
}
// Assert icon information
if (aIconURL) {
if (!aIconURL.IsEmpty()) {
nsCOMPtr<nsIRDFResource> iconURIRes;
nsDependentString iconURL(aIconURL);
gRDFService->GetUnicodeResource(iconURL, getter_AddRefs(iconURIRes));
gRDFService->GetUnicodeResource(aIconURL, getter_AddRefs(iconURIRes));
mDataSource->GetTarget(downloadRes, gNC_IconURL, PR_TRUE, getter_AddRefs(node));
if (node)
rv = mDataSource->Change(downloadRes, gNC_IconURL, node, iconURIRes);
@@ -655,13 +654,8 @@ nsDownloadManager::AddDownload(DownloadType aDownloadType,
return rv;
}
// if a persist object was specified, set the download item as the progress listener
// this will create a cycle that will be broken in nsDownload::OnStateChange
if (aPersist) {
internalDownload->SetPersist(aPersist);
nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(*aDownload);
aPersist->SetProgressListener(listener);
}
internalDownload->SetCancelable(aCancelable);
// If this is an install operation, ensure we have a progress listener for the
// install and track this download separately.
@@ -717,23 +711,11 @@ nsDownloadManager::CancelDownload(const PRUnichar* aPath)
internalDownload->SetDownloadState(nsIDownloadManager::DOWNLOAD_CANCELED);
// if a persist was provided, we can do the cancel ourselves.
nsCOMPtr<nsIWebBrowserPersist> persist;
internalDownload->GetPersist(getter_AddRefs(persist));
if (persist) {
rv = persist->CancelSave();
if (NS_FAILED(rv)) return rv;
}
// if an observer was provided, notify that the download was cancelled.
// if no persist was provided, this is necessary so that whatever transfer
// component being used can cancel the download itself.
nsCOMPtr<nsIObserver> observer;
internalDownload->GetObserver(getter_AddRefs(observer));
if (observer) {
rv = observer->Observe(internalDownload, "oncancel", nsnull);
if (NS_FAILED(rv)) return rv;
}
// Cancel using the provided object
nsCOMPtr<nsICancelable> cancelable;
internalDownload->GetCancelable(getter_AddRefs(cancelable));
if (cancelable)
cancelable->Cancel(NS_BINDING_ABORTED);
DownloadEnded(aPath, nsnull);
@@ -744,7 +726,7 @@ nsDownloadManager::CancelDownload(const PRUnichar* aPath)
nsCOMPtr<nsIProgressDialog> dialog;
internalDownload->GetDialog(getter_AddRefs(dialog));
if (dialog) {
observer = do_QueryInterface(dialog);
nsCOMPtr<nsIObserver> observer = do_QueryInterface(dialog);
rv = observer->Observe(internalDownload, "oncancel", nsnull);
if (NS_FAILED(rv)) return rv;
}
@@ -1878,9 +1860,9 @@ nsDownload::SetDownloadType(DownloadType aType)
}
nsresult
nsDownload::SetPersist(nsIWebBrowserPersist* aPersist)
nsDownload::SetCancelable(nsICancelable* aCancelable)
{
mPersist = aPersist;
mCancelable = aCancelable;
return NS_OK;
}
@@ -2066,7 +2048,7 @@ nsDownload::OnStateChange(nsIWebProgress* aWebProgress,
if (aStateFlags & STATE_START)
mStartTime = PR_Now();
// When we break the ref cycle with mPersist, we don't want to lose
// When we break the ref cycle with mCancelable, we don't want to lose
// access to out member vars!
nsCOMPtr<nsIDownload> kungFuDeathGrip;
CallQueryInterface(this, NS_STATIC_CAST(nsIDownload**,
@@ -2141,8 +2123,7 @@ nsDownload::OnStateChange(nsIWebProgress* aWebProgress,
gObserverService->NotifyObservers(NS_STATIC_CAST(nsIDownload *, this), "dl-done", nsnull);
// break the cycle we created in AddDownload
if (mPersist)
mPersist->SetProgressListener(nsnull);
mCancelable = nsnull;
// Now remove the download if the user's retention policy is "Remove when Done"
if (mDownloadManager->GetRetentionBehavior() == 0) {
@@ -2177,10 +2158,10 @@ nsDownload::OnSecurityChange(nsIWebProgress *aWebProgress,
NS_IMETHODIMP
nsDownload::Init(nsIURI* aSource,
nsIURI* aTarget,
const PRUnichar* aDisplayName,
const nsAString& aDisplayName,
nsIMIMEInfo *aMIMEInfo,
PRInt64 aStartTime,
nsIWebBrowserPersist* aPersist)
PRTime aStartTime,
nsICancelable* aCancelable)
{
NS_WARNING("Huh...how did we get here?!");
return NS_OK;
@@ -2193,6 +2174,14 @@ nsDownload::GetDisplayName(PRUnichar** aDisplayName)
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetCancelable(nsICancelable** aCancelable)
{
*aCancelable = mCancelable;
NS_IF_ADDREF(*aCancelable);
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetTarget(nsIURI** aTarget)
{
@@ -2209,14 +2198,6 @@ nsDownload::GetSource(nsIURI** aSource)
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetPersist(nsIWebBrowserPersist** aPersist)
{
*aPersist = mPersist;
NS_IF_ADDREF(*aPersist);
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetStartTime(PRInt64* aStartTime)
{
@@ -2245,21 +2226,6 @@ nsDownload::GetSize(PRUint64* aSize)
return NS_OK;
}
NS_IMETHODIMP
nsDownload::SetObserver(nsIObserver* aObserver)
{
mObserver = aObserver;
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetObserver(nsIObserver** aObserver)
{
*aObserver = mObserver;
NS_IF_ADDREF(*aObserver);
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetMIMEInfo(nsIMIMEInfo** aMIMEInfo)
{

View File

@@ -219,7 +219,7 @@ protected:
nsresult GetDialogListener(nsIWebProgressListener** aInternalListener);
nsresult SetDialog(nsIProgressDialog* aDialog);
nsresult GetDialog(nsIProgressDialog** aDialog);
nsresult SetPersist(nsIWebBrowserPersist* aPersist);
nsresult SetCancelable(nsICancelable* aCancelable);
nsresult SetTarget(nsIURI* aTarget);
nsresult SetDisplayName(const PRUnichar* aDisplayName);
nsresult SetSource(nsIURI* aSource);
@@ -238,10 +238,9 @@ private:
nsCOMPtr<nsIURI> mSource;
nsCOMPtr<nsIWebProgressListener> mDialogListener;
nsCOMPtr<nsIWebBrowserPersist> mPersist;
nsCOMPtr<nsICancelable> mCancelable;
nsCOMPtr<nsIRequest> mRequest;
nsCOMPtr<nsIProgressDialog> mDialog;
nsCOMPtr<nsIObserver> mObserver;
nsCOMPtr<nsIMIMEInfo> mMIMEInfo;
DownloadState mDownloadState;

View File

@@ -60,18 +60,18 @@ public:
NS_IMETHODIMP Init(nsIURI* aSource,
nsIURI* aTarget,
const PRUnichar* aDisplayName,
const nsAString& aDisplayName,
nsIMIMEInfo *aMIMEInfo,
PRInt64 aStartTime,
nsIWebBrowserPersist* aPersist) {
PRTime aStartTime,
nsICancelable* aCancelable) {
nsresult rv;
nsCOMPtr<nsIDownloadManager> dm = do_GetService("@mozilla.org/download-manager;1", &rv);
if (NS_FAILED(rv))
return rv;
rv = dm->AddDownload(nsIDownloadManager::DOWNLOAD_TYPE_DOWNLOAD, aSource, aTarget,
aDisplayName, nsnull, aMIMEInfo, aStartTime, aPersist,
getter_AddRefs(mInner));
rv = dm->AddDownload(nsIDownloadManager::DOWNLOAD_TYPE_DOWNLOAD, aSource,
aTarget, aDisplayName, EmptyString(), aMIMEInfo,
aStartTime, aCancelable, getter_AddRefs(mInner));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
@@ -142,19 +142,9 @@ public:
return mInner->GetSize(aSize);
}
NS_IMETHODIMP GetObserver(nsIObserver** aObserver)
NS_IMETHODIMP GetCancelable(nsICancelable** aCancelable)
{
return mInner->GetObserver(aObserver);
}
NS_IMETHODIMP SetObserver(nsIObserver* aObserver)
{
return mInner->SetObserver(aObserver);
}
NS_IMETHODIMP GetPersist(nsIWebBrowserPersist** aPersist)
{
return mInner->GetPersist(aPersist);
return mInner->GetCancelable(aCancelable);
}
NS_IMETHODIMP GetTargetFile(nsILocalFile** aTargetFile)

View File

@@ -353,11 +353,13 @@ function foundHeaderInfo(aSniffer, aData, aSkipPrompt)
}
const kWrapColumn = 80;
tr.init(aSniffer.uri, persistArgs.target, null, null, null, persist);
tr.init(aSniffer.uri, persistArgs.target, "", null, null, persist);
persist.progressListener = tr;
persist.saveDocument(persistArgs.source, persistArgs.target, filesFolder,
persistArgs.contentType, encodingFlags, kWrapColumn);
} else {
tr.init(source, persistArgs.target, null, null, null, persist);
tr.init(source, persistArgs.target, null, "", null, persist);
persist.progressListener = tr;
var referrer = aData.referrer || getReferrer(document)
persist.saveURI(source, null, referrer, persistArgs.postData, null, persistArgs.target);
}

View File

@@ -41,11 +41,11 @@
interface nsIURI;
interface nsILocalFile;
interface nsIObserver;
interface nsIWebBrowserPersist;
interface nsICancelable;
interface nsIWebProgressListener;
interface nsIMIMEInfo;
[scriptable, uuid(4584178b-ebbd-4d5e-91d3-aa676c2291d2)]
[scriptable, uuid(1cb42fb4-f092-4a0e-8930-6c06a524da07)]
interface nsIDownload : nsITransfer {
/**
@@ -81,13 +81,10 @@ interface nsIDownload : nsITransfer {
readonly attribute nsIURI target;
/**
* Optional. If set, it will be used for cancellation, and the transfer
* will be set as its listener. If not, |observer| should be set to listen
* and respond accordingly to topics like oncancel, and the client promises
* to set the transfer item as the listener for whatever transfer component
* is being used.
* Object that can be used to cancel the download.
* Will be null after the download is finished.
*/
readonly attribute nsIWebBrowserPersist persist;
readonly attribute nsICancelable cancelable;
/**
* The user-readable description of the transfer.

View File

@@ -39,47 +39,44 @@
#include "nsIWebProgressListener2.idl"
interface nsIURI;
interface nsIObserver;
interface nsIWebBrowserPersist;
interface nsICancelable;
interface nsIMIMEInfo;
[scriptable, uuid(4af66079-938d-4093-9cc4-561dac709c7b)]
[scriptable, uuid(0721AAF2-28AC-46cd-BCFA-5F8CA2A8B99B)]
interface nsITransfer : nsIWebProgressListener2 {
/**
* Initializes the transfer with certain properties. This function must
* be called prior to accessing any properties on this interface.
*
* @param aSource The source URI of the transfer.
* @param aSource The source URI of the transfer. Must not be null.
*
* @param aTarget The target URI of the transfer.
* @param aTarget The target URI of the transfer. Must not be null.
*
* @param aDisplayName The user-readable description of the transfer.
* Can be empty.
*
* @param aMIMEInfo The MIME info associated with the target,
* including MIME type and helper app when appropriate.
* This parameter is optional.
*
* @param aPersist The "persist" used for this transfer. If set,
* the manager will set its listener to the transfer item
* and use it for cancellation. If not set, the client
* is expected to set the transfer item as the listener on
* whatever transfer component is being used, and to
* set an observer on the transfer item that listens for
* the "oncancel" topic and cancels the transfer.
* @param startTime Time when the download started (ie, when the first
* response from the server was received)
* XXX presumably wbp and exthandler do this differently
*
* @param aCancelable An object that can be used to abort the download.
* Must not be null.
* Implementations are expected to hold a strong
* reference to this object until the download is
* finished, at which point they should release the
* reference.
*/
void init(in nsIURI aSource,
in nsIURI aTarget,
in wstring aDisplayName,
in AString aDisplayName,
in nsIMIMEInfo aMIMEInfo,
in long long startTime,
in nsIWebBrowserPersist aPersist);
/**
* If set, receives notifications of events like cancel ("oncancel").
* Must be set if no persist object is specified (see above).
*/
attribute nsIObserver observer;
in PRTime startTime,
in nsICancelable aCancelable);
};
%{C++
@@ -88,7 +85,7 @@ interface nsITransfer : nsIWebProgressListener2 {
* started, and nsITransfer::Init will be called on it and an observer will be set.
*
* Notifications of the download progress will happen via
* nsIWebProgressListener.
* nsIWebProgressListener/nsIWebProgressListener2.
*
* If nsIObserver is implemented, the component may get a notification with
* topic "temp-file" and an nsILocalFile instance as subject, which indicates
@@ -98,9 +95,13 @@ interface nsITransfer : nsIWebProgressListener2 {
* INTERFACES THAT MUST BE IMPLEMENTED:
* nsITransfer
* nsIWebProgressListener
* nsIWebProgressListener2
*
* INTERFACES THAT MAY BE IMPLEMENTED:
* nsIObserver
*
* XXX move this to nsEmbedCID.h once the interfaces (and the contract ID) are
* frozen.
*/
#define NS_TRANSFER_CONTRACTID "@mozilla.org/transfer;1"
%}

View File

@@ -1348,7 +1348,6 @@ NS_INTERFACE_MAP_BEGIN(nsExternalAppHandler)
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
NS_INTERFACE_MAP_ENTRY(nsIHelperAppLauncher)
NS_INTERFACE_MAP_ENTRY(nsICancelable)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_END_THREADSAFE
nsExternalAppHandler::nsExternalAppHandler(nsIMIMEInfo * aMIMEInfo,
@@ -1390,17 +1389,6 @@ nsExternalAppHandler::~nsExternalAppHandler()
sSrv->Release();
}
NS_IMETHODIMP nsExternalAppHandler::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData )
{
if (strcmp(aTopic, "oncancel") == 0)
{
// User pressed cancel button on dialog.
return Cancel(NS_BINDING_ABORTED);
}
return NS_OK;
}
NS_IMETHODIMP nsExternalAppHandler::SetWebProgressListener(nsIWebProgressListener2 * aWebProgressListener)
{
// this call back means we've succesfully brought up the
@@ -2013,9 +2001,6 @@ NS_IMETHODIMP nsExternalAppHandler::OnStopRequest(nsIRequest *request, nsISuppor
// This nsITransfer object holds a reference to us (we are its observer), so
// we need to release the reference to break a reference cycle (and therefore
// to prevent leaking)
nsCOMPtr<nsITransfer> tr(do_QueryInterface(mWebProgressListener));
if (tr)
tr->SetObserver(nsnull);
mWebProgressListener = nsnull;
return NS_OK;
@@ -2100,11 +2085,9 @@ nsresult nsExternalAppHandler::InitializeDownload(nsITransfer* aTransfer)
rv = NS_NewFileURI(getter_AddRefs(target), mFinalFileDestination);
if (NS_FAILED(rv)) return rv;
rv = aTransfer->Init(mSourceUrl, target, nsnull,
mMimeInfo, mTimeDownloadStarted, nsnull);
rv = aTransfer->Init(mSourceUrl, target, EmptyString(),
mMimeInfo, mTimeDownloadStarted, this);
if (NS_FAILED(rv)) return rv;
rv = aTransfer->SetObserver(this);
// Tell the listener about the location of the target file
nsCOMPtr<nsIObserver> obs(do_QueryInterface(aTransfer));
@@ -2457,9 +2440,6 @@ NS_IMETHODIMP nsExternalAppHandler::Cancel(nsresult aReason)
// Release the listener, to break the reference cycle with it (we are the
// observer of the listener).
nsCOMPtr<nsITransfer> tr(do_QueryInterface(mWebProgressListener));
if (tr)
tr->SetObserver(nsnull);
mWebProgressListener = nsnull;
return NS_OK;

View File

@@ -321,8 +321,7 @@ protected:
* data using a helper app.
*/
class nsExternalAppHandler : public nsIStreamListener,
public nsIHelperAppLauncher,
public nsIObserver
public nsIHelperAppLauncher
{
public:
NS_DECL_ISUPPORTS
@@ -330,7 +329,6 @@ public:
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSIHELPERAPPLAUNCHER
NS_DECL_NSICANCELABLE
NS_DECL_NSIOBSERVER
/**
* @param aMIMEInfo MIMEInfo object, representing the type of the

View File

@@ -416,12 +416,14 @@ function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition,
const kWrapColumn = 80;
tr.init((aChosenData ? aChosenData.uri : fileInfo.uri),
persistArgs.target, null, null, null, persist);
persistArgs.target, "", null, null, persist);
persist.progressListener = tr;
persist.saveDocument(persistArgs.source, persistArgs.target, filesFolder,
persistArgs.contentType, encodingFlags, kWrapColumn);
} else {
tr.init((aChosenData ? aChosenData.uri : source),
persistArgs.target, null, null, null, persist);
persistArgs.target, "", null, null, persist);
persist.progressListener = tr;
var referer = aReferrer || getReferrer(document);
persist.saveURI((aChosenData ? aChosenData.uri : source),
null, referer, persistArgs.postData, null, persistArgs.target);

View File

@@ -46,10 +46,10 @@ interface nsIDOMWindow;
interface nsIURI;
interface nsILocalFile;
interface nsIDownload;
interface nsIWebBrowserPersist;
interface nsICancelable;
interface nsIMIMEInfo;
[scriptable, uuid(17d403cc-364a-482c-b77e-914a0ecbf7a1)]
[scriptable, uuid(db2eb695-ebb3-4296-9f52-41ddcfce4ca3)]
interface nsIDownloadManager : nsISupports {
// Methods called by clients to carry out various managing functions
@@ -57,28 +57,31 @@ interface nsIDownloadManager : nsISupports {
/**
* Creates an nsIDownload and adds it to be managed by the download manager.
*
* @param aSource The source (nsIURI) of the download.
* @param aSource The source URI of the transfer. Must not be null.
*
* @param aTarget The local file to which the download is being saved.
* @param aTarget The target URI of the transfer. Must not be null.
*
* @param aDisplayName The user-readable description of the download.
* @param aDisplayName The user-readable description of the transfer.
* Can be empty.
*
* @param aPersist The "persist" used to transfer the download. If set,
* the manager will set its listener to the download item
* and use it for cancellation. If not set, the client
* is expected to set the download item as the listener on
* whatever transfer component is being used, and to
* set an observer on the download item that listens for
* the "oncancel" topic and cancels the download.
* @param aMIMEInfo The MIME info associated with the target,
* including MIME type and helper app when appropriate.
* This parameter is optional.
*
* @param startTime Time when the download started (ie, when the first
* response from the server was received)
*
* @param aCancelable An object that can be used to abort the download.
* Must not be null.
* @return The newly created download item with the passed-in properties.
*/
nsIDownload addDownload(in nsIURI aSource,
in nsIURI aTarget,
in wstring aDisplayName,
in AString aDisplayName,
in nsIMIMEInfo aMIMEInfo,
in long long startTime,
in nsIWebBrowserPersist aPersist);
in PRTime startTime,
in nsICancelable aCancelable);
/**
* Retrieves an in-progress download managed by the download manager.

View File

@@ -432,10 +432,10 @@ nsDownloadManager::AssertProgressInfoFor(const nsACString& aTargetPath)
NS_IMETHODIMP
nsDownloadManager::AddDownload(nsIURI* aSource,
nsIURI* aTarget,
const PRUnichar* aDisplayName,
const nsAString& aDisplayName,
nsIMIMEInfo *aMIMEInfo,
PRInt64 aStartTime,
nsIWebBrowserPersist* aPersist,
PRTime aStartTime,
nsICancelable* aCancelable,
nsIDownload** aDownload)
{
NS_ENSURE_ARG_POINTER(aSource);
@@ -446,7 +446,8 @@ nsDownloadManager::AddDownload(nsIURI* aSource,
nsresult rv = GetDownloadsContainer(getter_AddRefs(downloads));
if (NS_FAILED(rv)) return rv;
nsDownload* internalDownload = new nsDownload(this, aTarget, aSource);
// this will create a cycle that will be broken in nsDownload::OnStateChange
nsDownload* internalDownload = new nsDownload(this, aTarget, aSource, aCancelable);
if (!internalDownload)
return NS_ERROR_OUT_OF_MEMORY;
@@ -528,13 +529,6 @@ nsDownloadManager::AddDownload(nsIURI* aSource,
rv = remote->Flush();
if (NS_FAILED(rv)) return rv;
// if a persist object was specified, set the download item as the progress listener
// this will create a cycle that will be broken in nsDownload::OnStateChange
if (aPersist) {
internalDownload->SetPersist(aPersist);
aPersist->SetProgressListener(internalDownload);
}
mCurrDownloads.Put(utf8Path, internalDownload);
return rv;
@@ -555,45 +549,11 @@ nsDownloadManager::GetDownload(const nsACString & aTargetPath, nsIDownload** aDo
NS_IMETHODIMP
nsDownloadManager::CancelDownload(const nsACString & aTargetPath)
{
nsresult rv = NS_OK;
nsRefPtr<nsDownload> internalDownload = mCurrDownloads.GetWeak(aTargetPath);
if (!internalDownload)
return NS_ERROR_FAILURE;
// Don't cancel if download is already finished
if (internalDownload->GetDownloadState() == FINISHED)
return NS_OK;
internalDownload->SetDownloadState(CANCELED);
// if a persist was provided, we can do the cancel ourselves.
nsCOMPtr<nsIWebBrowserPersist> persist;
internalDownload->GetPersist(getter_AddRefs(persist));
if (persist) {
rv = persist->CancelSave();
if (NS_FAILED(rv)) return rv;
}
// if an observer was provided, notify that the download was cancelled.
// if no persist was provided, this is necessary so that whatever transfer
// component being used can cancel the download itself.
nsCOMPtr<nsIObserver> observer;
internalDownload->GetObserver(getter_AddRefs(observer));
if (observer) {
rv = observer->Observe(NS_STATIC_CAST(nsIDownload*, internalDownload), "oncancel", nsnull);
if (NS_FAILED(rv)) return rv;
}
DownloadEnded(aTargetPath, nsnull);
// if there's a progress dialog open for the item,
// we have to notify it that we're cancelling
observer = do_QueryInterface(internalDownload->GetDialog());
if (observer) {
rv = observer->Observe(NS_STATIC_CAST(nsIDownload*, internalDownload), "oncancel", nsnull);
}
return rv;
return internalDownload->Cancel();
}
NS_IMETHODIMP
@@ -801,7 +761,7 @@ nsDownloadManager::OpenProgressDialogFor(nsIDownload* aDownload, nsIDOMWindow* a
nsCOMPtr<nsIMIMEInfo> mimeInfo;
aDownload->GetMIMEInfo(getter_AddRefs(mimeInfo));
dialog->Init(source, target, nsnull, mimeInfo, startTime, nsnull);
dialog->Init(source, target, EmptyString(), mimeInfo, startTime, nsnull);
dialog->SetObserver(internalDownload);
// now set the listener so we forward notifications to the dialog
@@ -927,10 +887,12 @@ NS_IMPL_ISUPPORTS5(nsDownload, nsIDownload, nsITransfer, nsIWebProgressListener,
nsDownload::nsDownload(nsDownloadManager* aManager,
nsIURI* aTarget,
nsIURI* aSource) :
nsIURI* aSource,
nsICancelable* aCancelable) :
mDownloadManager(aManager),
mTarget(aTarget),
mSource(aSource),
mCancelable(aCancelable),
mDownloadState(NOTSTARTED),
mPercentComplete(0),
mCurrBytes(0),
@@ -957,6 +919,35 @@ nsDownload::Suspend()
return mRequest->Suspend();
}
nsresult
nsDownload::Cancel()
{
// Don't cancel if download is already finished or canceled
if (GetDownloadState() == FINISHED || GetDownloadState() == CANCELED)
return NS_OK;
nsresult rv = mCancelable->Cancel(NS_BINDING_ABORTED);
if (NS_FAILED(rv))
return rv;
SetDownloadState(CANCELED);
nsCAutoString path;
rv = GetFilePathUTF8(mTarget, path);
if (NS_FAILED(rv))
return rv;
mDownloadManager->DownloadEnded(path, nsnull);
// if there's a progress dialog open for the item,
// we have to notify it that we're cancelling
nsCOMPtr<nsIObserver> observer = do_QueryInterface(GetDialog());
if (observer) {
rv = observer->Observe(NS_STATIC_CAST(nsIDownload*, this), "oncancel", nsnull);
}
return rv;
}
nsresult
nsDownload::SetDisplayName(const PRUnichar* aDisplayName)
{
@@ -1001,11 +992,7 @@ nsDownload::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar*
if (strcmp(aTopic, "oncancel") == 0) {
SetDialog(nsnull);
nsCAutoString path;
nsresult rv = GetFilePathUTF8(mTarget, path);
// XXX why can't nsDownload cancel itself without help from the dl manager?
if (NS_SUCCEEDED(rv))
mDownloadManager->CancelDownload(path);
Cancel();
// Ignoring return value; this function will get called twice,
// and bad things happen if we return a failure code the second time.
return NS_OK;
@@ -1268,8 +1255,12 @@ nsDownload::OnStateChange(nsIWebProgress* aWebProgress,
}
// break the cycle we created in AddDownload
if (mPersist)
mPersist->SetProgressListener(nsnull);
mCancelable = nsnull;
// and the one with the progress dialog
if (mDialog) {
mDialog->SetObserver(nsnull);
mDialog = nsnull;
}
}
if (mDownloadManager->MustUpdateUI()) {
@@ -1279,8 +1270,13 @@ nsDownload::OnStateChange(nsIWebProgress* aWebProgress,
internalListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus, this);
}
if (mDialogListener)
if (mDialogListener) {
mDialogListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
if (aStateFlags & STATE_STOP) {
// Break this cycle, too
mDialogListener = nsnull;
}
}
return rv;
}
@@ -1308,12 +1304,12 @@ nsDownload::OnSecurityChange(nsIWebProgress *aWebProgress,
NS_IMETHODIMP
nsDownload::Init(nsIURI* aSource,
nsIURI* aTarget,
const PRUnichar* aDisplayName,
const nsAString& aDisplayName,
nsIMIMEInfo *aMIMEInfo,
PRInt64 aStartTime,
nsIWebBrowserPersist* aPersist)
PRTime aStartTime,
nsICancelable* aCancelable)
{
NS_WARNING("Huh...how did we get here?!");
NS_NOTREACHED("Huh...how did we get here?!");
return NS_OK;
}
@@ -1324,6 +1320,14 @@ nsDownload::GetDisplayName(PRUnichar** aDisplayName)
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetCancelable(nsICancelable** aCancelable)
{
*aCancelable = mCancelable;
NS_IF_ADDREF(*aCancelable);
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetTarget(nsIURI** aTarget)
{
@@ -1340,14 +1344,6 @@ nsDownload::GetSource(nsIURI** aSource)
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetPersist(nsIWebBrowserPersist** aPersist)
{
*aPersist = mPersist;
NS_IF_ADDREF(*aPersist);
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetStartTime(PRInt64* aStartTime)
{
@@ -1376,21 +1372,6 @@ nsDownload::GetSize(PRUint64* aSize)
return NS_OK;
}
NS_IMETHODIMP
nsDownload::SetObserver(nsIObserver* aObserver)
{
mObserver = aObserver;
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetObserver(nsIObserver** aObserver)
{
*aObserver = mObserver;
NS_IF_ADDREF(*aObserver);
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetMIMEInfo(nsIMIMEInfo** aMIMEInfo)
{

View File

@@ -51,7 +51,6 @@
#include "nsIRDFContainerUtils.h"
#include "nsIWebProgressListener.h"
#include "nsIURI.h"
#include "nsIWebBrowserPersist.h"
#include "nsILocalFile.h"
#include "nsRefPtrHashtable.h"
#include "nsIRequest.h"
@@ -114,9 +113,11 @@ public:
NS_DECL_NSIOBSERVER
NS_DECL_ISUPPORTS
nsDownload(nsDownloadManager* aManager, nsIURI* aTarget, nsIURI* aSource);
nsDownload(nsDownloadManager* aManager, nsIURI* aTarget, nsIURI* aSource,
nsICancelable* aCancelable);
~nsDownload();
nsresult Cancel();
nsresult Suspend();
nsresult SetDisplayName(const PRUnichar* aDisplayName);
nsresult Resume();
@@ -132,9 +133,6 @@ public:
nsIProgressDialog* GetDialog() {
return mDialog;
}
void SetPersist(nsIWebBrowserPersist* aPersist) {
mPersist = aPersist;
}
struct TransferInformation {
PRInt32 mCurrBytes, mMaxBytes;
@@ -167,10 +165,9 @@ private:
nsCOMPtr<nsIURI> mTarget;
nsCOMPtr<nsIURI> mSource;
nsCOMPtr<nsIWebProgressListener2> mDialogListener;
nsCOMPtr<nsIWebBrowserPersist> mPersist;
nsCOMPtr<nsICancelable> mCancelable;
nsCOMPtr<nsIRequest> mRequest;
nsCOMPtr<nsIProgressDialog> mDialog;
nsCOMPtr<nsIObserver> mObserver;
nsCOMPtr<nsIMIMEInfo> mMIMEInfo;
DownloadState mDownloadState;

View File

@@ -39,6 +39,7 @@
#ifndef downloadproxy___h___
#define downloadproxy___h___
#include "nsCOMPtr.h"
#include "nsIDownload.h"
#include "nsIDownloadManager.h"
#include "nsIPrefBranch.h"
@@ -47,7 +48,7 @@
#define DOWNLOAD_MANAGER_BEHAVIOR_PREF "browser.downloadmanager.behavior"
class nsDownloadProxy : public nsIDownload
class nsDownloadProxy : public nsITransfer
{
public:
@@ -55,19 +56,21 @@ public:
virtual ~nsDownloadProxy() { }
NS_DECL_ISUPPORTS
NS_FORWARD_SAFE_NSIWEBPROGRESSLISTENER(mInner)
NS_FORWARD_SAFE_NSIWEBPROGRESSLISTENER2(mInner)
NS_IMETHODIMP Init(nsIURI* aSource,
nsIURI* aTarget,
const PRUnichar* aDisplayName,
const nsAString& aDisplayName,
nsIMIMEInfo *aMIMEInfo,
PRInt64 aStartTime,
nsIWebBrowserPersist* aPersist) {
PRTime aStartTime,
nsICancelable* aCancelable) {
nsresult rv;
nsCOMPtr<nsIDownloadManager> dm = do_GetService("@mozilla.org/download-manager;1", &rv);
if (NS_FAILED(rv))
return rv;
rv = dm->AddDownload(aSource, aTarget, aDisplayName, aMIMEInfo, aStartTime, aPersist, getter_AddRefs(mInner));
rv = dm->AddDownload(aSource, aTarget, aDisplayName, aMIMEInfo, aStartTime, aCancelable, getter_AddRefs(mInner));
if (NS_FAILED(rv))
return rv;
@@ -79,171 +82,16 @@ public:
behavior = 0;
if (behavior == 0)
rv = dm->Open(nsnull, this);
rv = dm->Open(nsnull, mInner);
else if (behavior == 1)
rv = dm->OpenProgressDialogFor(mInner, nsnull, PR_TRUE);
return rv;
}
NS_IMETHODIMP GetDisplayName(PRUnichar** aDisplayName)
{
if (!mInner)
return NS_ERROR_NOT_INITIALIZED;
return mInner->GetDisplayName(aDisplayName);
}
NS_IMETHODIMP GetMIMEInfo(nsIMIMEInfo** aMIMEInfo)
{
if (!mInner)
return NS_ERROR_NOT_INITIALIZED;
return mInner->GetMIMEInfo(aMIMEInfo);
}
NS_IMETHODIMP GetSource(nsIURI** aSource)
{
if (!mInner)
return NS_ERROR_NOT_INITIALIZED;
return mInner->GetSource(aSource);
}
NS_IMETHODIMP GetTarget(nsIURI** aTarget)
{
if (!mInner)
return NS_ERROR_NOT_INITIALIZED;
return mInner->GetTarget(aTarget);
}
NS_IMETHODIMP GetStartTime(PRInt64* aStartTime)
{
if (!mInner)
return NS_ERROR_NOT_INITIALIZED;
return mInner->GetStartTime(aStartTime);
}
NS_IMETHODIMP GetPercentComplete(PRInt32* aPercentComplete)
{
if (!mInner)
return NS_ERROR_NOT_INITIALIZED;
return mInner->GetPercentComplete(aPercentComplete);
}
NS_IMETHODIMP GetAmountTransferred(PRUint64* aAmountTransferred)
{
return mInner->GetAmountTransferred(aAmountTransferred);
}
NS_IMETHODIMP GetSize(PRUint64* aSize)
{
return mInner->GetSize(aSize);
}
NS_IMETHODIMP GetObserver(nsIObserver** aObserver)
{
if (!mInner)
return NS_ERROR_NOT_INITIALIZED;
return mInner->GetObserver(aObserver);
}
NS_IMETHODIMP SetObserver(nsIObserver* aObserver)
{
if (!mInner)
return NS_ERROR_NOT_INITIALIZED;
return mInner->SetObserver(aObserver);
}
NS_IMETHODIMP GetPersist(nsIWebBrowserPersist** aPersist)
{
if (!mInner)
return NS_ERROR_NOT_INITIALIZED;
return mInner->GetPersist(aPersist);
}
NS_IMETHODIMP GetTargetFile(nsILocalFile** aTargetFile)
{
if (!mInner)
return NS_ERROR_NOT_INITIALIZED;
return mInner->GetTargetFile(aTargetFile);
}
NS_IMETHODIMP OnStateChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest, PRUint32 aStateFlags,
PRUint32 aStatus)
{
nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(mInner);
if (listener)
return listener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
return NS_OK;
}
NS_IMETHODIMP OnStatusChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest, nsresult aStatus,
const PRUnichar *aMessage)
{
nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(mInner);
if (listener)
return listener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
return NS_OK;
}
NS_IMETHODIMP OnLocationChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest, nsIURI *aLocation)
{
nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(mInner);
if (listener)
return listener->OnLocationChange(aWebProgress, aRequest, aLocation);
return NS_OK;
}
NS_IMETHODIMP OnProgressChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRInt32 aCurSelfProgress,
PRInt32 aMaxSelfProgress,
PRInt32 aCurTotalProgress,
PRInt32 aMaxTotalProgress)
{
nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(mInner);
if (listener)
return listener->OnProgressChange(aWebProgress, aRequest,
aCurSelfProgress,
aMaxSelfProgress,
aCurTotalProgress,
aMaxTotalProgress);
return NS_OK;
}
NS_IMETHODIMP OnProgressChange64(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRInt64 aCurSelfProgress,
PRInt64 aMaxSelfProgress,
PRInt64 aCurTotalProgress,
PRInt64 aMaxTotalProgress)
{
if (!mInner)
return NS_ERROR_NOT_INITIALIZED;
return mInner->OnProgressChange64(aWebProgress, aRequest,
aCurSelfProgress,
aMaxSelfProgress,
aCurTotalProgress,
aMaxTotalProgress);
}
NS_IMETHODIMP OnSecurityChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest, PRUint32 aState)
{
nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(mInner);
if (listener)
return listener->OnSecurityChange(aWebProgress, aRequest, aState);
return NS_OK;
}
private:
nsCOMPtr<nsIDownload> mInner;
};
NS_IMPL_ISUPPORTS4(nsDownloadProxy, nsIDownload, nsITransfer,
NS_IMPL_ISUPPORTS3(nsDownloadProxy, nsITransfer,
nsIWebProgressListener, nsIWebProgressListener2)
#endif