2001-10-19 19:41:13 +00:00
# import "ResourceDocument.h"
2002-02-14 23:24:53 +00:00
# import "ResourceDataSource.h"
2002-02-07 03:45:43 +00:00
# import "ResourceNameCell.h"
2002-02-23 03:40:24 +00:00
# import "Resource.h"
2002-02-07 03:45:43 +00:00
# import "CreateResourceSheetController.h"
2002-02-23 03:40:24 +00:00
# import "NSOutlineView-SelectedItems.h"
2001-10-19 19:41:13 +00:00
2002-02-07 20:33:31 +00:00
# import "ResKnifePluginProtocol.h"
2002-03-31 12:00:02 +00:00
NSString * DocumentInfoWillChangeNotification = @ "DocumentInfoWillChangeNotification" ;
NSString * DocumentInfoDidChangeNotification = @ "DocumentInfoDidChangeNotification" ;
2001-10-19 19:41:13 +00:00
@ implementation ResourceDocument
- ( id ) init
{
self = [ super init ] ;
2002-02-02 11:31:28 +00:00
resources = [ [ NSMutableArray alloc ] init ] ;
2002-03-21 04:02:26 +00:00
fork = nil ;
2001-10-19 19:41:13 +00:00
return self ;
}
- ( void ) dealloc
{
2002-02-14 23:24:53 +00:00
[ [ NSNotificationCenter defaultCenter ] removeObserver : self ] ;
2002-03-21 04:02:26 +00:00
if ( fork ) DisposePtr ( ( Ptr ) fork ) ;
2001-10-19 19:41:13 +00:00
[ resources release ] ;
[ super dealloc ] ;
}
2002-02-06 20:57:56 +00:00
/ * WINDOW DELEGATION * /
2002-02-07 03:45:43 +00:00
# pragma mark -
2002-02-06 20:57:56 +00:00
2001-10-19 19:41:13 +00:00
- ( NSString * ) windowNibName
{
return @ "ResourceDocument" ;
}
2002-02-23 03:40:24 +00:00
/ * This is not used , just here for reference in case I need it in the future
- ( void ) makeWindowControllers
{
ResourceWindowController * resourceController = [ [ ResourceWindowController allocWithZone : [ self zone ] ] initWithWindowNibName : @ "ResourceDocument" ] ;
[ self addWindowController : resourceController ] ;
} * /
2002-02-02 11:31:28 +00:00
- ( void ) windowControllerDidLoadNib : ( NSWindowController * ) controller
2001-10-19 19:41:13 +00:00
{
2002-02-07 03:45:43 +00:00
[ super windowControllerDidLoadNib : controller ] ;
2002-02-06 20:57:56 +00:00
[ self setupToolbar : controller ] ;
2002-02-07 03:45:43 +00:00
{ // set up first column in outline view to display images as well as text
ResourceNameCell * resourceNameCell = [ [ [ ResourceNameCell alloc ] init ] autorelease ] ;
[ resourceNameCell setEditable : YES ] ;
[ [ outlineView tableColumnWithIdentifier : @ "name" ] setDataCell : resourceNameCell ] ;
}
2002-02-14 23:24:53 +00:00
// register for resource will change notifications ( for undo management )
[ [ NSNotificationCenter defaultCenter ] addObserver : self selector : @ selector ( resourceNameWillChange : ) name : ResourceNameWillChangeNotification object : nil ] ;
[ [ NSNotificationCenter defaultCenter ] addObserver : self selector : @ selector ( resourceIDWillChange : ) name : ResourceIDWillChangeNotification object : nil ] ;
[ [ NSNotificationCenter defaultCenter ] addObserver : self selector : @ selector ( resourceTypeWillChange : ) name : ResourceTypeWillChangeNotification object : nil ] ;
[ [ NSNotificationCenter defaultCenter ] addObserver : self selector : @ selector ( resourceAttributesWillChange : ) name : ResourceAttributesWillChangeNotification object : nil ] ;
2002-02-11 01:22:17 +00:00
// [ [ controller window ] setResizeIncrements : NSMakeSize ( 1 , 18 ) ] ;
2001-10-19 19:41:13 +00:00
[ dataSource setResources : resources ] ;
}
2002-02-15 01:52:23 +00:00
- ( void ) printShowingPrintPanel : ( BOOL ) flag
{
2002-02-23 03:40:24 +00:00
NSPrintOperation * printOperation = [ NSPrintOperation printOperationWithView : [ mainWindow contentView ] ] ;
[ printOperation runOperationModalForWindow : mainWindow delegate : self didRunSelector : @ selector ( printOperationDidRun : success : contextInfo : ) contextInfo : nil ] ;
2002-02-15 01:52:23 +00:00
}
- ( void ) printOperationDidRun : ( NSPrintOperation * ) printOperation success : ( BOOL ) success contextInfo : ( void * ) contextInfo
{
if ( ! success ) NSLog ( @ "Printing Failed!" ) ;
}
2001-10-19 19:41:13 +00:00
- ( BOOL ) keepBackupFile
{
2002-02-07 03:45:43 +00:00
return [ [ NSUserDefaults standardUserDefaults ] boolForKey : @ "PreserveBackups" ] ;
2001-10-19 19:41:13 +00:00
}
2002-02-14 23:24:53 +00:00
- ( BOOL ) validateMenuItem : ( NSMenuItem * ) item
{
2002-02-15 01:52:23 +00:00
int selectedRows = [ outlineView numberOfSelectedRows ] ;
2002-02-23 03:40:24 +00:00
Resource * resource = ( Resource * ) [ outlineView selectedItem ] ;
2002-02-15 01:52:23 +00:00
// file menu
2002-02-14 23:24:53 +00:00
if ( [ item action ] = = @ selector ( saveDocument : ) ) return [ self isDocumentEdited ] ;
2002-02-15 01:52:23 +00:00
// edit menu
else if ( [ item action ] = = @ selector ( clear : ) ) return selectedRows > 0 ;
else if ( [ item action ] = = @ selector ( selectAll : ) ) return [ outlineView numberOfRows ] > 0 ;
else if ( [ item action ] = = @ selector ( deselectAll : ) ) return selectedRows > 0 ;
// resource menu
2002-03-31 12:00:02 +00:00
else if ( [ item action ] = = @ selector ( openResources : ) ) return selectedRows > 0 ;
else if ( [ item action ] = = @ selector ( openResourcesAsHex : ) ) return selectedRows > 0 ;
2002-02-15 01:52:23 +00:00
else if ( [ item action ] = = @ selector ( playSound : ) ) return selectedRows = = 1 && [ [ resource type ] isEqualToString : @ "snd " ] ;
else if ( [ item action ] = = @ selector ( revertResourceToSaved : ) ) return selectedRows = = 1 && [ resource isDirty ] ;
2002-02-14 23:24:53 +00:00
else return [ super validateMenuItem : item ] ;
}
2002-02-06 20:57:56 +00:00
/ * TOOLBAR MANAGMENT * /
2002-02-07 03:45:43 +00:00
# pragma mark -
2002-02-06 20:57:56 +00:00
2002-02-11 01:22:17 +00:00
static NSString * RKToolbarIdentifier = @ "com.nickshanks.resknife.toolbar" ;
static NSString * RKCreateItemIdentifier = @ "com.nickshanks.resknife.toolbar.create" ;
static NSString * RKDeleteItemIdentifier = @ "com.nickshanks.resknife.toolbar.delete" ;
static NSString * RKEditItemIdentifier = @ "com.nickshanks.resknife.toolbar.edit" ;
static NSString * RKEditHexItemIdentifier = @ "com.nickshanks.resknife.toolbar.edithex" ;
static NSString * RKSaveItemIdentifier = @ "com.nickshanks.resknife.toolbar.save" ;
static NSString * RKShowInfoItemIdentifier = @ "com.nickshanks.resknife.toolbar.showinfo" ;
2002-02-06 20:57:56 +00:00
2002-02-23 03:40:24 +00:00
- ( void ) setupToolbar : ( NSWindowController * ) windowController
2002-02-06 20:57:56 +00:00
{
/ * This routine should become invalid once toolbars are integrated into nib files * /
2002-02-23 03:40:24 +00:00
if ( [ windowController window ] = = mainWindow )
{
NSToolbar * toolbar = [ [ [ NSToolbar alloc ] initWithIdentifier : RKToolbarIdentifier ] autorelease ] ;
// set toolbar properties
[ toolbar setVisible : NO ] ;
[ toolbar setAutosavesConfiguration : YES ] ;
[ toolbar setAllowsUserCustomization : YES ] ;
[ toolbar setDisplayMode : NSToolbarDisplayModeDefault ] ;
// attach toolbar to window
[ toolbar setDelegate : self ] ;
[ mainWindow setToolbar : toolbar ] ;
}
2002-02-06 20:57:56 +00:00
}
- ( NSToolbarItem * ) toolbar : ( NSToolbar * ) toolbar itemForItemIdentifier : ( NSString * ) itemIdentifier willBeInsertedIntoToolbar : ( BOOL ) flag
{
2002-02-07 03:45:43 +00:00
NSToolbarItem * item = [ [ [ NSToolbarItem alloc ] initWithItemIdentifier : itemIdentifier ] autorelease ] ;
if ( [ itemIdentifier isEqual : RKCreateItemIdentifier ] )
{
2002-02-14 23:24:53 +00:00
[ item setLabel : NSLocalizedString ( @ "Create" , nil ) ] ;
[ item setPaletteLabel : NSLocalizedString ( @ "Create" , nil ) ] ;
[ item setToolTip : NSLocalizedString ( @ "Create New Resource" , nil ) ] ;
2002-02-07 03:45:43 +00:00
[ item setImage : [ NSImage imageNamed : @ "Create" ] ] ;
[ item setTarget : self ] ;
[ item setAction : @ selector ( showCreateResourceSheet : ) ] ;
return item ;
}
else if ( [ itemIdentifier isEqual : RKDeleteItemIdentifier ] )
{
2002-02-14 23:24:53 +00:00
[ item setLabel : NSLocalizedString ( @ "Delete" , nil ) ] ;
[ item setPaletteLabel : NSLocalizedString ( @ "Delete" , nil ) ] ;
[ item setToolTip : NSLocalizedString ( @ "Delete Selected Resource" , nil ) ] ;
2002-02-07 03:45:43 +00:00
[ item setImage : [ NSImage imageNamed : @ "Delete" ] ] ;
2002-02-14 23:24:53 +00:00
[ item setTarget : self ] ;
2002-02-07 03:45:43 +00:00
[ item setAction : @ selector ( clear : ) ] ;
return item ;
}
else if ( [ itemIdentifier isEqual : RKEditItemIdentifier ] )
{
2002-02-14 23:24:53 +00:00
[ item setLabel : NSLocalizedString ( @ "Edit" , nil ) ] ;
[ item setPaletteLabel : NSLocalizedString ( @ "Edit" , nil ) ] ;
[ item setToolTip : NSLocalizedString ( @ "Edit Resource In Default Editor" , nil ) ] ;
2002-02-07 03:45:43 +00:00
[ item setImage : [ NSImage imageNamed : @ "Edit" ] ] ;
[ item setTarget : self ] ;
[ item setAction : @ selector ( openResource : ) ] ;
return item ;
}
else if ( [ itemIdentifier isEqual : RKEditHexItemIdentifier ] )
{
2002-02-14 23:24:53 +00:00
[ item setLabel : NSLocalizedString ( @ "Edit Hex" , nil ) ] ;
[ item setPaletteLabel : NSLocalizedString ( @ "Edit Hex" , nil ) ] ;
[ item setToolTip : NSLocalizedString ( @ "Edit Resource As Hexadecimal" , nil ) ] ;
2002-02-07 03:45:43 +00:00
[ item setImage : [ NSImage imageNamed : @ "Edit Hex" ] ] ;
[ item setTarget : self ] ;
[ item setAction : @ selector ( openResourceAsHex : ) ] ;
return item ;
}
else if ( [ itemIdentifier isEqual : RKSaveItemIdentifier ] )
2002-02-06 20:57:56 +00:00
{
2002-02-14 23:24:53 +00:00
[ item setLabel : NSLocalizedString ( @ "Save" , nil ) ] ;
[ item setPaletteLabel : NSLocalizedString ( @ "Save" , nil ) ] ;
2002-03-21 04:02:26 +00:00
[ item setToolTip : [ NSString stringWithFormat : NSLocalizedString ( @ "Save To %@ Fork" , nil ) , ! fork ? NSLocalizedString ( @ "Data" , nil ) : NSLocalizedString ( @ "Resource" , nil ) ] ] ;
2002-02-06 20:57:56 +00:00
[ item setImage : [ NSImage imageNamed : @ "Save" ] ] ;
[ item setTarget : self ] ;
[ item setAction : @ selector ( saveDocument : ) ] ;
return item ;
}
2002-02-07 03:45:43 +00:00
else if ( [ itemIdentifier isEqual : RKShowInfoItemIdentifier ] )
{
2002-02-14 23:24:53 +00:00
[ item setLabel : NSLocalizedString ( @ "Show Info" , nil ) ] ;
[ item setPaletteLabel : NSLocalizedString ( @ "Show Info" , nil ) ] ;
[ item setToolTip : NSLocalizedString ( @ "Show Resource Information Window" , nil ) ] ;
2002-02-07 03:45:43 +00:00
[ item setImage : [ NSImage imageNamed : @ "Show Info" ] ] ;
[ item setTarget : [ NSApp delegate ] ] ;
[ item setAction : @ selector ( showInfo : ) ] ;
return item ;
}
2002-02-06 20:57:56 +00:00
else return nil ;
}
- ( NSArray * ) toolbarDefaultItemIdentifiers : ( NSToolbar * ) toolbar
{
2002-02-07 03:45:43 +00:00
return [ NSArray arrayWithObjects : RKCreateItemIdentifier , RKEditItemIdentifier , RKEditHexItemIdentifier , NSToolbarSeparatorItemIdentifier , RKSaveItemIdentifier , NSToolbarPrintItemIdentifier , NSToolbarFlexibleSpaceItemIdentifier , NSToolbarCustomizeToolbarItemIdentifier , nil ] ;
2002-02-06 20:57:56 +00:00
}
- ( NSArray * ) toolbarAllowedItemIdentifiers : ( NSToolbar * ) toolbar
{
2002-02-07 03:45:43 +00:00
return [ NSArray arrayWithObjects : RKCreateItemIdentifier , RKDeleteItemIdentifier , RKEditItemIdentifier , RKEditHexItemIdentifier , RKSaveItemIdentifier , RKShowInfoItemIdentifier , NSToolbarPrintItemIdentifier , NSToolbarCustomizeToolbarItemIdentifier , NSToolbarFlexibleSpaceItemIdentifier , NSToolbarSpaceItemIdentifier , NSToolbarSeparatorItemIdentifier , nil ] ;
2002-02-06 20:57:56 +00:00
}
2002-02-07 03:45:43 +00:00
- ( BOOL ) validateToolbarItem : ( NSToolbarItem * ) item
{
BOOL valid = NO ;
2002-02-23 03:40:24 +00:00
int selectedRows = [ outlineView numberOfSelectedRows ] ;
2002-02-07 03:45:43 +00:00
NSString * identifier = [ item itemIdentifier ] ;
2002-02-14 23:24:53 +00:00
if ( [ identifier isEqualToString : RKCreateItemIdentifier ] ) valid = YES ;
2002-02-23 03:40:24 +00:00
else if ( [ identifier isEqualToString : RKDeleteItemIdentifier ] ) valid = selectedRows > 0 ;
2002-03-31 12:42:07 +00:00
else if ( [ identifier isEqualToString : RKEditItemIdentifier ] ) valid = selectedRows > 0 ;
2002-02-23 03:40:24 +00:00
else if ( [ identifier isEqualToString : RKEditHexItemIdentifier ] ) valid = selectedRows > 0 ;
2002-02-14 23:24:53 +00:00
else if ( [ identifier isEqualToString : RKSaveItemIdentifier ] ) valid = [ self isDocumentEdited ] ;
else if ( [ identifier isEqualToString : NSToolbarPrintItemIdentifier ] ) valid = YES ;
2002-02-07 03:45:43 +00:00
return valid ;
}
/ * DOCUMENT MANAGEMENT * /
# pragma mark -
- ( IBAction ) showCreateResourceSheet : ( id ) sender
{
2002-02-23 03:40:24 +00:00
// bug : ResourceDocument allocs a sheet controller , but it ' s never disposed of
CreateResourceSheetController * sheetController = [ [ CreateResourceSheetController alloc ] initWithWindowNibName : @ "CreateResourceSheet" ] ;
[ sheetController showCreateResourceSheet : self ] ;
2002-02-07 03:45:43 +00:00
}
2002-02-11 01:22:17 +00:00
2002-03-31 12:00:02 +00:00
- ( IBAction ) openResources : ( id ) sender
2002-02-07 03:45:43 +00:00
{
2002-03-31 12:00:02 +00:00
Resource * resource ;
NSArray * selected = [ outlineView selectedItems ] ;
NSEnumerator * enumerator = [ selected objectEnumerator ] ;
while ( resource = [ enumerator nextObject ] )
[ self openResourceUsingEditor : resource ] ;
2002-02-23 03:40:24 +00:00
}
2002-03-31 12:00:02 +00:00
- ( IBAction ) openResourcesInTemplate : ( id ) sender
2002-02-23 03:40:24 +00:00
{
2002-03-31 12:00:02 +00:00
// opens the resource in its default template
Resource * resource ;
NSArray * selected = [ outlineView selectedItems ] ;
NSEnumerator * enumerator = [ selected objectEnumerator ] ;
while ( resource = [ enumerator nextObject ] )
[ self openResource : resource usingTemplate : [ resource type ] ] ;
}
- ( IBAction ) openResourcesAsHex : ( id ) sender
{
Resource * resource ;
NSArray * selected = [ outlineView selectedItems ] ;
NSEnumerator * enumerator = [ selected objectEnumerator ] ;
while ( resource = [ enumerator nextObject ] )
[ self openResourceAsHex : resource ] ;
2002-02-23 03:40:24 +00:00
}
2002-03-31 12:00:02 +00:00
- ( void ) openResourceUsingEditor : ( Resource * ) resource
{
// Placeholder , change at some point .
[ self openResource : resource usingTemplate : [ resource type ] ] ;
}
- ( void ) openResource : ( Resource * ) resource usingTemplate : ( NSString * ) templateName
2002-02-23 03:40:24 +00:00
{
// opens resource in template using TMPL resource with name templateName
NSBundle * templateEditor = [ NSBundle bundleWithPath : [ [ [ NSBundle mainBundle ] builtInPlugInsPath ] stringByAppendingPathComponent : @ "Template Editor.plugin" ] ] ;
2002-03-31 12:00:02 +00:00
2002-03-31 12:42:07 +00:00
// bug : this only checks the CURRENT DOCUMENT for template resources
2002-02-23 03:40:24 +00:00
Resource * tmpl = [ dataSource resourceNamed : [ resource type ] ofType : @ "TMPL" ] ;
2002-03-31 12:00:02 +00:00
// open the resources , passing in the template to use
2002-02-23 03:40:24 +00:00
if ( tmpl / * && [ [ templateEditor principalClass ] respondsToSelector : @ selector ( initWithResources : ) ] * / )
{
// bug : I alloc a plug instance here , but have no idea where I should dealloc it , perhaps the plug ought to call [ self autorelease ] when it ' s last window is closed ?
[ ( id < ResKnifePluginProtocol > ) [ [ templateEditor principalClass ] alloc ] initWithResources : resource , tmpl , nil ] ;
}
// if no template exists , or template editor is broken , open as hex
2002-03-31 12:00:02 +00:00
else [ self openResourceAsHex : resource ] ;
2002-02-07 03:45:43 +00:00
}
2002-02-11 01:22:17 +00:00
2002-03-31 12:00:02 +00:00
- ( void ) openResourceAsHex : ( Resource * ) resource
2002-02-07 03:45:43 +00:00
{
2002-02-07 20:33:31 +00:00
NSBundle * hexEditor = [ NSBundle bundleWithPath : [ [ [ NSBundle mainBundle ] builtInPlugInsPath ] stringByAppendingPathComponent : @ "Hexadecimal Editor.plugin" ] ] ;
2002-03-31 12:00:02 +00:00
// bug : I alloc a plug instance here , but have no idea where I should dealloc it , perhaps the plug ought to call [ self autorelease ] when it ' s last window is closed ?
2002-02-23 03:40:24 +00:00
2002-02-07 20:33:31 +00:00
[ ( id < ResKnifePluginProtocol > ) [ [ hexEditor principalClass ] alloc ] initWithResource : resource ] ;
2002-02-07 03:45:43 +00:00
}
2002-02-11 01:22:17 +00:00
2002-02-07 03:45:43 +00:00
- ( IBAction ) playSound : ( id ) sender
{
2002-03-31 12:00:02 +00:00
// bug : Can only cope with one selected item
2002-02-12 04:01:47 +00:00
Resource * resource = [ outlineView itemAtRow : [ outlineView selectedRow ] ] ;
NSSound * sound = [ [ NSSound alloc ] initWithData : [ resource data ] ] ;
[ sound setDelegate : self ] ;
[ sound play ] ;
}
- ( void ) sound : ( NSSound * ) sound didFinishPlaying : ( BOOL ) finished
{
if ( finished ) [ sound release ] ;
NSLog ( @ "sound released" ) ;
2002-02-07 03:45:43 +00:00
}
2002-02-11 01:22:17 +00:00
2002-02-14 23:24:53 +00:00
- ( void ) resourceNameWillChange : ( NSNotification * ) notification
{
// this saves the current resource ' s name so we can undo the change
Resource * resource = ( Resource * ) [ notification object ] ;
[ [ self undoManager ] registerUndoWithTarget : resource selector : @ selector ( setName : ) object : [ [ [ resource name ] copy ] autorelease ] ] ;
[ [ self undoManager ] setActionName : NSLocalizedString ( @ "Name Change" , nil ) ] ;
}
- ( void ) resourceIDWillChange : ( NSNotification * ) notification
{
// this saves the current resource ' s ID number so we can undo the change
Resource * resource = ( Resource * ) [ notification object ] ;
[ [ self undoManager ] registerUndoWithTarget : resource selector : @ selector ( setResID : ) object : [ [ [ resource resID ] copy ] autorelease ] ] ;
if ( [ [ resource name ] length ] = = 0 )
[ [ self undoManager ] setActionName : NSLocalizedString ( @ "ID Change" , nil ) ] ;
else [ [ self undoManager ] setActionName : [ NSString stringWithFormat : NSLocalizedString ( @ "ID Change for <20> %@<40> " , nil ) , [ resource name ] ] ] ;
}
- ( void ) resourceTypeWillChange : ( NSNotification * ) notification
{
// this saves the current resource ' s type so we can undo the change
Resource * resource = ( Resource * ) [ notification object ] ;
[ [ self undoManager ] registerUndoWithTarget : resource selector : @ selector ( setType : ) object : [ [ [ resource type ] copy ] autorelease ] ] ;
if ( [ [ resource name ] length ] = = 0 )
[ [ self undoManager ] setActionName : NSLocalizedString ( @ "Type Change" , nil ) ] ;
else [ [ self undoManager ] setActionName : [ NSString stringWithFormat : NSLocalizedString ( @ "Type Change for <20> %@<40> " , nil ) , [ resource name ] ] ] ;
}
- ( void ) resourceAttributesWillChange : ( NSNotification * ) notification
{
// this saves the current state of the resource ' s attributes so we can undo the change
Resource * resource = ( Resource * ) [ notification object ] ;
[ [ self undoManager ] registerUndoWithTarget : resource selector : @ selector ( setAttributes : ) object : [ [ [ resource attributes ] copy ] autorelease ] ] ;
if ( [ [ resource name ] length ] = = 0 )
[ [ self undoManager ] setActionName : NSLocalizedString ( @ "Attributes Change" , nil ) ] ;
else [ [ self undoManager ] setActionName : [ NSString stringWithFormat : NSLocalizedString ( @ "Attributes Change for <20> %@<40> " , nil ) , [ resource name ] ] ] ;
}
/ * EDIT OPERATIONS * /
# pragma mark -
- ( IBAction ) clear : ( id ) sender
{
Resource * resource ;
2002-03-31 12:42:07 +00:00
NSEnumerator * enumerator ;
NSArray * selectedItems = [ outlineView selectedItems ] ;
2002-02-14 23:24:53 +00:00
// enumerate through array and delete resources
2002-03-31 12:42:07 +00:00
[ [ self undoManager ] beginUndoGrouping ] ;
enumerator = [ selectedItems reverseObjectEnumerator ] ; // reverse so an undo will replace items in original order
2002-02-14 23:24:53 +00:00
while ( resource = [ enumerator nextObject ] )
{
[ dataSource removeResource : resource ] ;
if ( [ [ resource name ] length ] = = 0 )
[ [ self undoManager ] setActionName : NSLocalizedString ( @ "Delete Resource" , nil ) ] ;
else [ [ self undoManager ] setActionName : [ NSString stringWithFormat : NSLocalizedString ( @ "Delete Resource <20> %@<40> " , nil ) , [ resource name ] ] ] ;
}
[ [ self undoManager ] endUndoGrouping ] ;
// generalise undo name if more than one was deleted
2002-03-31 12:42:07 +00:00
if ( [ outlineView numberOfSelectedRows ] > 1 )
2002-02-14 23:24:53 +00:00
[ [ self undoManager ] setActionName : NSLocalizedString ( @ "Delete Resources" , nil ) ] ;
// deselct resources ( otherwise other resources move into selected rows ! )
[ outlineView deselectAll : self ] ;
}
2002-02-06 20:57:56 +00:00
/ * FILE HANDLING * /
2002-02-07 03:45:43 +00:00
# pragma mark -
2002-02-06 20:57:56 +00:00
2002-02-23 03:40:24 +00:00
/ * - ( BOOL ) prepareSavePanel : ( NSSavePanel * ) savePanel
{
[ savePanel setTreatsFilePackagesAsDirectories : YES ] ;
return YES ;
} * /
2001-10-19 19:41:13 +00:00
- ( BOOL ) readFromFile : ( NSString * ) fileName ofType : ( NSString * ) type
{
BOOL succeeded = NO ;
OSStatus error = noErr ;
HFSUniStr255 * resourceForkName = ( HFSUniStr255 * ) NewPtrClear ( sizeof ( HFSUniStr255 ) ) ;
FSRef * fileRef = ( FSRef * ) NewPtrClear ( sizeof ( FSRef ) ) ;
SInt16 fileRefNum = 0 ;
// open fork with resources in it
error = FSPathMakeRef ( [ fileName cString ] , fileRef , nil ) ;
error = FSGetResourceForkName ( resourceForkName ) ;
SetResLoad ( false ) ; // don ' t load "preload" resources
error = FSOpenResourceFile ( fileRef , resourceForkName -> length , ( UniChar * ) & resourceForkName -> unicode , fsRdPerm , & fileRefNum ) ;
if ( error ) // try to open data fork instead
2002-02-23 03:40:24 +00:00
{
NSLog ( @ "Opening Resource fork failed, trying data fork..." ) ;
2001-10-19 19:41:13 +00:00
error = FSOpenResourceFile ( fileRef , 0 , nil , fsRdPerm , & fileRefNum ) ;
2002-02-23 03:40:24 +00:00
}
2002-03-21 04:02:26 +00:00
else fork = resourceForkName ;
2001-10-19 19:41:13 +00:00
SetResLoad ( true ) ; // restore resource loading as soon as is possible
2002-02-23 03:40:24 +00:00
// read the resources ( without spawning thousands of undos for resource creation )
[ [ self undoManager ] disableUndoRegistration ] ;
2001-10-19 19:41:13 +00:00
if ( fileRefNum && ! error )
succeeded = [ self readResourceMap : fileRefNum ] ;
2002-03-21 04:02:26 +00:00
else if ( ! fileRefNum )
{
// supposed to read data fork as byte stream here
NSLog ( @ "Opening data fork failed too! (fileRef)" ) ;
}
2002-02-23 03:40:24 +00:00
else NSLog ( @ "Opening data fork failed too! (error)" ) ;
[ [ self undoManager ] enableUndoRegistration ] ;
2001-10-19 19:41:13 +00:00
// tidy up loose ends
2002-03-21 04:02:26 +00:00
if ( ! fork ) DisposePtr ( ( Ptr ) resourceForkName ) ; // only delete if we ' re not saving it
2001-10-19 19:41:13 +00:00
if ( fileRefNum ) FSClose ( fileRefNum ) ;
DisposePtr ( ( Ptr ) fileRef ) ;
return succeeded ;
}
- ( BOOL ) readResourceMap : ( SInt16 ) fileRefNum
{
OSStatus error = noErr ;
unsigned short i , j , n ;
SInt16 oldResFile = CurResFile ( ) ;
UseResFile ( fileRefNum ) ;
for ( i = 1 ; i <= Count1Types ( ) ; i + + )
{
ResType resType ;
Get1IndType ( & resType , i ) ;
n = Count1Resources ( resType ) ;
for ( j = 1 ; j <= n ; j + + )
{
Str255 nameStr ;
long sizeLong ;
short resIDShort ;
short attrsShort ;
Handle resourceHandle ;
resourceHandle = Get1IndResource ( resType , j ) ;
error = ResError ( ) ;
if ( error ! = noErr )
{
2002-02-23 03:40:24 +00:00
NSLog ( @ "Error reading resource map..." ) ;
2001-10-19 19:41:13 +00:00
UseResFile ( oldResFile ) ;
return NO ;
}
GetResInfo ( resourceHandle , & resIDShort , & resType , nameStr ) ;
sizeLong = GetResourceSizeOnDisk ( resourceHandle ) ;
attrsShort = GetResAttrs ( resourceHandle ) ;
HLockHi ( resourceHandle ) ;
2002-02-02 11:31:28 +00:00
// create the resource & add it to the array
2001-10-19 19:41:13 +00:00
{
NSString * name = [ NSString stringWithCString : & nameStr [ 1 ] length : nameStr [ 0 ] ] ;
NSString * type = [ NSString stringWithCString : ( char * ) & resType length : 4 ] ;
NSNumber * resID = [ NSNumber numberWithShort : resIDShort ] ;
NSNumber * attributes = [ NSNumber numberWithShort : attrsShort ] ;
NSData * data = [ NSData dataWithBytes : * resourceHandle length : sizeLong ] ;
2002-02-14 23:24:53 +00:00
Resource * resource = [ Resource resourceOfType : type andID : resID withName : name andAttributes : attributes data : data ] ;
2002-02-02 11:31:28 +00:00
[ resources addObject : resource ] ; // array retains resource
2001-10-19 19:41:13 +00:00
}
HUnlock ( resourceHandle ) ;
ReleaseResource ( resourceHandle ) ;
}
}
// save resource map and clean up
UseResFile ( oldResFile ) ;
return YES ;
}
- ( BOOL ) writeToFile : ( NSString * ) fileName ofType : ( NSString * ) type
{
BOOL succeeded = NO ;
OSStatus error = noErr ;
FSRef * parentRef = ( FSRef * ) NewPtrClear ( sizeof ( FSRef ) ) ;
FSRef * fileRef = ( FSRef * ) NewPtrClear ( sizeof ( FSRef ) ) ;
FSSpec * fileSpec = ( FSSpec * ) NewPtrClear ( sizeof ( FSSpec ) ) ;
SInt16 fileRefNum = 0 ;
// create and open file for writing
error = FSPathMakeRef ( [ [ fileName stringByDeletingLastPathComponent ] cString ] , parentRef , nil ) ;
2002-03-21 04:02:26 +00:00
if ( fork )
2001-10-19 19:41:13 +00:00
{
unichar * uniname = ( unichar * ) NewPtrClear ( sizeof ( unichar ) * 256 ) ;
[ [ fileName lastPathComponent ] getCharacters : uniname ] ;
2002-03-21 04:02:26 +00:00
error = FSCreateResourceFile ( parentRef , [ [ fileName lastPathComponent ] length ] , ( UniChar * ) uniname , kFSCatInfoNone , nil , fork -> length , ( UniChar * ) & fork -> unicode , fileRef , fileSpec ) ;
2001-10-19 19:41:13 +00:00
if ( ! error )
2002-03-21 04:02:26 +00:00
error = FSOpenResourceFile ( fileRef , fork -> length , ( UniChar * ) & fork -> unicode , fsWrPerm , & fileRefNum ) ;
2001-10-19 19:41:13 +00:00
}
else
{
unichar * uniname = ( unichar * ) NewPtrClear ( sizeof ( unichar ) * 256 ) ;
[ [ fileName lastPathComponent ] getCharacters : uniname ] ;
error = FSCreateResourceFile ( parentRef , [ [ fileName lastPathComponent ] length ] , ( UniChar * ) uniname , kFSCatInfoNone , nil , 0 , nil , fileRef , fileSpec ) ;
if ( ! error )
error = FSOpenResourceFile ( fileRef , 0 , nil , fsWrPerm , & fileRefNum ) ;
}
// write resource array to file
if ( fileRefNum && ! error )
succeeded = [ self writeResourceMap : fileRefNum ] ;
// tidy up loose ends
if ( fileRefNum ) FSClose ( fileRefNum ) ;
DisposePtr ( ( Ptr ) fileRef ) ;
return succeeded ;
}
- ( BOOL ) writeResourceMap : ( SInt16 ) fileRefNum
{
OSStatus error = noErr ;
unsigned long i ;
SInt16 oldResFile = CurResFile ( ) ;
UseResFile ( fileRefNum ) ;
for ( i = 0 ; i < [ resources count ] ; i + + )
{
Resource * resource = [ resources objectAtIndex : i ] ;
Str255 nameStr ;
ResType resType ;
short resIDShort = [ [ resource resID ] shortValue ] ;
short attrsShort = [ [ resource attributes ] shortValue ] ;
2002-02-14 23:24:53 +00:00
Handle resourceHandle = NewHandleClear ( [ [ resource data ] length ] ) ;
2001-10-19 19:41:13 +00:00
nameStr [ 0 ] = [ [ resource name ] cStringLength ] ;
BlockMoveData ( [ [ resource name ] cString ] , & nameStr [ 1 ] , nameStr [ 0 ] ) ;
[ [ resource type ] getCString : ( char * ) & resType maxLength : 4 ] ;
HLockHi ( resourceHandle ) ;
[ [ resource data ] getBytes : * resourceHandle ] ;
HUnlock ( resourceHandle ) ;
AddResource ( resourceHandle , resType , resIDShort , nameStr ) ;
if ( ResError ( ) = = addResFailed )
{
2002-02-14 23:24:53 +00:00
NSLog ( @ "*Saving failed*; could not add resource ID %@ of type %@ to file." , [ resource resID ] , [ resource type ] ) ;
2001-10-19 19:41:13 +00:00
error = addResFailed ;
}
else
{
2002-02-02 11:31:28 +00:00
NSLog ( @ "Added resource %@, \" % @ \ ", of type %@ to file." , [ resource resID ] , [ resource name ] , [ resource type ] ) ;
2001-10-19 19:41:13 +00:00
SetResAttrs ( resourceHandle , attrsShort ) ;
ChangedResource ( resourceHandle ) ;
UpdateResFile ( fileRefNum ) ;
}
}
// save resource map and clean up
UseResFile ( oldResFile ) ;
return error ? NO : YES ;
}
2002-02-06 20:57:56 +00:00
/ * ACCESSORS * /
2002-02-07 03:45:43 +00:00
# pragma mark -
2002-02-06 20:57:56 +00:00
2002-02-23 03:40:24 +00:00
- ( NSWindow * ) mainWindow
2001-10-19 19:41:13 +00:00
{
2002-02-23 03:40:24 +00:00
return mainWindow ;
2001-10-19 19:41:13 +00:00
}
- ( ResourceDataSource * ) dataSource
{
return dataSource ;
}
2002-02-23 03:40:24 +00:00
- ( NSOutlineView * ) outlineView
{
return outlineView ;
}
2002-02-12 01:24:53 +00:00
- ( NSArray * ) resources
{
return resources ;
}
2002-03-31 12:00:02 +00:00
- ( NSString * ) creator
{
return creator ;
}
- ( NSString * ) type
{
return type ;
}
- ( IBAction ) creatorChanged : ( id ) sender
{
[ self setCreator : [ sender stringValue ] ] ;
}
- ( IBAction ) typeChanged : ( id ) sender
{
[ self setType : [ sender stringValue ] ] ;
}
- ( void ) setCreator : ( NSString * ) newCreator
{
if ( ! [ newCreator isEqualToString : creator ] )
{
id old = creator ;
[ [ NSNotificationCenter defaultCenter ] postNotificationName : DocumentInfoWillChangeNotification object : [ NSDictionary dictionaryWithObjectsAndKeys : self , @ "NSDocument" , newCreator , @ "NSString creator" , nil ] ] ;
[ [ self undoManager ] registerUndoWithTarget : self selector : @ selector ( setCreator : ) object : creator ] ;
[ [ self undoManager ] setActionName : NSLocalizedString ( @ "Change Creator Code" , nil ) ] ;
creator = [ newCreator copy ] ;
[ old release ] ;
[ [ NSNotificationCenter defaultCenter ] postNotificationName : DocumentInfoDidChangeNotification object : [ NSDictionary dictionaryWithObjectsAndKeys : self , @ "NSDocument" , newCreator , @ "NSString creator" , nil ] ] ;
}
}
- ( void ) setType : ( NSString * ) newType
{
if ( ! [ newType isEqualToString : type ] )
{
id old = type ;
[ [ NSNotificationCenter defaultCenter ] postNotificationName : DocumentInfoWillChangeNotification object : [ NSDictionary dictionaryWithObjectsAndKeys : self , @ "NSDocument" , newType , @ "NSString type" , nil ] ] ;
[ [ self undoManager ] registerUndoWithTarget : self selector : @ selector ( setType : ) object : type ] ;
[ [ self undoManager ] setActionName : NSLocalizedString ( @ "Change File Type" , nil ) ] ;
type = [ newType copy ] ;
[ old release ] ;
[ [ NSNotificationCenter defaultCenter ] postNotificationName : DocumentInfoDidChangeNotification object : [ NSDictionary dictionaryWithObjectsAndKeys : self , @ "NSDocument" , newType , @ "NSString type" , nil ] ] ;
}
}
- ( void ) setCreator : ( NSString * ) newCreator andType : ( NSString * ) newType
{
BOOL changeAction = ! [ newCreator isEqualToString : creator ] && ! [ newType isEqualToString : type ] ;
[ [ self undoManager ] beginUndoGrouping ] ;
[ self setCreator : newCreator ] ;
[ self setType : newType ] ;
[ [ self undoManager ] endUndoGrouping ] ;
if ( changeAction )
[ [ self undoManager ] setActionName : NSLocalizedString ( @ "Change Creator & Type" , nil ) ] ;
}
@ end