Updating ITKit with additions to support Haven development.
[ITKit.git] / ITApplicationController.m
diff --git a/ITApplicationController.m b/ITApplicationController.m
new file mode 100644 (file)
index 0000000..f2ba7d5
--- /dev/null
@@ -0,0 +1,138 @@
+#import "ITApplicationController.h"
+#import "ITCategory-NSApplication.h"
+
+@protocol _ITKitITApplicationControllerFSInterpreterResultCompatibility <NSObject>
+- (NSRange)errorRange;
+- (NSString *)errorMessage;
+- (BOOL)isOK;
+@end
+
+@protocol _ITKitITApplicationControllerFSInterpreterCompatibility <NSObject>
+- (void)setObject:(id)object forIdentifier:(NSString *)identifier;
+- (id <_ITKitITApplicationControllerFSInterpreterResultCompatibility>)execute:(NSString *)command;
+@end
+
+@implementation ITApplicationController
+
+- (id)init {
+       if (self = [super init]) {
+               if ([[NSUserDefaults standardUserDefaults] boolForKey:@"ITDebugMode"]) {
+                       SetITDebugMode(YES);
+               }
+               
+               _plugins = nil;
+               
+               _dockMenu = [[NSMenu alloc] initWithTitle:[[NSApplication sharedApplication] applicationName]];
+               
+               _debugMenu = [[NSMenu alloc] initWithTitle:@"Debug"];
+               _debugMenuItem = [[NSMenuItem alloc] initWithTitle:@"Debug" action:nil keyEquivalent:@""];
+               [_debugMenuItem setSubmenu:_debugMenu];
+               _dockDebugMenuItem = [[NSMenuItem alloc] initWithTitle:@"Debug" action:nil keyEquivalent:@""];
+               [_dockDebugMenuItem setSubmenu:_debugMenu];
+       }
+       return self;
+}
+
+- (void)reloadPlugins {
+       if (_plugins) {
+               [_plugins release];
+       }
+       
+       _plugins = [[NSMutableArray alloc] init];
+       
+       NSArray *pluginPaths = [NSBundle pathsForResourcesOfType:@"plugin" inDirectory:[[NSBundle mainBundle] builtInPlugInsPath]];
+       NSEnumerator *pluginPathEnumerator = [pluginPaths objectEnumerator];
+       id pluginPath;
+       
+       while (pluginPath = [pluginPathEnumerator nextObject]) {
+               NSBundle *plugin = [NSBundle bundleWithPath:pluginPath];
+               if ([plugin load]) {
+                       Class pluginClass = [plugin principalClass];
+                       id pluginInstance;
+                       if ([pluginClass instancesRespondToSelector:@selector(initWithApplicationController:)]) {
+                               pluginInstance = [(id <ITApplicationControllerGenericPlugin>)[pluginClass alloc] initWithApplicationController:self];
+                       } else {
+                               pluginInstance = [[pluginClass alloc] init];
+                       }
+                       if (pluginInstance) {
+                               [_plugins addObject:[pluginInstance autorelease]]; // autoreleasing so that when we reload plugins, and the _plugins array is released, the accompanying previously-loaded plugins die with it.
+                       }
+               }
+       }
+       
+       Class fsinterpreterClass;
+       if (fsinterpreterClass = NSClassFromString(@"FSInterpreter")) {
+               NSArray *fscriptPaths = [NSBundle pathsForResourcesOfType:@"fscriptplugin" inDirectory:[[NSBundle mainBundle] builtInPlugInsPath]];
+               NSEnumerator *fscriptPathEnumerator = [fscriptPaths objectEnumerator];
+               id fscriptPath;
+               
+               while (fscriptPath = [fscriptPathEnumerator nextObject]) {
+                       NSString *fscriptSource = [NSString stringWithContentsOfFile:fscriptPath];
+                       if (fscriptSource) {
+                               id fscriptInterpreter = [(id <_ITKitITApplicationControllerFSInterpreterCompatibility>)[fsinterpreterClass alloc] init];
+                               id result;
+                               [fscriptInterpreter setObject:self forIdentifier:@"applicationController"];
+                               [fscriptInterpreter setObject:fscriptInterpreter forIdentifier:@"hostInterpreter"];
+                               result = [fscriptInterpreter execute:fscriptSource];
+                               if (![result isOK]) {
+                                       NSRunAlertPanel(@"F-Script Plugin Error",[NSString stringWithFormat:@"Plugin: %@\nRange: %@\nMessage:%@", fscriptPath, NSStringFromRange([result errorRange]), [result errorMessage]],@"Dismiss",nil,nil);
+                                       [fscriptInterpreter release];
+                               } else {
+                                       [_plugins addObject:[fscriptInterpreter autorelease]];
+                               }
+                       }
+               }
+       }
+}
+
+- (NSArray *)plugins {
+       return _plugins;
+}
+
+- (NSMenu *)dockMenu {
+       return _dockMenu;
+}
+
+- (NSMenu *)debugMenu {
+       return _debugMenu;
+}
+
+- (void)enableDebugMenu {
+       NSMenu *mainMenu = [[NSApplication sharedApplication] mainMenu];
+       int helpIndex = [mainMenu indexOfItemWithTitle:@"Help"];
+       if (helpIndex != -1) {
+               [mainMenu insertItem:_debugMenuItem atIndex:helpIndex];
+       } else {
+               [mainMenu addItem:_debugMenuItem];
+       }
+       
+       [_dockMenu insertItem:_dockDebugMenuItem atIndex:0];
+       if ([_dockMenu numberOfItems] > 1) {
+               [_dockMenu insertItem:[NSMenuItem separatorItem] atIndex:1];
+       }
+}
+
+- (void)disableDebugMenu {
+       [[[NSApplication sharedApplication] mainMenu] removeItem:_debugMenuItem];
+       [_dockMenu removeItem:_dockDebugMenuItem];
+       if ([_dockMenu numberOfItems] > 1) {
+               NSMenuItem *sep = [_dockMenu itemAtIndex:0];
+               if ([sep isSeparatorItem]) {
+                       [_dockMenu removeItem:sep];
+               }
+       }
+}
+
+- (void)dealloc {
+       [_dockDebugMenuItem release];
+       [_debugMenuItem release];
+       [_debugMenu release];
+       [_dockMenu release];
+       [super dealloc];
+}
+
+- (NSMenu *)applicationDockMenu:(NSApplication *)sender {
+       return _dockMenu;
+}
+
+@end