Added Undo/Redo. Made more easily localisable. Added 'delete resource' methods. Added (non-function) find sheet to hex editor.

This commit is contained in:
Nicholas Shanks 2002-02-14 23:24:53 +00:00
parent c2087c99be
commit 667ed16d05
36 changed files with 533 additions and 183 deletions

View File

@ -1,7 +1,7 @@
#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>
#import "Resource.h"
#import "ResourceDataSource.h"
@class ResourceDocument, ResourceDataSource;
@interface CreateResourceSheetController : NSWindowController
{
@ -13,6 +13,7 @@
IBOutlet NSTextField *resIDView;
IBOutlet NSTextField *typeView;
IBOutlet NSPopUpButton *typePopup;
IBOutlet ResourceDocument *document;
IBOutlet NSWindow *parent;
}

View File

@ -1,4 +1,7 @@
#import "CreateResourceSheetController.h"
#import "ResourceDataSource.h"
#import "ResourceDocument.h"
#import "Resource.h"
@implementation CreateResourceSheetController
@ -37,7 +40,13 @@
attributes ^= [[attributesMatrix cellAtRow:2 column:0] intValue]? resLocked:0;
attributes ^= [[attributesMatrix cellAtRow:0 column:1] intValue]? resSysHeap:0;
attributes ^= [[attributesMatrix cellAtRow:1 column:1] intValue]? resProtected:0;
[[document undoManager] beginUndoGrouping];
[dataSource addResource:[Resource resourceOfType:[typeView stringValue] andID:[NSNumber numberWithShort:(short) [resIDView intValue]] withName:[nameView stringValue] andAttributes:[NSNumber numberWithUnsignedShort:attributes]]];
if( [[nameView stringValue] length] == 0 )
[[document undoManager] setActionName:NSLocalizedString(@"Create Resource", nil)];
else [[document undoManager] setActionName:[NSString stringWithFormat:NSLocalizedString(@"Create Resource Ò%@Ó", nil), [nameView stringValue]]];
[[document undoManager] endUndoGrouping];
}
[[self window] orderOut:nil];
[NSApp endSheet:[self window]];

View File

@ -2,6 +2,11 @@
@implementation InfoWindow
- (BOOL)canBecomeKeyWindow
{
return NO;
}
- (BOOL)canBecomeMainWindow
{
return NO;

View File

@ -31,6 +31,7 @@ enum Attributes
- (void)updateInfoWindow;
- (void)setMainWindow:(NSWindow *)mainWindow;
- (IBAction)attributesChanged:(id)sender;
- (void)resourceAttributesDidChange:(NSNotification *)notification;
+ (id)sharedInfoWindowController;

View File

@ -33,6 +33,7 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mainWindowChanged:) name:NSWindowDidBecomeMainNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(selectedResourceChanged:) name:NSOutlineViewSelectionDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceAttributesDidChange:) name:ResourceAttributesDidChangeNotification object:nil];
}
- (void)updateInfoWindow
@ -86,6 +87,10 @@
short attr = 0x0001 << [sender selectedRow]+1;
short number = ([[selectedResource attributes] shortValue] ^ attr);
[selectedResource setAttributes:[NSNumber numberWithShort:number]];
}
- (void)resourceAttributesDidChange:(NSNotification *)notification;
{
[self updateInfoWindow];
}

View File

@ -1,4 +1,4 @@
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
@interface NameFormatter : NSFormatter
{

View File

@ -1,5 +1,4 @@
#import "NameFormatter.h"
#import <AppKit/NSColor.h>
@implementation NameFormatter
@ -19,7 +18,7 @@
{
NSString *string = [self stringForObjectValue:obj];
if( [obj isEqualToString:@""] )
return [[NSAttributedString alloc] initWithString:string attributes:[NSDictionary dictionaryWithObject:[NSColor grayColor] forKey:@"NSColor"]];
return [[NSAttributedString alloc] initWithString:string attributes:[NSDictionary dictionaryWithObject:[NSColor grayColor] forKey:NSForegroundColorAttributeName]];
else return [[NSAttributedString alloc] initWithString:string attributes:attrs];
}

View File

@ -6,7 +6,12 @@
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
NSTableColumn *nameColumn = [outlineView tableColumnWithIdentifier:@"name"];
if( [[tableColumn identifier] isEqualToString:@"name"] ) [cell setFormatter:nameFormatter];
else if( [[tableColumn identifier] isEqualToString:@"size"] ) [cell setFormatter:sizeFormatter];
else if( [[tableColumn identifier] isEqualToString:@"attributes"] ) [cell setFormatter:attributesFormatter];
// alternative to the above three lines, need to profile to find out which is faster
/* NSTableColumn *nameColumn = [outlineView tableColumnWithIdentifier:@"name"];
NSTableColumn *sizeColumn = [outlineView tableColumnWithIdentifier:@"size"];
NSTableColumn *attributesColumn = [outlineView tableColumnWithIdentifier:@"attributes"];
@ -14,9 +19,10 @@
if( [tableColumn isEqual:nameColumn] ) [cell setFormatter:nameFormatter];
else if( [tableColumn isEqual:sizeColumn] ) [cell setFormatter:sizeFormatter];
else if( [tableColumn isEqual:attributesColumn] ) [cell setFormatter:attributesFormatter];
*/
// set resource icon
if( [tableColumn isEqual:nameColumn] )
if( [[tableColumn identifier] isEqualToString:@"name"] )
{
[(ResourceNameCell *)cell setImage:[NSImage imageNamed:@"Resource file"]];
// [(ResourceNameCell *)cell setImage:[[NSWorkspace sharedWorkspace] iconForFileType:[(Resource *)item type]]];

View File

@ -4,41 +4,27 @@
@interface Resource : NSObject <ResKnifeResourceProtocol>
{
@private
// flags
BOOL dirty;
// resource information
NSString *name;
NSString *type;
NSNumber *resID; // signed short
NSNumber *size; // unsigned long
NSNumber *attributes; // unsigned short
// flags
BOOL dirty;
// the actual data
NSData *data;
NSData *data;
}
- (NSString *)name;
- (void)setName:(NSString *)newName;
- (NSString *)type;
- (void)setType:(NSString *)newType;
- (NSNumber *)resID;
- (void)setResID:(NSNumber *)newResID;
- (NSNumber *)size;
- (void)setSize:(NSNumber *)newSize;
- (NSNumber *)attributes;
- (void)setAttributes:(NSNumber *)newAttributes;
- (BOOL)dirty;
- (void)setDirty:(BOOL)newValue;
- (NSData *)data;
- (void)setData:(NSData *)newData;
- (id)initWithType:(NSString *)typeValue andID:(NSNumber *)resIDValue;
- (id)initWithType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue;
- (id)initWithType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue data:(NSData *)dataValue ofLength:(NSNumber *)sizeValue;
- (id)initWithType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue data:(NSData *)dataValue;
+ (id)resourceOfType:(NSString *)typeValue andID:(NSNumber *)resIDValue;
+ (id)resourceOfType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue;
+ (id)resourceOfType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue data:(NSData *)dataValue ofLength:(NSNumber *)sizeValue;
+ (id)resourceOfType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue data:(NSData *)dataValue;
@end

View File

@ -2,12 +2,24 @@
@implementation Resource
NSString *ResourceChangedNotification = @"ResourceChangedNotification";
NSString *ResourceWillChangeNotification = @"ResourceWillChangeNotification";
NSString *ResourceNameWillChangeNotification = @"ResourceNameWillChangeNotification";
NSString *ResourceTypeWillChangeNotification = @"ResourceTypeWillChangeNotification";
NSString *ResourceIDWillChangeNotification = @"ResourceIDWillChangeNotification";
NSString *ResourceAttributesWillChangeNotification = @"ResourceAttributesWillChangeNotification";
NSString *ResourceDataWillChangeNotification = @"ResourceDataWillChangeNotification";
NSString *ResourceNameDidChangeNotification = @"ResourceNameDidChangeNotification";
NSString *ResourceTypeDidChangeNotification = @"ResourceTypeDidChangeNotification";
NSString *ResourceIDDidChangeNotification = @"ResourceIDDidChangeNotification";
NSString *ResourceAttributesDidChangeNotification = @"ResourceAttributesDidChangeNotification";
NSString *ResourceDataDidChangeNotification = @"ResourceDataDidChangeNotification";
NSString *ResourceDidChangeNotification = @"ResourceDidChangeNotification";
- (id)init
{
self = [super init];
[self initWithType:@"" andID:[NSNumber numberWithShort:128]];
[self initWithType:@"NULL" andID:[NSNumber numberWithShort:128]];
return self;
}
@ -16,12 +28,24 @@ NSString *ResourceChangedNotification = @"ResourceChangedNotification";
[name release];
[type release];
[resID release];
[size release];
[attributes release];
[data release];
[super dealloc];
}
/* Accessors */
- (BOOL)isDirty
{
return dirty;
}
- (void)setDirty:(BOOL)newValue
{
dirty = newValue;
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceDidChangeNotification object:self];
}
- (NSString *)name
{
return name;
@ -29,10 +53,14 @@ NSString *ResourceChangedNotification = @"ResourceChangedNotification";
- (void)setName:(NSString *)newName
{
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWillChangeNotification object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceNameWillChangeNotification object:self];
[name autorelease];
name = [newName copy];
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceChangedNotification object:self];
// NSLog( @"%@ posted because name changed to %@", ResourceChangedNotification, name );
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceNameDidChangeNotification object:self];
[self setDirty:YES];
}
- (NSString *)type
@ -42,10 +70,14 @@ NSString *ResourceChangedNotification = @"ResourceChangedNotification";
- (void)setType:(NSString *)newType
{
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWillChangeNotification object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceTypeWillChangeNotification object:self];
[type autorelease];
type = [newType copy];
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceChangedNotification object:self];
// NSLog( @"%@ posted because type changed to %@", ResourceChangedNotification, type );
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceTypeDidChangeNotification object:self];
[self setDirty:YES];
}
- (NSNumber *)resID
@ -55,23 +87,14 @@ NSString *ResourceChangedNotification = @"ResourceChangedNotification";
- (void)setResID:(NSNumber *)newResID
{
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWillChangeNotification object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceIDWillChangeNotification object:self];
[resID autorelease];
resID = [newResID copy];
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceChangedNotification object:self];
// NSLog( @"%@ posted because res ID changed to %@", ResourceChangedNotification, [resID stringValue] );
}
- (NSNumber *)size
{
return size;
}
- (void)setSize:(NSNumber *)newSize
{
[size autorelease];
size = [newSize copy];
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceChangedNotification object:self];
// NSLog( @"%@ posted because size changed to %@", ResourceChangedNotification, [size stringValue] );
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceIDDidChangeNotification object:self];
[self setDirty:YES];
}
- (NSNumber *)attributes
@ -81,22 +104,19 @@ NSString *ResourceChangedNotification = @"ResourceChangedNotification";
- (void)setAttributes:(NSNumber *)newAttributes
{
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWillChangeNotification object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceAttributesWillChangeNotification object:self];
[attributes autorelease];
attributes = [newAttributes copy];
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceChangedNotification object:self];
// NSLog( @"%@ posted because attributes changed to %@", ResourceChangedNotification, [attributes stringValue] );
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceAttributesDidChangeNotification object:self];
[self setDirty:YES];
}
- (BOOL)dirty
- (NSNumber *)size
{
return dirty;
}
- (void)setDirty:(BOOL)newValue
{
dirty = newValue;
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceChangedNotification object:self];
// NSLog( @"%@ posted because resource became %@", ResourceChangedNotification, dirty? @"dirty":@"clean" );
return [NSNumber numberWithUnsignedLong:[data length]];
}
- (NSData *)data
@ -106,12 +126,19 @@ NSString *ResourceChangedNotification = @"ResourceChangedNotification";
- (void)setData:(NSData *)newData
{
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWillChangeNotification object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceDataWillChangeNotification object:self];
// note: this function retains, rather than copies, the supplied data
[data autorelease];
data = [newData retain];
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceChangedNotification object:self];
// NSLog( @"%@ posted because data changed", ResourceChangedNotification );
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceDataDidChangeNotification object:self];
[self setDirty:YES];
}
/* Creation */
- (id)initWithType:(NSString *)typeValue andID:(NSNumber *)resIDValue
{
[self initWithType:typeValue andID:resIDValue withName:@"" andAttributes:[NSNumber numberWithUnsignedShort:0]];
@ -120,19 +147,20 @@ NSString *ResourceChangedNotification = @"ResourceChangedNotification";
- (id)initWithType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue
{
[self initWithType:typeValue andID:resIDValue withName:nameValue andAttributes:attributesValue data:[NSData data] ofLength:[NSNumber numberWithUnsignedLong:0]];
[self initWithType:typeValue andID:resIDValue withName:nameValue andAttributes:attributesValue data:[NSData data]];
return self;
}
- (id)initWithType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue data:(NSData *)dataValue ofLength:(NSNumber *)sizeValue
- (id)initWithType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue data:(NSData *)dataValue
{
// sets values directly to avoid triggering notifications (would create undos all over the place!)
self = [super init];
[self setName:nameValue];
[self setType:typeValue];
[self setResID:resIDValue];
[self setSize:sizeValue];
[self setAttributes:attributesValue];
[self setData:dataValue];
dirty = NO;
name = [nameValue copy];
type = [typeValue copy];
resID = [resIDValue copy];
attributes = [attributesValue copy];
data = [dataValue retain];
return self;
}
@ -148,9 +176,9 @@ NSString *ResourceChangedNotification = @"ResourceChangedNotification";
return [resource autorelease];
}
+ (id)resourceOfType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue data:(NSData *)dataValue ofLength:(NSNumber *)sizeValue
+ (id)resourceOfType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue data:(NSData *)dataValue
{
Resource *resource = [[Resource allocWithZone:[self zone]] initWithType:typeValue andID:resIDValue withName:nameValue andAttributes:attributesValue data:dataValue ofLength:sizeValue];
Resource *resource = [[Resource allocWithZone:[self zone]] initWithType:typeValue andID:resIDValue withName:nameValue andAttributes:attributesValue data:dataValue];
return [resource autorelease];
}

View File

@ -1,13 +1,13 @@
#import <Cocoa/Cocoa.h>
#import "Resource.h"
@class CreateResourceSheetController;
@class CreateResourceSheetController, ResourceDocument, Resource;
@interface ResourceDataSource : NSObject
{
IBOutlet NSWindow *window;
IBOutlet NSOutlineView *outlineView;
IBOutlet CreateResourceSheetController *createResourceSheetController;
IBOutlet ResourceDocument *document;
IBOutlet NSOutlineView *outlineView;
IBOutlet NSWindow *window;
NSMutableArray *resources;
}
@ -17,6 +17,6 @@
- (NSArray *)resources;
- (void)setResources:(NSMutableArray *)newResources;
- (void)addResource:(Resource *)resource;
- (void)generateTestData;
- (void)removeResource:(Resource *)resource;
@end

View File

@ -1,11 +1,18 @@
#import "ResourceDataSource.h"
#import "ResourceDocument.h"
#import "Resource.h"
NSString *DataSourceWillAddResourceNotification = @"DataSourceWillAddResourceNotification";
NSString *DataSourceDidAddResourceNotification = @"DataSourceDidAddResourceNotification";
NSString *DataSourceWillRemoveResourceNotification = @"DataSourceWillRemoveResourceNotification";
NSString *DataSourceDidRemoveResourceNotification = @"DataSourceDidRemoveResourceNotification";
@implementation ResourceDataSource
- (id)init
{
self = [super init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceDidChange:) name:ResourceChangedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceDidChange:) name:ResourceDidChangeNotification object:nil];
return self;
}
@ -39,23 +46,35 @@
- (void)addResource:(Resource *)resource
{
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:self, @"DataSource", resource, @"Resource", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:DataSourceWillAddResourceNotification object:dictionary];
// it seems very inefficient to reload the entire data source when just adding/removing one item
// for large resource files, the data source gets reloaded hundereds of times upon load
[resources addObject:resource];
[outlineView reloadData];
// [outlineView noteNumberOfRowsChanged]; // what is this for if it doesn't update the damn outliine view!
[[NSNotificationCenter defaultCenter] postNotificationName:DataSourceDidAddResourceNotification object:dictionary];
[[document undoManager] registerUndoWithTarget:self selector:@selector(removeResource:) object:resource];
}
- (void)removeResource:(Resource *)resource
{
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:self, @"DataSource", resource, @"Resource", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:DataSourceWillRemoveResourceNotification object:dictionary];
// see comments in addResource: about inefficiency of reloadData
[resources removeObjectIdenticalTo:resource];
[outlineView reloadData];
[[NSNotificationCenter defaultCenter] postNotificationName:DataSourceDidRemoveResourceNotification object:dictionary];
[[document undoManager] registerUndoWithTarget:self selector:@selector(addResource:) object:resource]; // NB: I hope the undo manager retains the resource, because it just got deleted :)
}
- (void)resourceDidChange:(NSNotification *)notification
{
[outlineView reloadData];
}
- (void)generateTestData
{
[self addResource:[Resource resourceOfType:@"____" andID:[NSNumber numberWithShort:-1] withName:@"underscore" andAttributes:[NSNumber numberWithUnsignedShort:0x8080]]];
[self addResource:[Resource resourceOfType:@"ÐÐÐÐ" andID:[NSNumber numberWithShort:0] withName:@"hyphen" andAttributes:[NSNumber numberWithUnsignedShort:0xFFFF] data:[NSData data] ofLength:[NSNumber numberWithUnsignedLong:1023]]];
[self addResource:[Resource resourceOfType:@"----" andID:[NSNumber numberWithShort:128] withName:@"minus" andAttributes:[NSNumber numberWithUnsignedShort:0xABCD] data:[NSData data] ofLength:[NSNumber numberWithUnsignedLong:12000]]];
[self addResource:[Resource resourceOfType:@"ÑÑÑÑ" andID:[NSNumber numberWithShort:32000] withName:@"en-dash" andAttributes:[NSNumber numberWithUnsignedShort:0x1234] data:[NSData data] ofLength:[NSNumber numberWithUnsignedLong:4096]]];
[self addResource:[Resource resourceOfType:@"****" andID:[NSNumber numberWithShort:-32000]]];
// reload the data for the changed resource
[outlineView reloadItem:[notification object]];
}
- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item
@ -84,6 +103,7 @@
- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
#pragma unused( outlineView )
NSString *identifier = [tableColumn identifier];
[item takeValue:object forKey:identifier];
}

View File

@ -1,6 +1,7 @@
#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h> // Actually I only need CarbonCore.framework
#import "ResourceDataSource.h"
@class ResourceDataSource;
@interface ResourceDocument : NSDocument
{
@ -20,6 +21,13 @@
- (IBAction)playSound:(id)sender;
- (void)sound:(NSSound *)sound didFinishPlaying:(BOOL)finished;
- (IBAction)clear:(id)sender;
- (void)resourceNameWillChange:(NSNotification *)notification;
- (void)resourceIDWillChange:(NSNotification *)notification;
- (void)resourceTypeWillChange:(NSNotification *)notification;
- (void)resourceAttributesWillChange:(NSNotification *)notification;
- (BOOL)readResourceMap:(SInt16)fileRefNum;
- (BOOL)writeResourceMap:(SInt16)fileRefNum;

View File

@ -1,5 +1,6 @@
#import "ResourceDocument.h"
#import "Resource.h"
#import "ResourceDataSource.h"
#import "ResourceNameCell.h"
#import "CreateResourceSheetController.h"
@ -17,6 +18,7 @@
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
if( otherFork )
DisposePtr( (Ptr) otherFork );
[resources release];
@ -44,6 +46,12 @@
[[outlineView tableColumnWithIdentifier:@"name"] setDataCell:resourceNameCell];
}
// register for resource will change notifications (for undo management)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceNameWillChange:) name:ResourceNameWillChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceIDWillChange:) name:ResourceIDWillChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceTypeWillChange:) name:ResourceTypeWillChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceAttributesWillChange:) name:ResourceAttributesWillChangeNotification object:nil];
// [[controller window] setResizeIncrements:NSMakeSize(1,18)];
// [controller setDocumet:self];
[dataSource setResources:resources];
@ -54,11 +62,26 @@
return [[NSUserDefaults standardUserDefaults] boolForKey:@"PreserveBackups"];
}
- (BOOL)validateMenuItem:(NSMenuItem *)item
{
Resource *resource = (Resource *) [outlineView itemAtRow:[outlineView selectedRow]];
if( [item action] == @selector(saveDocument:) ) return [self isDocumentEdited];
else if( [item action] == @selector(openResource:) ) return ([outlineView numberOfSelectedRows] == 1)? YES:NO;
else if( [item action] == @selector(openResourceAsHex:) ) return [outlineView numberOfSelectedRows]? YES:NO;
else if( [item action] == @selector(playSound:) ) return [[resource type] isEqualToString:@"snd "];
else if( [item action] == @selector(revertResourceToSaved:) ) return [resource isDirty];
else return [super validateMenuItem:item];
}
/*
- (BOOL)windowShouldClose:(NSWindow *)sender
{
if( [self isDocumentEdited] == NO ) return YES;
// document has been modified, so display save dialog and defer close
NSString *file = [[[sender representedFilename] lastPathComponent] stringByDeletingPathExtension];
if( [file isEqualToString:@""] ) file = @"this document";
NSBeginAlertSheet( @"Save Document?", @"Save", @"DonÕt Save", @"Cancel", sender, self, @selector(didEndShouldCloseSheet:returnCode:contextInfo:), NULL, sender, @"Do you wish to save %@?", file );
if( [file isEqualToString:@""] ) file = NSLocalizedString(@"this document", nil);
NSBeginAlertSheet( NSLocalizedString(@"Save Document?", nil), NSLocalizedString(@"Save", nil), NSLocalizedString(@"DonÕt Save", nil), NSLocalizedString(@"Cancel", nil), sender, self, @selector(didEndShouldCloseSheet:returnCode:contextInfo:), NULL, sender, NSLocalizedString(@"Do you wish to save %@?", nil), file );
return NO;
}
@ -78,7 +101,7 @@
NSLog( @"didEndShouldCloseSheet received NSAlertErrorReturn return code" );
}
// else returnCode == NSAlertOtherReturn, cancel
}
}*/
/* TOOLBAR MANAGMENT */
#pragma mark -
@ -114,9 +137,9 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
if( [itemIdentifier isEqual:RKCreateItemIdentifier] )
{
[item setLabel:@"Create"];
[item setPaletteLabel:@"Create"];
[item setToolTip:@"Create New Resource"];
[item setLabel:NSLocalizedString(@"Create", nil)];
[item setPaletteLabel:NSLocalizedString(@"Create", nil)];
[item setToolTip:NSLocalizedString(@"Create New Resource", nil)];
[item setImage:[NSImage imageNamed:@"Create"]];
[item setTarget:self];
[item setAction:@selector(showCreateResourceSheet:)];
@ -124,19 +147,19 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
}
else if( [itemIdentifier isEqual:RKDeleteItemIdentifier] )
{
[item setLabel:@"Delete"];
[item setPaletteLabel:@"Delete"];
[item setToolTip:@"Delete Selected Resource"];
[item setLabel:NSLocalizedString(@"Delete", nil)];
[item setPaletteLabel:NSLocalizedString(@"Delete", nil)];
[item setToolTip:NSLocalizedString(@"Delete Selected Resource", nil)];
[item setImage:[NSImage imageNamed:@"Delete"]];
[item setTarget:outlineView];
[item setTarget:self];
[item setAction:@selector(clear:)];
return item;
}
else if( [itemIdentifier isEqual:RKEditItemIdentifier] )
{
[item setLabel:@"Edit"];
[item setPaletteLabel:@"Edit"];
[item setToolTip:@"Edit Resource In Default Editor"];
[item setLabel:NSLocalizedString(@"Edit", nil)];
[item setPaletteLabel:NSLocalizedString(@"Edit", nil)];
[item setToolTip:NSLocalizedString(@"Edit Resource In Default Editor", nil)];
[item setImage:[NSImage imageNamed:@"Edit"]];
[item setTarget:self];
[item setAction:@selector(openResource:)];
@ -144,9 +167,9 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
}
else if( [itemIdentifier isEqual:RKEditHexItemIdentifier] )
{
[item setLabel:@"Edit Hex"];
[item setPaletteLabel:@"Edit Hex"];
[item setToolTip:@"Edit Resource As Hexadecimal"];
[item setLabel:NSLocalizedString(@"Edit Hex", nil)];
[item setPaletteLabel:NSLocalizedString(@"Edit Hex", nil)];
[item setToolTip:NSLocalizedString(@"Edit Resource As Hexadecimal", nil)];
[item setImage:[NSImage imageNamed:@"Edit Hex"]];
[item setTarget:self];
[item setAction:@selector(openResourceAsHex:)];
@ -154,9 +177,9 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
}
else if( [itemIdentifier isEqual:RKSaveItemIdentifier] )
{
[item setLabel:@"Save"];
[item setPaletteLabel:@"Save"];
[item setToolTip:[NSString stringWithFormat:@"Save To %@ Fork", !otherFork? @"Data":@"Resource"]];
[item setLabel:NSLocalizedString(@"Save", nil)];
[item setPaletteLabel:NSLocalizedString(@"Save", nil)];
[item setToolTip:[NSString stringWithFormat:NSLocalizedString(@"Save To %@ Fork", nil), !otherFork? NSLocalizedString(@"Data", nil) : NSLocalizedString(@"Resource", nil)]];
[item setImage:[NSImage imageNamed:@"Save"]];
[item setTarget:self];
[item setAction:@selector(saveDocument:)];
@ -164,9 +187,9 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
}
else if( [itemIdentifier isEqual:RKShowInfoItemIdentifier] )
{
[item setLabel:@"Show Info"];
[item setPaletteLabel:@"Show Info"];
[item setToolTip:@"Show Resource Information Window"];
[item setLabel:NSLocalizedString(@"Show Info", nil)];
[item setPaletteLabel:NSLocalizedString(@"Show Info", nil)];
[item setToolTip:NSLocalizedString(@"Show Resource Information Window", nil)];
[item setImage:[NSImage imageNamed:@"Show Info"]];
[item setTarget:[NSApp delegate]];
[item setAction:@selector(showInfo:)];
@ -220,14 +243,15 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
- (BOOL)validateToolbarItem:(NSToolbarItem *)item
{
BOOL valid = NO;
int selection = [outlineView numberOfSelectedRows];
NSString *identifier = [item itemIdentifier];
if( [identifier isEqual:RKCreateItemIdentifier] ) valid = YES;
// else if( [identifier isEqual:RKDeleteItemIdentifier] ) valid = [outlineView numberOfSelectedRows]? YES:NO;
else if( [identifier isEqual:RKEditItemIdentifier] ) valid = NO;
else if( [identifier isEqual:RKEditHexItemIdentifier] ) valid = [outlineView numberOfSelectedRows]? YES:NO;
else if( [identifier isEqual:RKSaveItemIdentifier] ) valid = [self isDocumentEdited];
else if( [identifier isEqual:NSToolbarPrintItemIdentifier] ) valid = YES;
if( [identifier isEqualToString:RKCreateItemIdentifier] ) valid = YES;
else if( [identifier isEqualToString:RKDeleteItemIdentifier] ) valid = selection? YES:NO;
else if( [identifier isEqualToString:RKEditItemIdentifier] ) valid = (selection == 1)? YES:NO;
else if( [identifier isEqualToString:RKEditHexItemIdentifier] ) valid = selection? YES:NO;
else if( [identifier isEqualToString:RKSaveItemIdentifier] ) valid = [self isDocumentEdited];
else if( [identifier isEqualToString:NSToolbarPrintItemIdentifier] ) valid = YES;
return valid;
}
@ -299,6 +323,82 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
NSLog( @"sound released" );
}
- (void)resourceNameWillChange:(NSNotification *)notification
{
// this saves the current resource's name so we can undo the change
Resource *resource = (Resource *) [notification object];
[[self undoManager] registerUndoWithTarget:resource selector:@selector(setName:) object:[[[resource name] copy] autorelease]];
[[self undoManager] setActionName:NSLocalizedString(@"Name Change", nil)];
}
- (void)resourceIDWillChange:(NSNotification *)notification
{
// this saves the current resource's ID number so we can undo the change
Resource *resource = (Resource *) [notification object];
[[self undoManager] registerUndoWithTarget:resource selector:@selector(setResID:) object:[[[resource resID] copy] autorelease]];
if( [[resource name] length] == 0 )
[[self undoManager] setActionName:NSLocalizedString(@"ID Change", nil)];
else [[self undoManager] setActionName:[NSString stringWithFormat:NSLocalizedString(@"ID Change for Ò%@Ó", nil), [resource name]]];
}
- (void)resourceTypeWillChange:(NSNotification *)notification
{
// this saves the current resource's type so we can undo the change
Resource *resource = (Resource *) [notification object];
[[self undoManager] registerUndoWithTarget:resource selector:@selector(setType:) object:[[[resource type] copy] autorelease]];
if( [[resource name] length] == 0 )
[[self undoManager] setActionName:NSLocalizedString(@"Type Change", nil)];
else [[self undoManager] setActionName:[NSString stringWithFormat:NSLocalizedString(@"Type Change for Ò%@Ó", nil), [resource name]]];
}
- (void)resourceAttributesWillChange:(NSNotification *)notification
{
// this saves the current state of the resource's attributes so we can undo the change
Resource *resource = (Resource *) [notification object];
[[self undoManager] registerUndoWithTarget:resource selector:@selector(setAttributes:) object:[[[resource attributes] copy] autorelease]];
if( [[resource name] length] == 0 )
[[self undoManager] setActionName:NSLocalizedString(@"Attributes Change", nil)];
else [[self undoManager] setActionName:[NSString stringWithFormat:NSLocalizedString(@"Attributes Change for Ò%@Ó", nil), [resource name]]];
}
/* EDIT OPERATIONS */
#pragma mark -
- (IBAction)clear:(id)sender
{
NSNumber *row;
Resource *resource;
NSMutableArray *selectedObjects = [NSMutableArray array];
NSEnumerator *enumerator = [outlineView selectedRowEnumerator];
int selectedRows = [outlineView numberOfSelectedRows];
// obtain array of selected resources
[[self undoManager] beginUndoGrouping];
while( row = [enumerator nextObject] )
{
[selectedObjects addObject:[outlineView itemAtRow:[row intValue]]];
}
// enumerate through array and delete resources
// i can't just delete resources above, because it screws with the enumeration!
enumerator = [selectedObjects reverseObjectEnumerator]; // reverse so an undo will replace items in original order
while( resource = [enumerator nextObject] )
{
[dataSource removeResource:resource];
if( [[resource name] length] == 0 )
[[self undoManager] setActionName:NSLocalizedString(@"Delete Resource", nil)];
else [[self undoManager] setActionName:[NSString stringWithFormat:NSLocalizedString(@"Delete Resource Ò%@Ó", nil), [resource name]]];
}
[[self undoManager] endUndoGrouping];
// generalise undo name if more than one was deleted
if( selectedRows > 1 )
[[self undoManager] setActionName:NSLocalizedString(@"Delete Resources", nil)];
// deselct resources (otherwise other resources move into selected rows!)
[outlineView deselectAll:self];
}
/* FILE HANDLING */
#pragma mark -
@ -368,11 +468,10 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
{
NSString *name = [NSString stringWithCString:&nameStr[1] length:nameStr[0]];
NSString *type = [NSString stringWithCString:(char *) &resType length:4];
NSNumber *size = [NSNumber numberWithLong:sizeLong];
NSNumber *resID = [NSNumber numberWithShort:resIDShort];
NSNumber *attributes = [NSNumber numberWithShort:attrsShort];
NSData *data = [NSData dataWithBytes:*resourceHandle length:sizeLong];
Resource *resource = [Resource resourceOfType:type andID:resID withName:name andAttributes:attributes data:data ofLength:size];
Resource *resource = [Resource resourceOfType:type andID:resID withName:name andAttributes:attributes data:data];
[resources addObject:resource]; // array retains resource
}
@ -438,9 +537,8 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
Str255 nameStr;
ResType resType;
short resIDShort = [[resource resID] shortValue];
long sizeLong = [[resource size] longValue];
short attrsShort = [[resource attributes] shortValue];
Handle resourceHandle = NewHandleClear( sizeLong );
Handle resourceHandle = NewHandleClear( [[resource data] length] );
nameStr[0] = [[resource name] cStringLength];
BlockMoveData( [[resource name] cString], &nameStr[1], nameStr[0] );
@ -454,7 +552,7 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
AddResource( resourceHandle, resType, resIDShort, nameStr );
if( ResError() == addResFailed )
{
NSLog( @"*Saving failed*; could not add resource \"%@\" of type %@ to file.", [resource name], [resource type] );
NSLog( @"*Saving failed*; could not add resource ID %@ of type %@ to file.", [resource resID], [resource type] );
error = addResFailed;
}
else

View File

@ -24,19 +24,19 @@
switch( power )
{
case 0:
[string appendFormat:@"%.0f", value];
[string appendFormat:NSLocalizedString(@"%.0f", nil), value];
break;
case 10:
[string appendFormat:@"%.1f KB", value];
[string appendFormat:NSLocalizedString(@"%.1f KB", nil), value];
break;
case 20:
[string appendFormat:@"%.1f MB", value];
[string appendFormat:NSLocalizedString(@"%.1f MB", nil), value];
break;
default:
[string appendFormat:@"%.1f GB", value];
[string appendFormat:NSLocalizedString(@"%.1f GB", nil), value];
break;
}
return string;

View File

@ -8,11 +8,20 @@
},
{
ACTIONS = {
deselectAll = id;
findNext = id;
findPrevious = id;
findWithSelection = id;
openResource = id;
openResourceAsHex = id;
openResourceTemplate = id;
openResourceWithOtherTemplate = id;
playSound = id;
revertResourceToSaved = id;
scrollToSelection = id;
showAbout = id;
showCreateResourceSheet = id;
showFind = id;
showInfo = id;
showPrefs = id;
};

View File

@ -3,18 +3,14 @@
<plist version="0.9">
<dict>
<key>IBDocumentLocation</key>
<string>249 101 432 426 0 0 1024 746 </string>
<string>526 134 432 426 0 0 1280 1002 </string>
<key>IBEditorPositions</key>
<dict>
<key>29</key>
<string>56 391 347 44 0 0 1024 746 </string>
<string>77 534 347 44 0 0 1280 1002 </string>
</dict>
<key>IBFramework Version</key>
<string>248.0</string>
<key>IBOpenObjects</key>
<array>
<integer>29</integer>
</array>
<key>IBSystem Version</key>
<string>5P48</string>
</dict>

Binary file not shown.

View File

@ -2,5 +2,5 @@
CFBundleName = "ResKnife";
CFBundleShortVersionString = "Development Version";
CFBundleGetInfoString = "ResKnife 0.4d3, Copyright 2001 Nicholas Shanks.";
NSHumanReadableCopyright = "Copyright © 2001 Nicholas Shanks.";
CFBundleGetInfoString = "ResKnife 0.4d3, Copyright 2001-2 Nicholas Shanks.";
NSHumanReadableCopyright = "Copyright © 2001-2 Nicholas Shanks.";

Binary file not shown.

View File

@ -1,5 +1,54 @@
/* Localized versions of application-critical strings */
/* File window default resource names */
/* Save sheet contents */
"Save Document?" = "Save Document?";
"Do you wish to save %@?" = "Do you wish to save %@?";
"this document" = "this document";
"Save" = "Save";
"DonÕt Save" = "DonÕt Save";
"Cancel" = "Cancel";
/* File window default (grey) resource names */
"Untitled Resource" = "Untitled Resource";
"Custom Icon" = "Custom Icon";
/* Resource size indicators */
"%.0f" = "%.0f";
"%.1f KB" = "%.1f KB";
"%.1f MB" = "%.1f MB";
"%.1f GB" = "%.1f GB";
/* Toolbar names and tooltips */
"Create" = "Create";
"Create New Resource" = "Create New Resource";
"Delete" = "Delete";
"Delete Selected Resource" = "Delete Selected Resource";
"Edit" = "Edit";
"Edit Resource In Default Editor" = "Edit Resource In Default Editor";
"Edit Hex" = "Edit Hex";
"Edit Resource As Hexadecimal" = "Edit Resource As Hexadecimal";
"Save" = "Save";
"Save To %@ Fork" = "Save To %@ Fork";
"Data" = "Data";
"Resource" = "Resource";
"Show Info" = "Show Info";
"Show Resource Information Window" = "Show Resource Information Window";
/* Undo/Redo menu item titles */
"Add Resource" = "Add Resource";
"Add Resource Ò%@Ó" = "Add Resource Ò%@Ó";
"Create Resource" = "Create Resource";
"Create Resource Ò%@Ó" = "Create Resource Ò%@Ó";
"Remove Resource" = "Remove Resource";
"Remove Resource Ò%@Ó" = "Remove Resource Ò%@Ó";
"Delete Resource" = "Delete Resource";
"Delete Resource Ò%@Ó" = "Delete Resource Ò%@Ó";
"Name Change" = "Name Change";
"ID Change" = "ID Change";
"ID Change for Ò%@Ó" = "ID Change for Ò%@Ó";
"Type Change" = "Type Change";
"Type Change for Ò%@Ó" = "Type Change for Ò%@Ó";
"Attributes Change" = "Attributes Change";
"Attributes Change for Ò%@Ó" = "Attributes Change for Ò%@Ó";
"Edit Resource" = "Edit Resource";
"Edit of Ò%@Ó" = "Edit of Ò%@Ó";

View File

@ -10,15 +10,16 @@
CLASS = CreateResourceSheetController;
LANGUAGE = ObjC;
OUTLETS = {
attributesMatrix = id;
cancelButton = id;
createButton = id;
dataSource = id;
nameView = id;
parent = id;
resIDView = id;
typePopup = id;
typeView = id;
attributesMatrix = NSMatrix;
cancelButton = NSButton;
createButton = NSButton;
dataSource = ResourceDataSource;
document = ResourceDocument;
nameView = NSTextField;
parent = NSWindow;
resIDView = NSTextField;
typePopup = NSPopUpButton;
typeView = NSTextField;
};
SUPERCLASS = NSWindowController;
},
@ -38,7 +39,12 @@
{
CLASS = ResourceDataSource;
LANGUAGE = ObjC;
OUTLETS = {createResourceSheetController = id; outlineView = id; window = id; };
OUTLETS = {
createResourceSheetController = CreateResourceSheetController;
document = ResourceDocument;
outlineView = NSOutlineView;
window = NSWindow;
};
SUPERCLASS = NSObject;
},
{

View File

@ -3,7 +3,7 @@
<plist version="0.9">
<dict>
<key>IBDocumentLocation</key>
<string>104 127 480 547 0 0 1024 746 </string>
<string>153 217 480 547 0 0 1280 1002 </string>
<key>IBFramework Version</key>
<string>248.0</string>
<key>IBSystem Version</key>

View File

@ -6,6 +6,7 @@
LANGUAGE = ObjC;
OUTLETS = {
ascii = NSTextView;
controller = HexWindowController;
hex = NSTextView;
message = NSTextField;
offset = NSTextView;

View File

@ -0,0 +1,17 @@
#import <Cocoa/Cocoa.h>
@interface FindSheetController : NSWindowController
{
IBOutlet NSButton *cancelButton;
IBOutlet NSButton *findNextButton;
IBOutlet NSForm *form;
IBOutlet NSButton *replaceAllButton;
IBOutlet NSButton *replaceFindNextButton;
}
- (IBAction)findNext:(id)sender;
- (IBAction)hideWindow:(id)sender;
- (IBAction)replaceAll:(id)sender;
- (IBAction)replaceFindNext:(id)sender;
@end

View File

@ -0,0 +1,21 @@
#import "FindSheetController.h"
@implementation FindSheetController
- (IBAction)findNext:(id)sender
{
}
- (IBAction)hideWindow:(id)sender
{
}
- (IBAction)replaceAll:(id)sender
{
}
- (IBAction)replaceFindNext:(id)sender
{
}
@end

View File

@ -1,7 +1,12 @@
#import <Cocoa/Cocoa.h>
#import "ResKnifeResourceProtocol.h"
@class HexWindowController;
@interface HexEditorDelegate : NSObject
{
IBOutlet HexWindowController *controller;
IBOutlet NSTextView *ascii;
IBOutlet NSTextView *hex;
IBOutlet NSTextView *offset;

View File

@ -1,4 +1,5 @@
#import "HexEditorDelegate.h"
#import "HexWindowController.h"
/* Ideas, method names, and occasionally code stolen from HexEditor by Raphael Sebbe http://raphaelsebbe.multimania.com/ */
@ -117,6 +118,31 @@
/* delegation methods */
- (BOOL)textView:(NSTextView *)textView shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString;
{
#warning Every time a character is typed or string pasted, the entire resource is duplicated, operated on and disposed of! Perhaps I could do this in a better way?
unsigned char *buffer;
NSMutableData *data = [NSMutableData dataWithData:[controller data]];
NSMutableData *newData = [NSMutableData dataWithBytes:[replacementString cString] length:[replacementString cStringLength]];
NSRange range;
NSLog( @"Delegate received:\ntextView: shouldChangeTextInRange:%@ replacementString:%@", NSStringFromRange(affectedCharRange), replacementString );
if( textView == hex ) range = [self byteRangeFromHexRange:affectedCharRange];
else if( textView == ascii ) range = [self byteRangeFromAsciiRange:affectedCharRange];
else return YES;
#warning Does not cater for delete, forward delete, etc.
buffer = malloc( [newData length] );
[newData getBytes:buffer];
[data replaceBytesInRange:range withBytes:buffer];
free(buffer);
// update resource data - this causes a notification to be sent out, which the plug receives and acts upon to update the text views
[(id <ResKnifeResourceProtocol>)[controller resource] setData:data];
return NO;
}
- (NSRange)textView:(NSTextView *)textView willChangeSelectionFromCharacterRange:(NSRange)oldSelectedCharRange toCharacterRange:(NSRange)newSelectedCharRange
{
NSRange hexRange, asciiRange, byteRange = NSMakeRange(0,0);
@ -148,6 +174,8 @@
return newSelectedCharRange;
}
/* range conversion methods */
- (NSRange)byteRangeFromHexRange:(NSRange)hexRange;
{
// valid for all window widths
@ -192,15 +220,6 @@
return asciiRange;
}
- (BOOL)textView:(NSTextView *)textView shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString;
{
if( textView == hex ) // we're editing in hexadecimal constrain to 0-9, A-F
{
return YES;
}
else return YES; // we're editing in ASCII
}
- (NSTextView *)hex
{
return hex;

View File

@ -1,8 +1,5 @@
#import <Cocoa/Cocoa.h>
#import "HexEditorDelegate.h"
#import "HexWindowController.h"
#import "ResKnifeResourceProtocol.h"
@interface HexTextView : NSTextView
{

View File

@ -2,21 +2,13 @@
@implementation HexTextView
- (void)insertText:(id)insertString
- (id)init
{
#warning Every time a character is typed or string pasted, the entire resource is duplicated, operated on and disposed of! Perhaps I could do this in a better way?
NSMutableData *newData = [NSMutableData dataWithData:[[[self window] windowController] data]];
NSRange selection = [self selectedRange];
if( self == (id) [[self delegate] hex] )
selection = [[self delegate] byteRangeFromHexRange:selection];
else if( self == (id) [[self delegate] ascii] )
selection = [[self delegate] byteRangeFromAsciiRange:selection];
self = [super init];
if( !self ) return self;
NSLog( insertString );
// modify resource data
// update resource data - this causes a notification to be sent out, which the plug receives and acts upon to update the text views
[(id <ResKnifeResourceProtocol>)[[[self window] windowController] resource] setData:newData];
[self setFieldEditor:YES];
return self;
}
- (void)setSelectedRange:(NSRange)charRange affinity:(NSSelectionAffinity)affinity stillSelecting:(BOOL)flag

View File

@ -21,7 +21,7 @@
// normal methods
- (void)viewDidScroll:(NSNotification *)notification;
- (void)resourceDidChange:(NSNotification *)notification;
- (void)resourceDataDidChange:(NSNotification *)notification;
- (void)refreshData:(NSData *)data;
// accessors

View File

@ -2,7 +2,19 @@
@implementation HexWindowController
NSString *ResourceChangedNotification = @"ResourceChangedNotification";
NSString *ResourceWillChangeNotification = @"ResourceWillChangeNotification";
NSString *ResourceNameWillChangeNotification = @"ResourceNameWillChangeNotification";
NSString *ResourceTypeWillChangeNotification = @"ResourceTypeWillChangeNotification";
NSString *ResourceIDWillChangeNotification = @"ResourceIDWillChangeNotification";
NSString *ResourceAttributesWillChangeNotification = @"ResourceAttributesWillChangeNotification";
NSString *ResourceDataWillChangeNotification = @"ResourceDataWillChangeNotification";
NSString *ResourceNameDidChangeNotification = @"ResourceNameDidChangeNotification";
NSString *ResourceTypeDidChangeNotification = @"ResourceTypeDidChangeNotification";
NSString *ResourceIDDidChangeNotification = @"ResourceIDDidChangeNotification";
NSString *ResourceAttributesDidChangeNotification = @"ResourceAttributesDidChangeNotification";
NSString *ResourceDataDidChangeNotification = @"ResourceDataDidChangeNotification";
NSString *ResourceDidChangeNotification = @"ResourceDidChangeNotification";
+ (void)initialize
{
@ -39,8 +51,8 @@ NSString *ResourceChangedNotification = @"ResourceChangedNotification";
// swap text views to instances of my class instead
// An experianced NeXT programmer told me that poseAsClass would come back to bite me in the ass at some point, and that I should instead instanciate some HexTextViews and swap them in for now, and use IB do do things properly once IB is fixed. But, for now I think I'll not bother :-P
// we don't want this notification until we have a window!
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceDidChange:) name:ResourceChangedNotification object:nil];
// we don't want this notification until we have a window! (Only register for notifications on the resource we're editing)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceDataDidChange:) name:ResourceDataDidChangeNotification object:resource];
// put other notifications here too, just for togetherness
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidScroll:) name:NSViewBoundsDidChangeNotification object:[[offset enclosingScrollView] contentView]];
@ -93,9 +105,9 @@ NSString *ResourceChangedNotification = @"ResourceChangedNotification";
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidScroll:) name:NSViewBoundsDidChangeNotification object:asciiClip];
}
- (void)resourceDidChange:(NSNotification *)notification
- (void)resourceDataDidChange:(NSNotification *)notification
{
// see if it's our resource which got changed (we receive notifications for any resource being changed, allowing multi-resource editors)
// ensure it's our resource which got changed (should always be true, we don't register for other resource notifications)
if( [notification object] == resource )
[self refreshData:[(id <ResKnifeResourceProtocol>)resource data]];
}

View File

@ -4,22 +4,33 @@
@protocol ResKnifeResourceProtocol
- (BOOL)isDirty;
- (NSString *)name;
- (void)setName:(NSString *)newName;
- (NSString *)type;
- (void)setType:(NSString *)newType;
- (NSNumber *)resID;
- (void)setResID:(NSNumber *)newResID;
- (NSNumber *)size;
- (void)setSize:(NSNumber *)newSize;
- (NSNumber *)attributes;
- (void)setAttributes:(NSNumber *)newAttributes;
- (BOOL)dirty;
- (void)setDirty:(BOOL)newValue; // bug: may not be around forever
- (NSNumber *)size;
- (NSData *)data;
- (void)setData:(NSData *)newData;
@end
// Resource notifications
extern NSString *ResourceChangedNotification; // Note: when using internal notifications in your own plug-in, DO NOT use [NSNotificationCenter defaultCenter]. This is an application-wide notificaton center, use of it by plug-ins for their own means (i.e. not interacting with ResKnife) can cause conflicts with other plug-ins. You should create your own notification center and post to that.
// Note: when using internal notifications in your own plug-in, DO NOT use [NSNotificationCenter defaultCenter]. This is an application-wide notificaton center, use of it by plug-ins for their own means (i.e. not interacting with ResKnife) can cause conflicts with other plug-ins. You should create your own notification center and post to that.
extern NSString *ResourceWillChangeNotification;
extern NSString *ResourceNameWillChangeNotification;
extern NSString *ResourceTypeWillChangeNotification;
extern NSString *ResourceIDWillChangeNotification;
extern NSString *ResourceAttributesWillChangeNotification;
extern NSString *ResourceDataWillChangeNotification;
extern NSString *ResourceNameDidChangeNotification;
extern NSString *ResourceTypeDidChangeNotification;
extern NSString *ResourceIDDidChangeNotification;
extern NSString *ResourceAttributesDidChangeNotification;
extern NSString *ResourceDataDidChangeNotification;
extern NSString *ResourceDidChangeNotification;

View File

@ -23,6 +23,49 @@
settings = {
};
};
F54E6220021B6A0801A80001 = {
isa = PBXFileReference;
path = FindSheetController.h;
refType = 4;
};
F54E6221021B6A0801A80001 = {
isa = PBXFileReference;
path = FindSheetController.m;
refType = 4;
};
F54E6222021B6A0801A80001 = {
children = (
F54E6223021B6A0801A80001,
);
isa = PBXVariantGroup;
name = FindSheet.nib;
path = "";
refType = 4;
};
F54E6223021B6A0801A80001 = {
isa = PBXFileReference;
name = English;
path = English.lproj/FindSheet.nib;
refType = 4;
};
F54E6224021B6A0901A80001 = {
fileRef = F54E6220021B6A0801A80001;
isa = PBXBuildFile;
settings = {
};
};
F54E6225021B6A0901A80001 = {
fileRef = F54E6222021B6A0801A80001;
isa = PBXBuildFile;
settings = {
};
};
F54E6226021B6A0901A80001 = {
fileRef = F54E6221021B6A0801A80001;
isa = PBXBuildFile;
settings = {
};
};
F5502C3301C5586301C57124 = {
fileRef = F5B5884B0156D40B01000001;
isa = PBXBuildFile;
@ -238,6 +281,7 @@
F5EF83AA020C08E601A80001,
F5EF83AB020C08E601A80001,
F5EF83AD020C08E601A80001,
F54E6224021B6A0901A80001,
);
isa = PBXHeadersBuildPhase;
name = Headers;
@ -247,6 +291,7 @@
files = (
F5EF83AF020C08E601A80001,
F5EF83C9020C20D801A80001,
F54E6225021B6A0901A80001,
);
isa = PBXResourcesBuildPhase;
name = "Bundle Resources";
@ -257,6 +302,7 @@
F5EF83B0020C08E601A80001,
F5EF83B1020C08E601A80001,
F5EF83B3020C08E601A80001,
F54E6226021B6A0901A80001,
);
isa = PBXSourcesBuildPhase;
name = Sources;
@ -2405,6 +2451,8 @@
};
F5EF839F020C08E601A80001 = {
children = (
F54E6220021B6A0801A80001,
F54E6221021B6A0801A80001,
F5EF83A0020C08E601A80001,
F5EF83A1020C08E601A80001,
F5EF83A2020C08E601A80001,
@ -2412,6 +2460,7 @@
F5EF83A7020C08E601A80001,
F5EF83A8020C08E601A80001,
F5EF83C7020C20D701A80001,
F54E6222021B6A0801A80001,
F5EF83A9020C08E601A80001,
);
isa = PBXGroup;