]> git.saurik.com Git - wxWidgets.git/blame - src/mac/corefoundation/utilsexc_base.cpp
document On{Open,Save}Document()
[wxWidgets.git] / src / mac / corefoundation / utilsexc_base.cpp
CommitLineData
1ccb7433
DE
1/////////////////////////////////////////////////////////////////////////////
2// Name: mac/corefoundation/utilsexc_base.cpp
05718a98 3// Purpose: wxMacLaunch
1ccb7433
DE
4// Author: Ryan Norton
5// Modified by:
6// Created: 2005-06-21
7// RCS-ID: $Id$
8// Copyright: (c) Ryan Norton
9// Licence: wxWindows licence
10// Notes: Source was originally in utilsexc_cf.cpp,1.6 then moved
11// to totally unrelated hid.cpp,1.8.
12/////////////////////////////////////////////////////////////////////////////
13
7db33dd7
SC
14//===========================================================================
15// DECLARATIONS
16//===========================================================================
17
18//---------------------------------------------------------------------------
19// Pre-compiled header stuff
20//---------------------------------------------------------------------------
21
1ccb7433
DE
22// For compilers that support precompilation, includes "wx.h".
23#include "wx/wxprec.h"
7db33dd7
SC
24
25// WX includes
1ccb7433
DE
26#ifndef WX_PRECOMP
27 #include "wx/string.h"
28 #include "wx/log.h"
29 #include "wx/intl.h"
30 #include "wx/utils.h"
cdfc78b8 31 #include "wx/wxcrt.h"
1ccb7433
DE
32#endif // WX_PRECOMP
33
7db33dd7 34// Mac Includes
1ccb7433
DE
35#include <CoreFoundation/CoreFoundation.h>
36#include <ApplicationServices/ApplicationServices.h>
37
7db33dd7
SC
38// More WX Includes
39#include "wx/filename.h"
1ccb7433
DE
40#include "wx/mac/corefoundation/cfstring.h"
41
7db33dd7 42// Default path style
7db33dd7 43#define kDefaultPathStyle kCFURLPOSIXPathStyle
7db33dd7
SC
44
45//===========================================================================
46// IMPLEMENTATION
47//===========================================================================
48
49//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
50//
05718a98 51// wxMacLaunch
7db33dd7
SC
52//
53// argv is the command line split up, with the application path first
a8d69700 54// flags are the flags from wxExecute
7db33dd7
SC
55// process is the process passed from wxExecute for pipe streams etc.
56// returns -1 on error for wxEXEC_SYNC and 0 on error for wxEXEC_ASYNC
57//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
05718a98 58bool wxMacLaunch(char **argv)
1ccb7433 59{
7db33dd7
SC
60 // Obtains the number of arguments for determining the size of
61 // the CFArray used to hold them
1ccb7433 62 CFIndex cfiCount = 0;
05718a98 63 for(char** argvcopy = argv; *argvcopy != NULL ; ++argvcopy)
1ccb7433
DE
64 {
65 ++cfiCount;
66 }
67
7db33dd7
SC
68 // If there is not a single argument then there is no application
69 // to launch
70 if(cfiCount == 0)
1ccb7433 71 {
05718a98
VZ
72 wxLogDebug(wxT("wxMacLaunch No file to launch!"));
73 return false ;
1ccb7433 74 }
a8d69700 75
7db33dd7
SC
76 // Path to bundle
77 wxString path = *argv++;
78
79 // Create a CFURL for the application path
80 // Created this way because we are opening a bundle which is a directory
a8d69700 81 CFURLRef cfurlApp =
7db33dd7 82 CFURLCreateWithFileSystemPath(
1ccb7433 83 kCFAllocatorDefault,
504f8052 84 wxCFStringRef(path),
a8d69700 85 kDefaultPathStyle,
7db33dd7 86 true); //false == not a directory
1ccb7433 87
7db33dd7
SC
88 // Check for error from the CFURL
89 if(!cfurlApp)
90 {
05718a98
VZ
91 wxLogDebug(wxT("wxMacLaunch Can't open path: %s"), path.c_str());
92 return false ;
7db33dd7
SC
93 }
94
95 // Create a CFBundle from the CFURL created earlier
1ccb7433 96 CFBundleRef cfbApp = CFBundleCreate(kCFAllocatorDefault, cfurlApp);
7db33dd7
SC
97
98 // Check to see if CFBundleCreate returned an error,
99 // and if it did this was an invalid bundle or not a bundle
100 // at all (maybe a simple directory etc.)
1ccb7433
DE
101 if(!cfbApp)
102 {
05718a98 103 wxLogDebug(wxT("wxMacLaunch Bad bundle: %s"), path.c_str());
1ccb7433 104 CFRelease(cfurlApp);
05718a98 105 return false ;
1ccb7433 106 }
a8d69700 107
7db33dd7
SC
108 // Get the bundle type and make sure its an 'APPL' bundle
109 // Otherwise we're dealing with something else here...
1ccb7433
DE
110 UInt32 dwBundleType, dwBundleCreator;
111 CFBundleGetPackageInfo(cfbApp, &dwBundleType, &dwBundleCreator);
1ccb7433
DE
112 if(dwBundleType != 'APPL')
113 {
05718a98 114 wxLogDebug(wxT("wxMacLaunch Not an APPL bundle: %s"), path.c_str());
7db33dd7 115 CFRelease(cfbApp);
1ccb7433 116 CFRelease(cfurlApp);
05718a98 117 return false ;
1ccb7433 118 }
a8d69700 119
7db33dd7
SC
120 // Create a CFArray for dealing with the command line
121 // arguments to the bundle
a8d69700 122 CFMutableArrayRef cfaFiles = CFArrayCreateMutable(kCFAllocatorDefault,
7db33dd7
SC
123 cfiCount-1, &kCFTypeArrayCallBacks);
124 if(!cfaFiles) //This should never happen
1ccb7433 125 {
05718a98 126 wxLogDebug(wxT("wxMacLaunch Could not create CFMutableArray"));
7db33dd7
SC
127 CFRelease(cfbApp);
128 CFRelease(cfurlApp);
05718a98 129 return false ;
7db33dd7 130 }
a8d69700 131
7db33dd7
SC
132 // Loop through command line arguments to the bundle,
133 // turn them into CFURLs and then put them in cfaFiles
134 // For use to launch services call
1ccb7433
DE
135 for( ; *argv != NULL ; ++argv)
136 {
a8d69700 137 // Check for '<' as this will ring true for
7db33dd7
SC
138 // CFURLCreateWithString but is generally not considered
139 // typical on mac but is usually passed here from wxExecute
140 if (wxStrcmp(*argv, wxT("<")) == 0)
141 continue;
a8d69700
VZ
142
143
144 CFURLRef cfurlCurrentFile; // CFURL to hold file path
145 wxFileName argfn(*argv); // Filename for path
146
7db33dd7
SC
147 if(argfn.DirExists())
148 {
149 // First, try creating as a directory
150 cfurlCurrentFile = CFURLCreateWithFileSystemPath(
151 kCFAllocatorDefault,
504f8052 152 wxCFStringRef(*argv),
a8d69700 153 kDefaultPathStyle,
7db33dd7
SC
154 true); //true == directory
155 }
156 else if(argfn.FileExists())
157 {
158 // And if it isn't a directory try creating it
159 // as a regular file
160 cfurlCurrentFile = CFURLCreateWithFileSystemPath(
161 kCFAllocatorDefault,
504f8052 162 wxCFStringRef(*argv),
a8d69700 163 kDefaultPathStyle,
7db33dd7 164 false); //false == regular file
a8d69700 165 }
7db33dd7
SC
166 else
167 {
168 // Argument did not refer to
169 // an entry in the local filesystem,
170 // so try creating it through CFURLCreateWithString
171 cfurlCurrentFile = CFURLCreateWithString(
a8d69700 172 kCFAllocatorDefault,
504f8052 173 wxCFStringRef(*argv),
a8d69700 174 NULL);
7db33dd7 175 }
a8d69700 176
7db33dd7
SC
177 // Continue in the loop if the CFURL could not be created
178 if(!cfurlCurrentFile)
179 {
180 wxLogDebug(
05718a98 181 wxT("wxMacLaunch Could not create CFURL for argument:%s"),
7db33dd7
SC
182 *argv);
183 continue;
184 }
1ccb7433 185
7db33dd7
SC
186 // Add the valid CFURL to the argument array and then
187 // release it as the CFArray adds a ref count to it
1ccb7433
DE
188 CFArrayAppendValue(
189 cfaFiles,
190 cfurlCurrentFile
191 );
192 CFRelease(cfurlCurrentFile); // array has retained it
193 }
a8d69700 194
7db33dd7
SC
195 // Create a LSLaunchURLSpec for use with LSOpenFromURLSpec
196 // Note that there are several flag options (launchFlags) such
197 // as kLSLaunchDontSwitch etc. and maybe we could be more
198 // picky about the flags we choose
1ccb7433
DE
199 LSLaunchURLSpec launchspec;
200 launchspec.appURL = cfurlApp;
201 launchspec.itemURLs = cfaFiles;
a8d69700
VZ
202 launchspec.passThruParams = NULL; //AEDesc*
203 launchspec.launchFlags = kLSLaunchDefaults;
1ccb7433 204 launchspec.asyncRefCon = NULL;
a8d69700 205
7db33dd7
SC
206 // Finally, call LSOpenFromURL spec with our arguments
207 // 2nd parameter is a pointer to a CFURL that gets
208 // the actual path launched by the function
209 OSStatus status = LSOpenFromURLSpec(&launchspec, NULL);
1ccb7433 210
7db33dd7
SC
211 // Cleanup corefoundation references
212 CFRelease(cfbApp);
1ccb7433
DE
213 CFRelease(cfurlApp);
214 CFRelease(cfaFiles);
a8d69700 215
7db33dd7 216 // Check for error from LSOpenFromURLSpec
1ccb7433
DE
217 if(status != noErr)
218 {
05718a98 219 wxLogDebug(wxT("wxMacLaunch LSOpenFromURLSpec Error: %d"),
7db33dd7 220 (int)status);
05718a98 221 return false ;
1ccb7433 222 }
a8d69700 223
7db33dd7 224 // No error from LSOpenFromURLSpec, so app was launched
05718a98 225 return true ;
1ccb7433
DE
226}
227