Changes accumulated on my G5 while repository was inaccessible.

This commit is contained in:
Nicholas Shanks 2008-07-31 20:27:55 +00:00
parent d2a16f7a81
commit 7f491cbb39
104 changed files with 3328 additions and 2181 deletions

View File

@ -10,7 +10,7 @@
else return [self itemAtRow:[self selectedRow]];
}
- (NSArray *)selectedItems;
- (NSArray *)selectedItems
{
NSNumber *row;
NSMutableArray *items = [NSMutableArray array];

View File

@ -6,3 +6,11 @@
- (FSSpec *)createFSSpec;
@end
@interface NSString (ResKnifeBooleanExtensions)
- (BOOL)boolValue;
+ (NSString *)stringWithBool:(BOOL)boolean;
@end

View File

@ -4,25 +4,46 @@
- (FSRef *)createFSRef
{
FSRef *fsRef = NULL;
OSStatus error = FSPathMakeRef( [self fileSystemRepresentation], fsRef, NULL );
if( error == noErr )
// 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);
if(error == noErr)
return fsRef;
return NULL;
}
- (FSSpec *)createFSSpec
{
FSRef *fsRef = NULL;
FSSpec *fsSpec = NULL;
OSStatus error = FSPathMakeRef( [self fileSystemRepresentation], fsRef, NULL );
if( error == noErr )
// 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);
if(error == noErr)
{
error = FSGetCatalogInfo( fsRef, kFSCatInfoNone, NULL, NULL, fsSpec, NULL );
if( error == noErr )
error = FSGetCatalogInfo(fsRef, kFSCatInfoNone, NULL, NULL, fsSpec, NULL);
if(error == noErr)
{
DisposePtr((Ptr) fsRef);
return fsSpec;
}
}
DisposePtr((Ptr) fsRef);
return NULL;
}
@end
@implementation NSString (ResKnifeBooleanExtensions)
- (BOOL)boolValue
{
return ![self isEqualToString:@"NO"];
// return [self isEqualToString:@"YES"];
}
+ (NSString *)stringWithBool:(BOOL)boolean
{
return boolean? @"YES" : @"NO";
}
@end

View File

@ -1,75 +1,100 @@
#import <Cocoa/Cocoa.h>
/*! @header ApplicationDelegate.h
* @discussion This class is the delegate object for NSApp.
*/
/*!
@header ApplicationDelegate.h
@abstract This class is the delegate object for NSApp.
*/
/*! @class ApplicationDelegate
* @discussion This class is the delegate object for NSApp.
*/
/*!
@class ApplicationDelegate
@abstract This class is the delegate object for NSApp.
*/
@class OpenPanelDelegate;
@interface ApplicationDelegate : NSObject
{
/*! @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;
/*! @var openPanelDelegate Delegate for <tt>NSOpenPanels</tt>. */
IBOutlet OpenPanelDelegate *openPanelDelegate;
/*! @var icons A dictionary within which to cache icons. Keys are four-character <tt>NSStrings</tt> representing <tt>ResTypes</tt>. */
NSMutableDictionary *_icons;
}
/*! @function showAbout:
* @discussion Displays the about box located in <b>AboutPanel.nib</b>.
*/
/*!
@method showAbout:
@abstract Displays the about box located in <b>AboutPanel.nib</b>.
*/
- (IBAction)showAbout:(id)sender;
/*! @function visitWebsite:
* @discussion Takes the user to <i>http://web.nickshanks.com/resknife/</i>.
*/
/*!
@method visitWebsite:
@abstract Takes the user to <i>http://web.nickshanks.com/resknife/</i>.
*/
- (IBAction)visitWebsite:(id)sender;
/*! @function visitSourceforge:
* @discussion Takes the user to <i>http://resknife.sourceforge.net/</i>.
*/
/*!
@method visitSourceforge:
@abstract Takes the user to <i>http://resknife.sourceforge.net/</i>.
*/
- (IBAction)visitSourceforge:(id)sender;
/*! @function emailDeveloper:
* @discussion Launches email client and inserts <i>resknife@nickshanks.com</i> into To field.
*/
/*!
@method emailDeveloper:
@abstract Launches email client and inserts <i>resknife@nickshanks.com</i> into To field.
*/
- (IBAction)emailDeveloper:(id)sender;
/*! @function showInfo:
* @discussion Displays the Info panel stored in <b>InfoWindow.nib</b>
*/
/*!
@method showInfo:
@abstract Displays the Info panel stored in <b>InfoWindow.nib</b>
*/
- (IBAction)showInfo:(id)sender;
/*! @function showPasteboard:
* @discussion Displays the pasteboard document, a singleton instance of class <tt>PasteboardDocument</tt>
*/
/*!
@method showPasteboard:
@abstract 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>
*/
/*!
@method showPrefs:
@abstract Displays the preferences panel stored in <b>PrefsWindow.nib</b>
*/
- (IBAction)showPrefs:(id)sender;
/*! @function initUserDefaults
* @discussion Initalises any unset user preferences to default values as read in from <b>defaults.plist</b>.
*/
/*!
@method initUserDefaults
@abstract Initalises any unset user preferences to default values as read in from <b>defaults.plist</b>.
*/
- (void)initUserDefaults;
/*! @function openAuxView
* @discussion Accessor method for the <tt>openAuxView</tt> instance variable.
*/
- (NSView *)openAuxView;
/* accessors */
/*! @function icons
* @discussion Accessor method for the <tt>icons</tt> instance variable.
*/
/*!
@method openPanelDelegate
@abstract Accessor method for the <tt>openPanelDelegate</tt> instance variable.
*/
- (OpenPanelDelegate *)openPanelDelegate;
/*!
@@method iconForResourceType:
@abstract Returns the icon to be used throughout the UI for any given resource type.
*/
- (NSImage *)iconForResourceType:(NSString *)resourceType;
/*!
@@method _icons
@abstract Private accessor method for the <tt>_icons</tt> instance variable.
*/
- (NSMutableDictionary *)_icons;
/*!
@method icons
@abstract Accessor method for the <tt>_icons</tt> instance variable. Returns an immutable dictionary.
*/
- (NSDictionary *)icons;
@end
@interface NSSavePanel (PackageBrowser)
/* utility methods */
- (NSArray *)forksForFile:(FSRef *)fileRef;
@end

View File

@ -1,4 +1,5 @@
#import "ApplicationDelegate.h"
#import "OpenPanelDelegate.h"
#import "RKDocumentController.h"
#import "InfoWindowController.h"
#import "PasteboardWindowController.h"
@ -6,8 +7,9 @@
#import "CreateResourceSheetController.h"
#import "ResourceDocument.h"
#import "ResourceDataSource.h"
#import "RKEditorRegistry.h"
#import "ResknifePluginProtocol.h"
#import "ResKnifePluginProtocol.h"
#import "RKSupportResourceRegistry.h"
@ -23,49 +25,103 @@
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
// instanciate my own subclass of NSDocumentController so I can override the open dialog
RKDocumentController *docController = [[RKDocumentController alloc] init];
[RKSupportResourceRegistry scanForSupportResources: [NSDocumentController sharedDocumentController]];
[[RKDocumentController alloc] init];
[RKSupportResourceRegistry scanForSupportResources];
}
/*!
@method awakeFromNib
@updated 2003-10-24 NGS: moved icon caching into method called by timer (to speed up app launch time)
*/
- (void)awakeFromNib
{
NSTableColumn *tableColumn;
NSButtonCell *buttonCell;
// Part of my EvilPlanª to find out how many people use ResKnife and how often!
int launchCount = [[NSUserDefaults standardUserDefaults] integerForKey:@"LaunchCount"];
[[NSUserDefaults standardUserDefaults] setInteger:launchCount + 1 forKey:@"LaunchCount"];
// save a number of icons
icons = [[NSMutableDictionary alloc] init];
[icons setObject:[[NSWorkspace sharedWorkspace] iconForFileType:@"TEXT"] forKey:@"TEXT"];
[icons setObject:[[NSWorkspace sharedWorkspace] iconForFileType:@"PICT"] forKey:@"PICT"];
[icons setObject:[[NSWorkspace sharedWorkspace] iconForFileType:@"icns"] forKey:@"icns"];
// set up open dialog's aux table view
tableColumn = [forkTableView tableColumnWithIdentifier:@"parse"];
buttonCell = [[[NSButtonCell alloc] initTextCell:@""] autorelease];
[buttonCell setEditable:YES];
[buttonCell setButtonType:NSSwitchButton];
[tableColumn setDataCell:buttonCell];
// initalise an empty icon cache and create timer used to pre-cache a number of common icons
_icons = [[NSMutableDictionary alloc] init];
[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(precacheIcons:) userInfo:nil repeats:NO];
// set default preferences
[self initUserDefaults];
}
- (void)dealloc
{
[icons release];
[_icons release];
[super dealloc];
}
/*!
@method precacheIcons:
@author Nicholas Shanks
@created 2003-10-24
@abstract Pre-caches the icons for a number of common resource types.
@description Icon pre-caching now uses the more sophisticated iconForResourceType: instead of obtaining the images directly from the file system (otherwise pre-cached icons would not be overridable by plug-ins). In addition it has been moved from the awakeFromNib: method into one called by a timer. This method should not be called until after the editor registry has been built.
*/
- (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:@"CODE"];
[self iconForResourceType:@"icns"];
[self iconForResourceType:@"PICT"];
[self iconForResourceType:@"plst"];
[self iconForResourceType:@"snd "];
[self iconForResourceType:@"TEXT"];
}
- (NSArray *)forksForFile:(FSRef *)fileRef
{
if(!fileRef) return nil;
FSCatalogInfo catalogInfo;
FSCatalogInfoBitmap whichInfo = kFSCatInfoNodeFlags;
CatPositionRec forkIterator = { 0 };
NSMutableArray *forks = [NSMutableArray array];
// check we have a file, not a folder
OSErr error = FSGetCatalogInfo(fileRef, whichInfo, &catalogInfo, NULL, NULL, NULL);
if(!error && !(catalogInfo.nodeFlags & kFSNodeIsDirectoryMask))
{
// iterate over file and populate forks array
while(error == noErr)
{
HFSUniStr255 forkName;
SInt64 forkSize;
UInt64 forkPhysicalSize; // used if opening selected fork fails to find empty forks
error = FSIterateForks(fileRef, &forkIterator, &forkName, &forkSize, &forkPhysicalSize);
if(!error)
{
NSString *fName = [NSString stringWithCharacters:forkName.unicode length:forkName.length];
NSNumber *fSize = [NSNumber numberWithLongLong:forkSize];
NSNumber *fAlloc = [NSNumber numberWithUnsignedLongLong:forkPhysicalSize];
[forks addObject:[NSDictionary dictionaryWithObjectsAndKeys:fName, @"forkname", fSize, @"forksize", fAlloc, @"forkallocation", nil]];
}
else if(error != errFSNoMoreItems)
{
NSLog(@"FSIterateForks() error: %d", error);
}
}
}
else if(error)
{
NSLog(@"FSGetCatalogInfo() error: %d", error);
}
return forks;
}
- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender
{
#pragma unused( sender )
#pragma unused(sender)
NSString *launchAction = [[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchAction"];
if( [launchAction isEqualToString:@"OpenUntitledFile"] )
if([launchAction isEqualToString:@"OpenUntitledFile"])
return YES;
else if( [launchAction isEqualToString:@"DisplayOpenPanel"] )
else if([launchAction isEqualToString:@"DisplayOpenPanel"])
{
[[NSDocumentController sharedDocumentController] openDocument:sender];
return NO;
@ -75,7 +131,7 @@
- (BOOL)application:(NSApplication *)application openFile:(NSString *)file
{
#pragma unused( application )
#pragma unused(application)
// bug: check if application was an external editor (e.g. Iconographer) and update existing open file instead
[[NSDocumentController sharedDocumentController] openDocumentWithContentsOfFile:file display:YES];
return YES;
@ -83,14 +139,20 @@
- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
{
#pragma unused( sender )
#pragma unused(sender)
return !flag;
}
- (IBAction)showAbout:(id)sender
{
[NSApp orderFrontStandardAboutPanel:sender];
// get about box code from http://cocoadevcentral.com/tutorials/showpage.php?show=00000041.php
// could do with a better about box
/* NSWindowController *wc = [[NSWindowController alloc] initWithWindowNibName:@"AboutPanel"];
if([(NSTextView *)[[wc window] initialFirstResponder] readRTFDFromFile:[[NSBundle mainBundle] pathForResource:@"Credits" ofType:@"rtf"]])
{
[[wc window] center];
[[wc window] orderFront:nil];
}
else*/ [NSApp orderFrontStandardAboutPanel:sender];
}
- (IBAction)visitWebsite:(id)sender
@ -145,12 +207,12 @@
// enumerate over all the keys in the dictionary
overDefaults = [[defaultsPlist allKeys] objectEnumerator];
while( eachDefault = [overDefaults nextObject] )
while(eachDefault = [overDefaults nextObject])
{
// for each key in the dictionary
// check if there is a value already registered for it
// and if there isn't, then register the value that was in the file
if( ![defaults stringForKey:eachDefault] )
if(![defaults stringForKey:eachDefault])
{
[defaults setObject:[defaultsPlist objectForKey:eachDefault] forKey:eachDefault];
}
@ -160,26 +222,94 @@
[defaults synchronize];
}
- (NSView *)openAuxView
- (OpenPanelDelegate *)openPanelDelegate
{
return openAuxView;
return openPanelDelegate;
}
/*!
@method iconForResourceType:
@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.
@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)
{
NSString *iconPath = nil;
// try to load icon from the default editor for that type
Class editor = [[RKEditorRegistry defaultRegistry] editorForType:resourceType];
if(editor && resourceType)
{
// 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 && 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
{
NSString *bundlePath = [[NSBundle bundleWithIdentifier:fileType] bundlePath];
if(bundlePath)
icon = [[NSWorkspace sharedWorkspace] iconForFile:bundlePath];
}
}
// if we still don't have an icon, try to get the generic one - this is what icon represented forks get
// if(!icon) icon = [NSImage imageNamed:@"NSMysteryDocument"];
if(!icon) icon = [[NSWorkspace sharedWorkspace] iconForFileType:@"' '"];
// save the newly retreived icon in the cache
if(icon && resourceType)
[[self _icons] setObject:icon forKey:resourceType];
}
// return the cached icon, or nil if none was found
return icon;
}
- (NSMutableDictionary *)_icons
{
return _icons;
}
- (NSDictionary *)icons
{
return icons;
return [NSDictionary dictionaryWithDictionary:[self _icons]];
}
@end
@implementation NSSavePanel (PackageBrowser)
/* Don't tell anyone I did this... */
/*- (void)setTreatsFilePackagesAsDirectories:(BOOL)flag
{
#pragma unused( flag )
_spFlags.treatsFilePackagesAsDirectories = YES;
}*/
@end

View File

@ -5,62 +5,55 @@
@implementation CreateResourceSheetController
/* -----------------------------------------------------------------------------
controlTextDidChange:
Someone changed the control ID edit field. Check whether this is
a unique ID and appropriately enable the "create" button.
Check "notification" against being nil, which is how we call it when
we need to explicitly update the enabled state of the "create" button.
REVISIONS:
2003-08-01 UK Commented, changed to use data source's resourceOfType
instead of directly messing with the resource list's
enumerator Removed ID > 0 check -- negative IDs are
allowed as well.
-------------------------------------------------------------------------- */
/*!
@method controlTextDidChange:
@abstract Handles updating of the 'Create' button when valid values are present in the sheet's fields.
@updated 2003-08-01 UK: Changed to use data source's resourceOfType instead of directly messing with the resource list's enumerator.
@updated 2003-08-01 UK: Removed ID > 0 check -- negative IDs are allowed as well.<br/><small>Note from Nick: IIRC this was there as a workaround for another bug which prohibited negative IDs from being used. Not sure if that got fixed though :)</small>
@description Someone changed the control ID edit field. Check whether this is a unique ID and appropriately enable the "create" button.</p><p>Check "notification" against being nil, which is how we call it when we need to explicitly update the enabled state of the "create" button.
*/
-(void) controlTextDidChange: (NSNotification*)notification
- (void)controlTextDidChange:(NSNotification *)notification
{
BOOL enableButton = NO;
NSString *type = [typeView stringValue];
NSNumber *resID = [NSNumber numberWithInt:[resIDView intValue]];
if( [type length] == 4 )
if([type length] == 4)
{
// I could use +[Resource getResourceOfType:andID:inDocument:] != nil, but that would be much slower
Resource *resource = [[document dataSource] resourceOfType:type andID:resID];
if( resource == nil ) // No resource with that type and ID yet?
if(resource == nil) // No resource with that type and ID yet?
enableButton = YES;
}
[createButton setEnabled:enableButton];
}
/*!
@method showCreateResourceSheet:
@abstract Shows the sheet allowing the user to define the properties of a new resource.
@updated 2003-08-01 UK: Made it "fake" a popup selection so type field and popup match.
@updated 2003-08-01 UK: Made it suggest an unused resource ID.
*/
/* -----------------------------------------------------------------------------
showCreateResourceSheet:
Show our sheet and set it up before that.
REVISIONS:
2003-08-01 UK Commented, made it "fake" a popup selection so
type field and popup match. Made it suggest an unused
resource ID.
-------------------------------------------------------------------------- */
-(void) showCreateResourceSheet: (ResourceDocument*)sheetDoc
- (void)showCreateResourceSheet:(ResourceDocument *)sheetDoc
{
// bug: didEndSelector could be better employed than using the button's targets from interface builder
document = sheetDoc;
[NSApp beginSheet:[self window] modalForWindow:[document mainWindow] modalDelegate:self didEndSelector:NULL contextInfo:nil];
[resIDView setObjectValue: [[document dataSource] uniqueIDForType: [typeView stringValue]]];
[self typePopupSelection: typePopup]; // Puts current popup value in text field and updates state of "create" button.
[resIDView setObjectValue:[[document dataSource] uniqueIDForType:[typeView stringValue]]];
// put current popup value in text field and updates state of "create" button.
[self typePopupSelection:typePopup];
}
- (IBAction)hideCreateResourceSheet:(id)sender
{
if( sender == createButton )
if(sender == createButton)
{
// bug should be using cell's tag rather than position (so cells can be moved around if needed)
// attributes ^= [[attributesMatrix cellAtRow:0 column:0] intValue]? [[attributesMatrix cellAtRow:0 column:0] tag]:0;
unsigned short attributes = 0;
attributes ^= [[attributesMatrix cellAtRow:0 column:0] intValue]? resPreload:0;
attributes ^= [[attributesMatrix cellAtRow:1 column:0] intValue]? resPurgeable:0;
@ -68,28 +61,26 @@
attributes ^= [[attributesMatrix cellAtRow:0 column:1] intValue]? resSysHeap:0;
attributes ^= [[attributesMatrix cellAtRow:1 column:1] intValue]? resProtected:0;
Resource *resource = [Resource resourceOfType:[typeView stringValue] andID:[NSNumber numberWithShort:(short) [resIDView intValue]] withName:[nameView stringValue] andAttributes:[NSNumber numberWithUnsignedShort:attributes]];
[resource setDocumentName:[document displayName]];
[[document undoManager] beginUndoGrouping];
[[document dataSource] addResource:[Resource resourceOfType:[typeView stringValue] andID:[NSNumber numberWithShort:(short) [resIDView intValue]] withName:[nameView stringValue] andAttributes:[NSNumber numberWithUnsignedShort:attributes]]];
if( [[nameView stringValue] length] == 0 )
[[document dataSource] addResource:resource];
if([[nameView stringValue] length] == 0)
[[document undoManager] setActionName:NSLocalizedString(@"Create Resource", nil)];
else [[document undoManager] setActionName:[NSString stringWithFormat:NSLocalizedString(@"Create Resource Ò%@Ó", nil), [nameView stringValue]]];
else [[document undoManager] setActionName:[NSString stringWithFormat:NSLocalizedString(@"Create Resource '%@'", nil), [nameView stringValue]]];
[[document undoManager] endUndoGrouping];
}
[[self window] orderOut:nil];
[NSApp endSheet:[self window]];
}
/*!
@method typePopupSelection:
@abstract Updates the edit text field when the type pop-up selection is changed.
@updated 2003-08-01 UK: Commented, made it update state of "create" button.
*/
/* -----------------------------------------------------------------------------
typePopupSelection:
Someone chose an item from our "res type" popup menu. Update our
edit field to show that.
REVISIONS:
2003-08-01 UK Commented, made it update state of "create" button..
-------------------------------------------------------------------------- */
-(IBAction) typePopupSelection:(id)sender
- (IBAction)typePopupSelection:(id)sender
{
[typeView setStringValue:[typePopup titleOfSelectedItem]];
[typeView selectText:sender];

View File

@ -35,7 +35,7 @@ enum Attributes
- (void)updateInfoWindow;
- (void)setMainWindow:(NSWindow *)mainWindow;
- (IBAction)attributesChanged:(id)sender;
- (IBAction)nameChanged: (id)sender;
- (IBAction)nameDidChange:(id)sender;
- (void)resourceAttributesDidChange:(NSNotification *)notification;
- (void)documentInfoDidChange:(NSNotification *)notification;
@ -46,7 +46,7 @@ enum Attributes
@interface NSWindowController (InfoWindowAdditions)
/*! @function resource
@discussion Your plug-in should override this method to return the resource it's editing. Default implementation returns nil.
@discussion Your plug-in should override this method to return the primary resource it's editing. Default implementation returns nil.
*/
- (Resource *)resource;

View File

@ -2,18 +2,12 @@
#import <Carbon/Carbon.h> // Actually I only need CarbonCore.framework, but <Carbon/CarbonCore.h> and <CarbonCore/CarbonCore.h> don't work, so I don't know what else to do
#import "ResourceDocument.h"
#import "Resource.h"
#import "ApplicationDelegate.h"
#import "NSOutlineView-SelectedItems.h"
#import "MoreFilesX.h"
@implementation InfoWindowController
- (id)init
{
self = [self initWithWindowNibName:@"InfoWindow"];
if( self ) [self setWindowFrameAutosaveName:@"InfoWindow"];
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
@ -40,59 +34,87 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(documentInfoDidChange:) name:DocumentInfoDidChangeNotification object:nil];
}
-(void) updateInfoWindow
/*!
@method updateInfoWindow
@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
{
[nameView setEditable:(selectedResource != nil)];
[nameView setDrawsBackground:(selectedResource != nil)];
if( selectedResource )
if(selectedResource)
{
[[self window] setTitle:@"Resource Info"];
[placeholderView setContentView:resourceView];
// set UI values
[[self window] setTitle:NSLocalizedString(@"Resource Info",nil)];
[nameView setStringValue:[selectedResource name]];
[iconView setImage:[[NSWorkspace sharedWorkspace] iconForFileType:[selectedResource type]]];
[iconView setImage:[(ApplicationDelegate *)[NSApp delegate] iconForResourceType:[selectedResource type]]];
[[attributesMatrix cellAtRow:changedBox column:0] setState:[[selectedResource attributes] shortValue] & resChanged];
[[attributesMatrix cellAtRow:preloadBox column:0] setState:[[selectedResource attributes] shortValue] & resPreload];
[[attributesMatrix cellAtRow:protectedBox column:0] setState:[[selectedResource attributes] shortValue] & resProtected];
[[attributesMatrix cellAtRow:lockedBox column:0] setState:[[selectedResource attributes] shortValue] & resLocked];
[[attributesMatrix cellAtRow:purgableBox column:0] setState:[[selectedResource attributes] shortValue] & resPurgeable];
[[attributesMatrix cellAtRow:systemHeapBox column:0] setState:[[selectedResource attributes] shortValue] & resSysHeap];
// swap box
[placeholderView setContentView:resourceView];
}
else if( currentDocument != nil )
else if(currentDocument != nil)
{
// get sizes of forks as they are on disk
UInt64 dataLogicalSize = 0, rsrcLogicalSize = 0;
FSRef *fileRef = (FSRef *) NewPtrClear( sizeof(FSRef) );
if( fileRef && [currentDocument fileName] )
FSRef *fileRef = (FSRef *) NewPtrClear(sizeof(FSRef));
if(fileRef && [currentDocument fileName])
{
OSStatus error = FSPathMakeRef( [[currentDocument fileName] cString], fileRef, nil );
if( !error ) FSGetForkSizes( fileRef, &dataLogicalSize, &rsrcLogicalSize );
OSStatus error = FSPathMakeRef([[currentDocument fileName] fileSystemRepresentation], fileRef, nil);
if(!error) FSGetForkSizes(fileRef, &dataLogicalSize, &rsrcLogicalSize);
}
if( fileRef ) DisposePtr( (Ptr) fileRef );
if(fileRef) DisposePtr((Ptr) fileRef);
// set info window elements to correct values
[[self window] setTitle:@"Document Info"];
[iconView setImage:[NSImage imageNamed:@"Resource file"]];
[nameView setStringValue:[currentDocument fileName]? [[currentDocument fileName] lastPathComponent]:[currentDocument displayName]];
[[filePropertyForm cellAtIndex:0] setStringValue:[currentDocument creator]];
[[filePropertyForm cellAtIndex:1] setStringValue:[currentDocument type]];
[[self window] setTitle:NSLocalizedString(@"Document Info",nil)];
if([currentDocument fileName]) // document has been saved
{
[iconView setImage:[[NSWorkspace sharedWorkspace] iconForFile:[currentDocument fileName]]];
[nameView setStringValue:[[currentDocument fileName] lastPathComponent]];
}
else // new, untitled document
{
[iconView setImage:[NSImage imageNamed:@"Resource file"]];
[nameView setStringValue:[currentDocument displayName]];
}
[currentDocument creator];
[[NSString alloc] initWithData:[currentDocument creator] encoding:NSMacOSRomanStringEncoding];
[[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]];
// [[filePropertyForm cellAtIndex:3] setObjectValue:[NSNumber numberWithUnsignedLongLong:rsrcLogicalSize]];
[[filePropertyForm cellAtIndex:2] setStringValue:[[NSNumber numberWithUnsignedLongLong:dataLogicalSize] description]];
[[filePropertyForm cellAtIndex:3] setStringValue:[[NSNumber numberWithUnsignedLongLong:rsrcLogicalSize] description]];
// swap box
[placeholderView setContentView:documentView];
}
else
{
[iconView setImage:nil];
[nameView setStringValue:nil];
[placeholderView setContentView:nil];
}
}
- (void)setMainWindow:(NSWindow *)mainWindow
{
NSWindowController *controller = [mainWindow windowController];
if( [[controller document] isKindOfClass:[ResourceDocument class]] )
if([[controller document] isKindOfClass:[ResourceDocument class]])
currentDocument = [controller document];
else currentDocument = nil;
if( currentDocument )
if(currentDocument)
selectedResource = [[currentDocument outlineView] selectedItem];
else selectedResource = [controller resource];
[self updateInfoWindow];
@ -105,15 +127,15 @@
- (void)selectedResourceChanged:(NSNotification *)notification
{
if( ![[nameView stringValue] isEqualToString: [selectedResource name]] )
[self nameChanged:nameView];
selectedResource = [[notification object] selectedItem];
if(![[nameView stringValue] isEqualToString:[selectedResource name]])
[self nameDidChange:nameView];
selectedResource = (Resource *) [[notification object] selectedItem];
[self updateInfoWindow];
}
- (void)documentInfoDidChange:(NSNotification *)notification
{
#pragma unused( notification )
#pragma unused(notification)
[self updateInfoWindow];
}
@ -124,23 +146,21 @@
[selectedResource setAttributes:[NSNumber numberWithShort:number]];
}
-(IBAction) nameChanged: (id)sender
- (IBAction)nameDidChange:(id)sender
{
[selectedResource setName: [nameView stringValue]];
[selectedResource setName:[nameView stringValue]];
}
- (void)resourceAttributesDidChange:(NSNotification *)notification;
{
if( ![[nameView stringValue] isEqualToString: [selectedResource name]] )
[self nameChanged:nameView];
[self updateInfoWindow];
}
+ (id)sharedInfoWindowController
{
static InfoWindowController *sharedInfoWindowController = nil;
if( !sharedInfoWindowController )
sharedInfoWindowController = [[InfoWindowController allocWithZone:[self zone]] init];
if(!sharedInfoWindowController)
sharedInfoWindowController = [[InfoWindowController allocWithZone:[self zone]] initWithWindowNibName:@"InfoWindow"];
return sharedInfoWindowController;
}

View File

@ -2,6 +2,9 @@
#import "NSOutlineView-SelectedItems.h"
#import "Resource.h"
/* NameFormatter has been deprecated (it never did what I wanted anyway :-) */
/* functionality is now in -outlineView:willDisplayCell:forTableColumn:item: */
@implementation NameFormatter
- (NSString *)stringForObjectValue:(id)obj

View File

@ -1,19 +0,0 @@
/* 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

@ -1,113 +0,0 @@
#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 nil; //return _browser;
}
@end

View File

@ -0,0 +1,43 @@
#import <Cocoa/Cocoa.h>
@interface OpenPanelDelegate : NSObject
{
/*! @var openPanelAccessoryView Accessory view for <tt>NSOpenPanels</tt>. */
IBOutlet NSView *openPanelAccessoryView;
/*! @var forkTableView Table view inside <tt>openPanelAccessoryView</tt>. */
IBOutlet NSTableView *forkTableView;
/*! @var addForkButton Button for adding forks to a file. */
IBOutlet NSButton *addForkButton;
/*! @var removeForkButton Button for removing forks from a file. */
IBOutlet NSButton *removeForkButton;
/*! @var forks Array of forks representing the currently selected file. */
NSMutableArray *forks;
/*! @var readOpenPanelForFork Flag indicating whether ResKnife should ask for a fork to parse in a secondary dialog (false) or obtain it from the selected item in the open dialog (true). */
BOOL readOpenPanelForFork;
}
/* actions from aux view controls */
- (IBAction)addFork:(id)sender;
- (IBAction)removeFork:(id)sender;
/* accessors */
/*!
@method openPanelAccessoryView
@abstract Accessor method for the <tt>openPanelAccessoryView</tt> instance variable.
*/
- (NSView *)openPanelAccessoryView;
/*!
@method forkTableView
@abstract Accessor method for the <tt>forkTableView</tt> instance variable.
*/
- (NSTableView *)forkTableView;
- (NSArray *)forks;
- (void)setReadOpenPanelForFork:(BOOL)flag;
- (BOOL)readOpenPanelForFork;
@end

View File

@ -0,0 +1,131 @@
#import "OpenPanelDelegate.h"
#import "ApplicationDelegate.h"
#import "SizeFormatter.h"
#import "../Categories/NSString-FSSpec.h"
@implementation OpenPanelDelegate
- (id)init
{
self = [super init];
if(self)
{
forks = [[NSMutableArray alloc] init];
readOpenPanelForFork = NO;
}
return self;
}
- (void)awakeFromNib
{
// remove this when functionality actually works
[addForkButton setEnabled:NO];
[removeForkButton setEnabled:NO];
}
- (void)dealloc
{
[forks release];
[super dealloc];
}
// open panel delegate method
- (void)panelSelectionDidChange:(id)sender
{
[forks setArray:[(ApplicationDelegate *)[NSApp delegate] forksForFile:[[sender filename] createFSRef]]];
[forkTableView reloadData];
}
- (BOOL)readOpenPanelForFork
{
return readOpenPanelForFork;
}
- (void)setReadOpenPanelForFork:(BOOL)flag
{
readOpenPanelForFork = flag;
}
// table view data source methods
- (int)numberOfRowsInTableView:(NSTableView *)tableView
{
return [forks count];
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
{
// return object in array
if(row < [forks count])
{
if([[tableColumn identifier] isEqualToString:@"forkname"])
{
NSString *forkName = nil;
HFSUniStr255 *resourceForkName = (HFSUniStr255 *) NewPtrClear(sizeof(HFSUniStr255));
OSErr error = FSGetResourceForkName(resourceForkName);
forkName = [(NSDictionary *)[forks objectAtIndex:row] objectForKey:[tableColumn identifier]];
// return custom names for data and resource forks
if([forkName isEqualToString:@""])
forkName = NSLocalizedString(@"Data Fork", nil);
else if(!error && [forkName isEqualToString:[NSString stringWithCharacters:resourceForkName->unicode length:resourceForkName->length]])
forkName = NSLocalizedString(@"Resource Fork", nil);
DisposePtr((Ptr) resourceForkName);
return forkName;
}
// return default value otherwise
return [(NSDictionary *)[forks objectAtIndex:row] objectForKey:[tableColumn identifier]];
}
else return nil;
}
- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(int)row
{
if([[tableColumn identifier] isEqualToString:@"forkname"])
{
// update forks array
// create fork with new name
}
}
- (IBAction)addFork:(id)sender
{
// add placeholder to forks array
[forks addObject:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"UNTITLED_FORK", nil), @"forkname", [NSNumber numberWithInt:0], @"forksize", [NSNumber numberWithInt:0], @"forkallocation", nil]];
[forkTableView noteNumberOfRowsChanged];
[forkTableView reloadData];
// start editing placeholder
[forkTableView selectRow:[forks count]-1 byExtendingSelection:NO];
[forkTableView editColumn:0 row:[forks count]-1 withEvent:nil select:YES];
}
- (IBAction)removeFork:(id)sender
{
// display warning
// delete fork
// update table view
[forks removeObjectAtIndex:[forkTableView selectedRow]+1];
[forkTableView noteNumberOfRowsChanged];
[forkTableView reloadData];
}
- (NSArray *)forks
{
// returns an immutable array
return [NSArray arrayWithArray:forks];
}
- (NSView *)openPanelAccessoryView
{
return openPanelAccessoryView;
}
- (NSTableView *)forkTableView
{
return forkTableView;
}
@end

View File

@ -1,5 +1,4 @@
#import <Cocoa/Cocoa.h>
#import "NameFormatter.h"
#import "SizeFormatter.h"
#import "AttributesFormatter.h"
@ -7,20 +6,16 @@
@interface OutlineViewDelegate : NSObject
{
IBOutlet NSWindow *window;
IBOutlet NameFormatter *nameFormatter;
IBOutlet SizeFormatter *sizeFormatter;
IBOutlet AttributesFormatter *attributesFormatter;
IBOutlet NSWindow *window;
IBOutlet NSOutlineView *outlineView;
IBOutlet SizeFormatter *sizeFormatter;
IBOutlet AttributesFormatter *attributesFormatter;
}
int compareResourcesAscending( Resource *r1, Resource *r2, void *context );
int compareResourcesDescending( Resource *r1, Resource *r2, void *context );
int compareResourcesAscending(Resource *r1, Resource *r2, void *context);
int compareResourcesDescending(Resource *r1, Resource *r2, void *context);
@end
@interface NSOutlineView (OutlineSortView)
- (void)swapForOutlineSortView;
@end
@interface OutlineSortView : NSOutlineView
@interface RKOutlineView : NSOutlineView
@end

View File

@ -1,11 +1,42 @@
#import "OutlineViewDelegate.h"
#import "Resource.h"
#import "ResourceDocument.h"
#import "ResourceDataSource.h"
#import "ResourceNameCell.h"
#import "ApplicationDelegat