To complicate matter a bit more, there is a _new_ nsIProcess which  allows more 
control of running applications.  Lets not add another
entrypoint on nsIFile|nsILocalFile.  Can either Spawn or, better yet, nsIProcess be 
modify for your application?

Also, I don't think that |reveal| belongs on nsILocalFile.  This seams like a higher 
level service, like a desktop or windowing interface.

I am going to cc the moz newsgroup.

Simon Fraser wrote:

> Scott MacGregor wrote:
> >
> > Here's the diff for implementing a reveal and a launch method off of
> > nsILocalFile for the mac. Launch is used to simulate double clicking the
> > file on the desktop so I'm just sending an open event.
> >
> > I have several questions as I post this code for review:
> > 1) Can I leverage LaunchAppWithDoc or LaunchDocWithApp for my open
> > event? i.e. can my launch method call one of these instead of the
> > implementation I wrote? Looking at the code I don't think so. They don't
> > appear to be posting a basic open event. But I thought I'd ask.
> > 2) All of the code in ::Lauch I got from Paul on an application he
> > worked on in the past. I don't understand what I'm doing with regards to
> > the code for creating a new FS spec for the directory containing the
> > file and then calling methods like newAlias and HLock/HUnlock.
> >
> > I guess I don't have any questions about the reveal method just the
> > above questions in launch.
>
> How does nsILocalFile.launch differ from nsIFile.spawn? They appear
> to have similar functionality, though spawn assumes that the nsIFile is
> pointing to an executable. It's odd, though, that spawn and launch
> have related functionality, yet are on different interfaces.
>
> Also, your implementation of Launch on the Mac overlaps with
> functionality provided by nsLocalFile::OpenDocWithApp(). It sends
> an AE to the Finder to launch the app. This will almost always
> have the same outcome as calling nsILocalFileMac::OpenDocWithApp()
> with a NULL aAppToOpenWith param, so it might just be easier
> (and certainly faster) to call that. Perhaps Conrad has input here.
>
> Simon
>
> >
> >   ------------------------------------------------------------------------
> > ? 2.cpp
> > ? Bug63346ForMac.diff
> > ? Debug
> > ? doug.diff
> > ? mac.diff
> > ? nsLocalFileMac.diff
> > Index: nsILocalFile.idl
> > ===================================================================
> > RCS file: /cvsroot/mozilla/xpcom/io/nsILocalFile.idl,v
> > retrieving revision 1.12
> > diff -u -r1.12 nsILocalFile.idl
> > --- nsILocalFile.idl    2000/09/19 00:22:40     1.12
> > +++ nsILocalFile.idl    2001/01/29 20:00:20
> > @@ -101,6 +101,19 @@
> >       */
> >      attribute string persistentDescriptor;
> >
> > +       /**
> > +        * reveal --> Ask the operating system to open the folder which contains
> > +        * this file or folder. This routine only works on platforms which
> > +        * support the ability to open a folder...
> > +       */
> > +       void reveal();
> > +
> > +       /**
> > +        * launch --> Ask the operating system to attempt to open the file.
> > +     * this really just simulates "double clicking" the file on your platform.
> > +        * This routine only works on platforms which support this functionality.
> > +        */
> > +       void launch();
> >  };
> >
> >  %{C++
> > Index: nsLocalFileMac.cpp
> > ===================================================================
> > RCS file: /cvsroot/mozilla/xpcom/io/nsLocalFileMac.cpp,v
> > retrieving revision 1.50
> > diff -u -r1.50 nsLocalFileMac.cpp
> > --- nsLocalFileMac.cpp  2001/01/17 20:23:06     1.50
> > +++ nsLocalFileMac.cpp  2001/01/29 20:00:20
> > @@ -51,6 +51,7 @@
> >
> >  #include <AppleEvents.h>
> >  #include <AEDataModel.h>
> > +#include <AERegistry.h>
> >
> >  #include <Math64.h>
> >  #include <Aliases.h>
> > @@ -2375,6 +2376,116 @@
> >         }
> >
> >         return NS_OK;
> > +}
> > +
> > +#define aeSelectionKeyword     'fsel'
> > +#define kAEOpenSelection       'sope'
> > +#define kAERevealSelection  'srev'
> > +#define kFinderType                    'FNDR'
> > +
> > +NS_IMETHODIMP nsLocalFile::Launch()
> > +{
> > +  AppleEvent           aeEvent = {0, nil};
> > +  AppleEvent           aeReply = {0, nil};
> > +  StAEDesc                     aeDirDesc, listElem, myAddressDesc, fileList;
> > +  FSSpec                               dirSpec, appSpec;
> > +  AliasHandle                  DirAlias, FileAlias;
> > +  OSErr                                errorResult = noErr;
> > +  ProcessSerialNumber  process;
> > +
> > +  nsresult rv = FindRunningAppBySignature ('MACS', appSpec, process);
> > +  if (NS_SUCCEEDED(rv))
> > +  {
> > +    errorResult = AECreateDesc(typeProcessSerialNumber, (Ptr)&process, 
>sizeof(process), &myAddressDesc);
> > +    if (errorResult == noErr)
> > +    {
> > +         /* Create the FinderEvent */
> > +         errorResult = AECreateAppleEvent(kFinderType, kAEOpenSelection, 
>&myAddressDesc, kAutoGenerateReturnID, kAnyTransactionID,
> > +                                                                      &aeEvent);
> > +      if (errorResult == noErr)
> > +      {
> > +        errorResult = FSMakeFSSpec(mResolvedSpec.vRefNum, mResolvedSpec.parID, 
>nil, &dirSpec);
> > +           NewAlias(nil, &dirSpec, &DirAlias);
> > +               /* Create alias for file */
> > +               NewAlias(nil, &mResolvedSpec, &FileAlias);
> > +
> > +               /* Create the file  list */
> > +                errorResult = AECreateList(nil, 0, false, &fileList);
> > +               /*  create the folder  descriptor */
> > +               HLock((Handle)DirAlias);
> > +               errorResult = AECreateDesc(typeAlias, (Ptr)*DirAlias, 
>GetHandleSize((Handle)DirAlias), &aeDirDesc);
> > +               HUnlock((Handle)DirAlias);
> > +               if (errorResult == noErr)
> > +               {
> > +                 errorResult = AEPutParamDesc(&aeEvent, keyDirectObject, 
>&aeDirDesc);
> > +                 if ( errorResult == noErr)
> > +                 {
> > +                       /*  create the file descriptor and add to aliasList */
> > +                       HLock((Handle)FileAlias);
> > +                       errorResult = AECreateDesc(typeAlias, (Ptr)*FileAlias, 
>GetHandleSize((Handle)FileAlias), &listElem);
> > +                       HLock((Handle)FileAlias);
> > +                       if (errorResult == noErr)
> > +                       {
> > +                         errorResult = AEPutDesc(&fileList, 0, &listElem);
> > +                         if (errorResult == noErr)
> > +                         {
> > +                               /* Add the file alias list to the event */
> > +                               errorResult = AEPutParamDesc(&aeEvent, 
>aeSelectionKeyword, &fileList);
> > +                           if (errorResult == noErr)
> > +                                       AESend(&aeEvent, &aeReply, kAEWaitReply + 
>kAENeverInteract
> > +                                                             + kAECanSwitchLayer, 
>kAEHighPriority, kAEDefaultTimeout, nil, nil);
> > +                         }
> > +                   }
> > +                 }
> > +           }
> > +         }
> > +       }
> > +  }
> > +
> > +       return NS_OK;
> > +}
> > +
> > +NS_IMETHODIMP nsLocalFile::Reveal()
> > +{
> > +  AppleEvent           aeEvent = {0, nil};
> > +  AppleEvent           aeReply = {0, nil};
> > +  StAEDesc                     aeDirDesc, listElem, myAddressDesc, fileList;
> > +  OSErr                                errorResult = noErr;
> > +  ProcessSerialNumber  process;
> > +  FSSpec appSpec;
> > +
> > +  nsresult rv = FindRunningAppBySignature ('MACS', appSpec, process);
> > +  if (NS_SUCCEEDED(rv))
> > +  {
> > +    errorResult = AECreateDesc(typeProcessSerialNumber, (Ptr)&process, 
>sizeof(process), &myAddressDesc);
> > +    if (errorResult == noErr)
> > +    {
> > +         /* Create the FinderEvent */
> > +         errorResult = AECreateAppleEvent(kFinderType, kAERevealSelection, 
>&myAddressDesc, kAutoGenerateReturnID, kAnyTransactionID,
> > +                                                                      &aeEvent);
> > +      if (errorResult == noErr)
> > +      {
> > +               /* Create the file  list */
> > +           errorResult = AECreateList(nil, 0, false, &fileList);
> > +               if (errorResult == noErr)
> > +               {
> > +                 errorResult = AEPutPtr(&fileList, 0, typeFSS, &mResolvedSpec, 
>sizeof(FSSpec));
> > +                 if (errorResult == noErr)
> > +                 {
> > +                   errorResult = AEPutParamDesc(&aeEvent,keySelection, &fileList);
> > +                       if (errorResult == noErr)
> > +                       {
> > +                     errorResult = AESend(&aeEvent, &aeReply, kAENoReply, 
>kAENormalPriority, kAEDefaultTimeout, nil, nil);
> > +                         if (errorResult == noErr)
> > +                               SetFrontProcess(&process);
> > +                       }
> > +                 }
> > +               }
> > +         }
> > +       }
> > +  }
> > +
> > +  return NS_OK;
> >  }
> >
> >  nsresult nsLocalFile::MyLaunchAppWithDoc(const FSSpec& appSpec, const FSSpec* 
>aDocToLoad, PRBool aLaunchInBackground)
> > Index: nsLocalFileOS2.cpp
> > ===================================================================
> > RCS file: /cvsroot/mozilla/xpcom/io/nsLocalFileOS2.cpp,v
> > retrieving revision 1.22
> > diff -u -r1.22 nsLocalFileOS2.cpp
> > --- nsLocalFileOS2.cpp  2000/11/28 23:26:02     1.22
> > +++ nsLocalFileOS2.cpp  2001/01/29 20:00:21
> > @@ -2178,6 +2178,18 @@
> >     return InitWithPath(aPersistentDescriptor);
> >  }
> >
> > +NS_IMETHODIMP
> > +nsLocalFile::Reveal()
> > +{
> > +  return NS_ERROR_FAILURE;
> > +}
> > +
> > +
> > +NS_IMETHODIMP
> > +nsLocalFile::Launch()
> > +{
> > +  return NS_ERROR_FAILURE;
> > +}
> >
> >  nsresult
> >  NS_NewLocalFile(const char* path, PRBool followLinks, nsILocalFile* *result)
> > Index: nsLocalFileUnix.cpp
> > ===================================================================
> > RCS file: /cvsroot/mozilla/xpcom/io/nsLocalFileUnix.cpp,v
> > retrieving revision 1.41
> > diff -u -r1.41 nsLocalFileUnix.cpp
> > --- nsLocalFileUnix.cpp 2000/11/28 01:43:09     1.41
> > +++ nsLocalFileUnix.cpp 2001/01/29 20:00:21
> > @@ -1333,6 +1333,19 @@
> >      return InitWithPath(aPersistentDescriptor);
> >  }
> >
> > +NS_IMETHODIMP
> > +nsLocalFile::Reveal()
> > +{
> > +  return NS_ERROR_FAILURE;
> > +}
> > +
> > +
> > +NS_IMETHODIMP
> > +nsLocalFile::Launch()
> > +{
> > +  return NS_ERROR_FAILURE;
> > +}
> > +
> >  nsresult
> >  NS_NewLocalFile(const char *path, PRBool followSymlinks, nsILocalFile **result)
> >  {
> > Index: nsLocalFileWin.cpp
> > ===================================================================
> > RCS file: /cvsroot/mozilla/xpcom/io/nsLocalFileWin.cpp,v
> > retrieving revision 1.49
> > diff -u -r1.49 nsLocalFileWin.cpp
> > --- nsLocalFileWin.cpp  2000/11/28 23:26:02     1.49
> > +++ nsLocalFileWin.cpp  2001/01/29 20:00:21
> > @@ -44,6 +44,7 @@
> >  #include  <stdlib.h>
> >  #include  <mbstring.h>
> >
> > +#include "nsXPIDLString.h"
> >  #include "prproces.h"
> >
> >  // certainly not all the error that can be
> > @@ -1911,6 +1912,53 @@
> >     return InitWithPath(aPersistentDescriptor);
> >  }
> >
> > +NS_IMETHODIMP
> > +nsLocalFile::Reveal()
> > +{
> > +  nsresult rv = NS_OK;
> > +  PRBool isDirectory = PR_FALSE;
> > +  nsXPIDLCString path;
> > +
> > +  IsDirectory(&isDirectory);
> > +  if (isDirectory)
> > +  {
> > +    GetPath(getter_Copies(path));
> > +  }
> > +  else
> > +  {
> > +    nsCOMPtr<nsIFile> parent;
> > +    GetParent(getter_AddRefs(parent));
> > +    if (parent)
> > +      parent->GetPath(getter_Copies(path));
> > +  }
> > +
> > +  // use the app registry name to launch a shell execute....
> > +  LONG r = (LONG) ::ShellExecute( NULL, "explore", (const char *) path, NULL, 
>NULL, SW_SHOWNORMAL);
> > +  if (r < 32)
> > +    rv = NS_ERROR_FAILURE;
> > +       else
> > +               rv = NS_OK;
> > +
> > +  return rv;
> > +}
> > +
> > +
> > +NS_IMETHODIMP
> > +nsLocalFile::Launch()
> > +{
> > +  nsresult rv = NS_OK;
> > +  nsXPIDLCString path;
> > +  GetPath(getter_Copies(path));
> > +
> > +  // use the app registry name to launch a shell execute....
> > +  LONG r = (LONG) ::ShellExecute( NULL, "open", (const char *) path, NULL, NULL, 
>SW_SHOWNORMAL);
> > +  if (r < 32)
> > +    rv = NS_ERROR_FAILURE;
> > +       else
> > +               rv = NS_OK;
> > +
> > +  return rv;
> > +}
> >
> >  nsresult
> >  NS_NewLocalFile(const char* path, PRBool followLinks, nsILocalFile* *result)

Reply via email to