diff --git a/Tools/XcodeCapp/XcodeCapp.xcodeproj/project.pbxproj b/Tools/XcodeCapp/XcodeCapp.xcodeproj/project.pbxproj index e3f7d7cca..420f6d056 100644 --- a/Tools/XcodeCapp/XcodeCapp.xcodeproj/project.pbxproj +++ b/Tools/XcodeCapp/XcodeCapp.xcodeproj/project.pbxproj @@ -7,9 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - E1310C96172863BE002E0A59 /* icon-active@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E1310C93172863BE002E0A59 /* icon-active@2x.png */; }; - E1310C97172863BE002E0A59 /* icon-inactive@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E1310C94172863BE002E0A59 /* icon-inactive@2x.png */; }; - E1310C98172863BE002E0A59 /* icon-working@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E1310C95172863BE002E0A59 /* icon-working@2x.png */; }; + E10E4CD717298E5F004AB09E /* project.pbxproj in Resources */ = {isa = PBXBuildFile; fileRef = E164FE2A172188F300263CE3 /* project.pbxproj */; }; E132ED951724B64C00D870AE /* FSEventCallback.m in Sources */ = {isa = PBXBuildFile; fileRef = E132ED941724B64C00D870AE /* FSEventCallback.m */; }; E164FDD31720E77100263CE3 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E164FDD21720E77100263CE3 /* Cocoa.framework */; }; E164FDDF1720E77100263CE3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E164FDDE1720E77100263CE3 /* main.m */; }; @@ -20,16 +18,21 @@ E164FE001720EC5B00263CE3 /* UserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = E164FDFD1720EC5B00263CE3 /* UserDefaults.m */; }; E164FE061720ED4500263CE3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E164FE041720ED4400263CE3 /* InfoPlist.strings */; }; E164FE0D1720F26C00263CE3 /* help.rtfd in Resources */ = {isa = PBXBuildFile; fileRef = E164FE081720F26C00263CE3 /* help.rtfd */; }; - E164FE151720F40400263CE3 /* mod_pbxproj.py in Resources */ = {isa = PBXBuildFile; fileRef = E164FE131720F40400263CE3 /* mod_pbxproj.py */; }; - E164FE161720F40400263CE3 /* pbxprojModifier.py in Resources */ = {isa = PBXBuildFile; fileRef = E164FE141720F40400263CE3 /* pbxprojModifier.py */; }; E164FE181720F44B00263CE3 /* parser.j in Resources */ = {isa = PBXBuildFile; fileRef = E164FE171720F44B00263CE3 /* parser.j */; }; E164FE1A1720F49A00263CE3 /* Growl Registration Ticket.growlRegDict in Resources */ = {isa = PBXBuildFile; fileRef = E164FE191720F49A00263CE3 /* Growl Registration Ticket.growlRegDict */; }; E164FE1F1720F51E00263CE3 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E164FE1D1720F50100263CE3 /* CoreServices.framework */; }; E164FE211720F55600263CE3 /* Growl.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = E164FDF61720EBD600263CE3 /* Growl.framework */; }; - E164FE2B172188F300263CE3 /* project.pbxproj in Resources */ = {isa = PBXBuildFile; fileRef = E164FE2A172188F300263CE3 /* project.pbxproj */; }; E164FE2F1721A34900263CE3 /* icon-active.png in Resources */ = {isa = PBXBuildFile; fileRef = E164FE2C1721A34900263CE3 /* icon-active.png */; }; E164FE301721A34900263CE3 /* icon-inactive.png in Resources */ = {isa = PBXBuildFile; fileRef = E164FE2D1721A34900263CE3 /* icon-inactive.png */; }; E164FE311721A34900263CE3 /* icon-working.png in Resources */ = {isa = PBXBuildFile; fileRef = E164FE2E1721A34900263CE3 /* icon-working.png */; }; + E170C3FB17296205003DC489 /* pbxprojModifier.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = E164FE141720F40400263CE3 /* pbxprojModifier.py */; }; + E170C3FC1729620C003DC489 /* mod_pbxproj.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = E164FE131720F40400263CE3 /* mod_pbxproj.py */; }; + E170C3FD1729620F003DC489 /* parser.j in CopyFiles */ = {isa = PBXBuildFile; fileRef = E164FE171720F44B00263CE3 /* parser.j */; }; + E170C40317298833003DC489 /* icon-active@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E170C3FE17298833003DC489 /* icon-active@2x.png */; }; + E170C40417298833003DC489 /* icon-error.png in Resources */ = {isa = PBXBuildFile; fileRef = E170C3FF17298833003DC489 /* icon-error.png */; }; + E170C40517298833003DC489 /* icon-error@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E170C40017298833003DC489 /* icon-error@2x.png */; }; + E170C40617298833003DC489 /* icon-inactive@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E170C40117298833003DC489 /* icon-inactive@2x.png */; }; + E170C40717298833003DC489 /* icon-working@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E170C40217298833003DC489 /* icon-working@2x.png */; }; E17A822D172700B90095CD83 /* XcodeCapp.iconset in Resources */ = {isa = PBXBuildFile; fileRef = E17A822C172700B90095CD83 /* XcodeCapp.iconset */; }; /* End PBXBuildFile section */ @@ -44,12 +47,21 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + E170C3F9172961E6003DC489 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 12; + files = ( + E170C3FB17296205003DC489 /* pbxprojModifier.py in CopyFiles */, + E170C3FC1729620C003DC489 /* mod_pbxproj.py in CopyFiles */, + E170C3FD1729620F003DC489 /* parser.j in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - E1310C93172863BE002E0A59 /* icon-active@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-active@2x.png"; path = "Resources/icon-active@2x.png"; sourceTree = ""; }; - E1310C94172863BE002E0A59 /* icon-inactive@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-inactive@2x.png"; path = "Resources/icon-inactive@2x.png"; sourceTree = ""; }; - E1310C95172863BE002E0A59 /* icon-working@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-working@2x.png"; path = "Resources/icon-working@2x.png"; sourceTree = ""; }; E132ED941724B64C00D870AE /* FSEventCallback.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSEventCallback.m; sourceTree = ""; }; E132ED961724B6C400D870AE /* FSEventCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSEventCallback.h; sourceTree = ""; }; E132ED991724B71600D870AE /* TNXCodeCapp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TNXCodeCapp.h; sourceTree = ""; }; @@ -80,6 +92,11 @@ E164FE2C1721A34900263CE3 /* icon-active.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-active.png"; path = "Resources/icon-active.png"; sourceTree = ""; }; E164FE2D1721A34900263CE3 /* icon-inactive.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-inactive.png"; path = "Resources/icon-inactive.png"; sourceTree = ""; }; E164FE2E1721A34900263CE3 /* icon-working.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-working.png"; path = "Resources/icon-working.png"; sourceTree = ""; }; + E170C3FE17298833003DC489 /* icon-active@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-active@2x.png"; path = "Resources/icon-active@2x.png"; sourceTree = ""; }; + E170C3FF17298833003DC489 /* icon-error.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-error.png"; path = "Resources/icon-error.png"; sourceTree = ""; }; + E170C40017298833003DC489 /* icon-error@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-error@2x.png"; path = "Resources/icon-error@2x.png"; sourceTree = ""; }; + E170C40117298833003DC489 /* icon-inactive@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-inactive@2x.png"; path = "Resources/icon-inactive@2x.png"; sourceTree = ""; }; + E170C40217298833003DC489 /* icon-working@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-working@2x.png"; path = "Resources/icon-working@2x.png"; sourceTree = ""; }; E17A822C172700B90095CD83 /* XcodeCapp.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; name = XcodeCapp.iconset; path = Resources/XcodeCapp.iconset; sourceTree = ""; }; E1DD4DF517282BFC0063C0D7 /* UserDefaults.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UserDefaults.h; sourceTree = ""; }; /* End PBXFileReference section */ @@ -170,12 +187,14 @@ E164FE071720F25400263CE3 /* Resources */ = { isa = PBXGroup; children = ( - E164FE2C1721A34900263CE3 /* icon-active.png */, E164FE2D1721A34900263CE3 /* icon-inactive.png */, + E170C40117298833003DC489 /* icon-inactive@2x.png */, E164FE2E1721A34900263CE3 /* icon-working.png */, - E1310C93172863BE002E0A59 /* icon-active@2x.png */, - E1310C94172863BE002E0A59 /* icon-inactive@2x.png */, - E1310C95172863BE002E0A59 /* icon-working@2x.png */, + E170C40217298833003DC489 /* icon-working@2x.png */, + E164FE2C1721A34900263CE3 /* icon-active.png */, + E170C3FE17298833003DC489 /* icon-active@2x.png */, + E170C3FF17298833003DC489 /* icon-error.png */, + E170C40017298833003DC489 /* icon-error@2x.png */, E17A822C172700B90095CD83 /* XcodeCapp.iconset */, E164FDE71720E77100263CE3 /* MainMenu.xib */, E164FE2A172188F300263CE3 /* project.pbxproj */, @@ -188,9 +207,9 @@ E164FE121720F3E100263CE3 /* Scripts */ = { isa = PBXGroup; children = ( + E164FE171720F44B00263CE3 /* parser.j */, E164FE141720F40400263CE3 /* pbxprojModifier.py */, E164FE131720F40400263CE3 /* mod_pbxproj.py */, - E164FE171720F44B00263CE3 /* parser.j */, ); path = Scripts; sourceTree = ""; @@ -206,6 +225,7 @@ E164FDCC1720E77100263CE3 /* Frameworks */, E164FDCD1720E77100263CE3 /* Resources */, E164FE201720F54800263CE3 /* CopyFiles */, + E170C3F9172961E6003DC489 /* CopyFiles */, ); buildRules = ( ); @@ -250,18 +270,18 @@ E164FDE91720E77100263CE3 /* MainMenu.xib in Resources */, E164FE061720ED4500263CE3 /* InfoPlist.strings in Resources */, E164FE0D1720F26C00263CE3 /* help.rtfd in Resources */, - E164FE151720F40400263CE3 /* mod_pbxproj.py in Resources */, - E164FE161720F40400263CE3 /* pbxprojModifier.py in Resources */, + E10E4CD717298E5F004AB09E /* project.pbxproj in Resources */, E164FE181720F44B00263CE3 /* parser.j in Resources */, E164FE1A1720F49A00263CE3 /* Growl Registration Ticket.growlRegDict in Resources */, - E164FE2B172188F300263CE3 /* project.pbxproj in Resources */, E164FE2F1721A34900263CE3 /* icon-active.png in Resources */, E164FE301721A34900263CE3 /* icon-inactive.png in Resources */, E164FE311721A34900263CE3 /* icon-working.png in Resources */, E17A822D172700B90095CD83 /* XcodeCapp.iconset in Resources */, - E1310C96172863BE002E0A59 /* icon-active@2x.png in Resources */, - E1310C97172863BE002E0A59 /* icon-inactive@2x.png in Resources */, - E1310C98172863BE002E0A59 /* icon-working@2x.png in Resources */, + E170C40317298833003DC489 /* icon-active@2x.png in Resources */, + E170C40417298833003DC489 /* icon-error.png in Resources */, + E170C40517298833003DC489 /* icon-error@2x.png in Resources */, + E170C40617298833003DC489 /* icon-inactive@2x.png in Resources */, + E170C40717298833003DC489 /* icon-working@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Tools/XcodeCapp/XcodeCapp/AppController.h b/Tools/XcodeCapp/XcodeCapp/AppController.h index 82d49e362..d994293a2 100644 --- a/Tools/XcodeCapp/XcodeCapp/AppController.h +++ b/Tools/XcodeCapp/XcodeCapp/AppController.h @@ -40,7 +40,6 @@ + (AppController *)sharedAppController; - (IBAction)listenToProject:(id)aSender; -- (IBAction)openInXcode:(id)aSender; - (IBAction)openHelp:(id)aSender; - (IBAction)openAbout:(id)aSender; diff --git a/Tools/XcodeCapp/XcodeCapp/AppController.m b/Tools/XcodeCapp/XcodeCapp/AppController.m index 044079217..f8530d750 100644 --- a/Tools/XcodeCapp/XcodeCapp/AppController.m +++ b/Tools/XcodeCapp/XcodeCapp/AppController.m @@ -37,6 +37,7 @@ AppController *SharedAppControllerInstance = nil; @property (nonatomic) NSImage *iconActive; @property (nonatomic) NSImage *iconInactive; @property (nonatomic) NSImage *iconWorking; +@property (nonatomic) NSImage *iconError; @property (nonatomic) NSMenu *menuHistory; @property NSStatusItem *statusItem; @@ -104,15 +105,16 @@ AppController *SharedAppControllerInstance = nil; - (void)registerDefaults { NSDictionary *appDefaults = @{ - kDefaultLastEventId: [NSNumber numberWithUnsignedLongLong:kFSEventStreamEventIdSinceNow], - kDefaultFirstLaunch: @YES, - kDefaultFirstLaunchVersion: @2.0, - kDefaultXCCAPIMode: [NSNumber numberWithInt:kXCCAPIModeAuto], - kDefaultXCCReactMode: @YES, - kDefaultXCCReopenLastProject: @YES, - kDefaultXCCAutoOpenErrorsPanel: @YES, - kDefaultXCCProjectHistory: [NSArray new], - kDefaultMaxRecentProjects: @20 + kDefaultLastEventId: [NSNumber numberWithUnsignedLongLong:kFSEventStreamEventIdSinceNow], + kDefaultFirstLaunch: @YES, + kDefaultFirstLaunchVersion: @2.0, + kDefaultXCCAPIMode: [NSNumber numberWithInt:kXCCAPIModeAuto], + kDefaultXCCReactMode: @YES, + kDefaultXCCReopenLastProject: @YES, + kDefaultXCCAutoOpenErrorsPanelOnWarnings: @YES, + kDefaultXCCAutoOpenErrorsPanelOnErrors: @YES, + kDefaultXCCProjectHistory: [NSArray new], + kDefaultMaxRecentProjects: @20 }; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; @@ -171,6 +173,14 @@ AppController *SharedAppControllerInstance = nil; return _iconWorking; } +- (NSImage *)iconError +{ + if (!_iconError) + _iconError = [NSImage imageNamed:@"icon-error"]; + + return _iconError; +} + - (NSMenu *)menuHistory { if (!_menuHistory) @@ -205,7 +215,7 @@ AppController *SharedAppControllerInstance = nil; - (void)XcodeCappConversionDidStop:(NSNotification *)aNotification { if (!self.xcc.isLoadingProject) - self.statusItem.image = self.iconActive; + self.statusItem.image = self.xcc.hasErrors ? self.iconError : self.iconActive; } - (void)XcodeCappDidPopulateProject:(NSNotification *)aNotification @@ -214,7 +224,7 @@ AppController *SharedAppControllerInstance = nil; - (void)XcodeCappListeningDidStart:(NSNotification *)aNotification { - self.statusItem.image = self.iconActive; + self.statusItem.image = self.xcc.hasErrors ? self.iconError : self.iconActive; self.menuItemListen.title = [NSString stringWithFormat:@"Close “%@”", self.xcc.currentProjectPath.lastPathComponent]; self.menuItemListen.action = @selector(stopListening:); } @@ -308,15 +318,6 @@ AppController *SharedAppControllerInstance = nil; [self updateHistoryMenu]; } -- (IBAction)openInXcode:(id)aSender -{ - if (!self.xcc.currentProjectPath) - return; - - DLog(@"Opening Xcode project at: %@", self.xcc.XcodeSupportProjectURL.path); - system([[NSString stringWithFormat:@"open \"%@\"", self.xcc.XcodeSupportProjectURL.path] UTF8String]); -} - - (IBAction)openHelp:(id)aSender { [self.helpTextView readRTFDFromFile:[[NSBundle mainBundle] pathForResource:@"help" ofType:@"rtfd"]]; diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp-status-icons.psd b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp-status-icons.psd index 4233fb174..cfac28013 100644 Binary files a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp-status-icons.psd and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp-status-icons.psd differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/icon-active.png b/Tools/XcodeCapp/XcodeCapp/Resources/icon-active.png index be61d20da..1b55fe315 100644 Binary files a/Tools/XcodeCapp/XcodeCapp/Resources/icon-active.png and b/Tools/XcodeCapp/XcodeCapp/Resources/icon-active.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/icon-active@2x.png b/Tools/XcodeCapp/XcodeCapp/Resources/icon-active@2x.png index d3e535249..dd2bf9b49 100644 Binary files a/Tools/XcodeCapp/XcodeCapp/Resources/icon-active@2x.png and b/Tools/XcodeCapp/XcodeCapp/Resources/icon-active@2x.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/icon-error.png b/Tools/XcodeCapp/XcodeCapp/Resources/icon-error.png new file mode 100644 index 000000000..3792f55fd Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/icon-error.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/icon-error@2x.png b/Tools/XcodeCapp/XcodeCapp/Resources/icon-error@2x.png new file mode 100644 index 000000000..abdd05568 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/icon-error@2x.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/icon-inactive.png b/Tools/XcodeCapp/XcodeCapp/Resources/icon-inactive.png index 0de5b1913..5af77c35f 100644 Binary files a/Tools/XcodeCapp/XcodeCapp/Resources/icon-inactive.png and b/Tools/XcodeCapp/XcodeCapp/Resources/icon-inactive.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/icon-inactive@2x.png b/Tools/XcodeCapp/XcodeCapp/Resources/icon-inactive@2x.png index c58a2be73..dc626fa20 100644 Binary files a/Tools/XcodeCapp/XcodeCapp/Resources/icon-inactive@2x.png and b/Tools/XcodeCapp/XcodeCapp/Resources/icon-inactive@2x.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/icon-working.png b/Tools/XcodeCapp/XcodeCapp/Resources/icon-working.png index 2cda359e2..f6cc62bf5 100644 Binary files a/Tools/XcodeCapp/XcodeCapp/Resources/icon-working.png and b/Tools/XcodeCapp/XcodeCapp/Resources/icon-working.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/icon-working@2x.png b/Tools/XcodeCapp/XcodeCapp/Resources/icon-working@2x.png index a225eeb40..9741e0964 100644 Binary files a/Tools/XcodeCapp/XcodeCapp/Resources/icon-working@2x.png and b/Tools/XcodeCapp/XcodeCapp/Resources/icon-working@2x.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Scripts/parser.j b/Tools/XcodeCapp/XcodeCapp/Scripts/parser.j index 205d248c3..7709f9dae 100644 --- a/Tools/XcodeCapp/XcodeCapp/Scripts/parser.j +++ b/Tools/XcodeCapp/XcodeCapp/Scripts/parser.j @@ -41,8 +41,7 @@ function raise(pos, message) throw syntaxError; } -var hasWarnings = false, - errors = [], +var errors = [], xcc = ObjectiveJ.acorn.walk.make( { ClassDeclarationStatement: function(node, st, c) @@ -54,7 +53,7 @@ var hasWarnings = false, @"path": node.loc.source, @"line": node.loc.start.line }]; - hasWarnings = true; + return; } @@ -159,7 +158,8 @@ function main(args) tokens = ObjectiveJ.acorn.parse(source, { locations:true, sourceFile:sourceFile }), classesInformation = [], ObjectiveCSource = "", - ObjectiveCHeader = ""; + ObjectiveCHeader = "", + hasErrors = NO; compile(tokens, classesInformation, xcc); @@ -218,6 +218,8 @@ function main(args) @"path": sourceFile, @"line": e.line }]; + + hasErrors = YES; } if ([errors count]) @@ -225,7 +227,9 @@ function main(args) var plist = [CPPropertyListSerialization dataFromPropertyList:errors format:CPPropertyListXMLFormat_v1_0]; print([plist rawString]); - OS.exit(1); + + // If there were category warnings, hasErrors is NO, so return a warning status + OS.exit(hasErrors ? 1 : 2); } } diff --git a/Tools/XcodeCapp/XcodeCapp/Scripts/pbxprojModifier.py b/Tools/XcodeCapp/XcodeCapp/Scripts/pbxprojModifier.py index 1c60cd770..8bcc391f8 100755 --- a/Tools/XcodeCapp/XcodeCapp/Scripts/pbxprojModifier.py +++ b/Tools/XcodeCapp/XcodeCapp/Scripts/pbxprojModifier.py @@ -4,7 +4,7 @@ import re import sys from mod_pbxproj import XcodeProject -XCODE_SUPPORT_FOLDER = "XcodeSupport" +XCODE_SUPPORT_FOLDER = ".XcodeSupport" SLASH_REPLACEMENT = u"∕" # DIVISION SLASH Unicode U+2215 STRING_RE = re.compile(ur"^\s*(.*)\s*$", re.MULTILINE) FRAMEWORKS_RE = re.compile(ur"^(.+/Frameworks/(?:Debug|Source)/([^/]+))/.+$") diff --git a/Tools/XcodeCapp/XcodeCapp/TNXCodeCapp.h b/Tools/XcodeCapp/XcodeCapp/TNXCodeCapp.h index 8b8814561..f111270fe 100644 --- a/Tools/XcodeCapp/XcodeCapp/TNXCodeCapp.h +++ b/Tools/XcodeCapp/XcodeCapp/TNXCodeCapp.h @@ -51,6 +51,9 @@ extern NSString * const XCCListeningDidStartNotification; - (IBAction)openErrorsPanel:(id)sender; - (IBAction)clearErrors:(id)sender; - (IBAction)openErrorInEditor:(id)sender; +- (IBAction)openInXcode:(id)aSender; +- (IBAction)resetProject:(id)aSender; + - (void)start; - (void)stop; - (void)listenToProjectAtPath:(NSString *)path; @@ -63,6 +66,7 @@ extern NSString * const XCCListeningDidStartNotification; - (void)handleFileModificationAtPath:(NSString*)path notify:(BOOL)shouldNotify; - (void)handleFileRemovalAtPath:(NSString*)path; - (void)updateUserDefaultsWithLastEventId; +- (BOOL)hasErrors; @end diff --git a/Tools/XcodeCapp/XcodeCapp/TNXcodeCapp.m b/Tools/XcodeCapp/XcodeCapp/TNXcodeCapp.m index f7a99d5e4..6646b0641 100644 --- a/Tools/XcodeCapp/XcodeCapp/TNXcodeCapp.m +++ b/Tools/XcodeCapp/XcodeCapp/TNXcodeCapp.m @@ -39,6 +39,27 @@ enum XCCLineSpecifier { }; typedef enum XCCLineSpecifier XCCLineSpecifier; +enum { + XCCStatusCodeError = 1, + XCCStatusCodeWarning = 2 +}; + +const char *XCCCloseProjectScript = + "tell application \"Xcode\"\n" + "set docs to (document of every window)\n" + "repeat with doc in docs\n" + "if class of doc is workspace document then\n" + "set docURL to file of doc\n" + "set docPath to docURL as text\n" + "set docPath to POSIX path of docPath\n" + "if docPath begins with \"%@\" then\n" + "close doc\n" + "return\n" + "end if\n" + "end if\n" + "end repeat\n" + "end tell"; + NSString * const XCCDidPopulateProjectNotification = @"XCCDidPopulateProjectNotification"; NSString * const XCCConversionDidStartNotification = @"XCCConversionDidStartNotification"; NSString * const XCCConversionDidStopNotification = @"XCCConversionDidStopNotification"; @@ -67,6 +88,7 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; @property NSString *profilePath; @property NSString *shellPath; @property NSString *PBXModifierScriptPath; +@property NSString *closeProjectScriptSource; @property NSString *supportPath; @property NSDate *appStartedTimestamp; @property NSMutableDictionary *pathModificationDates; @@ -115,7 +137,8 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; self.errorList = [NSMutableArray arrayWithCapacity:10]; self.fm = [NSFileManager defaultManager]; self.ignoredPathRegexes = [NSMutableArray new]; - self.parserPath = [[NSBundle mainBundle] pathForResource:@"parser" ofType:@"j"]; + self.parserPath = [[[NSBundle mainBundle] sharedSupportPath] stringByAppendingPathComponent:@"parser.j"]; + self.closeProjectScriptSource = [NSString stringWithUTF8String:XCCCloseProjectScript]; self.lastEventId = [[NSUserDefaults standardUserDefaults] objectForKey:kDefaultLastEventId]; self.appStartedTimestamp = [NSDate date]; self.projectPathsForSourcePaths = [NSMutableDictionary new]; @@ -192,24 +215,24 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; NSURL *projectURL = [NSURL fileURLWithPath:self.currentProjectPath]; self.XcodeSupportProjectURL = [NSURL URLWithString:self.XcodeSupportProjectName relativeToURL:projectURL]; - self.supportPath = [[NSURL URLWithString:@"XcodeSupport" relativeToURL:projectURL] path]; + self.supportPath = [[NSURL URLWithString:@".XcodeSupport" relativeToURL:projectURL] path]; self.XcodeSupportPBXPath = [self.XcodeSupportProjectURL.path stringByAppendingPathComponent:@"project.pbxproj"]; - self.PBXModifierScriptPath = [[NSBundle mainBundle] pathForResource:@"pbxprojModifier" ofType:@"py"]; + self.PBXModifierScriptPath = [[[NSBundle mainBundle] sharedSupportPath] stringByAppendingPathComponent:@"pbxprojModifier.py"]; // Create the template project if it doesn't exist if (![self.fm fileExistsAtPath:self.supportPath]) { - NSLog(@"%@ Xcode support folder created at: %@", NSStringFromSelector(_cmd), self.XcodeSupportProjectURL.path); + NSLog(@"Xcode support folder created at: %@", self.XcodeSupportProjectURL.path); [self.fm createDirectoryAtPath:self.XcodeSupportProjectURL.path withIntermediateDirectories:YES attributes:nil error:nil]; - DLog(@"%@ Copying project.pbxproj from %@ to %@", NSStringFromSelector(_cmd), self.XcodeTemplatePBXPath, self.XcodeSupportProjectURL.path); + DLog(@"Copying project.pbxproj from %@ to %@", self.XcodeTemplatePBXPath, self.XcodeSupportProjectURL.path); [self.fm copyItemAtPath:self.XcodeTemplatePBXPath toPath:self.XcodeSupportPBXPath error:nil]; - DLog(@"%@ Reading the content of the project.pbxproj", NSStringFromSelector(_cmd)); + DLog(@"Reading the content of the project.pbxproj"); NSMutableString *PBXContent = [NSMutableString stringWithContentsOfFile:self.XcodeSupportPBXPath encoding:NSUTF8StringEncoding error:nil]; [PBXContent writeToFile:self.XcodeSupportPBXPath atomically:YES encoding:NSUTF8StringEncoding error:nil]; - DLog(@"%@ PBX file adapted to the project", NSStringFromSelector(_cmd)); + DLog(@"PBX file adapted to the project"); [self.fm createDirectoryAtPath:self.supportPath withIntermediateDirectories:YES attributes:nil error:nil]; @@ -226,9 +249,6 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; */ - (void)populateXcodeProject:(BOOL)shouldNotify { - if (shouldNotify) - [self notifyUserWithTitle:@"Loading project" message:self.currentProjectPath.lastPathComponent]; - // First populate with all non-framework code [self populateXcodeProjectWithProjectRelativePath:@""]; @@ -242,10 +262,7 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; [self populateXcodeProjectWithProjectRelativePath:@"Resources"]; if (shouldNotify) - { [[NSNotificationCenter defaultCenter] postNotificationName:XCCDidPopulateProjectNotification object:self userInfo:nil]; - [self notifyUserWithTitle:@"Project loaded" message:self.currentProjectPath.lastPathComponent]; - } } - (void)populateXcodeProjectWithProjectRelativePath:(NSString *)aProjectPath @@ -329,6 +346,8 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; - (void)listenToProjectAtPath:(NSString *)path { self.isLoadingProject = YES; + + [self notifyUserWithTitle:@"Loading project…" message:path.lastPathComponent]; [self clearErrors:self]; self.currentProjectPath = path; @@ -348,9 +367,36 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; [[NSUserDefaults standardUserDefaults] setObject:self.currentProjectPath forKey:kDefaultLastOpenedPath]; - [self notifyUserWithTitle:@"Listening to project" message:self.currentProjectPath.lastPathComponent]; + [self notifyUserWithTitle:@"Project loaded" message:self.currentProjectPath.lastPathComponent]; } +- (IBAction)openInXcode:(id)aSender +{ + if (!self.currentProjectPath) + return; + + DLog(@"Opening Xcode project at: %@", self.XcodeSupportProjectURL.path); + system([[NSString stringWithFormat:@"open \"%@\"", self.XcodeSupportProjectURL.path] UTF8String]); +} + +- (IBAction)resetProject:(id)aSender +{ + NSString *projectPath = self.currentProjectPath; + + [self stop]; + + // Close the project in Xcode if it's open + NSString *source = [NSString stringWithFormat:self.closeProjectScriptSource, projectPath]; + NSAppleScript *script = [[NSAppleScript alloc] initWithSource:source]; + + NSAppleEventDescriptor *descriptor; + descriptor = [script executeAndReturnError:nil]; + + [self.fm removeItemAtURL:self.XcodeSupportProjectURL error:nil]; + [self.fm removeItemAtPath:self.supportPath error:nil]; + + [self listenToProjectAtPath:projectPath]; +} #pragma mark - Event Stream @@ -371,7 +417,7 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; if (self.supportsFileBasedListening) { - DLog(@"%@ Initializing the FSEventStream at file level (clean)", NSStringFromSelector(_cmd)); + DLog(@"Initializing the FSEventStream at file level (clean)"); flags = kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents; } else @@ -464,7 +510,7 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; if (!self.supportsFileLevelAPI) { - DLog(@"%@ System doesn't support file level API", NSStringFromSelector(_cmd)); + DLog(@"System doesn't support file level API"); [defaults setObject:[NSNumber numberWithInt:kXCCAPIModeFolder] forKey:kDefaultXCCAPIMode]; } @@ -485,7 +531,7 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; if (self.supportsFileBasedListening) { - DLog(@"%@ using 10.7+ mode listening (clean)", NSStringFromSelector(_cmd)); + DLog(@"using 10.7+ mode listening (clean)"); self.currentAPIMode = @"File level (Lion)"; self.isUsingFileLevelAPI = YES; @@ -493,7 +539,7 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; } else { - DLog(@"%@ using 10.6 mode listening (dirty)", NSStringFromSelector(_cmd)); + DLog(@"using 10.6 mode listening (dirty)"); self.reactToInodeModification = NO; self.currentAPIMode = @"Folder level (Snow Leopard)"; self.isUsingFileLevelAPI = NO; @@ -615,10 +661,7 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; return; NSString *projectPath = [self projectPathForSourcePath:path]; - BOOL success = [self processModifiedFileAtPath:path projectSourcePath:projectPath notify:shouldNotify]; - - if (success) - [self notifyUserWithTitle:@"File successfully processed" message:path.lastPathComponent]; + [self processModifiedFileAtPath:path projectSourcePath:projectPath notify:shouldNotify]; } - (BOOL)processModifiedFileAtPath:(NSString *)realSourcePath projectSourcePath:(NSString *)projectSourcePath notify:(BOOL)shouldNotify @@ -629,35 +672,33 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; NSArray *arguments = nil; NSArray *pbxArguments = nil; - NSString *growlTitle = nil; - NSString *growlMessage = nil; NSString *response = nil; - NSString *projectRelativePath = [projectSourcePath substringFromIndex:self.currentProjectPath.length + 1]; + NSString *notificationTitle = nil; + NSString *notificationMessage = projectRelativePath.lastPathComponent; [[NSNotificationCenter defaultCenter] postNotificationName:XCCConversionDidStartNotification object:self]; // Remove all errors for the path being processed - BOOL (^pathMatcher)(id obj, NSUInteger idx, BOOL *stop); - - pathMatcher = ^(id obj, NSUInteger idx, BOOL *stop) - { - return [[obj valueForKey:@"path"] isEqualToString:realSourcePath]; - }; - - NSIndexSet *matchingErrors = [self.errorList indexesOfObjectsPassingTest:pathMatcher]; + NSIndexSet *matchingErrors = [self.errorList indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) + { + return [[obj valueForKey:@"path"] isEqualToString:realSourcePath]; + }]; + [self.errorListController removeObjectsAtArrangedObjectIndexes:matchingErrors]; if ([self isXibFile:realSourcePath]) { + // nib2cib can take a while to run, show a message while the conversion is happening + [self notifyUserWithTitle:@"Converting xib…" message:projectRelativePath.lastPathComponent]; + arguments = @[ @"-c", [NSString stringWithFormat:@"source '%@'; nib2cib --no-colors '%@'", self.profilePath, realSourcePath], @"" ]; - growlTitle = @"Converting xib..."; - growlMessage = projectRelativePath.lastPathComponent; + notificationTitle = @"Xib converted"; } else if ([self isObjjFile:realSourcePath]) { @@ -679,23 +720,20 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; projectSourcePath] ]; - growlTitle = @"Processing Objective-J source..."; - growlMessage = projectRelativePath.lastPathComponent; + notificationTitle = @"Objective-J source processed"; } else if ([self isXCCIgnoreFile:realSourcePath]) { [self computeIgnoredPaths]; - growlTitle = @"Parsing .xcodecapp-ignore..."; - growlMessage = @"Updating ignored paths"; + notificationTitle = @"Parsed .xcodecapp-ignore"; + notificationMessage = @"Ignored paths updated"; arguments = nil; } // Run the task and get the response if needed if (arguments) { - DLog(@"%@ Running conversion task...", NSStringFromSelector(_cmd)); - - [self notifyUserWithTitle:growlTitle message:growlMessage]; + DLog(@"Running conversion task..."); NSDictionary *taskResult = [self runTaskWithLaunchPath:self.shellPath arguments:arguments @@ -704,7 +742,7 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; NSInteger status = [taskResult[@"status"] intValue]; response = taskResult[@"response"]; - DLog(@"%@ Conversion task result/response: %ld/%@", NSStringFromSelector(_cmd), status, response); + DLog(@"Conversion task result/response: %ld/%@", status, response); if (status != 0) { @@ -715,40 +753,54 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; if ([self isXibFile:realSourcePath]) { + notificationTitle = @"Error converting xib"; + NSString *message = [NSString stringWithFormat:@"%@\n%@", realSourcePath.lastPathComponent, response]; - [self.errorListController addObject:@{ @"message":message, @"path":realSourcePath }]; + [self.errorListController addObject:@{ @"message":message, @"path":realSourcePath, @"status":taskResult[@"status"] }]; } else { + notificationTitle = [(XCCStatusCodeError ? @"Error" : @"Warning") stringByAppendingString:@" parsing Objective-J source"]; + NSArray *errors = [response propertyList]; for (NSDictionary *error in errors) { NSMutableDictionary *newError = [error mutableCopy]; newError[@"message"] = [NSString stringWithFormat:@"%@, line %d\n%@", [error[@"path"] lastPathComponent], [error[@"line"] intValue], error[@"message"]]; + newError[@"status"] = taskResult[@"status"]; [self.errorListController addObject:newError]; } } - if ([[NSUserDefaults standardUserDefaults] boolForKey:kDefaultXCCAutoOpenErrorsPanel]) + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + + if ((status == XCCStatusCodeError && [defaults boolForKey:kDefaultXCCAutoOpenErrorsPanelOnErrors]) || + (status == XCCStatusCodeWarning && [defaults boolForKey:kDefaultXCCAutoOpenErrorsPanelOnWarnings])) + { [self openErrorsPanel:self]; + } - [self notifyUserWithTitle:@"Error processing file" message:projectRelativePath.lastPathComponent]; + [self notifyUserWithTitle:notificationTitle message:notificationMessage]; + } + else if (!self.isLoadingProject) + { + [self notifyUserWithTitle:notificationTitle message:notificationMessage]; } } if (pbxArguments) { - DLog(@"%@ Running update PBX task...", NSStringFromSelector(_cmd)); + DLog(@"Running update PBX task..."); NSDictionary *taskResult; taskResult = [self runTaskWithLaunchPath:self.shellPath arguments:pbxArguments returnType:kTaskReturnTypeStdOut]; - DLog(@"%@ Update PBX Task result/response: %@/%@", NSStringFromSelector(_cmd), taskResult[@"status"], taskResult[@"response"]); + DLog(@"Update PBX Task result/response: %@/%@", taskResult[@"status"], taskResult[@"response"]); } [[NSNotificationCenter defaultCenter] postNotificationName:XCCConversionDidStopNotification object:self]; - DLog(@"%@ Processed: %@", NSStringFromSelector(_cmd), realSourcePath); + DLog(@"Processed: %@", realSourcePath); return success; } @@ -823,13 +875,13 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; NSString *shadowHeaderPath = [shadowBasePath stringByAppendingPathExtension:@"h"]; NSString *shadowImplementationPath = [shadowBasePath stringByAppendingPathExtension:@"m"]; - DLog(@"%@ Removing shadow header file: %@", NSStringFromSelector(_cmd), shadowHeaderPath); + DLog(@"Removing shadow header file: %@", shadowHeaderPath); [self.fm removeItemAtPath:shadowHeaderPath error:nil]; - DLog(@"%@ Removing shadow implementation file: %@", NSStringFromSelector(_cmd), shadowImplementationPath); + DLog(@"Removing shadow implementation file: %@", shadowImplementationPath); [self.fm removeItemAtPath:shadowImplementationPath error:nil]; - DLog(@"%@ Removing PBX reference", NSStringFromSelector(_cmd)); + DLog(@"Removing PBX reference"); NSString *projectSourcePath = [self projectPathForSourcePath:sourcePath]; NSArray *pbxArguments = @[ @@ -845,7 +897,7 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; taskResult = [self runTaskWithLaunchPath:self.shellPath arguments:pbxArguments returnType:kTaskReturnTypeStdOut]; - DLog(@"%@ PBX Reference removal status/response: %@/%@", NSStringFromSelector(_cmd), taskResult[@"status"], taskResult[@"response"]); + DLog(@"PBX Reference removal status/response: %@/%@", taskResult[@"status"], taskResult[@"response"]); } /*! @@ -951,7 +1003,7 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; return ignore; } -#pragma mark - Errors panel +#pragma mark - Errors - (IBAction)openErrorsPanel:(id)aSender { @@ -1082,6 +1134,16 @@ NSArray *XCCDefaultIgnoredPathRegexes = nil; self.errorListController.content = self.errorList; } +- (BOOL)hasErrors +{ + NSInteger index = [self.errorList indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) + { + return [[obj valueForKey:@"status"] intValue] == XCCStatusCodeError; + }]; + + return index != NSNotFound; +} + #pragma mark - User notifications - (NSString *)applicationNameForGrowl diff --git a/Tools/XcodeCapp/XcodeCapp/UserDefaults.h b/Tools/XcodeCapp/XcodeCapp/UserDefaults.h index 3e25d9797..8cbfc8098 100644 --- a/Tools/XcodeCapp/XcodeCapp/UserDefaults.h +++ b/Tools/XcodeCapp/XcodeCapp/UserDefaults.h @@ -17,7 +17,8 @@ extern NSString * const kDefaultFirstLaunchVersion; extern NSString * const kDefaultXCCAPIMode; extern NSString * const kDefaultXCCReactMode; extern NSString * const kDefaultXCCReopenLastProject; -extern NSString * const kDefaultXCCAutoOpenErrorsPanel; +extern NSString * const kDefaultXCCAutoOpenErrorsPanelOnWarnings; +extern NSString * const kDefaultXCCAutoOpenErrorsPanelOnErrors; extern NSString * const kDefaultXCCProjectHistory; extern NSString * const kDefaultLastOpenedPath; extern NSString * const kDefaultPathModificationDates; diff --git a/Tools/XcodeCapp/XcodeCapp/UserDefaults.m b/Tools/XcodeCapp/XcodeCapp/UserDefaults.m index 3a3bc34ff..6aa6cf68a 100644 --- a/Tools/XcodeCapp/XcodeCapp/UserDefaults.m +++ b/Tools/XcodeCapp/XcodeCapp/UserDefaults.m @@ -15,7 +15,8 @@ NSString * const kDefaultFirstLaunchVersion = @"firstLaunchVersion"; NSString * const kDefaultXCCAPIMode = @"XCCAPIMode"; NSString * const kDefaultXCCReactMode = @"XCCReactMode"; NSString * const kDefaultXCCReopenLastProject = @"XCCReopenLastProject"; -NSString * const kDefaultXCCAutoOpenErrorsPanel = @"XCCAutoOpenErrorsPanel"; +NSString * const kDefaultXCCAutoOpenErrorsPanelOnWarnings = @"XCCAutoOpenErrorsPanelOnWarnings"; +NSString * const kDefaultXCCAutoOpenErrorsPanelOnErrors = @"XCCAutoOpenErrorsPanelOnErrors"; NSString * const kDefaultXCCProjectHistory = @"XCCProjectHistory"; NSString * const kDefaultLastOpenedPath = @"LastOpenedPath"; NSString * const kDefaultPathModificationDates = @"pathModificationDates"; diff --git a/Tools/XcodeCapp/XcodeCapp/en.lproj/MainMenu.xib b/Tools/XcodeCapp/XcodeCapp/en.lproj/MainMenu.xib index 738ad0313..448a6bc06 100644 --- a/Tools/XcodeCapp/XcodeCapp/en.lproj/MainMenu.xib +++ b/Tools/XcodeCapp/XcodeCapp/en.lproj/MainMenu.xib @@ -12,7 +12,6 @@ NSArrayController - NSBox NSButton NSButtonCell NSCustomObject @@ -86,6 +85,14 @@ + + + Reset Project + + 2147483647 + + + YES @@ -181,7 +188,7 @@ 268 {{164, 23}, {172, 98}} - + YES 68157504 @@ -195,7 +202,7 @@ Y29tA 3100 - + 6 System textBackgroundColor @@ -221,7 +228,6 @@ Y29tA 266 {{164, 140}, {160, 14}} - YES @@ -260,7 +266,6 @@ Y29tA {{17, 46}, {128, 128}} - _NS:9 YES @@ -283,7 +288,6 @@ Y29tA {358, 185} - {{0, 0}, {2560, 1418}} @@ -518,36 +522,37 @@ Y29tA 3 2 - {{529, 541}, {336, 198}} + {{529, 541}, {341, 155}} 1685586944 Preferences NSWindow - + 256 - + 268 - {{18, 43}, {282, 18}} + {{18, 119}, {295, 18}} - + + YES - + -2080374784 0 - React to inode meta information changes + Listen to the most recent project on launch LucidaGrande 13 1044 - + 1211912448 2 - + NSImage NSSwitch @@ -561,70 +566,23 @@ Y29tA NO - - - 268 - {{18, 20}, {284, 17}} - - YES - - 68157504 - 272630784 - In "File level" API mode, react to touch, chown, etc. - - LucidaGrande - 11 - 16 - - - - - 1 - MC4zNDU1Mjg0ODM0IDAuMzQ1NTI4NDgzNCAwLjM0NTUyODQ4MzQAA - - - NO - - - - 268 - {{18, 162}, {295, 18}} - - - YES - - -2080374784 - 0 - Listen to the most recent project on launch - - - 1211912448 - 2 - - - - - 200 - 25 - - NO - 268 - {{18, 132}, {300, 18}} + {{37, 58}, {81, 18}} - + + YES -2080374784 0 - Automatically open Errors & Warnings panel + Warnings 1211912448 2 - + @@ -633,35 +591,37 @@ Y29tA NO - + - 10 - {{18, 76}, {300, 5}} + 268 + {{139, 58}, {60, 18}} - - _NS:9 - {0, 0} - - 67108864 + + + YES + + -2080374784 0 - Box + Errors - - - 3 - MCAwLjgwMDAwMDAxMTkAA - + + 1211912448 + 2 + + + + + 200 + 25 - 3 - 2 - 0 - NO + NO 268 - {{17, 101}, {106, 17}} + {{17, 21}, {106, 17}} + _NS:1535 YES @@ -680,9 +640,10 @@ Y29tA 268 - {{126, 95}, {56, 26}} + {{126, 15}, {56, 26}} - + + _NS:9 YES @@ -747,8 +708,31 @@ Y29tA NO + + + 268 + {{18, 84}, {306, 17}} + + + + _NS:1535 + YES + + 68157504 + 272630784 + Automatically open Errors & Warnings panel on: + + _NS:1535 + + + + + NO + - {336, 198} + {341, 155} + + {{0, 0}, {2560, 1418}} @@ -1024,14 +1008,6 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA 619 - - - openInXcode: - - - - 620 - menuItemHistory @@ -1096,6 +1072,14 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA 792 + + + save: + + + + 821 + errorTable @@ -1153,40 +1137,20 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA 786 - - value: values.XCCReactMode - - - - - - value: values.XCCReactMode - value - values.XCCReactMode - - NSValidatesImmediately - - - 2 - + + openInXcode: + + - 629 + 815 - - enabled: isUsingFileLevelAPI - - - - - - enabled: isUsingFileLevelAPI - enabled - isUsingFileLevelAPI - 2 - + + resetProject: + + - 630 + 816 @@ -1351,15 +1315,15 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA - value: values.XCCAutoOpenErrorsPanel + value: values.XCCAutoOpenErrorsPanelOnWarnings - value: values.XCCAutoOpenErrorsPanel + value: values.XCCAutoOpenErrorsPanelOnWarnings value - values.XCCAutoOpenErrorsPanel + values.XCCAutoOpenErrorsPanelOnWarnings NSValidatesImmediately @@ -1367,7 +1331,7 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA 2 - 793 + 823 @@ -1385,6 +1349,42 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA 810 + + + enabled: currentProjectPath.length + + + + + + enabled: currentProjectPath.length + enabled + currentProjectPath.length + 2 + + + 812 + + + + value: values.XCCAutoOpenErrorsPanelOnErrors + + + + + + value: values.XCCAutoOpenErrorsPanelOnErrors + value + values.XCCAutoOpenErrorsPanelOnErrors + + NSValidatesImmediately + + + 2 + + + 824 + @@ -1432,6 +1432,7 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA + @@ -1521,31 +1522,14 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA - - - - + + + - - 559 - - - - - - - - 561 - - - - - - 563 @@ -1559,16 +1543,6 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA - - 578 - - - - - 580 - - - 581 @@ -1770,11 +1744,6 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA - - 794 - - - 797 @@ -1842,6 +1811,37 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA + + 811 + + + + + 817 + + + + + + + + 818 + + + + + 819 + + + + + + + + 820 + + + @@ -1873,12 +1873,8 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1918,7 +1914,6 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1929,12 +1924,25 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + ToolTip + + ToolTip + + When an error or warning occurs, automatically open the Errors & Warnings panel + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin - 810 + 824 @@ -1945,7 +1953,7 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA id id id - id + id @@ -1960,8 +1968,8 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA openHelp: id - - openInXcode: + + openPreferences: id @@ -2052,6 +2060,8 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA id id id + id + id @@ -2066,6 +2076,14 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA openErrorsPanel: id + + openInXcode: + id + + + resetProject: + id + NSArrayController