зеркало из https://github.com/mozilla/pjs.git
Fix bug 145800 -- implement downlod progress UI in chimera. These changes allow us to reuse the nsDownloadListener and progress dialog for both Saving (with an nsIWebBrowserPersist) and downloading (where necko creates an nsIDownload, which we implement). They are also factored so that other cocoa apps could reuse the downloading backend with their own progress dialog. r=pinkerton/bryner/ccarlen.
This commit is contained in:
Родитель
1655a1a46f
Коммит
eaff371e3b
|
@ -36,7 +36,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "CHBrowserView.h"
|
||||
#import "ProgressDlgController.h"
|
||||
#import "FindDlgController.h"
|
||||
#import "nsCocoaBrowserService.h"
|
||||
#import "mozView.h"
|
||||
|
@ -65,18 +64,12 @@
|
|||
|
||||
// Saving of links/images/docs
|
||||
#include "nsIWebBrowserFocus.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDOMNSDocument.h"
|
||||
#include "nsIDOMLocation.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsIProperties.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsIMIMEInfo.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsISHistory.h"
|
||||
#include "nsIHistoryEntry.h"
|
||||
#include "nsISHEntry.h"
|
||||
|
@ -84,6 +77,7 @@
|
|||
#include "nsIContextMenuListener.h"
|
||||
#include "nsITooltipListener.h"
|
||||
#include "nsIEmbeddingSiteWindow2.h"
|
||||
#include "SaveHeaderSniffer.h"
|
||||
|
||||
typedef unsigned int DragReference;
|
||||
#include "nsIDragHelperService.h"
|
||||
|
@ -677,265 +671,7 @@ nsCocoaBrowserListener::SetContainer(id <NSBrowserContainer> aContainer)
|
|||
[mContainer retain];
|
||||
}
|
||||
|
||||
// Implementation of a header sniffer class that is used when saving Web pages and images.
|
||||
class nsHeaderSniffer : public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
|
||||
nsIDOMDocument* aDocument, nsIInputStream* aPostData,
|
||||
const nsCString& aSuggestedFilename, PRBool aBypassCache,
|
||||
NSView* aFilterView, NSPopUpButton* aFilterList)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mPersist = aPersist;
|
||||
mTmpFile = aFile;
|
||||
mURL = aURL;
|
||||
mDocument = aDocument;
|
||||
mPostData = aPostData;
|
||||
mDefaultFilename = aSuggestedFilename;
|
||||
mBypassCache = aBypassCache;
|
||||
mFilterView = aFilterView;
|
||||
mFilterList = aFilterList;
|
||||
}
|
||||
|
||||
virtual ~nsHeaderSniffer()
|
||||
{
|
||||
};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
protected:
|
||||
void PerformSave();
|
||||
|
||||
private:
|
||||
nsIWebBrowserPersist* mPersist; // Weak. It owns us as a listener.
|
||||
nsCOMPtr<nsIFile> mTmpFile;
|
||||
nsCOMPtr<nsIURI> mURL;
|
||||
nsCOMPtr<nsIDOMDocument> mDocument;
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
nsCString mDefaultFilename;
|
||||
PRBool mBypassCache;
|
||||
nsCString mContentType;
|
||||
nsCString mContentDisposition;
|
||||
NSView* mFilterView;
|
||||
NSPopUpButton* mFilterList;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsHeaderSniffer, nsIWebProgressListener)
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
if (aStateFlags & nsIWebProgressListener::STATE_START) {
|
||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
|
||||
channel->GetContentType(mContentType);
|
||||
|
||||
// Get the content-disposition if we're an HTTP channel.
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if (httpChannel)
|
||||
httpChannel->GetResponseHeader(nsCAutoString("content-disposition"), mContentDisposition);
|
||||
|
||||
mPersist->CancelSave();
|
||||
PRBool exists;
|
||||
mTmpFile->Exists(&exists);
|
||||
if (exists)
|
||||
mTmpFile->Remove(PR_FALSE);
|
||||
PerformSave();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsHeaderSniffer::PerformSave()
|
||||
{
|
||||
// Are we an HTML document? If so, we will want to append an accessory view to
|
||||
// the save dialog to provide the user with the option of doing a complete
|
||||
// save vs. a single file save.
|
||||
PRBool isHTML = (mDocument && mContentType.Equals("text/html") ||
|
||||
mContentType.Equals("text/xml") ||
|
||||
mContentType.Equals("application/xhtml+xml"));
|
||||
|
||||
// Next find out the directory that we should start in.
|
||||
nsCOMPtr<nsIPrefService> prefs(do_GetService("@mozilla.org/preferences-service;1"));
|
||||
if (!prefs)
|
||||
return;
|
||||
nsCOMPtr<nsIPrefBranch> dirBranch;
|
||||
prefs->GetBranch("browser.download.", getter_AddRefs(dirBranch));
|
||||
PRInt32 filterIndex = 0;
|
||||
if (dirBranch) {
|
||||
nsresult rv = dirBranch->GetIntPref("save_converter_index", &filterIndex);
|
||||
if (NS_FAILED(rv))
|
||||
filterIndex = 0;
|
||||
}
|
||||
if (mFilterList)
|
||||
[mFilterList selectItemAtIndex: filterIndex];
|
||||
|
||||
// We need to figure out what file name to use.
|
||||
nsCAutoString defaultFileName;
|
||||
if (!mContentDisposition.IsEmpty()) {
|
||||
// (1) Use the HTTP header suggestion.
|
||||
PRInt32 index = mContentDisposition.Find("filename=");
|
||||
if (index >= 0) {
|
||||
// Take the substring following the prefix.
|
||||
index += 9;
|
||||
nsCAutoString filename;
|
||||
mContentDisposition.Right(filename, mContentDisposition.Length() - index);
|
||||
defaultFileName = filename;
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(mURL));
|
||||
if (url)
|
||||
url->GetFileName(defaultFileName); // (2) For file URLs, use the file name.
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mDocument && isHTML) {
|
||||
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
|
||||
nsAutoString title;
|
||||
if (htmlDoc)
|
||||
htmlDoc->GetTitle(title); // (3) Use the title of the document.
|
||||
defaultFileName.AssignWithConversion(title);
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
// (4) Use the caller provided name.
|
||||
defaultFileName = mDefaultFilename;
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mURL)
|
||||
// (5) Use the host.
|
||||
mURL->GetHost(defaultFileName);
|
||||
|
||||
// One last case to handle about:blank and other fruity untitled pages.
|
||||
if (defaultFileName.IsEmpty())
|
||||
defaultFileName = "untitled";
|
||||
|
||||
// Validate the file name to ensure legality.
|
||||
for (PRUint32 i = 0; i < defaultFileName.Length(); i++)
|
||||
if (defaultFileName[i] == ':' || defaultFileName[i] == '/')
|
||||
defaultFileName.SetCharAt(i, ' ');
|
||||
|
||||
// Make sure the appropriate extension is appended to the suggested file name.
|
||||
nsCOMPtr<nsIURI> fileURI(do_CreateInstance("@mozilla.org/network/standard-url;1"));
|
||||
nsCOMPtr<nsIURL> fileURL(do_QueryInterface(fileURI));
|
||||
if (!fileURL)
|
||||
return;
|
||||
fileURL->SetFilePath(defaultFileName);
|
||||
|
||||
nsCAutoString fileExtension;
|
||||
fileURL->GetFileExtension(fileExtension);
|
||||
|
||||
PRBool setExtension = PR_FALSE;
|
||||
if (mContentType.Equals("text/html")) {
|
||||
if (fileExtension.IsEmpty() || (!fileExtension.Equals("htm") && !fileExtension.Equals("html"))) {
|
||||
defaultFileName += ".html";
|
||||
setExtension = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!setExtension && fileExtension.IsEmpty()) {
|
||||
nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1"));
|
||||
if (!mimeService)
|
||||
return;
|
||||
nsCOMPtr<nsIMIMEInfo> mimeInfo;
|
||||
mimeService->GetFromMIMEType(mContentType.get(), getter_AddRefs(mimeInfo));
|
||||
if (!mimeInfo)
|
||||
return;
|
||||
|
||||
PRUint32 extCount = 0;
|
||||
char** extList = nsnull;
|
||||
mimeInfo->GetFileExtensions(&extCount, &extList);
|
||||
if (extCount > 0 && extList) {
|
||||
defaultFileName += ".";
|
||||
defaultFileName += extList[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Now it's time to pose the save dialog.
|
||||
NSSavePanel* savePanel = [NSSavePanel savePanel];
|
||||
NSString* file = nil;
|
||||
if (!defaultFileName.IsEmpty())
|
||||
file = [[NSString alloc] initWithCString: defaultFileName.get()];
|
||||
|
||||
if (isHTML)
|
||||
[savePanel setAccessoryView: mFilterView];
|
||||
|
||||
if ([savePanel runModalForDirectory: nil file: file] == NSFileHandlingPanelCancelButton)
|
||||
return;
|
||||
|
||||
// Release the file string.
|
||||
[file release];
|
||||
|
||||
// Update the filter index.
|
||||
if (isHTML && mFilterList) {
|
||||
filterIndex = [mFilterList indexOfSelectedItem];
|
||||
dirBranch->SetIntPref("save_converter_index", filterIndex);
|
||||
}
|
||||
|
||||
// Convert the content type to text/plain if it was selected in the filter.
|
||||
if (isHTML && filterIndex == 2)
|
||||
mContentType = "text/plain";
|
||||
|
||||
nsCOMPtr<nsISupports> sourceData;
|
||||
if (isHTML && filterIndex != 1)
|
||||
sourceData = do_QueryInterface(mDocument);
|
||||
else
|
||||
sourceData = do_QueryInterface(mURL);
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPersist> webPersist(do_CreateInstance(persistContractID));
|
||||
ProgressDlgController* progressDialog = [[ProgressDlgController alloc] initWithWindowNibName: @"ProgressDialog"];
|
||||
[progressDialog setWebPersist: webPersist
|
||||
source: sourceData.get()
|
||||
destination: [savePanel filename]
|
||||
contentType: mContentType.get()
|
||||
postData: mPostData
|
||||
bypassCache: mBypassCache];
|
||||
|
||||
[progressDialog showWindow: progressDialog];
|
||||
}
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation CHBrowserView
|
||||
|
||||
|
@ -1244,13 +980,17 @@ nsHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aReq
|
|||
shEntry->GetPostData(getter_AddRefs(postData));
|
||||
}
|
||||
|
||||
// when saving, we first fire off a save with a nsHeaderSniffer as a progress
|
||||
// listener. This allows us to look for the content-disposition header, which
|
||||
// can supply a filename, and maybe has something to do with CGI-generated
|
||||
// content (?)
|
||||
nsCAutoString fileName(aFilename);
|
||||
nsHeaderSniffer* sniffer = new nsHeaderSniffer(webPersist, tmpFile, aURI,
|
||||
aDocument, postData, fileName, aBypassCache,
|
||||
aFilterView, aFilterList);
|
||||
if (!sniffer)
|
||||
return;
|
||||
webPersist->SetProgressListener(sniffer);
|
||||
webPersist->SetProgressListener(sniffer); // owned
|
||||
webPersist->SaveURI(aURI, nsnull, tmpFile);
|
||||
}
|
||||
|
||||
|
|
|
@ -89,8 +89,11 @@ app_getModuleInfo(nsStaticModuleInfo **info, PRUint32 *count);
|
|||
nsresult rv;
|
||||
ICStop (mInternetConfig);
|
||||
nsCOMPtr<nsIPrefService> pref(do_GetService(NS_PREF_CONTRACTID, &rv));
|
||||
if (!NS_FAILED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
//NSLog(@"Saving prefs file");
|
||||
pref->SavePrefFile(nsnull);
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
F512F52B02D1287F01072C9F,
|
||||
F5A3669702CCFAF601DC3354,
|
||||
F512F52C02D1287F01072C9F,
|
||||
F50D9DE602ECC32301BB4219,
|
||||
F512F52D02D1287F01072C9F,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
|
@ -471,6 +472,10 @@
|
|||
F59236C202C89ACA0100012B,
|
||||
F5A3669802CCFAF601DC3354,
|
||||
F55C4DD402D2864E0130B065,
|
||||
F50D9DE402ECC2C601BB4219,
|
||||
F50D9DEF02EE0AB101BB4219,
|
||||
F50D9DF302EE194001BB4219,
|
||||
F50D9DF702EE2B9B01BB4219,
|
||||
);
|
||||
isa = PBXHeadersBuildPhase;
|
||||
name = Headers;
|
||||
|
@ -585,6 +590,10 @@
|
|||
F53E012D02AEE93701A967F3,
|
||||
F632AF8602B9AEBC01000103,
|
||||
F59236C302C89ACA0100012B,
|
||||
F50D9DE502ECC2C601BB4219,
|
||||
F50D9DF002EE0AB101BB4219,
|
||||
F50D9DF402EE194001BB4219,
|
||||
F50D9DF802EE2B9B01BB4219,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
name = Sources;
|
||||
|
@ -840,6 +849,145 @@
|
|||
name = Graphics;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE202ECC2C601BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = nsDownloadListener.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE302ECC2C601BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = nsDownloadListener.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE402ECC2C601BB4219 = {
|
||||
fileRef = F50D9DE202ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE502ECC2C601BB4219 = {
|
||||
fileRef = F50D9DE302ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE602ECC32301BB4219 = {
|
||||
children = (
|
||||
F50D9DF902EE2C1D01BB4219,
|
||||
F50D9DFA02EE2C1D01BB4219,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Downloading;
|
||||
path = "";
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE702ECC36201BB4219 = {
|
||||
fileRef = F50D9DE202ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE802ECC36201BB4219 = {
|
||||
fileRef = F632AF8302B9AEBB01000103;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE902ECC36201BB4219 = {
|
||||
fileRef = F50D9DE302ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DED02EE0AB101BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadProgressDisplay.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DEE02EE0AB101BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadProgressDisplay.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DEF02EE0AB101BB4219 = {
|
||||
fileRef = F50D9DED02EE0AB101BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF002EE0AB101BB4219 = {
|
||||
fileRef = F50D9DEE02EE0AB101BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF102EE194001BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadFactories.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF202EE194001BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadFactories.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF302EE194001BB4219 = {
|
||||
fileRef = F50D9DF102EE194001BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF402EE194001BB4219 = {
|
||||
fileRef = F50D9DF202EE194001BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF502EE2B9A01BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = SaveHeaderSniffer.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF602EE2B9A01BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = SaveHeaderSniffer.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF702EE2B9B01BB4219 = {
|
||||
fileRef = F50D9DF502EE2B9A01BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF802EE2B9B01BB4219 = {
|
||||
fileRef = F50D9DF602EE2B9A01BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF902EE2C1D01BB4219 = {
|
||||
children = (
|
||||
F50D9DF102EE194001BB4219,
|
||||
F50D9DF202EE194001BB4219,
|
||||
F50D9DED02EE0AB101BB4219,
|
||||
F50D9DEE02EE0AB101BB4219,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Generic;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DFA02EE2C1D01BB4219 = {
|
||||
children = (
|
||||
F50D9DF502EE2B9A01BB4219,
|
||||
F50D9DF602EE2B9A01BB4219,
|
||||
F517395B020CE3740189DA0C,
|
||||
F50D9DE302ECC2C601BB4219,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Chimera;
|
||||
path = "";
|
||||
refType = 4;
|
||||
};
|
||||
F50DCB4302C2856001A967F3 = {
|
||||
isa = PBXFileReference;
|
||||
name = libjsj.dylib;
|
||||
|
@ -1143,7 +1291,6 @@
|
|||
F512F52B02D1287F01072C9F = {
|
||||
children = (
|
||||
F5DE10E90209DC0601A967DF,
|
||||
F517395B020CE3740189DA0C,
|
||||
F528E21A020FD9620168DE43,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
|
@ -1176,7 +1323,6 @@
|
|||
};
|
||||
F512F53302D17A2601072C9F = {
|
||||
children = (
|
||||
F55C4DD302D2864D0130B065,
|
||||
29B97316FDCFA39411CA2CEA,
|
||||
F59236C002C89AC90100012B,
|
||||
F5AE04BA0206A4FE01A967DF,
|
||||
|
@ -1330,6 +1476,7 @@
|
|||
F507BA480213AD5F01D93544,
|
||||
F57074B5026BA85F01A80166,
|
||||
F57074B9026BFD0101A80166,
|
||||
2EEC3E61028138714B000102,
|
||||
F57074BD026D80DF01A80166,
|
||||
2E293A00027F33604B000102,
|
||||
F5607CB5023944AD01A967DF,
|
||||
|
@ -1344,6 +1491,8 @@
|
|||
F53E013202AEEA2801A967F3,
|
||||
F5A3669302CCFAF601DC3354,
|
||||
F59236C102C89AC90100012B,
|
||||
F50D9DE202ECC2C601BB4219,
|
||||
F55C4DD302D2864D0130B065,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Headers;
|
||||
|
@ -4375,7 +4524,6 @@
|
|||
F57074B6026BA85F01A80166,
|
||||
F57074BA026BFD0101A80166,
|
||||
F53E012C02AEE93601A967F3,
|
||||
2EEC3E61028138714B000102,
|
||||
2EEC3E62028138714B000102,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
|
@ -4959,6 +5107,8 @@
|
|||
F53E013402AEEA2901A967F3,
|
||||
F59236C402C89ACA0100012B,
|
||||
F5A3669A02CCFB7A01DC3354,
|
||||
F50D9DE702ECC36201BB4219,
|
||||
F50D9DE802ECC36201BB4219,
|
||||
);
|
||||
isa = PBXHeadersBuildPhase;
|
||||
name = Headers;
|
||||
|
@ -5074,6 +5224,7 @@
|
|||
F59236C502C89ACA0100012B,
|
||||
F5A3669B02CCFB7A01DC3354,
|
||||
F5A3669C02CCFB7A01DC3354,
|
||||
F50D9DE902ECC36201BB4219,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
name = Sources;
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// This file contains implementations of factories for various
|
||||
// downloading-related interfaces.
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
#import "ProgressDlgController.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIFactory.h"
|
||||
|
||||
#include "nsDownloadListener.h"
|
||||
#include "DownloadFactories.h"
|
||||
|
||||
// factory for nsIDownload objects
|
||||
// XXX replace with generic factory stuff
|
||||
class DownloadListenerFactory : public nsIFactory
|
||||
{
|
||||
public:
|
||||
DownloadListenerFactory();
|
||||
virtual ~DownloadListenerFactory();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIFACTORY
|
||||
|
||||
protected:
|
||||
|
||||
DownloadControllerFactory* mControllerFactory; // factory which creates the Cocoa window controller
|
||||
};
|
||||
|
||||
|
||||
DownloadListenerFactory::DownloadListenerFactory()
|
||||
: mControllerFactory(nil)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mControllerFactory = [[[ChimeraDownloadControllerFactory alloc] init] retain];
|
||||
}
|
||||
|
||||
DownloadListenerFactory::~DownloadListenerFactory()
|
||||
{
|
||||
[mControllerFactory release];
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(DownloadListenerFactory, nsIFactory);
|
||||
|
||||
/* void createInstance (in nsISupports aOuter, in nsIIDRef iid, [iid_is (iid), retval] out nsQIResult result); */
|
||||
NS_IMETHODIMP
|
||||
DownloadListenerFactory::CreateInstance(nsISupports *aOuter, const nsIID& aIID, void* *aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsIDownload)))
|
||||
{
|
||||
nsDownloadListener* downloadListener = new nsDownloadListener(mControllerFactory);
|
||||
if (!downloadListener) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(downloadListener);
|
||||
rv = downloadListener->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(downloadListener);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
/* void lockFactory (in PRBool lock); */
|
||||
NS_IMETHODIMP
|
||||
DownloadListenerFactory::LockFactory(PRBool lock)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
nsresult NewDownloadListenerFactory(nsIFactory* *outFactory)
|
||||
{
|
||||
DownloadListenerFactory* newFactory = new DownloadListenerFactory();
|
||||
if (!newFactory) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(newFactory);
|
||||
nsresult rv = newFactory->QueryInterface(NS_GET_IID(nsIFactory), (void **)outFactory);
|
||||
NS_RELEASE(newFactory);
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
The classes and protocol in this file allow Cocoa applications to easily
|
||||
reuse the underlying download implementation, which deals with the complexity
|
||||
of Gecko's downloading callbacks.
|
||||
|
||||
There are three things here:
|
||||
|
||||
1. The DownloadProgressDisplay protocol.
|
||||
|
||||
This is a formal protocol that needs to be implemented by
|
||||
a window controller for your progress window. Its methods
|
||||
will be called by the underlying C++ downloading classes.
|
||||
|
||||
2. The Obj-C DownloadControllerFactory class.
|
||||
|
||||
This class should be subclassed by an embedder, with an
|
||||
implementation of 'createDownloadController' that hands back
|
||||
a new instance of an NSWindowController that implements the
|
||||
<DownloadProgressDisplay> protocol.
|
||||
|
||||
The underlying C++ classes use this factory to create the
|
||||
progress window controller.
|
||||
|
||||
3. The nsDownloader C++ class
|
||||
|
||||
This base class exists to hide the complextity of the download
|
||||
listener classes (which deal with Gecko callbacks) from the
|
||||
window controller. Embedders don't need to do anything with it.
|
||||
|
||||
How these classes fit together:
|
||||
|
||||
There are 2 ways in which a download is initiated:
|
||||
|
||||
(i) File->Save.
|
||||
|
||||
Chimera does a complex dance here in order to get certain
|
||||
information about the data being downloaded (it needs to
|
||||
start the download before it can read some optional MIME headers).
|
||||
|
||||
CBrowserView creates an nsIWebBrowserPersist (WBP), and then a
|
||||
nsHeaderSniffer, which implements nsIWebProgressListener and is set to
|
||||
observer the WBP. When nsHeaderSniffer hears about the start of the
|
||||
download, it decides on a file name, and what format to save the data
|
||||
in. It then cancels the current WPB, makes another one, and does
|
||||
a CreateInstance of an nsIDownload (making one of our nsDownloadListener
|
||||
-- aka nsDownloder -- objects), and sets that as the nsIWebProgressListener.
|
||||
The full download procedes from there.
|
||||
|
||||
(ii) Click to download (e.g. FTP link)
|
||||
|
||||
This is simpler. The backend (necko) does the CreateInstance of the
|
||||
nsIDownload, and the download progresses.
|
||||
|
||||
In both cases, creating the nsDownloadListener and calling its Init() method
|
||||
calls nsDownloder::CreateDownloadDisplay(). The nsDownloder has as a member
|
||||
variable a DownloadControllerFactory (see above), which got passed to it
|
||||
via our XPCOM factory for nsIDownload objects. It then uses that DownloadControllerFactory
|
||||
to get an instance of the download progress window controller, which then
|
||||
shows the download progress window.
|
||||
|
||||
Simple, eh?
|
||||
|
||||
*/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsDownloader;
|
||||
|
||||
// a formal protocol for something that implements progress display
|
||||
// Embedders can make a window controller that conforms to this
|
||||
// protocol, and reuse nsDownloadListener to get download UI.
|
||||
@protocol DownloadProgressDisplay
|
||||
|
||||
- (void)onStartDownload;
|
||||
- (void)onEndDownload;
|
||||
|
||||
- (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress;
|
||||
|
||||
- (void)setDownloadListener:(nsDownloader*)aDownloader;
|
||||
- (void)setSourceURL:(NSString*)aSourceURL;
|
||||
- (void)setDestinationPath:(NSString*)aDestPath;
|
||||
|
||||
@end
|
||||
|
||||
// subclass this, and have your subclass instantiate and return your window
|
||||
// controller in createDownloadController
|
||||
@interface DownloadControllerFactory : NSObject
|
||||
{
|
||||
}
|
||||
|
||||
- (NSWindowController<DownloadProgressDisplay> *)createDownloadController;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// Pure virtual base class for a generic downloader, that the progress UI can talk to.
|
||||
// It implements nsISupports so that it can be refcounted. This class insulates the
|
||||
// UI code from having to know too much about the nsIDownloadListener.
|
||||
// It is responsible for creating the download UI, via the DownloadControllerFactory
|
||||
// that it owns.
|
||||
class nsDownloader : public nsISupports
|
||||
{
|
||||
public:
|
||||
nsDownloader(DownloadControllerFactory* inControllerFactory);
|
||||
virtual ~nsDownloader();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void PauseDownload() = 0;
|
||||
virtual void ResumeDownload() = 0;
|
||||
virtual void CancelDownload() = 0;
|
||||
virtual void DownloadDone() = 0;
|
||||
|
||||
virtual void CreateDownloadDisplay();
|
||||
|
||||
protected:
|
||||
|
||||
DownloadControllerFactory* mControllerFactory;
|
||||
id <DownloadProgressDisplay> mDownloadDisplay; // something that implements the DownloadProgressDisplay protocol
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
|
||||
|
||||
@implementation DownloadControllerFactory
|
||||
|
||||
- (NSWindowController<DownloadProgressDisplay> *)createDownloadController
|
||||
{
|
||||
// a dummy implementation. You should provide a subclass that
|
||||
// returns an instance of your progress dialog controller.
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// see the header file for comments
|
||||
nsDownloader::nsDownloader(DownloadControllerFactory* inControllerFactory)
|
||||
: mControllerFactory(inControllerFactory)
|
||||
, mDownloadDisplay(nil)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
[mControllerFactory retain];
|
||||
}
|
||||
|
||||
nsDownloader::~nsDownloader()
|
||||
{
|
||||
[mControllerFactory release];
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDownloader, nsISupports);
|
||||
|
||||
void
|
||||
nsDownloader::CreateDownloadDisplay()
|
||||
{
|
||||
mDownloadDisplay = [mControllerFactory createDownloadController];
|
||||
[mDownloadDisplay setDownloadListener:this];
|
||||
}
|
|
@ -3,13 +3,13 @@
|
|||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>73 360 356 240 0 0 1152 848 </string>
|
||||
<string>61 108 356 240 0 0 1152 746 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>266</key>
|
||||
<string>418 452 277 90 0 0 1152 746 </string>
|
||||
<string>23 342 277 90 0 0 1152 746 </string>
|
||||
<key>29</key>
|
||||
<string>8 803 446 44 0 0 1152 848 </string>
|
||||
<string>8 701 446 44 0 0 1152 746 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
|
|
Двоичный файл не отображается.
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
IBClasses = (
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{
|
||||
CLASS = ProgressDlgController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mElapsedTimeLabel = id;
|
||||
mFromField = id;
|
||||
mProgressBar = id;
|
||||
mStatusLabel = id;
|
||||
mTimeLeftLabel = id;
|
||||
mToField = id;
|
||||
};
|
||||
SUPERCLASS = NSWindowController;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>152 212 356 240 0 0 1024 746 </string>
|
||||
<string>94 26 404 250 0 0 1152 746 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
<key>IBOpenObjects</key>
|
||||
|
@ -11,6 +11,6 @@
|
|||
<integer>5</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>5Q125</string>
|
||||
<string>5S66</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
Двоичный файл не отображается.
|
@ -3,13 +3,13 @@
|
|||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>73 360 356 240 0 0 1152 848 </string>
|
||||
<string>61 108 356 240 0 0 1152 746 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>266</key>
|
||||
<string>418 452 277 90 0 0 1152 746 </string>
|
||||
<string>23 342 277 90 0 0 1152 746 </string>
|
||||
<key>29</key>
|
||||
<string>8 803 446 44 0 0 1152 848 </string>
|
||||
<string>8 701 446 44 0 0 1152 746 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
|
|
Двоичный файл не отображается.
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
IBClasses = (
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{
|
||||
CLASS = ProgressDlgController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mElapsedTimeLabel = id;
|
||||
mFromField = id;
|
||||
mProgressBar = id;
|
||||
mStatusLabel = id;
|
||||
mTimeLeftLabel = id;
|
||||
mToField = id;
|
||||
};
|
||||
SUPERCLASS = NSWindowController;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>152 212 356 240 0 0 1024 746 </string>
|
||||
<string>94 26 404 250 0 0 1152 746 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
<key>IBOpenObjects</key>
|
||||
|
@ -11,6 +11,6 @@
|
|||
<integer>5</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>5Q125</string>
|
||||
<string>5S66</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
Двоичный файл не отображается.
|
@ -36,6 +36,9 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
class nsIWebBrowserPersist;
|
||||
|
@ -43,42 +46,37 @@ class nsISupports;
|
|||
class nsIInputStream;
|
||||
class nsDownloadListener;
|
||||
|
||||
@interface ProgressDlgController : NSWindowController {
|
||||
IBOutlet id mFromField;
|
||||
IBOutlet id mToField;
|
||||
IBOutlet id mStatusLabel;
|
||||
IBOutlet id mTimeLeftLabel;
|
||||
IBOutlet id mElapsedTimeLabel;
|
||||
IBOutlet id mProgressBar;
|
||||
|
||||
@interface ChimeraDownloadControllerFactory : DownloadControllerFactory
|
||||
@end
|
||||
|
||||
|
||||
@interface ProgressDlgController : NSWindowController <DownloadProgressDisplay>
|
||||
{
|
||||
IBOutlet NSTextField *mElapsedTimeLabel;
|
||||
IBOutlet NSTextField *mFromField;
|
||||
IBOutlet NSTextField *mStatusLabel;
|
||||
IBOutlet NSTextField *mTimeLeftLabel;
|
||||
IBOutlet NSTextField *mToField;
|
||||
IBOutlet NSProgressIndicator *mProgressBar;
|
||||
|
||||
NSToolbarItem *pauseResumeToggleToolbarItem;
|
||||
NSToolbarItem *leaveOpenToggleToolbarItem;
|
||||
|
||||
BOOL mDownloadIsPaused;
|
||||
BOOL mSaveFileDialogShouldStayOpen;
|
||||
BOOL mDownloadIsComplete;
|
||||
long int aCurrentProgress; // if progress bar is indeterminate, can still calc stats.
|
||||
BOOL mDownloadIsPaused;
|
||||
BOOL mSaveFileDialogShouldStayOpen;
|
||||
BOOL mDownloadIsComplete;
|
||||
long mCurrentProgress; // if progress bar is indeterminate, can still calc stats.
|
||||
|
||||
nsDownloadListener* mDownloadListener;
|
||||
NSTimer *mDownloadTimer;
|
||||
nsDownloader *mDownloader; // we hold a ref to this
|
||||
NSTimer *mDownloadTimer;
|
||||
}
|
||||
|
||||
-(void) setWebPersist: (nsIWebBrowserPersist*)aPersist
|
||||
source: (nsISupports*)aSource
|
||||
destination: (NSString*)aDestination
|
||||
contentType: (const char*)aContentType
|
||||
postData: (nsIInputStream*)aInputStream
|
||||
bypassCache: (BOOL)aBypassCache;
|
||||
|
||||
-(void) setProgressBar:(long int)aCurProgress
|
||||
maxProg:(long int)aMaxProgress;
|
||||
-(void) setDownloadTimer;
|
||||
-(void) setupDownloadTimer;
|
||||
-(void) killDownloadTimer;
|
||||
-(void) setDownloadProgress:(NSTimer *)aTimer;
|
||||
-(NSString *) formatTime:(int)aSeconds;
|
||||
-(NSString *) formatFuzzyTime:(int)aSeconds;
|
||||
-(NSString *) formatBytes:(float)aBytes;
|
||||
-(void) setSourceURL: (const PRUnichar*)aSource;
|
||||
-(void) setDestination: (const PRUnichar*)aDestination;
|
||||
|
||||
@end
|
||||
|
|
|
@ -46,282 +46,58 @@
|
|||
#include "nsILocalFile.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIDownload.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
|
||||
class nsDownloadListener : public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsDownloadListener(ProgressDlgController* aController,
|
||||
nsIWebBrowserPersist* aPersist,
|
||||
nsISupports* aSource,
|
||||
NSString* aDestination,
|
||||
const char* aContentType,
|
||||
nsIInputStream* aPostData,
|
||||
BOOL aBypassCache)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mController = aController;
|
||||
mWebPersist = aPersist;
|
||||
// The source is either a simple URL or a complete document.
|
||||
mURL = do_QueryInterface(aSource);
|
||||
if (!mURL)
|
||||
mDocument = do_QueryInterface(aSource);
|
||||
|
||||
PRUint32 dstLen = [aDestination length];
|
||||
PRUnichar* tmp = new PRUnichar[dstLen + sizeof(PRUnichar)];
|
||||
tmp[dstLen] = (PRUnichar)'\0';
|
||||
[aDestination getCharacters:tmp];
|
||||
nsAutoString dstStr(tmp);
|
||||
delete tmp;
|
||||
|
||||
NS_NewLocalFile(dstStr, PR_FALSE, getter_AddRefs(mDestination));
|
||||
// XXX check for failure
|
||||
|
||||
mContentType = aContentType;
|
||||
mPostData = aPostData;
|
||||
mBypassCache = aBypassCache;
|
||||
mNetworkTransfer = PR_FALSE;
|
||||
mGotFirstStateChange = PR_FALSE;
|
||||
};
|
||||
|
||||
virtual ~nsDownloadListener() {};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
public:
|
||||
void BeginDownload();
|
||||
void InitDialog();
|
||||
void CancelDownload();
|
||||
|
||||
private: // Member variables
|
||||
ProgressDlgController* mController; // Controller for our UI.
|
||||
nsCOMPtr<nsIWebBrowserPersist> mWebPersist; // Our web persist object.
|
||||
nsCOMPtr<nsIURL> mURL; // The URL of our source file. Null if we're saving a complete document.
|
||||
nsCOMPtr<nsILocalFile> mDestination; // Our destination URL.
|
||||
nsCString mContentType; // Our content type string.
|
||||
nsCOMPtr<nsIDOMHTMLDocument> mDocument; // A DOM document. Null if we're only saving a simple URL.
|
||||
nsCOMPtr<nsIInputStream> mPostData; // For complete documents, this is our post data from session history.
|
||||
PRPackedBool mBypassCache; // Whether we should bypass the cache or not.
|
||||
PRPackedBool mNetworkTransfer; // true if the first OnStateChange has the NETWORK bit set
|
||||
PRPackedBool mGotFirstStateChange; // true after we've seen the first OnStateChange
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDownloadListener, nsIWebProgressListener)
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
[mController setProgressBar:aCurTotalProgress maxProg:aMaxTotalProgress];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
// NSLog(@"State changed: state %u, status %u", aStateFlags, aStatus);
|
||||
if (!mGotFirstStateChange) {
|
||||
mNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0);
|
||||
mGotFirstStateChange = PR_TRUE;
|
||||
}
|
||||
|
||||
// when the entire download finishes, stop the progress timer and clean up
|
||||
// the window and controller. We will get this even in the event of a cancel,
|
||||
// so this is the only place in the listener where we should kill the download.
|
||||
if ((aStateFlags & STATE_STOP) && (!mNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) {
|
||||
[mController killDownloadTimer];
|
||||
[mController setDownloadProgress:nil];
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::BeginDownload()
|
||||
{
|
||||
if (mWebPersist) {
|
||||
mWebPersist->SetProgressListener(this);
|
||||
PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION |
|
||||
nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
|
||||
if (mBypassCache)
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE;
|
||||
else
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
|
||||
|
||||
if (mURL)
|
||||
mWebPersist->SaveURI(mURL, mPostData, mDestination);
|
||||
else {
|
||||
PRInt32 encodingFlags = 0;
|
||||
nsCOMPtr<nsILocalFile> filesFolder;
|
||||
|
||||
if (!mContentType.Equals("text/plain")) {
|
||||
// Create a local directory in the same dir as our file. It
|
||||
// will hold our associated files.
|
||||
filesFolder = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
nsAutoString unicodePath;
|
||||
mDestination->GetPath(unicodePath);
|
||||
filesFolder->InitWithPath(unicodePath);
|
||||
|
||||
nsAutoString leafName;
|
||||
filesFolder->GetLeafName(leafName);
|
||||
nsAutoString nameMinusExt(leafName);
|
||||
PRInt32 index = nameMinusExt.RFind(".");
|
||||
if (index >= 0)
|
||||
nameMinusExt.Left(nameMinusExt, index);
|
||||
nameMinusExt += NS_LITERAL_STRING(" Files"); // XXXdwh needs to be localizable!
|
||||
filesFolder->SetLeafName(nameMinusExt);
|
||||
PRBool exists = PR_FALSE;
|
||||
filesFolder->Exists(&exists);
|
||||
if (!exists)
|
||||
filesFolder->Create(nsILocalFile::DIRECTORY_TYPE, 0755);
|
||||
}
|
||||
else
|
||||
encodingFlags |= nsIWebBrowserPersist::ENCODE_FLAGS_FORMATTED |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_ABSOLUTE_LINKS |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_NOFRAMES_CONTENT;
|
||||
|
||||
mWebPersist->SaveDocument(mDocument, mDestination, filesFolder, mContentType.get(),
|
||||
encodingFlags, 80);
|
||||
}
|
||||
}
|
||||
|
||||
InitDialog();
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::InitDialog()
|
||||
{
|
||||
if (!mURL && !mDocument)
|
||||
return;
|
||||
|
||||
if (mWebPersist) {
|
||||
if (mURL) {
|
||||
nsCAutoString spec;
|
||||
mURL->GetSpec(spec);
|
||||
nsAutoString spec2; spec2.AssignWithConversion(spec.get());
|
||||
[mController setSourceURL: spec2.get()];
|
||||
}
|
||||
else {
|
||||
nsAutoString spec;
|
||||
mDocument->GetURL(spec);
|
||||
[mController setSourceURL: spec.get()];
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString pathStr;
|
||||
mDestination->GetPath(pathStr);
|
||||
[mController setDestination: pathStr.get()];
|
||||
[mController setDownloadTimer];
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::CancelDownload()
|
||||
{
|
||||
if (mWebPersist)
|
||||
mWebPersist->CancelSave();
|
||||
}
|
||||
|
||||
|
||||
static NSString *SaveFileToolbarIdentifier = @"Save File Dialog Toolbar";
|
||||
static NSString *CancelToolbarItemIdentifier = @"Cancel Toolbar Item";
|
||||
static NSString *SaveFileToolbarIdentifier = @"Save File Dialog Toolbar";
|
||||
static NSString *CancelToolbarItemIdentifier = @"Cancel Toolbar Item";
|
||||
static NSString *PauseResumeToolbarItemIdentifier = @"Pause and Resume Toggle Toolbar Item";
|
||||
static NSString *ShowFileToolbarItemIdentifier = @"Show File Toolbar Item";
|
||||
static NSString *OpenFileToolbarItemIdentifier = @"Open File Toolbar Item";
|
||||
static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar Item";
|
||||
|
||||
|
||||
@implementation ChimeraDownloadControllerFactory : DownloadControllerFactory
|
||||
|
||||
- (NSWindowController<DownloadProgressDisplay> *)createDownloadController
|
||||
{
|
||||
NSWindowController* progressController = [[ProgressDlgController alloc] initWithWindowNibName: @"ProgressDialog"];
|
||||
NSAssert([progressController conformsToProtocol:@protocol(DownloadProgressDisplay)],
|
||||
@"progressController should conform to DownloadProgressDisplay protocol");
|
||||
return progressController;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
@interface ProgressDlgController(Private)
|
||||
-(void)setupToolbar;
|
||||
@end
|
||||
|
||||
@implementation ProgressDlgController
|
||||
|
||||
-(void)setWebPersist:(nsIWebBrowserPersist*)aPersist
|
||||
source:(nsISupports*)aSource
|
||||
destination:(NSString*)aDestination
|
||||
contentType:(const char*)aContentType
|
||||
postData:(nsIInputStream*)aInputStream
|
||||
bypassCache:(BOOL)aBypassCache
|
||||
- (void)dealloc
|
||||
{
|
||||
mDownloadListener = new nsDownloadListener(self, aPersist, aSource,
|
||||
aDestination, aContentType,
|
||||
aInputStream, aBypassCache);
|
||||
NS_ADDREF(mDownloadListener);
|
||||
}
|
||||
|
||||
-(void) setProgressBar:(long int)curProgress maxProg:(long int)maxProgress
|
||||
{
|
||||
aCurrentProgress = curProgress; // fall back for stat calcs
|
||||
if (![mProgressBar isIndeterminate]) { //most likely - just update value
|
||||
if (curProgress == maxProgress) //handles little bug in FTP download size
|
||||
[mProgressBar setMaxValue:maxProgress];
|
||||
[mProgressBar setDoubleValue:curProgress];
|
||||
}
|
||||
else if (maxProgress > 0) { // ok, we're starting up with good max & cur values
|
||||
[mProgressBar setIndeterminate:NO];
|
||||
[mProgressBar setMaxValue:maxProgress];
|
||||
[mProgressBar setDoubleValue:curProgress];
|
||||
} // if neither case was true, it's barber pole city.
|
||||
}
|
||||
|
||||
-(void) setSourceURL: (const PRUnichar*)aSource
|
||||
{
|
||||
[mFromField setStringValue: [NSString stringWithCharacters:aSource length:nsCRT::strlen(aSource)]];
|
||||
}
|
||||
|
||||
-(void) setDestination: (const PRUnichar*)aDestination
|
||||
{
|
||||
[mToField setStringValue: [[NSString stringWithCharacters:aDestination length:nsCRT::strlen(aDestination)] stringByAbbreviatingWithTildeInPath]];
|
||||
NS_IF_RELEASE(mDownloader);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)windowDidLoad
|
||||
{
|
||||
mDownloadIsPaused = NO;
|
||||
mDownloadIsComplete = NO;
|
||||
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID));
|
||||
PRBool save = PR_FALSE;
|
||||
prefs->GetBoolPref("browser.download.progressDnldDialog.keepAlive",&save);
|
||||
prefs->GetBoolPref("browser.download.progressDnldDialog.keepAlive", &save);
|
||||
mSaveFileDialogShouldStayOpen = save;
|
||||
|
||||
[self setupToolbar];
|
||||
[mProgressBar setUsesThreadedAnimation:YES];
|
||||
[mProgressBar startAnimation:self];
|
||||
if (mDownloadListener)
|
||||
mDownloadListener->BeginDownload();
|
||||
[mProgressBar startAnimation:self]; // move to onStateChange
|
||||
}
|
||||
|
||||
- (void)setupToolbar
|
||||
|
@ -438,7 +214,9 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
|
||||
-(void)cancel
|
||||
{
|
||||
mDownloadListener->CancelDownload();
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->CancelDownload();
|
||||
|
||||
// clean up downloaded file. - do it here on in CancelDownload?
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSString *thePath = [[mToField stringValue] stringByExpandingTildeInPath];
|
||||
|
@ -457,22 +235,29 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
|
||||
-(void)pauseAndResumeDownload
|
||||
{
|
||||
if ( ! mDownloadIsPaused ) {
|
||||
//Do logic to pause download
|
||||
if ( !mDownloadIsPaused )
|
||||
{
|
||||
mDownloadIsPaused = YES;
|
||||
[pauseResumeToggleToolbarItem setLabel:@"Resume"];
|
||||
[pauseResumeToggleToolbarItem setPaletteLabel:@"Resume Download"];
|
||||
[pauseResumeToggleToolbarItem setToolTip:@"Resume the paused FTP download"];
|
||||
[pauseResumeToggleToolbarItem setImage:[NSImage imageNamed:@"saveResume"]];
|
||||
[self killDownloadTimer];
|
||||
} else {
|
||||
//Do logic to resume download
|
||||
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->PauseDownload();
|
||||
}
|
||||
else
|
||||
{
|
||||
mDownloadIsPaused = NO;
|
||||
[pauseResumeToggleToolbarItem setLabel:@"Pause"];
|
||||
[pauseResumeToggleToolbarItem setPaletteLabel:@"Pause Download"];
|
||||
[pauseResumeToggleToolbarItem setToolTip:@"Pause this FTP file download"];
|
||||
[pauseResumeToggleToolbarItem setImage:[NSImage imageNamed:@"savePause"]];
|
||||
[self setDownloadTimer];
|
||||
[self setupDownloadTimer];
|
||||
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->ResumeDownload();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,12 +316,6 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
NS_IF_RELEASE(mDownloadListener);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)killDownloadTimer
|
||||
{
|
||||
if (mDownloadTimer) {
|
||||
|
@ -545,7 +324,7 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
mDownloadTimer = nil;
|
||||
}
|
||||
}
|
||||
- (void)setDownloadTimer
|
||||
- (void)setupDownloadTimer
|
||||
{
|
||||
[self killDownloadTimer];
|
||||
mDownloadTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0
|
||||
|
@ -590,7 +369,7 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
return [[[NSString alloc] initWithString:[[NSBundle mainBundle] localizedStringForKey:@"UnderMin" value:@"Under a minute" table:@"ProgressDialog"]] autorelease];
|
||||
}
|
||||
// seconds becomes minutes and we keep checking.
|
||||
seconds=seconds/60;
|
||||
seconds = seconds/60;
|
||||
if (seconds < 60) {
|
||||
if (seconds < 2)
|
||||
return [[[NSString alloc] initWithString:[[NSBundle mainBundle] localizedStringForKey:@"AboutMin" value:@"About a minute" table:@"ProgressDialog"]] autorelease];
|
||||
|
@ -598,7 +377,7 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
return [[[NSString alloc] initWithFormat:[[NSBundle mainBundle] localizedStringForKey:@"AboutMins" value:@"About %d minutes" table:@"ProgressDialog"],seconds] autorelease];
|
||||
}
|
||||
//this download will never seemingly never end. now seconds become hours.
|
||||
seconds=seconds/60;
|
||||
seconds = seconds/60;
|
||||
if (seconds < 2)
|
||||
return [[[NSString alloc] initWithString:[[NSBundle mainBundle] localizedStringForKey:@"AboutHour" value:@"Over an hour" table:@"ProgressDialog"]] autorelease];
|
||||
return [[[NSString alloc] initWithFormat:[[NSBundle mainBundle] localizedStringForKey:@"AboutHours" value:@"Over %d hours" table:@"ProgressDialog"],seconds] autorelease];
|
||||
|
@ -629,8 +408,11 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
// this handles lots of things.
|
||||
- (void)setDownloadProgress:(NSTimer *)downloadTimer;
|
||||
{
|
||||
// XXX this logic needs cleaning up.
|
||||
|
||||
// Ack! we're closing the window with the download still running!
|
||||
if (mDownloadIsComplete) {
|
||||
if (mDownloadIsComplete)
|
||||
{
|
||||
[[self window] performClose:self];
|
||||
return;
|
||||
}
|
||||
|
@ -644,26 +426,28 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
[mElapsedTimeLabel setStringValue:[self formatTime:(++elapsedSec)]];
|
||||
// for status field & time left
|
||||
float maxBytes = ([mProgressBar maxValue]);
|
||||
float byteSec = aCurrentProgress/elapsedSec;
|
||||
float byteSec = mCurrentProgress/elapsedSec;
|
||||
// OK - if downloadTimer is nil, we're done - fix maxBytes value for status report.
|
||||
if (!downloadTimer)
|
||||
maxBytes = aCurrentProgress;
|
||||
maxBytes = mCurrentProgress;
|
||||
// update status field
|
||||
NSString *labelString = [[NSBundle mainBundle] localizedStringForKey:@"LabelString"
|
||||
value:@"%@ of %@ total (at %@/sec)"
|
||||
table:@"ProgressDialog"];
|
||||
[mStatusLabel setStringValue: [NSString stringWithFormat:labelString, [self formatBytes:aCurrentProgress], [self formatBytes:maxBytes], [self formatBytes:byteSec]]];
|
||||
[mStatusLabel setStringValue: [NSString stringWithFormat:labelString, [self formatBytes:mCurrentProgress], [self formatBytes:maxBytes], [self formatBytes:byteSec]]];
|
||||
// updating estimated time left field
|
||||
// if maxBytes < 0, can't calc time left.
|
||||
// if !downloadTimer, download is finished. either way, make sure time left is 0.
|
||||
if ((maxBytes > 0) && (downloadTimer)) {
|
||||
int secToGo = (int)ceil((elapsedSec*maxBytes/aCurrentProgress)-elapsedSec);
|
||||
if ((maxBytes > 0) && (downloadTimer))
|
||||
{
|
||||
int secToGo = (int)ceil((elapsedSec*maxBytes/mCurrentProgress) - elapsedSec);
|
||||
[mTimeLeftLabel setStringValue:[self formatFuzzyTime:secToGo]];
|
||||
}
|
||||
else if (!downloadTimer) { // download done. Set remaining time to 0, fix progress bar & cancel button
|
||||
else if (!downloadTimer)
|
||||
{ // download done. Set remaining time to 0, fix progress bar & cancel button
|
||||
mDownloadIsComplete = YES; // all done. we got a STATE_STOP
|
||||
[mTimeLeftLabel setStringValue:@""];
|
||||
[self setProgressBar:aCurrentProgress maxProg:aCurrentProgress];
|
||||
[self setProgressTo:mCurrentProgress ofMax:mCurrentProgress];
|
||||
if (!mSaveFileDialogShouldStayOpen)
|
||||
[[self window] performClose:self]; // close window
|
||||
else
|
||||
|
@ -673,4 +457,59 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
[mTimeLeftLabel setStringValue:@"???"];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// DownloadProgressDisplay protocol methods
|
||||
|
||||
- (void)onStartDownload
|
||||
{
|
||||
[self showWindow: self];
|
||||
[self setupDownloadTimer];
|
||||
}
|
||||
|
||||
- (void)onEndDownload
|
||||
{
|
||||
[self killDownloadTimer];
|
||||
[self setDownloadProgress:nil];
|
||||
}
|
||||
|
||||
- (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress
|
||||
{
|
||||
mCurrentProgress = aCurProgress; // fall back for stat calcs
|
||||
|
||||
if (![mProgressBar isIndeterminate]) //most likely - just update value
|
||||
{
|
||||
if (aCurProgress == aMaxProgress) //handles little bug in FTP download size
|
||||
[mProgressBar setMaxValue:aMaxProgress];
|
||||
|
||||
[mProgressBar setDoubleValue:aCurProgress];
|
||||
}
|
||||
else if (aMaxProgress > 0) // ok, we're starting up with good max & cur values
|
||||
{
|
||||
[mProgressBar setIndeterminate:NO];
|
||||
[mProgressBar setMaxValue:aMaxProgress];
|
||||
[mProgressBar setDoubleValue:aCurProgress];
|
||||
} // if neither case was true, it's barber pole city.
|
||||
}
|
||||
|
||||
-(void) setDownloadListener: (nsDownloader*)aDownloader
|
||||
{
|
||||
if (mDownloader != aDownloader)
|
||||
NS_IF_RELEASE(mDownloader);
|
||||
|
||||
NS_IF_ADDREF(mDownloader = aDownloader);
|
||||
}
|
||||
|
||||
- (void)setSourceURL:(NSString*)aSourceURL
|
||||
{
|
||||
[mFromField setStringValue: aSourceURL];
|
||||
[mFromField display]; // force an immmeditate update
|
||||
}
|
||||
|
||||
- (void)setDestinationPath:(NSString*)aDestPath
|
||||
{
|
||||
[mToField setStringValue: [aDestPath stringByAbbreviatingWithTildeInPath]];
|
||||
[mToField display]; // force an immmeditate update
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -55,7 +55,7 @@ class nsCocoaBrowserService : public nsIWindowCreator,
|
|||
public nsIPromptService,
|
||||
public nsIFactory,
|
||||
public nsIBadCertListener, public nsISecurityWarningDialogs, public nsINSSDialogs,
|
||||
public nsIHelperAppLauncherDialog, public nsIDownload, public nsIWebProgressListener
|
||||
public nsIHelperAppLauncherDialog
|
||||
{
|
||||
public:
|
||||
nsCocoaBrowserService();
|
||||
|
@ -69,8 +69,6 @@ public:
|
|||
NS_DECL_NSIBADCERTLISTENER
|
||||
NS_DECL_NSISECURITYWARNINGDIALOGS
|
||||
NS_DECL_NSIHELPERAPPLAUNCHERDIALOG
|
||||
NS_DECL_NSIDOWNLOAD
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
static nsresult InitEmbedding();
|
||||
static void TermEmbedding();
|
||||
|
|
|
@ -35,14 +35,15 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsCocoaBrowserService.h"
|
||||
#import "nsCocoaBrowserService.h"
|
||||
#import "DownloadFactories.h"
|
||||
#import "CHBrowserView.h"
|
||||
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIEmbeddingSiteWindow.h"
|
||||
#include "nsIProfile.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "CHBrowserView.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIPrompt.h"
|
||||
|
@ -74,13 +75,14 @@ nsCocoaBrowserService::~nsCocoaBrowserService()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS9(nsCocoaBrowserService,
|
||||
NS_IMPL_ISUPPORTS7(nsCocoaBrowserService,
|
||||
nsIWindowCreator,
|
||||
nsIPromptService,
|
||||
nsIFactory,
|
||||
nsIBadCertListener, nsISecurityWarningDialogs, nsINSSDialogs,
|
||||
nsIHelperAppLauncherDialog, nsIDownload, nsIWebProgressListener)
|
||||
nsIHelperAppLauncherDialog)
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsCocoaBrowserService::InitEmbedding()
|
||||
{
|
||||
|
@ -103,7 +105,7 @@ nsCocoaBrowserService::InitEmbedding()
|
|||
#define NS_PROMPTSERVICE_CID \
|
||||
{0xa2112d6a, 0x0e28, 0x421f, {0xb4, 0x6a, 0x25, 0xc0, 0xb3, 0x8, 0xcb, 0xd0}}
|
||||
static NS_DEFINE_CID(kPromptServiceCID, NS_PROMPTSERVICE_CID);
|
||||
nsresult rv = cr->RegisterFactory(kPromptServiceCID, "Prompt Service", "@mozilla.org/embedcomp/prompt-service;1",
|
||||
nsresult rv = cr->RegisterFactory(kPromptServiceCID, "Prompt Service", "@mozilla.org/embedcomp/prompt-service;1",
|
||||
sSingleton);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
@ -127,14 +129,18 @@ nsCocoaBrowserService::InitEmbedding()
|
|||
rv = cr->RegisterFactory(kHelperDlgCID, NS_IHELPERAPPLAUNCHERDLG_CLASSNAME, NS_IHELPERAPPLAUNCHERDLG_CONTRACTID,
|
||||
sSingleton);
|
||||
|
||||
// replace the downloader with our own which does rely on the xpfe downlaod manager
|
||||
// replace the downloader with our own which does not rely on the xpfe downlaod manager
|
||||
nsCOMPtr<nsIFactory> downloadFactory;
|
||||
rv = NewDownloadListenerFactory(getter_AddRefs(downloadFactory));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
static NS_DEFINE_CID(kDownloadCID, NS_DOWNLOAD_CID);
|
||||
rv = cr->RegisterFactory(kDownloadCID, "Download", NS_DOWNLOAD_CONTRACTID,
|
||||
sSingleton);
|
||||
rv = cr->RegisterFactory(kDownloadCID, "Download", NS_DOWNLOAD_CONTRACTID, downloadFactory);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsCocoaBrowserService::BrowserClosed()
|
||||
{
|
||||
|
@ -149,6 +155,7 @@ nsCocoaBrowserService::BrowserClosed()
|
|||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsCocoaBrowserService::TermEmbedding()
|
||||
{
|
||||
|
@ -195,8 +202,15 @@ nsCocoaBrowserService::CreateInstance(nsISupports *aOuter,
|
|||
const nsIID & aIID,
|
||||
void **aResult)
|
||||
{
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
/*
|
||||
if (aIID.Equals(NS_GET_IID(nsIHelperAppLauncherDialog)))
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
return sSingleton->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
|
@ -828,14 +842,12 @@ nsCocoaBrowserService::ConfirmPostToInsecureFromSecure(nsIInterfaceRequestor *ct
|
|||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::Show(nsIHelperAppLauncher* inLauncher, nsISupports* inContext)
|
||||
{
|
||||
NSLog(@"Show");
|
||||
return inLauncher->SaveToDisk(nsnull, PR_FALSE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::PromptForSaveToFile(nsISupports *aWindowContext, const PRUnichar *aDefaultFile, const PRUnichar *aSuggestedFileExtension, nsILocalFile **_retval)
|
||||
{
|
||||
NSLog(@"PromptForSaveToFile");
|
||||
NSString* filename = [NSString stringWithCharacters:aDefaultFile length:nsCRT::strlen(aDefaultFile)];
|
||||
NSSavePanel *thePanel = [NSSavePanel savePanel];
|
||||
|
||||
|
@ -844,7 +856,7 @@ NSLog(@"PromptForSaveToFile");
|
|||
// use nil for the path given to runModalForDirectory
|
||||
int runResult = [thePanel runModalForDirectory: nil file:filename];
|
||||
if (runResult == NSOKButton) {
|
||||
NSLog([thePanel filename]);
|
||||
// NSLog(@"Saving to %@", [thePanel filename]);
|
||||
NSString *theName = [thePanel filename];
|
||||
return NS_NewNativeLocalFile(nsDependentCString([theName fileSystemRepresentation]), PR_FALSE, _retval);
|
||||
}
|
||||
|
@ -856,140 +868,6 @@ NSLog([thePanel filename]);
|
|||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::ShowProgressDialog(nsIHelperAppLauncher *aLauncher, nsISupports *aContext)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::Init(nsIURI* aSource,
|
||||
nsILocalFile* aTarget,
|
||||
const PRUnichar* aDisplayName,
|
||||
const PRUnichar* aOpeningWith,
|
||||
PRInt64 aStartTime,
|
||||
nsIWebBrowserPersist* aPersist)
|
||||
{
|
||||
NSLog(@"nsIDownload::Init");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetDisplayName(PRUnichar** aDisplayName)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::SetDisplayName(const PRUnichar* aDisplayName)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetOpeningWith(PRUnichar** aOpeningWith)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetSource(nsIURI** aSource)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetTarget(nsILocalFile** aTarget)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetStartTime(PRInt64* aStartTime)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetPercentComplete(PRInt32* aPercentComplete)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetListener(nsIWebProgressListener** aListener)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::SetListener(nsIWebProgressListener* aListener)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetObserver(nsIObserver** aObserver)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::SetObserver(nsIObserver* aObserver)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetPersist(nsIWebBrowserPersist** aPersist)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnStateChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, nsIURI *aLocation)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnSecurityChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, PRUint32 aState)
|
||||
{
|
||||
NSLog(@"nsCocoaBrowserService::ShowProgressDialog");
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Appkit/Appkit.h>
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsIDownload.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsILocalFile.h"
|
||||
|
||||
|
||||
// maybe this should replace nsHeaderSniffer too?
|
||||
|
||||
class nsDownloadListener : public nsDownloader,
|
||||
public nsIDownload,
|
||||
public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsDownloadListener(DownloadControllerFactory* inDownloadControllerFactory);
|
||||
virtual ~nsDownloadListener();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOWNLOAD
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
public:
|
||||
//void BeginDownload();
|
||||
void InitDialog();
|
||||
|
||||
virtual void PauseDownload();
|
||||
virtual void ResumeDownload();
|
||||
virtual void CancelDownload();
|
||||
virtual void DownloadDone();
|
||||
|
||||
private:
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPersist> mWebPersist; // Our web persist object.
|
||||
nsCOMPtr<nsIURI> mURI; // The URI of our source file. Null if we're saving a complete document.
|
||||
nsCOMPtr<nsILocalFile> mDestination; // Our destination URL.
|
||||
PRInt64 mStartTime; // When the download started
|
||||
PRPackedBool mBypassCache; // Whether we should bypass the cache or not.
|
||||
PRPackedBool mNetworkTransfer; // true if the first OnStateChange has the NETWORK bit set
|
||||
PRPackedBool mGotFirstStateChange; // true after we've seen the first OnStateChange
|
||||
PRPackedBool mUserCanceled; // true if the user canceled the download
|
||||
};
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsDownloadListener.h"
|
||||
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIURL.h"
|
||||
#include "netCore.h"
|
||||
|
||||
nsDownloadListener::nsDownloadListener(DownloadControllerFactory* inControllerFactory)
|
||||
: nsDownloader(inControllerFactory)
|
||||
, mBypassCache(PR_FALSE)
|
||||
, mNetworkTransfer(PR_FALSE)
|
||||
, mGotFirstStateChange(PR_FALSE)
|
||||
, mUserCanceled(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
nsDownloadListener::~nsDownloadListener()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(nsDownloadListener, nsDownloader, nsIDownload, nsIWebProgressListener)
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in wstring openingWith, in long long startTime, in nsIWebBrowserPersist aPersist); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName,
|
||||
const PRUnichar *openingWith, PRInt64 startTime, nsIWebBrowserPersist *aPersist)
|
||||
{
|
||||
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()
|
||||
}
|
||||
|
||||
mDestination = aTarget;
|
||||
mURI = aSource;
|
||||
mStartTime = startTime;
|
||||
|
||||
InitDialog();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIURI source; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetSource(nsIURI * *aSource)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSource);
|
||||
NS_IF_ADDREF(*aSource = mURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsILocalFile target; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetTarget(nsILocalFile * *aTarget)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTarget);
|
||||
NS_IF_ADDREF(*aTarget = mDestination);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIWebBrowserPersist persist; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetPersist(nsIWebBrowserPersist * *aPersist)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPersist);
|
||||
NS_IF_ADDREF(*aPersist = mWebPersist);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute PRInt32 percentComplete; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetPercentComplete(PRInt32 *aPercentComplete)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute wstring displayName; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetDisplayName(PRUnichar * *aDisplayName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::SetDisplayName(const PRUnichar * aDisplayName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* readonly attribute long long startTime; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetStartTime(PRInt64 *aStartTime)
|
||||
{
|
||||
NS_ENSURE_ARG(aStartTime);
|
||||
*aStartTime = mStartTime;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute wstring openingWith; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetOpeningWith(PRUnichar * *aOpeningWith)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute nsIWebProgressListener listener; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetListener(nsIWebProgressListener * *aListener)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aListener);
|
||||
NS_IF_ADDREF(*aListener = (nsIWebProgressListener *)this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
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); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
if (mUserCanceled)
|
||||
{
|
||||
if (aRequest)
|
||||
aRequest->Cancel(NS_BINDING_ABORTED);
|
||||
|
||||
mUserCanceled = false;
|
||||
}
|
||||
|
||||
[mDownloadDisplay setProgressTo:aCurTotalProgress ofMax:aMaxTotalProgress];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
// NSLog(@"State changed: state %u, status %u", aStateFlags, aStatus);
|
||||
if (!mGotFirstStateChange) {
|
||||
mNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0);
|
||||
mGotFirstStateChange = PR_TRUE;
|
||||
}
|
||||
|
||||
// when the entire download finishes, stop the progress timer and clean up
|
||||
// the window and controller. We will get this even in the event of a cancel,
|
||||
// so this is the only place in the listener where we should kill the download.
|
||||
if ((aStateFlags & STATE_STOP) && (!mNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) {
|
||||
DownloadDone();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
void
|
||||
nsDownloadListener::InitDialog()
|
||||
{
|
||||
// dialog has to be shown before the outlets get hooked up
|
||||
[mDownloadDisplay onStartDownload];
|
||||
|
||||
if (mURI)
|
||||
{
|
||||
nsCAutoString spec;
|
||||
mURI->GetSpec(spec);
|
||||
[mDownloadDisplay setSourceURL: [NSString stringWithUTF8String:spec.get()]];
|
||||
}
|
||||
|
||||
nsAutoString pathStr;
|
||||
mDestination->GetPath(pathStr);
|
||||
[mDownloadDisplay setDestinationPath: [NSString stringWithCharacters:pathStr.get() length:pathStr.Length()]];
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::PauseDownload()
|
||||
{
|
||||
// write me
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::ResumeDownload()
|
||||
{
|
||||
// write me
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::CancelDownload()
|
||||
{
|
||||
mUserCanceled = PR_TRUE;
|
||||
|
||||
if (mWebPersist)
|
||||
{
|
||||
mWebPersist->CancelSave();
|
||||
mUserCanceled = PR_FALSE;
|
||||
}
|
||||
|
||||
// delete any files we've created...
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::DownloadDone()
|
||||
{
|
||||
// break the reference cycle by removing ourselves as a listener
|
||||
if (mWebPersist)
|
||||
{
|
||||
mWebPersist->SetProgressListener(nsnull);
|
||||
mWebPersist = nsnull;
|
||||
}
|
||||
|
||||
[mDownloadDisplay onEndDownload];
|
||||
}
|
||||
|
||||
#pragma mark -
|
|
@ -14,6 +14,7 @@
|
|||
F512F52B02D1287F01072C9F,
|
||||
F5A3669702CCFAF601DC3354,
|
||||
F512F52C02D1287F01072C9F,
|
||||
F50D9DE602ECC32301BB4219,
|
||||
F512F52D02D1287F01072C9F,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
|
@ -471,6 +472,10 @@
|
|||
F59236C202C89ACA0100012B,
|
||||
F5A3669802CCFAF601DC3354,
|
||||
F55C4DD402D2864E0130B065,
|
||||
F50D9DE402ECC2C601BB4219,
|
||||
F50D9DEF02EE0AB101BB4219,
|
||||
F50D9DF302EE194001BB4219,
|
||||
F50D9DF702EE2B9B01BB4219,
|
||||
);
|
||||
isa = PBXHeadersBuildPhase;
|
||||
name = Headers;
|
||||
|
@ -585,6 +590,10 @@
|
|||
F53E012D02AEE93701A967F3,
|
||||
F632AF8602B9AEBC01000103,
|
||||
F59236C302C89ACA0100012B,
|
||||
F50D9DE502ECC2C601BB4219,
|
||||
F50D9DF002EE0AB101BB4219,
|
||||
F50D9DF402EE194001BB4219,
|
||||
F50D9DF802EE2B9B01BB4219,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
name = Sources;
|
||||
|
@ -840,6 +849,145 @@
|
|||
name = Graphics;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE202ECC2C601BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = nsDownloadListener.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE302ECC2C601BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = nsDownloadListener.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE402ECC2C601BB4219 = {
|
||||
fileRef = F50D9DE202ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE502ECC2C601BB4219 = {
|
||||
fileRef = F50D9DE302ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE602ECC32301BB4219 = {
|
||||
children = (
|
||||
F50D9DF902EE2C1D01BB4219,
|
||||
F50D9DFA02EE2C1D01BB4219,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Downloading;
|
||||
path = "";
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE702ECC36201BB4219 = {
|
||||
fileRef = F50D9DE202ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE802ECC36201BB4219 = {
|
||||
fileRef = F632AF8302B9AEBB01000103;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE902ECC36201BB4219 = {
|
||||
fileRef = F50D9DE302ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DED02EE0AB101BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadProgressDisplay.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DEE02EE0AB101BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadProgressDisplay.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DEF02EE0AB101BB4219 = {
|
||||
fileRef = F50D9DED02EE0AB101BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF002EE0AB101BB4219 = {
|
||||
fileRef = F50D9DEE02EE0AB101BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF102EE194001BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadFactories.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF202EE194001BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadFactories.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF302EE194001BB4219 = {
|
||||
fileRef = F50D9DF102EE194001BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF402EE194001BB4219 = {
|
||||
fileRef = F50D9DF202EE194001BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF502EE2B9A01BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = SaveHeaderSniffer.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF602EE2B9A01BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = SaveHeaderSniffer.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF702EE2B9B01BB4219 = {
|
||||
fileRef = F50D9DF502EE2B9A01BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF802EE2B9B01BB4219 = {
|
||||
fileRef = F50D9DF602EE2B9A01BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF902EE2C1D01BB4219 = {
|
||||
children = (
|
||||
F50D9DF102EE194001BB4219,
|
||||
F50D9DF202EE194001BB4219,
|
||||
F50D9DED02EE0AB101BB4219,
|
||||
F50D9DEE02EE0AB101BB4219,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Generic;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DFA02EE2C1D01BB4219 = {
|
||||
children = (
|
||||
F50D9DF502EE2B9A01BB4219,
|
||||
F50D9DF602EE2B9A01BB4219,
|
||||
F517395B020CE3740189DA0C,
|
||||
F50D9DE302ECC2C601BB4219,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Chimera;
|
||||
path = "";
|
||||
refType = 4;
|
||||
};
|
||||
F50DCB4302C2856001A967F3 = {
|
||||
isa = PBXFileReference;
|
||||
name = libjsj.dylib;
|
||||
|
@ -1143,7 +1291,6 @@
|
|||
F512F52B02D1287F01072C9F = {
|
||||
children = (
|
||||
F5DE10E90209DC0601A967DF,
|
||||
F517395B020CE3740189DA0C,
|
||||
F528E21A020FD9620168DE43,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
|
@ -1176,7 +1323,6 @@
|
|||
};
|
||||
F512F53302D17A2601072C9F = {
|
||||
children = (
|
||||
F55C4DD302D2864D0130B065,
|
||||
29B97316FDCFA39411CA2CEA,
|
||||
F59236C002C89AC90100012B,
|
||||
F5AE04BA0206A4FE01A967DF,
|
||||
|
@ -1330,6 +1476,7 @@
|
|||
F507BA480213AD5F01D93544,
|
||||
F57074B5026BA85F01A80166,
|
||||
F57074B9026BFD0101A80166,
|
||||
2EEC3E61028138714B000102,
|
||||
F57074BD026D80DF01A80166,
|
||||
2E293A00027F33604B000102,
|
||||
F5607CB5023944AD01A967DF,
|
||||
|
@ -1344,6 +1491,8 @@
|
|||
F53E013202AEEA2801A967F3,
|
||||
F5A3669302CCFAF601DC3354,
|
||||
F59236C102C89AC90100012B,
|
||||
F50D9DE202ECC2C601BB4219,
|
||||
F55C4DD302D2864D0130B065,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Headers;
|
||||
|
@ -4375,7 +4524,6 @@
|
|||
F57074B6026BA85F01A80166,
|
||||
F57074BA026BFD0101A80166,
|
||||
F53E012C02AEE93601A967F3,
|
||||
2EEC3E61028138714B000102,
|
||||
2EEC3E62028138714B000102,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
|
@ -4959,6 +5107,8 @@
|
|||
F53E013402AEEA2901A967F3,
|
||||
F59236C402C89ACA0100012B,
|
||||
F5A3669A02CCFB7A01DC3354,
|
||||
F50D9DE702ECC36201BB4219,
|
||||
F50D9DE802ECC36201BB4219,
|
||||
);
|
||||
isa = PBXHeadersBuildPhase;
|
||||
name = Headers;
|
||||
|
@ -5074,6 +5224,7 @@
|
|||
F59236C502C89ACA0100012B,
|
||||
F5A3669B02CCFB7A01DC3354,
|
||||
F5A3669C02CCFB7A01DC3354,
|
||||
F50D9DE902ECC36201BB4219,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
name = Sources;
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>73 360 356 240 0 0 1152 848 </string>
|
||||
<string>61 108 356 240 0 0 1152 746 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>266</key>
|
||||
<string>418 452 277 90 0 0 1152 746 </string>
|
||||
<string>23 342 277 90 0 0 1152 746 </string>
|
||||
<key>29</key>
|
||||
<string>8 803 446 44 0 0 1152 848 </string>
|
||||
<string>8 701 446 44 0 0 1152 746 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
|
|
Двоичный файл не отображается.
|
@ -5,12 +5,12 @@
|
|||
CLASS = ProgressDlgController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mElapsedTimeLabel = id;
|
||||
mFromField = id;
|
||||
mProgressBar = id;
|
||||
mStatusLabel = id;
|
||||
mTimeLeftLabel = id;
|
||||
mToField = id;
|
||||
mElapsedTimeLabel = NSTextField;
|
||||
mFromField = NSTextField;
|
||||
mProgressBar = NSProgressIndicator;
|
||||
mStatusLabel = NSTextField;
|
||||
mTimeLeftLabel = NSTextField;
|
||||
mToField = NSTextField;
|
||||
};
|
||||
SUPERCLASS = NSWindowController;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>152 212 356 240 0 0 1024 746 </string>
|
||||
<string>94 26 404 250 0 0 1152 746 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
<key>IBOpenObjects</key>
|
||||
|
@ -11,6 +11,6 @@
|
|||
<integer>5</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>5Q125</string>
|
||||
<string>5S66</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
Двоичные данные
camino/resources/localized/English.lproj/ProgressDialog.nib/objects.nib
сгенерированный
Двоичные данные
camino/resources/localized/English.lproj/ProgressDialog.nib/objects.nib
сгенерированный
Двоичный файл не отображается.
|
@ -36,6 +36,9 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
class nsIWebBrowserPersist;
|
||||
|
@ -43,42 +46,37 @@ class nsISupports;
|
|||
class nsIInputStream;
|
||||
class nsDownloadListener;
|
||||
|
||||
@interface ProgressDlgController : NSWindowController {
|
||||
IBOutlet id mFromField;
|
||||
IBOutlet id mToField;
|
||||
IBOutlet id mStatusLabel;
|
||||
IBOutlet id mTimeLeftLabel;
|
||||
IBOutlet id mElapsedTimeLabel;
|
||||
IBOutlet id mProgressBar;
|
||||
|
||||
@interface ChimeraDownloadControllerFactory : DownloadControllerFactory
|
||||
@end
|
||||
|
||||
|
||||
@interface ProgressDlgController : NSWindowController <DownloadProgressDisplay>
|
||||
{
|
||||
IBOutlet NSTextField *mElapsedTimeLabel;
|
||||
IBOutlet NSTextField *mFromField;
|
||||
IBOutlet NSTextField *mStatusLabel;
|
||||
IBOutlet NSTextField *mTimeLeftLabel;
|
||||
IBOutlet NSTextField *mToField;
|
||||
IBOutlet NSProgressIndicator *mProgressBar;
|
||||
|
||||
NSToolbarItem *pauseResumeToggleToolbarItem;
|
||||
NSToolbarItem *leaveOpenToggleToolbarItem;
|
||||
|
||||
BOOL mDownloadIsPaused;
|
||||
BOOL mSaveFileDialogShouldStayOpen;
|
||||
BOOL mDownloadIsComplete;
|
||||
long int aCurrentProgress; // if progress bar is indeterminate, can still calc stats.
|
||||
BOOL mDownloadIsPaused;
|
||||
BOOL mSaveFileDialogShouldStayOpen;
|
||||
BOOL mDownloadIsComplete;
|
||||
long mCurrentProgress; // if progress bar is indeterminate, can still calc stats.
|
||||
|
||||
nsDownloadListener* mDownloadListener;
|
||||
NSTimer *mDownloadTimer;
|
||||
nsDownloader *mDownloader; // we hold a ref to this
|
||||
NSTimer *mDownloadTimer;
|
||||
}
|
||||
|
||||
-(void) setWebPersist: (nsIWebBrowserPersist*)aPersist
|
||||
source: (nsISupports*)aSource
|
||||
destination: (NSString*)aDestination
|
||||
contentType: (const char*)aContentType
|
||||
postData: (nsIInputStream*)aInputStream
|
||||
bypassCache: (BOOL)aBypassCache;
|
||||
|
||||
-(void) setProgressBar:(long int)aCurProgress
|
||||
maxProg:(long int)aMaxProgress;
|
||||
-(void) setDownloadTimer;
|
||||
-(void) setupDownloadTimer;
|
||||
-(void) killDownloadTimer;
|
||||
-(void) setDownloadProgress:(NSTimer *)aTimer;
|
||||
-(NSString *) formatTime:(int)aSeconds;
|
||||
-(NSString *) formatFuzzyTime:(int)aSeconds;
|
||||
-(NSString *) formatBytes:(float)aBytes;
|
||||
-(void) setSourceURL: (const PRUnichar*)aSource;
|
||||
-(void) setDestination: (const PRUnichar*)aDestination;
|
||||
|
||||
@end
|
||||
|
|
|
@ -46,282 +46,58 @@
|
|||
#include "nsILocalFile.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIDownload.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
|
||||
class nsDownloadListener : public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsDownloadListener(ProgressDlgController* aController,
|
||||
nsIWebBrowserPersist* aPersist,
|
||||
nsISupports* aSource,
|
||||
NSString* aDestination,
|
||||
const char* aContentType,
|
||||
nsIInputStream* aPostData,
|
||||
BOOL aBypassCache)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mController = aController;
|
||||
mWebPersist = aPersist;
|
||||
// The source is either a simple URL or a complete document.
|
||||
mURL = do_QueryInterface(aSource);
|
||||
if (!mURL)
|
||||
mDocument = do_QueryInterface(aSource);
|
||||
|
||||
PRUint32 dstLen = [aDestination length];
|
||||
PRUnichar* tmp = new PRUnichar[dstLen + sizeof(PRUnichar)];
|
||||
tmp[dstLen] = (PRUnichar)'\0';
|
||||
[aDestination getCharacters:tmp];
|
||||
nsAutoString dstStr(tmp);
|
||||
delete tmp;
|
||||
|
||||
NS_NewLocalFile(dstStr, PR_FALSE, getter_AddRefs(mDestination));
|
||||
// XXX check for failure
|
||||
|
||||
mContentType = aContentType;
|
||||
mPostData = aPostData;
|
||||
mBypassCache = aBypassCache;
|
||||
mNetworkTransfer = PR_FALSE;
|
||||
mGotFirstStateChange = PR_FALSE;
|
||||
};
|
||||
|
||||
virtual ~nsDownloadListener() {};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
public:
|
||||
void BeginDownload();
|
||||
void InitDialog();
|
||||
void CancelDownload();
|
||||
|
||||
private: // Member variables
|
||||
ProgressDlgController* mController; // Controller for our UI.
|
||||
nsCOMPtr<nsIWebBrowserPersist> mWebPersist; // Our web persist object.
|
||||
nsCOMPtr<nsIURL> mURL; // The URL of our source file. Null if we're saving a complete document.
|
||||
nsCOMPtr<nsILocalFile> mDestination; // Our destination URL.
|
||||
nsCString mContentType; // Our content type string.
|
||||
nsCOMPtr<nsIDOMHTMLDocument> mDocument; // A DOM document. Null if we're only saving a simple URL.
|
||||
nsCOMPtr<nsIInputStream> mPostData; // For complete documents, this is our post data from session history.
|
||||
PRPackedBool mBypassCache; // Whether we should bypass the cache or not.
|
||||
PRPackedBool mNetworkTransfer; // true if the first OnStateChange has the NETWORK bit set
|
||||
PRPackedBool mGotFirstStateChange; // true after we've seen the first OnStateChange
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDownloadListener, nsIWebProgressListener)
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
[mController setProgressBar:aCurTotalProgress maxProg:aMaxTotalProgress];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
// NSLog(@"State changed: state %u, status %u", aStateFlags, aStatus);
|
||||
if (!mGotFirstStateChange) {
|
||||
mNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0);
|
||||
mGotFirstStateChange = PR_TRUE;
|
||||
}
|
||||
|
||||
// when the entire download finishes, stop the progress timer and clean up
|
||||
// the window and controller. We will get this even in the event of a cancel,
|
||||
// so this is the only place in the listener where we should kill the download.
|
||||
if ((aStateFlags & STATE_STOP) && (!mNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) {
|
||||
[mController killDownloadTimer];
|
||||
[mController setDownloadProgress:nil];
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::BeginDownload()
|
||||
{
|
||||
if (mWebPersist) {
|
||||
mWebPersist->SetProgressListener(this);
|
||||
PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION |
|
||||
nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
|
||||
if (mBypassCache)
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE;
|
||||
else
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
|
||||
|
||||
if (mURL)
|
||||
mWebPersist->SaveURI(mURL, mPostData, mDestination);
|
||||
else {
|
||||
PRInt32 encodingFlags = 0;
|
||||
nsCOMPtr<nsILocalFile> filesFolder;
|
||||
|
||||
if (!mContentType.Equals("text/plain")) {
|
||||
// Create a local directory in the same dir as our file. It
|
||||
// will hold our associated files.
|
||||
filesFolder = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
nsAutoString unicodePath;
|
||||
mDestination->GetPath(unicodePath);
|
||||
filesFolder->InitWithPath(unicodePath);
|
||||
|
||||
nsAutoString leafName;
|
||||
filesFolder->GetLeafName(leafName);
|
||||
nsAutoString nameMinusExt(leafName);
|
||||
PRInt32 index = nameMinusExt.RFind(".");
|
||||
if (index >= 0)
|
||||
nameMinusExt.Left(nameMinusExt, index);
|
||||
nameMinusExt += NS_LITERAL_STRING(" Files"); // XXXdwh needs to be localizable!
|
||||
filesFolder->SetLeafName(nameMinusExt);
|
||||
PRBool exists = PR_FALSE;
|
||||
filesFolder->Exists(&exists);
|
||||
if (!exists)
|
||||
filesFolder->Create(nsILocalFile::DIRECTORY_TYPE, 0755);
|
||||
}
|
||||
else
|
||||
encodingFlags |= nsIWebBrowserPersist::ENCODE_FLAGS_FORMATTED |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_ABSOLUTE_LINKS |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_NOFRAMES_CONTENT;
|
||||
|
||||
mWebPersist->SaveDocument(mDocument, mDestination, filesFolder, mContentType.get(),
|
||||
encodingFlags, 80);
|
||||
}
|
||||
}
|
||||
|
||||
InitDialog();
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::InitDialog()
|
||||
{
|
||||
if (!mURL && !mDocument)
|
||||
return;
|
||||
|
||||
if (mWebPersist) {
|
||||
if (mURL) {
|
||||
nsCAutoString spec;
|
||||
mURL->GetSpec(spec);
|
||||
nsAutoString spec2; spec2.AssignWithConversion(spec.get());
|
||||
[mController setSourceURL: spec2.get()];
|
||||
}
|
||||
else {
|
||||
nsAutoString spec;
|
||||
mDocument->GetURL(spec);
|
||||
[mController setSourceURL: spec.get()];
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString pathStr;
|
||||
mDestination->GetPath(pathStr);
|
||||
[mController setDestination: pathStr.get()];
|
||||
[mController setDownloadTimer];
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::CancelDownload()
|
||||
{
|
||||
if (mWebPersist)
|
||||
mWebPersist->CancelSave();
|
||||
}
|
||||
|
||||
|
||||
static NSString *SaveFileToolbarIdentifier = @"Save File Dialog Toolbar";
|
||||
static NSString *CancelToolbarItemIdentifier = @"Cancel Toolbar Item";
|
||||
static NSString *SaveFileToolbarIdentifier = @"Save File Dialog Toolbar";
|
||||
static NSString *CancelToolbarItemIdentifier = @"Cancel Toolbar Item";
|
||||
static NSString *PauseResumeToolbarItemIdentifier = @"Pause and Resume Toggle Toolbar Item";
|
||||
static NSString *ShowFileToolbarItemIdentifier = @"Show File Toolbar Item";
|
||||
static NSString *OpenFileToolbarItemIdentifier = @"Open File Toolbar Item";
|
||||
static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar Item";
|
||||
|
||||
|
||||
@implementation ChimeraDownloadControllerFactory : DownloadControllerFactory
|
||||
|
||||
- (NSWindowController<DownloadProgressDisplay> *)createDownloadController
|
||||
{
|
||||
NSWindowController* progressController = [[ProgressDlgController alloc] initWithWindowNibName: @"ProgressDialog"];
|
||||
NSAssert([progressController conformsToProtocol:@protocol(DownloadProgressDisplay)],
|
||||
@"progressController should conform to DownloadProgressDisplay protocol");
|
||||
return progressController;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
@interface ProgressDlgController(Private)
|
||||
-(void)setupToolbar;
|
||||
@end
|
||||
|
||||
@implementation ProgressDlgController
|
||||
|
||||
-(void)setWebPersist:(nsIWebBrowserPersist*)aPersist
|
||||
source:(nsISupports*)aSource
|
||||
destination:(NSString*)aDestination
|
||||
contentType:(const char*)aContentType
|
||||
postData:(nsIInputStream*)aInputStream
|
||||
bypassCache:(BOOL)aBypassCache
|
||||
- (void)dealloc
|
||||
{
|
||||
mDownloadListener = new nsDownloadListener(self, aPersist, aSource,
|
||||
aDestination, aContentType,
|
||||
aInputStream, aBypassCache);
|
||||
NS_ADDREF(mDownloadListener);
|
||||
}
|
||||
|
||||
-(void) setProgressBar:(long int)curProgress maxProg:(long int)maxProgress
|
||||
{
|
||||
aCurrentProgress = curProgress; // fall back for stat calcs
|
||||
if (![mProgressBar isIndeterminate]) { //most likely - just update value
|
||||
if (curProgress == maxProgress) //handles little bug in FTP download size
|
||||
[mProgressBar setMaxValue:maxProgress];
|
||||
[mProgressBar setDoubleValue:curProgress];
|
||||
}
|
||||
else if (maxProgress > 0) { // ok, we're starting up with good max & cur values
|
||||
[mProgressBar setIndeterminate:NO];
|
||||
[mProgressBar setMaxValue:maxProgress];
|
||||
[mProgressBar setDoubleValue:curProgress];
|
||||
} // if neither case was true, it's barber pole city.
|
||||
}
|
||||
|
||||
-(void) setSourceURL: (const PRUnichar*)aSource
|
||||
{
|
||||
[mFromField setStringValue: [NSString stringWithCharacters:aSource length:nsCRT::strlen(aSource)]];
|
||||
}
|
||||
|
||||
-(void) setDestination: (const PRUnichar*)aDestination
|
||||
{
|
||||
[mToField setStringValue: [[NSString stringWithCharacters:aDestination length:nsCRT::strlen(aDestination)] stringByAbbreviatingWithTildeInPath]];
|
||||
NS_IF_RELEASE(mDownloader);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)windowDidLoad
|
||||
{
|
||||
mDownloadIsPaused = NO;
|
||||
mDownloadIsComplete = NO;
|
||||
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID));
|
||||
PRBool save = PR_FALSE;
|
||||
prefs->GetBoolPref("browser.download.progressDnldDialog.keepAlive",&save);
|
||||
prefs->GetBoolPref("browser.download.progressDnldDialog.keepAlive", &save);
|
||||
mSaveFileDialogShouldStayOpen = save;
|
||||
|
||||
[self setupToolbar];
|
||||
[mProgressBar setUsesThreadedAnimation:YES];
|
||||
[mProgressBar startAnimation:self];
|
||||
if (mDownloadListener)
|
||||
mDownloadListener->BeginDownload();
|
||||
[mProgressBar startAnimation:self]; // move to onStateChange
|
||||
}
|
||||
|
||||
- (void)setupToolbar
|
||||
|
@ -438,7 +214,9 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
|
||||
-(void)cancel
|
||||
{
|
||||
mDownloadListener->CancelDownload();
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->CancelDownload();
|
||||
|
||||
// clean up downloaded file. - do it here on in CancelDownload?
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSString *thePath = [[mToField stringValue] stringByExpandingTildeInPath];
|
||||
|
@ -457,22 +235,29 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
|
||||
-(void)pauseAndResumeDownload
|
||||
{
|
||||
if ( ! mDownloadIsPaused ) {
|
||||
//Do logic to pause download
|
||||
if ( !mDownloadIsPaused )
|
||||
{
|
||||
mDownloadIsPaused = YES;
|
||||
[pauseResumeToggleToolbarItem setLabel:@"Resume"];
|
||||
[pauseResumeToggleToolbarItem setPaletteLabel:@"Resume Download"];
|
||||
[pauseResumeToggleToolbarItem setToolTip:@"Resume the paused FTP download"];
|
||||
[pauseResumeToggleToolbarItem setImage:[NSImage imageNamed:@"saveResume"]];
|
||||
[self killDownloadTimer];
|
||||
} else {
|
||||
//Do logic to resume download
|
||||
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->PauseDownload();
|
||||
}
|
||||
else
|
||||
{
|
||||
mDownloadIsPaused = NO;
|
||||
[pauseResumeToggleToolbarItem setLabel:@"Pause"];
|
||||
[pauseResumeToggleToolbarItem setPaletteLabel:@"Pause Download"];
|
||||
[pauseResumeToggleToolbarItem setToolTip:@"Pause this FTP file download"];
|
||||
[pauseResumeToggleToolbarItem setImage:[NSImage imageNamed:@"savePause"]];
|
||||
[self setDownloadTimer];
|
||||
[self setupDownloadTimer];
|
||||
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->ResumeDownload();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,12 +316,6 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
NS_IF_RELEASE(mDownloadListener);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)killDownloadTimer
|
||||
{
|
||||
if (mDownloadTimer) {
|
||||
|
@ -545,7 +324,7 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
mDownloadTimer = nil;
|
||||
}
|
||||
}
|
||||
- (void)setDownloadTimer
|
||||
- (void)setupDownloadTimer
|
||||
{
|
||||
[self killDownloadTimer];
|
||||
mDownloadTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0
|
||||
|
@ -590,7 +369,7 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
return [[[NSString alloc] initWithString:[[NSBundle mainBundle] localizedStringForKey:@"UnderMin" value:@"Under a minute" table:@"ProgressDialog"]] autorelease];
|
||||
}
|
||||
// seconds becomes minutes and we keep checking.
|
||||
seconds=seconds/60;
|
||||
seconds = seconds/60;
|
||||
if (seconds < 60) {
|
||||
if (seconds < 2)
|
||||
return [[[NSString alloc] initWithString:[[NSBundle mainBundle] localizedStringForKey:@"AboutMin" value:@"About a minute" table:@"ProgressDialog"]] autorelease];
|
||||
|
@ -598,7 +377,7 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
return [[[NSString alloc] initWithFormat:[[NSBundle mainBundle] localizedStringForKey:@"AboutMins" value:@"About %d minutes" table:@"ProgressDialog"],seconds] autorelease];
|
||||
}
|
||||
//this download will never seemingly never end. now seconds become hours.
|
||||
seconds=seconds/60;
|
||||
seconds = seconds/60;
|
||||
if (seconds < 2)
|
||||
return [[[NSString alloc] initWithString:[[NSBundle mainBundle] localizedStringForKey:@"AboutHour" value:@"Over an hour" table:@"ProgressDialog"]] autorelease];
|
||||
return [[[NSString alloc] initWithFormat:[[NSBundle mainBundle] localizedStringForKey:@"AboutHours" value:@"Over %d hours" table:@"ProgressDialog"],seconds] autorelease];
|
||||
|
@ -629,8 +408,11 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
// this handles lots of things.
|
||||
- (void)setDownloadProgress:(NSTimer *)downloadTimer;
|
||||
{
|
||||
// XXX this logic needs cleaning up.
|
||||
|
||||
// Ack! we're closing the window with the download still running!
|
||||
if (mDownloadIsComplete) {
|
||||
if (mDownloadIsComplete)
|
||||
{
|
||||
[[self window] performClose:self];
|
||||
return;
|
||||
}
|
||||
|
@ -644,26 +426,28 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
[mElapsedTimeLabel setStringValue:[self formatTime:(++elapsedSec)]];
|
||||
// for status field & time left
|
||||
float maxBytes = ([mProgressBar maxValue]);
|
||||
float byteSec = aCurrentProgress/elapsedSec;
|
||||
float byteSec = mCurrentProgress/elapsedSec;
|
||||
// OK - if downloadTimer is nil, we're done - fix maxBytes value for status report.
|
||||
if (!downloadTimer)
|
||||
maxBytes = aCurrentProgress;
|
||||
maxBytes = mCurrentProgress;
|
||||
// update status field
|
||||
NSString *labelString = [[NSBundle mainBundle] localizedStringForKey:@"LabelString"
|
||||
value:@"%@ of %@ total (at %@/sec)"
|
||||
table:@"ProgressDialog"];
|
||||
[mStatusLabel setStringValue: [NSString stringWithFormat:labelString, [self formatBytes:aCurrentProgress], [self formatBytes:maxBytes], [self formatBytes:byteSec]]];
|
||||
[mStatusLabel setStringValue: [NSString stringWithFormat:labelString, [self formatBytes:mCurrentProgress], [self formatBytes:maxBytes], [self formatBytes:byteSec]]];
|
||||
// updating estimated time left field
|
||||
// if maxBytes < 0, can't calc time left.
|
||||
// if !downloadTimer, download is finished. either way, make sure time left is 0.
|
||||
if ((maxBytes > 0) && (downloadTimer)) {
|
||||
int secToGo = (int)ceil((elapsedSec*maxBytes/aCurrentProgress)-elapsedSec);
|
||||
if ((maxBytes > 0) && (downloadTimer))
|
||||
{
|
||||
int secToGo = (int)ceil((elapsedSec*maxBytes/mCurrentProgress) - elapsedSec);
|
||||
[mTimeLeftLabel setStringValue:[self formatFuzzyTime:secToGo]];
|
||||
}
|
||||
else if (!downloadTimer) { // download done. Set remaining time to 0, fix progress bar & cancel button
|
||||
else if (!downloadTimer)
|
||||
{ // download done. Set remaining time to 0, fix progress bar & cancel button
|
||||
mDownloadIsComplete = YES; // all done. we got a STATE_STOP
|
||||
[mTimeLeftLabel setStringValue:@""];
|
||||
[self setProgressBar:aCurrentProgress maxProg:aCurrentProgress];
|
||||
[self setProgressTo:mCurrentProgress ofMax:mCurrentProgress];
|
||||
if (!mSaveFileDialogShouldStayOpen)
|
||||
[[self window] performClose:self]; // close window
|
||||
else
|
||||
|
@ -673,4 +457,59 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
[mTimeLeftLabel setStringValue:@"???"];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// DownloadProgressDisplay protocol methods
|
||||
|
||||
- (void)onStartDownload
|
||||
{
|
||||
[self showWindow: self];
|
||||
[self setupDownloadTimer];
|
||||
}
|
||||
|
||||
- (void)onEndDownload
|
||||
{
|
||||
[self killDownloadTimer];
|
||||
[self setDownloadProgress:nil];
|
||||
}
|
||||
|
||||
- (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress
|
||||
{
|
||||
mCurrentProgress = aCurProgress; // fall back for stat calcs
|
||||
|
||||
if (![mProgressBar isIndeterminate]) //most likely - just update value
|
||||
{
|
||||
if (aCurProgress == aMaxProgress) //handles little bug in FTP download size
|
||||
[mProgressBar setMaxValue:aMaxProgress];
|
||||
|
||||
[mProgressBar setDoubleValue:aCurProgress];
|
||||
}
|
||||
else if (aMaxProgress > 0) // ok, we're starting up with good max & cur values
|
||||
{
|
||||
[mProgressBar setIndeterminate:NO];
|
||||
[mProgressBar setMaxValue:aMaxProgress];
|
||||
[mProgressBar setDoubleValue:aCurProgress];
|
||||
} // if neither case was true, it's barber pole city.
|
||||
}
|
||||
|
||||
-(void) setDownloadListener: (nsDownloader*)aDownloader
|
||||
{
|
||||
if (mDownloader != aDownloader)
|
||||
NS_IF_RELEASE(mDownloader);
|
||||
|
||||
NS_IF_ADDREF(mDownloader = aDownloader);
|
||||
}
|
||||
|
||||
- (void)setSourceURL:(NSString*)aSourceURL
|
||||
{
|
||||
[mFromField setStringValue: aSourceURL];
|
||||
[mFromField display]; // force an immmeditate update
|
||||
}
|
||||
|
||||
- (void)setDestinationPath:(NSString*)aDestPath
|
||||
{
|
||||
[mToField setStringValue: [aDestPath stringByAbbreviatingWithTildeInPath]];
|
||||
[mToField display]; // force an immmeditate update
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* David Hyatt <hyatt@netscape.com>
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Appkit/Appkit.h>
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
|
||||
|
||||
// Implementation of a header sniffer class that is used when saving Web pages and images.
|
||||
class nsHeaderSniffer : public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
|
||||
nsIDOMDocument* aDocument, nsIInputStream* aPostData,
|
||||
const nsCString& aSuggestedFilename, PRBool aBypassCache,
|
||||
NSView* aFilterView, NSPopUpButton* aFilterList);
|
||||
virtual ~nsHeaderSniffer();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
protected:
|
||||
|
||||
nsresult PerformSave(nsIURI* inOriginalURI);
|
||||
nsresult InitiateDownload(nsISupports* inSourceData, nsString& inFileName, nsIURI* inOriginalURI);
|
||||
|
||||
private:
|
||||
|
||||
nsIWebBrowserPersist* mPersist; // Weak. It owns us as a listener.
|
||||
nsCOMPtr<nsIFile> mTmpFile;
|
||||
nsCOMPtr<nsIURI> mURL;
|
||||
nsCOMPtr<nsIDOMDocument> mDocument;
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
nsCString mDefaultFilename;
|
||||
PRBool mBypassCache;
|
||||
nsCString mContentType;
|
||||
nsCString mContentDisposition;
|
||||
NSView* mFilterView;
|
||||
NSPopUpButton* mFilterList;
|
||||
};
|
||||
|
|
@ -0,0 +1,386 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* David Hyatt <hyatt@netscape.com>
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "SaveHeaderSniffer.h"
|
||||
|
||||
#include "netCore.h"
|
||||
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsIMIMEInfo.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDownload.h"
|
||||
|
||||
const char* const persistContractID = "@mozilla.org/embedding/browser/nsWebBrowserPersist;1";
|
||||
|
||||
nsHeaderSniffer::nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
|
||||
nsIDOMDocument* aDocument, nsIInputStream* aPostData,
|
||||
const nsCString& aSuggestedFilename, PRBool aBypassCache,
|
||||
NSView* aFilterView, NSPopUpButton* aFilterList)
|
||||
: mPersist(aPersist)
|
||||
, mTmpFile(aFile)
|
||||
, mURL(aURL)
|
||||
, mDocument(aDocument)
|
||||
, mPostData(aPostData)
|
||||
, mDefaultFilename(aSuggestedFilename)
|
||||
, mBypassCache(aBypassCache)
|
||||
, mFilterView(aFilterView)
|
||||
, mFilterList(aFilterList)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsHeaderSniffer::~nsHeaderSniffer()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsHeaderSniffer, nsIWebProgressListener)
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
if (aStateFlags & nsIWebProgressListener::STATE_START)
|
||||
{
|
||||
nsCOMPtr<nsIWebBrowserPersist> kungFuDeathGrip(mPersist); // be sure to keep it alive while we save
|
||||
// since it owns us as a listener
|
||||
nsCOMPtr<nsIWebProgressListener> kungFuSuicideGrip(this); // and keep ourslves alive
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest, &rv);
|
||||
if (!channel) return rv;
|
||||
channel->GetContentType(mContentType);
|
||||
|
||||
nsCOMPtr<nsIURI> origURI;
|
||||
channel->GetOriginalURI(getter_AddRefs(origURI));
|
||||
|
||||
// Get the content-disposition if we're an HTTP channel.
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if (httpChannel)
|
||||
httpChannel->GetResponseHeader(nsCAutoString("content-disposition"), mContentDisposition);
|
||||
|
||||
mPersist->CancelSave();
|
||||
PRBool exists;
|
||||
mTmpFile->Exists(&exists);
|
||||
if (exists)
|
||||
mTmpFile->Remove(PR_FALSE);
|
||||
|
||||
rv = PerformSave(origURI);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
// put up some UI
|
||||
NSLog(@"Error saving web page");
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
nsresult nsHeaderSniffer::PerformSave(nsIURI* inOriginalURI)
|
||||
{
|
||||
nsresult rv;
|
||||
// Are we an HTML document? If so, we will want to append an accessory view to
|
||||
// the save dialog to provide the user with the option of doing a complete
|
||||
// save vs. a single file save.
|
||||
PRBool isHTML = (mDocument && mContentType.Equals("text/html") ||
|
||||
mContentType.Equals("text/xml") ||
|
||||
mContentType.Equals("application/xhtml+xml"));
|
||||
|
||||
// Next find out the directory that we should start in.
|
||||
nsCOMPtr<nsIPrefService> prefs(do_GetService("@mozilla.org/preferences-service;1", &rv));
|
||||
if (!prefs)
|
||||
return rv;
|
||||
nsCOMPtr<nsIPrefBranch> dirBranch;
|
||||
prefs->GetBranch("browser.download.", getter_AddRefs(dirBranch));
|
||||
PRInt32 filterIndex = 0;
|
||||
if (dirBranch) {
|
||||
nsresult rv = dirBranch->GetIntPref("save_converter_index", &filterIndex);
|
||||
if (NS_FAILED(rv))
|
||||
filterIndex = 0;
|
||||
}
|
||||
if (mFilterList)
|
||||
[mFilterList selectItemAtIndex: filterIndex];
|
||||
|
||||
// We need to figure out what file name to use.
|
||||
nsCAutoString defaultFileName;
|
||||
if (!mContentDisposition.IsEmpty()) {
|
||||
// (1) Use the HTTP header suggestion.
|
||||
PRInt32 index = mContentDisposition.Find("filename=");
|
||||
if (index >= 0) {
|
||||
// Take the substring following the prefix.
|
||||
index += 9;
|
||||
nsCAutoString filename;
|
||||
mContentDisposition.Right(filename, mContentDisposition.Length() - index);
|
||||
defaultFileName = filename;
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(mURL));
|
||||
if (url)
|
||||
url->GetFileName(defaultFileName); // (2) For file URLs, use the file name.
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mDocument && isHTML) {
|
||||
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
|
||||
nsAutoString title;
|
||||
if (htmlDoc)
|
||||
htmlDoc->GetTitle(title); // (3) Use the title of the document.
|
||||
defaultFileName.AssignWithConversion(title);
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
// (4) Use the caller provided name.
|
||||
defaultFileName = mDefaultFilename;
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mURL)
|
||||
// (5) Use the host.
|
||||
mURL->GetHost(defaultFileName);
|
||||
|
||||
// One last case to handle about:blank and other fruity untitled pages.
|
||||
if (defaultFileName.IsEmpty())
|
||||
defaultFileName = "untitled";
|
||||
|
||||
// Validate the file name to ensure legality.
|
||||
for (PRUint32 i = 0; i < defaultFileName.Length(); i++)
|
||||
if (defaultFileName[i] == ':' || defaultFileName[i] == '/')
|
||||
defaultFileName.SetCharAt(i, ' ');
|
||||
|
||||
// Make sure the appropriate extension is appended to the suggested file name.
|
||||
nsCOMPtr<nsIURI> fileURI(do_CreateInstance("@mozilla.org/network/standard-url;1"));
|
||||
nsCOMPtr<nsIURL> fileURL(do_QueryInterface(fileURI, &rv));
|
||||
if (!fileURL)
|
||||
return rv;
|
||||
fileURL->SetFilePath(defaultFileName);
|
||||
|
||||
nsCAutoString fileExtension;
|
||||
fileURL->GetFileExtension(fileExtension);
|
||||
|
||||
PRBool setExtension = PR_FALSE;
|
||||
if (mContentType.Equals("text/html")) {
|
||||
if (fileExtension.IsEmpty() || (!fileExtension.Equals("htm") && !fileExtension.Equals("html"))) {
|
||||
defaultFileName += ".html";
|
||||
setExtension = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!setExtension && fileExtension.IsEmpty()) {
|
||||
nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1", &rv));
|
||||
if (!mimeService)
|
||||
return rv;
|
||||
nsCOMPtr<nsIMIMEInfo> mimeInfo;
|
||||
rv = mimeService->GetFromMIMEType(mContentType.get(), getter_AddRefs(mimeInfo));
|
||||
if (!mimeInfo)
|
||||
return rv;
|
||||
|
||||
PRUint32 extCount = 0;
|
||||
char** extList = nsnull;
|
||||
mimeInfo->GetFileExtensions(&extCount, &extList);
|
||||
if (extCount > 0 && extList) {
|
||||
defaultFileName += ".";
|
||||
defaultFileName += extList[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Now it's time to pose the save dialog.
|
||||
NSSavePanel* savePanel = [NSSavePanel savePanel];
|
||||
NSString* file = nil;
|
||||
if (!defaultFileName.IsEmpty())
|
||||
file = [[NSString alloc] initWithCString: defaultFileName.get()];
|
||||
|
||||
if (isHTML)
|
||||
[savePanel setAccessoryView: mFilterView];
|
||||
|
||||
if ([savePanel runModalForDirectory: nil file: file] == NSFileHandlingPanelCancelButton)
|
||||
return NS_OK;
|
||||
|
||||
// Release the file string.
|
||||
[file release];
|
||||
|
||||
// Update the filter index.
|
||||
if (isHTML && mFilterList) {
|
||||
filterIndex = [mFilterList indexOfSelectedItem];
|
||||
dirBranch->SetIntPref("save_converter_index", filterIndex);
|
||||
}
|
||||
|
||||
// Convert the content type to text/plain if it was selected in the filter.
|
||||
if (isHTML && filterIndex == 2)
|
||||
mContentType = "text/plain";
|
||||
|
||||
nsCOMPtr<nsISupports> sourceData;
|
||||
if (isHTML && filterIndex != 1)
|
||||
sourceData = do_QueryInterface(mDocument);
|
||||
else
|
||||
sourceData = do_QueryInterface(mURL);
|
||||
|
||||
NSString* destName = [savePanel filename];
|
||||
|
||||
PRUint32 dstLen = [destName length];
|
||||
PRUnichar* tmp = new PRUnichar[dstLen + sizeof(PRUnichar)];
|
||||
tmp[dstLen] = (PRUnichar)'\0';
|
||||
[destName getCharacters:tmp];
|
||||
nsAutoString dstString(tmp);
|
||||
delete tmp;
|
||||
|
||||
return InitiateDownload(sourceData, dstString, inOriginalURI);
|
||||
}
|
||||
|
||||
// inOriginalURI is always a URI. inSourceData can be an nsIURI or an nsIDOMDocument, depending
|
||||
// on what we're saving. It's that way for nsIWebBrowserPersist.
|
||||
nsresult nsHeaderSniffer::InitiateDownload(nsISupports* inSourceData, nsString& inFileName, nsIURI* inOriginalURI)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPersist> webPersist = do_CreateInstance(persistContractID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIURI> sourceURI = do_QueryInterface(inSourceData);
|
||||
|
||||
nsCOMPtr<nsILocalFile> destFile;
|
||||
rv = NS_NewLocalFile(inFileName, PR_FALSE, getter_AddRefs(destFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRInt64 timeNow = PR_Now();
|
||||
|
||||
nsCOMPtr<nsIDownload> downloader = do_CreateInstance(NS_DOWNLOAD_CONTRACTID);
|
||||
// dlListener attaches to its progress dialog here, which gains ownership
|
||||
rv = downloader->Init(inOriginalURI, destFile, inFileName.get(), nsString().get(), timeNow, webPersist);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION |
|
||||
nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
|
||||
if (mBypassCache)
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE;
|
||||
else
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
|
||||
|
||||
if (sourceURI)
|
||||
{
|
||||
rv = webPersist->SaveURI(sourceURI, mPostData, destFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsIDOMHTMLDocument> domDoc = do_QueryInterface(inSourceData, &rv);
|
||||
if (!domDoc) return rv; // should never happen
|
||||
|
||||
PRInt32 encodingFlags = 0;
|
||||
nsCOMPtr<nsILocalFile> filesFolder;
|
||||
|
||||
if (!mContentType.Equals("text/plain")) {
|
||||
// Create a local directory in the same dir as our file. It
|
||||
// will hold our associated files.
|
||||
filesFolder = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
nsAutoString unicodePath;
|
||||
destFile->GetPath(unicodePath);
|
||||
filesFolder->InitWithPath(unicodePath);
|
||||
|
||||
nsAutoString leafName;
|
||||
filesFolder->GetLeafName(leafName);
|
||||
nsAutoString nameMinusExt(leafName);
|
||||
PRInt32 index = nameMinusExt.RFind(".");
|
||||
if (index >= 0)
|
||||
nameMinusExt.Left(nameMinusExt, index);
|
||||
nameMinusExt += NS_LITERAL_STRING(" Files"); // XXXdwh needs to be localizable!
|
||||
filesFolder->SetLeafName(nameMinusExt);
|
||||
PRBool exists = PR_FALSE;
|
||||
filesFolder->Exists(&exists);
|
||||
if (!exists) {
|
||||
rv = filesFolder->Create(nsILocalFile::DIRECTORY_TYPE, 0755);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
encodingFlags |= nsIWebBrowserPersist::ENCODE_FLAGS_FORMATTED |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_ABSOLUTE_LINKS |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_NOFRAMES_CONTENT;
|
||||
}
|
||||
rv = webPersist->SaveDocument(domDoc, destFile, filesFolder, mContentType.get(), encodingFlags, 80);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Appkit/Appkit.h>
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsIDownload.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsILocalFile.h"
|
||||
|
||||
|
||||
// maybe this should replace nsHeaderSniffer too?
|
||||
|
||||
class nsDownloadListener : public nsDownloader,
|
||||
public nsIDownload,
|
||||
public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsDownloadListener(DownloadControllerFactory* inDownloadControllerFactory);
|
||||
virtual ~nsDownloadListener();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOWNLOAD
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
public:
|
||||
//void BeginDownload();
|
||||
void InitDialog();
|
||||
|
||||
virtual void PauseDownload();
|
||||
virtual void ResumeDownload();
|
||||
virtual void CancelDownload();
|
||||
virtual void DownloadDone();
|
||||
|
||||
private:
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPersist> mWebPersist; // Our web persist object.
|
||||
nsCOMPtr<nsIURI> mURI; // The URI of our source file. Null if we're saving a complete document.
|
||||
nsCOMPtr<nsILocalFile> mDestination; // Our destination URL.
|
||||
PRInt64 mStartTime; // When the download started
|
||||
PRPackedBool mBypassCache; // Whether we should bypass the cache or not.
|
||||
PRPackedBool mNetworkTransfer; // true if the first OnStateChange has the NETWORK bit set
|
||||
PRPackedBool mGotFirstStateChange; // true after we've seen the first OnStateChange
|
||||
PRPackedBool mUserCanceled; // true if the user canceled the download
|
||||
};
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsDownloadListener.h"
|
||||
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIURL.h"
|
||||
#include "netCore.h"
|
||||
|
||||
nsDownloadListener::nsDownloadListener(DownloadControllerFactory* inControllerFactory)
|
||||
: nsDownloader(inControllerFactory)
|
||||
, mBypassCache(PR_FALSE)
|
||||
, mNetworkTransfer(PR_FALSE)
|
||||
, mGotFirstStateChange(PR_FALSE)
|
||||
, mUserCanceled(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
nsDownloadListener::~nsDownloadListener()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(nsDownloadListener, nsDownloader, nsIDownload, nsIWebProgressListener)
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in wstring openingWith, in long long startTime, in nsIWebBrowserPersist aPersist); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName,
|
||||
const PRUnichar *openingWith, PRInt64 startTime, nsIWebBrowserPersist *aPersist)
|
||||
{
|
||||
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()
|
||||
}
|
||||
|
||||
mDestination = aTarget;
|
||||
mURI = aSource;
|
||||
mStartTime = startTime;
|
||||
|
||||
InitDialog();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIURI source; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetSource(nsIURI * *aSource)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSource);
|
||||
NS_IF_ADDREF(*aSource = mURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsILocalFile target; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetTarget(nsILocalFile * *aTarget)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTarget);
|
||||
NS_IF_ADDREF(*aTarget = mDestination);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIWebBrowserPersist persist; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetPersist(nsIWebBrowserPersist * *aPersist)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPersist);
|
||||
NS_IF_ADDREF(*aPersist = mWebPersist);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute PRInt32 percentComplete; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetPercentComplete(PRInt32 *aPercentComplete)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute wstring displayName; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetDisplayName(PRUnichar * *aDisplayName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::SetDisplayName(const PRUnichar * aDisplayName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* readonly attribute long long startTime; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetStartTime(PRInt64 *aStartTime)
|
||||
{
|
||||
NS_ENSURE_ARG(aStartTime);
|
||||
*aStartTime = mStartTime;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute wstring openingWith; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetOpeningWith(PRUnichar * *aOpeningWith)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute nsIWebProgressListener listener; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetListener(nsIWebProgressListener * *aListener)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aListener);
|
||||
NS_IF_ADDREF(*aListener = (nsIWebProgressListener *)this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
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); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
if (mUserCanceled)
|
||||
{
|
||||
if (aRequest)
|
||||
aRequest->Cancel(NS_BINDING_ABORTED);
|
||||
|
||||
mUserCanceled = false;
|
||||
}
|
||||
|
||||
[mDownloadDisplay setProgressTo:aCurTotalProgress ofMax:aMaxTotalProgress];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
// NSLog(@"State changed: state %u, status %u", aStateFlags, aStatus);
|
||||
if (!mGotFirstStateChange) {
|
||||
mNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0);
|
||||
mGotFirstStateChange = PR_TRUE;
|
||||
}
|
||||
|
||||
// when the entire download finishes, stop the progress timer and clean up
|
||||
// the window and controller. We will get this even in the event of a cancel,
|
||||
// so this is the only place in the listener where we should kill the download.
|
||||
if ((aStateFlags & STATE_STOP) && (!mNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) {
|
||||
DownloadDone();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
void
|
||||
nsDownloadListener::InitDialog()
|
||||
{
|
||||
// dialog has to be shown before the outlets get hooked up
|
||||
[mDownloadDisplay onStartDownload];
|
||||
|
||||
if (mURI)
|
||||
{
|
||||
nsCAutoString spec;
|
||||
mURI->GetSpec(spec);
|
||||
[mDownloadDisplay setSourceURL: [NSString stringWithUTF8String:spec.get()]];
|
||||
}
|
||||
|
||||
nsAutoString pathStr;
|
||||
mDestination->GetPath(pathStr);
|
||||
[mDownloadDisplay setDestinationPath: [NSString stringWithCharacters:pathStr.get() length:pathStr.Length()]];
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::PauseDownload()
|
||||
{
|
||||
// write me
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::ResumeDownload()
|
||||
{
|
||||
// write me
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::CancelDownload()
|
||||
{
|
||||
mUserCanceled = PR_TRUE;
|
||||
|
||||
if (mWebPersist)
|
||||
{
|
||||
mWebPersist->CancelSave();
|
||||
mUserCanceled = PR_FALSE;
|
||||
}
|
||||
|
||||
// delete any files we've created...
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::DownloadDone()
|
||||
{
|
||||
// break the reference cycle by removing ourselves as a listener
|
||||
if (mWebPersist)
|
||||
{
|
||||
mWebPersist->SetProgressListener(nsnull);
|
||||
mWebPersist = nsnull;
|
||||
}
|
||||
|
||||
[mDownloadDisplay onEndDownload];
|
||||
}
|
||||
|
||||
#pragma mark -
|
|
@ -55,7 +55,7 @@ class nsCocoaBrowserService : public nsIWindowCreator,
|
|||
public nsIPromptService,
|
||||
public nsIFactory,
|
||||
public nsIBadCertListener, public nsISecurityWarningDialogs, public nsINSSDialogs,
|
||||
public nsIHelperAppLauncherDialog, public nsIDownload, public nsIWebProgressListener
|
||||
public nsIHelperAppLauncherDialog
|
||||
{
|
||||
public:
|
||||
nsCocoaBrowserService();
|
||||
|
@ -69,8 +69,6 @@ public:
|
|||
NS_DECL_NSIBADCERTLISTENER
|
||||
NS_DECL_NSISECURITYWARNINGDIALOGS
|
||||
NS_DECL_NSIHELPERAPPLAUNCHERDIALOG
|
||||
NS_DECL_NSIDOWNLOAD
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
static nsresult InitEmbedding();
|
||||
static void TermEmbedding();
|
||||
|
|
|
@ -35,14 +35,15 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsCocoaBrowserService.h"
|
||||
#import "nsCocoaBrowserService.h"
|
||||
#import "DownloadFactories.h"
|
||||
#import "CHBrowserView.h"
|
||||
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIEmbeddingSiteWindow.h"
|
||||
#include "nsIProfile.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "CHBrowserView.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIPrompt.h"
|
||||
|
@ -74,13 +75,14 @@ nsCocoaBrowserService::~nsCocoaBrowserService()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS9(nsCocoaBrowserService,
|
||||
NS_IMPL_ISUPPORTS7(nsCocoaBrowserService,
|
||||
nsIWindowCreator,
|
||||
nsIPromptService,
|
||||
nsIFactory,
|
||||
nsIBadCertListener, nsISecurityWarningDialogs, nsINSSDialogs,
|
||||
nsIHelperAppLauncherDialog, nsIDownload, nsIWebProgressListener)
|
||||
nsIHelperAppLauncherDialog)
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsCocoaBrowserService::InitEmbedding()
|
||||
{
|
||||
|
@ -103,7 +105,7 @@ nsCocoaBrowserService::InitEmbedding()
|
|||
#define NS_PROMPTSERVICE_CID \
|
||||
{0xa2112d6a, 0x0e28, 0x421f, {0xb4, 0x6a, 0x25, 0xc0, 0xb3, 0x8, 0xcb, 0xd0}}
|
||||
static NS_DEFINE_CID(kPromptServiceCID, NS_PROMPTSERVICE_CID);
|
||||
nsresult rv = cr->RegisterFactory(kPromptServiceCID, "Prompt Service", "@mozilla.org/embedcomp/prompt-service;1",
|
||||
nsresult rv = cr->RegisterFactory(kPromptServiceCID, "Prompt Service", "@mozilla.org/embedcomp/prompt-service;1",
|
||||
sSingleton);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
@ -127,14 +129,18 @@ nsCocoaBrowserService::InitEmbedding()
|
|||
rv = cr->RegisterFactory(kHelperDlgCID, NS_IHELPERAPPLAUNCHERDLG_CLASSNAME, NS_IHELPERAPPLAUNCHERDLG_CONTRACTID,
|
||||
sSingleton);
|
||||
|
||||
// replace the downloader with our own which does rely on the xpfe downlaod manager
|
||||
// replace the downloader with our own which does not rely on the xpfe downlaod manager
|
||||
nsCOMPtr<nsIFactory> downloadFactory;
|
||||
rv = NewDownloadListenerFactory(getter_AddRefs(downloadFactory));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
static NS_DEFINE_CID(kDownloadCID, NS_DOWNLOAD_CID);
|
||||
rv = cr->RegisterFactory(kDownloadCID, "Download", NS_DOWNLOAD_CONTRACTID,
|
||||
sSingleton);
|
||||
rv = cr->RegisterFactory(kDownloadCID, "Download", NS_DOWNLOAD_CONTRACTID, downloadFactory);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsCocoaBrowserService::BrowserClosed()
|
||||
{
|
||||
|
@ -149,6 +155,7 @@ nsCocoaBrowserService::BrowserClosed()
|
|||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsCocoaBrowserService::TermEmbedding()
|
||||
{
|
||||
|
@ -195,8 +202,15 @@ nsCocoaBrowserService::CreateInstance(nsISupports *aOuter,
|
|||
const nsIID & aIID,
|
||||
void **aResult)
|
||||
{
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
/*
|
||||
if (aIID.Equals(NS_GET_IID(nsIHelperAppLauncherDialog)))
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
return sSingleton->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
|
@ -828,14 +842,12 @@ nsCocoaBrowserService::ConfirmPostToInsecureFromSecure(nsIInterfaceRequestor *ct
|
|||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::Show(nsIHelperAppLauncher* inLauncher, nsISupports* inContext)
|
||||
{
|
||||
NSLog(@"Show");
|
||||
return inLauncher->SaveToDisk(nsnull, PR_FALSE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::PromptForSaveToFile(nsISupports *aWindowContext, const PRUnichar *aDefaultFile, const PRUnichar *aSuggestedFileExtension, nsILocalFile **_retval)
|
||||
{
|
||||
NSLog(@"PromptForSaveToFile");
|
||||
NSString* filename = [NSString stringWithCharacters:aDefaultFile length:nsCRT::strlen(aDefaultFile)];
|
||||
NSSavePanel *thePanel = [NSSavePanel savePanel];
|
||||
|
||||
|
@ -844,7 +856,7 @@ NSLog(@"PromptForSaveToFile");
|
|||
// use nil for the path given to runModalForDirectory
|
||||
int runResult = [thePanel runModalForDirectory: nil file:filename];
|
||||
if (runResult == NSOKButton) {
|
||||
NSLog([thePanel filename]);
|
||||
// NSLog(@"Saving to %@", [thePanel filename]);
|
||||
NSString *theName = [thePanel filename];
|
||||
return NS_NewNativeLocalFile(nsDependentCString([theName fileSystemRepresentation]), PR_FALSE, _retval);
|
||||
}
|
||||
|
@ -856,140 +868,6 @@ NSLog([thePanel filename]);
|
|||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::ShowProgressDialog(nsIHelperAppLauncher *aLauncher, nsISupports *aContext)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::Init(nsIURI* aSource,
|
||||
nsILocalFile* aTarget,
|
||||
const PRUnichar* aDisplayName,
|
||||
const PRUnichar* aOpeningWith,
|
||||
PRInt64 aStartTime,
|
||||
nsIWebBrowserPersist* aPersist)
|
||||
{
|
||||
NSLog(@"nsIDownload::Init");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetDisplayName(PRUnichar** aDisplayName)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::SetDisplayName(const PRUnichar* aDisplayName)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetOpeningWith(PRUnichar** aOpeningWith)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetSource(nsIURI** aSource)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetTarget(nsILocalFile** aTarget)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetStartTime(PRInt64* aStartTime)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetPercentComplete(PRInt32* aPercentComplete)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetListener(nsIWebProgressListener** aListener)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::SetListener(nsIWebProgressListener* aListener)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetObserver(nsIObserver** aObserver)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::SetObserver(nsIObserver* aObserver)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetPersist(nsIWebBrowserPersist** aPersist)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnStateChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, nsIURI *aLocation)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnSecurityChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, PRUint32 aState)
|
||||
{
|
||||
NSLog(@"nsCocoaBrowserService::ShowProgressDialog");
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "CHBrowserView.h"
|
||||
#import "ProgressDlgController.h"
|
||||
#import "FindDlgController.h"
|
||||
#import "nsCocoaBrowserService.h"
|
||||
#import "mozView.h"
|
||||
|
@ -65,18 +64,12 @@
|
|||
|
||||
// Saving of links/images/docs
|
||||
#include "nsIWebBrowserFocus.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDOMNSDocument.h"
|
||||
#include "nsIDOMLocation.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsIProperties.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsIMIMEInfo.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsISHistory.h"
|
||||
#include "nsIHistoryEntry.h"
|
||||
#include "nsISHEntry.h"
|
||||
|
@ -84,6 +77,7 @@
|
|||
#include "nsIContextMenuListener.h"
|
||||
#include "nsITooltipListener.h"
|
||||
#include "nsIEmbeddingSiteWindow2.h"
|
||||
#include "SaveHeaderSniffer.h"
|
||||
|
||||
typedef unsigned int DragReference;
|
||||
#include "nsIDragHelperService.h"
|
||||
|
@ -677,265 +671,7 @@ nsCocoaBrowserListener::SetContainer(id <NSBrowserContainer> aContainer)
|
|||
[mContainer retain];
|
||||
}
|
||||
|
||||
// Implementation of a header sniffer class that is used when saving Web pages and images.
|
||||
class nsHeaderSniffer : public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
|
||||
nsIDOMDocument* aDocument, nsIInputStream* aPostData,
|
||||
const nsCString& aSuggestedFilename, PRBool aBypassCache,
|
||||
NSView* aFilterView, NSPopUpButton* aFilterList)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mPersist = aPersist;
|
||||
mTmpFile = aFile;
|
||||
mURL = aURL;
|
||||
mDocument = aDocument;
|
||||
mPostData = aPostData;
|
||||
mDefaultFilename = aSuggestedFilename;
|
||||
mBypassCache = aBypassCache;
|
||||
mFilterView = aFilterView;
|
||||
mFilterList = aFilterList;
|
||||
}
|
||||
|
||||
virtual ~nsHeaderSniffer()
|
||||
{
|
||||
};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
protected:
|
||||
void PerformSave();
|
||||
|
||||
private:
|
||||
nsIWebBrowserPersist* mPersist; // Weak. It owns us as a listener.
|
||||
nsCOMPtr<nsIFile> mTmpFile;
|
||||
nsCOMPtr<nsIURI> mURL;
|
||||
nsCOMPtr<nsIDOMDocument> mDocument;
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
nsCString mDefaultFilename;
|
||||
PRBool mBypassCache;
|
||||
nsCString mContentType;
|
||||
nsCString mContentDisposition;
|
||||
NSView* mFilterView;
|
||||
NSPopUpButton* mFilterList;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsHeaderSniffer, nsIWebProgressListener)
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
if (aStateFlags & nsIWebProgressListener::STATE_START) {
|
||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
|
||||
channel->GetContentType(mContentType);
|
||||
|
||||
// Get the content-disposition if we're an HTTP channel.
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if (httpChannel)
|
||||
httpChannel->GetResponseHeader(nsCAutoString("content-disposition"), mContentDisposition);
|
||||
|
||||
mPersist->CancelSave();
|
||||
PRBool exists;
|
||||
mTmpFile->Exists(&exists);
|
||||
if (exists)
|
||||
mTmpFile->Remove(PR_FALSE);
|
||||
PerformSave();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsHeaderSniffer::PerformSave()
|
||||
{
|
||||
// Are we an HTML document? If so, we will want to append an accessory view to
|
||||
// the save dialog to provide the user with the option of doing a complete
|
||||
// save vs. a single file save.
|
||||
PRBool isHTML = (mDocument && mContentType.Equals("text/html") ||
|
||||
mContentType.Equals("text/xml") ||
|
||||
mContentType.Equals("application/xhtml+xml"));
|
||||
|
||||
// Next find out the directory that we should start in.
|
||||
nsCOMPtr<nsIPrefService> prefs(do_GetService("@mozilla.org/preferences-service;1"));
|
||||
if (!prefs)
|
||||
return;
|
||||
nsCOMPtr<nsIPrefBranch> dirBranch;
|
||||
prefs->GetBranch("browser.download.", getter_AddRefs(dirBranch));
|
||||
PRInt32 filterIndex = 0;
|
||||
if (dirBranch) {
|
||||
nsresult rv = dirBranch->GetIntPref("save_converter_index", &filterIndex);
|
||||
if (NS_FAILED(rv))
|
||||
filterIndex = 0;
|
||||
}
|
||||
if (mFilterList)
|
||||
[mFilterList selectItemAtIndex: filterIndex];
|
||||
|
||||
// We need to figure out what file name to use.
|
||||
nsCAutoString defaultFileName;
|
||||
if (!mContentDisposition.IsEmpty()) {
|
||||
// (1) Use the HTTP header suggestion.
|
||||
PRInt32 index = mContentDisposition.Find("filename=");
|
||||
if (index >= 0) {
|
||||
// Take the substring following the prefix.
|
||||
index += 9;
|
||||
nsCAutoString filename;
|
||||
mContentDisposition.Right(filename, mContentDisposition.Length() - index);
|
||||
defaultFileName = filename;
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(mURL));
|
||||
if (url)
|
||||
url->GetFileName(defaultFileName); // (2) For file URLs, use the file name.
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mDocument && isHTML) {
|
||||
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
|
||||
nsAutoString title;
|
||||
if (htmlDoc)
|
||||
htmlDoc->GetTitle(title); // (3) Use the title of the document.
|
||||
defaultFileName.AssignWithConversion(title);
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
// (4) Use the caller provided name.
|
||||
defaultFileName = mDefaultFilename;
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mURL)
|
||||
// (5) Use the host.
|
||||
mURL->GetHost(defaultFileName);
|
||||
|
||||
// One last case to handle about:blank and other fruity untitled pages.
|
||||
if (defaultFileName.IsEmpty())
|
||||
defaultFileName = "untitled";
|
||||
|
||||
// Validate the file name to ensure legality.
|
||||
for (PRUint32 i = 0; i < defaultFileName.Length(); i++)
|
||||
if (defaultFileName[i] == ':' || defaultFileName[i] == '/')
|
||||
defaultFileName.SetCharAt(i, ' ');
|
||||
|
||||
// Make sure the appropriate extension is appended to the suggested file name.
|
||||
nsCOMPtr<nsIURI> fileURI(do_CreateInstance("@mozilla.org/network/standard-url;1"));
|
||||
nsCOMPtr<nsIURL> fileURL(do_QueryInterface(fileURI));
|
||||
if (!fileURL)
|
||||
return;
|
||||
fileURL->SetFilePath(defaultFileName);
|
||||
|
||||
nsCAutoString fileExtension;
|
||||
fileURL->GetFileExtension(fileExtension);
|
||||
|
||||
PRBool setExtension = PR_FALSE;
|
||||
if (mContentType.Equals("text/html")) {
|
||||
if (fileExtension.IsEmpty() || (!fileExtension.Equals("htm") && !fileExtension.Equals("html"))) {
|
||||
defaultFileName += ".html";
|
||||
setExtension = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!setExtension && fileExtension.IsEmpty()) {
|
||||
nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1"));
|
||||
if (!mimeService)
|
||||
return;
|
||||
nsCOMPtr<nsIMIMEInfo> mimeInfo;
|
||||
mimeService->GetFromMIMEType(mContentType.get(), getter_AddRefs(mimeInfo));
|
||||
if (!mimeInfo)
|
||||
return;
|
||||
|
||||
PRUint32 extCount = 0;
|
||||
char** extList = nsnull;
|
||||
mimeInfo->GetFileExtensions(&extCount, &extList);
|
||||
if (extCount > 0 && extList) {
|
||||
defaultFileName += ".";
|
||||
defaultFileName += extList[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Now it's time to pose the save dialog.
|
||||
NSSavePanel* savePanel = [NSSavePanel savePanel];
|
||||
NSString* file = nil;
|
||||
if (!defaultFileName.IsEmpty())
|
||||
file = [[NSString alloc] initWithCString: defaultFileName.get()];
|
||||
|
||||
if (isHTML)
|
||||
[savePanel setAccessoryView: mFilterView];
|
||||
|
||||
if ([savePanel runModalForDirectory: nil file: file] == NSFileHandlingPanelCancelButton)
|
||||
return;
|
||||
|
||||
// Release the file string.
|
||||
[file release];
|
||||
|
||||
// Update the filter index.
|
||||
if (isHTML && mFilterList) {
|
||||
filterIndex = [mFilterList indexOfSelectedItem];
|
||||
dirBranch->SetIntPref("save_converter_index", filterIndex);
|
||||
}
|
||||
|
||||
// Convert the content type to text/plain if it was selected in the filter.
|
||||
if (isHTML && filterIndex == 2)
|
||||
mContentType = "text/plain";
|
||||
|
||||
nsCOMPtr<nsISupports> sourceData;
|
||||
if (isHTML && filterIndex != 1)
|
||||
sourceData = do_QueryInterface(mDocument);
|
||||
else
|
||||
sourceData = do_QueryInterface(mURL);
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPersist> webPersist(do_CreateInstance(persistContractID));
|
||||
ProgressDlgController* progressDialog = [[ProgressDlgController alloc] initWithWindowNibName: @"ProgressDialog"];
|
||||
[progressDialog setWebPersist: webPersist
|
||||
source: sourceData.get()
|
||||
destination: [savePanel filename]
|
||||
contentType: mContentType.get()
|
||||
postData: mPostData
|
||||
bypassCache: mBypassCache];
|
||||
|
||||
[progressDialog showWindow: progressDialog];
|
||||
}
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation CHBrowserView
|
||||
|
||||
|
@ -1244,13 +980,17 @@ nsHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aReq
|
|||
shEntry->GetPostData(getter_AddRefs(postData));
|
||||
}
|
||||
|
||||
// when saving, we first fire off a save with a nsHeaderSniffer as a progress
|
||||
// listener. This allows us to look for the content-disposition header, which
|
||||
// can supply a filename, and maybe has something to do with CGI-generated
|
||||
// content (?)
|
||||
nsCAutoString fileName(aFilename);
|
||||
nsHeaderSniffer* sniffer = new nsHeaderSniffer(webPersist, tmpFile, aURI,
|
||||
aDocument, postData, fileName, aBypassCache,
|
||||
aFilterView, aFilterList);
|
||||
if (!sniffer)
|
||||
return;
|
||||
webPersist->SetProgressListener(sniffer);
|
||||
webPersist->SetProgressListener(sniffer); // owned
|
||||
webPersist->SaveURI(aURI, nsnull, tmpFile);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// This file contains implementations of factories for various
|
||||
// downloading-related interfaces.
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
#import "ProgressDlgController.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIFactory.h"
|
||||
|
||||
#include "nsDownloadListener.h"
|
||||
#include "DownloadFactories.h"
|
||||
|
||||
// factory for nsIDownload objects
|
||||
// XXX replace with generic factory stuff
|
||||
class DownloadListenerFactory : public nsIFactory
|
||||
{
|
||||
public:
|
||||
DownloadListenerFactory();
|
||||
virtual ~DownloadListenerFactory();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIFACTORY
|
||||
|
||||
protected:
|
||||
|
||||
DownloadControllerFactory* mControllerFactory; // factory which creates the Cocoa window controller
|
||||
};
|
||||
|
||||
|
||||
DownloadListenerFactory::DownloadListenerFactory()
|
||||
: mControllerFactory(nil)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mControllerFactory = [[[ChimeraDownloadControllerFactory alloc] init] retain];
|
||||
}
|
||||
|
||||
DownloadListenerFactory::~DownloadListenerFactory()
|
||||
{
|
||||
[mControllerFactory release];
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(DownloadListenerFactory, nsIFactory);
|
||||
|
||||
/* void createInstance (in nsISupports aOuter, in nsIIDRef iid, [iid_is (iid), retval] out nsQIResult result); */
|
||||
NS_IMETHODIMP
|
||||
DownloadListenerFactory::CreateInstance(nsISupports *aOuter, const nsIID& aIID, void* *aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsIDownload)))
|
||||
{
|
||||
nsDownloadListener* downloadListener = new nsDownloadListener(mControllerFactory);
|
||||
if (!downloadListener) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(downloadListener);
|
||||
rv = downloadListener->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(downloadListener);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
/* void lockFactory (in PRBool lock); */
|
||||
NS_IMETHODIMP
|
||||
DownloadListenerFactory::LockFactory(PRBool lock)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
nsresult NewDownloadListenerFactory(nsIFactory* *outFactory)
|
||||
{
|
||||
DownloadListenerFactory* newFactory = new DownloadListenerFactory();
|
||||
if (!newFactory) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(newFactory);
|
||||
nsresult rv = newFactory->QueryInterface(NS_GET_IID(nsIFactory), (void **)outFactory);
|
||||
NS_RELEASE(newFactory);
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
The classes and protocol in this file allow Cocoa applications to easily
|
||||
reuse the underlying download implementation, which deals with the complexity
|
||||
of Gecko's downloading callbacks.
|
||||
|
||||
There are three things here:
|
||||
|
||||
1. The DownloadProgressDisplay protocol.
|
||||
|
||||
This is a formal protocol that needs to be implemented by
|
||||
a window controller for your progress window. Its methods
|
||||
will be called by the underlying C++ downloading classes.
|
||||
|
||||
2. The Obj-C DownloadControllerFactory class.
|
||||
|
||||
This class should be subclassed by an embedder, with an
|
||||
implementation of 'createDownloadController' that hands back
|
||||
a new instance of an NSWindowController that implements the
|
||||
<DownloadProgressDisplay> protocol.
|
||||
|
||||
The underlying C++ classes use this factory to create the
|
||||
progress window controller.
|
||||
|
||||
3. The nsDownloader C++ class
|
||||
|
||||
This base class exists to hide the complextity of the download
|
||||
listener classes (which deal with Gecko callbacks) from the
|
||||
window controller. Embedders don't need to do anything with it.
|
||||
|
||||
How these classes fit together:
|
||||
|
||||
There are 2 ways in which a download is initiated:
|
||||
|
||||
(i) File->Save.
|
||||
|
||||
Chimera does a complex dance here in order to get certain
|
||||
information about the data being downloaded (it needs to
|
||||
start the download before it can read some optional MIME headers).
|
||||
|
||||
CBrowserView creates an nsIWebBrowserPersist (WBP), and then a
|
||||
nsHeaderSniffer, which implements nsIWebProgressListener and is set to
|
||||
observer the WBP. When nsHeaderSniffer hears about the start of the
|
||||
download, it decides on a file name, and what format to save the data
|
||||
in. It then cancels the current WPB, makes another one, and does
|
||||
a CreateInstance of an nsIDownload (making one of our nsDownloadListener
|
||||
-- aka nsDownloder -- objects), and sets that as the nsIWebProgressListener.
|
||||
The full download procedes from there.
|
||||
|
||||
(ii) Click to download (e.g. FTP link)
|
||||
|
||||
This is simpler. The backend (necko) does the CreateInstance of the
|
||||
nsIDownload, and the download progresses.
|
||||
|
||||
In both cases, creating the nsDownloadListener and calling its Init() method
|
||||
calls nsDownloder::CreateDownloadDisplay(). The nsDownloder has as a member
|
||||
variable a DownloadControllerFactory (see above), which got passed to it
|
||||
via our XPCOM factory for nsIDownload objects. It then uses that DownloadControllerFactory
|
||||
to get an instance of the download progress window controller, which then
|
||||
shows the download progress window.
|
||||
|
||||
Simple, eh?
|
||||
|
||||
*/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsDownloader;
|
||||
|
||||
// a formal protocol for something that implements progress display
|
||||
// Embedders can make a window controller that conforms to this
|
||||
// protocol, and reuse nsDownloadListener to get download UI.
|
||||
@protocol DownloadProgressDisplay
|
||||
|
||||
- (void)onStartDownload;
|
||||
- (void)onEndDownload;
|
||||
|
||||
- (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress;
|
||||
|
||||
- (void)setDownloadListener:(nsDownloader*)aDownloader;
|
||||
- (void)setSourceURL:(NSString*)aSourceURL;
|
||||
- (void)setDestinationPath:(NSString*)aDestPath;
|
||||
|
||||
@end
|
||||
|
||||
// subclass this, and have your subclass instantiate and return your window
|
||||
// controller in createDownloadController
|
||||
@interface DownloadControllerFactory : NSObject
|
||||
{
|
||||
}
|
||||
|
||||
- (NSWindowController<DownloadProgressDisplay> *)createDownloadController;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// Pure virtual base class for a generic downloader, that the progress UI can talk to.
|
||||
// It implements nsISupports so that it can be refcounted. This class insulates the
|
||||
// UI code from having to know too much about the nsIDownloadListener.
|
||||
// It is responsible for creating the download UI, via the DownloadControllerFactory
|
||||
// that it owns.
|
||||
class nsDownloader : public nsISupports
|
||||
{
|
||||
public:
|
||||
nsDownloader(DownloadControllerFactory* inControllerFactory);
|
||||
virtual ~nsDownloader();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void PauseDownload() = 0;
|
||||
virtual void ResumeDownload() = 0;
|
||||
virtual void CancelDownload() = 0;
|
||||
virtual void DownloadDone() = 0;
|
||||
|
||||
virtual void CreateDownloadDisplay();
|
||||
|
||||
protected:
|
||||
|
||||
DownloadControllerFactory* mControllerFactory;
|
||||
id <DownloadProgressDisplay> mDownloadDisplay; // something that implements the DownloadProgressDisplay protocol
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
|
||||
|
||||
@implementation DownloadControllerFactory
|
||||
|
||||
- (NSWindowController<DownloadProgressDisplay> *)createDownloadController
|
||||
{
|
||||
// a dummy implementation. You should provide a subclass that
|
||||
// returns an instance of your progress dialog controller.
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// see the header file for comments
|
||||
nsDownloader::nsDownloader(DownloadControllerFactory* inControllerFactory)
|
||||
: mControllerFactory(inControllerFactory)
|
||||
, mDownloadDisplay(nil)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
[mControllerFactory retain];
|
||||
}
|
||||
|
||||
nsDownloader::~nsDownloader()
|
||||
{
|
||||
[mControllerFactory release];
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDownloader, nsISupports);
|
||||
|
||||
void
|
||||
nsDownloader::CreateDownloadDisplay()
|
||||
{
|
||||
mDownloadDisplay = [mControllerFactory createDownloadController];
|
||||
[mDownloadDisplay setDownloadListener:this];
|
||||
}
|
|
@ -89,8 +89,11 @@ app_getModuleInfo(nsStaticModuleInfo **info, PRUint32 *count);
|
|||
nsresult rv;
|
||||
ICStop (mInternetConfig);
|
||||
nsCOMPtr<nsIPrefService> pref(do_GetService(NS_PREF_CONTRACTID, &rv));
|
||||
if (!NS_FAILED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
//NSLog(@"Saving prefs file");
|
||||
pref->SavePrefFile(nsnull);
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "CHBrowserView.h"
|
||||
#import "ProgressDlgController.h"
|
||||
#import "FindDlgController.h"
|
||||
#import "nsCocoaBrowserService.h"
|
||||
#import "mozView.h"
|
||||
|
@ -65,18 +64,12 @@
|
|||
|
||||
// Saving of links/images/docs
|
||||
#include "nsIWebBrowserFocus.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDOMNSDocument.h"
|
||||
#include "nsIDOMLocation.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsIProperties.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsIMIMEInfo.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsISHistory.h"
|
||||
#include "nsIHistoryEntry.h"
|
||||
#include "nsISHEntry.h"
|
||||
|
@ -84,6 +77,7 @@
|
|||
#include "nsIContextMenuListener.h"
|
||||
#include "nsITooltipListener.h"
|
||||
#include "nsIEmbeddingSiteWindow2.h"
|
||||
#include "SaveHeaderSniffer.h"
|
||||
|
||||
typedef unsigned int DragReference;
|
||||
#include "nsIDragHelperService.h"
|
||||
|
@ -677,265 +671,7 @@ nsCocoaBrowserListener::SetContainer(id <NSBrowserContainer> aContainer)
|
|||
[mContainer retain];
|
||||
}
|
||||
|
||||
// Implementation of a header sniffer class that is used when saving Web pages and images.
|
||||
class nsHeaderSniffer : public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
|
||||
nsIDOMDocument* aDocument, nsIInputStream* aPostData,
|
||||
const nsCString& aSuggestedFilename, PRBool aBypassCache,
|
||||
NSView* aFilterView, NSPopUpButton* aFilterList)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mPersist = aPersist;
|
||||
mTmpFile = aFile;
|
||||
mURL = aURL;
|
||||
mDocument = aDocument;
|
||||
mPostData = aPostData;
|
||||
mDefaultFilename = aSuggestedFilename;
|
||||
mBypassCache = aBypassCache;
|
||||
mFilterView = aFilterView;
|
||||
mFilterList = aFilterList;
|
||||
}
|
||||
|
||||
virtual ~nsHeaderSniffer()
|
||||
{
|
||||
};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
protected:
|
||||
void PerformSave();
|
||||
|
||||
private:
|
||||
nsIWebBrowserPersist* mPersist; // Weak. It owns us as a listener.
|
||||
nsCOMPtr<nsIFile> mTmpFile;
|
||||
nsCOMPtr<nsIURI> mURL;
|
||||
nsCOMPtr<nsIDOMDocument> mDocument;
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
nsCString mDefaultFilename;
|
||||
PRBool mBypassCache;
|
||||
nsCString mContentType;
|
||||
nsCString mContentDisposition;
|
||||
NSView* mFilterView;
|
||||
NSPopUpButton* mFilterList;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsHeaderSniffer, nsIWebProgressListener)
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
if (aStateFlags & nsIWebProgressListener::STATE_START) {
|
||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
|
||||
channel->GetContentType(mContentType);
|
||||
|
||||
// Get the content-disposition if we're an HTTP channel.
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if (httpChannel)
|
||||
httpChannel->GetResponseHeader(nsCAutoString("content-disposition"), mContentDisposition);
|
||||
|
||||
mPersist->CancelSave();
|
||||
PRBool exists;
|
||||
mTmpFile->Exists(&exists);
|
||||
if (exists)
|
||||
mTmpFile->Remove(PR_FALSE);
|
||||
PerformSave();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsHeaderSniffer::PerformSave()
|
||||
{
|
||||
// Are we an HTML document? If so, we will want to append an accessory view to
|
||||
// the save dialog to provide the user with the option of doing a complete
|
||||
// save vs. a single file save.
|
||||
PRBool isHTML = (mDocument && mContentType.Equals("text/html") ||
|
||||
mContentType.Equals("text/xml") ||
|
||||
mContentType.Equals("application/xhtml+xml"));
|
||||
|
||||
// Next find out the directory that we should start in.
|
||||
nsCOMPtr<nsIPrefService> prefs(do_GetService("@mozilla.org/preferences-service;1"));
|
||||
if (!prefs)
|
||||
return;
|
||||
nsCOMPtr<nsIPrefBranch> dirBranch;
|
||||
prefs->GetBranch("browser.download.", getter_AddRefs(dirBranch));
|
||||
PRInt32 filterIndex = 0;
|
||||
if (dirBranch) {
|
||||
nsresult rv = dirBranch->GetIntPref("save_converter_index", &filterIndex);
|
||||
if (NS_FAILED(rv))
|
||||
filterIndex = 0;
|
||||
}
|
||||
if (mFilterList)
|
||||
[mFilterList selectItemAtIndex: filterIndex];
|
||||
|
||||
// We need to figure out what file name to use.
|
||||
nsCAutoString defaultFileName;
|
||||
if (!mContentDisposition.IsEmpty()) {
|
||||
// (1) Use the HTTP header suggestion.
|
||||
PRInt32 index = mContentDisposition.Find("filename=");
|
||||
if (index >= 0) {
|
||||
// Take the substring following the prefix.
|
||||
index += 9;
|
||||
nsCAutoString filename;
|
||||
mContentDisposition.Right(filename, mContentDisposition.Length() - index);
|
||||
defaultFileName = filename;
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(mURL));
|
||||
if (url)
|
||||
url->GetFileName(defaultFileName); // (2) For file URLs, use the file name.
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mDocument && isHTML) {
|
||||
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
|
||||
nsAutoString title;
|
||||
if (htmlDoc)
|
||||
htmlDoc->GetTitle(title); // (3) Use the title of the document.
|
||||
defaultFileName.AssignWithConversion(title);
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
// (4) Use the caller provided name.
|
||||
defaultFileName = mDefaultFilename;
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mURL)
|
||||
// (5) Use the host.
|
||||
mURL->GetHost(defaultFileName);
|
||||
|
||||
// One last case to handle about:blank and other fruity untitled pages.
|
||||
if (defaultFileName.IsEmpty())
|
||||
defaultFileName = "untitled";
|
||||
|
||||
// Validate the file name to ensure legality.
|
||||
for (PRUint32 i = 0; i < defaultFileName.Length(); i++)
|
||||
if (defaultFileName[i] == ':' || defaultFileName[i] == '/')
|
||||
defaultFileName.SetCharAt(i, ' ');
|
||||
|
||||
// Make sure the appropriate extension is appended to the suggested file name.
|
||||
nsCOMPtr<nsIURI> fileURI(do_CreateInstance("@mozilla.org/network/standard-url;1"));
|
||||
nsCOMPtr<nsIURL> fileURL(do_QueryInterface(fileURI));
|
||||
if (!fileURL)
|
||||
return;
|
||||
fileURL->SetFilePath(defaultFileName);
|
||||
|
||||
nsCAutoString fileExtension;
|
||||
fileURL->GetFileExtension(fileExtension);
|
||||
|
||||
PRBool setExtension = PR_FALSE;
|
||||
if (mContentType.Equals("text/html")) {
|
||||
if (fileExtension.IsEmpty() || (!fileExtension.Equals("htm") && !fileExtension.Equals("html"))) {
|
||||
defaultFileName += ".html";
|
||||
setExtension = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!setExtension && fileExtension.IsEmpty()) {
|
||||
nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1"));
|
||||
if (!mimeService)
|
||||
return;
|
||||
nsCOMPtr<nsIMIMEInfo> mimeInfo;
|
||||
mimeService->GetFromMIMEType(mContentType.get(), getter_AddRefs(mimeInfo));
|
||||
if (!mimeInfo)
|
||||
return;
|
||||
|
||||
PRUint32 extCount = 0;
|
||||
char** extList = nsnull;
|
||||
mimeInfo->GetFileExtensions(&extCount, &extList);
|
||||
if (extCount > 0 && extList) {
|
||||
defaultFileName += ".";
|
||||
defaultFileName += extList[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Now it's time to pose the save dialog.
|
||||
NSSavePanel* savePanel = [NSSavePanel savePanel];
|
||||
NSString* file = nil;
|
||||
if (!defaultFileName.IsEmpty())
|
||||
file = [[NSString alloc] initWithCString: defaultFileName.get()];
|
||||
|
||||
if (isHTML)
|
||||
[savePanel setAccessoryView: mFilterView];
|
||||
|
||||
if ([savePanel runModalForDirectory: nil file: file] == NSFileHandlingPanelCancelButton)
|
||||
return;
|
||||
|
||||
// Release the file string.
|
||||
[file release];
|
||||
|
||||
// Update the filter index.
|
||||
if (isHTML && mFilterList) {
|
||||
filterIndex = [mFilterList indexOfSelectedItem];
|
||||
dirBranch->SetIntPref("save_converter_index", filterIndex);
|
||||
}
|
||||
|
||||
// Convert the content type to text/plain if it was selected in the filter.
|
||||
if (isHTML && filterIndex == 2)
|
||||
mContentType = "text/plain";
|
||||
|
||||
nsCOMPtr<nsISupports> sourceData;
|
||||
if (isHTML && filterIndex != 1)
|
||||
sourceData = do_QueryInterface(mDocument);
|
||||
else
|
||||
sourceData = do_QueryInterface(mURL);
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPersist> webPersist(do_CreateInstance(persistContractID));
|
||||
ProgressDlgController* progressDialog = [[ProgressDlgController alloc] initWithWindowNibName: @"ProgressDialog"];
|
||||
[progressDialog setWebPersist: webPersist
|
||||
source: sourceData.get()
|
||||
destination: [savePanel filename]
|
||||
contentType: mContentType.get()
|
||||
postData: mPostData
|
||||
bypassCache: mBypassCache];
|
||||
|
||||
[progressDialog showWindow: progressDialog];
|
||||
}
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation CHBrowserView
|
||||
|
||||
|
@ -1244,13 +980,17 @@ nsHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aReq
|
|||
shEntry->GetPostData(getter_AddRefs(postData));
|
||||
}
|
||||
|
||||
// when saving, we first fire off a save with a nsHeaderSniffer as a progress
|
||||
// listener. This allows us to look for the content-disposition header, which
|
||||
// can supply a filename, and maybe has something to do with CGI-generated
|
||||
// content (?)
|
||||
nsCAutoString fileName(aFilename);
|
||||
nsHeaderSniffer* sniffer = new nsHeaderSniffer(webPersist, tmpFile, aURI,
|
||||
aDocument, postData, fileName, aBypassCache,
|
||||
aFilterView, aFilterList);
|
||||
if (!sniffer)
|
||||
return;
|
||||
webPersist->SetProgressListener(sniffer);
|
||||
webPersist->SetProgressListener(sniffer); // owned
|
||||
webPersist->SaveURI(aURI, nsnull, tmpFile);
|
||||
}
|
||||
|
||||
|
|
|
@ -89,8 +89,11 @@ app_getModuleInfo(nsStaticModuleInfo **info, PRUint32 *count);
|
|||
nsresult rv;
|
||||
ICStop (mInternetConfig);
|
||||
nsCOMPtr<nsIPrefService> pref(do_GetService(NS_PREF_CONTRACTID, &rv));
|
||||
if (!NS_FAILED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
//NSLog(@"Saving prefs file");
|
||||
pref->SavePrefFile(nsnull);
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
F512F52B02D1287F01072C9F,
|
||||
F5A3669702CCFAF601DC3354,
|
||||
F512F52C02D1287F01072C9F,
|
||||
F50D9DE602ECC32301BB4219,
|
||||
F512F52D02D1287F01072C9F,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
|
@ -471,6 +472,10 @@
|
|||
F59236C202C89ACA0100012B,
|
||||
F5A3669802CCFAF601DC3354,
|
||||
F55C4DD402D2864E0130B065,
|
||||
F50D9DE402ECC2C601BB4219,
|
||||
F50D9DEF02EE0AB101BB4219,
|
||||
F50D9DF302EE194001BB4219,
|
||||
F50D9DF702EE2B9B01BB4219,
|
||||
);
|
||||
isa = PBXHeadersBuildPhase;
|
||||
name = Headers;
|
||||
|
@ -585,6 +590,10 @@
|
|||
F53E012D02AEE93701A967F3,
|
||||
F632AF8602B9AEBC01000103,
|
||||
F59236C302C89ACA0100012B,
|
||||
F50D9DE502ECC2C601BB4219,
|
||||
F50D9DF002EE0AB101BB4219,
|
||||
F50D9DF402EE194001BB4219,
|
||||
F50D9DF802EE2B9B01BB4219,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
name = Sources;
|
||||
|
@ -840,6 +849,145 @@
|
|||
name = Graphics;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE202ECC2C601BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = nsDownloadListener.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE302ECC2C601BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = nsDownloadListener.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE402ECC2C601BB4219 = {
|
||||
fileRef = F50D9DE202ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE502ECC2C601BB4219 = {
|
||||
fileRef = F50D9DE302ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE602ECC32301BB4219 = {
|
||||
children = (
|
||||
F50D9DF902EE2C1D01BB4219,
|
||||
F50D9DFA02EE2C1D01BB4219,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Downloading;
|
||||
path = "";
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE702ECC36201BB4219 = {
|
||||
fileRef = F50D9DE202ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE802ECC36201BB4219 = {
|
||||
fileRef = F632AF8302B9AEBB01000103;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE902ECC36201BB4219 = {
|
||||
fileRef = F50D9DE302ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DED02EE0AB101BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadProgressDisplay.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DEE02EE0AB101BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadProgressDisplay.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DEF02EE0AB101BB4219 = {
|
||||
fileRef = F50D9DED02EE0AB101BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF002EE0AB101BB4219 = {
|
||||
fileRef = F50D9DEE02EE0AB101BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF102EE194001BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadFactories.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF202EE194001BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadFactories.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF302EE194001BB4219 = {
|
||||
fileRef = F50D9DF102EE194001BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF402EE194001BB4219 = {
|
||||
fileRef = F50D9DF202EE194001BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF502EE2B9A01BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = SaveHeaderSniffer.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF602EE2B9A01BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = SaveHeaderSniffer.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF702EE2B9B01BB4219 = {
|
||||
fileRef = F50D9DF502EE2B9A01BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF802EE2B9B01BB4219 = {
|
||||
fileRef = F50D9DF602EE2B9A01BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF902EE2C1D01BB4219 = {
|
||||
children = (
|
||||
F50D9DF102EE194001BB4219,
|
||||
F50D9DF202EE194001BB4219,
|
||||
F50D9DED02EE0AB101BB4219,
|
||||
F50D9DEE02EE0AB101BB4219,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Generic;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DFA02EE2C1D01BB4219 = {
|
||||
children = (
|
||||
F50D9DF502EE2B9A01BB4219,
|
||||
F50D9DF602EE2B9A01BB4219,
|
||||
F517395B020CE3740189DA0C,
|
||||
F50D9DE302ECC2C601BB4219,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Chimera;
|
||||
path = "";
|
||||
refType = 4;
|
||||
};
|
||||
F50DCB4302C2856001A967F3 = {
|
||||
isa = PBXFileReference;
|
||||
name = libjsj.dylib;
|
||||
|
@ -1143,7 +1291,6 @@
|
|||
F512F52B02D1287F01072C9F = {
|
||||
children = (
|
||||
F5DE10E90209DC0601A967DF,
|
||||
F517395B020CE3740189DA0C,
|
||||
F528E21A020FD9620168DE43,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
|
@ -1176,7 +1323,6 @@
|
|||
};
|
||||
F512F53302D17A2601072C9F = {
|
||||
children = (
|
||||
F55C4DD302D2864D0130B065,
|
||||
29B97316FDCFA39411CA2CEA,
|
||||
F59236C002C89AC90100012B,
|
||||
F5AE04BA0206A4FE01A967DF,
|
||||
|
@ -1330,6 +1476,7 @@
|
|||
F507BA480213AD5F01D93544,
|
||||
F57074B5026BA85F01A80166,
|
||||
F57074B9026BFD0101A80166,
|
||||
2EEC3E61028138714B000102,
|
||||
F57074BD026D80DF01A80166,
|
||||
2E293A00027F33604B000102,
|
||||
F5607CB5023944AD01A967DF,
|
||||
|
@ -1344,6 +1491,8 @@
|
|||
F53E013202AEEA2801A967F3,
|
||||
F5A3669302CCFAF601DC3354,
|
||||
F59236C102C89AC90100012B,
|
||||
F50D9DE202ECC2C601BB4219,
|
||||
F55C4DD302D2864D0130B065,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Headers;
|
||||
|
@ -4375,7 +4524,6 @@
|
|||
F57074B6026BA85F01A80166,
|
||||
F57074BA026BFD0101A80166,
|
||||
F53E012C02AEE93601A967F3,
|
||||
2EEC3E61028138714B000102,
|
||||
2EEC3E62028138714B000102,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
|
@ -4959,6 +5107,8 @@
|
|||
F53E013402AEEA2901A967F3,
|
||||
F59236C402C89ACA0100012B,
|
||||
F5A3669A02CCFB7A01DC3354,
|
||||
F50D9DE702ECC36201BB4219,
|
||||
F50D9DE802ECC36201BB4219,
|
||||
);
|
||||
isa = PBXHeadersBuildPhase;
|
||||
name = Headers;
|
||||
|
@ -5074,6 +5224,7 @@
|
|||
F59236C502C89ACA0100012B,
|
||||
F5A3669B02CCFB7A01DC3354,
|
||||
F5A3669C02CCFB7A01DC3354,
|
||||
F50D9DE902ECC36201BB4219,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
name = Sources;
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// This file contains implementations of factories for various
|
||||
// downloading-related interfaces.
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
#import "ProgressDlgController.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIFactory.h"
|
||||
|
||||
#include "nsDownloadListener.h"
|
||||
#include "DownloadFactories.h"
|
||||
|
||||
// factory for nsIDownload objects
|
||||
// XXX replace with generic factory stuff
|
||||
class DownloadListenerFactory : public nsIFactory
|
||||
{
|
||||
public:
|
||||
DownloadListenerFactory();
|
||||
virtual ~DownloadListenerFactory();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIFACTORY
|
||||
|
||||
protected:
|
||||
|
||||
DownloadControllerFactory* mControllerFactory; // factory which creates the Cocoa window controller
|
||||
};
|
||||
|
||||
|
||||
DownloadListenerFactory::DownloadListenerFactory()
|
||||
: mControllerFactory(nil)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mControllerFactory = [[[ChimeraDownloadControllerFactory alloc] init] retain];
|
||||
}
|
||||
|
||||
DownloadListenerFactory::~DownloadListenerFactory()
|
||||
{
|
||||
[mControllerFactory release];
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(DownloadListenerFactory, nsIFactory);
|
||||
|
||||
/* void createInstance (in nsISupports aOuter, in nsIIDRef iid, [iid_is (iid), retval] out nsQIResult result); */
|
||||
NS_IMETHODIMP
|
||||
DownloadListenerFactory::CreateInstance(nsISupports *aOuter, const nsIID& aIID, void* *aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsIDownload)))
|
||||
{
|
||||
nsDownloadListener* downloadListener = new nsDownloadListener(mControllerFactory);
|
||||
if (!downloadListener) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(downloadListener);
|
||||
rv = downloadListener->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(downloadListener);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
/* void lockFactory (in PRBool lock); */
|
||||
NS_IMETHODIMP
|
||||
DownloadListenerFactory::LockFactory(PRBool lock)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
nsresult NewDownloadListenerFactory(nsIFactory* *outFactory)
|
||||
{
|
||||
DownloadListenerFactory* newFactory = new DownloadListenerFactory();
|
||||
if (!newFactory) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(newFactory);
|
||||
nsresult rv = newFactory->QueryInterface(NS_GET_IID(nsIFactory), (void **)outFactory);
|
||||
NS_RELEASE(newFactory);
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
The classes and protocol in this file allow Cocoa applications to easily
|
||||
reuse the underlying download implementation, which deals with the complexity
|
||||
of Gecko's downloading callbacks.
|
||||
|
||||
There are three things here:
|
||||
|
||||
1. The DownloadProgressDisplay protocol.
|
||||
|
||||
This is a formal protocol that needs to be implemented by
|
||||
a window controller for your progress window. Its methods
|
||||
will be called by the underlying C++ downloading classes.
|
||||
|
||||
2. The Obj-C DownloadControllerFactory class.
|
||||
|
||||
This class should be subclassed by an embedder, with an
|
||||
implementation of 'createDownloadController' that hands back
|
||||
a new instance of an NSWindowController that implements the
|
||||
<DownloadProgressDisplay> protocol.
|
||||
|
||||
The underlying C++ classes use this factory to create the
|
||||
progress window controller.
|
||||
|
||||
3. The nsDownloader C++ class
|
||||
|
||||
This base class exists to hide the complextity of the download
|
||||
listener classes (which deal with Gecko callbacks) from the
|
||||
window controller. Embedders don't need to do anything with it.
|
||||
|
||||
How these classes fit together:
|
||||
|
||||
There are 2 ways in which a download is initiated:
|
||||
|
||||
(i) File->Save.
|
||||
|
||||
Chimera does a complex dance here in order to get certain
|
||||
information about the data being downloaded (it needs to
|
||||
start the download before it can read some optional MIME headers).
|
||||
|
||||
CBrowserView creates an nsIWebBrowserPersist (WBP), and then a
|
||||
nsHeaderSniffer, which implements nsIWebProgressListener and is set to
|
||||
observer the WBP. When nsHeaderSniffer hears about the start of the
|
||||
download, it decides on a file name, and what format to save the data
|
||||
in. It then cancels the current WPB, makes another one, and does
|
||||
a CreateInstance of an nsIDownload (making one of our nsDownloadListener
|
||||
-- aka nsDownloder -- objects), and sets that as the nsIWebProgressListener.
|
||||
The full download procedes from there.
|
||||
|
||||
(ii) Click to download (e.g. FTP link)
|
||||
|
||||
This is simpler. The backend (necko) does the CreateInstance of the
|
||||
nsIDownload, and the download progresses.
|
||||
|
||||
In both cases, creating the nsDownloadListener and calling its Init() method
|
||||
calls nsDownloder::CreateDownloadDisplay(). The nsDownloder has as a member
|
||||
variable a DownloadControllerFactory (see above), which got passed to it
|
||||
via our XPCOM factory for nsIDownload objects. It then uses that DownloadControllerFactory
|
||||
to get an instance of the download progress window controller, which then
|
||||
shows the download progress window.
|
||||
|
||||
Simple, eh?
|
||||
|
||||
*/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsDownloader;
|
||||
|
||||
// a formal protocol for something that implements progress display
|
||||
// Embedders can make a window controller that conforms to this
|
||||
// protocol, and reuse nsDownloadListener to get download UI.
|
||||
@protocol DownloadProgressDisplay
|
||||
|
||||
- (void)onStartDownload;
|
||||
- (void)onEndDownload;
|
||||
|
||||
- (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress;
|
||||
|
||||
- (void)setDownloadListener:(nsDownloader*)aDownloader;
|
||||
- (void)setSourceURL:(NSString*)aSourceURL;
|
||||
- (void)setDestinationPath:(NSString*)aDestPath;
|
||||
|
||||
@end
|
||||
|
||||
// subclass this, and have your subclass instantiate and return your window
|
||||
// controller in createDownloadController
|
||||
@interface DownloadControllerFactory : NSObject
|
||||
{
|
||||
}
|
||||
|
||||
- (NSWindowController<DownloadProgressDisplay> *)createDownloadController;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// Pure virtual base class for a generic downloader, that the progress UI can talk to.
|
||||
// It implements nsISupports so that it can be refcounted. This class insulates the
|
||||
// UI code from having to know too much about the nsIDownloadListener.
|
||||
// It is responsible for creating the download UI, via the DownloadControllerFactory
|
||||
// that it owns.
|
||||
class nsDownloader : public nsISupports
|
||||
{
|
||||
public:
|
||||
nsDownloader(DownloadControllerFactory* inControllerFactory);
|
||||
virtual ~nsDownloader();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void PauseDownload() = 0;
|
||||
virtual void ResumeDownload() = 0;
|
||||
virtual void CancelDownload() = 0;
|
||||
virtual void DownloadDone() = 0;
|
||||
|
||||
virtual void CreateDownloadDisplay();
|
||||
|
||||
protected:
|
||||
|
||||
DownloadControllerFactory* mControllerFactory;
|
||||
id <DownloadProgressDisplay> mDownloadDisplay; // something that implements the DownloadProgressDisplay protocol
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
|
||||
|
||||
@implementation DownloadControllerFactory
|
||||
|
||||
- (NSWindowController<DownloadProgressDisplay> *)createDownloadController
|
||||
{
|
||||
// a dummy implementation. You should provide a subclass that
|
||||
// returns an instance of your progress dialog controller.
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// see the header file for comments
|
||||
nsDownloader::nsDownloader(DownloadControllerFactory* inControllerFactory)
|
||||
: mControllerFactory(inControllerFactory)
|
||||
, mDownloadDisplay(nil)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
[mControllerFactory retain];
|
||||
}
|
||||
|
||||
nsDownloader::~nsDownloader()
|
||||
{
|
||||
[mControllerFactory release];
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDownloader, nsISupports);
|
||||
|
||||
void
|
||||
nsDownloader::CreateDownloadDisplay()
|
||||
{
|
||||
mDownloadDisplay = [mControllerFactory createDownloadController];
|
||||
[mDownloadDisplay setDownloadListener:this];
|
||||
}
|
|
@ -3,13 +3,13 @@
|
|||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>73 360 356 240 0 0 1152 848 </string>
|
||||
<string>61 108 356 240 0 0 1152 746 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>266</key>
|
||||
<string>418 452 277 90 0 0 1152 746 </string>
|
||||
<string>23 342 277 90 0 0 1152 746 </string>
|
||||
<key>29</key>
|
||||
<string>8 803 446 44 0 0 1152 848 </string>
|
||||
<string>8 701 446 44 0 0 1152 746 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
|
|
Двоичный файл не отображается.
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
IBClasses = (
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{
|
||||
CLASS = ProgressDlgController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mElapsedTimeLabel = id;
|
||||
mFromField = id;
|
||||
mProgressBar = id;
|
||||
mStatusLabel = id;
|
||||
mTimeLeftLabel = id;
|
||||
mToField = id;
|
||||
};
|
||||
SUPERCLASS = NSWindowController;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>152 212 356 240 0 0 1024 746 </string>
|
||||
<string>94 26 404 250 0 0 1152 746 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
<key>IBOpenObjects</key>
|
||||
|
@ -11,6 +11,6 @@
|
|||
<integer>5</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>5Q125</string>
|
||||
<string>5S66</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
Двоичный файл не отображается.
|
@ -3,13 +3,13 @@
|
|||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>73 360 356 240 0 0 1152 848 </string>
|
||||
<string>61 108 356 240 0 0 1152 746 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>266</key>
|
||||
<string>418 452 277 90 0 0 1152 746 </string>
|
||||
<string>23 342 277 90 0 0 1152 746 </string>
|
||||
<key>29</key>
|
||||
<string>8 803 446 44 0 0 1152 848 </string>
|
||||
<string>8 701 446 44 0 0 1152 746 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
|
|
Двоичный файл не отображается.
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
IBClasses = (
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{
|
||||
CLASS = ProgressDlgController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mElapsedTimeLabel = id;
|
||||
mFromField = id;
|
||||
mProgressBar = id;
|
||||
mStatusLabel = id;
|
||||
mTimeLeftLabel = id;
|
||||
mToField = id;
|
||||
};
|
||||
SUPERCLASS = NSWindowController;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>152 212 356 240 0 0 1024 746 </string>
|
||||
<string>94 26 404 250 0 0 1152 746 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
<key>IBOpenObjects</key>
|
||||
|
@ -11,6 +11,6 @@
|
|||
<integer>5</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>5Q125</string>
|
||||
<string>5S66</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
Двоичный файл не отображается.
|
@ -36,6 +36,9 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
class nsIWebBrowserPersist;
|
||||
|
@ -43,42 +46,37 @@ class nsISupports;
|
|||
class nsIInputStream;
|
||||
class nsDownloadListener;
|
||||
|
||||
@interface ProgressDlgController : NSWindowController {
|
||||
IBOutlet id mFromField;
|
||||
IBOutlet id mToField;
|
||||
IBOutlet id mStatusLabel;
|
||||
IBOutlet id mTimeLeftLabel;
|
||||
IBOutlet id mElapsedTimeLabel;
|
||||
IBOutlet id mProgressBar;
|
||||
|
||||
@interface ChimeraDownloadControllerFactory : DownloadControllerFactory
|
||||
@end
|
||||
|
||||
|
||||
@interface ProgressDlgController : NSWindowController <DownloadProgressDisplay>
|
||||
{
|
||||
IBOutlet NSTextField *mElapsedTimeLabel;
|
||||
IBOutlet NSTextField *mFromField;
|
||||
IBOutlet NSTextField *mStatusLabel;
|
||||
IBOutlet NSTextField *mTimeLeftLabel;
|
||||
IBOutlet NSTextField *mToField;
|
||||
IBOutlet NSProgressIndicator *mProgressBar;
|
||||
|
||||
NSToolbarItem *pauseResumeToggleToolbarItem;
|
||||
NSToolbarItem *leaveOpenToggleToolbarItem;
|
||||
|
||||
BOOL mDownloadIsPaused;
|
||||
BOOL mSaveFileDialogShouldStayOpen;
|
||||
BOOL mDownloadIsComplete;
|
||||
long int aCurrentProgress; // if progress bar is indeterminate, can still calc stats.
|
||||
BOOL mDownloadIsPaused;
|
||||
BOOL mSaveFileDialogShouldStayOpen;
|
||||
BOOL mDownloadIsComplete;
|
||||
long mCurrentProgress; // if progress bar is indeterminate, can still calc stats.
|
||||
|
||||
nsDownloadListener* mDownloadListener;
|
||||
NSTimer *mDownloadTimer;
|
||||
nsDownloader *mDownloader; // we hold a ref to this
|
||||
NSTimer *mDownloadTimer;
|
||||
}
|
||||
|
||||
-(void) setWebPersist: (nsIWebBrowserPersist*)aPersist
|
||||
source: (nsISupports*)aSource
|
||||
destination: (NSString*)aDestination
|
||||
contentType: (const char*)aContentType
|
||||
postData: (nsIInputStream*)aInputStream
|
||||
bypassCache: (BOOL)aBypassCache;
|
||||
|
||||
-(void) setProgressBar:(long int)aCurProgress
|
||||
maxProg:(long int)aMaxProgress;
|
||||
-(void) setDownloadTimer;
|
||||
-(void) setupDownloadTimer;
|
||||
-(void) killDownloadTimer;
|
||||
-(void) setDownloadProgress:(NSTimer *)aTimer;
|
||||
-(NSString *) formatTime:(int)aSeconds;
|
||||
-(NSString *) formatFuzzyTime:(int)aSeconds;
|
||||
-(NSString *) formatBytes:(float)aBytes;
|
||||
-(void) setSourceURL: (const PRUnichar*)aSource;
|
||||
-(void) setDestination: (const PRUnichar*)aDestination;
|
||||
|
||||
@end
|
||||
|
|
|
@ -46,282 +46,58 @@
|
|||
#include "nsILocalFile.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIDownload.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
|
||||
class nsDownloadListener : public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsDownloadListener(ProgressDlgController* aController,
|
||||
nsIWebBrowserPersist* aPersist,
|
||||
nsISupports* aSource,
|
||||
NSString* aDestination,
|
||||
const char* aContentType,
|
||||
nsIInputStream* aPostData,
|
||||
BOOL aBypassCache)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mController = aController;
|
||||
mWebPersist = aPersist;
|
||||
// The source is either a simple URL or a complete document.
|
||||
mURL = do_QueryInterface(aSource);
|
||||
if (!mURL)
|
||||
mDocument = do_QueryInterface(aSource);
|
||||
|
||||
PRUint32 dstLen = [aDestination length];
|
||||
PRUnichar* tmp = new PRUnichar[dstLen + sizeof(PRUnichar)];
|
||||
tmp[dstLen] = (PRUnichar)'\0';
|
||||
[aDestination getCharacters:tmp];
|
||||
nsAutoString dstStr(tmp);
|
||||
delete tmp;
|
||||
|
||||
NS_NewLocalFile(dstStr, PR_FALSE, getter_AddRefs(mDestination));
|
||||
// XXX check for failure
|
||||
|
||||
mContentType = aContentType;
|
||||
mPostData = aPostData;
|
||||
mBypassCache = aBypassCache;
|
||||
mNetworkTransfer = PR_FALSE;
|
||||
mGotFirstStateChange = PR_FALSE;
|
||||
};
|
||||
|
||||
virtual ~nsDownloadListener() {};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
public:
|
||||
void BeginDownload();
|
||||
void InitDialog();
|
||||
void CancelDownload();
|
||||
|
||||
private: // Member variables
|
||||
ProgressDlgController* mController; // Controller for our UI.
|
||||
nsCOMPtr<nsIWebBrowserPersist> mWebPersist; // Our web persist object.
|
||||
nsCOMPtr<nsIURL> mURL; // The URL of our source file. Null if we're saving a complete document.
|
||||
nsCOMPtr<nsILocalFile> mDestination; // Our destination URL.
|
||||
nsCString mContentType; // Our content type string.
|
||||
nsCOMPtr<nsIDOMHTMLDocument> mDocument; // A DOM document. Null if we're only saving a simple URL.
|
||||
nsCOMPtr<nsIInputStream> mPostData; // For complete documents, this is our post data from session history.
|
||||
PRPackedBool mBypassCache; // Whether we should bypass the cache or not.
|
||||
PRPackedBool mNetworkTransfer; // true if the first OnStateChange has the NETWORK bit set
|
||||
PRPackedBool mGotFirstStateChange; // true after we've seen the first OnStateChange
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDownloadListener, nsIWebProgressListener)
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
[mController setProgressBar:aCurTotalProgress maxProg:aMaxTotalProgress];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
// NSLog(@"State changed: state %u, status %u", aStateFlags, aStatus);
|
||||
if (!mGotFirstStateChange) {
|
||||
mNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0);
|
||||
mGotFirstStateChange = PR_TRUE;
|
||||
}
|
||||
|
||||
// when the entire download finishes, stop the progress timer and clean up
|
||||
// the window and controller. We will get this even in the event of a cancel,
|
||||
// so this is the only place in the listener where we should kill the download.
|
||||
if ((aStateFlags & STATE_STOP) && (!mNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) {
|
||||
[mController killDownloadTimer];
|
||||
[mController setDownloadProgress:nil];
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::BeginDownload()
|
||||
{
|
||||
if (mWebPersist) {
|
||||
mWebPersist->SetProgressListener(this);
|
||||
PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION |
|
||||
nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
|
||||
if (mBypassCache)
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE;
|
||||
else
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
|
||||
|
||||
if (mURL)
|
||||
mWebPersist->SaveURI(mURL, mPostData, mDestination);
|
||||
else {
|
||||
PRInt32 encodingFlags = 0;
|
||||
nsCOMPtr<nsILocalFile> filesFolder;
|
||||
|
||||
if (!mContentType.Equals("text/plain")) {
|
||||
// Create a local directory in the same dir as our file. It
|
||||
// will hold our associated files.
|
||||
filesFolder = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
nsAutoString unicodePath;
|
||||
mDestination->GetPath(unicodePath);
|
||||
filesFolder->InitWithPath(unicodePath);
|
||||
|
||||
nsAutoString leafName;
|
||||
filesFolder->GetLeafName(leafName);
|
||||
nsAutoString nameMinusExt(leafName);
|
||||
PRInt32 index = nameMinusExt.RFind(".");
|
||||
if (index >= 0)
|
||||
nameMinusExt.Left(nameMinusExt, index);
|
||||
nameMinusExt += NS_LITERAL_STRING(" Files"); // XXXdwh needs to be localizable!
|
||||
filesFolder->SetLeafName(nameMinusExt);
|
||||
PRBool exists = PR_FALSE;
|
||||
filesFolder->Exists(&exists);
|
||||
if (!exists)
|
||||
filesFolder->Create(nsILocalFile::DIRECTORY_TYPE, 0755);
|
||||
}
|
||||
else
|
||||
encodingFlags |= nsIWebBrowserPersist::ENCODE_FLAGS_FORMATTED |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_ABSOLUTE_LINKS |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_NOFRAMES_CONTENT;
|
||||
|
||||
mWebPersist->SaveDocument(mDocument, mDestination, filesFolder, mContentType.get(),
|
||||
encodingFlags, 80);
|
||||
}
|
||||
}
|
||||
|
||||
InitDialog();
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::InitDialog()
|
||||
{
|
||||
if (!mURL && !mDocument)
|
||||
return;
|
||||
|
||||
if (mWebPersist) {
|
||||
if (mURL) {
|
||||
nsCAutoString spec;
|
||||
mURL->GetSpec(spec);
|
||||
nsAutoString spec2; spec2.AssignWithConversion(spec.get());
|
||||
[mController setSourceURL: spec2.get()];
|
||||
}
|
||||
else {
|
||||
nsAutoString spec;
|
||||
mDocument->GetURL(spec);
|
||||
[mController setSourceURL: spec.get()];
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString pathStr;
|
||||
mDestination->GetPath(pathStr);
|
||||
[mController setDestination: pathStr.get()];
|
||||
[mController setDownloadTimer];
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::CancelDownload()
|
||||
{
|
||||
if (mWebPersist)
|
||||
mWebPersist->CancelSave();
|
||||
}
|
||||
|
||||
|
||||
static NSString *SaveFileToolbarIdentifier = @"Save File Dialog Toolbar";
|
||||
static NSString *CancelToolbarItemIdentifier = @"Cancel Toolbar Item";
|
||||
static NSString *SaveFileToolbarIdentifier = @"Save File Dialog Toolbar";
|
||||
static NSString *CancelToolbarItemIdentifier = @"Cancel Toolbar Item";
|
||||
static NSString *PauseResumeToolbarItemIdentifier = @"Pause and Resume Toggle Toolbar Item";
|
||||
static NSString *ShowFileToolbarItemIdentifier = @"Show File Toolbar Item";
|
||||
static NSString *OpenFileToolbarItemIdentifier = @"Open File Toolbar Item";
|
||||
static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar Item";
|
||||
|
||||
|
||||
@implementation ChimeraDownloadControllerFactory : DownloadControllerFactory
|
||||
|
||||
- (NSWindowController<DownloadProgressDisplay> *)createDownloadController
|
||||
{
|
||||
NSWindowController* progressController = [[ProgressDlgController alloc] initWithWindowNibName: @"ProgressDialog"];
|
||||
NSAssert([progressController conformsToProtocol:@protocol(DownloadProgressDisplay)],
|
||||
@"progressController should conform to DownloadProgressDisplay protocol");
|
||||
return progressController;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
@interface ProgressDlgController(Private)
|
||||
-(void)setupToolbar;
|
||||
@end
|
||||
|
||||
@implementation ProgressDlgController
|
||||
|
||||
-(void)setWebPersist:(nsIWebBrowserPersist*)aPersist
|
||||
source:(nsISupports*)aSource
|
||||
destination:(NSString*)aDestination
|
||||
contentType:(const char*)aContentType
|
||||
postData:(nsIInputStream*)aInputStream
|
||||
bypassCache:(BOOL)aBypassCache
|
||||
- (void)dealloc
|
||||
{
|
||||
mDownloadListener = new nsDownloadListener(self, aPersist, aSource,
|
||||
aDestination, aContentType,
|
||||
aInputStream, aBypassCache);
|
||||
NS_ADDREF(mDownloadListener);
|
||||
}
|
||||
|
||||
-(void) setProgressBar:(long int)curProgress maxProg:(long int)maxProgress
|
||||
{
|
||||
aCurrentProgress = curProgress; // fall back for stat calcs
|
||||
if (![mProgressBar isIndeterminate]) { //most likely - just update value
|
||||
if (curProgress == maxProgress) //handles little bug in FTP download size
|
||||
[mProgressBar setMaxValue:maxProgress];
|
||||
[mProgressBar setDoubleValue:curProgress];
|
||||
}
|
||||
else if (maxProgress > 0) { // ok, we're starting up with good max & cur values
|
||||
[mProgressBar setIndeterminate:NO];
|
||||
[mProgressBar setMaxValue:maxProgress];
|
||||
[mProgressBar setDoubleValue:curProgress];
|
||||
} // if neither case was true, it's barber pole city.
|
||||
}
|
||||
|
||||
-(void) setSourceURL: (const PRUnichar*)aSource
|
||||
{
|
||||
[mFromField setStringValue: [NSString stringWithCharacters:aSource length:nsCRT::strlen(aSource)]];
|
||||
}
|
||||
|
||||
-(void) setDestination: (const PRUnichar*)aDestination
|
||||
{
|
||||
[mToField setStringValue: [[NSString stringWithCharacters:aDestination length:nsCRT::strlen(aDestination)] stringByAbbreviatingWithTildeInPath]];
|
||||
NS_IF_RELEASE(mDownloader);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)windowDidLoad
|
||||
{
|
||||
mDownloadIsPaused = NO;
|
||||
mDownloadIsComplete = NO;
|
||||
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID));
|
||||
PRBool save = PR_FALSE;
|
||||
prefs->GetBoolPref("browser.download.progressDnldDialog.keepAlive",&save);
|
||||
prefs->GetBoolPref("browser.download.progressDnldDialog.keepAlive", &save);
|
||||
mSaveFileDialogShouldStayOpen = save;
|
||||
|
||||
[self setupToolbar];
|
||||
[mProgressBar setUsesThreadedAnimation:YES];
|
||||
[mProgressBar startAnimation:self];
|
||||
if (mDownloadListener)
|
||||
mDownloadListener->BeginDownload();
|
||||
[mProgressBar startAnimation:self]; // move to onStateChange
|
||||
}
|
||||
|
||||
- (void)setupToolbar
|
||||
|
@ -438,7 +214,9 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
|
||||
-(void)cancel
|
||||
{
|
||||
mDownloadListener->CancelDownload();
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->CancelDownload();
|
||||
|
||||
// clean up downloaded file. - do it here on in CancelDownload?
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSString *thePath = [[mToField stringValue] stringByExpandingTildeInPath];
|
||||
|
@ -457,22 +235,29 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
|
||||
-(void)pauseAndResumeDownload
|
||||
{
|
||||
if ( ! mDownloadIsPaused ) {
|
||||
//Do logic to pause download
|
||||
if ( !mDownloadIsPaused )
|
||||
{
|
||||
mDownloadIsPaused = YES;
|
||||
[pauseResumeToggleToolbarItem setLabel:@"Resume"];
|
||||
[pauseResumeToggleToolbarItem setPaletteLabel:@"Resume Download"];
|
||||
[pauseResumeToggleToolbarItem setToolTip:@"Resume the paused FTP download"];
|
||||
[pauseResumeToggleToolbarItem setImage:[NSImage imageNamed:@"saveResume"]];
|
||||
[self killDownloadTimer];
|
||||
} else {
|
||||
//Do logic to resume download
|
||||
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->PauseDownload();
|
||||
}
|
||||
else
|
||||
{
|
||||
mDownloadIsPaused = NO;
|
||||
[pauseResumeToggleToolbarItem setLabel:@"Pause"];
|
||||
[pauseResumeToggleToolbarItem setPaletteLabel:@"Pause Download"];
|
||||
[pauseResumeToggleToolbarItem setToolTip:@"Pause this FTP file download"];
|
||||
[pauseResumeToggleToolbarItem setImage:[NSImage imageNamed:@"savePause"]];
|
||||
[self setDownloadTimer];
|
||||
[self setupDownloadTimer];
|
||||
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->ResumeDownload();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,12 +316,6 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
NS_IF_RELEASE(mDownloadListener);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)killDownloadTimer
|
||||
{
|
||||
if (mDownloadTimer) {
|
||||
|
@ -545,7 +324,7 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
mDownloadTimer = nil;
|
||||
}
|
||||
}
|
||||
- (void)setDownloadTimer
|
||||
- (void)setupDownloadTimer
|
||||
{
|
||||
[self killDownloadTimer];
|
||||
mDownloadTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0
|
||||
|
@ -590,7 +369,7 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
return [[[NSString alloc] initWithString:[[NSBundle mainBundle] localizedStringForKey:@"UnderMin" value:@"Under a minute" table:@"ProgressDialog"]] autorelease];
|
||||
}
|
||||
// seconds becomes minutes and we keep checking.
|
||||
seconds=seconds/60;
|
||||
seconds = seconds/60;
|
||||
if (seconds < 60) {
|
||||
if (seconds < 2)
|
||||
return [[[NSString alloc] initWithString:[[NSBundle mainBundle] localizedStringForKey:@"AboutMin" value:@"About a minute" table:@"ProgressDialog"]] autorelease];
|
||||
|
@ -598,7 +377,7 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
return [[[NSString alloc] initWithFormat:[[NSBundle mainBundle] localizedStringForKey:@"AboutMins" value:@"About %d minutes" table:@"ProgressDialog"],seconds] autorelease];
|
||||
}
|
||||
//this download will never seemingly never end. now seconds become hours.
|
||||
seconds=seconds/60;
|
||||
seconds = seconds/60;
|
||||
if (seconds < 2)
|
||||
return [[[NSString alloc] initWithString:[[NSBundle mainBundle] localizedStringForKey:@"AboutHour" value:@"Over an hour" table:@"ProgressDialog"]] autorelease];
|
||||
return [[[NSString alloc] initWithFormat:[[NSBundle mainBundle] localizedStringForKey:@"AboutHours" value:@"Over %d hours" table:@"ProgressDialog"],seconds] autorelease];
|
||||
|
@ -629,8 +408,11 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
// this handles lots of things.
|
||||
- (void)setDownloadProgress:(NSTimer *)downloadTimer;
|
||||
{
|
||||
// XXX this logic needs cleaning up.
|
||||
|
||||
// Ack! we're closing the window with the download still running!
|
||||
if (mDownloadIsComplete) {
|
||||
if (mDownloadIsComplete)
|
||||
{
|
||||
[[self window] performClose:self];
|
||||
return;
|
||||
}
|
||||
|
@ -644,26 +426,28 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
[mElapsedTimeLabel setStringValue:[self formatTime:(++elapsedSec)]];
|
||||
// for status field & time left
|
||||
float maxBytes = ([mProgressBar maxValue]);
|
||||
float byteSec = aCurrentProgress/elapsedSec;
|
||||
float byteSec = mCurrentProgress/elapsedSec;
|
||||
// OK - if downloadTimer is nil, we're done - fix maxBytes value for status report.
|
||||
if (!downloadTimer)
|
||||
maxBytes = aCurrentProgress;
|
||||
maxBytes = mCurrentProgress;
|
||||
// update status field
|
||||
NSString *labelString = [[NSBundle mainBundle] localizedStringForKey:@"LabelString"
|
||||
value:@"%@ of %@ total (at %@/sec)"
|
||||
table:@"ProgressDialog"];
|
||||
[mStatusLabel setStringValue: [NSString stringWithFormat:labelString, [self formatBytes:aCurrentProgress], [self formatBytes:maxBytes], [self formatBytes:byteSec]]];
|
||||
[mStatusLabel setStringValue: [NSString stringWithFormat:labelString, [self formatBytes:mCurrentProgress], [self formatBytes:maxBytes], [self formatBytes:byteSec]]];
|
||||
// updating estimated time left field
|
||||
// if maxBytes < 0, can't calc time left.
|
||||
// if !downloadTimer, download is finished. either way, make sure time left is 0.
|
||||
if ((maxBytes > 0) && (downloadTimer)) {
|
||||
int secToGo = (int)ceil((elapsedSec*maxBytes/aCurrentProgress)-elapsedSec);
|
||||
if ((maxBytes > 0) && (downloadTimer))
|
||||
{
|
||||
int secToGo = (int)ceil((elapsedSec*maxBytes/mCurrentProgress) - elapsedSec);
|
||||
[mTimeLeftLabel setStringValue:[self formatFuzzyTime:secToGo]];
|
||||
}
|
||||
else if (!downloadTimer) { // download done. Set remaining time to 0, fix progress bar & cancel button
|
||||
else if (!downloadTimer)
|
||||
{ // download done. Set remaining time to 0, fix progress bar & cancel button
|
||||
mDownloadIsComplete = YES; // all done. we got a STATE_STOP
|
||||
[mTimeLeftLabel setStringValue:@""];
|
||||
[self setProgressBar:aCurrentProgress maxProg:aCurrentProgress];
|
||||
[self setProgressTo:mCurrentProgress ofMax:mCurrentProgress];
|
||||
if (!mSaveFileDialogShouldStayOpen)
|
||||
[[self window] performClose:self]; // close window
|
||||
else
|
||||
|
@ -673,4 +457,59 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
[mTimeLeftLabel setStringValue:@"???"];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// DownloadProgressDisplay protocol methods
|
||||
|
||||
- (void)onStartDownload
|
||||
{
|
||||
[self showWindow: self];
|
||||
[self setupDownloadTimer];
|
||||
}
|
||||
|
||||
- (void)onEndDownload
|
||||
{
|
||||
[self killDownloadTimer];
|
||||
[self setDownloadProgress:nil];
|
||||
}
|
||||
|
||||
- (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress
|
||||
{
|
||||
mCurrentProgress = aCurProgress; // fall back for stat calcs
|
||||
|
||||
if (![mProgressBar isIndeterminate]) //most likely - just update value
|
||||
{
|
||||
if (aCurProgress == aMaxProgress) //handles little bug in FTP download size
|
||||
[mProgressBar setMaxValue:aMaxProgress];
|
||||
|
||||
[mProgressBar setDoubleValue:aCurProgress];
|
||||
}
|
||||
else if (aMaxProgress > 0) // ok, we're starting up with good max & cur values
|
||||
{
|
||||
[mProgressBar setIndeterminate:NO];
|
||||
[mProgressBar setMaxValue:aMaxProgress];
|
||||
[mProgressBar setDoubleValue:aCurProgress];
|
||||
} // if neither case was true, it's barber pole city.
|
||||
}
|
||||
|
||||
-(void) setDownloadListener: (nsDownloader*)aDownloader
|
||||
{
|
||||
if (mDownloader != aDownloader)
|
||||
NS_IF_RELEASE(mDownloader);
|
||||
|
||||
NS_IF_ADDREF(mDownloader = aDownloader);
|
||||
}
|
||||
|
||||
- (void)setSourceURL:(NSString*)aSourceURL
|
||||
{
|
||||
[mFromField setStringValue: aSourceURL];
|
||||
[mFromField display]; // force an immmeditate update
|
||||
}
|
||||
|
||||
- (void)setDestinationPath:(NSString*)aDestPath
|
||||
{
|
||||
[mToField setStringValue: [aDestPath stringByAbbreviatingWithTildeInPath]];
|
||||
[mToField display]; // force an immmeditate update
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -55,7 +55,7 @@ class nsCocoaBrowserService : public nsIWindowCreator,
|
|||
public nsIPromptService,
|
||||
public nsIFactory,
|
||||
public nsIBadCertListener, public nsISecurityWarningDialogs, public nsINSSDialogs,
|
||||
public nsIHelperAppLauncherDialog, public nsIDownload, public nsIWebProgressListener
|
||||
public nsIHelperAppLauncherDialog
|
||||
{
|
||||
public:
|
||||
nsCocoaBrowserService();
|
||||
|
@ -69,8 +69,6 @@ public:
|
|||
NS_DECL_NSIBADCERTLISTENER
|
||||
NS_DECL_NSISECURITYWARNINGDIALOGS
|
||||
NS_DECL_NSIHELPERAPPLAUNCHERDIALOG
|
||||
NS_DECL_NSIDOWNLOAD
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
static nsresult InitEmbedding();
|
||||
static void TermEmbedding();
|
||||
|
|
|
@ -35,14 +35,15 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsCocoaBrowserService.h"
|
||||
#import "nsCocoaBrowserService.h"
|
||||
#import "DownloadFactories.h"
|
||||
#import "CHBrowserView.h"
|
||||
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIEmbeddingSiteWindow.h"
|
||||
#include "nsIProfile.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "CHBrowserView.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIPrompt.h"
|
||||
|
@ -74,13 +75,14 @@ nsCocoaBrowserService::~nsCocoaBrowserService()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS9(nsCocoaBrowserService,
|
||||
NS_IMPL_ISUPPORTS7(nsCocoaBrowserService,
|
||||
nsIWindowCreator,
|
||||
nsIPromptService,
|
||||
nsIFactory,
|
||||
nsIBadCertListener, nsISecurityWarningDialogs, nsINSSDialogs,
|
||||
nsIHelperAppLauncherDialog, nsIDownload, nsIWebProgressListener)
|
||||
nsIHelperAppLauncherDialog)
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsCocoaBrowserService::InitEmbedding()
|
||||
{
|
||||
|
@ -103,7 +105,7 @@ nsCocoaBrowserService::InitEmbedding()
|
|||
#define NS_PROMPTSERVICE_CID \
|
||||
{0xa2112d6a, 0x0e28, 0x421f, {0xb4, 0x6a, 0x25, 0xc0, 0xb3, 0x8, 0xcb, 0xd0}}
|
||||
static NS_DEFINE_CID(kPromptServiceCID, NS_PROMPTSERVICE_CID);
|
||||
nsresult rv = cr->RegisterFactory(kPromptServiceCID, "Prompt Service", "@mozilla.org/embedcomp/prompt-service;1",
|
||||
nsresult rv = cr->RegisterFactory(kPromptServiceCID, "Prompt Service", "@mozilla.org/embedcomp/prompt-service;1",
|
||||
sSingleton);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
@ -127,14 +129,18 @@ nsCocoaBrowserService::InitEmbedding()
|
|||
rv = cr->RegisterFactory(kHelperDlgCID, NS_IHELPERAPPLAUNCHERDLG_CLASSNAME, NS_IHELPERAPPLAUNCHERDLG_CONTRACTID,
|
||||
sSingleton);
|
||||
|
||||
// replace the downloader with our own which does rely on the xpfe downlaod manager
|
||||
// replace the downloader with our own which does not rely on the xpfe downlaod manager
|
||||
nsCOMPtr<nsIFactory> downloadFactory;
|
||||
rv = NewDownloadListenerFactory(getter_AddRefs(downloadFactory));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
static NS_DEFINE_CID(kDownloadCID, NS_DOWNLOAD_CID);
|
||||
rv = cr->RegisterFactory(kDownloadCID, "Download", NS_DOWNLOAD_CONTRACTID,
|
||||
sSingleton);
|
||||
rv = cr->RegisterFactory(kDownloadCID, "Download", NS_DOWNLOAD_CONTRACTID, downloadFactory);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsCocoaBrowserService::BrowserClosed()
|
||||
{
|
||||
|
@ -149,6 +155,7 @@ nsCocoaBrowserService::BrowserClosed()
|
|||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsCocoaBrowserService::TermEmbedding()
|
||||
{
|
||||
|
@ -195,8 +202,15 @@ nsCocoaBrowserService::CreateInstance(nsISupports *aOuter,
|
|||
const nsIID & aIID,
|
||||
void **aResult)
|
||||
{
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
/*
|
||||
if (aIID.Equals(NS_GET_IID(nsIHelperAppLauncherDialog)))
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
return sSingleton->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
|
@ -828,14 +842,12 @@ nsCocoaBrowserService::ConfirmPostToInsecureFromSecure(nsIInterfaceRequestor *ct
|
|||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::Show(nsIHelperAppLauncher* inLauncher, nsISupports* inContext)
|
||||
{
|
||||
NSLog(@"Show");
|
||||
return inLauncher->SaveToDisk(nsnull, PR_FALSE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::PromptForSaveToFile(nsISupports *aWindowContext, const PRUnichar *aDefaultFile, const PRUnichar *aSuggestedFileExtension, nsILocalFile **_retval)
|
||||
{
|
||||
NSLog(@"PromptForSaveToFile");
|
||||
NSString* filename = [NSString stringWithCharacters:aDefaultFile length:nsCRT::strlen(aDefaultFile)];
|
||||
NSSavePanel *thePanel = [NSSavePanel savePanel];
|
||||
|
||||
|
@ -844,7 +856,7 @@ NSLog(@"PromptForSaveToFile");
|
|||
// use nil for the path given to runModalForDirectory
|
||||
int runResult = [thePanel runModalForDirectory: nil file:filename];
|
||||
if (runResult == NSOKButton) {
|
||||
NSLog([thePanel filename]);
|
||||
// NSLog(@"Saving to %@", [thePanel filename]);
|
||||
NSString *theName = [thePanel filename];
|
||||
return NS_NewNativeLocalFile(nsDependentCString([theName fileSystemRepresentation]), PR_FALSE, _retval);
|
||||
}
|
||||
|
@ -856,140 +868,6 @@ NSLog([thePanel filename]);
|
|||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::ShowProgressDialog(nsIHelperAppLauncher *aLauncher, nsISupports *aContext)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::Init(nsIURI* aSource,
|
||||
nsILocalFile* aTarget,
|
||||
const PRUnichar* aDisplayName,
|
||||
const PRUnichar* aOpeningWith,
|
||||
PRInt64 aStartTime,
|
||||
nsIWebBrowserPersist* aPersist)
|
||||
{
|
||||
NSLog(@"nsIDownload::Init");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetDisplayName(PRUnichar** aDisplayName)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::SetDisplayName(const PRUnichar* aDisplayName)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetOpeningWith(PRUnichar** aOpeningWith)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetSource(nsIURI** aSource)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetTarget(nsILocalFile** aTarget)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetStartTime(PRInt64* aStartTime)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetPercentComplete(PRInt32* aPercentComplete)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetListener(nsIWebProgressListener** aListener)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::SetListener(nsIWebProgressListener* aListener)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetObserver(nsIObserver** aObserver)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::SetObserver(nsIObserver* aObserver)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetPersist(nsIWebBrowserPersist** aPersist)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnStateChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, nsIURI *aLocation)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnSecurityChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, PRUint32 aState)
|
||||
{
|
||||
NSLog(@"nsCocoaBrowserService::ShowProgressDialog");
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Appkit/Appkit.h>
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsIDownload.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsILocalFile.h"
|
||||
|
||||
|
||||
// maybe this should replace nsHeaderSniffer too?
|
||||
|
||||
class nsDownloadListener : public nsDownloader,
|
||||
public nsIDownload,
|
||||
public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsDownloadListener(DownloadControllerFactory* inDownloadControllerFactory);
|
||||
virtual ~nsDownloadListener();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOWNLOAD
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
public:
|
||||
//void BeginDownload();
|
||||
void InitDialog();
|
||||
|
||||
virtual void PauseDownload();
|
||||
virtual void ResumeDownload();
|
||||
virtual void CancelDownload();
|
||||
virtual void DownloadDone();
|
||||
|
||||
private:
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPersist> mWebPersist; // Our web persist object.
|
||||
nsCOMPtr<nsIURI> mURI; // The URI of our source file. Null if we're saving a complete document.
|
||||
nsCOMPtr<nsILocalFile> mDestination; // Our destination URL.
|
||||
PRInt64 mStartTime; // When the download started
|
||||
PRPackedBool mBypassCache; // Whether we should bypass the cache or not.
|
||||
PRPackedBool mNetworkTransfer; // true if the first OnStateChange has the NETWORK bit set
|
||||
PRPackedBool mGotFirstStateChange; // true after we've seen the first OnStateChange
|
||||
PRPackedBool mUserCanceled; // true if the user canceled the download
|
||||
};
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsDownloadListener.h"
|
||||
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIURL.h"
|
||||
#include "netCore.h"
|
||||
|
||||
nsDownloadListener::nsDownloadListener(DownloadControllerFactory* inControllerFactory)
|
||||
: nsDownloader(inControllerFactory)
|
||||
, mBypassCache(PR_FALSE)
|
||||
, mNetworkTransfer(PR_FALSE)
|
||||
, mGotFirstStateChange(PR_FALSE)
|
||||
, mUserCanceled(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
nsDownloadListener::~nsDownloadListener()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(nsDownloadListener, nsDownloader, nsIDownload, nsIWebProgressListener)
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in wstring openingWith, in long long startTime, in nsIWebBrowserPersist aPersist); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName,
|
||||
const PRUnichar *openingWith, PRInt64 startTime, nsIWebBrowserPersist *aPersist)
|
||||
{
|
||||
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()
|
||||
}
|
||||
|
||||
mDestination = aTarget;
|
||||
mURI = aSource;
|
||||
mStartTime = startTime;
|
||||
|
||||
InitDialog();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIURI source; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetSource(nsIURI * *aSource)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSource);
|
||||
NS_IF_ADDREF(*aSource = mURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsILocalFile target; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetTarget(nsILocalFile * *aTarget)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTarget);
|
||||
NS_IF_ADDREF(*aTarget = mDestination);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIWebBrowserPersist persist; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetPersist(nsIWebBrowserPersist * *aPersist)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPersist);
|
||||
NS_IF_ADDREF(*aPersist = mWebPersist);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute PRInt32 percentComplete; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetPercentComplete(PRInt32 *aPercentComplete)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute wstring displayName; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetDisplayName(PRUnichar * *aDisplayName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::SetDisplayName(const PRUnichar * aDisplayName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* readonly attribute long long startTime; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetStartTime(PRInt64 *aStartTime)
|
||||
{
|
||||
NS_ENSURE_ARG(aStartTime);
|
||||
*aStartTime = mStartTime;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute wstring openingWith; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetOpeningWith(PRUnichar * *aOpeningWith)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute nsIWebProgressListener listener; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetListener(nsIWebProgressListener * *aListener)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aListener);
|
||||
NS_IF_ADDREF(*aListener = (nsIWebProgressListener *)this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
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); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
if (mUserCanceled)
|
||||
{
|
||||
if (aRequest)
|
||||
aRequest->Cancel(NS_BINDING_ABORTED);
|
||||
|
||||
mUserCanceled = false;
|
||||
}
|
||||
|
||||
[mDownloadDisplay setProgressTo:aCurTotalProgress ofMax:aMaxTotalProgress];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
// NSLog(@"State changed: state %u, status %u", aStateFlags, aStatus);
|
||||
if (!mGotFirstStateChange) {
|
||||
mNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0);
|
||||
mGotFirstStateChange = PR_TRUE;
|
||||
}
|
||||
|
||||
// when the entire download finishes, stop the progress timer and clean up
|
||||
// the window and controller. We will get this even in the event of a cancel,
|
||||
// so this is the only place in the listener where we should kill the download.
|
||||
if ((aStateFlags & STATE_STOP) && (!mNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) {
|
||||
DownloadDone();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
void
|
||||
nsDownloadListener::InitDialog()
|
||||
{
|
||||
// dialog has to be shown before the outlets get hooked up
|
||||
[mDownloadDisplay onStartDownload];
|
||||
|
||||
if (mURI)
|
||||
{
|
||||
nsCAutoString spec;
|
||||
mURI->GetSpec(spec);
|
||||
[mDownloadDisplay setSourceURL: [NSString stringWithUTF8String:spec.get()]];
|
||||
}
|
||||
|
||||
nsAutoString pathStr;
|
||||
mDestination->GetPath(pathStr);
|
||||
[mDownloadDisplay setDestinationPath: [NSString stringWithCharacters:pathStr.get() length:pathStr.Length()]];
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::PauseDownload()
|
||||
{
|
||||
// write me
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::ResumeDownload()
|
||||
{
|
||||
// write me
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::CancelDownload()
|
||||
{
|
||||
mUserCanceled = PR_TRUE;
|
||||
|
||||
if (mWebPersist)
|
||||
{
|
||||
mWebPersist->CancelSave();
|
||||
mUserCanceled = PR_FALSE;
|
||||
}
|
||||
|
||||
// delete any files we've created...
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::DownloadDone()
|
||||
{
|
||||
// break the reference cycle by removing ourselves as a listener
|
||||
if (mWebPersist)
|
||||
{
|
||||
mWebPersist->SetProgressListener(nsnull);
|
||||
mWebPersist = nsnull;
|
||||
}
|
||||
|
||||
[mDownloadDisplay onEndDownload];
|
||||
}
|
||||
|
||||
#pragma mark -
|
|
@ -14,6 +14,7 @@
|
|||
F512F52B02D1287F01072C9F,
|
||||
F5A3669702CCFAF601DC3354,
|
||||
F512F52C02D1287F01072C9F,
|
||||
F50D9DE602ECC32301BB4219,
|
||||
F512F52D02D1287F01072C9F,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
|
@ -471,6 +472,10 @@
|
|||
F59236C202C89ACA0100012B,
|
||||
F5A3669802CCFAF601DC3354,
|
||||
F55C4DD402D2864E0130B065,
|
||||
F50D9DE402ECC2C601BB4219,
|
||||
F50D9DEF02EE0AB101BB4219,
|
||||
F50D9DF302EE194001BB4219,
|
||||
F50D9DF702EE2B9B01BB4219,
|
||||
);
|
||||
isa = PBXHeadersBuildPhase;
|
||||
name = Headers;
|
||||
|
@ -585,6 +590,10 @@
|
|||
F53E012D02AEE93701A967F3,
|
||||
F632AF8602B9AEBC01000103,
|
||||
F59236C302C89ACA0100012B,
|
||||
F50D9DE502ECC2C601BB4219,
|
||||
F50D9DF002EE0AB101BB4219,
|
||||
F50D9DF402EE194001BB4219,
|
||||
F50D9DF802EE2B9B01BB4219,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
name = Sources;
|
||||
|
@ -840,6 +849,145 @@
|
|||
name = Graphics;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE202ECC2C601BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = nsDownloadListener.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE302ECC2C601BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = nsDownloadListener.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE402ECC2C601BB4219 = {
|
||||
fileRef = F50D9DE202ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE502ECC2C601BB4219 = {
|
||||
fileRef = F50D9DE302ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE602ECC32301BB4219 = {
|
||||
children = (
|
||||
F50D9DF902EE2C1D01BB4219,
|
||||
F50D9DFA02EE2C1D01BB4219,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Downloading;
|
||||
path = "";
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DE702ECC36201BB4219 = {
|
||||
fileRef = F50D9DE202ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE802ECC36201BB4219 = {
|
||||
fileRef = F632AF8302B9AEBB01000103;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DE902ECC36201BB4219 = {
|
||||
fileRef = F50D9DE302ECC2C601BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DED02EE0AB101BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadProgressDisplay.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DEE02EE0AB101BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadProgressDisplay.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DEF02EE0AB101BB4219 = {
|
||||
fileRef = F50D9DED02EE0AB101BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF002EE0AB101BB4219 = {
|
||||
fileRef = F50D9DEE02EE0AB101BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF102EE194001BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadFactories.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF202EE194001BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = DownloadFactories.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF302EE194001BB4219 = {
|
||||
fileRef = F50D9DF102EE194001BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF402EE194001BB4219 = {
|
||||
fileRef = F50D9DF202EE194001BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF502EE2B9A01BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = SaveHeaderSniffer.h;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF602EE2B9A01BB4219 = {
|
||||
isa = PBXFileReference;
|
||||
path = SaveHeaderSniffer.mm;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DF702EE2B9B01BB4219 = {
|
||||
fileRef = F50D9DF502EE2B9A01BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF802EE2B9B01BB4219 = {
|
||||
fileRef = F50D9DF602EE2B9A01BB4219;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F50D9DF902EE2C1D01BB4219 = {
|
||||
children = (
|
||||
F50D9DF102EE194001BB4219,
|
||||
F50D9DF202EE194001BB4219,
|
||||
F50D9DED02EE0AB101BB4219,
|
||||
F50D9DEE02EE0AB101BB4219,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Generic;
|
||||
refType = 4;
|
||||
};
|
||||
F50D9DFA02EE2C1D01BB4219 = {
|
||||
children = (
|
||||
F50D9DF502EE2B9A01BB4219,
|
||||
F50D9DF602EE2B9A01BB4219,
|
||||
F517395B020CE3740189DA0C,
|
||||
F50D9DE302ECC2C601BB4219,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Chimera;
|
||||
path = "";
|
||||
refType = 4;
|
||||
};
|
||||
F50DCB4302C2856001A967F3 = {
|
||||
isa = PBXFileReference;
|
||||
name = libjsj.dylib;
|
||||
|
@ -1143,7 +1291,6 @@
|
|||
F512F52B02D1287F01072C9F = {
|
||||
children = (
|
||||
F5DE10E90209DC0601A967DF,
|
||||
F517395B020CE3740189DA0C,
|
||||
F528E21A020FD9620168DE43,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
|
@ -1176,7 +1323,6 @@
|
|||
};
|
||||
F512F53302D17A2601072C9F = {
|
||||
children = (
|
||||
F55C4DD302D2864D0130B065,
|
||||
29B97316FDCFA39411CA2CEA,
|
||||
F59236C002C89AC90100012B,
|
||||
F5AE04BA0206A4FE01A967DF,
|
||||
|
@ -1330,6 +1476,7 @@
|
|||
F507BA480213AD5F01D93544,
|
||||
F57074B5026BA85F01A80166,
|
||||
F57074B9026BFD0101A80166,
|
||||
2EEC3E61028138714B000102,
|
||||
F57074BD026D80DF01A80166,
|
||||
2E293A00027F33604B000102,
|
||||
F5607CB5023944AD01A967DF,
|
||||
|
@ -1344,6 +1491,8 @@
|
|||
F53E013202AEEA2801A967F3,
|
||||
F5A3669302CCFAF601DC3354,
|
||||
F59236C102C89AC90100012B,
|
||||
F50D9DE202ECC2C601BB4219,
|
||||
F55C4DD302D2864D0130B065,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Headers;
|
||||
|
@ -4375,7 +4524,6 @@
|
|||
F57074B6026BA85F01A80166,
|
||||
F57074BA026BFD0101A80166,
|
||||
F53E012C02AEE93601A967F3,
|
||||
2EEC3E61028138714B000102,
|
||||
2EEC3E62028138714B000102,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
|
@ -4959,6 +5107,8 @@
|
|||
F53E013402AEEA2901A967F3,
|
||||
F59236C402C89ACA0100012B,
|
||||
F5A3669A02CCFB7A01DC3354,
|
||||
F50D9DE702ECC36201BB4219,
|
||||
F50D9DE802ECC36201BB4219,
|
||||
);
|
||||
isa = PBXHeadersBuildPhase;
|
||||
name = Headers;
|
||||
|
@ -5074,6 +5224,7 @@
|
|||
F59236C502C89ACA0100012B,
|
||||
F5A3669B02CCFB7A01DC3354,
|
||||
F5A3669C02CCFB7A01DC3354,
|
||||
F50D9DE902ECC36201BB4219,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
name = Sources;
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>73 360 356 240 0 0 1152 848 </string>
|
||||
<string>61 108 356 240 0 0 1152 746 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>266</key>
|
||||
<string>418 452 277 90 0 0 1152 746 </string>
|
||||
<string>23 342 277 90 0 0 1152 746 </string>
|
||||
<key>29</key>
|
||||
<string>8 803 446 44 0 0 1152 848 </string>
|
||||
<string>8 701 446 44 0 0 1152 746 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
|
|
Двоичный файл не отображается.
|
@ -5,12 +5,12 @@
|
|||
CLASS = ProgressDlgController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mElapsedTimeLabel = id;
|
||||
mFromField = id;
|
||||
mProgressBar = id;
|
||||
mStatusLabel = id;
|
||||
mTimeLeftLabel = id;
|
||||
mToField = id;
|
||||
mElapsedTimeLabel = NSTextField;
|
||||
mFromField = NSTextField;
|
||||
mProgressBar = NSProgressIndicator;
|
||||
mStatusLabel = NSTextField;
|
||||
mTimeLeftLabel = NSTextField;
|
||||
mToField = NSTextField;
|
||||
};
|
||||
SUPERCLASS = NSWindowController;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>152 212 356 240 0 0 1024 746 </string>
|
||||
<string>94 26 404 250 0 0 1152 746 </string>
|
||||
<key>IBFramework Version</key>
|
||||
<string>248.0</string>
|
||||
<key>IBOpenObjects</key>
|
||||
|
@ -11,6 +11,6 @@
|
|||
<integer>5</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>5Q125</string>
|
||||
<string>5S66</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
Двоичные данные
chimera/resources/localized/English.lproj/ProgressDialog.nib/objects.nib
сгенерированный
Двоичные данные
chimera/resources/localized/English.lproj/ProgressDialog.nib/objects.nib
сгенерированный
Двоичный файл не отображается.
|
@ -36,6 +36,9 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
class nsIWebBrowserPersist;
|
||||
|
@ -43,42 +46,37 @@ class nsISupports;
|
|||
class nsIInputStream;
|
||||
class nsDownloadListener;
|
||||
|
||||
@interface ProgressDlgController : NSWindowController {
|
||||
IBOutlet id mFromField;
|
||||
IBOutlet id mToField;
|
||||
IBOutlet id mStatusLabel;
|
||||
IBOutlet id mTimeLeftLabel;
|
||||
IBOutlet id mElapsedTimeLabel;
|
||||
IBOutlet id mProgressBar;
|
||||
|
||||
@interface ChimeraDownloadControllerFactory : DownloadControllerFactory
|
||||
@end
|
||||
|
||||
|
||||
@interface ProgressDlgController : NSWindowController <DownloadProgressDisplay>
|
||||
{
|
||||
IBOutlet NSTextField *mElapsedTimeLabel;
|
||||
IBOutlet NSTextField *mFromField;
|
||||
IBOutlet NSTextField *mStatusLabel;
|
||||
IBOutlet NSTextField *mTimeLeftLabel;
|
||||
IBOutlet NSTextField *mToField;
|
||||
IBOutlet NSProgressIndicator *mProgressBar;
|
||||
|
||||
NSToolbarItem *pauseResumeToggleToolbarItem;
|
||||
NSToolbarItem *leaveOpenToggleToolbarItem;
|
||||
|
||||
BOOL mDownloadIsPaused;
|
||||
BOOL mSaveFileDialogShouldStayOpen;
|
||||
BOOL mDownloadIsComplete;
|
||||
long int aCurrentProgress; // if progress bar is indeterminate, can still calc stats.
|
||||
BOOL mDownloadIsPaused;
|
||||
BOOL mSaveFileDialogShouldStayOpen;
|
||||
BOOL mDownloadIsComplete;
|
||||
long mCurrentProgress; // if progress bar is indeterminate, can still calc stats.
|
||||
|
||||
nsDownloadListener* mDownloadListener;
|
||||
NSTimer *mDownloadTimer;
|
||||
nsDownloader *mDownloader; // we hold a ref to this
|
||||
NSTimer *mDownloadTimer;
|
||||
}
|
||||
|
||||
-(void) setWebPersist: (nsIWebBrowserPersist*)aPersist
|
||||
source: (nsISupports*)aSource
|
||||
destination: (NSString*)aDestination
|
||||
contentType: (const char*)aContentType
|
||||
postData: (nsIInputStream*)aInputStream
|
||||
bypassCache: (BOOL)aBypassCache;
|
||||
|
||||
-(void) setProgressBar:(long int)aCurProgress
|
||||
maxProg:(long int)aMaxProgress;
|
||||
-(void) setDownloadTimer;
|
||||
-(void) setupDownloadTimer;
|
||||
-(void) killDownloadTimer;
|
||||
-(void) setDownloadProgress:(NSTimer *)aTimer;
|
||||
-(NSString *) formatTime:(int)aSeconds;
|
||||
-(NSString *) formatFuzzyTime:(int)aSeconds;
|
||||
-(NSString *) formatBytes:(float)aBytes;
|
||||
-(void) setSourceURL: (const PRUnichar*)aSource;
|
||||
-(void) setDestination: (const PRUnichar*)aDestination;
|
||||
|
||||
@end
|
||||
|
|
|
@ -46,282 +46,58 @@
|
|||
#include "nsILocalFile.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIDownload.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
|
||||
class nsDownloadListener : public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsDownloadListener(ProgressDlgController* aController,
|
||||
nsIWebBrowserPersist* aPersist,
|
||||
nsISupports* aSource,
|
||||
NSString* aDestination,
|
||||
const char* aContentType,
|
||||
nsIInputStream* aPostData,
|
||||
BOOL aBypassCache)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mController = aController;
|
||||
mWebPersist = aPersist;
|
||||
// The source is either a simple URL or a complete document.
|
||||
mURL = do_QueryInterface(aSource);
|
||||
if (!mURL)
|
||||
mDocument = do_QueryInterface(aSource);
|
||||
|
||||
PRUint32 dstLen = [aDestination length];
|
||||
PRUnichar* tmp = new PRUnichar[dstLen + sizeof(PRUnichar)];
|
||||
tmp[dstLen] = (PRUnichar)'\0';
|
||||
[aDestination getCharacters:tmp];
|
||||
nsAutoString dstStr(tmp);
|
||||
delete tmp;
|
||||
|
||||
NS_NewLocalFile(dstStr, PR_FALSE, getter_AddRefs(mDestination));
|
||||
// XXX check for failure
|
||||
|
||||
mContentType = aContentType;
|
||||
mPostData = aPostData;
|
||||
mBypassCache = aBypassCache;
|
||||
mNetworkTransfer = PR_FALSE;
|
||||
mGotFirstStateChange = PR_FALSE;
|
||||
};
|
||||
|
||||
virtual ~nsDownloadListener() {};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
public:
|
||||
void BeginDownload();
|
||||
void InitDialog();
|
||||
void CancelDownload();
|
||||
|
||||
private: // Member variables
|
||||
ProgressDlgController* mController; // Controller for our UI.
|
||||
nsCOMPtr<nsIWebBrowserPersist> mWebPersist; // Our web persist object.
|
||||
nsCOMPtr<nsIURL> mURL; // The URL of our source file. Null if we're saving a complete document.
|
||||
nsCOMPtr<nsILocalFile> mDestination; // Our destination URL.
|
||||
nsCString mContentType; // Our content type string.
|
||||
nsCOMPtr<nsIDOMHTMLDocument> mDocument; // A DOM document. Null if we're only saving a simple URL.
|
||||
nsCOMPtr<nsIInputStream> mPostData; // For complete documents, this is our post data from session history.
|
||||
PRPackedBool mBypassCache; // Whether we should bypass the cache or not.
|
||||
PRPackedBool mNetworkTransfer; // true if the first OnStateChange has the NETWORK bit set
|
||||
PRPackedBool mGotFirstStateChange; // true after we've seen the first OnStateChange
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDownloadListener, nsIWebProgressListener)
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
[mController setProgressBar:aCurTotalProgress maxProg:aMaxTotalProgress];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
// NSLog(@"State changed: state %u, status %u", aStateFlags, aStatus);
|
||||
if (!mGotFirstStateChange) {
|
||||
mNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0);
|
||||
mGotFirstStateChange = PR_TRUE;
|
||||
}
|
||||
|
||||
// when the entire download finishes, stop the progress timer and clean up
|
||||
// the window and controller. We will get this even in the event of a cancel,
|
||||
// so this is the only place in the listener where we should kill the download.
|
||||
if ((aStateFlags & STATE_STOP) && (!mNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) {
|
||||
[mController killDownloadTimer];
|
||||
[mController setDownloadProgress:nil];
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::BeginDownload()
|
||||
{
|
||||
if (mWebPersist) {
|
||||
mWebPersist->SetProgressListener(this);
|
||||
PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION |
|
||||
nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
|
||||
if (mBypassCache)
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE;
|
||||
else
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
|
||||
|
||||
if (mURL)
|
||||
mWebPersist->SaveURI(mURL, mPostData, mDestination);
|
||||
else {
|
||||
PRInt32 encodingFlags = 0;
|
||||
nsCOMPtr<nsILocalFile> filesFolder;
|
||||
|
||||
if (!mContentType.Equals("text/plain")) {
|
||||
// Create a local directory in the same dir as our file. It
|
||||
// will hold our associated files.
|
||||
filesFolder = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
nsAutoString unicodePath;
|
||||
mDestination->GetPath(unicodePath);
|
||||
filesFolder->InitWithPath(unicodePath);
|
||||
|
||||
nsAutoString leafName;
|
||||
filesFolder->GetLeafName(leafName);
|
||||
nsAutoString nameMinusExt(leafName);
|
||||
PRInt32 index = nameMinusExt.RFind(".");
|
||||
if (index >= 0)
|
||||
nameMinusExt.Left(nameMinusExt, index);
|
||||
nameMinusExt += NS_LITERAL_STRING(" Files"); // XXXdwh needs to be localizable!
|
||||
filesFolder->SetLeafName(nameMinusExt);
|
||||
PRBool exists = PR_FALSE;
|
||||
filesFolder->Exists(&exists);
|
||||
if (!exists)
|
||||
filesFolder->Create(nsILocalFile::DIRECTORY_TYPE, 0755);
|
||||
}
|
||||
else
|
||||
encodingFlags |= nsIWebBrowserPersist::ENCODE_FLAGS_FORMATTED |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_ABSOLUTE_LINKS |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_NOFRAMES_CONTENT;
|
||||
|
||||
mWebPersist->SaveDocument(mDocument, mDestination, filesFolder, mContentType.get(),
|
||||
encodingFlags, 80);
|
||||
}
|
||||
}
|
||||
|
||||
InitDialog();
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::InitDialog()
|
||||
{
|
||||
if (!mURL && !mDocument)
|
||||
return;
|
||||
|
||||
if (mWebPersist) {
|
||||
if (mURL) {
|
||||
nsCAutoString spec;
|
||||
mURL->GetSpec(spec);
|
||||
nsAutoString spec2; spec2.AssignWithConversion(spec.get());
|
||||
[mController setSourceURL: spec2.get()];
|
||||
}
|
||||
else {
|
||||
nsAutoString spec;
|
||||
mDocument->GetURL(spec);
|
||||
[mController setSourceURL: spec.get()];
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString pathStr;
|
||||
mDestination->GetPath(pathStr);
|
||||
[mController setDestination: pathStr.get()];
|
||||
[mController setDownloadTimer];
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::CancelDownload()
|
||||
{
|
||||
if (mWebPersist)
|
||||
mWebPersist->CancelSave();
|
||||
}
|
||||
|
||||
|
||||
static NSString *SaveFileToolbarIdentifier = @"Save File Dialog Toolbar";
|
||||
static NSString *CancelToolbarItemIdentifier = @"Cancel Toolbar Item";
|
||||
static NSString *SaveFileToolbarIdentifier = @"Save File Dialog Toolbar";
|
||||
static NSString *CancelToolbarItemIdentifier = @"Cancel Toolbar Item";
|
||||
static NSString *PauseResumeToolbarItemIdentifier = @"Pause and Resume Toggle Toolbar Item";
|
||||
static NSString *ShowFileToolbarItemIdentifier = @"Show File Toolbar Item";
|
||||
static NSString *OpenFileToolbarItemIdentifier = @"Open File Toolbar Item";
|
||||
static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar Item";
|
||||
|
||||
|
||||
@implementation ChimeraDownloadControllerFactory : DownloadControllerFactory
|
||||
|
||||
- (NSWindowController<DownloadProgressDisplay> *)createDownloadController
|
||||
{
|
||||
NSWindowController* progressController = [[ProgressDlgController alloc] initWithWindowNibName: @"ProgressDialog"];
|
||||
NSAssert([progressController conformsToProtocol:@protocol(DownloadProgressDisplay)],
|
||||
@"progressController should conform to DownloadProgressDisplay protocol");
|
||||
return progressController;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
@interface ProgressDlgController(Private)
|
||||
-(void)setupToolbar;
|
||||
@end
|
||||
|
||||
@implementation ProgressDlgController
|
||||
|
||||
-(void)setWebPersist:(nsIWebBrowserPersist*)aPersist
|
||||
source:(nsISupports*)aSource
|
||||
destination:(NSString*)aDestination
|
||||
contentType:(const char*)aContentType
|
||||
postData:(nsIInputStream*)aInputStream
|
||||
bypassCache:(BOOL)aBypassCache
|
||||
- (void)dealloc
|
||||
{
|
||||
mDownloadListener = new nsDownloadListener(self, aPersist, aSource,
|
||||
aDestination, aContentType,
|
||||
aInputStream, aBypassCache);
|
||||
NS_ADDREF(mDownloadListener);
|
||||
}
|
||||
|
||||
-(void) setProgressBar:(long int)curProgress maxProg:(long int)maxProgress
|
||||
{
|
||||
aCurrentProgress = curProgress; // fall back for stat calcs
|
||||
if (![mProgressBar isIndeterminate]) { //most likely - just update value
|
||||
if (curProgress == maxProgress) //handles little bug in FTP download size
|
||||
[mProgressBar setMaxValue:maxProgress];
|
||||
[mProgressBar setDoubleValue:curProgress];
|
||||
}
|
||||
else if (maxProgress > 0) { // ok, we're starting up with good max & cur values
|
||||
[mProgressBar setIndeterminate:NO];
|
||||
[mProgressBar setMaxValue:maxProgress];
|
||||
[mProgressBar setDoubleValue:curProgress];
|
||||
} // if neither case was true, it's barber pole city.
|
||||
}
|
||||
|
||||
-(void) setSourceURL: (const PRUnichar*)aSource
|
||||
{
|
||||
[mFromField setStringValue: [NSString stringWithCharacters:aSource length:nsCRT::strlen(aSource)]];
|
||||
}
|
||||
|
||||
-(void) setDestination: (const PRUnichar*)aDestination
|
||||
{
|
||||
[mToField setStringValue: [[NSString stringWithCharacters:aDestination length:nsCRT::strlen(aDestination)] stringByAbbreviatingWithTildeInPath]];
|
||||
NS_IF_RELEASE(mDownloader);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)windowDidLoad
|
||||
{
|
||||
mDownloadIsPaused = NO;
|
||||
mDownloadIsComplete = NO;
|
||||
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID));
|
||||
PRBool save = PR_FALSE;
|
||||
prefs->GetBoolPref("browser.download.progressDnldDialog.keepAlive",&save);
|
||||
prefs->GetBoolPref("browser.download.progressDnldDialog.keepAlive", &save);
|
||||
mSaveFileDialogShouldStayOpen = save;
|
||||
|
||||
[self setupToolbar];
|
||||
[mProgressBar setUsesThreadedAnimation:YES];
|
||||
[mProgressBar startAnimation:self];
|
||||
if (mDownloadListener)
|
||||
mDownloadListener->BeginDownload();
|
||||
[mProgressBar startAnimation:self]; // move to onStateChange
|
||||
}
|
||||
|
||||
- (void)setupToolbar
|
||||
|
@ -438,7 +214,9 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
|
||||
-(void)cancel
|
||||
{
|
||||
mDownloadListener->CancelDownload();
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->CancelDownload();
|
||||
|
||||
// clean up downloaded file. - do it here on in CancelDownload?
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSString *thePath = [[mToField stringValue] stringByExpandingTildeInPath];
|
||||
|
@ -457,22 +235,29 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
|
||||
-(void)pauseAndResumeDownload
|
||||
{
|
||||
if ( ! mDownloadIsPaused ) {
|
||||
//Do logic to pause download
|
||||
if ( !mDownloadIsPaused )
|
||||
{
|
||||
mDownloadIsPaused = YES;
|
||||
[pauseResumeToggleToolbarItem setLabel:@"Resume"];
|
||||
[pauseResumeToggleToolbarItem setPaletteLabel:@"Resume Download"];
|
||||
[pauseResumeToggleToolbarItem setToolTip:@"Resume the paused FTP download"];
|
||||
[pauseResumeToggleToolbarItem setImage:[NSImage imageNamed:@"saveResume"]];
|
||||
[self killDownloadTimer];
|
||||
} else {
|
||||
//Do logic to resume download
|
||||
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->PauseDownload();
|
||||
}
|
||||
else
|
||||
{
|
||||
mDownloadIsPaused = NO;
|
||||
[pauseResumeToggleToolbarItem setLabel:@"Pause"];
|
||||
[pauseResumeToggleToolbarItem setPaletteLabel:@"Pause Download"];
|
||||
[pauseResumeToggleToolbarItem setToolTip:@"Pause this FTP file download"];
|
||||
[pauseResumeToggleToolbarItem setImage:[NSImage imageNamed:@"savePause"]];
|
||||
[self setDownloadTimer];
|
||||
[self setupDownloadTimer];
|
||||
|
||||
if (mDownloader) // we should always have one
|
||||
mDownloader->ResumeDownload();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,12 +316,6 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
NS_IF_RELEASE(mDownloadListener);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)killDownloadTimer
|
||||
{
|
||||
if (mDownloadTimer) {
|
||||
|
@ -545,7 +324,7 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
mDownloadTimer = nil;
|
||||
}
|
||||
}
|
||||
- (void)setDownloadTimer
|
||||
- (void)setupDownloadTimer
|
||||
{
|
||||
[self killDownloadTimer];
|
||||
mDownloadTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0
|
||||
|
@ -590,7 +369,7 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
return [[[NSString alloc] initWithString:[[NSBundle mainBundle] localizedStringForKey:@"UnderMin" value:@"Under a minute" table:@"ProgressDialog"]] autorelease];
|
||||
}
|
||||
// seconds becomes minutes and we keep checking.
|
||||
seconds=seconds/60;
|
||||
seconds = seconds/60;
|
||||
if (seconds < 60) {
|
||||
if (seconds < 2)
|
||||
return [[[NSString alloc] initWithString:[[NSBundle mainBundle] localizedStringForKey:@"AboutMin" value:@"About a minute" table:@"ProgressDialog"]] autorelease];
|
||||
|
@ -598,7 +377,7 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
return [[[NSString alloc] initWithFormat:[[NSBundle mainBundle] localizedStringForKey:@"AboutMins" value:@"About %d minutes" table:@"ProgressDialog"],seconds] autorelease];
|
||||
}
|
||||
//this download will never seemingly never end. now seconds become hours.
|
||||
seconds=seconds/60;
|
||||
seconds = seconds/60;
|
||||
if (seconds < 2)
|
||||
return [[[NSString alloc] initWithString:[[NSBundle mainBundle] localizedStringForKey:@"AboutHour" value:@"Over an hour" table:@"ProgressDialog"]] autorelease];
|
||||
return [[[NSString alloc] initWithFormat:[[NSBundle mainBundle] localizedStringForKey:@"AboutHours" value:@"Over %d hours" table:@"ProgressDialog"],seconds] autorelease];
|
||||
|
@ -629,8 +408,11 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
// this handles lots of things.
|
||||
- (void)setDownloadProgress:(NSTimer *)downloadTimer;
|
||||
{
|
||||
// XXX this logic needs cleaning up.
|
||||
|
||||
// Ack! we're closing the window with the download still running!
|
||||
if (mDownloadIsComplete) {
|
||||
if (mDownloadIsComplete)
|
||||
{
|
||||
[[self window] performClose:self];
|
||||
return;
|
||||
}
|
||||
|
@ -644,26 +426,28 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
[mElapsedTimeLabel setStringValue:[self formatTime:(++elapsedSec)]];
|
||||
// for status field & time left
|
||||
float maxBytes = ([mProgressBar maxValue]);
|
||||
float byteSec = aCurrentProgress/elapsedSec;
|
||||
float byteSec = mCurrentProgress/elapsedSec;
|
||||
// OK - if downloadTimer is nil, we're done - fix maxBytes value for status report.
|
||||
if (!downloadTimer)
|
||||
maxBytes = aCurrentProgress;
|
||||
maxBytes = mCurrentProgress;
|
||||
// update status field
|
||||
NSString *labelString = [[NSBundle mainBundle] localizedStringForKey:@"LabelString"
|
||||
value:@"%@ of %@ total (at %@/sec)"
|
||||
table:@"ProgressDialog"];
|
||||
[mStatusLabel setStringValue: [NSString stringWithFormat:labelString, [self formatBytes:aCurrentProgress], [self formatBytes:maxBytes], [self formatBytes:byteSec]]];
|
||||
[mStatusLabel setStringValue: [NSString stringWithFormat:labelString, [self formatBytes:mCurrentProgress], [self formatBytes:maxBytes], [self formatBytes:byteSec]]];
|
||||
// updating estimated time left field
|
||||
// if maxBytes < 0, can't calc time left.
|
||||
// if !downloadTimer, download is finished. either way, make sure time left is 0.
|
||||
if ((maxBytes > 0) && (downloadTimer)) {
|
||||
int secToGo = (int)ceil((elapsedSec*maxBytes/aCurrentProgress)-elapsedSec);
|
||||
if ((maxBytes > 0) && (downloadTimer))
|
||||
{
|
||||
int secToGo = (int)ceil((elapsedSec*maxBytes/mCurrentProgress) - elapsedSec);
|
||||
[mTimeLeftLabel setStringValue:[self formatFuzzyTime:secToGo]];
|
||||
}
|
||||
else if (!downloadTimer) { // download done. Set remaining time to 0, fix progress bar & cancel button
|
||||
else if (!downloadTimer)
|
||||
{ // download done. Set remaining time to 0, fix progress bar & cancel button
|
||||
mDownloadIsComplete = YES; // all done. we got a STATE_STOP
|
||||
[mTimeLeftLabel setStringValue:@""];
|
||||
[self setProgressBar:aCurrentProgress maxProg:aCurrentProgress];
|
||||
[self setProgressTo:mCurrentProgress ofMax:mCurrentProgress];
|
||||
if (!mSaveFileDialogShouldStayOpen)
|
||||
[[self window] performClose:self]; // close window
|
||||
else
|
||||
|
@ -673,4 +457,59 @@ static NSString *LeaveOpenToolbarItemIdentifier = @"Leave Open Toggle Toolbar
|
|||
[mTimeLeftLabel setStringValue:@"???"];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// DownloadProgressDisplay protocol methods
|
||||
|
||||
- (void)onStartDownload
|
||||
{
|
||||
[self showWindow: self];
|
||||
[self setupDownloadTimer];
|
||||
}
|
||||
|
||||
- (void)onEndDownload
|
||||
{
|
||||
[self killDownloadTimer];
|
||||
[self setDownloadProgress:nil];
|
||||
}
|
||||
|
||||
- (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress
|
||||
{
|
||||
mCurrentProgress = aCurProgress; // fall back for stat calcs
|
||||
|
||||
if (![mProgressBar isIndeterminate]) //most likely - just update value
|
||||
{
|
||||
if (aCurProgress == aMaxProgress) //handles little bug in FTP download size
|
||||
[mProgressBar setMaxValue:aMaxProgress];
|
||||
|
||||
[mProgressBar setDoubleValue:aCurProgress];
|
||||
}
|
||||
else if (aMaxProgress > 0) // ok, we're starting up with good max & cur values
|
||||
{
|
||||
[mProgressBar setIndeterminate:NO];
|
||||
[mProgressBar setMaxValue:aMaxProgress];
|
||||
[mProgressBar setDoubleValue:aCurProgress];
|
||||
} // if neither case was true, it's barber pole city.
|
||||
}
|
||||
|
||||
-(void) setDownloadListener: (nsDownloader*)aDownloader
|
||||
{
|
||||
if (mDownloader != aDownloader)
|
||||
NS_IF_RELEASE(mDownloader);
|
||||
|
||||
NS_IF_ADDREF(mDownloader = aDownloader);
|
||||
}
|
||||
|
||||
- (void)setSourceURL:(NSString*)aSourceURL
|
||||
{
|
||||
[mFromField setStringValue: aSourceURL];
|
||||
[mFromField display]; // force an immmeditate update
|
||||
}
|
||||
|
||||
- (void)setDestinationPath:(NSString*)aDestPath
|
||||
{
|
||||
[mToField setStringValue: [aDestPath stringByAbbreviatingWithTildeInPath]];
|
||||
[mToField display]; // force an immmeditate update
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* David Hyatt <hyatt@netscape.com>
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Appkit/Appkit.h>
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
|
||||
|
||||
// Implementation of a header sniffer class that is used when saving Web pages and images.
|
||||
class nsHeaderSniffer : public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
|
||||
nsIDOMDocument* aDocument, nsIInputStream* aPostData,
|
||||
const nsCString& aSuggestedFilename, PRBool aBypassCache,
|
||||
NSView* aFilterView, NSPopUpButton* aFilterList);
|
||||
virtual ~nsHeaderSniffer();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
protected:
|
||||
|
||||
nsresult PerformSave(nsIURI* inOriginalURI);
|
||||
nsresult InitiateDownload(nsISupports* inSourceData, nsString& inFileName, nsIURI* inOriginalURI);
|
||||
|
||||
private:
|
||||
|
||||
nsIWebBrowserPersist* mPersist; // Weak. It owns us as a listener.
|
||||
nsCOMPtr<nsIFile> mTmpFile;
|
||||
nsCOMPtr<nsIURI> mURL;
|
||||
nsCOMPtr<nsIDOMDocument> mDocument;
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
nsCString mDefaultFilename;
|
||||
PRBool mBypassCache;
|
||||
nsCString mContentType;
|
||||
nsCString mContentDisposition;
|
||||
NSView* mFilterView;
|
||||
NSPopUpButton* mFilterList;
|
||||
};
|
||||
|
|
@ -0,0 +1,386 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* David Hyatt <hyatt@netscape.com>
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "SaveHeaderSniffer.h"
|
||||
|
||||
#include "netCore.h"
|
||||
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsIMIMEInfo.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDownload.h"
|
||||
|
||||
const char* const persistContractID = "@mozilla.org/embedding/browser/nsWebBrowserPersist;1";
|
||||
|
||||
nsHeaderSniffer::nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
|
||||
nsIDOMDocument* aDocument, nsIInputStream* aPostData,
|
||||
const nsCString& aSuggestedFilename, PRBool aBypassCache,
|
||||
NSView* aFilterView, NSPopUpButton* aFilterList)
|
||||
: mPersist(aPersist)
|
||||
, mTmpFile(aFile)
|
||||
, mURL(aURL)
|
||||
, mDocument(aDocument)
|
||||
, mPostData(aPostData)
|
||||
, mDefaultFilename(aSuggestedFilename)
|
||||
, mBypassCache(aBypassCache)
|
||||
, mFilterView(aFilterView)
|
||||
, mFilterList(aFilterList)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsHeaderSniffer::~nsHeaderSniffer()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsHeaderSniffer, nsIWebProgressListener)
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
if (aStateFlags & nsIWebProgressListener::STATE_START)
|
||||
{
|
||||
nsCOMPtr<nsIWebBrowserPersist> kungFuDeathGrip(mPersist); // be sure to keep it alive while we save
|
||||
// since it owns us as a listener
|
||||
nsCOMPtr<nsIWebProgressListener> kungFuSuicideGrip(this); // and keep ourslves alive
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest, &rv);
|
||||
if (!channel) return rv;
|
||||
channel->GetContentType(mContentType);
|
||||
|
||||
nsCOMPtr<nsIURI> origURI;
|
||||
channel->GetOriginalURI(getter_AddRefs(origURI));
|
||||
|
||||
// Get the content-disposition if we're an HTTP channel.
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if (httpChannel)
|
||||
httpChannel->GetResponseHeader(nsCAutoString("content-disposition"), mContentDisposition);
|
||||
|
||||
mPersist->CancelSave();
|
||||
PRBool exists;
|
||||
mTmpFile->Exists(&exists);
|
||||
if (exists)
|
||||
mTmpFile->Remove(PR_FALSE);
|
||||
|
||||
rv = PerformSave(origURI);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
// put up some UI
|
||||
NSLog(@"Error saving web page");
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
nsresult nsHeaderSniffer::PerformSave(nsIURI* inOriginalURI)
|
||||
{
|
||||
nsresult rv;
|
||||
// Are we an HTML document? If so, we will want to append an accessory view to
|
||||
// the save dialog to provide the user with the option of doing a complete
|
||||
// save vs. a single file save.
|
||||
PRBool isHTML = (mDocument && mContentType.Equals("text/html") ||
|
||||
mContentType.Equals("text/xml") ||
|
||||
mContentType.Equals("application/xhtml+xml"));
|
||||
|
||||
// Next find out the directory that we should start in.
|
||||
nsCOMPtr<nsIPrefService> prefs(do_GetService("@mozilla.org/preferences-service;1", &rv));
|
||||
if (!prefs)
|
||||
return rv;
|
||||
nsCOMPtr<nsIPrefBranch> dirBranch;
|
||||
prefs->GetBranch("browser.download.", getter_AddRefs(dirBranch));
|
||||
PRInt32 filterIndex = 0;
|
||||
if (dirBranch) {
|
||||
nsresult rv = dirBranch->GetIntPref("save_converter_index", &filterIndex);
|
||||
if (NS_FAILED(rv))
|
||||
filterIndex = 0;
|
||||
}
|
||||
if (mFilterList)
|
||||
[mFilterList selectItemAtIndex: filterIndex];
|
||||
|
||||
// We need to figure out what file name to use.
|
||||
nsCAutoString defaultFileName;
|
||||
if (!mContentDisposition.IsEmpty()) {
|
||||
// (1) Use the HTTP header suggestion.
|
||||
PRInt32 index = mContentDisposition.Find("filename=");
|
||||
if (index >= 0) {
|
||||
// Take the substring following the prefix.
|
||||
index += 9;
|
||||
nsCAutoString filename;
|
||||
mContentDisposition.Right(filename, mContentDisposition.Length() - index);
|
||||
defaultFileName = filename;
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(mURL));
|
||||
if (url)
|
||||
url->GetFileName(defaultFileName); // (2) For file URLs, use the file name.
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mDocument && isHTML) {
|
||||
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
|
||||
nsAutoString title;
|
||||
if (htmlDoc)
|
||||
htmlDoc->GetTitle(title); // (3) Use the title of the document.
|
||||
defaultFileName.AssignWithConversion(title);
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
// (4) Use the caller provided name.
|
||||
defaultFileName = mDefaultFilename;
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mURL)
|
||||
// (5) Use the host.
|
||||
mURL->GetHost(defaultFileName);
|
||||
|
||||
// One last case to handle about:blank and other fruity untitled pages.
|
||||
if (defaultFileName.IsEmpty())
|
||||
defaultFileName = "untitled";
|
||||
|
||||
// Validate the file name to ensure legality.
|
||||
for (PRUint32 i = 0; i < defaultFileName.Length(); i++)
|
||||
if (defaultFileName[i] == ':' || defaultFileName[i] == '/')
|
||||
defaultFileName.SetCharAt(i, ' ');
|
||||
|
||||
// Make sure the appropriate extension is appended to the suggested file name.
|
||||
nsCOMPtr<nsIURI> fileURI(do_CreateInstance("@mozilla.org/network/standard-url;1"));
|
||||
nsCOMPtr<nsIURL> fileURL(do_QueryInterface(fileURI, &rv));
|
||||
if (!fileURL)
|
||||
return rv;
|
||||
fileURL->SetFilePath(defaultFileName);
|
||||
|
||||
nsCAutoString fileExtension;
|
||||
fileURL->GetFileExtension(fileExtension);
|
||||
|
||||
PRBool setExtension = PR_FALSE;
|
||||
if (mContentType.Equals("text/html")) {
|
||||
if (fileExtension.IsEmpty() || (!fileExtension.Equals("htm") && !fileExtension.Equals("html"))) {
|
||||
defaultFileName += ".html";
|
||||
setExtension = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!setExtension && fileExtension.IsEmpty()) {
|
||||
nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1", &rv));
|
||||
if (!mimeService)
|
||||
return rv;
|
||||
nsCOMPtr<nsIMIMEInfo> mimeInfo;
|
||||
rv = mimeService->GetFromMIMEType(mContentType.get(), getter_AddRefs(mimeInfo));
|
||||
if (!mimeInfo)
|
||||
return rv;
|
||||
|
||||
PRUint32 extCount = 0;
|
||||
char** extList = nsnull;
|
||||
mimeInfo->GetFileExtensions(&extCount, &extList);
|
||||
if (extCount > 0 && extList) {
|
||||
defaultFileName += ".";
|
||||
defaultFileName += extList[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Now it's time to pose the save dialog.
|
||||
NSSavePanel* savePanel = [NSSavePanel savePanel];
|
||||
NSString* file = nil;
|
||||
if (!defaultFileName.IsEmpty())
|
||||
file = [[NSString alloc] initWithCString: defaultFileName.get()];
|
||||
|
||||
if (isHTML)
|
||||
[savePanel setAccessoryView: mFilterView];
|
||||
|
||||
if ([savePanel runModalForDirectory: nil file: file] == NSFileHandlingPanelCancelButton)
|
||||
return NS_OK;
|
||||
|
||||
// Release the file string.
|
||||
[file release];
|
||||
|
||||
// Update the filter index.
|
||||
if (isHTML && mFilterList) {
|
||||
filterIndex = [mFilterList indexOfSelectedItem];
|
||||
dirBranch->SetIntPref("save_converter_index", filterIndex);
|
||||
}
|
||||
|
||||
// Convert the content type to text/plain if it was selected in the filter.
|
||||
if (isHTML && filterIndex == 2)
|
||||
mContentType = "text/plain";
|
||||
|
||||
nsCOMPtr<nsISupports> sourceData;
|
||||
if (isHTML && filterIndex != 1)
|
||||
sourceData = do_QueryInterface(mDocument);
|
||||
else
|
||||
sourceData = do_QueryInterface(mURL);
|
||||
|
||||
NSString* destName = [savePanel filename];
|
||||
|
||||
PRUint32 dstLen = [destName length];
|
||||
PRUnichar* tmp = new PRUnichar[dstLen + sizeof(PRUnichar)];
|
||||
tmp[dstLen] = (PRUnichar)'\0';
|
||||
[destName getCharacters:tmp];
|
||||
nsAutoString dstString(tmp);
|
||||
delete tmp;
|
||||
|
||||
return InitiateDownload(sourceData, dstString, inOriginalURI);
|
||||
}
|
||||
|
||||
// inOriginalURI is always a URI. inSourceData can be an nsIURI or an nsIDOMDocument, depending
|
||||
// on what we're saving. It's that way for nsIWebBrowserPersist.
|
||||
nsresult nsHeaderSniffer::InitiateDownload(nsISupports* inSourceData, nsString& inFileName, nsIURI* inOriginalURI)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPersist> webPersist = do_CreateInstance(persistContractID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIURI> sourceURI = do_QueryInterface(inSourceData);
|
||||
|
||||
nsCOMPtr<nsILocalFile> destFile;
|
||||
rv = NS_NewLocalFile(inFileName, PR_FALSE, getter_AddRefs(destFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRInt64 timeNow = PR_Now();
|
||||
|
||||
nsCOMPtr<nsIDownload> downloader = do_CreateInstance(NS_DOWNLOAD_CONTRACTID);
|
||||
// dlListener attaches to its progress dialog here, which gains ownership
|
||||
rv = downloader->Init(inOriginalURI, destFile, inFileName.get(), nsString().get(), timeNow, webPersist);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION |
|
||||
nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
|
||||
if (mBypassCache)
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE;
|
||||
else
|
||||
flags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
|
||||
|
||||
if (sourceURI)
|
||||
{
|
||||
rv = webPersist->SaveURI(sourceURI, mPostData, destFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsIDOMHTMLDocument> domDoc = do_QueryInterface(inSourceData, &rv);
|
||||
if (!domDoc) return rv; // should never happen
|
||||
|
||||
PRInt32 encodingFlags = 0;
|
||||
nsCOMPtr<nsILocalFile> filesFolder;
|
||||
|
||||
if (!mContentType.Equals("text/plain")) {
|
||||
// Create a local directory in the same dir as our file. It
|
||||
// will hold our associated files.
|
||||
filesFolder = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
nsAutoString unicodePath;
|
||||
destFile->GetPath(unicodePath);
|
||||
filesFolder->InitWithPath(unicodePath);
|
||||
|
||||
nsAutoString leafName;
|
||||
filesFolder->GetLeafName(leafName);
|
||||
nsAutoString nameMinusExt(leafName);
|
||||
PRInt32 index = nameMinusExt.RFind(".");
|
||||
if (index >= 0)
|
||||
nameMinusExt.Left(nameMinusExt, index);
|
||||
nameMinusExt += NS_LITERAL_STRING(" Files"); // XXXdwh needs to be localizable!
|
||||
filesFolder->SetLeafName(nameMinusExt);
|
||||
PRBool exists = PR_FALSE;
|
||||
filesFolder->Exists(&exists);
|
||||
if (!exists) {
|
||||
rv = filesFolder->Create(nsILocalFile::DIRECTORY_TYPE, 0755);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
encodingFlags |= nsIWebBrowserPersist::ENCODE_FLAGS_FORMATTED |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_ABSOLUTE_LINKS |
|
||||
nsIWebBrowserPersist::ENCODE_FLAGS_NOFRAMES_CONTENT;
|
||||
}
|
||||
rv = webPersist->SaveDocument(domDoc, destFile, filesFolder, mContentType.get(), encodingFlags, 80);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Appkit/Appkit.h>
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsIDownload.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsILocalFile.h"
|
||||
|
||||
|
||||
// maybe this should replace nsHeaderSniffer too?
|
||||
|
||||
class nsDownloadListener : public nsDownloader,
|
||||
public nsIDownload,
|
||||
public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsDownloadListener(DownloadControllerFactory* inDownloadControllerFactory);
|
||||
virtual ~nsDownloadListener();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOWNLOAD
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
public:
|
||||
//void BeginDownload();
|
||||
void InitDialog();
|
||||
|
||||
virtual void PauseDownload();
|
||||
virtual void ResumeDownload();
|
||||
virtual void CancelDownload();
|
||||
virtual void DownloadDone();
|
||||
|
||||
private:
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPersist> mWebPersist; // Our web persist object.
|
||||
nsCOMPtr<nsIURI> mURI; // The URI of our source file. Null if we're saving a complete document.
|
||||
nsCOMPtr<nsILocalFile> mDestination; // Our destination URL.
|
||||
PRInt64 mStartTime; // When the download started
|
||||
PRPackedBool mBypassCache; // Whether we should bypass the cache or not.
|
||||
PRPackedBool mNetworkTransfer; // true if the first OnStateChange has the NETWORK bit set
|
||||
PRPackedBool mGotFirstStateChange; // true after we've seen the first OnStateChange
|
||||
PRPackedBool mUserCanceled; // true if the user canceled the download
|
||||
};
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsDownloadListener.h"
|
||||
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIURL.h"
|
||||
#include "netCore.h"
|
||||
|
||||
nsDownloadListener::nsDownloadListener(DownloadControllerFactory* inControllerFactory)
|
||||
: nsDownloader(inControllerFactory)
|
||||
, mBypassCache(PR_FALSE)
|
||||
, mNetworkTransfer(PR_FALSE)
|
||||
, mGotFirstStateChange(PR_FALSE)
|
||||
, mUserCanceled(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
nsDownloadListener::~nsDownloadListener()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(nsDownloadListener, nsDownloader, nsIDownload, nsIWebProgressListener)
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in wstring openingWith, in long long startTime, in nsIWebBrowserPersist aPersist); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName,
|
||||
const PRUnichar *openingWith, PRInt64 startTime, nsIWebBrowserPersist *aPersist)
|
||||
{
|
||||
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()
|
||||
}
|
||||
|
||||
mDestination = aTarget;
|
||||
mURI = aSource;
|
||||
mStartTime = startTime;
|
||||
|
||||
InitDialog();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIURI source; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetSource(nsIURI * *aSource)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSource);
|
||||
NS_IF_ADDREF(*aSource = mURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsILocalFile target; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetTarget(nsILocalFile * *aTarget)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTarget);
|
||||
NS_IF_ADDREF(*aTarget = mDestination);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIWebBrowserPersist persist; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetPersist(nsIWebBrowserPersist * *aPersist)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPersist);
|
||||
NS_IF_ADDREF(*aPersist = mWebPersist);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute PRInt32 percentComplete; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetPercentComplete(PRInt32 *aPercentComplete)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute wstring displayName; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetDisplayName(PRUnichar * *aDisplayName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::SetDisplayName(const PRUnichar * aDisplayName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* readonly attribute long long startTime; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetStartTime(PRInt64 *aStartTime)
|
||||
{
|
||||
NS_ENSURE_ARG(aStartTime);
|
||||
*aStartTime = mStartTime;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute wstring openingWith; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetOpeningWith(PRUnichar * *aOpeningWith)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute nsIWebProgressListener listener; */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::GetListener(nsIWebProgressListener * *aListener)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aListener);
|
||||
NS_IF_ADDREF(*aListener = (nsIWebProgressListener *)this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
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); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
if (mUserCanceled)
|
||||
{
|
||||
if (aRequest)
|
||||
aRequest->Cancel(NS_BINDING_ABORTED);
|
||||
|
||||
mUserCanceled = false;
|
||||
}
|
||||
|
||||
[mDownloadDisplay setProgressTo:aCurTotalProgress ofMax:aMaxTotalProgress];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
// NSLog(@"State changed: state %u, status %u", aStateFlags, aStatus);
|
||||
if (!mGotFirstStateChange) {
|
||||
mNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0);
|
||||
mGotFirstStateChange = PR_TRUE;
|
||||
}
|
||||
|
||||
// when the entire download finishes, stop the progress timer and clean up
|
||||
// the window and controller. We will get this even in the event of a cancel,
|
||||
// so this is the only place in the listener where we should kill the download.
|
||||
if ((aStateFlags & STATE_STOP) && (!mNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) {
|
||||
DownloadDone();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
void
|
||||
nsDownloadListener::InitDialog()
|
||||
{
|
||||
// dialog has to be shown before the outlets get hooked up
|
||||
[mDownloadDisplay onStartDownload];
|
||||
|
||||
if (mURI)
|
||||
{
|
||||
nsCAutoString spec;
|
||||
mURI->GetSpec(spec);
|
||||
[mDownloadDisplay setSourceURL: [NSString stringWithUTF8String:spec.get()]];
|
||||
}
|
||||
|
||||
nsAutoString pathStr;
|
||||
mDestination->GetPath(pathStr);
|
||||
[mDownloadDisplay setDestinationPath: [NSString stringWithCharacters:pathStr.get() length:pathStr.Length()]];
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::PauseDownload()
|
||||
{
|
||||
// write me
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::ResumeDownload()
|
||||
{
|
||||
// write me
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::CancelDownload()
|
||||
{
|
||||
mUserCanceled = PR_TRUE;
|
||||
|
||||
if (mWebPersist)
|
||||
{
|
||||
mWebPersist->CancelSave();
|
||||
mUserCanceled = PR_FALSE;
|
||||
}
|
||||
|
||||
// delete any files we've created...
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
nsDownloadListener::DownloadDone()
|
||||
{
|
||||
// break the reference cycle by removing ourselves as a listener
|
||||
if (mWebPersist)
|
||||
{
|
||||
mWebPersist->SetProgressListener(nsnull);
|
||||
mWebPersist = nsnull;
|
||||
}
|
||||
|
||||
[mDownloadDisplay onEndDownload];
|
||||
}
|
||||
|
||||
#pragma mark -
|
|
@ -55,7 +55,7 @@ class nsCocoaBrowserService : public nsIWindowCreator,
|
|||
public nsIPromptService,
|
||||
public nsIFactory,
|
||||
public nsIBadCertListener, public nsISecurityWarningDialogs, public nsINSSDialogs,
|
||||
public nsIHelperAppLauncherDialog, public nsIDownload, public nsIWebProgressListener
|
||||
public nsIHelperAppLauncherDialog
|
||||
{
|
||||
public:
|
||||
nsCocoaBrowserService();
|
||||
|
@ -69,8 +69,6 @@ public:
|
|||
NS_DECL_NSIBADCERTLISTENER
|
||||
NS_DECL_NSISECURITYWARNINGDIALOGS
|
||||
NS_DECL_NSIHELPERAPPLAUNCHERDIALOG
|
||||
NS_DECL_NSIDOWNLOAD
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
static nsresult InitEmbedding();
|
||||
static void TermEmbedding();
|
||||
|
|
|
@ -35,14 +35,15 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsCocoaBrowserService.h"
|
||||
#import "nsCocoaBrowserService.h"
|
||||
#import "DownloadFactories.h"
|
||||
#import "CHBrowserView.h"
|
||||
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIEmbeddingSiteWindow.h"
|
||||
#include "nsIProfile.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "CHBrowserView.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIPrompt.h"
|
||||
|
@ -74,13 +75,14 @@ nsCocoaBrowserService::~nsCocoaBrowserService()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS9(nsCocoaBrowserService,
|
||||
NS_IMPL_ISUPPORTS7(nsCocoaBrowserService,
|
||||
nsIWindowCreator,
|
||||
nsIPromptService,
|
||||
nsIFactory,
|
||||
nsIBadCertListener, nsISecurityWarningDialogs, nsINSSDialogs,
|
||||
nsIHelperAppLauncherDialog, nsIDownload, nsIWebProgressListener)
|
||||
nsIHelperAppLauncherDialog)
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsCocoaBrowserService::InitEmbedding()
|
||||
{
|
||||
|
@ -103,7 +105,7 @@ nsCocoaBrowserService::InitEmbedding()
|
|||
#define NS_PROMPTSERVICE_CID \
|
||||
{0xa2112d6a, 0x0e28, 0x421f, {0xb4, 0x6a, 0x25, 0xc0, 0xb3, 0x8, 0xcb, 0xd0}}
|
||||
static NS_DEFINE_CID(kPromptServiceCID, NS_PROMPTSERVICE_CID);
|
||||
nsresult rv = cr->RegisterFactory(kPromptServiceCID, "Prompt Service", "@mozilla.org/embedcomp/prompt-service;1",
|
||||
nsresult rv = cr->RegisterFactory(kPromptServiceCID, "Prompt Service", "@mozilla.org/embedcomp/prompt-service;1",
|
||||
sSingleton);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
@ -127,14 +129,18 @@ nsCocoaBrowserService::InitEmbedding()
|
|||
rv = cr->RegisterFactory(kHelperDlgCID, NS_IHELPERAPPLAUNCHERDLG_CLASSNAME, NS_IHELPERAPPLAUNCHERDLG_CONTRACTID,
|
||||
sSingleton);
|
||||
|
||||
// replace the downloader with our own which does rely on the xpfe downlaod manager
|
||||
// replace the downloader with our own which does not rely on the xpfe downlaod manager
|
||||
nsCOMPtr<nsIFactory> downloadFactory;
|
||||
rv = NewDownloadListenerFactory(getter_AddRefs(downloadFactory));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
static NS_DEFINE_CID(kDownloadCID, NS_DOWNLOAD_CID);
|
||||
rv = cr->RegisterFactory(kDownloadCID, "Download", NS_DOWNLOAD_CONTRACTID,
|
||||
sSingleton);
|
||||
rv = cr->RegisterFactory(kDownloadCID, "Download", NS_DOWNLOAD_CONTRACTID, downloadFactory);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsCocoaBrowserService::BrowserClosed()
|
||||
{
|
||||
|
@ -149,6 +155,7 @@ nsCocoaBrowserService::BrowserClosed()
|
|||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsCocoaBrowserService::TermEmbedding()
|
||||
{
|
||||
|
@ -195,8 +202,15 @@ nsCocoaBrowserService::CreateInstance(nsISupports *aOuter,
|
|||
const nsIID & aIID,
|
||||
void **aResult)
|
||||
{
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
/*
|
||||
if (aIID.Equals(NS_GET_IID(nsIHelperAppLauncherDialog)))
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
return sSingleton->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
|
@ -828,14 +842,12 @@ nsCocoaBrowserService::ConfirmPostToInsecureFromSecure(nsIInterfaceRequestor *ct
|
|||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::Show(nsIHelperAppLauncher* inLauncher, nsISupports* inContext)
|
||||
{
|
||||
NSLog(@"Show");
|
||||
return inLauncher->SaveToDisk(nsnull, PR_FALSE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::PromptForSaveToFile(nsISupports *aWindowContext, const PRUnichar *aDefaultFile, const PRUnichar *aSuggestedFileExtension, nsILocalFile **_retval)
|
||||
{
|
||||
NSLog(@"PromptForSaveToFile");
|
||||
NSString* filename = [NSString stringWithCharacters:aDefaultFile length:nsCRT::strlen(aDefaultFile)];
|
||||
NSSavePanel *thePanel = [NSSavePanel savePanel];
|
||||
|
||||
|
@ -844,7 +856,7 @@ NSLog(@"PromptForSaveToFile");
|
|||
// use nil for the path given to runModalForDirectory
|
||||
int runResult = [thePanel runModalForDirectory: nil file:filename];
|
||||
if (runResult == NSOKButton) {
|
||||
NSLog([thePanel filename]);
|
||||
// NSLog(@"Saving to %@", [thePanel filename]);
|
||||
NSString *theName = [thePanel filename];
|
||||
return NS_NewNativeLocalFile(nsDependentCString([theName fileSystemRepresentation]), PR_FALSE, _retval);
|
||||
}
|
||||
|
@ -856,140 +868,6 @@ NSLog([thePanel filename]);
|
|||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::ShowProgressDialog(nsIHelperAppLauncher *aLauncher, nsISupports *aContext)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::Init(nsIURI* aSource,
|
||||
nsILocalFile* aTarget,
|
||||
const PRUnichar* aDisplayName,
|
||||
const PRUnichar* aOpeningWith,
|
||||
PRInt64 aStartTime,
|
||||
nsIWebBrowserPersist* aPersist)
|
||||
{
|
||||
NSLog(@"nsIDownload::Init");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetDisplayName(PRUnichar** aDisplayName)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::SetDisplayName(const PRUnichar* aDisplayName)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetOpeningWith(PRUnichar** aOpeningWith)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetSource(nsIURI** aSource)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetTarget(nsILocalFile** aTarget)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetStartTime(PRInt64* aStartTime)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetPercentComplete(PRInt32* aPercentComplete)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetListener(nsIWebProgressListener** aListener)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::SetListener(nsIWebProgressListener* aListener)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetObserver(nsIObserver** aObserver)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::SetObserver(nsIObserver* aObserver)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::GetPersist(nsIWebBrowserPersist** aPersist)
|
||||
{
|
||||
NS_ERROR("NS_ERROR_NOT_IMPLEMENTED");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnStateChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, nsIURI *aLocation)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCocoaBrowserService::OnSecurityChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest, PRUint32 aState)
|
||||
{
|
||||
NSLog(@"nsCocoaBrowserService::ShowProgressDialog");
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "CHBrowserView.h"
|
||||
#import "ProgressDlgController.h"
|
||||
#import "FindDlgController.h"
|
||||
#import "nsCocoaBrowserService.h"
|
||||
#import "mozView.h"
|
||||
|
@ -65,18 +64,12 @@
|
|||
|
||||
// Saving of links/images/docs
|
||||
#include "nsIWebBrowserFocus.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDOMNSDocument.h"
|
||||
#include "nsIDOMLocation.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsIProperties.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsIMIMEInfo.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsISHistory.h"
|
||||
#include "nsIHistoryEntry.h"
|
||||
#include "nsISHEntry.h"
|
||||
|
@ -84,6 +77,7 @@
|
|||
#include "nsIContextMenuListener.h"
|
||||
#include "nsITooltipListener.h"
|
||||
#include "nsIEmbeddingSiteWindow2.h"
|
||||
#include "SaveHeaderSniffer.h"
|
||||
|
||||
typedef unsigned int DragReference;
|
||||
#include "nsIDragHelperService.h"
|
||||
|
@ -677,265 +671,7 @@ nsCocoaBrowserListener::SetContainer(id <NSBrowserContainer> aContainer)
|
|||
[mContainer retain];
|
||||
}
|
||||
|
||||
// Implementation of a header sniffer class that is used when saving Web pages and images.
|
||||
class nsHeaderSniffer : public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
|
||||
nsIDOMDocument* aDocument, nsIInputStream* aPostData,
|
||||
const nsCString& aSuggestedFilename, PRBool aBypassCache,
|
||||
NSView* aFilterView, NSPopUpButton* aFilterList)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mPersist = aPersist;
|
||||
mTmpFile = aFile;
|
||||
mURL = aURL;
|
||||
mDocument = aDocument;
|
||||
mPostData = aPostData;
|
||||
mDefaultFilename = aSuggestedFilename;
|
||||
mBypassCache = aBypassCache;
|
||||
mFilterView = aFilterView;
|
||||
mFilterList = aFilterList;
|
||||
}
|
||||
|
||||
virtual ~nsHeaderSniffer()
|
||||
{
|
||||
};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
protected:
|
||||
void PerformSave();
|
||||
|
||||
private:
|
||||
nsIWebBrowserPersist* mPersist; // Weak. It owns us as a listener.
|
||||
nsCOMPtr<nsIFile> mTmpFile;
|
||||
nsCOMPtr<nsIURI> mURL;
|
||||
nsCOMPtr<nsIDOMDocument> mDocument;
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
nsCString mDefaultFilename;
|
||||
PRBool mBypassCache;
|
||||
nsCString mContentType;
|
||||
nsCString mContentDisposition;
|
||||
NSView* mFilterView;
|
||||
NSPopUpButton* mFilterList;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsHeaderSniffer, nsIWebProgressListener)
|
||||
|
||||
// Implementation of nsIWebProgressListener
|
||||
/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
|
||||
PRUint32 aStatus)
|
||||
{
|
||||
if (aStateFlags & nsIWebProgressListener::STATE_START) {
|
||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
|
||||
channel->GetContentType(mContentType);
|
||||
|
||||
// Get the content-disposition if we're an HTTP channel.
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if (httpChannel)
|
||||
httpChannel->GetResponseHeader(nsCAutoString("content-disposition"), mContentDisposition);
|
||||
|
||||
mPersist->CancelSave();
|
||||
PRBool exists;
|
||||
mTmpFile->Exists(&exists);
|
||||
if (exists)
|
||||
mTmpFile->Remove(PR_FALSE);
|
||||
PerformSave();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsHeaderSniffer::PerformSave()
|
||||
{
|
||||
// Are we an HTML document? If so, we will want to append an accessory view to
|
||||
// the save dialog to provide the user with the option of doing a complete
|
||||
// save vs. a single file save.
|
||||
PRBool isHTML = (mDocument && mContentType.Equals("text/html") ||
|
||||
mContentType.Equals("text/xml") ||
|
||||
mContentType.Equals("application/xhtml+xml"));
|
||||
|
||||
// Next find out the directory that we should start in.
|
||||
nsCOMPtr<nsIPrefService> prefs(do_GetService("@mozilla.org/preferences-service;1"));
|
||||
if (!prefs)
|
||||
return;
|
||||
nsCOMPtr<nsIPrefBranch> dirBranch;
|
||||
prefs->GetBranch("browser.download.", getter_AddRefs(dirBranch));
|
||||
PRInt32 filterIndex = 0;
|
||||
if (dirBranch) {
|
||||
nsresult rv = dirBranch->GetIntPref("save_converter_index", &filterIndex);
|
||||
if (NS_FAILED(rv))
|
||||
filterIndex = 0;
|
||||
}
|
||||
if (mFilterList)
|
||||
[mFilterList selectItemAtIndex: filterIndex];
|
||||
|
||||
// We need to figure out what file name to use.
|
||||
nsCAutoString defaultFileName;
|
||||
if (!mContentDisposition.IsEmpty()) {
|
||||
// (1) Use the HTTP header suggestion.
|
||||
PRInt32 index = mContentDisposition.Find("filename=");
|
||||
if (index >= 0) {
|
||||
// Take the substring following the prefix.
|
||||
index += 9;
|
||||
nsCAutoString filename;
|
||||
mContentDisposition.Right(filename, mContentDisposition.Length() - index);
|
||||
defaultFileName = filename;
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(mURL));
|
||||
if (url)
|
||||
url->GetFileName(defaultFileName); // (2) For file URLs, use the file name.
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mDocument && isHTML) {
|
||||
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
|
||||
nsAutoString title;
|
||||
if (htmlDoc)
|
||||
htmlDoc->GetTitle(title); // (3) Use the title of the document.
|
||||
defaultFileName.AssignWithConversion(title);
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty()) {
|
||||
// (4) Use the caller provided name.
|
||||
defaultFileName = mDefaultFilename;
|
||||
}
|
||||
|
||||
if (defaultFileName.IsEmpty() && mURL)
|
||||
// (5) Use the host.
|
||||
mURL->GetHost(defaultFileName);
|
||||
|
||||
// One last case to handle about:blank and other fruity untitled pages.
|
||||
if (defaultFileName.IsEmpty())
|
||||
defaultFileName = "untitled";
|
||||
|
||||
// Validate the file name to ensure legality.
|
||||
for (PRUint32 i = 0; i < defaultFileName.Length(); i++)
|
||||
if (defaultFileName[i] == ':' || defaultFileName[i] == '/')
|
||||
defaultFileName.SetCharAt(i, ' ');
|
||||
|
||||
// Make sure the appropriate extension is appended to the suggested file name.
|
||||
nsCOMPtr<nsIURI> fileURI(do_CreateInstance("@mozilla.org/network/standard-url;1"));
|
||||
nsCOMPtr<nsIURL> fileURL(do_QueryInterface(fileURI));
|
||||
if (!fileURL)
|
||||
return;
|
||||
fileURL->SetFilePath(defaultFileName);
|
||||
|
||||
nsCAutoString fileExtension;
|
||||
fileURL->GetFileExtension(fileExtension);
|
||||
|
||||
PRBool setExtension = PR_FALSE;
|
||||
if (mContentType.Equals("text/html")) {
|
||||
if (fileExtension.IsEmpty() || (!fileExtension.Equals("htm") && !fileExtension.Equals("html"))) {
|
||||
defaultFileName += ".html";
|
||||
setExtension = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!setExtension && fileExtension.IsEmpty()) {
|
||||
nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1"));
|
||||
if (!mimeService)
|
||||
return;
|
||||
nsCOMPtr<nsIMIMEInfo> mimeInfo;
|
||||
mimeService->GetFromMIMEType(mContentType.get(), getter_AddRefs(mimeInfo));
|
||||
if (!mimeInfo)
|
||||
return;
|
||||
|
||||
PRUint32 extCount = 0;
|
||||
char** extList = nsnull;
|
||||
mimeInfo->GetFileExtensions(&extCount, &extList);
|
||||
if (extCount > 0 && extList) {
|
||||
defaultFileName += ".";
|
||||
defaultFileName += extList[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Now it's time to pose the save dialog.
|
||||
NSSavePanel* savePanel = [NSSavePanel savePanel];
|
||||
NSString* file = nil;
|
||||
if (!defaultFileName.IsEmpty())
|
||||
file = [[NSString alloc] initWithCString: defaultFileName.get()];
|
||||
|
||||
if (isHTML)
|
||||
[savePanel setAccessoryView: mFilterView];
|
||||
|
||||
if ([savePanel runModalForDirectory: nil file: file] == NSFileHandlingPanelCancelButton)
|
||||
return;
|
||||
|
||||
// Release the file string.
|
||||
[file release];
|
||||
|
||||
// Update the filter index.
|
||||
if (isHTML && mFilterList) {
|
||||
filterIndex = [mFilterList indexOfSelectedItem];
|
||||
dirBranch->SetIntPref("save_converter_index", filterIndex);
|
||||
}
|
||||
|
||||
// Convert the content type to text/plain if it was selected in the filter.
|
||||
if (isHTML && filterIndex == 2)
|
||||
mContentType = "text/plain";
|
||||
|
||||
nsCOMPtr<nsISupports> sourceData;
|
||||
if (isHTML && filterIndex != 1)
|
||||
sourceData = do_QueryInterface(mDocument);
|
||||
else
|
||||
sourceData = do_QueryInterface(mURL);
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPersist> webPersist(do_CreateInstance(persistContractID));
|
||||
ProgressDlgController* progressDialog = [[ProgressDlgController alloc] initWithWindowNibName: @"ProgressDialog"];
|
||||
[progressDialog setWebPersist: webPersist
|
||||
source: sourceData.get()
|
||||
destination: [savePanel filename]
|
||||
contentType: mContentType.get()
|
||||
postData: mPostData
|
||||
bypassCache: mBypassCache];
|
||||
|
||||
[progressDialog showWindow: progressDialog];
|
||||
}
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *location)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation CHBrowserView
|
||||
|
||||
|
@ -1244,13 +980,17 @@ nsHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aReq
|
|||
shEntry->GetPostData(getter_AddRefs(postData));
|
||||
}
|
||||
|
||||
// when saving, we first fire off a save with a nsHeaderSniffer as a progress
|
||||
// listener. This allows us to look for the content-disposition header, which
|
||||
// can supply a filename, and maybe has something to do with CGI-generated
|
||||
// content (?)
|
||||
nsCAutoString fileName(aFilename);
|
||||
nsHeaderSniffer* sniffer = new nsHeaderSniffer(webPersist, tmpFile, aURI,
|
||||
aDocument, postData, fileName, aBypassCache,
|
||||
aFilterView, aFilterList);
|
||||
if (!sniffer)
|
||||
return;
|
||||
webPersist->SetProgressListener(sniffer);
|
||||
webPersist->SetProgressListener(sniffer); // owned
|
||||
webPersist->SaveURI(aURI, nsnull, tmpFile);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// This file contains implementations of factories for various
|
||||
// downloading-related interfaces.
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
#import "ProgressDlgController.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIFactory.h"
|
||||
|
||||
#include "nsDownloadListener.h"
|
||||
#include "DownloadFactories.h"
|
||||
|
||||
// factory for nsIDownload objects
|
||||
// XXX replace with generic factory stuff
|
||||
class DownloadListenerFactory : public nsIFactory
|
||||
{
|
||||
public:
|
||||
DownloadListenerFactory();
|
||||
virtual ~DownloadListenerFactory();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIFACTORY
|
||||
|
||||
protected:
|
||||
|
||||
DownloadControllerFactory* mControllerFactory; // factory which creates the Cocoa window controller
|
||||
};
|
||||
|
||||
|
||||
DownloadListenerFactory::DownloadListenerFactory()
|
||||
: mControllerFactory(nil)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mControllerFactory = [[[ChimeraDownloadControllerFactory alloc] init] retain];
|
||||
}
|
||||
|
||||
DownloadListenerFactory::~DownloadListenerFactory()
|
||||
{
|
||||
[mControllerFactory release];
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(DownloadListenerFactory, nsIFactory);
|
||||
|
||||
/* void createInstance (in nsISupports aOuter, in nsIIDRef iid, [iid_is (iid), retval] out nsQIResult result); */
|
||||
NS_IMETHODIMP
|
||||
DownloadListenerFactory::CreateInstance(nsISupports *aOuter, const nsIID& aIID, void* *aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsIDownload)))
|
||||
{
|
||||
nsDownloadListener* downloadListener = new nsDownloadListener(mControllerFactory);
|
||||
if (!downloadListener) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(downloadListener);
|
||||
rv = downloadListener->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(downloadListener);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
/* void lockFactory (in PRBool lock); */
|
||||
NS_IMETHODIMP
|
||||
DownloadListenerFactory::LockFactory(PRBool lock)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
nsresult NewDownloadListenerFactory(nsIFactory* *outFactory)
|
||||
{
|
||||
DownloadListenerFactory* newFactory = new DownloadListenerFactory();
|
||||
if (!newFactory) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(newFactory);
|
||||
nsresult rv = newFactory->QueryInterface(NS_GET_IID(nsIFactory), (void **)outFactory);
|
||||
NS_RELEASE(newFactory);
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
The classes and protocol in this file allow Cocoa applications to easily
|
||||
reuse the underlying download implementation, which deals with the complexity
|
||||
of Gecko's downloading callbacks.
|
||||
|
||||
There are three things here:
|
||||
|
||||
1. The DownloadProgressDisplay protocol.
|
||||
|
||||
This is a formal protocol that needs to be implemented by
|
||||
a window controller for your progress window. Its methods
|
||||
will be called by the underlying C++ downloading classes.
|
||||
|
||||
2. The Obj-C DownloadControllerFactory class.
|
||||
|
||||
This class should be subclassed by an embedder, with an
|
||||
implementation of 'createDownloadController' that hands back
|
||||
a new instance of an NSWindowController that implements the
|
||||
<DownloadProgressDisplay> protocol.
|
||||
|
||||
The underlying C++ classes use this factory to create the
|
||||
progress window controller.
|
||||
|
||||
3. The nsDownloader C++ class
|
||||
|
||||
This base class exists to hide the complextity of the download
|
||||
listener classes (which deal with Gecko callbacks) from the
|
||||
window controller. Embedders don't need to do anything with it.
|
||||
|
||||
How these classes fit together:
|
||||
|
||||
There are 2 ways in which a download is initiated:
|
||||
|
||||
(i) File->Save.
|
||||
|
||||
Chimera does a complex dance here in order to get certain
|
||||
information about the data being downloaded (it needs to
|
||||
start the download before it can read some optional MIME headers).
|
||||
|
||||
CBrowserView creates an nsIWebBrowserPersist (WBP), and then a
|
||||
nsHeaderSniffer, which implements nsIWebProgressListener and is set to
|
||||
observer the WBP. When nsHeaderSniffer hears about the start of the
|
||||
download, it decides on a file name, and what format to save the data
|
||||
in. It then cancels the current WPB, makes another one, and does
|
||||
a CreateInstance of an nsIDownload (making one of our nsDownloadListener
|
||||
-- aka nsDownloder -- objects), and sets that as the nsIWebProgressListener.
|
||||
The full download procedes from there.
|
||||
|
||||
(ii) Click to download (e.g. FTP link)
|
||||
|
||||
This is simpler. The backend (necko) does the CreateInstance of the
|
||||
nsIDownload, and the download progresses.
|
||||
|
||||
In both cases, creating the nsDownloadListener and calling its Init() method
|
||||
calls nsDownloder::CreateDownloadDisplay(). The nsDownloder has as a member
|
||||
variable a DownloadControllerFactory (see above), which got passed to it
|
||||
via our XPCOM factory for nsIDownload objects. It then uses that DownloadControllerFactory
|
||||
to get an instance of the download progress window controller, which then
|
||||
shows the download progress window.
|
||||
|
||||
Simple, eh?
|
||||
|
||||
*/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsDownloader;
|
||||
|
||||
// a formal protocol for something that implements progress display
|
||||
// Embedders can make a window controller that conforms to this
|
||||
// protocol, and reuse nsDownloadListener to get download UI.
|
||||
@protocol DownloadProgressDisplay
|
||||
|
||||
- (void)onStartDownload;
|
||||
- (void)onEndDownload;
|
||||
|
||||
- (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress;
|
||||
|
||||
- (void)setDownloadListener:(nsDownloader*)aDownloader;
|
||||
- (void)setSourceURL:(NSString*)aSourceURL;
|
||||
- (void)setDestinationPath:(NSString*)aDestPath;
|
||||
|
||||
@end
|
||||
|
||||
// subclass this, and have your subclass instantiate and return your window
|
||||
// controller in createDownloadController
|
||||
@interface DownloadControllerFactory : NSObject
|
||||
{
|
||||
}
|
||||
|
||||
- (NSWindowController<DownloadProgressDisplay> *)createDownloadController;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// Pure virtual base class for a generic downloader, that the progress UI can talk to.
|
||||
// It implements nsISupports so that it can be refcounted. This class insulates the
|
||||
// UI code from having to know too much about the nsIDownloadListener.
|
||||
// It is responsible for creating the download UI, via the DownloadControllerFactory
|
||||
// that it owns.
|
||||
class nsDownloader : public nsISupports
|
||||
{
|
||||
public:
|
||||
nsDownloader(DownloadControllerFactory* inControllerFactory);
|
||||
virtual ~nsDownloader();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void PauseDownload() = 0;
|
||||
virtual void ResumeDownload() = 0;
|
||||
virtual void CancelDownload() = 0;
|
||||
virtual void DownloadDone() = 0;
|
||||
|
||||
virtual void CreateDownloadDisplay();
|
||||
|
||||
protected:
|
||||
|
||||
DownloadControllerFactory* mControllerFactory;
|
||||
id <DownloadProgressDisplay> mDownloadDisplay; // something that implements the DownloadProgressDisplay protocol
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chimera code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "DownloadProgressDisplay.h"
|
||||
|
||||
|
||||
@implementation DownloadControllerFactory
|
||||
|
||||
- (NSWindowController<DownloadProgressDisplay> *)createDownloadController
|
||||
{
|
||||
// a dummy implementation. You should provide a subclass that
|
||||
// returns an instance of your progress dialog controller.
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// see the header file for comments
|
||||
nsDownloader::nsDownloader(DownloadControllerFactory* inControllerFactory)
|
||||
: mControllerFactory(inControllerFactory)
|
||||
, mDownloadDisplay(nil)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
[mControllerFactory retain];
|
||||
}
|
||||
|
||||
nsDownloader::~nsDownloader()
|
||||
{
|
||||
[mControllerFactory release];
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDownloader, nsISupports);
|
||||
|
||||
void
|
||||
nsDownloader::CreateDownloadDisplay()
|
||||
{
|
||||
mDownloadDisplay = [mControllerFactory createDownloadController];
|
||||
[mDownloadDisplay setDownloadListener:this];
|
||||
}
|
|
@ -89,8 +89,11 @@ app_getModuleInfo(nsStaticModuleInfo **info, PRUint32 *count);
|
|||
nsresult rv;
|
||||
ICStop (mInternetConfig);
|
||||
nsCOMPtr<nsIPrefService> pref(do_GetService(NS_PREF_CONTRACTID, &rv));
|
||||
if (!NS_FAILED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
//NSLog(@"Saving prefs file");
|
||||
pref->SavePrefFile(nsnull);
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче