зеркало из https://github.com/mozilla/gecko-dev.git
Bugs 129614/129604/137676; ensure all download errors are shown to user (and fix download manager quirk so it doesn't think all downloads are 0kb of 0kb); r=bzbarsky, sr=blake
This commit is contained in:
Родитель
0aa5387f3b
Коммит
8b9240bcab
|
@ -63,6 +63,7 @@ function nsHelperAppDialog() {
|
|||
this.strings = new Array;
|
||||
this.elements = new Array;
|
||||
this.updateSelf = true;
|
||||
this.mTitle = "";
|
||||
}
|
||||
|
||||
nsHelperAppDialog.prototype = {
|
||||
|
@ -105,6 +106,9 @@ nsHelperAppDialog.prototype = {
|
|||
null );
|
||||
// Hook this object to the dialog.
|
||||
this.mDialog.dialog = this;
|
||||
// Watch for error notifications.
|
||||
this.progressListener.helperAppDlg = this;
|
||||
this.mLauncher.setWebProgressListener( this.progressListener );
|
||||
},
|
||||
|
||||
// promptForSaveToFile: Display file picker dialog and return selected file.
|
||||
|
@ -191,6 +195,49 @@ nsHelperAppDialog.prototype = {
|
|||
|
||||
// ---------- implementation methods ----------
|
||||
|
||||
// Web progress listener so we can detect errors while mLauncher is
|
||||
// streaming the data to a temporary file.
|
||||
progressListener: {
|
||||
// Implementation properties.
|
||||
helperAppDlg: null,
|
||||
|
||||
// nsIWebProgressListener methods.
|
||||
// Look for error notifications and display alert to user.
|
||||
onStatusChange: function( aWebProgress, aRequest, aStatus, aMessage ) {
|
||||
if ( aStatus != Components.results.NS_OK ) {
|
||||
// Get prompt service.
|
||||
var prompter = Components.classes[ "@mozilla.org/embedcomp/prompt-service;1" ]
|
||||
.getService( Components.interfaces.nsIPromptService );
|
||||
// Display error alert (using text supplied by back-end).
|
||||
prompter.alert( this.dialog, this.helperAppDlg.mTitle, aMessage );
|
||||
|
||||
// Close the dialog.
|
||||
this.helperAppDlg.onCancel();
|
||||
if ( this.helperAppDlg.mDialog ) {
|
||||
this.helperAppDlg.mDialog.close();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Ignore onProgressChange, onStateChange, onLocationChange, and onSecurityChange notifications.
|
||||
onProgressChange: function( aWebProgress,
|
||||
aRequest,
|
||||
aCurSelfProgress,
|
||||
aMaxSelfProgress,
|
||||
aCurTotalProgress,
|
||||
aMaxTotalProgress ) {
|
||||
},
|
||||
|
||||
onStateChange: function( aWebProgress, aRequest, aStateFlags, aStatus ) {
|
||||
},
|
||||
|
||||
onLocationChange: function( aWebProgress, aRequest, aLocation ) {
|
||||
},
|
||||
|
||||
onSecurityChange: function( aWebProgress, aRequest, state ) {
|
||||
},
|
||||
},
|
||||
|
||||
// initDialog: Fill various dialog fields with initial content.
|
||||
initDialog : function() {
|
||||
// Check if file is executable (in which case, we will go straight to
|
||||
|
@ -200,6 +247,9 @@ nsHelperAppDialog.prototype = {
|
|||
var tmpFile = this.mLauncher.getDownloadInfo( ignore1, ignore2 );
|
||||
if ( tmpFile.isExecutable() ) {
|
||||
this.mLauncher.saveToDisk( null, false );
|
||||
// Make sure onunload handler doesn't cancel.
|
||||
this.mDialog.dialog = null;
|
||||
// Close the dialog.
|
||||
this.mDialog.close();
|
||||
return;
|
||||
}
|
||||
|
@ -232,8 +282,8 @@ nsHelperAppDialog.prototype = {
|
|||
fname = suggestedFileName;
|
||||
|
||||
|
||||
var title = this.replaceInsert( win.getAttribute( "title" ), 1, fname);
|
||||
win.setAttribute( "title", title );
|
||||
this.mTitle = this.replaceInsert( win.getAttribute( "title" ), 1, fname);
|
||||
win.setAttribute( "title", this.mTitle );
|
||||
|
||||
// Put content type and location into intro.
|
||||
this.initIntro(url);
|
||||
|
@ -414,6 +464,10 @@ nsHelperAppDialog.prototype = {
|
|||
|
||||
this.processAlwaysAskState();
|
||||
|
||||
// Remove our web progress listener (a progress dialog will be
|
||||
// taking over).
|
||||
this.mLauncher.setWebProgressListener( null );
|
||||
|
||||
if ( this.dialogElement( "openUsing" ).selected )
|
||||
{
|
||||
// If no app "chosen" then convert input string to file.
|
||||
|
@ -435,6 +489,9 @@ nsHelperAppDialog.prototype = {
|
|||
|
||||
// onCancel:
|
||||
onCancel: function() {
|
||||
// Remove our web progress listener.
|
||||
this.mLauncher.setWebProgressListener( null );
|
||||
|
||||
// Cancel app launcher.
|
||||
try {
|
||||
this.mLauncher.Cancel();
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="&caption.label;"
|
||||
onload="dialog.initDialog()"
|
||||
onunload="if (dialog) dialog.onCancel()"
|
||||
style="width: 40em;"
|
||||
class="dialog">
|
||||
|
||||
|
|
|
@ -581,8 +581,11 @@ nsProgressDialog.prototype = {
|
|||
|
||||
// Activate reveal/launch buttons.
|
||||
this.enable( "reveal" );
|
||||
if ( this.target && !this.target.isExecutable() ) {
|
||||
this.enable( "launch" );
|
||||
try {
|
||||
if ( this.target && !this.target.isExecutable() ) {
|
||||
this.enable( "launch" );
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
|
||||
// Disable the Pause/Resume buttons.
|
||||
|
|
|
@ -41,4 +41,4 @@ launchError=%S could not be opened, because an unknown error occurred.\n\nSorry
|
|||
diskFull=There is not enough room on the disk to save %S.\n\nRemove unnecessary files from the disk and try again, or try saving in a different location.
|
||||
readOnly=%S could not be saved, because the disk, folder, or file is write-protected.\n\nWrite-enable the disk and try again, or try saving in a different location.
|
||||
accessError=%S could not be saved, because you cannot change the contents of that folder.\n\nChange the folder properties and try again, or try saving in a different location.
|
||||
|
||||
title=Downloading %S
|
||||
|
|
|
@ -1707,7 +1707,8 @@ nsTreeBodyFrame::PrefillPropertyArray(PRInt32 aRowIndex, nsTreeColumn* aCol)
|
|||
mScratchArray->AppendElement(nsXULAtoms::progressmeter);
|
||||
|
||||
PRInt32 state = nsITreeView::progressNone;
|
||||
mView->GetProgressMode(aRowIndex, aCol->GetID().get(), &state);
|
||||
if (aRowIndex != -1)
|
||||
mView->GetProgressMode(aRowIndex, aCol->GetID().get(), &state);
|
||||
if (state == nsITreeView::progressNormal)
|
||||
mScratchArray->AppendElement(nsXULAtoms::progressNormal);
|
||||
else if (state == nsITreeView::progressUndetermined)
|
||||
|
|
|
@ -53,6 +53,7 @@ REQUIRES = xpcom \
|
|||
plugin \
|
||||
pref \
|
||||
intl \
|
||||
windowwatcher \
|
||||
$(NULL)
|
||||
|
||||
OSHELPER = nsOSHelperAppService.cpp
|
||||
|
|
|
@ -33,6 +33,7 @@ REQUIRES = xpcom \
|
|||
plugin \
|
||||
unicharutil \
|
||||
intl \
|
||||
windowwatcher \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\config.mak>
|
||||
|
|
|
@ -78,6 +78,8 @@
|
|||
#include "nsEscape.h"
|
||||
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIPromptService.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
|
||||
const char *FORCE_ALWAYS_ASK_PREF = "browser.helperApps.alwaysAsk.force";
|
||||
|
||||
|
@ -758,23 +760,17 @@ NS_IMETHODIMP nsExternalAppHandler::Observe(nsISupports *aSubject, const char *a
|
|||
|
||||
NS_IMETHODIMP nsExternalAppHandler::SetWebProgressListener(nsIWebProgressListener * aWebProgressListener)
|
||||
{
|
||||
// this call back means we've succesfully brought up the
|
||||
// progress window so set the appropriate flag...
|
||||
|
||||
mProgressWindowCreated = PR_TRUE;
|
||||
|
||||
// while we were bringing up the progress dialog, we actually finished processing the
|
||||
// url. If that's the case then mStopRequestIssued will be true. Tell the dialog to go away in that
|
||||
// case and we need to execute the operation since we are actually done.
|
||||
if (mStopRequestIssued && aWebProgressListener)
|
||||
// The progress window only appears after the helper app dialog has told us
|
||||
// what to do. We need to be careful not to confuse helper app dialog
|
||||
// calls to this method with ones from the progress dialog!
|
||||
if (mReceivedDispostionInfo && aWebProgressListener)
|
||||
{
|
||||
// simulate a notification saying the document is done. This will turn around and cause our
|
||||
// progress dialog to go away....
|
||||
aWebProgressListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_STOP, NS_OK);
|
||||
return ExecuteDesiredAction();
|
||||
// this call back means we've succesfully brought up the
|
||||
// progress window so set the appropriate flag...
|
||||
mProgressWindowCreated = PR_TRUE;
|
||||
}
|
||||
|
||||
// o.t. go ahead and register the progress listener....
|
||||
// Go ahead and register the progress listener....
|
||||
|
||||
if (mLoadCookie)
|
||||
{
|
||||
|
@ -785,6 +781,15 @@ NS_IMETHODIMP nsExternalAppHandler::SetWebProgressListener(nsIWebProgressListene
|
|||
mWebProgressListener = aWebProgressListener;
|
||||
}
|
||||
}
|
||||
|
||||
// while we were bringing up the progress dialog, we actually finished processing the
|
||||
// url. If that's the case then mStopRequestIssued will be true. We need to execute the
|
||||
// operation since we are actually done now.
|
||||
if (mStopRequestIssued && aWebProgressListener)
|
||||
{
|
||||
return ExecuteDesiredAction();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1192,9 +1197,7 @@ NS_IMETHODIMP nsExternalAppHandler::OnStartRequest(nsIRequest *request, nsISuppo
|
|||
|
||||
// Convert error info into proper message text and send OnStatusChange notification
|
||||
// to the web progress listener.
|
||||
typedef enum { kReadError, kWriteError, kLaunchError } ErrorType;
|
||||
static void SendStatusChange(
|
||||
ErrorType type, nsresult rv, nsIRequest *aRequest, nsIWebProgressListener *aListener, const nsAFlatString &path)
|
||||
void nsExternalAppHandler::SendStatusChange(ErrorType type, nsresult rv, nsIRequest *aRequest, const nsAFlatString &path)
|
||||
{
|
||||
nsAutoString msgId;
|
||||
switch(rv)
|
||||
|
@ -1231,6 +1234,9 @@ static void SendStatusChange(
|
|||
}
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG_law
|
||||
printf( "\nError: %s, listener=0x%08X, rv=0x%08X\n\n", NS_LossyConvertUCS2toASCII(msgId).get(), (int)(void*)mWebProgressListener.get(), (int)rv );
|
||||
#endif
|
||||
// Get properties file bundle and extract status string.
|
||||
nsCOMPtr<nsIStringBundleService> s = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
|
||||
if (s)
|
||||
|
@ -1242,7 +1248,27 @@ static void SendStatusChange(
|
|||
const PRUnichar *strings[] = { path.get() };
|
||||
if(NS_SUCCEEDED(bundle->FormatStringFromName(msgId.get(), strings, 1, getter_Copies(msgText))))
|
||||
{
|
||||
aListener->OnStatusChange(nsnull, (type == kReadError) ? aRequest : nsnull, rv, msgText);
|
||||
if (mWebProgressListener)
|
||||
{
|
||||
// We have a listener, let it handle the error.
|
||||
mWebProgressListener->OnStatusChange(nsnull, (type == kReadError) ? aRequest : nsnull, rv, msgText);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't have a listener. Simply show the alert ourselves.
|
||||
nsCOMPtr<nsIPromptService> prompter(do_GetService("@mozilla.org/embedcomp/prompt-service;1"));
|
||||
nsXPIDLString title;
|
||||
bundle->FormatStringFromName(NS_LITERAL_STRING("title").get(),
|
||||
strings,
|
||||
1,
|
||||
getter_Copies(title));
|
||||
if (prompter)
|
||||
{
|
||||
// Extract parent window from context.
|
||||
nsCOMPtr<nsIDOMWindow> parent(do_GetInterface(mWindowContext));
|
||||
prompter->Alert(parent, title, msgText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1318,13 +1344,13 @@ NS_IMETHODIMP nsExternalAppHandler::OnDataAvailable(nsIRequest *request, nsISupp
|
|||
else
|
||||
{
|
||||
// An error occurred, notify listener.
|
||||
if (mWebProgressListener)
|
||||
{
|
||||
nsAutoString tempFilePath;
|
||||
if (mTempFile)
|
||||
mTempFile->GetPath(tempFilePath);
|
||||
SendStatusChange(readError ? kReadError : kWriteError, rv, request, mWebProgressListener, tempFilePath);
|
||||
}
|
||||
nsAutoString tempFilePath;
|
||||
if (mTempFile)
|
||||
mTempFile->GetPath(tempFilePath);
|
||||
SendStatusChange(readError ? kReadError : kWriteError, rv, request, tempFilePath);
|
||||
|
||||
// Cancel the download.
|
||||
Cancel();
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
@ -1335,15 +1361,21 @@ NS_IMETHODIMP nsExternalAppHandler::OnStopRequest(nsIRequest *request, nsISuppor
|
|||
{
|
||||
mStopRequestIssued = PR_TRUE;
|
||||
|
||||
// Cancel if the request did not complete successfully.
|
||||
if (!mCanceled && NS_FAILED(aStatus))
|
||||
{
|
||||
// Send error notification.
|
||||
nsAutoString tempFilePath;
|
||||
if (mTempFile)
|
||||
mTempFile->GetPath(tempFilePath);
|
||||
SendStatusChange( kReadError, aStatus, request, tempFilePath );
|
||||
|
||||
Cancel();
|
||||
}
|
||||
|
||||
// first, check to see if we've been canceled....
|
||||
if (mCanceled) { // then go cancel our underlying channel too
|
||||
nsresult rv = request->Cancel(NS_BINDING_ABORTED);
|
||||
// Notify dialog that download is complete.
|
||||
if(mWebProgressListener)
|
||||
{
|
||||
// XXX Do we need to check for errors here (server goes down, network cable cut, etc.)?
|
||||
mWebProgressListener->OnStateChange(nsnull, request, nsIWebProgressListener::STATE_STOP, NS_OK);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1359,13 +1391,6 @@ NS_IMETHODIMP nsExternalAppHandler::OnStopRequest(nsIRequest *request, nsISuppor
|
|||
mOutStream = nsnull;
|
||||
}
|
||||
|
||||
// Notify dialog that download is complete.
|
||||
if(mWebProgressListener)
|
||||
{
|
||||
// XXX Do we need to check for errors here (server goes down, network cable cut, etc.)?
|
||||
mWebProgressListener->OnStateChange(nsnull, request, nsIWebProgressListener::STATE_STOP, NS_OK);
|
||||
}
|
||||
|
||||
return ExecuteDesiredAction();
|
||||
}
|
||||
|
||||
|
@ -1377,6 +1402,8 @@ nsresult nsExternalAppHandler::ExecuteDesiredAction()
|
|||
nsMIMEInfoHandleAction action = nsIMIMEInfo::saveToDisk;
|
||||
mMimeInfo->GetPreferredAction(&action);
|
||||
if (action == nsIMIMEInfo::saveToDisk)
|
||||
// XXX Put progress dialog in barber-pole mode
|
||||
// and change text to say "Copying from:".
|
||||
rv = MoveFile(mFinalFileDestination);
|
||||
else
|
||||
{
|
||||
|
@ -1392,6 +1419,18 @@ nsresult nsExternalAppHandler::ExecuteDesiredAction()
|
|||
rv = OpenWithApplication(nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify dialog that download is complete.
|
||||
// By waiting till this point, it ensures that the progress dialog doesn't indicate
|
||||
// success until we're really done.
|
||||
if(mWebProgressListener)
|
||||
{
|
||||
if (!mCanceled)
|
||||
{
|
||||
mWebProgressListener->OnProgressChange(nsnull, nsnull, mContentLength, mContentLength, mContentLength, mContentLength);
|
||||
}
|
||||
mWebProgressListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_STOP, NS_OK);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -1535,12 +1574,13 @@ nsresult nsExternalAppHandler::MoveFile(nsIFile * aNewFileLocation)
|
|||
{
|
||||
rv = mTempFile->MoveToNative(directoryLocation, fileName);
|
||||
}
|
||||
if (NS_FAILED(rv) && mWebProgressListener)
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
// Send error notification.
|
||||
nsAutoString path;
|
||||
fileToUse->GetPath(path);
|
||||
SendStatusChange(kWriteError, rv, nsnull, mWebProgressListener, path);
|
||||
SendStatusChange(kWriteError, rv, nsnull, path);
|
||||
Cancel(); // Cancel (and clean up temp file).
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1563,6 +1603,9 @@ NS_IMETHODIMP nsExternalAppHandler::SaveToDisk(nsIFile * aNewFileLocation, PRBoo
|
|||
|
||||
mMimeInfo->SetPreferredAction(nsIMIMEInfo::saveToDisk);
|
||||
|
||||
// The helper app dialog has told us what to do.
|
||||
mReceivedDispostionInfo = PR_TRUE;
|
||||
|
||||
if (!aNewFileLocation)
|
||||
{
|
||||
nsAutoString leafName;
|
||||
|
@ -1597,7 +1640,6 @@ NS_IMETHODIMP nsExternalAppHandler::SaveToDisk(nsIFile * aNewFileLocation, PRBoo
|
|||
ProcessAnyRefreshTags();
|
||||
}
|
||||
|
||||
mReceivedDispostionInfo = PR_TRUE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1618,19 +1660,22 @@ nsresult nsExternalAppHandler::OpenWithApplication(nsIFile * aApplication)
|
|||
if (helperAppService)
|
||||
{
|
||||
rv = helperAppService->LaunchAppWithTempFile(mMimeInfo, mFinalFileDestination);
|
||||
if (NS_FAILED(rv) && mWebProgressListener)
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
// Send error notification.
|
||||
nsAutoString path;
|
||||
mFinalFileDestination->GetPath(path);
|
||||
SendStatusChange(kLaunchError, rv, nsnull, mWebProgressListener, path);
|
||||
SendStatusChange(kLaunchError, rv, nsnull, path);
|
||||
Cancel(); // Cancel, and clean up temp file.
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
#ifndef XP_MAC
|
||||
// Mac users have been very verbal about temp files being deleted on app exit - they
|
||||
// don't like it - but we'll continue to do this on other platforms for now
|
||||
helperAppService->DeleteTemporaryFileOnExit(mFinalFileDestination);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -227,6 +227,9 @@ protected:
|
|||
// the base class implementation ensures that mSuggestedFileName has
|
||||
// mTempFileExtension as extension;
|
||||
virtual void EnsureSuggestedFileName();
|
||||
// utility function to send proper error notification to web progress listener
|
||||
typedef enum { kReadError, kWriteError, kLaunchError } ErrorType;
|
||||
void SendStatusChange(ErrorType type, nsresult aStatus, nsIRequest *aRequest, const nsAFlatString &path);
|
||||
|
||||
nsCOMPtr<nsISupports> mLoadCookie; // load cookie used by the uri loader when we fetch the url
|
||||
nsCOMPtr<nsIWebProgressListener> mWebProgressListener;
|
||||
|
|
|
@ -130,8 +130,13 @@ var downloadViewController = {
|
|||
var isDownloading = gDownloadManager.getDownload(selectedItem.id);
|
||||
switch (aCommand) {
|
||||
case "cmd_openfile":
|
||||
if (!isDownloading && getFileForItem(selectedItem).isExecutable())
|
||||
try {
|
||||
if (!isDownloading && getFileForItem(selectedItem).isExecutable())
|
||||
return false;
|
||||
} catch(e) {
|
||||
// Exception means file doesn't exist; launch is not allowed.
|
||||
return false;
|
||||
}
|
||||
|
||||
case "cmd_showinshell":
|
||||
// some apps like kazaa/morpheus let you "preview" in-progress downloads because
|
||||
|
|
|
@ -4,6 +4,7 @@ notStarted=Not Started
|
|||
failed=Failed
|
||||
finished=Finished
|
||||
canceled=Canceled
|
||||
alertTitle=Download Error
|
||||
|
||||
showInShellLabelWin=Show in Explorer
|
||||
showInShellAccesskeyWin=E
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "nsIStringBundle.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIWindowMediator.h"
|
||||
#include "nsIPromptService.h"
|
||||
|
||||
/* Outstanding issues/todo:
|
||||
* 1. Implement pause/resume.
|
||||
|
@ -1032,9 +1033,8 @@ nsDownload::OnStatusChange(nsIWebProgress *aWebProgress,
|
|||
mDownloadState = FAILED;
|
||||
nsCAutoString path;
|
||||
nsresult rv = mTarget->GetNativePath(path);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
mDownloadManager->DownloadEnded(path.get(), aMessage);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mDownloadManager->DownloadEnded(path.get(), aMessage);
|
||||
}
|
||||
|
||||
if (mListener)
|
||||
|
@ -1049,6 +1049,31 @@ nsDownload::OnStatusChange(nsIWebProgress *aWebProgress,
|
|||
|
||||
if (mDialogListener)
|
||||
mDialogListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
|
||||
else {
|
||||
// Need to display error alert ourselves, if an error occurred.
|
||||
if (NS_FAILED(aStatus)) {
|
||||
// Get title for alert.
|
||||
nsXPIDLString title;
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(kStringBundleServiceCID, &rv);
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
if (bundleService)
|
||||
rv = bundleService->CreateBundle(DOWNLOAD_MANAGER_BUNDLE, getter_AddRefs(bundle));
|
||||
if (bundle)
|
||||
bundle->GetStringFromName(NS_LITERAL_STRING("alertTitle").get(), getter_Copies(title));
|
||||
|
||||
// Get Download Manager window, to be parent of alert.
|
||||
nsCOMPtr<nsIWindowMediator> wm = do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv);
|
||||
nsCOMPtr<nsIDOMWindowInternal> dmWindow;
|
||||
if (wm)
|
||||
wm->GetMostRecentWindow(NS_LITERAL_STRING("Download:Manager").get(), getter_AddRefs(dmWindow));
|
||||
|
||||
// Show alert.
|
||||
nsCOMPtr<nsIPromptService> prompter(do_GetService("@mozilla.org/embedcomp/prompt-service;1"));
|
||||
if (prompter)
|
||||
prompter->Alert(dmWindow, title, aMessage);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1077,6 +1102,9 @@ nsDownload::OnStateChange(nsIWebProgress* aWebProgress,
|
|||
if (aStateFlags & STATE_STOP) {
|
||||
if (mDownloadState == DOWNLOADING || mDownloadState == NOTSTARTED) {
|
||||
mDownloadState = FINISHED;
|
||||
// Files less than 1Kb shouldn't show up as 0Kb.
|
||||
if (mMaxBytes==0)
|
||||
mMaxBytes = 1;
|
||||
mCurrBytes = mMaxBytes;
|
||||
mPercentComplete = 100;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче