New and improved unknown file type dialog implementation

This commit is contained in:
law%netscape.com 1999-07-16 23:50:25 +00:00
Родитель 692555dae8
Коммит 6c9001419d
9 изменённых файлов: 149 добавлений и 400 удалений

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

@ -1249,11 +1249,22 @@ nsBrowserAppCore::HandleUnknownContentType(nsIDocumentLoader* loader,
if ( NS_SUCCEEDED( rv ) ) {
/* Have handler take care of this. */
// Get DOM window.
nsCOMPtr<nsIDOMWindow> domWindow;
rv = mWebShellWin->ConvertWebShellToDOMWindow( mWebShell,
getter_AddRefs( domWindow ) );
if ( NS_SUCCEEDED( rv ) && domWindow ) {
#ifdef NECKO
rv = handler->HandleUnknownContentType( channel, aContentType, loader );
rv = handler->HandleUnknownContentType( channel, aContentType, domWindow );
#else
rv = handler->HandleUnknownContentType( aURL, aContentType, loader );
rv = handler->HandleUnknownContentType( aURL, aContentType, domWindow );
#endif
} else {
#ifdef NS_DEBUG
printf( "%s %d: ConvertWebShellToDOMWindow failed, rv=0x%08X\n",
__FILE__, (int)__LINE__, (int)rv );
#endif
}
// Release the unknown content type handler service object.
nsServiceManager::ReleaseService( NS_IUNKNOWNCONTENTTYPEHANDLER_PROGID, handler );

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

@ -17,12 +17,13 @@
*/
#include "nsIAppShellComponent.idl"
#include "domstubs.idl"
interface nsIURI;
interface nsIDocumentLoader;
interface nsIChannel;
%{C++
class nsIDOMWindow; // Seems domstubs.idl should do this, though.
#ifndef NECKO // gross hack since we can't put ifdefs in idl:
#define nsIChannel nsIURI
#endif
@ -50,15 +51,13 @@ interface nsIUnknownContentTypeHandler : nsIAppShellComponent {
void HandleUnknownContentType( in nsIChannel aURL,
in string aContentType,
in nsIDocumentLoader aDocLoader );
in nsIDOMWindow aWindow );
};
%{C++
#define NS_IUNKNOWNCONTENTTYPEHANDLER_PROGID NS_IAPPSHELLCOMPONENT_PROGID "/unknownContentType"
#define NS_IUNKNOWNCONTENTTYPEHANDLER_CLASSNAME "Mozilla Unknown Content-Type Handler Component"
#define NS_DECL_IUNKNOWNCONTENTTYPEHANDLER \
NS_IMETHOD HandleUnknownContentType( nsIChannel *aURL, \
const char *aContentType, \
nsIDocumentLoader *aDocLoader );
#define NS_DECL_IUNKNOWNCONTENTTYPEHANDLER \
NS_IMETHOD HandleUnknownContentType( nsIChannel*, const char*, nsIDOMWindow*);
%}

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

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<?xml-stylesheet href="xul.css" type="text/css"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE window
[
@ -16,18 +16,8 @@
<window xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&unknownWindow.title;"
width="425"
height="180">
<data>
<broadcaster id="data.location" type="url" value="url...to be replaced"/>
<broadcaster id="data.contentType" type="string" value="content-type...to be replaced"/>
<!-- Commands: more/pick/save/close -->
<broadcaster id="data.execute" command=""/>
<!-- Temporary onLoad() trigger -->
<broadcaster id="dialog.start" ready="false"/>
<observes element="dialog.start" attribute="ready" onchange="onLoad()"/>
</data>
onload="onLoad()"
onunload="onUnload()">
<html:script>
var data;
@ -36,9 +26,8 @@
function initData() {
// Create data object and initialize.
data = new Object;
data.location = document.getElementById("data.location");
data.contentType = document.getElementById("data.contentType");
data.execute = document.getElementById("data.execute");
data.location = window.arguments[0];
data.contentType = window.arguments[1];
}
function initDialog() {
@ -53,7 +42,7 @@
function loadDialog() {
// Set initial dialog field contents.
dialog.contentType.childNodes[0].nodeValue = " " + data.contentType.getAttribute( "value" );
dialog.contentType.childNodes[0].nodeValue = " " + data.contentType;
}
function onLoad() {
@ -67,37 +56,55 @@
loadDialog();
}
function onUnload() {
// Nothing for now.
}
function more() {
// Have C++ code go to appropriate web page.
data.execute.setAttribute("command","more");
// Have parent browser window go to appropriate web page.
var moreInfo = "http://cgi.netscape.com/cgi-bin/plug-in_finder.cgi?";
moreInfo += data.contentType;
window.opener.content.location = moreInfo;
}
function pick() {
// Have C++ code prompt user for app and run it.
data.execute.setAttribute("command","pick");
alert( "PickApp not implemented yet!" );
}
function save() {
// Execute "save to disk" logic.
data.execute.setAttribute("command","save");
// Use stream xfer component to prompt for destination and save.
var xfer = Components.classes[ "component://netscape/appshell/component/xfer" ].getService();
xfer = xfer.QueryInterface( Components.interfaces.nsIStreamTransfer );
try {
// When Necko lands, we need to receive the real nsIChannel and
// do SelectFileAndTransferLocation!
// Use this for now...
xfer.SelectFileAndTransferLocationSpec( data.location );
} catch( exception ) {
// Failed (or cancelled), give them another chance.
return;
}
// Save underway, close this dialog.
window.close();
}
function cancel() {
// Close the window.
data.execute.setAttribute("command","close");
window.close();
}
</html:script>
<html:div flex="100%">
<html:table style="width:100%;">
<html:tr>
<html:td colspan="4">
&startDownload;
<html:div id="dialog.contentType" style="display:inline">
<html:strong>
<html:div id="dialog.contentType" style="display:inline;">
&contentType.label;
</html:div>
</html:strong>
</html:td>
</html:tr>
@ -117,6 +124,4 @@
</html:tr>
</html:table>
</html:div>
</window>

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

@ -35,6 +35,7 @@ EXTRA_DSO_LDOPTS = \
-lreg \
$(ZLIB_LIBS) \
$(NSPR_LIBS) \
-l$(MOZ_LIB_JS_PREFIX)js \
$(NULL)
ifndef NECKO

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

@ -49,6 +49,7 @@ LINCS = \
LLIBS = \
$(LIBNSPR) \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\js3250.lib \
!ifndef NECKO
$(DIST)\lib\netlib.lib \
!endif

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

@ -19,28 +19,10 @@
#include "nsIAppShellComponentImpl.h"
#include "nsIXULWindowCallbacks.h"
#include "nsIDocumentObserver.h"
#include "nsString.h"
#include "nsIURL.h"
#ifdef NECKO
#include "nsIIOService.h"
#include "nsIURL.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
#endif // NECKO
#include "nsIWebShellWindow.h"
#include "nsIContent.h"
#include "nsINameSpaceManager.h"
#include "nsIContentViewer.h"
#include "nsIDocumentViewer.h"
#include "nsIWebShell.h"
#include "nsIDocument.h"
#include "nsIDOMXULDocument.h"
#include "nsIDOMElement.h"
#include "nsIDocumentLoader.h"
#include "nsIStreamTransfer.h"
#include "nsIDOMWindow.h"
#include "nsIScriptGlobalObject.h"
// {42770B50-03E9-11d3-8068-00600811A9C3}
#define NS_UNKNOWNCONTENTTYPEHANDLER_CID \
@ -71,369 +53,98 @@ private:
nsInstanceCounter mInstanceCounter;
}; // nsUnknownContentTypeHandler
struct nsUnknownContentDialog : public nsIXULWindowCallbacks,
nsIDocumentObserver {
// Declare implementation of ISupports stuff.
NS_DECL_ISUPPORTS
// Declare implementations of nsIXULWindowCallbacks interface functions.
NS_IMETHOD ConstructBeforeJavaScript(nsIWebShell *aWebShell);
NS_IMETHOD ConstructAfterJavaScript(nsIWebShell *aWebShell) { return NS_OK; }
// Declare implementations of nsIDocumentObserver functions.
NS_IMETHOD BeginUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD EndReflow(nsIDocument *aDocument, nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD ContentChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsISupports* aSubContent) { return NS_OK; }
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
nsIContent* aContent1,
nsIContent* aContent2) { return NS_OK; }
// This one we care about; see implementation below.
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer) { return NS_OK; }
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) { return NS_OK; }
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer) { return NS_OK; }
NS_IMETHOD ContentRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) { return NS_OK; }
NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
PRBool aDisabled) { return NS_OK; }
NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule,
PRInt32 aHint) { return NS_OK; }
NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) { return NS_OK; }
NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) { return NS_OK; }
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument) { return NS_OK; }
// nsUnknownContentDialog stuff
nsUnknownContentDialog( nsIURI *aURL, const char *aContentType, nsIDocumentLoader *aDocLoader )
: mUrl( aURL ),
mContentType( aContentType ),
mDocLoader( aDocLoader ) {
NS_INIT_REFCNT();
}
virtual ~nsUnknownContentDialog() {
}
void SetWindow( nsIWebShellWindow *aWindow ) {
mWindow = aWindow;
}
void OnSave();
void OnMore();
void OnPick();
void OnClose() {
if ( mWindow ) {
mWindow->Close();
}
}
private:
nsCOMPtr<nsIURI> mUrl;
nsCOMPtr<nsIWebShell> mWebShell;
nsCOMPtr<nsIWebShellWindow> mWindow;
nsString mContentType;
nsCOMPtr<nsIDocumentLoader> mDocLoader;
nsInstanceCounter mInstanceCounter;
}; // nsUnknownContentDialog
// Standard implementations of addref/release.
NS_IMPL_ADDREF( nsUnknownContentDialog );
NS_IMPL_RELEASE( nsUnknownContentDialog );
// QueryInterface implementation for nsUnknownContentTypeDialog.
NS_IMETHODIMP
nsUnknownContentDialog::QueryInterface(REFNSIID aIID,void** aInstancePtr)
{
if (aInstancePtr == NULL) {
return NS_ERROR_NULL_POINTER;
}
// Always NULL result, in case of failure
*aInstancePtr = NULL;
if (aIID.Equals(nsIDocumentObserver::GetIID())) {
*aInstancePtr = (void*) ((nsIDocumentObserver*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(nsIXULWindowCallbacks::GetIID())) {
*aInstancePtr = (void*) ((nsIXULWindowCallbacks*)this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_ERROR_NO_INTERFACE;
}
// HandleUnknownContentType (from nsIUnknownContentTypeHandler) implementation.
NS_IMETHODIMP
nsUnknownContentTypeHandler::HandleUnknownContentType( nsIChannel *aURL,
nsUnknownContentTypeHandler::HandleUnknownContentType( nsIChannel *aChannel,
const char *aContentType,
nsIDocumentLoader *aDocLoader ) {
nsresult rv = NS_OK;
// Make sure we've been initialized.
if ( GetAppShell() ) {
// Open "Unknown file type" dialog.
nsCOMPtr<nsIWebShellWindow> newWindow;
// Make url for dialog xul.
nsIURI *url;
char * urlStr = "resource:/res/samples/unknownContent.xul";
#ifndef NECKO
rv = NS_NewURL( &url, urlStr );
#else
NS_WITH_SERVICE(nsIIOService, service, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsIURI *uri = nsnull;
rv = service->NewURI(urlStr, nsnull, &uri);
if (NS_FAILED(rv)) return rv;
rv = uri->QueryInterface(nsIURI::GetIID(), (void**)&url);
NS_RELEASE(uri);
#endif // NECKO
if ( NS_SUCCEEDED(rv) ) {
// Create "save to disk" nsIXULCallbacks...
#ifndef NECKO
nsUnknownContentDialog *dialog = new nsUnknownContentDialog( aURL, aContentType, aDocLoader );
#else
nsCOMPtr<nsIURI>channelUri = nsnull;
rv = aURL->GetURI(getter_AddRefs(channelUri));
nsUnknownContentDialog *dialog = new nsUnknownContentDialog( channelUri, aContentType, aDocLoader );
#endif // NECKO
rv = GetAppShell()->CreateTopLevelWindow( nsnull,
url,
PR_TRUE,
getter_AddRefs(newWindow),
nsnull,
dialog,
0, 0 );
// Give find dialog the window pointer (if it worked).
if ( NS_SUCCEEDED(rv) ) {
dialog->SetWindow( newWindow );
}
NS_RELEASE(url);
}
} else {
rv = NS_ERROR_NOT_INITIALIZED;
nsIDOMWindow *aWindow ) {
if ( !aWindow ) {
return NS_ERROR_NULL_POINTER;
}
return rv;
}
#if defined( NS_DEBUG ) && !defined( XP_MAC )
#define DEBUG_PRINTF PR_fprintf
#else
#define DEBUG_PRINTF (void)
#endif
// Do startup stuff from C++ side.
NS_IMETHODIMP
nsUnknownContentDialog::ConstructBeforeJavaScript( nsIWebShell *aWebShell ) {
nsresult rv = NS_OK;
// Save web shell pointer.
mWebShell = aWebShell;
// Open "Unknown content type" dialog.
// We pass in the url and the content type.
// Note that the "parent" browser window will be window.opener within the
// new dialog.
// Add as observer of the xul document.
nsCOMPtr<nsIContentViewer> cv;
rv = mWebShell->GetContentViewer(getter_AddRefs(cv));
if ( cv ) {
// Up-cast.
nsCOMPtr<nsIDocumentViewer> docv(do_QueryInterface(cv));
if ( docv ) {
// Get the document from the doc viewer.
nsCOMPtr<nsIDocument> doc;
rv = docv->GetDocument(*getter_AddRefs(doc));
if ( doc ) {
// Add this as observer.
doc->AddObserver( this );
#ifndef NECKO
// nsIChannel is really an nsIURI, I guess.
nsIChannel *channelUri = aChannel;
// Store instance information into dialog's DOM.
nsCOMPtr<nsIDOMXULDocument> xulDoc( do_QueryInterface(doc) ); // up cast
if ( xulDoc ) {
// Set data.location value attribute to the url.
nsCOMPtr<nsIDOMElement> location;
rv = xulDoc->GetElementById( "data.location", getter_AddRefs(location) );
if ( location ) {
// url string is const in this case.
const char *urlStr = 0;
#else // NECKO
// Extract URI from channel.
nsCOMPtr<nsIURI> channelUri = nsnull;
rv = aChannel->GetURI(getter_AddRefs(channelUri));
if ( NS_FAILED( rv ) ) {
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetURI failed, rv=0x%08X\n",
(char*)__FILE__, (int)__LINE__, (int)rv );
return rv;
}
// url string non-const in this case.
char *urlStr = 0;
#endif // NECKO
// Get url string from channel.
channelUri->GetSpec( &urlStr );
// Get JS context from parent window.
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface( aWindow, &rv );
if ( NS_SUCCEEDED( rv ) && sgo ) {
nsCOMPtr<nsIScriptContext> context;
sgo->GetContext( getter_AddRefs( context ) );
if ( context ) {
JSContext *jsContext = (JSContext*)context->GetNativeContext();
if ( jsContext ) {
void *stackPtr;
jsval *argv = JS_PushArguments( jsContext,
&stackPtr,
"svsss",
"resource:/res/samples/unknownContent.xul",
JSVAL_NULL,
"chrome",
urlStr,
aContentType );
#ifdef NECKO
char *loc = 0;
mUrl->GetSpec( &loc );
rv = location->SetAttribute( "value", loc );
nsCRT::free(loc);
#else
const char *loc = 0;
mUrl->GetSpec( &loc );
rv = location->SetAttribute( "value", loc );
#endif
if ( NS_SUCCEEDED( rv ) ) {
// Set data.contentType value attribute to the content type.
nsCOMPtr<nsIDOMElement> contentType;
rv = xulDoc->GetElementById( "data.contentType", getter_AddRefs(contentType) );
if ( contentType ) {
rv = contentType->SetAttribute( "value", mContentType );
if ( NS_SUCCEEDED( rv ) ) {
// Set dialog.start value attribute to trigger onLoad().
nsCOMPtr<nsIDOMElement> trigger;
rv = xulDoc->GetElementById( "dialog.start", getter_AddRefs(trigger) );
if ( trigger ) {
rv = trigger->SetAttribute( "ready", "true" );
if ( NS_SUCCEEDED( rv ) ) {
} else {
DEBUG_PRINTF( PR_STDOUT, "SetAttribute failed, rv=0x%X\n", (int)rv );
}
} else {
DEBUG_PRINTF( PR_STDOUT, "GetElementById failed, rv=0x%X\n", (int)rv );
}
} else {
DEBUG_PRINTF( PR_STDOUT, "SetAttribute failed, rv=0x%X\n", (int)rv );
}
} else {
DEBUG_PRINTF( PR_STDOUT, "GetElementById failed, rv=0x%X\n", (int)rv );
}
} else {
DEBUG_PRINTF( PR_STDOUT, "SetAttribute failed, rv=0x%X\n", (int)rv );
}
// Free url string.
nsCRT::free(urlStr);
#endif // NECKO
if ( argv ) {
nsIDOMWindow *newWindow;
rv = aWindow->OpenDialog( jsContext, argv, 5, &newWindow );
if ( NS_SUCCEEDED( rv ) ) {
newWindow->Release();
} else {
DEBUG_PRINTF( PR_STDOUT, "GetElementById failed, rv=0x%X\n", (int)rv );
DEBUG_PRINTF( PR_STDOUT, "%s %d: OpenDialog failed, rv=0x%08X\n",
(char*)__FILE__, (int)__LINE__, (int)rv );
}
JS_PopArguments( jsContext, stackPtr );
} else {
DEBUG_PRINTF( PR_STDOUT, "Upcast to nsIDOMXULDocument failed\n" );
DEBUG_PRINTF( PR_STDOUT, "%s %d: JS_PushArguments failed\n",
(char*)__FILE__, (int)__LINE__ );
rv = NS_ERROR_FAILURE;
}
} else {
DEBUG_PRINTF( PR_STDOUT, "GetDocument failed, rv=0x%X\n", (int)rv);
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetNativeContext failed\n",
(char*)__FILE__, (int)__LINE__ );
rv = NS_ERROR_FAILURE;
}
} else {
DEBUG_PRINTF( PR_STDOUT, "Upcast to nsIDocumentViewer failed\n" );
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetContext failed\n",
(char*)__FILE__, (int)__LINE__ );
rv = NS_ERROR_FAILURE;
}
} else {
DEBUG_PRINTF( PR_STDOUT, "GetContentViewer failed, rv=0x%X\n", (int)rv);
DEBUG_PRINTF( PR_STDOUT, "%s %d: QueryInterface (for nsIScriptGlobalObject) failed, rv=0x%08X\n",
(char*)__FILE__, (int)__LINE__, (int)rv );
}
return rv;
}
// Handle attribute changing; we only care about the element "data.execute"
// which is used to signal command execution from the UI.
NS_IMETHODIMP
nsUnknownContentDialog::AttributeChanged( nsIDocument *aDocument,
nsIContent* aContent,
nsIAtom* aAttribute,
PRInt32 aHint ) {
nsresult rv = NS_OK;
// Look for data.execute command changing.
nsString id;
nsCOMPtr<nsIAtom> atomId = nsDontQueryInterface<nsIAtom>( NS_NewAtom("id") );
aContent->GetAttribute( kNameSpaceID_None, atomId, id );
if ( id == "data.execute" ) {
nsString cmd;
nsCOMPtr<nsIAtom> atomCommand = nsDontQueryInterface<nsIAtom>( NS_NewAtom("command") );
// Get requested command.
aContent->GetAttribute( kNameSpaceID_None, atomCommand, cmd );
// Reset (immediately, to prevent feedback loop).
aContent->SetAttribute( kNameSpaceID_None, atomCommand, "", PR_FALSE );
if ( cmd == "save" ) {
OnSave();
} else if ( cmd == "more" ) {
OnMore();
} else if ( cmd == "pick" ) {
OnPick();
} else if ( cmd == "close" ) {
OnClose();
} else {
}
}
return rv;
}
static NS_DEFINE_IID( kAppShellServiceCID, NS_APPSHELL_SERVICE_CID );
// OnMore: Go to netcenter 'plugin picker" page.
void
nsUnknownContentDialog::OnMore() {
if ( mDocLoader ) {
nsCOMPtr<nsIContentViewerContainer> container;
nsresult rv = mDocLoader->GetContainer( getter_AddRefs( container ) );
if ( NS_SUCCEEDED( rv ) ) {
nsCOMPtr<nsIWebShell> webShell;
rv = container->QueryInterface( nsIWebShell::GetIID(),
(void**)getter_AddRefs( webShell ) );
if ( NS_SUCCEEDED( rv ) ) {
nsString moreUrl = "http://cgi.netscape.com/cgi-bin/plug-in_finder.cgi?";
moreUrl += mContentType;
webShell->LoadURL( moreUrl.GetUnicode() );
}
}
}
}
// OnPick: Launch (platform specific) app picker.
void
nsUnknownContentDialog::OnPick() {
DEBUG_PRINTF( PR_STDOUT, "nsUnknownContentdialog::OnPick() not implemented yet\n" );
}
// OnSave: Pass on the URL to the "stream xfer" component.
void
nsUnknownContentDialog::OnSave() {
nsresult rv = NS_OK;
// Get "stream xfer component".
nsIStreamTransfer *xfer;
rv = nsAppShellComponentImpl::mServiceMgr->GetService( NS_ISTREAMTRANSFER_PROGID,
nsIStreamTransfer::GetIID(),
(nsISupports**)&xfer );
if ( NS_SUCCEEDED( rv ) ) {
// Have the component stream the url to a user-selected file.
rv = xfer->SelectFileAndTransferLocation( mUrl );
if ( NS_SUCCEEDED( rv ) ) {
// Close this dialog.
mWindow->Close();
} else {
DEBUG_PRINTF( PR_STDOUT, "%s %d: Error saving file, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
}
nsAppShellComponentImpl::mServiceMgr->ReleaseService( NS_ISTREAMTRANSFER_PROGID, xfer );
} else {
DEBUG_PRINTF( PR_STDOUT, "Unable to get stream transfer, GetService rv=0x%X\n", (int)rv );
}
return;
}
// Generate base nsIAppShellComponent implementation.
NS_IMPL_IAPPSHELLCOMPONENT( nsUnknownContentTypeHandler,

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

@ -50,6 +50,7 @@ interface nsIStreamTransfer : nsIAppShellComponent {
| dialog. |
--------------------------------------------------------------------------*/
void SelectFileAndTransferLocation( in nsIURI aURL );
void SelectFileAndTransferLocationSpec( in string aURL );
};
@ -57,5 +58,6 @@ interface nsIStreamTransfer : nsIAppShellComponent {
#define NS_ISTREAMTRANSFER_PROGID NS_IAPPSHELLCOMPONENT_PROGID "/xfer"
#define NS_ISTREAMTRANSFER_CLASSNAME "Mozilla Stream Transfer Component"
#define NS_DECL_ISTREAMTRANSFER \
NS_IMETHOD SelectFileAndTransferLocation( nsIURI *aURL );
NS_IMETHOD SelectFileAndTransferLocation( nsIURI* ); \
NS_IMETHOD SelectFileAndTransferLocationSpec( char const* );
%}

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

@ -1,6 +1,5 @@
<?xml version="1.0"?>
<?xml-stylesheet href="xul.css" type="text/css"?>
<?xml-stylesheet href="downloadProgress.css" type="text/css"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE window
[

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

@ -83,6 +83,26 @@ nsStreamTransfer::SelectFileAndTransferLocation( nsIURI *aURL ) {
return rv;
}
NS_IMETHODIMP
nsStreamTransfer::SelectFileAndTransferLocationSpec( char const *aURL ) {
nsresult rv = NS_OK;
// Construct URI from spec.
nsIURI *uri;
#ifndef NECKO
rv = NS_NewURL( &uri, aURL );
#else // NECKO
rv = NS_NewURI( &uri, aURL );
#endif // NECKO
if ( NS_SUCCEEDED( rv ) && uri ) {
rv = this->SelectFileAndTransferLocation( uri );
NS_RELEASE( uri );
}
return rv;
}
NS_IMETHODIMP
nsStreamTransfer::SelectFile( nsFileSpec &aResult ) {
nsresult rv = NS_OK;