Change nsIHandlerInfo::LaunchWithFile to be launchWithURI (bug 386078), r+sr=biesi

This commit is contained in:
dmose@mozilla.org 2007-07-17 15:59:58 -07:00
parent df5d9ed078
commit f17228f4ff
8 changed files with 142 additions and 63 deletions

View File

@ -49,7 +49,7 @@ typedef long nsHandlerInfoAction;
* nsIHandlerInfo gives access to the information about how a given protocol
* scheme or MIME-type is handled.
*/
[scriptable, uuid(feaa5a46-45aa-4124-8e9e-bc23d517c2d4)]
[scriptable, uuid(2ec1216d-59e7-424c-aa1e-70aa3c897520)]
interface nsIHandlerInfo : nsISupports {
/**
* A human readable description of the handler type
@ -76,16 +76,17 @@ interface nsIHandlerInfo : nsISupports {
readonly attribute AString defaultDescription;
/**
* Launches the application with the specified file, in a way that
* Launches the application with the specified URI, 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.
* @param aURI The URI to launch this application with; this may or may
* not be a local file.
*
* @throw NS_ERROR_INVALID_ARG if action is not valid for this function.
* Other exceptions may be thrown.
*/
void launchWithFile(in nsIFile aFile);
void launchWithURI(in nsIURI aURI);
/**
* preferredAction is how the user specified they would like to handle

View File

@ -23,6 +23,7 @@
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
* Christian Biesinger <cbiesinger@web.de>
* Dan Mosedale <dmose@mozilla.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -42,56 +43,64 @@
#include "nsMIMEInfoMac.h"
#include "nsILocalFileMac.h"
#include "nsIFileURL.h"
NS_IMETHODIMP
nsMIMEInfoMac::LaunchWithFile(nsIFile* aFile)
nsMIMEInfoMac::LaunchWithURI(nsIURI* aURI)
{
nsCOMPtr<nsIFile> application;
nsresult rv;
if (mPreferredAction == useHelperApp) {
nsresult rv;
nsCOMPtr<nsILocalHandlerApp> localHandlerApp =
// check for and launch with web handler app
nsCOMPtr<nsIWebHandlerApp> webHandlerApp =
do_QueryInterface(mPreferredApplication, &rv);
if (NS_SUCCEEDED(rv)) {
return LaunchWithWebHandler(webHandlerApp, aURI);
}
// otherwise, get the application executable from the handler
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 (application) {
nsresult rv;
nsCOMPtr<nsILocalFileMac> app = do_QueryInterface(application, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsILocalFile> docToLoad = do_QueryInterface(aFile, &rv);
if (NS_FAILED(rv)) return rv;
return app->LaunchWithDoc(docToLoad, PR_FALSE);
}
#ifdef XP_MACOSX
// We didn't get an application to handle the file from aMIMEInfo, ask LaunchServices directly
nsresult rv;
nsCOMPtr <nsILocalFileMac> tempFile = do_QueryInterface(aFile, &rv);
// get the nsILocalFile version of the doc to launch with
nsCOMPtr<nsILocalFile> docToLoad;
rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
if (NS_FAILED(rv)) return rv;
FSRef tempFileRef;
tempFile->GetFSRef(&tempFileRef);
FSRef appFSRef;
if (::LSGetApplicationForItem(&tempFileRef, kLSRolesAll, &appFSRef, nsnull) == noErr)
{
nsCOMPtr<nsILocalFileMac> app(do_CreateInstance("@mozilla.org/file/local;1"));
if (!app) return NS_ERROR_FAILURE;
app->InitWithFSRef(&appFSRef);
nsCOMPtr <nsILocalFile> docToLoad = do_QueryInterface(aFile, &rv);
// 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;
rv = app->LaunchWithDoc(docToLoad, PR_FALSE);
} 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;
}
}
return rv;
#endif
return app->LaunchWithDoc(docToLoad, PR_FALSE);
}

View File

@ -44,7 +44,7 @@ class nsMIMEInfoMac : public nsMIMEInfoImpl {
nsMIMEInfoMac(const char* aMIMEType = "") : nsMIMEInfoImpl(aMIMEType) {}
nsMIMEInfoMac(const nsACString& aMIMEType) : nsMIMEInfoImpl(aMIMEType) {}
NS_IMETHOD LaunchWithFile(nsIFile* aFile);
NS_IMETHOD LaunchWithURI(nsIURI* aURI);
#ifdef DEBUG
protected:

View File

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

View File

@ -41,6 +41,8 @@
#include "nsReadableUtils.h"
#include "nsStringEnumerator.h"
#include "nsIProcess.h"
#include "nsILocalFile.h"
#include "nsIFileURL.h"
// nsISupports methods
NS_IMPL_THREADSAFE_ISUPPORTS2(nsMIMEInfoBase, nsIMIMEInfo, nsIHandlerInfo)
@ -276,26 +278,59 @@ nsMIMEInfoBase::SetAlwaysAskBeforeHandling(PRBool aAlwaysAsk)
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoBase::LaunchWithFile(nsIFile* aFile)
/* static */
nsresult
nsMIMEInfoBase::GetLocalFileFromURI(nsIURI *aURI, nsILocalFile **aFile)
{
nsresult rv;
nsCOMPtr<nsIFileURL> fileUrl = do_QueryInterface(aURI, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIFile> file;
rv = fileUrl->GetFile(getter_AddRefs(file));
if (NS_FAILED(rv)) return rv;
return CallQueryInterface(file, aFile);
}
NS_IMETHODIMP
nsMIMEInfoBase::LaunchWithURI(nsIURI* aURI)
{
nsCOMPtr<nsILocalFile> docToLoad;
nsresult rv;
if (mPreferredAction == useHelperApp) {
if (!mPreferredApplication)
return NS_ERROR_FILE_NOT_FOUND;
nsCOMPtr<nsILocalHandlerApp> localHandler;
nsresult rv;
localHandler = do_QueryInterface(mPreferredApplication, &rv);
// check for and possibly launch with web application
nsCOMPtr<nsIWebHandlerApp> webHandler =
do_QueryInterface(mPreferredApplication, &rv);
if (NS_SUCCEEDED(rv)) {
return LaunchWithWebHandler(webHandler, aURI);
}
// ok, we must have a local handler app
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);
return LaunchWithIProcess(executable, aFile);
rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
NS_ENSURE_SUCCESS(rv, rv);
return LaunchWithIProcess(executable, docToLoad);
}
else if (mPreferredAction == useSystemDefault) {
return LaunchDefaultWithFile(aFile);
rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
NS_ENSURE_SUCCESS(rv, rv);
return LaunchDefaultWithFile(docToLoad);
}
return NS_ERROR_INVALID_ARG;
@ -335,6 +370,14 @@ nsMIMEInfoBase::LaunchWithIProcess(nsIFile* aApp, nsIFile* aFile)
return process->Run(PR_FALSE, &strPath, 1, &pid);
}
/* static */
nsresult
nsMIMEInfoBase::LaunchWithWebHandler(nsIWebHandlerApp *aApp, nsIURI *aURI)
{
// we'll be implementing this Real Soon Now!
return NS_ERROR_NOT_IMPLEMENTED;
}
// nsMIMEInfoImpl implementation
NS_IMETHODIMP
nsMIMEInfoImpl::GetDefaultDescription(nsAString& aDefaultDescription)

View File

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et: */
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:set ts=4 sw=4 sts=4 et: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -85,7 +85,7 @@ class nsMIMEInfoBase : public nsIMIMEInfo {
NS_IMETHOD GetPreferredApplicationHandler(nsIHandlerApp * *aPreferredApplicationHandler);
NS_IMETHOD SetPreferredApplicationHandler(nsIHandlerApp * aPreferredApplicationHandler);
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);
NS_IMETHOD GetAlwaysAskBeforeHandling(PRBool *aAlwaysAskBeforeHandling);
@ -137,6 +137,23 @@ class nsMIMEInfoBase : public nsIMIMEInfo {
*/
static NS_HIDDEN_(nsresult) LaunchWithIProcess(nsIFile* aApp, nsIFile* aFile);
/**
* Used to launch a web-based handler with this URI.
*
* @param aURI The URI to launch with.
*/
static NS_HIDDEN_(nsresult) LaunchWithWebHandler(nsIWebHandlerApp *aApp,
nsIURI *aURI);
/**
* Given a file: nsIURI, return the associated nsILocalFile
*
* @param aURI the file: URI in question
* @param aFile the associated nsILocalFile (out param)
*/
static NS_HIDDEN_(nsresult) GetLocalFileFromURI(nsIURI *aURI,
nsILocalFile **aFile);
// member variables
nsCStringArray mExtensions; ///< array of file extensions associated w/ this MIME obj
nsString mDescription; ///< human readable description
@ -154,8 +171,9 @@ class nsMIMEInfoBase : public nsIMIMEInfo {
* This is a complete implementation of nsIMIMEInfo, and contains all necessary
* methods. However, depending on your platform you may want to use a different
* way of launching applications. This class stores the default application in a
* member variable and provides a function for setting it. Launching is done
* using nsIProcess, native path of the file to open as first argument.
* member variable and provides a function for setting it. For local
* applications, launching is done using nsIProcess, native path of the file to
* open as first argument.
*/
class nsMIMEInfoImpl : public nsMIMEInfoBase {
public:

View File

@ -63,13 +63,17 @@ nsMIMEInfoOS2::~nsMIMEInfoOS2()
{
}
NS_IMETHODIMP nsMIMEInfoOS2::LaunchWithFile(nsIFile* aFile)
NS_IMETHODIMP nsMIMEInfoOS2::LaunchWithURI(nsIFile* aURI)
{
nsresult rv = NS_OK;
nsCAutoString path;
aFile->GetNativePath(path);
nsCOMPtr<nsILocalFile> docToLoad;
rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString path;
docToLoad->GetNativePath(path);
nsCOMPtr<nsIFile> application;
if (mPreferredAction == useHelperApp) {
nsCOMPtr<nsILocalHandlerApp> localHandlerApp =
@ -108,7 +112,7 @@ NS_IMETHODIMP nsMIMEInfoOS2::LaunchWithFile(nsIFile* aFile)
if (helperAppService)
{
nsCAutoString leafName;
aFile->GetNativeLeafName(leafName);
docToLoad->GetNativeLeafName(leafName);
const char* lastDot = strrchr(leafName.get(), '.');
char suffix[CCHMAXPATH + 1] = "";
if (lastDot)
@ -130,10 +134,10 @@ NS_IMETHODIMP nsMIMEInfoOS2::LaunchWithFile(nsIFile* aFile)
saltedTempLeafName.Append(table[(rand()%TABLE_SIZE)]);
}
AppendASCIItoUTF16(suffix, saltedTempLeafName);
rv = aFile->MoveTo(nsnull, saltedTempLeafName);
rv = docToLoad->MoveTo(nsnull, saltedTempLeafName);
} while (NS_FAILED(rv));
helperAppService->DeleteTemporaryFileOnExit(aFile);
aFile->GetNativePath(path);
helperAppService->DeleteTemporaryFileOnExit(docToLoad);
docToLoad->GetNativePath(path);
}
} else {
path.Insert('\"', 0);

View File

@ -46,7 +46,7 @@ class nsMIMEInfoOS2 : public nsMIMEInfoImpl
nsMIMEInfoOS2(const nsACString& aMIMEType) : nsMIMEInfoImpl(aMIMEType) {}
virtual ~nsMIMEInfoOS2();
NS_IMETHOD LaunchWithFile(nsIFile* aFile);
NS_IMETHOD LaunchWithURI(nsIURI* aURI);
#ifdef DEBUG
protected: