Split nsIHandlerInfo.launchWithURI into nsIHandlerInfo.launchWithURI and nsIMIMEInfo.launchWithFile (bug 391194) r=cbiesinger@gmx.at, sr=bzbarsky@mit.edu

This commit is contained in:
dmose@mozilla.org 2007-08-20 17:47:47 -07:00
Родитель 45eef8675c
Коммит ab74de52a8
6 изменённых файлов: 138 добавлений и 95 удалений

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

@ -99,9 +99,14 @@ interface nsIHandlerInfo : nsISupports {
* Launches the application with the specified URI, in a way that
* depends on the value of preferredAction. preferredAction must be
* useHelperApp or useSystemDefault.
*
* @note Only the URI scheme is used to determine how to launch. This is
* essentially a pass-by-value operation. This means that in the case of
* a file: URI, the handler that is registered for file: will be launched
* and our code will not make any decision based on the content-type or
* extension, though the invoked file: handler is free to do so.
*
* @param aURI The URI to launch this application with; this may or may
* not be a local file.
* @param aURI The URI to launch this application with
*
* @throw NS_ERROR_INVALID_ARG if action is not valid for this function.
* Other exceptions may be thrown.
@ -142,7 +147,7 @@ interface nsIHandlerInfo : nsISupports {
* MIMEInfo objects are generally retrieved from the MIME Service
* @see nsIMIMEService
*/
[scriptable, uuid(ba01eb13-c2fd-4652-94f8-b33c61e6d77e)]
[scriptable, uuid(a4011016-81a1-47d9-b01e-19a2272ae89b)]
interface nsIMIMEInfo : nsIHandlerInfo {
/**
* Gives you an array of file types associated with this type.
@ -200,6 +205,18 @@ interface nsIMIMEInfo : nsIHandlerInfo {
* @returns PR_TRUE if the two are considered equal
*/
boolean equals(in nsIMIMEInfo aMIMEInfo);
/**
* Launches the application with the specified file, in a way that
* depends on the value of preferredAction. preferredAction must be
* useHelperApp or useSystemDefault.
*
* @param aFile The file to launch this application with.
*
* @throw NS_ERROR_INVALID_ARG if action is not valid for this function.
* Other exceptions may be thrown.
*/
void launchWithFile(in nsIFile aFile);
};
/**

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

@ -46,12 +46,71 @@
#include "nsIFileURL.h"
#include "nsIInternetConfigService.h"
NS_IMETHODIMP
nsMIMEInfoMac::LaunchWithFile(nsIFile *aFile)
{
nsCOMPtr<nsIFile> application;
nsresult rv;
NS_ASSERTION(mClass == eMIMEInfo, "only MIME infos are currently allowed"
"to pass content by value");
if (mPreferredAction == useHelperApp) {
// we don't yet support passing content by value (rather than reference)
// to web apps. at some point, we will probably want to.
nsCOMPtr<nsILocalHandlerApp> localHandlerApp =
do_QueryInterface(mPreferredApplication, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = localHandlerApp->GetExecutable(getter_AddRefs(application));
NS_ENSURE_SUCCESS(rv, rv);
} else if (mPreferredAction == useSystemDefault) {
application = mDefaultApplication;
}
else
return NS_ERROR_INVALID_ARG;
// if we've already got an app, just QI so we have the launchWithDoc method
nsCOMPtr<nsILocalFileMac> app;
if (application) {
app = do_QueryInterface(application, &rv);
if (NS_FAILED(rv)) return rv;
} else {
// otherwise ask LaunchServices for an app directly
nsCOMPtr<nsILocalFileMac> tempFile = do_QueryInterface(aFile, &rv);
if (NS_FAILED(rv)) return rv;
FSRef tempFileRef;
tempFile->GetFSRef(&tempFileRef);
FSRef appFSRef;
if (::LSGetApplicationForItem(&tempFileRef, kLSRolesAll, &appFSRef, nsnull) == noErr)
{
app = (do_CreateInstance("@mozilla.org/file/local;1"));
if (!app) return NS_ERROR_FAILURE;
app->InitWithFSRef(&appFSRef);
} else {
return NS_ERROR_FAILURE;
}
}
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(aFile);
return app->LaunchWithDoc(localFile, PR_FALSE);
}
NS_IMETHODIMP
nsMIMEInfoMac::LaunchWithURI(nsIURI* aURI)
{
nsCOMPtr<nsIFile> application;
nsresult rv;
// for now, this is only being called with protocol handlers; that
// will change once we get to more general registerContentHandler
// support
NS_ASSERTION(mClass == eProtocolInfo,
"nsMIMEInfoBase should be a protocol handler");
if (mPreferredAction == useHelperApp) {
// check for and launch with web handler app
@ -68,66 +127,18 @@ nsMIMEInfoMac::LaunchWithURI(nsIURI* aURI)
rv = localHandlerApp->GetExecutable(getter_AddRefs(application));
NS_ENSURE_SUCCESS(rv, rv);
} else if (mPreferredAction == useSystemDefault) {
// because nsMIMEInfoMac isn't yet set up with mDefaultApplication
// in the protocol handler case, we need to do it another way for now
// (which is fine, but this code would be a little more readable if we
// could fall through this case).
if (mClass == eProtocolInfo) {
return LoadUriInternal(aURI);
}
application = mDefaultApplication;
}
else
return NS_ERROR_INVALID_ARG;
// get the nsILocalFile version of the doc to launch with
nsCOMPtr<nsILocalFile> docToLoad;
rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
if (NS_FAILED(rv)) {
// If we don't have a file, we must be a protocol handler
NS_ASSERTION(mClass == eProtocolInfo,
"nsMIMEInfoMac should be a protocol handler");
// so pass the entire URI to the handler.
// pass the entire URI to the handler.
nsCAutoString spec;
aURI->GetSpec(spec);
return OpenApplicationWithURI(application, spec);
}
// note that the file pointed to by docToLoad could possibly have originated
// as a file: URI if we're in some non-browser application.
}
// if we've already got an app, just QI so we have the launchWithDoc method
nsCOMPtr<nsILocalFileMac> app;
if (application) {
app = do_QueryInterface(application, &rv);
if (NS_FAILED(rv)) return rv;
} else {
// otherwise ask LaunchServices for an app directly
nsCOMPtr<nsILocalFileMac> tempFile = do_QueryInterface(docToLoad, &rv);
if (NS_FAILED(rv)) return rv;
FSRef tempFileRef;
tempFile->GetFSRef(&tempFileRef);
FSRef appFSRef;
if (::LSGetApplicationForItem(&tempFileRef, kLSRolesAll, &appFSRef, nsnull) == noErr)
{
app = (do_CreateInstance("@mozilla.org/file/local;1"));
if (!app) return NS_ERROR_FAILURE;
app->InitWithFSRef(&appFSRef);
} else {
return NS_ERROR_FAILURE;
}
if (mPreferredAction == useSystemDefault) {
return LoadUriInternal(aURI);
}
return app->LaunchWithDoc(docToLoad, PR_FALSE);
return NS_ERROR_INVALID_ARG;
}
nsresult

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

@ -47,6 +47,7 @@ class nsMIMEInfoMac : public nsMIMEInfoImpl {
nsMIMEInfoImpl(aType, aClass) {}
NS_IMETHOD LaunchWithURI(nsIURI* aURI);
NS_IMETHOD LaunchWithFile(nsIFile* aFile);
NS_IMETHOD GetHasDefaultHandler(PRBool *_retval);
protected:
virtual NS_HIDDEN_(nsresult) LoadUriInternal(nsIURI *aURI);

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

@ -2497,11 +2497,7 @@ nsresult nsExternalAppHandler::OpenWithApplication()
// if a stop request was already issued then proceed with launching the application.
if (mStopRequestIssued)
{
nsCOMPtr<nsIURI> fileUri;
rv = NS_NewFileURI(getter_AddRefs(fileUri), mFinalFileDestination);
if (NS_SUCCEEDED(rv)) {
rv = mMimeInfo->LaunchWithURI(fileUri);
}
rv = mMimeInfo->LaunchWithFile(mFinalFileDestination);
if (NS_FAILED(rv))
{
// Send error notification.
@ -2572,7 +2568,7 @@ NS_IMETHODIMP nsExternalAppHandler::LaunchWithApplication(nsIFile * aApplication
if (NS_SUCCEEDED(rv))
{
rv = mMimeInfo->LaunchWithURI(fileUrl);
rv = mMimeInfo->LaunchWithFile(file);
if (NS_SUCCEEDED(rv))
return NS_OK;
}

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

@ -345,13 +345,55 @@ nsMIMEInfoBase::GetLocalFileFromURI(nsIURI *aURI, nsILocalFile **aFile)
return CallQueryInterface(file, aFile);
}
NS_IMETHODIMP
nsMIMEInfoBase::LaunchWithFile(nsIFile* aFile)
{
nsresult rv;
// it doesn't make any sense to call this on protocol handlers
NS_ASSERTION(mClass == eMIMEInfo,
"nsMIMEInfoBase should have mClass == eMIMEInfo");
if (mPreferredAction == useSystemDefault) {
return LaunchDefaultWithFile(aFile);
}
if (mPreferredAction == useHelperApp) {
if (!mPreferredApplication)
return NS_ERROR_FILE_NOT_FOUND;
// at the moment, we only know how to hand files off to local handlers
nsCOMPtr<nsILocalHandlerApp> localHandler =
do_QueryInterface(mPreferredApplication, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFile> executable;
rv = localHandler->GetExecutable(getter_AddRefs(executable));
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString path;
aFile->GetNativePath(path);
return LaunchWithIProcess(executable, path);
}
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP
nsMIMEInfoBase::LaunchWithURI(nsIURI* aURI)
{
nsCOMPtr<nsILocalFile> docToLoad;
nsresult rv;
// for now, this is only being called with protocol handlers; that
// will change once we get to more general registerContentHandler
// support
NS_ASSERTION(mClass == eProtocolInfo,
"nsMIMEInfoBase should be a protocol handler");
if (mPreferredAction == useSystemDefault) {
return LoadUriInternal(aURI);
}
if (mPreferredAction == useHelperApp) {
if (!mPreferredApplication)
return NS_ERROR_FILE_NOT_FOUND;
@ -372,36 +414,11 @@ nsMIMEInfoBase::LaunchWithURI(nsIURI* aURI)
rv = localHandler->GetExecutable(getter_AddRefs(executable));
NS_ENSURE_SUCCESS(rv, rv);
// get the nsILocalFile version of the doc to launch with
rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
if (NS_FAILED(rv)) {
// If we don't have a file, we must be a protocol handler
NS_ASSERTION(mClass == eProtocolInfo,
"nsMIMEInfoBase should be a protocol handler");
// so pass the entire URI to the handler.
nsCAutoString spec;
aURI->GetSpec(spec);
return LaunchWithIProcess(executable, spec);
}
// note that the file pointed to by docToLoad could possibly have
// originated as a file: URI if we're in some non-browser application.
nsCAutoString path;
docToLoad->GetNativePath(path);
return LaunchWithIProcess(executable, path);
}
else if (mPreferredAction == useSystemDefault) {
if (mClass == eProtocolInfo)
return LoadUriInternal(aURI);
rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
NS_ENSURE_SUCCESS(rv, rv);
return LaunchDefaultWithFile(docToLoad);
}
// pass the entire URI to the handler.
nsCAutoString spec;
aURI->GetSpec(spec);
return LaunchWithIProcess(executable, spec);
}
return NS_ERROR_INVALID_ARG;
}

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

@ -88,6 +88,7 @@ class nsMIMEInfoBase : public nsIMIMEInfo {
NS_IMETHOD SetPreferredApplicationHandler(nsIHandlerApp * aPreferredAppHandler);
NS_IMETHOD GetPossibleApplicationHandlers(nsIMutableArray * *aPossibleAppHandlers);
NS_IMETHOD GetDefaultDescription(nsAString & aDefaultDescription);
NS_IMETHOD LaunchWithFile(nsIFile *aFile);
NS_IMETHOD LaunchWithURI(nsIURI *aURI);
NS_IMETHOD GetPreferredAction(nsHandlerInfoAction *aPreferredAction);
NS_IMETHOD SetPreferredAction(nsHandlerInfoAction aPreferredAction);