diff --git a/Tools/XcodeCapp/.gitignore b/Tools/XcodeCapp/.gitignore deleted file mode 100644 index f921bd442..000000000 --- a/Tools/XcodeCapp/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.DS_Store -*.mode1v3 -*.pbxuser -*.perspectivev3 -build diff --git a/Tools/XcodeCapp/AppController.h b/Tools/XcodeCapp/AppController.h deleted file mode 100644 index 1eec6dfb5..000000000 --- a/Tools/XcodeCapp/AppController.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is a part of program XcodeCapp - * Copyright (C) 2011 Antoine Mercadal () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import -#import -#import "PRHEmptyGrowlDelegate.h" -#import "TNXCodeCapp.h" -#import "TNErrorDataView.h" - -@interface AppController : NSObject -{ - IBOutlet NSMenu *statusMenu; - IBOutlet NSMenuItem *menuItemOpenXCode; - IBOutlet NSMenuItem *menuItemStartStop; - IBOutlet NSPanel *errorsPanel; - IBOutlet NSTableView *errorsTable; - IBOutlet NSPanel *aboutWindow; - IBOutlet NSWindow *helpWindow; - IBOutlet NSTextView *helpTextView; - IBOutlet NSTextField *labelVersion; - IBOutlet NSPopUpButton *buttonPreferencesAPIMode; - IBOutlet NSButton *checkBoxPreferencesReactMode; - IBOutlet NSUserDefaultsController *preferencesController; - IBOutlet TNXCodeCapp *__strong xcc; - IBOutlet NSWindow *windowDebug; - IBOutlet NSMenuItem *menuDebug; - IBOutlet NSMenuItem *menuHistory; - IBOutlet TNErrorDataView *dataViewError; - - NSImage *_iconActive; - NSImage *_iconInactive; - NSImage *_iconWorking; - NSStatusItem *_statusItem; - PRHEmptyGrowlDelegate *growlDelegateRef; - NSData *_archivedDataView; -} - -@property BOOL supportsFileModeListening; -@property (strong) TNXCodeCapp *xcc; - -+ (AppController *)sharedAppController; - -- (BOOL)validateMenuItem:(NSMenuItem*)menuItem; -- (void)registerDefaults; -- (void)growlWithTitle:(NSString *)aTitle message:(NSString *)aMessage; -- (void)openCenteredWindow:(NSWindow *)aWindow; -- (void)_prepareHistoryMenu; - -- (IBAction)chooseFolder:(id)aSender; -- (IBAction)openErrors:(id)sender; -- (IBAction)clearErrors:(id)sender; -- (IBAction)openXCode:(id)aSender; -- (IBAction)stopListener:(id)aSender; -- (IBAction)openHelp:(id)aSender; -- (IBAction)openAbout:(id)aSender; -- (IBAction)updatePreferences:(id)aSender; -- (IBAction)switchProject:(id)aSender; -- (IBAction)clearProjectHistory:(id)aSender; - -@end - diff --git a/Tools/XcodeCapp/AppController.m b/Tools/XcodeCapp/AppController.m deleted file mode 100644 index d49925786..000000000 --- a/Tools/XcodeCapp/AppController.m +++ /dev/null @@ -1,443 +0,0 @@ -/* - * This file is a part of program XcodeCapp - * Copyright (C) 2011 Antoine Mercadal () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#import - -#import "AppController.h" -#include "macros.h" - - -AppController *SharedAppControllerInstance = nil; - -float heightForStringDrawing(NSString *myString, NSFont *myFont, float myWidth) -{ - NSTextStorage *textStorage = [[NSTextStorage alloc] initWithString:myString]; - NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:NSMakeSize(myWidth, FLT_MAX)]; - NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; - - [layoutManager addTextContainer:textContainer]; - [textStorage addLayoutManager:layoutManager]; - [textStorage addAttribute:NSFontAttributeName value:myFont range:NSMakeRange(0, [textStorage length])]; - [textContainer setLineFragmentPadding:0.0]; - - (void) [layoutManager glyphRangeForTextContainer:textContainer]; - return [layoutManager usedRectForTextContainer:textContainer].size.height; -} - -@implementation AppController - -@synthesize supportsFileModeListening; -@synthesize xcc; - -+ (AppController *)sharedAppController -{ - return SharedAppControllerInstance; -} - -#pragma mark - -#pragma mark Initialization - -/*! - Called when NIB is ready - */ -- (void)awakeFromNib -{ - SharedAppControllerInstance = self; - - _archivedDataView = [NSKeyedArchiver archivedDataWithRootObject:dataViewError]; - - if (!growlDelegateRef) - growlDelegateRef = [[PRHEmptyGrowlDelegate alloc] init]; - - [GrowlApplicationBridge setGrowlDelegate:growlDelegateRef]; - - NSBundle *bundle = [NSBundle mainBundle]; - - [labelVersion setStringValue:[NSString stringWithFormat:@"Version %@", [bundle objectForInfoDictionaryKey:@"CFBundleVersion"]]]; - - [self registerDefaults]; - - _iconInactive = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"xcodecapp-icon-inactive" ofType:@"png"]]; - _iconActive = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"xcodecapp-icon-active" ofType:@"png"]]; - _iconWorking = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"xcodecapp-icon-working" ofType:@"png"]]; - [_iconActive setSize:NSMakeSize(14.0, 16.0)]; - [_iconInactive setSize:NSMakeSize(14.0, 16.0)]; - [_iconWorking setSize:NSMakeSize(14.0, 16.0)]; - - _statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; - [_statusItem setMenu:statusMenu]; - [_statusItem setImage:_iconInactive]; - [_statusItem setHighlightMode:YES]; - [statusMenu setDelegate:self]; - - if ([[NSUserDefaults standardUserDefaults] integerForKey:@"FirstLaunch"]) - { - [[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInt:0] forKey:@"FirstLaunch"]; - [self openHelp:self]; - } - - [xcc setDelegate:self]; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(XCodeCappConversionDidStart:) name:XCCConversionStartNotification object:xcc]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(XCodeCappConversionDidStop:) name:XCCConversionStopNotification object:xcc]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(XCodeCappPopulateProject:) name:XCCDidPopulateProjectNotification object:xcc]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(XCodeCappListeningDidStart:) name:XCCListeningStartNotification object:xcc]; - - [helpTextView setTextContainerInset:NSSizeFromCGSize(CGSizeMake(10.0, 10.0))]; - - [xcc start]; - - [self _prepareHistoryMenu]; -} - -/*! - Checks if aplication should show the debug window - */ -- (void)applicationDidFinishLaunching:(NSNotification *)notif -{ - CGEventRef event = CGEventCreate(NULL); - CGEventFlags modifiers = CGEventGetFlags(event); - CFRelease(event); - - if (modifiers & kCGEventFlagMaskAlternate) - { - [statusMenu insertItem:menuDebug atIndex:6]; - } -} - -/*! - Register the application defaults - */ -- (void)registerDefaults -{ - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - NSNumber *streamEventIdSinceNow = [NSNumber numberWithUnsignedLongLong:kFSEventStreamEventIdSinceNow]; - NSMutableDictionary *appDefaults = [NSMutableDictionary new]; - - [appDefaults setObject:streamEventIdSinceNow forKey:@"lastEventId"]; - [appDefaults setObject:[NSNumber numberWithInt:1] forKey:@"FirstLaunch"]; - [appDefaults setObject:[NSNumber numberWithInt:0] forKey:@"XCCAPIMode"]; - [appDefaults setObject:[NSNumber numberWithInt:1] forKey:@"XCCReactMode"]; - [appDefaults setObject:[NSNumber numberWithInt:1] forKey:@"XCCReopenLastProject"]; - [appDefaults setObject:[[NSArray alloc] init] forKey:@"XCCProjectHistory"]; - - [defaults registerDefaults:appDefaults]; -} - - -#pragma mark - -#pragma mark Notification handlers - -/*! - Handle cleaning operation when application will stop. - It will stop the FSEvent listener, and store the last event id - */ -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app -{ - [xcc clear]; - - return NSTerminateNow; -} - -/*! - Called when XCC start a conversion - @param aNotification the notification - */ -- (void)XCodeCappConversionDidStart:(NSNotification *)aNotification -{ - [_statusItem setImage:_iconWorking]; -} - -/*! - Called when XCC finish a conversion - @param aNotification the notification - */ -- (void)XCodeCappConversionDidStop:(NSNotification *)aNotification -{ - [_statusItem setImage:_iconActive]; - - if ([errorsPanel isVisible]) - [errorsTable reloadData]; -} - -/*! - Called when XCC has populated a project - @param aNotification the notification - */ -- (void)XCodeCappPopulateProject:(NSNotification *)aNotification -{ - [self growlWithTitle:@"Project loaded" message:[[[aNotification userInfo] objectForKey:@"URL"] path]]; -} - -/*! - Called when XCC start a to listen to a project - @param aNotification the notification - */ -- (void)XCodeCappListeningDidStart:(NSNotification *)aNotification -{ - [_statusItem setImage:_iconActive]; - [menuItemStartStop setTitle:[NSString stringWithFormat:@"Stop Listening to “%@”", [xcc currentProjectName]]]; - [menuItemStartStop setAction:@selector(stopListener:)]; - - [self growlWithTitle:@"Listening to project" message:[[xcc currentProjectURL] path]]; -} - - -#pragma mark - -#pragma mark Utilities - -/*! - Simple growl wrapper - @param aTitle the growl title - @param aMessage the growl message - */ -- (void)growlWithTitle:(NSString *)aTitle message:(NSString *)aMessage -{ - [GrowlApplicationBridge notifyWithTitle:aTitle - description:aMessage - notificationName:@"DefaultNotifications" - iconData:nil - priority:0 - isSticky:NO - clickContext:nil]; -} - -/*! - Prepare the history menu - */ -- (void)_prepareHistoryMenu -{ - NSMenu *menu = [[NSMenu alloc] init]; - NSArray *projectHistory = [[NSUserDefaults standardUserDefaults] objectForKey:@"XCCProjectHistory"]; - - for(int i = 0; i < [projectHistory count]; i++) - { - NSString *itemTitle = [[projectHistory objectAtIndex:i] lastPathComponent]; - NSString *projectPath = [[projectHistory objectAtIndex:i] stringByStandardizingPath]; - NSString *currentProjectPath = [[[xcc currentProjectURL] path] stringByStandardizingPath]; - NSMenuItem *item = [menu addItemWithTitle:itemTitle action:@selector(switchProject:) keyEquivalent:@""]; - - [item setRepresentedObject:projectPath]; - - if ([currentProjectPath isEqualToString:projectPath]) - [item setAction:nil]; - } - - [menu addItem:[NSMenuItem separatorItem]]; - [menu addItemWithTitle:@"Clear history" action:@selector(clearProjectHistory:) keyEquivalent:@""]; - - [menuHistory setEnabled:([projectHistory count]) ? YES : NO]; - [menuHistory setSubmenu:menu]; -} - - -#pragma mark - -#pragma mark Actions - -/*! - Save preferences - @param aSender the sender of the action - */ -- (IBAction)updatePreferences:(id)aSender -{ - [preferencesController save:aSender]; - NSLog(@"Preferences change notified"); - - [xcc configure]; -} - -/*! - Open the folder chooser and eventually start to listen - @param aSender the sender of the action - */ -- (IBAction)chooseFolder:(id)aSender -{ - [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; - - NSOpenPanel *openPanel = [NSOpenPanel openPanel]; - - [openPanel setCanChooseDirectories:YES]; - [openPanel setCanCreateDirectories:YES]; - [openPanel setTitle:@"Choose Cappuccino Project"]; - [openPanel setCanChooseFiles:NO]; - - if ([openPanel runModal] != NSFileHandlingPanelOKButton) - return; - - NSString *projectPath = [NSString stringWithFormat:@"%@/", [[[openPanel URLs] objectAtIndex:0] path]]; - NSMutableArray *projectHistory = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"XCCProjectHistory"]]; - - if ([projectHistory containsObject:[projectPath stringByStandardizingPath]]) - [projectHistory removeObject:[projectPath stringByStandardizingPath]]; - - [projectHistory insertObject:[projectPath stringByStandardizingPath] atIndex:0]; - - [[NSUserDefaults standardUserDefaults] setObject:projectHistory forKey:@"XCCProjectHistory"]; - - [xcc listenProjectAtPath:projectPath]; - - [self _prepareHistoryMenu]; -} - -/*! - Stop listening to a project - @param aSender the sender of the action - */ -- (IBAction)stopListener:(id)aSender -{ - [xcc clear]; - - [_statusItem setImage:_iconInactive]; - [menuItemStartStop setTitle:@"Listen to Project…"]; - [menuItemStartStop setAction:@selector(chooseFolder:)]; - [self _prepareHistoryMenu]; - - [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"LastOpenedPath"]; -} - -- (IBAction)switchProject:(id)aSender -{ - NSString *newPath = [aSender representedObject]; - - [self stopListener:aSender]; - [xcc listenProjectAtPath:newPath]; - [self _prepareHistoryMenu]; -} - -- (IBAction)clearProjectHistory:(id)aSender -{ - [[NSUserDefaults standardUserDefaults] setObject:[NSArray array] forKey:@"XCCProjectHistory"]; - [self _prepareHistoryMenu]; -} - -/*! - Open the xCode support project in xCode - @param aSender the sender of the action - */ -- (IBAction)openXCode:(id)aSender -{ - if (![xcc currentProjectURL]) - return; - - DLog(@"Opening Xcode project at URL: '%@'", [[xcc XCodeSupportProject] path]); - system([[NSString stringWithFormat:@"open \"%@\"", [[xcc XCodeSupportProject] path]] UTF8String]); -} - -/*! - Open the errors window - @param aSender the sender of the action - */ -- (IBAction)openErrors:(id)aSender -{ - [self openCenteredWindow:errorsPanel]; -} - -/*! - Clear all errors in errors table - @param aSender the sender of the action - */ -- (IBAction)clearErrors:(id)sender -{ - [[xcc errorList] removeAllObjects]; - [errorsTable reloadData]; -} - -/*! - Open the help file - @param aSender the sender of the action - */ -- (IBAction)openHelp:(id)aSender -{ - [helpTextView readRTFDFromFile:[[NSBundle mainBundle] pathForResource:@"help" ofType:@"rtfd"]]; - - [self openCenteredWindow:helpWindow]; -} - -/*! - Open the about window - @param aSender the sender of the action - */ -- (IBAction)openAbout:(id)aSender -{ - [self openCenteredWindow:aboutWindow]; -} - -/*! - Open the preferences window - @param aSender the sender of the action - */ -- (IBAction)openPreferences:(id)aSender -{ - [self openCenteredWindow:windowDebug]; -} - -/*! - Open a centered window. -*/ -- (void)openCenteredWindow:(NSWindow *)aWindow -{ - [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; - - [aWindow center]; - [aWindow makeKeyAndOrderFront:nil]; -} - - -#pragma mark - -#pragma mark Delegates - -- (BOOL)validateMenuItem:(NSMenuItem *)aMenuItem -{ - if (aMenuItem == menuItemOpenXCode) - return !![xcc currentProjectURL]; - - return YES; -} - -- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView -{ - return [[xcc errorList] count]; -} - -- (id)tableView:(NSTableView*)aTableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row -{ - return [[xcc errorList] objectAtIndex:row]; -} - -- (void)tableViewColumnDidResize:(NSNotification *)tableView -{ - [errorsTable noteHeightOfRowsWithIndexesChanged: - [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [[xcc errorList] count])]]; -} - -- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row -{ - return [NSKeyedUnarchiver unarchiveObjectWithData:_archivedDataView]; -} - -- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)aRow -{ - NSString *content = [[[xcc errorList] objectAtIndex:aRow] objectForKey:@"message"]; - NSFont *currentFont = [[dataViewError fieldMessage] font]; - float height = heightForStringDrawing(content, currentFont, [tableView frame].size.width); - - return height + 31; -} - -@end diff --git a/Tools/XcodeCapp/English.lproj/InfoPlist.strings b/Tools/XcodeCapp/English.lproj/InfoPlist.strings deleted file mode 100644 index 5e45963c3..000000000 Binary files a/Tools/XcodeCapp/English.lproj/InfoPlist.strings and /dev/null differ diff --git a/Tools/XcodeCapp/English.lproj/MainMenu.nib/keyedobjects.nib b/Tools/XcodeCapp/English.lproj/MainMenu.nib/keyedobjects.nib deleted file mode 100644 index 8719077ec..000000000 Binary files a/Tools/XcodeCapp/English.lproj/MainMenu.nib/keyedobjects.nib and /dev/null differ diff --git a/Tools/XcodeCapp/FSEvent.m b/Tools/XcodeCapp/FSEvent.m deleted file mode 100644 index b6a215f67..000000000 --- a/Tools/XcodeCapp/FSEvent.m +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is a part of program xcodecapp-cocoa - * Copyright (C) 2011 Antoine Mercadal (primalmotion@archipelproject.org) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import "FSEventCallback.h" - -/*! - This is the FSEvent callback - */ -void fsevents_callback(ConstFSEventStreamRef streamRef, - void *userData, - size_t numEvents, - void *eventPaths, - const FSEventStreamEventFlags eventFlags[], - const FSEventStreamEventId eventIds[]) -{ - TNXCodeCapp *xcc = (TNXCodeCapp *)userData; - size_t i; - - for(i = 0; i < numEvents; i++) - { - NSString *path = [(NSArray *)eventPaths objectAtIndex:i]; - - #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7) - // kFSEventStreamEventFlagItemIsFile = 0x00010000 - if (!(eventFlags[i] & 0x00010000) - || [xcc isPathMatchingIgnoredPaths:path] - || (![xcc isXIBFile:path] && ![xcc isObjJFile:path] && ![xcc isXCCIgnoreFile:path])) - continue; - - // kFSEventStreamEventFlagItemRemoved = 0x00000200 - if (eventFlags[i] & 0x00000200) - { - [xcc handleFileRemoval:path]; - } - else - { - NSLog(@"this file has been modified or created"); - [xcc handleFileModification:path notify:YES]; - } - #else - NSArray *subpaths = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL]; - for(NSString *currentPath in subpaths) - [xcc handleFileModification:currentPath notify:YES]; - #endif - - [xcc updateLastEventId:eventIds[i]]; - } -} \ No newline at end of file diff --git a/Tools/XcodeCapp/Growl.framework/Versions/A/Growl b/Tools/XcodeCapp/Growl.framework/Versions/A/Growl deleted file mode 100755 index a289fe7b6..000000000 Binary files a/Tools/XcodeCapp/Growl.framework/Versions/A/Growl and /dev/null differ diff --git a/Tools/XcodeCapp/Growl.framework/Versions/A/Headers/Growl.h b/Tools/XcodeCapp/Growl.framework/Versions/A/Headers/Growl.h deleted file mode 100644 index e2a44255d..000000000 --- a/Tools/XcodeCapp/Growl.framework/Versions/A/Headers/Growl.h +++ /dev/null @@ -1,6 +0,0 @@ -#include "GrowlDefines.h" - -#ifdef __OBJC__ -# include "GrowlApplicationBridge.h" -#endif -#include "GrowlApplicationBridge-Carbon.h" diff --git a/Tools/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlApplicationBridge-Carbon.h b/Tools/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlApplicationBridge-Carbon.h deleted file mode 100644 index d4adefd43..000000000 --- a/Tools/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlApplicationBridge-Carbon.h +++ /dev/null @@ -1,780 +0,0 @@ -// -// GrowlApplicationBridge-Carbon.h -// Growl -// -// Created by Mac-arena the Bored Zo on Wed Jun 18 2004. -// Based on GrowlApplicationBridge.h by Evan Schoenberg. -// This source code is in the public domain. You may freely link it into any -// program. -// - -#ifndef _GROWLAPPLICATIONBRIDGE_CARBON_H_ -#define _GROWLAPPLICATIONBRIDGE_CARBON_H_ - -#include -#include - -#ifndef GROWL_EXPORT -#define GROWL_EXPORT __attribute__((visibility("default"))) DEPRECATED_ATTRIBUTE -#endif - -/*! @header GrowlApplicationBridge-Carbon.h - * @abstract Declares an API that Carbon applications can use to interact with Growl. - * @discussion GrowlApplicationBridge uses a delegate to provide information //XXX - * to Growl (such as your application's name and what notifications it may - * post) and to provide information to your application (such as that Growl - * is listening for notifications or that a notification has been clicked). - * - * You can set the Growldelegate with Growl_SetDelegate and find out the - * current delegate with Growl_GetDelegate. See struct Growl_Delegate for more - * information about the delegate. - */ - -__BEGIN_DECLS - -/*! @struct Growl_Delegate - * @abstract Delegate to supply GrowlApplicationBridge with information and respond to events. - * @discussion The Growl delegate provides your interface to - * GrowlApplicationBridge. When GrowlApplicationBridge needs information about - * your application, it looks for it in the delegate; when Growl or the user - * does something that you might be interested in, GrowlApplicationBridge - * looks for a callback in the delegate and calls it if present - * (meaning, if it is not NULL). - * XXX on all of that - * @field size The size of the delegate structure. - * @field applicationName The name of your application. - * @field registrationDictionary A dictionary describing your application and the notifications it can send out. - * @field applicationIconData Your application's icon. - * @field growlInstallationWindowTitle The title of the installation window. - * @field growlInstallationInformation Text to display in the installation window. - * @field growlUpdateWindowTitle The title of the update window. - * @field growlUpdateInformation Text to display in the update window. - * @field referenceCount A count of owners of the delegate. - * @field retain Called when GrowlApplicationBridge receives this delegate. - * @field release Called when GrowlApplicationBridge no longer needs this delegate. - * @field growlIsReady Called when GrowlHelperApp is listening for notifications. - * @field growlNotificationWasClicked Called when a Growl notification is clicked. - * @field growlNotificationTimedOut Called when a Growl notification timed out. - */ -struct Growl_Delegate { - /* @discussion This should be sizeof(struct Growl_Delegate). - */ - size_t size; - - /*All of these attributes are optional. - *Optional attributes can be NULL; required attributes that - * are NULL cause setting the Growl delegate to fail. - *XXX - move optional/required status into the discussion for each field - */ - - /* This name is used both internally and in the Growl preferences. - * - * This should remain stable between different versions and incarnations of - * your application. - * For example, "SurfWriter" is a good app name, whereas "SurfWriter 2.0" and - * "SurfWriter Lite" are not. - * - * This can be NULL if it is provided elsewhere, namely in an - * auto-discoverable plist file in your app bundle - * (XXX refer to more information on that) or in registrationDictionary. - */ - CFStringRef applicationName; - - /* - * Must contain at least these keys: - * GROWL_NOTIFICATIONS_ALL (CFArray): - * Contains the names of all notifications your application may post. - * - * Can also contain these keys: - * GROWL_NOTIFICATIONS_DEFAULT (CFArray): - * Names of notifications that should be enabled by default. - * If omitted, GROWL_NOTIFICATIONS_ALL will be used. - * GROWL_APP_NAME (CFString): - * Same as the applicationName member of this structure. - * If both are present, the applicationName member shall prevail. - * If this key is present, you may omit applicationName (set it to NULL). - * GROWL_APP_ICON (CFData): - * Same as the iconData member of this structure. - * If both are present, the iconData member shall prevail. - * If this key is present, you may omit iconData (set it to NULL). - * - * If you change the contents of this dictionary after setting the delegate, - * be sure to call Growl_Reregister. - * - * This can be NULL if you have an auto-discoverable plist file in your app - * bundle. (XXX refer to more information on that) - */ - CFDictionaryRef registrationDictionary; - - /* The data can be in any format supported by NSImage. As of - * Mac OS X 10.3, this includes the .icns, TIFF, JPEG, GIF, PNG, PDF, and - * PICT formats. - * - * If this is not supplied, Growl will look up your application's icon by - * its application name. - */ - CFDataRef applicationIconData; - - /* Installer display attributes - * - * These four attributes are used by the Growl installer, if this framework - * supports it. - * For any of these being NULL, a localised default will be - * supplied. - */ - - /* If this is NULL, Growl will use a default, - * localized title. - * - * Only used if you're using Growl-WithInstaller.framework. Otherwise, - * this member is ignored. - */ - CFStringRef growlInstallationWindowTitle; - /* This information may be as long or short as desired (the - * window will be sized to fit it). If Growl is not installed, it will - * be displayed to the user as an explanation of what Growl is and what - * it can do in your application. - * It should probably note that no download is required to install. - * - * If this is NULL, Growl will use a default, localized - * explanation. - * - * Only used if you're using Growl-WithInstaller.framework. Otherwise, - * this member is ignored. - */ - CFStringRef growlInstallationInformation; - /* If this is NULL, Growl will use a default, - * localized title. - * - * Only used if you're using Growl-WithInstaller.framework. Otherwise, - * this member is ignored. - */ - CFStringRef growlUpdateWindowTitle; - /* This information may be as long or short as desired (the - * window will be sized to fit it). If an older version of Growl is - * installed, it will be displayed to the user as an explanation that an - * updated version of Growl is included in your application and - * no download is required. - * - * If this is NULL, Growl will use a default, localized - * explanation. - * - * Only used if you're using Growl-WithInstaller.framework. Otherwise, - * this member is ignored. - */ - CFStringRef growlUpdateInformation; - - /* This member is provided for use by your retain and release - * callbacks (see below). - * - * GrowlApplicationBridge never directly uses this member. Instead, it - * calls your retain callback (if non-NULL) and your release - * callback (if non-NULL). - */ - unsigned referenceCount; - - //Functions. Currently all of these are optional (any of them can be NULL). - - /* When you call Growl_SetDelegate(newDelegate), it will call - * oldDelegate->release(oldDelegate), and then it will call - * newDelegate->retain(newDelegate), and the return value from retain - * is what will be set as the delegate. - * (This means that this member works like CFRetain and -[NSObject retain].) - * This member is optional (it can be NULL). - * For a delegate allocated with malloc, this member would be - * NULL. - * @result A delegate to which GrowlApplicationBridge holds a reference. - */ - void *(*retain)(void *); - /* When you call Growl_SetDelegate(newDelegate), it will call - * oldDelegate->release(oldDelegate), and then it will call - * newDelegate->retain(newDelegate), and the return value from retain - * is what will be set as the delegate. - * (This means that this member works like CFRelease and - * -[NSObject release].) - * This member is optional (it can be NULL). - * For a delegate allocated with malloc, this member might be - * free(3). - */ - void (*release)(void *); - - /* Informs the delegate that Growl (specifically, the GrowlHelperApp) was - * launched successfully (or was already running). The application can - * take actions with the knowledge that Growl is installed and functional. - */ - void (*growlIsReady)(void); - - /* Informs the delegate that a Growl notification was clicked. It is only - * sent for notifications sent with a non-NULL clickContext, - * so if you want to receive a message when a notification is clicked, - * clickContext must not be NULL when calling - * Growl_PostNotification or - * Growl_NotifyWithTitleDescriptionNameIconPriorityStickyClickContext. - */ - void (*growlNotificationWasClicked)(CFPropertyListRef clickContext); - - /* Informs the delegate that a Growl notification timed out. It is only - * sent for notifications sent with a non-NULL clickContext, - * so if you want to receive a message when a notification is clicked, - * clickContext must not be NULL when calling - * Growl_PostNotification or - * Growl_NotifyWithTitleDescriptionNameIconPriorityStickyClickContext. - */ - void (*growlNotificationTimedOut)(CFPropertyListRef clickContext); -}; - -/*! @struct Growl_Notification - * @abstract Structure describing a Growl notification. - * @discussion XXX - * @field size The size of the notification structure. - * @field name Identifies the notification. - * @field title Short synopsis of the notification. - * @field description Additional text. - * @field iconData An icon for the notification. - * @field priority An indicator of the notification's importance. - * @field reserved Bits reserved for future usage. - * @field isSticky Requests that a notification stay on-screen until dismissed explicitly. - * @field clickContext An identifier to be passed to your click callback when a notification is clicked. - * @field clickCallback A callback to call when the notification is clicked. - */ -struct Growl_Notification { - /* This should be sizeof(struct Growl_Notification). - */ - size_t size; - - /* The notification name distinguishes one type of - * notification from another. The name should be human-readable, as it - * will be displayed in the Growl preference pane. - * - * The name is used in the GROWL_NOTIFICATIONS_ALL and - * GROWL_NOTIFICATIONS_DEFAULT arrays in the registration dictionary, and - * in this member of the Growl_Notification structure. - */ - CFStringRef name; - - /* A notification's title describes the notification briefly. - * It should be easy to read quickly by the user. - */ - CFStringRef title; - - /* The description supplements the title with more - * information. It is usually longer and sometimes involves a list of - * subjects. For example, for a 'Download complete' notification, the - * description might have one filename per line. GrowlMail in Growl 0.6 - * uses a description of '%d new mail(s)' (formatted with the number of - * messages). - */ - CFStringRef description; - - /* The notification icon usually indicates either what - * happened (it may have the same icon as e.g. a toolbar item that - * started the process that led to the notification), or what it happened - * to (e.g. a document icon). - * - * The icon data is optional, so it can be NULL. In that - * case, the application icon is used alone. Not all displays support - * icons. - * - * The data can be in any format supported by NSImage. As of Mac OS X - * 10.3, this includes the .icns, TIFF, JPEG, GIF, PNG, PDF, and PICT form - * ats. - */ - CFDataRef iconData; - - /* Priority is new in Growl 0.6, and is represented as a - * signed integer from -2 to +2. 0 is Normal priority, -2 is Very Low - * priority, and +2 is Very High priority. - * - * Not all displays support priority. If you do not wish to assign a - * priority to your notification, assign 0. - */ - signed int priority; - - /* These bits are not used in Growl 0.6. Set them to 0. - */ - unsigned reserved: 31; - - /* When the sticky bit is clear, in most displays, - * notifications disappear after a certain amount of time. Sticky - * notifications, however, remain on-screen until the user dismisses them - * explicitly, usually by clicking them. - * - * Sticky notifications were introduced in Growl 0.6. Most notifications - * should not be sticky. Not all displays support sticky notifications, - * and the user may choose in Growl's preference pane to force the - * notification to be sticky or non-sticky, in which case the sticky bit - * in the notification will be ignored. - */ - unsigned isSticky: 1; - - /* If this is not NULL, and your click callback - * is not NULL either, this will be passed to the callback - * when your notification is clicked by the user. - * - * Click feedback was introduced in Growl 0.6, and it is optional. Not - * all displays support click feedback. - */ - CFPropertyListRef clickContext; - - /* If this is not NULL, it will be called instead - * of the Growl delegate's click callback when clickContext is - * non-NULL and the notification is clicked on by the user. - * - * Click feedback was introduced in Growl 0.6, and it is optional. Not - * all displays support click feedback. - * - * The per-notification click callback is not yet supported as of Growl - * 0.7. - */ - void (*clickCallback)(CFPropertyListRef clickContext); - - CFStringRef identifier; -}; - -#pragma mark - -#pragma mark Easy initialisers - -/*! @defined InitGrowlDelegate - * @abstract Callable macro. Initializes a Growl delegate structure to defaults. - * @discussion Call with a pointer to a struct Growl_Delegate. All of the - * members of the structure will be set to 0 or NULL, except for - * size (which will be set to sizeof(struct Growl_Delegate)) and - * referenceCount (which will be set to 1). - */ -#define InitGrowlDelegate(delegate) \ - do { \ - if (delegate) { \ - (delegate)->size = sizeof(struct Growl_Delegate); \ - (delegate)->applicationName = NULL; \ - (delegate)->registrationDictionary = NULL; \ - (delegate)->applicationIconData = NULL; \ - (delegate)->growlInstallationWindowTitle = NULL; \ - (delegate)->growlInstallationInformation = NULL; \ - (delegate)->growlUpdateWindowTitle = NULL; \ - (delegate)->growlUpdateInformation = NULL; \ - (delegate)->referenceCount = 1U; \ - (delegate)->retain = NULL; \ - (delegate)->release = NULL; \ - (delegate)->growlIsReady = NULL; \ - (delegate)->growlNotificationWasClicked = NULL; \ - (delegate)->growlNotificationTimedOut = NULL; \ - } \ - } while(0) - -/*! @defined InitGrowlNotification - * @abstract Callable macro. Initializes a Growl notification structure to defaults. - * @discussion Call with a pointer to a struct Growl_Notification. All of - * the members of the structure will be set to 0 or NULL, except - * for size (which will be set to - * sizeof(struct Growl_Notification)). - */ -#define InitGrowlNotification(notification) \ - do { \ - if (notification) { \ - (notification)->size = sizeof(struct Growl_Notification); \ - (notification)->name = NULL; \ - (notification)->title = NULL; \ - (notification)->description = NULL; \ - (notification)->iconData = NULL; \ - (notification)->priority = 0; \ - (notification)->reserved = 0U; \ - (notification)->isSticky = false; \ - (notification)->clickContext = NULL; \ - (notification)->clickCallback = NULL; \ - (notification)->identifier = NULL; \ - } \ - } while(0) - -#pragma mark - -#pragma mark Public API - -// @functiongroup Managing the Growl delegate - -/*! @function Growl_SetDelegate - * @abstract Replaces the current Growl delegate with a new one, or removes - * the Growl delegate. - * @param newDelegate - * @result Returns false and does nothing else if a pointer that was passed in - * is unsatisfactory (because it is non-NULL, but at least one - * required member of it is NULL). Otherwise, sets or unsets the - * delegate and returns true. - * @discussion When newDelegate is non-NULL, sets - * the delegate to newDelegate. When it is NULL, - * the current delegate will be unset, and no delegate will be in place. - * - * It is legal for newDelegate to be the current delegate; - * nothing will happen, and Growl_SetDelegate will return true. It is also - * legal for it to be NULL, as described above; again, it will - * return true. - * - * If there was a delegate in place before the call, Growl_SetDelegate will - * call the old delegate's release member if it was non-NULL. If - * newDelegate is non-NULL, Growl_SetDelegate will - * call newDelegate->retain, and set the delegate to its return - * value. - * - * If you are using Growl-WithInstaller.framework, and an older version of - * Growl is installed on the user's system, the user will automatically be - * prompted to update. - * - * GrowlApplicationBridge currently does not copy this structure, nor does it - * retain any of the CF objects in the structure (it regards the structure as - * a container that retains the objects when they are added and releases them - * when they are removed or the structure is destroyed). Also, - * GrowlApplicationBridge currently does not modify any member of the - * structure, except possibly the referenceCount by calling the retain and - * release members. - */ -GROWL_EXPORT Boolean Growl_SetDelegate(struct Growl_Delegate *newDelegate); - -/*! @function Growl_GetDelegate - * @abstract Returns the current Growl delegate, if any. - * @result The current Growl delegate. - * @discussion Returns the last pointer passed into Growl_SetDelegate, or - * NULL if no such call has been made. - * - * This function follows standard Core Foundation reference-counting rules. - * Because it is a Get function, not a Copy function, it will not retain the - * delegate on your behalf. You are responsible for retaining and releasing - * the delegate as needed. - */ -GROWL_EXPORT struct Growl_Delegate *Growl_GetDelegate(void); - -#pragma mark - - -// @functiongroup Posting Growl notifications - -/*! @function Growl_PostNotification - * @abstract Posts a Growl notification. - * @param notification The notification to post. - * @discussion This is the preferred means for sending a Growl notification. - * The notification name and at least one of the title and description are - * required (all three are preferred). All other parameters may be - * NULL (or 0 or false as appropriate) to accept default values. - * - * If using the Growl-WithInstaller framework, if Growl is not installed the - * user will be prompted to install Growl. - * If the user cancels, this function will have no effect until the next - * application session, at which time when it is called the user will be - * prompted again. The user is also given the option to not be prompted again. - * If the user does choose to install Growl, the requested notification will - * be displayed once Growl is installed and running. - */ -GROWL_EXPORT void Growl_PostNotification(const struct Growl_Notification *notification); - -/*! @function Growl_PostNotificationWithDictionary -* @abstract Notifies using a userInfo dictionary suitable for passing to -* CFDistributedNotificationCenter. -* @param userInfo The dictionary to notify with. -* @discussion Before Growl 0.6, your application would have posted -* notifications using CFDistributedNotificationCenter by creating a userInfo -* dictionary with the notification data. This had the advantage of allowing -* you to add other data to the dictionary for programs besides Growl that -* might be listening. -* -* This function allows you to use such dictionaries without being restricted -* to using CFDistributedNotificationCenter. The keys for this dictionary - * can be found in GrowlDefines.h. -*/ -GROWL_EXPORT void Growl_PostNotificationWithDictionary(CFDictionaryRef userInfo); - -/*! @function Growl_NotifyWithTitleDescriptionNameIconPriorityStickyClickContext - * @abstract Posts a Growl notification using parameter values. - * @param title The title of the notification. - * @param description The description of the notification. - * @param notificationName The name of the notification as listed in the - * registration dictionary. - * @param iconData Data representing a notification icon. Can be NULL. - * @param priority The priority of the notification (-2 to +2, with -2 - * being Very Low and +2 being Very High). - * @param isSticky If true, requests that this notification wait for a - * response from the user. - * @param clickContext An object to pass to the clickCallback, if any. Can - * be NULL, in which case the clickCallback is not called. - * @discussion Creates a temporary Growl_Notification, fills it out with the - * supplied information, and calls Growl_PostNotification on it. - * See struct Growl_Notification and Growl_PostNotification for more - * information. - * - * The icon data can be in any format supported by NSImage. As of Mac OS X - * 10.3, this includes the .icns, TIFF, JPEG, GIF, PNG, PDF, and PICT formats. - */ -GROWL_EXPORT void Growl_NotifyWithTitleDescriptionNameIconPriorityStickyClickContext( - /*inhale*/ - CFStringRef title, - CFStringRef description, - CFStringRef notificationName, - CFDataRef iconData, - signed int priority, - Boolean isSticky, - CFPropertyListRef clickContext); - -#pragma mark - - -// @functiongroup Registering - -/*! @function Growl_RegisterWithDictionary - * @abstract Register your application with Growl without setting a delegate. - * @discussion When you call this function with a dictionary, - * GrowlApplicationBridge registers your application using that dictionary. - * If you pass NULL, GrowlApplicationBridge will ask the delegate - * (if there is one) for a dictionary, and if that doesn't work, it will look - * in your application's bundle for an auto-discoverable plist. - * (XXX refer to more information on that) - * - * If you pass a dictionary to this function, it must include the - * GROWL_APP_NAME key, unless a delegate is set. - * - * This function is mainly an alternative to the delegate system introduced - * with Growl 0.6. Without a delegate, you cannot receive callbacks such as - * growlIsReady (since they are sent to the delegate). You can, - * however, set a delegate after registering without one. - * - * This function was introduced in Growl.framework 0.7. - * @result false if registration failed (e.g. if Growl isn't installed). - */ -GROWL_EXPORT Boolean Growl_RegisterWithDictionary(CFDictionaryRef regDict); - -/*! @function Growl_Reregister - * @abstract Updates your registration with Growl. - * @discussion If your application changes the contents of the - * GROWL_NOTIFICATIONS_ALL key in the registrationDictionary member of the - * Growl delegate, or if it changes the value of that member, or if it - * changes the contents of its auto-discoverable plist, call this function - * to have Growl update its registration information for your application. - * - * Otherwise, this function does not normally need to be called. If you're - * using a delegate, your application will be registered when you set the - * delegate if both the delegate and its registrationDictionary member are - * non-NULL. - * - * This function is now implemented using - * Growl_RegisterWithDictionary. - */ -GROWL_EXPORT void Growl_Reregister(void); - -#pragma mark - - -/*! @function Growl_SetWillRegisterWhenGrowlIsReady - * @abstract Tells GrowlApplicationBridge to register with Growl when Growl - * launches (or not). - * @discussion When Growl has started listening for notifications, it posts a - * GROWL_IS_READY notification on the Distributed Notification - * Center. GrowlApplicationBridge listens for this notification, using it to - * perform various tasks (such as calling your delegate's - * growlIsReady callback, if it has one). If this function is - * called with true, one of those tasks will be to reregister - * with Growl (in the manner of Growl_Reregister). - * - * This attribute is automatically set back to false - * (the default) after every GROWL_IS_READY notification. - * @param flag true if you want GrowlApplicationBridge to register with - * Growl when next it is ready; false if not. - */ -GROWL_EXPORT void Growl_SetWillRegisterWhenGrowlIsReady(Boolean flag); -/*! @function Growl_WillRegisterWhenGrowlIsReady - * @abstract Reports whether GrowlApplicationBridge will register with Growl - * when Growl next launches. - * @result true if GrowlApplicationBridge will register with - * Growl when next it posts GROWL_IS_READY; false if not. - */ -GROWL_EXPORT Boolean Growl_WillRegisterWhenGrowlIsReady(void); - -#pragma mark - - -// @functiongroup Obtaining registration dictionaries - -/*! @function Growl_CopyRegistrationDictionaryFromDelegate - * @abstract Asks the delegate for a registration dictionary. - * @discussion If no delegate is set, or if the delegate's - * registrationDictionary member is NULL, this - * function returns NULL. - * - * This function does not attempt to clean up the dictionary in any way - for - * example, if it is missing the GROWL_APP_NAME key, the result - * will be missing it too. Use - * Growl_CreateRegistrationDictionaryByFillingInDictionary or - * Growl_CreateRegistrationDictionaryByFillingInDictionaryRestrictedToKeys - * to try to fill in missing keys. - * - * This function was introduced in Growl.framework 0.7. - * @result A registration dictionary. - */ -GROWL_EXPORT CFDictionaryRef Growl_CopyRegistrationDictionaryFromDelegate(void); - -/*! @function Growl_CopyRegistrationDictionaryFromBundle - * @abstract Looks in a bundle for a registration dictionary. - * @discussion This function looks in a bundle for an auto-discoverable - * registration dictionary file using CFBundleCopyResourceURL. - * If it finds one, it loads the file using CFPropertyList and - * returns the result. - * - * If you pass NULL as the bundle, the main bundle is examined. - * - * This function does not attempt to clean up the dictionary in any way - for - * example, if it is missing the GROWL_APP_NAME key, the result - * will be missing it too. Use - * Growl_CreateRegistrationDictionaryByFillingInDictionary: or - * Growl_CreateRegistrationDictionaryByFillingInDictionaryRestrictedToKeys - * to try to fill in missing keys. - * - * This function was introduced in Growl.framework 0.7. - * @result A registration dictionary. - */ -GROWL_EXPORT CFDictionaryRef Growl_CopyRegistrationDictionaryFromBundle(CFBundleRef bundle); - -/*! @function Growl_CreateBestRegistrationDictionary - * @abstract Obtains a registration dictionary, filled out to the best of - * GrowlApplicationBridge's knowledge. - * @discussion This function creates a registration dictionary as best - * GrowlApplicationBridge knows how. - * - * First, GrowlApplicationBridge examines the Growl delegate (if there is - * one) and gets the registration dictionary from that. If no such dictionary - * was obtained, GrowlApplicationBridge looks in your application's main - * bundle for an auto-discoverable registration dictionary file. If that - * doesn't exist either, this function returns NULL. - * - * Second, GrowlApplicationBridge calls - * Growl_CreateRegistrationDictionaryByFillingInDictionary with - * whatever dictionary was obtained. The result of that function is the - * result of this function. - * - * GrowlApplicationBridge uses this function when you call - * Growl_SetDelegate, or when you call - * Growl_RegisterWithDictionary with NULL. - * - * This function was introduced in Growl.framework 0.7. - * @result A registration dictionary. - */ -GROWL_EXPORT CFDictionaryRef Growl_CreateBestRegistrationDictionary(void); - -#pragma mark - - -// @functiongroup Filling in registration dictionaries - -/*! @function Growl_CreateRegistrationDictionaryByFillingInDictionary - * @abstract Tries to fill in missing keys in a registration dictionary. - * @param regDict The dictionary to fill in. - * @result The dictionary with the keys filled in. - * @discussion This function examines the passed-in dictionary for missing keys, - * and tries to work out correct values for them. As of 0.7, it uses: - * - * Key Value - * --- ----- - * GROWL_APP_NAME CFBundleExecutableName - * GROWL_APP_ICON The icon of the application. - * GROWL_APP_LOCATION The location of the application. - * GROWL_NOTIFICATIONS_DEFAULT GROWL_NOTIFICATIONS_ALL - * - * Keys are only filled in if missing; if a key is present in the dictionary, - * its value will not be changed. - * - * This function was introduced in Growl.framework 0.7. - */ -GROWL_EXPORT CFDictionaryRef Growl_CreateRegistrationDictionaryByFillingInDictionary(CFDictionaryRef regDict); -/*! @function Growl_CreateRegistrationDictionaryByFillingInDictionaryRestrictedToKeys - * @abstract Tries to fill in missing keys in a registration dictionary. - * @param regDict The dictionary to fill in. - * @param keys The keys to fill in. If NULL, any missing keys are filled in. - * @result The dictionary with the keys filled in. - * @discussion This function examines the passed-in dictionary for missing keys, - * and tries to work out correct values for them. As of 0.7, it uses: - * - * Key Value - * --- ----- - * GROWL_APP_NAME CFBundleExecutableName - * GROWL_APP_ICON The icon of the application. - * GROWL_APP_LOCATION The location of the application. - * GROWL_NOTIFICATIONS_DEFAULT GROWL_NOTIFICATIONS_ALL - * - * Only those keys that are listed in keys will be filled in. - * Other missing keys are ignored. Also, keys are only filled in if missing; - * if a key is present in the dictionary, its value will not be changed. - * - * This function was introduced in Growl.framework 0.7. - */ -GROWL_EXPORT CFDictionaryRef Growl_CreateRegistrationDictionaryByFillingInDictionaryRestrictedToKeys(CFDictionaryRef regDict, CFSetRef keys); - -/*! @brief Tries to fill in missing keys in a notification dictionary. - * @param notifDict The dictionary to fill in. - * @return The dictionary with the keys filled in. This will be a separate instance from \a notifDict. - * @discussion This function examines the \a notifDict for missing keys, and - * tries to get them from the last known registration dictionary. As of 1.1, - * the keys that it will look for are: - * - * \li GROWL_APP_NAME - * \li GROWL_APP_ICON - * - * @since Growl.framework 1.1 - */ -GROWL_EXPORT CFDictionaryRef Growl_CreateNotificationDictionaryByFillingInDictionary(CFDictionaryRef notifDict); - -#pragma mark - - -// @functiongroup Querying Growl's status - -/*! @function Growl_IsInstalled - * @abstract Determines whether the Growl prefpane and its helper app are - * installed. - * @result Returns true if Growl is installed, false otherwise. - */ -GROWL_EXPORT Boolean Growl_IsInstalled(void); - -/*! @function Growl_IsRunning - * @abstract Cycles through the process list to find whether GrowlHelperApp - * is running. - * @result Returns true if Growl is running, false otherwise. - */ -GROWL_EXPORT Boolean Growl_IsRunning(void); - -#pragma mark - - -// @functiongroup Launching Growl - -/*! @typedef GrowlLaunchCallback - * @abstract Callback to notify you that Growl is running. - * @param context The context pointer passed to Growl_LaunchIfInstalled. - * @discussion Growl_LaunchIfInstalled calls this callback function if Growl - * was already running or if it launched Growl successfully. - */ -typedef void (*GrowlLaunchCallback)(void *context); - -/*! @function Growl_LaunchIfInstalled - * @abstract Launches GrowlHelperApp if it is not already running. - * @param callback A callback function which will be called if Growl was successfully - * launched or was already running. Can be NULL. - * @param context The context pointer to pass to the callback. Can be NULL. - * @result Returns true if Growl was successfully launched or was already - * running; returns false and does not call the callback otherwise. - * @discussion Returns true and calls the callback (if the callback is not - * NULL) if the Growl helper app began launching or was already - * running. Returns false and performs no other action if Growl could not be - * launched (e.g. because the Growl preference pane is not properly installed). - * - * If Growl_CreateBestRegistrationDictionary returns - * non-NULL, this function will register with Growl atomically. - * - * The callback should take a single argument; this is to allow applications - * to have context-relevant information passed back. It is perfectly - * acceptable for context to be NULL. The callback itself can be - * NULL if you don't want one. - */ -GROWL_EXPORT Boolean Growl_LaunchIfInstalled(GrowlLaunchCallback callback, void *context); - -#pragma mark - -#pragma mark Constants - -/*! @defined GROWL_PREFPANE_BUNDLE_IDENTIFIER - * @abstract The CFBundleIdentifier of the Growl preference pane bundle. - * @discussion GrowlApplicationBridge uses this to determine whether Growl is - * currently installed, by searching for the Growl preference pane. Your - * application probably does not need to use this macro itself. - */ -#ifndef GROWL_PREFPANE_BUNDLE_IDENTIFIER -#define GROWL_PREFPANE_BUNDLE_IDENTIFIER CFSTR("com.growl.prefpanel") -#endif - -__END_DECLS - -#endif /* _GROWLAPPLICATIONBRIDGE_CARBON_H_ */ diff --git a/Tools/XcodeCapp/Jakefile b/Tools/XcodeCapp/Jakefile deleted file mode 100644 index 1fb239767..000000000 --- a/Tools/XcodeCapp/Jakefile +++ /dev/null @@ -1,45 +0,0 @@ - -require("../../common.jake"); - -var OS = require("os"), - task = require("jake").task, - stream = require("narwhal/term").stream, - applicationName = "XcodeCapp.app"; - -task ("build", function() -{ - if (executableExists("xcodebuild")) - { - var args = "-sdk macosx -alltargets -configuration Release", - supportPath = FILE.join($BUILD_CJS_CAPPUCCINO, "support", applicationName), - installPath = FILE.join("/", "Applications", applicationName); - - if (OS.system("xcodebuild " + args)) - OS.exit(1); - - rm_rf(supportPath); - FILE.mkdirs(supportPath); - cp_r(FILE.join("build", "Release", "XcodeCapp.app"), supportPath); - FILE.chmod(FILE.join(supportPath, "Contents", "MacOS", "XcodeCapp"), 0755); - - OS.system(["ln", "-sf", supportPath, installPath]); - } - else - { - print("Building " + applicationName + " requires Xcode."); - } -}); - -task ("clean", function() -{ - if (OS.system("xcodebuild clean")) - OS.exit(1); -}); - -task ("clobber", function() -{ - if (OS.system("xcodebuild clean")) - OS.exit(1); -}); - -task ("default", ["build"]); diff --git a/Tools/XcodeCapp/PRHEmptyGrowlDelegate.h b/Tools/XcodeCapp/PRHEmptyGrowlDelegate.h deleted file mode 100644 index 480ea6d46..000000000 --- a/Tools/XcodeCapp/PRHEmptyGrowlDelegate.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// PRHEmptyGrowlDelegate.h -// XcodeCapp -// -// Created by Andrea D'Amore on 19/06/11. -// Copyright 2011 by author. All rights reserved. -// -// taken from -// http://groups.google.com/group/growl-development/browse_thread/thread/6b0c3fb9fa31f765 - -#import -#import - -@interface PRHEmptyGrowlDelegate : NSObject { - -} - -@end diff --git a/Tools/XcodeCapp/PRHEmptyGrowlDelegate.m b/Tools/XcodeCapp/PRHEmptyGrowlDelegate.m deleted file mode 100644 index cdd5148a0..000000000 --- a/Tools/XcodeCapp/PRHEmptyGrowlDelegate.m +++ /dev/null @@ -1,14 +0,0 @@ -// -// PRHEmptyGrowlDelegate.h -// XcodeCapp -// -// Created by Andrea D'Amore on 19/06/11. -// Copyright 2011 by author. All rights reserved. -// - -#import "PRHEmptyGrowlDelegate.h" - - -@implementation PRHEmptyGrowlDelegate - -@end diff --git a/Tools/XcodeCapp/README.md b/Tools/XcodeCapp/README.md deleted file mode 100644 index c23a01c80..000000000 --- a/Tools/XcodeCapp/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# xCodeCapp-Cocoa - -xcodecapp-cocoa is a port from the original xcodecapp application. It works basically the same than this -tools shipped with Cappuccino framework but have serveral advantages: - - * It uses the FSEventStream system to be notified when a file changes. So no useless looping - * It consumes about no CPU when idle - * It allows you to choose graphically the project you want to use - * It will keep track of your already generated project helper - * It supports .xcodecapp-ignore - * It uses Growl to notify you when a conversion is done. - -# License - -All the code is distributed under AGPL v3.0 license. The parse.j comes from Cappuccino parser and uses the Cappuccino license. - -# Author - -Antoine Meradal \ No newline at end of file diff --git a/Tools/XcodeCapp/TNErrorDataView.h b/Tools/XcodeCapp/TNErrorDataView.h deleted file mode 100644 index 5a1b10074..000000000 --- a/Tools/XcodeCapp/TNErrorDataView.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is a part of program XcodeCapp - * Copyright (C) 2013 Antoine Mercadal () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import - -@interface TNErrorDataView : NSView -{ - IBOutlet NSTextField *fieldFileName; - IBOutlet NSTextField *__strong fieldMessage; - IBOutlet NSButton *buttonOpenFile; - - NSString *_fullPath; -} - -@property (strong) NSTextField *fieldMessage; - -- (IBAction)openFile:(id)aSender; - -@end diff --git a/Tools/XcodeCapp/TNErrorDataView.m b/Tools/XcodeCapp/TNErrorDataView.m deleted file mode 100644 index a8a49d31f..000000000 --- a/Tools/XcodeCapp/TNErrorDataView.m +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is a part of program XcodeCapp - * Copyright (C) 2013 Antoine Mercadal () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import "TNErrorDataView.h" - -@implementation TNErrorDataView - -@synthesize fieldMessage; - -/*! - Set the data view's object value - @param aValue the dictionary representing the error - */ -- (void)setObjectValue:(NSDictionary *)aValue -{ - [fieldMessage setStringValue:[aValue valueForKey:@"message"]]; - [fieldFileName setStringValue:[aValue valueForKey:@"file"]]; - _fullPath = [aValue valueForKey:@"path"]; -} - - -#pragma - -#pragma Actions - -/*! - Open the errored file in default editor - @param aSender the sender of the action - */ -- (IBAction)openFile:(id)aSender -{ - NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; - [workspace openFile:_fullPath]; -} - - -#pragma - -#pragma CPCoding - -- (id)initWithCoder:(NSCoder*)aCoder -{ - if (self = [super initWithCoder:aCoder]) - { - fieldFileName = [aCoder decodeObjectForKey:@"fieldFileName"]; - fieldMessage = [aCoder decodeObjectForKey:@"fieldMessage"]; - buttonOpenFile = [aCoder decodeObjectForKey:@"buttonOpenFile"]; - } - - return self; -} - -- (void)encodeWithCoder:(NSCoder*)aCoder -{ - [super encodeWithCoder:aCoder]; - - [aCoder encodeObject:fieldFileName forKey:@"fieldFileName"]; - [aCoder encodeObject:fieldMessage forKey:@"fieldMessage"]; - [aCoder encodeObject:buttonOpenFile forKey:@"buttonOpenFile"]; -} - -@end diff --git a/Tools/XcodeCapp/TNXCodeCapp.h b/Tools/XcodeCapp/TNXCodeCapp.h deleted file mode 100644 index 6fab4af18..000000000 --- a/Tools/XcodeCapp/TNXCodeCapp.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is a part of program XcodeCapp - * Copyright (C) 2011 Antoine Mercadal () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import -#import "PRHEmptyGrowlDelegate.h" -#import "FSEventCallback.h" - -extern NSString * const XCCDidPopulateProjectNotification; -extern NSString * const XCCConversionStartNotification; -extern NSString * const XCCConversionStopNotification; -extern NSString * const XCCListeningStartNotification; - - -@interface TNXCodeCapp : NSObject -{ - FSEventStreamRef stream; - NSFileManager *fm; - NSMutableArray *errorList; - NSMutableSet *ignoredFilePaths; - NSNumber *lastEventId; - NSString *currentAPIMode; - NSString *currentProjectName; - NSString *parserPath; - NSString *XCodeSupportPBXPath; - NSString *XCodeSupportProjectName; - NSString *XCodeTemplatePBXPath; - NSString *profilePath; - NSString *shellPath; - NSString *PBXModifierScriptPath; - NSURL *currentProjectURL; - NSURL *XCodeSupportProject; - NSURL *XCodeSupportProjectSources; - PRHEmptyGrowlDelegate *growlDelegateRef; - NSObject *delegate; - NSDate *appStartedTimestamp; - NSMutableDictionary *pathModificationDates; - BOOL supportsFileBasedListening; - BOOL reactToInodeModification; - BOOL isListening; - BOOL isUsingFileLevelAPI; - BOOL supportFileLevelAPI; -} - -@property (strong) NSObject* delegate; -@property (strong) NSMutableArray* errorList; -@property (strong) NSURL* XCodeSupportProject; -@property (strong) NSURL* currentProjectURL; -@property (strong) NSString* currentProjectName; -@property (strong) NSString* currentAPIMode; -@property BOOL supportsFileBasedListening; -@property BOOL reactToInodeModification; -@property BOOL isListening; -@property BOOL supportFileLevelAPI; -@property BOOL isUsingFileLevelAPI; - -- (BOOL)isObjJFile:(NSString*)path; -- (void)computeIgnoredPaths; -- (BOOL)isPathMatchingIgnoredPaths:(NSString*)aPath; -- (BOOL)isXIBFile:(NSString *)path; -- (BOOL)isXCCIgnoreFile:(NSString *)path; -- (BOOL)prepareXCodeSupportProject; -- (NSURL*)shadowHeaderURLForSourceURL:(NSURL*)aSourceURL; -- (void)cleanUpShadowsRelatedToSourceURL:(NSURL*)aSourceURL; -- (NSURL*)shadowImplementationURLForSourceURL:(NSURL*)aSourceURL; -- (NSURL*)sourceURLForShadowName:(NSString *)aString; -- (void)handleFileModification:(NSString*)fullPath notify:(BOOL)shouldNotify; -- (void)handleFileRemoval:(NSString*)fullPath; -- (void)initializeEventStreamWithPath:(NSString*)aPath; -- (void)stopEventStream; -- (void)updateLastEventId:(uint64_t)eventId; -- (void)updateUserDefaultsWithLastEventId; -- (void)synchronizeUserDefaultsWithDisk; -- (void)listenProjectAtPath:(NSString *)path; -- (void)clear; -- (void)start; -- (void)configure; -- (void)tidyShadowedFiles; - -@end - - -@interface TNXCodeCapp (SnowLeopard) - -- (void)updateLastModificationDate:(NSDate *)date forPath:(NSString *)path; -- (NSDate*)lastModificationDateForPath:(NSString *)path; - -@end diff --git a/Tools/XcodeCapp/TNXCodeCapp.m b/Tools/XcodeCapp/TNXCodeCapp.m deleted file mode 100644 index d6ef190b0..000000000 --- a/Tools/XcodeCapp/TNXCodeCapp.m +++ /dev/null @@ -1,882 +0,0 @@ -/* - * This file is a part of program XcodeCapp - * Copyright (C) 2011 Antoine Mercadal () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import "TNXCodeCapp.h" -#include "macros.h" - -NSString * const XCCUnderscoreReplacement = @"DoNotPutThisStringInFileNameOrWorldWillDie"; -NSString * const XCCDidPopulateProjectNotification = @"XCCDidPopulateProjectNotification"; -NSString * const XCCConversionStartNotification = @"XCCConversionStartNotification"; -NSString * const XCCConversionStopNotification = @"XCCConversionStopNotification"; -NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification"; - - -@implementation TNXCodeCapp - -@synthesize delegate; -@synthesize errorList; -@synthesize XCodeSupportProject; -@synthesize currentProjectURL; -@synthesize currentProjectName; -@synthesize supportsFileBasedListening; -@synthesize reactToInodeModification; -@synthesize currentAPIMode; -@synthesize isListening; -@synthesize supportFileLevelAPI; -@synthesize isUsingFileLevelAPI; - - -#pragma mark - Initialization - -/*! - Initialize the AppController - */ -- (id)init -{ - self = [super init]; - - if (self) - { - errorList = [NSMutableArray arrayWithCapacity:10]; - fm = [NSFileManager defaultManager]; - ignoredFilePaths = [NSMutableSet new]; - parserPath = [[NSBundle mainBundle] pathForResource:@"parser" ofType:@"j"]; - lastEventId = [[NSUserDefaults standardUserDefaults] objectForKey:@"lastEventId"]; - appStartedTimestamp = [NSDate date]; - - [self setIsListening:NO]; - [self setIsUsingFileLevelAPI:NO]; - - SInt32 versionMajor = 0; - SInt32 versionMinor = 0; - Gestalt(gestaltSystemVersionMajor, &versionMajor); - Gestalt(gestaltSystemVersionMinor, &versionMinor); - - [self setSupportFileLevelAPI:versionMajor >= 10 && versionMinor >= 7]; - // Uncomment to simulate 10.6 mode - // [self setSupportFileLevelAPI:NO]; - - [self configure]; - - NSString* myShell = [[[NSProcessInfo processInfo] environment] objectForKey:@"SHELL"]; - - if (myShell) - { - shellPath = myShell; - } - else - { - shellPath = @"/bin/bash"; - } - - if([shellPath isEqualToString:@"/bin/bash"]) - { - if([fm fileExistsAtPath:[@"~/.bash_profile" stringByExpandingTildeInPath]]) - profilePath = [@"source ~/.bash_profile" stringByExpandingTildeInPath]; - else if([fm fileExistsAtPath:[@"~/.bashrc" stringByExpandingTildeInPath]]) - profilePath = [@"source ~/.bashrc" stringByExpandingTildeInPath]; - else if([fm fileExistsAtPath:[@"~/.profile" stringByExpandingTildeInPath]]) - profilePath = [@"source ~/.profile" stringByExpandingTildeInPath]; - else - profilePath = @""; - } - else if ([shellPath isEqualToString:@"/bin/zsh"]) - { - if([fm fileExistsAtPath:[@"~/.zshrc" stringByExpandingTildeInPath]]) - profilePath = [@"source ~/.zshrc" stringByExpandingTildeInPath]; - else if([fm fileExistsAtPath:[@"~/.profile" stringByExpandingTildeInPath]]) - profilePath = [@"source ~/.profile" stringByExpandingTildeInPath]; - else - profilePath = @""; - } - else - { - NSAlert *alert = [NSAlert alertWithMessageText:@"Shell not recognized." - defaultButton:@"OK" - alternateButton:nil - otherButton:nil - informativeTextWithFormat:@"You are running %@ as your shell, which is not supported. Please change your shell to either BASH or ZSH.", shellPath]; - [alert runModal]; - profilePath = @""; - } - } - - return self; -} - -- (void)start -{ - if (![[NSUserDefaults standardUserDefaults] boolForKey:@"XCCReopenLastProject"]) - return; - - NSString *lastOpenedPath = [[NSUserDefaults standardUserDefaults] objectForKey:@"LastOpenedPath"]; - - if (lastOpenedPath) - { - if ([fm fileExistsAtPath:lastOpenedPath]) - { - [self listenProjectAtPath:[NSString stringWithFormat:@"%@/", lastOpenedPath]]; - } - else - { - [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"LastOpenedPath"]; - } - } -} - - -#pragma mark - Project Management - -/*! - Check if .XcodeSupport needs to be initialized. - If not needed, check that all J files are mirrored. If no, - then launch conversion for missing mirrored h files - @return YES or NO - */ -- (BOOL)prepareXCodeSupportProject -{ - XCodeSupportProjectName = [NSString stringWithFormat:@"%@.xcodeproj/", currentProjectName]; - XCodeTemplatePBXPath = [[NSBundle mainBundle] pathForResource:@"project.pbxproj" ofType:@"sample"]; - XCodeSupportProject = [NSURL URLWithString:XCodeSupportProjectName relativeToURL:currentProjectURL]; - XCodeSupportProjectSources = [NSURL URLWithString:@".XcodeSupport/" relativeToURL:currentProjectURL]; - XCodeSupportPBXPath = [NSString stringWithFormat:@"%@/project.pbxproj", [XCodeSupportProject path]]; - PBXModifierScriptPath = [[NSBundle mainBundle] pathForResource:@"pbxprojModifier" ofType:@"py"]; - - - //[fm removeItemAtURL:XCodeSupportProjectSources error:nil]; - //[fm removeItemAtURL:XCodeSupportProject error:nil]; - - // create the template project if it doesn't exist - if (![fm fileExistsAtPath:[XCodeSupportProjectSources path]]) - { - NSLog(@"prepareXCodeSupportProject: Xcode support folder created at: %@", [XCodeSupportProject path]); - [fm createDirectoryAtPath:[XCodeSupportProject path] withIntermediateDirectories:YES attributes:nil error:nil]; - - DLog(@"prepareXCodeSupportProject: Copying project.pbxproj from %@ to %@", XCodeTemplatePBXPath, [XCodeSupportProject path]); - [fm copyItemAtPath:XCodeTemplatePBXPath toPath:XCodeSupportPBXPath error:nil]; - - DLog(@"prepareXCodeSupportProject: Reading the content of the project.pbxproj"); - NSMutableString *PBXContent = [NSMutableString stringWithContentsOfFile:XCodeSupportPBXPath encoding:NSUTF8StringEncoding error:nil]; - - [PBXContent writeToFile:XCodeSupportPBXPath atomically:YES encoding:NSUTF8StringEncoding error:nil]; - DLog(@"prepareXCodeSupportProject: PBX file adapted to the project"); - - [self createXcodeSupportProjectSourcesDirIfNecessary]; - return NO; - } - - [self createXcodeSupportProjectSourcesDirIfNecessary]; - return YES; -} - -/*! - Create the .XcodeSupport/Sources folder if necessary. - */ -- (void)createXcodeSupportProjectSourcesDirIfNecessary -{ - if ([fm fileExistsAtPath:[XCodeSupportProjectSources path]]) - return; - - DLog(@"createXcodeSupportProjectSourcesDirIfNecessary: Creating source folder %@", [XCodeSupportProjectSources path]); - [fm createDirectoryAtPath:[XCodeSupportProjectSources path] withIntermediateDirectories:YES attributes:nil error:nil]; -} - -/*! - Initialize the creation of the .XcodeSupport project. This - Operation is threaded - @param arguments Thread arguments (not used) - @param shouldNotify is YES, XCCDidPopulateProjectNotification will be send - */ -- (void)populateXCodeProject:(NSNumber *)shouldNotify -{ - if ([shouldNotify boolValue]) - [delegate performSelector:@selector(growlWithTitle:message:) withObject:@"Loading project" withObject:[currentProjectURL path]]; - - NSArray *subdpaths = [fm subpathsAtPath:[currentProjectURL path]]; - - for (NSString *p in subdpaths) - { - NSString *filePath = [NSString stringWithFormat:@"%@/%@", [currentProjectURL path], p]; - - BOOL isDir = NO; - [fm fileExistsAtPath:filePath isDirectory:&isDir]; - - if (isDir || ![self isObjJFile:filePath] || [self isPathMatchingIgnoredPaths:filePath]) - continue; - - NSURL *eventualShadow = [self shadowHeaderURLForSourceURL:[NSURL fileURLWithPath:filePath]]; - - if (![fm fileExistsAtPath:[eventualShadow path]]) - { - DLog(@"populateXCodeProject: Computing missing shadow file for %@", filePath); - [self handleFileModification:filePath notify:NO]; - } - } - - if ([shouldNotify boolValue]) - { - NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:currentProjectURL, @"URL", nil]; - [[NSNotificationCenter defaultCenter] postNotificationName:XCCDidPopulateProjectNotification object:self userInfo:info]; - } -} - -/*! - Start all needed processes for listening to a given path - @param path The folder path to listen to - */ -- (void)listenProjectAtPath:(NSString *)path -{ - NSMutableString *tempName = [NSMutableString stringWithString:[path lastPathComponent]]; - - currentProjectURL = [NSURL fileURLWithPath:path]; - - [tempName replaceOccurrencesOfString:@" " - withString:@"_" - options:NSCaseInsensitiveSearch - range:NSMakeRange(0, [tempName length])]; - currentProjectName = [NSString stringWithString:tempName]; - - [self computeIgnoredPaths]; - - BOOL isProjectReady = [self prepareXCodeSupportProject]; - - [NSThread detachNewThreadSelector:@selector(populateXCodeProject:) toTarget:self withObject:[NSNumber numberWithBool:!isProjectReady]]; - - [self initializeEventStreamWithPath:[currentProjectURL path]]; - - NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:path, @"path", [NSNumber numberWithInt:(isProjectReady) ? 1 : 0], @"ready", nil]; - [[NSNotificationCenter defaultCenter] postNotificationName:XCCListeningStartNotification object:self userInfo:info]; - - [[NSUserDefaults standardUserDefaults] setObject:[currentProjectURL path] forKey:@"LastOpenedPath"]; -} - - -#pragma mark - Event Stream - -/*! - Initializes the FSEvent stream - @param aPath the path of the folder to listen - */ -- (void)initializeEventStreamWithPath:(NSString*)aPath -{ - if ([self isListening]) - return; - - [self stopEventStream]; - - NSMutableArray *pathsToWatch = [NSMutableArray arrayWithObject:aPath]; - void *appPointer = (__bridge void *)self; - FSEventStreamContext context = {0, appPointer, NULL, NULL, NULL}; - CFTimeInterval latency = 2.0; - FSEventStreamCreateFlags flags = 0; - - if (supportsFileBasedListening) - { - DLog(@"initializeEventStreamWithPath: Initializing the FSEventStream at file level (clean)"); - flags = kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents; - } - else - { - NSLog(@"Initializing the FSEventStream at folder level (dirty)"); - flags = kFSEventStreamCreateFlagUseCFTypes; - } - - // add symlinked directories - NSArray *fileList = [fm contentsOfDirectoryAtPath:aPath error:nil]; - - for (NSString *node in fileList) - { - NSDictionary *attributes = [fm attributesOfItemAtPath:aPath error:nil]; - if ([[attributes objectForKey:@"NSFileType"] isEqualTo:NSFileTypeDirectory]) - { - NSString *subDirectoryPath = [aPath stringByAppendingPathComponent:node]; - NSString *symlinkDestination = [fm destinationOfSymbolicLinkAtPath:subDirectoryPath error:nil]; - - if (symlinkDestination) - { - [pathsToWatch addObject:subDirectoryPath]; - } - } - } - - stream = FSEventStreamCreate(NULL, &fsevents_callback, &context, (__bridge CFArrayRef) pathsToWatch, - [lastEventId unsignedLongLongValue], latency, flags); - - FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); - FSEventStreamStart(stream); - [self setIsListening:YES]; -} - -/*! - Stop listening the FSEvent stream if active - */ -- (void)stopEventStream -{ - if (stream) - { - FSEventStreamStop(stream); - FSEventStreamUnscheduleFromRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); - FSEventStreamInvalidate(stream); - FSEventStreamRelease(stream); - stream = NULL; - } - - [self setIsListening:NO]; -} - -/*! - Stops and clear the worker - */ -- (void)clear -{ - [self updateUserDefaultsWithLastEventId]; - [self synchronizeUserDefaultsWithDisk]; - currentProjectURL = nil; - currentProjectName = nil; - [ignoredFilePaths removeAllObjects]; - [self stopEventStream]; -} - -/*! - Choose the API mode according to default - */ -- (void)configure -{ - if (![self supportFileLevelAPI]) - { - DLog(@"configure: System doesn't support file level API"); - [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:2] forKey:@"XCCAPIMode"]; - } - - switch ([[NSUserDefaults standardUserDefaults] integerForKey:@"XCCAPIMode"]) - { - case 0: - supportsFileBasedListening = [self supportFileLevelAPI] ? YES : NO; - break; - case 1: - supportsFileBasedListening = YES; - break; - case 2: - supportsFileBasedListening = NO; - break; - } - - if (supportsFileBasedListening) - { - DLog(@"configure: using 10.7+ mode listening (clean)"); - - [self setCurrentAPIMode:@"File level (Lion)"]; - [self setIsUsingFileLevelAPI:YES]; - reactToInodeModification = [[NSUserDefaults standardUserDefaults] boolForKey:@"XCCReactMode"]; - } - else - { - DLog(@"configure: using 10.6 mode listening (dirty)"); - reactToInodeModification = NO; - [self setCurrentAPIMode:@"Folder level (Snow Leopard)"]; - [self setIsUsingFileLevelAPI:NO]; - } -} - -/*! - Update the last event ID. We use a method because - This is called from outside the class, in the FSEvent callback - @param eventId the current event ID value - */ -- (void)updateLastEventId:(uint64_t)eventId -{ - lastEventId = [NSNumber numberWithUnsignedLongLong:eventId]; -} - -/*! - Updates the user defaults with the last recorded event Id. - */ -- (void)updateUserDefaultsWithLastEventId -{ - if (lastEventId && [lastEventId longLongValue] != 0) - { - [[NSUserDefaults standardUserDefaults] setObject:lastEventId forKey:@"lastEventId"]; - } -} - -/*! - Tells the standard user defaults to synchronize with disk. - */ -- (void)synchronizeUserDefaultsWithDisk -{ - [[NSUserDefaults standardUserDefaults] synchronize]; -} - - -#pragma mark - Shell Helpers - -/*! - Run a NSTask with the given arguments - @param arguments NSArray containing the NSTask arguments - @return NSarray containing the return code (int) and the eventual response (string) - */ -- (NSArray *)runTask:(NSArray *)arguments -{ - NSTask *task; - NSData *stdOut; - NSString *response; - NSNumber *status; - - task = [[NSTask alloc] init]; - - [task setLaunchPath:shellPath]; - [task setArguments: arguments]; - [task setStandardOutput:[NSPipe pipe]]; - [task launch]; - [task waitUntilExit]; - - stdOut = [[[task standardOutput] fileHandleForReading] availableData]; - response = [[NSString alloc] initWithData:stdOut encoding:NSUTF8StringEncoding]; - status = [NSNumber numberWithInt:[task terminationStatus]]; - - return [NSArray arrayWithObjects:status, response, nil]; -} - - -#pragma mark - Event Handlers - -/*! - Handle a file modification. If it's a .J or XIB or NIB, it will - perform the according conversion. If it's .xcodecapp-ignore, it will - update the list of ignored files. - @param fullPath the full path of the modified file - @param shouldNotify if YES, Growl notifications will be displayed - */ -- (void)handleFileModification:(NSString*)fullPath notify:(BOOL)shouldNotify -{ - if (![self isXIBFile:fullPath] && ![self isObjJFile:fullPath] && ![self isXCCIgnoreFile:fullPath]) - return; - - if ([self isPathMatchingIgnoredPaths:fullPath] || ![fm fileExistsAtPath:fullPath]) - return; - - DLog(@"handleFileModification:notify: Parsing modified file: %@", fullPath); - - NSArray *arguments = nil; - NSArray *PBXArguments = nil; - NSString *successTitle = nil; - NSString *successMsg = nil; - NSString *response = nil; - NSNumber *status = [NSNumber numberWithInt:0]; - NSString *splitPath = [fullPath substringFromIndex:[[currentProjectURL path] length] + 1]; - NSURL *encodedURL = [NSURL URLWithString:[fullPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; - NSURL *shadowHeaderURL = [self shadowHeaderURLForSourceURL:encodedURL]; - NSURL *shadowImplementationURL = [self shadowImplementationURLForSourceURL:encodedURL]; - - DLog(@"handleFileModification:notify: Shadow header path: %@", shadowHeaderURL); - DLog(@"handleFileModification:notify: Shadow implementation path: %@", shadowImplementationURL); - - [[NSNotificationCenter defaultCenter] postNotificationName:XCCConversionStartNotification object:self]; - - if ([self isXIBFile:fullPath]) - { - arguments = [NSArray arrayWithObjects: @"-c", - [NSString stringWithFormat:@"(%@; nib2cib '%@';) 2>&1", profilePath, fullPath],@"",nil]; - - successTitle = @"XIB converted"; - successMsg = splitPath; - } - else if ([self isObjJFile:fullPath]) - { - arguments = [NSArray arrayWithObjects: @"-c", - [NSString stringWithFormat:@"(%@; objj '%@' '%@' '%@' '%@';) 2>&1", - profilePath, - parserPath, - fullPath, - [shadowHeaderURL path], - [shadowImplementationURL path]],nil]; - - PBXArguments = [NSArray arrayWithObjects: @"-c", - [NSString stringWithFormat:@"(%@; python %@ add '%@' '%@' '%@' '%@' '%@') 2>&1", - profilePath, - PBXModifierScriptPath, - XCodeSupportPBXPath, - [shadowHeaderURL path], - [shadowImplementationURL path], - fullPath, - [currentProjectURL path]],nil]; - - successTitle = @"Objective-J source processed"; - successMsg = splitPath; - } - else if ([self isXCCIgnoreFile:fullPath]) - { - [self computeIgnoredPaths]; - successTitle = @".xcodecapp-ignore processed"; - successMsg = @"Ignored files list updated"; - arguments = nil; - } - - // Run the task and get the response if needed - if (arguments) - { - DLog(@"handleFileModification:notify: Running conversion task..."); - NSArray *statusInfo = [self runTask:arguments]; - - status = [statusInfo objectAtIndex:0]; - response = [statusInfo objectAtIndex:1]; - - DLog(@"handleFileModification:notify: Conversion task result/response: %@/%@", status, response); - - if ([status intValue] == 0 && shouldNotify) - { - [delegate performSelector:@selector(growlWithTitle:message:) withObject:successTitle withObject:successMsg]; - } - else if (![status intValue] == 0) - { - if (response) - { - NSDictionary *errorDictionary = [NSDictionary dictionaryWithObjectsAndKeys:response, @"message", - splitPath, @"file", - fullPath, @"path", nil]; - - [errorList addObject:errorDictionary]; - } - - [delegate performSelector:@selector(growlWithTitle:message:) withObject:@"Error processing file" withObject:splitPath]; - } - } - - if (PBXArguments) - { - DLog(@"handleFileModification:notify: Running update PBX task..."); - NSArray *statusInfo = [self runTask:PBXArguments]; - status = [statusInfo objectAtIndex:0]; - response = [statusInfo objectAtIndex:1]; - DLog(@"handleFileModification:notify: Update PBX Task result/response: %@/%@", status, response); - } - - [[NSNotificationCenter defaultCenter] postNotificationName:XCCConversionStopNotification object:self]; - DLog(@"handleFileModification:notify: Processed: %@", fullPath); -} - -/*! - Handle a file deletion. If it's a .J, it will - remove the shadowed .h file. If it's .xcodecapp-ignore - it will reset the list of ignored files. - @param fullPath the full path of the modified file - @param shouldNotify if YES, Growl notifications will be displayed - */ -- (void)handleFileRemoval:(NSString*)fullPath -{ - if ([self isPathMatchingIgnoredPaths:fullPath] || [fm fileExistsAtPath:fullPath]) - return; - - NSString *encodedPath = [fullPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - - if ([self isObjJFile:fullPath]) - [self cleanUpShadowsRelatedToSourceURL:[NSURL URLWithString:encodedPath]]; - else if ([self isXCCIgnoreFile:fullPath]) - [self computeIgnoredPaths]; -} - - -#pragma mark - Source Files Management - -/*! - Check if given full path is Objective-J file - @param path the path to check - @return YES or NO - */ -- (BOOL)isObjJFile:(NSString *)path -{ - return [[[path pathExtension] uppercaseString] isEqual:@"J"]; -} - -/*! - Check if given full path is XIB or NIB file - @param path the path to check - @return YES or NO - */ -- (BOOL)isXIBFile:(NSString *)path -{ - path = [[path pathExtension] uppercaseString]; - return [path isEqual:@"XIB"] || [path isEqual:@"NIB"]; -} - -/*! - Check if given full path is the .xcodecapp-ignore file - @param path the path to check - @return YES or NO - */ -- (BOOL)isXCCIgnoreFile:(NSString *)path -{ - path = [path lastPathComponent]; - return [path isEqual:@".xcodecapp-ignore"]; -} - - -#pragma mark - Shadow Files Management - -/*! - Compute the mirorred (shadow) header file name for a given path - @param aSourceURL the origin path - @return NSURL representing the shadow URL for the header file - */ -- (NSURL *)shadowHeaderURLForSourceURL:(NSURL*)aSourceURL -{ - if (!aSourceURL) - [NSException raise:NSInvalidArgumentException format:@"shadowHeaderURLForSourceURL: aSource URL must not be null"]; - - NSMutableString *flattenedPath = [NSMutableString stringWithString:[aSourceURL path]]; - - // Replace "_" with a substring that is unlikely to be in a filename - [flattenedPath replaceOccurrencesOfString:@"_" - withString:XCCUnderscoreReplacement - options:0 - range:NSMakeRange(0, [flattenedPath length])]; - - [flattenedPath replaceOccurrencesOfString:@"/" - withString:@"_" - options:0 - range:NSMakeRange(0, [flattenedPath length])]; - - DLog(@"shadowHeaderURLForSourceURL: Flattened path: %@", flattenedPath); - NSString *basename = [NSString stringWithFormat:@"%@.h", [[flattenedPath stringByDeletingPathExtension] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; - - return [NSURL URLWithString:basename relativeToURL:XCodeSupportProjectSources]; -} - -/*! - Compute the mirorred (shadow) implementation file name for a given path - @param aSourceURL the origin path - @return NSURL representing the shadow URL for the implementation file - */ -- (NSURL *)shadowImplementationURLForSourceURL:(NSURL*)aSourceURL -{ - if (!aSourceURL) - [NSException raise:NSInvalidArgumentException format:@"shadowImplementationURLForSourceURL: aSource URL must not be null"]; - - NSURL *shadowHeaderURL = [self shadowHeaderURLForSourceURL:aSourceURL]; - NSURL *shadowImplPath = [[shadowHeaderURL URLByDeletingPathExtension] URLByAppendingPathExtension:@"m"]; - - return shadowImplPath; -} - -/*! - Compute the Cappuccino source file that is related to the given shadow header file URL - @param aString the origin path - @return NSURL representing the URL for the related Cappuccino source file - */ -- (NSURL *)sourceURLForShadowName:(NSString *)aString -{ - NSMutableString * unshadowedPath = [NSMutableString stringWithString:aString]; - - [unshadowedPath replaceOccurrencesOfString:@"_" - withString:@"/" - options:0 - range:NSMakeRange(0, [unshadowedPath length])]; - - [unshadowedPath replaceOccurrencesOfString:XCCUnderscoreReplacement - withString:@"_" - options:0 - range:NSMakeRange(0, [unshadowedPath length])]; - - [unshadowedPath replaceOccurrencesOfString:@".h" - withString:@".j" - options:0 - range:NSMakeRange(0, [unshadowedPath length])]; - - return [NSURL fileURLWithPath:[NSString stringWithString:unshadowedPath]]; -} - -/*! - Clean up any shadow files and PBX entries related to given the Cappuccino source file URL - @param anURL the Cappuccino source file URL - */ -- (void)cleanUpShadowsRelatedToSourceURL:(NSURL *)anURL -{ - NSURL *shadowHeaderURL = [self shadowHeaderURLForSourceURL:anURL]; - NSURL *shadowImplementationURL = [self shadowImplementationURLForSourceURL:anURL]; - - DLog(@"cleanUpShadowsRelatedToSourceURL: Removing shadow header file: %@", shadowHeaderURL); - [fm removeItemAtURL:shadowHeaderURL error:nil]; - - DLog(@"cleanUpShadowsRelatedToSourceURL: Removing shadow implementation file: %@", shadowImplementationURL); - [fm removeItemAtURL:shadowImplementationURL error:nil]; - - DLog(@"cleanUpShadowsRelatedToSourceURL:Removing PBX reference task..."); - NSArray *PBXArguments = [NSArray arrayWithObjects: @"-c", - [NSString stringWithFormat:@"(%@; python %@ remove '%@' '%@' '%@' '%@' '%@') 2>&1", - profilePath, - PBXModifierScriptPath, - XCodeSupportPBXPath, - [shadowHeaderURL path], - [shadowImplementationURL path], - [anURL path], - [currentProjectURL path]],nil]; - - NSArray *statusInfo = [self runTask:PBXArguments]; - NSNumber *status = [statusInfo objectAtIndex:0]; - NSString *response = [statusInfo objectAtIndex:1]; - DLog(@"cleanUpShadowsRelatedToSourceURL: PBX Reference removal status/response: %@/%@", status, response); -} - -/*! - Clean the support folder according to files present in given path - */ -- (void)tidyShadowedFiles -{ - NSArray *subpaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[XCodeSupportProjectSources path] error:NULL]; - - for (NSString *subpath in subpaths) - { - if (![[subpath pathExtension] isEqual:@".h"] || [[subpath lastPathComponent] isEqual:@"xcc_general_include.h"]) - continue; - - NSURL *unshadowed = [self sourceURLForShadowName:subpath]; - - if (![fm fileExistsAtPath:[unshadowed path]]) - { - [self cleanUpShadowsRelatedToSourceURL:unshadowed]; - - if (![self supportFileLevelAPI] && [self respondsToSelector:@selector(updateLastModificationDate:forPath:)]) - [self performSelector:@selector(updateLastModificationDate:forPath:) withObject:nil withObject:unshadowed]; - } - } -} - - -#pragma mark - XCC Ignore management - -/*! - Compute the ignored paths according to any existing - .xcodecapp-ignore file - */ -- (void)computeIgnoredPaths -{ - NSString *ignorePath = [NSString stringWithFormat:@"%@/.xcodecapp-ignore", [currentProjectURL path]]; - [ignoredFilePaths removeAllObjects]; - - if ([fm fileExistsAtPath:ignorePath]) - { - NSString *ignoreFileContent = [NSString stringWithContentsOfFile:ignorePath encoding:NSUTF8StringEncoding error:nil]; - NSArray *ignoredPatterns = [ignoreFileContent componentsSeparatedByString:@"\n"]; - - for (NSString *pattern in ignoredPatterns) - { - if ([pattern length]) - [ignoredFilePaths addObject:pattern]; - } - } - - [ignoredFilePaths addObject:@"*/.git/*"]; - [ignoredFilePaths addObject:@"*/.svn/*"]; - [ignoredFilePaths addObject:@"*/.hg/*"]; - [ignoredFilePaths addObject:@"*/Frameworks/*"]; - [ignoredFilePaths addObject:@"*/.XcodeSupport/*"]; - [ignoredFilePaths addObject:@"*/Build/*"]; - [ignoredFilePaths addObject:@"*/NS_*.j"]; - [ignoredFilePaths addObject:@"*main.j"]; - [ignoredFilePaths addObject:@"*.xcodeproj/*"]; - [ignoredFilePaths addObject:@"*.DS_Store"]; - - NSLog(@"Ignoring file paths: %@", ignoredFilePaths); -} - -/*! - Check is given path should be ignored - @param aPath the path to check - @return YES if it should be ignored, NO otherwise - */ -- (BOOL)isPathMatchingIgnoredPaths:(NSString*)aPath -{ - if ([ignoredFilePaths count] == 0) - return NO; - - for (NSString *ignoredPath in ignoredFilePaths) - { - if ([ignoredPath length] == 0) - continue; - - NSMutableString *regexp = [ignoredPath mutableCopy]; - - [regexp replaceOccurrencesOfString:@"/" - withString:@"\\/" - options:0 - range:NSMakeRange(0, [regexp length])]; - - [regexp replaceOccurrencesOfString:@"." - withString:@"\\." - options:0 - range:NSMakeRange(0, [regexp length])]; - - [regexp replaceOccurrencesOfString:@"*" - withString:@".*" - options:0 - range:NSMakeRange(0, [regexp length])]; - - [regexp replaceOccurrencesOfString:@" " - withString:@"\\ " - options:0 - range:NSMakeRange(0, [regexp length])]; - - NSPredicate *regextest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regexp]; - - if ([regextest evaluateWithObject:aPath]) - return YES; - } - - return NO; -} - -@end - - -@implementation TNXCodeCapp (SnowLeopard) - -- (void)updateLastModificationDate:(NSDate *)date forPath:(NSString *)path -{ - if (!pathModificationDates) - { - pathModificationDates = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"pathModificationDates"] mutableCopy]; - - if (!pathModificationDates) - pathModificationDates = [NSMutableDictionary new]; - } - - if (date) - [pathModificationDates setObject:date forKey:path]; - else - [pathModificationDates removeObjectForKey:path]; - - [[NSUserDefaults standardUserDefaults] setObject:pathModificationDates forKey:@"pathModificationDates"]; -} - -- (NSDate *)lastModificationDateForPath:(NSString *)path -{ - if (!pathModificationDates) - { - pathModificationDates = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"pathModificationDates"] mutableCopy]; - - if (!pathModificationDates) - pathModificationDates = [NSMutableDictionary new]; - } - - if ([pathModificationDates valueForKey:path] != nil) - return [pathModificationDates valueForKey:path]; - else - return appStartedTimestamp; -} - -@end diff --git a/Tools/XcodeCapp/XcodeCapp.icns b/Tools/XcodeCapp/XcodeCapp.icns deleted file mode 100644 index defc3dc7f..000000000 Binary files a/Tools/XcodeCapp/XcodeCapp.icns and /dev/null differ diff --git a/Tools/XcodeCapp/XcodeCapp.xcodeproj/TemplateIcon.icns b/Tools/XcodeCapp/XcodeCapp.xcodeproj/TemplateIcon.icns deleted file mode 100644 index 62cb7015e..000000000 Binary files a/Tools/XcodeCapp/XcodeCapp.xcodeproj/TemplateIcon.icns and /dev/null differ diff --git a/Tools/XcodeCapp/XcodeCapp.xcodeproj/awt.mode1v3 b/Tools/XcodeCapp/XcodeCapp.xcodeproj/awt.mode1v3 deleted file mode 100644 index 9ab3eb4ed..000000000 --- a/Tools/XcodeCapp/XcodeCapp.xcodeproj/awt.mode1v3 +++ /dev/null @@ -1,1389 +0,0 @@ - - - - - ActivePerspectiveName - Project - AllowedModules - - - BundleLoadPath - - MaxInstances - n - Module - PBXSmartGroupTreeModule - Name - Groups and Files Outline View - - - BundleLoadPath - - MaxInstances - n - Module - PBXNavigatorGroup - Name - Editor - - - BundleLoadPath - - MaxInstances - n - Module - XCTaskListModule - Name - Task List - - - BundleLoadPath - - MaxInstances - n - Module - XCDetailModule - Name - File and Smart Group Detail Viewer - - - BundleLoadPath - - MaxInstances - 1 - Module - PBXBuildResultsModule - Name - Detailed Build Results Viewer - - - BundleLoadPath - - MaxInstances - 1 - Module - PBXProjectFindModule - Name - Project Batch Find Tool - - - BundleLoadPath - - MaxInstances - n - Module - XCProjectFormatConflictsModule - Name - Project Format Conflicts List - - - BundleLoadPath - - MaxInstances - n - Module - PBXBookmarksModule - Name - Bookmarks Tool - - - BundleLoadPath - - MaxInstances - n - Module - PBXClassBrowserModule - Name - Class Browser - - - BundleLoadPath - - MaxInstances - n - Module - PBXCVSModule - Name - Source Code Control Tool - - - BundleLoadPath - - MaxInstances - n - Module - PBXDebugBreakpointsModule - Name - Debug Breakpoints Tool - - - BundleLoadPath - - MaxInstances - n - Module - XCDockableInspector - Name - Inspector - - - BundleLoadPath - - MaxInstances - n - Module - PBXOpenQuicklyModule - Name - Open Quickly Tool - - - BundleLoadPath - - MaxInstances - 1 - Module - PBXDebugSessionModule - Name - Debugger - - - BundleLoadPath - - MaxInstances - 1 - Module - PBXDebugCLIModule - Name - Debug Console - - - BundleLoadPath - - MaxInstances - n - Module - XCSnapshotModule - Name - Snapshots Tool - - - BundlePath - /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources - Description - DefaultDescriptionKey - DockingSystemVisible - - Extension - mode1v3 - FavBarConfig - - PBXProjectModuleGUID - 8E01A8EE0DE51C830008BB35 - XCBarModuleItemNames - - XCBarModuleItems - - - FirstTimeWindowDisplayed - - Identifier - com.apple.perspectives.project.mode1v3 - MajorVersion - 33 - MinorVersion - 0 - Name - Default - Notifications - - OpenEditors - - PerspectiveWidths - - -1 - -1 - - Perspectives - - - ChosenToolbarItems - - active-target-popup - active-buildstyle-popup - action - NSToolbarFlexibleSpaceItem - buildOrClean - build-and-goOrGo - com.apple.ide.PBXToolbarStopButton - get-info - toggle-editor - NSToolbarFlexibleSpaceItem - com.apple.pbx.toolbar.searchfield - - ControllerClassBaseName - - IconName - WindowOfProjectWithEditor - Identifier - perspective.project - IsVertical - - Layout - - - BecomeActive - - ContentConfiguration - - PBXBottomSmartGroupGIDs - - 1C37FBAC04509CD000000102 - 1C37FAAC04509CD000000102 - 1C08E77C0454961000C914BD - 1C37FABC05509CD000000102 - 1C37FABC05539CD112110102 - E2644B35053B69B200211256 - 1C37FABC04509CD000100104 - 1CC0EA4004350EF90044410B - 1CC0EA4004350EF90041110B - - PBXProjectModuleGUID - 1CE0B1FE06471DED0097A5F4 - PBXProjectModuleLabel - Files - PBXProjectStructureProvided - yes - PBXSmartGroupTreeModuleColumnData - - PBXSmartGroupTreeModuleColumnWidthsKey - - 269 - - PBXSmartGroupTreeModuleColumnsKey_v4 - - MainColumn - - - PBXSmartGroupTreeModuleOutlineStateKey_v7 - - PBXSmartGroupTreeModuleOutlineStateExpansionKey - - 29B97314FDCFA39411CA2CEA - 080E96DDFE201D6D7F000001 - 29B97323FDCFA39411CA2CEA - 1058C7A0FEA54F0111CA2CBB - 1C37FABC05509CD000000102 - 1CC0EA4004350EF90041110B - - PBXSmartGroupTreeModuleOutlineStateSelectionKey - - - 21 - 20 - - - PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 0}, {269, 430}} - - PBXTopSmartGroupGIDs - - XCIncludePerspectivesSwitch - - XCSharingToken - com.apple.Xcode.GFSharingToken - - GeometryConfiguration - - Frame - {{0, 0}, {286, 448}} - GroupTreeTableConfiguration - - MainColumn - 269 - - RubberWindowFrame - 545 -696 601 489 0 -800 1280 800 - - Module - PBXSmartGroupTreeModule - Proportion - 286pt - - - Dock - - - ContentConfiguration - - PBXProjectModuleGUID - 1CE0B20306471E060097A5F4 - PBXProjectModuleLabel - MyNewFile14.java - PBXSplitModuleInNavigatorKey - - Split0 - - PBXProjectModuleGUID - 1CE0B20406471E060097A5F4 - PBXProjectModuleLabel - MyNewFile14.java - - SplitCount - 1 - - StatusBarVisibility - - - GeometryConfiguration - - Frame - {{0, 0}, {310, 0}} - RubberWindowFrame - 545 -696 601 489 0 -800 1280 800 - - Module - PBXNavigatorGroup - Proportion - 0pt - - - ContentConfiguration - - PBXProjectModuleGUID - 1CE0B20506471E060097A5F4 - PBXProjectModuleLabel - Detail - - GeometryConfiguration - - Frame - {{0, 5}, {310, 443}} - RubberWindowFrame - 545 -696 601 489 0 -800 1280 800 - - Module - XCDetailModule - Proportion - 443pt - - - Proportion - 310pt - - - Name - Project - ServiceClasses - - XCModuleDock - PBXSmartGroupTreeModule - XCModuleDock - PBXNavigatorGroup - XCDetailModule - - TableOfContents - - 8E480DF30E980A1F005A51A6 - 1CE0B1FE06471DED0097A5F4 - 8E480DF40E980A1F005A51A6 - 1CE0B20306471E060097A5F4 - 1CE0B20506471E060097A5F4 - - ToolbarConfiguration - xcode.toolbar.config.defaultV3 - - - ControllerClassBaseName - - IconName - WindowOfProject - Identifier - perspective.morph - IsVertical - 0 - Layout - - - BecomeActive - 1 - ContentConfiguration - - PBXBottomSmartGroupGIDs - - 1C37FBAC04509CD000000102 - 1C37FAAC04509CD000000102 - 1C08E77C0454961000C914BD - 1C37FABC05509CD000000102 - 1C37FABC05539CD112110102 - E2644B35053B69B200211256 - 1C37FABC04509CD000100104 - 1CC0EA4004350EF90044410B - 1CC0EA4004350EF90041110B - - PBXProjectModuleGUID - 11E0B1FE06471DED0097A5F4 - PBXProjectModuleLabel - Files - PBXProjectStructureProvided - yes - PBXSmartGroupTreeModuleColumnData - - PBXSmartGroupTreeModuleColumnWidthsKey - - 186 - - PBXSmartGroupTreeModuleColumnsKey_v4 - - MainColumn - - - PBXSmartGroupTreeModuleOutlineStateKey_v7 - - PBXSmartGroupTreeModuleOutlineStateExpansionKey - - 29B97314FDCFA39411CA2CEA - 1C37FABC05509CD000000102 - - PBXSmartGroupTreeModuleOutlineStateSelectionKey - - - 0 - - - PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 0}, {186, 337}} - - PBXTopSmartGroupGIDs - - XCIncludePerspectivesSwitch - 1 - XCSharingToken - com.apple.Xcode.GFSharingToken - - GeometryConfiguration - - Frame - {{0, 0}, {203, 355}} - GroupTreeTableConfiguration - - MainColumn - 186 - - RubberWindowFrame - 373 269 690 397 0 0 1440 878 - - Module - PBXSmartGroupTreeModule - Proportion - 100% - - - Name - Morph - PreferredWidth - 300 - ServiceClasses - - XCModuleDock - PBXSmartGroupTreeModule - - TableOfContents - - 11E0B1FE06471DED0097A5F4 - - ToolbarConfiguration - xcode.toolbar.config.default.shortV3 - - - PerspectivesBarVisible - - ShelfIsVisible - - SourceDescription - file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' - StatusbarIsVisible - - TimeStamp - 0.0 - ToolbarDisplayMode - 1 - ToolbarIsVisible - - ToolbarSizeMode - 1 - Type - Perspectives - UpdateMessage - The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? - WindowJustification - 5 - WindowOrderList - - 8E01A8EF0DE51C830008BB35 - 1C78EAAD065D492600B07095 - 1CD10A99069EF8BA00B06720 - /Users/awt/xcodecapp-cocoa/xcodecapp-cocoa.xcodeproj - - WindowString - 545 -696 601 489 0 -800 1280 800 - WindowToolsV3 - - - FirstTimeWindowDisplayed - - Identifier - windowTool.build - IsVertical - - Layout - - - Dock - - - BecomeActive - - ContentConfiguration - - PBXProjectModuleGUID - 1CD0528F0623707200166675 - PBXProjectModuleLabel - AppController.m - StatusBarVisibility - - - GeometryConfiguration - - Frame - {{0, 0}, {892, 440}} - RubberWindowFrame - 18 -722 892 722 0 -800 1280 800 - - Module - PBXNavigatorGroup - Proportion - 440pt - - - ContentConfiguration - - PBXProjectModuleGUID - XCMainBuildResultsModuleGUID - PBXProjectModuleLabel - Build - XCBuildResultsTrigger_Collapse - 1021 - XCBuildResultsTrigger_Open - 1011 - - GeometryConfiguration - - Frame - {{0, 445}, {892, 236}} - RubberWindowFrame - 18 -722 892 722 0 -800 1280 800 - - Module - PBXBuildResultsModule - Proportion - 236pt - - - Proportion - 681pt - - - Name - Build Results - ServiceClasses - - PBXBuildResultsModule - - StatusbarIsVisible - - TableOfContents - - 8E01A8EF0DE51C830008BB35 - 8E480DF50E980A1F005A51A6 - 1CD0528F0623707200166675 - XCMainBuildResultsModuleGUID - - ToolbarConfiguration - xcode.toolbar.config.buildV3 - WindowString - 18 -722 892 722 0 -800 1280 800 - WindowToolGUID - 8E01A8EF0DE51C830008BB35 - WindowToolIsVisible - - - - FirstTimeWindowDisplayed - - Identifier - windowTool.debugger - IsVertical - - Layout - - - Dock - - - ContentConfiguration - - Debugger - - HorizontalSplitView - - _collapsingFrameDimension - 0.0 - _indexOfCollapsedView - 0 - _percentageOfCollapsedView - 0.0 - isCollapsed - yes - sizes - - {{0, 0}, {316, 203}} - {{316, 0}, {378, 203}} - - - VerticalSplitView - - _collapsingFrameDimension - 0.0 - _indexOfCollapsedView - 0 - _percentageOfCollapsedView - 0.0 - isCollapsed - yes - sizes - - {{0, 0}, {694, 203}} - {{0, 203}, {694, 178}} - - - - LauncherConfigVersion - 8 - PBXProjectModuleGUID - 1C162984064C10D400B95A72 - PBXProjectModuleLabel - Debug - GLUTExamples (Underwater) - - GeometryConfiguration - - DebugConsoleVisible - None - DebugConsoleWindowFrame - {{200, 200}, {500, 300}} - DebugSTDIOWindowFrame - {{200, 200}, {500, 300}} - Frame - {{0, 0}, {694, 381}} - PBXDebugSessionStackFrameViewKey - - DebugVariablesTableConfiguration - - Name - 120 - Value - 85 - Summary - 148 - - Frame - {{316, 0}, {378, 203}} - RubberWindowFrame - 429 -422 694 422 0 -800 1280 800 - - RubberWindowFrame - 429 -422 694 422 0 -800 1280 800 - - Module - PBXDebugSessionModule - Proportion - 381pt - - - Proportion - 381pt - - - Name - Debugger - ServiceClasses - - PBXDebugSessionModule - - StatusbarIsVisible - - TableOfContents - - 1CD10A99069EF8BA00B06720 - 8E480DF60E980A1F005A51A6 - 1C162984064C10D400B95A72 - 8E480DF70E980A1F005A51A6 - 8E480DF80E980A1F005A51A6 - 8E480DF90E980A1F005A51A6 - 8E480DFA0E980A1F005A51A6 - 8E480DFB0E980A1F005A51A6 - - ToolbarConfiguration - xcode.toolbar.config.debugV3 - WindowString - 429 -422 694 422 0 -800 1280 800 - WindowToolGUID - 1CD10A99069EF8BA00B06720 - WindowToolIsVisible - - - - Identifier - windowTool.find - Layout - - - Dock - - - Dock - - - ContentConfiguration - - PBXProjectModuleGUID - 1CDD528C0622207200134675 - PBXProjectModuleLabel - <No Editor> - PBXSplitModuleInNavigatorKey - - Split0 - - PBXProjectModuleGUID - 1CD0528D0623707200166675 - - SplitCount - 1 - - StatusBarVisibility - 1 - - GeometryConfiguration - - Frame - {{0, 0}, {781, 167}} - RubberWindowFrame - 62 385 781 470 0 0 1440 878 - - Module - PBXNavigatorGroup - Proportion - 781pt - - - Proportion - 50% - - - BecomeActive - 1 - ContentConfiguration - - PBXProjectModuleGUID - 1CD0528E0623707200166675 - PBXProjectModuleLabel - Project Find - - GeometryConfiguration - - Frame - {{8, 0}, {773, 254}} - RubberWindowFrame - 62 385 781 470 0 0 1440 878 - - Module - PBXProjectFindModule - Proportion - 50% - - - Proportion - 428pt - - - Name - Project Find - ServiceClasses - - PBXProjectFindModule - - StatusbarIsVisible - 1 - TableOfContents - - 1C530D57069F1CE1000CFCEE - 1C530D58069F1CE1000CFCEE - 1C530D59069F1CE1000CFCEE - 1CDD528C0622207200134675 - 1C530D5A069F1CE1000CFCEE - 1CE0B1FE06471DED0097A5F4 - 1CD0528E0623707200166675 - - WindowString - 62 385 781 470 0 0 1440 878 - WindowToolGUID - 1C530D57069F1CE1000CFCEE - WindowToolIsVisible - 0 - - - Identifier - MENUSEPARATOR - - - FirstTimeWindowDisplayed - - Identifier - windowTool.debuggerConsole - IsVertical - - Layout - - - Dock - - - BecomeActive - - ContentConfiguration - - PBXProjectModuleGUID - 1C78EAAC065D492600B07095 - PBXProjectModuleLabel - Debugger Console - - GeometryConfiguration - - Frame - {{0, 0}, {1696, 681}} - RubberWindowFrame - 109 222 1696 722 0 0 1920 1178 - - Module - PBXDebugCLIModule - Proportion - 681pt - - - Proportion - 681pt - - - Name - Debugger Console - ServiceClasses - - PBXDebugCLIModule - - StatusbarIsVisible - - TableOfContents - - 1C78EAAD065D492600B07095 - 8E480E040E980B9A005A51A6 - 1C78EAAC065D492600B07095 - - ToolbarConfiguration - xcode.toolbar.config.consoleV3 - WindowString - 109 222 1696 722 0 0 1920 1178 - WindowToolGUID - 1C78EAAD065D492600B07095 - WindowToolIsVisible - - - - Identifier - windowTool.snapshots - Layout - - - Dock - - - Module - XCSnapshotModule - Proportion - 100% - - - Proportion - 100% - - - Name - Snapshots - ServiceClasses - - XCSnapshotModule - - StatusbarIsVisible - Yes - ToolbarConfiguration - xcode.toolbar.config.snapshots - WindowString - 315 824 300 550 0 0 1440 878 - WindowToolIsVisible - Yes - - - Identifier - windowTool.scm - Layout - - - Dock - - - ContentConfiguration - - PBXProjectModuleGUID - 1C78EAB2065D492600B07095 - PBXProjectModuleLabel - <No Editor> - PBXSplitModuleInNavigatorKey - - Split0 - - PBXProjectModuleGUID - 1C78EAB3065D492600B07095 - - SplitCount - 1 - - StatusBarVisibility - 1 - - GeometryConfiguration - - Frame - {{0, 0}, {452, 0}} - RubberWindowFrame - 743 379 452 308 0 0 1280 1002 - - Module - PBXNavigatorGroup - Proportion - 0pt - - - BecomeActive - 1 - ContentConfiguration - - PBXProjectModuleGUID - 1CD052920623707200166675 - PBXProjectModuleLabel - SCM - - GeometryConfiguration - - ConsoleFrame - {{0, 259}, {452, 0}} - Frame - {{0, 7}, {452, 259}} - RubberWindowFrame - 743 379 452 308 0 0 1280 1002 - TableConfiguration - - Status - 30 - FileName - 199 - Path - 197.09500122070312 - - TableFrame - {{0, 0}, {452, 250}} - - Module - PBXCVSModule - Proportion - 262pt - - - Proportion - 266pt - - - Name - SCM - ServiceClasses - - PBXCVSModule - - StatusbarIsVisible - 1 - TableOfContents - - 1C78EAB4065D492600B07095 - 1C78EAB5065D492600B07095 - 1C78EAB2065D492600B07095 - 1CD052920623707200166675 - - ToolbarConfiguration - xcode.toolbar.config.scm - WindowString - 743 379 452 308 0 0 1280 1002 - - - Identifier - windowTool.breakpoints - IsVertical - 0 - Layout - - - Dock - - - BecomeActive - 1 - ContentConfiguration - - PBXBottomSmartGroupGIDs - - 1C77FABC04509CD000000102 - - PBXProjectModuleGUID - 1CE0B1FE06471DED0097A5F4 - PBXProjectModuleLabel - Files - PBXProjectStructureProvided - no - PBXSmartGroupTreeModuleColumnData - - PBXSmartGroupTreeModuleColumnWidthsKey - - 168 - - PBXSmartGroupTreeModuleColumnsKey_v4 - - MainColumn - - - PBXSmartGroupTreeModuleOutlineStateKey_v7 - - PBXSmartGroupTreeModuleOutlineStateExpansionKey - - 1C77FABC04509CD000000102 - - PBXSmartGroupTreeModuleOutlineStateSelectionKey - - - 0 - - - PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 0}, {168, 350}} - - PBXTopSmartGroupGIDs - - XCIncludePerspectivesSwitch - 0 - - GeometryConfiguration - - Frame - {{0, 0}, {185, 368}} - GroupTreeTableConfiguration - - MainColumn - 168 - - RubberWindowFrame - 315 424 744 409 0 0 1440 878 - - Module - PBXSmartGroupTreeModule - Proportion - 185pt - - - ContentConfiguration - - PBXProjectModuleGUID - 1CA1AED706398EBD00589147 - PBXProjectModuleLabel - Detail - - GeometryConfiguration - - Frame - {{190, 0}, {554, 368}} - RubberWindowFrame - 315 424 744 409 0 0 1440 878 - - Module - XCDetailModule - Proportion - 554pt - - - Proportion - 368pt - - - MajorVersion - 3 - MinorVersion - 0 - Name - Breakpoints - ServiceClasses - - PBXSmartGroupTreeModule - XCDetailModule - - StatusbarIsVisible - 1 - TableOfContents - - 1CDDB66807F98D9800BB5817 - 1CDDB66907F98D9800BB5817 - 1CE0B1FE06471DED0097A5F4 - 1CA1AED706398EBD00589147 - - ToolbarConfiguration - xcode.toolbar.config.breakpointsV3 - WindowString - 315 424 744 409 0 0 1440 878 - WindowToolGUID - 1CDDB66807F98D9800BB5817 - WindowToolIsVisible - 1 - - - Identifier - windowTool.debugAnimator - Layout - - - Dock - - - Module - PBXNavigatorGroup - Proportion - 100% - - - Proportion - 100% - - - Name - Debug Visualizer - ServiceClasses - - PBXNavigatorGroup - - StatusbarIsVisible - 1 - ToolbarConfiguration - xcode.toolbar.config.debugAnimatorV3 - WindowString - 100 100 700 500 0 0 1280 1002 - - - Identifier - windowTool.bookmarks - Layout - - - Dock - - - Module - PBXBookmarksModule - Proportion - 100% - - - Proportion - 100% - - - Name - Bookmarks - ServiceClasses - - PBXBookmarksModule - - StatusbarIsVisible - 0 - WindowString - 538 42 401 187 0 0 1280 1002 - - - Identifier - windowTool.projectFormatConflicts - Layout - - - Dock - - - Module - XCProjectFormatConflictsModule - Proportion - 100% - - - Proportion - 100% - - - Name - Project Format Conflicts - ServiceClasses - - XCProjectFormatConflictsModule - - StatusbarIsVisible - 0 - WindowContentMinSize - 450 300 - WindowString - 50 850 472 307 0 0 1440 877 - - - Identifier - windowTool.classBrowser - Layout - - - Dock - - - BecomeActive - 1 - ContentConfiguration - - OptionsSetName - Hierarchy, all classes - PBXProjectModuleGUID - 1CA6456E063B45B4001379D8 - PBXProjectModuleLabel - Class Browser - NSObject - - GeometryConfiguration - - ClassesFrame - {{0, 0}, {374, 96}} - ClassesTreeTableConfiguration - - PBXClassNameColumnIdentifier - 208 - PBXClassBookColumnIdentifier - 22 - - Frame - {{0, 0}, {630, 331}} - MembersFrame - {{0, 105}, {374, 395}} - MembersTreeTableConfiguration - - PBXMemberTypeIconColumnIdentifier - 22 - PBXMemberNameColumnIdentifier - 216 - PBXMemberTypeColumnIdentifier - 97 - PBXMemberBookColumnIdentifier - 22 - - PBXModuleWindowStatusBarHidden2 - 1 - RubberWindowFrame - 385 179 630 352 0 0 1440 878 - - Module - PBXClassBrowserModule - Proportion - 332pt - - - Proportion - 332pt - - - Name - Class Browser - ServiceClasses - - PBXClassBrowserModule - - StatusbarIsVisible - 0 - TableOfContents - - 1C0AD2AF069F1E9B00FABCE6 - 1C0AD2B0069F1E9B00FABCE6 - 1CA6456E063B45B4001379D8 - - ToolbarConfiguration - xcode.toolbar.config.classbrowser - WindowString - 385 179 630 352 0 0 1440 878 - WindowToolGUID - 1C0AD2AF069F1E9B00FABCE6 - WindowToolIsVisible - 0 - - - Identifier - windowTool.refactoring - IncludeInToolsMenu - 0 - Layout - - - Dock - - - BecomeActive - 1 - GeometryConfiguration - - Frame - {0, 0}, {500, 335} - RubberWindowFrame - {0, 0}, {500, 335} - - Module - XCRefactoringModule - Proportion - 100% - - - Proportion - 100% - - - Name - Refactoring - ServiceClasses - - XCRefactoringModule - - WindowString - 200 200 500 356 0 0 1920 1200 - - - - diff --git a/Tools/XcodeCapp/XcodeCapp.xcodeproj/awt.pbxuser b/Tools/XcodeCapp/XcodeCapp.xcodeproj/awt.pbxuser deleted file mode 100644 index f03c50e2b..000000000 --- a/Tools/XcodeCapp/XcodeCapp.xcodeproj/awt.pbxuser +++ /dev/null @@ -1,152 +0,0 @@ -// !$*UTF8*$! -{ - 29B97313FDCFA39411CA2CEA /* Project object */ = { - activeArchitecture = i386; - activeBuildConfigurationName = Debug; - activeExecutable = 8E01A8CD0DE519E70008BB35 /* xcodecapp-cocoa */; - activeTarget = 8D1107260486CEB800E47090 /* xcodecapp-cocoa */; - addToTargets = ( - 8D1107260486CEB800E47090 /* xcodecapp-cocoa */, - ); - breakpoints = ( - 8EF107B90DFCF23200C52EB1 /* AppController.m:30 */, - 8EF107CA0DFCF4A100C52EB1 /* AppController.m:62 */, - ); - codeSenseManager = 8E01A8DC0DE51A060008BB35 /* Code sense */; - executables = ( - 8E01A8CD0DE519E70008BB35 /* xcodecapp-cocoa */, - ); - perUserDictionary = { - PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { - PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; - PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; - PBXFileTableDataSourceColumnWidthsKey = ( - 20, - 71, - 20, - 48, - 43, - 43, - 20, - ); - PBXFileTableDataSourceColumnsKey = ( - PBXFileDataSource_FiletypeID, - PBXFileDataSource_Filename_ColumnID, - PBXFileDataSource_Built_ColumnID, - PBXFileDataSource_ObjectSize_ColumnID, - PBXFileDataSource_Errors_ColumnID, - PBXFileDataSource_Warnings_ColumnID, - PBXFileDataSource_Target_ColumnID, - ); - }; - PBXPerProjectTemplateStateSaveDate = 244845075; - PBXWorkspaceStateSaveDate = 244845075; - }; - sourceControlManager = 8E01A8DB0DE51A060008BB35 /* Source Control */; - userBuildSettings = { - }; - }; - 29B97316FDCFA39411CA2CEA /* main.m */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1176, 392}}"; - sepNavSelRange = "{818, 0}"; - sepNavVisRange = "{297, 521}"; - }; - }; - 8D1107260486CEB800E47090 /* xcodecapp-cocoa */ = { - activeExec = 0; - executables = ( - 8E01A8CD0DE519E70008BB35 /* xcodecapp-cocoa */, - ); - }; - 8E01A8CD0DE519E70008BB35 /* xcodecapp-cocoa */ = { - isa = PBXExecutable; - activeArgIndices = ( - ); - argumentStrings = ( - ); - autoAttachOnCrash = 1; - breakpointsEnabled = 0; - configStateDict = { - }; - customDataFormattersEnabled = 1; - debuggerPlugin = GDBDebugging; - disassemblyDisplayState = 0; - dylibVariantSuffix = ""; - enableDebugStr = 1; - environmentEntries = ( - ); - executableSystemSymbolLevel = 0; - executableUserSymbolLevel = 0; - libgmallocEnabled = 0; - name = xcodecapp-cocoa; - savedGlobals = { - }; - sourceDirectories = ( - ); - variableFormatDictionary = { - "*eventIds-long long unsigned int-mycallback" = 3; - }; - }; - 8E01A8DB0DE51A060008BB35 /* Source Control */ = { - isa = PBXSourceControlManager; - fallbackIsa = XCSourceControlManager; - isSCMEnabled = 0; - scmConfiguration = { - }; - }; - 8E01A8DC0DE51A060008BB35 /* Code sense */ = { - isa = PBXCodeSenseManager; - indexTemplatePath = ""; - }; - 8E01A91D0DE9EED20008BB35 /* AppController.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {692, 280}}"; - sepNavSelRange = "{234, 37}"; - sepNavVisRange = "{146, 185}"; - sepNavWindowFrame = "{{112, 264}, {1441, 774}}"; - }; - }; - 8E01A91E0DE9EED20008BB35 /* AppController.m */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {692, 2324}}"; - sepNavSelRange = "{4949, 0}"; - sepNavVisRange = "{3760, 551}"; - sepNavWindowFrame = "{{15, -1}, {1441, 774}}"; - }; - }; - 8EF107B90DFCF23200C52EB1 /* AppController.m:30 */ = { - isa = PBXFileBreakpoint; - actions = ( - ); - breakpointStyle = 0; - continueAfterActions = 0; - countType = 0; - delayBeforeContinue = 0; - fileReference = 8E01A91E0DE9EED20008BB35 /* AppController.m */; - functionName = "-awakeFromNib"; - hitCount = 1; - ignoreCount = 0; - lineNumber = 30; - location = xcodecapp-cocoa; - modificationTime = 234708321.122562; - state = 2; - }; - 8EF107CA0DFCF4A100C52EB1 /* AppController.m:62 */ = { - isa = PBXFileBreakpoint; - actions = ( - ); - breakpointStyle = 0; - continueAfterActions = 0; - countType = 0; - delayBeforeContinue = 0; - fileReference = 8E01A91E0DE9EED20008BB35 /* AppController.m */; - functionName = "mycallback()"; - hitCount = 0; - ignoreCount = 0; - lineNumber = 62; - location = xcodecapp-cocoa; - modificationTime = 234708306.739971; - state = 2; - }; -} diff --git a/Tools/XcodeCapp/XcodeCapp.xcodeproj/project.pbxproj b/Tools/XcodeCapp/XcodeCapp.xcodeproj/project.pbxproj index 338a5e36d..67b152a26 100644 --- a/Tools/XcodeCapp/XcodeCapp.xcodeproj/project.pbxproj +++ b/Tools/XcodeCapp/XcodeCapp.xcodeproj/project.pbxproj @@ -7,419 +7,346 @@ objects = { /* Begin PBXBuildFile section */ - 0218442515D32B5D00A782B8 /* pbxprojModifier.py in Resources */ = {isa = PBXBuildFile; fileRef = 0218442415D32B5D00A782B8 /* pbxprojModifier.py */; }; - 022BCEA71468632000B72910 /* project.pbxproj.sample in Resources */ = {isa = PBXBuildFile; fileRef = 022BCEA61468632000B72910 /* project.pbxproj.sample */; }; - 024A041413699DD400DCBE4D /* parser.j in Resources */ = {isa = PBXBuildFile; fileRef = 024A041113699D6800DCBE4D /* parser.j */; }; - 026F3B6213866B0B00EE5B83 /* xcodecapp-icon-inactive.png in Resources */ = {isa = PBXBuildFile; fileRef = 026F3B6113866B0B00EE5B83 /* xcodecapp-icon-inactive.png */; }; - 026F3B6513866E7D00EE5B83 /* xcodecapp-icon-active.png in Resources */ = {isa = PBXBuildFile; fileRef = 026F3B6413866E7D00EE5B83 /* xcodecapp-icon-active.png */; }; - 027D999B13696A7000D3DB13 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; }; - 027D999C13696A7000D3DB13 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; - 027D999E13696A7000D3DB13 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; - 027D999F13696A7000D3DB13 /* AppController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E01A91E0DE9EED20008BB35 /* AppController.m */; }; - 027D99A113696A7000D3DB13 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; - 027D99A213696A7000D3DB13 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E01A8DD0DE51A7C0008BB35 /* CoreServices.framework */; }; - 027FE49D1462D74C00B1AB92 /* TNXCodeCapp.m in Sources */ = {isa = PBXBuildFile; fileRef = 027FE49C1462D74C00B1AB92 /* TNXCodeCapp.m */; }; - 027FE4BA1462F64E00B1AB92 /* xcodecapp-icon-working.png in Resources */ = {isa = PBXBuildFile; fileRef = 027FE4B91462F64E00B1AB92 /* xcodecapp-icon-working.png */; }; - 027FE4BD1462F7EB00B1AB92 /* FSEventCallback.m in Sources */ = {isa = PBXBuildFile; fileRef = 027FE4BC1462F7EB00B1AB92 /* FSEventCallback.m */; }; - 0289AC9414668CAF003CD975 /* XcodeCapp.icns in Resources */ = {isa = PBXBuildFile; fileRef = 0289AC9314668CAF003CD975 /* XcodeCapp.icns */; }; - 0294F09315D345A500840547 /* mod_pbxproj.py in Resources */ = {isa = PBXBuildFile; fileRef = 0294F09215D345A500840547 /* mod_pbxproj.py */; }; - 02998CEB1369BF7D006C73DB /* Growl Registration Ticket.growlRegDict in Resources */ = {isa = PBXBuildFile; fileRef = 02998CEA1369BF7D006C73DB /* Growl Registration Ticket.growlRegDict */; }; - 02998CF71369C339006C73DB /* Growl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02998CF61369C339006C73DB /* Growl.framework */; }; - 02998CF91369C38A006C73DB /* Growl.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 02998CF61369C339006C73DB /* Growl.framework */; }; - 02B1C8D816B25C74003C6E82 /* TNErrorDataView.m in Sources */ = {isa = PBXBuildFile; fileRef = 02B1C8D716B25C74003C6E82 /* TNErrorDataView.m */; }; - 4E2D0D01154840B400475C01 /* help.rtfd in Resources */ = {isa = PBXBuildFile; fileRef = 4E2D0D00154840B400475C01 /* help.rtfd */; }; - 4E2D0D03154840BC00475C01 /* help.rtfd in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4E2D0D00154840B400475C01 /* help.rtfd */; }; - 651DAE1F13B0CAB900ECA3F0 /* PRHEmptyGrowlDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 651DAE1D13B0CAB900ECA3F0 /* PRHEmptyGrowlDelegate.m */; }; + 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 */; }; + E164FDE91720E77100263CE3 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = E164FDE71720E77100263CE3 /* MainMenu.xib */; }; + E164FDF51720EBC100263CE3 /* AppController.m in Sources */ = {isa = PBXBuildFile; fileRef = E164FDF41720EBC100263CE3 /* AppController.m */; }; + E164FDF71720EBD600263CE3 /* Growl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E164FDF61720EBD600263CE3 /* Growl.framework */; }; + E164FDFF1720EC5B00263CE3 /* TNXcodeCapp.m in Sources */ = {isa = PBXBuildFile; fileRef = E164FDFB1720EC5B00263CE3 /* TNXcodeCapp.m */; }; + 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 */; }; + E17A822D172700B90095CD83 /* XcodeCapp.iconset in Resources */ = {isa = PBXBuildFile; fileRef = E17A822C172700B90095CD83 /* XcodeCapp.iconset */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ - 02998CF81369C383006C73DB /* CopyFiles */ = { + E164FE201720F54800263CE3 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - 02998CF91369C38A006C73DB /* Growl.framework in CopyFiles */, - 4E2D0D03154840BC00475C01 /* help.rtfd in CopyFiles */, + E164FE211720F55600263CE3 /* Growl.framework in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 0218442415D32B5D00A782B8 /* pbxprojModifier.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = pbxprojModifier.py; sourceTree = ""; }; - 022BCEA61468632000B72910 /* project.pbxproj.sample */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = project.pbxproj.sample; sourceTree = ""; }; - 024A041113699D6800DCBE4D /* parser.j */ = {isa = PBXFileReference; explicitFileType = sourcecode.javascript; fileEncoding = 4; path = parser.j; sourceTree = ""; }; - 026F3B6113866B0B00EE5B83 /* xcodecapp-icon-inactive.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "xcodecapp-icon-inactive.png"; sourceTree = ""; }; - 026F3B6413866E7D00EE5B83 /* xcodecapp-icon-active.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "xcodecapp-icon-active.png"; sourceTree = ""; }; - 027D9989136969DD00D3DB13 /* XcodeCapp.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XcodeCapp.pch; sourceTree = ""; }; - 027D99A613696A7000D3DB13 /* XcodeCapp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XcodeCapp.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 027FE49B1462D74C00B1AB92 /* TNXCodeCapp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TNXCodeCapp.h; sourceTree = ""; }; - 027FE49C1462D74C00B1AB92 /* TNXCodeCapp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TNXCodeCapp.m; sourceTree = ""; }; - 027FE4B91462F64E00B1AB92 /* xcodecapp-icon-working.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "xcodecapp-icon-working.png"; sourceTree = ""; }; - 027FE4BB1462F7D600B1AB92 /* FSEventCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSEventCallback.h; sourceTree = ""; }; - 027FE4BC1462F7EB00B1AB92 /* FSEventCallback.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSEventCallback.m; sourceTree = ""; }; - 0289AC9314668CAF003CD975 /* XcodeCapp.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = XcodeCapp.icns; sourceTree = ""; }; - 0294F09215D345A500840547 /* mod_pbxproj.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = mod_pbxproj.py; sourceTree = ""; }; - 02998CEA1369BF7D006C73DB /* Growl Registration Ticket.growlRegDict */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Growl Registration Ticket.growlRegDict"; sourceTree = ""; }; - 02998CF61369C339006C73DB /* Growl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Growl.framework; sourceTree = ""; }; - 02B1C8D616B25C74003C6E82 /* TNErrorDataView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TNErrorDataView.h; sourceTree = ""; }; - 02B1C8D716B25C74003C6E82 /* TNErrorDataView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TNErrorDataView.m; sourceTree = ""; }; - 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; - 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = ""; }; - 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; - 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; - 4E2D0D00154840B400475C01 /* help.rtfd */ = {isa = PBXFileReference; lastKnownFileType = wrapper.rtfd; path = help.rtfd; sourceTree = ""; }; - 651DAE1C13B0CAB900ECA3F0 /* PRHEmptyGrowlDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.objj.h; path = PRHEmptyGrowlDelegate.h; sourceTree = ""; }; - 651DAE1D13B0CAB900ECA3F0 /* PRHEmptyGrowlDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PRHEmptyGrowlDelegate.m; sourceTree = ""; }; - 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 8E01A8DD0DE51A7C0008BB35 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = ""; }; - 8E01A91D0DE9EED20008BB35 /* AppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppController.h; sourceTree = ""; }; - 8E01A91E0DE9EED20008BB35 /* AppController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AppController.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; - E12AA95F14637828006F55D6 /* macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.objj.h; path = macros.h; 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 = ""; }; + E132ED9A1724B71D00D870AE /* AppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppController.h; sourceTree = ""; }; + E164FDCF1720E77100263CE3 /* XcodeCapp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XcodeCapp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + E164FDD21720E77100263CE3 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + E164FDD51720E77100263CE3 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + E164FDD61720E77100263CE3 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + E164FDD71720E77100263CE3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + E164FDDA1720E77100263CE3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E164FDDE1720E77100263CE3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + E164FDE01720E77100263CE3 /* XcodeCapp-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XcodeCapp-Prefix.pch"; sourceTree = ""; }; + E164FDE81720E77100263CE3 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; + E164FDEF1720E7FA00263CE3 /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + E164FDF01720E7FA00263CE3 /* Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + E164FDF41720EBC100263CE3 /* AppController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppController.m; sourceTree = ""; }; + E164FDF61720EBD600263CE3 /* Growl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Growl.framework; path = XcodeCapp/Growl.framework; sourceTree = SOURCE_ROOT; }; + E164FDFB1720EC5B00263CE3 /* TNXcodeCapp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TNXcodeCapp.m; sourceTree = ""; }; + E164FDFD1720EC5B00263CE3 /* UserDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserDefaults.m; sourceTree = ""; }; + E164FE051720ED4500263CE3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = XcodeCapp/en.lproj/InfoPlist.strings; sourceTree = ""; }; + E164FE081720F26C00263CE3 /* help.rtfd */ = {isa = PBXFileReference; lastKnownFileType = wrapper.rtfd; name = help.rtfd; path = Resources/help.rtfd; sourceTree = ""; }; + E164FE131720F40400263CE3 /* mod_pbxproj.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = mod_pbxproj.py; sourceTree = ""; }; + E164FE141720F40400263CE3 /* pbxprojModifier.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = pbxprojModifier.py; sourceTree = ""; }; + E164FE171720F44B00263CE3 /* parser.j */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = parser.j; sourceTree = ""; }; + E164FE191720F49A00263CE3 /* Growl Registration Ticket.growlRegDict */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Growl Registration Ticket.growlRegDict"; sourceTree = ""; }; + E164FE1D1720F50100263CE3 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; + E164FE2A172188F300263CE3 /* project.pbxproj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.pbxproject; name = project.pbxproj; path = Resources/project.pbxproj; sourceTree = ""; }; + 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 = ""; }; + E17A822C172700B90095CD83 /* XcodeCapp.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; name = XcodeCapp.iconset; path = Resources/XcodeCapp.iconset; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 027D99A013696A7000D3DB13 /* Frameworks */ = { + E164FDCC1720E77100263CE3 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 027D99A113696A7000D3DB13 /* Cocoa.framework in Frameworks */, - 027D99A213696A7000D3DB13 /* CoreServices.framework in Frameworks */, - 02998CF71369C339006C73DB /* Growl.framework in Frameworks */, + E164FDD31720E77100263CE3 /* Cocoa.framework in Frameworks */, + E164FE1F1720F51E00263CE3 /* CoreServices.framework in Frameworks */, + E164FDF71720EBD600263CE3 /* Growl.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 080E96DDFE201D6D7F000001 /* Classes */ = { + E164FDC61720E77100263CE3 = { isa = PBXGroup; children = ( - 651DAE1C13B0CAB900ECA3F0 /* PRHEmptyGrowlDelegate.h */, - 651DAE1D13B0CAB900ECA3F0 /* PRHEmptyGrowlDelegate.m */, - 02B1C8D616B25C74003C6E82 /* TNErrorDataView.h */, - 02B1C8D716B25C74003C6E82 /* TNErrorDataView.m */, - 8E01A91D0DE9EED20008BB35 /* AppController.h */, - 8E01A91E0DE9EED20008BB35 /* AppController.m */, - 027FE49B1462D74C00B1AB92 /* TNXCodeCapp.h */, - 027FE49C1462D74C00B1AB92 /* TNXCodeCapp.m */, - 027FE4BB1462F7D600B1AB92 /* FSEventCallback.h */, - 027FE4BC1462F7EB00B1AB92 /* FSEventCallback.m */, + E164FDD81720E77100263CE3 /* XcodeCapp */, + E164FDD11720E77100263CE3 /* Frameworks */, + E164FDD01720E77100263CE3 /* Products */, ); - name = Classes; sourceTree = ""; }; - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + E164FDD01720E77100263CE3 /* Products */ = { isa = PBXGroup; children = ( - 8E01A8DD0DE51A7C0008BB35 /* CoreServices.framework */, - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, - ); - name = "Linked Frameworks"; - sourceTree = ""; - }; - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - 29B97324FDCFA39411CA2CEA /* AppKit.framework */, - 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */, - 29B97325FDCFA39411CA2CEA /* Foundation.framework */, - ); - name = "Other Frameworks"; - sourceTree = ""; - }; - 19C28FACFE9D520D11CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 027D99A613696A7000D3DB13 /* XcodeCapp.app */, + E164FDCF1720E77100263CE3 /* XcodeCapp.app */, ); name = Products; sourceTree = ""; }; - 29B97314FDCFA39411CA2CEA /* xcodecapp-cocoa */ = { + E164FDD11720E77100263CE3 /* Frameworks */ = { isa = PBXGroup; children = ( - 080E96DDFE201D6D7F000001 /* Classes */, - 29B97315FDCFA39411CA2CEA /* Other Sources */, - 29B97317FDCFA39411CA2CEA /* Resources */, - 29B97323FDCFA39411CA2CEA /* Frameworks */, - 19C28FACFE9D520D11CA2CBB /* Products */, + E164FDD21720E77100263CE3 /* Cocoa.framework */, + E164FE1D1720F50100263CE3 /* CoreServices.framework */, + E164FDF61720EBD600263CE3 /* Growl.framework */, + E164FDD41720E77100263CE3 /* Other Frameworks */, ); - name = "xcodecapp-cocoa"; + name = Frameworks; sourceTree = ""; }; - 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + E164FDD41720E77100263CE3 /* Other Frameworks */ = { isa = PBXGroup; children = ( - 027D9989136969DD00D3DB13 /* XcodeCapp.pch */, - 29B97316FDCFA39411CA2CEA /* main.m */, - E12AA95F14637828006F55D6 /* macros.h */, + E164FDD51720E77100263CE3 /* AppKit.framework */, + E164FDD61720E77100263CE3 /* CoreData.framework */, + E164FDD71720E77100263CE3 /* Foundation.framework */, ); - name = "Other Sources"; + name = "Other Frameworks"; sourceTree = ""; }; - 29B97317FDCFA39411CA2CEA /* Resources */ = { + E164FDD81720E77100263CE3 /* XcodeCapp */ = { isa = PBXGroup; children = ( - 0294F09215D345A500840547 /* mod_pbxproj.py */, - 0218442415D32B5D00A782B8 /* pbxprojModifier.py */, - 4E2D0D00154840B400475C01 /* help.rtfd */, - 022BCEA61468632000B72910 /* project.pbxproj.sample */, - 027FE4B91462F64E00B1AB92 /* xcodecapp-icon-working.png */, - 026F3B6413866E7D00EE5B83 /* xcodecapp-icon-active.png */, - 026F3B6113866B0B00EE5B83 /* xcodecapp-icon-inactive.png */, - 024A041113699D6800DCBE4D /* parser.j */, - 8D1107310486CEB800E47090 /* Info.plist */, - 0289AC9314668CAF003CD975 /* XcodeCapp.icns */, - 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, - 29B97318FDCFA39411CA2CEA /* MainMenu.nib */, - 02998CEA1369BF7D006C73DB /* Growl Registration Ticket.growlRegDict */, + E164FDF41720EBC100263CE3 /* AppController.m */, + E132ED9A1724B71D00D870AE /* AppController.h */, + E164FDFB1720EC5B00263CE3 /* TNXcodeCapp.m */, + E132ED991724B71600D870AE /* TNXCodeCapp.h */, + E132ED941724B64C00D870AE /* FSEventCallback.m */, + E132ED961724B6C400D870AE /* FSEventCallback.h */, + E164FDFD1720EC5B00263CE3 /* UserDefaults.m */, + E164FDEF1720E7FA00263CE3 /* Debug.xcconfig */, + E164FDF01720E7FA00263CE3 /* Release.xcconfig */, + E164FE121720F3E100263CE3 /* Scripts */, + E164FE071720F25400263CE3 /* Resources */, + E164FDD91720E77100263CE3 /* Supporting Files */, + ); + path = XcodeCapp; + sourceTree = ""; + }; + E164FDD91720E77100263CE3 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + E164FDDA1720E77100263CE3 /* Info.plist */, + E164FE041720ED4400263CE3 /* InfoPlist.strings */, + E164FDDE1720E77100263CE3 /* main.m */, + E164FDE01720E77100263CE3 /* XcodeCapp-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + E164FE071720F25400263CE3 /* Resources */ = { + isa = PBXGroup; + children = ( + E17A822C172700B90095CD83 /* XcodeCapp.iconset */, + E164FE2C1721A34900263CE3 /* icon-active.png */, + E164FE2D1721A34900263CE3 /* icon-inactive.png */, + E164FE2E1721A34900263CE3 /* icon-working.png */, + E164FDE71720E77100263CE3 /* MainMenu.xib */, + E164FE2A172188F300263CE3 /* project.pbxproj */, + E164FE191720F49A00263CE3 /* Growl Registration Ticket.growlRegDict */, + E164FE081720F26C00263CE3 /* help.rtfd */, ); name = Resources; sourceTree = ""; }; - 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + E164FE121720F3E100263CE3 /* Scripts */ = { isa = PBXGroup; children = ( - 02998CF61369C339006C73DB /* Growl.framework */, - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, + E164FE141720F40400263CE3 /* pbxprojModifier.py */, + E164FE131720F40400263CE3 /* mod_pbxproj.py */, + E164FE171720F44B00263CE3 /* parser.j */, ); - name = Frameworks; + path = Scripts; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 027D999913696A7000D3DB13 /* XcodeCapp */ = { + E164FDCE1720E77100263CE3 /* XcodeCapp */ = { isa = PBXNativeTarget; - buildConfigurationList = 027D99A313696A7000D3DB13 /* Build configuration list for PBXNativeTarget "XcodeCapp" */; + buildConfigurationList = E164FDEC1720E77100263CE3 /* Build configuration list for PBXNativeTarget "XcodeCapp" */; buildPhases = ( - 024699001602C04A00F0AE43 /* ShellScript */, - 027D999A13696A7000D3DB13 /* Resources */, - 027D999D13696A7000D3DB13 /* Sources */, - 02998CF81369C383006C73DB /* CopyFiles */, - 027D99A013696A7000D3DB13 /* Frameworks */, + E164FDCB1720E77100263CE3 /* Sources */, + E164FDCC1720E77100263CE3 /* Frameworks */, + E164FDCD1720E77100263CE3 /* Resources */, + E164FE201720F54800263CE3 /* CopyFiles */, ); buildRules = ( ); dependencies = ( ); name = XcodeCapp; - productInstallPath = "$(HOME)/Applications"; - productName = "xcodecapp-cocoa"; - productReference = 027D99A613696A7000D3DB13 /* XcodeCapp.app */; + productName = XcodeCapp; + productReference = E164FDCF1720E77100263CE3 /* XcodeCapp.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ - 29B97313FDCFA39411CA2CEA /* Project object */ = { + E164FDC71720E77100263CE3 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0440; + LastUpgradeCheck = 0460; + ORGANIZATIONNAME = "Cappuccino Project"; }; - buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "XcodeCapp" */; + buildConfigurationList = E164FDCA1720E77100263CE3 /* Build configuration list for PBXProject "XcodeCapp" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; - hasScannedForEncodings = 1; + hasScannedForEncodings = 0; knownRegions = ( en, ); - mainGroup = 29B97314FDCFA39411CA2CEA /* xcodecapp-cocoa */; + mainGroup = E164FDC61720E77100263CE3; + productRefGroup = E164FDD01720E77100263CE3 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - 027D999913696A7000D3DB13 /* XcodeCapp */, + E164FDCE1720E77100263CE3 /* XcodeCapp */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 027D999A13696A7000D3DB13 /* Resources */ = { + E164FDCD1720E77100263CE3 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 027D999B13696A7000D3DB13 /* MainMenu.nib in Resources */, - 027D999C13696A7000D3DB13 /* InfoPlist.strings in Resources */, - 024A041413699DD400DCBE4D /* parser.j in Resources */, - 02998CEB1369BF7D006C73DB /* Growl Registration Ticket.growlRegDict in Resources */, - 026F3B6213866B0B00EE5B83 /* xcodecapp-icon-inactive.png in Resources */, - 026F3B6513866E7D00EE5B83 /* xcodecapp-icon-active.png in Resources */, - 027FE4BA1462F64E00B1AB92 /* xcodecapp-icon-working.png in Resources */, - 0289AC9414668CAF003CD975 /* XcodeCapp.icns in Resources */, - 022BCEA71468632000B72910 /* project.pbxproj.sample in Resources */, - 4E2D0D01154840B400475C01 /* help.rtfd in Resources */, - 0218442515D32B5D00A782B8 /* pbxprojModifier.py in Resources */, - 0294F09315D345A500840547 /* mod_pbxproj.py in Resources */, + 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 */, + 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 */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - 024699001602C04A00F0AE43 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/*.m", - "$(SRCROOT)/*.h", - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /usr/bin/perl; - shellScript = "#!/usr/bin/perl\n\nwhile (<>) {\n s/\\s+$//;\n print \"$_\\n\";\n}"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ - 027D999D13696A7000D3DB13 /* Sources */ = { + E164FDCB1720E77100263CE3 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 027D999E13696A7000D3DB13 /* main.m in Sources */, - 027D999F13696A7000D3DB13 /* AppController.m in Sources */, - 651DAE1F13B0CAB900ECA3F0 /* PRHEmptyGrowlDelegate.m in Sources */, - 027FE49D1462D74C00B1AB92 /* TNXCodeCapp.m in Sources */, - 027FE4BD1462F7EB00B1AB92 /* FSEventCallback.m in Sources */, - 02B1C8D816B25C74003C6E82 /* TNErrorDataView.m in Sources */, + E164FDDF1720E77100263CE3 /* main.m in Sources */, + E164FDF51720EBC100263CE3 /* AppController.m in Sources */, + E164FDFF1720EC5B00263CE3 /* TNXcodeCapp.m in Sources */, + E164FE001720EC5B00263CE3 /* UserDefaults.m in Sources */, + E132ED951724B64C00D870AE /* FSEventCallback.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ - 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { + E164FDE71720E77100263CE3 /* MainMenu.xib */ = { isa = PBXVariantGroup; children = ( - 089C165DFE840E0CC02AAC07 /* English */, + E164FDE81720E77100263CE3 /* en */, ); - name = InfoPlist.strings; + name = MainMenu.xib; sourceTree = ""; }; - 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = { + E164FE041720ED4400263CE3 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( - 29B97319FDCFA39411CA2CEA /* English */, + E164FE051720ED4500263CE3 /* en */, ); - name = MainMenu.nib; + name = InfoPlist.strings; + path = ..; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - 027D99A413696A7000D3DB13 /* Debug */ = { + E164FDEA1720E77100263CE3 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = E164FDEF1720E7FA00263CE3 /* Debug.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_ENABLE_OBJC_ARC = YES; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)\"", - ); - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_GC = unsupported; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = XcodeCapp.pch; - INFOPLIST_FILE = Info.plist; - INSTALL_PATH = /Applications; - MACOSX_DEPLOYMENT_TARGET = 10.6.8; - PRODUCT_NAME = XcodeCapp; }; name = Debug; }; - 027D99A513696A7000D3DB13 /* Release */ = { + E164FDEB1720E77100263CE3 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = E164FDF01720E7FA00263CE3 /* Release.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_ENABLE_OBJC_ARC = YES; - COMBINE_HIDPI_IMAGES = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)\"", - ); - GCC_ENABLE_OBJC_GC = unsupported; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = XcodeCapp.pch; - INFOPLIST_FILE = Info.plist; - INSTALL_PATH = /Applications; - MACOSX_DEPLOYMENT_TARGET = 10.6.8; - PRODUCT_NAME = XcodeCapp; }; name = Release; }; - C01FCF4F08A954540054247B /* Debug */ = { + E164FDED1720E77100263CE3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - FRAMEWORK_SEARCH_PATHS = ""; - GCC_ENABLE_OBJC_GC = required; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1"; - GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ""; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.5; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/XcodeCapp\"", + ); + MACOSX_DEPLOYMENT_TARGET = 10.6.8; }; name = Debug; }; - C01FCF5008A954540054247B /* Release */ = { + E164FDEE1720E77100263CE3 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - FRAMEWORK_SEARCH_PATHS = ""; - GCC_ENABLE_OBJC_GC = required; - GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = ""; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.5; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/XcodeCapp\"", + ); + MACOSX_DEPLOYMENT_TARGET = 10.6.8; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 027D99A313696A7000D3DB13 /* Build configuration list for PBXNativeTarget "XcodeCapp" */ = { + E164FDCA1720E77100263CE3 /* Build configuration list for PBXProject "XcodeCapp" */ = { isa = XCConfigurationList; buildConfigurations = ( - 027D99A413696A7000D3DB13 /* Debug */, - 027D99A513696A7000D3DB13 /* Release */, + E164FDEA1720E77100263CE3 /* Debug */, + E164FDEB1720E77100263CE3 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C01FCF4E08A954540054247B /* Build configuration list for PBXProject "XcodeCapp" */ = { + E164FDEC1720E77100263CE3 /* Build configuration list for PBXNativeTarget "XcodeCapp" */ = { isa = XCConfigurationList; buildConfigurations = ( - C01FCF4F08A954540054247B /* Debug */, - C01FCF5008A954540054247B /* Release */, + E164FDED1720E77100263CE3 /* Debug */, + E164FDEE1720E77100263CE3 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; - rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; + rootObject = E164FDC71720E77100263CE3 /* Project object */; } diff --git a/Tools/XcodeCapp/XcodeCapp.xcodeproj/project.xcworkspace/xcuserdata/Tonio.xcuserdatad/WorkspaceSettings.xcsettings b/Tools/XcodeCapp/XcodeCapp.xcodeproj/project.xcworkspace/xcuserdata/Tonio.xcuserdatad/WorkspaceSettings.xcsettings deleted file mode 100644 index 6ff33e603..000000000 --- a/Tools/XcodeCapp/XcodeCapp.xcodeproj/project.xcworkspace/xcuserdata/Tonio.xcuserdatad/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,10 +0,0 @@ - - - - - IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges - - IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges - - - diff --git a/Tools/XcodeCapp/XcodeCapp.xcodeproj/xcuserdata/Tonio.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist b/Tools/XcodeCapp/XcodeCapp.xcodeproj/xcuserdata/Tonio.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist deleted file mode 100644 index 05301bc25..000000000 --- a/Tools/XcodeCapp/XcodeCapp.xcodeproj/xcuserdata/Tonio.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/Tools/XcodeCapp/XcodeCapp.xcodeproj/xcuserdata/Tonio.xcuserdatad/xcschemes/xcschememanagement.plist b/Tools/XcodeCapp/XcodeCapp.xcodeproj/xcuserdata/Tonio.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 202513f40..000000000 --- a/Tools/XcodeCapp/XcodeCapp.xcodeproj/xcuserdata/Tonio.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,42 +0,0 @@ - - - - - SchemeUserState - - XcodeCapp Debug.xcscheme - - orderHint - 0 - - XcodeCapp Release.xcscheme - - orderHint - 1 - - XcodeCapp.xcscheme - - orderHint - 0 - - - SuppressBuildableAutocreation - - 027D998A13696A0700D3DB13 - - primary - - - 027D999913696A7000D3DB13 - - primary - - - 8D1107260486CEB800E47090 - - primary - - - - - diff --git a/Tools/XcodeCapp/XcodeCapp/AppController.h b/Tools/XcodeCapp/XcodeCapp/AppController.h new file mode 100644 index 000000000..82d49e362 --- /dev/null +++ b/Tools/XcodeCapp/XcodeCapp/AppController.h @@ -0,0 +1,48 @@ +/* + * This file is a part of program XcodeCapp + * Copyright (C) 2011 Antoine Mercadal () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import +#import + +#import "TNXcodeCapp.h" + +@interface AppController : NSObject + +@property (strong) IBOutlet NSMenu *statusMenu; +@property (assign) IBOutlet NSMenuItem *menuItemHistory; +@property (assign) IBOutlet NSMenuItem *menuItemOpenInXcode; +@property (assign) IBOutlet NSMenuItem *menuItemListen; + +@property (strong) IBOutlet NSPanel *aboutWindow; +@property (strong) IBOutlet NSWindow *preferencesWindow; + +@property (strong) IBOutlet NSWindow *helpWindow; +@property (assign) IBOutlet NSTextView *helpTextView; + +@property (strong) IBOutlet NSUserDefaultsController *preferencesController; +@property (strong) IBOutlet TNXcodeCapp *xcc; + ++ (AppController *)sharedAppController; + +- (IBAction)listenToProject:(id)aSender; +- (IBAction)openInXcode:(id)aSender; +- (IBAction)openHelp:(id)aSender; +- (IBAction)openAbout:(id)aSender; + +@end + diff --git a/Tools/XcodeCapp/XcodeCapp/AppController.m b/Tools/XcodeCapp/XcodeCapp/AppController.m new file mode 100644 index 000000000..ee8f9d6c0 --- /dev/null +++ b/Tools/XcodeCapp/XcodeCapp/AppController.m @@ -0,0 +1,338 @@ +/* + * This file is a part of program XcodeCapp + * Copyright (C) 2011 Antoine Mercadal () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#import + +#import "AppController.h" +#import "TNXcodeCapp.h" +#import "UserDefaults.h" + +#include "macros.h" + + +const NSInteger kHelpMenuItemTag = 7; + +AppController *SharedAppControllerInstance = nil; + + +@interface AppController () + +@property BOOL supportsFileModeListening; +@property (nonatomic) NSImage *iconActive; +@property (nonatomic) NSImage *iconInactive; +@property (nonatomic) NSImage *iconWorking; +@property (nonatomic) NSMenu *menuHistory; +@property NSStatusItem *statusItem; + +@end + + +@implementation AppController + ++ (AppController *)sharedAppController +{ + return SharedAppControllerInstance; +} + +#pragma mark - Initialization + +- (void)awakeFromNib +{ + SharedAppControllerInstance = self; + + [self registerDefaults]; + + self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; + self.statusItem.menu = self.statusMenu; + self.statusItem.image = self.iconInactive; + self.statusItem.highlightMode = YES; + self.statusItem.length = self.iconInactive.size.width + 8; // Add some space around the icon + self.statusMenu.delegate = self; + self.helpTextView.textContainerInset = NSMakeSize(10.0, 10.0); + + if ([[NSUserDefaults standardUserDefaults] boolForKey:kDefaultFirstLaunch]) + { + [[NSUserDefaults standardUserDefaults] setBool:NO forKey:kDefaultFirstLaunch]; + [self openHelp:self]; + } + + NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; + + [defaultCenter addObserver:self selector:@selector(XcodeCappConversionDidStart:) name:XCCConversionDidStartNotification object:self.xcc]; + [defaultCenter addObserver:self selector:@selector(XcodeCappConversionDidStop:) name:XCCConversionDidStopNotification object:self.xcc]; + [defaultCenter addObserver:self selector:@selector(XcodeCappDidPopulateProject:) name:XCCDidPopulateProjectNotification object:self.xcc]; + [defaultCenter addObserver:self selector:@selector(XcodeCappListeningDidStart:) name:XCCListeningDidStartNotification object:self.xcc]; + + [self pruneProjectHistory]; + [self updateHistoryMenu]; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)notification +{ + [self.xcc start]; +} + +/*! + Register default values for preferences +*/ +- (void)registerDefaults +{ + NSDictionary *appDefaults = @{ + kDefaultLastEventId: [NSNumber numberWithUnsignedLongLong:kFSEventStreamEventIdSinceNow], + kDefaultFirstLaunch: @YES, + kDefaultXCCAPIMode: [NSNumber numberWithInt:kXCCAPIModeAuto], + kDefaultXCCReactMode: @YES, + kDefaultXCCReopenLastProject: @YES, + kDefaultXCCAutoOpenErrorsPanel: @YES, + kDefaultXCCProjectHistory: [NSArray new] + }; + + [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; +} + +- (void)pruneProjectHistory +{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSMutableArray *projectHistory = [[defaults arrayForKey:kDefaultXCCProjectHistory] mutableCopy]; + NSFileManager *fm = [NSFileManager new]; + + for (NSInteger i = projectHistory.count - 1; i >= 0; --i) + { + if (![fm fileExistsAtPath:projectHistory[i]]) + [projectHistory removeObjectAtIndex:i]; + } + + [defaults setObject:projectHistory forKey:kDefaultXCCProjectHistory]; +} + +#pragma mark - +#pragma mark Properties + +- (NSImage *)iconActive +{ + if (!_iconActive) + _iconActive = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"icon-active.png"]]; + + return _iconActive; +} + +- (NSImage *)iconInactive +{ + if (!_iconInactive) + _iconInactive = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"icon-inactive.png"]]; + + return _iconInactive; +} + +- (NSImage *)iconWorking +{ + if (!_iconWorking) + _iconWorking = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"icon-working.png"]]; + + return _iconWorking; +} + +- (NSMenu *)menuHistory +{ + if (!_menuHistory) + { + _menuHistory = [NSMenu new]; + _menuHistory.autoenablesItems = NO; + self.menuItemHistory.submenu = _menuHistory; + } + + return _menuHistory; +} + +#pragma mark - +#pragma mark Notification handlers + +/*! + Clean up when the application stops. + It will stop the FSEvent listener, and store the last event id. +*/ +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app +{ + [self.xcc stop]; + + return NSTerminateNow; +} + +- (void)XcodeCappConversionDidStart:(NSNotification *)aNotification +{ + self.statusItem.image = self.iconWorking; +} + +- (void)XcodeCappConversionDidStop:(NSNotification *)aNotification +{ + if (!self.xcc.isLoadingProject) + self.statusItem.image = self.iconActive; +} + +- (void)XcodeCappDidPopulateProject:(NSNotification *)aNotification +{ +} + +- (void)XcodeCappListeningDidStart:(NSNotification *)aNotification +{ + self.statusItem.image = self.iconActive; + self.menuItemListen.title = [NSString stringWithFormat:@"Stop Listening to “%@”", self.xcc.currentProjectPath.lastPathComponent]; + self.menuItemListen.action = @selector(stopListening:); +} + + +#pragma mark - +#pragma mark Utilities + +- (void)updateHistoryMenu +{ + [self.menuHistory removeAllItems]; + NSArray *projectHistory = [[NSUserDefaults standardUserDefaults] arrayForKey:kDefaultXCCProjectHistory]; + + for (NSString *path in projectHistory) + { + NSMenuItem *item = [self.menuHistory addItemWithTitle:path.lastPathComponent action:@selector(switchToProject:) keyEquivalent:@""]; + [item setEnabled:YES]; + item.representedObject = path; + } + + [self.menuHistory addItem:[NSMenuItem separatorItem]]; + [self.menuHistory addItemWithTitle:@"Clear history" action:@selector(clearProjectHistory:) keyEquivalent:@""]; + + self.menuItemHistory.enabled = [projectHistory count] > 0; +} + + +#pragma mark - +#pragma mark Actions + +- (IBAction)listenToProject:(id)aSender +{ + [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; + + NSOpenPanel *openPanel = [NSOpenPanel openPanel]; + openPanel.title = @"Choose Cappuccino Project"; + openPanel.canChooseDirectories = YES; + openPanel.canCreateDirectories = YES; + openPanel.canChooseFiles = NO; + + if ([openPanel runModal] != NSFileHandlingPanelOKButton) + return; + + NSString *projectPath = [[openPanel.URLs[0] path] stringByStandardizingPath]; + [self listenToProjectAtPath:projectPath]; +} + +- (void)listenToProjectAtPath:(NSString *)path +{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSMutableArray *projectHistory = [[defaults arrayForKey:kDefaultXCCProjectHistory] mutableCopy]; + + if ([projectHistory containsObject:path]) + [projectHistory removeObject:path]; + + [projectHistory insertObject:path atIndex:0]; + + [defaults setObject:projectHistory forKey:kDefaultXCCProjectHistory]; + [self updateHistoryMenu]; + + [self stopListening:self]; + [self.xcc listenToProjectAtPath:path]; +} + +- (void)stopListening:(id)aSender +{ + [self.xcc stop]; + + self.statusItem.image = self.iconInactive; + self.menuItemListen.title = @"Listen to Project…"; + self.menuItemListen.action = @selector(listenToProject:); + + [[NSUserDefaults standardUserDefaults] removeObjectForKey:kDefaultLastOpenedPath]; +} + +- (void)switchToProject:(id)aSender +{ + NSString *projectPath = [aSender representedObject]; + + [self stopListening:aSender]; + [self listenToProjectAtPath:projectPath]; +} + +- (void)clearProjectHistory:(id)aSender +{ + [[NSUserDefaults standardUserDefaults] setObject:[NSArray array] forKey:kDefaultXCCProjectHistory]; + [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"]]; + + [self openWindow:self.helpWindow centered:YES]; +} + +- (IBAction)openAbout:(id)aSender +{ + [self openWindow:self.aboutWindow centered:YES]; +} + +- (IBAction)openPreferences:(id)aSender +{ + [self openWindow:self.preferencesWindow centered:NO]; +} + +- (void)openWindow:(NSWindow *)aWindow centered:(BOOL)shouldBeCentered +{ + [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; + + if (shouldBeCentered) + [aWindow center]; + + [aWindow makeKeyAndOrderFront:nil]; +} + + +#pragma mark - Delegates + +- (BOOL)validateMenuItem:(NSMenuItem *)aMenuItem +{ + if (aMenuItem == self.menuItemListen) + return !!self.xcc.currentProjectPath; + + return YES; +} + +#pragma mark - Private Helpers + +- (NSString *)bundleVersion +{ + return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; +} + +@end diff --git a/Tools/XcodeCapp/FSEventCallback.h b/Tools/XcodeCapp/XcodeCapp/FSEventCallback.h similarity index 98% rename from Tools/XcodeCapp/FSEventCallback.h rename to Tools/XcodeCapp/XcodeCapp/FSEventCallback.h index eac8aabcf..7f845f245 100644 --- a/Tools/XcodeCapp/FSEventCallback.h +++ b/Tools/XcodeCapp/XcodeCapp/FSEventCallback.h @@ -19,7 +19,7 @@ #ifndef xcodecapp_cocoa_FSEventCallback_h #define xcodecapp_cocoa_FSEventCallback_h -#import "TNXCodeCapp.h" +#import "TNXcodeCapp.h" #import #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_6 diff --git a/Tools/XcodeCapp/FSEventCallback.m b/Tools/XcodeCapp/XcodeCapp/FSEventCallback.m similarity index 59% rename from Tools/XcodeCapp/FSEventCallback.m rename to Tools/XcodeCapp/XcodeCapp/FSEventCallback.m index 6b537a068..02cd2c83d 100644 --- a/Tools/XcodeCapp/FSEventCallback.m +++ b/Tools/XcodeCapp/XcodeCapp/FSEventCallback.m @@ -20,10 +20,6 @@ #import "FSEventCallback.h" #import "macros.h" - -/*! - This is the FSEvent callback for 10.7 - */ void fsevents_callback(ConstFSEventStreamRef streamRef, void *userData, size_t numEvents, @@ -31,83 +27,85 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) { - TNXCodeCapp *xcc = (__bridge TNXCodeCapp *)userData; - BOOL useFileBasedListening = [xcc supportsFileBasedListening]; - size_t i; + TNXcodeCapp *xcc = (__bridge TNXcodeCapp *)userData; + NSArray *paths = (__bridge NSArray *)eventPaths; + BOOL usingFileBasedListening = [xcc supportsFileBasedListening]; - for (i = 0; i < numEvents; i++) + for (size_t i = 0; i < numEvents; ++i) { [xcc updateLastEventId:eventIds[i]]; FSEventStreamEventFlags flags = eventFlags[i]; + NSString *path = [[paths objectAtIndex:i] stringByStandardizingPath]; - NSString *path = [[(__bridge NSArray *)eventPaths objectAtIndex:i] stringByStandardizingPath]; - - if (useFileBasedListening) + if (usingFileBasedListening) { - BOOL conditionIsFile = flags & kFSEventStreamEventFlagItemIsFile; - BOOL conditionIsDirectory = NO; - BOOL conditionIsIgnored = [xcc isPathMatchingIgnoredPaths:path]; - BOOL conditionIsValidFile = [xcc isXIBFile:path] || [xcc isObjJFile:path] || [xcc isXCCIgnoreFile:path]; - BOOL conditionPathExists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&conditionIsDirectory]; - - if (conditionIsIgnored) + if ([xcc pathMatchesIgnoredPaths:path]) continue; - - if (conditionIsFile && !conditionIsValidFile) + + if ((flags & kFSEventStreamEventFlagItemIsFile) && + !([xcc isXibFile:path] || [xcc isObjjFile:path] || [xcc isXCCIgnoreFile:path])) + { continue; + } // Events are not so reliable. For example, moving a folder to the trash is not - // a deletion. In order to simplify the code, we simply tidyUp the project when we receive + // a deletion. In order to simplify the code, we simply tidy up the project when we receive // an event. [xcc tidyShadowedFiles]; - if (conditionIsDirectory) + BOOL isDirectory = NO; + BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory]; + + if (isDirectory) continue; - if (!conditionPathExists) + if (!exists) { DLog(@"File removed: %@", path); - [xcc handleFileRemoval:path]; + [xcc handleFileRemovalAtPath:path]; } else { DLog(@"File modified/added: %@", path); - [xcc handleFileModification:path notify:YES]; + [xcc handleFileModificationAtPath:path notify:YES]; } } else { // We should drop support for Snow Leopard soon. - BOOL isDir = NO; - [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir]; + BOOL isDirectory = NO; + [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory]; // If for some reasons the path is not a directory, // we don't want to deal with it in this mode. - if (!isDir) + if (!isDirectory) continue; [xcc tidyShadowedFiles]; - NSArray *subpaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL]; + NSFileManager *fm = [NSFileManager defaultManager]; + NSArray *subpaths = [fm contentsOfDirectoryAtPath:path error:NULL]; for (NSString *subpath in subpaths) { - NSString *fullPath = [[NSString stringWithFormat:@"%@/%@", path, subpath] stringByStandardizingPath]; + NSString *fullPath = [path stringByAppendingPathComponent:subpath]; - if ([xcc isPathMatchingIgnoredPaths:fullPath] - || (![xcc isXIBFile:fullPath] && ![xcc isObjJFile:fullPath] && ![xcc isXCCIgnoreFile:fullPath])) + if ([xcc pathMatchesIgnoredPaths:fullPath] || + !([xcc isXibFile:fullPath] || [xcc isObjjFile:fullPath] || [xcc isXCCIgnoreFile:fullPath])) + { continue; + } NSDate *lastModifiedDate = [xcc lastModificationDateForPath:fullPath]; - NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:fullPath error:nil]; + NSDictionary *fileAttributes = [fm attributesOfItemAtPath:fullPath error:nil]; NSDate *fileModDate = [fileAttributes objectForKey:NSFileModificationDate]; if ([fileModDate compare:lastModifiedDate] == NSOrderedDescending) { [xcc updateLastModificationDate:fileModDate forPath:fullPath]; - [xcc handleFileModification:fullPath notify:YES]; + [xcc handleFileModificationAtPath:fullPath notify:YES]; } } } diff --git a/Tools/XcodeCapp/Growl Registration Ticket.growlRegDict b/Tools/XcodeCapp/XcodeCapp/Growl Registration Ticket.growlRegDict similarity index 100% rename from Tools/XcodeCapp/Growl Registration Ticket.growlRegDict rename to Tools/XcodeCapp/XcodeCapp/Growl Registration Ticket.growlRegDict diff --git a/Tools/XcodeCapp/Growl.framework/Growl b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Growl similarity index 100% rename from Tools/XcodeCapp/Growl.framework/Growl rename to Tools/XcodeCapp/XcodeCapp/Growl.framework/Growl diff --git a/Tools/XcodeCapp/Growl.framework/Headers b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Headers similarity index 100% rename from Tools/XcodeCapp/Growl.framework/Headers rename to Tools/XcodeCapp/XcodeCapp/Growl.framework/Headers diff --git a/Tools/XcodeCapp/Growl.framework/Resources b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Resources similarity index 100% rename from Tools/XcodeCapp/Growl.framework/Resources rename to Tools/XcodeCapp/XcodeCapp/Growl.framework/Resources diff --git a/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Growl b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Growl new file mode 100755 index 000000000..e35673015 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Growl differ diff --git a/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Headers/Growl.h b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Headers/Growl.h new file mode 100644 index 000000000..7b1a3247d --- /dev/null +++ b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Headers/Growl.h @@ -0,0 +1,5 @@ +#include + +#ifdef __OBJC__ +# include +#endif diff --git a/Tools/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h similarity index 86% rename from Tools/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h rename to Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h index 1e39f8d65..363975762 100644 --- a/Tools/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h +++ b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h @@ -18,14 +18,11 @@ #import #import -#import "GrowlDefines.h" +#import //Forward declarations @protocol GrowlApplicationBridgeDelegate; -//Internal notification when the user chooses not to install (to avoid continuing to cache notifications awaiting installation) -#define GROWL_USER_CHOSE_NOT_TO_INSTALL_NOTIFICATION @"User chose not to install" - //------------------------------------------------------------------------------ #pragma mark - @@ -45,9 +42,9 @@ * @method isGrowlInstalled * @abstract Detects whether Growl is installed. * @discussion Determines if the Growl prefpane and its helper app are installed. - * @result Returns YES if Growl is installed, NO otherwise. + * @result this method will forever return YES. */ -+ (BOOL) isGrowlInstalled; ++ (BOOL) isGrowlInstalled __attribute__((deprecated)); /*! * @method isGrowlRunning @@ -57,6 +54,34 @@ */ + (BOOL) isGrowlRunning; + +/*! + * @method isMistEnabled + * @abstract Gives the caller a fairly good indication of whether or not built-in notifications(Mist) will be used. + * @discussion since this call makes use of isGrowlRunning it is entirely possible for this value to change between call and + * executing a notification dispatch + * @result Returns YES if Growl isn't reachable and the developer has not opted-out of + * Mist and the user hasn't set the global mist enable key to false. + */ ++ (BOOL)isMistEnabled; + +/*! + * @method setShouldUseBuiltInNotifications + * @abstract opt-out mechanism for the mist notification style in the event growl can't be reached. + * @discussion if growl is unavailable due to not being installed or as a result of being turned off then + * this option can enable/disable a built-in fire and forget display style + * @param should Specifies whether or not the developer wants to opt-in (default) or opt out + * of the built-in Mist style in the event Growl is unreachable. + */ ++ (void)setShouldUseBuiltInNotifications:(BOOL)should; + +/*! + * @method shouldUseBuiltInNotifications + * @abstract returns the current opt-in state of the framework's use of the Mist display style. + * @result Returns NO if the developer opt-ed out of Mist, the default value is YES. + */ ++ (BOOL)shouldUseBuiltInNotifications; + #pragma mark - /*! @@ -87,7 +112,7 @@ * * @param inDelegate The delegate for the GrowlApplicationBridge. It must conform to the GrowlApplicationBridgeDelegate protocol. */ -+ (void) setGrowlDelegate:(NSObject *)inDelegate; ++ (void) setGrowlDelegate:(id)inDelegate; /*! * @method growlDelegate @@ -95,7 +120,7 @@ * @discussion See setGrowlDelegate: for details. * @result The Growl delegate. */ -+ (NSObject *) growlDelegate; ++ (id) growlDelegate; #pragma mark - @@ -235,6 +260,7 @@ * Growl when next it is ready; NO if not. */ + (void) setWillRegisterWhenGrowlIsReady:(BOOL)flag; + /*! @method willRegisterWhenGrowlIsReady * @abstract Reports whether GrowlApplicationBridge will register with Growl * when Growl next launches. @@ -323,7 +349,7 @@ * Key Value * --- ----- * GROWL_APP_NAME CFBundleExecutableName - * GROWL_APP_ICON The icon of the application. + * GROWL_APP_ICON_DATA The data of the icon of the application. * GROWL_APP_LOCATION The location of the application. * GROWL_NOTIFICATIONS_DEFAULT GROWL_NOTIFICATIONS_ALL * @@ -336,6 +362,7 @@ * copy of regDict. */ + (NSDictionary *) registrationDictionaryByFillingInDictionary:(NSDictionary *)regDict; + /*! @method registrationDictionaryByFillingInDictionary:restrictToKeys: * @abstract Tries to fill in missing keys in a registration dictionary. * @discussion This method examines the passed-in dictionary for missing keys, @@ -344,7 +371,7 @@ * Key Value * --- ----- * GROWL_APP_NAME CFBundleExecutableName - * GROWL_APP_ICON The icon of the application. + * GROWL_APP_ICON_DATA The data of the icon of the application. * GROWL_APP_LOCATION The location of the application. * GROWL_NOTIFICATIONS_DEFAULT GROWL_NOTIFICATIONS_ALL * @@ -368,13 +395,39 @@ * the keys that it will look for are: * * \li GROWL_APP_NAME - * \li GROWL_APP_ICON + * \li GROWL_APP_ICON_DATA * * @since Growl.framework 1.1 */ + (NSDictionary *) notificationDictionaryByFillingInDictionary:(NSDictionary *)regDict; + (NSDictionary *) frameworkInfoDictionary; + +#pragma mark - + +/*! + *@method growlURLSchemeAvailable + *@abstract Lets the app know whether growl:// is registered on the system, used for certain methods below this + *@return Returns whether growl:// is registered on the system + *@discussion Methods such as openGrowlPreferences rely on the growl:// URL scheme to function + * Further, this method can provide a check on whether Growl is installed, + * however, the framework will not be relying on this method for choosing when/how to notify, + * and it is not recommended that the app rely on it for other than whether to use growl:// methods + *@since Growl.framework 1.4 + */ ++ (BOOL) isGrowlURLSchemeAvailable; + +/*! + * @method openGrowlPreferences: + * @abstract Open Growl preferences, optionally to this app's settings, growl:// method + * @param showApp Whether to show the application's settings, otherwise just opens to the last position + * @return Return's whether opening the URL was succesfull or not. + * @discussion Will launch if Growl is installed, but not running, and open the preferences window + * Uses growl:// URL scheme + * @since Growl.framework 1.4 + */ ++ (BOOL) openGrowlPreferences:(BOOL)showApp; + @end //------------------------------------------------------------------------------ @@ -383,27 +436,15 @@ /*! * @protocol GrowlApplicationBridgeDelegate * @abstract Required protocol for the Growl delegate. - * @discussion The methods in this protocol are required and are called + * @discussion The methods in this protocol are optional and are called * automatically as needed by GrowlApplicationBridge. See * +[GrowlApplicationBridge setGrowlDelegate:]. * See also GrowlApplicationBridgeDelegate_InformalProtocol. */ -@protocol GrowlApplicationBridgeDelegate +@protocol GrowlApplicationBridgeDelegate -// -registrationDictionaryForGrowl has moved to the informal protocol as of 0.7. - -@end - -//------------------------------------------------------------------------------ -#pragma mark - - -/*! - * @category NSObject(GrowlApplicationBridgeDelegate_InformalProtocol) - * @abstract Methods which may be optionally implemented by the GrowlDelegate. - * @discussion The methods in this informal protocol will only be called if implemented by the delegate. - */ -@interface NSObject (GrowlApplicationBridgeDelegate_InformalProtocol) +@optional /*! * @method registrationDictionaryForGrowl @@ -510,66 +551,17 @@ */ - (void) growlNotificationTimedOut:(id)clickContext; + +/*! + * @method hasNetworkClientEntitlement + * @abstract Used only in sandboxed situations since we don't know whether the app has com.apple.security.network.client entitlement + * @discussion GrowlDelegate calls to find out if we have the com.apple.security.network.client entitlement, + * since we can't find this out without hitting the sandbox. We only call it if we detect that the application is sandboxed. + */ +- (BOOL) hasNetworkClientEntitlement; + @end #pragma mark - -/*! - * @category NSObject(GrowlApplicationBridgeDelegate_Installation_InformalProtocol) - * @abstract Methods which may be optionally implemented by the Growl delegate when used with Growl-WithInstaller.framework. - * @discussion The methods in this informal protocol will only be called if - * implemented by the delegate. They allow greater control of the information - * presented to the user when installing or upgrading Growl from within your - * application when using Growl-WithInstaller.framework. - */ -@interface NSObject (GrowlApplicationBridgeDelegate_Installation_InformalProtocol) - -/*! - * @method growlInstallationWindowTitle - * @abstract Return the title of the installation window. - * @discussion If not implemented, Growl will use a default, localized title. - * @result An NSString object to use as the title. - */ -- (NSString *)growlInstallationWindowTitle; - -/*! - * @method growlUpdateWindowTitle - * @abstract Return the title of the upgrade window. - * @discussion If not implemented, Growl will use a default, localized title. - * @result An NSString object to use as the title. - */ -- (NSString *)growlUpdateWindowTitle; - -/*! - * @method growlInstallationInformation - * @abstract Return the information to display when installing. - * @discussion This information may be as long or short as desired (the window - * will be sized to fit it). It will be displayed to the user as an - * explanation of what Growl is and what it can do in your application. It - * should probably note that no download is required to install. - * - * If this is not implemented, Growl will use a default, localized explanation. - * @result An NSAttributedString object to display. - */ -- (NSAttributedString *)growlInstallationInformation; - -/*! - * @method growlUpdateInformation - * @abstract Return the information to display when upgrading. - * @discussion This information may be as long or short as desired (the window - * will be sized to fit it). It will be displayed to the user as an - * explanation that an updated version of Growl is included in your - * application and no download is required. - * - * If this is not implemented, Growl will use a default, localized explanation. - * @result An NSAttributedString object to display. - */ -- (NSAttributedString *)growlUpdateInformation; - -@end - -//private -@interface GrowlApplicationBridge (GrowlInstallationPrompt_private) -+ (void) _userChoseNotToInstallGrowl; -@end #endif /* __GrowlApplicationBridge_h__ */ diff --git a/Tools/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlDefines.h b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlDefines.h similarity index 77% rename from Tools/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlDefines.h rename to Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlDefines.h index 2b971cfe5..0a196f1e3 100644 --- a/Tools/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlDefines.h +++ b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Headers/GrowlDefines.h @@ -7,10 +7,8 @@ #ifdef __OBJC__ #define XSTR(x) (@x) -#define STRING_TYPE NSString * #else #define XSTR CFSTR -#define STRING_TYPE CFStringRef #endif /*! @header GrowlDefines.h @@ -56,7 +54,7 @@ * This key is optional. */ #define GROWL_APP_ID XSTR("ApplicationId") -/*! @defined GROWL_APP_ICON +/*! @defined GROWL_APP_ICON_DATA * @abstract The image data for your application's icon. * @discussion Image data representing your application's icon. This may be * superimposed on a notification icon as a badge, used as the notification @@ -66,7 +64,7 @@ * * Optional. Not supported by all display plugins. */ -#define GROWL_APP_ICON XSTR("ApplicationIcon") +#define GROWL_APP_ICON_DATA XSTR("ApplicationIcon") /*! @defined GROWL_NOTIFICATIONS_DEFAULT * @abstract The array of notifications to turn on by default. * @discussion These are the names of the notifications that should be enabled @@ -101,6 +99,14 @@ * This key is optional. */ #define GROWL_NOTIFICATIONS_DESCRIPTIONS XSTR("NotificationDescriptions") +/*! @defined GROWL_NOTIFICATIONS_ICONS + * @abstract A dictionary of icons for each notification + * @discussion This is an NSDictionary whose keys are GROWL_NOTIFICATION_NAME strings and whose objects are + * icons for each notification, for GNTP spec + * + * This key is optional. + */ +#define GROWL_NOTIFICATIONS_ICONS XSTR("NotificationIcons") /*! @defined GROWL_TICKET_VERSION * @abstract The version of your registration ticket. @@ -144,20 +150,20 @@ */ #define GROWL_NOTIFICATION_DESCRIPTION XSTR("NotificationDescription") /*! @defined GROWL_NOTIFICATION_ICON - * @discussion Image data for the notification icon. Must be in a format + * @discussion Image data for the notification icon. Image data must be in a format * supported by NSImage, such as TIFF, PNG, GIF, JPEG, BMP, PICT, or PDF. * * Optional. Not supported by all display plugins. */ -#define GROWL_NOTIFICATION_ICON XSTR("NotificationIcon") +#define GROWL_NOTIFICATION_ICON_DATA XSTR("NotificationIcon") /*! @defined GROWL_NOTIFICATION_APP_ICON * @discussion Image data for the application icon, in case GROWL_APP_ICON does - * not apply for some reason. Must be in a format supported by NSImage, such + * not apply for some reason. Image data be in a format supported by NSImage, such * as TIFF, PNG, GIF, JPEG, BMP, PICT, or PDF. * * Optional. Not supported by all display plugins. */ -#define GROWL_NOTIFICATION_APP_ICON XSTR("NotificationAppIcon") +#define GROWL_NOTIFICATION_APP_ICON_DATA XSTR("NotificationAppIcon") /*! @defined GROWL_NOTIFICATION_PRIORITY * @discussion The priority of the notification as an integer number from * -2 to +2 (+2 being highest). @@ -185,16 +191,6 @@ */ #define GROWL_NOTIFICATION_CLICK_CONTEXT XSTR("NotificationClickContext") -/*! @defined GROWL_DISPLAY_PLUGIN - * @discussion The name of a display plugin which should be used for this notification. - * Optional. If this key is not set or the specified display plugin does not - * exist, the display plugin stored in the application ticket is used. This key - * allows applications to use different default display plugins for their - * notifications. The user can still override those settings in the preference - * pane. - */ -#define GROWL_DISPLAY_PLUGIN XSTR("NotificationDisplayPlugin") - /*! @defined GROWL_NOTIFICATION_IDENTIFIER * @abstract An identifier for the notification for coalescing purposes. * Notifications with the same identifier fall into the same class; only @@ -224,6 +220,19 @@ */ #define GROWL_NOTIFICATION_PROGRESS XSTR("NotificationProgress") +/*! @defined GROWL_NOTIFICATION_ALREADY_SHOWN + * @abstract If this key is set, it should contain a bool value wrapped + * in a NSNumber which describes whether the notification has + * already been displayed, for instance by built in Notification + * Center support. This value can be used to allow display + * plugins to skip a notification, while still allowing Growl + * actions to run on them. + * + * Optional. Not supported by all display plugins. + */ +#define GROWL_NOTIFICATION_ALREADY_SHOWN XSTR("AlreadyShown") + + // Notifications #pragma mark Notifications @@ -245,7 +254,7 @@ * The userInfo dictionary for this notification can contain these keys: *
    *
  • GROWL_APP_NAME
  • - *
  • GROWL_APP_ICON
  • + *
  • GROWL_APP_ICON_DATA
  • *
  • GROWL_NOTIFICATIONS_ALL
  • *
  • GROWL_NOTIFICATIONS_DEFAULT
  • *
@@ -288,12 +297,6 @@ * Growl_PostNotification. */ #define GROWL_NOTIFICATION XSTR("GrowlNotification") -/*! @defined GROWL_SHUTDOWN -* @abstract The distributed notification name that tells Growl to shutdown. -* @discussion The Growl preference pane posts this notification when the -* "Stop Growl" button is clicked. -*/ -#define GROWL_SHUTDOWN XSTR("GrowlShutdown") /*! @defined GROWL_PING * @abstract A distributed notification to check whether Growl is running. * @discussion This is used by the Growl preference pane. If it receives a @@ -313,15 +316,48 @@ * registration dictionary supplied by its delegate. */ #define GROWL_IS_READY XSTR("Lend Me Some Sugar; I Am Your Neighbor!") -/*! @defined GROWL_NOTIFICATION_CLICKED - * @abstract The distributed notification sent when a supported notification is clicked. + + +/*! @defined GROWL_DISTRIBUTED_NOTIFICATION_CLICKED_SUFFIX + * @abstract Part of the name of the distributed notification sent when a supported notification is clicked. * @discussion When a Growl notification with a click context is clicked on by - * the user, Growl posts this distributed notification. - * The GrowlApplicationBridge responds to this notification by calling a - * callback in its delegate. + * the user, Growl posts a distributed notification whose name is in the format: + * [NSString stringWithFormat:@"%@-%d-%@", appName, pid, GROWL_DISTRIBUTED_NOTIFICATION_CLICKED_SUFFIX] + * The GrowlApplicationBridge responds to this notification by calling a callback in its delegate. */ -#define GROWL_NOTIFICATION_CLICKED XSTR("GrowlClicked!") -#define GROWL_NOTIFICATION_TIMED_OUT XSTR("GrowlTimedOut!") +#define GROWL_DISTRIBUTED_NOTIFICATION_CLICKED_SUFFIX XSTR("GrowlClicked!") + +/*! @defined GROWL_DISTRIBUTED_NOTIFICATION_TIMED_OUT_SUFFIX + * @abstract Part of the name of the distributed notification sent when a supported notification times out without being clicked. + * @discussion When a Growl notification with a click context times out, Growl posts a distributed notification + * whose name is in the format: + * [NSString stringWithFormat:@"%@-%d-%@", appName, pid, GROWL_DISTRIBUTED_NOTIFICATION_TIMED_OUT_SUFFIX] + * The GrowlApplicationBridge responds to this notification by calling a callback in its delegate. + * NOTE: The user may have actually clicked the 'close' button; this triggers an *immediate* time-out of the notification. + */ +#define GROWL_DISTRIBUTED_NOTIFICATION_TIMED_OUT_SUFFIX XSTR("GrowlTimedOut!") + +/*! @defined GROWL_DISTRIBUTED_NOTIFICATION_NOTIFICATIONCENTER_ON + * @abstract The distributed notification sent when the Notification Center support is toggled on in Growl 2.0 + * @discussion When the user enables Notification Center support in Growl 2.0, this notification is sent + * to inform all running apps that they should now speak to Notification Center directly. + */ +#define GROWL_DISTRIBUTED_NOTIFICATION_NOTIFICATIONCENTER_ON XSTR("GrowlNotificationCenterOn!") + +/*! @defined GROWL_DISTRIBUTED_NOTIFICATION_NOTIFICATIONCENTER_OFF + * @abstract The distributed notification sent when the Notification Center support is toggled off in Growl 2.0 + * @discussion When the user enables Notification Center support in Growl 2.0, this notification is sent + * to inform all running apps that they should no longer speak to Notification Center directly. + */ +#define GROWL_DISTRIBUTED_NOTIFICATION_NOTIFICATIONCENTER_OFF XSTR("GrowlNotificationCenterOff!") + +/*! @defined GROWL_DISTRIBUTED_NOTIFICATION_NOTIFICATIONCENTER_QUERY + * @abstract The distributed notification sent by an application to query Growl 2.0's notification center support. + * @discussion When an app starts up, it will send this query to get Growl 2.0 to spit out whether notification + * center support is on or off. + */ +#define GROWL_DISTRIBUTED_NOTIFICATION_NOTIFICATIONCENTER_QUERY XSTR("GrowlNotificationCenterYN?") + /*! @group Other symbols */ /* Symbols which don't fit into any of the other categories. */ @@ -345,4 +381,6 @@ #define GROWL_POSITION_PREFERENCE_KEY @"GrowlSelectedPosition" +#define GROWL_PLUGIN_CONFIG_ID XSTR("GrowlPluginConfigurationID") + #endif //ndef _GROWLDEFINES_H diff --git a/Tools/XcodeCapp/Growl.framework/Versions/A/Resources/Info.plist b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Resources/Info.plist similarity index 59% rename from Tools/XcodeCapp/Growl.framework/Versions/A/Resources/Info.plist rename to Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Resources/Info.plist index 5a76a5f19..6a90f41b9 100644 --- a/Tools/XcodeCapp/Growl.framework/Versions/A/Resources/Info.plist +++ b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/Resources/Info.plist @@ -2,6 +2,8 @@ + BuildMachineOSBuild + 12C60 CFBundleDevelopmentRegion English CFBundleExecutable @@ -13,11 +15,25 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.2.1 + 2.0.1 CFBundleSignature GRRR CFBundleVersion - 1.2.1 + 2.0.1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 4G2008a + DTPlatformVersion + GM + DTSDKBuild + 12C37 + DTSDKName + macosx10.8 + DTXcode + 0452 + DTXcodeBuild + 4G2008a NSPrincipalClass GrowlApplicationBridge diff --git a/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/_CodeSignature/CodeResources b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/_CodeSignature/CodeResources new file mode 100644 index 000000000..420b594ac --- /dev/null +++ b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/A/_CodeSignature/CodeResources @@ -0,0 +1,34 @@ + + + + + files + + Resources/Info.plist + + VZb3f8My4te/5JwcjfvotgCXTAs= + + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^version.plist$ + + + + diff --git a/Tools/XcodeCapp/Growl.framework/Versions/Current b/Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/Current similarity index 100% rename from Tools/XcodeCapp/Growl.framework/Versions/Current rename to Tools/XcodeCapp/XcodeCapp/Growl.framework/Versions/Current diff --git a/Tools/XcodeCapp/Info.plist b/Tools/XcodeCapp/XcodeCapp/Info.plist similarity index 95% rename from Tools/XcodeCapp/Info.plist rename to Tools/XcodeCapp/XcodeCapp/Info.plist index 53973c70a..780a34d48 100644 --- a/Tools/XcodeCapp/Info.plist +++ b/Tools/XcodeCapp/XcodeCapp/Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.0 + 3.0 CFBundleSignature ???? CFBundleVersion - 2.0 + 3.0.0 LSApplicationCategoryType public.app-category.developer-tools LSUIElement diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_128x128.psd b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_128x128.psd new file mode 100644 index 000000000..cbc052cf5 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_128x128.psd differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_128x128@2x.psd b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_128x128@2x.psd new file mode 100644 index 000000000..9e8acc137 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_128x128@2x.psd differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_16x16.psd b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_16x16.psd new file mode 100644 index 000000000..6ecca284b Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_16x16.psd differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_16x16@2x.psd b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_16x16@2x.psd new file mode 100644 index 000000000..de7233474 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_16x16@2x.psd differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_256x256.psd b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_256x256.psd new file mode 100644 index 000000000..6f7fc0c15 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_256x256.psd differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_256x256@2x.psd b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_256x256@2x.psd new file mode 100644 index 000000000..14e0b7bc4 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_256x256@2x.psd differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_32x32.psd b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_32x32.psd new file mode 100644 index 000000000..458a77966 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_32x32.psd differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_32x32@2x.psd b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_32x32@2x.psd new file mode 100644 index 000000000..7bfbf9dbc Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_32x32@2x.psd differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_512x512.psd b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_512x512.psd new file mode 100644 index 000000000..d74c37eed Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_512x512.psd differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_512x512@2x.psd b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_512x512@2x.psd new file mode 100644 index 000000000..628d0501b Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp icons/icon_512x512@2x.psd differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp-status-icons.psd b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp-status-icons.psd new file mode 100644 index 000000000..3f4f370ff Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp-status-icons.psd differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_128x128.png b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_128x128.png new file mode 100644 index 000000000..2f2b12c41 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_128x128.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_128x128@2x.png b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_128x128@2x.png new file mode 100644 index 000000000..2828424ba Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_128x128@2x.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_16x16.png b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_16x16.png new file mode 100644 index 000000000..2d980b6e6 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_16x16.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_16x16@2x.png b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_16x16@2x.png new file mode 100644 index 000000000..d852f1502 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_16x16@2x.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_256x256.png b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_256x256.png new file mode 100644 index 000000000..2828424ba Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_256x256.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_256x256@2x.png b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_256x256@2x.png new file mode 100644 index 000000000..5459552f2 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_256x256@2x.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_32x32.png b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_32x32.png new file mode 100644 index 000000000..c3287a5fd Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_32x32.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_32x32@2x.png b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_32x32@2x.png new file mode 100644 index 000000000..d90892068 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_32x32@2x.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_512x512.png b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_512x512.png new file mode 100644 index 000000000..8428a569f Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_512x512.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_512x512@2x.png b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_512x512@2x.png new file mode 100644 index 000000000..6e1c696ab Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/XcodeCapp.iconset/icon_512x512@2x.png differ diff --git a/Tools/XcodeCapp/help.rtfd/TXT.rtf b/Tools/XcodeCapp/XcodeCapp/Resources/help.rtfd/TXT.rtf similarity index 100% rename from Tools/XcodeCapp/help.rtfd/TXT.rtf rename to Tools/XcodeCapp/XcodeCapp/Resources/help.rtfd/TXT.rtf diff --git a/Tools/XcodeCapp/help.rtfd/action.png b/Tools/XcodeCapp/XcodeCapp/Resources/help.rtfd/action.png similarity index 100% rename from Tools/XcodeCapp/help.rtfd/action.png rename to Tools/XcodeCapp/XcodeCapp/Resources/help.rtfd/action.png diff --git a/Tools/XcodeCapp/help.rtfd/menu1.png b/Tools/XcodeCapp/XcodeCapp/Resources/help.rtfd/menu1.png similarity index 100% rename from Tools/XcodeCapp/help.rtfd/menu1.png rename to Tools/XcodeCapp/XcodeCapp/Resources/help.rtfd/menu1.png diff --git a/Tools/XcodeCapp/help.rtfd/menu2.png b/Tools/XcodeCapp/XcodeCapp/Resources/help.rtfd/menu2.png similarity index 100% rename from Tools/XcodeCapp/help.rtfd/menu2.png rename to Tools/XcodeCapp/XcodeCapp/Resources/help.rtfd/menu2.png diff --git a/Tools/XcodeCapp/help.rtfd/outlets.png b/Tools/XcodeCapp/XcodeCapp/Resources/help.rtfd/outlets.png similarity index 100% rename from Tools/XcodeCapp/help.rtfd/outlets.png rename to Tools/XcodeCapp/XcodeCapp/Resources/help.rtfd/outlets.png diff --git a/Tools/XcodeCapp/help.rtfd/outlets2.png b/Tools/XcodeCapp/XcodeCapp/Resources/help.rtfd/outlets2.png similarity index 100% rename from Tools/XcodeCapp/help.rtfd/outlets2.png rename to Tools/XcodeCapp/XcodeCapp/Resources/help.rtfd/outlets2.png diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/icon-active.png b/Tools/XcodeCapp/XcodeCapp/Resources/icon-active.png new file mode 100644 index 000000000..be61d20da Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/icon-active.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/icon-inactive.png b/Tools/XcodeCapp/XcodeCapp/Resources/icon-inactive.png new file mode 100644 index 000000000..0de5b1913 Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/icon-inactive.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/icon-working.png b/Tools/XcodeCapp/XcodeCapp/Resources/icon-working.png new file mode 100644 index 000000000..064ec820e Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/Resources/icon-working.png differ diff --git a/Tools/XcodeCapp/XcodeCapp/Resources/project.pbxproj b/Tools/XcodeCapp/XcodeCapp/Resources/project.pbxproj new file mode 100644 index 000000000..717e5dcd2 --- /dev/null +++ b/Tools/XcodeCapp/XcodeCapp/Resources/project.pbxproj @@ -0,0 +1,72 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXFileReference section */ + E164FE29172185F500263CE3 /* Resources */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Resources; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + E164FE221721857400263CE3 = { + isa = PBXGroup; + children = ( + E164FE29172185F500263CE3 /* Resources */, + ); + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXProject section */ + E164FE231721857400263CE3 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0460; + }; + buildConfigurationList = E164FE261721857400263CE3 /* Build configuration list for PBXProject "Cappuccino" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E164FE221721857400263CE3; + projectDirPath = ""; + projectRoot = ""; + targets = ( + ); + }; +/* End PBXProject section */ + +/* Begin XCBuildConfiguration section */ + E164FE271721857400263CE3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Debug; + }; + E164FE281721857400263CE3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E164FE261721857400263CE3 /* Build configuration list for PBXProject "Cappuccino" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E164FE271721857400263CE3 /* Debug */, + E164FE281721857400263CE3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E164FE231721857400263CE3 /* Project object */; +} diff --git a/Tools/XcodeCapp/XcodeCapp/Scripts/mod_pbxproj.py b/Tools/XcodeCapp/XcodeCapp/Scripts/mod_pbxproj.py index 6af471f01..8291e0b23 100755 --- a/Tools/XcodeCapp/XcodeCapp/Scripts/mod_pbxproj.py +++ b/Tools/XcodeCapp/XcodeCapp/Scripts/mod_pbxproj.py @@ -1,16 +1,16 @@ # Copyright 2012 Calvin Rien # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. # A pbxproj file is an OpenStep format plist # {} represents dictionary of key=value pairs delimited by ; @@ -143,39 +143,39 @@ class PBXFileReference(PBXType): self.build_phase = None types = { - '.a':('archive.ar', 'PBXFrameworksBuildPhase'), - '.app': ('wrapper.application', None), - '.s': ('sourcecode.asm', 'PBXSourcesBuildPhase'), - '.c': ('sourcecode.c.c', 'PBXSourcesBuildPhase'), - '.cpp': ('sourcecode.cpp.cpp', 'PBXSourcesBuildPhase'), - '.framework': ('wrapper.framework','PBXFrameworksBuildPhase'), - '.h': ('sourcecode.c.h', None), - '.icns': ('image.icns','PBXResourcesBuildPhase'), - '.m': ('sourcecode.c.objc', 'PBXSourcesBuildPhase'), - '.j': ('sourcecode.c.objc', 'PBXSourcesBuildPhase'), - '.mm': ('sourcecode.cpp.objcpp', 'PBXSourcesBuildPhase'), - '.nib': ('wrapper.nib', 'PBXResourcesBuildPhase'), - '.plist': ('text.plist.xml', 'PBXResourcesBuildPhase'), - '.json': ('text.json', 'PBXResourcesBuildPhase'), - '.png': ('image.png', 'PBXResourcesBuildPhase'), - '.rtf': ('text.rtf', 'PBXResourcesBuildPhase'), - '.tiff': ('image.tiff', 'PBXResourcesBuildPhase'), - '.txt': ('text', 'PBXResourcesBuildPhase'), - '.xcodeproj': ('wrapper.pb-project', None), - '.xib': ('file.xib', 'PBXResourcesBuildPhase'), - '.strings': ('text.plist.strings', 'PBXResourcesBuildPhase'), - '.bundle': ('wrapper.plug-in', 'PBXResourcesBuildPhase'), - '.dylib': ('compiled.mach-o.dylib', 'PBXFrameworksBuildPhase') + '.a':('archive.ar', 'PBXFrameworksBuildPhase'), + '.app': ('wrapper.application', None), + '.s': ('sourcecode.asm', 'PBXSourcesBuildPhase'), + '.c': ('sourcecode.c.c', 'PBXSourcesBuildPhase'), + '.cpp': ('sourcecode.cpp.cpp', 'PBXSourcesBuildPhase'), + '.framework': ('wrapper.framework','PBXFrameworksBuildPhase'), + '.h': ('sourcecode.c.h', None), + '.icns': ('image.icns','PBXResourcesBuildPhase'), + '.m': ('sourcecode.c.objc', 'PBXSourcesBuildPhase'), + '.j': ('sourcecode.c.objc', 'PBXSourcesBuildPhase'), + '.mm': ('sourcecode.cpp.objcpp', 'PBXSourcesBuildPhase'), + '.nib': ('wrapper.nib', 'PBXResourcesBuildPhase'), + '.plist': ('text.plist.xml', 'PBXResourcesBuildPhase'), + '.json': ('text.json', 'PBXResourcesBuildPhase'), + '.png': ('image.png', 'PBXResourcesBuildPhase'), + '.rtf': ('text.rtf', 'PBXResourcesBuildPhase'), + '.tiff': ('image.tiff', 'PBXResourcesBuildPhase'), + '.txt': ('text', 'PBXResourcesBuildPhase'), + '.xcodeproj': ('wrapper.pb-project', None), + '.xib': ('file.xib', 'PBXResourcesBuildPhase'), + '.strings': ('text.plist.strings', 'PBXResourcesBuildPhase'), + '.bundle': ('wrapper.plug-in', 'PBXResourcesBuildPhase'), + '.dylib': ('compiled.mach-o.dylib', 'PBXFrameworksBuildPhase') } trees = [ - '', - '', - 'BUILT_PRODUCTS_DIR', - 'DEVELOPER_DIR', - 'SDKROOT', - 'SOURCE_ROOT', - ] + '', + '', + 'BUILT_PRODUCTS_DIR', + 'DEVELOPER_DIR', + 'SDKROOT', + 'SOURCE_ROOT', + ] def guess_file_type(self): self.remove('explicitFileType') @@ -355,6 +355,10 @@ class PBXVariantGroup(PBXType): pass +class PBXTargetDependency(PBXType): + pass + + class PBXBuildPhase(PBXType): def add_build_file(self, bf): if bf.get('isa') != 'PBXBuildFile': @@ -590,7 +594,7 @@ class XcodeProject(PBXDict): if b.add_library_search_paths(paths, recursive): self.modified = True - # TODO: need to return value if project has been modified + # TODO: need to return value if project has been modified def get_obj(self, id): return self.objects.get(id) @@ -600,36 +604,36 @@ class XcodeProject(PBXDict): def get_files_by_os_path(self, os_path, tree='SOURCE_ROOT'): files = [f for f in self.objects.values() if f.get('isa') == 'PBXFileReference' - and f.get('path') == os_path - and f.get('sourceTree') == tree] + and f.get('path') == os_path + and f.get('sourceTree') == tree] return files def get_files_by_name(self, name, parent=None): if parent: files = [f for f in self.objects.values() if f.get('isa') == 'PBXFileReference' - and f.get(name) == name - and parent.has_child(f)] + and f.get(name) == name + and parent.has_child(f)] else: files = [f for f in self.objects.values() if f.get('isa') == 'PBXFileReference' - and f.get(name) == name] + and f.get(name) == name] return files def get_build_files(self, id): files = [f for f in self.objects.values() if f.get('isa') == 'PBXBuildFile' - and f.get('fileRef') == id] + and f.get('fileRef') == id] return files def get_groups_by_name(self, name, parent=None): if parent: groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup' - and g.get_name() == name - and parent.has_child(g)] + and g.get_name() == name + and parent.has_child(g)] else: groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup' - and g.get_name() == name] + and g.get_name() == name] return groups @@ -662,7 +666,7 @@ class XcodeProject(PBXDict): path = os.path.abspath(path) groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup' - and os.path.abspath(g.get('path','/dev/null')) == path] + and os.path.abspath(g.get('path','/dev/null')) == path] return groups @@ -739,9 +743,9 @@ class XcodeProject(PBXDict): continue kwds = { - 'create_build_files': create_build_files, - 'parent': grp, - 'name': f + 'create_build_files': create_build_files, + 'parent': grp, + 'name': f } f_path = os.path.join(grp_path, f) @@ -812,12 +816,12 @@ class XcodeProject(PBXDict): results.append(build_file) if abs_path and tree == 'SOURCE_ROOT' and os.path.isfile(abs_path)\ - and file_ref.build_phase == 'PBXFrameworksBuildPhase': + and file_ref.build_phase == 'PBXFrameworksBuildPhase': library_path = os.path.join('$(SRCROOT)', os.path.split(f_path)[0]) self.add_library_search_paths([library_path], recursive=False) if abs_path and tree == 'SOURCE_ROOT' and not os.path.isfile(abs_path)\ - and file_ref.build_phase == 'PBXFrameworksBuildPhase': + and file_ref.build_phase == 'PBXFrameworksBuildPhase': framework_path = os.path.join('$(SRCROOT)', os.path.split(f_path)[0]) self.add_framework_search_paths([framework_path,'$(inherited)'], recursive=False) @@ -849,12 +853,24 @@ class XcodeProject(PBXDict): if(not os.path.exists(finalLib)): os.symlink(srcLib, finalLib); - def remove_group(self, grp): pass - def remove_file(self, id): - pass + def remove_file(self, id, recursive=True): + if not PBXType.IsGuid(id): + id = id.id + + if id in self.objects: + self.objects.remove(id) + + if recursive: + groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup'] + + for group in groups: + if id in group['children']: + group.remove_child(id) + + self.modified = True def move_file(self, id, dest_grp=None): pass @@ -1023,11 +1039,11 @@ class XcodeProject(PBXDict): for f in v: filerefs.extend([fr.id for fr in self.objects.values() if fr.get('isa') == 'PBXFileReference' - and fr.get('name') == f]) + and fr.get('name') == f]) buildfiles = [bf for bf in self.objects.values() if bf.get('isa') == 'PBXBuildFile' - and bf.get('fileRef') in filerefs] + and bf.get('fileRef') in filerefs] for bf in buildfiles: if bf.add_compiler_flag(k): @@ -1137,26 +1153,30 @@ class XcodeProject(PBXDict): #root.remove('objects') #remove it to avoid problems sections = [ - ('PBXBuildFile',False), - ('PBXCopyFilesBuildPhase',True), - ('PBXFileReference',False), - ('PBXFrameworksBuildPhase',True), - ('PBXGroup',True), - ('PBXNativeTarget',True), - ('PBXProject',True), - ('PBXResourcesBuildPhase',True), - ('PBXShellScriptBuildPhase',True), - ('PBXSourcesBuildPhase',True), - ('XCBuildConfiguration',True), - ('XCConfigurationList',True)] + ('PBXBuildFile',False), + ('PBXCopyFilesBuildPhase',True), + ('PBXFileReference',False), + ('PBXFrameworksBuildPhase',True), + ('PBXGroup',True), + ('PBXNativeTarget',True), + ('PBXProject',True), + ('PBXResourcesBuildPhase',True), + ('PBXShellScriptBuildPhase',True), + ('PBXSourcesBuildPhase',True), + ('XCBuildConfiguration',True), + ('XCConfigurationList',True), + ('PBXTargetDependency', True), + ('PBXVariantGroup', True), + ('PBXReferenceProxy', True), + ('PBXContainerItemProxy', True)] - for section in sections: #iterate over the sections + for section in sections: #iterate over the sections if(self.sections.get(section[0]) == None): continue; out.write('\n/* Begin %s section */'%section[0]); self.sections.get(section[0]).sort(cmp=lambda x,y: cmp(x[0],y[0])) - #if(self.sections.get(section[0])=='PBXGroup' and ): //add the patch to add the missing but existing files. + #if(self.sections.get(section[0])=='PBXGroup' and ): //add the patch to add the missing but existing files. for pair in self.sections.get(section[0]): key = pair[0] @@ -1206,7 +1226,7 @@ class XcodeProject(PBXDict): out.write('"'+XcodeProject.addslashes(root)+'"') if(root in self.uuids): out.write(" /* "+self.uuids[root]+" */"); - + @classmethod def getJSONFromXML(cls, root): result = '' @@ -1232,7 +1252,7 @@ class XcodeProject(PBXDict): for child in root.childNodes: if child.nodeType != Node.ELEMENT_NODE: continue; - + if(i>0): result += "," result += XcodeProject.getJSONFromXML(child); @@ -1242,28 +1262,28 @@ class XcodeProject(PBXDict): data = '""' for node in root.childNodes: if node.nodeType == node.TEXT_NODE: - data = '"'+XcodeProject.addslashes(node.data).replace('\n','\\n')+'"' + data = '"'+XcodeProject.addslashes(node.data).replace('\n','\\n').replace('\\\'', '\'')+'"' break result += data return result; - + @classmethod def Load(cls, path): cls.plutil_path = os.path.join(os.path.split(__file__)[0], 'plutil') - + if not os.path.isfile(XcodeProject.plutil_path): cls.plutil_path = 'plutil' - + if subprocess.call([XcodeProject.plutil_path,'-lint','-s',path]): print 'ERROR: not a valid .pbxproj file' return None - + # load project by converting to JSON and parse p = subprocess.Popen([XcodeProject.plutil_path, '-convert', 'xml1', '-o', '-', path], stdout=subprocess.PIPE) rawXML = p.communicate()[0] - + xml = parseString(rawXML); jsonStr = XcodeProject.getJSONFromXML(xml.getElementsByTagName('dict')[0]); - + tree = json.loads(jsonStr) return XcodeProject(tree, path) diff --git a/Tools/XcodeCapp/XcodeCapp/Scripts/parser.j b/Tools/XcodeCapp/XcodeCapp/Scripts/parser.j index 43040dab9..205d248c3 100644 --- a/Tools/XcodeCapp/XcodeCapp/Scripts/parser.j +++ b/Tools/XcodeCapp/XcodeCapp/Scripts/parser.j @@ -2,7 +2,7 @@ * parser.j * * Created by Francisco Tolmasky. - * Modified by Antoine Mercadal, with great help of Martin Carlberg + * Modified by Antoine Mercadal, with great help from Martin Carlberg * Copyright 2008-2013, 280 North, Inc. * * This library is free software; you can redistribute it and/or @@ -23,7 +23,9 @@ @import var FILE = require("file"), - OS = require("os"); + OS = require("os"), + + SLASH_REPLACEMENT = "∕"; // DIVISION SLASH, Unicode: U+2215 // Debug function to print some JS objects function dump(obj) @@ -35,22 +37,23 @@ function raise(pos, message) { var syntaxError = new SyntaxError(message); syntaxError.line = pos.line; - syntaxError.column = pos.column; - syntaxError.lineStart = pos.lineStart; - syntaxError.lineEnd = pos.lineEnd; throw syntaxError; } var hasWarnings = false, + errors = [], xcc = ObjectiveJ.acorn.walk.make( { ClassDeclarationStatement: function(node, st, c) { if (node.categoryname) { - print("Line " + node.loc.start.line + ", " + node.loc.source); - print("Categories are not supported yet. Ignoring it."); + [errors addObject:@{ + @"message": "Categories are not supported yet, ignoring it.", + @"path": node.loc.source, + @"line": node.loc.start.line + }]; hasWarnings = true; return; } @@ -135,18 +138,25 @@ function compile(node, state, visitor) c(node, state); }; +function shadowBaseNameForPath(path) +{ + // strip the extension and replace slashes + return path.substring(0, path.length - 2).replace(/[/]/g, SLASH_REPLACEMENT); +} function main(args) { try { var fileURL = new CFURL(args[1]), - outputBaseURL = new CFURL(args[2]), - outputHeaderURL = new CFURL(outputBaseURL.path() + ".h"), - outputSourceURL = new CFURL(outputBaseURL.path() + ".m"), + outputDirectory = args[2], + baseFilename = shadowBaseNameForPath(fileURL.path()), + outputHeaderURL = new CFURL([outputDirectory stringByAppendingPathComponent:baseFilename + ".h"]), + outputImplementationURL = new CFURL([outputDirectory stringByAppendingPathComponent:baseFilename + ".m"]), source = FILE.read(fileURL, { charset: "UTF-8" }), flags = ObjectiveJ.Preprocessor.Flags.IncludeDebugSymbols | ObjectiveJ.Preprocessor.Flags.IncludeTypeSignatures, - tokens = ObjectiveJ.acorn.parse(source, { locations:true, sourceFile:fileURL.path() }), + sourceFile = fileURL.path(), + tokens = ObjectiveJ.acorn.parse(source, { locations:true, sourceFile:sourceFile }), classesInformation = [], ObjectiveCSource = "", ObjectiveCHeader = ""; @@ -158,54 +168,65 @@ function main(args) ObjectiveCHeader += "#import \n" + "#import \n" + - "#import \"xcc_general_include.h\"\n\n"; + '#import "xcc_general_include.h"\n'; - ObjectiveCSource += "#import \"" + outputHeaderURL.lastPathComponent() + "\"\n\n"; + ObjectiveCSource += "#import \"" + outputHeaderURL.lastPathComponent() + "\"\n"; // Traverse each found classes classesInformation.forEach(function(aClass) { // add new class definition - ObjectiveCHeader += "@interface " + aClass.name + " : " + NSCompatibleClassName(aClass.superClass) + "\n\n"; + ObjectiveCHeader += [CPString stringWithFormat:@"\n@interface %@ : %@", aClass.name, NSCompatibleClassName(aClass.superClass)]; + + // add each outlet in header + if (aClass.outlets.length > 0) + ObjectiveCHeader += "\n"; - // Add each outlets in header aClass.outlets.forEach(function(anOutlet) { - ObjectiveCHeader += "@property (assign) IBOutlet " + NSCompatibleClassName(anOutlet.type, YES) + " " + anOutlet.name + ";\n"; + ObjectiveCHeader += [CPString stringWithFormat:@"\n@property (assign) IBOutlet %@ %@;", NSCompatibleClassName(anOutlet.type, YES), anOutlet.name]; }); - ObjectiveCHeader += "\n"; + if (aClass.actions.length > 0) + ObjectiveCHeader += "\n"; - // Add each actions in header + // add each action in header aClass.actions.forEach(function(anAction) { - ObjectiveCHeader += "- (IBAction)" + anAction.name + ":(" + anAction.arguments[0].type + ")" + anAction.arguments[0].name + ";\n"; + ObjectiveCHeader += [CPString stringWithFormat:@"\n- (IBAction)%@:(%@)%@;", anAction.name, anAction.arguments[0].type, anAction.arguments[0].name]; }); - ObjectiveCHeader += "\n@end\n\n\n"; + if (aClass.outlets.length > 0 || aClass.actions.length > 0) + ObjectiveCHeader += "\n"; + + ObjectiveCHeader += "\n@end\n"; // fill up the implementation file - ObjectiveCSource += "@implementation " + aClass.name + "\n@end\n\n"; + ObjectiveCSource += "\n@implementation " + aClass.name + "\n@end\n"; }); - // write files - if (ObjectiveCSource.length) - FILE.write(outputSourceURL, ObjectiveCSource, { charset:"UTF-8" }); + if (ObjectiveCSource.length) + FILE.write(outputImplementationURL, ObjectiveCSource, { charset:"UTF-8" }); - if (ObjectiveCHeader.length) - FILE.write(outputHeaderURL, ObjectiveCHeader, { charset:"UTF-8" }); + if (ObjectiveCHeader.length) + FILE.write(outputHeaderURL, ObjectiveCHeader, { charset:"UTF-8" }); } catch (e) { - if (e instanceof SyntaxError) - print("Line " + e.line + ", " + fileURL.path()); - - print(e.name + ": " + e.message); - OS.exit(1); + [errors addObject:@{ + @"message": e.message, + @"path": sourceFile, + @"line": e.line + }]; } - if (hasWarnings) - OS.exit(2); + if ([errors count]) + { + var plist = [CPPropertyListSerialization dataFromPropertyList:errors format:CPPropertyListXMLFormat_v1_0]; + + print([plist rawString]); + OS.exit(1); + } } function NSCompatibleClassName(aClassName, asPointer) diff --git a/Tools/XcodeCapp/XcodeCapp/Scripts/pbxprojModifier.py b/Tools/XcodeCapp/XcodeCapp/Scripts/pbxprojModifier.py index 09137f9d4..895035240 100755 --- a/Tools/XcodeCapp/XcodeCapp/Scripts/pbxprojModifier.py +++ b/Tools/XcodeCapp/XcodeCapp/Scripts/pbxprojModifier.py @@ -4,40 +4,64 @@ import re import sys from mod_pbxproj import XcodeProject -XCODESUPPORTFOLDER = ".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/([^/]+))/.+$") +XCC_GENERAL_INCLUDE = u"xcc_general_include.h" -def update_general_include(project, projectBasePath): - xcc_general_include_file = os.path.join(projectBasePath, XCODESUPPORTFOLDER, u"xcc_general_include.h") +def update_general_include(project, projectBasePath, shadowGroup): + xcc_general_include_path = os.path.join(projectBasePath, XCODE_SUPPORT_FOLDER, XCC_GENERAL_INCLUDE) content = u"" - for file in os.listdir(os.path.join(projectBasePath, XCODESUPPORTFOLDER)): - if file.endswith(".h"): - content += u'#include "{0}"\n'.format(os.path.basename(unicode(file))) + for path in os.listdir(os.path.join(projectBasePath, XCODE_SUPPORT_FOLDER)): + filename = unicode(os.path.basename(path)) - f = open(xcc_general_include_file, "w") + if filename.endswith(".h") and filename != XCC_GENERAL_INCLUDE: + content += u'#include "{0}"\n'.format(filename) + + f = open(xcc_general_include_path, "w") f.write(content.encode("utf-8")) f.close() - if len(project.get_files_by_os_path(os.path.join(XCODESUPPORTFOLDER, os.path.basename(xcc_general_include_file)))) == 0: - project.add_file(xcc_general_include_file, parent=shadowGroup) + if len(project.get_files_by_os_path(os.path.join(XCODE_SUPPORT_FOLDER, XCC_GENERAL_INCLUDE))) == 0: + project.add_file(xcc_general_include_path, parent=shadowGroup) -def add_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationFilePath, sourcePath, projectBasePath): - project.add_file(shadowHeaderPath, parent=shadowGroup) - project.add_file(shadowImplementationFilePath, parent=shadowGroup) +def file_with_path(path, projectPath, project): + relPath = os.path.relpath(path, projectPath) - if sourcePath in project.get_files_by_os_path(os.path.relpath(sourcePath, projectBasePath)): - return + for fileRef in [f for f in project.objects.values() if f.get("isa") == "PBXFileReference"]: + filePath = path if fileRef.get("sourceTree") == "" else relPath - project.add_file(sourcePath, parent=sourceGroup) + if fileRef.get("path") == filePath: + return fileRef -def remove_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationFilePath, sourcePath, projectBasePath): - project.remove_file(os.path.join(XCODESUPPORTFOLDER, os.path.basename(shadowHeaderPath)), parent=shadowGroup) - project.remove_file(os.path.join(XCODESUPPORTFOLDER, os.path.basename(shadowImplementationFilePath)), parent=shadowGroup) - project.remove_file(os.path.relpath(sourcePath, projectBasePath), parent=sourceGroup) + return None + +def add_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationPath, sourcePath, projectBasePath): + # Shadow files are always project-relative + if not file_with_path(shadowHeaderPath, projectBasePath, project): + project.add_file(shadowHeaderPath, parent=shadowGroup, tree="SOURCE_ROOT", create_build_files=False) + + if not file_with_path(shadowImplementationPath, projectBasePath, project): + project.add_file(shadowImplementationPath, parent=shadowGroup, tree="SOURCE_ROOT", create_build_files=False) + + # If the file is within the project directory, the file reference will be project-relative, otherwise absolute + if sourcePath.startswith(projectBasePath): + tree = "SOURCE_ROOT" + else: + tree = "" + + if not file_with_path(sourcePath, projectBasePath, project): + project.add_file(sourcePath, parent=sourceGroup, tree=tree, create_build_files=False) + +def remove_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationPath, sourcePath, projectBasePath): + for path in (shadowHeaderPath, shadowImplementationPath, sourcePath): + fileRef = file_with_path(path, projectBasePath, project) + + if fileRef: + project.remove_file(fileRef) def xml_converter(matchObj): return "{0}".format(matchObj.group(1).encode('ascii', 'xmlcharrefreplace')) @@ -66,6 +90,10 @@ def add_framework_resources(project, resourcesPath): framework = os.path.basename(os.path.dirname(resourcesPath)) files[0]['name'] = framework + " Resources" +def save_project(project, pbxPath): + project.save() + convert_unicode_to_xml(pbxPath) + if __name__ == "__main__": @@ -76,10 +104,10 @@ if __name__ == "__main__": projectSourcePath = unicode(sys.argv[3]) sourcePath = os.path.realpath(projectSourcePath) - shadowBasePath = os.path.join(projectBasePath, ".XcodeSupport") - shadowBasename = os.path.splitext(sourcePath)[0].replace(u"/", SLASH_REPLACEMENT) - shadowHeaderPath = os.path.join(shadowBasePath, shadowBasename + ".h") - shadowImplementationPath = os.path.join(shadowBasePath, shadowBasename + ".m") + shadowBasePath = os.path.join(projectBasePath, XCODE_SUPPORT_FOLDER) + shadowBaseName = os.path.splitext(sourcePath)[0].replace(u"/", SLASH_REPLACEMENT) + shadowHeaderPath = os.path.join(shadowBasePath, shadowBaseName + ".h") + shadowImplementationPath = os.path.join(shadowBasePath, shadowBaseName + ".m") projectName = os.path.basename(projectBasePath) pbxPath = os.path.join(projectBasePath, projectName + ".xcodeproj", "project.pbxproj") @@ -88,11 +116,11 @@ if __name__ == "__main__": shadowGroup = project.get_or_create_group("Classes") sourceGroup = project.get_or_create_group("Sources") - files = project.get_files_by_os_path(os.path.join(XCODESUPPORTFOLDER, os.path.basename(shadowHeaderPath))) - if action == "add": - if len(files) == 0: - update_general_include(project, projectBasePath) + fileRef = file_with_path(shadowHeaderPath, projectBasePath, project) + + if not fileRef: + update_general_include(project, projectBasePath, shadowGroup) add_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationPath, sourcePath, projectBasePath) match = FRAMEWORKS_RE.match(projectSourcePath) @@ -104,10 +132,9 @@ if __name__ == "__main__": if os.path.isdir(resourcesPath): add_framework_resources(project, resourcesPath) - project.save() - convert_unicode_to_xml(pbxPath) + save_project(project, pbxPath) - elif action == "remove" and len(files) == 1: - update_general_include(project, projectBasePath) + elif action == "remove": + update_general_include(project, projectBasePath, shadowGroup) remove_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationPath, sourcePath, projectBasePath) - project.save() + save_project(project, pbxPath) diff --git a/Tools/XcodeCapp/XcodeCapp/TNXCodeCapp.h b/Tools/XcodeCapp/XcodeCapp/TNXCodeCapp.h new file mode 100644 index 000000000..7a66855b5 --- /dev/null +++ b/Tools/XcodeCapp/XcodeCapp/TNXCodeCapp.h @@ -0,0 +1,74 @@ +/* + * This file is a part of program XcodeCapp + * Copyright (C) 2011 Antoine Mercadal () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import +#import + +enum XCCAPIMode { + kXCCAPIModeAuto = 0, + kXCCAPIModeFile, + kXCCAPIModeFolder +}; + +extern NSString * const XCCDidPopulateProjectNotification; +extern NSString * const XCCConversionDidStartNotification; +extern NSString * const XCCConversionDidStopNotification; +extern NSString * const XCCListeningDidStartNotification; + + +@interface TNXcodeCapp : NSObject + +@property NSURL* XcodeSupportProjectURL; +@property NSString* currentProjectPath; +@property NSString* currentAPIMode; +@property BOOL supportsFileBasedListening; +@property BOOL reactToInodeModification; +@property BOOL isListening; +@property BOOL supportsFileLevelAPI; +@property BOOL isUsingFileLevelAPI; +@property BOOL isLoadingProject; +@property NSMutableArray* errorList; + +@property (unsafe_unretained) IBOutlet NSTableView *errorTable; +@property (strong) IBOutlet NSPanel *errorsPanel; +@property (strong) IBOutlet NSArrayController *errorListController; + +- (IBAction)openErrorsPanel:(id)sender; +- (IBAction)clearErrors:(id)sender; +- (IBAction)openErrorInEditor:(id)sender; +- (void)start; +- (void)stop; +- (void)listenToProjectAtPath:(NSString *)path; +- (void)updateLastEventId:(uint64_t)eventId; +- (BOOL)pathMatchesIgnoredPaths:(NSString*)aPath; +- (BOOL)isObjjFile:(NSString *)path; +- (BOOL)isXibFile:(NSString *)path; +- (BOOL)isXCCIgnoreFile:(NSString *)path; +- (void)tidyShadowedFiles; +- (void)handleFileModificationAtPath:(NSString*)path notify:(BOOL)shouldNotify; +- (void)handleFileRemovalAtPath:(NSString*)path; +- (void)updateUserDefaultsWithLastEventId; + +@end + +@interface TNXcodeCapp (SnowLeopard) + +- (void)updateLastModificationDate:(NSDate *)date forPath:(NSString *)path; +- (NSDate *)lastModificationDateForPath:(NSString *)path; + +@end diff --git a/Tools/XcodeCapp/XcodeCapp/TNXcodeCapp.m b/Tools/XcodeCapp/XcodeCapp/TNXcodeCapp.m new file mode 100644 index 000000000..2b93be124 --- /dev/null +++ b/Tools/XcodeCapp/XcodeCapp/TNXcodeCapp.m @@ -0,0 +1,1142 @@ +/* + * This file is a part of program XcodeCapp + * Copyright (C) 2011 Antoine Mercadal () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import + +#import "TNXcodeCapp.h" +#import "FSEventCallback.h" +#import "UserDefaults.h" + +#include "macros.h" + +enum XCCTaskReturnType { + kTaskReturnTypeNone, + kTaskReturnTypeStdOut, + kTaskReturnTypeStdError +}; +typedef enum XCCTaskReturnType XCCTaskReturnType; + +enum XCCLineSpecifier { + kLineSpecifierNone, + kLineSpecifierColon, + kLineSpecifierMinusL, + kLineSpecifierPlus +}; +typedef enum XCCLineSpecifier XCCLineSpecifier; + +NSString * const XCCDidPopulateProjectNotification = @"XCCDidPopulateProjectNotification"; +NSString * const XCCConversionDidStartNotification = @"XCCConversionDidStartNotification"; +NSString * const XCCConversionDidStopNotification = @"XCCConversionDidStopNotification"; +NSString * const XCCListeningDidStartNotification = @"XCCListeningDidStartNotification"; + +NSString * const XCCSlashReplacement = @"∕"; // DIVISION SLASH, Unicode: U+2215 +NSString * const XCCBashPath = @"/bin/bash"; +NSString * const XCCZShPath = @"/bin/zsh"; + +NSString * const XCCDirectoriesToIgnorePattern = @"^(?:Build|F(?:rameworks|oundation)|AppKit|Objective-J|(?:Browser|CommonJS)\\.environment|Resources|XcodeSupport|.+\\.xcodeproj)$"; +NSRegularExpression * XCCDirectoriesToIgnoreRegex = nil; + +NSArray *XCCDefaultIgnoredPathRegexes = nil; + + +@interface TNXcodeCapp () + +@property FSEventStreamRef stream; +@property NSFileManager *fm; +@property NSMutableArray *ignoredPathRegexes; +@property NSNumber *lastEventId; +@property NSString *parserPath; +@property NSString *XcodeSupportPBXPath; +@property NSString *XcodeSupportProjectName; +@property NSString *XcodeTemplatePBXPath; +@property NSString *profilePath; +@property NSString *shellPath; +@property NSString *PBXModifierScriptPath; +@property NSString *supportPath; +@property NSDate *appStartedTimestamp; +@property NSMutableDictionary *pathModificationDates; +@property NSMutableDictionary *projectPathsForSourcePaths; + +@end + + +@implementation TNXcodeCapp + +#pragma mark - Initialization + ++ (void)initialize +{ + if (self != [TNXcodeCapp class]) + return; + + NSError *error = NULL; + XCCDirectoriesToIgnoreRegex = [NSRegularExpression regularExpressionWithPattern:XCCDirectoriesToIgnorePattern options:0 error:&error]; + + NSArray *defaultIgnoredPaths = @[ + @"*/Frameworks/", + @"!*/Frameworks/Debug/", + @"*/AppKit/", + @"*/Foundation/", + @"*/Objective-J/", + @"*/*.environment/", + @"*/Build/", + @"*/.*/", + @"*/NS_*.j", + @"*/main.j", + @"*/.*" + ]; + + XCCDefaultIgnoredPathRegexes = [self parseIgnorePaths:defaultIgnoredPaths]; +} + +- (id)init +{ + self = [super init]; + + if (self) + { + self.errorList = [NSMutableArray arrayWithCapacity:10]; + self.fm = [NSFileManager defaultManager]; + self.ignoredPathRegexes = [NSMutableArray new]; + self.parserPath = [[NSBundle mainBundle] pathForResource:@"parser" ofType:@"j"]; + self.lastEventId = [[NSUserDefaults standardUserDefaults] objectForKey:kDefaultLastEventId]; + self.appStartedTimestamp = [NSDate date]; + self.projectPathsForSourcePaths = [NSMutableDictionary new]; + + self.isListening = NO; + self.isUsingFileLevelAPI = NO; + self.isLoadingProject = NO; + + SInt32 versionMajor = 0; + SInt32 versionMinor = 0; + Gestalt(gestaltSystemVersionMajor, &versionMajor); + Gestalt(gestaltSystemVersionMinor, &versionMinor); + + self.supportsFileLevelAPI = versionMajor >= 10 && versionMinor >= 7; + // Uncomment to simulate 10.6 mode + // self.supportsFileLevelAPI = NO; + + [self configureFileAPI]; + [self getShellProfilePath]; + + [GrowlApplicationBridge setGrowlDelegate:self]; + } + + return self; +} + +- (void)start +{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + + if (![defaults boolForKey:kDefaultXCCReopenLastProject]) + return; + + NSString *lastOpenedPath = [defaults objectForKey:kDefaultLastOpenedPath]; + + if (lastOpenedPath) + { + if ([self.fm fileExistsAtPath:lastOpenedPath]) + [self listenToProjectAtPath:lastOpenedPath]; + else + [defaults removeObjectForKey:kDefaultLastOpenedPath]; + } +} + +/*! + Stops the event listener, clears state + */ +- (void)stop +{ + [self stopEventStream]; + [self clearErrors:self]; + [self updateUserDefaultsWithLastEventId]; + [[NSUserDefaults standardUserDefaults] synchronize]; + self.currentProjectPath = nil; + [self.ignoredPathRegexes removeAllObjects]; +} + + +#pragma mark - Project Management + +/*! + Check if XcodeSupport needs to be initialized. + If not needed, check that all .j files are mirrored. + If not, then launch conversion for missing mirrored .h files. + + @return YES if Xcode project exists, NO if not +*/ +- (BOOL)prepareXcodeSupportProject +{ + self.XcodeSupportProjectName = [NSString stringWithFormat:@"%@.xcodeproj", self.currentProjectPath.lastPathComponent]; + self.XcodeTemplatePBXPath = [[NSBundle mainBundle] pathForResource:@"project" ofType:@"pbxproj"]; + + NSURL *projectURL = [NSURL fileURLWithPath:self.currentProjectPath]; + self.XcodeSupportProjectURL = [NSURL URLWithString:self.XcodeSupportProjectName relativeToURL:projectURL]; + self.supportPath = [[NSURL URLWithString:@"XcodeSupport" relativeToURL:projectURL] path]; + self.XcodeSupportPBXPath = [self.XcodeSupportProjectURL.path stringByAppendingPathComponent:@"project.pbxproj"]; + self.PBXModifierScriptPath = [[NSBundle mainBundle] pathForResource:@"pbxprojModifier" ofType:@"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); + [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); + [self.fm copyItemAtPath:self.XcodeTemplatePBXPath toPath:self.XcodeSupportPBXPath error:nil]; + + DLog(@"%@ Reading the content of the project.pbxproj", NSStringFromSelector(_cmd)); + 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)); + + [self.fm createDirectoryAtPath:self.supportPath withIntermediateDirectories:YES attributes:nil error:nil]; + + return NO; + } + + return YES; +} + +/*! + Create and initialize the Xcode project. + + @param shouldNotify If YES, XCCDidPopulateProjectNotification will be sent +*/ +- (void)populateXcodeProject:(BOOL)shouldNotify +{ + if (shouldNotify) + [self growlWithTitle:@"Loading project" message:self.currentProjectPath.lastPathComponent]; + + // First populate with all non-framework code + [self populateXcodeProjectWithProjectRelativePath:@""]; + + // Now populate with any user source debug frameworks + [self populateXcodeProjectWithProjectRelativePath:@"Frameworks/Debug"]; + + // Now populate with any source frameworks + [self populateXcodeProjectWithProjectRelativePath:@"Frameworks/Source"]; + + // Now populate resources + [self populateXcodeProjectWithProjectRelativePath:@"Resources"]; + + if (shouldNotify) + { + [[NSNotificationCenter defaultCenter] postNotificationName:XCCDidPopulateProjectNotification object:self userInfo:nil]; + [self growlWithTitle:@"Project loaded" message:self.currentProjectPath.lastPathComponent]; + } +} + +- (void)populateXcodeProjectWithProjectRelativePath:(NSString *)aProjectPath +{ + NSError *error = NULL; + NSString *projectPath = [self.currentProjectPath stringByAppendingPathComponent:aProjectPath]; + + NSArray *urls = [self.fm contentsOfDirectoryAtURL:[NSURL fileURLWithPath:[projectPath stringByResolvingSymlinksInPath]] + includingPropertiesForKeys:@[NSURLIsDirectoryKey, NSURLIsSymbolicLinkKey] + options:NSDirectoryEnumerationSkipsHiddenFiles | NSDirectoryEnumerationSkipsPackageDescendants | NSDirectoryEnumerationSkipsSubdirectoryDescendants + error:&error]; + + if (!urls) + return; + + for (NSURL *url in urls) + { + NSString *filename = url.lastPathComponent; + + NSString *projectRelativePath = [aProjectPath stringByAppendingPathComponent:filename]; + NSString *realPath = url.path; + NSURL *resolvedURL = url; + + NSNumber *isDirectory, *isSymlink; + [url getResourceValue:&isSymlink forKey:NSURLIsSymbolicLinkKey error:nil]; + + if (isSymlink.boolValue == YES) + { + resolvedURL = [url URLByResolvingSymlinksInPath]; + + if ([resolvedURL checkResourceIsReachableAndReturnError:nil]) + { + filename = resolvedURL.lastPathComponent; + realPath = resolvedURL.path; + } + else + continue; + } + + [resolvedURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil]; + + if (isDirectory.boolValue == YES) + { + if ([XCCDirectoriesToIgnoreRegex numberOfMatchesInString:filename options:0 range:NSMakeRange(0, filename.length)] > 0) + continue; + + // If the resolved path is not within the project directory, add a mapping to it + // so we can map the resolved path back to the project directory later. + if (isSymlink.boolValue == YES) + { + NSString *fullProjectPath = [self.currentProjectPath stringByAppendingPathComponent:projectRelativePath]; + + if (![realPath hasPrefix:fullProjectPath]) + self.projectPathsForSourcePaths[realPath] = fullProjectPath; + } + + [self populateXcodeProjectWithProjectRelativePath:projectRelativePath]; + continue; + } + + if ([self pathMatchesIgnoredPaths:realPath]) + continue; + + NSString *projectSourcePath = [self.currentProjectPath stringByAppendingPathComponent:projectRelativePath]; + + if ([self isObjjFile:filename] || [self isXibFile:filename]) + { + NSString *processedPath; + + if ([self isObjjFile:filename]) + processedPath = [[self shadowBasePathForSourcePath:realPath] stringByAppendingPathExtension:@"h"]; + else + processedPath = [[realPath stringByDeletingPathExtension] stringByAppendingPathExtension:@"cib"]; + + if (![self.fm fileExistsAtPath:processedPath]) + [self processModifiedFileAtPath:realPath projectSourcePath:projectSourcePath notify:YES]; + } + } +} + +- (void)listenToProjectAtPath:(NSString *)path +{ + self.isLoadingProject = YES; + + [self clearErrors:self]; + self.currentProjectPath = path; + self.projectPathsForSourcePaths = [NSMutableDictionary new]; + [self computeIgnoredPaths]; + + BOOL isProjectReady = [self prepareXcodeSupportProject]; + [self populateXcodeProject:!isProjectReady]; + + self.isLoadingProject = NO; + + [self initializeEventStreamWithPath:self.currentProjectPath]; + + NSDictionary *info = @{ @"path": path, @"ready": [NSNumber numberWithBool:isProjectReady] }; + [[NSNotificationCenter defaultCenter] postNotificationName:XCCListeningDidStartNotification object:self userInfo:info]; + + [[NSUserDefaults standardUserDefaults] setObject:self.currentProjectPath forKey:kDefaultLastOpenedPath]; + + [self growlWithTitle:@"Listening to project" message:self.currentProjectPath.lastPathComponent]; +} + + +#pragma mark - Event Stream + +/*! + Initializes the FSEvent stream + + @param path the path of the folder to watch + */ +- (void)initializeEventStreamWithPath:(NSString *)path +{ + if (self.isListening) + return; + + [self stopEventStream]; + + NSMutableArray *pathsToWatch = [NSMutableArray arrayWithObject:path]; + FSEventStreamCreateFlags flags = 0; + + if (self.supportsFileBasedListening) + { + DLog(@"%@ Initializing the FSEventStream at file level (clean)", NSStringFromSelector(_cmd)); + flags = kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents; + } + else + { + NSLog(@"Initializing the FSEventStream at folder level (dirty)"); + flags = kFSEventStreamCreateFlagUseCFTypes; + } + + NSArray *directoriesToWatch = @[@"", @"Frameworks/Debug", @"Frameworks/Source"]; + + for (NSString *directory in directoriesToWatch) + { + NSString *fullPath = [self.currentProjectPath stringByAppendingPathComponent:directory]; + + BOOL exists, isDirectory; + exists = [self.fm fileExistsAtPath:fullPath isDirectory:&isDirectory]; + + if (exists && isDirectory) + [self watchSymlinkedDirectoriesAtPath:directory pathsToWatch:pathsToWatch]; + } + + void *appPointer = (__bridge void *)self; + FSEventStreamContext context = { 0, appPointer, NULL, NULL, NULL }; + CFTimeInterval latency = 2.0; + + self.stream = FSEventStreamCreate(NULL, &fsevents_callback, &context, (__bridge CFArrayRef) pathsToWatch, + self.lastEventId.unsignedLongLongValue, latency, flags); + + FSEventStreamScheduleWithRunLoop(self.stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + FSEventStreamStart(self.stream); + self.isListening = YES; +} + +- (void)watchSymlinkedDirectoriesAtPath:(NSString *)projectPath pathsToWatch:(NSMutableArray *)pathsToWatch +{ + NSString *fullProjectPath = [self.currentProjectPath stringByAppendingPathComponent:projectPath]; + NSError *error = NULL; + + NSArray *urls = [self.fm contentsOfDirectoryAtURL:[NSURL fileURLWithPath:fullProjectPath] + includingPropertiesForKeys:@[NSURLIsDirectoryKey, NSURLIsSymbolicLinkKey] + options:NSDirectoryEnumerationSkipsHiddenFiles | NSDirectoryEnumerationSkipsPackageDescendants | NSDirectoryEnumerationSkipsSubdirectoryDescendants + error:&error]; + + for (NSURL *url in urls) + { + NSNumber *isSymlink; + [url getResourceValue:&isSymlink forKey:NSURLIsSymbolicLinkKey error:nil]; + + if (isSymlink.boolValue == YES) + { + NSURL *resolvedURL = [url URLByResolvingSymlinksInPath]; + + if ([resolvedURL checkResourceIsReachableAndReturnError:nil]) + { + NSNumber *isDirectory; + [resolvedURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil]; + + if (isDirectory.boolValue == YES) + { + NSString *filename = resolvedURL.lastPathComponent; + + if ([XCCDirectoriesToIgnoreRegex numberOfMatchesInString:filename options:0 range:NSMakeRange(0, filename.length)] == 0) + [pathsToWatch addObject:resolvedURL.path]; + } + } + } + } +} + +- (void)stopEventStream +{ + if (self.stream) + { + FSEventStreamStop(self.stream); + FSEventStreamUnscheduleFromRunLoop(self.stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + FSEventStreamInvalidate(self.stream); + FSEventStreamRelease(self.stream); + self.stream = NULL; + } + + self.isListening = NO; +} + +/*! + Choose the API mode according to default + */ +- (void)configureFileAPI +{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + + if (!self.supportsFileLevelAPI) + { + DLog(@"%@ System doesn't support file level API", NSStringFromSelector(_cmd)); + [defaults setObject:[NSNumber numberWithInt:kXCCAPIModeFolder] forKey:kDefaultXCCAPIMode]; + } + + switch ([defaults integerForKey:kDefaultXCCAPIMode]) + { + case kXCCAPIModeAuto: + self.supportsFileBasedListening = self.supportsFileLevelAPI; + break; + + case kXCCAPIModeFile: + self.supportsFileBasedListening = YES; + break; + + case kXCCAPIModeFolder: + self.supportsFileBasedListening = NO; + break; + } + + if (self.supportsFileBasedListening) + { + DLog(@"%@ using 10.7+ mode listening (clean)", NSStringFromSelector(_cmd)); + + self.currentAPIMode = @"File level (Lion)"; + self.isUsingFileLevelAPI = YES; + self.reactToInodeModification = [defaults boolForKey:kDefaultXCCReactMode]; + } + else + { + DLog(@"%@ using 10.6 mode listening (dirty)", NSStringFromSelector(_cmd)); + self.reactToInodeModification = NO; + self.currentAPIMode = @"Folder level (Snow Leopard)"; + self.isUsingFileLevelAPI = NO; + } +} + +/*! + Update the last event ID. We use a method because + this is called from outside the class, in the FSEvent callback. + + @param eventId the current event ID value +*/ +- (void)updateLastEventId:(uint64_t)eventId +{ + self.lastEventId = [NSNumber numberWithUnsignedLongLong:eventId]; +} + +/*! + Updates the user defaults with the last recorded event Id. +*/ +- (void)updateUserDefaultsWithLastEventId +{ + if (self.lastEventId && self.lastEventId.longLongValue != 0) + [[NSUserDefaults standardUserDefaults] setObject:self.lastEventId forKey:kDefaultLastEventId]; +} + + +#pragma mark - Shell Helpers + +/*! + Run an NSTask with the given arguments + + @param arguments NSArray containing the NSTask arguments + @return NSarray containing the return status (int) and the response (string) + */ +- (NSDictionary *)runTaskWithLaunchPath:(NSString *)launchPath arguments:(NSArray *)arguments returnType:(XCCTaskReturnType)returnType +{ + NSTask *task = [NSTask new]; + + task.launchPath = launchPath; + task.arguments = arguments; + task.standardOutput = [NSPipe pipe]; + task.standardError = [NSPipe pipe]; + [task launch]; + + if (returnType != kTaskReturnTypeNone) + { + [task waitUntilExit]; + + NSData *data = [[(returnType == kTaskReturnTypeStdOut ? task.standardOutput : task.standardError) fileHandleForReading] availableData]; + NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSNumber *status = [NSNumber numberWithInt:task.terminationStatus]; + + return @{ @"status":status, @"response":response }; + } + else + { + return @{ @"status":@0, @"response":@"" }; + } +} + +- (void)getShellProfilePath +{ + NSString* myShell = [[[NSProcessInfo processInfo] environment] objectForKey:@"SHELL"]; + self.shellPath = myShell ? myShell : XCCBashPath; + self.profilePath = @""; + NSArray *profiles; + NSString *path; + + if ([self.shellPath hasSuffix:@"/bash"]) + { + profiles = @[@"~/.bash_profile", @"~/.bashrc", @"~/.profile"]; + } + else if ([self.shellPath hasSuffix:@"/zsh"]) + { + profiles = @[@"~/.zshrc", @"~/.profile"]; + } + else + { + NSAlert *alert = [NSAlert alertWithMessageText:@"Unsupported shell." + defaultButton:@"OK" + alternateButton:nil + otherButton:nil + informativeTextWithFormat:@"You are using %@ as your shell. XcodeCapp requires either bash or zsh to run.", self.shellPath]; + [alert runModal]; + + [[NSRunningApplication currentApplication] terminate]; + return; + } + + for (NSString *profile in profiles) + { + path = [profile stringByExpandingTildeInPath]; + + if ([self.fm fileExistsAtPath:path]) + { + self.profilePath = path; + return; + } + } +} + +#pragma mark - Event Handlers + +/*! + Handle a file modification. If it's a .j or xib/nib, + perform the appropriate conversion. If it's .xcodecapp-ignore, it will + update the list of ignored files. + + @param fullPath The full path of the modified file + @param shouldNotify If YES, Growl notifications will be displayed +*/ +- (void)handleFileModificationAtPath:(NSString*)path notify:(BOOL)shouldNotify +{ + if (![self isXibFile:path] && ![self isObjjFile:path] && ![self isXCCIgnoreFile:path]) + return; + + if ([self pathMatchesIgnoredPaths:path] || ![self.fm fileExistsAtPath:path]) + return; + + NSString *projectPath = [self projectPathForSourcePath:path]; + BOOL success = [self processModifiedFileAtPath:path projectSourcePath:projectPath notify:shouldNotify]; + + if (success) + [self growlWithTitle:@"File successfully processed" message:path.lastPathComponent]; +} + +- (BOOL)processModifiedFileAtPath:(NSString *)realSourcePath projectSourcePath:(NSString *)projectSourcePath notify:(BOOL)shouldNotify +{ + DLog(@"Processing modified file: %@", realSourcePath); + + BOOL success = YES; + + NSArray *arguments = nil; + NSArray *pbxArguments = nil; + NSString *growlTitle = nil; + NSString *growlMessage = nil; + NSString *response = nil; + + NSString *projectRelativePath = [projectSourcePath substringFromIndex:self.currentProjectPath.length + 1]; + + [[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]; + [self.errorListController removeObjectsAtArrangedObjectIndexes:matchingErrors]; + + if ([self isXibFile:realSourcePath]) + { + arguments = @[ + @"-c", + [NSString stringWithFormat:@"source '%@'; nib2cib --no-colors '%@'", self.profilePath, realSourcePath], + @"" + ]; + + growlTitle = @"Converting xib..."; + growlMessage = projectRelativePath.lastPathComponent; + } + else if ([self isObjjFile:realSourcePath]) + { + arguments = @[ + @"-c", + [NSString stringWithFormat:@"(source '%@'; objj '%@' '%@' '%@') 2>&1", + self.profilePath, + self.parserPath, + realSourcePath, + self.supportPath] + ]; + + pbxArguments = @[ + @"-c", + [NSString stringWithFormat:@"(source '%@'; python '%@' add '%@' '%@') 2>&1", + self.profilePath, + self.PBXModifierScriptPath, + self.currentProjectPath, + projectSourcePath] + ]; + + growlTitle = @"Processing Objective-J source..."; + growlMessage = projectRelativePath.lastPathComponent; + } + else if ([self isXCCIgnoreFile:realSourcePath]) + { + [self computeIgnoredPaths]; + growlTitle = @"Parsing .xcodecapp-ignore..."; + growlMessage = @"Updating ignored paths"; + arguments = nil; + } + + // Run the task and get the response if needed + if (arguments) + { + DLog(@"%@ Running conversion task...", NSStringFromSelector(_cmd)); + + [self growlWithTitle:growlTitle message:growlMessage]; + + NSDictionary *taskResult = [self runTaskWithLaunchPath:self.shellPath + arguments:arguments + returnType:[self isObjjFile:realSourcePath] ? kTaskReturnTypeStdOut : kTaskReturnTypeStdError]; + + NSInteger status = [taskResult[@"status"] intValue]; + response = taskResult[@"response"]; + + DLog(@"%@ Conversion task result/response: %ld/%@", NSStringFromSelector(_cmd), status, response); + + if (status != 0) + { + success = NO; + + if (response.length == 0) + response = @"An unspecified error occurred"; + + if ([self isXibFile:realSourcePath]) + { + NSString *message = [NSString stringWithFormat:@"%@\n%@", realSourcePath.lastPathComponent, response]; + [self.errorListController addObject:@{ @"message":message, @"path":realSourcePath }]; + } + else + { + 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"]]; + [self.errorListController addObject:newError]; + } + } + + if ([[NSUserDefaults standardUserDefaults] boolForKey:kDefaultXCCAutoOpenErrorsPanel]) + [self openErrorsPanel:self]; + + [self growlWithTitle:@"Error processing file" message:projectRelativePath.lastPathComponent]; + } + } + + if (pbxArguments) + { + DLog(@"%@ Running update PBX task...", NSStringFromSelector(_cmd)); + NSDictionary *taskResult = [self runTaskWithLaunchPath:self.shellPath arguments:pbxArguments returnType:kTaskReturnTypeStdOut]; + DLog(@"%@ Update PBX Task result/response: %@/%@", NSStringFromSelector(_cmd), taskResult[@"status"], taskResult[@"response"]); + } + + [[NSNotificationCenter defaultCenter] postNotificationName:XCCConversionDidStopNotification object:self]; + DLog(@"%@ Processed: %@", NSStringFromSelector(_cmd), realSourcePath); + + return success; +} + +/*! + Handle a file deletion. If it's a .j, it will + remove the shadowed .h file. If it's .xcodecapp-ignore + it will reset the list of ignored files. + + @param fullPath the full path of the modified file + @param shouldNotify if YES, Growl notifications will be displayed +*/ +- (void)handleFileRemovalAtPath:(NSString*)path +{ + if ([self pathMatchesIgnoredPaths:path] || [self.fm fileExistsAtPath:path]) + return; + + if ([self isObjjFile:path]) + { + [self removeReferencesToSourcePath:path]; + [self growlWithTitle:@"Removed Objective-J file" message:path.lastPathComponent]; + } + else if ([self isXCCIgnoreFile:path]) + [self computeIgnoredPaths]; +} + +#pragma mark - Source Files Management + +- (BOOL)isObjjFile:(NSString *)path +{ + return [path.pathExtension.lowercaseString isEqual:@"j"]; +} + +- (BOOL)isXibFile:(NSString *)path +{ + NSString *extension = path.pathExtension.lowercaseString; + return [extension isEqual:@"xib"] || [extension isEqual:@"nib"]; +} + +- (BOOL)isXCCIgnoreFile:(NSString *)path +{ + return [path.lastPathComponent isEqual:@".xcodecapp-ignore"]; +} + +- (NSString *)projectPathForSourcePath:(NSString *)path +{ + NSString *base = [path stringByDeletingLastPathComponent]; + NSString *projectPath = self.projectPathsForSourcePaths[base]; + + return projectPath ? [projectPath stringByAppendingPathComponent:path.lastPathComponent] : path; +} + +#pragma mark - Shadow Files Management + +- (NSString *)shadowBasePathForSourcePath:(NSString *)path +{ + return [self.supportPath stringByAppendingPathComponent:[[path stringByDeletingPathExtension] stringByReplacingOccurrencesOfString:@"/" withString:XCCSlashReplacement]]; +} + +- (NSString *)sourcePathForShadowPath:(NSString *)path +{ + path = [path stringByReplacingOccurrencesOfString:XCCSlashReplacement withString:@"/"]; + return [[path stringByDeletingPathExtension] stringByAppendingPathExtension:@"j"]; +} + +/*! + Clean up any shadow files and PBX entries related to given the Cappuccino source file path +*/ +- (void)removeReferencesToSourcePath:(NSString *)sourcePath +{ + NSString *shadowBasePath = [self shadowBasePathForSourcePath:sourcePath]; + NSString *shadowHeaderPath = [shadowBasePath stringByAppendingPathExtension:@"h"]; + NSString *shadowImplementationPath = [shadowBasePath stringByAppendingPathExtension:@"m"]; + + DLog(@"%@ Removing shadow header file: %@", NSStringFromSelector(_cmd), shadowHeaderPath); + [self.fm removeItemAtPath:shadowHeaderPath error:nil]; + + DLog(@"%@ Removing shadow implementation file: %@", NSStringFromSelector(_cmd), shadowImplementationPath); + [self.fm removeItemAtPath:shadowImplementationPath error:nil]; + + DLog(@"%@ Removing PBX reference", NSStringFromSelector(_cmd)); + NSString *projectSourcePath = [self projectPathForSourcePath:sourcePath]; + + NSArray *pbxArguments = @[ + @"-c", + [NSString stringWithFormat:@"(source %@; python %@ remove '%@' '%@') 2>&1", + self.profilePath, + self.PBXModifierScriptPath, + self.currentProjectPath, + projectSourcePath] + ]; + + NSDictionary *taskResult = [self runTaskWithLaunchPath:self.shellPath arguments:pbxArguments returnType:kTaskReturnTypeStdOut]; + DLog(@"%@ PBX Reference removal status/response: %@/%@", NSStringFromSelector(_cmd), taskResult[@"status"], taskResult[@"response"]); +} + +/*! + Clean the support folder according to files present in given path +*/ +- (void)tidyShadowedFiles +{ + NSArray *subpaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:self.supportPath error:nil]; + + for (NSString *path in subpaths) + { + if ([path.pathExtension isEqual:@"m"] || [path.lastPathComponent isEqualToString:@"xcc_general_include.h"]) + continue; + + NSString *sourcePath = [self sourcePathForShadowPath:path]; + + if (![self.fm fileExistsAtPath:sourcePath]) + { + [self removeReferencesToSourcePath:sourcePath]; + + if (!self.supportsFileLevelAPI && [self respondsToSelector:@selector(updateLastModificationDate:forPath:)]) + [self updateLastModificationDate:nil forPath:sourcePath]; + } + } +} + +#pragma mark - XCC Ignore management + ++ (NSString *)globToRegexPattern:(NSString *)glob +{ + NSMutableString *regex = [glob mutableCopy]; + + if ([regex characterAtIndex:0] == '!') + [regex deleteCharactersInRange:NSMakeRange(0, 1)]; + + [regex replaceOccurrencesOfString:@"." + withString:@"\\." + options:0 + range:NSMakeRange(0, [regex length])]; + + [regex replaceOccurrencesOfString:@"*" + withString:@".*" + options:0 + range:NSMakeRange(0, [regex length])]; + + // If the glob ends with "/", match that directory and anything below it. + if ([regex characterAtIndex:regex.length - 1] == '/') + [regex replaceCharactersInRange:NSMakeRange(regex.length - 1, 1) withString:@"(?:/.*)?"]; + + return [NSString stringWithFormat:@"^%@$", regex]; +} + ++ (NSArray *)parseIgnorePaths:(NSArray *)paths +{ + NSMutableArray *parsedPaths = [NSMutableArray array]; + NSError *error = NULL; + NSCharacterSet *whitespace = [NSCharacterSet whitespaceCharacterSet]; + + for (NSString *pattern in paths) + { + if ([pattern stringByTrimmingCharactersInSet:whitespace].length == 0) + continue; + + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:[self globToRegexPattern:pattern] options:0 error:&error]; + [parsedPaths addObject:@{ @"regex": regex, @"exclude": @([pattern characterAtIndex:0] != '!') }]; + } + + return parsedPaths; +} + +/*! + Compute the ignored paths according to any existing .xcodecapp-ignore file +*/ +- (void)computeIgnoredPaths +{ + self.ignoredPathRegexes = [XCCDefaultIgnoredPathRegexes mutableCopy]; + NSString *ignorePath = [self.currentProjectPath stringByAppendingPathComponent:@".xcodecapp-ignore"]; + + if ([self.fm fileExistsAtPath:ignorePath]) + { + NSString *ignoreFileContent = [NSString stringWithContentsOfFile:ignorePath encoding:NSUTF8StringEncoding error:nil]; + NSArray *ignoredPatterns = [ignoreFileContent componentsSeparatedByString:@"\n"]; + NSArray *parsedPaths = [[self class] parseIgnorePaths:ignoredPatterns]; + [self.ignoredPathRegexes addObjectsFromArray:parsedPaths]; + } + + DLog(@"Ignoring file paths: %@", self.ignoredPathRegexes); +} + +- (BOOL)pathMatchesIgnoredPaths:(NSString*)aPath +{ + BOOL ignore = NO; + NSRange range = NSMakeRange(0, aPath.length); + + for (NSDictionary *ignoreInfo in self.ignoredPathRegexes) + { + BOOL matches = [ignoreInfo[@"regex"] numberOfMatchesInString:aPath options:0 range:range] > 0; + + if (matches) + ignore = [ignoreInfo[@"exclude"] boolValue]; + } + + return ignore; +} + +#pragma mark - Errors panel + +- (IBAction)openErrorsPanel:(id)aSender +{ + [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; + [self.errorsPanel makeKeyAndOrderFront:nil]; +} + +- (IBAction)openErrorInEditor:(id)sender +{ + id info = self.errorListController.selection; + + NSString *path = [info valueForKey:@"path"]; + + if (path == NSNoSelectionMarker) + return; + + if ([self isObjjFile:path]) + { + [self openObjjFile:path line:[[info valueForKey:@"line"] intValue]]; + } + else // xib + { + NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; + [workspace openFile:path]; + } + + [self.errorsPanel orderOut:self]; +} + +- (void)openObjjFile:(NSString *)path line:(NSInteger)line +{ + NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; + + NSString *app, *type; + BOOL success = [workspace getInfoForFile:path application:&app type:&type]; + + if (!success) + { + NSBeep(); + return; + } + + NSBundle *bundle = [NSBundle bundleWithPath:app]; + NSString *identifier = bundle.bundleIdentifier; + NSString *executablePath = nil; + XCCLineSpecifier lineSpecifier = kLineSpecifierNone; + + if ([identifier hasPrefix:@"com.sublimetext."]) + { + lineSpecifier = kLineSpecifierColon; + executablePath = [[bundle sharedSupportPath] stringByAppendingPathComponent:@"bin/subl"]; + } + else if ([identifier isEqualToString:@"com.barebones.textwrangler"]) + { + lineSpecifier = kLineSpecifierColon; + executablePath = [[bundle bundlePath] stringByAppendingPathComponent:@"Contents/Helpers/edit"]; + } + else if ([identifier isEqualToString:@"com.barebones.bbedit"]) + { + lineSpecifier = kLineSpecifierColon; + executablePath = [[bundle bundlePath] stringByAppendingPathComponent:@"Contents/Helpers/bbedit"]; + } + else if ([identifier isEqualToString:@"com.macromates.textmate"]) // TextMate 1.x + { + lineSpecifier = kLineSpecifierMinusL; + executablePath = [[bundle sharedSupportPath] stringByAppendingPathComponent:@"Support/bin/mate"]; + } + else if ([identifier hasPrefix:@"com.macromates.TextMate"]) // TextMate 2.x + { + lineSpecifier = kLineSpecifierMinusL; + executablePath = [bundle pathForResource:@"mate" ofType:@""]; + } + else if ([identifier isEqualToString:@"com.chocolatapp.Chocolat"]) + { + lineSpecifier = kLineSpecifierMinusL; + executablePath = [[bundle sharedSupportPath] stringByAppendingPathComponent:@"choc"]; + } + else if ([identifier isEqualToString:@"org.vim.MacVim"]) + { + lineSpecifier = kLineSpecifierPlus; + executablePath = @"/usr/local/bin/mvim"; + } + else if ([identifier isEqualToString:@"org.gnu.Aquamacs"]) + { + if ([self.fm isExecutableFileAtPath:@"/usr/bin/aquamacs"]) + executablePath = @"/usr/bin/aquamacs"; + else if ([self.fm isExecutableFileAtPath:@"/usr/local/bin/aquamacs"]) + executablePath = @"/usr/local/bin/aquamacs"; + } + else if ([identifier isEqualToString:@"com.apple.dt.Xcode"]) + { + executablePath = [[bundle bundlePath] stringByAppendingPathComponent:@"Contents/Developer/usr/bin/xed"]; + } + + if (!executablePath || ![self.fm isExecutableFileAtPath:executablePath]) + { + [workspace openFile:path]; + return; + } + + NSArray *args; + + switch (lineSpecifier) + { + case kLineSpecifierNone: + args = @[path]; + break; + + case kLineSpecifierColon: + args = @[[NSString stringWithFormat:@"%1$@:%2$ld", path, line]]; + break; + + case kLineSpecifierMinusL: + args = @[@"-l", [NSString stringWithFormat:@"%ld", line], path]; + break; + + case kLineSpecifierPlus: + args = @[[NSString stringWithFormat:@"+%ld", line], path]; + break; + } + + [self runTaskWithLaunchPath:executablePath arguments:args returnType:kTaskReturnTypeNone]; +} + +- (IBAction)clearErrors:(id)sender +{ + [self.errorList removeAllObjects]; + self.errorListController.content = self.errorList; +} + +#pragma mark - Growl + +- (NSString *)applicationNameForGrowl +{ + return @"XcodeCapp"; +} + +- (void)growlWithTitle:(NSString *)aTitle message:(NSString *)aMessage +{ + if ([NSUserNotificationCenter class]) + { + NSUserNotification *note = [NSUserNotification new]; + note.title = aTitle; + note.informativeText = aMessage; + + [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:note]; + } + else + { + [GrowlApplicationBridge notifyWithTitle:aTitle + description:aMessage + notificationName:GROWL_NOTIFICATIONS_DEFAULT + iconData:nil + priority:0 + isSticky:NO + clickContext:nil]; + } +} + +@end + + +@implementation TNXcodeCapp (SnowLeopard) + +- (void)updateLastModificationDate:(NSDate *)date forPath:(NSString *)path +{ + if (!self.pathModificationDates) + { + self.pathModificationDates = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:kDefaultPathModificationDates] mutableCopy]; + + if (!self.pathModificationDates) + self.pathModificationDates = [NSMutableDictionary new]; + } + + if (date) + [self.pathModificationDates setObject:date forKey:path]; + else + [self.pathModificationDates removeObjectForKey:path]; + + [[NSUserDefaults standardUserDefaults] setObject:self.pathModificationDates forKey:kDefaultPathModificationDates]; +} + +- (NSDate *)lastModificationDateForPath:(NSString *)path +{ + if (!self.pathModificationDates) + { + self.pathModificationDates = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:kDefaultPathModificationDates] mutableCopy]; + + if (!self.pathModificationDates) + self.pathModificationDates = [NSMutableDictionary new]; + } + + if ([self.pathModificationDates valueForKey:path] != nil) + return [self.pathModificationDates valueForKey:path]; + else + return self.appStartedTimestamp; +} + +@end diff --git a/Tools/XcodeCapp/XcodeCapp/UserDefaults.h b/Tools/XcodeCapp/XcodeCapp/UserDefaults.h new file mode 100644 index 000000000..4697b1e45 --- /dev/null +++ b/Tools/XcodeCapp/XcodeCapp/UserDefaults.h @@ -0,0 +1,24 @@ +// +// UserDefaults.h +// XcodeCapp +// +// Created by Aparajita on 4/9/13. +// +// + +#ifndef XcodeCapp_UserDefaults_h +#define XcodeCapp_UserDefaults_h + +#import + +extern NSString * const kDefaultLastEventId; +extern NSString * const kDefaultFirstLaunch; +extern NSString * const kDefaultXCCAPIMode; +extern NSString * const kDefaultXCCReactMode; +extern NSString * const kDefaultXCCReopenLastProject; +extern NSString * const kDefaultXCCAutoOpenErrorsPanel; +extern NSString * const kDefaultXCCProjectHistory; +extern NSString * const kDefaultLastOpenedPath; +extern NSString * const kDefaultPathModificationDates; + +#endif diff --git a/Tools/XcodeCapp/XcodeCapp/UserDefaults.m b/Tools/XcodeCapp/XcodeCapp/UserDefaults.m new file mode 100644 index 000000000..9b79c934d --- /dev/null +++ b/Tools/XcodeCapp/XcodeCapp/UserDefaults.m @@ -0,0 +1,20 @@ +// +// UserDefaults.m +// XcodeCapp +// +// Created by Aparajita on 4/9/13. +// +// + +#include "UserDefaults.h" + + +NSString * const kDefaultLastEventId = @"lastEventId"; +NSString * const kDefaultFirstLaunch = @"FirstLaunch"; +NSString * const kDefaultXCCAPIMode = @"XCCAPIMode"; +NSString * const kDefaultXCCReactMode = @"XCCReactMode"; +NSString * const kDefaultXCCReopenLastProject = @"XCCReopenLastProject"; +NSString * const kDefaultXCCAutoOpenErrorsPanel = @"XCCAutoOpenErrorsPanel"; +NSString * const kDefaultXCCProjectHistory = @"XCCProjectHistory"; +NSString * const kDefaultLastOpenedPath = @"LastOpenedPath"; +NSString * const kDefaultPathModificationDates = @"pathModificationDates"; diff --git a/Tools/XcodeCapp/XcodeCapp.pch b/Tools/XcodeCapp/XcodeCapp/XcodeCapp-Prefix.pch similarity index 100% rename from Tools/XcodeCapp/XcodeCapp.pch rename to Tools/XcodeCapp/XcodeCapp/XcodeCapp-Prefix.pch diff --git a/Tools/XcodeCapp/XcodeCapp/en.lproj/InfoPlist.strings b/Tools/XcodeCapp/XcodeCapp/en.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/Tools/XcodeCapp/XcodeCapp/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/Tools/XcodeCapp/English.lproj/MainMenu.nib/designable.nib b/Tools/XcodeCapp/XcodeCapp/en.lproj/MainMenu.nib/designable.nib similarity index 90% rename from Tools/XcodeCapp/English.lproj/MainMenu.nib/designable.nib rename to Tools/XcodeCapp/XcodeCapp/en.lproj/MainMenu.nib/designable.nib index 0a71a52a7..6ab4f96bb 100644 --- a/Tools/XcodeCapp/English.lproj/MainMenu.nib/designable.nib +++ b/Tools/XcodeCapp/XcodeCapp/en.lproj/MainMenu.nib/designable.nib @@ -2,7 +2,7 @@ 1050 - 12D61 + 12D78 3084 1187.37 626.00 @@ -11,6 +11,7 @@ 3084 + NSArrayController NSButton NSButtonCell NSCustomObject @@ -53,29 +54,29 @@ 8215 2 - {{196, 240}, {375, 153}} + {{196, 240}, {286, 180}} 1685585920 About NSPanel - + 256 - 269 - {{27, 63}, {320, 70}} + 268 + {{32, 62}, {219, 98}} YES 68157504 - 138544128 - WGNvZGVDYXBwIGRldmVsb3BlZCBieSBBbnRvaW5lIE1lcmNhZGFsCnByaW1hbG1vdGlvbkBhcmNoaXBl -bHByb2plY3Qub3JnCgp3aXRoIGNvbnRyaWJ1dGlvbnMgZnJvbSBBcGFyYWppdGEgRmlzaG1hbgphcGFy -YWppdGFAYXBhcmFqaXRhLmNvbQ + 4326400 + WGNvZGVDYXBwIGRldmVsb3BlZCBieToKCiAgICAgQW50b2luZSBNZXJjYWRhbAogICAgIHByaW1hbG1v +dGlvbkBhcmNoaXBlbHByb2plY3Qub3JnCgogICAgIEFwYXJhaml0YSBGaXNobWFuCiAgICAgYXBhcmFq +aXRhQGFwYXJhaml0YS5jb20 LucidaGrande 11 @@ -100,8 +101,8 @@ YWppdGFAYXBhcmFqaXRhLmNvbQ - 269 - {{108, 20}, {158, 14}} + 266 + {{-3, 20}, {292, 14}} YES @@ -116,11 +117,10 @@ YWppdGFAYXBhcmFqaXRhLmNvbQ NO - {375, 153} - + {286, 180} - {{0, 0}, {1440, 878}} + {{0, 0}, {2560, 1418}} {10000000000000, 10000000000000} YES @@ -187,7 +187,7 @@ YWppdGFAYXBhcmFqaXRhLmNvbQ - About... + About XcodeCapp... 2147483647 @@ -195,11 +195,12 @@ YWppdGFAYXBhcmFqaXRhLmNvbQ - Help + XcodeCapp Help 2147483647 + 7 @@ -213,13 +214,14 @@ YWppdGFAYXBhcmFqaXRhLmNvbQ - Quit + Quit XcodeCapp 2147483647 + YES 95 @@ -231,7 +233,7 @@ YWppdGFAYXBhcmFqaXRhLmNvbQ - + 256 @@ -245,6 +247,7 @@ YWppdGFAYXBhcmFqaXRhLmNvbQ 256 + {512, 249} @@ -317,7 +320,7 @@ YWppdGFAYXBhcmFqaXRhLmNvbQ 1 MSAxIDEgMAA - 17 + 52 -759169024 @@ -367,7 +370,7 @@ YWppdGFAYXBhcmFqaXRhLmNvbQ - QSAAAEEgAABBmAAAQZgAAA + QSAAAEEgAABCWAAAQlgAAA 0.25 4 1 @@ -421,10 +424,9 @@ YWppdGFAYXBhcmFqaXRhLmNvbQ {512, 285} - - {{0, 0}, {1440, 878}} + {{0, 0}, {2560, 1418}} {10000000000000, 10000000000000} YES @@ -438,7 +440,7 @@ YWppdGFAYXBhcmFqaXRhLmNvbQ - + 256 @@ -454,7 +456,7 @@ YWppdGFAYXBhcmFqaXRhLmNvbQ 2322 {716, 571} - + @@ -474,7 +476,7 @@ YWppdGFAYXBhcmFqaXRhLmNvbQ 1 - 67120389 + 11525 0 @@ -549,6 +551,7 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA 256 {{701, 1}, {16, 571}} + NO _doScroller: @@ -571,7 +574,7 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA {{-1, -1}, {718, 573}} - + 133138 @@ -582,9 +585,10 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA {716, 571} + - {{0, 0}, {1440, 878}} + {{0, 0}, {2560, 1418}} {10000000000000, 10000000000000} YES @@ -843,7 +847,7 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 {435, 199} - {{0, 0}, {1440, 878}} + {{0, 0}, {2560, 1418}} {10000000000000, 10000000000000} xcc-prefs YES @@ -851,8 +855,17 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 YES + + YES + + YES + YES + YES + YES + YES + - TNXCodeCapp + TNXcodeCapp Debug… @@ -861,22 +874,23 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 - + 268 - - + + 297 {{182, 19}, {18, 19}} - + + YES - + -2080374784 134217728 - + -2033958912 164 @@ -890,32 +904,32 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 NO - - + + 274 {{7, 9}, {170, 18}} - - + + YES - + 67108864 272629760 Label - + NO - - + + 266 {{7, 30}, {170, 17}} - - + + YES - + 67108928 272632320 Label @@ -924,7 +938,7 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 13 2072 - + 1 @@ -936,7 +950,7 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 {209, 57} - + TNErrorDataView @@ -966,22 +980,6 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 453 - - - chooseFolder: - - - - 454 - - - - openXCode: - - - - 457 - errorsPanel @@ -990,14 +988,6 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 475 - - - errorsTable - - - - 476 - clearErrors: @@ -1030,14 +1020,6 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 517 - - - labelVersion - - - - 524 - aboutWindow @@ -1054,22 +1036,6 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 527 - - - menuItemStartStop - - - - 539 - - - - menuItemOpenXCode - - - - 540 - openAbout: @@ -1078,38 +1044,6 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 571 - - - buttonPreferencesAPIMode - - - - 573 - - - - checkBoxPreferencesReactMode - - - - 574 - - - - updatePreferences: - - - - 600 - - - - updatePreferences: - - - - 601 - preferencesController @@ -1126,22 +1060,6 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 611 - - - openPreferences: - - - - 646 - - - - menuDebug - - - - 659 - windowDebug @@ -1151,20 +1069,60 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 660 - - dataViewError + + listenToProject: - + - 682 + 715 + + + + openInXcode: + + + + 716 - menuHistory + menuItemHistory - 694 + 731 + + + + menuItemListen + + + + 732 + + + + menuItemOpenInXcode + + + + 733 + + + + enabled: currentProjectPath.length + + + + + + enabled: currentProjectPath.length + enabled + currentProjectPath.length + 2 + + + 736 @@ -1190,6 +1148,26 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 478 + + + displayPatternValue1: bundleVersion + + + + + + displayPatternValue1: bundleVersion + displayPatternValue1 + bundleVersion + + NSDisplayPattern + Version %{value1}@ + + 2 + + + 714 + value: values.XCCReactMode @@ -1248,25 +1226,19 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 - enabled: supportFileLevelAPI + enabled: supportsFileLevelAPI - + - enabled: supportFileLevelAPI + enabled: supportsFileLevelAPI enabled - supportFileLevelAPI - - - - - - + supportsFileLevelAPI 2 - 642 + 729 @@ -1286,11 +1258,11 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 NSNegateBoolean - + 2 - 645 + 730 @@ -1339,34 +1311,34 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 fieldFileName - - + + - 678 + 724 fieldMessage - - + + - 681 + 725 openFile: - - + + - 689 + 726 buttonOpenFile - - + + - 690 + 727 @@ -1474,9 +1446,9 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 465 - + @@ -1778,6 +1750,7 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 610 + XCodeCapp 648 @@ -1810,55 +1783,6 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 - - 675 - - - - - - - - - - 676 - - - - - - - - 677 - - - - - 679 - - - - - - - - 680 - - - - - 687 - - - - - - - - 688 - - - 691 @@ -1869,6 +1793,61 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 + + 711 + + + Errors Controller + + + 717 + + + + + + + + + + 718 + + + + + + + + 719 + + + + + + + + 720 + + + + + + + + 721 + + + + + 722 + + + + + 723 + + + @@ -1907,6 +1886,7 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1944,21 +1924,22 @@ d2hhdCB5b3UgYXJlIGRvaW5nLCBsZWF2ZSB0aGlzIG9uICJBdXRvIi4 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 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 - 694 + 736 0 diff --git a/Tools/XcodeCapp/XcodeCapp/en.lproj/MainMenu.nib/keyedobjects.nib b/Tools/XcodeCapp/XcodeCapp/en.lproj/MainMenu.nib/keyedobjects.nib new file mode 100644 index 000000000..dfb052cdc Binary files /dev/null and b/Tools/XcodeCapp/XcodeCapp/en.lproj/MainMenu.nib/keyedobjects.nib differ diff --git a/Tools/XcodeCapp/XcodeCapp/en.lproj/MainMenu.xib b/Tools/XcodeCapp/XcodeCapp/en.lproj/MainMenu.xib new file mode 100644 index 000000000..ea6f85446 --- /dev/null +++ b/Tools/XcodeCapp/XcodeCapp/en.lproj/MainMenu.xib @@ -0,0 +1,1930 @@ + + + + 1060 + 12D78 + 3084 + 1187.37 + 626.00 + + com.apple.InterfaceBuilder.CocoaPlugin + 3084 + + + NSArrayController + NSBox + NSButton + NSButtonCell + NSCustomObject + NSImageCell + NSImageView + NSMenu + NSMenuItem + NSScrollView + NSScroller + NSTableColumn + NSTableView + NSTextField + NSTextFieldCell + NSTextView + NSUserDefaultsController + NSView + NSWindowTemplate + + + com.apple.InterfaceBuilder.CocoaPlugin + + + PluginDependencyRecalculationVersion + + + + + NSApplication + + + FirstResponder + + + NSApplication + + + NSFontManager + + + + + + + Listen to Project… + + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + + + + Open Recent + + 2147483647 + + + + + + Open Project in Xcode + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Show Errors & Warnings + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + About XcodeCapp... + + 2147483647 + + + + + + Preferences… + + 2147483647 + + + + + + XcodeCapp Help + + 2147483647 + + + 7 + + + + YES + YES + + + 2147483647 + + + + + + Quit XcodeCapp + + 2147483647 + + + + + YES + + + AppController + + + 19 + 2 + {{196, 240}, {362, 185}} + 1685586944 + About + NSPanel + + + + + 256 + + + + 268 + {{164, 23}, {179, 98}} + + + + YES + + 68157504 + 4326400 + WGNvZGVDYXBwIGRldmVsb3BlZCBieToKCiAgICAgQW50b2luZSBNZXJjYWRhbAogICAgIGFudG9pbmUu +bWVyY2FkYWxAZ21haWwuY29tCgogICAgIEFwYXJhaml0YSBGaXNobWFuCiAgICAgYXBhcmFqaXRhQGFw +YXJhaml0YS5jb20 + + LucidaGrande + 11 + 3100 + + + + 6 + System + textBackgroundColor + + 3 + MQA + + + + 6 + System + textColor + + 3 + MAA + + + + NO + + + + 266 + {{164, 140}, {164, 14}} + + + + YES + + 68157504 + 4326400 + version + + LucidaGrande-Bold + 11 + 3357 + + + + 6 + System + controlColor + + 3 + MC42NjY2NjY2NjY3AA + + + + + NO + + + + 268 + + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple PNG pasteboard type + NSFilenamesPboardType + NeXT Encapsulated PostScript v1.2 pasteboard type + NeXT TIFF v4.0 pasteboard type + + {{17, 46}, {128, 128}} + + + + _NS:9 + YES + + 134217728 + 33554432 + + NSImage + XcodeCapp + + _NS:9 + 0 + 0 + 0 + NO + + NO + YES + + + {362, 185} + + + + + {{0, 0}, {2560, 1418}} + {10000000000000, 10000000000000} + NO + + + 31 + 2 + {{462, 324}, {550, 237}} + 1685586944 + Errors & Warnings + NSPanel + + + {315, 77} + + + 256 + + + + 274 + + + + 2304 + + + + 256 + + {550, 201} + + + + YES + NO + YES + + + -2147483392 + {{413, 0}, {16, 17}} + + + + + error + 536 + 40 + 1000 + + 75497536 + 2048 + Error + + + 3 + MC4zMzMzMzI5ODU2AA + + + 6 + System + headerTextColor + + + + + 69206081 + 2304 + Text Cell + + + + 6 + System + controlBackgroundColor + + + + 6 + System + controlTextColor + + + + 1 + YES + + + + 14 + 10 + + + 1 + MSAxIDEgMAA + + 30 + -1832910848 + + + 2 + 15 + 0 + NO + 0 + 1 + + + {{1, 1}, {550, 201}} + + + + + + 4 + + + + -2147483392 + {{535, 1}, {16, 45}} + + + + NO + + _doScroller: + 0.9375 + + + + -2147483392 + {{1, 273}, {512, 16}} + + + + NO + 1 + + _doScroller: + 0.99805068226120852 + + + {{-1, 35}, {552, 203}} + + + + 133682 + + + + QSAAAEEgAABCIAAAQiAAAA + 0.25 + 4 + 1 + + + + 289 + {{352, 8}, {85, 19}} + + + + YES + + -2080374784 + 134217728 + Clear + + LucidaGrande + 12 + 16 + + + -2038153216 + 164 + + + 400 + 75 + + NO + + + + 292 + {{20, 8}, {85, 19}} + + + + YES + + -1543503872 + 134217728 + Open + + + -2038153216 + 164 + + + 400 + 75 + + NO + + + + 289 + {{445, 8}, {85, 19}} + + + + YES + + -2080374784 + 134217728 + Close + + + -2038153216 + 164 + + + 400 + 75 + + NO + + + {550, 237} + + + + + {{0, 0}, {2560, 1418}} + {315, 93} + {10000000000000, 10000000000000} + errorPanel + YES + + + 3 + 2 + {{529, 541}, {336, 159}} + 1685586944 + Preferences + NSWindow + + + + + 256 + + + + 268 + {{18, 39}, {282, 18}} + + + YES + + -2080374784 + 0 + React to inode meta information changes + + LucidaGrande + 13 + 1044 + + + 1211912448 + 2 + + NSImage + NSSwitch + + + NSSwitch + + + + 200 + 25 + + NO + + + + 268 + {{18, 16}, {284, 17}} + + YES + + 68157504 + 272630784 + In "File level" API mode, react to touch, chown, etc. + + LucidaGrande + 11 + 16 + + + + + 1 + MC4zNDU1Mjg0ODM0IDAuMzQ1NTI4NDgzNCAwLjM0NTUyODQ4MzQAA + + + NO + + + + 268 + {{18, 123}, {295, 18}} + + + YES + + -2080374784 + 0 + Listen to the most recent project on launch + + + 1211912448 + 2 + + + + + 200 + 25 + + NO + + + + 268 + {{18, 93}, {300, 18}} + + + YES + + -2080374784 + 0 + Automatically open Errors & Warnings panel + + + 1211912448 + 2 + + + + + 200 + 25 + + NO + + + + 10 + {{20, 72}, {296, 5}} + + + _NS:9 + {0, 0} + + 67108864 + 0 + Box + + + + 3 + MCAwLjgwMDAwMDAxMTkAA + + + 3 + 2 + 0 + NO + + + {336, 159} + + + {{0, 0}, {2560, 1418}} + {10000000000000, 10000000000000} + xcc-prefs + YES + + + 15 + 2 + {{163, 199}, {716, 571}} + 1685586944 + Help + NSWindow + + + + + 256 + + + + 274 + + + + 2304 + + + + 2322 + {716, 571} + + + + + + + + + + + + + + 166 + + + + 716 + 1 + + + 67120389 + 0 + + + + + 6 + System + selectedTextBackgroundColor + + + + 6 + System + selectedTextColor + + + + + + + 1 + MCAwIDEAA + + + {8, -8} + 13 + + + + + + 1 + + 6 + {716, 10000000} + + + + {{1, 1}, {716, 571}} + + + + + + {4, 5} + + 12582912 + + + + + + TU0AKgAAAHCAFUqgBVKsAAAAwdVQUqwaEQeIRGJRGFlYqwWLQ+JxuOQpVRmEx2RROKwOQyOUQSPyaUym +SxqWyKXyeYxyZzWbSuJTScRCbz2Nz+gRKhUOfTqeUai0OSxiWTiBQSHSGFquGwekxyAgAAAOAQAAAwAA +AAEAEAAAAQEAAwAAAAEAEAAAAQIAAwAAAAIACAAIAQMAAwAAAAEABQAAAQYAAwAAAAEAAQAAAREABAAA +AAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEAAgAAARYAAwAAAAEAEAAAARcABAAAAAEAAABnARwAAwAA +AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA + + + + + + 3 + MCAwAA + + + + 4 + + + + 256 + {{701, 1}, {16, 571}} + + NO + + _doScroller: + 1 + 0.85256409645080566 + + + + -2147483392 + {{-100, -100}, {87, 18}} + + + NO + 1 + + _doScroller: + 1 + 0.94565218687057495 + + + {{-1, -1}, {718, 573}} + + + 133138 + + + + 0.25 + 4 + 1 + + + {716, 571} + + + {{0, 0}, {2560, 1418}} + {10000000000000, 10000000000000} + YES + + + YES + + + TNXcodeCapp + + + + message + file + + YES + + YES + YES + YES + + + + + + + delegate + + + + 694 + + + + terminate: + + + + 695 + + + + statusMenu + + + + 607 + + + + helpWindow + + + + 610 + + + + helpTextView + + + + 611 + + + + openHelp: + + + + 612 + + + + aboutWindow + + + + 613 + + + + openAbout: + + + + 615 + + + + preferencesController + + + + 616 + + + + xcc + + + + 617 + + + + listenToProject: + + + + 619 + + + + openInXcode: + + + + 620 + + + + menuItemHistory + + + + 621 + + + + menuItemListen + + + + 622 + + + + menuItemOpenInXcode + + + + 623 + + + + preferencesWindow + + + + 795 + + + + openPreferences: + + + + 796 + + + + performClose: + + + + 625 + + + + save: + + + + 634 + + + + save: + + + + 792 + + + + errorTable + + + + 748 + + + + clearErrors + + + + 749 + + + + clearErrors: + + + + 751 + + + + errorListController + + + + 760 + + + + openErrorsPanel: + + + + 774 + + + + errorsPanel + + + + 775 + + + + openErrorInEditor: + + + + 786 + + + + value: values.XCCReactMode + + + + + + value: values.XCCReactMode + value + values.XCCReactMode + + NSValidatesImmediately + + + 2 + + + 629 + + + + enabled: isUsingFileLevelAPI + + + + + + enabled: isUsingFileLevelAPI + enabled + isUsingFileLevelAPI + 2 + + + 630 + + + + value: values.XCCReopenLastProject + + + + + + value: values.XCCReopenLastProject + value + values.XCCReopenLastProject + + NSValidatesImmediately + + + 2 + + + 636 + + + + dataSource + + + + 752 + + + + delegate + + + + 753 + + + + doubleClickArgument: errorTable + + + + + + doubleClickArgument: errorTable + doubleClickArgument + errorTable + + NSSelectorName + openErrorInEditor: + + 2 + + + 787 + + + + doubleClickTarget: self + + + + + + doubleClickTarget: self + doubleClickTarget + self + + NSSelectorName + openErrorInEditor: + + + 2 + + + 788 + + + + value: arrangedObjects.message + + + + + + value: arrangedObjects.message + value + arrangedObjects.message + 2 + + + 770 + + + + displayPatternValue1: bundleVersion + + + + + + displayPatternValue1: bundleVersion + displayPatternValue1 + bundleVersion + + NSDisplayPattern + XcodeCapp %{value1}@ + + 2 + + + 800 + + + + enabled: currentProjectPath.length + + + + + + enabled: currentProjectPath.length + enabled + currentProjectPath.length + 2 + + + 624 + + + + enabled: selection.@count + + + + + + enabled: selection.@count + enabled + selection.@count + 2 + + + 765 + + + + contentArray: errorList + + + + + + contentArray: errorList + contentArray + errorList + 2 + + + 762 + + + + value: values.XCCAutoOpenErrorsPanel + + + + + + value: values.XCCAutoOpenErrorsPanel + value + values.XCCAutoOpenErrorsPanel + + NSValidatesImmediately + + + 2 + + + 793 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 420 + + + + + 538 + + + + + + + + + + + + + + + + + + 539 + + + + + 540 + + + + + + + + 541 + + + + + + + + 542 + + + + + + + + 543 + + + + + + + + 544 + + + + + 545 + + + XCodeCapp + + + 553 + + + + + + + + 554 + + + + + + + + + + 555 + + + + + 556 + + + + + 557 + + + + + 558 + + + + + + + + + + + + 559 + + + + + + + + 561 + + + + + + + + 563 + + + + + + + + 576 + + + + + 578 + + + + + 580 + + + + + 581 + + + + + + + + + + + 582 + + + + + + + + + + 583 + + + + + + + + 584 + + + + + + + + 585 + + + + + 586 + + + + + 587 + + + + + + + + 588 + + + + + 589 + + + + + 590 + + + + + + + + 591 + + + + + 592 + + + + + + + + + + 593 + + + + + + + + 594 + + + + + + + + 595 + + + + + 596 + + + + + 597 + + + + + 598 + + + + + 599 + + + + + 600 + + + + + 601 + + + + + 602 + + + + + 603 + + + + + 604 + + + + + 605 + + + + + 606 + + + + + 754 + + + + + + + + 755 + + + + + 759 + + + Errors Controller + + + 537 + + + + + 789 + + + + + + + + 790 + + + + + 794 + + + + + 797 + + + + + + + + 798 + + + + + + + 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 + + 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 + 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 + 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 + 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 + + ToolTip + + ToolTip + + When an error or warning occurs, automatically open the Errors & Warnings panel + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + 800 + + + + + AppController + NSObject + + id + id + id + id + + + + listenToProject: + id + + + openAbout: + id + + + openHelp: + id + + + openInXcode: + id + + + + NSPanel + NSTextView + NSWindow + NSMenuItem + NSMenuItem + NSMenuItem + NSUserDefaultsController + NSWindow + NSMenu + TNXcodeCapp + + + + aboutWindow + NSPanel + + + helpTextView + NSTextView + + + helpWindow + NSWindow + + + menuItemHistory + NSMenuItem + + + menuItemListen + NSMenuItem + + + menuItemOpenInXcode + NSMenuItem + + + preferencesController + NSUserDefaultsController + + + preferencesWindow + NSWindow + + + statusMenu + NSMenu + + + xcc + TNXcodeCapp + + + + IBProjectSource + ./Classes/AppController.h + + + + TNXcodeCapp + NSObject + + id + id + id + + + + clearErrors: + id + + + openErrorInEditor: + id + + + openErrorsPanel: + id + + + + NSArrayController + NSTableView + NSPanel + + + + errorListController + NSArrayController + + + errorTable + NSTableView + + + errorsPanel + NSPanel + + + + IBProjectSource + ./Classes/TNXcodeCapp.h + + + + + 0 + IBCocoaFramework + + com.apple.InterfaceBuilder.CocoaPlugin.macosx + + + YES + 3 + + {11, 11} + {10, 3} + {15, 15} + {512, 512} + + + diff --git a/Tools/XcodeCapp/macros.h b/Tools/XcodeCapp/XcodeCapp/macros.h similarity index 100% rename from Tools/XcodeCapp/macros.h rename to Tools/XcodeCapp/XcodeCapp/macros.h diff --git a/Tools/XcodeCapp/XcodeCapp/main.m b/Tools/XcodeCapp/XcodeCapp/main.m new file mode 100644 index 000000000..c4385ce48 --- /dev/null +++ b/Tools/XcodeCapp/XcodeCapp/main.m @@ -0,0 +1,14 @@ +// +// main.m +// XcodeCapp +// +// Created by Aparajita on 4/18/13. +// Copyright (c) 2013 Cappuccino Project. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) +{ + return NSApplicationMain(argc, (const char **)argv); +} diff --git a/Tools/XcodeCapp/main.m b/Tools/XcodeCapp/main.m deleted file mode 100644 index 1dc23cbfb..000000000 --- a/Tools/XcodeCapp/main.m +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is a part of program XcodeCapp - * Copyright (C) 2011 Antoine Mercadal () - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#import -#include - -int main(int argc, char *argv[]) -{ - return NSApplicationMain(argc, (const char **) argv); -} diff --git a/Tools/XcodeCapp/mod_pbxproj.py b/Tools/XcodeCapp/mod_pbxproj.py deleted file mode 100755 index c7aaed2fc..000000000 --- a/Tools/XcodeCapp/mod_pbxproj.py +++ /dev/null @@ -1,968 +0,0 @@ -# Copyright 2012 Calvin Rien -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# A pbxproj file is an OpenStep format plist -# {} represents dictionary of key=value pairs delimited by ; -# () represents list of values delimited by , -# file starts with a comment specifying the character type -# // !$*UTF8*$! - -# when adding a file to a project, create the PBXFileReference -# add the PBXFileReference's guid to a group -# create a PBXBuildFile with the PBXFileReference's guid -# add the PBXBuildFile to the appropriate build phase - -# when adding a header search path add -# HEADER_SEARCH_PATHS = "path/**"; -# to each XCBuildConfiguration object - -# Xcode4 will read either a OpenStep or XML plist. -# this script uses `plutil` to validate, read and write -# the pbxproj file. Plutil is available in OS X 10.2 and higher -# Plutil can't write OpenStep plists, so I save as XML - -import re, uuid, sys, os, shutil, subprocess, datetime, json - -from UserDict import IterableUserDict -from UserList import UserList - -class PBXEncoder(json.JSONEncoder): - - def default(self, obj): - """Tests the input object, obj, to encode as JSON.""" - - if isinstance(obj, (PBXList, PBXDict)): - return obj.data - - return json.JSONEncoder.default(self, obj) - - -class PBXDict(IterableUserDict): - def __init__(self, d=None): - if d: - d = dict([(PBXType.Convert(k),PBXType.Convert(v)) for k,v in d.items()]) - - IterableUserDict.__init__(self, d) - - def __setitem__(self, key, value): - IterableUserDict.__setitem__(self, PBXType.Convert(key), PBXType.Convert(value)) - - def remove(self, key): - self.data.pop(PBXType.Convert(key), None) - - - -class PBXList(UserList): - def __init__(self, l=None): - if isinstance(l, basestring): - UserList.__init__(self) - self.add(l) - return - elif l: - l = [PBXType.Convert(v) for v in l] - - UserList.__init__(self, l) - - def add(self, value): - value = PBXType.Convert(value) - - if value in self.data: - return False - - self.data.append(value) - return True - - def remove(self, value): - value = PBXType.Convert(value) - - if value in self.data: - self.data.remove(value) - - def __setitem__(self, key, value): - UserList.__setitem__(self, PBXType.Convert(key), PBXType.Convert(value)) - - -class PBXType(PBXDict): - def __init__(self, d=None): - PBXDict.__init__(self, d) - - if not self.has_key('isa'): - self['isa'] = self.__class__.__name__ - self.id = None - - @staticmethod - def Convert(o): - if isinstance(o, list): - return PBXList(o) - elif isinstance(o, dict): - isa = o.get('isa') - - if not isa: - return PBXDict(o) - - cls = globals().get(isa) - - if cls and issubclass(cls, PBXType): - return cls(o) - - print 'warning: unknown PBX type: %s' % isa - return PBXDict(o) - else: - return o - - @staticmethod - def IsGuid(o): - return re.match('^[A-F0-9]{24}$', str(o)) - - @classmethod - def GenerateId(cls): - return ''.join(str(uuid.uuid4()).upper().split('-')[1:]) - - @classmethod - def Create(cls, *args, **kwargs): - return cls(*args, **kwargs) - - -class PBXFileReference(PBXType): - def __init__(self, d=None): - PBXType.__init__(self, d) - self.build_phase = None - - types = { - '.a':('archive.ar', 'PBXFrameworksBuildPhase'), - '.app': ('wrapper.application', None), - '.s': ('sourcecode.asm', 'PBXSourcesBuildPhase'), - '.c': ('sourcecode.c.c', 'PBXSourcesBuildPhase'), - '.cpp': ('sourcecode.cpp.cpp', 'PBXSourcesBuildPhase'), - '.framework': ('wrapper.framework','PBXFrameworksBuildPhase'), - '.h': ('sourcecode.c.h', None), - '.icns': ('image.icns','PBXResourcesBuildPhase'), - '.m': ('sourcecode.c.objc', 'PBXSourcesBuildPhase'), - '.mm': ('sourcecode.cpp.objcpp', 'PBXSourcesBuildPhase'), - '.nib': ('wrapper.nib', 'PBXResourcesBuildPhase'), - '.plist': ('text.plist.xml', 'PBXResourcesBuildPhase'), - '.png': ('image.png', 'PBXResourcesBuildPhase'), - '.rtf': ('text.rtf', 'PBXResourcesBuildPhase'), - '.tiff': ('image.tiff', 'PBXResourcesBuildPhase'), - '.txt': ('text', 'PBXResourcesBuildPhase'), - '.xcodeproj': ('wrapper.pb-project', None), - '.xib': ('file.xib', 'PBXResourcesBuildPhase'), - '.strings': ('text.plist.strings', 'PBXResourcesBuildPhase'), - '.bundle': ('wrapper.plug-in', 'PBXResourcesBuildPhase'), - '.dylib': ('compiled.mach-o.dylib', 'PBXFrameworksBuildPhase') - } - - trees = [ - '', - '', - 'BUILT_PRODUCTS_DIR', - 'DEVELOPER_DIR', - 'SDKROOT', - 'SOURCE_ROOT', - ] - - def guess_file_type(self): - self.remove('explicitFileType') - self.remove('lastKnownFileType') - ext = os.path.splitext(self.get('name', ''))[1] - - f_type, build_phase = PBXFileReference.types.get(ext, ('?', None)) - - self['lastKnownFileType'] = f_type - self.build_phase = build_phase - - if f_type == '?': - print 'unknown file extension: %s' % ext - print 'please add extension and Xcode type to PBXFileReference.types' - - return f_type - - def set_file_type(self, ft): - self.remove('explicitFileType') - self.remove('lastKnownFileType') - - self['explicitFileType'] = ft - - @classmethod - def Create(cls, os_path, tree='SOURCE_ROOT'): - if tree not in cls.trees: - print 'Not a valid sourceTree type: %s' % tree - return None - - fr = cls() - fr.id = cls.GenerateId() - fr['path'] = os_path - fr['name'] = os.path.split(os_path)[1] - fr['sourceTree'] = '' if os.path.isabs(os_path) else tree - fr.guess_file_type() - - return fr - -class PBXBuildFile(PBXType): - def set_weak_link(self, weak=False): - k_settings = 'settings' - k_attributes = 'ATTRIBUTES' - - s = self.get(k_settings) - - if not s: - if weak: - self[k_settings] = PBXDict({k_attributes:PBXList(['Weak'])}) - - return True - - atr = s.get(k_attributes) - - if not atr: - if weak: - atr = PBXList() - else: - return False - - if weak: - atr.add('Weak') - else: - atr.remove('Weak') - - self[k_settings][k_attributes] = atr - - return True - - def add_compiler_flag(self, flag): - k_settings = 'settings' - k_attributes = 'COMPILER_FLAGS' - - if not self.has_key(k_settings): - self[k_settings] = PBXDict() - - if not self[k_settings].has_key(k_attributes): - self[k_settings][k_attributes] = flag - return True - - flags = self[k_settings][k_attributes].split(' ') - - if flag in flags: - return False - - flags.append(flag) - - self[k_settings][k_attributes] = ' '.join(flags) - - @classmethod - def Create(cls, file_ref, weak=False): - if isinstance(file_ref, PBXFileReference): - file_ref = file_ref.id - - bf = cls() - bf.id = cls.GenerateId() - bf['fileRef'] = file_ref - - if weak: - bf.set_weak_link(True) - - return bf - -class PBXGroup(PBXType): - def add_child(self, ref): - if not isinstance(ref, PBXDict): - return None - - isa = ref.get('isa') - - if isa != 'PBXFileReference' and isa != 'PBXGroup': - return None - - if not self.has_key('children'): - self['children'] = PBXList() - - self['children'].add(ref.id) - - return ref.id - - def remove_child(self, id): - if not self.has_key('children'): - self['children'] = PBXList() - return - - if not PBXType.IsGuid(id): - id = id.id - - self['children'].remove(id) - - def has_child(self, id): - if not self.has_key('children'): - self['children'] = PBXList() - return False - - if not PBXType.IsGuid(id): - id = id.id - - return id in self['children'] - - def get_name(self): - path_name = os.path.split(self.get('path',''))[1] - return self.get('name', path_name) - - @classmethod - def Create(cls, name, path=None, tree='SOURCE_ROOT'): - grp = cls() - grp.id = cls.GenerateId() - grp['name'] = name - grp['children'] = PBXList() - - if path: - grp['path'] = path - grp['sourceTree'] = tree - else: - grp['sourceTree'] = '' - - return grp - - -class PBXNativeTarget(PBXType): - pass - - -class PBXProject(PBXType): - pass - - -class PBXContainerItemProxy(PBXType): - pass - - -class PBXReferenceProxy(PBXType): - pass - - -class PBXVariantGroup(PBXType): - pass - - -class PBXBuildPhase(PBXType): - def add_build_file(self, bf): - if bf.get('isa') != 'PBXBuildFile': - return False - - if not self.has_key('files'): - self['files'] = PBXList() - - self['files'].add(bf.id) - - return True - - def remove_build_file(self, id): - if not self.has_key('files'): - self['files'] = PBXList() - return - - self['files'].remove(id) - - def has_build_file(self, id): - if not self.has_key('files'): - self['files'] = PBXList() - return False - - if not PBXType.IsGuid(id): - id = id.id - - return id in self['files'] - - -class PBXFrameworksBuildPhase(PBXBuildPhase): - pass - - -class PBXResourcesBuildPhase(PBXBuildPhase): - pass - - -class PBXShellScriptBuildPhase(PBXBuildPhase): - pass - - -class PBXSourcesBuildPhase(PBXBuildPhase): - pass - - -class PBXCopyFilesBuildPhase(PBXBuildPhase): - pass - - -class XCBuildConfiguration(PBXType): - def add_search_paths(self, paths, base, key, recursive=True): - modified = False - - if not isinstance(paths, list): - paths = [paths] - - if not self.has_key(base): - self[base] = PBXDict() - - for path in paths: - if recursive and not path.endswith('/**'): - path = os.path.join(path, '**') - - if not self[base].has_key(key): - self[base][key] = PBXList() - elif isinstance(self[base][key], basestring): - self[base][key] = PBXList(self[base][key]) - - if self[base][key].add('\\"%s\\"' % path): - modified = True - - return modified - - def add_header_search_paths(self, paths, recursive=True): - return self.add_search_paths(paths, 'buildSettings', 'HEADER_SEARCH_PATHS', recursive=recursive) - - def add_library_search_paths(self, paths, recursive=True): - return self.add_search_paths(paths, 'buildSettings', 'LIBRARY_SEARCH_PATHS', recursive=recursive) - - def add_other_cflags(self, flags): - modified = False - - base = 'buildSettings' - key = 'OTHER_CFLAGS' - - if isinstance(flags, basestring): - flags = PBXList(flags) - - if not self.has_key(base): - self[base] = PBXDict() - - for flag in flags: - - if not self[base].has_key(key): - self[base][key] = PBXList() - elif isinstance(self[base][key], basestring): - self[base][key] = PBXList(self[base][key]) - - if self[base][key].add(flag): - self[base][key] = [e for e in self[base][key] if e] - modified = True - - return modified - - -class XCConfigurationList(PBXType): - pass - - -class XcodeProject(PBXDict): - plutil_path = 'plutil' - special_folders = ['.bundle', '.framework', '.xcodeproj'] - - def __init__(self, d=None, path=None): - if not path: - path = os.path.join(os.getcwd(), 'project.pbxproj') - - self.pbxproj_path =os.path.abspath(path) - self.source_root = os.path.abspath(os.path.join(os.path.split(path)[0], '..')) - - IterableUserDict.__init__(self, d) - - self.data = PBXDict(self.data) - self.objects = self.get('objects') - self.modified = False - - root_id = self.get('rootObject') - if root_id: - self.root_object = self.objects[root_id] - root_group_id = self.root_object.get('mainGroup') - self.root_group = self.objects[root_group_id] - else: - print "error: project has no root object" - self.root_object = None - self.root_group = None - - for k,v in self.objects.iteritems(): - v.id = k - - def add_other_cflags(self, flags): - build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration'] - - for b in build_configs: - if b.add_other_cflags(flags): - self.modified = True - - def add_header_search_paths(self, paths, recursive=True): - build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration'] - - for b in build_configs: - if b.add_header_search_paths(paths, recursive): - self.modified = True - - def add_library_search_paths(self, paths, recursive=True): - build_configs = [b for b in self.objects.values() if b.get('isa') == 'XCBuildConfiguration'] - - for b in build_configs: - if b.add_library_search_paths(paths, recursive): - self.modified = True - - # TODO: need to return value if project has been modified - - def get_obj(self, id): - return self.objects.get(id) - - def get_files_by_os_path(self, os_path, tree='SOURCE_ROOT'): - files = [f for f in self.objects.values() if f.get('isa') == 'PBXFileReference' - and f.get('path') == os_path] - - return files - - def get_files_by_name(self, name, parent=None): - if parent: - files = [f for f in self.objects.values() if f.get('isa') == 'PBXFileReference' - and f.get(name) == name - and parent.has_child(f)] - else: - files = [f for f in self.objects.values() if f.get('isa') == 'PBXFileReference' - and f.get(name) == name] - - return files - - def get_build_files(self, id): - files = [f for f in self.objects.values() if f.get('isa') == 'PBXBuildFile' - and f.get('fileRef') == id] - - return files - - def get_groups_by_name(self, name, parent=None): - if parent: - groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup' - and g.get_name() == name - and parent.has_child(g)] - else: - groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup' - and g.get_name() == name] - - return groups - - def get_or_create_group(self, name, path=None, parent=None): - if not name: - return None - - if not parent: - parent = self.root_group - elif not isinstance(parent, PBXGroup): - # assume it's an id - parent = self.objects.get(parent, self.root_group) - - groups = self.get_groups_by_name(name) - - for grp in groups: - if parent.has_child(grp.id): - return grp - - grp = PBXGroup.Create(name, path) - parent.add_child(grp) - - self.objects[grp.id] = grp - - self.modified = True - - return grp - - def get_groups_by_os_path(self, path): - path = os.path.abspath(path) - - groups = [g for g in self.objects.values() if g.get('isa') == 'PBXGroup' - and os.path.abspath(g.get('path','/dev/null')) == path] - - return groups - - def get_build_phases(self, phase_name): - phases = [p for p in self.objects.values() if p.get('isa') == phase_name] - - return phases - - def get_relative_path(self, os_path): - return os.path.relpath(os_path, self.source_root) - - def verify_files(self, file_list, parent=None): - # returns list of files not in the current project. - if not file_list: - return [] - - if parent: - exists_list = [f.get('name') for f in self.objects.values() if f.get('isa') == 'PBXFileReference' and f.get('name') in file_list and parent.has_child(f)] - else: - exists_list = [f.get('name') for f in self.objects.values() if f.get('isa') == 'PBXFileReference' and f.get('name') in file_list] - - return set(file_list).difference(exists_list) - - def add_folder(self, os_path, parent=None, excludes=None, recursive=True, create_build_files=True): - if not os.path.isdir(os_path): - return [] - - if not excludes: - excludes = [] - - results = [] - - if not parent: - parent = self.root_group - elif not isinstance(parent, PBXGroup): - # assume it's an id - parent = self.objects.get(parent, self.root_group) - - path_dict = {os.path.split(os_path)[0]:parent} - special_list = [] - - for (grp_path, subdirs, files) in os.walk(os_path): - parent_folder, folder_name = os.path.split(grp_path) - parent = path_dict.get(parent_folder, parent) - - if [sp for sp in special_list if parent_folder.startswith(sp)]: - continue - - if folder_name.startswith('.'): - special_list.append(grp_path) - continue - - if os.path.splitext(grp_path)[1] in XcodeProject.special_folders: - # if this file has a special extension (bundle or framework mainly) treat it as a file - special_list.append(grp_path) - - new_files = self.verify_files([folder_name], parent=parent) - - if new_files: - results.extend(self.add_file(grp_path, parent, create_build_files=create_build_files)) - - continue - - # create group - grp = self.get_or_create_group(folder_name, path=self.get_relative_path(grp_path) , parent=parent) - path_dict[grp_path] = grp - - results.append(grp) - - file_dict = {} - - for f in files: - if f[0] == '.' or [m for m in excludes if re.match(m,f)]: - continue - - kwds = { - 'create_build_files': create_build_files, - 'parent': grp, - 'name': f - } - - f_path = os.path.join(grp_path, f) - - file_dict[f_path] = kwds - - new_files = self.verify_files([n.get('name') for n in file_dict.values()], parent=grp) - - add_files = [(k,v) for k,v in file_dict.items() if v.get('name') in new_files] - - for path, kwds in add_files: - kwds.pop('name', None) - - self.add_file(path, **kwds) - - if not recursive: - break - - for r in results: - self.objects[r.id] = r - - return results - - def add_file(self, f_path, parent=None, tree='SOURCE_ROOT', create_build_files=True, weak=False): - results = [] - - abs_path = '' - - if os.path.isabs(f_path): - abs_path = f_path - - if not os.path.exists(f_path): - return results - elif tree == 'SOURCE_ROOT': - f_path = os.path.relpath(f_path, self.source_root) - else: - tree = '' - - if not parent: - parent = self.root_group - elif not isinstance(parent, PBXGroup): - # assume it's an id - parent = self.objects.get(parent, self.root_group) - - file_ref = PBXFileReference.Create(f_path, tree) - parent.add_child(file_ref) - results.append(file_ref) - # create a build file for the file ref - if file_ref.build_phase and create_build_files: - phases = self.get_build_phases(file_ref.build_phase) - - for phase in phases: - build_file = PBXBuildFile.Create(file_ref, weak=weak) - - phase.add_build_file(build_file) - results.append(build_file) - - if abs_path and tree == 'SOURCE_ROOT' and os.path.isfile(abs_path)\ - and file_ref.build_phase == 'PBXFrameworksBuildPhase': - - library_path = os.path.join('$(SRCROOT)', os.path.split(f_path)[0]) - - self.add_library_search_paths([library_path], recursive=False) - - for r in results: - self.objects[r.id] = r - - if results: - self.modified = True - - return results - - def remove_group(self, grp): - pass - - def remove_file(self, path, parent): - files = self.get_files_by_os_path(path) - for r in files: - del self.objects[r.id] - self.modified = True - - def move_file(self, id, dest_grp=None): - pass - - def apply_patch(self, patch_path, xcode_path): - if not os.path.isfile(patch_path) or not os.path.isdir(xcode_path): - print 'ERROR: couldn\'t apply "%s" to "%s"' % (patch_path, xcode_path) - return - - print 'applying "%s" to "%s"' % (patch_path, xcode_path) - - return subprocess.call(['patch', '-p1', '--forward', '--directory=%s'%xcode_path, '--input=%s'%patch_path]) - - def apply_mods(self, mod_dict, default_path=None): - if not default_path: - default_path = os.getcwd() - - keys = mod_dict.keys() - - for k in keys: - v = mod_dict.pop(k) - - mod_dict[k.lower()] = v - - parent = mod_dict.pop('group', None) - - if parent: - parent = self.get_or_create_group(parent) - - excludes = mod_dict.pop('excludes', []) - - if excludes: - excludes = [re.compile(e) for e in excludes] - - compiler_flags = mod_dict.pop('compiler_flags', {}) - - for k,v in mod_dict.items(): - if k == 'patches': - for p in v: - if not os.path.isabs(p): - p = os.path.join(default_path, p) - - self.apply_patch(p, self.source_root) - elif k == 'folders': - # get and compile excludes list - # do each folder individually - for folder in v: - kwds = {} - - # if path contains ':' remove it and set recursive to False - if ':' in folder: - args = folder.split(':') - kwds['recursive'] = False - folder = args.pop(0) - - if os.path.isabs(folder) and os.path.isdir(folder): - pass - else: - folder = os.path.join(default_path, folder) - if not os.path.isdir(folder): - continue - - if parent: - kwds['parent'] = parent - - if excludes: - kwds['excludes'] = excludes - - self.add_folder(folder, **kwds) - elif k == 'headerpaths' or k == 'librarypaths': - paths = [] - - for p in v: - if p.endswith('/**'): - p = os.path.split(p)[0] - - if not os.path.isabs(p): - p = os.path.join(default_path, p) - - if not os.path.exists(p): - continue - - p = self.get_relative_path(p) - - paths.append(os.path.join('$(SRCROOT)', p, "**")) - - if k == 'headerpaths': - self.add_header_search_paths(paths) - else: - self.add_library_search_paths(paths) - elif k == 'other_cflags': - self.add_other_cflags(v) - elif k == 'libs' or k == 'frameworks' or k == 'files': - paths = {} - - for p in v: - kwds = {} - - if ':' in p: - args = p.split(':') - p = args.pop(0) - - if 'weak' in args: - kwds['weak'] = True - - file_path = os.path.join(default_path, p) - search_path, file_name = os.path.split(file_path) - - if [m for m in excludes if re.match(m,file_name)]: - continue - - try: - expr = re.compile(file_name) - except re.error: - expr = None - - if expr and os.path.isdir(search_path): - file_list = os.listdir(search_path) - - for f in file_list: - if [m for m in excludes if re.match(m,f)]: - continue - - if re.search(expr,f): - kwds['name'] = f - paths[os.path.join(search_path, f)] = kwds - p = None - - if k == 'libs': - kwds['parent'] = self.get_or_create_group('Libraries', parent=parent) - elif k == 'frameworks': - kwds['parent'] = self.get_or_create_group('Frameworks', parent=parent) - - if p: - kwds['name'] = file_name - - if k == 'libs': - p = os.path.join('usr','lib',p) - kwds['tree'] = 'SDKROOT' - elif k == 'frameworks': - p = os.path.join('System','Library','Frameworks',p) - kwds['tree'] = 'SDKROOT' - elif k == 'files' and not os.path.exists(file_path): - # don't add non-existent files to the project. - continue - - paths[p] = kwds - - new_files = self.verify_files([n.get('name') for n in paths.values()]) - - add_files = [(k,v) for k,v in paths.items() if v.get('name') in new_files] - - for path, kwds in add_files: - kwds.pop('name', None) - - if not kwds.has_key('parent') and parent: - kwds['parent'] = parent - - self.add_file(path, **kwds) - - if compiler_flags: - for k,v in compiler_flags.items(): - filerefs = [] - - for f in v: - filerefs.extend([fr.id for fr in self.objects.values() if fr.get('isa') == 'PBXFileReference' - and fr.get('name') == f]) - - - buildfiles = [bf for bf in self.objects.values() if bf.get('isa') == 'PBXBuildFile' - and bf.get('fileRef') in filerefs] - - for bf in buildfiles: - if bf.add_compiler_flag(k): - self.modified = True - - - def backup(self, file_name=None): - if not file_name: - file_name = self.pbxproj_path - - backup_name = "%s.%s.backup" % (file_name, datetime.datetime.now().strftime('%d%m%y-%H%M%S')) - - shutil.copy2(file_name, backup_name) - - def save(self, file_name=None): - if not file_name: - file_name = self.pbxproj_path - - # JSON serialize the project and convert that json to an xml plist - p = subprocess.Popen([XcodeProject.plutil_path, '-convert', 'xml1', '-o', file_name, '-'], stdin=subprocess.PIPE) - p.communicate(PBXEncoder().encode(self.data)) - - @classmethod - def Load(cls, path): - cls.plutil_path = os.path.join(os.path.split(__file__)[0], 'plutil') - - if not os.path.isfile(XcodeProject.plutil_path): - cls.plutil_path = 'plutil' - - if subprocess.call([XcodeProject.plutil_path,'-lint','-s',path]): - print 'ERROR: not a valid .pbxproj file' - return None - - # load project by converting to JSON and parse - p = subprocess.Popen([XcodeProject.plutil_path, '-convert', 'json', '-o', '-', path], stdout=subprocess.PIPE) - tree = json.loads(p.communicate()[0]) - - return XcodeProject(tree, path) - - -def test(argv=None): - if not argv: - argv = sys.argv - - proj = XcodeProject.Load('../../Build/Unity-iPhone.xcodeproj/project.pbxproj') - - proj.add_folder('../Assets/Editor/Airship/UI/Default/StoreFront') - - proj.add_file('../Assets/Editor/Airship/libUAirship-1.1.4.a') - proj.add_file('../Assets/Plugins/Airship/AirshipConfig.plist') - - proj.backup() - proj.save() - - print str(proj) - diff --git a/Tools/XcodeCapp/parser.j b/Tools/XcodeCapp/parser.j deleted file mode 100644 index 0855eed36..000000000 --- a/Tools/XcodeCapp/parser.j +++ /dev/null @@ -1,556 +0,0 @@ -/* - * parser.j - * - * Created by Francisco Tolmasky. - * Modified by Antoine Mercadal, with great help of Martin Carlberg - * Copyright 2008-2013, 280 North, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -@import - -var FILE = require("file"); - -// Debug function to print some JS objects -function dump(obj) -{ - CPLogPrint(JSON.stringify(obj)); -} - -var xcc = ObjectiveJ.acorn.walk.make( - { - ClassDeclarationStatement: function(node, st, c) - { - if (node.categoryname) - { - CPLogPrint("Categories are not supported yet. Ignoring it."); - return; - } - - var className = node.classname.name, - superclassname = node.superclassname.name, - declaredOutletsName = [], - classInfo = { - "name": className, - "superClass": superclassname, - "outlets": [], - "actions": [], - "actionNames": [] - }; - - if (node.ivardeclarations) - { - for (var i = 0; i < node.ivardeclarations.length; ++i) - { - var ivarDecl = node.ivardeclarations[i], - ivarType = ivarDecl.ivartype ? ivarDecl.ivartype.name : null, - ivarName = ivarDecl.id.name, - ivarHasOutlet = ivarDecl.outlet ? "@outlet" : null; - - if (ivarHasOutlet) - { - if (declaredOutletsName.indexOf(ivarName) !== -1) - throw("Outlet named '" + ivarName + "' is declared multiple times."); - - declaredOutletsName.push(ivarName); - classInfo.outlets.push({"type": ivarType, "name": ivarName}); - } - } - } - - st.push(classInfo) - - for (var i = 0; i < node.body.length; ++i) - c(node.body[i], classInfo, "Statement"); - }, - - MethodDeclarationStatement: function(node, st, c) - { - var selectors = node.selectors, - arguments = node.arguments, - methodReturnType = [node.returntype ? node.returntype.name : "id"], - methodHasAction = node.action ? "IBAction" : null, - selector = selectors[0].name, - actionInformations = {"name": selector, "arguments":[]}; - - if (methodHasAction && arguments.length == 1) - { - if (st.actionNames.indexOf(selector) !== -1) - throw("Action named '" + selector + "' is declared multiple times."); - - st.actionNames.push(selector); - - for (var i = 0; i < arguments.length; i++) - { - var argument = arguments[i], - argumentName = argument.identifier.name, - argumentType = argument.type ? argument.type.name : null; - - actionInformations.arguments.push({"type": argumentType, "name": argumentName}); - } - - st.actions.push(actionInformations) - } - else if (methodHasAction) - throw("Method '" + selector + "' is an action but has more than one parameter."); - - } - } -); - -function compile(node, state, visitor) -{ - function c(node, st, override) - { - visitor[override || node.type](node, st, c); - } - - c(node, state); -}; - - -function main(args) -{ - var fileURL = new CFURL(args[1]), - outputHeaderURL = new CFURL(args[2]), - outputSourceURL = new CFURL(args[3]), - source = FILE.read(fileURL, { charset: "UTF-8" }), - flags = ObjectiveJ.Preprocessor.Flags.IncludeDebugSymbols | ObjectiveJ.Preprocessor.Flags.IncludeTypeSignatures, - tokens = ObjectiveJ.acorn.parse(source), - classesInformation = [], - ObjectiveCSource = "", - ObjectiveCHeader = ""; - - - compile(tokens, classesInformation, xcc); - - // dump(classesInformation) - - ObjectiveCHeader += - "#import \n" + - "#import \n" + - "#import \"xcc_general_include.h\"\n\n"; - - ObjectiveCSource += "#import \"" + outputHeaderURL.absoluteString().replace(/\\/g,'/').replace(/(.*\/)/g, '') + "\"\n\n"; - - // Traverse each found classes - classesInformation.forEach(function(aClass) - { - // add new class definition - ObjectiveCHeader += "@interface " + aClass.name + " : " + NSCompatibleClassName(aClass.superClass) + "\n\n"; - - // Add each outlets in header - aClass.outlets.forEach(function(anOutlet) - { - ObjectiveCHeader += "@property (assign) IBOutlet " + NSCompatibleClassName(anOutlet.type, YES) + " " + anOutlet.name + ";\n"; - }); - - ObjectiveCHeader += "\n"; - - // Add each actions in header - aClass.actions.forEach(function(anAction) - { - ObjectiveCHeader += "- (IBAction)" + anAction.name + ":(" + anAction.arguments[0].type + ")" + anAction.arguments[0].name + ";\n"; - }); - - ObjectiveCHeader += "\n@end\n\n\n"; - - // fill up the implementation file - ObjectiveCSource += "@implementation " + aClass.name + "\n@end\n\n"; - }); - - // write files - if (ObjectiveCSource.length) - FILE.write(outputSourceURL, ObjectiveCSource, { charset:"UTF-8" }); - - if (ObjectiveCHeader.length) - FILE.write(outputHeaderURL, ObjectiveCHeader, { charset:"UTF-8" }); -} - -function NSCompatibleClassName(aClassName, asPointer) -{ - if (aClassName === "var" || aClassName === "id") - return "id"; - - var prefix = aClassName.substr(0, 2), - asterisk = asPointer ? "*" : ""; - - if (prefix !== "CP") - return aClassName + asterisk; - - var NSClassName = "NS" + aClassName.substr(2); - - if (NSClasses[NSClassName]) - return NSClassName + asterisk; - - if (ReplacementClasses[aClassName]) - return ReplacementClasses[aClassName] + asterisk; - - return aClassName + asterisk; -} - -var ReplacementClasses = { - "CPWebView": "WebView", - "CPRadio": "NSButtonCell", - "CPRadioGroup": "NSMatrix" - }; - -var NSClasses = { - "NSAffineTransform" : YES, - "NSAppleEventDescriptor" : YES, - "NSAppleEventManager" : YES, - "NSAppleScript" : YES, - "NSArchiver" : YES, - "NSArray" : YES, - "NSAssertionHandler" : YES, - "NSAttributedString" : YES, - "NSAutoreleasePool" : YES, - "NSBlockOperation" : YES, - "NSBundle" : YES, - "NSCache" : YES, - "NSCachedURLResponse" : YES, - "NSCalendar" : YES, - "NSCharacterSet" : YES, - "NSClassDescription" : YES, - "NSCloneCommand" : YES, - "NSCloseCommand" : YES, - "NSCoder" : YES, - "NSComparisonPredicate" : YES, - "NSCompoundPredicate" : YES, - "NSCondition" : YES, - "NSConditionLock" : YES, - "NSConnection" : YES, - "NSCountCommand" : YES, - "NSCountedSet" : YES, - "NSCreateCommand" : YES, - "NSData" : YES, - "NSDate" : YES, - "NSDateComponents" : YES, - "NSDateFormatter" : YES, - "NSDecimalNumber" : YES, - "NSDecimalNumberHandler" : YES, - "NSDeleteCommand" : YES, - "NSDeserializer" : YES, - "NSDictionary" : YES, - "NSDirectoryEnumerator" : YES, - "NSDistantObject" : YES, - "NSDistantObjectRequest" : YES, - "NSDistributedLock" : YES, - "NSDistributedNotificationCenter" : YES, - "NSEnumerator" : YES, - "NSError" : YES, - "NSException" : YES, - "NSExistsCommand" : YES, - "NSExpression" : YES, - "NSFileHandle" : YES, - "NSFileManager" : YES, - "NSFileWrapper" : YES, - "NSFormatter" : YES, - "NSGarbageCollector" : YES, - "NSGetCommand" : YES, - "NSHashTable" : YES, - "NSHost" : YES, - "NSHTTPCookie" : YES, - "NSHTTPCookieStorage" : YES, - "NSHTTPURLResponse" : YES, - "NSIndexPath" : YES, - "NSIndexSet" : YES, - "NSIndexSpecifier" : YES, - "NSInputStream" : YES, - "NSInvocation" : YES, - "NSInvocationOperation" : YES, - "NSKeyedArchiver" : YES, - "NSKeyedUnarchiver" : YES, - "NSLocale" : YES, - "NSLock" : YES, - "NSLogicalTest" : YES, - "NSMachBootstrapServer" : YES, - "NSMachPort" : YES, - "NSMapTable" : YES, - "NSMessagePort" : YES, - "NSMessagePortNameServer" : YES, - "NSMetadataItem" : YES, - "NSMetadataQuery" : YES, - "NSMetadataQueryAttributeValueTuple" : YES, - "NSMetadataQueryResultGroup" : YES, - "NSMethodSignature" : YES, - "NSMiddleSpecifier" : YES, - "NSMoveCommand" : YES, - "NSMutableArray" : YES, - "NSMutableAttributedString" : YES, - "NSMutableCharacterSet" : YES, - "NSMutableData" : YES, - "NSMutableDictionary" : YES, - "NSMutableIndexSet" : YES, - "NSMutableSet" : YES, - "NSMutableString" : YES, - "NSMutableURLRequest" : YES, - "NSNameSpecifier" : YES, - "NSNetService" : YES, - "NSNetServiceBrowser" : YES, - "NSNotification" : YES, - "NSNotificationCenter" : YES, - "NSNotificationQueue" : YES, - "NSNull" : YES, - "NSNumber" : YES, - "NSNumberFormatter" : YES, - "NSObject" : YES, - "NSOperation" : YES, - "NSOperationQueue" : YES, - "NSOrthography" : YES, - "NSOutputStream" : YES, - "NSPipe" : YES, - "NSPointerArray" : YES, - "NSPointerFunctions" : YES, - "NSPort" : YES, - "NSPortCoder" : YES, - "NSPortMessage" : YES, - "NSPortNameServer" : YES, - "NSPositionalSpecifier" : YES, - "NSPredicate" : YES, - "NSProcessInfo" : YES, - "NSPropertyListSerialization" : YES, - "NSPropertySpecifier" : YES, - "NSProtocolChecker" : YES, - "NSProxy" : YES, - "NSPurgeableData" : YES, - "NSQuitCommand" : YES, - "NSRandomSpecifier" : YES, - "NSRangeSpecifier" : YES, - "NSRecursiveLock" : YES, - "NSRelativeSpecifier" : YES, - "NSRunLoop" : YES, - "NSScanner" : YES, - "NSScriptClassDescription" : YES, - "NSScriptCoercionHandler" : YES, - "NSScriptCommand" : YES, - "NSScriptCommandDescription" : YES, - "NSScriptExecutionContext" : YES, - "NSScriptObjectSpecifier" : YES, - "NSScriptSuiteRegistry" : YES, - "NSScriptWhoseTest" : YES, - "NSSerializer" : YES, - "NSSet" : YES, - "NSSetCommand" : YES, - "NSSocketPort" : YES, - "NSSocketPortNameServer" : YES, - "NSSortDescriptor" : YES, - "NSSpecifierTest" : YES, - "NSSpellServer" : YES, - "NSStream" : YES, - "NSString" : YES, - "NSTask" : YES, - "NSTextCheckingResult" : YES, - "NSThread" : YES, - "NSTimer" : YES, - "NSTimeZone" : YES, - "NSUnarchiver" : YES, - "NSUndoManager" : YES, - "NSUniqueIDSpecifier" : YES, - "NSURL" : YES, - "NSURLAuthenticationChallenge" : YES, - "NSURLCache" : YES, - "NSURLConnection" : YES, - "NSURLCredential" : YES, - "NSURLCredentialStorage" : YES, - "NSURLDownload" : YES, - "NSURLHandle" : YES, - "NSURLProtectionSpace" : YES, - "NSURLProtocol" : YES, - "NSURLRequest" : YES, - "NSURLResponse" : YES, - "NSUserDefaults" : YES, - "NSValue" : YES, - "NSValueTransformer" : YES, - "NSWhoseSpecifier" : YES, - "NSXMLDocument" : YES, - "NSXMLDTD" : YES, - "NSXMLDTDNode" : YES, - "NSXMLElement" : YES, - "NSXMLNode" : YES, - "NSXMLParser" : YES, - "NSActionCell" : YES, - "NSAffineTransform Additions" : YES, - "NSAlert" : YES, - "NSAnimation" : YES, - "NSAnimationContext" : YES, - "NSAppleScript Additions" : YES, - "NSApplication" : YES, - "NSArrayController" : YES, - "NSATSTypesetter" : YES, - "NSAttributedString Application Kit Additions" : YES, - "NSBezierPath" : YES, - "NSBitmapImageRep" : YES, - "NSBox" : YES, - "NSBrowser" : YES, - "NSBrowserCell" : YES, - "NSBundle Additions" : YES, - "NSButton" : YES, - "NSButtonCell" : YES, - "NSCachedImageRep" : YES, - "NSCell" : YES, - "NSCIImageRep" : YES, - "NSClipView" : YES, - "NSCoder Application Kit Additions" : YES, - "NSCollectionView" : YES, - "NSCollectionViewItem" : YES, - "NSColor" : YES, - "NSColorList" : YES, - "NSColorPanel" : YES, - "NSColorPicker" : YES, - "NSColorSpace" : YES, - "NSColorWell" : YES, - "NSComboBox" : YES, - "NSComboBoxCell" : YES, - "NSControl" : YES, - "NSController" : YES, - "NSCursor" : YES, - "NSCustomImageRep" : YES, - "NSDatePicker" : YES, - "NSDatePickerCell" : YES, - "NSDictionaryController" : YES, - "NSDockTile" : YES, - "NSDocument" : YES, - "NSDocumentController" : YES, - "NSDrawer" : YES, - "NSEPSImageRep" : YES, - "NSEvent" : YES, - "NSFileWrapper" : YES, - "NSFont" : YES, - "NSFontDescriptor" : YES, - "NSFontManager" : YES, - "NSFontPanel" : YES, - "NSForm" : YES, - "NSFormCell" : YES, - "NSGlyphGenerator" : YES, - "NSGlyphInfo" : YES, - "NSGradient" : YES, - "NSGraphicsContext" : YES, - "NSHelpManager" : YES, - "NSImage" : YES, - "NSImageCell" : YES, - "NSImageRep" : YES, - "NSImageView" : YES, - "NSLayoutManager" : YES, - "NSLevelIndicator" : YES, - "NSLevelIndicatorCell" : YES, - "NSMatrix" : YES, - "NSMenu" : YES, - "NSMenuItem" : YES, - "NSMenuItemCell" : YES, - "NSMenuView" : YES, - "NSMutableAttributedString Additions" : YES, - "NSMutableParagraphStyle" : YES, - "NSNib" : YES, - "NSNibConnector" : YES, - "NSNibControlConnector" : YES, - "NSNibOutletConnector" : YES, - "NSObjectController" : YES, - "NSOpenGLContext" : YES, - "NSOpenGLLayer" : YES, - "NSOpenGLPixelBuffer" : YES, - "NSOpenGLPixelFormat" : YES, - "NSOpenGLView" : YES, - "NSOpenPanel" : YES, - "NSOutlineView" : YES, - "NSPageLayout" : YES, - "NSPanel" : YES, - "NSParagraphStyle" : YES, - "NSPasteboard" : YES, - "NSPasteboardItem" : YES, - "NSPathCell" : YES, - "NSPathComponentCell" : YES, - "NSPathControl" : YES, - "NSPDFImageRep" : YES, - "NSPersistentDocument" : YES, - "NSPICTImageRep" : YES, - "NSPopUpButton" : YES, - "NSPopUpButtonCell" : YES, - "NSPredicateEditor" : YES, - "NSPredicateEditorRowTemplate" : YES, - "NSPrinter" : YES, - "NSPrintInfo" : YES, - "NSPrintOperation" : YES, - "NSPrintPanel" : YES, - "NSProgressIndicator" : YES, - "NSResponder" : YES, - "NSRuleEditor" : YES, - "NSRulerMarker" : YES, - "NSRulerView" : YES, - "NSRunningApplication" : YES, - "NSSavePanel" : YES, - "NSScreen" : YES, - "NSScroller" : YES, - "NSScrollView" : YES, - "NSSearchField" : YES, - "NSSearchFieldCell" : YES, - "NSSecureTextField" : YES, - "NSSecureTextFieldCell" : YES, - "NSSegmentedCell" : YES, - "NSSegmentedControl" : YES, - "NSShadow" : YES, - "NSSlider" : YES, - "NSSliderCell" : YES, - "NSSound" : YES, - "NSSpeechRecognizer" : YES, - "NSSpeechSynthesizer" : YES, - "NSSpellChecker" : YES, - "NSSplitView" : YES, - "NSStatusBar" : YES, - "NSStatusItem" : YES, - "NSStepper" : YES, - "NSStepperCell" : YES, - "NSString Application Kit Additions" : YES, - "NSTableColumn" : YES, - "NSTableHeaderCell" : YES, - "NSTableHeaderView" : YES, - "NSTableView" : YES, - "NSTabView" : YES, - "NSTabViewItem" : YES, - "NSText" : YES, - "NSTextAttachment" : YES, - "NSTextAttachmentCell" : YES, - "NSTextBlock" : YES, - "NSTextContainer" : YES, - "NSTextField" : YES, - "NSTextFieldCell" : YES, - "NSTextInputContext" : YES, - "NSTextList" : YES, - "NSTextStorage" : YES, - "NSTextTab" : YES, - "NSTextTable" : YES, - "NSTextTableBlock" : YES, - "NSTextView" : YES, - "NSTokenField" : YES, - "NSTokenFieldCell" : YES, - "NSToolbar" : YES, - "NSToolbarItem" : YES, - "NSToolbarItemGroup" : YES, - "NSTouch" : YES, - "NSTrackingArea" : YES, - "NSTreeController" : YES, - "NSTreeNode" : YES, - "NSTypesetter" : YES, - "NSURL Additions" : YES, - "NSUserDefaultsController" : YES, - "NSView" : YES, - "NSViewAnimation" : YES, - "NSViewController" : YES, - "NSWindow" : YES, - "NSWindowController" : YES, - "NSWorkspace" : YES, - "NSPopover": YES - }; diff --git a/Tools/XcodeCapp/pbxprojModifier.py b/Tools/XcodeCapp/pbxprojModifier.py deleted file mode 100755 index 8904d2367..000000000 --- a/Tools/XcodeCapp/pbxprojModifier.py +++ /dev/null @@ -1,63 +0,0 @@ -import sys, os -from mod_pbxproj import XcodeProject - -XCODESUPPORTFOLDER = ".XcodeSupport" - -def update_general_include(project, projectBaseURL): - xcc_general_include_file = "%s/%s/xcc_general_include.h" % (projectBaseURL, XCODESUPPORTFOLDER) - content = "" - - for file in os.listdir("%s/%s" % (projectBaseURL, XCODESUPPORTFOLDER)): - if file.endswith(".h"): - content += "#include \"%s\"\n" % file - - f = open(xcc_general_include_file, "w") - f.write(content) - f.close() - - if len(project.get_files_by_os_path("%s/%s" % (XCODESUPPORTFOLDER, os.path.basename(xcc_general_include_file)))) == 0: - project.add_file(xcc_general_include_file, parent=shadowGroup) - - -def add_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationFilePath, sourcePath, projectBaseURL): - project.add_file(shadowHeaderPath, parent=shadowGroup) - project.add_file(shadowImplementationFilePath, parent=shadowGroup) - - if sourcePath in project.get_files_by_os_path(os.path.relpath(sourcePath, projectBaseURL)): - return - project.add_file(sourcePath, parent=sourceGroup) - -def remove_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationFilePath, sourcePath, projectBaseURL): - project.remove_file("%s/%s" % (XCODESUPPORTFOLDER, os.path.basename(shadowHeaderPath)), parent=shadowGroup) - project.remove_file("%s/%s" % (XCODESUPPORTFOLDER, os.path.basename(shadowImplementationFilePath)), parent=shadowGroup) - project.remove_file(os.path.relpath(sourcePath, projectBaseURL), parent=sourceGroup) - - -if __name__ == '__main__': - - action = sys.argv[1] - PBXProjectFilePath = sys.argv[2] - shadowHeaderFilePath = sys.argv[3] - shadowImplementationFilePath = sys.argv[4] - sourceFilePath = sys.argv[5] - projectBaseURL = sys.argv[6] - - project = XcodeProject.Load(PBXProjectFilePath) - - shadowGroup = project.get_or_create_group('Classes') - sourceGroup = project.get_or_create_group('Sources') - - if "main.j" in sourceFilePath: - sys.exit(0) - - files = project.get_files_by_os_path("%s/%s" % (XCODESUPPORTFOLDER, os.path.basename(shadowHeaderFilePath))) - - if action == "add" and len(files) == 0: - update_general_include(project, projectBaseURL) - add_file(project, shadowGroup, sourceGroup, shadowHeaderFilePath, shadowImplementationFilePath, sourceFilePath, projectBaseURL) - project.save() - - elif action == "remove" and len(files) == 1: - update_general_include(project, projectBaseURL) - remove_file(project, shadowGroup, sourceGroup, shadowHeaderFilePath, shadowImplementationFilePath, sourceFilePath, projectBaseURL) - project.save() diff --git a/Tools/XcodeCapp/project.pbxproj.sample b/Tools/XcodeCapp/project.pbxproj.sample deleted file mode 100644 index 45e5b705f..000000000 --- a/Tools/XcodeCapp/project.pbxproj.sample +++ /dev/null @@ -1,226 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 9EEC4498135749D200615446 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EEC4497135749D200615446 /* Cocoa.framework */; }; - 9EEC44CC13574A0B00615446 /* CappuccinoResources in Resources */ = {isa = PBXBuildFile; fileRef = 9EEC44CB13574A0B00615446 /* CappuccinoResources */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 9EEC4493135749D200615446 /* Another.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Another.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 9EEC4497135749D200615446 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; - 9EEC449A135749D300615446 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; - 9EEC449B135749D300615446 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; - 9EEC449C135749D300615446 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 9EEC44CB13574A0B00615446 /* CappuccinoResources */ = {isa = PBXFileReference; lastKnownFileType = folder; name = CappuccinoResources; path = Resources; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 9EEC4490135749D200615446 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9EEC4498135749D200615446 /* Cocoa.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 9EEC4488135749D200615446 = { - isa = PBXGroup; - children = ( - 9EEC44CB13574A0B00615446 /* CappuccinoResources */, - 9EEC4496135749D200615446 /* Frameworks */, - ); - sourceTree = ""; - }; - 9EEC4494135749D200615446 /* Products */ = { - isa = PBXGroup; - children = ( - 9EEC4493135749D200615446 /* Another.app */, - ); - name = Products; - sourceTree = ""; - }; - 9EEC4496135749D200615446 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 9EEC4497135749D200615446 /* Cocoa.framework */, - 9EEC4499135749D300615446 /* Other Frameworks */, - ); - name = Frameworks; - sourceTree = ""; - }; - 9EEC4499135749D300615446 /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - 9EEC449A135749D300615446 /* AppKit.framework */, - 9EEC449B135749D300615446 /* CoreData.framework */, - 9EEC449C135749D300615446 /* Foundation.framework */, - ); - name = "Other Frameworks"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 9EEC4492135749D200615446 /* Another */ = { - isa = PBXNativeTarget; - buildConfigurationList = 9EEC44C5135749D300615446 /* Build configuration list for PBXNativeTarget "Another" */; - buildPhases = ( - 9EEC448F135749D200615446 /* Sources */, - 9EEC4490135749D200615446 /* Frameworks */, - 9EEC4491135749D200615446 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Another; - productName = Another; - productReference = 9EEC4493135749D200615446 /* Another.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 9EEC448A135749D200615446 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0440; - ORGANIZATIONNAME = "280 North, Inc."; - }; - buildConfigurationList = 9EEC448D135749D200615446 /* Build configuration list for PBXProject "XCCSampleProj" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 9EEC4488135749D200615446; - productRefGroup = 9EEC4494135749D200615446 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 9EEC4492135749D200615446 /* Another */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 9EEC4491135749D200615446 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 9EEC44CC13574A0B00615446 /* CappuccinoResources in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 9EEC448F135749D200615446 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 9EEC44C3135749D300615446 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = DEBUG; - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - }; - name = Debug; - }; - 9EEC44C4135749D300615446 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; - SDKROOT = macosx; - }; - name = Release; - }; - 9EEC44C6135749D300615446 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Another/Another-Prefix.pch"; - INFOPLIST_FILE = "Another/Another-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - 9EEC44C7135749D300615446 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Another/Another-Prefix.pch"; - INFOPLIST_FILE = "Another/Another-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 9EEC448D135749D200615446 /* Build configuration list for PBXProject "XCCSampleProj" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 9EEC44C3135749D300615446 /* Debug */, - 9EEC44C4135749D300615446 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 9EEC44C5135749D300615446 /* Build configuration list for PBXNativeTarget "Another" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 9EEC44C6135749D300615446 /* Debug */, - 9EEC44C7135749D300615446 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 9EEC448A135749D200615446 /* Project object */; -} diff --git a/Tools/XcodeCapp/xcodecapp-cocoa-icon-active.psd b/Tools/XcodeCapp/xcodecapp-cocoa-icon-active.psd deleted file mode 100644 index 2fd63397e..000000000 Binary files a/Tools/XcodeCapp/xcodecapp-cocoa-icon-active.psd and /dev/null differ diff --git a/Tools/XcodeCapp/xcodecapp-icon-active.png b/Tools/XcodeCapp/xcodecapp-icon-active.png deleted file mode 100644 index c48bbe7da..000000000 Binary files a/Tools/XcodeCapp/xcodecapp-icon-active.png and /dev/null differ diff --git a/Tools/XcodeCapp/xcodecapp-icon-inactive.png b/Tools/XcodeCapp/xcodecapp-icon-inactive.png deleted file mode 100644 index 8d62f1c40..000000000 Binary files a/Tools/XcodeCapp/xcodecapp-icon-inactive.png and /dev/null differ diff --git a/Tools/XcodeCapp/xcodecapp-icon-working.png b/Tools/XcodeCapp/xcodecapp-icon-working.png deleted file mode 100644 index e629c2198..000000000 Binary files a/Tools/XcodeCapp/xcodecapp-icon-working.png and /dev/null differ