From 02d5f734e9907ae0f4b0fa44935097e7747e0eb5 Mon Sep 17 00:00:00 2001 From: Joseph Spiros Date: Fri, 19 Sep 2008 12:36:57 +0000 Subject: [PATCH] Updating ITKit with additions to support Haven development. ITApplicationController is a subclass of ITSharedController from ITFoundation, and provides a standard debug menu, generic plugin loading, and fscriptplugin loading if FScript is loaded. ITCategory-NSApplication adds a method to NSApplication for determining the application's name. --- ITApplicationController.h | 38 +++++++++ ITApplicationController.m | 138 ++++++++++++++++++++++++++++++ ITCategory-NSApplication.h | 18 ++++ ITCategory-NSApplication.m | 13 +++ ITKit.h | 5 +- ITKit.xcodeproj/project.pbxproj | 145 +++++++------------------------- 6 files changed, 240 insertions(+), 117 deletions(-) create mode 100644 ITApplicationController.h create mode 100644 ITApplicationController.m create mode 100644 ITCategory-NSApplication.h create mode 100644 ITCategory-NSApplication.m diff --git a/ITApplicationController.h b/ITApplicationController.h new file mode 100644 index 0000000..5a54907 --- /dev/null +++ b/ITApplicationController.h @@ -0,0 +1,38 @@ +/* + * ITKit + * ITApplicationController.h + * + * Copyright (c) 2008 by iThink Software. + * All Rights Reserved. + * + * $Id$ + * + */ + +#import +#import + +@class ITApplicationController; + +@protocol ITApplicationControllerGenericPlugin +- (id)initWithApplicationController:(ITApplicationController *)applicationController; +@end + +@interface ITApplicationController : ITSharedController { + NSMutableArray *_plugins; + + NSMenu *_dockMenu; + NSMenu *_debugMenu; + NSMenuItem *_debugMenuItem; + NSMenuItem *_dockDebugMenuItem; +} + +- (void)reloadPlugins; +- (NSArray *)plugins; + +- (NSMenu *)dockMenu; +- (NSMenu *)debugMenu; +- (void)enableDebugMenu; +- (void)disableDebugMenu; + +@end diff --git a/ITApplicationController.m b/ITApplicationController.m new file mode 100644 index 0000000..f2ba7d5 --- /dev/null +++ b/ITApplicationController.m @@ -0,0 +1,138 @@ +#import "ITApplicationController.h" +#import "ITCategory-NSApplication.h" + +@protocol _ITKitITApplicationControllerFSInterpreterResultCompatibility +- (NSRange)errorRange; +- (NSString *)errorMessage; +- (BOOL)isOK; +@end + +@protocol _ITKitITApplicationControllerFSInterpreterCompatibility +- (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 )[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 diff --git a/ITCategory-NSApplication.h b/ITCategory-NSApplication.h new file mode 100644 index 0000000..953c281 --- /dev/null +++ b/ITCategory-NSApplication.h @@ -0,0 +1,18 @@ +/* + * ITKit + * ITCategory-NSApplication.h + * + * Copyright (c) 2008 by iThink Software. + * All Rights Reserved. + * + * $Id$ + * + */ + +#import + +@interface NSApplication (ITKitCategory) + +- (NSString *)applicationName; + +@end diff --git a/ITCategory-NSApplication.m b/ITCategory-NSApplication.m new file mode 100644 index 0000000..dec26f4 --- /dev/null +++ b/ITCategory-NSApplication.m @@ -0,0 +1,13 @@ +#import "ITCategory-NSApplication.h" + +@implementation NSApplication (ITKitCategory) + +- (NSString *)applicationName { + NSString *applicationName; + if (!(applicationName = [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:(NSString *)kCFBundleNameKey])) { + applicationName = [[NSProcessInfo processInfo] processName]; + } + return applicationName; +} + +@end diff --git a/ITKit.h b/ITKit.h index 6293924..c9496ef 100644 --- a/ITKit.h +++ b/ITKit.h @@ -4,7 +4,7 @@ * * iThink Software's custom extensions to Apple's Cocoa framework. * - * Copyright (c) 2005 by iThink Software. + * Copyright (c) 2008 by iThink Software. * All Rights Reserved. * * $Id$ @@ -13,6 +13,8 @@ #import +#import + #import #import #import @@ -45,5 +47,6 @@ #import +#import #import #import \ No newline at end of file diff --git a/ITKit.xcodeproj/project.pbxproj b/ITKit.xcodeproj/project.pbxproj index a02dc4c..9caac78 100644 --- a/ITKit.xcodeproj/project.pbxproj +++ b/ITKit.xcodeproj/project.pbxproj @@ -116,34 +116,12 @@ 8DC2EF510486A6940098B216 /* ITKit_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32DBCF5E0370ADEE00C91783 /* ITKit_Prefix.pch */; }; 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; + FAD6912F0E7BD0E800EC3B64 /* ITApplicationController.h in Headers */ = {isa = PBXBuildFile; fileRef = FAD6912D0E7BD0E800EC3B64 /* ITApplicationController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FAD691300E7BD0E800EC3B64 /* ITApplicationController.m in Sources */ = {isa = PBXBuildFile; fileRef = FAD6912E0E7BD0E800EC3B64 /* ITApplicationController.m */; }; + FAD6927F0E7C601800EC3B64 /* ITCategory-NSApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = FAD6927D0E7C601800EC3B64 /* ITCategory-NSApplication.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FAD692800E7C601800EC3B64 /* ITCategory-NSApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = FAD6927E0E7C601800EC3B64 /* ITCategory-NSApplication.m */; }; /* End PBXBuildFile section */ -/* Begin PBXBuildStyle section */ - 014CEA440018CDF011CA2923 /* Development */ = { - isa = PBXBuildStyle; - buildSettings = { - COPY_PHASE_STRIP = NO; - DEBUGGING_SYMBOLS = YES; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_GENERATE_DEBUGGING_SYMBOLS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - OPTIMIZATION_CFLAGS = "-O0"; - ZERO_LINK = YES; - }; - name = Development; - }; - 014CEA450018CDF011CA2923 /* Deployment */ = { - isa = PBXBuildStyle; - buildSettings = { - COPY_PHASE_STRIP = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - ZERO_LINK = NO; - }; - name = Deployment; - }; -/* End PBXBuildStyle section */ - /* Begin PBXContainerItemProxy section */ 2AC8297F056C451900A7D7E2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -230,7 +208,7 @@ 7C02301C08A84A1E00DDBD03 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/ITAboutWindow.nib; sourceTree = SOURCE_ROOT; }; 7C4BBADA05F98C9900734027 /* ITMultilineTextFieldCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITMultilineTextFieldCell.h; sourceTree = ""; }; 7C4BBADB05F98C9900734027 /* ITMultilineTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ITMultilineTextFieldCell.m; sourceTree = ""; }; - 7C6E5BF607D7774500A5F91F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; + 7C6E5BF607D7774500A5F91F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7C6E5BF707D7776F00A5F91F /* Japanese */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Japanese; path = Japanese.lproj/Localizable.strings; sourceTree = ""; }; 7C6E5BF807D7778300A5F91F /* French */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = French; path = French.lproj/Localizable.strings; sourceTree = ""; }; 7C6E5BF907D7778700A5F91F /* German */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = German; path = German.lproj/Localizable.strings; sourceTree = ""; }; @@ -310,6 +288,10 @@ 7CEA43C907D77F1600CACD9D /* ITLoginItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ITLoginItem.m; sourceTree = ""; }; 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 8DC2EF5B0486A6940098B216 /* ITKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ITKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + FAD6912D0E7BD0E800EC3B64 /* ITApplicationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITApplicationController.h; sourceTree = ""; }; + FAD6912E0E7BD0E800EC3B64 /* ITApplicationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ITApplicationController.m; sourceTree = ""; }; + FAD6927D0E7C601800EC3B64 /* ITCategory-NSApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ITCategory-NSApplication.h"; sourceTree = ""; }; + FAD6927E0E7C601800EC3B64 /* ITCategory-NSApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ITCategory-NSApplication.m"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -399,6 +381,7 @@ 7C992F9B054F547C000B93EA /* ITHotKey */, 37B7F65C0754F8440089C005 /* ITSplashScreen */, 7C02300808A8486A00DDBD03 /* ITAboutWindowController */, + FAD9C0340E83CC5D00E110AF /* ITApplicationController */, ); name = Classes; sourceTree = ""; @@ -502,10 +485,12 @@ 7C992F90054F53D9000B93EA /* Categories */ = { isa = PBXGroup; children = ( - 7C992DD1054F5179000B93EA /* ITCategory-NSView.h */, - 7C992DD2054F5179000B93EA /* ITCategory-NSView.m */, + FAD6927D0E7C601800EC3B64 /* ITCategory-NSApplication.h */, + FAD6927E0E7C601800EC3B64 /* ITCategory-NSApplication.m */, 7C992DCF054F5179000B93EA /* ITCategory-NSMenu.h */, 7C992DD0054F5179000B93EA /* ITCategory-NSMenu.m */, + 7C992DD1054F5179000B93EA /* ITCategory-NSView.h */, + 7C992DD2054F5179000B93EA /* ITCategory-NSView.m */, ); name = Categories; sourceTree = ""; @@ -762,6 +747,15 @@ name = ITLoginItem; sourceTree = ""; }; + FAD9C0340E83CC5D00E110AF /* ITApplicationController */ = { + isa = PBXGroup; + children = ( + FAD6912D0E7BD0E800EC3B64 /* ITApplicationController.h */, + FAD6912E0E7BD0E800EC3B64 /* ITApplicationController.m */, + ); + name = ITApplicationController; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -819,6 +813,8 @@ 7C02300B08A8488B00DDBD03 /* ITAboutWindowController.h in Headers */, 37FA494D094DE28B0078A329 /* ITCoreImageWindowEffect.h in Headers */, 370C98540995CC7E008C3200 /* ITCoreImageView.h in Headers */, + FAD6912F0E7BD0E800EC3B64 /* ITApplicationController.h in Headers */, + FAD6927F0E7C601800EC3B64 /* ITCategory-NSApplication.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -837,26 +833,6 @@ ); buildRules = ( ); - buildSettings = { - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_PREFIX_HEADER = ""; - GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; - GCC_WARN_UNKNOWN_PRAGMAS = NO; - INFOPLIST_FILE = Showcase/Info.plist; - INSTALL_PATH = "$(USER_APPS_DIR)"; - MACOSX_DEPLOYMENT_TARGET = 10.2; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ( - "-framework", - Foundation, - "-framework", - AppKit, - ); - OTHER_REZFLAGS = ""; - PRODUCT_NAME = ITKitShowcase; - SECTORDER_FLAGS = ""; - WARNING_CFLAGS = "-Wmost"; - }; dependencies = ( 7C105BEA07D787D8002DE061 /* PBXTargetDependency */, 2AC82980056C451900A7D7E2 /* PBXTargetDependency */, @@ -864,33 +840,6 @@ name = ITKitShowcase; productName = ITKitShowcase; productReference = 7C992F87054F5389000B93EA /* ITKitShowcase.app */; - productSettingsXML = " - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ITKitShowcase - CFBundleGetInfoString - - CFBundleIconFile - - CFBundleIdentifier - com.MySoftwareCompany.ITKitShowcase - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleShortVersionString - - CFBundleSignature - ???? - CFBundleVersion - 1.0.0d1 - - -"; productType = "com.apple.product-type.application"; }; 8DC2EF4F0486A6940098B216 /* ITKit */ = { @@ -904,36 +853,6 @@ ); buildRules = ( ); - buildSettings = { - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_VERSION = A; - GCC_ENABLE_TRIGRAPHS = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = ITKit_Prefix.pch; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; - GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; - GCC_WARN_UNKNOWN_PRAGMAS = NO; - HEADER_SEARCH_PATHS = ""; - INFOPLIST_FILE = Info.plist; - INSTALL_PATH = "@executable_path/../Frameworks"; - LIBRARY_SEARCH_PATHS = ""; - LIBRARY_STYLE = Dynamic; - MACOSX_DEPLOYMENT_TARGET = 10.2; - OTHER_LDFLAGS = ( - "-seg1addr", - 0x19000000, - ); - PRODUCT_NAME = ITKit; - SECTORDER_FLAGS = ""; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); - WRAPPER_EXTENSION = framework; - }; dependencies = ( 7C105BE807D787D0002DE061 /* PBXTargetDependency */, ); @@ -949,14 +868,7 @@ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 7C022FEF08A8465D00DDBD03 /* Build configuration list for PBXProject "ITKit" */; - buildSettings = { - MACOSX_DEPLOYMENT_TARGET = 10.2; - SDKROOT = /Developer/SDKs/MacOSX10.2.8.sdk; - }; - buildStyles = ( - 014CEA440018CDF011CA2923 /* Development */, - 014CEA450018CDF011CA2923 /* Deployment */, - ); + compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 0867D691FE84028FC02AAC07 /* ITKit */; productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; @@ -967,6 +879,7 @@ ProjectRef = 7CDC144907D7869C00B64193 /* ITFoundation.xcodeproj */; }, ); + projectRoot = ""; targets = ( 8DC2EF4F0486A6940098B216 /* ITKit */, 7C992F86054F5389000B93EA /* ITKitShowcase */, @@ -1068,6 +981,8 @@ 7C02300C08A8488B00DDBD03 /* ITAboutWindowController.m in Sources */, 37FA494E094DE28B0078A329 /* ITCoreImageWindowEffect.m in Sources */, 370C98550995CC7E008C3200 /* ITCoreImageView.m in Sources */, + FAD691300E7BD0E800EC3B64 /* ITApplicationController.m in Sources */, + FAD692800E7C601800EC3B64 /* ITCategory-NSApplication.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1187,7 +1102,6 @@ LIBRARY_STYLE = Dynamic; MACH_O_TYPE = mh_dylib; MACOSX_DEPLOYMENT_TARGET = 10.2; - OPTIMIZATION_CFLAGS = "-O0"; OTHER_LDFLAGS = ( "-seg1addr", 0x19000000, @@ -1296,7 +1210,6 @@ INFOPLIST_FILE = Showcase/Info.plist; INSTALL_PATH = "$(USER_APPS_DIR)"; MACOSX_DEPLOYMENT_TARGET = 10.2; - OPTIMIZATION_CFLAGS = "-O0"; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( "-framework", -- 2.20.1