Updating ITKit with additions to support Haven development.
[ITKit.git] / ITApplicationController.m
1 #import "ITApplicationController.h"
2 #import "ITCategory-NSApplication.h"
3
4 @protocol _ITKitITApplicationControllerFSInterpreterResultCompatibility <NSObject>
5 - (NSRange)errorRange;
6 - (NSString *)errorMessage;
7 - (BOOL)isOK;
8 @end
9
10 @protocol _ITKitITApplicationControllerFSInterpreterCompatibility <NSObject>
11 - (void)setObject:(id)object forIdentifier:(NSString *)identifier;
12 - (id <_ITKitITApplicationControllerFSInterpreterResultCompatibility>)execute:(NSString *)command;
13 @end
14
15 @implementation ITApplicationController
16
17 - (id)init {
18         if (self = [super init]) {
19                 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"ITDebugMode"]) {
20                         SetITDebugMode(YES);
21                 }
22                 
23                 _plugins = nil;
24                 
25                 _dockMenu = [[NSMenu alloc] initWithTitle:[[NSApplication sharedApplication] applicationName]];
26                 
27                 _debugMenu = [[NSMenu alloc] initWithTitle:@"Debug"];
28                 _debugMenuItem = [[NSMenuItem alloc] initWithTitle:@"Debug" action:nil keyEquivalent:@""];
29                 [_debugMenuItem setSubmenu:_debugMenu];
30                 _dockDebugMenuItem = [[NSMenuItem alloc] initWithTitle:@"Debug" action:nil keyEquivalent:@""];
31                 [_dockDebugMenuItem setSubmenu:_debugMenu];
32         }
33         return self;
34 }
35
36 - (void)reloadPlugins {
37         if (_plugins) {
38                 [_plugins release];
39         }
40         
41         _plugins = [[NSMutableArray alloc] init];
42         
43         NSArray *pluginPaths = [NSBundle pathsForResourcesOfType:@"plugin" inDirectory:[[NSBundle mainBundle] builtInPlugInsPath]];
44         NSEnumerator *pluginPathEnumerator = [pluginPaths objectEnumerator];
45         id pluginPath;
46         
47         while (pluginPath = [pluginPathEnumerator nextObject]) {
48                 NSBundle *plugin = [NSBundle bundleWithPath:pluginPath];
49                 if ([plugin load]) {
50                         Class pluginClass = [plugin principalClass];
51                         id pluginInstance;
52                         if ([pluginClass instancesRespondToSelector:@selector(initWithApplicationController:)]) {
53                                 pluginInstance = [(id <ITApplicationControllerGenericPlugin>)[pluginClass alloc] initWithApplicationController:self];
54                         } else {
55                                 pluginInstance = [[pluginClass alloc] init];
56                         }
57                         if (pluginInstance) {
58                                 [_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.
59                         }
60                 }
61         }
62         
63         Class fsinterpreterClass;
64         if (fsinterpreterClass = NSClassFromString(@"FSInterpreter")) {
65                 NSArray *fscriptPaths = [NSBundle pathsForResourcesOfType:@"fscriptplugin" inDirectory:[[NSBundle mainBundle] builtInPlugInsPath]];
66                 NSEnumerator *fscriptPathEnumerator = [fscriptPaths objectEnumerator];
67                 id fscriptPath;
68                 
69                 while (fscriptPath = [fscriptPathEnumerator nextObject]) {
70                         NSString *fscriptSource = [NSString stringWithContentsOfFile:fscriptPath];
71                         if (fscriptSource) {
72                                 id fscriptInterpreter = [(id <_ITKitITApplicationControllerFSInterpreterCompatibility>)[fsinterpreterClass alloc] init];
73                                 id result;
74                                 [fscriptInterpreter setObject:self forIdentifier:@"applicationController"];
75                                 [fscriptInterpreter setObject:fscriptInterpreter forIdentifier:@"hostInterpreter"];
76                                 result = [fscriptInterpreter execute:fscriptSource];
77                                 if (![result isOK]) {
78                                         NSRunAlertPanel(@"F-Script Plugin Error",[NSString stringWithFormat:@"Plugin: %@\nRange: %@\nMessage:%@", fscriptPath, NSStringFromRange([result errorRange]), [result errorMessage]],@"Dismiss",nil,nil);
79                                         [fscriptInterpreter release];
80                                 } else {
81                                         [_plugins addObject:[fscriptInterpreter autorelease]];
82                                 }
83                         }
84                 }
85         }
86 }
87
88 - (NSArray *)plugins {
89         return _plugins;
90 }
91
92 - (NSMenu *)dockMenu {
93         return _dockMenu;
94 }
95
96 - (NSMenu *)debugMenu {
97         return _debugMenu;
98 }
99
100 - (void)enableDebugMenu {
101         NSMenu *mainMenu = [[NSApplication sharedApplication] mainMenu];
102         int helpIndex = [mainMenu indexOfItemWithTitle:@"Help"];
103         if (helpIndex != -1) {
104                 [mainMenu insertItem:_debugMenuItem atIndex:helpIndex];
105         } else {
106                 [mainMenu addItem:_debugMenuItem];
107         }
108         
109         [_dockMenu insertItem:_dockDebugMenuItem atIndex:0];
110         if ([_dockMenu numberOfItems] > 1) {
111                 [_dockMenu insertItem:[NSMenuItem separatorItem] atIndex:1];
112         }
113 }
114
115 - (void)disableDebugMenu {
116         [[[NSApplication sharedApplication] mainMenu] removeItem:_debugMenuItem];
117         [_dockMenu removeItem:_dockDebugMenuItem];
118         if ([_dockMenu numberOfItems] > 1) {
119                 NSMenuItem *sep = [_dockMenu itemAtIndex:0];
120                 if ([sep isSeparatorItem]) {
121                         [_dockMenu removeItem:sep];
122                 }
123         }
124 }
125
126 - (void)dealloc {
127         [_dockDebugMenuItem release];
128         [_debugMenuItem release];
129         [_debugMenu release];
130         [_dockMenu release];
131         [super dealloc];
132 }
133
134 - (NSMenu *)applicationDockMenu:(NSApplication *)sender {
135         return _dockMenu;
136 }
137
138 @end