mirror of
https://github.com/nickshanks/ResKnife.git
synced 2024-09-29 09:54:50 +00:00
Added toolbar to ResKnife, fixed HexEditor selection bugs.
This commit is contained in:
parent
85b7550e17
commit
734fad59e5
@ -1,8 +1,6 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "ResKnifeResourceProtocol.h"
|
||||
|
||||
extern NSString *ResourceChangedNotification;
|
||||
|
||||
@interface Resource : NSObject <ResKnifeResourceProtocol>
|
||||
{
|
||||
@private
|
||||
|
@ -12,6 +12,8 @@
|
||||
HFSUniStr255 *otherFork; // name of fork to save to if not using data fork (usually 'RESOURCE_FORK' as returned from FSGetResourceForkName() -- ignored if saveToDataFork is YES )
|
||||
}
|
||||
|
||||
- (void)setupToolbar:(NSWindowController *)controller;
|
||||
|
||||
- (BOOL)readResourceMap:(SInt16)fileRefNum;
|
||||
- (BOOL)writeResourceMap:(SInt16)fileRefNum;
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* WINDOW DELEGATION */
|
||||
|
||||
- (NSString *)windowNibName
|
||||
{
|
||||
// Override returning the nib file name of the document
|
||||
@ -30,6 +32,7 @@
|
||||
{
|
||||
[super windowControllerDidLoadNib:controller];
|
||||
// Add any code here that need to be executed once the windowController has loaded the document's window.
|
||||
[self setupToolbar:controller];
|
||||
// [controller setDocumet:self];
|
||||
[dataSource setResources:resources];
|
||||
}
|
||||
@ -65,6 +68,145 @@
|
||||
// else returnCode == NSAlertAlternateReturn, cancel
|
||||
}
|
||||
|
||||
/* TOOLBAR MANAGMENT */
|
||||
|
||||
static NSString *RKToolbarIdentifier = @"com.nickshanks.resknife.toolbar";
|
||||
static NSString *RKSaveItemIdentifier = @"com.nickshanks.resknife.toolbar.save";
|
||||
|
||||
- (void)setupToolbar:(NSWindowController *)controller
|
||||
{
|
||||
/* This routine should become invalid once toolbars are integrated into nib files */
|
||||
|
||||
NSToolbar *toolbar = [[[NSToolbar alloc] initWithIdentifier:RKToolbarIdentifier] autorelease];
|
||||
|
||||
// set toolbar properties
|
||||
[toolbar setVisible:NO];
|
||||
[toolbar setAutosavesConfiguration:YES];
|
||||
[toolbar setAllowsUserCustomization:YES];
|
||||
[toolbar setDisplayMode:NSToolbarDisplayModeDefault];
|
||||
|
||||
// attach toolbar to window
|
||||
[toolbar setDelegate:self];
|
||||
[[controller window] setToolbar:toolbar];
|
||||
}
|
||||
|
||||
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
|
||||
{
|
||||
if( [itemIdentifier isEqual:RKSaveItemIdentifier] )
|
||||
{
|
||||
NSToolbarItem *item = [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier] autorelease];
|
||||
[item setLabel:@"Save"];
|
||||
[item setPaletteLabel:@"Save"];
|
||||
[item setToolTip:[NSString stringWithFormat:@"Save To %@ Fork", saveToDataFork? @"Data":@"Resource"]];
|
||||
[item setImage:[NSImage imageNamed:@"Save"]];
|
||||
[item setTarget:self];
|
||||
[item setAction:@selector(saveDocument:)];
|
||||
return item;
|
||||
}
|
||||
else return nil;
|
||||
/* // Required delegate method Given an item identifier, self method returns an item
|
||||
// The toolbar will use self method to obtain toolbar items that can be displayed in the customization sheet, or in the toolbar itself
|
||||
NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier] autorelease];
|
||||
|
||||
if ([itemIdent isEqual: SaveDocToolbarItemIdentifier]) {
|
||||
// Set the text label to be displayed in the toolbar and customization palette
|
||||
[toolbarItem setLabel: @"Save"];
|
||||
[toolbarItem setPaletteLabel: @"Save"];
|
||||
|
||||
// Set up a reasonable tooltip, and image Note, these aren't localized, but you will likely want to localize many of the item's properties
|
||||
[toolbarItem setToolTip: @"Save Your Document"];
|
||||
[toolbarItem setImage: [NSImage imageNamed: @"SaveDocumentItemImage"]];
|
||||
|
||||
// Tell the item what message to send when it is clicked
|
||||
[toolbarItem setTarget: self];
|
||||
[toolbarItem setAction: @selector(saveDocument:)];
|
||||
} else if([itemIdent isEqual: SearchDocToolbarItemIdentifier]) {
|
||||
NSMenu *submenu = nil;
|
||||
NSMenuItem *submenuItem = nil, *menuFormRep = nil;
|
||||
|
||||
// Set up the standard properties
|
||||
[toolbarItem setLabel: @"Search"];
|
||||
[toolbarItem setPaletteLabel: @"Search"];
|
||||
[toolbarItem setToolTip: @"Search Your Document"];
|
||||
|
||||
// Use a custom view, a text field, for the search item
|
||||
[toolbarItem setView: searchFieldOutlet];
|
||||
[toolbarItem setMinSize:NSMakeSize(30, NSHeight([searchFieldOutlet frame]))];
|
||||
[toolbarItem setMaxSize:NSMakeSize(400,NSHeight([searchFieldOutlet frame]))];
|
||||
|
||||
// By default, in text only mode, a custom items label will be shown as disabled text, but you can provide a
|
||||
// custom menu of your own by using <item> setMenuFormRepresentation]
|
||||
submenu = [[[NSMenu alloc] init] autorelease];
|
||||
submenuItem = [[[NSMenuItem alloc] initWithTitle: @"Search Panel" action: @selector(searchUsingSearchPanel:) keyEquivalent: @""] autorelease];
|
||||
menuFormRep = [[[NSMenuItem alloc] init] autorelease];
|
||||
|
||||
[submenu addItem: submenuItem];
|
||||
[submenuItem setTarget: self];
|
||||
[menuFormRep setSubmenu: submenu];
|
||||
[menuFormRep setTitle: [toolbarItem label]];
|
||||
[toolbarItem setMenuFormRepresentation: menuFormRep];
|
||||
} else {
|
||||
// itemIdent refered to a toolbar item that is not provide or supported by us or cocoa
|
||||
// Returning nil will inform the toolbar self kind of item is not supported
|
||||
toolbarItem = nil;
|
||||
}
|
||||
return toolbarItem;*/
|
||||
}
|
||||
|
||||
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar
|
||||
{
|
||||
return [NSArray arrayWithObjects:RKSaveItemIdentifier, NSToolbarPrintItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier, NSToolbarCustomizeToolbarItemIdentifier, nil];
|
||||
}
|
||||
|
||||
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
|
||||
{
|
||||
return [NSArray arrayWithObjects:RKSaveItemIdentifier, NSToolbarPrintItemIdentifier, NSToolbarCustomizeToolbarItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier, NSToolbarSpaceItemIdentifier, NSToolbarSeparatorItemIdentifier, nil];
|
||||
}
|
||||
/*
|
||||
- (void) toolbarWillAddItem: (NSNotification *) notif {
|
||||
// Optional delegate method Before an new item is added to the toolbar, self notification is posted
|
||||
// self is the best place to notice a new item is going into the toolbar For instance, if you need to
|
||||
// cache a reference to the toolbar item or need to set up some initial state, self is the best place
|
||||
// to do it The notification object is the toolbar to which the item is being added The item being
|
||||
// added is found by referencing the @"item" key in the userInfo
|
||||
NSToolbarItem *addedItem = [[notif userInfo] objectForKey: @"item"];
|
||||
if([[addedItem itemIdentifier] isEqual: SearchDocToolbarItemIdentifier]) {
|
||||
activeSearchItem = [addedItem retain];
|
||||
[activeSearchItem setTarget: self];
|
||||
[activeSearchItem setAction: @selector(searchUsingToolbarTextField:)];
|
||||
} else if ([[addedItem itemIdentifier] isEqual: NSToolbarPrintItemIdentifier]) {
|
||||
[addedItem setToolTip: @"Print Your Document"];
|
||||
[addedItem setTarget: self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) toolbarDidRemoveItem: (NSNotification *) notif {
|
||||
// Optional delegate method After an item is removed from a toolbar the notification is sent self allows
|
||||
// the chance to tear down information related to the item that may have been cached The notification object
|
||||
// is the toolbar to which the item is being added The item being added is found by referencing the @"item"
|
||||
// key in the userInfo
|
||||
NSToolbarItem *removedItem = [[notif userInfo] objectForKey: @"item"];
|
||||
if (removedItem==activeSearchItem) {
|
||||
[activeSearchItem autorelease];
|
||||
activeSearchItem = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) validateToolbarItem: (NSToolbarItem *) toolbarItem {
|
||||
// Optional method self message is sent to us since we are the target of some toolbar item actions
|
||||
// (for example: of the save items action)
|
||||
BOOL enable = NO;
|
||||
if ([[toolbarItem itemIdentifier] isEqual: SaveDocToolbarItemIdentifier]) {
|
||||
// We will return YES (ie the button is enabled) only when the document is dirty and needs saving
|
||||
enable = [self isDocumentEdited];
|
||||
} else if ([[toolbarItem itemIdentifier] isEqual: NSToolbarPrintItemIdentifier]) {
|
||||
enable = YES;
|
||||
}
|
||||
return enable;
|
||||
}*/
|
||||
|
||||
/* FILE HANDLING */
|
||||
|
||||
- (BOOL)readFromFile:(NSString *)fileName ofType:(NSString *)type
|
||||
{
|
||||
BOOL succeeded = NO;
|
||||
@ -234,6 +376,8 @@
|
||||
return error? NO:YES;
|
||||
}
|
||||
|
||||
/* ACCESSORS */
|
||||
|
||||
- (NSOutlineView *)outlineView
|
||||
{
|
||||
return outlineView;
|
||||
|
@ -5,12 +5,18 @@
|
||||
IBOutlet NSTextView *ascii;
|
||||
IBOutlet NSTextView *hex;
|
||||
IBOutlet NSTextView *offset;
|
||||
IBOutlet NSTextField *message;
|
||||
}
|
||||
|
||||
- (NSString *)offsetRepresentation:(NSData *)data;
|
||||
- (NSString *)hexRepresentation:(NSData *)data;
|
||||
- (NSString *)asciiRepresentation:(NSData *)data;
|
||||
|
||||
- (NSRange)byteRangeFromHexRange:(NSRange)hexRange;
|
||||
- (NSRange)hexRangeFromByteRange:(NSRange)byteRange;
|
||||
- (NSRange)byteRangeFromAsciiRange:(NSRange)asciiRange;
|
||||
- (NSRange)asciiRangeFromByteRange:(NSRange)byteRange;
|
||||
|
||||
- (NSTextView *)hex;
|
||||
- (NSTextView *)ascii;
|
||||
|
||||
|
@ -6,17 +6,16 @@
|
||||
|
||||
- (NSString *)offsetRepresentation:(NSData *)data;
|
||||
{
|
||||
int row;
|
||||
int rows = ([data length] / 16) + (([data length] % 16)? 1:0);
|
||||
int row, dataLength = [data length];
|
||||
int rows = (dataLength / 16) + ((dataLength % 16)? 1:0);
|
||||
NSMutableString *representation = [NSMutableString string];
|
||||
|
||||
for( row = 0; row < rows; row++ )
|
||||
{
|
||||
[representation appendFormat:@"%08lX:\n", row * 16];
|
||||
}
|
||||
|
||||
// remove last character (the return on the end)
|
||||
[representation deleteCharactersInRange:NSMakeRange([representation length] -1, 1)];
|
||||
if( dataLength % 16 != 0 )
|
||||
[representation deleteCharactersInRange:NSMakeRange([representation length] -1, 1)];
|
||||
|
||||
return representation;
|
||||
}
|
||||
@ -63,7 +62,7 @@
|
||||
|
||||
// append buffer to representation
|
||||
[representation appendString:[NSString stringWithCString:buffer]];
|
||||
if( currentByte != dataLength )
|
||||
if( currentByte != dataLength || dataLength % 16 == 0 )
|
||||
[representation appendString:@"\n"];
|
||||
}
|
||||
|
||||
@ -104,7 +103,7 @@
|
||||
|
||||
// append buffer to representation
|
||||
[representation appendString:[NSString stringWithCString:buffer]];
|
||||
if( currentByte != dataLength )
|
||||
if( currentByte != dataLength || dataLength % 16 == 0 )
|
||||
[representation appendString:@"\n"];
|
||||
}
|
||||
|
||||
@ -115,7 +114,7 @@
|
||||
|
||||
- (NSRange)textView:(NSTextView *)textView willChangeSelectionFromCharacterRange:(NSRange)oldSelectedCharRange toCharacterRange:(NSRange)newSelectedCharRange
|
||||
{
|
||||
NSRange hexRange, asciiRange;
|
||||
NSRange hexRange, asciiRange, byteRange = NSMakeRange(0,0);
|
||||
|
||||
// temporarilly removing the delegate stops this function being called recursivly!
|
||||
id oldDelegate = [hex delegate];
|
||||
@ -124,42 +123,70 @@
|
||||
|
||||
if( textView == hex ) // we're selecting hexadecimal
|
||||
{
|
||||
if( newSelectedCharRange.length == 0 ) // moving insertion point
|
||||
{
|
||||
asciiRange = NSMakeRange( newSelectedCharRange.location /3, 0 );
|
||||
}
|
||||
else // dragging a selection
|
||||
{
|
||||
int numReturns = (newSelectedCharRange.length /47) + (newSelectedCharRange.location % 47? 1:0);
|
||||
asciiRange = NSMakeRange( newSelectedCharRange.location /3, (newSelectedCharRange.length+1) /3 );
|
||||
}
|
||||
NSLog( @"hex selection changed from %@ to %@", NSStringFromRange(oldSelectedCharRange), NSStringFromRange(newSelectedCharRange) );
|
||||
NSLog( @"changing ascii selection to %@", NSStringFromRange(asciiRange) );
|
||||
byteRange = [self byteRangeFromHexRange:newSelectedCharRange];
|
||||
asciiRange = [self asciiRangeFromByteRange:byteRange];
|
||||
[ascii setSelectedRange:asciiRange];
|
||||
}
|
||||
else if( textView == ascii ) // we're selecting ASCII
|
||||
{
|
||||
|
||||
if( newSelectedCharRange.length == 0 ) // moving insertion point
|
||||
{
|
||||
hexRange = NSMakeRange( newSelectedCharRange.location *3, 0 );
|
||||
}
|
||||
else // dragging a selection
|
||||
{
|
||||
int numReturns = (newSelectedCharRange.length /17) + (newSelectedCharRange.location % 17? 1:0);
|
||||
hexRange = NSMakeRange( (newSelectedCharRange.location - numReturns) *3 + numReturns, ((newSelectedCharRange.length - numReturns) *3) -1 );
|
||||
}
|
||||
NSLog( @"ascii selection changed from %@ to %@", NSStringFromRange(oldSelectedCharRange), NSStringFromRange(newSelectedCharRange) );
|
||||
NSLog( @"changing hex selection to %@", NSStringFromRange(hexRange) );
|
||||
|
||||
byteRange = [self byteRangeFromAsciiRange:newSelectedCharRange];
|
||||
hexRange = [self hexRangeFromByteRange:byteRange];
|
||||
[hex setSelectedRange:hexRange];
|
||||
}
|
||||
else NSLog( @"What the hell are you selecting?" );
|
||||
|
||||
// put the new selection into the message bar
|
||||
[message setStringValue:[NSString stringWithFormat:@"Current selection: %@", NSStringFromRange(byteRange)]];
|
||||
|
||||
// restore delegates
|
||||
[hex setDelegate:oldDelegate];
|
||||
[ascii setDelegate:oldDelegate];
|
||||
return newSelectedCharRange;
|
||||
}
|
||||
|
||||
- (NSRange)byteRangeFromHexRange:(NSRange)hexRange;
|
||||
{
|
||||
// valid for all window widths
|
||||
NSRange byteRange = NSMakeRange(0,0);
|
||||
|
||||
byteRange.location = (hexRange.location / 3);
|
||||
byteRange.length = (hexRange.length / 3) + ((hexRange.length % 3)? 1:0);
|
||||
|
||||
return byteRange;
|
||||
}
|
||||
|
||||
- (NSRange)hexRangeFromByteRange:(NSRange)byteRange;
|
||||
{
|
||||
NSRange hexRange = NSMakeRange(0,0);
|
||||
|
||||
hexRange.location = (byteRange.location * 3);
|
||||
hexRange.length = (byteRange.length * 3);
|
||||
|
||||
return hexRange;
|
||||
}
|
||||
|
||||
- (NSRange)byteRangeFromAsciiRange:(NSRange)asciiRange;
|
||||
{
|
||||
// assumes 16 byte wide window
|
||||
NSRange byteRange;
|
||||
|
||||
byteRange.location = asciiRange.location - (asciiRange.location / 17);
|
||||
byteRange.length = asciiRange.length - ((asciiRange.location + asciiRange.length) / 17) + (asciiRange.location / 17);
|
||||
|
||||
return byteRange;
|
||||
}
|
||||
|
||||
- (NSRange)asciiRangeFromByteRange:(NSRange)byteRange;
|
||||
{
|
||||
// assumes 16 byte wide window
|
||||
NSRange asciiRange = NSMakeRange(0,0);
|
||||
|
||||
asciiRange.location = byteRange.location + (byteRange.location / 17);
|
||||
asciiRange.length = byteRange.length + ((byteRange.location + byteRange.length) / 17) - (byteRange.location / 17);
|
||||
|
||||
return asciiRange;
|
||||
}
|
||||
|
||||
/*
|
||||
- (void)textViewDidChangeSelection:(NSNotification *)notification;
|
||||
{
|
||||
|
@ -1,11 +1,19 @@
|
||||
#import "HexTextView.h"
|
||||
#import "ResKnifeResourceProtocol.h"
|
||||
|
||||
@implementation HexTextView
|
||||
|
||||
- (void)insertText:(id)insertString
|
||||
{
|
||||
// bug: 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];
|
||||
|
||||
NSLog( insertString );
|
||||
[super insertText: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];
|
||||
}
|
||||
|
||||
- (void)setSelectedRange:(NSRange)charRange affinity:(NSSelectionAffinity)affinity stillSelecting:(BOOL)flag
|
||||
@ -13,13 +21,43 @@
|
||||
NSRange newRange = charRange;
|
||||
|
||||
// select whole bytes at a time (only if selecting in hex!)
|
||||
if( self == [[self delegate] hex] )
|
||||
if( self == (id) [[self delegate] hex] )
|
||||
{
|
||||
newRange = [self selectionRangeForProposedRange:charRange
|
||||
granularity:NSSelectByWord];
|
||||
// newRange.location -= newRange.location % 3;
|
||||
// newRange.length -= (newRange.length % 3) -2;
|
||||
NSLog( @"hex selection changed to %@", NSStringFromRange(newRange) );
|
||||
// NSLog( NSStringFromRange(newRange) );
|
||||
|
||||
// move selection offset to beginning of byte
|
||||
newRange.location -= (charRange.location % 3);
|
||||
newRange.length += (charRange.location % 3);
|
||||
|
||||
// set selection length to whole number of bytes
|
||||
if( charRange.length != 0 )
|
||||
newRange.length -= (newRange.length % 3) -2;
|
||||
else newRange.length = 0;
|
||||
|
||||
// move insertion point to next byte if needs be
|
||||
if( newRange.location == charRange.location -1 && newRange.length == 0 )
|
||||
newRange.location += 3;
|
||||
|
||||
// NSLog( NSStringFromRange(newRange) );
|
||||
// NSLog( @"===========" );
|
||||
}
|
||||
// select return character if selecting ascii
|
||||
else if( self == (id) [[self delegate] ascii] )
|
||||
{
|
||||
// if ascii selection goes up to sixteenth byte on last line, select return character too
|
||||
if( (charRange.length + charRange.location) % 17 == 16)
|
||||
{
|
||||
// if selection is zero bytes long, move insertion point to character after return
|
||||
if( charRange.length == 0 )
|
||||
{
|
||||
// if moving back from first byte of line to previous line, skip return char
|
||||
NSRange selected = [self selectedRange];
|
||||
if( (selected.length + selected.location) % 17 == 0 )
|
||||
newRange.location -= 1;
|
||||
else newRange.location += 1;
|
||||
}
|
||||
else newRange.length += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// call the superclass to update the selection
|
||||
|
@ -10,12 +10,19 @@
|
||||
IBOutlet NSTextView *ascii;
|
||||
IBOutlet NSTextView *hex;
|
||||
IBOutlet NSTextView *offset;
|
||||
IBOutlet NSTextField *message;
|
||||
|
||||
id resource;
|
||||
}
|
||||
|
||||
// conform to the ResKnifePluginProtocol with the inclusion of these methods
|
||||
- (id)initWithResource:(id)newResource;
|
||||
- (void)resourceDidChange:(NSNotification *)notification;
|
||||
- (void)refreshData:(NSData *)data;
|
||||
|
||||
// conform to the ResKnifePluginProtocol with the inclusion of these methods
|
||||
- (id)initWithResource:(id)newResource;
|
||||
|
||||
// accessors
|
||||
- (id)resource;
|
||||
- (NSData *)data;
|
||||
|
||||
@end
|
||||
|
@ -1,8 +1,12 @@
|
||||
#import "HexWindowController.h"
|
||||
#import "HexTextView.h"
|
||||
|
||||
#import "ResKnifeResourceProtocol.h"
|
||||
|
||||
@implementation HexWindowController
|
||||
|
||||
NSString *ResourceChangedNotification = @"ResourceChangedNotification";
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
// causes window controller to use HexTextViews wherever it would previously use NSTextView
|
||||
@ -23,23 +27,36 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)windowDidLoad
|
||||
{
|
||||
[super windowDidLoad];
|
||||
|
||||
// set up text boxes (this doesn't do what I think it should!)
|
||||
// [hex setSelectionGranularity:NSSelectByWord];
|
||||
// we don't want this notification until we have a window!
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceDidChange:) name:ResourceChangedNotification object:nil];
|
||||
|
||||
// insert the resources' data into the text fields
|
||||
[self refreshData:[(id <ResKnifeResourceProtocol>)resource data]];
|
||||
|
||||
// finally, show the window
|
||||
[self showWindow:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)resourceDidChange:(NSNotification *)notification
|
||||
{
|
||||
// see if it's our resource which got changed (we receive notifications for any resource being changed, allowing multi-resource editors)
|
||||
if( [notification object] == resource )
|
||||
[self refreshData:[(id <ResKnifeResourceProtocol>)resource data]];
|
||||
}
|
||||
|
||||
- (void)refreshData:(NSData *)data;
|
||||
{
|
||||
// clear delegates (see HexEditorDelegate class for more info)
|
||||
// clear delegates (see HexEditorDelegate class for explanation of why)
|
||||
id oldDelegate = [hex delegate];
|
||||
[hex setDelegate:nil];
|
||||
[ascii setDelegate:nil];
|
||||
@ -54,4 +71,14 @@
|
||||
[ascii setDelegate:oldDelegate];
|
||||
}
|
||||
|
||||
- (id)resource
|
||||
{
|
||||
return resource;
|
||||
}
|
||||
|
||||
- (NSData *)data
|
||||
{
|
||||
return [(id <ResKnifeResourceProtocol>)resource data];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -1,17 +1,12 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/* Your plug-in's principle class must implement the following methods else it won't be loaded by ResKnife (so neh-neh!) */
|
||||
/* Your plug-in's principle class must implement initWithResource: else it won't be loaded by ResKnife (so neh-neh!), all other methods are optional */
|
||||
|
||||
@protocol ResKnifePluginProtocol
|
||||
|
||||
/*! @function initWithResource:newResource
|
||||
/*! @function initWithResource:
|
||||
* @abstract Your plug-in is inited with this call. This allows immediate access to the resource you are about to edit, and with this information you can set up different windows, etc.
|
||||
*/
|
||||
- (id)initWithResource:(id)newResource;
|
||||
|
||||
/*! @function refreshData:data
|
||||
* @abstract When your data set is changed via some means other than yourslf, you receive this.
|
||||
*/
|
||||
- (void)refreshData:(NSData *)data;
|
||||
|
||||
@end
|
||||
@end
|
@ -15,8 +15,11 @@
|
||||
- (NSNumber *)attributes;
|
||||
- (void)setAttributes:(NSNumber *)newAttributes;
|
||||
- (BOOL)dirty;
|
||||
- (void)setDirty:(BOOL)newValue;
|
||||
- (void)setDirty:(BOOL)newValue; // bug: may not be around forever
|
||||
- (NSData *)data;
|
||||
- (void)setData:(NSData *)newData;
|
||||
|
||||
@end
|
||||
@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.
|
BIN
Cocoa/Resources/Save.tiff
Normal file
BIN
Cocoa/Resources/Save.tiff
Normal file
Binary file not shown.
@ -58,6 +58,17 @@
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F577A8F30211CFA701A80001 = {
|
||||
isa = PBXFileReference;
|
||||
path = Save.tiff;
|
||||
refType = 4;
|
||||
};
|
||||
F577A8F40211CFA801A80001 = {
|
||||
fileRef = F577A8F30211CFA701A80001;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F57CEE0B0189C95101A8010B = {
|
||||
children = (
|
||||
F5502C4001C579FF01C57124,
|
||||
@ -149,7 +160,8 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F5EF83AF020C08E601A80001,
|
||||
F5EF83C6020C162C01A80001,
|
||||
F5EF83C9020C20D801A80001,
|
||||
F577A8F40211CFA801A80001,
|
||||
);
|
||||
isa = PBXResourcesBuildPhase;
|
||||
name = "Bundle Resources";
|
||||
@ -586,6 +598,7 @@
|
||||
F5B588460156D40B01000001,
|
||||
F5B588470156D40B01000001,
|
||||
F5B588480156D40B01000001,
|
||||
F577A8F30211CFA701A80001,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
path = Resources;
|
||||
@ -2306,8 +2319,8 @@
|
||||
F5EF83A5020C08E601A80001,
|
||||
F5EF83A7020C08E601A80001,
|
||||
F5EF83A8020C08E601A80001,
|
||||
F5EF83C7020C20D701A80001,
|
||||
F5EF83A9020C08E601A80001,
|
||||
F5EF83C5020C162B01A80001,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = "Hex Editor";
|
||||
@ -2413,22 +2426,23 @@
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5EF83C3020C10C601A80001 = {
|
||||
isa = PBXFileReference;
|
||||
name = HexWindow.nib;
|
||||
path = English.lproj/HexWindow.nib;
|
||||
refType = 4;
|
||||
};
|
||||
F5EF83C5020C162B01A80001 = {
|
||||
F5EF83C7020C20D701A80001 = {
|
||||
children = (
|
||||
F5EF83C3020C10C601A80001,
|
||||
F5EF83C8020C20D701A80001,
|
||||
);
|
||||
isa = PBXVariantGroup;
|
||||
name = HexWindow.nib;
|
||||
path = "";
|
||||
refType = 4;
|
||||
};
|
||||
F5EF83C6020C162C01A80001 = {
|
||||
fileRef = F5EF83C5020C162B01A80001;
|
||||
F5EF83C8020C20D701A80001 = {
|
||||
isa = PBXFileReference;
|
||||
name = English;
|
||||
path = English.lproj/HexWindow.nib;
|
||||
refType = 4;
|
||||
};
|
||||
F5EF83C9020C20D801A80001 = {
|
||||
fileRef = F5EF83C7020C20D701A80001;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user