2002-02-02 11:48:54 +00:00
|
|
|
#import "HexEditorDelegate.h"
|
2002-02-14 23:24:53 +00:00
|
|
|
#import "HexWindowController.h"
|
2008-07-31 20:27:55 +00:00
|
|
|
#import "HexTextView.h"
|
2002-02-07 03:45:43 +00:00
|
|
|
|
2002-02-02 11:48:54 +00:00
|
|
|
@implementation HexEditorDelegate
|
|
|
|
|
2002-04-30 23:44:23 +00:00
|
|
|
- (id)init
|
|
|
|
{
|
|
|
|
self = [super init];
|
2008-07-31 20:27:55 +00:00
|
|
|
if(!self) return nil;
|
2002-06-04 13:57:55 +00:00
|
|
|
|
|
|
|
editedLow = NO;
|
2002-04-30 23:44:23 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
- (void)awakeFromNib
|
2002-02-02 11:48:54 +00:00
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
// - MOVED TO HEX WINDOW CONTROLLER DUE TO BUG IN IB MEANING OFFSET, HEX AND ASCII AREN'T SET AT THIS TIME
|
2002-02-02 11:48:54 +00:00
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
// notify me when a view scrolls so I can update the other two
|
|
|
|
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidScroll:) name:NSViewBoundsDidChangeNotification object:[[offset enclosingScrollView] contentView]];
|
|
|
|
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidScroll:) name:NSViewBoundsDidChangeNotification object:[[hex enclosingScrollView] contentView]];
|
|
|
|
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidScroll:) name:NSViewBoundsDidChangeNotification object:[[ascii enclosingScrollView] contentView]];
|
2002-02-02 11:48:54 +00:00
|
|
|
}
|
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
/* REMOVE THESE WHEN I.B. IS FIXED */
|
|
|
|
- (void)setHex:(id)newView
|
2002-02-02 11:48:54 +00:00
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
hex = newView;
|
2002-02-02 11:48:54 +00:00
|
|
|
}
|
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
- (void)setAscii:(id)newView
|
2002-02-02 11:48:54 +00:00
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
ascii = newView;
|
|
|
|
}
|
|
|
|
/* END REMOVE MARKER */
|
|
|
|
|
|
|
|
/* data re-representation methods */
|
|
|
|
|
|
|
|
- (NSString *)offsetRepresentation:(NSData *)data
|
|
|
|
{
|
|
|
|
int dataLength = [data length], bytesPerRow = [controller bytesPerRow];
|
2002-03-21 04:02:26 +00:00
|
|
|
int rows = (dataLength / bytesPerRow) + ((dataLength % bytesPerRow)? 1:0);
|
2002-02-02 11:48:54 +00:00
|
|
|
NSMutableString *representation = [NSMutableString string];
|
2003-08-01 22:23:50 +00:00
|
|
|
int row;
|
2002-02-02 11:48:54 +00:00
|
|
|
|
2003-08-01 22:23:50 +00:00
|
|
|
for( row = 0; row < rows; row++ )
|
2008-07-31 20:27:55 +00:00
|
|
|
[representation appendFormat:@"%08lX:", row * bytesPerRow];
|
2002-02-02 11:48:54 +00:00
|
|
|
|
|
|
|
return representation;
|
|
|
|
}
|
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
/* delegation methods */
|
|
|
|
|
|
|
|
- (void)viewDidScroll:(NSNotification *)notification
|
2002-11-15 15:12:42 +00:00
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
// get object refs for increased speed
|
|
|
|
NSClipView *object = (NSClipView *) [notification object];
|
|
|
|
NSClipView *offsetClip = [[offset enclosingScrollView] contentView];
|
|
|
|
NSClipView *hexClip = [[hex enclosingScrollView] contentView];
|
|
|
|
NSClipView *asciiClip = [[ascii enclosingScrollView] contentView];
|
2003-08-01 22:23:50 +00:00
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
// remove observer to stop myself from receiving bounds changed notifications (n.b. -setPostsBoundsChangedNotifications: only suspends them temporarilly - you get a unified bounds changed notification upon enabling it again and is designed for live resizing and such, so of no use here)
|
|
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSViewBoundsDidChangeNotification object:nil];
|
|
|
|
|
|
|
|
// when a view scrolls, update the other two
|
|
|
|
if( object != offsetClip ) [offsetClip setBoundsOrigin:[object bounds].origin];
|
|
|
|
if( object != hexClip ) [hexClip setBoundsOrigin:[object bounds].origin];
|
|
|
|
if( object != asciiClip ) [asciiClip setBoundsOrigin:[object bounds].origin];
|
|
|
|
|
|
|
|
// restore notifications
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidScroll:) name:NSViewBoundsDidChangeNotification object:offsetClip];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidScroll:) name:NSViewBoundsDidChangeNotification object:hexClip];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidScroll:) name:NSViewBoundsDidChangeNotification object:asciiClip];
|
2002-11-15 15:12:42 +00:00
|
|
|
}
|
|
|
|
|
2002-02-02 11:48:54 +00:00
|
|
|
- (NSRange)textView:(NSTextView *)textView willChangeSelectionFromCharacterRange:(NSRange)oldSelectedCharRange toCharacterRange:(NSRange)newSelectedCharRange
|
|
|
|
{
|
2002-02-06 20:57:56 +00:00
|
|
|
NSRange hexRange, asciiRange, byteRange = NSMakeRange(0,0);
|
2002-02-02 11:48:54 +00:00
|
|
|
|
|
|
|
// temporarilly removing the delegate stops this function being called recursivly!
|
|
|
|
id oldDelegate = [hex delegate];
|
|
|
|
[hex setDelegate:nil];
|
|
|
|
[ascii setDelegate:nil];
|
|
|
|
|
|
|
|
if( textView == hex ) // we're selecting hexadecimal
|
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
byteRange = [HexWindowController byteRangeFromHexRange:newSelectedCharRange];
|
|
|
|
asciiRange = [HexWindowController asciiRangeFromByteRange:byteRange];
|
2002-02-02 11:48:54 +00:00
|
|
|
[ascii setSelectedRange:asciiRange];
|
|
|
|
}
|
|
|
|
else if( textView == ascii ) // we're selecting ASCII
|
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
byteRange = [HexWindowController byteRangeFromAsciiRange:newSelectedCharRange];
|
|
|
|
hexRange = [HexWindowController hexRangeFromByteRange:byteRange];
|
2002-02-02 11:48:54 +00:00
|
|
|
[hex setSelectedRange:hexRange];
|
|
|
|
}
|
2002-02-06 20:57:56 +00:00
|
|
|
|
|
|
|
// put the new selection into the message bar
|
|
|
|
[message setStringValue:[NSString stringWithFormat:@"Current selection: %@", NSStringFromRange(byteRange)]];
|
2002-02-02 11:48:54 +00:00
|
|
|
|
|
|
|
// restore delegates
|
|
|
|
[hex setDelegate:oldDelegate];
|
|
|
|
[ascii setDelegate:oldDelegate];
|
|
|
|
return newSelectedCharRange;
|
|
|
|
}
|
2002-02-06 20:57:56 +00:00
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
- (HexWindowController *)controller
|
2002-02-06 20:57:56 +00:00
|
|
|
{
|
2008-07-31 20:27:55 +00:00
|
|
|
return controller;
|
2002-02-06 20:57:56 +00:00
|
|
|
}
|
|
|
|
|
2002-02-02 11:48:54 +00:00
|
|
|
- (NSTextView *)hex
|
|
|
|
{
|
|
|
|
return hex;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSTextView *)ascii
|
|
|
|
{
|
|
|
|
return ascii;
|
|
|
|
}
|
|
|
|
|
2002-04-30 23:44:23 +00:00
|
|
|
- (BOOL)editedLow
|
|
|
|
{
|
|
|
|
return editedLow;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setEditedLow:(BOOL)flag
|
|
|
|
{
|
|
|
|
editedLow = flag;
|
|
|
|
}
|
|
|
|
|
2008-07-31 20:27:55 +00:00
|
|
|
- (NSRange)rangeForUserTextChange
|
|
|
|
{
|
|
|
|
// if editing hex, convert hex selection to byte selection
|
|
|
|
if( [[controller window] firstResponder] == hex )
|
|
|
|
rangeForUserTextChange = [HexWindowController byteRangeFromHexRange:[hex rangeForUserTextChange]];
|
|
|
|
|
|
|
|
// if editing ascii, convert ascii selection to byte selection
|
|
|
|
else if( [[controller window] firstResponder] == ascii )
|
|
|
|
rangeForUserTextChange = [HexWindowController byteRangeFromAsciiRange:[ascii rangeForUserTextChange]];
|
|
|
|
|
|
|
|
return rangeForUserTextChange;
|
|
|
|
}
|
|
|
|
|
2002-02-02 11:48:54 +00:00
|
|
|
@end
|