25 @
typedef CPModalSession
35 - (CPApplicationTerminateReply)applicationShouldTerminate:(
CPApplication)sender;
38 - (void)applicationDidChangeScreenParameters:(
CPNotification)aNotification;
39 - (void)applicationDidFinishLaunching:(
CPNotification)aNotification;
42 - (void)applicationWillFinishLaunching:(
CPNotification)aNotification;
77 CPArray _eventListeners;
78 int _eventListenerInsertionIndex;
91 CPModalSession _currentSession;
94 id <CPApplicationDelegate> _delegate;
95 CPInteger _implementedDelegateMethods;
97 BOOL _finishedLaunching;
137 _eventListeners = [];
138 _eventListenerInsertionIndex = 0;
154 - (void)setDelegate:(
id <CPApplicationDelegate>)aDelegate
156 if (_delegate == aDelegate)
159 _implementedDelegateMethods = 0;
162 delegateNotifications =
164 CPApplicationWillFinishLaunchingNotification, @selector(applicationWillFinishLaunching:),
165 CPApplicationDidFinishLaunchingNotification, @selector(applicationDidFinishLaunching:),
166 CPApplicationWillBecomeActiveNotification, @selector(applicationWillBecomeActive:),
167 CPApplicationDidBecomeActiveNotification, @selector(applicationDidBecomeActive:),
168 CPApplicationWillResignActiveNotification, @selector(applicationWillResignActive:),
169 CPApplicationDidResignActiveNotification, @selector(applicationDidResignActive:),
170 CPApplicationWillTerminateNotification, @selector(applicationWillTerminate:),
171 CPApplicationDidChangeScreenParametersNotification, @selector(applicationDidChangeScreenParameters:)
173 count = [delegateNotifications count];
179 for (; index < count; index += 2)
181 var notificationName = delegateNotifications[index],
182 selector = delegateNotifications[index + 1];
184 if ([_delegate respondsToSelector:selector])
185 [defaultCenter removeObserver:_delegate name:notificationName object:self];
189 _delegate = aDelegate;
193 for (; index < count; index += 2)
195 var notificationName = delegateNotifications[index],
196 selector = delegateNotifications[index + 1];
198 if ([_delegate respondsToSelector:selector])
199 [defaultCenter addObserver:_delegate selector:selector name:notificationName object:self];
202 if ([_delegate respondsToSelector:
@selector(applicationShouldTerminate:)])
205 if ([_delegate respondsToSelector:
@selector(applicationShouldTerminateMessage:)])
223 - (void)finishLaunching
236 delegateClassName = [bundle objectForInfoDictionaryKey:@"CPApplicationDelegateClass"];
238 if (delegateClassName)
240 var delegateClass = objj_getClass(delegateClassName);
249 postNotificationName:CPApplicationWillFinishLaunchingNotification
252 var types = [bundle objectForInfoDictionaryKey:@"CPBundleDocumentTypes"];
254 if ([types count] > 0)
257 var needsUntitled = !!_documentController,
261 URLStrings = window.cpOpeningURLStrings && window.cpOpeningURLStrings();
265 count = [URLStrings count];
267 for (; index < count; ++index)
268 needsUntitled = ![
self _openURL:[
CPURL URLWithString:URLStrings[index]]] && needsUntitled;
270 if (needsUntitled && [_delegate respondsToSelector:
@selector(applicationShouldOpenUntitledFile:)])
271 needsUntitled = [_delegate applicationShouldOpenUntitledFile:self];
274 [_documentController newDocument:self];
276 [_documentController _updateRecentDocumentsMenu];
279 postNotificationName:CPApplicationDidFinishLaunchingNotification
284 _finishedLaunching = YES;
287 - (void)terminate:(
id)aSender
296 didCloseAllSelector:@selector(_documentController:didCloseAll:context:)
311 - (void)setApplicationIconImage:(
CPImage)anImage
313 _applicationIconImage = anImage;
322 if (_applicationIconImage)
323 return _applicationIconImage;
329 return _applicationIconImage;
335 - (void)orderFrontStandardAboutPanel:(
id)sender
369 applicationTitle = [options
objectForKey:"ApplicationName"] || [mainInfo objectForKey:@"CPBundleName"],
371 version = [options
objectForKey:@"Version"] || [mainInfo objectForKey:@"CPBundleVersion"],
372 applicationVersion = [options
objectForKey:@"ApplicationVersion"] || [mainInfo objectForKey:@"CPBundleShortVersionString"],
373 copyright = [options
objectForKey:@"Copyright"] || [mainInfo objectForKey:@"CPHumanReadableCopyright"];
375 var windowWidth = 275,
381 imageView = [[
CPImageView alloc] initWithFrame:CGRectMake((windowWidth / 2) - (imgWidth / 2), interField, imgWidth, imgHeight)],
382 applicationLabel = [[
CPTextField alloc] initWithFrame:CGRectMake(17, imgHeight + 16, windowWidth - 34, 24)],
383 versionLabel = [[
CPTextField alloc] initWithFrame:CGRectMake(17, imgHeight + 48, windowWidth - 34, 16)],
384 copyrightLabel = [[
CPTextField alloc] initWithFrame:CGRectMake(17, imgHeight + 72, windowWidth - 34, 32)],
385 contentView = [aboutPanel contentView];
388 [applicationLabel setAlignment:CPCenterTextAlignment];
390 [versionLabel setAlignment:CPCenterTextAlignment];
392 [copyrightLabel setAlignment:CPCenterTextAlignment];
393 [copyrightLabel setLineBreakMode:CPLineBreakByWordWrapping];
395 [contentView addSubview:imageView];
396 [contentView addSubview:applicationLabel];
397 [contentView addSubview:versionLabel];
398 [contentView addSubview:copyrightLabel];
403 size:CGSizeMake(256, 256)]];
405 [applicationLabel setStringValue:applicationTitle || ""];
407 if (applicationVersion && version)
408 [versionLabel setStringValue:@"Version " + applicationVersion + " (" + version + ")"];
409 else if (applicationVersion || version)
410 [versionLabel setStringValue:@"Version " + (applicationVersion || version)];
412 [versionLabel setStringValue:@""];
414 [copyrightLabel setStringValue:copyright || @""];
417 _aboutPanel = aboutPanel;
420 [_aboutPanel orderFront:self];
424 - (void)_documentController:(
CPDocumentController)docController didCloseAll:(BOOL)didCloseAll context:(Object)info
428 [
self replyToApplicationShouldTerminate:[
self _sendDelegateApplicationShouldTerminate]];
431 - (void)replyToApplicationShouldTerminate:(BOOL)terminate
440 - (void)activateIgnoringOtherApps:(BOOL)shouldIgnoreOtherApps
445 [
self _willBecomeActive];
450 [
self _didBecomeActive];
458 [
self _willResignActive];
463 [
self _didResignActive];
471 - (void)hideOtherApplications:(
id)aSender
509 - (void)stopModalWithCode:(
int)aCode
511 if (!_currentSession)
517 _currentSession._state = aCode;
518 _currentSession = _currentSession._previous;
521 [
self _removeRunModalLoop];
525 - (void)_removeRunModalLoop
527 var count = _eventListeners.length;
530 if (_eventListeners[count]._callback === _CPRunModalLoop)
532 _eventListeners.splice(count, 1);
533 if (count <= _eventListenerInsertionIndex)
534 _eventListenerInsertionIndex--;
560 - (CPModalSession)beginModalSessionForWindow:(
CPWindow)aWindow
562 return _CPModalSessionMake(aWindow, 0);
569 - (void)runModalSession:(CPModalSession)aModalSession
571 aModalSession._previous = _currentSession;
572 _currentSession = aModalSession;
574 var theWindow = aModalSession._window;
577 [theWindow makeKeyWindow];
578 [theWindow orderFront:self];
582 [CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:YES];
591 if (!_currentSession)
594 return _currentSession._window;
598 - (BOOL)_handleKeyEquivalent:(
CPEvent)anEvent
600 return [[
self keyWindow] performKeyEquivalent:anEvent] ||
601 [[
self mainMenu] performKeyEquivalent:anEvent];
610 _currentEvent = anEvent;
613 var theWindow = [anEvent
window];
617 if (theWindow !== _lastMouseMoveWindow)
618 [_lastMouseMoveWindow _mouseExitedResizeRect];
620 _lastMouseMoveWindow = theWindow;
629 for (var i = _eventListeners.length - 1; i >= 0; i--)
631 var listener = _eventListeners[i];
633 if (listener._mask & (1 << [anEvent type]))
635 _eventListeners.splice(i, 1);
637 _eventListenerInsertionIndex = i;
638 listener._callback(anEvent);
640 if (listener._dequeue)
643 _eventListenerInsertionIndex = _eventListeners.length;
649 _eventListenerInsertionIndex = _eventListeners.length;
652 if ([anEvent _couldBeKeyEquivalent] && [
self _handleKeyEquivalent:anEvent])
657 [theWindow sendEvent:anEvent];
664 - (void)doCommandBySelector:(
SEL)aSelector
666 if ([_delegate respondsToSelector:aSelector])
667 [_delegate performSelector:aSelector];
691 - (
CPWindow)windowWithWindowNumber:(
int)aWindowNumber
697 return _windows[aWindowNumber];
706 return [_windows subarrayWithRange:CPMakeRange(1, [_windows count] - 1)];
712 - (CPArray)orderedWindows
715 return CPWindowObjectList();
721 - (void)hide:(
id)aSender
746 if ([aMenu _menuName] ===
"CPMainMenu")
748 if ([
self menu] === aMenu)
754 window.cpSetMainMenu([
self menu]);
757 [aMenu _setMenuName:@"CPMainMenu"];
764 - (void)orderFrontColorPanel:(
id)aSender
779 - (BOOL)tryToPerform:(
SEL)anAction with:(
id)anObject
784 if ([super tryToPerform:anAction with:anObject])
787 if ([_delegate respondsToSelector:anAction])
789 [_delegate performSelector:anAction withObject:anObject];
804 - (BOOL)sendAction:(
SEL)anAction to:(
id)aTarget from:(
id)aSender
811 [target performSelector:anAction withObject:aSender];
827 - (id)targetForAction:(
SEL)anAction to:(
id)aTarget from:(
id)aSender
855 - (id)_targetForWindow:(
CPWindow)aWindow action:(
SEL)anAction
862 if ([responder respondsToSelector:anAction])
865 if (responder == aWindow)
868 responder = [responder nextResponder];
871 if (checkWindow && [aWindow respondsToSelector:anAction])
876 if ([
delegate respondsToSelector:anAction])
881 if ([windowController respondsToSelector:anAction])
882 return windowController;
884 var theDocument = [windowController document];
885 if (theDocument !==
delegate && [theDocument respondsToSelector:anAction])
905 - (id)targetForAction:(
SEL)anAction
910 var target = [
self _targetForWindow:[
self keyWindow] action:anAction];
915 target = [
self _targetForWindow:[
self mainWindow] action:anAction];
920 if ([
self respondsToSelector:anAction])
923 if ([_delegate respondsToSelector:anAction])
926 if ([_documentController respondsToSelector:anAction])
927 return _documentController;
947 - (void)setCallback:(Function)aCallback forNextEventMatchingMask:(
unsigned int)aMask untilDate:(
CPDate)anExpiration inMode:(
CPString)aMode dequeue:(BOOL)shouldDequeue
949 _eventListeners.splice(_eventListenerInsertionIndex++, 0, _CPEventListenerMake(aMask, aCallback, shouldDequeue));
969 - (void)setTarget:(
id)aTarget selector:(
SEL)aSelector forNextEventMatchingMask:(
unsigned int)aMask untilDate:(
CPDate)anExpiration inMode:(
CPString)aMode dequeue:(BOOL)shouldDequeue
971 _eventListeners.splice(_eventListenerInsertionIndex++, 0, _CPEventListenerMake(aMask,
function (anEvent) {
if (aTarget != null) aTarget.isa.objj_msgSend1(aTarget, aSelector, anEvent); }, shouldDequeue));
979 return _currentEvent;
992 - (void)beginSheet:(
CPWindow)aSheet modalForWindow:(
CPWindow)aWindow modalDelegate:(
id)aModalDelegate didEndSelector:(
SEL)didEndSelector contextInfo:(
id)contextInfo
994 if ([aWindow isSheet])
996 [
CPException raise:CPInternalInconsistencyException
reason:@"The target window of beginSheet: cannot be a sheet"];
1000 if (![aWindow attachedSheet])
1001 [aSheet._windowView _enableSheet:YES inWindow:aWindow];
1003 [aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:didEndSelector contextInfo:contextInfo];
1019 - (void)endSheet:(
CPWindow)sheet returnCode:(
int)returnCode
1021 var count = [_windows count];
1023 while (--count >= 0)
1025 var aWindow = [_windows objectAtIndex:count],
1026 context = aWindow._sheetContext;
1028 if (context && context[
"sheet"] === sheet)
1030 context["returnCode"] = returnCode;
1031 [aWindow _endSheet];
1062 - (CPArray)arguments
1065 if (window && window.location && _fullArgsString !== window.location.
hash)
1066 [
self _reloadArguments];
1087 - (void)setArguments:(CPArray)args
1089 if (!args || args.length == 0)
1093 if (window && window.location)
1094 window.location.hash =
@"#";
1098 if (![args isKindOfClass:CPArray])
1099 args = [CPArray arrayWithObject:args];
1103 var toEncode = [_args copy];
1104 for (var i = 0, count = toEncode.length; i < count; i++)
1105 toEncode[i] = encodeURIComponent(toEncode[i]);
1107 var hash = [toEncode componentsJoinedByString:@"/"];
1110 if (window && window.location)
1111 window.location.hash =
@"#" + hash;
1114 - (void)_reloadArguments
1117 _fullArgsString = (window && window.location) ? window.location.
hash :
"";
1121 var args = _fullArgsString.substring(1).split(
"/");
1123 for (var i = 0, count = args.length; i < count; i++)
1124 args[i] = decodeURIComponent(args[i]);
1154 - (BOOL)_openURL:(
CPURL)aURL
1156 if (_delegate && [_delegate respondsToSelector:
@selector(application:openFile:)])
1158 CPLog.warn(
"application:openFile: is deprecated, use application:openURL: instead.");
1159 return [_delegate application:self openFile:[aURL
absoluteString]];
1162 if (_delegate && [_delegate respondsToSelector:
@selector(application:openURL:)])
1163 return [_delegate application:self openURL:aURL];
1165 return !![_documentController openDocumentWithContentsOfURL:aURL display:YES error:NULL];
1168 - (void)_willBecomeActive
1175 - (void)_didBecomeActive
1177 if (![
self keyWindow] && _previousKeyWindow &&
1178 [[
self windows] indexOfObjectIdenticalTo:_previousKeyWindow] !==
CPNotFound)
1179 [_previousKeyWindow makeKeyWindow];
1181 if (![
self mainWindow] && _previousMainWindow &&
1182 [[
self windows] indexOfObjectIdenticalTo:_previousMainWindow] !==
CPNotFound)
1183 [_previousMainWindow makeMainWindow];
1185 if ([
self keyWindow])
1186 [[
self keyWindow] orderFront:self];
1187 else if ([
self mainWindow])
1188 [[
self mainWindow] makeKeyAndOrderFront:self];
1189 else if ([
self mainMenu])
1190 [[
self mainMenu]._menuWindow makeKeyWindow];
1192 _previousKeyWindow = nil;
1193 _previousMainWindow = nil;
1200 - (void)_willResignActive
1207 - (BOOL)_sendDelegateApplicationShouldTerminate
1212 return [_delegate applicationShouldTerminate:self];
1215 - (
CPString)_sendDelegateApplicationShouldTerminateMessage
1218 return @"You have attempted to leave this page. Are you sure you want to exit this page?";
1220 return [_delegate applicationShouldTerminateMessage:self];
1223 - (void)_didResignActive
1225 if (
self._activeMenu)
1226 [
self._activeMenu cancelTracking];
1228 if ([
self keyWindow])
1230 _previousKeyWindow = [
self keyWindow];
1231 [_previousKeyWindow resignKeyWindow];
1234 if ([
self mainWindow])
1236 _previousMainWindow = [
self mainWindow];
1237 [_previousMainWindow resignMainWindow];
1247 return ([[
CPBundle mainBundle] objectForInfoDictionaryKey:
"CPDefaultTheme"] ||
@"Aristo2");
1252 var _CPModalSessionMake =
function(aWindow, aStopCode)
1257 var _CPEventListenerMake =
function(anEventMask, aCallback, shouldDequeue)
1259 return { _mask:anEventMask, _callback:aCallback, _dequeue:shouldDequeue };
1263 _CPRunModalLoop =
function(anEvent)
1265 [CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:YES];
1267 var theWindow = [anEvent
window],
1268 modalSession =
CPApp._currentSession;
1273 if (theWindow == modalSession._window ||
1274 [theWindow worksWhenModal] ||
1275 [theWindow attachedSheet] == modalSession._window ||
1276 ([theWindow isKindOfClass:_CPPopoverWindow] && [[theWindow targetView] window] === modalSession._window))
1278 [theWindow sendEvent:anEvent];
1293 if (window.parent !== window && typeof window.parent._childAppIsStarting ===
"function")
1297 window.parent._childAppIsStarting(window);
1302 CPLog.warn(
"Failed to call parent frame's _childAppIsStarting().");
1308 principalClass = [mainBundle principalClass];
1310 if (!principalClass)
1313 [principalClass sharedApplication];
1315 if ([args containsObject:
"debug"])
1316 CPLogRegister(CPLogPopup);
1319 CPApp._namedArgs = namedArgs;
1321 [_CPAppBootstrapper performActions];
1324 var _CPAppBootstrapperActions = nil;
1325 @implementation _CPAppBootstrapper :
CPObject 1332 return [@selector(bootstrapPlatform), @selector(loadDefaultTheme), @selector(loadMainCibFile)];
1335 + (void)performActions
1337 if (!_CPAppBootstrapperActions)
1338 _CPAppBootstrapperActions = [
self actions];
1340 while (_CPAppBootstrapperActions.length)
1342 var action = _CPAppBootstrapperActions.shift();
1344 if (
self.
isa.objj_msgSend0(
self, action))
1351 + (BOOL)bootstrapPlatform
1356 + (BOOL)loadDefaultTheme
1361 if (defaultThemeName ===
@"Aristo" || defaultThemeName ===
@"Aristo2")
1367 [blend loadWithDelegate:self];
1372 + (void)blendDidFinishLoading:(
CPThemeBlend)aThemeBlend
1377 [
self performActions];
1380 + (BOOL)loadMainCibFile
1383 mainCibFile = [mainBundle objectForInfoDictionaryKey:CPMainCibFile] || [mainBundle objectForInfoDictionaryKey:CPMainCibFileHumanFriendly];
1387 [mainBundle loadCibFile:mainCibFile
1388 externalNameTable:@{ CPCibOwner: CPApp }
1394 [
self loadCiblessBrowserMainMenu];
1399 + (void)loadCiblessBrowserMainMenu
1404 [mainMenu setAutoenablesItems:NO];
1411 [mainMenu addItem:newMenuItem];
1418 [mainMenu addItem:openMenuItem];
1429 [saveMenuItem setSubmenu:saveMenu];
1431 [mainMenu addItem:saveMenuItem];
1439 [undoMenuItem setKeyEquivalentModifierMask:CPUndoKeyEquivalentModifierMask];
1440 [redoMenuItem setKeyEquivalentModifierMask:CPRedoKeyEquivalentModifierMask];
1442 [editMenu addItem:undoMenuItem];
1443 [editMenu addItem:redoMenuItem];
1449 [editMenuItem setSubmenu:editMenu];
1450 [editMenuItem setHidden:YES];
1452 [mainMenu addItem:editMenuItem];
1456 [CPApp setMainMenu:mainMenu];
1459 + (void)cibDidFinishLoading:(
CPCib)aCib
1461 [
self performActions];
1464 + (void)cibDidFailToLoad:(
CPCib)aCib
1466 throw new Error(
"Could not load main cib file. Did you forget to nib2cib it?");
1471 _CPAppBootstrapperActions = nil;
1482 + (unsigned)modifierFlags
1504 _themeBlend = aValue;
Used to implement exception handling (creating & raising).
CPModalSession var CPMainCibFileHumanFriendly
void endSheet:returnCode:(CPWindow sheet, [returnCode] int returnCode)
id targetForAction:(SEL anAction)
CPColorPanel sharedColorPanel()
A representation of a single point in time.
void postNotificationName:object:userInfo:(CPString aNotificationName, [object] id anObject, [userInfo] CPDictionary aUserInfo)
An object representation of nil.
CPWindowController windowController()
CPFont systemFontOfSize:(CGSize aSize)
id valueForAttributeWithName:inState:forClass:(CPString aName, [inState] ThemeState aState, [forClass] id aClass)
id sharedDocumentController()
CPModalSession var CPMainCibFile
The main run loop for the application.
void orderFrontStandardAboutPanelWithOptions:(CPDictionary options)
CPResponder firstResponder()
void postNotificationName:object:(CPString aNotificationName, [object] id anObject)
void raise:reason:(CPString aName, [reason] CPString aReason)
void setMenu:(CPMenu aMenu)
CPString defaultThemeName()
void setDefaultTheme:(CPTheme aTheme)
CPNotificationCenter defaultCenter()
A mutable key-value pair collection.
id targetForAction:to:from:(SEL anAction, [to] id aTarget, [from] id aSender)
CPRunLoop currentRunLoop()
void runModalSession:(CPModalSession aModalSession)
id initWithContentRect:styleMask:(CGRect aContentRect, [styleMask] unsigned aStyleMask)
CPString pathForResource:(CPString aFilename)
var CPApplicationDelegate_applicationShouldTerminateMessage_
An immutable string (collection of characters).
CPString absoluteString()
id objectForKey:(id aKey)
if(CPFeatureIsCompatible(CPHTMLCanvasFeature))
void setThemeBlend:(CPThemeBlend aValue)
void orderFront:(id aSender)
CPApplication sharedApplication()
CPImage applicationIconImage()
id initWithContentsOfFile:size:(CPString aFilename, [size] CGSize aSize)
void stopModalWithCode:(int aCode)
void doCommandBySelector:(SEL aSelector)
id initWithContentsOfFile:(CPString aFilename)
A notification that can be posted to a CPNotificationCenter.
CPEvent otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:(CPEventType anEventType, [location] CGPoint aLocation, [modifierFlags] unsigned modifierFlags, [timestamp] CPTimeInterval aTimestamp, [windowNumber] int aWindowNumber, [context] CPGraphicsContext aGraphicsContext, [subtype] short aSubtype, [data1] int aData1, [data2] int aData2)
CPDate limitDateForMode:(CPString aMode)
CPModalSession beginModalSessionForWindow:(CPWindow aWindow)
CPFont boldSystemFontOfSize:(CGSize aSize)
CPApplicationTerminateReply CPTerminateNow
function CPApplicationMain(args, namedArgs)
id objectForInfoDictionaryKey:(CPString aKey)
void setMenu:(CPMenu aMenu)
var CPApplicationDelegate_applicationShouldTerminate_
void sendEvent:(CPEvent anEvent)
Sends messages (CPNotification) between objects.
CPTimeInterval currentTimestamp()
CPBundle bundleForClass:(Class aClass)
CPTheme themeNamed:(CPString aName)
CPModalSession var CPEventModifierFlags
CPPlatformWindow platformWindow()
id valueForAttributeWithName:forClass:(CPString aName, [forClass] id aClass)
CPDictionary infoDictionary()
void setDelegate:(id< CPApplicationDelegate > aDelegate)