Update for Uli

This commit is contained in:
Nicholas Shanks 2003-04-03 15:38:42 +00:00
parent 9f6f97977b
commit 1880029f77
46 changed files with 2923 additions and 579 deletions

View File

@ -70,7 +70,6 @@ int main( int argc, char* argv[] )
ParseDialogEvents( null, &theEvent, null );
else ParseEvents( &theEvent );
}
QuitResKnife();
#endif
#if __profile__
@ -78,6 +77,10 @@ int main( int argc, char* argv[] )
ProfilerTerm();
#endif
#if !TARGET_API_MAC_CARBON
QuitResKnife();
#endif
return error;
}

View File

@ -30,6 +30,7 @@ FileWindow::FileWindow( FSSpecPtr spec )
error = CreateWindowFromNib( nibRef, CFSTR("File Window"), &window );
if( error != noErr || window == null )
{
DisposeNibReference( nibRef );
DisplayError( "\pA file window could not be obtained from the nib file." );
return;
}

View File

@ -1,6 +1,17 @@
// abbreviations
#define null NULL
#define qdb qd.screenBits.bounds
#define null NULL
#if TARGET_API_MAC_CARBON
#define qdb ScreenBounds()
inline Rect ScreenBounds()
{
Rect rect;
GetAvailableWindowPositioningBounds( GetMainDevice(), &rect );
return rect;
}
#else
#define qdb qd.screenBits.bounds
#endif
// Easier API call names
#define GetWindowRefCon( window ) (long) GetWRefCon( window )

View File

@ -112,12 +112,14 @@ struct prefs
Boolean quitIfNoWindowsAreOpen; // silly name! - perhaps grandmaMode ?
Boolean autoSave;
UInt32 autoSaveInterval; // should be in units of time
Boolean warnOnDelete; // "Are you sure?" dialog, Š Microsoft 1992-2000
Boolean warnOnDelete; // "Are you sure?" dialog, © Microsoft 1986-2003
};
/*** CONSTANTS ***/
// Mac OS versions
const SInt32 kMacOS607 = 0x00000607;
const SInt32 kMacOS7 = 0x00000710;
const SInt32 kMacOS71 = 0x00000710;
const SInt32 kMacOS755 = 0x00000755;
const SInt32 kMacOS8 = 0x00000800;
@ -129,6 +131,7 @@ const SInt32 kMacOS91 = 0x00000910;
const SInt32 kMacOS921 = 0x00000921;
const SInt32 kMacOS10 = 0x00001000;
const SInt32 kMacOS101 = 0x00001010;
const SInt32 kMacOS102 = 0x00001020;
const SInt32 kMacOSX = kMacOS10;
// CarbonLib versions
@ -139,6 +142,8 @@ const SInt32 kCarbonLib125 = 0x00000125;
const SInt32 kCarbonLib131 = 0x00000131;
const SInt32 kCarbonLib14 = 0x00000140;
const SInt32 kCarbonLib145 = 0x00000145;
const SInt32 kCarbonLib15 = 0x00000150;
const SInt32 kCarbonLib16 = 0x00000160;
// ResKnife version & file types
const UInt32 kCurrentVersion = 0x00040001;

View File

@ -10,7 +10,11 @@
@interface ApplicationDelegate : NSObject
{
/*! @var icons A dictionary within which to cache icons. Keys are four-character <tt>NSStrings</tt> representing <tt>ResTypes</tt>. */
/*! @var openAuxView Accessory view for <tt>NSOpenPanels</tt>. */
IBOutlet NSView *openAuxView;
/*! @var forkTableView Table view inside <tt>openAuxView</tt>. */
IBOutlet NSTableView *forkTableView;
/*! @var icons A dictionary within which to cache icons. Keys are four-character <tt>NSStrings</tt> representing <tt>ResTypes</tt>. */
NSMutableDictionary *icons;
}
@ -39,6 +43,11 @@
*/
- (IBAction)showInfo:(id)sender;
/*! @function showPasteboard:
* @discussion Displays the pasteboard document, a singleton instance of class <tt>PasteboardDocument</tt>
*/
- (IBAction)showPasteboard:(id)sender;
/*! @function showPrefs:
* @discussion Displays the preferences panel stored in <b>PrefsWindow.nib</b>
*/
@ -49,6 +58,11 @@
*/
- (void)initUserDefaults;
/*! @function openAuxView
* @discussion Accessor method for the <tt>openAuxView</tt> instance variable.
*/
- (NSView *)openAuxView;
/*! @function icons
* @discussion Accessor method for the <tt>icons</tt> instance variable.
*/

View File

@ -1,5 +1,7 @@
#import "ApplicationDelegate.h"
#import "RKDocumentController.h"
#import "InfoWindowController.h"
#import "PasteboardWindowController.h"
#import "PrefsWindowController.h"
#import "CreateResourceSheetController.h"
#import "ResourceDocument.h"
@ -16,6 +18,13 @@
return self;
}
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
// instanciate my own subclass of NSDocumentController so I can override the open dialog
RKDocumentController *docController = [[RKDocumentController alloc] init];
#pragma unused( docController )
}
- (void)awakeFromNib
{
// Part of my EvilPlanª to find out how many people use ResKnife and how often!
@ -28,6 +37,13 @@
[icons setObject:[[NSWorkspace sharedWorkspace] iconForFileType:@"PICT"] forKey:@"PICT"];
[icons setObject:[[NSWorkspace sharedWorkspace] iconForFileType:@"icns"] forKey:@"icns"];
// set up open dialog's aux table view
NSTableColumn *tableColumn = [forkTableView tableColumnWithIdentifier:@"parse"];
NSButtonCell *buttonCell = [[[NSButtonCell alloc] initTextCell:@""] autorelease];
[buttonCell setEditable:YES];
[buttonCell setButtonType:NSSwitchButton];
[tableColumn setDataCell:buttonCell];
[self initUserDefaults];
}
@ -41,7 +57,7 @@
{
#pragma unused( sender )
NSString *launchAction = [[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchAction"];
if( [launchAction isEqualToString:@"OpenUntitledFile"] )
if( [launchAction isEqualToString:@"OpenUntitledFile"] )
return YES;
else if( [launchAction isEqualToString:@"DisplayOpenPanel"] )
{
@ -91,6 +107,11 @@
[[InfoWindowController sharedInfoWindowController] showWindow:sender];
}
- (IBAction)showPasteboard:(id)sender
{
[[PasteboardWindowController sharedPasteboardWindowController] showWindow:sender];
}
- (IBAction)showPrefs:(id)sender
{
[[PrefsWindowController sharedPrefsWindowController] showWindow:sender];
@ -133,6 +154,11 @@
[defaults synchronize];
}
- (NSView *)openAuxView
{
return openAuxView;
}
- (NSDictionary *)icons
{
return icons;

View File

@ -28,10 +28,8 @@
[(NSPanel *)[self window] setBecomesKeyOnlyIfNeeded:YES];
// retain views for swapping in and out
[documentView retain];
[documentView removeFromSuperview];
[resourceView retain];
[resourceView removeFromSuperview];
[[documentView retain] removeFromSuperview];
[[resourceView retain] removeFromSuperview];
[self setMainWindow:[NSApp mainWindow]];
[self updateInfoWindow];

View File

@ -0,0 +1,19 @@
/* OpenFileDataSource */
#import <Cocoa/Cocoa.h>
@interface OpenFileDataSource : NSObject
{
IBOutlet NSTableView *forkTableView;
}
@end
@interface OpenPanelDelegate : NSObject
{
id originalDelegate;
}
@end
@interface NSSavePanel (ResKnife)
- (NSBrowser *)browser;
@end

View File

@ -0,0 +1,113 @@
#import "OpenFileDataSource.h"
#import <unistd.h>
#import <sys/attr.h>
struct directoryinfo {
ÊÊ unsigned long length;
ÊÊ u_int32_t dirid;
};
struct dunnowhat
{
unsigned long length;
u_int32_t data1;
u_int32_t data2;
u_int32_t data3;
u_int32_t data4;
u_int32_t data5;
u_int32_t data6;
};
@implementation OpenFileDataSource
//get action method and target of browser, intercept (or re-route and call it myself)
/* NSTableView data source protocol implementation */
- (int)numberOfRowsInTableView:(NSTableView *)tableView
{
NSBrowser *browser = [(NSOpenPanel *)[tableView window] browser];
if( [[browser selectedCells] count] == 1 )
{
// only one file is selected, parse it for forks
/* const char *path = [[browser path] cString];
struct attrlist attributes;
struct directoryinfo fileinfo;
NSLog( @"%s", path );
// memset( &attributes, 0, sizeof(struct attrlist) );
bzero( &attributes, sizeof(struct attrlist) );
attributes.bitmapcount = ATTR_BIT_MAP_COUNT;
// attributes.fileattr = ATTR_FILE_FORKCOUNT;
attributes.commonattr = ATTR_CMN_OBJID;
int result = getattrlist( path, &attributes, &fileinfo, sizeof(struct directoryinfo), 0 );
NSLog( @"%d", result );
if( result != 0 ) return 0;
NSLog( @"%d", fileinfo.length );
NSLog( @"%d", fileinfo.dirid );
*/
struct attrlist alist;
struct directoryinfo dirinfo;
char *path = [[browser path] cString];
bzero(&alist, sizeof(alist));
alist.bitmapcount = 5;
alist.commonattr = ATTR_CMN_OBJID;
int result = getattrlist(path, &alist, &dirinfo, sizeof(dirinfo), 0);
printf("result: %d; directory id: %lu; %s\n", result, dirinfo.dirid, path);
return 3;
}
// multiple/no selected files, return nothing
else return 0;
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
{
return nil;
}
- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(int)row
{
;
}
/*
NSLog( [browser path] );
CatPositionRec forkIterator;
forkIterator.initialize = 0;
FSIterateForks( FSRef *ref, &forkIterator, NULL, NULL, NULL );
*/
@end
@implementation OpenPanelDelegate
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
/* NSMethodSignature *sig;
NS_DURING
sig = [super methodSignatureForSelector:selector];
NS_HANDLER
sig = [originalDelegate methodSignatureForSelector:selector];
NS_ENDHANDLER
return sig; */
return [originalDelegate methodSignatureForSelector:selector];
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
if( [originalDelegate respondsToSelector:[invocation selector]] )
[invocation invokeWithTarget:originalDelegate];
else [self doesNotRecognizeSelector:[invocation selector]];
}
@end
@implementation NSSavePanel (ResKnife)
- (NSBrowser *)browser
{
return _browser;
}
@end

View File

@ -0,0 +1,11 @@
#import <Cocoa/Cocoa.h>
#import "ResourceDocument.h"
@interface PasteboardDocument : ResourceDocument
{
unsigned long generalChangeCount; // change count for the general pasteboard
}
- (void)readPasteboard:(NSString *)pbName;
@end

View File

@ -0,0 +1,43 @@
#import "PasteboardDocument.h"
#import "Resource.h"
@implementation PasteboardDocument
- (id)init
{
self = [super init];
if( self )
{
[self readPasteboard:NSGeneralPboard];
}
return self;
}
- (void)readPasteboard:(NSString *)pbName
{
NSPasteboard *pb = [NSPasteboard pasteboardWithName:pbName];
NSArray *types = [pb types];
NSEnumerator *enumerator = [types objectEnumerator];
NSString *currentType;
[[self undoManager] disableUndoRegistration];
while( currentType = [enumerator nextObject] )
{
// create the resource & add it to the array
NSString *name = pbName;
NSString *type;
NS_DURING
type = [currentType substringToIndex:3];
NS_HANDLER
type = currentType;
NS_ENDHANDLER
NSNumber *resID = [NSNumber numberWithShort:0];
NSNumber *attributes = [NSNumber numberWithShort:0];
NSData *data = [pb dataForType:type];
Resource *resource = [Resource resourceOfType:type andID:resID withName:name andAttributes:attributes data:data];
[resources addObject:resource]; // array retains resource
}
[[self undoManager] enableUndoRegistration];
}
@end

View File

@ -0,0 +1,9 @@
#import <Cocoa/Cocoa.h>
@interface PasteboardWindowController : NSWindowController
{
}
+ (id)sharedPasteboardWindowController;
@end

View File

@ -0,0 +1,20 @@
#import "PasteboardWindowController.h"
@implementation PasteboardWindowController
- (id)init
{
self = [self initWithWindowNibName:@"ResourceDocument"];
if( self ) [self setWindowFrameAutosaveName:@"PasteboardWindow"];
return self;
}
+ (id)sharedPasteboardWindowController
{
static PasteboardWindowController *sharedPasteboardWindowController = nil;
if( !sharedPasteboardWindowController )
sharedPasteboardWindowController = [[PasteboardWindowController allocWithZone:[self zone]] init];
return sharedPasteboardWindowController;
}
@end

View File

@ -0,0 +1,6 @@
#import <Cocoa/Cocoa.h>
@interface RKDocumentController : NSDocumentController
{
}
@end

View File

@ -0,0 +1,29 @@
#import "RKDocumentController.h"
#import "ApplicationDelegate.h"
#import "OpenFileDataSource.h"
@implementation RKDocumentController
// because I swap the isa pointer I can't add instance variables, so use statics instead (there will only ever be one RKDocumentController)
static id oldDelegate = nil;
- (id)init
{
self = [super init];
if( self )
{
// for some reason calling -[super init] causes a new instance of self to be returned (which is not of my subclass) so to get my overridden methods called again, I have to do this...
isa = [RKDocumentController class];
oldDelegate = [[NSOpenPanel openPanel] delegate];
[[NSOpenPanel openPanel] setDelegate:[[[OpenPanelDelegate alloc] init] autorelease]];
}
return self;
}
- (int)runModalOpenPanel:(NSOpenPanel *)openPanel forTypes:(NSArray *)extensions
{
[openPanel setAccessoryView:[(ApplicationDelegate *)[NSApp delegate] openAuxView]];
return [super runModalOpenPanel:openPanel forTypes:extensions];
}
@end

View File

@ -6,6 +6,7 @@
@private
// flags
BOOL dirty;
NSString *representedFork;
// resource information
NSString *name;
@ -17,12 +18,17 @@
NSData *data;
}
// accessor methods not part of the protocol
- (void)setDirty:(BOOL)newValue;
- (NSString *)representedFork;
- (void)setRepresentedFork:(NSString *)forkName;
// init methods
- (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;
// autoreleased resource methods
+ (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;

View File

@ -30,6 +30,7 @@ NSString *RKResourcePboardType = @"RKResourcePboardType";
// sets values directly for speed reasons (less messaging overhead)
self = [super init];
dirty = NO;
representedFork = nil;
name = [nameValue copy];
type = [typeValue copy];
resID = [resIDValue copy];
@ -122,6 +123,7 @@ NSString *RKResourcePboardType = @"RKResourcePboardType";
- (void)dealloc
{
[representedFork release];
[name release];
[type release];
[resID release];
@ -154,6 +156,16 @@ NSString *RKResourcePboardType = @"RKResourcePboardType";
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceDidChangeNotification object:self];
}
- (NSString *)representedFork
{
return representedFork;
}
- (void)setRepresentedFork:(NSString *)forkName
{
representedFork = [forkName copy];
}
- (NSString *)name
{
return name;

View File

@ -42,6 +42,7 @@
- (void)resourceTypeWillChange:(NSNotification *)notification;
- (void)resourceAttributesWillChange:(NSNotification *)notification;
- (BOOL)readFork:(NSString *)forkName asStreamFromFile:(NSString *)fileName;
- (BOOL)readResourceMap:(SInt16)fileRefNum;
- (BOOL)writeResourceMap:(SInt16)fileRefNum;

View File

@ -288,9 +288,10 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
- (void)openResourceUsingEditor:(Resource *)resource
{
#warning openResourceUsingEditor: shortcuts to NovaTools !!
// #warning openResourceUsingEditor: shortcuts to NovaTools !!
// opens resource in template using TMPL resource with name templateName
NSBundle *editor = [NSBundle bundleWithPath:[[[NSBundle mainBundle] builtInPlugInsPath] stringByAppendingPathComponent:@"NovaTools.plugin"]];
// NSBundle *editor = [NSBundle bundleWithPath:[[[NSBundle mainBundle] builtInPlugInsPath] stringByAppendingPathComponent:@"NovaTools.plugin"]];
NSBundle *editor = [NSBundle bundleWithPath:[[[NSBundle mainBundle] builtInPlugInsPath] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@ Editor.plugin", [resource type]]]];
// open the resources, passing in the template to use
if( editor /*&& [[editor principalClass] respondsToSelector:@selector(initWithResource:)]*/ )
@ -339,6 +340,7 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
NSData *data = [(Resource *)[outlineView itemAtRow:[outlineView selectedRow]] data];
if( data && [data length] != 0 )
{
// bug: plays sound synchronously in main thread!
SndListPtr sndPtr = (SndListPtr) [data bytes];
SndPlay( nil, &sndPtr, false );
}
@ -529,7 +531,11 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
NSLog( @"Opening Resource fork failed, trying data fork..." );
error = FSOpenResourceFile( fileRef, 0, nil, fsRdPerm, &fileRefNum);
}
else fork = resourceForkName;
else
{
fork = resourceForkName;
[self readFork:@"" asStreamFromFile:fileName]; // bug: only reads data fork for now, need to scan file for other forks too
}
SetResLoad( true ); // restore resource loading as soon as is possible
// read the resources (without spawning thousands of undos for resource creation)
@ -551,19 +557,38 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
return succeeded;
}
- (BOOL)readFork:(NSString *)forkName asStreamFromFile:(NSString *)fileName
{
NSData *data = [NSData dataWithContentsOfFile:fileName];
Resource *resource = [Resource resourceOfType:@"" andID:0 withName:NSLocalizedString(@"Data Fork", nil) andAttributes:0 data:data];
if( data && resource )
{
/* NTFS Note: When running SFM (Services for Macintosh) a Windows NT-based system (including 2000 & XP) serving NTFS-formatted drives stores Mac resource forks in a stream named "AFP_Resource". The finder info/attributes are stored in a stream called "Afp_AfpInfo". The default data fork stream is called "$DATA" and any of these can be accessed thus: "c:\filename.txt:forkname".
As a result, ResKnife prohibits creation of forks with the following names: "" (empty string, Mac data fork name),
"$DATA" (NTFS data fork name),
"AFP_Resource" and "Afp_AfpInfo".
It is perfectly legal in ResKnife to read in forks of these names when accessing a shared NTFS drive from a server running SFM. */
[resource setRepresentedFork:forkName];
[resources insertObject:resource atIndex:0];
return YES;
}
else return NO;
}
- (BOOL)readResourceMap:(SInt16)fileRefNum
{
OSStatus error = noErr;
unsigned short i, j, n;
unsigned short n;
SInt16 oldResFile = CurResFile();
UseResFile( fileRefNum );
for( i = 1; i <= Count1Types(); i++ )
for( unsigned short i = 1; i <= Count1Types(); i++ )
{
ResType resType;
Get1IndType( &resType, i );
n = Count1Resources( resType );
for( j = 1; j <= n; j++ )
for( unsigned short j = 1; j <= n; j++ )
{
Str255 nameStr;
long sizeLong;
@ -586,15 +611,13 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
HLockHi( resourceHandle );
// create the resource & add it to the array
{
NSString *name = [NSString stringWithCString:&nameStr[1] length:nameStr[0]];
NSString *type = [NSString stringWithCString:(char *) &resType length:4];
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];
[resources addObject:resource]; // array retains resource
}
NSString *name = [NSString stringWithCString:&nameStr[1] length:nameStr[0]];
NSString *type = [NSString stringWithCString:(char *) &resType length:4];
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];
[resources addObject:resource]; // array retains resource
HUnlock( resourceHandle );
ReleaseResource( resourceHandle );
@ -624,6 +647,17 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
error = FSCreateResourceFile( parentRef, [[fileName lastPathComponent] length], (UniChar *) uniname, kFSCatInfoNone, nil, fork->length, (UniChar *) &fork->unicode, fileRef, fileSpec );
if( !error )
error = FSOpenResourceFile( fileRef, fork->length, (UniChar *) &fork->unicode, fsWrPerm, &fileRefNum);
/* at some point make use of:
FSCreateResourceFork( const FSRef * ref,
UniCharCount forkNameLength,
const UniChar * forkName, // can be NULL
UInt32 flags);
Creates the named fork and initalises as a resource fork
Mac OS 10.2 or later */
}
else
{
@ -654,12 +688,13 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
for( i = 0; i < [resources count]; i++ )
{
Resource *resource = [resources objectAtIndex:i];
if( [resource representedFork] != nil ) continue;
Str255 nameStr;
ResType resType;
short resIDShort = [[resource resID] shortValue];
short attrsShort = [[resource attributes] shortValue];
Handle resourceHandle = NewHandleClear( [[resource data] length] );
Handle resourceHandle = NewHandleClear( [[resource data] length] );
nameStr[0] = [[resource name] cStringLength];
BlockMoveData( [[resource name] cString], &nameStr[1], nameStr[0] );

View File

@ -42,12 +42,15 @@
- (void)setImage:(NSImage *)newImage
{
// save image and set to 16x16 pixels
id old = image;
image = [newImage retain];
[image setScalesWhenResized:YES];
[image setSize:NSMakeSize(16,16)];
[old autorelease];
if( image != newImage )
{
// save image and set to 16x16 pixels
id old = image;
image = [newImage retain];
[image setScalesWhenResized:YES];
[image setSize:NSMakeSize(16,16)];
[old release];
}
}
- (NSRect)imageFrameForCellFrame:(NSRect)cellFrame
@ -104,7 +107,8 @@
// get image frame
NSDivideRect( cellFrame, &imageFrame, &cellFrame, 3 + imageSize.width, NSMinXEdge );
if( [self drawsBackground] )
// NSLog( "drawing name cell with bg: %@ colour: %@", [self drawsBackground]? @"YES":@"NO", [self backgroundColor] );
if( [self drawsBackground] && ![self isHighlighted] /* ![self cellAttribute:NSCellHighlighted] */ )
{
[[self backgroundColor] set];
NSRectFill(imageFrame);

View File

@ -1,9 +1,10 @@
{
IBClasses = (
{
ACTIONS = {showInfo = id; showPrefs = id; };
ACTIONS = {showInfo = id; showPasteboard = id; showPrefs = id; };
CLASS = ApplicationDelegate;
LANGUAGE = ObjC;
OUTLETS = {forkTableView = NSTableView; openAuxView = NSView; };
SUPERCLASS = NSObject;
},
{
@ -29,6 +30,12 @@
CLASS = FirstResponder;
LANGUAGE = ObjC;
SUPERCLASS = NSObject;
},
{
CLASS = OpenFileDataSource;
LANGUAGE = ObjC;
OUTLETS = {forkTableView = NSTableView; };
SUPERCLASS = NSObject;
}
);
IBVersion = 1;

View File

@ -1,17 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>159 91 432 426 0 0 1152 848 </string>
<string>535 90 432 426 0 0 1600 1002 </string>
<key>IBEditorPositions</key>
<dict>
<key>246</key>
<string>630 582 340 222 0 0 1600 1002 </string>
<key>29</key>
<string>59 443 347 44 0 0 1152 848 </string>
<string>92 528 347 44 0 0 1600 1002 </string>
</dict>
<key>IBFramework Version</key>
<string>263.2</string>
<string>286.0</string>
<key>IBOpenObjects</key>
<array>
<integer>29</integer>
<integer>246</integer>
</array>
<key>IBSystem Version</key>
<string>5Q125</string>
<string>6G30</string>
</dict>
</plist>

Binary file not shown.

View File

@ -3,11 +3,11 @@
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>75 336 486 325 0 0 1024 746 </string>
<string>71 141 530 549 0 0 1600 1002 </string>
<key>IBFramework Version</key>
<string>286.0</string>
<key>IBSystem Version</key>
<string>6C115</string>
<string>6F21</string>
<key>IBUserGuides</key>
<dict>
<key>CreateResourceSheet</key>

View File

@ -11,6 +11,6 @@
<integer>6</integer>
</array>
<key>IBSystem Version</key>
<string>6C115</string>
<string>6F21</string>
</dict>
</plist>

View File

@ -220,9 +220,11 @@
return charIndex;
}
- (unsigned int)draggingSourceOperationMaskForLocal:(BOOL)isLocal
- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal
{
return NSDragOperationCopy | NSDragOperationMove | NSDragOperationGeneric;
/* if( isLocal ) return NSDragOperationEvery;
else return NSDragOperationCopy;
*/ return NSDragOperationCopy | NSDragOperationMove | NSDragOperationGeneric;
}
static NSRange draggedRange;
@ -234,16 +236,18 @@ static NSRange draggedRange;
- (void)draggedImage:(NSImage *)image endedAt:(NSPoint)point operation:(NSDragOperation)operation
{
if( operation == NSDragOperationMove )
/* if( operation == NSDragOperationMove )
{
NSRange selection = [self rangeForUserTextChange];
[self editData:[[[self window] windowController] data] replaceBytesInRange:draggedRange withData:[NSData data]];
// set the new selection/insertion point
selection.location -= draggedRange.length;
selection.length = draggedRange.length;
if( selection.location > draggedRange.location )
selection.location -= draggedRange.length;
[self setSelectedRange:selection];
}
}*/
}
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
@ -256,13 +260,44 @@ static NSRange draggedRange;
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
// get the insertion point location
NSPasteboard *pb = [sender draggingPasteboard];
NSData *pastedData = [pb dataForType:NSStringPboardType];
int charIndex = [self _insertionGlyphIndexForDrag:sender];
if( self == [[self delegate] hex] ) charIndex /= 3;
// convert hex string to data
if( [sender draggingSource] == [[self delegate] hex] )
pastedData = [[[self delegate] hexToAscii:pastedData] dataUsingEncoding:NSASCIIStringEncoding];
if( [sender draggingSource] == [[self delegate] hex] || [sender draggingSource] == [[self delegate] ascii] )
// if( operation == NSDragOperationMove )
{
NSRange deleteRange = draggedRange;
if( self == [[self delegate] hex] )
{
deleteRange.location /= 3;
deleteRange.length += 1;
deleteRange.length /= 3;
}
// if moving the data, remove the selection from the data
[self editData:[[[self window] windowController] data] replaceBytesInRange:deleteRange withData:[NSData data]];
// compensate for already removing the dragged data
if( charIndex > draggedRange.location )
charIndex -= draggedRange.length;
}
// insert data at insertion point
if( self == [[self delegate] hex] ) charIndex /= 3;
[self editData:[[[self window] windowController] data] replaceBytesInRange:NSMakeRange(charIndex,0) withData:pastedData];
// set the new selection/insertion point
NSRange selection = [self rangeForUserTextChange];
selection.location -= draggedRange.length;
selection.length = draggedRange.length;
[self setSelectedRange:selection];
return YES;
}

View File

@ -2,6 +2,22 @@
#import "HexTextView.h"
#import "FindSheetController.h"
/*
OSStatus Plug_InitInstance( Plug_PlugInRef plug, Plug_ResourceRef resource )
{
// init function called by carbon apps
if( NSApplicationLoad() )
{
id newResource = [NSClassFromString(@"Resource") resourceOfType:[NSString stringWithCString:length:4] andID:[NSNumber numberWithInt:] withName:[NSString stringWithCString:length:] andAttributes:[NSNumber numberWithUnsignedShort:] data:[NSData dataWithBytes:length:]];
if( !newResource ) return paramErr;
id windowController = [[HexWindowController alloc] initWithResource:newResource];
if( !windowController ) return paramErr;
else return noErr;
}
else return paramErr;
}
*/
@implementation HexWindowController
- (id)initWithResource:(id)newResource
@ -33,14 +49,14 @@
- (id)initWithResources:(id)newResource, ...
{
[undoManager release];
return nil;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[(id)resource release];
[(id)resource autorelease];
[undoManager release];
[super dealloc];
}

View File

@ -0,0 +1,12 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
CLASS = PictWindowController;
LANGUAGE = ObjC;
OUTLETS = {imageView = NSImageView; resource = id; };
SUPERCLASS = NSWindowController;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>445 178 356 240 0 0 1600 1002 </string>
<key>IBFramework Version</key>
<string>286.0</string>
<key>IBLockedObjects</key>
<array>
<integer>8</integer>
</array>
<key>IBSystem Version</key>
<string>6F21</string>
</dict>
</plist>

Binary file not shown.

View File

@ -0,0 +1,13 @@
#import <Cocoa/Cocoa.h>
#import "ResKnifePluginProtocol.h"
#import "ResKnifeResourceProtocol.h"
@interface PictWindowController : NSWindowController <ResKnifePluginProtocol>
{
IBOutlet NSImageView *imageView;
id <ResKnifeResourceProtocol> resource;
}
@end

View File

@ -0,0 +1,77 @@
#import "PictWindowController.h"
#import "Element.h"
#import <stdarg.h>
@implementation PictWindowController
- (id)initWithResource:(id)newResource
{
self = [self initWithWindowNibName:@"PictWindow"];
if( !self ) return nil;
resource = [newResource retain];
// load the window from the nib
[self window];
return self;
}
- (id)initWithResources:(id)newResource, ...
{
return nil;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[(id)resource autorelease];
[super dealloc];
}
- (void)windowDidLoad
{
[super windowDidLoad];
// set the window's title
if( ![[resource name] isEqualToString:@""] )
{
[[self window] setTitle:[resource name]];
SetWindowAlternateTitle( (WindowRef) [[self window] windowRef], (CFStringRef) [NSString stringWithFormat:@"%@ %@: Ò%@Ó", [resource type], [resource resID], [resource name]] );
}
NSImage *image = [[[NSImage alloc] initWithData:[resource data]] autorelease];
if( image )
{
// resize the window to the size of the image
[[self window] setContentSize:[image size]];
// update image view with PICT
[imageView setImage:image];
}
// 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];
// finally, show the window
[self showWindow:self];
}
- (void)resourceDataDidChange:(NSNotification *)notification
{
// ensure it's our resource which got changed (should always be true, we don't register for notifications on other resource objects)
if( [notification object] == (id)resource )
{
// refresh image
NSImage *image = [[[NSImage alloc] initWithData:[resource data]] autorelease];
if( image )
{
// resize the window to the size of the image
[[self window] setContentSize:[image size]];
// update image view with PICT
[imageView setImage:image];
}
}
}
@end

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>SupportedTypes</key>
<array>
<string>PICT</string>
</array>
</dict>
</plist>

View File

@ -23,6 +23,10 @@
<integer>5</integer>
</array>
<key>IBSystem Version</key>
<<<<<<< info.nib
<string>6F21</string>
=======
<string>6G30</string>
>>>>>>> 1.2
</dict>
</plist>

View File

@ -0,0 +1,233 @@
#include "HexUtility.h"
/**********************/
/* QUICKDRAW ROUTINES */
/**********************/
/*** SET COLOUR ***/
void SetColour( RGBColor *colour, UInt16 red, UInt16 green, UInt16 blue )
{
colour->red = red;
colour->green = green;
colour->blue = blue;
}
/*** MAKE LOCAL ***/
void MakeLocal( WindowRef window, Point globalPoint, Point *localPoint )
{
GrafPtr oldPort;
GetPort( &oldPort );
SetPortWindowPort( window );
localPoint->h = globalPoint.h;
localPoint->v = globalPoint.v;
GlobalToLocal( localPoint );
SetPort( oldPort );
}
/*** MAKE GLOBAL ***/
void MakeGlobal( WindowRef window, Point localPoint, Point *globalPoint )
{
GrafPtr oldPort;
GetPort( &oldPort );
SetPortWindowPort( window );
globalPoint->h = localPoint.h;
globalPoint->v = localPoint.v;
LocalToGlobal( globalPoint );
SetPort( oldPort );
}
/*****************************/
/* HEX <==> ASCII CONVERSION */
/*****************************/
/*** ASCII TO TEXT ***/
void AsciiToText( char *source, char *dest, unsigned long size )
{
char ascii = 0x00, text = 0x00;
unsigned long sourceOffset = 0, destOffset = 0;
while( sourceOffset < size )
{
ascii = *(source + sourceOffset);
if( ascii < 0x20 || ascii >= 0x7F ) text = (char) 0x2E; // full stop
else if( ascii == 0x20 ) text = (char) 0xCA; // nbsp
else text = ascii;
*(dest + destOffset++) = text;
sourceOffset++;
}
}
/*** ASCII TO HEX ***/
void AsciiToHex( char *source, char *dest, unsigned long size )
{
char hex1 = 0x00, hex2 = 0x00;
unsigned long sourceOffset = 0, destOffset = 0;
while( sourceOffset < size )
{
hex1 = *(source + sourceOffset);
hex2 = *(source + sourceOffset);
hex1 >>= 4;
hex1 &= 0x0F;
hex2 &= 0x0F;
hex1 += (hex1 < 10)? 0x30 : 0x37;
hex2 += (hex2 < 10)? 0x30 : 0x37;
*(dest + destOffset++) = hex1;
*(dest + destOffset++) = hex2;
*(dest + destOffset++) = 0x20;
sourceOffset++;
}
}
/*** HEX TO ASCII ***/
void HexToAscii( char *source, char *dest, unsigned long size )
{
char currentByte = 0x00, newByte = 0x00, tempByte = 0x00;
unsigned long sourceOffset = 0, destOffset = 0;
while( sourceOffset < size )
{
currentByte = *(source + sourceOffset);
if( currentByte >= 0x30 && currentByte <= 0x39 ) newByte = currentByte - 0x30; // 0 to 9
else if( currentByte >= 0x41 && currentByte <= 0x46 ) newByte = currentByte - 0x37; // A to F
else if( currentByte >= 0x61 && currentByte <= 0x66 ) newByte = currentByte - 0x57; // a to f
else newByte = 0x00;
newByte <<= 4;
currentByte = *(source + sourceOffset +1);
if( currentByte >= 0x30 && currentByte <= 0x39 ) tempByte = currentByte - 0x30; // 0 to 9
else if( currentByte >= 0x41 && currentByte <= 0x46 ) tempByte = currentByte - 0x37; // A to F
else if( currentByte >= 0x61 && currentByte <= 0x66 ) tempByte = currentByte - 0x57; // a to f
else tempByte = 0x00;
newByte += tempByte & 0x0F;
*(dest + destOffset++) = newByte;
sourceOffset += 3;
}
}
/*** LONG TO HEX ***/
void LongToHex( char *source, char *dest )
{
// copy of AsciiToHex but with changes as noted
char hex1 = 0x00, hex2 = 0x00;
unsigned long sourceOffset = 0, destOffset = 0;
while( sourceOffset < sizeof(unsigned long) ) // size is always four
{
hex1 = *(source + sourceOffset);
hex2 = *(source + sourceOffset);
hex1 >>= 4;
hex1 &= 0x0F;
hex2 &= 0x0F;
hex1 += (hex1 < 10)? 0x30 : 0x37;
hex2 += (hex2 < 10)? 0x30 : 0x37;
*(dest + destOffset++) = hex1;
*(dest + destOffset++) = hex2; // no space inserted
sourceOffset++;
}
}
/*******************/
/* STRING ROUTINES */
/*******************/
/*** C STRING LENGTH ***/
unsigned long CStringLength( char *string )
{
unsigned long length;
Boolean end = false;
for( length = 0; end == false; length++ )
if( *(string + length) == 0x00 ) end = true;
return length;
}
/*** PASCAL STRING LENGTH ***/
unsigned char PStringLength( unsigned char *string )
{
return *string;
}
/*** TYPE TO C STRING ***/
void TypeToCString( const OSType type, char *string )
{
BlockMoveData( &type, &string[0], sizeof(OSType) );
string[sizeof(OSType)] = 0x00;
}
/*** TYPE TO PASCAL STRING ***/
void TypeToPString( const OSType type, Str255 string )
{
string[0] = sizeof(OSType);
BlockMoveData( &type, &string[1], sizeof(OSType) );
}
/*** TYPE TO CORE FOUNDATION STRING ***/
void TypeToCFString( const OSType type, CFStringRef *string )
{
char cString[5];
TypeToCString( type, (char *) &cString );
*string = CFStringCreateWithCString( CFAllocatorGetDefault(), (char *) &cString, kCFStringEncodingMacRoman );
}
/*** COPY C STRING ***/
void CopyCString( UInt8 *source, UInt8 *dest )
{
// #pragma warning off
while( *dest++ = *source++ );
// #pragma warning reset
}
/*** COPY PASCAL STRING ***/
void CopyPString( UInt8 *source, UInt8 *dest )
{
UInt8 length = *source, count;
for( count = 0; count <= length; count++ )
*dest++ = *source++;
}
/*** EQUAL C STRINGS ***/
Boolean EqualCStrings( UInt8 *source, UInt8 *dest )
{
while( *source != 0x00 )
if( *source++ != *dest++ ) return false;
return true;
}
/*** EQUAL PASCAL STRINGS ***/
Boolean EqualPStrings( UInt8 *source, UInt8 *dest )
{
UInt8 length = *source, count;
for( count = 0; count <= length; count++ )
if( *source++ != *dest++ ) return false;
return true;
}
/*** APPEND ONE PASCAL STRING ONTO ANOTHER ***/
void AppendPString( Str255 original, ConstStr255Param added )
{
short numberBytes = added[0]; // length of string to be added
short totalLength = added[0] + original[0];
if( totalLength > 255 ) // too long, adjust number of bytes to add
{
totalLength = 255;
numberBytes = totalLength - original[0];
}
BlockMoveData( &added[1], &original[totalLength-numberBytes + 1], numberBytes );
original[0] = totalLength; // new length of original string
while( ++totalLength <= 255 )
original[totalLength] = 0x00; // set rest of string to zero
}
/*****************/
/* MENU ROUTINES */
/*****************/
/*** ENABLE MENU COMMAND ***/
void EnableCommand( MenuRef menu, MenuCommand command, Boolean enable )
{
if( enable ) EnableMenuCommand( menu, command );
else DisableMenuCommand( menu, command );
}

View File

@ -0,0 +1,31 @@
#include "Hex Editor.h"
#ifndef _ResKnife_HexEditor_Utility_
#define _ResKnife_HexEditor_Utility_
/* QuickDraw Routines */
void SetColour( RGBColor *colour, UInt16 red, UInt16 green, UInt16 blue );
void MakeLocal( WindowRef window, Point globalPoint, Point *localPoint );
void MakeGlobal( WindowRef window, Point localPoint, Point *globalPoint );
/* ASCII <=> hex */
void AsciiToText( char *source, char *dest, unsigned long size );
void AsciiToHex( char *source, char *dest, unsigned long size );
void HexToAscii( char *source, char *dest, unsigned long size );
void LongToHex( char *source, char *dest );
/* strings */
unsigned long CStringLength( char *string );
unsigned char PStringLength( unsigned char *string );
void TypeToCString( const OSType type, char *string );
void TypeToPString( const OSType type, Str255 string );
void TypeToCFString( const OSType type, CFStringRef *string );
void CopyCString( UInt8 *source, UInt8 *dest );
void CopyPString( UInt8 *source, UInt8 *dest );
Boolean EqualCStrings( UInt8 *source, UInt8 *dest );
Boolean EqualPStrings( UInt8 *source, UInt8 *dest );
void AppendPString( Str255 original, ConstStr255Param added );
void EnableCommand( MenuRef menu, MenuCommand command, Boolean enable );
#endif

1065
HexEditor.graffle Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,113 @@
#include "TemplateInitalisation.h"
#include "TemplateWindow.h"
globals g;
/*** INITALISE NEW EDITOR INSTANCE ***/
OSStatus Plug_InitInstance( Plug_PlugInRef plug, Plug_ResourceRef resource )
{
// get system version
OSStatus error = Gestalt( gestaltSystemVersion, &g.systemVersion );
if( error ) return error;
// check appearance availablilty
#if TARGET_API_MAC_CARBON
g.useAppearance = true;
#else
ProcessSerialNumber psn;
error = GetCurrentProcess( &psn );
if( error ) g.useAppearance = false;
else g.useAppearance = IsAppearanceClient( &psn );
#endif
// get template for resource
ResType type = Host_GetResourceType( resource );
Handle tmpl = Host_GetDefaultTemplate( type );
SInt32 size = GetHandleSize( tmpl ); // cannot be less than 5 (string length of zero, four char code)
if( tmpl == null || size < 5 ) return paramErr; // not the best error to return for this situation
// create window
Rect creationBounds;
WindowRef window;
SetRect( &creationBounds, 0, 0, kDefaultWindowWidth, kDefaultWindowHeight );
OffsetRect( &creationBounds, 8, 48 );
WindowAttributes attributes = kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute | kWindowInWindowMenuAttribute;
if( g.systemVersion >= kMacOSX ) attributes |= kWindowLiveResizeAttribute;
error = CreateNewWindow( kDocumentWindowClass, attributes, &creationBounds, &window );
Plug_WindowRef plugWindow = Host_RegisterWindow( plug, resource, window );
#if TARGET_API_MAC_CARBON
// install window event handler
EventHandlerRef ref = null;
EventHandlerUPP handler = NewEventHandlerUPP( CarbonWindowEventHandler );
EventTypeSpec events[] = { { kEventClassWindow, kEventWindowClose } };
InstallWindowEventHandler( window, handler, GetEventTypeCount(events), events, plug, &ref );
#else
ClassicEventHandlerUPP handler = NewClassicEventHandlerUPP( ClassicWindowEventHandler );
Host_InstallClassicWindowEventHandler( plugWindow, handler );
#endif
// set window's background to default for theme
if( g.useAppearance )
SetThemeWindowBackground( window, kThemeBrushModelessDialogBackgroundActive, false );
// cerate new template window class
TemplateWindowPtr templateWindow = new TemplateWindow( window );
Host_SetWindowRefCon( plugWindow, (UInt32) templateWindow );
// parse the resource data
Handle data = Host_GetResourceData( resource );
error = templateWindow->UseTemplate( tmpl ); // pass responsibility for disposing to the window
error = templateWindow->ParseData( data ); // parses the resource into an array of Elements
// show window
ShowWindow( window );
SelectWindow( window );
return error;
}
/*** ELEMENT CONSTRUCTOR ***/
Element::Element( void )
{
BlockZero( this, sizeof(Element) );
}
/*** CARBON WINDOW EVENT HANDLER ***/
pascal OSStatus CarbonWindowEventHandler( EventHandlerCallRef handler, EventRef event, void *userData )
{
#pragma unused( handler )
OSStatus error = eventNotHandledErr;
Plug_PlugInRef plugRef = (Plug_PlugInRef) userData;
WindowRef window = GetUserFocusWindow(); // overridden below for window class events
// get event type
UInt32 eventClass = GetEventClass( event );
UInt32 eventKind = GetEventKind( event );
// get event parameters
if( eventClass == kEventClassWindow )
GetEventParameter( event, kEventParamDirectObject, typeWindowRef, null, sizeof(WindowRef), null, &window );
if( !window ) return error;
Plug_WindowRef plugWindow = Host_GetPlugWindowFromWindowRef( window );
if( !plugWindow ) return error;
TemplateWindowPtr templateWindow = (TemplateWindowPtr) Host_GetWindowRefCon( plugWindow );
if( !templateWindow ) return error;
// get window rect
Rect windowBounds;
GetWindowPortBounds( window, &windowBounds );
// handle event
static EventHandlerRef resizeEventHandlerRef = null;
switch( eventClass )
{
case kEventClassWindow:
switch( eventKind )
{
case kEventWindowClose:
delete templateWindow;
break;
}
break;
}
return error;
}

View File

@ -0,0 +1 @@
#include "Template Editor.h" pascal OSStatus CarbonWindowEventHandler( EventHandlerCallRef handler, EventRef event, void *userData );