]> git.saurik.com Git - wxWidgets.git/blame - src/osx/cocoa/utils.mm
Don't pass NULL to wxDir, rather hop over when trying to find dir with translation
[wxWidgets.git] / src / osx / cocoa / utils.mm
CommitLineData
33e90275 1/////////////////////////////////////////////////////////////////////////////
0f9b48d1 2// Name: src/osx/cocoa/utils.mm
33e90275
SC
3// Purpose: various cocoa utility functions
4// Author: Stefan Csomor
5// Modified by:
6// Created: 1998-01-01
7// RCS-ID: $Id: utils.mm 48805 2007-09-19 14:52:25Z SC $
8// Copyright: (c) Stefan Csomor
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
33e90275
SC
14#include "wx/utils.h"
15
16#ifndef WX_PRECOMP
17 #include "wx/intl.h"
18 #include "wx/app.h"
19 #if wxUSE_GUI
bfa92264 20 #include "wx/dialog.h"
33e90275
SC
21 #include "wx/toplevel.h"
22 #include "wx/font.h"
23 #endif
24#endif
25
26#include "wx/apptrait.h"
27
28#include "wx/osx/private.h"
29
30#if wxUSE_GUI
31#if wxOSX_USE_COCOA_OR_CARBON
33e90275 32 #include <CoreServices/CoreServices.h>
928e7a7e 33 #include "wx/osx/dcclient.h"
33e90275
SC
34 #include "wx/osx/private/timer.h"
35#endif
36#endif // wxUSE_GUI
37
38#if wxOSX_USE_COCOA
39
40#if wxUSE_BASE
41
42// Emit a beeeeeep
43void wxBell()
44{
45 NSBeep();
46}
47
33e90275 48#endif // wxUSE_BASE
945eac79 49
36eca861
SC
50#if wxUSE_GUI
51
c8fdb345 52@interface wxNSAppController : NSObject wxOSX_10_6_AND_LATER(<NSApplicationDelegate>)
c6aa5caf
SC
53{
54}
55
175e9d71
SC
56- (void)applicationWillFinishLaunching:(NSApplication *)sender;
57
c6aa5caf
SC
58- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
59- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
60- (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename;
c6aa5caf 61- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
175e9d71
SC
62 withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
63
64- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender;
65- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
66- (void)applicationWillTerminate:(NSApplication *)sender;
c6aa5caf
SC
67@end
68
69@implementation wxNSAppController
70
175e9d71
SC
71- (void)applicationWillFinishLaunching:(NSApplication *)application {
72 wxUnusedVar(application);
c6aa5caf
SC
73}
74
75- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
76{
d8207702 77 wxUnusedVar(sender);
c6aa5caf
SC
78 wxCFStringRef cf(wxCFRetain(filename));
79 wxTheApp->MacOpenFile(cf.AsString()) ;
80 return YES;
81}
82
83- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
84{
d8207702 85 wxUnusedVar(sender);
c6aa5caf
SC
86 wxTheApp->MacNewFile() ;
87 return NO;
88}
89
90- (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename
91{
d8207702 92 wxUnusedVar(sender);
c6aa5caf
SC
93 wxCFStringRef cf(wxCFRetain(filename));
94 wxTheApp->MacPrintFile(cf.AsString()) ;
95 return YES;
96}
97
175e9d71
SC
98- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
99{
100 wxUnusedVar(flag);
101 wxUnusedVar(sender);
102 wxTheApp->MacReopenApp() ;
103 return NO;
104}
105
106- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
107 withReplyEvent:(NSAppleEventDescriptor *)replyEvent
108{
109 wxUnusedVar(replyEvent);
110 NSString* url = [[event descriptorAtIndex:1] stringValue];
111 wxCFStringRef cf(wxCFRetain(url));
112 wxTheApp->MacOpenURL(cf.AsString()) ;
113}
114
945eac79 115/*
c6aa5caf
SC
116 Allowable return values are:
117 NSTerminateNow - it is ok to proceed with termination
118 NSTerminateCancel - the application should not be terminated
119 NSTerminateLater - it may be ok to proceed with termination later. The application must call -replyToApplicationShouldTerminate: with YES or NO once the answer is known
120 this return value is for delegates who need to provide document modal alerts (sheets) in order to decide whether to quit.
121*/
122- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
123{
d8207702 124 wxUnusedVar(sender);
175e9d71
SC
125 wxCloseEvent event;
126 wxTheApp->OnQueryEndSession(event);
127 if ( event.GetVeto() )
128 return NSTerminateCancel;
129
130 return NSTerminateNow;
c6aa5caf
SC
131}
132
175e9d71
SC
133- (void)applicationWillTerminate:(NSApplication *)application {
134 wxUnusedVar(application);
135 wxCloseEvent event;
136 event.SetCanVeto(false);
137 wxTheApp->OnEndSession(event);
138}
139
140- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
c6aa5caf 141{
d8207702 142 wxUnusedVar(sender);
175e9d71 143 // let wx do this, not cocoa
c6aa5caf
SC
144 return NO;
145}
146
c6aa5caf
SC
147@end
148
03647350 149/*
724999ee 150 allows ShowModal to work when using sheets.
03647350 151 see include/wx/osx/cocoa/private.h for more info
724999ee
KO
152*/
153@implementation ModalDialogDelegate
154- (id)init
155{
156 [super init];
157 sheetFinished = NO;
158 resultCode = -1;
bfa92264 159 impl = 0;
724999ee
KO
160 return self;
161}
162
bfa92264
KO
163- (void)setImplementation: (wxDialog *)dialog
164{
165 impl = dialog;
166}
167
03647350 168- (BOOL)finished
724999ee
KO
169{
170 return sheetFinished;
171}
172
173- (int)code
174{
175 return resultCode;
176}
177
178- (void)waitForSheetToFinish
179{
180 while (!sheetFinished)
181 {
182 wxSafeYield();
183 }
184}
185
186- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
187{
d8207702 188 wxUnusedVar(contextInfo);
724999ee
KO
189 resultCode = returnCode;
190 sheetFinished = YES;
037f9d3b
KO
191 // NSAlerts don't need nor respond to orderOut
192 if ([sheet respondsToSelector:@selector(orderOut:)])
193 [sheet orderOut: self];
bfa92264
KO
194
195 if (impl)
196 impl->ModalFinishedCallback(sheet, returnCode);
724999ee
KO
197}
198@end
199
dbeddfb9
SC
200bool wxApp::DoInitGui()
201{
ab9df4fb 202 wxMacAutoreleasePool pool;
dbeddfb9 203 [NSApplication sharedApplication];
c6aa5caf
SC
204
205 if (!sm_isEmbedded)
206 {
207 wxNSAppController* controller = [[wxNSAppController alloc] init];
cc96f525 208 [NSApp setDelegate:controller];
945eac79 209
c6aa5caf
SC
210 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
211 [appleEventManager setEventHandler:controller andSelector:@selector(handleGetURLEvent:withReplyEvent:)
212 forEventClass:kInternetEventClass andEventID:kAEGetURL];
cc96f525
SC
213
214 [NSApp finishLaunching];
c6aa5caf 215 }
dbeddfb9
SC
216 return true;
217}
218
219void wxApp::DoCleanUp()
220{
221}
33e90275 222
33e90275
SC
223void wxClientDisplayRect(int *x, int *y, int *width, int *height)
224{
225 NSRect displayRect = [[NSScreen mainScreen] visibleFrame];
226 wxRect r = wxFromNSRect( NULL, displayRect );
227 if ( x )
228 *x = r.x;
229 if ( y )
230 *y = r.y;
231 if ( width )
232 *width = r.GetWidth();
233 if ( height )
234 *height = r.GetHeight();
945eac79 235
33e90275
SC
236}
237
238void wxGetMousePosition( int* x, int* y )
239{
240 wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]);
54f11060
SC
241 if ( x )
242 *x = pt.x;
243 if ( y )
244 *y = pt.y;
33e90275
SC
245};
246
f3769d53
SC
247#if wxOSX_USE_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
248
249wxMouseState wxGetMouseState()
250{
251 wxMouseState ms;
252
253 wxPoint pt = wxGetMousePosition();
254 ms.SetX(pt.x);
255 ms.SetY(pt.y);
256
257 NSUInteger modifiers = [NSEvent modifierFlags];
258 NSUInteger buttons = [NSEvent pressedMouseButtons];
259
260 ms.SetLeftDown( (buttons & 0x01) != 0 );
261 ms.SetMiddleDown( (buttons & 0x04) != 0 );
262 ms.SetRightDown( (buttons & 0x02) != 0 );
263
264 ms.SetControlDown(modifiers & NSControlKeyMask);
265 ms.SetShiftDown(modifiers & NSShiftKeyMask);
266 ms.SetAltDown(modifiers & NSAlternateKeyMask);
267 ms.SetMetaDown(modifiers & NSCommandKeyMask);
268
269 return ms;
270}
271
272
273#endif
274
33e90275
SC
275wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
276{
dbeddfb9 277 return new wxOSXTimerImpl(timer);
33e90275
SC
278}
279
280int gs_wxBusyCursorCount = 0;
281extern wxCursor gMacCurrentCursor;
282wxCursor gMacStoredActiveCursor;
283
284// Set the cursor to the busy cursor for all windows
285void wxBeginBusyCursor(const wxCursor *cursor)
286{
287 if (gs_wxBusyCursorCount++ == 0)
288 {
289 gMacStoredActiveCursor = gMacCurrentCursor;
290 cursor->MacInstall();
291
292 wxSetCursor(*cursor);
293 }
294 //else: nothing to do, already set
295}
296
297// Restore cursor to normal
298void wxEndBusyCursor()
299{
300 wxCHECK_RET( gs_wxBusyCursorCount > 0,
301 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
302
303 if (--gs_wxBusyCursorCount == 0)
304 {
305 gMacStoredActiveCursor.MacInstall();
306 gMacStoredActiveCursor = wxNullCursor;
307
308 wxSetCursor(wxNullCursor);
309 }
310}
311
312// true if we're between the above two calls
313bool wxIsBusy()
314{
315 return (gs_wxBusyCursorCount > 0);
316}
317
928e7a7e
KO
318wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
319{
320 // wxScreenDC is derived from wxWindowDC, so a screen dc will
321 // call this method when a Blit is performed with it as a source.
322 if (!m_window)
323 return wxNullBitmap;
945eac79 324
928e7a7e 325 wxSize sz = m_window->GetSize();
945eac79 326
928e7a7e
KO
327 int left = subrect != NULL ? subrect->x : 0 ;
328 int top = subrect != NULL ? subrect->y : 0 ;
329 int width = subrect != NULL ? subrect->width : sz.x;
330 int height = subrect != NULL ? subrect->height : sz.y ;
945eac79 331
928e7a7e
KO
332 NSRect rect = NSMakeRect(left, top, width, height );
333 NSView* view = (NSView*) m_window->GetHandle();
334 [view lockFocus];
945eac79 335 // we use this method as other methods force a repaint, and this method can be
928e7a7e
KO
336 // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
337 NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]] retain];
338 [view unlockFocus];
03647350 339
1034a6bb
SC
340 wxBitmap bitmap(width, height);
341 if ( [rep respondsToSelector:@selector(CGImage)] )
342 {
343 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
945eac79 344
1034a6bb
SC
345 CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
346 // since our context is upside down we dont use CGContextDrawImage
347 wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
348 CGImageRelease(cgImageRef);
349 cgImageRef = NULL;
350 }
351 else
352 {
353 // TODO for 10.4 in case we can support this for osx_cocoa
354 }
928e7a7e 355 [rep release];
945eac79 356
928e7a7e
KO
357 return bitmap;
358}
359
33e90275
SC
360#endif // wxUSE_GUI
361
3c7eea25 362#endif // wxOSX_USE_COCOA