83
84 // used by JavaRuntimeSupport.framework's [JRSAppKitAWT awtAppDelegate]
85 // to expose our app delegate to the SWT or other apps that have knoledge
86 // of Java's AWT and want to install their own app delegate that will delegate
87 // to the AWT for some operations
88
89 @interface JavaAWTAppDelegateLoader : NSObject { }
90 @end
91
92 @implementation JavaAWTAppDelegateLoader
93 + (ApplicationDelegate *) awtAppDelegate {
94 return [ApplicationDelegate sharedDelegate];
95 }
96 @end
97
98
99 @implementation ApplicationDelegate
100
101 @synthesize fPreferencesMenu;
102 @synthesize fAboutMenu;
103
104 @synthesize fDockMenu;
105 @synthesize fDefaultMenuBar;
106
107
108 + (ApplicationDelegate *)sharedDelegate {
109 static ApplicationDelegate *sApplicationDelegate = nil;
110 static BOOL checked = NO;
111
112 if (sApplicationDelegate != nil) return sApplicationDelegate;
113 if (checked) return nil;
114
115 AWT_ASSERT_APPKIT_THREAD;
116
117 // don't install the EAWT delegate if another kind of NSApplication is installed, like say, Safari
118 BOOL shouldInstall = NO;
119 if (NSApp != nil) {
120 if ([NSApp isMemberOfClass:[NSApplication class]]) shouldInstall = YES;
121 if ([NSApp isKindOfClass:[NSApplicationAWT class]]) shouldInstall = YES;
122 }
184
185 - (id) init {
186 AWT_ASSERT_APPKIT_THREAD;
187
188 self = [super init];
189 if (!self) return self;
190
191 // Prep for about and preferences menu
192 BOOL usingDefaultNib = YES;
193 if ([NSApp isKindOfClass:[NSApplicationAWT class]]) {
194 usingDefaultNib = [NSApp usingDefaultNib];
195 }
196 if (!usingDefaultNib) return self;
197
198 NSMenu *menuBar = [[NSApplication sharedApplication] mainMenu];
199 NSMenu *appMenu = [[menuBar itemAtIndex:0] submenu];
200
201 self.fPreferencesMenu = (NSMenuItem*)[appMenu itemWithTag:PREFERENCES_TAG];
202 self.fAboutMenu = (NSMenuItem*)[appMenu itemAtIndex:0];
203
204 // If the java application has a bundle with an Info.plist file with
205 // a CFBundleDocumentTypes entry, then it is set up to handle Open Doc
206 // and Print Doc commands for these files. Therefore java AWT will
207 // cache Open Doc and Print Doc events that are sent prior to a
208 // listener being installed by the client java application.
209 NSBundle *bundle = [NSBundle mainBundle];
210 fHandlesDocumentTypes = [bundle objectForInfoDictionaryKey:@"CFBundleDocumentTypes"] != nil || [bundle _hasEAWTOverride:@"DocumentHandler"];
211 fHandlesURLTypes = [bundle objectForInfoDictionaryKey:@"CFBundleURLTypes"] != nil || [bundle _hasEAWTOverride:@"URLHandler"];
212 if (fHandlesURLTypes) {
213 [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self
214 andSelector:@selector(_handleOpenURLEvent:withReplyEvent:)
215 forEventClass:kInternetEventClass
216 andEventID:kAEGetURL];
217 }
218
219 // By HIG, Preferences are not available unless there is a handler. By default in Mac OS X,
220 // there is not a handler, but it is in the nib file for convenience.
221 removeMenuItem(self.fPreferencesMenu);
222
223 [self _updateAboutMenu:YES enabled:YES];
235 JNFCallStaticVoidMethod(env, sjm_initMenuStates, aboutAvailable, aboutEnabled, prefsAvailable, prefsEnabled);
236
237 // register for the finish launching and system power off notifications by default
238 NSNotificationCenter *ctr = [NSNotificationCenter defaultCenter];
239 Class clz = [ApplicationDelegate class];
240 [ctr addObserver:clz selector:@selector(_willFinishLaunching) name:NSApplicationWillFinishLaunchingNotification object:nil];
241 [ctr addObserver:clz selector:@selector(_systemWillPowerOff) name:NSWorkspaceWillPowerOffNotification object:nil];
242 [ctr addObserver:clz selector:@selector(_appDidActivate) name:NSApplicationDidBecomeActiveNotification object:nil];
243 [ctr addObserver:clz selector:@selector(_appDidDeactivate) name:NSApplicationDidResignActiveNotification object:nil];
244 [ctr addObserver:clz selector:@selector(_appDidHide) name:NSApplicationDidHideNotification object:nil];
245 [ctr addObserver:clz selector:@selector(_appDidUnhide) name:NSApplicationDidUnhideNotification object:nil];
246
247 return self;
248 }
249
250 - (void)dealloc {
251 self.fPreferencesMenu = nil;
252 self.fAboutMenu = nil;
253 self.fDockMenu = nil;
254 self.fDefaultMenuBar = nil;
255
256 [super dealloc];
257 }
258
259 #pragma mark Callbacks from AppKit
260
261 static JNF_CLASS_CACHE(sjc_AppEventHandler, "com/apple/eawt/_AppEventHandler");
262
263 - (void)_handleOpenURLEvent:(NSAppleEventDescriptor *)openURLEvent withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
264 AWT_ASSERT_APPKIT_THREAD;
265 if (!fHandlesURLTypes) return;
266
267 NSString *url = [[openURLEvent paramDescriptorForKeyword:keyDirectObject] stringValue];
268
269 //fprintf(stderr,"jm_handleOpenURL\n");
270 JNIEnv *env = [ThreadUtilities getJNIEnv];
271 jstring jURL = JNFNSToJavaString(env, url);
272 static JNF_STATIC_MEMBER_CACHE(jm_handleOpenURI, sjc_AppEventHandler, "handleOpenURI", "(Ljava/lang/String;)V");
273 JNFCallStaticVoidMethod(env, jm_handleOpenURI, jURL); // AWT_THREADING Safe (event)
274 (*env)->DeleteLocalRef(env, jURL);
451
452
453 #pragma mark Helpers called on the main thread from Java
454
455 // Sets a new NSImageView on the Dock tile
456 + (void)_setDockIconImage:(NSImage *)image {
457 AWT_ASSERT_APPKIT_THREAD;
458
459 NSDockTile *dockTile = [NSApp dockTile];
460 if (image == nil) {
461 [dockTile setContentView:nil];
462 return;
463 }
464
465 // setup an image view for the dock tile
466 NSRect frame = NSMakeRect(0, 0, dockTile.size.width, dockTile.size.height);
467 NSImageView *dockImageView = [[NSImageView alloc] initWithFrame: frame];
468 [dockImageView setImageScaling:NSImageScaleProportionallyUpOrDown];
469 [dockImageView setImage:image];
470
471 // add it to the NSDockTile
472 [dockTile setContentView: dockImageView];
473 [dockTile display];
474
475 [dockImageView release];
476 }
477
478 // Obtains the image of the Dock icon, either manually set, a drawn copy, or the default NSApplicationIcon
479 + (NSImage *)_dockIconImage {
480 AWT_ASSERT_APPKIT_THREAD;
481
482 NSDockTile *dockTile = [NSApp dockTile];
483 NSView *view = [dockTile contentView];
484
485 if ([view isKindOfClass:[NSImageView class]]) {
486 NSImage *img = [((NSImageView *)view) image];
487 if (img) return img;
488 }
489
490 if (view == nil) {
491 return [NSImage imageNamed:@"NSApplicationIcon"];
492 }
493
494 NSRect frame = [view frame];
495 NSImage *image = [[NSImage alloc] initWithSize:frame.size];
496 [image lockFocus];
497 [view drawRect:frame];
589 JNF_COCOA_EXIT(env);
590 }
591
592 /*
593 * Class: com_apple_eawt__AppDockIconHandler
594 * Method: nativeSetDockIconImage
595 * Signature: (J)V
596 */
597 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockIconImage
598 (JNIEnv *env, jclass clz, jlong nsImagePtr)
599 {
600 JNF_COCOA_ENTER(env);
601
602 NSImage *_image = (NSImage *)jlong_to_ptr(nsImagePtr);
603 [ThreadUtilities performOnMainThread:@selector(_setDockIconImage:)
604 on:[ApplicationDelegate class]
605 withObject:_image
606 waitUntilDone:NO];
607
608 JNF_COCOA_EXIT(env);
609 }
610
611 /*
612 * Class: com_apple_eawt__AppDockIconHandler
613 * Method: nativeGetDockIconImage
614 * Signature: ()J
615 */
616 JNIEXPORT jlong JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeGetDockIconImage
617 (JNIEnv *env, jclass clz)
618 {
619 __block NSImage *image = nil;
620
621 JNF_COCOA_ENTER(env);
622
623 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
624 image = [[ApplicationDelegate _dockIconImage] retain];
625 }];
626
627 JNF_COCOA_EXIT(env);
628
|
83
84 // used by JavaRuntimeSupport.framework's [JRSAppKitAWT awtAppDelegate]
85 // to expose our app delegate to the SWT or other apps that have knoledge
86 // of Java's AWT and want to install their own app delegate that will delegate
87 // to the AWT for some operations
88
89 @interface JavaAWTAppDelegateLoader : NSObject { }
90 @end
91
92 @implementation JavaAWTAppDelegateLoader
93 + (ApplicationDelegate *) awtAppDelegate {
94 return [ApplicationDelegate sharedDelegate];
95 }
96 @end
97
98
99 @implementation ApplicationDelegate
100
101 @synthesize fPreferencesMenu;
102 @synthesize fAboutMenu;
103 @synthesize fProgressIndicator;
104
105 @synthesize fDockMenu;
106 @synthesize fDefaultMenuBar;
107
108
109 + (ApplicationDelegate *)sharedDelegate {
110 static ApplicationDelegate *sApplicationDelegate = nil;
111 static BOOL checked = NO;
112
113 if (sApplicationDelegate != nil) return sApplicationDelegate;
114 if (checked) return nil;
115
116 AWT_ASSERT_APPKIT_THREAD;
117
118 // don't install the EAWT delegate if another kind of NSApplication is installed, like say, Safari
119 BOOL shouldInstall = NO;
120 if (NSApp != nil) {
121 if ([NSApp isMemberOfClass:[NSApplication class]]) shouldInstall = YES;
122 if ([NSApp isKindOfClass:[NSApplicationAWT class]]) shouldInstall = YES;
123 }
185
186 - (id) init {
187 AWT_ASSERT_APPKIT_THREAD;
188
189 self = [super init];
190 if (!self) return self;
191
192 // Prep for about and preferences menu
193 BOOL usingDefaultNib = YES;
194 if ([NSApp isKindOfClass:[NSApplicationAWT class]]) {
195 usingDefaultNib = [NSApp usingDefaultNib];
196 }
197 if (!usingDefaultNib) return self;
198
199 NSMenu *menuBar = [[NSApplication sharedApplication] mainMenu];
200 NSMenu *appMenu = [[menuBar itemAtIndex:0] submenu];
201
202 self.fPreferencesMenu = (NSMenuItem*)[appMenu itemWithTag:PREFERENCES_TAG];
203 self.fAboutMenu = (NSMenuItem*)[appMenu itemAtIndex:0];
204
205 NSDockTile *dockTile = [NSApp dockTile];
206 self.fProgressIndicator = [[NSProgressIndicator alloc]
207 initWithFrame:NSMakeRect(3.f, 0.f, dockTile.size.width - 6.f, 20.f)];
208
209 [fProgressIndicator setStyle:NSProgressIndicatorBarStyle];
210 [fProgressIndicator setIndeterminate:NO];
211 [[dockTile contentView] addSubview:fProgressIndicator];
212 [fProgressIndicator setMinValue:0];
213 [fProgressIndicator setMaxValue:100];
214 [fProgressIndicator setHidden:YES];
215 [fProgressIndicator release];
216
217 // If the java application has a bundle with an Info.plist file with
218 // a CFBundleDocumentTypes entry, then it is set up to handle Open Doc
219 // and Print Doc commands for these files. Therefore java AWT will
220 // cache Open Doc and Print Doc events that are sent prior to a
221 // listener being installed by the client java application.
222 NSBundle *bundle = [NSBundle mainBundle];
223 fHandlesDocumentTypes = [bundle objectForInfoDictionaryKey:@"CFBundleDocumentTypes"] != nil || [bundle _hasEAWTOverride:@"DocumentHandler"];
224 fHandlesURLTypes = [bundle objectForInfoDictionaryKey:@"CFBundleURLTypes"] != nil || [bundle _hasEAWTOverride:@"URLHandler"];
225 if (fHandlesURLTypes) {
226 [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self
227 andSelector:@selector(_handleOpenURLEvent:withReplyEvent:)
228 forEventClass:kInternetEventClass
229 andEventID:kAEGetURL];
230 }
231
232 // By HIG, Preferences are not available unless there is a handler. By default in Mac OS X,
233 // there is not a handler, but it is in the nib file for convenience.
234 removeMenuItem(self.fPreferencesMenu);
235
236 [self _updateAboutMenu:YES enabled:YES];
248 JNFCallStaticVoidMethod(env, sjm_initMenuStates, aboutAvailable, aboutEnabled, prefsAvailable, prefsEnabled);
249
250 // register for the finish launching and system power off notifications by default
251 NSNotificationCenter *ctr = [NSNotificationCenter defaultCenter];
252 Class clz = [ApplicationDelegate class];
253 [ctr addObserver:clz selector:@selector(_willFinishLaunching) name:NSApplicationWillFinishLaunchingNotification object:nil];
254 [ctr addObserver:clz selector:@selector(_systemWillPowerOff) name:NSWorkspaceWillPowerOffNotification object:nil];
255 [ctr addObserver:clz selector:@selector(_appDidActivate) name:NSApplicationDidBecomeActiveNotification object:nil];
256 [ctr addObserver:clz selector:@selector(_appDidDeactivate) name:NSApplicationDidResignActiveNotification object:nil];
257 [ctr addObserver:clz selector:@selector(_appDidHide) name:NSApplicationDidHideNotification object:nil];
258 [ctr addObserver:clz selector:@selector(_appDidUnhide) name:NSApplicationDidUnhideNotification object:nil];
259
260 return self;
261 }
262
263 - (void)dealloc {
264 self.fPreferencesMenu = nil;
265 self.fAboutMenu = nil;
266 self.fDockMenu = nil;
267 self.fDefaultMenuBar = nil;
268 self.fProgressIndicator = nil;
269
270 [super dealloc];
271 }
272
273 #pragma mark Callbacks from AppKit
274
275 static JNF_CLASS_CACHE(sjc_AppEventHandler, "com/apple/eawt/_AppEventHandler");
276
277 - (void)_handleOpenURLEvent:(NSAppleEventDescriptor *)openURLEvent withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
278 AWT_ASSERT_APPKIT_THREAD;
279 if (!fHandlesURLTypes) return;
280
281 NSString *url = [[openURLEvent paramDescriptorForKeyword:keyDirectObject] stringValue];
282
283 //fprintf(stderr,"jm_handleOpenURL\n");
284 JNIEnv *env = [ThreadUtilities getJNIEnv];
285 jstring jURL = JNFNSToJavaString(env, url);
286 static JNF_STATIC_MEMBER_CACHE(jm_handleOpenURI, sjc_AppEventHandler, "handleOpenURI", "(Ljava/lang/String;)V");
287 JNFCallStaticVoidMethod(env, jm_handleOpenURI, jURL); // AWT_THREADING Safe (event)
288 (*env)->DeleteLocalRef(env, jURL);
465
466
467 #pragma mark Helpers called on the main thread from Java
468
469 // Sets a new NSImageView on the Dock tile
470 + (void)_setDockIconImage:(NSImage *)image {
471 AWT_ASSERT_APPKIT_THREAD;
472
473 NSDockTile *dockTile = [NSApp dockTile];
474 if (image == nil) {
475 [dockTile setContentView:nil];
476 return;
477 }
478
479 // setup an image view for the dock tile
480 NSRect frame = NSMakeRect(0, 0, dockTile.size.width, dockTile.size.height);
481 NSImageView *dockImageView = [[NSImageView alloc] initWithFrame: frame];
482 [dockImageView setImageScaling:NSImageScaleProportionallyUpOrDown];
483 [dockImageView setImage:image];
484
485 [[ApplicationDelegate sharedDelegate].fProgressIndicator removeFromSuperview];
486 [dockImageView addSubview:[ApplicationDelegate sharedDelegate].fProgressIndicator];
487
488 // add it to the NSDockTile
489 [dockTile setContentView: dockImageView];
490 [dockTile display];
491
492 [dockImageView release];
493 }
494
495 + (void)_setDockIconProgress:(NSNumber *)value {
496 AWT_ASSERT_APPKIT_THREAD;
497
498 ApplicationDelegate *delegate = [ApplicationDelegate sharedDelegate];
499 if ([value doubleValue] >= 0 && [value doubleValue] <=100) {
500 [delegate.fProgressIndicator setDoubleValue:[value doubleValue]];
501 [delegate.fProgressIndicator setHidden:NO];
502 } else {
503 [delegate.fProgressIndicator setHidden:YES];
504 }
505
506 [[NSApp dockTile] display];
507 }
508
509 // Obtains the image of the Dock icon, either manually set, a drawn copy, or the default NSApplicationIcon
510 + (NSImage *)_dockIconImage {
511 AWT_ASSERT_APPKIT_THREAD;
512
513 NSDockTile *dockTile = [NSApp dockTile];
514 NSView *view = [dockTile contentView];
515
516 if ([view isKindOfClass:[NSImageView class]]) {
517 NSImage *img = [((NSImageView *)view) image];
518 if (img) return img;
519 }
520
521 if (view == nil) {
522 return [NSImage imageNamed:@"NSApplicationIcon"];
523 }
524
525 NSRect frame = [view frame];
526 NSImage *image = [[NSImage alloc] initWithSize:frame.size];
527 [image lockFocus];
528 [view drawRect:frame];
620 JNF_COCOA_EXIT(env);
621 }
622
623 /*
624 * Class: com_apple_eawt__AppDockIconHandler
625 * Method: nativeSetDockIconImage
626 * Signature: (J)V
627 */
628 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockIconImage
629 (JNIEnv *env, jclass clz, jlong nsImagePtr)
630 {
631 JNF_COCOA_ENTER(env);
632
633 NSImage *_image = (NSImage *)jlong_to_ptr(nsImagePtr);
634 [ThreadUtilities performOnMainThread:@selector(_setDockIconImage:)
635 on:[ApplicationDelegate class]
636 withObject:_image
637 waitUntilDone:NO];
638
639 JNF_COCOA_EXIT(env);
640 }
641
642 /*
643 * Class: com_apple_eawt__AppDockIconHandler
644 * Method: nativeSetDockIconProgress
645 * Signature: (I)V
646 */
647 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockIconProgress
648 (JNIEnv *env, jclass clz, jint value)
649 {
650 JNF_COCOA_ENTER(env);
651
652 [ThreadUtilities performOnMainThread:@selector(_setDockIconProgress:)
653 on:[ApplicationDelegate class]
654 withObject:[NSNumber numberWithInt:value]
655 waitUntilDone:NO];
656
657 JNF_COCOA_EXIT(env);
658 }
659
660 /*
661 * Class: com_apple_eawt__AppDockIconHandler
662 * Method: nativeGetDockIconImage
663 * Signature: ()J
664 */
665 JNIEXPORT jlong JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeGetDockIconImage
666 (JNIEnv *env, jclass clz)
667 {
668 __block NSImage *image = nil;
669
670 JNF_COCOA_ENTER(env);
671
672 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
673 image = [[ApplicationDelegate _dockIconImage] retain];
674 }];
675
676 JNF_COCOA_EXIT(env);
677
|