diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index 76e65a768..c5033ed53 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -39,6 +39,11 @@ CPApp = nil; CPApplicationWillFinishLaunchingNotification = @"CPApplicationWillFinishLaunchingNotification"; CPApplicationDidFinishLaunchingNotification = @"CPApplicationDidFinishLaunchingNotification"; +CPApplicationWillTerminateNotification = @"CPApplicationWillTerminateNotification"; + +CPTerminateNow = YES; +CPTerminateCancel = NO; +CPTerminateLater = -1; // not currently supported CPRunStoppedResponse = -1000; CPRunAbortedResponse = -1001; @@ -295,7 +300,30 @@ CPRunContinuesResponse = -1002; - (void)terminate:(id)aSender { - [CPPlatform terminateApplication]; + [[CPDocumentController sharedDocumentController] closeAllDocumentsWithDelegate:self + didCloseAllSelector:@selector(_documentController:didCloseAll:context:) + contextInfo:nil]; +} + +- (void)_documentController:(NSDocumentController *)docController didCloseAll:(BOOL)didCloseAll context:(Object)info +{ + // callback method for terminate: + if (didCloseAll) + { + if ([_delegate respondsToSelector:@selector(applicationShouldTerminate:)]) + [self replyToApplicationShouldTerminate:[_delegate applicationShouldTerminate:self]]; + else + [self replyToApplicationShouldTerminate:YES]; + } +} + +- (void)replyToApplicationShouldTerminate:(BOOL)terminate +{ + if (terminate == CPTerminateNow) + { + [[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationWillTerminateNotification object:self]; + [CPPlatform terminateApplication]; + } } - (void)activateIgnoringOtherApps:(BOOL)shouldIgnoreOtherApps diff --git a/AppKit/CPDocumentController.j b/AppKit/CPDocumentController.j index 7011c7902..c392d172e 100644 --- a/AppKit/CPDocumentController.j +++ b/AppKit/CPDocumentController.j @@ -323,3 +323,38 @@ var CPSharedDocumentController = nil; } @end + +@implementation CPDocumentController (Closing) + +- (void)closeAllDocumentsWithDelegate:(id)aDelegate didCloseAllSelector:(SEL)didCloseSelector contextInfo:(Object)info +{ + var context = { + delegate: aDelegate, + selector: didCloseSelector, + context: info + }; + + [self _closeDocumentsStartingWith:nil shouldClose:YES context:context]; +} + +// Recursive callback method. Start it by passing in a document of nil. +- (void)_closeDocumentsStartingWith:(CPDocument)aDocument shouldClose:(BOOL)shouldClose context:(Object)context +{ + if (shouldClose) + { + [aDocument close]; + + if ([[self documents] count] > 0) + { + [[[self documents] lastObject] canCloseDocumentWithDelegate:self + shouldCloseSelector:@selector(_closeDocumentsStartingWith:shouldClose:context:) + contextInfo:context]; + return; + } + } + + if ([context.delegate respondsToSelector:context.selector]) + objj_msgSend(context.delegate, context.selector, self, [[self documents] count] === 0, context.context); +} + +@end