]> git.saurik.com Git - wxWidgets.git/blame - src/osx/cocoa/utils.mm
Initialize time zone information before using it in wxGetTimeZone().
[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];
e8f25fcf
SC
213
214 // calling finishLaunching so early before running the loop seems to trigger some 'MenuManager compatibility' which leads
215 // to the duplication of menus under 10.5 and a warning under 10.6
216#if 0
cc96f525 217 [NSApp finishLaunching];
e8f25fcf 218#endif
c6aa5caf 219 }
dbeddfb9
SC
220 return true;
221}
222
223void wxApp::DoCleanUp()
224{
225}
33e90275 226
33e90275
SC
227void wxClientDisplayRect(int *x, int *y, int *width, int *height)
228{
5d57348e 229 NSRect displayRect = [wxOSXGetMenuScreen() visibleFrame];
33e90275
SC
230 wxRect r = wxFromNSRect( NULL, displayRect );
231 if ( x )
232 *x = r.x;
233 if ( y )
234 *y = r.y;
235 if ( width )
236 *width = r.GetWidth();
237 if ( height )
238 *height = r.GetHeight();
945eac79 239
33e90275
SC
240}
241
242void wxGetMousePosition( int* x, int* y )
243{
244 wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]);
54f11060
SC
245 if ( x )
246 *x = pt.x;
247 if ( y )
248 *y = pt.y;
33e90275
SC
249};
250
f3769d53
SC
251#if wxOSX_USE_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
252
253wxMouseState wxGetMouseState()
254{
255 wxMouseState ms;
256
257 wxPoint pt = wxGetMousePosition();
258 ms.SetX(pt.x);
259 ms.SetY(pt.y);
260
261 NSUInteger modifiers = [NSEvent modifierFlags];
262 NSUInteger buttons = [NSEvent pressedMouseButtons];
263
264 ms.SetLeftDown( (buttons & 0x01) != 0 );
265 ms.SetMiddleDown( (buttons & 0x04) != 0 );
266 ms.SetRightDown( (buttons & 0x02) != 0 );
267
268 ms.SetControlDown(modifiers & NSControlKeyMask);
269 ms.SetShiftDown(modifiers & NSShiftKeyMask);
270 ms.SetAltDown(modifiers & NSAlternateKeyMask);
271 ms.SetMetaDown(modifiers & NSCommandKeyMask);
272
273 return ms;
274}
275
276
277#endif
278
33e90275
SC
279wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
280{
dbeddfb9 281 return new wxOSXTimerImpl(timer);
33e90275
SC
282}
283
284int gs_wxBusyCursorCount = 0;
285extern wxCursor gMacCurrentCursor;
286wxCursor gMacStoredActiveCursor;
287
288// Set the cursor to the busy cursor for all windows
289void wxBeginBusyCursor(const wxCursor *cursor)
290{
291 if (gs_wxBusyCursorCount++ == 0)
292 {
293 gMacStoredActiveCursor = gMacCurrentCursor;
294 cursor->MacInstall();
295
296 wxSetCursor(*cursor);
297 }
298 //else: nothing to do, already set
299}
300
301// Restore cursor to normal
302void wxEndBusyCursor()
303{
304 wxCHECK_RET( gs_wxBusyCursorCount > 0,
305 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
306
307 if (--gs_wxBusyCursorCount == 0)
308 {
309 gMacStoredActiveCursor.MacInstall();
310 gMacStoredActiveCursor = wxNullCursor;
311
312 wxSetCursor(wxNullCursor);
313 }
314}
315
316// true if we're between the above two calls
317bool wxIsBusy()
318{
319 return (gs_wxBusyCursorCount > 0);
320}
321
928e7a7e
KO
322wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
323{
324 // wxScreenDC is derived from wxWindowDC, so a screen dc will
325 // call this method when a Blit is performed with it as a source.
326 if (!m_window)
327 return wxNullBitmap;
945eac79 328
928e7a7e 329 wxSize sz = m_window->GetSize();
945eac79 330
928e7a7e
KO
331 int left = subrect != NULL ? subrect->x : 0 ;
332 int top = subrect != NULL ? subrect->y : 0 ;
333 int width = subrect != NULL ? subrect->width : sz.x;
334 int height = subrect != NULL ? subrect->height : sz.y ;
945eac79 335
928e7a7e
KO
336 NSRect rect = NSMakeRect(left, top, width, height );
337 NSView* view = (NSView*) m_window->GetHandle();
338 [view lockFocus];
945eac79 339 // we use this method as other methods force a repaint, and this method can be
928e7a7e
KO
340 // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
341 NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]] retain];
342 [view unlockFocus];
03647350 343
1034a6bb
SC
344 wxBitmap bitmap(width, height);
345 if ( [rep respondsToSelector:@selector(CGImage)] )
346 {
347 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
945eac79 348
1034a6bb
SC
349 CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
350 // since our context is upside down we dont use CGContextDrawImage
351 wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
352 CGImageRelease(cgImageRef);
353 cgImageRef = NULL;
354 }
355 else
356 {
357 // TODO for 10.4 in case we can support this for osx_cocoa
358 }
928e7a7e 359 [rep release];
945eac79 360
928e7a7e
KO
361 return bitmap;
362}
363
33e90275
SC
364#endif // wxUSE_GUI
365
3c7eea25 366#endif // wxOSX_USE_COCOA