landing patch for bug 24867 "UI for FTP upload" r=biesi,neil sr=bryner

This commit is contained in:
darin%meer.net 2004-04-17 00:58:23 +00:00
Родитель 20de877e45
Коммит b86829b878
23 изменённых файлов: 511 добавлений и 212 удалений

Просмотреть файл

@ -233,7 +233,7 @@ function foundHeaderInfo(aSniffer, aData, aSkipPrompt)
var persistArgs = {
source : source,
contentType : (isDocument && saveAsType == kSaveAsType_Text) ? "text/plain" : contentType,
target : file,
target : makeFileURL(file),
postData : aData.document ? getPostData() : null,
bypassCache : aData.bypassCache
};
@ -259,10 +259,7 @@ function foundHeaderInfo(aSniffer, aData, aSkipPrompt)
var filesFolder = null;
if (persistArgs.contentType != "text/plain") {
// Create the local directory into which to save associated files.
const nsILocalFile = Components.interfaces.nsILocalFile;
const lfContractID = "@mozilla.org/file/local;1";
filesFolder = Components.classes[lfContractID].createInstance(nsILocalFile);
filesFolder.initWithPath(persistArgs.target.path);
filesFolder = file.clone();
var nameWithoutExtension = filesFolder.leafName;
nameWithoutExtension = nameWithoutExtension.substring(0, nameWithoutExtension.lastIndexOf("."));
@ -690,7 +687,13 @@ function makeURL(aURL)
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
return ioService.newURI(aURL, null, null);
}
function makeFileURL(aFile)
{
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
return ioService.newFileURI(aFile);
}
function makeFilePicker()

Просмотреть файл

@ -46,8 +46,8 @@ interface nsIDOMWindow;
* not need to hold a reference to it.
*/
[scriptable, uuid(88A478B3-AF65-440a-94DC-ED9B154D2990)]
interface nsIProgressDialog : nsIDownload {
[scriptable, uuid(1915c4f1-ee57-4684-b46a-0d9f695403b4)]
interface nsIProgressDialog : nsITransfer {
/**
* Open the dialog
*

Просмотреть файл

@ -63,6 +63,7 @@ function nsProgressDialog() {
this.strings = new Array;
this.mSource = null;
this.mTarget = null;
this.mTargetFile = null;
this.mMIMEInfo = null;
this.mDialog = null;
this.mDisplayName = null;
@ -76,7 +77,13 @@ function nsProgressDialog() {
this.mCancelDownloadOnClose = true;
}
const nsIProgressDialog = Components.interfaces.nsIProgressDialog;
const nsIProgressDialog = Components.interfaces.nsIProgressDialog;
const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
const nsITextToSubURI = Components.interfaces.nsITextToSubURI;
const nsIChannel = Components.interfaces.nsIChannel;
const nsIFileURL = Components.interfaces.nsIFileURL;
const nsIURL = Components.interfaces.nsIURL;
nsProgressDialog.prototype = {
// Turn this on to get debugging messages.
@ -108,7 +115,7 @@ nsProgressDialog.prototype = {
get source() { return this.mSource; },
set source(newval) { return this.mSource = newval; },
get target() { return this.mTarget; },
set target(newval) { return this.mTarget = newval; },
get targetFile() { return this.mTargetFile; },
get MIMEInfo() { return this.mMIMEInfo; },
set MIMEInfo(newval) { return this.mMIMEInfo = newval; },
get dialog() { return this.mDialog; },
@ -126,6 +133,14 @@ nsProgressDialog.prototype = {
get cancelDownloadOnClose() { return this.mCancelDownloadOnClose; },
set cancelDownloadOnClose(newval) { return this.mCancelDownloadOnClose = newval; },
set target(newval) {
// If newval references a file on the local filesystem, then grab a
// reference to its corresponding nsIFile.
this.mTargetFile = newval instanceof nsIFileURL ? newfile.file : null;
return this.mTarget = newval;
},
// These setters use functions that update the dialog.
set paused(newval) { return this.setPaused(newval); },
set completed(newval) { return this.setCompleted(newval); },
@ -142,7 +157,7 @@ nsProgressDialog.prototype = {
// Open dialog using the WindowWatcher service.
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService( Components.interfaces.nsIWindowWatcher );
.getService( nsIWindowWatcher );
this.dialog = ww.openWindow( this.parent,
this.dialogChrome,
null,
@ -165,9 +180,25 @@ nsProgressDialog.prototype = {
// Look for STATE_STOP and update dialog to indicate completion when it happens.
onStateChange: function( aWebProgress, aRequest, aStateFlags, aStatus ) {
if ( aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP ) {
// we are done downloading...
this.completed = true;
if ( aStateFlags & nsIWebProgressListener.STATE_STOP ) {
// if we are downloading, then just wait for the first STATE_STOP
if ( this.targetFile != null ) {
// we are done transfering...
this.completed = true;
return;
}
// otherwise, wait for STATE_STOP with aRequest corresponding to
// our target. XXX redirects might screw up this logic.
try {
var chan = aRequest.QueryInterface(nsIChannel);
if (chan.URI.equals(this.target)) {
// we are done transfering...
this.completed = true;
}
}
catch (e) {
}
}
},
@ -326,14 +357,35 @@ nsProgressDialog.prototype = {
QueryInterface: function (iid) {
if (!iid.equals(Components.interfaces.nsIProgressDialog) &&
!iid.equals(Components.interfaces.nsIDownload) &&
!iid.equals(Components.interfaces.nsITransfer) &&
!iid.equals(Components.interfaces.nsIWebProgressListener) &&
!iid.equals(Components.interfaces.nsIObserver) &&
!iid.equals(Components.interfaces.nsIInterfaceRequestor) &&
!iid.equals(Components.interfaces.nsISupports)) {
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
},
// ---------- nsIInterfaceRequestor methods ----------
getInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIPrompt) ||
iid.equals(Components.interfaces.nsIAuthPrompt)) {
// use the window watcher service to get a nsIPrompt/nsIAuthPrompt impl
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
var prompt;
if (iid.equals(Components.interfaces.nsIPrompt))
prompt = ww.getNewPrompter(this.parent);
else
prompt = ww.getNewAuthPrompter(this.parent);
return prompt;
}
Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
return null;
},
// ---------- implementation methods ----------
// Initialize the dialog.
@ -384,8 +436,15 @@ nsProgressDialog.prototype = {
this.hide( "targetRow" );
}
} else {
// Target is the destination file.
this.setValue( "target", this.target.path );
// If target is not a local file, then hide extra dialog controls.
if (this.targetFile != null) {
this.setValue( "target", this.targetFile.path );
} else {
this.setValue( "target", this.target.spec );
this.hide( "pauseResume" );
this.hide( "launch" );
this.hide( "reveal" );
}
}
// Set source field.
@ -402,8 +461,9 @@ nsProgressDialog.prototype = {
this.setValue( "timeElapsed", this.formatSeconds( this.elapsed / 1000 ) );
this.setValue( "timeLeft", this.getString( "unknownTime" ) );
// Initialize the "keep open" box. Hide this if we're opening a helper app.
if ( !this.saving ) {
// Initialize the "keep open" box. Hide this if we're opening a helper app
// or if we are uploading.
if ( !this.saving || !this.targetFile ) {
// Hide this in this case.
this.hide( "keep" );
} else {
@ -422,17 +482,17 @@ nsProgressDialog.prototype = {
// Cancel button stops the download (if not completed),
// and closes the dialog.
onCancel: function() {
// Cancel the download, if not completed.
if ( !this.completed ) {
if ( this.operation ) {
this.operation.cancelSave();
// XXX We're supposed to clean up files/directories.
}
if ( this.observer ) {
this.observer.observe( this, "oncancel", "" );
}
this.paused = false;
}
// Cancel the download, if not completed.
if ( !this.completed ) {
if ( this.operation ) {
this.operation.cancelSave();
// XXX We're supposed to clean up files/directories.
}
if ( this.observer ) {
this.observer.observe( this, "oncancel", "" );
}
this.paused = false;
}
// Test whether the dialog is already closed.
// This will be the case if we've come through onUnload.
if ( this.dialog ) {
@ -477,7 +537,7 @@ nsProgressDialog.prototype = {
// we need to ask if we're unsure
dontAskAgain = false;
}
if ( !dontAskAgain && this.target.isExecutable() ) {
if ( !dontAskAgain && this.targetFile.isExecutable() ) {
try {
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService( Components.interfaces.nsIPromptService );
@ -503,7 +563,7 @@ nsProgressDialog.prototype = {
if ( !okToProceed )
return;
}
this.target.launch();
this.targetFile.launch();
this.dialog.close();
} catch ( exception ) {
// XXX Need code here to tell user the launch failed!
@ -515,15 +575,23 @@ nsProgressDialog.prototype = {
// Invoke the reveal method of the target file.
onReveal: function() {
try {
this.target.reveal();
this.targetFile.reveal();
this.dialog.close();
} catch ( exception ) {
}
},
// Get filename from target file.
// Get filename from the target.
fileName: function() {
return this.target ? this.target.leafName : "";
if ( this.targetFile != null )
return this.targetFile.leafName;
try {
var escapedFileName = this.target.QueryInterface(nsIURL).fileName;
var textToSubURI = Components.classes["@mozilla.org/intl/texttosuburi;1"]
.getService(nsITextToSubURI);
return textToSubURI.unEscapeURIForUI(this.target.originCharset, escapedFileName);
} catch (e) {}
return "";
},
// Set the dialog title.
@ -623,7 +691,7 @@ nsProgressDialog.prototype = {
this.formatSeconds( this.elapsed/1000 ) );
string = this.replaceInsert( string,
2,
this.target.fileSize >> 10 );
this.targetFile.fileSize >> 10 );
this.setValue( "status", string);
// Put progress meter at 100%.
@ -649,7 +717,7 @@ nsProgressDialog.prototype = {
if ( enableButtons ) {
this.enable( "reveal" );
try {
if ( this.target ) {
if ( this.targetFile != null ) {
this.enable( "launch" );
}
} catch(e) {
@ -795,15 +863,17 @@ nsProgressDialog.prototype = {
// Hide a given dialog field.
hide: function( field ) {
this.dialogElement( field ).setAttribute( "style", "display: none;" );
// Hide the associated separator, too.
this.dialogElement( field+"Separator" ).setAttribute( "style", "display: none;" );
this.dialogElement( field ).hidden = true;
// Also hide any related separator element...
var sep = this.dialogElement( field+"Separator" );
if (sep)
sep.hidden = true;
},
// Return input in hex, prepended with "0x" and leading zeros (to 8 digits).
hex: function( x ) {
var hex = Number(x).toString(16);
return "0x" + ( "00000000" + hex ).substring( hex.length );
return "0x" + ("0000000" + Number(x).toString(16)).slice(-8);
},
// Dump text (if debug is on).

Просмотреть файл

@ -64,7 +64,8 @@
class="dialog"
title="&defaultTitle;"
onload="notifyObserver('onload')"
onunload="notifyObserver('onunload')">
onunload="notifyObserver('onunload')"
style="width: 32em;">
<!-- This is the only JS code in this file. It simply routes the "command"
to the dialog's observer (the implementation in nsProgressDialog.js).

Просмотреть файл

@ -1043,39 +1043,18 @@ nsresult nsWebBrowserPersist::GetValidURIFromObject(nsISupports *aObject, nsIURI
nsresult nsWebBrowserPersist::GetLocalFileFromURI(nsIURI *aURI, nsILocalFile **aLocalFile) const
{
NS_ENSURE_ARG_POINTER(aURI);
NS_ENSURE_ARG_POINTER(aLocalFile);
*aLocalFile = nsnull;
nsresult rv = NS_OK;
PRBool isFile = PR_FALSE;
aURI->SchemeIs("file", &isFile);
if (!isFile)
return NS_OK;
nsresult rv;
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
if (NS_FAILED(rv) || !fileURL)
{
return NS_ERROR_MALFORMED_URI;
}
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIFile> file;
rv = fileURL->GetFile(getter_AddRefs(file));
if (NS_FAILED(rv) || !file)
{
return NS_ERROR_FAILURE;
}
if (NS_SUCCEEDED(rv))
rv = CallQueryInterface(file, aLocalFile);
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(file, &rv);
if (NS_FAILED(rv) || !localFile)
{
return NS_ERROR_FAILURE;
}
*aLocalFile = localFile;
NS_ADDREF(*aLocalFile);
return NS_OK;
return rv;
}
nsresult nsWebBrowserPersist::AppendPathToURI(nsIURI *aURI, const nsAString & aPath) const
@ -2147,27 +2126,16 @@ nsresult
nsWebBrowserPersist::MakeOutputStream(
nsIURI *aURI, nsIOutputStream **aOutputStream)
{
NS_ENSURE_ARG_POINTER(aURI);
NS_ENSURE_ARG_POINTER(aOutputStream);
nsresult rv;
PRBool isFile = PR_FALSE;
aURI->SchemeIs("file", &isFile);
if (isFile)
{
nsCOMPtr<nsILocalFile> localFile;
GetLocalFileFromURI(aURI, getter_AddRefs(localFile));
NS_ENSURE_TRUE(localFile, NS_ERROR_FAILURE);
nsresult rv = MakeOutputStreamFromFile(localFile, aOutputStream);
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsILocalFile> localFile;
GetLocalFileFromURI(aURI, getter_AddRefs(localFile));
if (localFile)
rv = MakeOutputStreamFromFile(localFile, aOutputStream);
else
{
nsresult rv = MakeOutputStreamFromURI(aURI, aOutputStream);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = MakeOutputStreamFromURI(aURI, aOutputStream);
return NS_OK;
return rv;
}
nsresult
@ -2320,14 +2288,23 @@ nsWebBrowserPersist::EnumFixRedirect(nsHashKey *aKey, void *aData, void* closure
void
nsWebBrowserPersist::CalcTotalProgress()
{
mTotalCurrentProgress = 0;
mTotalMaxProgress = 0;
if (mOutputMap.Count() > 0)
{
// Total up the progress of each output stream
mTotalCurrentProgress = 0;
mTotalMaxProgress = 0;
mOutputMap.Enumerate(EnumCalcProgress, this);
}
else
if (mUploadList.Count() > 0)
{
// Total up the progress of each upload
mUploadList.Enumerate(EnumCalcUploadProgress, this);
}
// XXX this code seems pretty bogus and pointless
if (mTotalCurrentProgress == 0 && mTotalMaxProgress == 0)
{
// No output streams so we must be complete
mTotalCurrentProgress = 10000;
@ -2340,8 +2317,14 @@ nsWebBrowserPersist::EnumCalcProgress(nsHashKey *aKey, void *aData, void* closur
{
nsWebBrowserPersist *pthis = (nsWebBrowserPersist *) closure;
OutputData *data = (OutputData *) aData;
pthis->mTotalCurrentProgress += data->mSelfProgress;
pthis->mTotalMaxProgress += data->mSelfProgressMax;
// only count toward total progress if destination file is local
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(data->mFile);
if (fileURL)
{
pthis->mTotalCurrentProgress += data->mSelfProgress;
pthis->mTotalMaxProgress += data->mSelfProgressMax;
}
return PR_TRUE;
}

Просмотреть файл

@ -1842,9 +1842,12 @@ nsresult nsSaveMsgListener::InitializeDownload(nsIRequest * aRequest, PRInt32 aB
{
PRTime timeDownloadStarted = PR_Now();
nsCOMPtr<nsIURI> outputURI;
NS_NewFileURI(getter_AddRefs(outputURI), outputFile);
nsCOMPtr<nsIURI> url;
channel->GetURI(getter_AddRefs(url));
rv = dl->Init(url, outputFile, nsnull, mimeinfo, timeDownloadStarted, nsnull);
rv = dl->Init(url, outputURI, nsnull, mimeinfo, timeDownloadStarted, nsnull);
dl->SetObserver(this);
// now store the web progresslistener

Просмотреть файл

@ -595,7 +595,7 @@ nsFTPChannel::OnProgress(nsIRequest *request, nsISupports* aContext,
return NS_OK;
return mEventSink->OnProgress(this, mUserContext,
aProgress, (PRUint32) mContentLength);
aProgress, aProgressMax);
}

Просмотреть файл

@ -86,7 +86,7 @@ interface nsIDownloadManager : nsISupports {
*/
nsIDownload addDownload(in short aDownloadType,
in nsIURI aSource,
in nsILocalFile aTarget,
in nsIURI aTarget,
in wstring aDisplayName,
in wstring aIconURL,
in nsIMIMEInfo aMIMEInfo,

Просмотреть файл

@ -63,6 +63,7 @@
#include "nsIPrefService.h"
#include "nsVoidArray.h"
#include "nsEnumeratorUtils.h"
#include "nsIFileURL.h"
/* Outstanding issues/todo:
* 1. Implement pause/resume.
@ -100,6 +101,28 @@ static nsIRDFService* gRDFService = nsnull;
static nsIObserverService* gObserverService = nsnull;
static PRInt32 gRefCnt = 0;
/**
* Extract the file path associated with a URI. We try to convert to a
* nsIFile instead of extracting the path from the URI directly since this
* ensures that we get a string in the right charset and that all %-encoded
* characters have been expanded.
*/
static nsresult
GetFilePathFromURI(nsIURI *aURI, nsAString &aPath)
{
nsresult rv;
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIFile> file;
rv = fileURL->GetFile(getter_AddRefs(file));
if (NS_SUCCEEDED(rv))
rv = file->GetPath(aPath);
return rv;
}
///////////////////////////////////////////////////////////////////////////////
// nsDownloadManager
@ -463,7 +486,7 @@ nsDownloadManager::AssertProgressInfoFor(const PRUnichar* aPath)
NS_IMETHODIMP
nsDownloadManager::AddDownload(DownloadType aDownloadType,
nsIURI* aSource,
nsILocalFile* aTarget,
nsIURI* aTarget,
const PRUnichar* aDisplayName,
const PRUnichar* aIconURL,
nsIMIMEInfo *aMIMEInfo,
@ -475,8 +498,18 @@ nsDownloadManager::AddDownload(DownloadType aDownloadType,
NS_ENSURE_ARG_POINTER(aTarget);
NS_ENSURE_ARG_POINTER(aDownload);
nsresult rv;
// target must be on the local filesystem
nsCOMPtr<nsIFileURL> targetFileURL = do_QueryInterface(aTarget, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFile> targetFile;
rv = targetFileURL->GetFile(getter_AddRefs(targetFile));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIRDFContainer> downloads;
nsresult rv = GetDownloadsContainer(getter_AddRefs(downloads));
rv = GetDownloadsContainer(getter_AddRefs(downloads));
if (NS_FAILED(rv)) return rv;
nsDownload* internalDownload = new nsDownload();
@ -515,14 +548,14 @@ nsDownloadManager::AddDownload(DownloadType aDownloadType,
if (action == nsIMIMEInfo::useHelperApp ||
action == nsIMIMEInfo::useSystemDefault) {
PRBool fileExists;
aTarget->Exists(&fileExists);
targetFile->Exists(&fileExists);
if (fileExists)
aTarget->Remove(PR_TRUE);
targetFile->Remove(PR_TRUE);
}
}
nsAutoString path;
rv = aTarget->GetPath(path);
rv = targetFile->GetPath(path);
if (NS_FAILED(rv)) return rv;
nsStringKey key(path);
@ -571,7 +604,7 @@ nsDownloadManager::AddDownload(DownloadType aDownloadType,
// Set and assert the "pretty" (display) name of the download
nsAutoString displayName; displayName.Assign(aDisplayName);
if (displayName.IsEmpty()) {
aTarget->GetLeafName(displayName);
targetFile->GetLeafName(displayName);
}
(*aDownload)->SetDisplayName(displayName.get());
@ -1205,11 +1238,11 @@ nsDownloadManager::Observe(nsISupports* aSubject, const char* aTopic, const PRUn
if (nsCRT::strcmp(aTopic, "oncancel") == 0) {
nsCOMPtr<nsIProgressDialog> dialog = do_QueryInterface(aSubject);
nsCOMPtr<nsILocalFile> target;
nsCOMPtr<nsIURI> target;
dialog->GetTarget(getter_AddRefs(target));
nsAutoString path;
rv = target->GetPath(path);
rv = GetFilePathFromURI(target, path);
if (NS_FAILED(rv)) return rv;
nsStringKey key(path);
@ -1538,11 +1571,11 @@ nsXPIProgressListener::OnProgress(PRUint32 aIndex, PRUint32 aValue, PRUint32 aMa
void
nsXPIProgressListener::AssertProgressInfoForDownload(nsDownload* aDownload)
{
nsCOMPtr<nsILocalFile> target;
nsCOMPtr<nsIURI> target;
aDownload->GetTarget(getter_AddRefs(target));
nsAutoString path;
target->GetPath(path);
GetFilePathFromURI(target, path);
mDownloadManager->AssertProgressInfoFor(path.get());
}
@ -1796,7 +1829,7 @@ nsDownloadsDataSource::FlushTo(const char* aURI)
///////////////////////////////////////////////////////////////////////////////
// nsDownload
NS_IMPL_ISUPPORTS2(nsDownload, nsIDownload, nsIWebProgressListener)
NS_IMPL_ISUPPORTS3(nsDownload, nsIDownload, nsITransfer, nsIWebProgressListener)
nsDownload::nsDownload():mDownloadState(nsIDownloadManager::DOWNLOAD_NOTSTARTED),
mPercentComplete(0),
@ -1887,7 +1920,7 @@ nsDownload::SetSource(nsIURI* aSource)
}
nsresult
nsDownload::SetTarget(nsILocalFile* aTarget)
nsDownload::SetTarget(nsIURI* aTarget)
{
mTarget = aTarget;
return NS_OK;
@ -1941,7 +1974,7 @@ nsDownload::OnProgressChange(nsIWebProgress *aWebProgress,
if (mDownloadState == nsIDownloadManager::DOWNLOAD_NOTSTARTED) {
nsAutoString path;
nsresult rv = mTarget->GetPath(path);
nsresult rv = GetFilePathFromURI(mTarget, path);
if (NS_FAILED(rv)) return rv;
mDownloadState = nsIDownloadManager::DOWNLOAD_DOWNLOADING;
@ -1983,7 +2016,7 @@ nsDownload::OnStatusChange(nsIWebProgress *aWebProgress,
if (NS_FAILED(aStatus)) {
mDownloadState = nsIDownloadManager::DOWNLOAD_FAILED;
nsAutoString path;
nsresult rv = mTarget->GetPath(path);
nsresult rv = GetFilePathFromURI(mTarget, path);
if (NS_SUCCEEDED(rv)) {
mDownloadManager->DownloadEnded(path.get(), nsnull);
gObserverService->NotifyObservers(NS_STATIC_CAST(nsIDownload *, this), "dl-failed", nsnull);
@ -2045,7 +2078,7 @@ nsDownload::OnStateChange(nsIWebProgress* aWebProgress,
mPercentComplete = 100;
nsAutoString path;
rv = mTarget->GetPath(path);
rv = GetFilePathFromURI(mTarget, path);
// can't do an early return; have to break reference cycle below
if (NS_SUCCEEDED(rv)) {
mDownloadManager->DownloadEnded(path.get(), nsnull);
@ -2103,7 +2136,7 @@ nsDownload::OnStateChange(nsIWebProgress* aWebProgress,
// Now remove the download if the user's retention policy is "Remove when Done"
if (mDownloadManager->GetRetentionBehavior() == 0) {
nsAutoString path;
mTarget->GetPath(path);
GetFilePathFromURI(mTarget, path);
mDownloadManager->RemoveDownload(path.get());
}
@ -2132,7 +2165,7 @@ nsDownload::OnSecurityChange(nsIWebProgress *aWebProgress,
NS_IMETHODIMP
nsDownload::Init(nsIURI* aSource,
nsILocalFile* aTarget,
nsIURI* aTarget,
const PRUnichar* aDisplayName,
nsIMIMEInfo *aMIMEInfo,
PRInt64 aStartTime,
@ -2153,7 +2186,7 @@ nsDownload::SetDisplayName(const PRUnichar* aDisplayName)
nsCOMPtr<nsIRDFLiteral> nameLiteral;
nsCOMPtr<nsIRDFResource> res;
nsAutoString path;
nsresult rv = mTarget->GetPath(path);
nsresult rv = GetFilePathFromURI(mTarget, path);
if (NS_FAILED(rv)) return rv;
gRDFService->GetUnicodeResource(path, getter_AddRefs(res));
@ -2172,7 +2205,7 @@ nsDownload::GetDisplayName(PRUnichar** aDisplayName)
}
NS_IMETHODIMP
nsDownload::GetTarget(nsILocalFile** aTarget)
nsDownload::GetTarget(nsIURI** aTarget)
{
*aTarget = mTarget;
NS_IF_ADDREF(*aTarget);
@ -2245,6 +2278,21 @@ nsDownload::GetMIMEInfo(nsIMIMEInfo** aMIMEInfo)
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetTargetFile(nsILocalFile** aTargetFile)
{
nsresult rv;
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(mTarget, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIFile> file;
rv = fileURL->GetFile(getter_AddRefs(file));
if (NS_SUCCEEDED(rv))
rv = CallQueryInterface(file, aTargetFile);
return rv;
}
void
nsDownload::Pause(PRBool aPaused)
{

Просмотреть файл

@ -205,6 +205,7 @@ class nsDownload : public nsIDownload,
{
public:
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSITRANSFER
NS_DECL_NSIDOWNLOAD
NS_DECL_ISUPPORTS
@ -224,7 +225,7 @@ protected:
nsresult SetDialog(nsIProgressDialog* aDialog);
nsresult GetDialog(nsIProgressDialog** aDialog);
nsresult SetPersist(nsIWebBrowserPersist* aPersist);
nsresult SetTarget(nsILocalFile* aTarget);
nsresult SetTarget(nsIURI* aTarget);
nsresult SetSource(nsIURI* aSource);
nsresult GetTransferInformation(PRInt32* aCurr, PRInt32* aMax);
nsresult SetMIMEInfo(nsIMIMEInfo* aMIMEInfo);
@ -234,7 +235,7 @@ protected:
PRBool IsPaused();
nsDownloadManager* mDownloadManager;
nsCOMPtr<nsILocalFile> mTarget;
nsCOMPtr<nsIURI> mTarget;
private:
nsString mDisplayName;

Просмотреть файл

@ -44,6 +44,7 @@
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsIMIMEInfo.h"
#include "nsIFileURL.h"
#define PREF_BDM_SHOWWHENSTARTING "browser.download.manager.showWhenStarting"
#define PREF_BDM_USEWINDOW "browser.download.manager.useWindow"
@ -59,7 +60,7 @@ public:
NS_DECL_ISUPPORTS
NS_IMETHODIMP Init(nsIURI* aSource,
nsILocalFile* aTarget,
nsIURI* aTarget,
const PRUnichar* aDisplayName,
nsIMIMEInfo *aMIMEInfo,
PRInt64 aStartTime,
@ -84,8 +85,17 @@ public:
branch->GetBoolPref(PREF_BDM_USEWINDOW, &useWindow);
if (showDM && useWindow) {
nsAutoString path;
rv = aTarget->GetPath(path);
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aTarget, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIFile> file;
rv = fileURL->GetFile(getter_AddRefs(file));
if (NS_FAILED(rv)) return rv;
rv = file->GetPath(path);
if (NS_FAILED(rv)) return rv;
return dm->Open(nsnull, path.get());
}
return rv;
@ -112,7 +122,7 @@ public:
return mInner->GetSource(aSource);
}
NS_IMETHODIMP GetTarget(nsILocalFile** aTarget)
NS_IMETHODIMP GetTarget(nsIURI** aTarget)
{
return mInner->GetTarget(aTarget);
}
@ -152,6 +162,11 @@ public:
return mInner->GetPersist(aPersist);
}
NS_IMETHODIMP GetTargetFile(nsILocalFile** aTargetFile)
{
return mInner->GetTargetFile(aTargetFile);
}
NS_IMETHODIMP OnStateChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest, PRUint32 aStateFlags,
PRUint32 aStatus)
@ -208,6 +223,6 @@ private:
nsCOMPtr<nsIDownload> mInner;
};
NS_IMPL_ISUPPORTS2(nsDownloadProxy, nsIDownload, nsIWebProgressListener)
NS_IMPL_ISUPPORTS3(nsDownloadProxy, nsIDownload, nsITransfer, nsIWebProgressListener)
#endif

Просмотреть файл

@ -93,8 +93,6 @@ function filepickerLoad() {
(filePickerMode == nsIFilePicker.modeOpenMultiple) ||
(filePickerMode == nsIFilePicker.modeSave)) {
treeView.setFilter(filterTypes[0]);
/* build filter popup */
var filterPopup = document.createElement("menupopup");
@ -116,6 +114,9 @@ function filepickerLoad() {
filterBox.removeAttribute("hidden");
filterMenuList.selectedIndex = o.filterIndex;
treeView.setFilter(filterTypes[o.filterIndex]);
} else if (filePickerMode == nsIFilePicker.modeGetFolder) {
treeView.showOnlyDirectories = true;
}

Просмотреть файл

@ -45,82 +45,81 @@ interface nsIWebBrowserPersist;
interface nsIWebProgressListener;
interface nsIMIMEInfo;
[scriptable, uuid(06cb92f2-1dd2-11b2-95f2-96dfdfb804a1)]
interface nsIDownload : nsISupports {
[scriptable, uuid(d80095a7-e81c-464c-a13f-ecb84feb969f)]
interface nsITransfer : nsISupports {
/**
* Initializes the download with certain properties. This function must
* Initializes the transfer with certain properties. This function must
* be called prior to accessing any properties on this interface.
*
* @param aSource The source (nsIURI) of the download.
* @param aSource The source URI of the transfer.
*
* @param aTarget The local file to which the download is being saved.
* @param aTarget The target URI of the transfer.
*
* @param aDisplayName The user-readable description of the download.
* @param aDisplayName The user-readable description of the transfer.
*
* @param aMIMEInfo The MIME info associated with the download file,
* @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 to transfer the download. If set,
* the manager will set its listener to the download item
* @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 download item as the listener on
* is expected to set the transfer 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.
* set an observer on the transfer item that listens for
* the "oncancel" topic and cancels the transfer.
*/
void init(in nsIURI aSource,
in nsILocalFile aTarget,
in nsIURI aTarget,
in wstring aDisplayName,
in nsIMIMEInfo aMIMEInfo,
in long long startTime,
in nsIWebBrowserPersist aPersist);
/**
* The source of the download.
* The source of the transfer.
*/
readonly attribute nsIURI source;
/**
* The local file to which the download is being saved.
* The target of the transfer.
*/
readonly attribute nsILocalFile target;
readonly attribute nsIURI target;
/**
* Optional. If set, it will be used for cancellation, and the download
* 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 download item as the listener for whatever transfer component
* being used.
* to set the transfer item as the listener for whatever transfer component
* is being used.
*/
readonly attribute nsIWebBrowserPersist persist;
/**
* The percentage of completion of the download.
* The percentage of transfer completed;
*/
readonly attribute PRInt32 percentComplete;
/**
* The user-readable description of the download.
* The user-readable description of the transfer.
*/
attribute wstring displayName;
/**
* The time a download was started.
* The time a transfer was started.
*/
readonly attribute long long startTime;
/**
* Optional. If set, it will contain the download's relevant MIME information.
* Optional. If set, it will contain the target's relevant MIME information.
* This includes it's MIME Type, helper app, and whether that helper should be
* executed.
*/
readonly attribute nsIMIMEInfo MIMEInfo;
/**
* Optional; downloading information is passed to this listener and used to
* Optional; transfering information is passed to this listener and used to
* update client UI.
*/
attribute nsIWebProgressListener listener;
@ -132,6 +131,15 @@ interface nsIDownload : nsISupports {
attribute nsIObserver observer;
};
[scriptable, uuid(b0aae798-78aa-4769-9f0e-9aef4cf9474d)]
interface nsIDownload : nsITransfer {
/**
* The target of a download is always a file on the local file system.
*/
readonly attribute nsILocalFile targetFile;
};
%{C++
#define NS_DOWNLOAD_CONTRACTID "@mozilla.org/download;1"
// {E3FA9D0A-1DD1-11B2-BDEF-8C720B597445}

Просмотреть файл

@ -1818,9 +1818,11 @@ nsresult nsExternalAppHandler::InitializeDownload(nsIDownload* aDownload)
{
nsresult rv;
nsCOMPtr<nsILocalFile> local = do_QueryInterface(mFinalFileDestination);
nsCOMPtr<nsIURI> target;
rv = NS_NewFileURI(getter_AddRefs(target), mFinalFileDestination);
if (NS_FAILED(rv)) return rv;
rv = aDownload->Init(mSourceUrl, local, nsnull,
rv = aDownload->Init(mSourceUrl, target, nsnull,
mMimeInfo, mTimeDownloadStarted, nsnull);
if (NS_FAILED(rv)) return rv;

Просмотреть файл

@ -1184,20 +1184,54 @@ function delayedOpenTab(url)
setTimeout(function(aTabElt) { getBrowser().selectedTab = aTabElt; }, 0, getBrowser().addTab(url));
}
function BrowserOpenFileWindow()
/* Show file picker dialog configured for opening a file, and return
* the selected nsIFileURL instance. */
function selectFileToOpen(label, prefRoot)
{
// Get filepicker component.
try {
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
fp.init(window, gNavigatorBundle.getString("openFile"), nsIFilePicker.modeOpen);
fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText | nsIFilePicker.filterImages |
nsIFilePicker.filterXML | nsIFilePicker.filterHTML);
var fileURL = null;
if (fp.show() == nsIFilePicker.returnOK)
openTopWin(fp.fileURL.spec);
// Get filepicker component.
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
fp.init(window, gNavigatorBundle.getString(label), nsIFilePicker.modeOpen);
fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText | nsIFilePicker.filterImages |
nsIFilePicker.filterXML | nsIFilePicker.filterHTML);
const filterIndexPref = prefRoot + "filterIndex";
const lastDirPref = prefRoot + "dir";
// use a pref to remember the filterIndex selected by the user.
var index = 0;
try {
index = pref.getIntPref(filterIndexPref);
} catch (ex) {
}
fp.filterIndex = index;
// use a pref to remember the displayDirectory selected by the user.
var dir = null;
try {
dir = pref.getComplexValue(lastDirPref, Components.interfaces.nsILocalFile);
} catch (ex) {
}
fp.displayDirectory = dir;
if (fp.show() == nsIFilePicker.returnOK) {
pref.setIntPref(filterIndexPref, fp.filterIndex);
pref.setComplexValue(lastDirPref,
Components.interfaces.nsILocalFile,
fp.file.parent.QueryInterface(Components.interfaces.nsILocalFile));
fileURL = fp.fileURL;
}
return fileURL;
}
function BrowserOpenFileWindow()
{
try {
openTopWin(selectFileToOpen("openFile", "browser.open."));
} catch (e) {}
}
function BrowserEditBookmarks()
@ -2290,3 +2324,79 @@ function WindowIsClosing()
return reallyClose;
}
/**
* file upload support
*/
/* This function returns the URI of the currently focused content frame
* or frameset.
*/
function getCurrentURI()
{
const CI = Components.interfaces;
var focusedWindow = document.commandDispatcher.focusedWindow;
var contentFrame = isContentFrame(focusedWindow) ? focusedWindow : window.content;
var nav = contentFrame.QueryInterface(CI.nsIInterfaceRequestor)
.getInterface(CI.nsIWebNavigation);
return nav.currentURI;
}
function uploadFile(fileURL)
{
const CI = Components.interfaces;
var targetBaseURI = getCurrentURI();
// generate the target URI. we use fileURL.file.leafName to get the
// unicode value of the target filename w/o any URI-escaped chars.
// this gives the protocol handler the best chance of generating a
// properly formatted URI spec. we pass null for the origin charset
// parameter since we want the URI to inherit the origin charset
// property from targetBaseURI.
var leafName = fileURL.file.leafName;
const IOS = Components.classes["@mozilla.org/network/io-service;1"]
.getService(CI.nsIIOService);
var targetURI = IOS.newURI(leafName, null, targetBaseURI);
// ok, start uploading...
var dialog = Components.classes["@mozilla.org/progressdialog;1"]
.createInstance(CI.nsIProgressDialog);
var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(CI.nsIWebBrowserPersist);
dialog.init(fileURL, targetURI, leafName, null, Date.now()*1000, persist);
dialog.open(window);
persist.progressListener = dialog;
persist.saveURI(fileURL, null, null, null, null, targetURI);
}
function BrowserUploadFile()
{
try {
uploadFile(selectFileToOpen("uploadFile", "browser.upload."));
} catch (e) {}
}
/* This function is called whenever the file menu is about to be displayed.
* Enable the upload menu item if appropriate. */
function updateFileUploadItem()
{
var canUpload = false;
try {
canUpload = getCurrentURI().schemeIs('ftp');
} catch (e) {}
var item = document.getElementById('Browser:UploadFile');
if (canUpload)
item.removeAttribute('disabled');
else
item.setAttribute('disabled', 'true');
}

Просмотреть файл

@ -122,6 +122,7 @@
<command id="Browser:OpenFile" oncommand="BrowserOpenFileWindow();"/>
<command id="Browser:SavePage" oncommand="saveDocument(window._content.document);"/>
<command id="Browser:EditPage" oncommand="editPageOrFrame();" observes="isImage"/>
<command id="Browser:UploadFile" oncommand="BrowserUploadFile();"/>
<command id="Browser:Open" oncommand="BrowserOpenWindow();"/>
<command id="cmd_printSetup" oncommand="NSPrintSetup();"/>
<command id="Browser:Print" oncommand="NSPrint();"/>
@ -308,7 +309,7 @@
<!-- Menu -->
<menubar id="main-menubar" class="chromeclass-menubar">
<menu id="menu_File">
<menupopup id="menu_FilePopup" onpopupshowing="updateCloseItems();getContentAreaFrameCount();">
<menupopup id="menu_FilePopup" onpopupshowing="updateCloseItems();getContentAreaFrameCount();updateFileUploadItem();">
<menu id="menu_New">
<menupopup id="menu_NewPopup">
<!-- From utilityOverlay.xul -->
@ -330,6 +331,8 @@
<menuseparator id="saveMenuBlockEnd"/>
<menuitem label="&editPageCmd.label;" accesskey="&editPageCmd.accesskey;" key="key_editPage" command="Browser:EditPage" />
<menuseparator/>
<menuitem command="Browser:UploadFile" label="&uploadFile.label;"/>
<menuseparator/>
<menuitem id="printSetupMenuItem" label="&printSetupCmd.label;" accesskey="&printSetupCmd.accesskey;" command="cmd_printSetup"/>
<menuitem id="printPreviewMenuItem" label="&printPreviewCmd.label;" accesskey="&printPreviewCmd.accesskey;" command="Browser:PrintPreview"/>
<menuitem id="printMenuItem" label="&printCmd.label;" accesskey="&printCmd.accesskey;" key="printKb" command="Browser:Print"/>

Просмотреть файл

@ -351,7 +351,7 @@ function foundHeaderInfo(aSniffer, aData)
var persistArgs = {
source : source,
contentType : (useSaveDocument && fp.filterIndex == 2) ? "text/plain" : contentType,
target : fp.file,
target : makeFileURL(fp.file),
postData : isDocument ? getPostData() : null,
bypassCache : aData.bypassCache
};
@ -377,10 +377,7 @@ function foundHeaderInfo(aSniffer, aData)
var filesFolder = null;
if (persistArgs.contentType != "text/plain") {
// Create the local directory into which to save associated files.
const lfContractID = "@mozilla.org/file/local;1";
const lfIID = Components.interfaces.nsILocalFile;
filesFolder = Components .classes[lfContractID].createInstance(lfIID);
filesFolder.initWithPath(persistArgs.target.path);
filesFolder = fp.file.clone();
var nameWithoutExtension = filesFolder.leafName.replace(/\.[^.]*$/, "");
var filesFolderLeafName = getStringBundle().formatStringFromName("filesFolder",
@ -706,7 +703,13 @@ function makeURL(aURL)
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
return ioService.newURI(aURL, null, null);
}
function makeFileURL(aFile)
{
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
return ioService.newFileURI(aFile);
}
function makeFilePicker()

Просмотреть файл

@ -74,7 +74,7 @@ interface nsIDownloadManager : nsISupports {
*/
nsIDownload addDownload(in nsIURI aSource,
in nsILocalFile aTarget,
in nsIURI aTarget,
in wstring aDisplayName,
in nsIMIMEInfo aMIMEInfo,
in long long startTime,

Просмотреть файл

@ -56,7 +56,7 @@ const dlObserver = {
function selectDownload(aDownload)
{
var dlElt = document.getElementById(aDownload.target.path);
var dlElt = document.getElementById(aDownload.targetFile.path);
var dlIndex = gDownloadView.contentView.getIndexOfItem(dlElt);
gDownloadView.treeBoxObject.selection.select(dlIndex);
gDownloadView.treeBoxObject.ensureRowIsVisible(dlIndex);

Просмотреть файл

@ -61,7 +61,7 @@
#include "nsIProfileChangeStatus.h"
#include "nsISound.h"
#include "nsIPrefService.h"
#include "nsIURL.h"
#include "nsIFileURL.h"
/* Outstanding issues/todo:
* 1. Implement pause/resume.
@ -88,6 +88,28 @@ static nsIRDFService* gRDFService = nsnull;
static PRInt32 gRefCnt = 0;
/**
* This function extracts the local file path corresponding to the given URI.
*/
static nsresult
GetFilePathUTF8(nsIURI *aURI, nsACString &aResult)
{
nsresult rv;
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIFile> file;
rv = fileURL->GetFile(getter_AddRefs(file));
if (NS_FAILED(rv)) return rv;
nsAutoString path;
rv = file->GetPath(path);
if (NS_SUCCEEDED(rv))
CopyUTF16toUTF8(path, aResult);
return rv;
}
///////////////////////////////////////////////////////////////////////////////
// nsDownloadManager
@ -397,7 +419,7 @@ nsDownloadManager::AssertProgressInfoFor(const nsACString& aTargetPath)
NS_IMETHODIMP
nsDownloadManager::AddDownload(nsIURI* aSource,
nsILocalFile* aTarget,
nsIURI* aTarget,
const PRUnichar* aDisplayName,
nsIMIMEInfo *aMIMEInfo,
PRInt64 aStartTime,
@ -418,13 +440,17 @@ nsDownloadManager::AddDownload(nsIURI* aSource,
NS_ADDREF(*aDownload = internalDownload);
// the persistent descriptor of the target is the unique identifier we use
nsAutoString path;
rv = aTarget->GetPath(path);
// the path of the target is the unique identifier we use
nsCOMPtr<nsILocalFile> targetFile;
rv = internalDownload->GetTargetFile(getter_AddRefs(targetFile));
if (NS_FAILED(rv)) return rv;
NS_ConvertUCS2toUTF8 utf8Path(path);
nsAutoString path;
rv = targetFile->GetPath(path);
if (NS_FAILED(rv)) return rv;
NS_ConvertUTF16toUTF8 utf8Path(path);
nsCOMPtr<nsIRDFResource> downloadRes;
gRDFService->GetResource(utf8Path, getter_AddRefs(downloadRes));
@ -446,7 +472,7 @@ nsDownloadManager::AddDownload(nsIURI* aSource,
// Set and assert the "pretty" (display) name of the download
nsAutoString displayName; displayName.Assign(aDisplayName);
if (displayName.IsEmpty()) {
aTarget->GetLeafName(displayName);
targetFile->GetLeafName(displayName);
}
internalDownload->SetDisplayName(displayName.get());
@ -740,7 +766,7 @@ nsDownloadManager::OpenProgressDialogFor(nsIDownload* aDownload, nsIDOMWindow* a
aDownload->GetSource(getter_AddRefs(source));
// target...
nsCOMPtr<nsILocalFile> target;
nsCOMPtr<nsIURI> target;
aDownload->GetTarget(getter_AddRefs(target));
// helper app...
@ -797,21 +823,19 @@ nsDownloadManager::Observe(nsISupports* aSubject, const char* aTopic, const PRUn
nsresult rv;
if (nsCRT::strcmp(aTopic, "oncancel") == 0) {
nsCOMPtr<nsIProgressDialog> dialog = do_QueryInterface(aSubject);
nsCOMPtr<nsILocalFile> target;
nsCOMPtr<nsIURI> target;
dialog->GetTarget(getter_AddRefs(target));
nsAutoString path;
rv = target->GetPath(path);
if (NS_FAILED(rv)) return rv;
NS_ConvertUCS2toUTF8 utf8Path(path);
nsCAutoString path;
rv = GetFilePathUTF8(target, path);
if (NS_FAILED(rv)) return rv;
nsDownload* download = mCurrDownloads.GetWeak(utf8Path);
nsDownload* download = mCurrDownloads.GetWeak(path);
if (download) {
// unset dialog since it's closing
download->SetDialog(nsnull);
return CancelDownload(utf8Path);
return CancelDownload(path);
}
}
else if (nsCRT::strcmp(aTopic, "profile-approve-change") == 0) {
@ -887,10 +911,10 @@ nsDownloadManager::Observe(nsISupports* aSubject, const char* aTopic, const PRUn
///////////////////////////////////////////////////////////////////////////////
// nsDownload
NS_IMPL_ISUPPORTS2(nsDownload, nsIDownload, nsIWebProgressListener)
NS_IMPL_ISUPPORTS3(nsDownload, nsIDownload, nsITransfer, nsIWebProgressListener)
nsDownload::nsDownload(nsDownloadManager* aManager,
nsILocalFile* aTarget,
nsIURI* aTarget,
nsIURI* aSource) :
mDownloadManager(aManager),
mTarget(aTarget),
@ -906,11 +930,11 @@ nsDownload::nsDownload(nsDownloadManager* aManager,
nsDownload::~nsDownload()
{
nsAutoString path;
nsresult rv = mTarget->GetPath(path);
nsCAutoString path;
nsresult rv = GetFilePathUTF8(mTarget, path);
if (NS_FAILED(rv)) return;
mDownloadManager->AssertProgressInfoFor(NS_ConvertUCS2toUTF8(path));
mDownloadManager->AssertProgressInfoFor(path);
}
///////////////////////////////////////////////////////////////////////////////
@ -938,12 +962,12 @@ nsDownload::OnProgressChange(nsIWebProgress *aWebProgress,
mLastUpdate = now;
if (mDownloadState == NOTSTARTED) {
nsAutoString path;
nsresult rv = mTarget->GetPath(path);
nsCAutoString path;
nsresult rv = GetFilePathUTF8(mTarget, path);
if (NS_FAILED(rv)) return rv;
mDownloadState = DOWNLOADING;
mDownloadManager->DownloadStarted(NS_ConvertUCS2toUTF8(path));
mDownloadManager->DownloadStarted(path);
}
if (aMaxTotalProgress > 0)
@ -1003,10 +1027,10 @@ nsDownload::OnStatusChange(nsIWebProgress *aWebProgress,
{
if (NS_FAILED(aStatus)) {
mDownloadState = FAILED;
nsAutoString path;
nsresult rv = mTarget->GetPath(path);
nsCAutoString path;
nsresult rv = GetFilePathUTF8(mTarget, path);
if (NS_SUCCEEDED(rv))
mDownloadManager->DownloadEnded(NS_ConvertUCS2toUTF8(path), aMessage);
mDownloadManager->DownloadEnded(path, aMessage);
}
if (mListener)
@ -1104,11 +1128,11 @@ nsDownload::OnStateChange(nsIWebProgress* aWebProgress,
}
}
nsAutoString path;
rv = mTarget->GetPath(path);
nsCAutoString path;
rv = GetFilePathUTF8(mTarget, path);
// can't do an early return; have to break reference cycle below
if (NS_SUCCEEDED(rv)) {
mDownloadManager->DownloadEnded(NS_ConvertUCS2toUTF8(path), nsnull);
mDownloadManager->DownloadEnded(path, nsnull);
}
}
@ -1155,7 +1179,7 @@ nsDownload::OnSecurityChange(nsIWebProgress *aWebProgress,
NS_IMETHODIMP
nsDownload::Init(nsIURI* aSource,
nsILocalFile* aTarget,
nsIURI* aTarget,
const PRUnichar* aDisplayName,
nsIMIMEInfo *aMIMEInfo,
PRInt64 aStartTime,
@ -1175,11 +1199,11 @@ nsDownload::SetDisplayName(const PRUnichar* aDisplayName)
nsCOMPtr<nsIRDFLiteral> nameLiteral;
nsCOMPtr<nsIRDFResource> res;
nsAutoString path;
nsresult rv = mTarget->GetPath(path);
nsCAutoString path;
nsresult rv = GetFilePathUTF8(mTarget, path);
if (NS_FAILED(rv)) return rv;
gRDFService->GetUnicodeResource(path, getter_AddRefs(res));
gRDFService->GetResource(path, getter_AddRefs(res));
gRDFService->GetLiteral(aDisplayName, getter_AddRefs(nameLiteral));
ds->Assert(res, gNC_Name, nameLiteral, PR_TRUE);
@ -1195,7 +1219,7 @@ nsDownload::GetDisplayName(PRUnichar** aDisplayName)
}
NS_IMETHODIMP
nsDownload::GetTarget(nsILocalFile** aTarget)
nsDownload::GetTarget(nsIURI** aTarget)
{
*aTarget = mTarget;
NS_IF_ADDREF(*aTarget);
@ -1269,3 +1293,18 @@ nsDownload::GetMIMEInfo(nsIMIMEInfo** aMIMEInfo)
NS_IF_ADDREF(*aMIMEInfo);
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetTargetFile(nsILocalFile** aTargetFile)
{
nsresult rv;
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(mTarget, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIFile> file;
rv = fileURL->GetFile(getter_AddRefs(file));
if (NS_SUCCEEDED(rv))
rv = CallQueryInterface(file, aTargetFile);
return rv;
}

Просмотреть файл

@ -108,10 +108,11 @@ class nsDownload : public nsIDownload,
{
public:
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSITRANSFER
NS_DECL_NSIDOWNLOAD
NS_DECL_ISUPPORTS
nsDownload(nsDownloadManager* aManager, nsILocalFile* aTarget, nsIURI* aSource);
nsDownload(nsDownloadManager* aManager, nsIURI* aTarget, nsIURI* aSource);
~nsDownload();
void SetDialogListener(nsIWebProgressListener* aInternalListener) {
@ -156,7 +157,7 @@ private:
nsString mDisplayName;
nsCOMPtr<nsILocalFile> mTarget;
nsCOMPtr<nsIURI> mTarget;
nsCOMPtr<nsIURI> mSource;
nsCOMPtr<nsIWebProgressListener> mListener;
nsCOMPtr<nsIWebProgressListener> mDialogListener;

Просмотреть файл

@ -58,7 +58,7 @@ public:
NS_DECL_ISUPPORTS
NS_IMETHODIMP Init(nsIURI* aSource,
nsILocalFile* aTarget,
nsIURI* aTarget,
const PRUnichar* aDisplayName,
nsIMIMEInfo *aMIMEInfo,
PRInt64 aStartTime,
@ -115,7 +115,7 @@ public:
return mInner->GetSource(aSource);
}
NS_IMETHODIMP GetTarget(nsILocalFile** aTarget)
NS_IMETHODIMP GetTarget(nsIURI** aTarget)
{
if (!mInner)
return NS_ERROR_NOT_INITIALIZED;
@ -171,6 +171,13 @@ public:
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)
@ -227,6 +234,6 @@ private:
nsCOMPtr<nsIDownload> mInner;
};
NS_IMPL_ISUPPORTS2(nsDownloadProxy, nsIDownload, nsIWebProgressListener)
NS_IMPL_ISUPPORTS3(nsDownloadProxy, nsIDownload, nsITransfer, nsIWebProgressListener)
#endif

Просмотреть файл

@ -94,8 +94,6 @@ function filepickerLoad() {
(filePickerMode == nsIFilePicker.modeOpenMultiple) ||
(filePickerMode == nsIFilePicker.modeSave)) {
treeView.setFilter(filterTypes[0]);
/* build filter popup */
var filterPopup = document.createElement("menupopup");
@ -117,6 +115,9 @@ function filepickerLoad() {
filterBox.removeAttribute("hidden");
filterMenuList.selectedIndex = o.filterIndex;
treeView.setFilter(filterTypes[o.filterIndex]);
} else if (filePickerMode == nsIFilePicker.modeGetFolder) {
treeView.showOnlyDirectories = true;
}