Browse Source

Merge with nickloose's modifications. (9345b2cc7b18ce8ffacd)

Manoel Trapier 8 years ago
parent
commit
5184104849

+ 2 - 2
Classes/IJInventoryItem.h

@@ -20,12 +20,12 @@
 @interface IJInventoryItem : NSObject <NSCoding> {
 	int16_t itemId;
 	int16_t damage;
-	int8_t count;
+	uint8_t count;
 	int8_t slot;
 }
 @property (nonatomic, assign) int16_t itemId;
 @property (nonatomic, assign) int16_t damage;
-@property (nonatomic, assign) int8_t count;
+@property (nonatomic, assign) uint8_t count;
 @property (nonatomic, assign) int8_t slot;
 
 @property (nonatomic, readonly) NSString *itemName;

+ 9 - 3
Classes/IJInventoryItem.m

@@ -69,12 +69,18 @@
 	
 	if (itemId <= 94)
 	{
-		if (itemId <= 17)
+		if (itemId <= 17){
 			index = itemId - 1; // first item is 1
-		else if (itemId <= 35 )
+		}
+		else if (itemId <= 34 ){
 			index = itemId + 1;
-		else if (itemId >= 37)
+		}
+		else if (itemId == 35 ){
+			index = itemId - 8;
+		}
+		else if (itemId >= 37){
 			index = itemId + 6;
+		}
 		atlasOffset = NSMakePoint(36, 75);
 	}
 	else if (itemId >= 256 && itemId <= 351)

+ 11 - 4
Classes/IJInventoryWindowController.h

@@ -19,7 +19,7 @@
    IJMinecraftLevel *player; /***< SMP Player.dat file use same format as level.dat */
 	NSArray *inventory;
 	
-	NSSegmentedControl *worldSelectionControl;
+	NSPopUpButton *worldSelectionControl;
 	NSTextField *statusTextField;
 	
 	IJInventoryView *inventoryView;
@@ -49,15 +49,13 @@
    NSString *loadedPlayer;
 }
 
-@property (nonatomic, assign) IBOutlet NSSegmentedControl *worldSelectionControl;
+@property (nonatomic, assign) IBOutlet NSPopUpButton *worldSelectionControl;
 @property (nonatomic, assign) IBOutlet NSTextField *statusTextField;
 @property (nonatomic, assign) IBOutlet IJInventoryView *inventoryView;
 @property (nonatomic, assign) IBOutlet IJInventoryView *quickView;
 @property (nonatomic, assign) IBOutlet IJInventoryView *armorView;
 @property (nonatomic, assign) IBOutlet NSSearchField *itemSearchField;
 @property (nonatomic, assign) IBOutlet NSTableView *itemTableView;
-@property (nonatomic, assign) IBOutlet NSTextField *playerNameTextField;
-
 
 @property (nonatomic, retain) NSNumber *worldTime;
 @property (nonatomic, retain) NSString *playerName;
@@ -69,4 +67,13 @@
 - (IBAction)makeSearchFieldFirstResponder:(id)sender;
 - (IBAction)itemTableViewDoubleClicked:(id)sender;
 
+- (IBAction)setNextDay:(id)sender;
+- (IBAction)setNextNight:(id)sender;
+- (IBAction)setNextNoon:(id)sender;
+- (IBAction)setNextMidnight:(id)sender;
+
+- (IBAction)emptyInventory:(id)sender;
+- (IBAction)saveInventoryItems:(id)sender;
+- (IBAction)loadInventoryItems:(id)sender;
+
 @end

+ 246 - 38
Classes/IJInventoryWindowController.m

@@ -12,12 +12,14 @@
 #import "IJInventoryView.h"
 #import "IJItemPropertiesViewController.h"
 #import "MAAttachedWindow.h"
+#import "NSFileManager+DirectoryLocations.h"
 
 @interface IJInventoryWindowController ()
 - (void)saveWorld;
 - (void)loadWorldAtIndex:(int)worldIndex;
-- (void)loadWorldAtFolder:(NSString *)worldFolder;
 - (BOOL)isDocumentEdited;
+- (void)loadWorldAtFolder:(NSString *)worldFolder;
+- (void)loadWorldSelectionControl;
 @end
 
 @implementation IJInventoryWindowController
@@ -30,6 +32,8 @@
 
 - (void)awakeFromNib
 {
+    [self loadWorldSelectionControl];
+    
 	armorInventory = [[NSMutableArray alloc] init];
 	quickInventory = [[NSMutableArray alloc] init];
 	normalInventory = [[NSMutableArray alloc] init];
@@ -47,7 +51,6 @@
 	keys = [keys sortedArrayUsingSelector:@selector(compare:)];
 	allItemIds = [[NSArray alloc] initWithArray:keys];
 	filteredItemIds = [allItemIds retain];
-	
 	[itemTableView setTarget:self];
 	[itemTableView setDoubleAction:@selector(itemTableViewDoubleClicked:)];
 }
@@ -72,7 +75,7 @@
 {
 	if (returnCode == NSAlertOtherReturn) // Cancel
 	{
-		[worldSelectionControl setSelectedSegment:loadedWorldIndex-1];
+		[worldSelectionControl selectItemWithTitle:[loadedWorldFolder lastPathComponent]];
 		return;
 	}
 	
@@ -124,11 +127,26 @@
 	[self didChangeValueForKey:@"worldTime"];
 	
 	statusTextField.stringValue = @"No world loaded.";
-		
-	NSString *levelPath = [IJMinecraftLevel pathForLevelDatAtFolder:worldPath];
-   
-	NSData *fileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:levelPath]];
+   NSString *levelPath = [IJMinecraftLevel pathForLevelDatAtFolder:worldPath];
+   NSData *fileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:levelPath]];
+
+	sessionLockValue = [IJMinecraftLevel writeToSessionLockAtFolder:worldPath];
+	if (![IJMinecraftLevel checkSessionLockAtFolder:worldPath value:sessionLockValue])
+	{
+		NSBeginCriticalAlertSheet(@"Error loading world.", @"Dismiss", nil, nil, self.window, nil, nil, nil, nil, @"Inside Job was unable obtain the session lock.");
+		return;
+	}
+    
+	if (!fileData)
+	{
+		// Error loading 
+		NSBeginCriticalAlertSheet(@"Error loading world.", @"Dismiss", nil, nil, self.window, nil, nil, nil, nil, @"InsideJob was unable to load the level at %@.", levelPath);
+		return;
+	}
 	
+	[self willChangeValueForKey:@"worldTime"];
+	
+	/* Now search for first player .dat file (but by default try to load from level.dat */
 	if (!fileData)
 	{
 		// Error loading 
@@ -141,7 +159,6 @@
    /* Now search for first player .dat file (but by default try to load from level.dat */
 #if 1
    loadedPlayer = nil;
-   
    NSString *playerPath = [IJMinecraftLevel pathForPlayer:loadedPlayer withWorld:worldPath];
 #else
    NSString *playerPath = [worldPath stringByAppendingString:@"/players/Godzil.dat"];
@@ -200,6 +217,10 @@
 	[self setDocumentEdited:NO];
 	statusTextField.stringValue = @"";
 	loadedWorldFolder = [worldPath retain];
+    
+    NSLog(@"%@",loadedWorldFolder);
+    NSLog(@"%@",worldPath);
+    
 }
 
 - (void)loadWorldAtIndex:(int)worldIndex
@@ -214,7 +235,7 @@
 - (void)saveWorld
 {
 	NSString *worldPath = loadedWorldFolder;
-   
+
 	if (inventory == nil)
 		return; // no world loaded, nothing to save
 	
@@ -337,40 +358,88 @@
 {
 	int worldIndex = [sender tag];
 	[self loadWorldAtIndex:worldIndex];
-	[worldSelectionControl setSelectedSegment:worldIndex - 1];
+	[worldSelectionControl selectItemWithTitle:[loadedWorldFolder lastPathComponent]];
 }
 
 - (IBAction)menuSelectWorldFromPath:(id)sender
 {
-   NSInteger openResult;
-   /* Ask user for world folder path */
-   NSOpenPanel *panel = [NSOpenPanel openPanel];   
-   NSString *worldPath;
-   
-   /* Only allow to choose a folder */
-   [panel setCanChooseDirectories:YES];
-   [panel setCanChooseFiles:NO];
-   openResult = [panel runModal];
-   
-   if (openResult == NSOKButton)
-   {
-      worldPath = [[panel directoryURL] path];
+    NSInteger openResult;
+    /* Ask user for world folder path */
+    NSOpenPanel *panel = [NSOpenPanel openPanel];   
+    NSString *worldPath;
     
-      /* Verify for level.dat */
-      if (![IJMinecraftLevel worldExistsAtFolder: worldPath])
-      {
-         NSBeginCriticalAlertSheet(@"No world exists in that slot.", @"Dismiss", nil, nil, self.window, nil, nil, nil, nil, @"Please create a new single player world in this slot using Minecraft and try again.");
-         return;
-      }
-      /* Now try to open the world... */
-      [self loadWorldAtFolder:[[panel directoryURL] path]];
-   }
+    /* Only allow to choose a folder */
+    [panel setCanChooseDirectories:YES];
+    [panel setCanChooseFiles:NO];
+    openResult = [panel runModal];
+    
+    if (openResult == NSOKButton)
+    {
+        worldPath = [[panel directoryURL] path];
+        
+        /* Verify for level.dat */
+        if (![IJMinecraftLevel worldExistsAtFolder: worldPath])
+        {
+            NSBeginCriticalAlertSheet(@"No world exists in that slot.", @"Dismiss", nil, nil, self.window, nil, nil, nil, nil, @"Please create a new single player world in this slot using Minecraft and try again.");
+            return;
+        }
+        /* Now try to open the world... */
+        [self loadWorldAtFolder:[[panel directoryURL] path]];
+        [worldSelectionControl addItemWithTitle:[loadedWorldFolder lastPathComponent]];
+        [worldSelectionControl selectItemWithTitle:[loadedWorldFolder lastPathComponent]];
+        
+    }
 }
 
 - (IBAction)worldSelectionChanged:(id)sender
 {
-	int worldIndex = [worldSelectionControl selectedSegment] + 1;
-	[self loadWorldAtIndex:worldIndex];
+	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
+	NSString *path = [paths objectAtIndex:0];
+	path = [path stringByAppendingPathComponent:@"minecraft"];
+	path = [path stringByAppendingPathComponent:@"saves"];
+    
+    
+    NSString* worldName = [worldSelectionControl titleOfSelectedItem];
+	NSString* worldPath = [path stringByAppendingPathComponent:worldName];
+    
+    NSLog(@"loadedWorldFolder: %@",loadedWorldFolder);
+    NSLog(@"worldName: %@",worldName);
+    NSLog(@"worldPath: %@",worldPath);
+
+    [self loadWorldAtFolder:worldPath];
+}
+
+- (void)loadWorldSelectionControl
+{
+    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
+	NSString *path = [paths objectAtIndex:0];
+	path = [path stringByAppendingPathComponent:@"minecraft"];
+	path = [path stringByAppendingPathComponent:@"saves"];
+    
+    
+    NSFileManager *filemgr;
+    NSArray *filelist;
+    NSError *fileError;
+    int count;
+    int i;
+    
+    filemgr = [NSFileManager defaultManager];
+    
+    filelist = [filemgr contentsOfDirectoryAtPath:path error:&fileError];
+    
+    count = [filelist count];
+    
+    
+    [worldSelectionControl removeAllItems];
+    for (i = 0; i < count; i++)
+    {
+        NSLog (@"%@", [filelist objectAtIndex: i]);
+        if([IJMinecraftLevel worldExistsAtFolder:[path stringByAppendingPathComponent:[filelist objectAtIndex: i]]])
+            [worldSelectionControl addItemWithTitle:[filelist objectAtIndex: i]];
+    }
+    
+    [filemgr release];
+    
 }
 
 - (void)saveDocument:(id)sender
@@ -401,10 +470,12 @@
 	return YES;
 }
 
+
 - (NSNumber *)worldTime
 {
 	return 	[level worldTimeContainer].numberValue;
 }
+
 - (void)setWorldTime:(NSNumber *)number
 {
 	[self willChangeValueForKey:@"worldTime"];
@@ -415,13 +486,143 @@
 
 - (NSString *)playerName
 {
-	return 	[level ].numberValue;
+	return @"Godzil";
 }
 - (void)setPlayerName:(NSString *)playerName
 {
+}
 
+- (void)calcTimePoints:(int)number
+{
+	int result;
+	int wTime = [[self worldTime] intValue];
+	result =wTime +(number - (wTime % number));
+	
+	NSNumber *newTime = [NSNumber numberWithInt:result];
+	[self setWorldTime:newTime];
 }
 
+- (IBAction)setNextDay:(id)sender
+{
+	int number = 24000;
+	[self calcTimePoints:number];
+}
+
+- (IBAction)setNextNight:(id)sender
+{
+	int number = 12000;
+	[self calcTimePoints:number];
+}
+
+- (IBAction)setNextMidnight:(id)sender
+{
+	int number = 18000;
+	[self calcTimePoints:number];
+}
+
+- (IBAction)setNextNoon:(id)sender
+{
+	int number = 6000;
+	[self calcTimePoints:number];
+}
+
+- (void)clearInventory{
+	
+	[armorInventory removeAllObjects];
+	[quickInventory removeAllObjects];
+	[normalInventory removeAllObjects];
+	
+	[inventoryView setItems:normalInventory];
+	[quickView setItems:quickInventory];
+	[armorView setItems:armorInventory];
+	
+	[self setDocumentEdited:YES];
+}
+
+- (void)saveInventory
+{
+	
+	NSString *path = [[NSFileManager defaultManager] applicationSupportDirectory];
+	NSLog(@"%@",path);
+	NSString *file = @"Inventory.plist";
+	
+	
+	NSString *InventoryPath = [path stringByAppendingPathComponent:file];
+	
+	NSLog(@"%@",InventoryPath);
+
+	
+	NSMutableArray *newInventory = [NSMutableArray array];
+	
+	for (NSArray *items in [NSArray arrayWithObjects:armorInventory, quickInventory, normalInventory, nil])
+	{
+		for (IJInventoryItem *item in items)
+		{
+			if (item.count > 0 && item.itemId > 0)
+				[newInventory addObject:item];
+		}
+	}
+	
+	[NSKeyedArchiver archiveRootObject: newInventory toFile:InventoryPath];
+}
+
+-(void)loadInventory
+{
+	NSString *path = [[NSFileManager defaultManager] applicationSupportDirectory];
+	NSString *file = @"Inventory.plist";
+	NSString *InventoryPath = [path stringByAppendingPathComponent:file];
+	
+	
+	[self clearInventory];
+	NSArray *newInventory = [NSKeyedUnarchiver unarchiveObjectWithFile:InventoryPath];
+	
+	for (int i = 0; i < IJInventorySlotQuickLast + 1 - IJInventorySlotQuickFirst; i++)
+		[quickInventory addObject:[IJInventoryItem emptyItemWithSlot:IJInventorySlotQuickFirst + i]];
+	
+	for (int i = 0; i < IJInventorySlotNormalLast + 1 - IJInventorySlotNormalFirst; i++)
+		[normalInventory addObject:[IJInventoryItem emptyItemWithSlot:IJInventorySlotNormalFirst + i]];
+	
+	for (int i = 0; i < IJInventorySlotArmorLast + 1 - IJInventorySlotArmorFirst; i++)
+		[armorInventory addObject:[IJInventoryItem emptyItemWithSlot:IJInventorySlotArmorFirst + i]];
+	
+	for (IJInventoryItem *item in newInventory)
+	{
+		if (IJInventorySlotQuickFirst <= item.slot && item.slot <= IJInventorySlotQuickLast)
+		{
+			[quickInventory replaceObjectAtIndex:item.slot - IJInventorySlotQuickFirst withObject:item];
+		}
+		else if (IJInventorySlotNormalFirst <= item.slot && item.slot <= IJInventorySlotNormalLast)
+		{
+			[normalInventory replaceObjectAtIndex:item.slot - IJInventorySlotNormalFirst withObject:item];
+		}
+		else if (IJInventorySlotArmorFirst <= item.slot && item.slot <= IJInventorySlotArmorLast)
+		{
+			[armorInventory replaceObjectAtIndex:item.slot - IJInventorySlotArmorFirst withObject:item];
+		}
+	}
+	
+	[inventoryView setItems:normalInventory];
+	[quickView setItems:quickInventory];
+	[armorView setItems:armorInventory];
+	
+}
+
+- (IBAction)emptyInventory:(id)sender
+{
+	[self clearInventory];
+}
+
+- (IBAction)saveInventoryItems:(id)sender
+{
+	[self saveInventory];
+}
+
+- (IBAction)loadInventoryItems:(id)sender
+{
+	[self loadInventory];
+}
+
+
 #pragma mark -
 #pragma mark IJInventoryViewDelegate
 
@@ -534,6 +735,14 @@
 																	   [propertiesWindow setAlphaValue:0.0];
 																   }];
 	propertiesViewController.item = item;
+	
+	if (propertiesViewController.item.damage == -1000){
+		[propertiesViewController setState:YES];
+	}else {
+		[propertiesViewController setState:NO];
+	}
+
+	
 	[propertiesWindow setPoint:point side:MAPositionRight];
 	[propertiesWindow makeKeyAndOrderFront:nil];
 	[propertiesWindow setAlphaValue:1.0];
@@ -649,12 +858,12 @@
 	NSMutableArray *inventoryArray = [self inventoryArrayWithEmptySlot:&slot];
 	if (!inventoryArray)
 		return;
-	
+
 	IJInventoryItem *item = [inventoryArray objectAtIndex:slot];
 	item.itemId = [[filteredItemIds objectAtIndex:[itemTableView selectedRow]] shortValue];
 	item.count = 1;
 	[self setDocumentEdited:YES];
-	
+
 	IJInventoryView *invView = [self inventoryViewForItemArray:inventoryArray];
 	[invView reloadItemAtIndex:slot];
 	[self inventoryView:invView selectedItemAtIndex:slot];
@@ -715,5 +924,4 @@
 	return YES;
 }
 
-
 @end

+ 3 - 1
Classes/IJItemPropertiesViewController.h

@@ -12,9 +12,11 @@
 
 @interface IJItemPropertiesViewController : NSViewController {
 	IJInventoryItem *item;
+	IBOutlet NSButton *checkIndestructible;
 }
 @property (nonatomic, retain) IJInventoryItem *item;
 
+- (void)setState:(bool)enabel;
 - (IBAction)closeButton:(id)sender;
-
+- (IBAction)makeIndestructible:(id)sender;
 @end

+ 13 - 0
Classes/IJItemPropertiesViewController.m

@@ -20,4 +20,17 @@
 	self.item = nil; // Hack to prevent this item as coming up as 'lastItem' if they click again.
 }
 
+- (IBAction)makeIndestructible:(id)sender
+{
+	if ([checkIndestructible state] == NSOnState) {
+		self.item.damage = -1000;
+		
+	}else {
+		self.item.damage = 0;
+	}
+}
+
+- (void)setState:(bool)enabel{
+	[checkIndestructible setState:enabel];
+}
 @end

+ 2 - 4
Classes/IJMinecraftLevel.h

@@ -11,20 +11,18 @@
 #import "NBTContainer.h"
 
 @interface IJMinecraftLevel : NBTContainer {
-
+    
 }
 
 @property (nonatomic, copy) NSArray *inventory; // Array of IJInventoryItem objects.
 @property (nonatomic, readonly) NBTContainer *worldTimeContainer;
 
 + (NSString *)pathForWorldAtIndex:(int)worldIndex;
-
++ (BOOL)worldExistsAtFolder:(NSString *)worldPath;
 + (NSString *)pathForLevelDatAtFolder:(NSString *)worldPath;
 + (NSString *)pathForSessionLockAtFolder:(NSString *)worldPath;
 + (NSString *)pathForPlayer:(NSString *)loadedPlayer withWorld:(NSString *)worldPath;
 
-+ (BOOL)worldExistsAtFolder:(NSString *)worldPath;
-
 + (int64_t)writeToSessionLockAtFolder:(NSString *)worldPath;
 + (BOOL)checkSessionLockAtFolder:(NSString *)worldPath value:(int64_t)checkValue;
 

+ 7 - 7
Classes/IJMinecraftLevel.m

@@ -53,7 +53,7 @@
 	for (NSArray *listItems in [self inventoryList].children)
 	{
 		IJInventoryItem *invItem = [[IJInventoryItem alloc] init];
-		
+        
 		invItem.itemId = [[self containerWithName:@"id" inArray:listItems].numberValue shortValue];
 		invItem.count = [[self containerWithName:@"Count" inArray:listItems].numberValue unsignedCharValue];
 		invItem.damage = [[self containerWithName:@"Damage" inArray:listItems].numberValue shortValue];
@@ -68,7 +68,7 @@
 {
 	NSMutableArray *newChildren = [NSMutableArray array];
 	NBTContainer *inventoryList = [self inventoryList];
-	
+    
 	if (inventoryList.listType != NBTTypeCompound)
 	{
 		// There appears to be a bug in the way Minecraft writes empty inventory lists; it appears to
@@ -76,7 +76,7 @@
 		NSLog(@"%s Fixing inventory list type; was %d.", __PRETTY_FUNCTION__, inventoryList.listType);
 		inventoryList.listType = NBTTypeCompound;
 	}
-	
+    
 	for (IJInventoryItem *invItem in newInventory)
 	{
 		NSArray *listItems = [NSArray arrayWithObjects:
@@ -158,10 +158,10 @@
 	NSTimeInterval interval = [now timeIntervalSince1970];
 	int64_t milliseconds = (int64_t)(interval * 1000.0);
 	// write as number of milliseconds
-	
+    
 	NSData *data = [IJMinecraftLevel dataWithInt64:milliseconds];
 	[data writeToFile:path atomically:YES];
-	
+    
 	return milliseconds;
 }
 
@@ -169,13 +169,13 @@
 {
 	NSString *path = [IJMinecraftLevel pathForSessionLockAtFolder:worldPath];
 	NSData *data = [NSData dataWithContentsOfFile:path];
-   
+
 	if (!data)
 	{
 		NSLog(@"Failed to read session lock at %@", path);
 		return NO;
 	}
-	
+    
 	int64_t milliseconds = [IJMinecraftLevel int64FromData:data];
 	return checkValue == milliseconds;
 }

+ 27 - 0
Classes/NSFileManager+DirectoryLocations.h

@@ -0,0 +1,27 @@
+//
+//  NSFileManager+DirectoryLocations.h
+//
+//  Created by Matt Gallagher on 06 May 2010
+//
+//  Permission is given to use this source code file, free of charge, in any
+//  project, commercial or otherwise, entirely at your risk, with the condition
+//  that any redistribution (in part or whole) of source code must retain
+//  this copyright and permission notice. Attribution in compiled projects is
+//  appreciated but not required.
+//
+
+#import <Foundation/Foundation.h>
+
+//
+// DirectoryLocations is a set of global methods for finding the fixed location
+// directoriess.
+//
+@interface NSFileManager (DirectoryLocations)
+
+- (NSString *)findOrCreateDirectory:(NSSearchPathDirectory)searchPathDirectory
+	inDomain:(NSSearchPathDomainMask)domainMask
+	appendPathComponent:(NSString *)appendComponent
+	error:(NSError **)errorOut;
+- (NSString *)applicationSupportDirectory;
+
+@end

+ 179 - 0
Classes/NSFileManager+DirectoryLocations.m

@@ -0,0 +1,179 @@
+//
+//  NSFileManager+DirectoryLocations.m
+//
+//  Created by Matt Gallagher on 06 May 2010
+//
+//  Permission is given to use this source code file, free of charge, in any
+//  project, commercial or otherwise, entirely at your risk, with the condition
+//  that any redistribution (in part or whole) of source code must retain
+//  this copyright and permission notice. Attribution in compiled projects is
+//  appreciated but not required.
+//
+
+#import "NSFileManager+DirectoryLocations.h"
+
+enum
+{
+	DirectoryLocationErrorNoPathFound,
+	DirectoryLocationErrorFileExistsAtLocation
+};
+	
+NSString * const DirectoryLocationDomain = @"DirectoryLocationDomain";
+
+@implementation NSFileManager (DirectoryLocations)
+
+//
+// findOrCreateDirectory:inDomain:appendPathComponent:error:
+//
+// Method to tie together the steps of:
+//	1) Locate a standard directory by search path and domain mask
+//  2) Select the first path in the results
+//	3) Append a subdirectory to that path
+//	4) Create the directory and intermediate directories if needed
+//	5) Handle errors by emitting a proper NSError object
+//
+// Parameters:
+//    searchPathDirectory - the search path passed to NSSearchPathForDirectoriesInDomains
+//    domainMask - the domain mask passed to NSSearchPathForDirectoriesInDomains
+//    appendComponent - the subdirectory appended
+//    errorOut - any error from file operations
+//
+// returns the path to the directory (if path found and exists), nil otherwise
+//
+- (NSString *)findOrCreateDirectory:(NSSearchPathDirectory)searchPathDirectory
+	inDomain:(NSSearchPathDomainMask)domainMask
+	appendPathComponent:(NSString *)appendComponent
+	error:(NSError **)errorOut
+{
+	//
+	// Search for the path
+	//
+	NSArray* paths = NSSearchPathForDirectoriesInDomains(
+		searchPathDirectory,
+		domainMask,
+		YES);
+	if ([paths count] == 0)
+	{
+		if (errorOut)
+		{
+			NSDictionary *userInfo =
+				[NSDictionary dictionaryWithObjectsAndKeys:
+					NSLocalizedStringFromTable(
+						@"No path found for directory in domain.",
+						@"Errors",
+					nil),
+					NSLocalizedDescriptionKey,
+					[NSNumber numberWithInteger:searchPathDirectory],
+					@"NSSearchPathDirectory",
+					[NSNumber numberWithInteger:domainMask],
+					@"NSSearchPathDomainMask",
+				nil];
+			*errorOut =
+				[NSError 
+					errorWithDomain:DirectoryLocationDomain
+					code:DirectoryLocationErrorNoPathFound
+					userInfo:userInfo];
+		}
+		return nil;
+	}
+	
+	//
+	// Normally only need the first path returned
+	//
+	NSString *resolvedPath = [paths objectAtIndex:0];
+
+	//
+	// Append the extra path component
+	//
+	if (appendComponent)
+	{
+		resolvedPath = [resolvedPath
+			stringByAppendingPathComponent:appendComponent];
+	}
+	
+	//
+	// Check if the path exists
+	//
+	BOOL exists;
+	BOOL isDirectory;
+	exists = [self
+		fileExistsAtPath:resolvedPath
+		isDirectory:&isDirectory];
+	if (!exists || !isDirectory)
+	{
+		if (exists)
+		{
+			if (errorOut)
+			{
+				NSDictionary *userInfo =
+					[NSDictionary dictionaryWithObjectsAndKeys:
+						NSLocalizedStringFromTable(
+							@"File exists at requested directory location.",
+							@"Errors",
+						nil),
+						NSLocalizedDescriptionKey,
+						[NSNumber numberWithInteger:searchPathDirectory],
+						@"NSSearchPathDirectory",
+						[NSNumber numberWithInteger:domainMask],
+						@"NSSearchPathDomainMask",
+					nil];
+				*errorOut =
+					[NSError 
+						errorWithDomain:DirectoryLocationDomain
+						code:DirectoryLocationErrorFileExistsAtLocation
+						userInfo:userInfo];
+			}
+			return nil;
+		}
+		
+		//
+		// Create the path if it doesn't exist
+		//
+		NSError *error = nil;
+		BOOL success = [self
+			createDirectoryAtPath:resolvedPath
+			withIntermediateDirectories:YES
+			attributes:nil
+			error:&error];
+		if (!success) 
+		{
+			if (errorOut)
+			{
+				*errorOut = error;
+			}
+			return nil;
+		}
+	}
+	
+	if (errorOut)
+	{
+		*errorOut = nil;
+	}
+	return resolvedPath;
+}
+
+//
+// applicationSupportDirectory
+//
+// Returns the path to the applicationSupportDirectory (creating it if it doesn't
+// exist).
+//
+- (NSString *)applicationSupportDirectory
+{
+	NSString *executableName =
+		[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"];
+	NSError *error;
+	NSString *result =
+		[self
+			findOrCreateDirectory:NSApplicationSupportDirectory
+			inDomain:NSUserDomainMask
+			appendPathComponent:executableName
+			error:&error];
+	if (!result)
+	{
+		NSLog(@"Unable to find or create application support directory:\n%@", error);
+	}
+	return result;
+}
+
+@end

+ 210 - 57
English.lproj/ItemPropertiesView.xib

@@ -2,13 +2,13 @@
 <archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
 	<data>
 		<int key="IBDocument.SystemTarget">1060</int>
-		<string key="IBDocument.SystemVersion">10F569</string>
-		<string key="IBDocument.InterfaceBuilderVersion">804</string>
-		<string key="IBDocument.AppKitVersion">1038.29</string>
+		<string key="IBDocument.SystemVersion">10H574</string>
+		<string key="IBDocument.InterfaceBuilderVersion">823</string>
+		<string key="IBDocument.AppKitVersion">1038.35</string>
 		<string key="IBDocument.HIToolboxVersion">461.00</string>
 		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
 			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
-			<string key="NS.object.0">804</string>
+			<string key="NS.object.0">823</string>
 		</object>
 		<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
 			<bool key="EncodedWithXMLCoder">YES</bool>
@@ -43,21 +43,80 @@
 				<int key="NSvFlags">268</int>
 				<object class="NSMutableArray" key="NSSubviews">
 					<bool key="EncodedWithXMLCoder">YES</bool>
-					<object class="NSButton" id="443904501">
+					<object class="NSButton" id="655316018">
 						<reference key="NSNextResponder" ref="1005"/>
 						<int key="NSvFlags">268</int>
-						<string key="NSFrame">{{127, 54}, {12, 30}}</string>
+						<string key="NSFrame">{{106, 11}, {21, 21}}</string>
 						<reference key="NSSuperview" ref="1005"/>
 						<bool key="NSEnabled">YES</bool>
-						<object class="NSButtonCell" key="NSCell" id="67413845">
+						<object class="NSButtonCell" key="NSCell" id="499735237">
 							<int key="NSCellFlags">67239424</int>
-							<int key="NSCellFlags2">268435456</int>
-							<string key="NSContents">Button</string>
+							<int key="NSCellFlags2">0</int>
+							<string key="NSContents">checkIndestructible</string>
 							<object class="NSFont" key="NSSupport" id="1068884137">
 								<string key="NSName">LucidaGrande</string>
 								<double key="NSSize">13</double>
 								<int key="NSfFlags">1044</int>
 							</object>
+							<reference key="NSControlView" ref="655316018"/>
+							<int key="NSButtonFlags">1211912703</int>
+							<int key="NSButtonFlags2">2</int>
+							<object class="NSCustomResource" key="NSNormalImage">
+								<string key="NSClassName">NSImage</string>
+								<string key="NSResourceName">NSSwitch</string>
+							</object>
+							<object class="NSButtonImageSource" key="NSAlternateImage">
+								<string key="NSImageName">NSSwitch</string>
+							</object>
+							<string key="NSAlternateContents"/>
+							<string key="NSKeyEquivalent"/>
+							<int key="NSPeriodicDelay">200</int>
+							<int key="NSPeriodicInterval">25</int>
+						</object>
+					</object>
+					<object class="NSTextField" id="200212759">
+						<reference key="NSNextResponder" ref="1005"/>
+						<int key="NSvFlags">268</int>
+						<string key="NSFrame">{{8, 13}, {95, 17}}</string>
+						<reference key="NSSuperview" ref="1005"/>
+						<bool key="NSEnabled">YES</bool>
+						<object class="NSTextFieldCell" key="NSCell" id="70045272">
+							<int key="NSCellFlags">68288064</int>
+							<int key="NSCellFlags2">71304192</int>
+							<string key="NSContents">Indestructible:</string>
+							<reference key="NSSupport" ref="1068884137"/>
+							<reference key="NSControlView" ref="200212759"/>
+							<object class="NSColor" key="NSBackgroundColor" id="1036798693">
+								<int key="NSColorSpace">6</int>
+								<string key="NSCatalogName">System</string>
+								<string key="NSColorName">controlColor</string>
+								<object class="NSColor" key="NSColor">
+									<int key="NSColorSpace">3</int>
+									<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
+								</object>
+							</object>
+							<object class="NSColor" key="NSTextColor" id="646856644">
+								<int key="NSColorSpace">6</int>
+								<string key="NSCatalogName">System</string>
+								<string key="NSColorName">controlTextColor</string>
+								<object class="NSColor" key="NSColor" id="833234732">
+									<int key="NSColorSpace">3</int>
+									<bytes key="NSWhite">MAA</bytes>
+								</object>
+							</object>
+						</object>
+					</object>
+					<object class="NSButton" id="443904501">
+						<reference key="NSNextResponder" ref="1005"/>
+						<int key="NSvFlags">268</int>
+						<string key="NSFrame">{{156, 88}, {13, 20}}</string>
+						<reference key="NSSuperview" ref="1005"/>
+						<bool key="NSEnabled">YES</bool>
+						<object class="NSButtonCell" key="NSCell" id="67413845">
+							<int key="NSCellFlags">67239424</int>
+							<int key="NSCellFlags2">268435456</int>
+							<string key="NSContents">Button</string>
+							<reference key="NSSupport" ref="1068884137"/>
 							<reference key="NSControlView" ref="443904501"/>
 							<int key="NSButtonFlags">-2042347265</int>
 							<int key="NSButtonFlags2">129</int>
@@ -74,11 +133,11 @@
 					<object class="NSTextField" id="644098962">
 						<reference key="NSNextResponder" ref="1005"/>
 						<int key="NSvFlags">268</int>
-						<string key="NSFrame">{{74, 9}, {51, 22}}</string>
+						<string key="NSFrame">{{108, 36}, {51, 22}}</string>
 						<reference key="NSSuperview" ref="1005"/>
 						<bool key="NSEnabled">YES</bool>
 						<object class="NSTextFieldCell" key="NSCell" id="213635492">
-							<int key="NSCellFlags">-1804468671</int>
+							<int key="NSCellFlags">343014977</int>
 							<int key="NSCellFlags2">272630848</int>
 							<reference key="NSSupport" ref="1068884137"/>
 							<object class="NSNumberFormatter" key="NSFormatter" id="593187453">
@@ -88,6 +147,7 @@
 										<bool key="EncodedWithXMLCoder">YES</bool>
 										<string>allowsFloats</string>
 										<string>formatterBehavior</string>
+										<string>lenient</string>
 										<string>locale</string>
 										<string>negativeInfinitySymbol</string>
 										<string>nilSymbol</string>
@@ -98,17 +158,18 @@
 										<bool key="EncodedWithXMLCoder">YES</bool>
 										<boolean value="YES"/>
 										<integer value="1040"/>
+										<boolean value="NO"/>
 										<object class="NSLocale" id="301643830">
 											<string key="NS.identifier"/>
 										</object>
 										<string>-∞</string>
 										<string/>
-										<integer value="1"/>
+										<integer value="0"/>
 										<string>+∞</string>
 									</object>
 								</object>
-								<string key="NS.positiveformat">#,##0.###</string>
-								<string key="NS.negativeformat">#,##0.###</string>
+								<string key="NS.positiveformat">#</string>
+								<string key="NS.negativeformat">#</string>
 								<nil key="NS.positiveattrs"/>
 								<nil key="NS.negativeattrs"/>
 								<nil key="NS.zero"/>
@@ -142,7 +203,7 @@
 								</object>
 								<string key="NS.decimal">.</string>
 								<string key="NS.thousand">,</string>
-								<bool key="NS.hasthousands">YES</bool>
+								<bool key="NS.hasthousands">NO</bool>
 								<bool key="NS.localized">NO</bool>
 								<bool key="NS.allowsfloats">YES</bool>
 							</object>
@@ -161,17 +222,14 @@
 								<int key="NSColorSpace">6</int>
 								<string key="NSCatalogName">System</string>
 								<string key="NSColorName">textColor</string>
-								<object class="NSColor" key="NSColor" id="833234732">
-									<int key="NSColorSpace">3</int>
-									<bytes key="NSWhite">MAA</bytes>
-								</object>
+								<reference key="NSColor" ref="833234732"/>
 							</object>
 						</object>
 					</object>
 					<object class="NSTextField" id="380391011">
 						<reference key="NSNextResponder" ref="1005"/>
 						<int key="NSvFlags">268</int>
-						<string key="NSFrame">{{74, 36}, {51, 22}}</string>
+						<string key="NSFrame">{{108, 62}, {51, 22}}</string>
 						<reference key="NSSuperview" ref="1005"/>
 						<bool key="NSEnabled">YES</bool>
 						<object class="NSTextFieldCell" key="NSCell" id="247292744">
@@ -237,7 +295,7 @@
 					<object class="NSTextField" id="112492398">
 						<reference key="NSNextResponder" ref="1005"/>
 						<int key="NSvFlags">268</int>
-						<string key="NSFrame">{{3, 11}, {66, 17}}</string>
+						<string key="NSFrame">{{37, 38}, {66, 17}}</string>
 						<reference key="NSSuperview" ref="1005"/>
 						<bool key="NSEnabled">YES</bool>
 						<object class="NSTextFieldCell" key="NSCell" id="503317427">
@@ -246,27 +304,14 @@
 							<string key="NSContents">Damage:</string>
 							<reference key="NSSupport" ref="1068884137"/>
 							<reference key="NSControlView" ref="112492398"/>
-							<object class="NSColor" key="NSBackgroundColor" id="1036798693">
-								<int key="NSColorSpace">6</int>
-								<string key="NSCatalogName">System</string>
-								<string key="NSColorName">controlColor</string>
-								<object class="NSColor" key="NSColor">
-									<int key="NSColorSpace">3</int>
-									<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
-								</object>
-							</object>
-							<object class="NSColor" key="NSTextColor" id="646856644">
-								<int key="NSColorSpace">6</int>
-								<string key="NSCatalogName">System</string>
-								<string key="NSColorName">controlTextColor</string>
-								<reference key="NSColor" ref="833234732"/>
-							</object>
+							<reference key="NSBackgroundColor" ref="1036798693"/>
+							<reference key="NSTextColor" ref="646856644"/>
 						</object>
 					</object>
 					<object class="NSTextField" id="908946299">
 						<reference key="NSNextResponder" ref="1005"/>
 						<int key="NSvFlags">268</int>
-						<string key="NSFrame">{{8, 63}, {120, 14}}</string>
+						<string key="NSFrame">{{8, 92}, {120, 14}}</string>
 						<reference key="NSSuperview" ref="1005"/>
 						<bool key="NSEnabled">YES</bool>
 						<object class="NSTextFieldCell" key="NSCell" id="405749842">
@@ -286,7 +331,7 @@
 					<object class="NSTextField" id="274194782">
 						<reference key="NSNextResponder" ref="1005"/>
 						<int key="NSvFlags">268</int>
-						<string key="NSFrame">{{3, 38}, {66, 17}}</string>
+						<string key="NSFrame">{{37, 65}, {66, 17}}</string>
 						<reference key="NSSuperview" ref="1005"/>
 						<bool key="NSEnabled">YES</bool>
 						<object class="NSTextFieldCell" key="NSCell" id="255423386">
@@ -300,7 +345,7 @@
 						</object>
 					</object>
 				</object>
-				<string key="NSFrameSize">{140, 80}</string>
+				<string key="NSFrameSize">{174, 109}</string>
 				<reference key="NSSuperview"/>
 				<string key="NSClassName">NSView</string>
 			</object>
@@ -372,6 +417,22 @@
 					</object>
 					<int key="connectionID">25</int>
 				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">makeIndestructible:</string>
+						<reference key="source" ref="1001"/>
+						<reference key="destination" ref="655316018"/>
+					</object>
+					<int key="connectionID">34</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBOutletConnection" key="connection">
+						<string key="label">checkIndestructible</string>
+						<reference key="source" ref="1001"/>
+						<reference key="destination" ref="655316018"/>
+					</object>
+					<int key="connectionID">35</int>
+				</object>
 			</object>
 			<object class="IBMutableOrderedSet" key="objectRecords">
 				<object class="NSArray" key="orderedObjects">
@@ -405,12 +466,14 @@
 						<reference key="object" ref="1005"/>
 						<object class="NSMutableArray" key="children">
 							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="908946299"/>
 							<reference ref="274194782"/>
 							<reference ref="112492398"/>
 							<reference ref="380391011"/>
+							<reference ref="200212759"/>
+							<reference ref="655316018"/>
 							<reference ref="644098962"/>
 							<reference ref="443904501"/>
-							<reference ref="908946299"/>
 						</object>
 						<reference key="parent" ref="0"/>
 					</object>
@@ -516,6 +579,35 @@
 						<reference key="object" ref="405749842"/>
 						<reference key="parent" ref="908946299"/>
 					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">26</int>
+						<reference key="object" ref="200212759"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="70045272"/>
+						</object>
+						<reference key="parent" ref="1005"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">27</int>
+						<reference key="object" ref="70045272"/>
+						<reference key="parent" ref="200212759"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">28</int>
+						<reference key="object" ref="655316018"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="499735237"/>
+						</object>
+						<reference key="parent" ref="1005"/>
+						<string key="objectName">checkIndestructible</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">29</int>
+						<reference key="object" ref="499735237"/>
+						<reference key="parent" ref="655316018"/>
+					</object>
 				</object>
 			</object>
 			<object class="NSMutableDictionary" key="flattenedProperties">
@@ -524,6 +616,7 @@
 					<bool key="EncodedWithXMLCoder">YES</bool>
 					<string>1.IBEditorWindowLastContentRect</string>
 					<string>1.IBPluginDependency</string>
+					<string>1.IBViewBoundsToFrameTransform</string>
 					<string>1.WindowOrigin</string>
 					<string>1.editorWindowContentRectSynchronizationRect</string>
 					<string>10.IBPluginDependency</string>
@@ -531,6 +624,7 @@
 					<string>11.IBPluginDependency</string>
 					<string>12.IBNumberFormatterBehaviorMetadataKey</string>
 					<string>12.IBNumberFormatterLocalizesFormatMetadataKey</string>
+					<string>12.IBNumberFormatterSampleNumberKey</string>
 					<string>12.IBPluginDependency</string>
 					<string>17.IBPluginDependency</string>
 					<string>17.IBViewBoundsToFrameTransform</string>
@@ -538,6 +632,12 @@
 					<string>22.IBPluginDependency</string>
 					<string>22.IBViewBoundsToFrameTransform</string>
 					<string>23.IBPluginDependency</string>
+					<string>26.IBPluginDependency</string>
+					<string>26.IBViewBoundsToFrameTransform</string>
+					<string>27.IBPluginDependency</string>
+					<string>28.IBPluginDependency</string>
+					<string>28.IBViewBoundsToFrameTransform</string>
+					<string>29.IBPluginDependency</string>
 					<string>3.IBPluginDependency</string>
 					<string>3.IBViewBoundsToFrameTransform</string>
 					<string>4.IBPluginDependency</string>
@@ -553,21 +653,23 @@
 				</object>
 				<object class="NSMutableArray" key="dict.values">
 					<bool key="EncodedWithXMLCoder">YES</bool>
-					<string>{{550, 448}, {140, 80}}</string>
+					<string>{{1100, 300}, {174, 109}}</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform"/>
 					<string>{628, 654}</string>
 					<string>{{217, 442}, {480, 272}}</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">P4AAAL+AAABClAAAwjwAAA</bytes>
+						<bytes key="NSTransformStruct">P4AAAL+AAABC2AAAwmAAAA</bytes>
 					</object>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<integer value="1041"/>
 					<boolean value="YES"/>
+					<real value="1275"/>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">P4AAAL+AAABCogAAwo4AAA</bytes>
+						<bytes key="NSTransformStruct">P4AAAL+AAABDHAAAwtQAAA</bytes>
 					</object>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -577,17 +679,27 @@
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">P4AAAL+AAABAQAAAwmQAAA</bytes>
+						<bytes key="NSTransformStruct">P4AAAL+AAADAAAAAwfAAAA</bytes>
 					</object>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">P4AAAL+AAABAQAAAwjAAAA</bytes>
+						<bytes key="NSTransformStruct">P4AAAL+AAABC1AAAwfAAAA</bytes>
 					</object>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<object class="NSAffineTransform">
-						<bytes key="NSTransformStruct">P4AAAL+AAABClAAAwpQAAA</bytes>
+						<bytes key="NSTransformStruct">P4AAAL+AAABB2AAAwqQAAA</bytes>
+					</object>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABB2AAAwlwAAA</bytes>
+					</object>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABCxAAAwqgAAA</bytes>
 					</object>
 					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 					<integer value="1041"/>
@@ -611,7 +723,7 @@
 				</object>
 			</object>
 			<nil key="sourceID"/>
-			<int key="maxID">25</int>
+			<int key="maxID">35</int>
 		</object>
 		<object class="IBClassDescriber" key="IBDocument.Classes">
 			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -620,19 +732,51 @@
 					<string key="className">IJItemPropertiesViewController</string>
 					<string key="superclassName">NSViewController</string>
 					<object class="NSMutableDictionary" key="actions">
-						<string key="NS.key.0">closeButton:</string>
-						<string key="NS.object.0">id</string>
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<object class="NSArray" key="dict.sortedKeys">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>closeButton:</string>
+							<string>makeIndestructible:</string>
+						</object>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>id</string>
+							<string>id</string>
+						</object>
 					</object>
 					<object class="NSMutableDictionary" key="actionInfosByName">
-						<string key="NS.key.0">closeButton:</string>
-						<object class="IBActionInfo" key="NS.object.0">
-							<string key="name">closeButton:</string>
-							<string key="candidateClassName">id</string>
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<object class="NSArray" key="dict.sortedKeys">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>closeButton:</string>
+							<string>makeIndestructible:</string>
+						</object>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<object class="IBActionInfo">
+								<string key="name">closeButton:</string>
+								<string key="candidateClassName">id</string>
+							</object>
+							<object class="IBActionInfo">
+								<string key="name">makeIndestructible:</string>
+								<string key="candidateClassName">id</string>
+							</object>
+						</object>
+					</object>
+					<object class="NSMutableDictionary" key="outlets">
+						<string key="NS.key.0">checkIndestructible</string>
+						<string key="NS.object.0">NSButton</string>
+					</object>
+					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
+						<string key="NS.key.0">checkIndestructible</string>
+						<object class="IBToOneOutletInfo" key="NS.object.0">
+							<string key="name">checkIndestructible</string>
+							<string key="candidateClassName">NSButton</string>
 						</object>
 					</object>
 					<object class="IBClassDescriptionSource" key="sourceIdentifier">
 						<string key="majorKey">IBProjectSource</string>
-						<string key="minorKey">IJItemPropertiesViewController.h</string>
+						<string key="minorKey">Classes/IJItemPropertiesViewController.h</string>
 					</object>
 				</object>
 			</object>
@@ -1099,11 +1243,20 @@
 			<integer value="3000" key="NS.object.0"/>
 		</object>
 		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
-		<string key="IBDocument.LastKnownRelativeProjectPath">InsideJob.xcodeproj</string>
+		<string key="IBDocument.LastKnownRelativeProjectPath">../InsideJob.xcodeproj</string>
 		<int key="IBDocument.defaultPropertyAccessControl">3</int>
 		<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
-			<string key="NS.key.0">NSStopProgressFreestandingTemplate</string>
-			<string key="NS.object.0">{83, 83}</string>
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="NSArray" key="dict.sortedKeys">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<string>NSStopProgressFreestandingTemplate</string>
+				<string>NSSwitch</string>
+			</object>
+			<object class="NSMutableArray" key="dict.values">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<string>{83, 83}</string>
+				<string>{15, 15}</string>
+			</object>
 		</object>
 	</data>
 </archive>

File diff suppressed because it is too large
+ 423 - 509
English.lproj/MainMenu.xib


+ 17 - 9
InsideJob.xcodeproj/project.pbxproj

@@ -9,7 +9,6 @@
 /* Begin PBXBuildFile section */
 		1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58140DA1D0A300B32029 /* MainMenu.xib */; };
 		256AC3DA0F4B6AC300CF3369 /* InsideJobAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 256AC3D90F4B6AC300CF3369 /* InsideJobAppDelegate.m */; };
-		663803B2131769E90015CFAD /* blockNotFound.png in Resources */ = {isa = PBXBuildFile; fileRef = 663803B1131769E90015CFAD /* blockNotFound.png */; };
 		668B2556125D5A3E0060BF71 /* NBTContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B2555125D5A3E0060BF71 /* NBTContainer.m */; };
 		668B255C125D5BCA0060BF71 /* NSData+CocoaDevAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B255B125D5BCA0060BF71 /* NSData+CocoaDevAdditions.m */; };
 		668B2560125D5C1C0060BF71 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 668B255F125D5C1C0060BF71 /* libz.dylib */; };
@@ -17,7 +16,6 @@
 		668B27B2125D8F8E0060BF71 /* IJInventoryItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B27B1125D8F8E0060BF71 /* IJInventoryItem.m */; };
 		668B27F2125D963F0060BF71 /* IJInventoryWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B27F1125D963F0060BF71 /* IJInventoryWindowController.m */; };
 		668B290F125E40560060BF71 /* Items.csv in Resources */ = {isa = PBXBuildFile; fileRef = 668B28D8125E370A0060BF71 /* Items.csv */; };
-		6697AD7212B86762001890C6 /* IJTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6697AD7112B86762001890C6 /* IJTableView.m */; };
 		66BC00031260215C005A23F4 /* IJInventoryView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BC00021260215C005A23F4 /* IJInventoryView.m */; };
 		66BC000E12602359005A23F4 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66BC000D12602359005A23F4 /* QuartzCore.framework */; };
 		66BC033B1260CC59005A23F4 /* MAAttachedWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 66BC033A1260CC59005A23F4 /* MAAttachedWindow.m */; };
@@ -30,6 +28,9 @@
 		8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
 		8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
 		8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+		BA24598B1297428900F8B9C2 /* blockNotFound.png in Resources */ = {isa = PBXBuildFile; fileRef = BA24598A1297428900F8B9C2 /* blockNotFound.png */; };
+		BA3329A9129889860079447B /* NSFileManager+DirectoryLocations.m in Sources */ = {isa = PBXBuildFile; fileRef = BA3329A8129889860079447B /* NSFileManager+DirectoryLocations.m */; };
+		BA9186CB1328C1C600769DEC /* IJTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = BA9186CA1328C1C600769DEC /* IJTableView.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -43,7 +44,6 @@
 		29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
 		29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
 		29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
-		663803B1131769E90015CFAD /* blockNotFound.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = blockNotFound.png; sourceTree = "<group>"; };
 		668B2554125D5A3E0060BF71 /* NBTContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NBTContainer.h; sourceTree = "<group>"; };
 		668B2555125D5A3E0060BF71 /* NBTContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NBTContainer.m; sourceTree = "<group>"; };
 		668B255A125D5BCA0060BF71 /* NSData+CocoaDevAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+CocoaDevAdditions.h"; sourceTree = "<group>"; };
@@ -74,8 +74,12 @@
 		66BCFE61125FCEC6005A23F4 /* DataValuesV110Transparent.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = DataValuesV110Transparent.png; sourceTree = "<group>"; };
 		8D1107310486CEB800E47090 /* InsideJob-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "InsideJob-Info.plist"; sourceTree = "<group>"; };
 		8D1107320486CEB800E47090 /* Inside Job.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Inside Job.app"; sourceTree = BUILT_PRODUCTS_DIR; };
-		D13FDB481322757D00D318D1 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
-		D13FDB491322782100D318D1 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file; name = fr; path = fr.lproj/MainMenu.xib; sourceTree = "<group>"; };
+		BA24598A1297428900F8B9C2 /* blockNotFound.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = blockNotFound.png; sourceTree = "<group>"; };
+		BA3329A7129889860079447B /* NSFileManager+DirectoryLocations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSFileManager+DirectoryLocations.h"; sourceTree = "<group>"; };
+		BA3329A8129889860079447B /* NSFileManager+DirectoryLocations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSFileManager+DirectoryLocations.m"; sourceTree = "<group>"; };
+		BA9186C91328C1C600769DEC /* IJTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJTableView.h; sourceTree = "<group>"; };
+		BA9186CA1328C1C600769DEC /* IJTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJTableView.m; sourceTree = "<group>"; };
+		D13FDB481322757D00D318D1 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -198,6 +202,8 @@
 				668B255B125D5BCA0060BF71 /* NSData+CocoaDevAdditions.m */,
 				66BC04F612619072005A23F4 /* NSColor+Additions.h */,
 				66BC04F712619072005A23F4 /* NSColor+Additions.m */,
+				BA3329A7129889860079447B /* NSFileManager+DirectoryLocations.h */,
+				BA3329A8129889860079447B /* NSFileManager+DirectoryLocations.m */,
 			);
 			name = Categories;
 			sourceTree = "<group>";
@@ -218,6 +224,8 @@
 		66BC033E1260CC68005A23F4 /* Views & Windows */ = {
 			isa = PBXGroup;
 			children = (
+				BA9186C91328C1C600769DEC /* IJTableView.h */,
+				BA9186CA1328C1C600769DEC /* IJTableView.m */,
 				66BC03391260CC59005A23F4 /* MAAttachedWindow.h */,
 				66BC033A1260CC59005A23F4 /* MAAttachedWindow.m */,
 				6697AD7012B86762001890C6 /* IJTableView.h */,
@@ -229,7 +237,7 @@
 		66BC07711262823E005A23F4 /* Images */ = {
 			isa = PBXGroup;
 			children = (
-				663803B1131769E90015CFAD /* blockNotFound.png */,
+				BA24598A1297428900F8B9C2 /* blockNotFound.png */,
 				66BCFE61125FCEC6005A23F4 /* DataValuesV110Transparent.png */,
 				66BCFC35125EA53E005A23F4 /* InsideJob.icns */,
 			);
@@ -297,7 +305,7 @@
 				66BCFC36125EA53E005A23F4 /* InsideJob.icns in Resources */,
 				66BCFE62125FCEC6005A23F4 /* DataValuesV110Transparent.png in Resources */,
 				66BC077312628257005A23F4 /* ItemPropertiesView.xib in Resources */,
-				663803B2131769E90015CFAD /* blockNotFound.png in Resources */,
+				BA24598B1297428900F8B9C2 /* blockNotFound.png in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -319,7 +327,8 @@
 				66BC033B1260CC59005A23F4 /* MAAttachedWindow.m in Sources */,
 				66BC03621260D095005A23F4 /* IJItemPropertiesViewController.m in Sources */,
 				66BC04F812619072005A23F4 /* NSColor+Additions.m in Sources */,
-				6697AD7212B86762001890C6 /* IJTableView.m in Sources */,
+				BA3329A9129889860079447B /* NSFileManager+DirectoryLocations.m in Sources */,
+				BA9186CB1328C1C600769DEC /* IJTableView.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -339,7 +348,6 @@
 			isa = PBXVariantGroup;
 			children = (
 				1DDD58150DA1D0A300B32029 /* English */,
-				D13FDB491322782100D318D1 /* fr */,
 			);
 			name = MainMenu.xib;
 			sourceTree = "<group>";

File diff suppressed because it is too large
+ 0 - 2719
fr.lproj/MainMenu.xib