diff --git a/Carbon/Classes/Application.cpp b/Carbon/Classes/Application.cpp index 9f976f7..012fb20 100644 --- a/Carbon/Classes/Application.cpp +++ b/Carbon/Classes/Application.cpp @@ -968,7 +968,7 @@ Boolean GotRequiredParams( const AppleEvent *event ) DescType actualType; Size actualSize; - // check if we have retreived the required parameters + // check if we have retrieved the required parameters error = AEGetAttributePtr( event, keyMissedKeywordAttr, typeWildCard, &actualType, null, 0, &actualSize ); return error == errAEDescNotFound; } diff --git a/Carbon/Classes/Asynchronous.cpp b/Carbon/Classes/Asynchronous.cpp index 1844645..597fd0b 100644 --- a/Carbon/Classes/Asynchronous.cpp +++ b/Carbon/Classes/Asynchronous.cpp @@ -566,7 +566,7 @@ OSErr SHQueueCallback( SndChannel *channel ) // causes a crash if more than one SndPlay call is made on the same channel. Helper // will never do this on its own, and you shouldn't either. If you want a sound // channel that you want to send commands to, call SHPlayByHandle with a nil handle, -// then call SHGetChannel to retreive a pointer to the channel. +// then call SHGetChannel to retrieve a pointer to the channel. // //======================================================================================= OSErr SHBeginPlayback( SHOutPtr outRec ) diff --git a/Cocoa/Categories/NSOutlineView-SelectedItems.m b/Cocoa/Categories/NSOutlineView-SelectedItems.m index d768516..493f2d0 100644 --- a/Cocoa/Categories/NSOutlineView-SelectedItems.m +++ b/Cocoa/Categories/NSOutlineView-SelectedItems.m @@ -2,22 +2,31 @@ /* The methods in the following catagory were based upon those in OmniAppKit */ -@implementation NSOutlineView (ResKnifeSelectedItemExtensions) +@implementation NSOutlineView (RKSelectedItemExtensions) - (id)selectedItem { - if( [self numberOfSelectedRows] != 1 ) return nil; + if ([self numberOfSelectedRows] != 1) return nil; else return [self itemAtRow:[self selectedRow]]; } - (NSArray *)selectedItems { - NSNumber *row; NSMutableArray *items = [NSMutableArray array]; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3 + NSIndexSet *indicies = [self selectedRowIndexes]; + unsigned int rowIndex = [indicies firstIndex]; + while (rowIndex != NSNotFound) + { + [items addObject:[self itemAtRow:rowIndex]]; + rowIndex = [indicies indexGreaterThanIndex:rowIndex]; + } +#else + NSNumber *row; NSEnumerator *enumerator = [self selectedRowEnumerator]; - - while( row = [enumerator nextObject] ) + while (row = [enumerator nextObject]) [items addObject:[self itemAtRow:[row intValue]]]; +#endif return items; } diff --git a/Cocoa/Categories/NSString-FSSpec.m b/Cocoa/Categories/NSString-FSSpec.m index 267ac96..d0398eb 100644 --- a/Cocoa/Categories/NSString-FSSpec.m +++ b/Cocoa/Categories/NSString-FSSpec.m @@ -6,7 +6,7 @@ { // caller is responsible for disposing of the FSRef (method is a 'create' method) FSRef *fsRef = (FSRef *) NewPtrClear(sizeof(FSRef)); - OSStatus error = FSPathMakeRef([self fileSystemRepresentation], fsRef, NULL); + OSStatus error = FSPathMakeRef((unsigned char *)[self fileSystemRepresentation], fsRef, NULL); if(error == noErr) return fsRef; return NULL; @@ -17,7 +17,7 @@ // caller is responsible for disposing of the FSSpec (method is a 'create' method) FSRef *fsRef = (FSRef *) NewPtrClear(sizeof(FSRef)); FSSpec *fsSpec = (FSSpec *) NewPtrClear(sizeof(FSSpec)); - OSStatus error = FSPathMakeRef([self fileSystemRepresentation], fsRef, NULL); + OSStatus error = FSPathMakeRef((unsigned char *)[self fileSystemRepresentation], fsRef, NULL); if(error == noErr) { error = FSGetCatalogInfo(fsRef, kFSCatInfoNone, NULL, NULL, fsSpec, NULL); diff --git a/Cocoa/Classes/ApplicationDelegate.m b/Cocoa/Classes/ApplicationDelegate.m index 2c2ba86..3a938cc 100644 --- a/Cocoa/Classes/ApplicationDelegate.m +++ b/Cocoa/Classes/ApplicationDelegate.m @@ -65,6 +65,8 @@ - (void)precacheIcons:(NSTimer *)timer { // pre-cache a number of common icons (ignores return value, relies on iconForResourceType: to do the actual caching) + [self iconForResourceType:@" "]; + [self iconForResourceType:@"????"]; [self iconForResourceType:@"CODE"]; [self iconForResourceType:@"icns"]; [self iconForResourceType:@"PICT"]; @@ -231,70 +233,82 @@ @author Nicholas Shanks @created 2003-10-24 @abstract Manages the cache of icons used for representing resource types. -@description This method loads icons for each resource type from a variety of places and caches them for faster access. Your plug-in may be asked to return an icon for any resource type it declares it can edit. To implement this, your plug should respond to the iconForResourceType: selector with the same method signature as this method. The icons can be in any format recognised by NSImage. Alternativly, just leave your icons in "Your.plugin/Contents/Resources/Resource Type Icons/" (or any equivalent localised directory) with a name like "TYPE.tiff" and ResKnife will retreive them automatically. +@description This method loads icons for each resource type from a variety of places and caches them for faster access. Your plug-in may be asked to return an icon for any resource type it declares it can edit. To implement this, your plug should respond to the iconForResourceType: selector with the same method signature as this method. The icons can be in any format recognised by NSImage. Alternativly, just leave your icons in "Your.plugin/Contents/Resources/Resource Type Icons/" (or any equivalent localised directory) with a name like "TYPE.tiff" and ResKnife will retrieve them automatically. @pending I don't like the name I chose here for the resource type icons directory. Can anyone think of something better? */ - (NSImage *)iconForResourceType:(NSString *)resourceType { - // check if we have image in cache already NSImage *icon = nil; if([resourceType isEqualToString:@""]) resourceType = nil; - if(resourceType); - icon = [[self _icons] valueForKey:resourceType]; - if(!icon) + if(resourceType) { - NSString *iconPath = nil; + // check if we have image in cache already + icon = [[self _icons] objectForKey:resourceType]; // valueForKey: raises when the resourceType begins with '@' (e.g. the @GN4 owner resource from Gene!) - // try to load icon from the default editor for that type - Class editor = [[RKEditorRegistry defaultRegistry] editorForType:resourceType]; - if(editor && resourceType) + if(!icon) { - // ask politly for icon - if([editor respondsToSelector:@selector(iconForResourceType:)]) - icon = [editor iconForResourceType:resourceType]; + NSString *iconPath = nil; - // try getting it myself + // try to load icon from the default editor for that type + Class editor = [[RKEditorRegistry defaultRegistry] editorForType:resourceType]; + if(editor) + { + // ask politly for icon + if([editor respondsToSelector:@selector(iconForResourceType:)]) + icon = [editor iconForResourceType:resourceType]; + + // try getting it myself + if(!icon) + { + iconPath = [[NSBundle bundleForClass:editor] pathForResource:resourceType ofType:nil inDirectory:@"Resource Type Icons"]; + if(iconPath) + icon = [[[NSImage alloc] initWithContentsOfFile:iconPath] autorelease]; + } + } + + // try to load icon from the ResKnife app bundle itself if(!icon) { - iconPath = [[NSBundle bundleForClass:editor] pathForResource:resourceType ofType:nil inDirectory:@"Resource Type Icons"]; + iconPath = [[NSBundle mainBundle] pathForResource:resourceType ofType:nil inDirectory:@"Resource Type Icons"]; if(iconPath) icon = [[[NSImage alloc] initWithContentsOfFile:iconPath] autorelease]; } - } - - // try to load icon from the ResKnife app bundle itself - if(!icon && resourceType) - { - iconPath = [[NSBundle mainBundle] pathForResource:resourceType ofType:nil inDirectory:@"Resource Type Icons"]; - if(iconPath) - icon = [[[NSImage alloc] initWithContentsOfFile:iconPath] autorelease]; - } - - // try to retreive from file system (after first mangling the type through our converter strings file) - if(!icon && resourceType) - { - NSString *fileType = [[NSBundle mainBundle] localizedStringForKey:resourceType value:@"" table:@"Resource Type Mappings"]; - NSRange range = [fileType rangeOfString:@"."]; - if(range.location == NSNotFound) - icon = [[NSWorkspace sharedWorkspace] iconForFileType:fileType]; - else // a '.' character in a file type means ResKnife should look for a bundle icon with fileType as the bundle's identifier + + // try to retrieve from file system using our resource type to file name extension/bundle identifier code + if(!icon) { - NSString *bundlePath = [[NSBundle bundleWithIdentifier:fileType] bundlePath]; - if(bundlePath) - icon = [[NSWorkspace sharedWorkspace] iconForFile:bundlePath]; + NSString *fileType = [[NSBundle mainBundle] localizedStringForKey:resourceType value:@"" table:@"Resource Type Mappings"]; + NSRange range = [fileType rangeOfString:@"."]; + if(range.location == NSNotFound) + icon = [[NSWorkspace sharedWorkspace] iconForFileType:fileType]; + else // a '.' character in a file type means ResKnife should look for a bundle icon with fileType as the bundle's identifier + { + NSString *bundlePath = [[NSBundle bundleWithIdentifier:fileType] bundlePath]; + if(bundlePath) + icon = [[NSWorkspace sharedWorkspace] iconForFile:bundlePath]; + } } + + // TODO: convert to a UTI and try that + + // try to retrieve from file system as an OSType code + if(!icon) + icon = [[NSWorkspace sharedWorkspace] iconForFileType:[NSString stringWithFormat:@"'%@'", resourceType]]; + + // save the newly retrieved icon in the cache + if(icon) + [[self _icons] setObject:icon forKey:resourceType]; } - - // if we still don't have an icon, try to get the generic one - this is what icon represented forks get - if(!icon) - icon = [[NSWorkspace sharedWorkspace] iconForFileType:@"????"]; - - // save the newly retreived icon in the cache - if(icon && resourceType) - [[self _icons] setObject:icon forKey:resourceType]; + } + else + { + // we have no resource type, try to get a generic icon - this is what icon represented forks get +// if(!icon) icon = [NSImage imageNamed:@"NSMysteryDocument"]; +// if(!icon) icon = [[NSWorkspace sharedWorkspace] iconForFileType:@"' '"]; + if(!icon) icon = [[NSWorkspace sharedWorkspace] iconForFileType:[NSString stringWithFormat:@"'%@'", @"????"]]; } // return the cached icon, or nil if none was found diff --git a/Cocoa/Classes/InfoWindowController.m b/Cocoa/Classes/InfoWindowController.m index e88fa49..1e19602 100644 --- a/Cocoa/Classes/InfoWindowController.m +++ b/Cocoa/Classes/InfoWindowController.m @@ -36,9 +36,9 @@ /*! @method updateInfoWindow -@change 2003-11-06 NS: Fixed creator/type handling. -@change 2003-10-26 NS: Now asks app delegate for icon instead of NSWorkspace. -@change 2003-10-26 NS: Improved document name & icon display. +@updated 2003-11-06 NGS: Fixed creator/type handling. +@updated 2003-10-26 NGS: Now asks app delegate for icon instead of NSWorkspace. +@updated 2003-10-26 NGS: Improved document name & icon display. */ - (void)updateInfoWindow @@ -48,6 +48,8 @@ if(selectedResource) { + NSLog(@"selected resource data: %@", [selectedResource data]); + // set UI values [[self window] setTitle:NSLocalizedString(@"Resource Info",nil)]; [nameView setStringValue:[selectedResource name]]; @@ -86,8 +88,8 @@ [iconView setImage:[NSImage imageNamed:@"Resource file"]]; [nameView setStringValue:[currentDocument displayName]]; } - [currentDocument creator]; - [[NSString alloc] initWithData:[currentDocument creator] encoding:NSMacOSRomanStringEncoding]; + + #warning FIXME: the creator and type codes need to be swapped on intel [[filePropertyForm cellAtIndex:0] setStringValue:[[[NSString alloc] initWithData:[currentDocument creator] encoding:NSMacOSRomanStringEncoding] autorelease]]; [[filePropertyForm cellAtIndex:1] setStringValue:[[[NSString alloc] initWithData:[currentDocument type] encoding:NSMacOSRomanStringEncoding] autorelease]]; // [[filePropertyForm cellAtIndex:2] setObjectValue:[NSNumber numberWithUnsignedLongLong:dataLogicalSize]]; @@ -101,7 +103,7 @@ else { [iconView setImage:nil]; - [nameView setStringValue:nil]; + [nameView setStringValue:@""]; [placeholderView setContentView:nil]; } } diff --git a/Cocoa/Classes/ResourceDocument.mm b/Cocoa/Classes/ResourceDocument.mm index a9950fd..bf1ac94 100644 --- a/Cocoa/Classes/ResourceDocument.mm +++ b/Cocoa/Classes/ResourceDocument.mm @@ -250,13 +250,12 @@ extern NSString *RKResourcePboardType; for(unsigned short i = 1; i <= Count1Types(); i++) { - ResType resType; - Get1IndType(&resType, i); - ResType swappedType = EndianS32_NtoB(resType); // Swapped type for use as string (types are treated as numbers by the resource manager and swapped on Intel). - unsigned short n = Count1Resources(resType); + ResType resTypeCode; + Get1IndType(&resTypeCode, i); + unsigned short n = Count1Resources(resTypeCode); for(unsigned short j = 1; j <= n; j++) { - Handle resourceHandle = Get1IndResource(resType, j); + Handle resourceHandle = Get1IndResource(resTypeCode, j); error = ResError(); if(error != noErr) { @@ -267,21 +266,33 @@ extern NSString *RKResourcePboardType; Str255 nameStr; short resIDShort; - GetResInfo(resourceHandle, &resIDShort, &resType, nameStr); - long sizeLong = GetResourceSizeOnDisk(resourceHandle); + GetResInfo(resourceHandle, &resIDShort, &resTypeCode, nameStr); + long sizeLong = GetResourceSizeOnDisk(resourceHandle), badSize = 0; + if (sizeLong < 0 || sizeLong > 16777215) // the max size of resource manager file is ~12 MB; I am rounding up to three bytes + { + // this only happens when opening ResEdit using the x86 binary (not under Rosetta, for example) + badSize = sizeLong; + sizeLong = EndianS32_BtoL(sizeLong); + } short attrsShort = GetResAttrs(resourceHandle); HLockHi(resourceHandle); +#if __LITTLE_ENDIAN__ + CoreEndianFlipData(kCoreEndianResourceManagerDomain, resTypeCode, resIDShort, *resourceHandle, sizeLong, true); +#endif // cool: "The advantage of obtaining a methodŐs implementation and calling it as a function is that you can invoke the implementation multiple times within a loop, or similar C construct, without the overhead of Objective-C messaging." // create the resource & add it to the array + ResType logicalType = EndianS32_NtoB(resTypeCode); // swapped type for use as string (types are treated as numbers by the resource manager and swapped on Intel). NSString *name = [[NSString alloc] initWithBytes:&nameStr[1] length:nameStr[0] encoding:NSMacOSRomanStringEncoding]; - NSString *resType = [[NSString alloc] initWithBytes:(char *) &swappedType length:4 encoding:NSMacOSRomanStringEncoding]; + NSString *resType = [[NSString alloc] initWithBytes:(char *) &logicalType length:4 encoding:NSMacOSRomanStringEncoding]; NSNumber *resID = [NSNumber numberWithShort:resIDShort]; NSNumber *attributes = [NSNumber numberWithShort:attrsShort]; NSData *data = [NSData dataWithBytes:*resourceHandle length:sizeLong]; Resource *resource = [Resource resourceOfType:resType andID:resID withName:name andAttributes:attributes data:data]; [resources addObject:resource]; // array retains resource + if (badSize != 0) + NSLog(@"GetResourceSizeOnDisk() reported incorrect size for %@ resource %@ in %@: %li should be %li", resType, resID, [self displayName], badSize, sizeLong); [name release]; [resType release]; @@ -296,8 +307,8 @@ extern NSString *RKResourcePboardType; } /*! -@pending Uli's changed this routine - see what I had and unify the two -@pending Doesn't write correct type/creator info - always ResKnife's! +@pending Uli has changed this routine - see what I had and unify the two +@pending Doesn't write correct type/creator info - always ResKnife's! */ - (BOOL)writeToFile:(NSString *)fileName ofType:(NSString *)type @@ -406,32 +417,39 @@ extern NSString *RKResourcePboardType; while(Resource *resource = [enumerator nextObject]) { Str255 nameStr; - char resType[5]; // includes null char for getCString: + ResType resTypeCode; + char resTypeStr[5]; // includes null char for getCString: short resIDShort; short attrsShort; + long sizeLong; Handle resourceHandle; // if the resource represents another fork in the file, skip it if([resource representedFork] != nil) continue; + sizeLong = [[resource data] length]; resIDShort = [[resource resID] shortValue]; attrsShort = [[resource attributes] shortValue]; - resourceHandle = NewHandleClear([[resource data] length]); + resourceHandle = NewHandleClear(sizeLong); // convert unicode name to pascal string nameStr[0] = [[resource name] lengthOfBytesUsingEncoding:NSMacOSRomanStringEncoding]; BlockMoveData([[resource name] cStringUsingEncoding:NSMacOSRomanStringEncoding], &nameStr[1], nameStr[0]); // convert type string to ResType - [[resource type] getCString:resType maxLength:4]; + [[resource type] getCString:resTypeStr maxLength:4]; + resTypeCode = CFSwapInt32HostToBig(*(ResType *)resTypeStr); // convert NSData to resource handle HLockHi(resourceHandle); [[resource data] getBytes:*resourceHandle]; +#if __LITTLE_ENDIAN__ + CoreEndianFlipData(kCoreEndianResourceManagerDomain, resTypeCode, resIDShort, *resourceHandle, sizeLong, false); +#endif HUnlock(resourceHandle); // now that everything's converted, tell the resource manager we want to create this resource - AddResource(resourceHandle, *(ResType *)resType, resIDShort, nameStr); + AddResource(resourceHandle, resTypeCode, resIDShort, nameStr); if(ResError() == addResFailed) { NSLog(@"*Saving failed*; could not add resource ID %@ of type %@ to file.", [resource resID], [resource type]); diff --git a/Cocoa/English.lproj/InfoPlist.strings b/Cocoa/English.lproj/InfoPlist.strings index 0c3a28f..010ccd6 100644 Binary files a/Cocoa/English.lproj/InfoPlist.strings and b/Cocoa/English.lproj/InfoPlist.strings differ diff --git a/Cocoa/Info.plist b/Cocoa/Info.plist index b765b4e..8d2b4aa 100644 --- a/Cocoa/Info.plist +++ b/Cocoa/Info.plist @@ -10,15 +10,18 @@ CFBundleTypeExtensions rsrc + * CFBundleTypeIconFile Resource file.icns CFBundleTypeName - com.apple.resource-map + ResourceMap CFBundleTypeOSTypes rsrc RSRC + ???? + **** CFBundleTypeRole Editor @@ -29,27 +32,6 @@ NSDocumentClass ResourceDocument - - CFBundleTypeExtensions - - * - - CFBundleTypeOSTypes - - **** - ???? - - CFBundleTypeName - public.data - CFBundleTypeRole - Editor - LSItemContentTypes - - public.data - - NSDocumentClass - ResourceDocument - CFBundleExecutable ResKnife Cocoa @@ -66,11 +48,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.6 beta 4 + 0.6 cvs CFBundleSignature ResK CFBundleVersion - 18 + 19 NSAppleScriptEnabled NSMainNibFile diff --git a/Cocoa/Plug-Ins/Hex Editor/HexWindowController.mm b/Cocoa/Plug-Ins/Hex Editor/HexWindowController.mm index 7b3a77c..daa669d 100644 --- a/Cocoa/Plug-Ins/Hex Editor/HexWindowController.mm +++ b/Cocoa/Plug-Ins/Hex Editor/HexWindowController.mm @@ -143,7 +143,7 @@ OSStatus Plug_InitInstance(Plug_PlugInRef plug, Plug_ResourceRef resource) { if([[self window] isDocumentEdited]) { - NSBeginAlertSheet(@"Do you want to keep the changes you made to this resource?", @"Keep", @"DonŐt Keep", @"Cancel", sender, self, @selector(saveSheetDidClose:returnCode:contextInfo:), nil, nil, @"Your changes cannot be saved later if you don't keep them."); + NSBeginAlertSheet(@"Do you want to keep the changes you made to this resource?", @"Keep", @"Don't Keep", @"Cancel", sender, self, @selector(saveSheetDidClose:returnCode:contextInfo:), nil, nil, @"Your changes cannot be saved later if you don't keep them."); return NO; } else return YES; diff --git a/Cocoa/Plug-Ins/ResKnifePluginProtocol.h b/Cocoa/Plug-Ins/ResKnifePluginProtocol.h index cfebce1..0641118 100644 --- a/Cocoa/Plug-Ins/ResKnifePluginProtocol.h +++ b/Cocoa/Plug-Ins/ResKnifePluginProtocol.h @@ -78,4 +78,10 @@ + (NSString *)filenameExtensionForFileExport:(id )resource; +/*! +@@method iconForResourceType: +@abstract Returns the icon to be used throughout the UI for any given resource type. +*/ +- (NSImage *)iconForResourceType:(NSString *)resourceType; + @end diff --git a/Cocoa/Plug-Ins/ResKnifeResourceProtocol.h b/Cocoa/Plug-Ins/ResKnifeResourceProtocol.h index 3e5c98b..2f1983e 100644 --- a/Cocoa/Plug-Ins/ResKnifeResourceProtocol.h +++ b/Cocoa/Plug-Ins/ResKnifeResourceProtocol.h @@ -41,7 +41,7 @@ - (void)setData:(NSData *)newData; - (NSString *)defaultWindowTitle; -- (NSDocument *)document; +- (NSDocument *)document; // Owner of this resource. Useful for looking for resources in same file as yours. // These methods are used to retrieve resources other than the one you're editing. // Passing a document of nil will indicate to search in all open documents. @@ -56,6 +56,8 @@ @end + +// See note in Notifications.m about usage of these extern NSString *ResourceWillChangeNotification; extern NSString *ResourceNameWillChangeNotification; extern NSString *ResourceTypeWillChangeNotification; diff --git a/Cocoa/Plug-Ins/Template Editor/ElementDBYT.m b/Cocoa/Plug-Ins/Template Editor/ElementDBYT.m index c4a4a2f..827de0b 100644 --- a/Cocoa/Plug-Ins/Template Editor/ElementDBYT.m +++ b/Cocoa/Plug-Ins/Template Editor/ElementDBYT.m @@ -1,5 +1,7 @@ #import "ElementDBYT.h" +#define SIZE_ON_DISK (1) + @implementation ElementDBYT - (id)copyWithZone:(NSZone *)zone @@ -11,17 +13,17 @@ - (void)readDataFrom:(TemplateStream *)stream { - [stream readAmount:sizeof(value) toBuffer:&value]; + [stream readAmount:SIZE_ON_DISK toBuffer:&value]; } - (unsigned int)sizeOnDisk { - return sizeof(value); + return SIZE_ON_DISK; } - (void)writeDataTo:(TemplateStream *)stream { - [stream writeAmount:sizeof(value) fromBuffer:&value]; + [stream writeAmount:SIZE_ON_DISK fromBuffer:&value]; } - (void)setValue:(SInt8)v diff --git a/Cocoa/Plug-Ins/Template Editor/ElementDLLG.m b/Cocoa/Plug-Ins/Template Editor/ElementDLLG.m index 51a2411..868e994 100644 --- a/Cocoa/Plug-Ins/Template Editor/ElementDLLG.m +++ b/Cocoa/Plug-Ins/Template Editor/ElementDLLG.m @@ -1,5 +1,7 @@ #import "ElementDLLG.h" +#define SIZE_ON_DISK (8) + @implementation ElementDLLG - (id)copyWithZone:(NSZone*)zone @@ -11,17 +13,20 @@ - (void)readDataFrom:(TemplateStream *)stream { - [stream readAmount:sizeof(value) toBuffer:&value]; + SInt64 tmp; + [stream readAmount:SIZE_ON_DISK toBuffer:&tmp]; + value = CFSwapInt64BigToHost(tmp); } - (unsigned int)sizeOnDisk { - return sizeof(value); + return SIZE_ON_DISK; } - (void)writeDataTo:(TemplateStream *)stream { - [stream writeAmount:sizeof(value) fromBuffer:&value]; + SInt64 tmp = CFSwapInt64HostToBig(value); + [stream writeAmount:SIZE_ON_DISK fromBuffer:&tmp]; } - (void)setValue:(SInt64)v diff --git a/Cocoa/Plug-Ins/Template Editor/ElementDLNG.m b/Cocoa/Plug-Ins/Template Editor/ElementDLNG.m index edb5380..738d7e0 100644 --- a/Cocoa/Plug-Ins/Template Editor/ElementDLNG.m +++ b/Cocoa/Plug-Ins/Template Editor/ElementDLNG.m @@ -1,5 +1,7 @@ #import "ElementDLNG.h" +#define SIZE_ON_DISK (4) + @implementation ElementDLNG - (id)copyWithZone:(NSZone *)zone @@ -11,17 +13,20 @@ - (void)readDataFrom:(TemplateStream *)stream { - [stream readAmount:sizeof(value) toBuffer:&value]; + SInt32 tmp; + [stream readAmount:SIZE_ON_DISK toBuffer:&tmp]; + value = CFSwapInt32BigToHost(tmp); } - (unsigned int)sizeOnDisk { - return sizeof(value); + return SIZE_ON_DISK; } - (void)writeDataTo:(TemplateStream *)stream { - [stream writeAmount:sizeof(value) fromBuffer:&value]; + SInt32 tmp = CFSwapInt32HostToBig(value); + [stream writeAmount:SIZE_ON_DISK fromBuffer:&tmp]; } - (void)setValue:(SInt32)v diff --git a/Cocoa/Plug-Ins/Template Editor/ElementDWRD.m b/Cocoa/Plug-Ins/Template Editor/ElementDWRD.m index 6051e11..c6324c8 100644 --- a/Cocoa/Plug-Ins/Template Editor/ElementDWRD.m +++ b/Cocoa/Plug-Ins/Template Editor/ElementDWRD.m @@ -1,5 +1,7 @@ #import "ElementDWRD.h" +#define SIZE_ON_DISK (2) + @implementation ElementDWRD - (id)copyWithZone:(NSZone *)zone @@ -11,17 +13,20 @@ - (void)readDataFrom:(TemplateStream *)stream { - [stream readAmount:sizeof(value) toBuffer:&value]; + SInt16 tmp; + [stream readAmount:SIZE_ON_DISK toBuffer:&tmp]; + value = CFSwapInt16BigToHost(tmp); } - (unsigned int)sizeOnDisk { - return sizeof(value); + return SIZE_ON_DISK; } - (void)writeDataTo:(TemplateStream *)stream { - [stream writeAmount:sizeof(value) fromBuffer:&value]; + SInt16 tmp = CFSwapInt16HostToBig(value); + [stream writeAmount:SIZE_ON_DISK fromBuffer:&tmp]; } - (void)setValue:(SInt16)v diff --git a/Cocoa/Plug-Ins/Template Editor/ElementOCNT.m b/Cocoa/Plug-Ins/Template Editor/ElementOCNT.m index 69d3a9f..e6a3c00 100644 --- a/Cocoa/Plug-Ins/Template Editor/ElementOCNT.m +++ b/Cocoa/Plug-Ins/Template Editor/ElementOCNT.m @@ -19,6 +19,7 @@ if ([type isEqualToString:@"LCNT"] || [type isEqualToString:@"LZCT"]) [stream readAmount:4 toBuffer:&value]; else if([type isEqualToString:@"BCNT"] || [type isEqualToString:@"BZCT"]) [stream readAmount:1 toBuffer:(char *)(&value)+3]; else [stream readAmount:2 toBuffer:(short *)(&value)+1]; + value = CFSwapInt32BigToHost(value); if([self countFromZero]) value += 1; } @@ -32,9 +33,10 @@ - (void)writeDataTo:(TemplateStream *)stream { if([self countFromZero]) value -= 1; - if ([type isEqualToString:@"LCNT"] || [type isEqualToString:@"LZCT"]) [stream writeAmount:4 fromBuffer:&value]; - else if([type isEqualToString:@"BCNT"] || [type isEqualToString:@"BZCT"]) [stream writeAmount:1 fromBuffer:(char *)(&value)+3]; - else [stream writeAmount:2 fromBuffer:(short *)(&value)+1]; + unsigned long tmp = CFSwapInt32HostToBig(value); + if ([type isEqualToString:@"LCNT"] || [type isEqualToString:@"LZCT"]) [stream writeAmount:4 fromBuffer:&tmp]; + else if([type isEqualToString:@"BCNT"] || [type isEqualToString:@"BZCT"]) [stream writeAmount:1 fromBuffer:(char *)(&tmp)+3]; + else [stream writeAmount:2 fromBuffer:(short *)(&tmp)+1]; if([self countFromZero]) value += 1; } diff --git a/Cocoa/Plug-Ins/Template Editor/ElementPSTR.m b/Cocoa/Plug-Ins/Template Editor/ElementPSTR.m index d493d0a..77ba58f 100644 --- a/Cocoa/Plug-Ins/Template Editor/ElementPSTR.m +++ b/Cocoa/Plug-Ins/Template Editor/ElementPSTR.m @@ -51,7 +51,11 @@ if(_lengthBytes > 0) { [stream readAmount:_lengthBytes toBuffer:&length]; +#if __BIG_ENDIAN__ length >>= (4 - _lengthBytes) << 3; +#else + #warning FIXME: This probably doesn't work for WSTR and LSTR on intel machines +#endif } if(_terminatingByte) length += [stream bytesToNull]; @@ -72,8 +76,8 @@ // skip over empty bytes if(_terminatingByte) [stream advanceAmount:1 pad:NO]; - if(_pad == kPadToOddLength && (length + _lengthBytes) % 2 == 0) [stream advanceAmount:1 pad:NO]; - if(_pad == kPadToEvenLength && (length + _lengthBytes) % 2 == 1) [stream advanceAmount:1 pad:NO]; + if(_pad == kPadToOddLength && (length + _terminatingByte ? 1:0) % 2 == 0) [stream advanceAmount:1 pad:NO]; + if(_pad == kPadToEvenLength && (length + _terminatingByte ? 1:0) % 2 == 1) [stream advanceAmount:1 pad:NO]; // alignment unhandled here } @@ -97,22 +101,30 @@ // write string UInt32 length = [value length], writeLength; if(_maxLength && length > _maxLength) length = _maxLength; +#if __BIG_ENDIAN__ writeLength = length << ((4 - _lengthBytes) << 3); +#else + #warning FIXME: This probably doesn't work for WSTR and LSTR on intel machines +#endif if(_lengthBytes) [stream writeAmount:_lengthBytes fromBuffer:&writeLength]; - #warning FIXME: This code should display a warning saying that the string in the PSTR is not MacOSRoman - if([value respondsToSelector:@selector(cStringUsingEncoding:)]) + if ([value canBeConvertedToEncoding:NSMacOSRomanStringEncoding]) { - const void *buffer = [value cStringUsingEncoding:NSMacOSRomanStringEncoding]; + const void *buffer = NULL; + if([value respondsToSelector:@selector(cStringUsingEncoding:)]) // 10.4 + buffer = [value cStringUsingEncoding:NSMacOSRomanStringEncoding]; + else + { + NSData *data = [value dataUsingEncoding:NSMacOSRomanStringEncoding]; + buffer = [data bytes]; + } if(buffer) [stream writeAmount:length fromBuffer:buffer]; else [stream advanceAmount:length pad:YES]; } else { - const void *buffer = [value cString]; - if(buffer) [stream writeAmount:length fromBuffer:buffer]; - else [stream advanceAmount:length pad:YES]; + #warning FIXME: This code should display a warning saying that the string in the PSTR is not MacOSRoman } // pad to minimum length with spaces diff --git a/Cocoa/Plug-Ins/Template Editor/ElementUBYT.m b/Cocoa/Plug-Ins/Template Editor/ElementUBYT.m index 1b74f85..433fc15 100644 --- a/Cocoa/Plug-Ins/Template Editor/ElementUBYT.m +++ b/Cocoa/Plug-Ins/Template Editor/ElementUBYT.m @@ -1,5 +1,7 @@ #import "ElementUBYT.h" +#define SIZE_ON_DISK (1) + @implementation ElementUBYT - (id)copyWithZone:(NSZone *)zone @@ -11,17 +13,17 @@ - (void)readDataFrom:(TemplateStream *)stream { - [stream readAmount:sizeof(value) toBuffer:&value]; + [stream readAmount:SIZE_ON_DISK toBuffer:&value]; } - (unsigned int)sizeOnDisk { - return sizeof(value); + return SIZE_ON_DISK; } - (void)writeDataTo:(TemplateStream *)stream { - [stream writeAmount:sizeof(value) fromBuffer:&value]; + [stream writeAmount:SIZE_ON_DISK fromBuffer:&value]; } - (void)setValue:(UInt8)v diff --git a/Cocoa/Plug-Ins/Template Editor/ElementULLG.m b/Cocoa/Plug-Ins/Template Editor/ElementULLG.m index 4b1a83d..94d7c8d 100644 --- a/Cocoa/Plug-Ins/Template Editor/ElementULLG.m +++ b/Cocoa/Plug-Ins/Template Editor/ElementULLG.m @@ -1,5 +1,7 @@ #import "ElementULLG.h" +#define SIZE_ON_DISK (8) + @implementation ElementULLG - (id)copyWithZone:(NSZone*)zone @@ -11,17 +13,20 @@ - (void)readDataFrom:(TemplateStream *)stream { - [stream readAmount:sizeof(value) toBuffer:&value]; + UInt64 tmp; + [stream readAmount:SIZE_ON_DISK toBuffer:&tmp]; + value = CFSwapInt64BigToHost(tmp); } - (unsigned int)sizeOnDisk { - return sizeof(value); + return SIZE_ON_DISK; } - (void)writeDataTo:(TemplateStream *)stream { - [stream writeAmount:sizeof(value) fromBuffer:&value]; + UInt64 tmp = CFSwapInt64HostToBig(value); + [stream writeAmount:SIZE_ON_DISK fromBuffer:&tmp]; } - (void)setValue:(UInt64)v diff --git a/Cocoa/Plug-Ins/Template Editor/ElementULNG.m b/Cocoa/Plug-Ins/Template Editor/ElementULNG.m index 015a396..f81960a 100644 --- a/Cocoa/Plug-Ins/Template Editor/ElementULNG.m +++ b/Cocoa/Plug-Ins/Template Editor/ElementULNG.m @@ -1,5 +1,7 @@ #import "ElementULNG.h" +#define SIZE_ON_DISK (4) + @implementation ElementULNG - (id)copyWithZone:(NSZone *)zone @@ -11,17 +13,20 @@ - (void)readDataFrom:(TemplateStream *)stream { - [stream readAmount:sizeof(value) toBuffer:&value]; + UInt32 tmp; + [stream readAmount:SIZE_ON_DISK toBuffer:&tmp]; + value = CFSwapInt32BigToHost(tmp); } - (unsigned int)sizeOnDisk { - return sizeof(value); + return SIZE_ON_DISK; } - (void)writeDataTo:(TemplateStream *)stream { - [stream writeAmount:sizeof(value) fromBuffer:&value]; + UInt32 tmp = CFSwapInt32HostToBig(value); + [stream writeAmount:SIZE_ON_DISK fromBuffer:&tmp]; } - (void)setValue:(UInt32)v diff --git a/Cocoa/Plug-Ins/Template Editor/ElementUWRD.m b/Cocoa/Plug-Ins/Template Editor/ElementUWRD.m index 640a580..21a8f54 100644 --- a/Cocoa/Plug-Ins/Template Editor/ElementUWRD.m +++ b/Cocoa/Plug-Ins/Template Editor/ElementUWRD.m @@ -1,5 +1,7 @@ #import "ElementUWRD.h" +#define SIZE_ON_DISK (2) + @implementation ElementUWRD - (id)copyWithZone:(NSZone *)zone @@ -11,17 +13,20 @@ - (void)readDataFrom:(TemplateStream *)stream { - [stream readAmount:sizeof(value) toBuffer:&value]; + UInt16 tmp; + [stream readAmount:SIZE_ON_DISK toBuffer:&tmp]; + value = CFSwapInt16BigToHost(tmp); } - (unsigned int)sizeOnDisk { - return sizeof(value); + return SIZE_ON_DISK; } - (void)writeDataTo:(TemplateStream *)stream { - [stream writeAmount:sizeof(value) fromBuffer:&value]; + UInt16 tmp = CFSwapInt16HostToBig(value); + [stream writeAmount:SIZE_ON_DISK fromBuffer:&tmp]; } - (void)setValue:(UInt16)v diff --git a/Cocoa/Plug-Ins/Template Editor/English.lproj/Localizable.strings b/Cocoa/Plug-Ins/Template Editor/English.lproj/Localizable.strings index f01b20f..f30a9bc 100644 --- a/Cocoa/Plug-Ins/Template Editor/English.lproj/Localizable.strings +++ b/Cocoa/Plug-Ins/Template Editor/English.lproj/Localizable.strings @@ -5,7 +5,8 @@ "Error: Hex Dump" = "Error: Dumping Hex"; /* Keep changes dialog */ -"Do you want to keep the changes you made to this resource?" = "Do you want to keep the changes you made to this resource?"; -"Keep" = "Keep"; -"Don't Keep" = "Don’t Keep"; -"Your changes cannot be saved later if you don't keep them." = "Your changes cannot be saved later if you don’t keep them."; \ No newline at end of file +"KeepChangesDialogTitle" = "Do you want to keep the changes you made to this resource?"; +"KeepChangesDialogMessage" = "Your changes cannot be saved later if you don’t keep them."; +"KeepChangesButton" = "Keep"; +"DiscardChangesButton" = "Discard"; +"CancelButton" = "Cancel"; diff --git a/Cocoa/Plug-Ins/Template Editor/Info.plist b/Cocoa/Plug-Ins/Template Editor/Info.plist index 8bdecc2..e67a2ac 100644 --- a/Cocoa/Plug-Ins/Template Editor/Info.plist +++ b/Cocoa/Plug-Ins/Template Editor/Info.plist @@ -1,5 +1,5 @@ - + CFBundleDevelopmentRegion @@ -15,7 +15,7 @@ CFBundleSignature ResK CFBundleVersion - 3 + 4 NSPrincipalClass TemplateWindowController RKSupportedTypes diff --git a/Cocoa/Plug-Ins/Template Editor/TemplateStream.h b/Cocoa/Plug-Ins/Template Editor/TemplateStream.h index b8b84e6..4af5841 100644 --- a/Cocoa/Plug-Ins/Template Editor/TemplateStream.h +++ b/Cocoa/Plug-Ins/Template Editor/TemplateStream.h @@ -1,6 +1,6 @@ #import -@class Element; +@class Element, ElementOCNT; @interface TemplateStream : NSObject { char *data; @@ -18,8 +18,8 @@ - (char *)data; - (unsigned int)bytesToGo; - (void)setBytesToGo:(unsigned int)b; -- (Element *)counter; -- (void)pushCounter:(Element *)c; +- (ElementOCNT *)counter; +- (void)pushCounter:(ElementOCNT *)c; - (void)popCounter; - (Element *)key; - (void)pushKey:(Element *)k; diff --git a/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.m b/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.m index f691ae4..48c077d 100644 --- a/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.m +++ b/Cocoa/Plug-Ins/Template Editor/TemplateWindowController.m @@ -126,7 +126,7 @@ BOOL pushedCounter = NO; BOOL pushedKey = NO; if(cc == [ElementOCNT class]) - { [stream pushCounter:clone]; pushedCounter = YES; } + { [stream pushCounter:(ElementOCNT *)clone]; pushedCounter = YES; } if(cc == [ElementKBYT class] || cc == [ElementKWRD class] || cc == [ElementKLNG class] ) @@ -156,7 +156,8 @@ if([[self window] isDocumentEdited]) { - NSBeginAlertSheet(NSLocalizedString(@"Do you want to keep the changes you made to this resource?", nil), NSLocalizedString(@"Keep", nil), NSLocalizedString(@"Don't Keep", nil), NSLocalizedString(@"Cancel", nil), sender, self, @selector(saveSheetDidClose:returnCode:contextInfo:), nil, nil, NSLocalizedString(@"Your changes cannot be saved later if you don't keep them.", nil)); + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSBeginAlertSheet(NSLocalizedStringFromTableInBundle(@"KeepChangesDialogTitle", nil, bundle, nil), NSLocalizedStringFromTableInBundle(@"KeepChangesButton", nil, bundle, nil), NSLocalizedStringFromTableInBundle(@"DiscardChangesButton", nil, bundle, nil), NSLocalizedStringFromTableInBundle(@"CancelButton", nil, bundle, nil), sender, self, @selector(saveSheetDidClose:returnCode:contextInfo:), nil, nil, NSLocalizedStringFromTableInBundle(@"KeepChangesDialogMessage", nil, bundle, nil)); return NO; } else return YES; @@ -307,7 +308,7 @@ #pragma mark - #pragma mark Menu Management -// these next five methods are a crude hack - the items ought ot be in the responder chain themselves +// these next five methods are a crude hack - the items ought to be in the responder chain themselves - (IBAction)createListEntry:(id)sender; { // This works by selecting an item that serves as a template (another LSTB), or knows how to create an item (LSTE) and passing the message on to it. diff --git a/Cocoa/Resources/ResKnife.scriptSuite b/Cocoa/Resources/ResKnife.scriptSuite index c4e0ad6..a7c7b77 100755 --- a/Cocoa/Resources/ResKnife.scriptSuite +++ b/Cocoa/Resources/ResKnife.scriptSuite @@ -28,7 +28,7 @@ orderedDocuments - AppleEventCode< + AppleEventCode docu Type ResourceDocument diff --git a/Hex Editor/Classes/Initalisation.cpp b/Hex Editor/Classes/Initalisation.cpp index 9e73100..6a739e7 100644 --- a/Hex Editor/Classes/Initalisation.cpp +++ b/Hex Editor/Classes/Initalisation.cpp @@ -1 +1 @@ -#include "Initalisation.h" #include "HexWindow.h" #include "Events.h" #include "HexUtility.h" globals g; prefs p; /************************/ /* EDITOR INITALIZATION */ /************************/ /*** INITALISE GLOBALS ***/ OSStatus InitGlobals( void ) { // get system version OSStatus error = Gestalt( gestaltSystemVersion, &g.systemVersion ); if( error ) return error; // set up colours SetColour( &g.white, 0xFFFF, 0xFFFF, 0xFFFF ); SetColour( &g.bgColour, 0xEEEE, 0xEEEE, 0xEEEE ); SetColour( &g.sortColour, 0xDDDD, 0xDDDD, 0xDDDD ); SetColour( &g.bevelColour, 0xAAAA, 0xAAAA, 0xAAAA ); SetColour( &g.textColour, 0x7777, 0x7777, 0x7777 ); SetColour( &g.frameColour, 0x5555, 0x5555, 0x5555 ); SetColour( &g.black, 0x0000, 0x0000, 0x0000 ); // 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 // initalise preferences p.version = kHexEditorCurrentVersion; p.lowChar = 0x20; p.highChar = 0x7F; p.GWorldDepth = 8; return error; } /*** INITALISE NEW EDITOR INSTANCE ***/ OSStatus Plug_InitInstance( Plug_PlugInRef plug, Plug_ResourceRef resource ) { WindowRef window; OSStatus error = InitGlobals(); if( error ) return error; #if USE_NIBS // create a nib reference (only searches the application bundle) IBNibRef nibRef = null; error = CreateNibReference( CFSTR("Hex Editor"), &nibRef ); if( error != noErr || nibRef == null ) { // Host_DisplayError( "\pThe nib file reference could not be obtained.", "\p", 0 ); return error; } // create window error = CreateWindowFromNib( nibRef, CFSTR("Hex Window"), &window ); if( error != noErr || window == null ) { // Host_DisplayError( "\pA file window could not be obtained from the nib file.", "\p", 0 ); return error; } // dispose of nib ref DisposeNibReference( nibRef ); #elif TARGET_API_MAC_CARBON // create window Rect creationBounds; 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 ); #else /* if( g.useAppearance && g.systemVersion >= kMacOSEight ) { window = GetNewCWindow( kFileWindow8, null, kFirstWindowOfClass ); themeSavvy = true; } else { */ window = GetNewCWindow( kFileWindow7, null, kFirstWindowOfClass ); DrawGrowIcon( window ); /* themeSavvy = false; } */ SizeWindow( window, kDefaultWindowWidth, kDefaultWindowHeight, false ); #endif // register mac window with host and retreive plug window Plug_WindowRef plugWindow = Host_RegisterWindow( plug, resource, window ); // cerate new hex window class HexWindowPtr hexWindow = new HexWindow( window ); // set window refCon to my class Host_SetWindowRefCon( plugWindow, (UInt32) hexWindow ); // load resource data into handle hexWindow->data = Host_GetResourceData( resource ); // handle disposed of by calling Host_ReleaseResData() // window is not yet active, will receive activate event soon hexWindow->activeWindow = false; // set window's background to default for theme if( g.useAppearance ) SetThemeWindowBackground( window, kThemeBrushModelessDialogBackgroundActive, false ); #if TARGET_API_MAC_CARBON // install window event handler EventHandlerRef ref = null; EventHandlerUPP handler = NewEventHandlerUPP( CarbonWindowEventHandler ); EventTypeSpec events[] = { { kEventClassWindow, kEventWindowClose }, { kEventClassWindow, kEventWindowActivated }, { kEventClassWindow, kEventWindowDeactivated }, { kEventClassWindow, kEventWindowBoundsChanging }, { kEventClassWindow, kEventWindowBoundsChanged }, { kEventClassWindow, kEventWindowHandleContentClick }, { kEventClassWindow, kEventWindowDrawContent }, { kEventClassKeyboard, kEventRawKeyDown }, { kEventClassKeyboard, kEventRawKeyRepeat } }; InstallWindowEventHandler( window, handler, GetEventTypeCount(events), events, plug, &ref ); // install HI event handler ref = null; handler = NewEventHandlerUPP( CarbonHIEventHandler ); EventTypeSpec HIevents[] = { { kEventClassMenu, kEventMenuEnableItems }, { kEventClassCommand, kEventCommandProcess } }; InstallWindowEventHandler( window, handler, GetEventTypeCount(HIevents), HIevents, null, &ref ); #else ClassicEventHandlerUPP handler = NewClassicEventHandlerUPP( ClassicWindowEventHandler ); Host_InstallClassicWindowEventHandler( plugWindow, handler ); #endif // get window rect Rect windowBounds; GetWindowPortBounds( window, &windowBounds ); #if USE_NIBS // get text edit controls which were created from the nib #elif TARGET_API_MAC_CARBON // create header ControlID id; Rect bounds = windowBounds; InsetRect( &bounds, -1, -1 ); bounds.bottom = bounds.top + kHeaderHeight +1; CreateWindowHeaderControl( window, &bounds, false, &hexWindow->header ); id.id = 0; id.signature = kHeaderSignature; SetControlID( hexWindow->header, &id ); // set up header font information ControlFontStyleRec fontStyle = {}; fontStyle.flags = kControlUseFontMask + kControlUseJustMask; fontStyle.font = kControlFontSmallSystemFont; fontStyle.just = teJustLeft; // create header static text controls GetWindowPortBounds( window, &windowBounds ); SetRect( &bounds, windowBounds.left +4, 2, (windowBounds.right - windowBounds.left) /2, kHeaderHeight -2 ); CreateStaticTextControl( window, &bounds, CFSTR("left side"), &fontStyle, &hexWindow->left ); id.id = 0; id.signature = kLeftTextSignature; SetControlID( hexWindow->left, &id ); fontStyle.just = teJustRight; SetRect( &bounds, (windowBounds.right - windowBounds.left) /2, 2, windowBounds.right -4, kHeaderHeight -2 ); CreateStaticTextControl( window, &bounds, CFSTR("right side"), &fontStyle, &hexWindow->right ); id.id = 0; id.signature = kRightTextSignature; SetControlID( hexWindow->right, &id ); // SetHeaderText(); // embed text controls within header EmbedControl( hexWindow->left, hexWindow->header ); EmbedControl( hexWindow->right, hexWindow->header ); #else // only create a scroll bar, draw everything else DrawWindow( window ); #endif #if TARGET_API_MAC_CARBON // install blinking timer EventLoopTimerUPP timerProc = NewEventLoopTimerUPP( BlinkInsertionPoint ); InstallEventLoopTimer( GetMainEventLoop(), 0, kEventDurationSecond /3, timerProc, window, &hexWindow->timer ); #endif // set scrollbar globals hexWindow->UpdateHexInfo(); // add menu to menu bar Host_AppendMenuToBar( plug, kEditorMenu ); // show window ShowWindow( window ); // this is the plug's responsibility SelectWindow( window ); BringToFront( window ); return error; } \ No newline at end of file +#include "Initalisation.h" #include "HexWindow.h" #include "Events.h" #include "HexUtility.h" globals g; prefs p; /************************/ /* EDITOR INITALIZATION */ /************************/ /*** INITALISE GLOBALS ***/ OSStatus InitGlobals( void ) { // get system version OSStatus error = Gestalt( gestaltSystemVersion, &g.systemVersion ); if( error ) return error; // set up colours SetColour( &g.white, 0xFFFF, 0xFFFF, 0xFFFF ); SetColour( &g.bgColour, 0xEEEE, 0xEEEE, 0xEEEE ); SetColour( &g.sortColour, 0xDDDD, 0xDDDD, 0xDDDD ); SetColour( &g.bevelColour, 0xAAAA, 0xAAAA, 0xAAAA ); SetColour( &g.textColour, 0x7777, 0x7777, 0x7777 ); SetColour( &g.frameColour, 0x5555, 0x5555, 0x5555 ); SetColour( &g.black, 0x0000, 0x0000, 0x0000 ); // 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 // initalise preferences p.version = kHexEditorCurrentVersion; p.lowChar = 0x20; p.highChar = 0x7F; p.GWorldDepth = 8; return error; } /*** INITALISE NEW EDITOR INSTANCE ***/ OSStatus Plug_InitInstance( Plug_PlugInRef plug, Plug_ResourceRef resource ) { WindowRef window; OSStatus error = InitGlobals(); if( error ) return error; #if USE_NIBS // create a nib reference (only searches the application bundle) IBNibRef nibRef = null; error = CreateNibReference( CFSTR("Hex Editor"), &nibRef ); if( error != noErr || nibRef == null ) { // Host_DisplayError( "\pThe nib file reference could not be obtained.", "\p", 0 ); return error; } // create window error = CreateWindowFromNib( nibRef, CFSTR("Hex Window"), &window ); if( error != noErr || window == null ) { // Host_DisplayError( "\pA file window could not be obtained from the nib file.", "\p", 0 ); return error; } // dispose of nib ref DisposeNibReference( nibRef ); #elif TARGET_API_MAC_CARBON // create window Rect creationBounds; 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 ); #else /* if( g.useAppearance && g.systemVersion >= kMacOSEight ) { window = GetNewCWindow( kFileWindow8, null, kFirstWindowOfClass ); themeSavvy = true; } else { */ window = GetNewCWindow( kFileWindow7, null, kFirstWindowOfClass ); DrawGrowIcon( window ); /* themeSavvy = false; } */ SizeWindow( window, kDefaultWindowWidth, kDefaultWindowHeight, false ); #endif // register mac window with host and retrieve plug window Plug_WindowRef plugWindow = Host_RegisterWindow( plug, resource, window ); // cerate new hex window class HexWindowPtr hexWindow = new HexWindow( window ); // set window refCon to my class Host_SetWindowRefCon( plugWindow, (UInt32) hexWindow ); // load resource data into handle hexWindow->data = Host_GetResourceData( resource ); // handle disposed of by calling Host_ReleaseResData() // window is not yet active, will receive activate event soon hexWindow->activeWindow = false; // set window's background to default for theme if( g.useAppearance ) SetThemeWindowBackground( window, kThemeBrushModelessDialogBackgroundActive, false ); #if TARGET_API_MAC_CARBON // install window event handler EventHandlerRef ref = null; EventHandlerUPP handler = NewEventHandlerUPP( CarbonWindowEventHandler ); EventTypeSpec events[] = { { kEventClassWindow, kEventWindowClose }, { kEventClassWindow, kEventWindowActivated }, { kEventClassWindow, kEventWindowDeactivated }, { kEventClassWindow, kEventWindowBoundsChanging }, { kEventClassWindow, kEventWindowBoundsChanged }, { kEventClassWindow, kEventWindowHandleContentClick }, { kEventClassWindow, kEventWindowDrawContent }, { kEventClassKeyboard, kEventRawKeyDown }, { kEventClassKeyboard, kEventRawKeyRepeat } }; InstallWindowEventHandler( window, handler, GetEventTypeCount(events), events, plug, &ref ); // install HI event handler ref = null; handler = NewEventHandlerUPP( CarbonHIEventHandler ); EventTypeSpec HIevents[] = { { kEventClassMenu, kEventMenuEnableItems }, { kEventClassCommand, kEventCommandProcess } }; InstallWindowEventHandler( window, handler, GetEventTypeCount(HIevents), HIevents, null, &ref ); #else ClassicEventHandlerUPP handler = NewClassicEventHandlerUPP( ClassicWindowEventHandler ); Host_InstallClassicWindowEventHandler( plugWindow, handler ); #endif // get window rect Rect windowBounds; GetWindowPortBounds( window, &windowBounds ); #if USE_NIBS // get text edit controls which were created from the nib #elif TARGET_API_MAC_CARBON // create header ControlID id; Rect bounds = windowBounds; InsetRect( &bounds, -1, -1 ); bounds.bottom = bounds.top + kHeaderHeight +1; CreateWindowHeaderControl( window, &bounds, false, &hexWindow->header ); id.id = 0; id.signature = kHeaderSignature; SetControlID( hexWindow->header, &id ); // set up header font information ControlFontStyleRec fontStyle = {}; fontStyle.flags = kControlUseFontMask + kControlUseJustMask; fontStyle.font = kControlFontSmallSystemFont; fontStyle.just = teJustLeft; // create header static text controls GetWindowPortBounds( window, &windowBounds ); SetRect( &bounds, windowBounds.left +4, 2, (windowBounds.right - windowBounds.left) /2, kHeaderHeight -2 ); CreateStaticTextControl( window, &bounds, CFSTR("left side"), &fontStyle, &hexWindow->left ); id.id = 0; id.signature = kLeftTextSignature; SetControlID( hexWindow->left, &id ); fontStyle.just = teJustRight; SetRect( &bounds, (windowBounds.right - windowBounds.left) /2, 2, windowBounds.right -4, kHeaderHeight -2 ); CreateStaticTextControl( window, &bounds, CFSTR("right side"), &fontStyle, &hexWindow->right ); id.id = 0; id.signature = kRightTextSignature; SetControlID( hexWindow->right, &id ); // SetHeaderText(); // embed text controls within header EmbedControl( hexWindow->left, hexWindow->header ); EmbedControl( hexWindow->right, hexWindow->header ); #else // only create a scroll bar, draw everything else DrawWindow( window ); #endif #if TARGET_API_MAC_CARBON // install blinking timer EventLoopTimerUPP timerProc = NewEventLoopTimerUPP( BlinkInsertionPoint ); InstallEventLoopTimer( GetMainEventLoop(), 0, kEventDurationSecond /3, timerProc, window, &hexWindow->timer ); #endif // set scrollbar globals hexWindow->UpdateHexInfo(); // add menu to menu bar Host_AppendMenuToBar( plug, kEditorMenu ); // show window ShowWindow( window ); // this is the plug's responsibility SelectWindow( window ); BringToFront( window ); return error; } \ No newline at end of file diff --git a/PICT Editor/Classes/Initalisation.cpp b/PICT Editor/Classes/Initalisation.cpp index ede5f5d..6fc19cb 100644 --- a/PICT Editor/Classes/Initalisation.cpp +++ b/PICT Editor/Classes/Initalisation.cpp @@ -1 +1 @@ -#include "Initalisation.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; // create window Rect creationBounds; WindowRef window; SetRect( &creationBounds, 0, 0, kDefaultWindowWidth, kDefaultWindowHeight ); OffsetRect( &creationBounds, 8, 48 ); WindowAttributes attributes = kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute | kWindowInWindowMenuAttribute; if( g.systemVersion >= kMacOSX ) attributes |= kWindowLiveResizeAttribute; error = CreateNewWindow( kDocumentWindowClass, attributes, &creationBounds, &window ); // register mac window with host and retreive plug window Plug_WindowRef plugWindow = Host_RegisterWindow( plug, resource, window ); // cerate new pict window class PictWindowPtr pictWindow = new PictWindow( window ); // set window refCon to my class Host_SetWindowRefCon( plugWindow, (UInt32) pictWindow ); // set the window pic to the data handle PicHandle picture = (PicHandle) Host_GetResourceData( resource ); if( picture == null ) Host_DisplayError( "\pNo picture could be obtained.", "\p", 0 ); // get pict rect PictInfo pictInfo; GetPictInfo( picture, &pictInfo, 0, 0, 0, 0 ); Rect pictRect; pictRect.top = 0; pictRect.left = 0; pictRect.right = pictInfo.sourceRect.right - pictInfo.sourceRect.left; pictRect.bottom = pictInfo.sourceRect.bottom - pictInfo.sourceRect.top; SizeWindow( window, pictRect.right, pictRect.bottom, false ); #if TARGET_API_MAC_CARBON ControlRef picControl; // this is better than SetWindowPic() in Carbon ControlButtonContentInfo content; content.contentType = kControlContentPictHandle; content.u.picture = picture; // bug: if handle dissapears, control is fucked CreatePictureControl( window, &pictRect, &content, true, &picControl ); // DrawOneControl( picControl ); // bug: work around for bug in ControlManager /* HLockHi( picture ); SetControlData( picControl, kControlPicturePart, kControlPictureHandleTag, sizeof(picture), *picture ); */ #else SetWindowPic( window, picture ); // this doesn't work properly on X #endif // show window ShowWindow( window ); SelectWindow( window ); return error; } \ No newline at end of file +#include "Initalisation.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; // create window Rect creationBounds; WindowRef window; SetRect( &creationBounds, 0, 0, kDefaultWindowWidth, kDefaultWindowHeight ); OffsetRect( &creationBounds, 8, 48 ); WindowAttributes attributes = kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute | kWindowInWindowMenuAttribute; if( g.systemVersion >= kMacOSX ) attributes |= kWindowLiveResizeAttribute; error = CreateNewWindow( kDocumentWindowClass, attributes, &creationBounds, &window ); // register mac window with host and retrieve plug window Plug_WindowRef plugWindow = Host_RegisterWindow( plug, resource, window ); // cerate new pict window class PictWindowPtr pictWindow = new PictWindow( window ); // set window refCon to my class Host_SetWindowRefCon( plugWindow, (UInt32) pictWindow ); // set the window pic to the data handle PicHandle picture = (PicHandle) Host_GetResourceData( resource ); if( picture == null ) Host_DisplayError( "\pNo picture could be obtained.", "\p", 0 ); // get pict rect PictInfo pictInfo; GetPictInfo( picture, &pictInfo, 0, 0, 0, 0 ); Rect pictRect; pictRect.top = 0; pictRect.left = 0; pictRect.right = pictInfo.sourceRect.right - pictInfo.sourceRect.left; pictRect.bottom = pictInfo.sourceRect.bottom - pictInfo.sourceRect.top; SizeWindow( window, pictRect.right, pictRect.bottom, false ); #if TARGET_API_MAC_CARBON ControlRef picControl; // this is better than SetWindowPic() in Carbon ControlButtonContentInfo content; content.contentType = kControlContentPictHandle; content.u.picture = picture; // bug: if handle dissapears, control is fucked CreatePictureControl( window, &pictRect, &content, true, &picControl ); // DrawOneControl( picControl ); // bug: work around for bug in ControlManager /* HLockHi( picture ); SetControlData( picControl, kControlPicturePart, kControlPictureHandleTag, sizeof(picture), *picture ); */ #else SetWindowPic( window, picture ); // this doesn't work properly on X #endif // show window ShowWindow( window ); SelectWindow( window ); return error; } \ No newline at end of file diff --git a/README.txt b/README.txt index cfd6048..2125bcf 100644 --- a/README.txt +++ b/README.txt @@ -72,7 +72,7 @@ ResKnife methods, functions, headers, classes, ivars and practically anything el @abstract @author @created - @change [reverse chronological, i.e. most recent at the top] + @updated [reverse chronological, i.e. most recent at the top] ... @pending [higher priority TODO items should be above lower priority ones] ... diff --git a/ResKnife.xcodeproj/project.pbxproj b/ResKnife.xcodeproj/project.pbxproj index bb83e8c..1fc1d25 100644 --- a/ResKnife.xcodeproj/project.pbxproj +++ b/ResKnife.xcodeproj/project.pbxproj @@ -7,7 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 0E85D4AC10A72953004240C0 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3D2EE5E204E5C56F00515930 /* Localizable.strings */; }; + 0EF71540122BD0D0005DF94E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0EF7153F122BD0D0005DF94E /* Localizable.strings */; }; E1193609099830D300A3A6EA /* FontDocument.nib in Resources */ = {isa = PBXBuildFile; fileRef = E1193607099830D200A3A6EA /* FontDocument.nib */; }; E119363A099833AE00A3A6EA /* Categories.h in Headers */ = {isa = PBXBuildFile; fileRef = E1193638099833AE00A3A6EA /* Categories.h */; }; E119363B099833AE00A3A6EA /* Categories.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1193639099833AE00A3A6EA /* Categories.mm */; }; @@ -302,7 +302,7 @@ E18BF6AD069FEA1800F076B8 /* ElementOCNT.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D50046F04EF040900F3B64D /* ElementOCNT.h */; }; E18BF6AE069FEA1800F076B8 /* ElementLSTC.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D50047404EF122000F3B64D /* ElementLSTC.h */; }; E18BF6B0069FEA1800F076B8 /* TemplateWindow.nib in Resources */ = {isa = PBXBuildFile; fileRef = 3D0B38B504DEF465005AED5E /* TemplateWindow.nib */; }; - E18BF6B4069FEA1800F076B8 /* TemplateWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3D0B38B304DEF41E005AED5E /* TemplateWindowController.mm */; }; + E18BF6B4069FEA1800F076B8 /* TemplateWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D0B38B304DEF41E005AED5E /* TemplateWindowController.m */; }; E18BF6B5069FEA1800F076B8 /* Notifications.m in Sources */ = {isa = PBXBuildFile; fileRef = F5C9ECCE027F474A01A8010C /* Notifications.m */; }; E18BF6B6069FEA1800F076B8 /* Element.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D0933A704DEFEE600DD74B1 /* Element.m */; }; E18BF6B8069FEA1800F076B8 /* TemplateStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D0933BF04DF151C00DD74B1 /* TemplateStream.m */; }; @@ -430,9 +430,9 @@ 3D0ABFB904E152CA00C85300 /* Read Me.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Read Me.txt"; sourceTree = ""; }; 3D0ABFBC04E172F700C85300 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README.txt; sourceTree = SOURCE_ROOT; }; 3D0B38B204DEF41E005AED5E /* TemplateWindowController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TemplateWindowController.h; sourceTree = ""; }; - 3D0B38B304DEF41E005AED5E /* TemplateWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = TemplateWindowController.mm; sourceTree = ""; }; + 3D0B38B304DEF41E005AED5E /* TemplateWindowController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = TemplateWindowController.m; sourceTree = ""; }; 3D0B38B604DEF465005AED5E /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/TemplateWindow.nib; sourceTree = ""; }; - 3D2EE5E204E5C56F00515930 /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; }; + 3D2EE5E204E5C56F00515930 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Localizable.strings; sourceTree = ""; }; 3D35755A04DAEB4300B8225B /* main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 3D35755C04DAEB6200B8225B /* RKEditorRegistry.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RKEditorRegistry.h; sourceTree = ""; }; 3D35755D04DAEB6200B8225B /* RKEditorRegistry.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = RKEditorRegistry.m; sourceTree = ""; }; @@ -607,7 +607,7 @@ F5B5883B0156D40B01000001 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/InfoWindow.nib; sourceTree = ""; }; F5B5883F0156D40B01000001 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/PrefsWindow.nib; sourceTree = ""; }; F5B588410156D40B01000001 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/ResourceDocument.nib; sourceTree = ""; }; - F5B588430156D40B01000001 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + F5B588430156D40B01000001 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; F5B588450156D40B01000001 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; lineEnding = 0; name = English; path = English.lproj/Localizable.strings; sourceTree = ""; }; F5B588460156D40B01000001 /* ResKnife.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = ResKnife.icns; sourceTree = ""; }; F5B588470156D40B01000001 /* Resource file.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "Resource file.icns"; sourceTree = ""; }; @@ -881,7 +881,7 @@ children = ( 3D0ABFB904E152CA00C85300 /* Read Me.txt */, 3D0B38B204DEF41E005AED5E /* TemplateWindowController.h */, - 3D0B38B304DEF41E005AED5E /* TemplateWindowController.mm */, + 3D0B38B304DEF41E005AED5E /* TemplateWindowController.m */, 3D0933BE04DF151C00DD74B1 /* TemplateStream.h */, 3D0933BF04DF151C00DD74B1 /* TemplateStream.m */, 3D0933A604DEFEE600DD74B1 /* Element.h */, @@ -890,7 +890,7 @@ E1A984F7099C2D7F00A70612 /* Resources */, E11937F309991C1100A3A6EA /* Support Resources */, E18BFA3606A20B7A00F076B8 /* Info.plist */, - 3D2EE5E204E5C56F00515930 /* Localizable.strings */, + 0EF7153F122BD0D0005DF94E /* Localizable.strings */, ); path = "Template Editor"; sourceTree = ""; @@ -2046,7 +2046,7 @@ files = ( E18BF6B0069FEA1800F076B8 /* TemplateWindow.nib in Resources */, E1A984FE099C309400A70612 /* DisplayTMPL.png in Resources */, - 0E85D4AC10A72953004240C0 /* Localizable.strings in Resources */, + 0EF71540122BD0D0005DF94E /* Localizable.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2326,7 +2326,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E18BF6B4069FEA1800F076B8 /* TemplateWindowController.mm in Sources */, + E18BF6B4069FEA1800F076B8 /* TemplateWindowController.m in Sources */, E18BF6B5069FEA1800F076B8 /* Notifications.m in Sources */, E18BF6B6069FEA1800F076B8 /* Element.m in Sources */, E18BF6B8069FEA1800F076B8 /* TemplateStream.m in Sources */, @@ -2383,6 +2383,14 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ + 0EF7153F122BD0D0005DF94E /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 3D2EE5E204E5C56F00515930 /* English */, + ); + name = Localizable.strings; + sourceTree = ""; + }; 3D0B38B504DEF465005AED5E /* TemplateWindow.nib */ = { isa = PBXVariantGroup; children = ( @@ -3300,6 +3308,8 @@ E13F7F0708F0411100E2A5CB /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; GCC_VERSION = 4.0; SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; }; diff --git a/TODO.txt b/TODO.txt index 23abf9f..1b6a2bd 100644 --- a/TODO.txt +++ b/TODO.txt @@ -6,3 +6,12 @@ Auto-uncollapse list items in template editor when they are created and when a r Add preference to "Show Resource Fork even if empty." Add viewers for MooV and PICT. Modify -[Resource data] and -[Resource setData] to use ResourceManager functions behind the scenes instead of an NSData object. This should fix the problem with new resources not being saved at times. + + +// some old to-dos. don't know if these still apply + +-> "Open as Hex" displays "(null)" as the document name. Why? +-> Changing the type/creator of a file isn't written to disk by ResourceDocument. +-> Create small versions of the doc icons in Photoshop instead of letting IconComposer use its cheap scaling on them. +-> Auto-uncollapse list items in template editor when they are created and when a resource is opened. +-> Template editor should maintain "dirty" flag for resource.