2001-10-19 19:41:13 +00:00
# import "ApplicationDelegate.h"
2008-07-31 20:27:55 +00:00
# import "OpenPanelDelegate.h"
2003-04-03 15:38:42 +00:00
# import "RKDocumentController.h"
2001-10-19 19:41:13 +00:00
# import "InfoWindowController.h"
2003-04-03 15:38:42 +00:00
# import "PasteboardWindowController.h"
2001-10-19 19:41:13 +00:00
# import "PrefsWindowController.h"
# import "CreateResourceSheetController.h"
2002-02-02 11:31:28 +00:00
# import "ResourceDocument.h"
# import "ResourceDataSource.h"
2008-07-31 20:27:55 +00:00
# import "RKEditorRegistry.h"
2002-02-02 11:31:28 +00:00
2008-07-31 20:27:55 +00:00
# import "ResKnifePluginProtocol.h"
2003-08-20 14:53:20 +00:00
# import "RKSupportResourceRegistry.h"
2001-10-19 19:41:13 +00:00
@ implementation ApplicationDelegate
- ( id ) init
{
self = [ super init ] ;
2002-02-11 01:22:17 +00:00
[ NSApp registerServicesMenuSendTypes : [ NSArray arrayWithObject : NSStringPboardType ] returnTypes : [ NSArray arrayWithObject : NSStringPboardType ] ] ;
2001-10-19 19:41:13 +00:00
return self ;
}
2003-04-03 15:38:42 +00:00
- ( void ) applicationWillFinishLaunching : ( NSNotification * ) notification
{
// instanciate my own subclass of NSDocumentController so I can override the open dialog
2008-07-31 20:27:55 +00:00
[ [ RKDocumentController alloc ] init ] ;
[ RKSupportResourceRegistry scanForSupportResources ] ;
2003-04-03 15:38:42 +00:00
}
2008-07-31 20:27:55 +00:00
/ * !
@ method awakeFromNib
@ updated 2003 -10 -24 NGS : moved icon caching into method called by timer ( to speed up app launch time )
* /
2001-10-19 19:41:13 +00:00
- ( void ) awakeFromNib
{
// Part of my EvilPlan <EFBFBD> to find out how many people use ResKnife and how often !
int launchCount = [ [ NSUserDefaults standardUserDefaults ] integerForKey : @ "LaunchCount" ] ;
[ [ NSUserDefaults standardUserDefaults ] setInteger : launchCount + 1 forKey : @ "LaunchCount" ] ;
2008-07-31 20:27:55 +00:00
// 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 ] ;
2003-04-03 15:38:42 +00:00
2008-07-31 20:27:55 +00:00
// set default preferences
2001-10-19 19:41:13 +00:00
[ self initUserDefaults ] ;
2002-04-27 18:17:47 +00:00
}
- ( void ) dealloc
{
2008-07-31 20:27:55 +00:00
[ _icons release ] ;
2002-04-27 18:17:47 +00:00
[ super dealloc ] ;
}
2001-10-19 19:41:13 +00:00
2008-07-31 20:27:55 +00:00
/ * !
@ 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 ;
}
2002-02-11 01:22:17 +00:00
- ( BOOL ) applicationShouldOpenUntitledFile : ( NSApplication * ) sender
{
2008-07-31 20:27:55 +00:00
# pragma unused ( sender )
2002-02-23 03:40:24 +00:00
NSString * launchAction = [ [ NSUserDefaults standardUserDefaults ] stringForKey : @ "LaunchAction" ] ;
2008-07-31 20:27:55 +00:00
if ( [ launchAction isEqualToString : @ "OpenUntitledFile" ] )
2002-02-23 03:40:24 +00:00
return YES ;
2008-07-31 20:27:55 +00:00
else if ( [ launchAction isEqualToString : @ "DisplayOpenPanel" ] )
2002-02-23 03:40:24 +00:00
{
[ [ NSDocumentController sharedDocumentController ] openDocument : sender ] ;
return NO ;
}
else return NO ; // should be @ "None" , but we shall return NO for any other value
2002-02-11 01:22:17 +00:00
}
2002-05-31 00:17:53 +00:00
- ( BOOL ) application : ( NSApplication * ) application openFile : ( NSString * ) file
{
2008-07-31 20:27:55 +00:00
# pragma unused ( application )
2002-05-31 00:17:53 +00:00
// bug : check if application was an external editor ( e . g . Iconographer ) and update existing open file instead
[ [ NSDocumentController sharedDocumentController ] openDocumentWithContentsOfFile : file display : YES ] ;
2002-05-31 17:31:41 +00:00
return YES ;
2002-05-31 00:17:53 +00:00
}
2002-03-21 04:02:26 +00:00
- ( BOOL ) applicationShouldHandleReopen : ( NSApplication * ) sender hasVisibleWindows : ( BOOL ) flag
{
2008-07-31 20:27:55 +00:00
# pragma unused ( sender )
2002-03-21 04:02:26 +00:00
return ! flag ;
}
2002-02-02 11:31:28 +00:00
- ( IBAction ) showAbout : ( id ) sender
{
2008-07-31 20:27:55 +00:00
// 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 ] ;
2002-02-02 11:31:28 +00:00
}
2002-02-23 03:40:24 +00:00
- ( IBAction ) visitWebsite : ( id ) sender
{
2002-05-31 00:17:53 +00:00
[ [ NSWorkspace sharedWorkspace ] openURL : [ NSURL URLWithString : @ "http://web.nickshanks.com/resknife/" ] ] ;
2002-02-23 03:40:24 +00:00
}
- ( IBAction ) visitSourceforge : ( id ) sender
{
[ [ NSWorkspace sharedWorkspace ] openURL : [ NSURL URLWithString : @ "http://resknife.sourceforge.net/" ] ] ;
}
- ( IBAction ) emailDeveloper : ( id ) sender
{
[ [ NSWorkspace sharedWorkspace ] openURL : [ NSURL URLWithString : @ "mailto:resknife@nickshanks.com?Subject=Comments,%20Suggestions%20and%20Bug%20Reports" ] ] ;
}
2001-10-19 19:41:13 +00:00
- ( IBAction ) showInfo : ( id ) sender
{
[ [ InfoWindowController sharedInfoWindowController ] showWindow : sender ] ;
}
2003-04-03 15:38:42 +00:00
- ( IBAction ) showPasteboard : ( id ) sender
{
[ [ PasteboardWindowController sharedPasteboardWindowController ] showWindow : sender ] ;
}
2001-10-19 19:41:13 +00:00
- ( IBAction ) showPrefs : ( id ) sender
{
[ [ PrefsWindowController sharedPrefsWindowController ] showWindow : sender ] ;
}
- ( void ) initUserDefaults
{
// This should probably be added to NSUserDefaults as a category ,
// since its universally useful . It loads a defaults . plist file
// from the app wrapper , and then sets the defaults if they don ' t
// already exist .
NSUserDefaults * defaults ;
NSDictionary * defaultsPlist ;
NSEnumerator * overDefaults ;
id eachDefault ;
// this isn ' t required , but saves us a few method calls
defaults = [ NSUserDefaults standardUserDefaults ] ;
// load the defaults . plist from the app wrapper . This makes it
// easy to add new defaults just using a text editor instead of
// hard - coding them into the application
defaultsPlist = [ NSDictionary dictionaryWithContentsOfFile : [ [ NSBundle mainBundle ] pathForResource : @ "defaults" ofType : @ "plist" ] ] ;
// enumerate over all the keys in the dictionary
overDefaults = [ [ defaultsPlist allKeys ] objectEnumerator ] ;
2008-07-31 20:27:55 +00:00
while ( eachDefault = [ overDefaults nextObject ] )
2001-10-19 19:41:13 +00:00
{
// 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
2008-07-31 20:27:55 +00:00
if ( ! [ defaults stringForKey : eachDefault ] )
2001-10-19 19:41:13 +00:00
{
[ defaults setObject : [ defaultsPlist objectForKey : eachDefault ] forKey : eachDefault ] ;
}
}
// force the defaults to save to the disk
[ defaults synchronize ] ;
}
2008-07-31 20:27:55 +00:00
- ( OpenPanelDelegate * ) openPanelDelegate
2003-04-03 15:38:42 +00:00
{
2008-07-31 20:27:55 +00:00
return openPanelDelegate ;
2003-04-03 15:38:42 +00:00
}
2008-07-31 20:27:55 +00:00
/ * !
@ 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
2002-04-27 18:17:47 +00:00
{
2008-07-31 20:27:55 +00:00
// 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 ;
2002-04-27 18:17:47 +00:00
}
2008-07-31 20:27:55 +00:00
- ( NSMutableDictionary * ) _icons
{
return _icons ;
}
2002-02-23 03:40:24 +00:00
2008-07-31 20:27:55 +00:00
- ( NSDictionary * ) icons
2002-02-23 03:40:24 +00:00
{
2008-07-31 20:27:55 +00:00
return [ NSDictionary dictionaryWithDictionary : [ self _icons ] ] ;
}
2002-02-23 03:40:24 +00:00
@ end