├── .gitattributes ├── .gitignore ├── Frameworks └── Sparkle.framework │ ├── Headers │ ├── Resources │ ├── Sparkle │ └── Versions │ ├── A │ ├── Headers │ │ ├── SUAppcast.h │ │ ├── SUAppcastItem.h │ │ ├── SUUpdater.h │ │ ├── SUVersionComparisonProtocol.h │ │ └── Sparkle.h │ ├── Resources │ │ ├── Info.plist │ │ ├── License.txt │ │ ├── SUModelTranslation.plist │ │ ├── SUStatus.nib │ │ │ ├── classes.nib │ │ │ ├── info.nib │ │ │ └── keyedobjects.nib │ │ ├── de.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ └── Sparkle.strings │ │ ├── en.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ └── Sparkle.strings │ │ ├── es.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ └── Sparkle.strings │ │ ├── fr.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ └── Sparkle.strings │ │ ├── fr_CA.lproj │ │ ├── it.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ └── Sparkle.strings │ │ ├── nl.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ └── Sparkle.strings │ │ ├── relaunch │ │ ├── ru.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ │ ├── classes.nib │ │ │ │ ├── info.nib │ │ │ │ └── keyedobjects.nib │ │ │ └── Sparkle.strings │ │ └── sv.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── classes.nib │ │ │ ├── info.nib │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── classes.nib │ │ │ ├── info.nib │ │ │ └── keyedobjects.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ ├── classes.nib │ │ │ ├── info.nib │ │ │ └── keyedobjects.nib │ │ │ └── Sparkle.strings │ └── Sparkle │ └── Current ├── Libraries ├── libapr-1.0.2.12.dylib ├── libapr-1.0.dylib ├── libaprutil-1.0.2.12.dylib ├── libaprutil-1.0.dylib ├── libexpat.0.1.0.dylib ├── libneon.27.1.2.dylib ├── libserf-0.0.0.0.dylib ├── libsvn_client-1.0.0.0.dylib ├── libsvn_delta-1.0.0.0.dylib ├── libsvn_diff-1.0.0.0.dylib ├── libsvn_fs-1.0.0.0.dylib ├── libsvn_fs_fs-1.0.0.0.dylib ├── libsvn_fs_util-1.0.0.0.dylib ├── libsvn_ra-1.0.0.0.dylib ├── libsvn_ra_local-1.0.0.0.dylib ├── libsvn_ra_neon-1.0.0.0.dylib ├── libsvn_ra_serf-1.0.0.0.dylib ├── libsvn_ra_svn-1.0.0.0.dylib ├── libsvn_repos-1.0.0.0.dylib ├── libsvn_subr-1.0.0.0.dylib └── libsvn_wc-1.0.0.0.dylib ├── ProjectPlus.xcodeproj └── project.pbxproj ├── Rakefile ├── dsa_pub.pem ├── libs ├── README ├── apr-1.3.2.tar.bz2 ├── apr-util-1.3.2.tar.bz2 ├── convert.sh └── subversion-1.6.0.tar.bz2 ├── release_notes.txt ├── release_notes_template.html.erb ├── resources ├── English.lproj │ └── InfoPlist.strings ├── Info.plist ├── Preferences.xib ├── icons │ ├── Bookmark │ │ ├── Added.png │ │ ├── Conflicted.png │ │ ├── Deleted.png │ │ ├── Locked.png │ │ ├── Modified.png │ │ ├── ReadOnly.png │ │ ├── Versioned.png │ │ └── badges.svg │ ├── CVSClassic │ │ ├── Added.ico │ │ ├── Conflicted.ico │ │ ├── Deleted.ico │ │ ├── Locked.ico │ │ ├── Modified.ico │ │ ├── ReadOnly.ico │ │ └── Versioned.ico │ ├── Classic │ │ ├── Added.ico │ │ ├── Conflicted.ico │ │ ├── Deleted.ico │ │ ├── Locked.ico │ │ ├── Modified.ico │ │ ├── ReadOnly.ico │ │ └── Versioned.ico │ ├── Modern │ │ ├── Added.ico │ │ ├── Conflicted.ico │ │ ├── Deleted.ico │ │ ├── Locked.ico │ │ ├── Modified.ico │ │ ├── ReadOnly.ico │ │ └── Versioned.ico │ ├── Straight │ │ ├── Added.ico │ │ ├── Conflicted.ico │ │ ├── Deleted.ico │ │ ├── Locked.ico │ │ ├── Modified.ico │ │ ├── ReadOnly.ico │ │ └── Versioned.ico │ ├── Subclipse │ │ ├── Added.ico │ │ ├── Conflicted.ico │ │ ├── Deleted.ico │ │ ├── Locked.ico │ │ ├── Modified.ico │ │ ├── ReadOnly.ico │ │ └── Versioned.ico │ ├── XPStyle │ │ ├── Added.ico │ │ ├── Conflicted.ico │ │ ├── Deleted.ico │ │ ├── Locked.ico │ │ ├── Modified.ico │ │ ├── ReadOnly.ico │ │ └── Versioned.ico │ └── license.txt └── projectplus.tiff └── src ├── OpenWith.mm ├── ProjectPlus.h ├── ProjectPlus.mm ├── ProjectTree.mm ├── Sorting.mm ├── TMLabels.mm ├── Tooltips.mm ├── etc ├── JRSwizzle.h ├── JRSwizzle.m ├── ProjectPlus_Prefix.pch └── TextMate.h ├── scm ├── BzrIcons.mm ├── GitIcons.mm ├── HgIcons.mm ├── SCMIcons.h ├── SCMIcons.mm ├── SVNIcons.mm └── SvkIcons.mm └── sidebar ├── CWTMSplitView.h ├── CWTMSplitView.mm ├── KFSplitView.h ├── KFSplitView.m └── SideBarSwitching.mm /.gitattributes: -------------------------------------------------------------------------------- 1 | Preferences.xib -diff 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | ProjectPlus.xcodeproj/ciaran.* 3 | *.tmproj 4 | .DS_Store 5 | dsa_priv.pem 6 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Headers: -------------------------------------------------------------------------------- 1 | Versions/Current/Headers -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Resources: -------------------------------------------------------------------------------- 1 | Versions/Current/Resources -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Sparkle: -------------------------------------------------------------------------------- 1 | Versions/Current/Sparkle -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcast.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcast.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUAPPCAST_H 10 | #define SUAPPCAST_H 11 | 12 | @class SUAppcastItem; 13 | @interface SUAppcast : NSObject { 14 | NSArray *items; 15 | NSString *userAgentString; 16 | id delegate; 17 | NSMutableData *incrementalData; 18 | } 19 | 20 | - (void)fetchAppcastFromURL:(NSURL *)url; 21 | - (void)setDelegate:delegate; 22 | - (void)setUserAgentString:(NSString *)userAgentString; 23 | 24 | - (NSArray *)items; 25 | 26 | @end 27 | 28 | @interface NSObject (SUAppcastDelegate) 29 | - (void)appcastDidFinishLoading:(SUAppcast *)appcast; 30 | - (void)appcast:(SUAppcast *)appcast failedToLoadWithError:(NSError *)error; 31 | @end 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcastItem.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUAPPCASTITEM_H 10 | #define SUAPPCASTITEM_H 11 | 12 | @interface SUAppcastItem : NSObject { 13 | NSString *title; 14 | NSDate *date; 15 | NSString *itemDescription; 16 | 17 | NSURL *releaseNotesURL; 18 | 19 | NSString *DSASignature; 20 | NSString *minimumSystemVersion; 21 | 22 | NSURL *fileURL; 23 | NSString *versionString; 24 | NSString *displayVersionString; 25 | 26 | NSDictionary *propertiesDictionary; 27 | } 28 | 29 | // Initializes with data from a dictionary provided by the RSS class. 30 | - initWithDictionary:(NSDictionary *)dict; 31 | 32 | - (NSString *)title; 33 | - (NSString *)versionString; 34 | - (NSString *)displayVersionString; 35 | - (NSDate *)date; 36 | - (NSString *)itemDescription; 37 | - (NSURL *)releaseNotesURL; 38 | - (NSURL *)fileURL; 39 | - (NSString *)DSASignature; 40 | - (NSString *)minimumSystemVersion; 41 | 42 | // Returns the dictionary provided in initWithDictionary; this might be useful later for extensions. 43 | - (NSDictionary *)propertiesDictionary; 44 | 45 | @end 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Headers/SUUpdater.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdater.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 1/4/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUUPDATER_H 10 | #define SUUPDATER_H 11 | 12 | #import 13 | 14 | @class SUUpdateDriver, SUAppcastItem, SUHost, SUAppcast; 15 | @interface SUUpdater : NSObject { 16 | NSTimer *checkTimer; 17 | SUUpdateDriver *driver; 18 | 19 | SUHost *host; 20 | IBOutlet id delegate; 21 | } 22 | 23 | + (SUUpdater *)sharedUpdater; 24 | + (SUUpdater *)updaterForBundle:(NSBundle *)bundle; 25 | - (NSBundle *)hostBundle; 26 | 27 | - (void)setDelegate:(id)delegate; 28 | - delegate; 29 | 30 | - (void)setAutomaticallyChecksForUpdates:(BOOL)automaticallyChecks; 31 | - (BOOL)automaticallyChecksForUpdates; 32 | 33 | - (void)setUpdateCheckInterval:(NSTimeInterval)interval; 34 | - (NSTimeInterval)updateCheckInterval; 35 | 36 | - (void)setFeedURL:(NSURL *)feedURL; 37 | - (NSURL *)feedURL; 38 | 39 | - (void)setSendsSystemProfile:(BOOL)sendsSystemProfile; 40 | - (BOOL)sendsSystemProfile; 41 | 42 | - (void)setAutomaticallyDownloadsUpdates:(BOOL)automaticallyDownloadsUpdates; 43 | - (BOOL)automaticallyDownloadsUpdates; 44 | 45 | // This IBAction is meant for a main menu item. Hook up any menu item to this action, 46 | // and Sparkle will check for updates and report back its findings verbosely. 47 | - (IBAction)checkForUpdates:sender; 48 | 49 | // This kicks off an update meant to be programmatically initiated. That is, it will display no UI unless it actually finds an update, 50 | // in which case it proceeds as usual. If the fully automated updating is turned on, however, this will invoke that behavior, and if an 51 | // update is found, it will be downloaded and prepped for installation. 52 | - (void)checkForUpdatesInBackground; 53 | 54 | // Date of last update check. Returns null if no check has been performed. 55 | - (NSDate*)lastUpdateCheckDate; 56 | 57 | // This begins a "probing" check for updates which will not actually offer to update to that version. The delegate methods, though, 58 | // (up to updater:didFindValidUpdate: and updaterDidNotFindUpdate:), are called, so you can use that information in your UI. 59 | - (void)checkForUpdateInformation; 60 | 61 | // Call this to appropriately schedule or cancel the update checking timer according to the preferences for time interval and automatic checks. This call does not change the date of the next check, but only the internal NSTimer. 62 | - (void)resetUpdateCycle; 63 | 64 | - (BOOL)updateInProgress; 65 | @end 66 | 67 | @interface NSObject (SUUpdaterDelegateInformalProtocol) 68 | // This method allows you to add extra parameters to the appcast URL, potentially based on whether or not Sparkle will also be sending along the system profile. This method should return an array of dictionaries with keys: "key", "value", "displayKey", "displayValue", the latter two being specifically for display to the user. 69 | - (NSArray *)feedParametersForUpdater:(SUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile; 70 | 71 | // Use this to override the default behavior for Sparkle prompting the user about automatic update checks. 72 | - (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SUUpdater *)bundle; 73 | 74 | // Implement this if you want to do some special handling with the appcast once it finishes loading. 75 | - (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast; 76 | 77 | // If you're using special logic or extensions in your appcast, implement this to use your own logic for finding 78 | // a valid update, if any, in the given appcast. 79 | - (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)bundle; 80 | 81 | // Sent when a valid update is found by the update driver. 82 | - (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)update; 83 | 84 | // Sent when a valid update is not found. 85 | - (void)updaterDidNotFindUpdate:(SUUpdater *)update; 86 | 87 | // Sent immediately before installing the specified update. 88 | - (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update; 89 | 90 | // Return YES to delay the relaunch until you do some processing; invoke the given NSInvocation to continue. 91 | - (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)update untilInvoking:(NSInvocation *)invocation; 92 | 93 | // Called immediately before relaunching. 94 | - (void)updaterWillRelaunchApplication:(SUUpdater *)updater; 95 | 96 | // This method allows you to provide a custom version comparator. 97 | // If you don't implement this method or return nil, the standard version comparator will be used. 98 | - (id )versionComparatorForUpdater:(SUUpdater *)updater; 99 | 100 | // Returns the path which is used to relaunch the client after the update is installed. By default, the path of the host bundle. 101 | - (NSString *)pathToRelaunchForUpdater:(SUUpdater *)updater; 102 | 103 | @end 104 | 105 | // Define some minimum intervals to avoid DOS-like checking attacks. These are in seconds. 106 | #ifdef DEBUG 107 | #define SU_MIN_CHECK_INTERVAL 60 108 | #else 109 | #define SU_MIN_CHECK_INTERVAL 60*60 110 | #endif 111 | 112 | #ifdef DEBUG 113 | #define SU_DEFAULT_CHECK_INTERVAL 60 114 | #else 115 | #define SU_DEFAULT_CHECK_INTERVAL 60*60*24 116 | #endif 117 | 118 | #endif 119 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUVersionComparisonProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/21/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUVERSIONCOMPARISONPROTOCOL_H 10 | #define SUVERSIONCOMPARISONPROTOCOL_H 11 | 12 | /*! 13 | @protocol 14 | @abstract Implement this protocol to provide version comparison facilities for Sparkle. 15 | */ 16 | @protocol SUVersionComparison 17 | 18 | /*! 19 | @method 20 | @abstract An abstract method to compare two version strings. 21 | @discussion Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, and NSOrderedSame if they are equivalent. 22 | */ 23 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; 24 | 25 | @end 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Headers/Sparkle.h: -------------------------------------------------------------------------------- 1 | // 2 | // Sparkle.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07) 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SPARKLE_H 10 | #define SPARKLE_H 11 | 12 | // This list should include the shared headers. It doesn't matter if some of them aren't shared (unless 13 | // there are name-space collisions) so we can list all of them to start with: 14 | 15 | #import 16 | 17 | #import 18 | #import 19 | #import 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | Sparkle 9 | CFBundleIdentifier 10 | org.andymatuschak.Sparkle 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Sparkle 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.5 Beta (bzr) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 296 23 | 24 | 25 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006 Andy Matuschak 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ADP2,1 6 | Developer Transition Kit 7 | MacBook1,1 8 | MacBook (Core Duo) 9 | MacBook2,1 10 | MacBook (Core 2 Duo) 11 | MacBook4,1 12 | MacBook (Core 2 Duo Feb 2008) 13 | MacBookAir1,1 14 | MacBook Air (January 2008) 15 | MacBookPro1,1 16 | MacBook Pro Core Duo (15-inch) 17 | MacBookPro1,2 18 | MacBook Pro Core Duo (17-inch) 19 | MacBookPro2,1 20 | MacBook Pro Core 2 Duo (17-inch) 21 | MacBookPro2,2 22 | MacBook Pro Core 2 Duo (15-inch) 23 | MacBookPro3,1 24 | MacBook Pro Core 2 Duo (15-inch LED, Core 2 Duo) 25 | MacBookPro3,2 26 | MacBook Pro Core 2 Duo (17-inch HD, Core 2 Duo) 27 | MacBookPro4,1 28 | MacBook Pro (Core 2 Duo Feb 2008) 29 | MacPro1,1 30 | Mac Pro (four-core) 31 | MacPro2,1 32 | Mac Pro (eight-core) 33 | MacPro3,1 34 | Mac Pro (January 2008 4- or 8- core "Harpertown") 35 | Macmini1,1 36 | Mac Mini (Core Solo/Duo) 37 | PowerBook1,1 38 | PowerBook G3 39 | PowerBook2,1 40 | iBook G3 41 | PowerBook2,2 42 | iBook G3 (FireWire) 43 | PowerBook2,3 44 | iBook G3 45 | PowerBook2,4 46 | iBook G3 47 | PowerBook3,1 48 | PowerBook G3 (FireWire) 49 | PowerBook3,2 50 | PowerBook G4 51 | PowerBook3,3 52 | PowerBook G4 (Gigabit Ethernet) 53 | PowerBook3,4 54 | PowerBook G4 (DVI) 55 | PowerBook3,5 56 | PowerBook G4 (1GHz / 867MHz) 57 | PowerBook4,1 58 | iBook G3 (Dual USB, Late 2001) 59 | PowerBook4,2 60 | iBook G3 (16MB VRAM) 61 | PowerBook4,3 62 | iBook G3 Opaque 16MB VRAM, 32MB VRAM, Early 2003) 63 | PowerBook5,1 64 | PowerBook G4 (17 inch) 65 | PowerBook5,2 66 | PowerBook G4 (15 inch FW 800) 67 | PowerBook5,3 68 | PowerBook G4 (17-inch 1.33GHz) 69 | PowerBook5,4 70 | PowerBook G4 (15 inch 1.5/1.33GHz) 71 | PowerBook5,5 72 | PowerBook G4 (17-inch 1.5GHz) 73 | PowerBook5,6 74 | PowerBook G4 (15 inch 1.67GHz/1.5GHz) 75 | PowerBook5,7 76 | PowerBook G4 (17-inch 1.67GHz) 77 | PowerBook5,8 78 | PowerBook G4 (Double layer SD, 15 inch) 79 | PowerBook5,9 80 | PowerBook G4 (Double layer SD, 17 inch) 81 | PowerBook6,1 82 | PowerBook G4 (12 inch) 83 | PowerBook6,2 84 | PowerBook G4 (12 inch, DVI) 85 | PowerBook6,3 86 | iBook G4 87 | PowerBook6,4 88 | PowerBook G4 (12 inch 1.33GHz) 89 | PowerBook6,5 90 | iBook G4 (Early-Late 2004) 91 | PowerBook6,7 92 | iBook G4 (Mid 2005) 93 | PowerBook6,8 94 | PowerBook G4 (12 inch 1.5GHz) 95 | PowerMac1,1 96 | Power Macintosh G3 (Blue & White) 97 | PowerMac1,2 98 | Power Macintosh G4 (PCI Graphics) 99 | PowerMac10,1 100 | Mac Mini G4 101 | PowerMac10,2 102 | Mac Mini (Late 2005) 103 | PowerMac11,2 104 | Power Macintosh G5 (Late 2005) 105 | PowerMac12,1 106 | iMac G5 (iSight) 107 | PowerMac2,1 108 | iMac G3 (Slot-loading CD-ROM) 109 | PowerMac2,2 110 | iMac G3 (Summer 2000) 111 | PowerMac3,1 112 | Power Macintosh G4 (AGP Graphics) 113 | PowerMac3,2 114 | Power Macintosh G4 (AGP Graphics) 115 | PowerMac3,3 116 | Power Macintosh G4 (Gigabit Ethernet) 117 | PowerMac3,4 118 | Power Macintosh G4 (Digital Audio) 119 | PowerMac3,5 120 | Power Macintosh G4 (Quick Silver) 121 | PowerMac3,6 122 | Power Macintosh G4 (Mirrored Drive Door) 123 | PowerMac4,1 124 | iMac G3 (Early/Summer 2001) 125 | PowerMac4,2 126 | iMac G4 (Flat Panel) 127 | PowerMac4,4 128 | eMac 129 | PowerMac4,5 130 | iMac G4 (17-inch Flat Panel) 131 | PowerMac5,1 132 | Power Macintosh G4 Cube 133 | PowerMac6,1 134 | iMac G4 (USB 2.0) 135 | PowerMac6,3 136 | iMac G4 (20-inch Flat Panel) 137 | PowerMac6,4 138 | eMac (USB 2.0, 2005) 139 | PowerMac7,2 140 | Power Macintosh G5 141 | PowerMac7,3 142 | Power Macintosh G5 143 | PowerMac8,1 144 | iMac G5 145 | PowerMac8,2 146 | iMac G5 (Ambient Light Sensor) 147 | PowerMac9,1 148 | Power Macintosh G5 (Late 2005) 149 | RackMac1,1 150 | Xserve G4 151 | RackMac1,2 152 | Xserve G4 (slot-loading, cluster node) 153 | RackMac3,1 154 | Xserve G5 155 | Xserve1,1 156 | Xserve (Intel Xeon) 157 | Xserve2,1 158 | Xserve (January 2008 quad-core) 159 | iMac1,1 160 | iMac G3 (Rev A-D) 161 | iMac4,1 162 | iMac (Core Duo) 163 | iMac4,2 164 | iMac for Education (17-inch, Core Duo) 165 | iMac5,1 166 | iMac (Core 2 Duo, 17 or 20 inch, SuperDrive) 167 | iMac5,2 168 | iMac (Core 2 Duo, 17 inch, Combo Drive) 169 | iMac6,1 170 | iMac (Core 2 Duo, 24 inch, SuperDrive) 171 | iMac8,1 172 | iMac (April 2008) 173 | 174 | 175 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | CLASS 25 | FirstResponder 26 | LANGUAGE 27 | ObjC 28 | SUPERCLASS 29 | NSObject 30 | 31 | 32 | CLASS 33 | NSObject 34 | LANGUAGE 35 | ObjC 36 | 37 | 38 | CLASS 39 | SUStatusController 40 | LANGUAGE 41 | ObjC 42 | OUTLETS 43 | 44 | actionButton 45 | NSButton 46 | progressBar 47 | NSProgressIndicator 48 | 49 | SUPERCLASS 50 | SUWindowController 51 | 52 | 53 | IBVersion 54 | 1 55 | 56 | 57 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 10A96 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 658 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9C7010 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 18 14 | 15 | IBSystem Version 16 | 10A96 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 41 15 | 16 | IBSystem Version 17 | 10A96 18 | targetFramework 19 | IBCocoaFramework 20 | 21 | 22 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 629 7 | IBOldestOS 8 | 5 9 | IBOpenObjects 10 | 11 | IBSystem Version 12 | 9D34 13 | targetFramework 14 | IBCocoaFramework 15 | 16 | 17 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 629 7 | IBOldestOS 8 | 5 9 | IBOpenObjects 10 | 11 | IBSystem Version 12 | 9E17 13 | targetFramework 14 | IBCocoaFramework 15 | 16 | 17 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 629 7 | IBOldestOS 8 | 5 9 | IBOpenObjects 10 | 11 | IBSystem Version 12 | 9E17 13 | targetFramework 14 | IBCocoaFramework 15 | 16 | 17 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/fr_CA.lproj: -------------------------------------------------------------------------------- 1 | /Users/ciaran/code/sparkle/build/Release/Sparkle.framework/Resources/fr.lproj -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 5 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 629 7 | IBOldestOS 8 | 5 9 | IBOpenObjects 10 | 11 | 6 12 | 13 | IBSystem Version 14 | 9D34 15 | targetFramework 16 | IBCocoaFramework 17 | 18 | 19 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 629 7 | IBOldestOS 8 | 5 9 | IBOpenObjects 10 | 11 | 6 12 | 13 | IBSystem Version 14 | 9D34 15 | targetFramework 16 | IBCocoaFramework 17 | 18 | 19 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 629 7 | IBOldestOS 8 | 5 9 | IBOpenObjects 10 | 11 | IBSystem Version 12 | 9D34 13 | targetFramework 14 | IBCocoaFramework 15 | 16 | 17 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/relaunch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/relaunch -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9E17 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9E17 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | NSObject 10 | LANGUAGE 11 | ObjC 12 | 13 | 14 | CLASS 15 | SUWindowController 16 | LANGUAGE 17 | ObjC 18 | SUPERCLASS 19 | NSWindowController 20 | 21 | 22 | ACTIONS 23 | 24 | finishPrompt 25 | id 26 | toggleMoreInfo 27 | id 28 | 29 | CLASS 30 | SUUpdatePermissionPrompt 31 | LANGUAGE 32 | ObjC 33 | OUTLETS 34 | 35 | delegate 36 | id 37 | descriptionTextField 38 | NSTextField 39 | moreInfoButton 40 | NSButton 41 | moreInfoView 42 | NSView 43 | 44 | SUPERCLASS 45 | SUWindowController 46 | 47 | 48 | CLASS 49 | FirstResponder 50 | LANGUAGE 51 | ObjC 52 | SUPERCLASS 53 | NSObject 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | IBSystem Version 14 | 9E17 15 | targetFramework 16 | IBCocoaFramework 17 | 18 | 19 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 10A96 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | { 4 | CLASS = FirstResponder; 5 | LANGUAGE = ObjC; 6 | SUPERCLASS = NSObject; 7 | }, 8 | { 9 | CLASS = NSApplication; 10 | LANGUAGE = ObjC; 11 | SUPERCLASS = NSResponder; 12 | }, 13 | { 14 | CLASS = NSObject; 15 | LANGUAGE = ObjC; 16 | }, 17 | { 18 | ACTIONS = { 19 | installUpdate = id; 20 | remindMeLater = id; 21 | skipThisVersion = id; 22 | }; 23 | CLASS = SUUpdateAlert; 24 | LANGUAGE = ObjC; 25 | OUTLETS = { 26 | delegate = id; 27 | description = NSTextField; 28 | releaseNotesView = WebView; 29 | }; 30 | SUPERCLASS = SUWindowController; 31 | }, 32 | { 33 | CLASS = SUWindowController; 34 | LANGUAGE = ObjC; 35 | SUPERCLASS = NSWindowController; 36 | } 37 | ); 38 | IBVersion = 1; 39 | } -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 69 14 356 240 0 0 1280 778 7 | IBFramework Version 8 | 489.0 9 | IBLastKnownRelativeProjectPath 10 | ../Sparkle.xcodeproj 11 | IBOldestOS 12 | 5 13 | IBSystem Version 14 | 9D34 15 | targetFramework 16 | IBCocoaFramework 17 | 18 | 19 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 10A96 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/A/Sparkle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Frameworks/Sparkle.framework/Versions/A/Sparkle -------------------------------------------------------------------------------- /Frameworks/Sparkle.framework/Versions/Current: -------------------------------------------------------------------------------- 1 | A -------------------------------------------------------------------------------- /Libraries/libapr-1.0.2.12.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libapr-1.0.2.12.dylib -------------------------------------------------------------------------------- /Libraries/libapr-1.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libapr-1.0.dylib -------------------------------------------------------------------------------- /Libraries/libaprutil-1.0.2.12.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libaprutil-1.0.2.12.dylib -------------------------------------------------------------------------------- /Libraries/libaprutil-1.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libaprutil-1.0.dylib -------------------------------------------------------------------------------- /Libraries/libexpat.0.1.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libexpat.0.1.0.dylib -------------------------------------------------------------------------------- /Libraries/libneon.27.1.2.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libneon.27.1.2.dylib -------------------------------------------------------------------------------- /Libraries/libserf-0.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libserf-0.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_client-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_client-1.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_delta-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_delta-1.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_diff-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_diff-1.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_fs-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_fs-1.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_fs_fs-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_fs_fs-1.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_fs_util-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_fs_util-1.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_ra-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_ra-1.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_ra_local-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_ra_local-1.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_ra_neon-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_ra_neon-1.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_ra_serf-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_ra_serf-1.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_ra_svn-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_ra_svn-1.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_repos-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_repos-1.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_subr-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_subr-1.0.0.0.dylib -------------------------------------------------------------------------------- /Libraries/libsvn_wc-1.0.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/Libraries/libsvn_wc-1.0.0.0.dylib -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "rubygems" 2 | require "rake" 3 | 4 | require "choctop" 5 | 6 | ChocTop.new do |s| 7 | s.info_plist_path = 'resources/Info.plist' 8 | s.remote_dir = 'ciaranwal.sh/projectplus-files' 9 | s.target = "ProjectPlus.tmplugin" 10 | end 11 | -------------------------------------------------------------------------------- /dsa_pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIDOjCCAi0GByqGSM44BAEwggIgAoIBAQDpmd941RlsHn2X7rudy+xwTb/LnE0v 3 | o1NYqZc3DLhxRciOwBuoE/iuAre59nrfYNjwjaEXrkoOvqd8ZJY8iAf+G4xMijsq 4 | F8o+zfL1POwyoY45ARt/JlhXu1+Y8Ls1OKviyYvrmfekQlcB3xvETeqtGRR8IIlU 5 | 1y6pDR/V6GEn+Tm2NIlTW11JwrtGw8PI1CcT51S2IiwK8Fho2gDPT3NDynIkNF3m 6 | rMuLVbezPq7KfzyJHAfN1hvzkwmdsu82fijILygoNb03BjTfF7AF/+7nMSpLYT1+ 7 | iq/HAZ9OPvPZUVChsk7WXytPVhkivo86Xs3sUVTc4PZUdtVSM45K/5THAhUAoAbd 8 | cebX63vJQ6xtr1pvl4JOwzcCggEAEoCVNekBKnjxbO1smYeFf+ffS/HETjOgQAN+ 9 | EbPgzk1QJike0otDcRN3bzyTmApZBcmilDAPsp9ao6kBntLz215jf4oNCCCSQNh2 10 | AEX+z9MGfuXxBRkkZAyqSpkkLCcpUK+DMK75dNaePMDMiZpmse5WaQVd5Bk1f/gp 11 | 5OBrZmzbPkcHx3nDdIQwP11xZXOtAdS1K3eLtc+0IZggrp7ralqBoIZo7c1Dy8c0 12 | DZeBEC6yRAaHlew54huOJNOl58RaHM01rol6AqoE308w+G5rjoLx8CUf6/8N/zgl 13 | Fqnz0MQctkbtx0QCVTajv5Lz/wVI8edj7rXH0mhvUys8QfGXqgOCAQUAAoIBAFQw 14 | aC3BGsochKBBvHXgN+gg4UI2zl5fW3KOqs6wnig5cPj+2jiwPvQrmj5Tipv8qnvK 15 | jaCj+qP4pRqWMLlvZPznwB7eMArmympw26WmB1c18VZboIo+vBJCQtSlHFRmGc4j 16 | 4iz4tJOcajzlV9f5NsJgUoU8MIiZHvw+Cz58BshElyp/wVO2d+QSp8tW8oD9zBFR 17 | 8DhBAhPajDcfFXa1q677Lo3Y3Zz1kvO3+CwQh6gFPTyKl9PHg2OONtYvf+wMYTDT 18 | hshtgZHNH0EW4DW9bo6Pw9sbDW0xxvXuZi/EtKpMWzJvs+3xV9U0rw2bMpQo+DZe 19 | BoO+H8Q0GHSET+7vyeQ= 20 | -----END PUBLIC KEY----- 21 | -------------------------------------------------------------------------------- /libs/README: -------------------------------------------------------------------------------- 1 | Download APR from http://www.smudge-it.co.uk/pub/apache/apr/apr-1.3.2.tar.bz2 2 | 3 | * configure 4 | * Edit Makefile: change libdir to libdir = @loader_path/../Libraries 5 | * Remove the check in ./libtool to allow for relative rpath values 6 | * make EXTRA_CFLAGS='-arch ppc -arch i386' 7 | 8 | Download APR-Util http://www.smudge-it.co.uk/pub/apache/apr/apr-util-1.3.2.tar.bz2 9 | 10 | * configure --with-apr=/path/to/apr/download 11 | * Edit Makefile: change APU_DSO_LIBDIR and libdir to @loader_path/../Libraries 12 | * make EXTRA_CFLAGS='-arch ppc -arch i386' 13 | 14 | Downloaded SVN from http://subversion.tigris.org/downloads/subversion-1.6.0.tar.bz2 15 | 16 | * configure --with-apr=/path/to/apr/download --with-apr-util=/path/to/apr-util/download --without-neon 17 | * Edit the libdir= line in the Makefile to be: libdir = @loader_path/../Libraries 18 | * Remove the check in ./libtool to allow for relative rpath values 19 | * Run make EXTRA_CFLAGS='-arch ppc -arch i386' 20 | -------------------------------------------------------------------------------- /libs/apr-1.3.2.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/libs/apr-1.3.2.tar.bz2 -------------------------------------------------------------------------------- /libs/apr-util-1.3.2.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/libs/apr-util-1.3.2.tar.bz2 -------------------------------------------------------------------------------- /libs/convert.sh: -------------------------------------------------------------------------------- 1 | for lib in "$1"/*.dylib; do 2 | echo "Processing $lib" 3 | install_path="$(otool -D "$lib"|tail -n1)" 4 | new_install_path="${install_path/executable_path/loader_path}" 5 | if [[ "${install_path}" == "${new_install_path}" ]]; then 6 | echo "- Install path already uses @loader_path" 7 | else 8 | echo "- Changing install path from $install_path to ${new_install_path}" 9 | fi 10 | install_name_tool -id "${new_install_path}" "$lib" 11 | otool -L "$lib"|egrep --only-matching '^ @executable_path.+\.dylib'|while read dependancy_path; do 12 | echo "- Switching dependancy path ${dependancy_path} to @loader_path${dependancy_path#@executable_path}" 13 | install_name_tool -change "${dependancy_path}" "@loader_path${dependancy_path#@executable_path}" "$lib" 14 | done 15 | done -------------------------------------------------------------------------------- /libs/subversion-1.6.0.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/libs/subversion-1.6.0.tar.bz2 -------------------------------------------------------------------------------- /release_notes.txt: -------------------------------------------------------------------------------- 1 | h1. ProjectPlus Version 1.3 2 | 3 | * Updated Subversion libraries to 1.6 4 | * Preferences for default sorting options (thanks to Lakshmi Vya) 5 | 6 | h1. ProjectPlus Version 1.2 7 | 8 | * SCM Badges would not display in some cases 9 | ** When a project was saved in a directory other than the project root, badges would not display. 10 | ** Also fixes some other less common cases which would prevent badges from working. 11 | 12 | Please report any issues you find at the "bug tracker":http://ciaranwal.sh/projectplus-files/ticket. 13 | 14 | h1. ProjectPlus Version 1.1 15 | 16 | * Sidebar 17 | ** TextMate does not load plug-ins until after the application is finished launching, which was causing problems when launching by double-clicking a project file (the project would open without a drawer or pane). This is now handled gracefully, but projects opened in this way will always have the drawer as they are opened before ProjectPlus is loaded. 18 | * SCM Badges 19 | ** Added support for Mercurial, Svk and Bazaar (these should be considered experimental – I don’t use them so please report issues) 20 | ** Hopefully more to come, based on demand and how easy they are to implement 21 | ** Since there are now quite a few, and some of them are expensive to have enabled (as all except SVN use shell execution), all of the SCM modules are disabled by default and you must selectively enable the ones you want 22 | ** Fixed a memory leak that could occur when using SVN badging 23 | ** Misc. performance improvements and bugfixes 24 | * General: 25 | ** Added Sparkle for automatic updates to future versions 26 | ** Added an icon (thanks to Oliver Busch) 27 | ** Other miscellaneous tweaks and improvements 28 | 29 | Please report any issues you find at the new "bug tracker":http://ciaranwal.sh/projectplus-files/ticket. 30 | -------------------------------------------------------------------------------- /release_notes_template.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | Release Notes 4 | 9 | 10 | 11 | <%= release_notes_html %> 12 | 13 | -------------------------------------------------------------------------------- /resources/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleName 10 | ${PRODUCT_NAME} 11 | CFBundleIconFile 12 | projectplus.tiff 13 | CFBundleIdentifier 14 | sh.ciaranwal.projectplus 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.3 23 | NSPrincipalClass 24 | ProjectPlus 25 | SUFeedURL 26 | http://ciaranwal.sh/projectplus-files/appcast.xml 27 | SUPublicDSAKeyFile 28 | dsa_pub.pem 29 | SUEnableSystemProfiling 30 | 31 | ReliesOnClassesFromVersion 32 | 1400 33 | 34 | 35 | -------------------------------------------------------------------------------- /resources/icons/Bookmark/Added.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Bookmark/Added.png -------------------------------------------------------------------------------- /resources/icons/Bookmark/Conflicted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Bookmark/Conflicted.png -------------------------------------------------------------------------------- /resources/icons/Bookmark/Deleted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Bookmark/Deleted.png -------------------------------------------------------------------------------- /resources/icons/Bookmark/Locked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Bookmark/Locked.png -------------------------------------------------------------------------------- /resources/icons/Bookmark/Modified.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Bookmark/Modified.png -------------------------------------------------------------------------------- /resources/icons/Bookmark/ReadOnly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Bookmark/ReadOnly.png -------------------------------------------------------------------------------- /resources/icons/Bookmark/Versioned.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Bookmark/Versioned.png -------------------------------------------------------------------------------- /resources/icons/CVSClassic/Added.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/CVSClassic/Added.ico -------------------------------------------------------------------------------- /resources/icons/CVSClassic/Conflicted.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/CVSClassic/Conflicted.ico -------------------------------------------------------------------------------- /resources/icons/CVSClassic/Deleted.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/CVSClassic/Deleted.ico -------------------------------------------------------------------------------- /resources/icons/CVSClassic/Locked.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/CVSClassic/Locked.ico -------------------------------------------------------------------------------- /resources/icons/CVSClassic/Modified.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/CVSClassic/Modified.ico -------------------------------------------------------------------------------- /resources/icons/CVSClassic/ReadOnly.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/CVSClassic/ReadOnly.ico -------------------------------------------------------------------------------- /resources/icons/CVSClassic/Versioned.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/CVSClassic/Versioned.ico -------------------------------------------------------------------------------- /resources/icons/Classic/Added.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Classic/Added.ico -------------------------------------------------------------------------------- /resources/icons/Classic/Conflicted.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Classic/Conflicted.ico -------------------------------------------------------------------------------- /resources/icons/Classic/Deleted.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Classic/Deleted.ico -------------------------------------------------------------------------------- /resources/icons/Classic/Locked.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Classic/Locked.ico -------------------------------------------------------------------------------- /resources/icons/Classic/Modified.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Classic/Modified.ico -------------------------------------------------------------------------------- /resources/icons/Classic/ReadOnly.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Classic/ReadOnly.ico -------------------------------------------------------------------------------- /resources/icons/Classic/Versioned.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Classic/Versioned.ico -------------------------------------------------------------------------------- /resources/icons/Modern/Added.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Modern/Added.ico -------------------------------------------------------------------------------- /resources/icons/Modern/Conflicted.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Modern/Conflicted.ico -------------------------------------------------------------------------------- /resources/icons/Modern/Deleted.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Modern/Deleted.ico -------------------------------------------------------------------------------- /resources/icons/Modern/Locked.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Modern/Locked.ico -------------------------------------------------------------------------------- /resources/icons/Modern/Modified.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Modern/Modified.ico -------------------------------------------------------------------------------- /resources/icons/Modern/ReadOnly.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Modern/ReadOnly.ico -------------------------------------------------------------------------------- /resources/icons/Modern/Versioned.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Modern/Versioned.ico -------------------------------------------------------------------------------- /resources/icons/Straight/Added.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Straight/Added.ico -------------------------------------------------------------------------------- /resources/icons/Straight/Conflicted.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Straight/Conflicted.ico -------------------------------------------------------------------------------- /resources/icons/Straight/Deleted.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Straight/Deleted.ico -------------------------------------------------------------------------------- /resources/icons/Straight/Locked.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Straight/Locked.ico -------------------------------------------------------------------------------- /resources/icons/Straight/Modified.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Straight/Modified.ico -------------------------------------------------------------------------------- /resources/icons/Straight/ReadOnly.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Straight/ReadOnly.ico -------------------------------------------------------------------------------- /resources/icons/Straight/Versioned.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Straight/Versioned.ico -------------------------------------------------------------------------------- /resources/icons/Subclipse/Added.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Subclipse/Added.ico -------------------------------------------------------------------------------- /resources/icons/Subclipse/Conflicted.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Subclipse/Conflicted.ico -------------------------------------------------------------------------------- /resources/icons/Subclipse/Deleted.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Subclipse/Deleted.ico -------------------------------------------------------------------------------- /resources/icons/Subclipse/Locked.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Subclipse/Locked.ico -------------------------------------------------------------------------------- /resources/icons/Subclipse/Modified.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Subclipse/Modified.ico -------------------------------------------------------------------------------- /resources/icons/Subclipse/ReadOnly.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Subclipse/ReadOnly.ico -------------------------------------------------------------------------------- /resources/icons/Subclipse/Versioned.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/Subclipse/Versioned.ico -------------------------------------------------------------------------------- /resources/icons/XPStyle/Added.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/XPStyle/Added.ico -------------------------------------------------------------------------------- /resources/icons/XPStyle/Conflicted.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/XPStyle/Conflicted.ico -------------------------------------------------------------------------------- /resources/icons/XPStyle/Deleted.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/XPStyle/Deleted.ico -------------------------------------------------------------------------------- /resources/icons/XPStyle/Locked.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/XPStyle/Locked.ico -------------------------------------------------------------------------------- /resources/icons/XPStyle/Modified.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/XPStyle/Modified.ico -------------------------------------------------------------------------------- /resources/icons/XPStyle/ReadOnly.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/XPStyle/ReadOnly.ico -------------------------------------------------------------------------------- /resources/icons/XPStyle/Versioned.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/icons/XPStyle/Versioned.ico -------------------------------------------------------------------------------- /resources/icons/license.txt: -------------------------------------------------------------------------------- 1 | The CVSClassic, Classic, Modern, Straight, Subclipse and XPStyle icon packs used in this plug-in were taken from the TortoiseSVN Project, under the following license, found at 2 | http://tortoisesvn.tigris.org/svn/tortoisesvn/trunk/src/Resources/license.txt 3 | =================================================================== 4 | 5 | 6 | 7 | The icons in these folders are available either under the terms 8 | of the GNU Public License, or under the terms of the TortoiseSVN 9 | Icon License below, unless the folder contains an alternative 10 | license file. 11 | 12 | ==================================================================== 13 | Copyright (c) 2006 The TortoiseSVN Project. All rights reserved. 14 | 15 | Redistribution and use of these icons, with or without modification, 16 | are permitted provided that the following conditions are met: 17 | 18 | 1. Redistributions of these icons as part of a source or binary 19 | distribution must retain the above copyright notice and this 20 | list of conditions. 21 | 22 | 2. The icons may only be used for a Subversion client application, 23 | or for an application with Subversion support (e.g. an IDE). 24 | You may not use these icons for to represent actions which are 25 | not directly related to Subversion. If the application supports 26 | other version control systems besides Subversion, the icons may 27 | be used for those other version control systems too. 28 | 29 | 3. Software using these icons must provide an acknowledgement 30 | that the icons were derived from the TortoiseSVN project, 31 | with a link to the project website (tortoisesvn.tigris.org) 32 | in one or more of the following places: 33 | a) an "about" box. 34 | b) the product user manual. 35 | c) a textfile in the installation folder of the application. 36 | d) a contributors page on the product web page. 37 | 38 | 4. The name "TortoiseSVN" must not be used to endorse or 39 | promote products using these icons without prior written 40 | permission. For written permission, please contact 41 | dev@tortoisesvn.tigris.org. 42 | 43 | 5. If you provide additional icon sets for Subversion actions or 44 | status besides those you use from us, you must give us 45 | permission to use your icon sets too. -------------------------------------------------------------------------------- /resources/projectplus.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ciaran/projectplus/184fafd390dd6a6c1e4601c54503150dd3049b2a/resources/projectplus.tiff -------------------------------------------------------------------------------- /src/OpenWith.mm: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #import "TextMate.h" 4 | 5 | @interface OpenWith : NSObject 6 | + (BOOL)useOpenWith; 7 | + (NSArray*)applicationsForURL:(NSURL*)URL; 8 | @end 9 | 10 | @implementation NSButton (OakMenuButton_OpenWith) 11 | - (void)OpenWith_awakeFromNib 12 | { 13 | [self OpenWith_awakeFromNib]; 14 | 15 | if(not [OpenWith useOpenWith]) 16 | return; 17 | 18 | if(not [[self window] isKindOfClass:NSClassFromString(@"NSDrawerWindow")]) 19 | return; 20 | 21 | NSMenu *menu = [self valueForKey:@"actionMenu"]; 22 | 23 | NSArray* items = [menu itemArray]; 24 | for(int index = 0; index < [items count]; index++) 25 | { 26 | if([[items objectAtIndex:index] action] == @selector(openFileWithFinder:)) 27 | { 28 | NSMenuItem *openWithMenuItem = [[NSMenuItem alloc] initWithTitle:@"Open With…" action:nil keyEquivalent:@""]; 29 | { 30 | NSMenu *openWithSubMenu = [[NSMenu alloc] init]; 31 | [openWithSubMenu setDelegate:self]; 32 | 33 | [openWithMenuItem setSubmenu:openWithSubMenu]; 34 | [openWithSubMenu release]; 35 | } 36 | [menu insertItem:openWithMenuItem atIndex:index+1]; 37 | [openWithMenuItem release]; 38 | break; 39 | } 40 | } 41 | 42 | } 43 | 44 | - (NSURL*)URLForOpeningApp 45 | { 46 | NSOutlineView* outlineView = [self valueForKey:@"outlineView"]; 47 | NSDictionary* item = [outlineView itemAtRow:[outlineView selectedRow]]; 48 | NSString* path = nil; 49 | if([item objectForKey:@"filename"]) 50 | path = [item objectForKey:@"filename"]; 51 | else if([item objectForKey:@"sourceDirectory"]) 52 | path = [item objectForKey:@"sourceDirectory"]; 53 | return [NSURL fileURLWithPath:path]; 54 | } 55 | 56 | - (int)numberOfItemsInMenu:(NSMenu*)menu 57 | { 58 | return [[OpenWith applicationsForURL:[self URLForOpeningApp]] count]; 59 | } 60 | 61 | - (BOOL)menu:(NSMenu*)menu updateItem:(NSMenuItem*)item atIndex:(int)index shouldCancel:(BOOL)flag 62 | { 63 | NSURL* URL = [[OpenWith applicationsForURL:[self URLForOpeningApp]] objectAtIndex:index]; 64 | NSString* title; 65 | LSCopyDisplayNameForURL((CFURLRef)URL, (CFStringRef*)&title); 66 | [item setTitle:title]; 67 | [title release]; 68 | [item setTarget:self]; 69 | [item setTag:index]; 70 | NSImage* icon = [[NSImage alloc] initWithSize:NSMakeSize(16, 16)]; 71 | { 72 | [icon lockFocus]; 73 | [[[NSWorkspace sharedWorkspace] iconForFile:[URL path]] drawInRect:NSMakeRect(0, 0, 16, 16) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; 74 | [item setImage:icon]; 75 | [icon unlockFocus]; 76 | } 77 | [icon release]; 78 | [item setAction:@selector(openSelectedItemWith:)]; 79 | 80 | return YES; 81 | } 82 | 83 | - (void)openSelectedItemWith:(id )sender 84 | { 85 | NSString* filePath = [[self URLForOpeningApp] path]; 86 | NSString* appPath = [[[OpenWith applicationsForURL:[self URLForOpeningApp]] objectAtIndex:[sender tag]] path]; 87 | [[NSWorkspace sharedWorkspace] openFile:filePath withApplication:appPath]; 88 | } 89 | 90 | - (BOOL)OpenWith_validateMenuItem:(id )item 91 | { 92 | if([item action] == @selector(openSelectedItemWith:)) 93 | return YES; 94 | 95 | return [self OpenWith_validateMenuItem:item]; 96 | } 97 | @end 98 | 99 | static NSMutableDictionary* applicationBindings = [[NSMutableDictionary alloc] init]; 100 | 101 | @implementation OpenWith 102 | + (void)load 103 | { 104 | [OakMenuButton jr_swizzleMethod:@selector(awakeFromNib) withMethod:@selector(OpenWith_awakeFromNib) error:NULL]; 105 | [OakMenuButton jr_swizzleMethod:@selector(validateMenuItem:) withMethod:@selector(OpenWith_validateMenuItem:) error:NULL]; 106 | } 107 | 108 | + (BOOL)useOpenWith 109 | { 110 | return YES; 111 | } 112 | 113 | + (NSArray*)applicationsForURL:(NSURL*)URL 114 | { 115 | if(! [applicationBindings objectForKey:URL]) 116 | { 117 | NSArray* apps = (NSArray*)LSCopyApplicationURLsForURL((CFURLRef)URL, kLSRolesAll); 118 | [applicationBindings setObject:(NSArray*)apps forKey:URL]; 119 | [apps release]; 120 | } 121 | return [applicationBindings objectForKey:URL]; 122 | } 123 | @end 124 | -------------------------------------------------------------------------------- /src/ProjectPlus.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "Sparkle/SUUpdater.h" 3 | 4 | extern NSString* ProjectPlus_redrawRequired; 5 | 6 | @protocol TMPlugInController 7 | - (float)version; 8 | @end 9 | 10 | @interface ProjectPlus : NSObject 11 | { 12 | NSImage* icon; 13 | BOOL quickLookAvailable; 14 | IBOutlet NSView *preferencesView; 15 | IBOutlet NSTabView* preferencesTabView; 16 | IBOutlet NSWindow* sortingDefaultsSheet; 17 | 18 | IBOutlet SUUpdater* sparkleUpdater; 19 | } 20 | + (ProjectPlus*)sharedInstance; 21 | - (id)initWithPlugInController:(id )aController; 22 | 23 | - (IBAction)showSortingDefaultsSheet:(id)sender; 24 | - (IBAction)orderOutShortingDefaultSheet:(id)sender; 25 | 26 | - (IBAction)notifyOutlineViewsAsDirty:(id)sender; 27 | - (void)watchDefaultsKey:(NSString*)keyPath; 28 | 29 | - (NSView*)preferencesView; 30 | - (NSImage*)iconImage; 31 | @end -------------------------------------------------------------------------------- /src/ProjectPlus.mm: -------------------------------------------------------------------------------- 1 | #import "ProjectPlus.h" 2 | #import "TextMate.h" 3 | 4 | NSString* ProjectPlus_redrawRequired = @"ProjectPlus_redrawRequired"; 5 | 6 | float ToolbarHeightForWindow(NSWindow *window) 7 | { 8 | NSToolbar *toolbar; 9 | float toolbarHeight = 0.0; 10 | NSRect windowFrame; 11 | 12 | toolbar = [window toolbar]; 13 | 14 | if(toolbar && [toolbar isVisible]) 15 | { 16 | windowFrame = [NSWindow contentRectForFrameRect:[window frame] styleMask:[window styleMask]]; 17 | toolbarHeight = NSHeight(windowFrame) - NSHeight([[window contentView] frame]); 18 | } 19 | 20 | return toolbarHeight; 21 | } 22 | 23 | static const NSString* PROJECTPLUS_PREFERENCES_LABEL = @"Project+"; 24 | 25 | @implementation NSWindowController (PreferenceAdditions) 26 | - (NSArray*)ProjectPlus_toolbarAllowedItemIdentifiers:(id)sender 27 | { 28 | return [[self ProjectPlus_toolbarAllowedItemIdentifiers:sender] arrayByAddingObject:PROJECTPLUS_PREFERENCES_LABEL]; 29 | } 30 | - (NSArray*)ProjectPlus_toolbarDefaultItemIdentifiers:(id)sender 31 | { 32 | return [[self ProjectPlus_toolbarDefaultItemIdentifiers:sender] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:PROJECTPLUS_PREFERENCES_LABEL,nil]]; 33 | } 34 | - (NSArray*)ProjectPlus_toolbarSelectableItemIdentifiers:(id)sender 35 | { 36 | return [[self ProjectPlus_toolbarSelectableItemIdentifiers:sender] arrayByAddingObject:PROJECTPLUS_PREFERENCES_LABEL]; 37 | } 38 | 39 | - (NSToolbarItem*)ProjectPlus_toolbar:(NSToolbar*)toolbar itemForItemIdentifier:(NSString*)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag 40 | { 41 | NSToolbarItem *item = [self ProjectPlus_toolbar:toolbar itemForItemIdentifier:itemIdentifier willBeInsertedIntoToolbar:flag]; 42 | if([itemIdentifier isEqualToString:PROJECTPLUS_PREFERENCES_LABEL]) 43 | [item setImage:[[ProjectPlus sharedInstance] iconImage]]; 44 | return item; 45 | } 46 | 47 | - (void)ProjectPlus_selectToolbarItem:(id)item 48 | { 49 | if ([[item label] isEqualToString:PROJECTPLUS_PREFERENCES_LABEL]) { 50 | if ([[self valueForKey:@"selectedToolbarItem"] isEqualToString:[item label]]) return; 51 | [[self window] setTitle:[item label]]; 52 | [self setValue:[item label] forKey:@"selectedToolbarItem"]; 53 | 54 | NSSize prefsSize = [[[ProjectPlus sharedInstance] preferencesView] frame].size; 55 | NSRect frame = [[self window] frame]; 56 | prefsSize.width = [[self window] contentMinSize].width; 57 | 58 | [[self window] setContentView:[[ProjectPlus sharedInstance] preferencesView]]; 59 | 60 | float newHeight = prefsSize.height + ToolbarHeightForWindow([self window]) + 22; 61 | frame.origin.y += frame.size.height - newHeight; 62 | frame.size.height = newHeight; 63 | frame.size.width = prefsSize.width; 64 | [[self window] setFrame:frame display:YES animate:YES]; 65 | } else { 66 | [self ProjectPlus_selectToolbarItem:item]; 67 | } 68 | } 69 | @end 70 | 71 | @implementation NSWindowController (OakProjectController_Redrawing) 72 | - (id)ProjectPlus_init 73 | { 74 | self = [self ProjectPlus_init]; 75 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ProjectPlus_redrawRequired:) name:ProjectPlus_redrawRequired object:nil]; 76 | return self; 77 | } 78 | 79 | - (void)ProjectPlus_redrawRequired:(NSNotification*)notification 80 | { 81 | [(NSOutlineView*)[self valueForKey:@"outlineView"] setNeedsDisplay:YES]; 82 | } 83 | @end 84 | 85 | static ProjectPlus* SharedInstance = nil; 86 | @implementation ProjectPlus 87 | + (ProjectPlus*)sharedInstance 88 | { 89 | return SharedInstance ?: [[self new] autorelease]; 90 | } 91 | 92 | - (id)init 93 | { 94 | if(SharedInstance) 95 | { 96 | [self release]; 97 | } 98 | else if(self = SharedInstance = [[super init] retain]) 99 | { 100 | quickLookAvailable = [[NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/QuickLookUI.framework"] load]; 101 | 102 | NSApp = [NSApplication sharedApplication]; 103 | 104 | sparkleUpdater = [SUUpdater updaterForBundle:[NSBundle bundleForClass:[self class]]]; 105 | [sparkleUpdater applicationDidFinishLaunching:[NSNotification notificationWithName:NSApplicationDidFinishLaunchingNotification object:NSApp]]; 106 | 107 | // Preferences 108 | NSString* nibPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"Preferences" ofType:@"nib"]; 109 | NSWindowController *controller = [[NSWindowController alloc] initWithWindowNibPath:nibPath owner:self]; 110 | [controller showWindow:self]; 111 | 112 | 113 | [OakPreferencesManager jr_swizzleMethod:@selector(toolbarAllowedItemIdentifiers:) withMethod:@selector(ProjectPlus_toolbarAllowedItemIdentifiers:) error:NULL]; 114 | [OakPreferencesManager jr_swizzleMethod:@selector(toolbarDefaultItemIdentifiers:) withMethod:@selector(ProjectPlus_toolbarDefaultItemIdentifiers:) error:NULL]; 115 | [OakPreferencesManager jr_swizzleMethod:@selector(toolbarSelectableItemIdentifiers:) withMethod:@selector(ProjectPlus_toolbarSelectableItemIdentifiers:) error:NULL]; 116 | [OakPreferencesManager jr_swizzleMethod:@selector(toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:) withMethod:@selector(ProjectPlus_toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:) error:NULL]; 117 | [OakPreferencesManager jr_swizzleMethod:@selector(selectToolbarItem:) withMethod:@selector(ProjectPlus_selectToolbarItem:) error:NULL]; 118 | 119 | [OakProjectController jr_swizzleMethod:@selector(init) withMethod:@selector(ProjectPlus_init) error:NULL]; 120 | } 121 | 122 | return SharedInstance; 123 | } 124 | 125 | - (id)initWithPlugInController:(id )aController 126 | { 127 | if(self = [self init]) 128 | { 129 | NSString* iconPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"projectplus" ofType:@"tiff"]; 130 | icon = [[NSImage alloc] initByReferencingFile:iconPath]; 131 | } 132 | return self; 133 | } 134 | 135 | - (void)dealloc 136 | { 137 | [icon release]; 138 | [super dealloc]; 139 | } 140 | 141 | - (void)awakeFromNib 142 | { 143 | if([[NSUserDefaults standardUserDefaults] stringForKey:@"ProjectPlus Selected Tab Identifier"]) 144 | [preferencesTabView selectTabViewItemWithIdentifier:[[NSUserDefaults standardUserDefaults] stringForKey:@"ProjectPlus Selected Tab Identifier"]]; 145 | } 146 | 147 | - (IBAction)showSortingDefaultsSheet:(id)sender 148 | { 149 | [NSApp beginSheet:sortingDefaultsSheet modalForWindow:[preferencesTabView window] modalDelegate:nil didEndSelector:NULL contextInfo:NULL]; 150 | } 151 | 152 | - (IBAction)orderOutShortingDefaultSheet:(id)sender 153 | { 154 | [sortingDefaultsSheet orderOut:nil]; 155 | [NSApp endSheet:sortingDefaultsSheet]; 156 | } 157 | 158 | - (void)tabView:(NSTabView*)tabView didSelectTabViewItem:(NSTabViewItem*)tabViewItem 159 | { 160 | [[NSUserDefaults standardUserDefaults] setObject:[tabViewItem identifier] forKey:@"ProjectPlus Selected Tab Identifier"]; 161 | } 162 | 163 | - (IBAction)notifyOutlineViewsAsDirty:(id)sender; 164 | { 165 | [[NSNotificationCenter defaultCenter] postNotificationName:ProjectPlus_redrawRequired object:nil]; 166 | } 167 | 168 | - (void)watchDefaultsKey:(NSString*)keyPath 169 | { 170 | [[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:keyPath options:NULL context:NULL]; 171 | } 172 | 173 | - (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)changes context:(void*)context 174 | { 175 | [self notifyOutlineViewsAsDirty:self]; 176 | } 177 | 178 | - (NSView*)preferencesView 179 | { 180 | return preferencesView; 181 | } 182 | 183 | - (NSImage*)iconImage; 184 | { 185 | return icon; 186 | } 187 | 188 | - (BOOL)quickLookAvailable 189 | { 190 | return quickLookAvailable; 191 | } 192 | @end 193 | -------------------------------------------------------------------------------- /src/ProjectTree.mm: -------------------------------------------------------------------------------- 1 | #import "JRSwizzle.h" 2 | 3 | @interface ProjectTree : NSObject 4 | + (BOOL)preserveTreeState; 5 | @end 6 | 7 | @implementation NSWindowController (OakProjectController) 8 | - (void)expandItems:(NSArray*)items inOutlineView:(NSOutlineView*)outlineView toState:(NSDictionary*)treeState 9 | { 10 | unsigned int itemCount = [items count]; 11 | 12 | for(unsigned int index = 0; index < itemCount; index += 1) 13 | { 14 | NSDictionary *item = [items objectAtIndex:index]; 15 | 16 | if(not [item objectForKey:@"children"]) 17 | continue; // We are only interested in directories 18 | 19 | if(NSDictionary *treeItem = [treeState objectForKey:[item objectForKey:@"displayName"]]) 20 | { 21 | if([[treeItem objectForKey:@"isExpanded"] boolValue]) 22 | [outlineView expandItem:item]; 23 | 24 | if([[treeItem objectForKey:@"subItems"] count]) 25 | [self expandItems:[item objectForKey:@"children"] inOutlineView:outlineView toState:[treeItem objectForKey:@"subItems"]]; 26 | } 27 | } 28 | } 29 | 30 | - (void)ProjectTree_windowDidLoad 31 | { 32 | [self ProjectTree_windowDidLoad]; 33 | 34 | if(not [ProjectTree preserveTreeState]) 35 | return; 36 | 37 | [[self valueForKey:@"outlineView"] reloadData]; 38 | 39 | NSDictionary *treeState = [[NSDictionary dictionaryWithContentsOfFile:[self valueForKey:@"filename"]] objectForKey:@"treeState"]; 40 | if(treeState) 41 | { 42 | NSArray *rootItems = [self valueForKey:@"rootItems"]; 43 | NSOutlineView *outlineView = [self valueForKey:@"outlineView"]; 44 | [self expandItems:rootItems inOutlineView:outlineView toState:treeState]; 45 | } 46 | } 47 | 48 | - (NSDictionary*)outlineView:(NSOutlineView*)outlineView stateForItems:(NSArray*)items 49 | { 50 | NSMutableDictionary *treeState = [NSMutableDictionary dictionaryWithCapacity:3]; 51 | unsigned int itemCount = [items count]; 52 | 53 | for(unsigned int index = 0; index < itemCount; index += 1) 54 | { 55 | NSDictionary *item = [items objectAtIndex:index]; 56 | if([outlineView isItemExpanded:item]) 57 | { 58 | NSDictionary *subTreeState = [self outlineView:outlineView stateForItems:[item objectForKey:@"children"]]; 59 | [treeState setObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],@"isExpanded", 60 | subTreeState,@"subItems", 61 | nil] forKey:[item objectForKey:@"displayName"]]; 62 | } 63 | } 64 | 65 | return treeState; 66 | } 67 | 68 | - (BOOL)ProjectTree_writeToFile:(NSString*)fileName 69 | { 70 | BOOL result = [self ProjectTree_writeToFile:fileName]; 71 | if(result && [ProjectTree preserveTreeState]) 72 | { 73 | NSMutableDictionary *project = [NSMutableDictionary dictionaryWithContentsOfFile:fileName]; 74 | NSDictionary *treeState = [self outlineView:[self valueForKey:@"outlineView"] stateForItems:[self valueForKey:@"rootItems"]]; 75 | [project setObject:treeState forKey:@"treeState"]; 76 | result = [project writeToFile:fileName atomically:NO]; 77 | } 78 | return result; 79 | } 80 | @end 81 | 82 | @implementation ProjectTree 83 | + (void)load 84 | { 85 | [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys: 86 | [NSNumber numberWithBool:YES],@"ProjectPlus Preserve Tree", 87 | nil]]; 88 | 89 | [NSClassFromString(@"OakProjectController") jr_swizzleMethod:@selector(windowDidLoad) withMethod:@selector(ProjectTree_windowDidLoad) error:NULL]; 90 | [NSClassFromString(@"OakProjectController") jr_swizzleMethod:@selector(writeToFile:) withMethod:@selector(ProjectTree_writeToFile:) error:NULL]; 91 | } 92 | 93 | + (BOOL)preserveTreeState; 94 | { 95 | return [[NSUserDefaults standardUserDefaults] boolForKey:@"ProjectPlus Preserve Tree"]; 96 | } 97 | @end 98 | -------------------------------------------------------------------------------- /src/Sorting.mm: -------------------------------------------------------------------------------- 1 | #import "TextMate.h" 2 | 3 | @interface ProjectPlusSorting : NSObject 4 | { 5 | } 6 | + (BOOL)useSorting; 7 | + (BOOL)descending; 8 | + (BOOL)byExtension; 9 | + (BOOL)foldersOnTop; 10 | 11 | + (void)addProjectController:(id)projectController; 12 | + (void)removeProjectController:(id)projectController; 13 | + (NSMutableDictionary*)sortDescriptorForProjectController:(id)projectController; 14 | @end 15 | 16 | struct item_sort_descriptor 17 | { 18 | BOOL ascending; 19 | BOOL by_extension; 20 | BOOL folders_on_top; 21 | }; 22 | 23 | int sort_items(id a, id b, void *context) 24 | { 25 | item_sort_descriptor *sortDescriptor = (item_sort_descriptor*)context; 26 | NSString *aText = [a objectForKey:@"displayName"]; 27 | NSString *bText = [b objectForKey:@"displayName"]; 28 | BOOL ignoreExtensions = NO; 29 | 30 | if(sortDescriptor->folders_on_top) 31 | { 32 | BOOL aIsDir = [a objectForKey:@"children"] != nil; 33 | BOOL bIsDir = [b objectForKey:@"children"] != nil; 34 | 35 | if(aIsDir && bIsDir) 36 | ignoreExtensions = NO; // Fall through to name sorting but ignore extensions 37 | else if(aIsDir) 38 | return NSOrderedAscending; 39 | else if(bIsDir) 40 | return NSOrderedDescending; 41 | } 42 | 43 | if(sortDescriptor->by_extension && ! ignoreExtensions) 44 | { 45 | aText = [aText pathExtension]; 46 | bText = [bText pathExtension]; 47 | } 48 | 49 | int result = [aText caseInsensitiveCompare:bText]; 50 | if (not sortDescriptor->ascending) 51 | result = -result; 52 | return result; 53 | } 54 | 55 | @interface NSMutableArray (RecursiveSort) 56 | - (void)recursiveSortItemsAscending:(BOOL)ascending 57 | byExtension:(BOOL)byExtension 58 | foldersOnTop:(BOOL)foldersOnTop; 59 | @end 60 | 61 | 62 | @implementation NSMutableArray (RecursiveSort) 63 | - (void)recursiveSortItemsAscending:(BOOL)ascending 64 | byExtension:(BOOL)byExtension 65 | foldersOnTop:(BOOL)foldersOnTop 66 | { 67 | struct item_sort_descriptor sortDescriptor; 68 | sortDescriptor.ascending = ascending; 69 | sortDescriptor.by_extension = byExtension; 70 | sortDescriptor.folders_on_top = foldersOnTop; 71 | 72 | unsigned int itemCount = [self count]; 73 | 74 | for(unsigned int index = 0; index < itemCount; index += 1) 75 | { 76 | id item = [self objectAtIndex:index]; 77 | 78 | if([item objectForKey:@"children"]) 79 | [[item objectForKey:@"children"] recursiveSortItemsAscending:ascending byExtension:byExtension foldersOnTop:foldersOnTop]; 80 | } 81 | 82 | [self sortUsingFunction:sort_items context:&sortDescriptor]; 83 | } 84 | @end 85 | 86 | @implementation NSWindowController (OakProjectController_Sorting) 87 | - (NSMutableDictionary*)sortDescriptor 88 | { 89 | return [ProjectPlusSorting sortDescriptorForProjectController:self]; 90 | } 91 | 92 | - (void)resortItems 93 | { 94 | NSMutableArray* rootItems = [self valueForKey:@"rootItems"]; 95 | [rootItems recursiveSortItemsAscending:! [[[self sortDescriptor] objectForKey:@"descending"] boolValue] 96 | byExtension:[[[self sortDescriptor] objectForKey:@"byExtension"] boolValue] 97 | foldersOnTop:[[[self sortDescriptor] objectForKey:@"foldersOnTop"] boolValue]]; 98 | [[self valueForKey:@"outlineView"] reloadData]; 99 | } 100 | 101 | - (void)ProjectPlus_Sorting_windowDidLoad 102 | { 103 | [self ProjectPlus_Sorting_windowDidLoad]; 104 | 105 | if(not [ProjectPlusSorting useSorting]) 106 | return; 107 | 108 | [ProjectPlusSorting addProjectController:self]; 109 | [[self sortDescriptor] setObject:[NSNumber numberWithBool:[ProjectPlusSorting foldersOnTop]] forKey:@"foldersOnTop"]; 110 | [[self sortDescriptor] setObject:[NSNumber numberWithBool:[ProjectPlusSorting byExtension]] forKey:@"byExtension"]; 111 | [[self sortDescriptor] setObject:[NSNumber numberWithBool:[ProjectPlusSorting descending]] forKey:@"descending"]; 112 | [self resortItems]; 113 | } 114 | 115 | - (void)toggleDescending:(id )menuItem 116 | { 117 | [menuItem setState:! [menuItem state]]; 118 | [[self sortDescriptor] setObject:[NSNumber numberWithBool:[menuItem state]] forKey:@"descending"]; 119 | [self resortItems]; 120 | } 121 | 122 | - (void)toggleByExtension:(id )menuItem 123 | { 124 | [menuItem setState:! [menuItem state]]; 125 | [[self sortDescriptor] setObject:[NSNumber numberWithBool:[menuItem state]] forKey:@"byExtension"]; 126 | [self resortItems]; 127 | } 128 | 129 | - (void)toggleFoldersOnTop:(id )menuItem 130 | { 131 | [menuItem setState:! [menuItem state]]; 132 | [[self sortDescriptor] setObject:[NSNumber numberWithBool:[menuItem state]] forKey:@"foldersOnTop"]; 133 | [self resortItems]; 134 | } 135 | @end 136 | 137 | @implementation NSButton (OakMenuButton_ProjectPlus_Sorting) 138 | - (void)ProjectPlus_Sorting_awakeFromNib 139 | { 140 | [self ProjectPlus_Sorting_awakeFromNib]; 141 | 142 | if(not [[self window] isKindOfClass:NSClassFromString(@"NSDrawerWindow")]) 143 | return; 144 | 145 | NSMenu *menu = (NSMenu*)[self valueForKey:@"actionMenu"]; 146 | [menu addItem:[NSMenuItem separatorItem]]; 147 | 148 | NSMenuItem *sortingMenu = [[NSMenuItem alloc] initWithTitle:@"Sort" action:nil keyEquivalent:@""]; 149 | { 150 | NSMenu *sortingSubMenu = [[NSMenu alloc] init]; 151 | NSMenuItem *item; 152 | 153 | item = [[NSMenuItem alloc] initWithTitle:@"Descending" 154 | action:@selector(toggleDescending:) 155 | keyEquivalent:@""]; 156 | [item setTarget:[self valueForKey:@"delegate"]]; 157 | [item setState:[ProjectPlusSorting descending]]; 158 | [sortingSubMenu addItem:item]; 159 | [item release]; 160 | 161 | item = [[NSMenuItem alloc] initWithTitle:@"By Extension" 162 | action:@selector(toggleByExtension:) 163 | keyEquivalent:@""]; 164 | [item setTarget:[self valueForKey:@"delegate"]]; 165 | [item setState:[ProjectPlusSorting byExtension]]; 166 | [sortingSubMenu addItem:item]; 167 | [item release]; 168 | 169 | item = [[NSMenuItem alloc] initWithTitle:@"Folders on Top" 170 | action:@selector(toggleFoldersOnTop:) 171 | keyEquivalent:@""]; 172 | [item setTarget:[self valueForKey:@"delegate"]]; 173 | [item setState:[ProjectPlusSorting foldersOnTop]]; 174 | [sortingSubMenu addItem:item]; 175 | [item release]; 176 | 177 | [sortingMenu setSubmenu:sortingSubMenu]; 178 | [sortingSubMenu release]; 179 | } 180 | [menu addItem:sortingMenu]; 181 | [sortingMenu release]; 182 | } 183 | 184 | - (BOOL)ProjectPlus_Sorting_validateMenuItem:(id )menuItem 185 | { 186 | if([menuItem action] == @selector(toggleDescending:) || [menuItem action] == @selector(toggleByExtension:)) 187 | return YES; 188 | 189 | return [self ProjectPlus_Sorting_validateMenuItem:menuItem]; 190 | } 191 | @end 192 | 193 | static NSMutableArray* sortDescriptors = [[NSMutableArray alloc] initWithCapacity:1]; 194 | 195 | @implementation ProjectPlusSorting 196 | + (void)load 197 | { 198 | [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:@"ProjectPlus Use Sorting"]]; 199 | 200 | [OakProjectController jr_swizzleMethod:@selector(windowDidLoad) withMethod:@selector(ProjectPlus_Sorting_windowDidLoad) error:NULL]; 201 | [OakMenuButton jr_swizzleMethod:@selector(awakeFromNib) withMethod:@selector(ProjectPlus_Sorting_awakeFromNib) error:NULL]; 202 | [OakMenuButton jr_swizzleMethod:@selector(validateMenuItem:) withMethod:@selector(ProjectPlus_Sorting_validateMenuItem:) error:NULL]; 203 | } 204 | 205 | + (BOOL)foldersOnTop 206 | { 207 | return [[NSUserDefaults standardUserDefaults] boolForKey:@"ProjectPlusSortingFoldersOnTop"]; 208 | } 209 | 210 | + (BOOL)byExtension 211 | { 212 | return [[NSUserDefaults standardUserDefaults] boolForKey:@"ProjectPlusSortingByExtension"]; 213 | } 214 | 215 | + (BOOL)descending 216 | { 217 | return [[NSUserDefaults standardUserDefaults] boolForKey:@"ProjectPlusSortingDescending"]; 218 | } 219 | 220 | + (BOOL)useSorting 221 | { 222 | return [[NSUserDefaults standardUserDefaults] boolForKey:@"ProjectPlus Use Sorting"]; 223 | } 224 | 225 | + (void)addProjectController:(id)projectController; 226 | { 227 | NSMutableDictionary* sortDescriptor = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],@"descending", 228 | [NSNumber numberWithBool:NO],@"byExtension", 229 | [NSNumber numberWithBool:NO],@"foldersOnTop", 230 | nil]; 231 | [sortDescriptors addObject:[NSDictionary dictionaryWithObjectsAndKeys:projectController,@"controller",sortDescriptor,@"sortDescriptor",nil]]; 232 | } 233 | 234 | + (void)removeProjectController:(id)projectController; 235 | { 236 | unsigned int controllerCount = [sortDescriptors count]; 237 | 238 | for(unsigned int index = 0; index < controllerCount; index += 1) 239 | { 240 | NSDictionary* info = [sortDescriptors objectAtIndex:index]; 241 | if([info objectForKey:@"controller"] == projectController) 242 | { 243 | [sortDescriptors removeObject:info]; 244 | return; 245 | } 246 | } 247 | } 248 | 249 | + (NSMutableDictionary*)sortDescriptorForProjectController:(id)projectController; 250 | { 251 | unsigned int controllerCount = [sortDescriptors count]; 252 | 253 | for(unsigned int index = 0; index < controllerCount; index += 1) 254 | { 255 | NSDictionary* info = [sortDescriptors objectAtIndex:index]; 256 | if([info objectForKey:@"controller"] == projectController) 257 | return [info objectForKey:@"sortDescriptor"]; 258 | } 259 | 260 | return nil; 261 | } 262 | @end 263 | -------------------------------------------------------------------------------- /src/Tooltips.mm: -------------------------------------------------------------------------------- 1 | @implementation NSWindowController (Tooltips) 2 | - (NSString*)outlineView:(NSOutlineView*)anOutlineView toolTipForCell:(NSCell*)aCell rect:(NSRectPointer)aRectPointer tableColumn:(NSTableColumn*)aTableColumn item:(id)anId mouseLocation:(NSPoint)aPoint 3 | { 4 | NSString *tip = nil; 5 | 6 | if([[NSUserDefaults standardUserDefaults] boolForKey:@"ProjectPlus Tooltips Enabled"]) 7 | { 8 | NSString *name = [anId objectForKey:@"displayName"]; 9 | NSSize nameSize = [name sizeWithAttributes:nil]; 10 | 11 | if (nameSize.width < aRectPointer->size.width) 12 | name = nil; 13 | 14 | tip = name; 15 | } 16 | return tip; 17 | } 18 | @end 19 | 20 | @interface ProjectPlus_Tooltips : NSObject 21 | @end 22 | 23 | @implementation ProjectPlus_Tooltips 24 | + (void)load 25 | { 26 | [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:@"ProjectPlus Tooltips Enabled"]]; 27 | } 28 | @end -------------------------------------------------------------------------------- /src/etc/JRSwizzle.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | JRSwizzle.h 3 | Copyright (c) 2007 Jonathan 'Wolf' Rentzsch: 4 | Some rights reserved: 5 | 6 | ***************************************************************************/ 7 | 8 | #import 9 | 10 | @interface NSObject (JRSwizzle) 11 | + (BOOL)jr_swizzleMethod:(SEL)origSel_ withMethod:(SEL)altSel_ error:(NSError**)error_; 12 | + (BOOL)jr_swizzleClassMethod:(SEL)origSel_ withClassMethod:(SEL)altSel_ error:(NSError**)error_; 13 | @end 14 | -------------------------------------------------------------------------------- /src/etc/JRSwizzle.m: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | JRSwizzle.m 3 | Copyright (c) 2007 Jonathan 'Wolf' Rentzsch: 4 | Some rights reserved: 5 | 6 | ***************************************************************************/ 7 | 8 | #import "JRSwizzle.h" 9 | #import 10 | 11 | #define SetNSError(ERROR_VAR, FORMAT,...) \ 12 | if (ERROR_VAR) { \ 13 | NSString *errStr = [@"+[NSObject(JRSwizzle) jr_swizzleMethod:withMethod:error:]: " stringByAppendingFormat:FORMAT,##__VA_ARGS__]; \ 14 | *ERROR_VAR = [NSError errorWithDomain:@"NSCocoaErrorDomain" \ 15 | code:-1 \ 16 | userInfo:[NSDictionary dictionaryWithObject:errStr forKey:NSLocalizedDescriptionKey]]; \ 17 | } 18 | 19 | @implementation NSObject (JRSwizzle) 20 | 21 | + (BOOL)jr_swizzleMethod:(SEL)origSel_ withMethod:(SEL)altSel_ error:(NSError**)error_ { 22 | #if OBJC_API_VERSION >= 2 23 | Method origMethod = class_getInstanceMethod(self, origSel_); 24 | if (!origMethod) { 25 | SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self className]); 26 | return NO; 27 | } 28 | 29 | Method altMethod = class_getInstanceMethod(self, altSel_); 30 | if (!altMethod) { 31 | SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self className]); 32 | return NO; 33 | } 34 | 35 | class_addMethod(self, 36 | origSel_, 37 | class_getMethodImplementation(self, origSel_), 38 | method_getTypeEncoding(origMethod)); 39 | class_addMethod(self, 40 | altSel_, 41 | class_getMethodImplementation(self, altSel_), 42 | method_getTypeEncoding(altMethod)); 43 | 44 | method_exchangeImplementations(class_getInstanceMethod(self, origSel_), class_getInstanceMethod(self, altSel_)); 45 | return YES; 46 | #else 47 | // Scan for non-inherited methods. 48 | Method directOriginalMethod = NULL, directAlternateMethod = NULL; 49 | 50 | void *iterator = NULL; 51 | struct objc_method_list *mlist = class_nextMethodList(self, &iterator); 52 | while (mlist) { 53 | int method_index = 0; 54 | for (; method_index < mlist->method_count; method_index++) { 55 | if (mlist->method_list[method_index].method_name == origSel_) { 56 | assert(!directOriginalMethod); 57 | directOriginalMethod = &mlist->method_list[method_index]; 58 | } 59 | if (mlist->method_list[method_index].method_name == altSel_) { 60 | assert(!directAlternateMethod); 61 | directAlternateMethod = &mlist->method_list[method_index]; 62 | } 63 | } 64 | mlist = class_nextMethodList(self, &iterator); 65 | } 66 | 67 | // If either method is inherited, copy it up to the target class to make it non-inherited. 68 | if (!directOriginalMethod || !directAlternateMethod) { 69 | Method inheritedOriginalMethod = NULL, inheritedAlternateMethod = NULL; 70 | if (!directOriginalMethod) { 71 | inheritedOriginalMethod = class_getInstanceMethod(self, origSel_); 72 | if (!inheritedOriginalMethod) { 73 | SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self className]); 74 | return NO; 75 | } 76 | } 77 | if (!directAlternateMethod) { 78 | inheritedAlternateMethod = class_getInstanceMethod(self, altSel_); 79 | if (!inheritedAlternateMethod) { 80 | SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self className]); 81 | return NO; 82 | } 83 | } 84 | 85 | int hoisted_method_count = !directOriginalMethod && !directAlternateMethod ? 2 : 1; 86 | struct objc_method_list *hoisted_method_list = malloc(sizeof(struct objc_method_list) + (sizeof(struct objc_method)*(hoisted_method_count-1))); 87 | hoisted_method_list->method_count = hoisted_method_count; 88 | Method hoisted_method = hoisted_method_list->method_list; 89 | 90 | if (!directOriginalMethod) { 91 | bcopy(inheritedOriginalMethod, hoisted_method, sizeof(struct objc_method)); 92 | directOriginalMethod = hoisted_method++; 93 | } 94 | if (!directAlternateMethod) { 95 | bcopy(inheritedAlternateMethod, hoisted_method, sizeof(struct objc_method)); 96 | directAlternateMethod = hoisted_method; 97 | } 98 | class_addMethods(self, hoisted_method_list); 99 | } 100 | 101 | // Swizzle. 102 | IMP temp = directOriginalMethod->method_imp; 103 | directOriginalMethod->method_imp = directAlternateMethod->method_imp; 104 | directAlternateMethod->method_imp = temp; 105 | 106 | return YES; 107 | #endif 108 | } 109 | 110 | + (BOOL)jr_swizzleClassMethod:(SEL)origSel_ withClassMethod:(SEL)altSel_ error:(NSError**)error_ { 111 | assert(0); 112 | return NO; 113 | } 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /src/etc/ProjectPlus_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'ProjectPlus' target in the 'ProjectPlus' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /src/etc/TextMate.h: -------------------------------------------------------------------------------- 1 | #import "JRSwizzle.h" 2 | 3 | #define OakProjectController NSClassFromString(@"OakProjectController") 4 | #define OakPreferencesManager NSClassFromString(@"OakPreferencesManager") 5 | #define OakOutlineView NSClassFromString(@"OakOutlineView") 6 | #define OakMenuButton NSClassFromString(@"OakMenuButton") 7 | #define OakWindow NSClassFromString(@"OakWindow") 8 | -------------------------------------------------------------------------------- /src/scm/BzrIcons.mm: -------------------------------------------------------------------------------- 1 | #import "SCMIcons.h" 2 | 3 | #define USE_THREADING 4 | 5 | @interface BzrIcons : NSObject 6 | { 7 | NSMutableDictionary* projectStatuses; 8 | BOOL refreshingProject; 9 | } 10 | + (BzrIcons*)sharedInstance; 11 | @end 12 | 13 | static BzrIcons *SharedInstance; 14 | 15 | @implementation BzrIcons 16 | // ================== 17 | // = Setup/Teardown = 18 | // ================== 19 | + (BzrIcons*)sharedInstance 20 | { 21 | return SharedInstance ?: [[self new] autorelease]; 22 | } 23 | 24 | + (void)load 25 | { 26 | [[SCMIcons sharedInstance] registerSCMDelegate:[[self new] autorelease]]; 27 | } 28 | 29 | - (NSString*)scmName; 30 | { 31 | return @"Bazaar"; 32 | } 33 | 34 | - (id)init 35 | { 36 | if(SharedInstance) 37 | { 38 | [self release]; 39 | } 40 | else if(self = SharedInstance = [[super init] retain]) 41 | { 42 | projectStatuses = [NSMutableDictionary new]; 43 | } 44 | return SharedInstance; 45 | } 46 | 47 | - (void)dealloc 48 | { 49 | [projectStatuses release]; 50 | [super dealloc]; 51 | } 52 | 53 | - (NSString*)bzrPath; 54 | { 55 | return [[SCMIcons sharedInstance] pathForVariable:@"TM_BZR" paths:[NSArray arrayWithObjects:@"/opt/local/bin/bzr",@"/usr/local/bin/bzr",@"/usr/bin/bzr",nil]]; 56 | } 57 | 58 | - (NSString*)launchExecutable:(NSString*)exePath inPath:(NSString*)workingPath withArguments:(NSArray*)arguments; 59 | { 60 | NSTask* task = [[NSTask new] autorelease]; 61 | [task setLaunchPath:exePath]; 62 | [task setCurrentDirectoryPath:workingPath]; 63 | [task setArguments:arguments]; 64 | 65 | NSPipe *pipe = [NSPipe pipe]; 66 | [task setStandardOutput: pipe]; 67 | [task setStandardError:[NSPipe pipe]]; 68 | 69 | NSFileHandle *file = [pipe fileHandleForReading]; 70 | 71 | [task launch]; 72 | 73 | NSData *data = [file readDataToEndOfFile]; 74 | 75 | [task waitUntilExit]; 76 | 77 | if([task terminationStatus] != 0) 78 | return nil; 79 | 80 | return [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease]; 81 | } 82 | 83 | - (void)executeLsFilesUnderPath:(NSString*)path inProject:(NSString*)projectPath; 84 | { 85 | NSString* exePath = [self bzrPath]; 86 | if(!exePath || ![[NSFileManager defaultManager] fileExistsAtPath:exePath]) 87 | return; 88 | 89 | @try 90 | { 91 | NSString* lsResult = [self launchExecutable:exePath inPath:projectPath withArguments:[NSArray arrayWithObjects:@"ls", @"--versioned", @"--null", path, nil]]; 92 | NSArray* lsLines = [lsResult componentsSeparatedByString:@"\0"]; 93 | if(!lsResult) 94 | { 95 | // Prevent repeated calling 96 | [projectStatuses setObject:[NSDictionary dictionary] forKey:projectPath]; 97 | return; 98 | } 99 | 100 | if([lsLines count] > 1) 101 | { 102 | NSMutableDictionary* project = [[NSMutableDictionary alloc] initWithCapacity:[lsLines count]-1]; 103 | for(int index = 0; index < [lsLines count]; index++) 104 | { 105 | NSString* filename = [lsLines objectAtIndex:index]; 106 | [project setObject:[NSNumber numberWithInt:SCMIconsStatusVersioned] forKey:filename]; 107 | } 108 | [projectStatuses setObject:project forKey:projectPath]; 109 | [project release]; 110 | } 111 | 112 | NSString* statusResult = [self launchExecutable:exePath inPath:projectPath withArguments:[NSArray arrayWithObjects:@"status", @"-S", path, nil]]; 113 | if(!statusResult) 114 | { 115 | // Prevent repeated calling 116 | [projectStatuses setObject:[NSDictionary dictionary] forKey:projectPath]; 117 | return; 118 | } 119 | 120 | NSArray* statusLines = [statusResult componentsSeparatedByString:@"\n"]; 121 | if([statusLines count] > 1) 122 | { 123 | NSMutableDictionary* project = [[NSMutableDictionary alloc] initWithCapacity:[statusLines count]-1]; 124 | 125 | for(int index = 0; index < [statusLines count]; index++) 126 | { 127 | NSString* line = [statusLines objectAtIndex:index]; 128 | if([line length] > 3) 129 | { 130 | const char* versioningStatusChar = [[line substringToIndex:1] UTF8String]; 131 | const char* contentsStatusChar = [[line substringWithRange:NSMakeRange(1, 1)] UTF8String]; 132 | NSString* filename = [projectPath stringByAppendingPathComponent:[line substringFromIndex:4]]; 133 | SCMIconsStatus status = SCMIconsStatusUnknown; 134 | switch(*contentsStatusChar) 135 | { 136 | case 'N': status = SCMIconsStatusAdded; break; 137 | case 'M': status = SCMIconsStatusModified; break; 138 | } 139 | if(status == SCMIconsStatusUnknown) 140 | { 141 | switch(*versioningStatusChar) 142 | { 143 | case '+': status = SCMIconsStatusVersioned; break; 144 | case 'C': status = SCMIconsStatusConflicted; break; 145 | } 146 | } 147 | [project setObject:[NSNumber numberWithInt:status] forKey:filename]; 148 | } 149 | } 150 | [projectStatuses setObject:project forKey:projectPath]; 151 | [project release]; 152 | } 153 | } 154 | @catch(NSException* exception) 155 | { 156 | NSLog(@"%s %@: launch path \"%@\"", _cmd, exception, exePath); 157 | } 158 | } 159 | 160 | - (void)executeLsFilesForProject:(NSString*)projectPath; 161 | { 162 | NSAutoreleasePool* pool = [NSAutoreleasePool new]; 163 | [self executeLsFilesUnderPath:nil inProject:projectPath]; 164 | [self performSelectorOnMainThread:@selector(redisplayStatuses) withObject:nil waitUntilDone:NO]; 165 | [pool release]; 166 | } 167 | 168 | // SCMIconDelegate 169 | - (SCMIconsStatus)statusForPath:(NSString*)path inProject:(NSString*)projectPath reload:(BOOL)reload; 170 | { 171 | if(reload || ![projectStatuses objectForKey:projectPath]) 172 | [self executeLsFilesUnderPath:path inProject:projectPath]; 173 | 174 | NSNumber* status = [[projectStatuses objectForKey:projectPath] objectForKey:path]; 175 | if(status) 176 | return (SCMIconsStatus)[status intValue]; 177 | else 178 | return SCMIconsStatusUnknown; 179 | } 180 | 181 | - (void)redisplayStatuses; 182 | { 183 | refreshingProject = YES; 184 | [[SCMIcons sharedInstance] redisplayProjectTrees]; 185 | refreshingProject = NO; 186 | } 187 | 188 | - (void)reloadStatusesForProject:(NSString*)projectPath; 189 | { 190 | #ifdef USE_THREADING 191 | [NSThread detachNewThreadSelector:@selector(executeLsFilesForProject:) toTarget:self withObject:projectPath]; 192 | #else 193 | [projectStatuses removeObjectForKey:projectPath]; 194 | [self executeLsFilesUnderPath:nil inProject:projectPath]; 195 | #endif 196 | } 197 | @end 198 | -------------------------------------------------------------------------------- /src/scm/GitIcons.mm: -------------------------------------------------------------------------------- 1 | #import "SCMIcons.h" 2 | 3 | #define USE_THREADING 4 | 5 | @interface GitIcons : NSObject 6 | { 7 | NSMutableDictionary* projectStatuses; 8 | } 9 | + (GitIcons*)sharedInstance; 10 | @end 11 | 12 | static GitIcons *SharedInstance; 13 | 14 | @implementation GitIcons 15 | // ================== 16 | // = Setup/Teardown = 17 | // ================== 18 | + (GitIcons*)sharedInstance 19 | { 20 | return SharedInstance ?: [[self new] autorelease]; 21 | } 22 | 23 | + (void)load 24 | { 25 | [[SCMIcons sharedInstance] registerSCMDelegate:[self sharedInstance]]; 26 | } 27 | 28 | - (NSString*)scmName; 29 | { 30 | return @"Git"; 31 | } 32 | 33 | - (id)init 34 | { 35 | if(SharedInstance) 36 | { 37 | [self release]; 38 | } 39 | else if(self = SharedInstance = [[super init] retain]) 40 | { 41 | projectStatuses = [NSMutableDictionary new]; 42 | } 43 | return SharedInstance; 44 | } 45 | 46 | - (void)dealloc 47 | { 48 | [projectStatuses release]; 49 | [super dealloc]; 50 | } 51 | 52 | - (NSString*)gitPath; 53 | { 54 | return [[SCMIcons sharedInstance] pathForVariable:@"TM_GIT" paths:[NSArray arrayWithObjects:@"/opt/local/bin/git",@"/usr/local/bin/git",@"/usr/bin/git",nil]]; 55 | } 56 | 57 | - (void)executeLsFilesUnderPath:(NSString*)path inProject:(NSString*)projectPath; 58 | { 59 | NSString* exePath = [self gitPath]; 60 | if(!exePath || ![[NSFileManager defaultManager] fileExistsAtPath:exePath]) 61 | return; 62 | 63 | @try 64 | { 65 | NSTask* task = [[NSTask new] autorelease]; 66 | [task setLaunchPath:exePath]; 67 | [task setCurrentDirectoryPath:projectPath]; 68 | if(path) 69 | [task setArguments:[NSArray arrayWithObjects:@"ls-files", @"--exclude-standard", @"-z", @"-t", @"-m", @"-c", @"-d", nil]]; 70 | else 71 | [task setArguments:[NSArray arrayWithObjects:@"ls-files", @"--exclude-standard", @"-z", @"-t", @"-m", @"-c", @"-d", path, nil]]; 72 | 73 | NSPipe *pipe = [NSPipe pipe]; 74 | [task setStandardOutput: pipe]; 75 | [task setStandardError:[NSPipe pipe]]; // Prevent errors from being printed to the Console 76 | 77 | NSFileHandle *file = [pipe fileHandleForReading]; 78 | 79 | [task launch]; 80 | 81 | NSData *data = [file readDataToEndOfFile]; 82 | 83 | [task waitUntilExit]; 84 | 85 | if([task terminationStatus] != 0) 86 | { 87 | // Prevent repeated calling 88 | [projectStatuses setObject:[NSDictionary dictionary] forKey:projectPath]; 89 | return; 90 | } 91 | 92 | NSString *string = [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease]; 93 | 94 | NSArray* lines = [string componentsSeparatedByString:@"\0"]; 95 | NSMutableDictionary* project = [[NSMutableDictionary alloc] initWithCapacity:([lines count]>0) ? ([lines count]-1) : 0]; 96 | if([lines count] > 1) 97 | { 98 | for(int index = 0; index < [lines count]; index++) 99 | { 100 | NSString* line = [lines objectAtIndex:index]; 101 | if([line length] > 3) 102 | { 103 | const char* statusChar = [[line substringToIndex:1] UTF8String]; 104 | NSString* filename = [projectPath stringByAppendingPathComponent:[line substringFromIndex:2]]; 105 | SCMIconsStatus status = SCMIconsStatusUnknown; 106 | switch(*statusChar) 107 | { 108 | case 'H': status = SCMIconsStatusVersioned; break; 109 | case 'C': status = SCMIconsStatusModified; break; 110 | } 111 | [project setObject:[NSNumber numberWithInt:status] forKey:filename]; 112 | } 113 | } 114 | } 115 | [projectStatuses setObject:project forKey:projectPath]; 116 | [project release]; 117 | } 118 | @catch(NSException* exception) 119 | { 120 | NSLog(@"%s %@: launch path \"%@\"", _cmd, exception, exePath); 121 | [projectStatuses setObject:[NSDictionary dictionary] forKey:projectPath]; 122 | } 123 | } 124 | 125 | - (void)executeLsFilesForProject:(NSString*)projectPath; 126 | { 127 | NSAutoreleasePool* pool = [NSAutoreleasePool new]; 128 | [self executeLsFilesUnderPath:nil inProject:projectPath]; 129 | [self performSelectorOnMainThread:@selector(redisplayStatuses) withObject:nil waitUntilDone:NO]; 130 | [pool release]; 131 | } 132 | 133 | // SCMIconDelegate 134 | - (SCMIconsStatus)statusForPath:(NSString*)path inProject:(NSString*)projectPath reload:(BOOL)reload; 135 | { 136 | if(reload || ![projectStatuses objectForKey:projectPath]) 137 | [self executeLsFilesUnderPath:path inProject:projectPath]; 138 | 139 | NSNumber* status = [[projectStatuses objectForKey:projectPath] objectForKey:path]; 140 | if(status) 141 | return (SCMIconsStatus)[status intValue]; 142 | else 143 | return SCMIconsStatusUnknown; 144 | } 145 | 146 | - (void)redisplayStatuses; 147 | { 148 | [[SCMIcons sharedInstance] redisplayProjectTrees]; 149 | } 150 | 151 | - (void)reloadStatusesForProject:(NSString*)projectPath; 152 | { 153 | #ifdef USE_THREADING 154 | [NSThread detachNewThreadSelector:@selector(executeLsFilesForProject:) toTarget:self withObject:projectPath]; 155 | #else 156 | [projectStatuses removeObjectForKey:projectPath]; 157 | [self executeLsFilesUnderPath:nil inProject:projectPath]; 158 | #endif 159 | } 160 | @end 161 | -------------------------------------------------------------------------------- /src/scm/HgIcons.mm: -------------------------------------------------------------------------------- 1 | #import "SCMIcons.h" 2 | 3 | #define USE_THREADING 4 | 5 | @interface HgIcons : NSObject 6 | { 7 | NSMutableDictionary* projectStatuses; 8 | BOOL refreshingProject; 9 | } 10 | + (HgIcons*)sharedInstance; 11 | @end 12 | 13 | static HgIcons *SharedInstance; 14 | 15 | @implementation HgIcons 16 | // ================== 17 | // = Setup/Teardown = 18 | // ================== 19 | + (HgIcons*)sharedInstance 20 | { 21 | return SharedInstance ?: [[self new] autorelease]; 22 | } 23 | 24 | + (void)load 25 | { 26 | [[SCMIcons sharedInstance] registerSCMDelegate:[self sharedInstance]]; 27 | } 28 | 29 | - (NSString*)scmName; 30 | { 31 | return @"Mercurial"; 32 | } 33 | 34 | - (id)init 35 | { 36 | if(SharedInstance) 37 | { 38 | [self release]; 39 | } 40 | else if(self = SharedInstance = [[super init] retain]) 41 | { 42 | projectStatuses = [NSMutableDictionary new]; 43 | } 44 | return SharedInstance; 45 | } 46 | 47 | - (void)dealloc 48 | { 49 | [projectStatuses release]; 50 | [super dealloc]; 51 | } 52 | 53 | - (NSString*)hgPath; 54 | { 55 | return [[SCMIcons sharedInstance] pathForVariable:@"TM_HG" paths:[NSArray arrayWithObjects:@"/opt/local/bin/hg",@"/usr/local/bin/hg",@"/usr/bin/hg",nil]]; 56 | } 57 | 58 | - (void)executeLsFilesUnderPath:(NSString*)path inProject:(NSString*)projectPath; 59 | { 60 | NSString* exePath = [self hgPath]; 61 | if(!exePath || ![[NSFileManager defaultManager] fileExistsAtPath:exePath]) 62 | return; 63 | 64 | @try 65 | { 66 | NSTask* task = [[NSTask new] autorelease]; 67 | [task setLaunchPath:exePath]; 68 | [task setCurrentDirectoryPath:projectPath]; 69 | if(path) 70 | [task setArguments:[NSArray arrayWithObjects:@"status", @"-A", @"-0", nil]]; 71 | else 72 | [task setArguments:[NSArray arrayWithObjects:@"status", @"-A", @"-0", path, nil]]; 73 | 74 | NSPipe *pipe = [NSPipe pipe]; 75 | [task setStandardOutput: pipe]; 76 | [task setStandardError:[NSPipe pipe]]; 77 | 78 | NSFileHandle *file = [pipe fileHandleForReading]; 79 | 80 | [task launch]; 81 | 82 | NSData *data = [file readDataToEndOfFile]; 83 | 84 | [task waitUntilExit]; 85 | 86 | if([task terminationStatus] != 0) 87 | { 88 | // Prevent repeated calling 89 | [projectStatuses setObject:[NSDictionary dictionary] forKey:projectPath]; 90 | return; 91 | } 92 | 93 | NSString *string = [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease]; 94 | NSArray* lines = [string componentsSeparatedByString:@"\0"]; 95 | NSMutableDictionary* project = [[NSMutableDictionary alloc] initWithCapacity:([lines count]>0) ? ([lines count]-1) : 0]; 96 | if([lines count] > 1) 97 | { 98 | for(int index = 0; index < [lines count]; index++) 99 | { 100 | NSString* line = [lines objectAtIndex:index]; 101 | if([line length] > 3) 102 | { 103 | const char* statusChar = [[line substringToIndex:1] UTF8String]; 104 | NSString* filename = [projectPath stringByAppendingPathComponent:[line substringFromIndex:2]]; 105 | SCMIconsStatus status = SCMIconsStatusUnknown; 106 | switch(*statusChar) 107 | { 108 | case 'C': status = SCMIconsStatusVersioned; break; 109 | case 'M': status = SCMIconsStatusModified; break; 110 | case 'A': status = SCMIconsStatusAdded; break; 111 | case 'R': status = SCMIconsStatusDeleted; break; 112 | } 113 | [project setObject:[NSNumber numberWithInt:status] forKey:filename]; 114 | } 115 | } 116 | } 117 | [projectStatuses setObject:project forKey:projectPath]; 118 | [project release]; 119 | } 120 | @catch(NSException* exception) 121 | { 122 | NSLog(@"%s %@: launch path \"%@\"", _cmd, exception, exePath); 123 | [projectStatuses setObject:[NSDictionary dictionary] forKey:projectPath]; 124 | } 125 | } 126 | 127 | - (void)executeLsFilesForProject:(NSString*)projectPath; 128 | { 129 | NSAutoreleasePool* pool = [NSAutoreleasePool new]; 130 | [self executeLsFilesUnderPath:nil inProject:projectPath]; 131 | [self performSelectorOnMainThread:@selector(redisplayStatuses) withObject:nil waitUntilDone:NO]; 132 | [pool release]; 133 | } 134 | 135 | // SCMIconDelegate 136 | - (SCMIconsStatus)statusForPath:(NSString*)path inProject:(NSString*)projectPath reload:(BOOL)reload; 137 | { 138 | if(reload || ![projectStatuses objectForKey:projectPath]) 139 | [self executeLsFilesUnderPath:path inProject:projectPath]; 140 | 141 | NSNumber* status = [[projectStatuses objectForKey:projectPath] objectForKey:path]; 142 | if(status) 143 | return (SCMIconsStatus)[status intValue]; 144 | else 145 | return SCMIconsStatusUnknown; 146 | } 147 | 148 | - (void)redisplayStatuses; 149 | { 150 | refreshingProject = YES; 151 | [[SCMIcons sharedInstance] redisplayProjectTrees]; 152 | refreshingProject = NO; 153 | } 154 | 155 | - (void)reloadStatusesForProject:(NSString*)projectPath; 156 | { 157 | #ifdef USE_THREADING 158 | [NSThread detachNewThreadSelector:@selector(executeLsFilesForProject:) toTarget:self withObject:projectPath]; 159 | #else 160 | [projectStatuses removeObjectForKey:projectPath]; 161 | [self executeLsFilesUnderPath:nil inProject:projectPath]; 162 | #endif 163 | } 164 | @end 165 | -------------------------------------------------------------------------------- /src/scm/SCMIcons.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "TextMate.h" 3 | 4 | enum SCMIconsStatus { 5 | SCMIconsStatusVersioned = 1, 6 | SCMIconsStatusModified, 7 | SCMIconsStatusAdded, 8 | SCMIconsStatusDeleted, 9 | SCMIconsStatusConflicted, 10 | SCMIconsStatusUnversioned, 11 | SCMIconsStatusUnknown, 12 | }; 13 | 14 | @protocol SCMIconDelegate 15 | - (SCMIconsStatus)statusForPath:(NSString*)path inProject:(NSString*)projectPath reload:(BOOL)reload; 16 | - (NSString*)scmName; 17 | @end 18 | // Optional methods: 19 | // - (void)reloadStatusesForProject:(NSString*)projectPath; 20 | 21 | @interface SCMIcons : NSWindowController 22 | { 23 | NSMutableArray* delegates; 24 | NSMutableArray* iconPacks; 25 | IBOutlet NSArrayController* iconPacksController; 26 | } 27 | + (SCMIcons*)sharedInstance; 28 | 29 | - (void)redisplayProjectTrees; 30 | 31 | - (void)registerSCMDelegate:(id )delegate; 32 | 33 | - (void)loadIconPacks; 34 | - (NSDictionary*)iconPack; 35 | - (NSImage*)overlayIcon:(NSString*)name; 36 | 37 | - (void)setSelectedIconPackIndex:(int)index; 38 | 39 | - (NSString*)pathForVariable:(NSString*)shellVariableName paths:(NSArray*)paths; 40 | @end 41 | -------------------------------------------------------------------------------- /src/scm/SCMIcons.mm: -------------------------------------------------------------------------------- 1 | #import "SCMIcons.h" 2 | #import "ProjectPlus.h" 3 | #import "TextMate.h" 4 | 5 | #define LIST_OFFSET 4 6 | #define ICON_SIZE 15 7 | #define BADGE_SIZE 10 8 | 9 | const NSString* overlayImageNames[] = {@"Modified", @"Added", @"Deleted", @"Versioned", @"Conflicted", @"Unversioned"}; 10 | 11 | @interface SCMIcons (Private) 12 | - (void)reloadStatusesForAllProjects; 13 | - (void)reloadStatusesForProject:(NSString*)projectPath; 14 | - (NSImage*)imageForStatusCode:(SCMIconsStatus)status; 15 | - (SCMIconsStatus)statusForPath:(NSString*)path inProject:(NSString*)projectPath reload:(BOOL)reload; 16 | @end 17 | 18 | @interface NSWindowController (SCMAppSwitching) 19 | - (void)scmRefreshApplicationDidBecomeActiveNotification:(id)sender; 20 | @end 21 | 22 | @implementation NSWindowController (SCMAppSwitching) 23 | - (void)scmRefreshApplicationDidBecomeActiveNotification:(id)sender 24 | { 25 | [[SCMIcons sharedInstance] reloadStatusesForAllProjects]; 26 | [self scmRefreshApplicationDidBecomeActiveNotification:sender]; 27 | } 28 | @end 29 | 30 | @implementation NSOutlineView (SCMOutlineView) 31 | - (void)drawOverlayForRow:(int)rowNumber inProject:(NSString*)projectPath; 32 | { 33 | NSDictionary* item = [self itemAtRow:rowNumber]; 34 | 35 | if (item) { 36 | NSString* path = [item objectForKey:@"filename"]; 37 | if (!path) path = [item objectForKey:@"sourceDirectory"]; 38 | SCMIconsStatus status = [[SCMIcons sharedInstance] statusForPath:path inProject:projectPath reload:NO]; 39 | 40 | NSImage* overlay = [[SCMIcons sharedInstance] imageForStatusCode:status]; 41 | if (overlay) 42 | { 43 | // NSAffineTransform* transform = [NSAffineTransform transform]; 44 | // [transform rotateByDegrees:180]; 45 | // [transform concat]; 46 | [overlay setFlipped:YES]; 47 | [overlay drawInRect:NSMakeRect(LIST_OFFSET + ([self levelForRow:rowNumber] + 1) * [self indentationPerLevel], 48 | rowNumber * ([self rowHeight] + [self intercellSpacing].height), 49 | ICON_SIZE, ICON_SIZE) 50 | fromRect:NSZeroRect 51 | operation:NSCompositeSourceOver 52 | fraction:1]; 53 | [overlay setFlipped:NO]; 54 | } 55 | } 56 | } 57 | 58 | - (void)scmDrawRect:(NSRect)rect 59 | { 60 | [self scmDrawRect:rect]; 61 | 62 | NSString* projectPath = [[self delegate] performSelector:@selector(findProjectDirectory)]; 63 | NSRange rows = [self rowsInRect:rect]; 64 | int rowNumber = rows.location; 65 | while (rowNumber <= rows.location + rows.length) 66 | [self drawOverlayForRow:rowNumber++ inProject:projectPath]; 67 | } 68 | @end 69 | 70 | @interface NSWindowPoser : NSWindow 71 | @end 72 | 73 | @implementation NSWindowPoser 74 | // called when the user switches tabs (or load files) 75 | - (void)setRepresentedFilename:(NSString*)path 76 | { 77 | [super setRepresentedFilename:path]; 78 | 79 | if([[self delegate] isKindOfClass:OakProjectController]) 80 | { 81 | NSString* projectPath = [[self delegate] valueForKey:@"projectDirectory"]; 82 | 83 | SCMIconsStatus status = [[SCMIcons sharedInstance] statusForPath:path inProject:projectPath reload:YES]; 84 | NSImage* overlay = [[SCMIcons sharedInstance] imageForStatusCode:status]; 85 | 86 | NSImage* icon = [[[self standardWindowButton:NSWindowDocumentIconButton] image] copy]; 87 | [icon lockFocus]; 88 | 89 | [overlay drawInRect:NSMakeRect(0, 0, [icon size].width, [icon size].height) 90 | fromRect:NSZeroRect 91 | operation:NSCompositeSourceOver 92 | fraction:1]; 93 | 94 | [icon unlockFocus]; 95 | 96 | [[self standardWindowButton:NSWindowDocumentIconButton] setImage:icon]; 97 | [icon release]; 98 | } 99 | } 100 | @end 101 | 102 | static SCMIcons* SharedInstance; 103 | 104 | @implementation SCMIcons 105 | // ================== 106 | // = Setup/Teardown = 107 | // ================== 108 | + (SCMIcons*)sharedInstance 109 | { 110 | return SharedInstance ?: [[self new] autorelease]; 111 | } 112 | 113 | - (id)init 114 | { 115 | if(SharedInstance) 116 | { 117 | [self release]; 118 | } 119 | else if(self = SharedInstance = [[super init] retain]) 120 | { 121 | NSApp = [NSApplication sharedApplication]; 122 | 123 | delegates = [[NSMutableArray alloc] initWithCapacity:1]; 124 | 125 | [NSWindowPoser poseAsClass:[NSWindow class]]; 126 | 127 | [self loadIconPacks]; 128 | 129 | [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:@"SCMMateSelectedIconPack"]]; 130 | 131 | [NSClassFromString(@"OakOutlineView") jr_swizzleMethod:@selector(drawRect:) withMethod:@selector(scmDrawRect:) error:NULL]; 132 | [NSClassFromString(@"OakProjectController") jr_swizzleMethod:@selector(applicationDidBecomeActiveNotification:) withMethod:@selector(scmRefreshApplicationDidBecomeActiveNotification:) error:NULL]; 133 | 134 | // [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:NSApplicationDidBecomeActiveNotification object:nil]; 135 | } 136 | return SharedInstance; 137 | } 138 | 139 | // - (void)applicationDidBecomeActive:(id)sender 140 | // { 141 | // NSLog(@"[%@ applicationDidBecomeActiveNotification:%@]", [self class], sender); 142 | // [[SCMIcons sharedInstance] reloadStatusesForAllProjects]; 143 | // 144 | // NSArray* windows = [NSApp windows]; 145 | // 146 | // for(int index = 0; index < [windows count]; index++) 147 | // { 148 | // NSWindow* window = [windows objectAtIndex:index]; 149 | // if([window delegate] && [[window delegate] isKindOfClass:OakProjectController]) 150 | // [[[window delegate] valueForKey:@"outlineView"] setNeedsDisplay:YES]; 151 | // } 152 | // } 153 | 154 | - (BOOL)scmIsEnabled:(NSString*)scmName; 155 | { 156 | return [[NSUserDefaults standardUserDefaults] boolForKey:[NSString stringWithFormat:@"ProjectPlus %@ Enabled", scmName]]; 157 | } 158 | 159 | - (void)setScm:(NSString*)scmName isEnabled:(BOOL)enabled; 160 | { 161 | [[NSUserDefaults standardUserDefaults] setBool:enabled forKey:[NSString stringWithFormat:@"ProjectPlus %@ Enabled", scmName]]; 162 | } 163 | 164 | - (void)redisplayProjectTrees; 165 | { 166 | [[NSNotificationCenter defaultCenter] postNotificationName:ProjectPlus_redrawRequired object:nil]; 167 | } 168 | 169 | - (void)registerSCMDelegate:(id )delegate; 170 | { 171 | [delegates addObject:delegate]; 172 | [self redisplayProjectTrees]; 173 | } 174 | 175 | - (void)awakeFromNib 176 | { 177 | [self setSelectedIconPackIndex:[[NSUserDefaults standardUserDefaults] integerForKey:@"SCMMateSelectedIconPack"]]; 178 | [iconPacksController addObserver:self forKeyPath:@"selectionIndex" options:NULL context:NULL]; 179 | } 180 | 181 | - (void)dealloc 182 | { 183 | [delegates release]; 184 | [iconPacks release]; 185 | [super dealloc]; 186 | } 187 | 188 | // ========= 189 | // = Icons = 190 | // ========= 191 | - (NSDictionary*)iconPackNamed:(NSString*)iconPackName; 192 | { 193 | size_t imageCount = sizeof(overlayImageNames) / sizeof(NSString*); 194 | NSMutableDictionary* iconPack = [NSMutableDictionary dictionaryWithCapacity:imageCount]; 195 | NSString* path = [@"icons" stringByAppendingPathComponent:iconPackName]; 196 | 197 | for(size_t index = 0; index < imageCount; index += 1) 198 | { 199 | NSString* imageName = overlayImageNames[index]; 200 | size_t imageTypeCount = [[NSImage imageFileTypes] count]; 201 | 202 | for(size_t index = 0; index < imageTypeCount; index += 1) 203 | { 204 | NSString* imageType = [[NSImage imageFileTypes] objectAtIndex:index]; 205 | 206 | if(NSString* imagePath = [[NSBundle bundleForClass:[SCMIcons class]] pathForResource:imageName ofType:imageType inDirectory:path]) 207 | { 208 | if(NSImage* image = [[NSImage alloc] initByReferencingFile:imagePath]) 209 | { 210 | // [image setFlipped:YES]; 211 | [iconPack setObject:image forKey:imageName]; 212 | [image release]; 213 | break; 214 | } 215 | } 216 | } 217 | } 218 | return iconPack; 219 | } 220 | 221 | - (void)loadIconPacks; 222 | { 223 | [iconPacks release]; 224 | iconPacks = [[NSMutableArray alloc] initWithCapacity:5]; 225 | 226 | // NSArray* iconPackNames = [NSArray arrayWithObjects:@"Straight",@"Classic",nil]; 227 | NSString* iconsPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"icons" ofType:nil]; 228 | NSDirectoryEnumerator* dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:iconsPath]; 229 | NSString* iconPackName; 230 | 231 | while(iconPackName = [dirEnum nextObject]) 232 | { 233 | [dirEnum skipDescendents]; 234 | if([[dirEnum fileAttributes] objectForKey:NSFileType] == NSFileTypeDirectory) 235 | { 236 | NSDictionary* icons = [self iconPackNamed:iconPackName]; 237 | if(icons && [icons count]) 238 | { 239 | NSDictionary* iconPack = [NSDictionary dictionaryWithObjectsAndKeys:[self iconPackNamed:iconPackName],@"icons",iconPackName,@"name",nil]; 240 | [iconPacks addObject:iconPack]; 241 | } 242 | } 243 | } 244 | } 245 | 246 | - (NSDictionary*)iconPack; 247 | { 248 | NSDictionary* iconPack = nil; 249 | int selectedIndex = [[NSUserDefaults standardUserDefaults] integerForKey:@"SCMMateSelectedIconPack"]; 250 | 251 | if(selectedIndex < [[iconPacksController arrangedObjects] count]) 252 | iconPack = [[[iconPacksController arrangedObjects] objectAtIndex:selectedIndex] objectForKey:@"icons"]; 253 | 254 | return iconPack; 255 | } 256 | 257 | - (NSImage*)overlayIcon:(NSString*)name 258 | { 259 | return [[self iconPack] objectForKey:name]; 260 | } 261 | 262 | - (NSImage*)imageForStatusCode:(SCMIconsStatus)status 263 | { 264 | switch(status) 265 | { 266 | case 0: 267 | case SCMIconsStatusVersioned: return [self overlayIcon:@"Versioned"]; 268 | case SCMIconsStatusModified: return [self overlayIcon:@"Modified"]; 269 | case SCMIconsStatusAdded: return [self overlayIcon:@"Added"]; 270 | case SCMIconsStatusDeleted: return [self overlayIcon:@"Deleted"]; 271 | case SCMIconsStatusConflicted: return [self overlayIcon:@"Conflicted"]; 272 | case SCMIconsStatusUnversioned: return [self overlayIcon:@"Unversioned"]; 273 | } 274 | 275 | return nil; 276 | } 277 | 278 | - (void)setSelectedIconPackIndex:(int)index 279 | { 280 | [iconPacksController setSelectionIndex:index]; 281 | [[NSUserDefaults standardUserDefaults] setInteger:index forKey:@"SCMMateSelectedIconPack"]; 282 | [self redisplayProjectTrees]; 283 | } 284 | 285 | - (void)observeValueForKeyPath:(NSString*)key ofObject:(id)object change:(NSDictionary*)changes context:(void*)context 286 | { 287 | [self setSelectedIconPackIndex:[iconPacksController selectionIndex]]; 288 | } 289 | 290 | // Delegate notifications/requests 291 | - (void)reloadStatusesForAllProjects; 292 | { 293 | NSArray* windows = [NSApp windows]; 294 | 295 | for(int index = 0; index < [windows count]; index++) 296 | { 297 | NSWindow* window = [windows objectAtIndex:index]; 298 | if([window delegate] && [[window delegate] isKindOfClass:OakProjectController]) 299 | { 300 | [self reloadStatusesForProject:[[window delegate] valueForKey:@"projectDirectory"]]; 301 | } 302 | } 303 | [self redisplayProjectTrees]; 304 | } 305 | 306 | - (void)reloadStatusesForProject:(NSString*)projectPath; 307 | { 308 | for(int delegateIndex = 0; delegateIndex < [delegates count]; delegateIndex++) 309 | { 310 | id delegate = [delegates objectAtIndex:delegateIndex]; 311 | if([self scmIsEnabled:[delegate scmName]] && [delegate respondsToSelector:@selector(reloadStatusesForProject:)]) 312 | [delegate reloadStatusesForProject:projectPath]; 313 | } 314 | } 315 | 316 | - (SCMIconsStatus)statusForPath:(NSString*)path inProject:(NSString*)projectPath reload:(BOOL)reload; 317 | { 318 | if([path length] == 0) 319 | return SCMIconsStatusUnknown; 320 | 321 | for(int index = 0; index < [delegates count]; index++) 322 | { 323 | id delegate = [delegates objectAtIndex:index]; 324 | if([self scmIsEnabled:[delegate scmName]]) 325 | { 326 | SCMIconsStatus status = [delegate statusForPath:path inProject:projectPath reload:reload]; 327 | if(status != SCMIconsStatusUnknown) 328 | return status; 329 | } 330 | } 331 | return SCMIconsStatusUnknown; 332 | } 333 | 334 | - (int)numberOfRowsInTableView:(NSTableView*)tableView 335 | { 336 | return [delegates count]; 337 | } 338 | 339 | - (void)tableView:(NSTableView*)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)tableColumn row:(int)rowIndex 340 | { 341 | NSString* name = [[delegates objectAtIndex:rowIndex] scmName]; 342 | [cell setTitle:name]; 343 | [cell setState:[self scmIsEnabled:name] ? NSOnState : NSOffState]; 344 | } 345 | 346 | - (id)tableView:(NSTableView*)tableView objectValueForTableColumn:(NSTableColumn*)tableColumn row:(int)rowIndex 347 | { 348 | return [[delegates objectAtIndex:rowIndex] scmName]; 349 | } 350 | 351 | - (void)tableView:(NSTableView*)tableView setObjectValue:(id)value forTableColumn:(NSTableColumn*)tableColumn row:(int)rowIndex 352 | { 353 | [self setScm:[[delegates objectAtIndex:rowIndex] scmName] isEnabled:[value boolValue]]; 354 | [self reloadStatusesForAllProjects]; 355 | [self redisplayProjectTrees]; 356 | } 357 | 358 | // =========== 359 | // = Utility = 360 | // =========== 361 | - (NSString*)pathForVariable:(NSString*)shellVariableName paths:(NSArray*)paths; 362 | { 363 | NSArray* prefs = [[OakPreferencesManager sharedInstance] performSelector:@selector(shellVariables)]; 364 | for(int index = 0; index < [prefs count]; index++) 365 | { 366 | NSDictionary* pref = [prefs objectAtIndex:index]; 367 | if([[pref objectForKey:@"variable"] isEqualToString:shellVariableName] && [[pref objectForKey:@"enabled"] boolValue]) 368 | return [pref objectForKey:@"value"]; 369 | } 370 | for(int index = 0; index < [paths count]; index++) 371 | { 372 | NSString* path = [paths objectAtIndex:index]; 373 | if([[NSFileManager defaultManager] fileExistsAtPath:path]) 374 | return path; 375 | } 376 | return nil; 377 | } 378 | @end 379 | -------------------------------------------------------------------------------- /src/scm/SVNIcons.mm: -------------------------------------------------------------------------------- 1 | #import "SCMIcons.h" 2 | #import "svn_client.h" 3 | #import "svn_cmdline.h" 4 | #import "svn_pools.h" 5 | 6 | struct svn_pool_t 7 | { 8 | svn_pool_t () { pool = svn_pool_create(NULL); } 9 | svn_pool_t (apr_pool_t* parent_pool) { pool = svn_pool_create(parent_pool); } 10 | ~svn_pool_t () { svn_pool_destroy(pool); pool = NULL; } 11 | operator bool () const { return pool != 0; } 12 | operator apr_pool_t* () const { return pool; } 13 | 14 | private: 15 | apr_pool_t* pool; 16 | }; 17 | 18 | @interface SVNIcons : NSObject 19 | + (SVNIcons*)sharedInstance; 20 | @end 21 | 22 | NSString* message_for_error (svn_error_t* error) 23 | { 24 | NSMutableString* message = [NSMutableString string]; 25 | 26 | for(svn_error_t* itr = error; itr; itr = itr->child) 27 | [message appendFormat:@"%s\n", error->message]; 28 | 29 | return message; 30 | } 31 | 32 | @interface SVNIcons (Private) 33 | - (svn_wc_status_kind)svnStatusForPath:(NSString*)path; 34 | 35 | #if 0 36 | - (BOOL)addPath:(NSString*)path; 37 | - (BOOL)renamePath:(NSString*)origPath toPath:(NSString*)newPath; 38 | - (BOOL)deletePaths:(NSArray*)paths; 39 | #endif 40 | @end 41 | 42 | apr_pool_t* pool; 43 | svn_client_ctx_t* ctx; 44 | NSMutableDictionary* statusForFiles; 45 | 46 | #if 0 47 | @implementation NSWindowController (SVNAppSwitching) 48 | - (void)showAddToRepositorySheet:(NSArray*)unversionedFilePaths; 49 | { 50 | NSAlert* addSheet = [NSAlert new]; 51 | [addSheet setMessageText:@"Add to repository?"]; 52 | [addSheet addButtonWithTitle:@"OK"]; 53 | [addSheet addButtonWithTitle:@"Cancel"]; 54 | [addSheet setInformativeText:[NSString stringWithFormat:@"Would you also like to add the new file%@ to your SVN repository?", [unversionedFilePaths count] == 1 ? @"" : @"s"]]; 55 | [addSheet beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:@selector(fileAddingAlertDidEnd:returnCode:contextInfo:) contextInfo:unversionedFilePaths]; 56 | [addSheet release]; 57 | } 58 | 59 | - (void)SVN_insertItemsBeforeSelection:(id)items; 60 | { 61 | [self SVN_insertItemsBeforeSelection:items]; 62 | 63 | NSMutableArray* unversionedFilePaths = [NSMutableArray new]; // released in the didEndSelector 64 | 65 | for(NSEnumerator* itemEnum = [items objectEnumerator]; NSDictionary* item = [itemEnum nextObject]; ) 66 | { 67 | NSString* filename = [item objectForKey:@"filename"]; 68 | if(!filename) 69 | filename = [item objectForKey:@"sourceDirectory"]; 70 | 71 | svn_wc_status_kind status = [[SVNIcons sharedInstance] statusForPath:filename]; 72 | if(status == svn_wc_status_unversioned) 73 | [unversionedFilePaths addObject:filename]; 74 | } 75 | 76 | if([unversionedFilePaths count] > 0) 77 | [self performSelector:@selector(showAddToRepositorySheet:) withObject:unversionedFilePaths afterDelay:0.0]; 78 | else 79 | [unversionedFilePaths release]; 80 | } 81 | 82 | - (void)fileAddingAlertDidEnd:(NSAlert*)alert returnCode:(int)returnCode contextInfo:(NSArray*)filepaths; 83 | { 84 | if(returnCode == NSAlertFirstButtonReturn) // "OK" 85 | { 86 | for(NSEnumerator* fileEnum = [filepaths objectEnumerator]; NSString* file = [fileEnum nextObject]; ) 87 | [[SVNIcons sharedInstance] addPath:file]; 88 | } 89 | 90 | [filepaths release]; 91 | } 92 | 93 | 94 | ============ 95 | = Renaming = 96 | ============ 97 | - (void)SVN_outlineView:(id)outlineView setObjectValue:(id)newName forTableColumn:(id)column byItem:(id)item; 98 | { 99 | NSString* filename = [item objectForKey:@"filename"]; 100 | if(!filename) 101 | filename = [item objectForKey:@"sourceDirectory"]; 102 | NSString* newFilename = [[filename stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"%@",newName]; 103 | BOOL didSVNRename = NO; 104 | svn_wc_status_kind status = [[SVNIcons sharedInstance] statusForPath:filename]; 105 | 106 | if(! [filename isEqualToString:newFilename] && status != svn_wc_status_unversioned && status != svn_wc_status_ignored && status != svn_wc_status_none) 107 | { 108 | int choice = NSRunAlertPanel(@"Rename in repository?", @"Would you also like to rename this file in your SVN repository?", @"OK", @"Cancel", nil); 109 | if(choice == NSAlertDefaultReturn) // "OK" 110 | { 111 | if([[SVNIcons sharedInstance] renamePath:filename toPath:newFilename]) 112 | didSVNRename = YES; 113 | else 114 | NSLog(@"SVNMate: Rename %@ → %@ failed – status: %d. Proceeding with filesystem rename.", filename, newFilename, status); 115 | } 116 | } 117 | 118 | if(!didSVNRename) 119 | [self SVN_outlineView:outlineView setObjectValue:newName forTableColumn:column byItem:item]; 120 | } 121 | 122 | ============ 123 | = Deleting = 124 | ============ 125 | - (void)SVN_removeProjectFilesWarningDidEnd:(NSAlert*)alert returnCode:(int)returnCode contextInfo:(void*)context; 126 | { 127 | [[alert window] orderOut:nil]; 128 | 129 | NSMutableArray* versionedFilePaths = [NSMutableArray new]; // released in the didEndSelector 130 | NSIndexSet* selectedRowIndexes = [[self valueForKey:@"outlineView"] selectedRowIndexes]; 131 | 132 | unsigned int bufSize = [selectedRowIndexes count]; 133 | unsigned int* buf = new unsigned int[bufSize]; 134 | NSRange range = NSMakeRange([selectedRowIndexes firstIndex], [selectedRowIndexes lastIndex]); 135 | [selectedRowIndexes getIndexes:buf maxCount:bufSize inIndexRange:&range]; 136 | for(unsigned int i = 0; i != bufSize; i++) 137 | { 138 | unsigned int index = buf[i]; 139 | id item = [[self valueForKey:@"outlineView"] itemAtRow:index]; 140 | NSString* filename = [item objectForKey:@"filename"]; 141 | if(!filename) 142 | filename = [item objectForKey:@"sourceDirectory"]; 143 | 144 | svn_wc_status_kind status = [[SVNIcons sharedInstance] statusForPath:filename]; 145 | if(status != svn_wc_status_unversioned && status != svn_wc_status_ignored && status != svn_wc_status_none) 146 | { 147 | [versionedFilePaths addObject:filename]; 148 | } 149 | } 150 | delete[] buf; 151 | 152 | if([versionedFilePaths count] > 0) 153 | { 154 | NSAlert* removeSheet = [[NSAlert alloc] init]; 155 | [removeSheet setMessageText:@"Remove from repository?"]; 156 | [removeSheet addButtonWithTitle:@"OK"]; 157 | [removeSheet addButtonWithTitle:@"Cancel"]; 158 | [removeSheet setInformativeText:[NSString stringWithFormat:@"Would you also like to remove the selected file%@ from your SVN repository?", [versionedFilePaths count] == 1 ? @"" : @"s"]]; 159 | [removeSheet beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:@selector(fileRemovalAlertDidEnd:returnCode:contextInfo:) contextInfo:versionedFilePaths]; 160 | [removeSheet release]; 161 | } 162 | else 163 | { 164 | [versionedFilePaths release]; 165 | [self SVN_removeProjectFilesWarningDidEnd:alert returnCode:returnCode contextInfo:context]; 166 | } 167 | } 168 | 169 | - (void)fileRemovalAlertDidEnd:(NSAlert*)alert returnCode:(int)returnCode contextInfo:(NSArray*)contextInfo; 170 | { 171 | if(returnCode == NSAlertFirstButtonReturn) // "OK" 172 | { 173 | [[SVNIcons sharedInstance] deletePaths:contextInfo]; 174 | } 175 | else // Do standard delete 176 | [self SVN_removeProjectFilesWarningDidEnd:alert returnCode:returnCode contextInfo:contextInfo]; 177 | 178 | [contextInfo release]; 179 | } 180 | 181 | @end 182 | #endif 183 | 184 | static SVNIcons* SharedInstance; 185 | 186 | @implementation SVNIcons 187 | // ================== 188 | // = Setup/Teardown = 189 | // ================== 190 | + (SVNIcons*)sharedInstance 191 | { 192 | return SharedInstance ?: [[self new] autorelease]; 193 | } 194 | 195 | + (void)load 196 | { 197 | [[SCMIcons sharedInstance] registerSCMDelegate:[[self new] autorelease]]; 198 | } 199 | 200 | - (NSString*)scmName; 201 | { 202 | return @"Subversion"; 203 | } 204 | 205 | - (id)init 206 | { 207 | if(SharedInstance) 208 | { 209 | [self release]; 210 | } 211 | else if(self = SharedInstance = [[super init] retain]) 212 | { 213 | if(svn_cmdline_init("SVNIcons", stderr) != EXIT_SUCCESS) 214 | return NULL; 215 | 216 | pool = svn_pool_create(NULL); 217 | svn_error_t* err = svn_client_create_context(&ctx, pool); // This could fail, but rather than handling errors we will check for ctx above 218 | if(err) 219 | { 220 | svn_error_clear(err); 221 | ctx = NULL; 222 | } 223 | statusForFiles = [[NSMutableDictionary alloc] init]; 224 | } 225 | return SharedInstance; 226 | } 227 | 228 | - (void)dealloc 229 | { 230 | [statusForFiles release]; 231 | svn_pool_destroy(pool); 232 | pool = NULL; 233 | [super dealloc]; 234 | } 235 | 236 | // SCMIconDelegate 237 | - (SCMIconsStatus)statusForPath:(NSString*)path inProject:(NSString*)projectPath reload:(BOOL)reload; 238 | { 239 | svn_wc_status_kind status = [self svnStatusForPath:path]; 240 | 241 | switch(status) 242 | { 243 | case svn_wc_status_none: return SCMIconsStatusUnknown; 244 | case svn_wc_status_normal: return SCMIconsStatusVersioned; 245 | case svn_wc_status_modified: return SCMIconsStatusModified; 246 | case svn_wc_status_added: return SCMIconsStatusAdded; 247 | case svn_wc_status_deleted: return SCMIconsStatusDeleted; 248 | case svn_wc_status_conflicted: return SCMIconsStatusConflicted; 249 | default: return SCMIconsStatusUnversioned; 250 | } 251 | } 252 | 253 | // ============= 254 | // = SVN stuff = 255 | // ============= 256 | static void status_func(void* baton, const char* path, svn_wc_status2_t* status) 257 | { 258 | [statusForFiles setObject:[NSNumber numberWithInt:status->text_status] forKey:(NSString*)baton]; 259 | } 260 | 261 | - (svn_wc_status_kind)svnStatusForPath:(NSString*)path 262 | { 263 | svn_wc_status_kind status = svn_wc_status_none; 264 | 265 | if(path && pool) 266 | { 267 | svn_pool_t subpool(pool); 268 | if(subpool) 269 | { 270 | svn_opt_revision_t rev; 271 | rev.kind = svn_opt_revision_head; 272 | 273 | // (result_rev, path, revision, status_func, status_baton, recurse, get_all, update, no_ignore, ignore_externals, ctx, pool) 274 | svn_error_t* err = svn_client_status2(NULL, [path UTF8String], &rev, status_func, path, false, false, false, false, true, ctx, subpool); 275 | 276 | if(err) 277 | svn_error_clear(err); 278 | else if([statusForFiles objectForKey:path]) 279 | { 280 | status = (svn_wc_status_kind)[[statusForFiles objectForKey:path] intValue]; 281 | [statusForFiles removeObjectForKey:path]; 282 | } 283 | else 284 | status = svn_wc_status_normal; 285 | } 286 | } 287 | 288 | return status; 289 | } 290 | 291 | #if 0 292 | - (BOOL)renamePath:(NSString*)origPath toPath:(NSString*)newPath 293 | { 294 | if(!origPath || !newPath) return NO; 295 | 296 | if(!pool) 297 | return NO; 298 | 299 | apr_pool_t* subpool; 300 | 301 | subpool = svn_pool_create(pool); 302 | if(!subpool) 303 | return NO; 304 | 305 | svn_error_t* err = svn_client_move4(NULL, [origPath UTF8String], [newPath UTF8String], YES, ctx, subpool); 306 | 307 | svn_pool_destroy(subpool); 308 | 309 | if(err) 310 | { 311 | if(NSString* error = message_for_error(err)]) 312 | NSRunAlertPanel(@"Error", error, @"OK", nil, nil); 313 | svn_error_clear(err); 314 | return NO; 315 | } 316 | 317 | return YES; 318 | } 319 | 320 | - (BOOL)addPath:(NSString*)path; 321 | { 322 | if(!path) 323 | return NO; 324 | 325 | if(!pool) 326 | return NO; 327 | 328 | apr_pool_t* subpool; 329 | 330 | subpool = svn_pool_create(pool); 331 | if(!subpool) 332 | return NO; 333 | 334 | svn_error_t* err = svn_client_add([path UTF8String], FALSE, ctx, subpool); 335 | 336 | svn_pool_destroy(subpool); 337 | 338 | if(err) 339 | { 340 | if(NSString* error = message_for_error(err)) 341 | NSRunAlertPanel(@"Error", error, @"OK", nil, nil); 342 | svn_error_clear(err); 343 | return NO; 344 | } 345 | 346 | return YES; 347 | } 348 | 349 | - (BOOL)deletePaths:(NSArray*)paths; 350 | { 351 | if(!paths) 352 | return NO; 353 | 354 | if(!pool) 355 | return NO; 356 | 357 | apr_pool_t* subpool; 358 | 359 | subpool = svn_pool_create(pool); 360 | if(!subpool) 361 | return NO; 362 | 363 | apr_array_header_t* files = apr_array_make(subpool, 1, sizeof(const char*)); 364 | APR_ARRAY_PUSH(files, const char*) = [[paths objectAtIndex:0] UTF8String]; 365 | svn_error_t* err = svn_client_delete2(NULL, files, true, ctx, subpool); 366 | 367 | svn_pool_destroy(subpool); 368 | 369 | if(err) 370 | { 371 | if(NSString* error = message_for_error(err)) 372 | NSRunAlertPanel(@"Error", error, @"OK", nil, nil); 373 | svn_error_clear(err); 374 | return NO; 375 | } 376 | 377 | 378 | return YES; 379 | } 380 | #endif 381 | @end 382 | -------------------------------------------------------------------------------- /src/scm/SvkIcons.mm: -------------------------------------------------------------------------------- 1 | #import "SCMIcons.h" 2 | 3 | #define USE_THREADING 4 | 5 | @interface SvkIcons : NSObject 6 | { 7 | NSMutableDictionary* projectStatuses; 8 | BOOL refreshingProject; 9 | } 10 | + (SvkIcons*)sharedInstance; 11 | @end 12 | 13 | static SvkIcons *SharedInstance; 14 | 15 | @implementation SvkIcons 16 | // ================== 17 | // = Setup/Teardown = 18 | // ================== 19 | + (SvkIcons*)sharedInstance 20 | { 21 | return SharedInstance ?: [[self new] autorelease]; 22 | } 23 | 24 | + (void)load 25 | { 26 | [[SCMIcons sharedInstance] registerSCMDelegate:[self sharedInstance]]; 27 | } 28 | 29 | - (NSString*)scmName; 30 | { 31 | return @"Svk"; 32 | } 33 | 34 | - (id)init 35 | { 36 | if(SharedInstance) 37 | { 38 | [self release]; 39 | } 40 | else if(self = SharedInstance = [[super init] retain]) 41 | { 42 | projectStatuses = [NSMutableDictionary new]; 43 | } 44 | return SharedInstance; 45 | } 46 | 47 | - (void)dealloc 48 | { 49 | [projectStatuses release]; 50 | [super dealloc]; 51 | } 52 | 53 | - (NSString*)svkPath; 54 | { 55 | return [[SCMIcons sharedInstance] pathForVariable:@"TM_SVK" paths:[NSArray arrayWithObjects:@"/opt/local/bin/svk",@"/usr/local/bin/svk",@"/usr/bin/svk",nil]]; 56 | } 57 | 58 | - (void)executeLsFilesUnderPath:(NSString*)path inProject:(NSString*)projectPath; 59 | { 60 | NSString* exePath = [self svkPath]; 61 | if(!exePath || ![[NSFileManager defaultManager] fileExistsAtPath:exePath]) 62 | return; 63 | 64 | @try 65 | { 66 | NSTask* task = [[NSTask new] autorelease]; 67 | [task setLaunchPath:exePath]; 68 | [task setCurrentDirectoryPath:projectPath]; 69 | if(path) 70 | [task setArguments:[NSArray arrayWithObjects:@"status", @"-v", nil]]; 71 | else 72 | [task setArguments:[NSArray arrayWithObjects:@"status", @"-v", path, nil]]; 73 | 74 | NSPipe *pipe = [NSPipe pipe]; 75 | [task setStandardOutput: pipe]; 76 | [task setStandardError:[NSPipe pipe]]; 77 | 78 | NSFileHandle *file = [pipe fileHandleForReading]; 79 | 80 | [task launch]; 81 | 82 | NSData *data = [file readDataToEndOfFile]; 83 | 84 | [task waitUntilExit]; 85 | 86 | if([task terminationStatus] != 0) 87 | { 88 | // Prevent repeated calling 89 | [projectStatuses setObject:[NSDictionary dictionary] forKey:projectPath]; 90 | return; 91 | } 92 | 93 | NSString *string = [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease]; 94 | NSArray* lines = [string componentsSeparatedByString:@"\n"]; 95 | NSMutableDictionary* project = [[NSMutableDictionary alloc] initWithCapacity:([lines count]>0) ? ([lines count]-1) : 0]; 96 | if([lines count] > 1) 97 | { 98 | for(int index = 0; index < [lines count]; index++) 99 | { 100 | NSString* line = [lines objectAtIndex:index]; 101 | if([line length] > 3) 102 | { 103 | const char* statusChar = [[line substringToIndex:1] UTF8String]; 104 | NSString* filename = [projectPath stringByAppendingPathComponent:[line substringFromIndex:35]]; 105 | SCMIconsStatus status = SCMIconsStatusUnknown; 106 | switch(*statusChar) 107 | { 108 | case ' ': status = SCMIconsStatusVersioned; break; 109 | case 'M': status = SCMIconsStatusModified; break; 110 | case 'A': status = SCMIconsStatusAdded; break; 111 | case 'C': status = SCMIconsStatusConflicted; break; 112 | case 'D': status = SCMIconsStatusDeleted; break; 113 | } 114 | [project setObject:[NSNumber numberWithInt:status] forKey:filename]; 115 | } 116 | } 117 | } 118 | [projectStatuses setObject:project forKey:projectPath]; 119 | [project release]; 120 | } 121 | @catch(NSException* exception) 122 | { 123 | NSLog(@"%s %@: launch path \"%@\"", _cmd, exception, exePath); 124 | [projectStatuses setObject:[NSDictionary dictionary] forKey:projectPath]; 125 | } 126 | } 127 | 128 | - (void)executeLsFilesForProject:(NSString*)projectPath; 129 | { 130 | NSAutoreleasePool* pool = [NSAutoreleasePool new]; 131 | [self executeLsFilesUnderPath:nil inProject:projectPath]; 132 | [self performSelectorOnMainThread:@selector(redisplayStatuses) withObject:nil waitUntilDone:NO]; 133 | [pool release]; 134 | } 135 | 136 | // SCMIconDelegate 137 | - (SCMIconsStatus)statusForPath:(NSString*)path inProject:(NSString*)projectPath reload:(BOOL)reload; 138 | { 139 | if(reload || ![projectStatuses objectForKey:projectPath]) 140 | { 141 | [self executeLsFilesUnderPath:path inProject:projectPath]; 142 | } 143 | 144 | NSNumber* status = [[projectStatuses objectForKey:projectPath] objectForKey:path]; 145 | if(status) 146 | return (SCMIconsStatus)[status intValue]; 147 | else 148 | return SCMIconsStatusUnknown; 149 | } 150 | 151 | - (void)redisplayStatuses; 152 | { 153 | refreshingProject = YES; 154 | [[SCMIcons sharedInstance] redisplayProjectTrees]; 155 | refreshingProject = NO; 156 | } 157 | 158 | - (void)reloadStatusesForProject:(NSString*)projectPath; 159 | { 160 | #ifdef USE_THREADING 161 | [NSThread detachNewThreadSelector:@selector(executeLsFilesForProject:) toTarget:self withObject:projectPath]; 162 | #else 163 | [projectStatuses removeObjectForKey:projectPath]; 164 | [self executeLsFilesUnderPath:nil inProject:projectPath]; 165 | #endif 166 | } 167 | @end 168 | -------------------------------------------------------------------------------- /src/sidebar/CWTMSplitView.h: -------------------------------------------------------------------------------- 1 | #import "KFSplitView.h" 2 | 3 | @interface CWTMSplitView : KFSplitView 4 | { 5 | BOOL sidebarOnRight; 6 | } 7 | - (BOOL)sideBarOnRight; 8 | - (void)setSideBarOnRight:(BOOL)onRight; 9 | 10 | - (NSView*)drawerView; 11 | - (NSView*)documentView; 12 | 13 | - (float)minLeftWidth; 14 | - (float)minRightWidth; 15 | @end 16 | -------------------------------------------------------------------------------- /src/sidebar/CWTMSplitView.mm: -------------------------------------------------------------------------------- 1 | #import "CWTMSplitView.h" 2 | 3 | @implementation CWTMSplitView 4 | + (NSImage*)horizontalGradientImage; 5 | { 6 | static NSImage* _horizontalGradientImage=nil; 7 | if(_horizontalGradientImage==nil){ 8 | UInt8 bytes[]={ 9 | 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 10 | 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x08, 0x02, 0x00, 0x00, 0x00, 0xee, 0x03, 0xda, 11 | 0x87, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 12 | 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x23, 0x49, 0x44, 0x41, 0x54, 0x08, 0x99, 13 | 0x63, 0x5c, 0xba, 0x74, 0x69, 0x78, 0x78, 0xf8, 0xbf, 0x7f, 0xff, 0xfe, 0xfe, 0xfd, 0xfb, 0xe7, 14 | 0xcf, 0x9f, 0xdf, 0x48, 0xe0, 0xd8, 0xb1, 0x63, 0x4c, 0x0c, 0x78, 0x01, 0x00, 0x9d, 0xdc, 0x19, 15 | 0xf3, 0xdb, 0x7c, 0x7c, 0x73, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 16 | 0x82 }; 17 | 18 | NSData* data=[NSData dataWithBytes:bytes length:sizeof(bytes)]; 19 | _horizontalGradientImage=[[NSImage alloc]initWithData:data]; 20 | } 21 | return _horizontalGradientImage; 22 | } 23 | 24 | 25 | - (void)drawDividerInRect:(NSRect)rect 26 | { 27 | if([self isVertical]) 28 | { 29 | NSRect fromRect; 30 | NSImage* image = [CWTMSplitView horizontalGradientImage]; 31 | fromRect.size = [image size]; 32 | fromRect.origin.x = 1; 33 | fromRect.origin.y = 0; 34 | fromRect.size.width--; 35 | 36 | [image drawInRect:rect fromRect:fromRect operation:NSCompositeCopy fraction:1.0]; 37 | } 38 | [super drawDividerInRect:rect]; 39 | } 40 | 41 | - (float)dividerThickness 42 | { 43 | return 8; 44 | } 45 | 46 | - (BOOL)sideBarOnRight; 47 | { 48 | return sidebarOnRight; 49 | } 50 | 51 | - (void)setSideBarOnRight:(BOOL)onRight; 52 | { 53 | sidebarOnRight = onRight; 54 | } 55 | 56 | - (NSView*)drawerView 57 | { 58 | if([self sideBarOnRight]) 59 | return [[[[self window] contentView] subviews] objectAtIndex:1]; 60 | else 61 | return [[[[self window] contentView] subviews] objectAtIndex:0]; 62 | } 63 | 64 | - (NSView*)documentView 65 | { 66 | if([self sideBarOnRight]) 67 | return [[[[self window] contentView] subviews] objectAtIndex:0]; 68 | else 69 | return [[[[self window] contentView] subviews] objectAtIndex:1]; 70 | } 71 | 72 | 73 | #define MIN_DRAWER_VIEW_WIDTH 85 74 | #define MIN_DOCUMENT_VIEW_WIDTH 400 75 | 76 | - (float)minLeftWidth 77 | { 78 | return [self sideBarOnRight] ? MIN_DOCUMENT_VIEW_WIDTH : MIN_DRAWER_VIEW_WIDTH; 79 | } 80 | 81 | - (float)minRightWidth 82 | { 83 | return [self sideBarOnRight] ? MIN_DRAWER_VIEW_WIDTH : MIN_DOCUMENT_VIEW_WIDTH; 84 | } 85 | @end 86 | -------------------------------------------------------------------------------- /src/sidebar/KFSplitView.h: -------------------------------------------------------------------------------- 1 | // 2 | // KFSplitView.h 3 | // KFSplitView v. 1.3, 11/27/2004 4 | // 5 | // Copyright (c) 2003-2004 Ken Ferry. Some rights reserved. 6 | // http://homepage.mac.com/kenferry/software.html 7 | // 8 | // This work is licensed under a Creative Commons license: 9 | // http://creativecommons.org/licenses/by-nc/1.0/ 10 | // 11 | // Send me an email if you have any problems (after you've read what there is to read). 12 | // 13 | // You can reach me at kenferry at the domain mac.com. 14 | 15 | #import 16 | 17 | @interface KFSplitView:NSSplitView 18 | { 19 | // retained 20 | NSMutableSet *kfCollapsedSubviews; 21 | NSMutableArray *kfDividerRects; 22 | NSString *kfPositionAutosaveName; 23 | NSCursor *kfIsVerticalResizeCursor; 24 | NSCursor *kfNotIsVerticalResizeCursor; 25 | 26 | // not retained 27 | NSCursor *kfCurrentResizeCursor; 28 | NSUserDefaults *kfDefaults; 29 | NSNotificationCenter *kfNotificationCenter; 30 | BOOL kfIsVertical; 31 | id kfDelegate; 32 | } 33 | 34 | // sets the collapse-state of a subview, which is completely independent 35 | // of that subview's frame (as in NSSplitView). (Sometime) after calling this 36 | // you'll need to tell the splitview to resize its subviews. 37 | // Normally, that would be this call: 38 | // [kfSplitView resizeSubviewsWithOldSize:[kfSplitView bounds].size]; 39 | - (void)setSubview:(NSView *)subview isCollapsed:(BOOL)flag; 40 | 41 | // To find documentation for these methods refer to Apple's NSWindow 42 | // documentation for the corresponding methods (e.g. -setFrameAutosaveName:). 43 | // To use an autosave name, call -setPositionAutosaveName: from the -awakeFromNib 44 | // method of a controller. 45 | + (void)removePositionUsingName:(NSString *)name; 46 | - (void)savePositionUsingName:(NSString *)name; 47 | - (BOOL)setPositionUsingName:(NSString *)name; 48 | - (BOOL)setPositionAutosaveName:(NSString *)name; 49 | - (NSString *)positionAutosaveName; 50 | - (void)setPositionFromPlistObject:(id)string; 51 | - (id)plistObjectWithSavedPosition; 52 | 53 | @end 54 | 55 | @interface NSObject(KFSplitViewDelegate) 56 | 57 | // in notification argument 'object' will be sender, 'userInfo' will have key @"subview" 58 | - (void)splitViewDidCollapseSubview:(NSNotification *)notification; 59 | - (void)splitViewDidExpandSubview:(NSNotification *)notification; 60 | 61 | - (void)splitView:(id)sender didDoubleClickInDivider:(int)index; 62 | - (void)splitView:(id)sender didFinishDragInDivider:(int)index; 63 | 64 | @end 65 | 66 | // notifications: 'object' will be sender, 'userInfo' will have key @"subview". 67 | // The delegate is automatically registered to receive these notifications. 68 | extern NSString *KFSplitViewDidCollapseSubviewNotification; 69 | extern NSString *KFSplitViewDidExpandSubviewNotification; 70 | 71 | -------------------------------------------------------------------------------- /src/sidebar/SideBarSwitching.mm: -------------------------------------------------------------------------------- 1 | #import "TextMate.h" 2 | #import "CWTMSplitView.h" 3 | 4 | @interface SideBarSwitching : NSObject 5 | + (BOOL)useSidebar; 6 | + (BOOL)sidebarOnRight; 7 | @end 8 | 9 | @interface NSWindowController (OakProjectController_Methods) 10 | - (void)openProjectDrawer:(id)sender; 11 | @end 12 | 13 | @implementation NSWindowController (OakProjectController_SideBarSwitching) 14 | - (BOOL)sidebarIsClosed 15 | { 16 | CWTMSplitView* splitView = [[self window] contentView]; 17 | return [splitView isSubviewCollapsed:[splitView drawerView]]; 18 | } 19 | 20 | - (void)setSidebarIsClosed:(BOOL)closed 21 | { 22 | CWTMSplitView* splitView = [[self window] contentView]; 23 | [splitView setSubview:[splitView drawerView] isCollapsed:closed]; 24 | [splitView resizeSubviewsWithOldSize:[splitView bounds].size]; 25 | } 26 | 27 | - (void)SideBarSwitching_windowDidLoad 28 | { 29 | [self SideBarSwitching_windowDidLoad]; 30 | 31 | if(not [SideBarSwitching useSidebar]) 32 | return; 33 | 34 | NSWindow* window = [self window]; 35 | NSDrawer* drawer = [[window drawers] objectAtIndex:0]; 36 | NSView* drawerView = [[drawer contentView] retain]; 37 | NSView* documentView = [[window contentView] retain]; 38 | 39 | [drawer setContentView:nil]; 40 | [window setContentView:nil]; 41 | 42 | CWTMSplitView* splitView = [[CWTMSplitView alloc] initWithFrame:[documentView frame]]; 43 | { 44 | [splitView setVertical:YES]; 45 | [splitView setDelegate:self]; 46 | [splitView setSideBarOnRight:[SideBarSwitching sidebarOnRight]]; 47 | 48 | if(not [SideBarSwitching sidebarOnRight]) 49 | [splitView addSubview:drawerView]; 50 | [splitView addSubview:documentView]; 51 | if([SideBarSwitching sidebarOnRight]) 52 | [splitView addSubview:drawerView]; 53 | [window setContentView:splitView]; 54 | } 55 | [splitView release]; 56 | 57 | [documentView release]; 58 | [drawerView release]; 59 | 60 | // Restoring from project 61 | NSDictionary *project = [NSDictionary dictionaryWithContentsOfFile:[self valueForKey:@"filename"]]; 62 | if(project) 63 | { 64 | int sidebarWidth = [[project objectForKey:@"fileHierarchyDrawerWidth"] intValue]; 65 | int documentWidth = [splitView bounds].size.width - [splitView dividerThickness] - sidebarWidth; 66 | int height = [splitView bounds].size.height; 67 | [[splitView drawerView] setFrameSize:NSMakeSize(sidebarWidth, height)]; 68 | [[splitView documentView] setFrameSize:NSMakeSize(documentWidth, height)]; 69 | 70 | BOOL closed = NO; 71 | NSNumber* flag = [project objectForKey:@"showFileHierarchyPanel"]; 72 | if(flag) 73 | closed = ! [flag boolValue]; 74 | 75 | [self setSidebarIsClosed:closed]; 76 | } 77 | 78 | [drawer close]; 79 | } 80 | 81 | - (void)SideBarSwitching_openProjectDrawer:(id)sender 82 | { 83 | CWTMSplitView* splitView = [[self window] contentView]; 84 | if(not [splitView isKindOfClass:[CWTMSplitView class]]) 85 | { 86 | [self SideBarSwitching_openProjectDrawer:sender]; 87 | return; 88 | } 89 | 90 | [self setSidebarIsClosed:NO]; 91 | } 92 | 93 | - (void)SideBarSwitching_toggleGroupsAndFilesDrawer:(id)sender 94 | { 95 | CWTMSplitView* splitView = [[self window] contentView]; 96 | if(not [splitView isKindOfClass:[CWTMSplitView class]]) 97 | { 98 | [self SideBarSwitching_toggleGroupsAndFilesDrawer:sender]; 99 | return; 100 | } 101 | 102 | BOOL close = ! [splitView isSubviewCollapsed:[splitView drawerView]]; 103 | 104 | [self setSidebarIsClosed:close]; 105 | } 106 | 107 | - (BOOL)SideBarSwitching_validateMenuItem:(id )item; 108 | { 109 | BOOL valid = [self SideBarSwitching_validateMenuItem:item]; 110 | 111 | if(valid && [[[self window] contentView] isKindOfClass:[CWTMSplitView class]] && [item action] == @selector(toggleGroupsAndFilesDrawer:)) 112 | { 113 | if([self sidebarIsClosed]) 114 | [item setTitle:@"Show Project Panel"]; 115 | else 116 | [item setTitle:@"Hide Project Panel"]; 117 | } 118 | 119 | return valid; 120 | } 121 | 122 | - (float)splitView:(CWTMSplitView*)splitview constrainMinCoordinate:(float)proposedMin ofSubviewAt:(int)offset 123 | { 124 | return (proposedMin + [splitview minLeftWidth]); 125 | } 126 | 127 | - (float)splitView:(CWTMSplitView*)splitview constrainMaxCoordinate:(float)proposedMax ofSubviewAt:(int)offset 128 | { 129 | return (proposedMax - [splitview minRightWidth]); 130 | } 131 | 132 | 133 | - (void)splitView:(id)sender resizeSubviewsWithOldSize:(NSSize)oldSize 134 | { 135 | if(![sender isKindOfClass:[CWTMSplitView class]]) 136 | return; 137 | float newHeight = [sender frame].size.height; 138 | float newWidth = [sender frame].size.width - [[sender drawerView] frame].size.width - [sender dividerThickness]; 139 | 140 | NSRect newFrame = [[sender drawerView] frame]; 141 | newFrame.size.height = newHeight; 142 | [[sender drawerView] setFrame:newFrame]; 143 | 144 | newFrame = [[sender documentView] frame]; 145 | newFrame.size.width = newWidth; 146 | newFrame.size.height = newHeight; 147 | [[sender documentView] setFrame:newFrame]; 148 | 149 | [sender adjustSubviews]; 150 | } 151 | 152 | // ====================================== 153 | // = Saving to project file = 154 | // ====================================== 155 | - (BOOL)SideBarSwitching_writeToFile:(NSString*)fileName 156 | { 157 | BOOL result = [self SideBarSwitching_writeToFile:fileName]; 158 | if(result && [[[self window] contentView] isKindOfClass:[CWTMSplitView class]] && [SideBarSwitching useSidebar]) 159 | { 160 | NSMutableDictionary *project = [NSMutableDictionary dictionaryWithContentsOfFile:fileName]; 161 | CWTMSplitView* splitView = [[self window] contentView]; 162 | [project setObject:[NSNumber numberWithBool:! [self sidebarIsClosed]] forKey:@"showFileHierarchyPanel"]; 163 | [project setObject:[NSNumber numberWithInt:[[splitView drawerView] bounds].size.width] forKey:@"fileHierarchyDrawerWidth"]; 164 | result = [project writeToFile:fileName atomically:NO]; 165 | } 166 | return result; 167 | } 168 | @end 169 | 170 | @implementation SideBarSwitching 171 | + (void)load 172 | { 173 | [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys: 174 | [NSNumber numberWithBool:YES],@"ProjectPlus Sidebar Enabled", 175 | [NSNumber numberWithBool:NO], @"ProjectPlus Sidebar on Right", 176 | nil]]; 177 | 178 | [OakProjectController jr_swizzleMethod:@selector(windowDidLoad) withMethod:@selector(SideBarSwitching_windowDidLoad) error:NULL]; 179 | [OakProjectController jr_swizzleMethod:@selector(openProjectDrawer:) withMethod:@selector(SideBarSwitching_openProjectDrawer:) error:NULL]; 180 | [OakProjectController jr_swizzleMethod:@selector(toggleGroupsAndFilesDrawer:) withMethod:@selector(SideBarSwitching_toggleGroupsAndFilesDrawer:) error:NULL]; 181 | [OakProjectController jr_swizzleMethod:@selector(writeToFile:) withMethod:@selector(SideBarSwitching_writeToFile:) error:NULL]; 182 | [OakProjectController jr_swizzleMethod:@selector(validateMenuItem:) withMethod:@selector(SideBarSwitching_validateMenuItem:) error:NULL]; 183 | } 184 | 185 | + (BOOL)useSidebar 186 | { 187 | return [[NSUserDefaults standardUserDefaults] boolForKey:@"ProjectPlus Sidebar Enabled"]; 188 | } 189 | 190 | + (BOOL)sidebarOnRight 191 | { 192 | return [[NSUserDefaults standardUserDefaults] boolForKey:@"ProjectPlus Sidebar on Right"]; 193 | } 194 | @end 195 | --------------------------------------------------------------------------------