mirror of
https://github.com/nickshanks/ResKnife.git
synced 2024-06-03 01:29:40 +00:00
Added save dialog to Hex Editor and finished Boom & Char Nova Tools
This commit is contained in:
parent
a484060e30
commit
9f6f97977b
|
@ -667,7 +667,7 @@ pascal OSStatus CarbonEventUpdateMenus( EventHandlerCallRef callRef, EventRef ev
|
||||||
{
|
{
|
||||||
#pragma unused( callRef, event, userData )
|
#pragma unused( callRef, event, userData )
|
||||||
OSStatus error = eventNotHandledErr;
|
OSStatus error = eventNotHandledErr;
|
||||||
Boolean fileOpen = (Boolean) FrontNonFloatingWindow();
|
Boolean fileOpen = (Boolean) (FrontNonFloatingWindow() != NULL);
|
||||||
|
|
||||||
// application menu (passing null causes all menus to be searched)
|
// application menu (passing null causes all menus to be searched)
|
||||||
EnableCommand( null, kMenuCommandAbout, true );
|
EnableCommand( null, kMenuCommandAbout, true );
|
||||||
|
@ -1046,6 +1046,7 @@ OSStatus ShowAboutBox( void )
|
||||||
SetRect( &creationBounds, 0, 0, 300, 300 );
|
SetRect( &creationBounds, 0, 0, 300, 300 );
|
||||||
OffsetRect( &creationBounds, 50, 50 );
|
OffsetRect( &creationBounds, 50, 50 );
|
||||||
OSStatus error = CreateNewWindow( kDocumentWindowClass, kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute | kWindowInWindowMenuAttribute, &creationBounds, &window );
|
OSStatus error = CreateNewWindow( kDocumentWindowClass, kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute | kWindowInWindowMenuAttribute, &creationBounds, &window );
|
||||||
|
if( error ) return error;
|
||||||
|
|
||||||
ControlRef picControl;
|
ControlRef picControl;
|
||||||
ControlButtonContentInfo content;
|
ControlButtonContentInfo content;
|
||||||
|
|
|
@ -8,7 +8,7 @@ extern globals g;
|
||||||
/*** CREATOR ***/
|
/*** CREATOR ***/
|
||||||
EditorWindow::EditorWindow( FileWindowPtr ownerFile, ResourceObjectPtr targetResource, WindowRef inputWindow ) : PlugWindow( ownerFile )
|
EditorWindow::EditorWindow( FileWindowPtr ownerFile, ResourceObjectPtr targetResource, WindowRef inputWindow ) : PlugWindow( ownerFile )
|
||||||
{
|
{
|
||||||
OSStatus error = noErr;
|
// OSStatus error = noErr;
|
||||||
|
|
||||||
// set default variables
|
// set default variables
|
||||||
window = inputWindow;
|
window = inputWindow;
|
||||||
|
|
|
@ -369,7 +369,7 @@ pascal OSStatus FileWindowEventHandler( EventHandlerCallRef callRef, EventRef ev
|
||||||
pascal OSStatus FileWindowUpdateMenus( EventHandlerCallRef callRef, EventRef event, void *userData )
|
pascal OSStatus FileWindowUpdateMenus( EventHandlerCallRef callRef, EventRef event, void *userData )
|
||||||
{
|
{
|
||||||
#pragma unused( callRef, event )
|
#pragma unused( callRef, event )
|
||||||
OSStatus error = eventNotHandledErr;
|
// OSStatus error = eventNotHandledErr;
|
||||||
|
|
||||||
// get file window
|
// get file window
|
||||||
FileWindowPtr file = (FileWindowPtr) userData;
|
FileWindowPtr file = (FileWindowPtr) userData;
|
||||||
|
@ -1602,7 +1602,7 @@ OSStatus FileWindow::OpenResource( DataBrowserItemID itemID, MenuCommand command
|
||||||
#pragma unused( command )
|
#pragma unused( command )
|
||||||
// get opened resource
|
// get opened resource
|
||||||
OSStatus error = noErr;
|
OSStatus error = noErr;
|
||||||
Boolean stop = false;
|
// Boolean stop = false;
|
||||||
ResourceObjectPtr resource = GetResource( itemID );
|
ResourceObjectPtr resource = GetResource( itemID );
|
||||||
|
|
||||||
// check for null resource
|
// check for null resource
|
||||||
|
|
|
@ -200,10 +200,10 @@ OSStatus FileWindow::DisplayModelessAskSaveChangesDialog( void )
|
||||||
{
|
{
|
||||||
OSStatus error;
|
OSStatus error;
|
||||||
NavEventUPP eventProc = NewNavEventUPP( ModelessAskSaveChangesHandler );
|
NavEventUPP eventProc = NewNavEventUPP( ModelessAskSaveChangesHandler );
|
||||||
NavPreviewUPP previewProc = null;
|
/* NavPreviewUPP previewProc = null;
|
||||||
NavObjectFilterUPP filterProc = null;
|
NavObjectFilterUPP filterProc = null;
|
||||||
NavTypeListHandle typeList = null;
|
NavTypeListHandle typeList = null;
|
||||||
NavAskSaveChangesAction action = g.quitting? kNavSaveChangesQuittingApplication : kNavSaveChangesClosingDocument;
|
*/ NavAskSaveChangesAction action = g.quitting? kNavSaveChangesQuittingApplication : kNavSaveChangesClosingDocument;
|
||||||
NavDialogCreationOptions options;
|
NavDialogCreationOptions options;
|
||||||
error = NavGetDefaultDialogCreationOptions( &options );
|
error = NavGetDefaultDialogCreationOptions( &options );
|
||||||
options.parentWindow = window;
|
options.parentWindow = window;
|
||||||
|
@ -438,7 +438,7 @@ pascal void ModelessAskSaveChangesHandler( const NavEventCallbackMessage callBac
|
||||||
pascal void ModelessPutFileHandler( const NavEventCallbackMessage callBackSelector, NavCBRecPtr cbRecord, NavCallBackUserData callBackUD )
|
pascal void ModelessPutFileHandler( const NavEventCallbackMessage callBackSelector, NavCBRecPtr cbRecord, NavCallBackUserData callBackUD )
|
||||||
{
|
{
|
||||||
OSStatus error = noErr;
|
OSStatus error = noErr;
|
||||||
FileWindowPtr file = (FileWindowPtr) callBackUD;
|
// FileWindowPtr file = (FileWindowPtr) callBackUD;
|
||||||
switch( callBackSelector )
|
switch( callBackSelector )
|
||||||
{
|
{
|
||||||
case kNavCBUserAction:
|
case kNavCBUserAction:
|
||||||
|
@ -464,7 +464,7 @@ pascal void ModelessPutFileHandler( const NavEventCallbackMessage callBackSelect
|
||||||
pascal void ModelessAskDiscardChangesHandler( const NavEventCallbackMessage callBackSelector, NavCBRecPtr cbRecord, NavCallBackUserData callBackUD )
|
pascal void ModelessAskDiscardChangesHandler( const NavEventCallbackMessage callBackSelector, NavCBRecPtr cbRecord, NavCallBackUserData callBackUD )
|
||||||
{
|
{
|
||||||
OSStatus error = noErr;
|
OSStatus error = noErr;
|
||||||
FileWindowPtr file = (FileWindowPtr) callBackUD;
|
// FileWindowPtr file = (FileWindowPtr) callBackUD;
|
||||||
switch( callBackSelector )
|
switch( callBackSelector )
|
||||||
{
|
{
|
||||||
case kNavCBUserAction:
|
case kNavCBUserAction:
|
||||||
|
|
|
@ -55,7 +55,7 @@ Plug_PlugInRef Host_GetPlugRef( WindowRef window )
|
||||||
|
|
||||||
Plug_ResourceRef Host_GetResource( ResType type, SInt32 resID, Plug_ResourceRef sameFileAsResource )
|
Plug_ResourceRef Host_GetResource( ResType type, SInt32 resID, Plug_ResourceRef sameFileAsResource )
|
||||||
{
|
{
|
||||||
FilWindowPtr file;
|
// FileWindowPtr file;
|
||||||
if( sameFileAsResource != NULL )
|
if( sameFileAsResource != NULL )
|
||||||
{
|
{
|
||||||
// file = ((ResourceObjectPtr) sameFileAsResource)->file;
|
// file = ((ResourceObjectPtr) sameFileAsResource)->file;
|
||||||
|
|
|
@ -25,85 +25,89 @@ InspectorWindow::InspectorWindow( void )
|
||||||
SetRect( &creationBounds, 0, 0, kInspectorWindowWidth, kInspectorWindowHeight );
|
SetRect( &creationBounds, 0, 0, kInspectorWindowWidth, kInspectorWindowHeight );
|
||||||
OffsetRect( &creationBounds, 520, 45 );
|
OffsetRect( &creationBounds, 520, 45 );
|
||||||
OSStatus error = CreateNewWindow( kFloatingWindowClass, kWindowStandardFloatingAttributes | kWindowStandardHandlerAttribute, &creationBounds, &window );
|
OSStatus error = CreateNewWindow( kFloatingWindowClass, kWindowStandardFloatingAttributes | kWindowStandardHandlerAttribute, &creationBounds, &window );
|
||||||
GetIndString( windowName, kWindowNameStrings, kStringInspectorWindowName );
|
if( !error )
|
||||||
SetWindowTitle( window, windowName );
|
|
||||||
SetWindowKind( window, kInspectorWindowKind );
|
|
||||||
SetThemeWindowBackground( window, kThemeBrushUtilityWindowBackgroundActive, false );
|
|
||||||
|
|
||||||
// install window event handler
|
|
||||||
EventHandlerRef ref = null;
|
|
||||||
EventHandlerUPP eventHandler = NewEventHandlerUPP( CloseInspectorWindow );
|
|
||||||
EventTypeSpec events[] = { { kEventClassWindow, kEventWindowClose } };
|
|
||||||
InstallWindowEventHandler( window, eventHandler, GetEventTypeCount(events), (EventTypeSpec *) &events, this, &ref );
|
|
||||||
|
|
||||||
// create root control
|
|
||||||
Rect bounds;
|
|
||||||
if( g.systemVersion < kMacOSX )
|
|
||||||
{
|
{
|
||||||
ControlRef root;
|
GetIndString( windowName, kWindowNameStrings, kStringInspectorWindowName );
|
||||||
CreateRootControl( window, &root );
|
SetWindowTitle( window, windowName );
|
||||||
|
SetWindowKind( window, kInspectorWindowKind );
|
||||||
|
SetThemeWindowBackground( window, kThemeBrushUtilityWindowBackgroundActive, false );
|
||||||
|
|
||||||
|
// install window event handler
|
||||||
|
EventHandlerRef ref = null;
|
||||||
|
EventHandlerUPP eventHandler = NewEventHandlerUPP( CloseInspectorWindow );
|
||||||
|
EventTypeSpec events[] = { { kEventClassWindow, kEventWindowClose } };
|
||||||
|
InstallWindowEventHandler( window, eventHandler, GetEventTypeCount(events), (EventTypeSpec *) &events, this, &ref );
|
||||||
|
|
||||||
|
// create root control
|
||||||
|
Rect bounds;
|
||||||
|
if( g.systemVersion < kMacOSX )
|
||||||
|
{
|
||||||
|
ControlRef root;
|
||||||
|
CreateRootControl( window, &root );
|
||||||
|
}
|
||||||
|
|
||||||
|
// create image well
|
||||||
|
ControlRef imageWell;
|
||||||
|
ControlButtonContentInfo content;
|
||||||
|
content.contentType = kControlNoContent;
|
||||||
|
SetRect( &bounds, 0, 0, 44, 44 );
|
||||||
|
OffsetRect( &bounds, 8, 8 );
|
||||||
|
CreateImageWellControl( window, &bounds, &content, &imageWell );
|
||||||
|
|
||||||
|
// create static text controls
|
||||||
|
Rect windowRect;
|
||||||
|
ControlRef name, type, id;
|
||||||
|
ControlFontStyleRec fontStyle;
|
||||||
|
fontStyle.flags = kControlUseFontMask + kControlUseJustMask;
|
||||||
|
fontStyle.font = kControlFontSmallSystemFont;
|
||||||
|
fontStyle.just = teJustLeft;
|
||||||
|
GetWindowPortBounds( window, &windowRect );
|
||||||
|
SetRect( &bounds, windowRect.left +60, windowRect.top +8, windowRect.right - windowRect.left -8, windowRect.top +36 );
|
||||||
|
CreateStaticTextControl( window, &bounds, CFSTR(""), &fontStyle, &name );
|
||||||
|
fontStyle.font = kControlFontSmallBoldSystemFont;
|
||||||
|
SetRect( &bounds, windowRect.left +60, windowRect.top +38, windowRect.right - windowRect.left -70, windowRect.top +52 );
|
||||||
|
CreateStaticTextControl( window, &bounds, CFSTR(""), &fontStyle, &type );
|
||||||
|
SetRect( &bounds, windowRect.right - windowRect.left -70, windowRect.top +38, windowRect.right - windowRect.left -8, windowRect.top +52 );
|
||||||
|
CreateStaticTextControl( window, &bounds, CFSTR(""), &fontStyle, &id );
|
||||||
|
|
||||||
|
// create group control
|
||||||
|
ControlRef group;
|
||||||
|
GetWindowPortBounds( window, &bounds );
|
||||||
|
InsetRect( &bounds, 8, 8 );
|
||||||
|
bounds.top += kInspectorHeaderHeight;
|
||||||
|
CreateGroupBoxControl( window, &bounds, CFSTR("Attributes"), true, &group );
|
||||||
|
|
||||||
|
// create checkboxes
|
||||||
|
ControlRef changedBox, preloadBox, protectedBox,
|
||||||
|
lockedBox, purgeableBox, sysHeapBox;
|
||||||
|
InsetRect( &bounds, 4, 4 );
|
||||||
|
bounds.top = bounds.bottom - kControlCheckBoxHeight;
|
||||||
|
CreateCheckBoxControl( window, &bounds, CFSTR("System Heap"), kControlCheckBoxUncheckedValue, true, &sysHeapBox );
|
||||||
|
bounds.top -= kControlCheckBoxHeight;
|
||||||
|
bounds.bottom -= kControlCheckBoxHeight;
|
||||||
|
CreateCheckBoxControl( window, &bounds, CFSTR("Purgeable"), kControlCheckBoxUncheckedValue, true, &purgeableBox );
|
||||||
|
bounds.top -= kControlCheckBoxHeight;
|
||||||
|
bounds.bottom -= kControlCheckBoxHeight;
|
||||||
|
CreateCheckBoxControl( window, &bounds, CFSTR("Locked"), kControlCheckBoxUncheckedValue, true, &lockedBox );
|
||||||
|
bounds.top -= kControlCheckBoxHeight;
|
||||||
|
bounds.bottom -= kControlCheckBoxHeight;
|
||||||
|
CreateCheckBoxControl( window, &bounds, CFSTR("Protected"), kControlCheckBoxUncheckedValue, true, &protectedBox );
|
||||||
|
bounds.top -= kControlCheckBoxHeight;
|
||||||
|
bounds.bottom -= kControlCheckBoxHeight;
|
||||||
|
CreateCheckBoxControl( window, &bounds, CFSTR("Preload"), kControlCheckBoxUncheckedValue, true, &preloadBox );
|
||||||
|
bounds.top -= kControlCheckBoxHeight;
|
||||||
|
bounds.bottom -= kControlCheckBoxHeight;
|
||||||
|
CreateCheckBoxControl( window, &bounds, CFSTR("Changed"), kControlCheckBoxUncheckedValue, true, &changedBox );
|
||||||
|
|
||||||
|
// embed controls
|
||||||
|
EmbedControl( changedBox, group );
|
||||||
|
EmbedControl( preloadBox, group );
|
||||||
|
EmbedControl( protectedBox, group );
|
||||||
|
EmbedControl( lockedBox, group );
|
||||||
|
EmbedControl( purgeableBox, group );
|
||||||
|
EmbedControl( sysHeapBox, group );
|
||||||
}
|
}
|
||||||
|
else window = NULL;
|
||||||
// create image well
|
|
||||||
ControlRef imageWell;
|
|
||||||
ControlButtonContentInfo content;
|
|
||||||
content.contentType = kControlNoContent;
|
|
||||||
SetRect( &bounds, 0, 0, 44, 44 );
|
|
||||||
OffsetRect( &bounds, 8, 8 );
|
|
||||||
CreateImageWellControl( window, &bounds, &content, &imageWell );
|
|
||||||
|
|
||||||
// create static text controls
|
|
||||||
Rect windowRect;
|
|
||||||
ControlRef name, type, id;
|
|
||||||
ControlFontStyleRec fontStyle;
|
|
||||||
fontStyle.flags = kControlUseFontMask + kControlUseJustMask;
|
|
||||||
fontStyle.font = kControlFontSmallSystemFont;
|
|
||||||
fontStyle.just = teJustLeft;
|
|
||||||
GetWindowPortBounds( window, &windowRect );
|
|
||||||
SetRect( &bounds, windowRect.left +60, windowRect.top +8, windowRect.right - windowRect.left -8, windowRect.top +36 );
|
|
||||||
CreateStaticTextControl( window, &bounds, CFSTR(""), &fontStyle, &name );
|
|
||||||
fontStyle.font = kControlFontSmallBoldSystemFont;
|
|
||||||
SetRect( &bounds, windowRect.left +60, windowRect.top +38, windowRect.right - windowRect.left -70, windowRect.top +52 );
|
|
||||||
CreateStaticTextControl( window, &bounds, CFSTR(""), &fontStyle, &type );
|
|
||||||
SetRect( &bounds, windowRect.right - windowRect.left -70, windowRect.top +38, windowRect.right - windowRect.left -8, windowRect.top +52 );
|
|
||||||
CreateStaticTextControl( window, &bounds, CFSTR(""), &fontStyle, &id );
|
|
||||||
|
|
||||||
// create group control
|
|
||||||
ControlRef group;
|
|
||||||
GetWindowPortBounds( window, &bounds );
|
|
||||||
InsetRect( &bounds, 8, 8 );
|
|
||||||
bounds.top += kInspectorHeaderHeight;
|
|
||||||
CreateGroupBoxControl( window, &bounds, CFSTR("Attributes"), true, &group );
|
|
||||||
|
|
||||||
// create checkboxes
|
|
||||||
ControlRef changedBox, preloadBox, protectedBox,
|
|
||||||
lockedBox, purgeableBox, sysHeapBox;
|
|
||||||
InsetRect( &bounds, 4, 4 );
|
|
||||||
bounds.top = bounds.bottom - kControlCheckBoxHeight;
|
|
||||||
CreateCheckBoxControl( window, &bounds, CFSTR("System Heap"), kControlCheckBoxUncheckedValue, true, &sysHeapBox );
|
|
||||||
bounds.top -= kControlCheckBoxHeight;
|
|
||||||
bounds.bottom -= kControlCheckBoxHeight;
|
|
||||||
CreateCheckBoxControl( window, &bounds, CFSTR("Purgeable"), kControlCheckBoxUncheckedValue, true, &purgeableBox );
|
|
||||||
bounds.top -= kControlCheckBoxHeight;
|
|
||||||
bounds.bottom -= kControlCheckBoxHeight;
|
|
||||||
CreateCheckBoxControl( window, &bounds, CFSTR("Locked"), kControlCheckBoxUncheckedValue, true, &lockedBox );
|
|
||||||
bounds.top -= kControlCheckBoxHeight;
|
|
||||||
bounds.bottom -= kControlCheckBoxHeight;
|
|
||||||
CreateCheckBoxControl( window, &bounds, CFSTR("Protected"), kControlCheckBoxUncheckedValue, true, &protectedBox );
|
|
||||||
bounds.top -= kControlCheckBoxHeight;
|
|
||||||
bounds.bottom -= kControlCheckBoxHeight;
|
|
||||||
CreateCheckBoxControl( window, &bounds, CFSTR("Preload"), kControlCheckBoxUncheckedValue, true, &preloadBox );
|
|
||||||
bounds.top -= kControlCheckBoxHeight;
|
|
||||||
bounds.bottom -= kControlCheckBoxHeight;
|
|
||||||
CreateCheckBoxControl( window, &bounds, CFSTR("Changed"), kControlCheckBoxUncheckedValue, true, &changedBox );
|
|
||||||
|
|
||||||
// embed controls
|
|
||||||
EmbedControl( changedBox, group );
|
|
||||||
EmbedControl( preloadBox, group );
|
|
||||||
EmbedControl( protectedBox, group );
|
|
||||||
EmbedControl( lockedBox, group );
|
|
||||||
EmbedControl( purgeableBox, group );
|
|
||||||
EmbedControl( sysHeapBox, group );
|
|
||||||
#else
|
#else
|
||||||
if( g.useAppearance && g.systemVersion >= kMacOS8 )
|
if( g.useAppearance && g.systemVersion >= kMacOS8 )
|
||||||
window = GetNewCWindow( kFileWindow8, null, kFirstWindowOfClass );
|
window = GetNewCWindow( kFileWindow8, null, kFirstWindowOfClass );
|
||||||
|
@ -111,10 +115,14 @@ InspectorWindow::InspectorWindow( void )
|
||||||
window = GetNewCWindow( kFileWindow7, null, kFirstWindowOfClass );
|
window = GetNewCWindow( kFileWindow7, null, kFirstWindowOfClass );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// update and show window
|
if( window )
|
||||||
Update();
|
{
|
||||||
ShowWindow( window );
|
// update and show window
|
||||||
g.inspector = this;
|
Update();
|
||||||
|
ShowWindow( window );
|
||||||
|
g.inspector = this;
|
||||||
|
}
|
||||||
|
else g.inspector = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** DESTRUCTOR ***/
|
/*** DESTRUCTOR ***/
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
- (FSRef *)createFSRef
|
- (FSRef *)createFSRef
|
||||||
{
|
{
|
||||||
FSRef *fsRef = NULL;
|
FSRef *fsRef = NULL;
|
||||||
OSStatus error = FSPathMakeRef( [self fileSystemRepresentation], &fsRef, NULL );
|
OSStatus error = FSPathMakeRef( [self fileSystemRepresentation], fsRef, NULL );
|
||||||
if( error == noErr )
|
if( error == noErr )
|
||||||
return fsRef;
|
return fsRef;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -15,10 +15,10 @@
|
||||||
{
|
{
|
||||||
FSRef *fsRef = NULL;
|
FSRef *fsRef = NULL;
|
||||||
FSSpec *fsSpec = NULL;
|
FSSpec *fsSpec = NULL;
|
||||||
OSStatus error = FSPathMakeRef( [self fileSystemRepresentation], &fsRef, NULL );
|
OSStatus error = FSPathMakeRef( [self fileSystemRepresentation], fsRef, NULL );
|
||||||
if( error == noErr )
|
if( error == noErr )
|
||||||
{
|
{
|
||||||
error = FSGetCatalogInfo( &fsRef, kFSCatInfoNone, NULL, NULL, fsSpec, NULL );
|
error = FSGetCatalogInfo( fsRef, kFSCatInfoNone, NULL, NULL, fsSpec, NULL );
|
||||||
if( error == noErr )
|
if( error == noErr )
|
||||||
return fsSpec;
|
return fsSpec;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "ResKnifeResourceProtocol.h"
|
#import "ResKnifeResourceProtocol.h"
|
||||||
|
|
||||||
@interface Resource : NSObject <NSCoding, ResKnifeResourceProtocol>
|
@interface Resource : NSObject <NSCopying, NSCoding, ResKnifeResourceProtocol>
|
||||||
{
|
{
|
||||||
@private
|
@private
|
||||||
// flags
|
// flags
|
||||||
|
|
|
@ -130,6 +130,12 @@ NSString *RKResourcePboardType = @"RKResourcePboardType";
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (id)copyWithZone:(NSZone *)zone
|
||||||
|
{
|
||||||
|
Resource *copy = [[Resource alloc] initWithType:type andID:resID withName:name andAttributes:attributes data:[data copy]];
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
/* Accessors */
|
/* Accessors */
|
||||||
|
|
||||||
- (void)touch
|
- (void)touch
|
||||||
|
@ -284,7 +290,7 @@ NSString *RKResourcePboardType = @"RKResourcePboardType";
|
||||||
|
|
||||||
- (NSString *)description
|
- (NSString *)description
|
||||||
{
|
{
|
||||||
return [NSString stringWithFormat:@"\nName: %@\nType: %@ ID: %@\nModified: %@", name, type, resID, dirty? @"YES":@"NO"];
|
return [NSString stringWithFormat:@"\n%@\nName: %@\nType: %@ ID: %@\nSize: %d Modified: %@", [super description], name, type, resID, [data length], dirty? @"YES":@"NO"];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -310,10 +310,11 @@ static NSString *RKShowInfoItemIdentifier = @"com.nickshanks.resknife.toolbar.sh
|
||||||
NSBundle *templateEditor = [NSBundle bundleWithPath:[[[NSBundle mainBundle] builtInPlugInsPath] stringByAppendingPathComponent:@"Template Editor.plugin"]];
|
NSBundle *templateEditor = [NSBundle bundleWithPath:[[[NSBundle mainBundle] builtInPlugInsPath] stringByAppendingPathComponent:@"Template Editor.plugin"]];
|
||||||
|
|
||||||
// bug: this checks EVERY DOCUMENT for template resources (might not be desired)
|
// bug: this checks EVERY DOCUMENT for template resources (might not be desired)
|
||||||
|
// bug: it doesn't, however, check the application's resource map for a matching template!
|
||||||
Resource *tmpl = [Resource resourceOfType:@"TMPL" withName:[resource type] inDocument:nil];
|
Resource *tmpl = [Resource resourceOfType:@"TMPL" withName:[resource type] inDocument:nil];
|
||||||
|
|
||||||
// open the resources, passing in the template to use
|
// open the resources, passing in the template to use
|
||||||
if( tmpl && [[templateEditor principalClass] respondsToSelector:@selector(initWithResources:)] )
|
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?
|
// 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?
|
||||||
// update: doug says window controllers automatically release themselves when their window is closed.
|
// update: doug says window controllers automatically release themselves when their window is closed.
|
||||||
|
|
|
@ -124,7 +124,7 @@
|
||||||
// get the superclass to draw the text stuff
|
// get the superclass to draw the text stuff
|
||||||
[super drawWithFrame:cellFrame inView:controlView];
|
[super drawWithFrame:cellFrame inView:controlView];
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
- (NSSize)cellSize
|
- (NSSize)cellSize
|
||||||
{
|
{
|
||||||
NSSize cellSize = [super cellSize];
|
NSSize cellSize = [super cellSize];
|
||||||
|
@ -132,5 +132,5 @@
|
||||||
cellSize.width += (image? [image size].width:0) + 3;
|
cellSize.width += (image? [image size].width:0) + 3;
|
||||||
return cellSize;
|
return cellSize;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>IBDocumentLocation</key>
|
<key>IBDocumentLocation</key>
|
||||||
<string>681 234 356 240 0 0 1600 1002 </string>
|
<string>366 155 356 240 0 0 1024 746 </string>
|
||||||
<key>IBFramework Version</key>
|
<key>IBFramework Version</key>
|
||||||
<string>286.0</string>
|
<string>283.0</string>
|
||||||
<key>IBGroupedObjects</key>
|
<key>IBGroupedObjects</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>0</key>
|
<key>0</key>
|
||||||
|
@ -26,6 +26,6 @@
|
||||||
<integer>7</integer>
|
<integer>7</integer>
|
||||||
</array>
|
</array>
|
||||||
<key>IBSystem Version</key>
|
<key>IBSystem Version</key>
|
||||||
<string>6F21</string>
|
<string>6G30</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
Binary file not shown.
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
/* FORM DELEGATION METHOD */
|
/* FORM DELEGATION METHOD */
|
||||||
|
|
||||||
- (void)controlTextDidEndEditing:(NSNotification *)aNotification
|
- (void)controlTextDidEndEditing:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
[self updateStrings];
|
[self updateStrings];
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,16 @@
|
||||||
|
|
||||||
- (IBAction)showFindSheet:(id)sender
|
- (IBAction)showFindSheet:(id)sender
|
||||||
{
|
{
|
||||||
|
// load window so I can play with boxes
|
||||||
|
[self window];
|
||||||
|
|
||||||
|
// enable/disable boxes
|
||||||
|
[searchSelectionOnlyBox setEnabled:([(NSTextView *)[[sender window] firstResponder] rangeForUserTextChange].length != 0)];
|
||||||
|
|
||||||
|
// set inital vales
|
||||||
|
if( ![searchSelectionOnlyBox isEnabled] ) [searchSelectionOnlyBox setIntValue:0];
|
||||||
|
|
||||||
|
// show sheet
|
||||||
[NSApp beginSheet:[self window] modalForWindow:[sender window] modalDelegate:self didEndSelector:NULL contextInfo:nil];
|
[NSApp beginSheet:[self window] modalForWindow:[sender window] modalDelegate:self didEndSelector:NULL contextInfo:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
@interface HexTextView : NSTextView
|
@interface HexTextView : NSTextView
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
- (IBAction)clear:(id)sender;
|
||||||
- (IBAction)pasteAsASCII:(id)sender;
|
- (IBAction)pasteAsASCII:(id)sender;
|
||||||
- (IBAction)pasteAsHex:(id)sender;
|
- (IBAction)pasteAsHex:(id)sender;
|
||||||
- (IBAction)pasteAsUnicode:(id)sender;
|
- (IBAction)pasteAsUnicode:(id)sender;
|
||||||
|
|
|
@ -444,7 +444,7 @@ static NSRange draggedRange;
|
||||||
[newData replaceBytesInRange:range withBytes:[newBytes bytes] length:[newBytes length]];
|
[newData replaceBytesInRange:range withBytes:[newBytes bytes] length:[newBytes length]];
|
||||||
[[(HexWindowController *)[[self window] windowController] resource] setData:newData];
|
[[(HexWindowController *)[[self window] windowController] resource] setData:newData];
|
||||||
[self setSelectedRange:NSMakeRange(range.location + [newBytes length], 0)];
|
[self setSelectedRange:NSMakeRange(range.location + [newBytes length], 0)];
|
||||||
[[self window] setDocumentEdited:YES];
|
// [[self window] setDocumentEdited:YES]; // moved to window controller's -resourceDataDidChange: notification method
|
||||||
|
|
||||||
// record undo with new data object
|
// record undo with new data object
|
||||||
[[[[self window] undoManager] prepareWithInvocationTarget:self] editData:newData replaceBytesInRange:newRange withData:oldBytes];
|
[[[[self window] undoManager] prepareWithInvocationTarget:self] editData:newData replaceBytesInRange:newRange withData:oldBytes];
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
NSUndoManager *undoManager;
|
NSUndoManager *undoManager;
|
||||||
id <ResKnifeResourceProtocol> resource;
|
id <ResKnifeResourceProtocol> resource;
|
||||||
|
id <ResKnifeResourceProtocol> backup;
|
||||||
|
BOOL liveEdit;
|
||||||
int bytesPerRow;
|
int bytesPerRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,10 +32,16 @@
|
||||||
// show find sheet
|
// show find sheet
|
||||||
- (IBAction)showFind:(id)sender;
|
- (IBAction)showFind:(id)sender;
|
||||||
|
|
||||||
|
// save sheet methods
|
||||||
|
- (void)saveSheetDidClose:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo;
|
||||||
|
- (void)saveResource;
|
||||||
|
- (void)revertResource;
|
||||||
|
|
||||||
// normal methods
|
// normal methods
|
||||||
- (void)viewDidScroll:(NSNotification *)notification;
|
- (void)viewDidScroll:(NSNotification *)notification;
|
||||||
- (void)resourceNameDidChange:(NSNotification *)notification;
|
- (void)resourceNameDidChange:(NSNotification *)notification;
|
||||||
- (void)resourceDataDidChange:(NSNotification *)notification;
|
- (void)resourceDataDidChange:(NSNotification *)notification;
|
||||||
|
- (void)resourceWasSaved:(NSNotification *)notification;
|
||||||
- (void)refreshData:(NSData *)data;
|
- (void)refreshData:(NSData *)data;
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
|
|
|
@ -11,7 +11,17 @@
|
||||||
|
|
||||||
// one instance of your principal class will be created for every resource the user wants to edit (similar to Windows apps)
|
// one instance of your principal class will be created for every resource the user wants to edit (similar to Windows apps)
|
||||||
undoManager = [[NSUndoManager alloc] init];
|
undoManager = [[NSUndoManager alloc] init];
|
||||||
resource = [newResource retain];
|
liveEdit = NO;
|
||||||
|
if( liveEdit )
|
||||||
|
{
|
||||||
|
resource = [newResource retain];
|
||||||
|
backup = [newResource copy];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resource = [newResource copy];
|
||||||
|
backup = [newResource retain];
|
||||||
|
}
|
||||||
bytesPerRow = 16;
|
bytesPerRow = 16;
|
||||||
|
|
||||||
// load the window from the nib file and set it's title
|
// load the window from the nib file and set it's title
|
||||||
|
@ -30,7 +40,7 @@
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
[(id)resource autorelease];
|
[(id)resource release];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +69,8 @@
|
||||||
// we don't want this notification until we have a window! (Only register for notifications on the resource we're editing)
|
// we don't want this notification until we have a window! (Only register for notifications on the resource we're editing)
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceNameDidChange:) name:ResourceNameDidChangeNotification object:resource];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceNameDidChange:) name:ResourceNameDidChangeNotification object:resource];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceDataDidChange:) name:ResourceDataDidChangeNotification object:resource];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceDataDidChange:) name:ResourceDataDidChangeNotification object:resource];
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceWasSaved:) name:ResourceWasSavedNotification object:resource];
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resourceWasSaved:) name:ResourceWasSavedNotification object:backup];
|
||||||
|
|
||||||
// put other notifications here too, just for togetherness
|
// put other notifications here too, just for togetherness
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidScroll:) name:NSViewBoundsDidChangeNotification object:[[offset enclosingScrollView] contentView]];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidScroll:) name:NSViewBoundsDidChangeNotification object:[[offset enclosingScrollView] contentView]];
|
||||||
|
@ -105,11 +117,55 @@
|
||||||
[pasteItem setKeyEquivalentModifierMask:NSCommandKeyMask];
|
[pasteItem setKeyEquivalentModifierMask:NSCommandKeyMask];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
- (BOOL)windowShouldClose:(id)sender
|
||||||
- (BOOL)windowShouldClose:(NSWindow *)sender
|
|
||||||
{
|
{
|
||||||
return [sender isDocumentEdited];
|
if( [[self window] isDocumentEdited] )
|
||||||
}*/
|
{
|
||||||
|
NSBeginAlertSheet( @"Do you want to save the changes you made to this resource?", @"Save", @"DonÕt Save", @"Cancel", sender, self, @selector(saveSheetDidClose:returnCode:contextInfo:), nil, nil, @"Your changes will be lost if you don't save them." );
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
else return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)saveSheetDidClose:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
|
||||||
|
{
|
||||||
|
switch( returnCode )
|
||||||
|
{
|
||||||
|
case NSAlertDefaultReturn: // save
|
||||||
|
[self saveResource];
|
||||||
|
[[self window] close];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NSAlertAlternateReturn: // don't save
|
||||||
|
[self revertResource];
|
||||||
|
[[self window] close];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NSAlertOtherReturn: // cancel
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)saveResource
|
||||||
|
{
|
||||||
|
if( liveEdit )
|
||||||
|
{
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWillBeSavedNotification object:resource];
|
||||||
|
[backup setData:[resource data]];
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWasSavedNotification object:resource];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWillBeSavedNotification object:backup];
|
||||||
|
[backup setData:[resource data]];
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWasSavedNotification object:backup];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)revertResource
|
||||||
|
{
|
||||||
|
[resource setData:[backup data]];
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)showFind:(id)sender
|
- (IBAction)showFind:(id)sender
|
||||||
{
|
{
|
||||||
|
@ -127,7 +183,7 @@
|
||||||
NSClipView *asciiClip = [[ascii enclosingScrollView] contentView];
|
NSClipView *asciiClip = [[ascii enclosingScrollView] contentView];
|
||||||
|
|
||||||
// due to a bug in -[NSView setPostsBoundsChangedNotifications:] (it basically doesn't work), I am having to work around it by removing myself from the notification center and restoring things later on!
|
// due to a bug in -[NSView setPostsBoundsChangedNotifications:] (it basically doesn't work), I am having to work around it by removing myself from the notification center and restoring things later on!
|
||||||
// update, Apple say this isn't their bug.
|
// update, Apple say this isn't their bug. Yeah, right!
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSViewBoundsDidChangeNotification object:nil];
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSViewBoundsDidChangeNotification object:nil];
|
||||||
|
|
||||||
// when a view scrolls, update the other two
|
// when a view scrolls, update the other two
|
||||||
|
@ -169,7 +225,36 @@
|
||||||
{
|
{
|
||||||
// ensure it's our resource which got changed (should always be true, we don't register for other resource notifications)
|
// ensure it's our resource which got changed (should always be true, we don't register for other resource notifications)
|
||||||
if( [notification object] == (id)resource )
|
if( [notification object] == (id)resource )
|
||||||
|
{
|
||||||
[self refreshData:[resource data]];
|
[self refreshData:[resource data]];
|
||||||
|
[self setDocumentEdited:YES];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)resourceWasSaved:(NSNotification *)notification
|
||||||
|
{
|
||||||
|
NSLog( @"%@; %@; %@", [notification object], resource, backup );
|
||||||
|
if( [notification object] == (id)resource )
|
||||||
|
{
|
||||||
|
// if resource gets saved, liveEdit is true and this resource is saving
|
||||||
|
[backup setData:[resource data]];
|
||||||
|
[self setDocumentEdited:NO];
|
||||||
|
}
|
||||||
|
else if( [notification object] == (id)backup && !liveEdit )
|
||||||
|
{
|
||||||
|
// backup will get saved by this resource if liveEdit is false, rather than the 'resource' variable
|
||||||
|
// but really the data to preserve is in the resource variable
|
||||||
|
[backup setData:[resource data]];
|
||||||
|
// [self refreshData:[resource data]];
|
||||||
|
[self setDocumentEdited:NO];
|
||||||
|
}
|
||||||
|
else if( [notification object] == (id)backup )
|
||||||
|
{
|
||||||
|
// backup will get saved by another editor too if liveEdit is false
|
||||||
|
[resource setData:[backup data]];
|
||||||
|
// [self refreshData:[resource data]];
|
||||||
|
[self setDocumentEdited:NO];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)refreshData:(NSData *)data;
|
- (void)refreshData:(NSData *)data;
|
||||||
|
|
|
@ -12,10 +12,12 @@ NSString *ResourceTypeWillChangeNotification = @"ResourceTypeWillChangeNotifica
|
||||||
NSString *ResourceIDWillChangeNotification = @"ResourceIDWillChangeNotification";
|
NSString *ResourceIDWillChangeNotification = @"ResourceIDWillChangeNotification";
|
||||||
NSString *ResourceAttributesWillChangeNotification = @"ResourceAttributesWillChangeNotification";
|
NSString *ResourceAttributesWillChangeNotification = @"ResourceAttributesWillChangeNotification";
|
||||||
NSString *ResourceDataWillChangeNotification = @"ResourceDataWillChangeNotification";
|
NSString *ResourceDataWillChangeNotification = @"ResourceDataWillChangeNotification";
|
||||||
|
NSString *ResourceWillBeSavedNotification = @"ResourceWillBeSavedNotification";
|
||||||
|
|
||||||
NSString *ResourceNameDidChangeNotification = @"ResourceNameDidChangeNotification";
|
NSString *ResourceNameDidChangeNotification = @"ResourceNameDidChangeNotification";
|
||||||
NSString *ResourceTypeDidChangeNotification = @"ResourceTypeDidChangeNotification";
|
NSString *ResourceTypeDidChangeNotification = @"ResourceTypeDidChangeNotification";
|
||||||
NSString *ResourceIDDidChangeNotification = @"ResourceIDDidChangeNotification";
|
NSString *ResourceIDDidChangeNotification = @"ResourceIDDidChangeNotification";
|
||||||
NSString *ResourceAttributesDidChangeNotification = @"ResourceAttributesDidChangeNotification";
|
NSString *ResourceAttributesDidChangeNotification = @"ResourceAttributesDidChangeNotification";
|
||||||
NSString *ResourceDataDidChangeNotification = @"ResourceDataDidChangeNotification";
|
NSString *ResourceDataDidChangeNotification = @"ResourceDataDidChangeNotification";
|
||||||
NSString *ResourceDidChangeNotification = @"ResourceDidChangeNotification";
|
NSString *ResourceDidChangeNotification = @"ResourceDidChangeNotification";
|
||||||
|
NSString *ResourceWasSavedNotification = @"ResourceWasSavedNotification";
|
||||||
|
|
|
@ -39,10 +39,12 @@ extern NSString *ResourceTypeWillChangeNotification;
|
||||||
extern NSString *ResourceIDWillChangeNotification;
|
extern NSString *ResourceIDWillChangeNotification;
|
||||||
extern NSString *ResourceAttributesWillChangeNotification;
|
extern NSString *ResourceAttributesWillChangeNotification;
|
||||||
extern NSString *ResourceDataWillChangeNotification;
|
extern NSString *ResourceDataWillChangeNotification;
|
||||||
|
extern NSString *ResourceWillBeSavedNotification;
|
||||||
|
|
||||||
extern NSString *ResourceNameDidChangeNotification;
|
extern NSString *ResourceNameDidChangeNotification;
|
||||||
extern NSString *ResourceTypeDidChangeNotification;
|
extern NSString *ResourceTypeDidChangeNotification;
|
||||||
extern NSString *ResourceIDDidChangeNotification;
|
extern NSString *ResourceIDDidChangeNotification;
|
||||||
extern NSString *ResourceAttributesDidChangeNotification;
|
extern NSString *ResourceAttributesDidChangeNotification;
|
||||||
extern NSString *ResourceDataDidChangeNotification;
|
extern NSString *ResourceDataDidChangeNotification;
|
||||||
extern NSString *ResourceDidChangeNotification;
|
extern NSString *ResourceDidChangeNotification;
|
||||||
|
extern NSString *ResourceWasSavedNotification;
|
|
@ -4,8 +4,7 @@
|
||||||
{
|
{
|
||||||
NSString *type;
|
NSString *type;
|
||||||
NSString *label;
|
NSString *label;
|
||||||
NSMutableArray *subelements; // elements of a list type have a sub-array of elements
|
union // for resource arrays only, ignored for TMPL arrays
|
||||||
union // for resource data only, ignored for templates
|
|
||||||
{
|
{
|
||||||
NSString *string;
|
NSString *string;
|
||||||
NSNumber *number;
|
NSNumber *number;
|
||||||
|
@ -19,7 +18,6 @@
|
||||||
|
|
||||||
- (NSString *)label;
|
- (NSString *)label;
|
||||||
- (NSString *)type;
|
- (NSString *)type;
|
||||||
- (NSMutableArray *)subelements;
|
|
||||||
- (unsigned long)typeAsLong;
|
- (unsigned long)typeAsLong;
|
||||||
- (NSString *)string;
|
- (NSString *)string;
|
||||||
- (void)setString:(NSString *)string;
|
- (void)setString:(NSString *)string;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
- (id)copy
|
- (id)copy
|
||||||
{
|
{
|
||||||
Element *element = [[Element alloc] initWithType:type andLabel:label];
|
Element *element = [[Element alloc] initWithType:type andLabel:label];
|
||||||
// copy other stuff here
|
// bug: copy other stuff here
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
{
|
{
|
||||||
return *(unsigned long *)[type cString];
|
return *(unsigned long *)[type cString];
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
- (NSMutableArray *)subelements;
|
- (NSMutableArray *)subelements;
|
||||||
{
|
{
|
||||||
long myType = [self typeAsLong];
|
long myType = [self typeAsLong];
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
else subelements = nil;
|
else subelements = nil;
|
||||||
return subelements;
|
return subelements;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/* DATA ACCESSORS */
|
/* DATA ACCESSORS */
|
||||||
|
|
||||||
- (NSString *)string
|
- (NSString *)string
|
||||||
|
@ -105,4 +105,9 @@
|
||||||
elementData.boolean = boolean;
|
elementData.boolean = boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString *)description
|
||||||
|
{
|
||||||
|
return [NSString stringWithFormat:@"{ %@, %@ }", type, label];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
{
|
{
|
||||||
CLASS = TemplateWindowController;
|
CLASS = TemplateWindowController;
|
||||||
LANGUAGE = ObjC;
|
LANGUAGE = ObjC;
|
||||||
OUTLETS = {fieldsMatrix = NSMatrix; };
|
OUTLETS = {containerView = NSView; };
|
||||||
SUPERCLASS = NSWindowController;
|
SUPERCLASS = NSWindowController;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,10 +3,26 @@
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>IBDocumentLocation</key>
|
<key>IBDocumentLocation</key>
|
||||||
<string>672 193 356 240 0 0 1600 1002 </string>
|
<string>276 97 356 240 0 0 1024 746 </string>
|
||||||
|
<key>IBEditorPositions</key>
|
||||||
|
<dict>
|
||||||
|
<key>22</key>
|
||||||
|
<string>114 377 480 236 0 0 1024 746 </string>
|
||||||
|
<key>45</key>
|
||||||
|
<string>163 366 480 162 0 0 1024 746 </string>
|
||||||
|
</dict>
|
||||||
<key>IBFramework Version</key>
|
<key>IBFramework Version</key>
|
||||||
<string>286.0</string>
|
<string>283.0</string>
|
||||||
|
<key>IBLockedObjects</key>
|
||||||
|
<array>
|
||||||
|
<integer>20</integer>
|
||||||
|
<integer>19</integer>
|
||||||
|
</array>
|
||||||
|
<key>IBOpenObjects</key>
|
||||||
|
<array>
|
||||||
|
<integer>5</integer>
|
||||||
|
</array>
|
||||||
<key>IBSystem Version</key>
|
<key>IBSystem Version</key>
|
||||||
<string>6D52</string>
|
<string>6G30</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
Binary file not shown.
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
@interface TemplateWindowController : NSWindowController <ResKnifePluginProtocol>
|
@interface TemplateWindowController : NSWindowController <ResKnifePluginProtocol>
|
||||||
{
|
{
|
||||||
IBOutlet NSMatrix *fieldsMatrix;
|
IBOutlet NSView *containerView;
|
||||||
|
|
||||||
NSMutableArray *tmpl;
|
NSMutableArray *tmpl;
|
||||||
NSMutableArray *res;
|
NSMutableArray *res;
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
tmpl = [[NSMutableArray alloc] init];
|
tmpl = [[NSMutableArray alloc] init];
|
||||||
res = [[NSMutableArray alloc] init];
|
res = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
[self readTemplate:va_arg( resourceList, id )]; // reads (but doesn't retain) the TMPL resource
|
[self readTemplate:va_arg( resourceList, id )]; // reads (but doesn't retain) the template for this resource (TMPL resource with name equal to the passed resource's type)
|
||||||
while( currentResource = va_arg( resourceList, id ) )
|
while( currentResource = va_arg( resourceList, id ) )
|
||||||
NSLog( @"too many params passed to -initWithResources: %@", [currentResource description] );
|
NSLog( @"too many params passed to -initWithResources: %@", [currentResource description] );
|
||||||
va_end( resourceList );
|
va_end( resourceList );
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
[[self window] setTitle:[resource name]];
|
[[self window] setTitle:[resource name]];
|
||||||
|
|
||||||
// parse data using pre-scanned template and create the fields as needed
|
// parse data using pre-scanned template and create the fields as needed
|
||||||
[self parseData];
|
[self readData];
|
||||||
[self createUI];
|
[self createUI];
|
||||||
|
|
||||||
// insert the resources' data into the text fields
|
// insert the resources' data into the text fields
|
||||||
|
@ -88,29 +88,94 @@
|
||||||
currentByte += 4;
|
currentByte += 4;
|
||||||
|
|
||||||
// add element to array
|
// add element to array
|
||||||
// NSLog( @"Adding object %@ of type %@ to array", label, type );
|
|
||||||
[tmpl addObject:[Element elementOfType:type withLabel:label]];
|
[tmpl addObject:[Element elementOfType:type withLabel:label]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)readData
|
||||||
|
{
|
||||||
|
// tmpl == array of Elements describing the template for this resource
|
||||||
|
// res == array of either Elements or Arrays containing the resource data
|
||||||
|
|
||||||
|
// this function creates the res instance variable, filling it with data from the resource if there's data available.
|
||||||
|
|
||||||
|
unsigned long position = 0; // position (byte offset) in resource I'm currently reading from
|
||||||
|
char *data = (char *) [[resource data] bytes]; // address of initial byte of resource in memory
|
||||||
|
|
||||||
|
unsigned long templateCounter = 0; // index into template array of the current template element
|
||||||
|
Element *currentTemplateElement; // current template element
|
||||||
|
NSMutableArray *targetStack = [NSMutableArray arrayWithObject:res]; // stack of arrays (target for addition of new elements)
|
||||||
|
NSMutableArray *loopStack = [NSMutableArray array]; // stack for 'LSTB' and 'LSTC' elements
|
||||||
|
NSMutableArray *loopCountStack = [NSMutableArray array]; // stack for counting how many times to loop
|
||||||
|
|
||||||
|
// when templateCounter >= [tmpl count], loop is only exited if targetStack has more than one target (this handles empty templates)
|
||||||
|
while( templateCounter < [tmpl count] || [targetStack count] > 1 )
|
||||||
|
{
|
||||||
|
currentTemplateElement = [tmpl objectAtIndex:templateCounter];
|
||||||
|
NSLog( @"template = %@", currentTemplateElement );
|
||||||
|
/* unsigned long type = [currentTemplateElement typeAsLong];
|
||||||
|
switch( type )
|
||||||
|
{
|
||||||
|
case 'BCNT':
|
||||||
|
case 'BZCT':
|
||||||
|
[resourceElement setNumberWithLong:*(unsigned char *)(data + position)];
|
||||||
|
lim = *(unsigned char *)(data + position) + (type == 'BZCT'? 1:0);
|
||||||
|
position += 1;
|
||||||
|
break;
|
||||||
|
case 'OCNT':
|
||||||
|
case 'ZCNT':
|
||||||
|
[resourceElement setNumberWithLong:*(unsigned short *)(data + position)];
|
||||||
|
lim = *(unsigned short *)(data + position) + (type == 'ZCNT'? 1:0);
|
||||||
|
position += 2;
|
||||||
|
break;
|
||||||
|
case 'LCNT':
|
||||||
|
case 'LZCT':
|
||||||
|
[resourceElement setNumberWithLong:*(unsigned long *)(data + position)];
|
||||||
|
lim = *(unsigned long *)(data + position) + (type == 'LZCT'? 1:0);
|
||||||
|
position += 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'LSTB':
|
||||||
|
case 'LSTC':
|
||||||
|
[(NSMutableArray *)[targetStack lastObject] addObject:[NSMutableArray array]];
|
||||||
|
[loopStack addObject:currentTemplateElement]; // append the template loop start object to the array
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
// [(NSMutableArray *)[targetStack lastObject] addItem:[self createElementForTemplate:currentTemplateElement
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
templateCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)parseData
|
- (void)parseData
|
||||||
{
|
{
|
||||||
unsigned long position = 0;
|
unsigned long position = 0;
|
||||||
char *data = (char *) [resource data];
|
char *data = (char *) [[resource data] bytes];
|
||||||
|
|
||||||
// used for nesting of elements, 'target' is current object to append to, targetStack is a FILO stack of mutable array pointers
|
// used for nesting of elements, 'target' is current object to append to, targetStack is a FILO stack of mutable array pointers, loopStack is a stack of element indicies to the start of loops, so I can go back to the head of a loop when iterating it
|
||||||
NSMutableArray *target = res;
|
NSMutableArray *target = res;
|
||||||
NSMutableArray *targetArray = [NSMutableArray arrayWithObject:res];
|
NSMutableArray *targetStack = [NSMutableArray arrayWithObject:res];
|
||||||
|
NSMutableArray *loopStack = [NSMutableArray array];
|
||||||
|
|
||||||
|
// n = current item in TMPL to read, c = loop counter, when exiting loop, go back 'c' items in the template, lim is how many times to loop, obtained from a loop count
|
||||||
|
unsigned long n = 0, c = 0, lim = 0;
|
||||||
|
|
||||||
// creates an array of elements containing the data in whatever format the template dictates
|
// creates an array of elements containing the data in whatever format the template dictates
|
||||||
// array can then simply be manipulated one element at a time, or flattened to save
|
// array can then simply be manipulated one element at a time, or flattened to save
|
||||||
Element *currentTemplateElement, *resourceElement;
|
Element *currentTemplateElement, *resourceElement;
|
||||||
NSEnumerator *enumerator = [tmpl objectEnumerator];
|
// NSEnumerator *enumerator = [tmpl objectEnumerator];
|
||||||
while( currentTemplateElement = [enumerator nextObject] )
|
// while( currentTemplateElement = [enumerator nextObject] )
|
||||||
|
while( position < [[resource size] unsignedLongValue] )
|
||||||
{
|
{
|
||||||
|
currentTemplateElement = [tmpl objectAtIndex:n];
|
||||||
|
n++, c++;
|
||||||
unsigned long type = [currentTemplateElement typeAsLong];
|
unsigned long type = [currentTemplateElement typeAsLong];
|
||||||
resourceElement = [[currentTemplateElement copy] autorelease];
|
resourceElement = [[currentTemplateElement copy] autorelease];
|
||||||
|
NSLog( @"tmpl element = %@; position = %d", currentTemplateElement, position );
|
||||||
switch( type )
|
switch( type )
|
||||||
{
|
{
|
||||||
/* Alignment */
|
/* Alignment */
|
||||||
|
@ -163,38 +228,60 @@
|
||||||
// bug: doesn't check HEXD is the last element
|
// bug: doesn't check HEXD is the last element
|
||||||
[resourceElement setData:[NSData dataWithBytes:(void *)(data + position) length:([[resource size] intValue] - position)]];
|
[resourceElement setData:[NSData dataWithBytes:(void *)(data + position) length:([[resource size] intValue] - position)]];
|
||||||
position = [[resource size] intValue];
|
position = [[resource size] intValue];
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Strings */
|
||||||
|
case 'CHAR':
|
||||||
|
[resourceElement setString:[[NSString alloc] initWithData:[NSData dataWithBytes:(void *)(data + position) length:1] encoding:NSMacOSRomanStringEncoding]];
|
||||||
|
position += 1;
|
||||||
|
break;
|
||||||
|
case 'TNAM':
|
||||||
|
[resourceElement setString:[[NSString alloc] initWithData:[NSData dataWithBytes:(void *)(data + position) length:4] encoding:NSMacOSRomanStringEncoding]];
|
||||||
|
position += 4;
|
||||||
|
break;
|
||||||
|
case 'PSTR':
|
||||||
|
[resourceElement setString:[[NSString alloc] initWithData:[NSData dataWithBytes:(void *)(data + position + 1) length:*(unsigned char *)(data + position)] encoding:NSMacOSRomanStringEncoding]];
|
||||||
|
position += *(unsigned char *)(data + position) + 1;
|
||||||
|
break;
|
||||||
|
|
||||||
/* List Counts */
|
/* List Counts */
|
||||||
case 'BCNT':
|
case 'BCNT':
|
||||||
case 'BZCT':
|
case 'BZCT':
|
||||||
// bug: how big are these various count fields?
|
// bug: how big are these various count fields?
|
||||||
[resourceElement setNumberWithLong:*(char *)(data + position)];
|
[resourceElement setNumberWithLong:*(unsigned char *)(data + position)];
|
||||||
|
lim = *(unsigned char *)(data + position) + (type == 'BZCT'? 1:0);
|
||||||
position += 1;
|
position += 1;
|
||||||
break;
|
break;
|
||||||
case 'OCNT':
|
case 'OCNT':
|
||||||
case 'ZCNT':
|
case 'ZCNT':
|
||||||
// bug: how big are these various count fields?
|
// bug: how big are these various count fields?
|
||||||
[resourceElement setNumberWithLong:*(short *)(data + position)];
|
[resourceElement setNumberWithLong:*(unsigned short *)(data + position)];
|
||||||
|
lim = *(unsigned short *)(data + position) + (type == 'ZCNT'? 1:0);
|
||||||
position += 2;
|
position += 2;
|
||||||
break;
|
break;
|
||||||
case 'LCNT':
|
case 'LCNT':
|
||||||
case 'LZCT':
|
case 'LZCT':
|
||||||
// bug: how big are these various count fields?
|
// bug: how big are these various count fields?
|
||||||
[resourceElement setNumberWithLong:*(long *)(data + position)];
|
[resourceElement setNumberWithLong:*(unsigned long *)(data + position)];
|
||||||
|
lim = *(unsigned long *)(data + position) + (type == 'LZCT'? 1:0);
|
||||||
position += 4;
|
position += 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* List beginning and end */
|
/* List beginning and end */
|
||||||
case 'LSTB':
|
case 'LSTB':
|
||||||
case 'LSTC':
|
case 'LSTC':
|
||||||
target = [resourceElement subelements];
|
[target addObject:resourceElement]; // add list item to current target array
|
||||||
[targetArray addObject:target];
|
// target = [resourceElement subelements]; // change current array to list's sub-elements
|
||||||
|
[targetStack addObject:target]; // append sub-element array to target stack so it can be popped off afterwards
|
||||||
|
resourceElement = nil; // don't add item to it's own sub-elements later!
|
||||||
break;
|
break;
|
||||||
case 'LSTE':
|
case 'LSTE':
|
||||||
// bug: if there is a LSTE without a preceeding LSTB or LSTC this will crash
|
// bug: if there is a LSTE without a preceeding LSTB or LSTC this will crash
|
||||||
[targetArray removeLastObject];
|
[targetStack removeLastObject]; // pop off current target from stack
|
||||||
target = [targetArray lastObject];
|
target = [targetStack lastObject]; // set current target to whatever was second from top on the stack
|
||||||
resourceElement = nil; // relies on element being previously autoreleased to avoid a leak
|
resourceElement = nil; // list end items are not needed in a resource array
|
||||||
|
if( n < lim ) n -= c;
|
||||||
|
c = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Cxxx, Hxxx or P0xx */
|
/* Cxxx, Hxxx or P0xx */
|
||||||
|
@ -205,21 +292,26 @@
|
||||||
*/ char *lengthStr = (type & 0x00FFFFFF) & (3 << 24);
|
*/ char *lengthStr = (type & 0x00FFFFFF) & (3 << 24);
|
||||||
unsigned long length;
|
unsigned long length;
|
||||||
StringToNum(lengthStr, &length);
|
StringToNum(lengthStr, &length);
|
||||||
NSLog( @"error, Cxxx, Hxxx and P0xx unsupported, skipping %d bytes", length );
|
NSLog( @"error, '%@' is unsupported, skipping %d bytes", [resourceElement type], length );
|
||||||
resourceElement = nil; // relies on element being previously autoreleased to avoid a leak
|
resourceElement = nil; // relies on element being previously autoreleased to avoid a leak
|
||||||
position += length;
|
position += length;
|
||||||
} break;
|
} break;
|
||||||
} // end switch
|
} // end template element type switch
|
||||||
if( resourceElement ) [target addObject:resourceElement];
|
|
||||||
} // end while loop
|
if( resourceElement )
|
||||||
|
{
|
||||||
|
NSLog( @"adding %@", resourceElement );
|
||||||
|
[target addObject:resourceElement];
|
||||||
|
}
|
||||||
|
} // end while position < size
|
||||||
|
|
||||||
|
NSLog( [target description] );
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)createUI
|
- (void)createUI
|
||||||
{
|
{
|
||||||
// iterate through res creating fields
|
// iterate through res (the resource element array) creating fields
|
||||||
[self enumerateElements:res];
|
[self enumerateElements:res];
|
||||||
NSLog( [fieldsMatrix description] );
|
|
||||||
[fieldsMatrix setNeedsDisplay];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)enumerateElements:(NSMutableArray *)elements
|
- (void)enumerateElements:(NSMutableArray *)elements
|
||||||
|
@ -227,17 +319,21 @@
|
||||||
// iterate through the array of resource elements, creating fields
|
// iterate through the array of resource elements, creating fields
|
||||||
Element *currentResourceElement;
|
Element *currentResourceElement;
|
||||||
NSEnumerator *enumerator = [elements objectEnumerator];
|
NSEnumerator *enumerator = [elements objectEnumerator];
|
||||||
NSLog( @"%d", [elements count] );
|
NSLog( @"elements in resource array = %d", [elements count] );
|
||||||
while( currentResourceElement = [enumerator nextObject] )
|
while( currentResourceElement = [enumerator nextObject] )
|
||||||
{
|
{
|
||||||
// if element is a container, iterate inside it first
|
// if element is a container (subelements != nil), iterate inside it first
|
||||||
if( [currentResourceElement subelements] )
|
/* if( [currentResourceElement subelements] )
|
||||||
[self enumerateElements:[currentResourceElement subelements]];
|
|
||||||
else // element is normal
|
|
||||||
{
|
{
|
||||||
NSFormCell *newField = [[NSFormCell alloc] initTextCell:[currentResourceElement label]];
|
// bug: need to indent view right
|
||||||
[fieldsMatrix addRowWithCells:[NSArray arrayWithObject:[newField autorelease]]];
|
[self enumerateElements:[currentResourceElement subelements]];
|
||||||
NSLog( @"%@ added to matrix", [newField description] );
|
// bug: need to remove indentation
|
||||||
|
}
|
||||||
|
else // element is normal
|
||||||
|
*/ {
|
||||||
|
/* NSFormCell *newField = [[NSFormCell alloc] initTextCell:[currentResourceElement label]];
|
||||||
|
[fieldsMatrix addRowWithCells:[NSArray arrayWithObject:[newField autorelease]]]; */
|
||||||
|
NSLog( [currentResourceElement description] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,8 @@
|
||||||
|
|
||||||
- (void)parseForString:(NSString *)string sorted:(BOOL)sort
|
- (void)parseForString:(NSString *)string sorted:(BOOL)sort
|
||||||
{
|
{
|
||||||
[self parseForString:string withinRange:NSMakeRange(-32767, 65536) sorted:sort];
|
// bug: for some reason +[NSNumber isBoundedByRange:] doesn't like a range with a minimum below -30,000 (such as INT16_MIN), so I'm using INT8_MIN and screw everyone using resource IDs below that :P
|
||||||
|
[self parseForString:string withinRange:NSMakeRange(INT8_MIN, INT16_MAX) sorted:sort];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)parseForString:(NSString *)string withinRange:(NSRange)resIDRange sorted:(BOOL)sort
|
- (void)parseForString:(NSString *)string withinRange:(NSRange)resIDRange sorted:(BOOL)sort
|
||||||
|
@ -63,6 +64,7 @@
|
||||||
NSString *trimmedString = [DataSource resNameFromStringValue:string];
|
NSString *trimmedString = [DataSource resNameFromStringValue:string];
|
||||||
NSEnumerator *enumerator = [[data allKeys] objectEnumerator];
|
NSEnumerator *enumerator = [[data allKeys] objectEnumerator];
|
||||||
[parsed removeAllObjects];
|
[parsed removeAllObjects];
|
||||||
|
if( trimmedString == nil ) trimmedString = @"";
|
||||||
while( resID = [enumerator nextObject] )
|
while( resID = [enumerator nextObject] )
|
||||||
{
|
{
|
||||||
NSString *value = [data objectForKey:resID];
|
NSString *value = [data objectForKey:resID];
|
||||||
|
@ -70,6 +72,11 @@
|
||||||
if( ((range.location != NSNotFound && range.length != 0) || [trimmedString isEqualToString:@""]) && [resID isBoundedByRange:resIDRange] )
|
if( ((range.location != NSNotFound && range.length != 0) || [trimmedString isEqualToString:@""]) && [resID isBoundedByRange:resIDRange] )
|
||||||
[parsed addObject:[self stringValueForResID:resID]];
|
[parsed addObject:[self stringValueForResID:resID]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// crap hack to allow user to change the insertion point if what they typed doesn't yet match an existing resource
|
||||||
|
if( [parsed count] == 0 ) [parsed addObject:string];
|
||||||
|
|
||||||
|
// sort case insensitive if sorting is requested
|
||||||
if( sort ) [parsed sortUsingSelector:@selector(caseInsensitiveCompare:)];
|
if( sort ) [parsed sortUsingSelector:@selector(caseInsensitiveCompare:)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +89,7 @@
|
||||||
{
|
{
|
||||||
if( resID && [data objectForKey:resID] )
|
if( resID && [data objectForKey:resID] )
|
||||||
return [NSString stringWithFormat:@"%@ {%@}", [data objectForKey:resID], resID];
|
return [NSString stringWithFormat:@"%@ {%@}", [data objectForKey:resID], resID];
|
||||||
else if( [resID isEqualToNumber:[NSNumber numberWithInt:-1]] )
|
else if( [resID shortValue] == -1 )
|
||||||
return @"";
|
return @"";
|
||||||
else if( resID )
|
else if( resID )
|
||||||
return [NSString stringWithFormat:@"{%@}", resID];
|
return [NSString stringWithFormat:@"{%@}", resID];
|
||||||
|
@ -101,21 +108,17 @@
|
||||||
NS_DURING
|
NS_DURING
|
||||||
NS_VALUERETURN( [[[NSNumber alloc] initWithInt:[[string substringWithRange:range] intValue]] autorelease], NSNumber* );
|
NS_VALUERETURN( [[[NSNumber alloc] initWithInt:[[string substringWithRange:range] intValue]] autorelease], NSNumber* );
|
||||||
NS_HANDLER
|
NS_HANDLER
|
||||||
NS_VALUERETURN( nil, NSNumber* );
|
NS_VALUERETURN( [NSNumber numberWithInt:-1], NSNumber* );
|
||||||
NS_ENDHANDLER
|
NS_ENDHANDLER
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSString *)resNameFromStringValue:(NSString *)string
|
+ (NSString *)resNameFromStringValue:(NSString *)string
|
||||||
{
|
{
|
||||||
NSRange range = [string rangeOfString:@"{" options:NSBackwardsSearch];
|
NSRange range = [string rangeOfString:@"{" options:NSBackwardsSearch];
|
||||||
if( range.location != NSNotFound )
|
if( range.location != NSNotFound && range.location > 0 )
|
||||||
{
|
return [string substringToIndex:range.location -1];
|
||||||
NS_DURING
|
else if( range.location == 0 )
|
||||||
NS_VALUERETURN( [string substringToIndex:range.location -1], NSString* );
|
return nil;
|
||||||
NS_HANDLER
|
|
||||||
NS_VALUERETURN( nil, NSString* );
|
|
||||||
NS_ENDHANDLER
|
|
||||||
}
|
|
||||||
else return string;
|
else return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,8 @@
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
[(id)resource autorelease];
|
[(id)resource autorelease];
|
||||||
[undoManager release];
|
[undoManager release];
|
||||||
[shipDataSource release]; // bug: release all data sources
|
[shipDataSource release];
|
||||||
|
[soundDataSource release];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +76,7 @@
|
||||||
if( [[self window] isDocumentEdited] )
|
if( [[self window] isDocumentEdited] )
|
||||||
{
|
{
|
||||||
NSDictionary *errorValues = [self validateValues];
|
NSDictionary *errorValues = [self validateValues];
|
||||||
NSArray *fields = [errorValues allKeys];
|
NSArray *fields = [errorValues allKeys]; // bug: order of items in array is not guaranteed
|
||||||
NSArray *descriptions = [errorValues allValues];
|
NSArray *descriptions = [errorValues allValues];
|
||||||
switch( [errorValues count] )
|
switch( [errorValues count] )
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
#import <Carbon/Carbon.h>
|
#import <Carbon/Carbon.h>
|
||||||
|
|
||||||
|
#pragma options align=packed
|
||||||
|
// see http://developer.apple.com/techpubs/macosx/DeveloperTools/MachORuntime/2rt_powerpc_abi/PowerPC_Data_Alignment.html
|
||||||
|
// align=reset is at the bottom of the file.
|
||||||
|
|
||||||
typedef struct RLEPixelData
|
typedef struct RLEPixelData
|
||||||
{
|
{
|
||||||
// 'rl‘#' resource
|
// 'rl‘#' resource
|
||||||
|
@ -577,7 +581,7 @@ typedef struct NebuRec
|
||||||
typedef struct BoomRec
|
typedef struct BoomRec
|
||||||
{
|
{
|
||||||
short FrameAdvance; // 100 = normal speed, less is slower, higher faster
|
short FrameAdvance; // 100 = normal speed, less is slower, higher faster
|
||||||
short SoundIndex; // 0-63 index, mapping to 300-363 resID
|
short SoundIndex; // 0-63 index, mapping to 300-363 resID, -1 == no sound
|
||||||
short GraphicIndex; // 0-63 index, mapping to 400-463 resID
|
short GraphicIndex; // 0-63 index, mapping to 400-463 resID
|
||||||
} BoomRec;
|
} BoomRec;
|
||||||
|
|
||||||
|
@ -716,4 +720,6 @@ typedef struct IntfRec
|
||||||
short StatFontSize;
|
short StatFontSize;
|
||||||
short SubtitleSize;
|
short SubtitleSize;
|
||||||
short StatusBkgnd;
|
short StatusBkgnd;
|
||||||
} IntfRec;
|
} IntfRec;
|
||||||
|
|
||||||
|
#pragma options align=reset
|
|
@ -1,12 +1,18 @@
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import "NovaWindowController.h"
|
#import "NovaWindowController.h"
|
||||||
|
|
||||||
enum
|
enum // boom defaults
|
||||||
{
|
{
|
||||||
kMinSpinID = 400,
|
kMinBoomSpinID = 400,
|
||||||
kSpinIDRange = 64,
|
kBoomSpinIDRange = 64,
|
||||||
kMinSoundID = 300,
|
kMinBoomSoundID = 300,
|
||||||
kSoundIDRange = 64
|
kBoomSoundIDRange = 64,
|
||||||
|
kMinBoomFrameAdvance = 1,
|
||||||
|
kBoomFrameAdvanceRange = 1000,
|
||||||
|
|
||||||
|
kDefaultBoomSpinID = kMinBoomSpinID,
|
||||||
|
kDefaultBoomSoundID = kMinBoomSoundID,
|
||||||
|
kDefaultBoomFrameAdvance = 100
|
||||||
};
|
};
|
||||||
|
|
||||||
@interface BoomWindowController : NovaWindowController
|
@interface BoomWindowController : NovaWindowController
|
||||||
|
|
|
@ -9,10 +9,19 @@
|
||||||
|
|
||||||
boomRec = (BoomRec *) calloc( 1, sizeof(BoomRec) );
|
boomRec = (BoomRec *) calloc( 1, sizeof(BoomRec) );
|
||||||
[[newResource data] getBytes:boomRec];
|
[[newResource data] getBytes:boomRec];
|
||||||
|
|
||||||
|
// fill in default values if necessary
|
||||||
|
if( boomRec->GraphicIndex < 0 || boomRec->GraphicIndex > 63 )
|
||||||
|
boomRec->GraphicIndex = 0;
|
||||||
|
if( (boomRec->SoundIndex < 0 || boomRec->SoundIndex > 63) && (boomRec->SoundIndex != -1) )
|
||||||
|
boomRec->SoundIndex = 0;
|
||||||
|
if( boomRec->FrameAdvance < 1 || boomRec->FrameAdvance > 1000 )
|
||||||
|
boomRec->FrameAdvance = 100;
|
||||||
|
|
||||||
|
// use resource values to create NS objects
|
||||||
silent = (boomRec->SoundIndex == -1);
|
silent = (boomRec->SoundIndex == -1);
|
||||||
if( boomRec->FrameAdvance == 0 ) boomRec->FrameAdvance = 100;
|
image = [[NSNumber alloc] initWithShort:boomRec->GraphicIndex + kMinBoomSpinID];
|
||||||
image = [[NSNumber alloc] initWithShort:boomRec->GraphicIndex +400];
|
sound = [[NSNumber alloc] initWithShort:(silent? kMinBoomSoundID : boomRec->SoundIndex + kMinBoomSoundID)];
|
||||||
sound = [[NSNumber alloc] initWithShort:boomRec->SoundIndex +300 + (silent? 1:0)];
|
|
||||||
frameRate = [[NSNumber alloc] initWithShort:boomRec->FrameAdvance];
|
frameRate = [[NSNumber alloc] initWithShort:boomRec->FrameAdvance];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -33,6 +42,13 @@
|
||||||
[localCenter addObserver:self selector:@selector(controlTextDidChange:) name:NSComboBoxWillDismissNotification object:nil];
|
[localCenter addObserver:self selector:@selector(controlTextDidChange:) name:NSComboBoxWillDismissNotification object:nil];
|
||||||
[localCenter addObserver:self selector:@selector(controlTextDidChange:) name:NSControlTextDidChangeNotification object:nil];
|
[localCenter addObserver:self selector:@selector(controlTextDidChange:) name:NSControlTextDidChangeNotification object:nil];
|
||||||
|
|
||||||
|
// mark window changed if initial values were invalid
|
||||||
|
if( ![[resource data] isEqualToData:[NSData dataWithBytes:boomRec length:sizeof(BoomRec)]] )
|
||||||
|
{
|
||||||
|
[resource touch];
|
||||||
|
[self setDocumentEdited:YES];
|
||||||
|
}
|
||||||
|
|
||||||
[self update];
|
[self update];
|
||||||
[self showWindow:self];
|
[self showWindow:self];
|
||||||
}
|
}
|
||||||
|
@ -41,12 +57,10 @@
|
||||||
{
|
{
|
||||||
// graphics
|
// graphics
|
||||||
[graphicsField setObjectValue:[spinDataSource stringValueForResID:image]];
|
[graphicsField setObjectValue:[spinDataSource stringValueForResID:image]];
|
||||||
// [spinDataSource parseForString:[graphicsField stringValue] withinRange:NSMakeRange(kMinSpinID, kSpinIDRange) sorted:NO];
|
|
||||||
[frameRateField setObjectValue:frameRate];
|
[frameRateField setObjectValue:frameRate];
|
||||||
|
|
||||||
// sound
|
// sound
|
||||||
[soundField setObjectValue:[soundDataSource stringValueForResID:sound]];
|
[soundField setObjectValue:[soundDataSource stringValueForResID:sound]];
|
||||||
// [soundDataSource parseForString:[soundField stringValue] withinRange:NSMakeRange(kMinSoundID, kSoundIDRange) sorted:NO];
|
|
||||||
[soundButton setState:!silent];
|
[soundButton setState:!silent];
|
||||||
[soundField setEnabled:!silent];
|
[soundField setEnabled:!silent];
|
||||||
[playButton setEnabled:!silent];
|
[playButton setEnabled:!silent];
|
||||||
|
@ -59,11 +73,11 @@
|
||||||
{
|
{
|
||||||
id sender = [notification object];
|
id sender = [notification object];
|
||||||
if( sender == graphicsField )
|
if( sender == graphicsField )
|
||||||
[spinDataSource parseForString:[sender stringValue] withinRange:NSMakeRange(kMinSpinID, kSpinIDRange) sorted:YES];
|
[spinDataSource parseForString:[sender stringValue] withinRange:NSMakeRange(kMinBoomSpinID, kBoomSpinIDRange) sorted:YES];
|
||||||
else if( sender == soundField )
|
else if( sender == soundField )
|
||||||
[soundDataSource parseForString:[sender stringValue] withinRange:NSMakeRange(kMinSoundID, kSoundIDRange) sorted:YES];
|
[soundDataSource parseForString:[sender stringValue] withinRange:NSMakeRange(kMinBoomSoundID, kBoomSoundIDRange) sorted:YES];
|
||||||
|
|
||||||
if( [sender class] == NSClassFromString(@"NSComboBox") )
|
if( [sender class] == [NSComboBox class] )
|
||||||
[sender reloadData];
|
[sender reloadData];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,9 +135,9 @@
|
||||||
{
|
{
|
||||||
NSMutableDictionary *errorValues = [NSMutableDictionary dictionary];
|
NSMutableDictionary *errorValues = [NSMutableDictionary dictionary];
|
||||||
|
|
||||||
// get current values
|
// put current values into boomRec
|
||||||
boomRec->GraphicIndex = [image shortValue] -400;
|
boomRec->GraphicIndex = [image shortValue] - kMinBoomSpinID;
|
||||||
boomRec->SoundIndex = [sound shortValue] -300;
|
boomRec->SoundIndex = [sound shortValue] - kMinBoomSoundID;
|
||||||
boomRec->FrameAdvance = [frameRate shortValue];
|
boomRec->FrameAdvance = [frameRate shortValue];
|
||||||
if( silent ) boomRec->SoundIndex = -1;
|
if( silent ) boomRec->SoundIndex = -1;
|
||||||
|
|
||||||
|
@ -142,7 +156,7 @@
|
||||||
- (void)saveResource
|
- (void)saveResource
|
||||||
{
|
{
|
||||||
// save new data into resource structure (should have already been validated, and boomRec filled out correctly)
|
// save new data into resource structure (should have already been validated, and boomRec filled out correctly)
|
||||||
[resource setData:[NSData dataWithBytes:boomRec length:sizeof(boomRec)]];
|
[resource setData:[NSData dataWithBytes:boomRec length:sizeof(BoomRec)]];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
10
NovaTools/boom/English.lproj/boom.nib/info.nib
generated
10
NovaTools/boom/English.lproj/boom.nib/info.nib
generated
|
@ -1,16 +1,16 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="0.9">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>IBDocumentLocation</key>
|
<key>IBDocumentLocation</key>
|
||||||
<string>161 150 356 240 0 0 1600 1002 </string>
|
<string>86 100 356 240 0 0 1024 746 </string>
|
||||||
<key>IBFramework Version</key>
|
<key>IBFramework Version</key>
|
||||||
<string>248.0</string>
|
<string>283.0</string>
|
||||||
<key>IBOpenObjects</key>
|
<key>IBOpenObjects</key>
|
||||||
<array>
|
<array>
|
||||||
<integer>5</integer>
|
<integer>5</integer>
|
||||||
</array>
|
</array>
|
||||||
<key>IBSystem Version</key>
|
<key>IBSystem Version</key>
|
||||||
<string>5S66</string>
|
<string>6G30</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
BIN
NovaTools/boom/English.lproj/boom.nib/objects.nib
generated
BIN
NovaTools/boom/English.lproj/boom.nib/objects.nib
generated
Binary file not shown.
|
@ -48,7 +48,7 @@
|
||||||
IBOutlet NSComboBox *introPictField4;
|
IBOutlet NSComboBox *introPictField4;
|
||||||
IBOutlet NSForm *introDelayForm;
|
IBOutlet NSForm *introDelayForm;
|
||||||
IBOutlet NSComboBox *introTextField;
|
IBOutlet NSComboBox *introTextField;
|
||||||
IBOutlet NSImageView *introImageView;
|
IBOutlet NSButton *introImageView; // button so user can click to skip to next pic
|
||||||
IBOutlet NSTextView *introTextView;
|
IBOutlet NSTextView *introTextView;
|
||||||
|
|
||||||
IBOutlet NSForm *ncbForm;
|
IBOutlet NSForm *ncbForm;
|
||||||
|
@ -93,6 +93,7 @@
|
||||||
NSNumber *introDelay3;
|
NSNumber *introDelay3;
|
||||||
NSNumber *introDelay4;
|
NSNumber *introDelay4;
|
||||||
NSTimer *introPictTimer;
|
NSTimer *introPictTimer;
|
||||||
|
short currentPict;
|
||||||
|
|
||||||
// Nova Control Bits
|
// Nova Control Bits
|
||||||
NSString *onStart;
|
NSString *onStart;
|
||||||
|
@ -101,6 +102,8 @@
|
||||||
- (void)update;
|
- (void)update;
|
||||||
- (IBAction)editDate:(id)sender;
|
- (IBAction)editDate:(id)sender;
|
||||||
- (IBAction)stepDate:(id)sender;
|
- (IBAction)stepDate:(id)sender;
|
||||||
|
- (IBAction)togglePrincipalChar:(id)sender;
|
||||||
|
- (void)rotateIntroPict:(NSTimer *)timer;
|
||||||
- (void)comboBoxWillPopUp:(NSNotification *)notification;
|
- (void)comboBoxWillPopUp:(NSNotification *)notification;
|
||||||
- (void)controlTextDidChange:(NSNotification *)notification;
|
- (void)controlTextDidChange:(NSNotification *)notification;
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,66 @@
|
||||||
// load data from resource
|
// load data from resource
|
||||||
charRec = (CharRec *) calloc( 1, sizeof(CharRec) );
|
charRec = (CharRec *) calloc( 1, sizeof(CharRec) );
|
||||||
[[newResource data] getBytes:charRec];
|
[[newResource data] getBytes:charRec];
|
||||||
|
|
||||||
|
// fill in default values if necessary
|
||||||
|
if( charRec->startYear == 0 || charRec->startMonth == 0 || charRec->startDay == 0 )
|
||||||
|
{
|
||||||
|
NSCalendarDate *today = [NSCalendarDate calendarDate];
|
||||||
|
charRec->startDay = [today dayOfMonth];
|
||||||
|
charRec->startMonth = [today monthOfYear];
|
||||||
|
charRec->startYear = [today yearOfCommonEra];
|
||||||
|
}
|
||||||
|
|
||||||
|
// set ship to -1 if unused
|
||||||
|
if( charRec->startShipType == 0 ) charRec->startShipType = -1;
|
||||||
|
|
||||||
|
// set unused starting locations to -1
|
||||||
|
if( charRec->startSystem[0] == 0 ) charRec->startSystem[0] = -1;
|
||||||
|
if( charRec->startSystem[1] == 0 ) charRec->startSystem[1] = -1;
|
||||||
|
if( charRec->startSystem[2] == 0 ) charRec->startSystem[2] = -1;
|
||||||
|
if( charRec->startSystem[3] == 0 ) charRec->startSystem[3] = -1;
|
||||||
|
|
||||||
|
// set unused governments to -1
|
||||||
|
if( charRec->startGovt[0] == 0 ) charRec->startGovt[0] = -1;
|
||||||
|
if( charRec->startGovt[1] == 0 ) charRec->startGovt[1] = -1;
|
||||||
|
if( charRec->startGovt[2] == 0 ) charRec->startGovt[2] = -1;
|
||||||
|
if( charRec->startGovt[3] == 0 ) charRec->startGovt[3] = -1;
|
||||||
|
|
||||||
|
// set unused government's status' to -1
|
||||||
|
if( charRec->startGovt[0] == -1 ) charRec->startStatus[0] = -1;
|
||||||
|
if( charRec->startGovt[1] == -1 ) charRec->startStatus[1] = -1;
|
||||||
|
if( charRec->startGovt[2] == -1 ) charRec->startStatus[2] = -1;
|
||||||
|
if( charRec->startGovt[3] == -1 ) charRec->startStatus[3] = -1;
|
||||||
|
|
||||||
|
// set unused intro text to -1
|
||||||
|
if( charRec->introTextID == 0 ) charRec->introTextID = -1;
|
||||||
|
|
||||||
|
// set unused intro picts to -1
|
||||||
|
if( charRec->introPictID[0] == 0 ) charRec->introPictID[0] = -1;
|
||||||
|
if( charRec->introPictID[1] == 0 ) charRec->introPictID[1] = -1;
|
||||||
|
if( charRec->introPictID[2] == 0 ) charRec->introPictID[2] = -1;
|
||||||
|
if( charRec->introPictID[3] == 0 ) charRec->introPictID[3] = -1;
|
||||||
|
|
||||||
|
// set unused/invalid intro pict delays to -1
|
||||||
|
if( charRec->introPictDelay[0] < 1 || charRec->introPictDelay[0] > 300 )
|
||||||
|
charRec->introPictDelay[0] = -1;
|
||||||
|
if( charRec->introPictDelay[1] < 1 || charRec->introPictDelay[1] > 300 )
|
||||||
|
charRec->introPictDelay[1] = -1;
|
||||||
|
if( charRec->introPictDelay[2] < 1 || charRec->introPictDelay[2] > 300 )
|
||||||
|
charRec->introPictDelay[2] = -1;
|
||||||
|
if( charRec->introPictDelay[3] < 1 || charRec->introPictDelay[3] > 300 )
|
||||||
|
charRec->introPictDelay[3] = -1;
|
||||||
|
|
||||||
|
// use resource values to create NS objects
|
||||||
principalChar = charRec->Flags & 0x0001;
|
principalChar = charRec->Flags & 0x0001;
|
||||||
ship = [[NSNumber alloc] initWithShort:charRec->startShipType]; // resID
|
ship = [[NSNumber alloc] initWithShort:charRec->startShipType]; // resID
|
||||||
cash = [[NSNumber alloc] initWithLong:charRec->startCash];
|
cash = [[NSNumber alloc] initWithLong:charRec->startCash];
|
||||||
kills = [[NSNumber alloc] initWithShort:charRec->startKills];
|
kills = [[NSNumber alloc] initWithShort:charRec->startKills];
|
||||||
date = [[NSCalendarDate alloc] initWithYear:charRec->startYear month:charRec->startMonth day:charRec->startDay hour:0 minute:0 second:0 timeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
|
date = [[NSCalendarDate alloc] initWithYear:charRec->startYear month:charRec->startMonth day:charRec->startDay hour:0 minute:0 second:0 timeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
|
||||||
prefix = [[NSString alloc] initWithCString:charRec->Prefix length:16];
|
NSString *tempPrefix = [[[NSString alloc] initWithData:[NSData dataWithBytes:charRec->Prefix length:16] encoding:NSMacOSRomanStringEncoding] autorelease];
|
||||||
suffix = [[NSString alloc] initWithCString:charRec->Suffix length:16];
|
prefix = [[NSString alloc] initWithCString:[tempPrefix cString] length:[tempPrefix cStringLength]];
|
||||||
|
NSString *tempSuffix = [[[NSString alloc] initWithData:[NSData dataWithBytes:charRec->Suffix length:16] encoding:NSMacOSRomanStringEncoding] autorelease];
|
||||||
|
suffix = [[NSString alloc] initWithCString:[tempSuffix cString] length:[tempSuffix cStringLength]];
|
||||||
start1 = [[NSNumber alloc] initWithShort:charRec->startSystem[0]];
|
start1 = [[NSNumber alloc] initWithShort:charRec->startSystem[0]];
|
||||||
start2 = [[NSNumber alloc] initWithShort:charRec->startSystem[1]];
|
start2 = [[NSNumber alloc] initWithShort:charRec->startSystem[1]];
|
||||||
start3 = [[NSNumber alloc] initWithShort:charRec->startSystem[2]];
|
start3 = [[NSNumber alloc] initWithShort:charRec->startSystem[2]];
|
||||||
|
@ -38,8 +91,12 @@
|
||||||
introDelay2 = [[NSNumber alloc] initWithShort:charRec->introPictDelay[1]];
|
introDelay2 = [[NSNumber alloc] initWithShort:charRec->introPictDelay[1]];
|
||||||
introDelay3 = [[NSNumber alloc] initWithShort:charRec->introPictDelay[2]];
|
introDelay3 = [[NSNumber alloc] initWithShort:charRec->introPictDelay[2]];
|
||||||
introDelay4 = [[NSNumber alloc] initWithShort:charRec->introPictDelay[3]];
|
introDelay4 = [[NSNumber alloc] initWithShort:charRec->introPictDelay[3]];
|
||||||
onStart = [[NSString alloc] initWithCString:charRec->OnStart length:256];
|
NSString *tempStart = [[[NSString alloc] initWithData:[NSData dataWithBytes:charRec->OnStart length:256] encoding:NSMacOSRomanStringEncoding] autorelease];
|
||||||
|
onStart = [[NSString alloc] initWithCString:[tempStart cString] length:[tempStart cStringLength]];
|
||||||
|
|
||||||
|
// rotating image
|
||||||
|
currentPict = 0;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +137,7 @@
|
||||||
[introPictField3 setDataSource:pictureDataSource];
|
[introPictField3 setDataSource:pictureDataSource];
|
||||||
[introPictField4 setDelegate:pictureDataSource];
|
[introPictField4 setDelegate:pictureDataSource];
|
||||||
[introPictField4 setDataSource:pictureDataSource];
|
[introPictField4 setDataSource:pictureDataSource];
|
||||||
|
[introTextField setDelegate:descriptionDataSource];
|
||||||
[introTextField setDataSource:descriptionDataSource];
|
[introTextField setDataSource:descriptionDataSource];
|
||||||
|
|
||||||
// set notifications for ending editing on a combo box
|
// set notifications for ending editing on a combo box
|
||||||
|
@ -87,6 +145,16 @@
|
||||||
[localCenter addObserver:self selector:@selector(controlTextDidChange:) name:NSComboBoxWillDismissNotification object:nil];
|
[localCenter addObserver:self selector:@selector(controlTextDidChange:) name:NSComboBoxWillDismissNotification object:nil];
|
||||||
[localCenter addObserver:self selector:@selector(controlTextDidChange:) name:NSControlTextDidChangeNotification object:nil];
|
[localCenter addObserver:self selector:@selector(controlTextDidChange:) name:NSControlTextDidChangeNotification object:nil];
|
||||||
|
|
||||||
|
// mark window changed if initial values were invalid
|
||||||
|
if( ![[resource data] isEqualToData:[NSData dataWithBytes:charRec length:sizeof(CharRec)]] )
|
||||||
|
{
|
||||||
|
[resource touch];
|
||||||
|
[self setDocumentEdited:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
// set initial picture
|
||||||
|
[self rotateIntroPict:nil];
|
||||||
|
|
||||||
// finally, show the window
|
// finally, show the window
|
||||||
[self update];
|
[self update];
|
||||||
[self showWindow:self];
|
[self showWindow:self];
|
||||||
|
@ -113,47 +181,38 @@
|
||||||
[suffixField setStringValue:suffix];
|
[suffixField setStringValue:suffix];
|
||||||
|
|
||||||
// starting locations
|
// starting locations
|
||||||
if( [start1 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [startField1 setObjectValue:nil];
|
[startField1 setObjectValue:[planetDataSource stringValueForResID:start1]];
|
||||||
else [startField1 setObjectValue:[planetDataSource stringValueForResID:start1]];
|
[startField2 setObjectValue:[planetDataSource stringValueForResID:start2]];
|
||||||
if( [start2 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [startField2 setObjectValue:nil];
|
[startField3 setObjectValue:[planetDataSource stringValueForResID:start3]];
|
||||||
else [startField2 setObjectValue:[planetDataSource stringValueForResID:start2]];
|
[startField4 setObjectValue:[planetDataSource stringValueForResID:start4]];
|
||||||
if( [start3 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [startField3 setObjectValue:nil];
|
|
||||||
else [startField3 setObjectValue:[planetDataSource stringValueForResID:start3]];
|
|
||||||
if( [start4 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [startField4 setObjectValue:nil];
|
|
||||||
else [startField4 setObjectValue:[planetDataSource stringValueForResID:start4]];
|
|
||||||
|
|
||||||
// governments
|
// governments
|
||||||
[statusField1 setObjectValue:status1];
|
[statusField1 setObjectValue:status1];
|
||||||
[statusField2 setObjectValue:status2];
|
[statusField2 setObjectValue:status2];
|
||||||
[statusField3 setObjectValue:status3];
|
[statusField3 setObjectValue:status3];
|
||||||
[statusField4 setObjectValue:status4];
|
[statusField4 setObjectValue:status4];
|
||||||
if( [government1 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [governmentField1 setObjectValue:nil];
|
[governmentField1 setObjectValue:[governmentDataSource stringValueForResID:government1]];
|
||||||
else [governmentField1 setObjectValue:[governmentDataSource stringValueForResID:government1]];
|
[governmentField2 setObjectValue:[governmentDataSource stringValueForResID:government2]];
|
||||||
if( [government2 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [governmentField2 setObjectValue:nil];
|
[governmentField3 setObjectValue:[governmentDataSource stringValueForResID:government3]];
|
||||||
else [governmentField2 setObjectValue:[governmentDataSource stringValueForResID:government2]];
|
[governmentField4 setObjectValue:[governmentDataSource stringValueForResID:government4]];
|
||||||
if( [government3 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [governmentField3 setObjectValue:nil];
|
|
||||||
else [governmentField3 setObjectValue:[governmentDataSource stringValueForResID:government3]];
|
|
||||||
if( [government4 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [governmentField4 setObjectValue:nil];
|
|
||||||
else [governmentField4 setObjectValue:[governmentDataSource stringValueForResID:government4]];
|
|
||||||
|
|
||||||
// intro text & pics
|
// intro text & pics
|
||||||
if( [introPict1 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [introPictField1 setObjectValue:nil];
|
[introDelayField1 setObjectValue:introDelay1];
|
||||||
else [introPictField1 setObjectValue:[governmentDataSource stringValueForResID:government1]];
|
[introDelayField2 setObjectValue:introDelay2];
|
||||||
if( [introPict2 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [introPictField2 setObjectValue:nil];
|
[introDelayField3 setObjectValue:introDelay3];
|
||||||
else [introPictField2 setObjectValue:[governmentDataSource stringValueForResID:government2]];
|
[introDelayField4 setObjectValue:introDelay4];
|
||||||
if( [introPict3 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [introPictField3 setObjectValue:nil];
|
[introPictField1 setObjectValue:[pictureDataSource stringValueForResID:introPict1]];
|
||||||
else [introPictField3 setObjectValue:[governmentDataSource stringValueForResID:government3]];
|
[introPictField2 setObjectValue:[pictureDataSource stringValueForResID:introPict2]];
|
||||||
if( [introPict4 isEqualToNumber:[NSNumber numberWithInt:-1]] ) [introPictField4 setObjectValue:nil];
|
[introPictField3 setObjectValue:[pictureDataSource stringValueForResID:introPict3]];
|
||||||
else [introPictField4 setObjectValue:[governmentDataSource stringValueForResID:government4]];
|
[introPictField4 setObjectValue:[pictureDataSource stringValueForResID:introPict4]];
|
||||||
if( [introText isEqualToNumber:[NSNumber numberWithInt:-1]] ) [introTextField setObjectValue:nil];
|
[introTextField setObjectValue:[descriptionDataSource stringValueForResID:introText]];
|
||||||
else [introTextField setObjectValue:[descriptionDataSource stringValueForResID:introText]];
|
|
||||||
|
|
||||||
|
NSData *stringData = [(id <ResKnifeResourceProtocol>)[NSClassFromString(@"Resource") getResourceOfType:[plugBundle localizedStringForKey:@"desc" value:@"" table:@"Resource Types"] andID:introText inDocument:nil] data];
|
||||||
|
if( stringData != nil )
|
||||||
{
|
{
|
||||||
const char *stringData = [[(id <ResKnifeResourceProtocol>)[NSClassFromString(@"Resource") getResourceOfType:[plugBundle localizedStringForKey:@"desc" value:@"" table:@"Resource Types"] andID:introText inDocument:nil] data] bytes];
|
[introTextView setString:[[[NSString alloc] initWithData:stringData encoding:NSMacOSRomanStringEncoding] autorelease]];
|
||||||
if( stringData != NULL )
|
// [introTextView scrollToTop]; // bug: made up method - needs implementing
|
||||||
[introTextView setString:[NSString stringWithCString:stringData]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ncbs
|
// ncbs
|
||||||
[onStartField setStringValue:onStart];
|
[onStartField setStringValue:onStart];
|
||||||
}
|
}
|
||||||
|
@ -174,6 +233,61 @@
|
||||||
[self update];
|
[self update];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)togglePrincipalChar:(id)sender
|
||||||
|
{
|
||||||
|
principalChar = [principalCharButton state];
|
||||||
|
[resource touch];
|
||||||
|
[self setDocumentEdited:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)rotateIntroPictEarly:(id)sender
|
||||||
|
{
|
||||||
|
[introPictTimer fire];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)rotateIntroPict:(NSTimer *)timer
|
||||||
|
{
|
||||||
|
// identify next frame
|
||||||
|
currentPict++;
|
||||||
|
if( currentPict == 2 && [introPict2 intValue] == -1 ) currentPict = 1;
|
||||||
|
else if( currentPict == 3 && [introPict3 intValue] == -1 ) currentPict = 1;
|
||||||
|
else if( currentPict == 4 && [introPict4 intValue] == -1 ) currentPict = 1;
|
||||||
|
else if( currentPict > 4 ) currentPict = 1;
|
||||||
|
|
||||||
|
// install new timer
|
||||||
|
switch( currentPict )
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
// install new timer
|
||||||
|
introPictTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)[introDelay1 doubleValue] target:self selector:@selector(rotateIntroPict:) userInfo:nil repeats:NO];
|
||||||
|
// set next picture
|
||||||
|
[introImageView setImage:[[[NSImage alloc] initWithData:[(id <ResKnifeResourceProtocol>)[NSClassFromString(@"Resource") getResourceOfType:[plugBundle localizedStringForKey:@"PICT" value:@"" table:@"Resource Types"] andID:introPict1 inDocument:nil] data]] autorelease]];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
// install new timer
|
||||||
|
introPictTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)[introDelay2 doubleValue] target:self selector:@selector(rotateIntroPict:) userInfo:nil repeats:NO];
|
||||||
|
// set next picture
|
||||||
|
[introImageView setImage:[[[NSImage alloc] initWithData:[(id <ResKnifeResourceProtocol>)[NSClassFromString(@"Resource") getResourceOfType:[plugBundle localizedStringForKey:@"PICT" value:@"" table:@"Resource Types"] andID:introPict2 inDocument:nil] data]] autorelease]];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
// install new timer
|
||||||
|
introPictTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)[introDelay3 doubleValue] target:self selector:@selector(rotateIntroPict:) userInfo:nil repeats:NO];
|
||||||
|
// set next picture
|
||||||
|
[introImageView setImage:[[[NSImage alloc] initWithData:[(id <ResKnifeResourceProtocol>)[NSClassFromString(@"Resource") getResourceOfType:[plugBundle localizedStringForKey:@"PICT" value:@"" table:@"Resource Types"] andID:introPict3 inDocument:nil] data]] autorelease]];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
// install new timer
|
||||||
|
introPictTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)[introDelay4 doubleValue] target:self selector:@selector(rotateIntroPict:) userInfo:nil repeats:NO];
|
||||||
|
// set next picture
|
||||||
|
[introImageView setImage:[[[NSImage alloc] initWithData:[(id <ResKnifeResourceProtocol>)[NSClassFromString(@"Resource") getResourceOfType:[plugBundle localizedStringForKey:@"PICT" value:@"" table:@"Resource Types"] andID:introPict4 inDocument:nil] data]] autorelease]];
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)comboBoxWillPopUp:(NSNotification *)notification
|
- (void)comboBoxWillPopUp:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
id sender = [notification object];
|
id sender = [notification object];
|
||||||
|
@ -188,79 +302,160 @@
|
||||||
else if( sender == introTextField )
|
else if( sender == introTextField )
|
||||||
[descriptionDataSource parseForString:[sender stringValue] sorted:YES];
|
[descriptionDataSource parseForString:[sender stringValue] sorted:YES];
|
||||||
|
|
||||||
if( [sender class] == NSClassFromString(@"NSComboBox") )
|
if( [sender class] == [NSComboBox class] )
|
||||||
[sender reloadData];
|
[sender reloadData];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)controlTextDidChange:(NSNotification *)notification
|
- (void)controlTextDidChange:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
|
// get the control or form cell being changed
|
||||||
id sender = [notification object];
|
id sender = [notification object];
|
||||||
|
if( [sender class] == [NSForm class] )
|
||||||
|
sender = [sender cellAtIndex:[sender indexOfSelectedItem]];
|
||||||
|
|
||||||
/* ship combo box */
|
/* ship, cash, kills */
|
||||||
|
if( sender == shipField && [sender stringValue] )
|
||||||
if( sender == shipField )
|
|
||||||
{
|
{
|
||||||
id old = ship;
|
id old = ship;
|
||||||
ship = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
ship = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
if( ![ship isEqualToNumber:old] ) [resource touch];
|
if( ![ship isEqualToNumber:old] ) [resource touch];
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
|
else if( sender == cashField )
|
||||||
|
{
|
||||||
|
id old = cash;
|
||||||
|
cash = [[NSNumber alloc] initWithInt:[sender intValue]];
|
||||||
|
if( ![cash isEqualToNumber:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
else if( sender == killsField )
|
||||||
|
{
|
||||||
|
id old = kills;
|
||||||
|
kills = [[NSNumber alloc] initWithInt:[sender intValue]];
|
||||||
|
if( ![kills isEqualToNumber:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start date */
|
||||||
|
else if( sender == dayField || sender == dayStepper )
|
||||||
|
{
|
||||||
|
id old = date;
|
||||||
|
date = [[NSCalendarDate alloc] initWithYear:[old yearOfCommonEra] month:[old monthOfYear] day:[sender intValue] hour:0 minute:0 second:0 timeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];;
|
||||||
|
if( ![date isEqualToDate:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
else if( sender == monthField || sender == monthStepper )
|
||||||
|
{
|
||||||
|
id old = date;
|
||||||
|
date = [[NSCalendarDate alloc] initWithYear:[old yearOfCommonEra] month:[sender intValue] day:[old dayOfMonth] hour:0 minute:0 second:0 timeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];;
|
||||||
|
if( ![date isEqualToDate:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
else if( sender == yearField || sender == yearStepper )
|
||||||
|
{
|
||||||
|
id old = date;
|
||||||
|
date = [[NSCalendarDate alloc] initWithYear:[sender intValue] month:[old monthOfYear] day:[old dayOfMonth] hour:0 minute:0 second:0 timeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];;
|
||||||
|
if( ![date isEqualToDate:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
else if( sender == prefixField && [sender stringValue] )
|
||||||
|
{
|
||||||
|
id old = prefix;
|
||||||
|
prefix = [[sender stringValue] retain];
|
||||||
|
if( ![prefix isEqualToString:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
else if( sender == suffixField && [sender stringValue] )
|
||||||
|
{
|
||||||
|
id old = suffix;
|
||||||
|
suffix = [[sender stringValue] retain];
|
||||||
|
if( ![suffix isEqualToString:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
|
||||||
/* planet combo boxes */
|
/* planet combo boxes */
|
||||||
|
else if( sender == startField1 && [sender stringValue] )
|
||||||
else if( sender == startField1 )
|
|
||||||
{
|
{
|
||||||
id old = start1;
|
id old = start1;
|
||||||
start1 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
start1 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
if( ![start1 isEqualToNumber:old] ) [resource touch];
|
if( ![start1 isEqualToNumber:old] ) [resource touch];
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
else if( sender == startField2 )
|
else if( sender == startField2 && [sender stringValue] )
|
||||||
{
|
{
|
||||||
id old = start2;
|
id old = start2;
|
||||||
start2 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
start2 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
if( ![start2 isEqualToNumber:old] ) [resource touch];
|
if( ![start2 isEqualToNumber:old] ) [resource touch];
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
else if( sender == startField3 )
|
else if( sender == startField3 && [sender stringValue] )
|
||||||
{
|
{
|
||||||
id old = start3;
|
id old = start3;
|
||||||
start3 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
start3 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
if( ![start3 isEqualToNumber:old] ) [resource touch];
|
if( ![start3 isEqualToNumber:old] ) [resource touch];
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
else if( sender == startField4 )
|
else if( sender == startField4 && [sender stringValue] )
|
||||||
{
|
{
|
||||||
id old = start4;
|
id old = start4;
|
||||||
start4 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
start4 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
if( ![start4 isEqualToNumber:old] ) [resource touch];
|
if( ![start4 isEqualToNumber:old] ) [resource touch];
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* starting government status */
|
||||||
|
else if( sender == statusField1 )
|
||||||
|
{
|
||||||
|
id old = status1;
|
||||||
|
status1 = [[NSNumber alloc] initWithInt:[sender intValue]];
|
||||||
|
if( ![status1 isEqualToNumber:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
else if( sender == statusField2 )
|
||||||
|
{
|
||||||
|
id old = status2;
|
||||||
|
status2 = [[NSNumber alloc] initWithInt:[sender intValue]];
|
||||||
|
if( ![status2 isEqualToNumber:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
else if( sender == statusField3 )
|
||||||
|
{
|
||||||
|
id old = status3;
|
||||||
|
status3 = [[NSNumber alloc] initWithInt:[sender intValue]];
|
||||||
|
if( ![status3 isEqualToNumber:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
else if( sender == statusField4 )
|
||||||
|
{
|
||||||
|
id old = status4;
|
||||||
|
status4 = [[NSNumber alloc] initWithInt:[sender intValue]];
|
||||||
|
if( ![status4 isEqualToNumber:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
|
||||||
/* government combo boxes */
|
/* government combo boxes */
|
||||||
|
else if( sender == governmentField1 && [sender stringValue] )
|
||||||
else if( sender == governmentField1 )
|
|
||||||
{
|
{
|
||||||
id old = government1;
|
id old = government1;
|
||||||
government1 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
government1 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
if( ![government1 isEqualToNumber:old] ) [resource touch];
|
if( ![government1 isEqualToNumber:old] ) [resource touch];
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
else if( sender == governmentField2 )
|
else if( sender == governmentField2 && [sender stringValue] )
|
||||||
{
|
{
|
||||||
id old = government2;
|
id old = government2;
|
||||||
government2 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
government2 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
if( ![government2 isEqualToNumber:old] ) [resource touch];
|
if( ![government2 isEqualToNumber:old] ) [resource touch];
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
else if( sender == governmentField3 )
|
else if( sender == governmentField3 && [sender stringValue] )
|
||||||
{
|
{
|
||||||
id old = government3;
|
id old = government3;
|
||||||
government3 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
government3 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
if( ![government3 isEqualToNumber:old] ) [resource touch];
|
if( ![government3 isEqualToNumber:old] ) [resource touch];
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
else if( sender == governmentField4 )
|
else if( sender == governmentField4 && [sender stringValue] )
|
||||||
{
|
{
|
||||||
id old = government4;
|
id old = government4;
|
||||||
government4 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
government4 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
|
@ -268,44 +463,85 @@
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* planet combo boxes */
|
/* intro text combo box */
|
||||||
|
else if( sender == introTextField && [sender stringValue] )
|
||||||
|
{
|
||||||
|
id old = introText;
|
||||||
|
introText = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
|
if( ![introText isEqualToNumber:old] )
|
||||||
|
{
|
||||||
|
[resource touch];
|
||||||
|
[self update]; // to draw text in text box
|
||||||
|
}
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
|
||||||
else if( sender == introPictField1 )
|
/* intro picture combo boxes */
|
||||||
|
else if( sender == introPictField1 && [sender stringValue] )
|
||||||
{
|
{
|
||||||
id old = introPict1;
|
id old = introPict1;
|
||||||
introPict1 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
introPict1 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
if( ![introPict1 isEqualToNumber:old] ) [resource touch];
|
if( ![introPict1 isEqualToNumber:old] ) [resource touch];
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
else if( sender == introPictField2 )
|
else if( sender == introPictField2 && [sender stringValue] )
|
||||||
{
|
{
|
||||||
id old = introPict2;
|
id old = introPict2;
|
||||||
introPict2 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
introPict2 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
if( ![introPict2 isEqualToNumber:old] ) [resource touch];
|
if( ![introPict2 isEqualToNumber:old] ) [resource touch];
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
else if( sender == introPictField3 )
|
else if( sender == introPictField3 && [sender stringValue] )
|
||||||
{
|
{
|
||||||
id old = introPict3;
|
id old = introPict3;
|
||||||
introPict3 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
introPict3 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
if( ![introPict3 isEqualToNumber:old] ) [resource touch];
|
if( ![introPict3 isEqualToNumber:old] ) [resource touch];
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
else if( sender == introPictField4 )
|
else if( sender == introPictField4 && [sender stringValue] )
|
||||||
{
|
{
|
||||||
id old = introPict4;
|
id old = introPict4;
|
||||||
introPict4 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
introPict4 = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
||||||
if( ![introPict4 isEqualToNumber:old] ) [resource touch];
|
if( ![introPict4 isEqualToNumber:old] ) [resource touch];
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* intro text combo box */
|
|
||||||
|
|
||||||
else if( sender == introTextField )
|
/* intro picture delays */
|
||||||
|
else if( sender == introDelayField1 )
|
||||||
{
|
{
|
||||||
id old = introText;
|
id old = introDelay1;
|
||||||
introText = [[DataSource resIDFromStringValue:[sender stringValue]] retain];
|
introDelay1 = [[NSNumber alloc] initWithInt:[sender intValue]];
|
||||||
if( ![introText isEqualToNumber:old] ) [resource touch];
|
if( ![introDelay1 isEqualToNumber:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
else if( sender == introDelayField2 )
|
||||||
|
{
|
||||||
|
id old = introDelay2;
|
||||||
|
introDelay2 = [[NSNumber alloc] initWithInt:[sender intValue]];
|
||||||
|
if( ![introDelay2 isEqualToNumber:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
else if( sender == introDelayField3 )
|
||||||
|
{
|
||||||
|
id old = introDelay3;
|
||||||
|
introDelay3 = [[NSNumber alloc] initWithInt:[sender intValue]];
|
||||||
|
if( ![introDelay3 isEqualToNumber:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
else if( sender == introDelayField4 )
|
||||||
|
{
|
||||||
|
id old = introDelay4;
|
||||||
|
introDelay4 = [[NSNumber alloc] initWithInt:[sender intValue]];
|
||||||
|
if( ![introDelay4 isEqualToNumber:old] ) [resource touch];
|
||||||
|
[old release];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* on start field */
|
||||||
|
else if( sender == onStartField && [sender stringValue] )
|
||||||
|
{
|
||||||
|
id old = onStart;
|
||||||
|
onStart = [[sender stringValue] retain];
|
||||||
|
if( ![onStart isEqualToString:old] ) [resource touch];
|
||||||
[old release];
|
[old release];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,4 +550,69 @@
|
||||||
[self setDocumentEdited:[resource isDirty]];
|
[self setDocumentEdited:[resource isDirty]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSDictionary *)validateValues
|
||||||
|
{
|
||||||
|
NSMutableDictionary *errorValues = [NSMutableDictionary dictionary];
|
||||||
|
|
||||||
|
// put current values into boomRec
|
||||||
|
charRec->Flags = 0x0000;
|
||||||
|
charRec->Flags |= principalChar? 0x0001:0;
|
||||||
|
charRec->startShipType = [ship shortValue];
|
||||||
|
charRec->startCash = [cash longValue];
|
||||||
|
charRec->startKills = [kills shortValue];
|
||||||
|
charRec->startDay = [date dayOfMonth];
|
||||||
|
charRec->startMonth = [date monthOfYear];
|
||||||
|
charRec->startYear = [date yearOfCommonEra];
|
||||||
|
BlockZero( charRec->Prefix, 16 );
|
||||||
|
BlockMoveData( [prefix cString], charRec->Prefix, [prefix cStringLength] <= 15? [prefix cStringLength]+1:16 );
|
||||||
|
BlockZero( charRec->Suffix, 16 );
|
||||||
|
BlockMoveData( [suffix cString], charRec->Suffix, [suffix cStringLength] <= 15? [suffix cStringLength]+1:16 );
|
||||||
|
charRec->startSystem[0] = [start1 shortValue];
|
||||||
|
charRec->startSystem[1] = [start2 shortValue];
|
||||||
|
charRec->startSystem[2] = [start3 shortValue];
|
||||||
|
charRec->startSystem[3] = [start4 shortValue];
|
||||||
|
charRec->startGovt[0] = [government1 shortValue];
|
||||||
|
charRec->startGovt[1] = [government2 shortValue];
|
||||||
|
charRec->startGovt[2] = [government3 shortValue];
|
||||||
|
charRec->startGovt[3] = [government4 shortValue];
|
||||||
|
charRec->startStatus[0] = [status1 shortValue];
|
||||||
|
charRec->startStatus[1] = [status2 shortValue];
|
||||||
|
charRec->startStatus[2] = [status3 shortValue];
|
||||||
|
charRec->startStatus[3] = [status4 shortValue];
|
||||||
|
charRec->introTextID = [introText shortValue];
|
||||||
|
charRec->introPictID[0] = [introPict1 shortValue];
|
||||||
|
charRec->introPictID[1] = [introPict2 shortValue];
|
||||||
|
charRec->introPictID[2] = [introPict3 shortValue];
|
||||||
|
charRec->introPictID[3] = [introPict4 shortValue];
|
||||||
|
charRec->introPictDelay[0] = [introDelay1 shortValue];
|
||||||
|
charRec->introPictDelay[1] = [introDelay2 shortValue];
|
||||||
|
charRec->introPictDelay[2] = [introDelay3 shortValue];
|
||||||
|
charRec->introPictDelay[3] = [introDelay4 shortValue];
|
||||||
|
BlockZero( charRec->OnStart, 256 );
|
||||||
|
BlockMoveData( [onStart cString], charRec->OnStart, [onStart cStringLength] <= 255? [onStart cStringLength]+1:256 );
|
||||||
|
BlockZero( charRec->UnusedA, 8*sizeof(short) );
|
||||||
|
|
||||||
|
// verify values are valid
|
||||||
|
if(charRec->startDay < 1 || charRec->startDay > 31 )
|
||||||
|
[errorValues setObject:@"must be between 1 and 31." forKey:@"Start Day"];
|
||||||
|
if( charRec->startMonth < 1 || charRec->startMonth > 12 )
|
||||||
|
[errorValues setObject:@"must be between 1 and 12." forKey:@"Start Month"];
|
||||||
|
if( charRec->startYear < 1 )
|
||||||
|
[errorValues setObject:@"must be above zero." forKey:@"Start Year"];
|
||||||
|
if(((charRec->introPictDelay[0] < 1 || charRec->introPictDelay[0] > 300) && (charRec->introPictDelay[0] != -1))
|
||||||
|
|| ((charRec->introPictDelay[1] < 1 || charRec->introPictDelay[1] > 300) && (charRec->introPictDelay[1] != -1))
|
||||||
|
|| ((charRec->introPictDelay[2] < 1 || charRec->introPictDelay[2] > 300) && (charRec->introPictDelay[2] != -1))
|
||||||
|
|| ((charRec->introPictDelay[3] < 1 || charRec->introPictDelay[3] > 300) && (charRec->introPictDelay[3] != -1)))
|
||||||
|
[errorValues setObject:@"valid delays are 1 to 300 seconds, or -1 for unused values." forKey:@"Intro Picture Delays"];
|
||||||
|
|
||||||
|
// all values fell within acceptable range
|
||||||
|
return errorValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)saveResource
|
||||||
|
{
|
||||||
|
// save new data into resource structure (should have already been validated, and charRec filled out correctly)
|
||||||
|
[resource setData:[NSData dataWithBytes:charRec length:sizeof(CharRec)]];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
11
NovaTools/char/English.lproj/char.nib/classes.nib
generated
11
NovaTools/char/English.lproj/char.nib/classes.nib
generated
|
@ -1,7 +1,12 @@
|
||||||
{
|
{
|
||||||
IBClasses = (
|
IBClasses = (
|
||||||
{
|
{
|
||||||
ACTIONS = {editDate = id; stepDate = id; };
|
ACTIONS = {
|
||||||
|
editDate = id;
|
||||||
|
rotateIntroPictEarly = id;
|
||||||
|
stepDate = id;
|
||||||
|
togglePrincipalChar = id;
|
||||||
|
};
|
||||||
CLASS = CharWindowController;
|
CLASS = CharWindowController;
|
||||||
LANGUAGE = ObjC;
|
LANGUAGE = ObjC;
|
||||||
OUTLETS = {
|
OUTLETS = {
|
||||||
|
@ -13,7 +18,7 @@
|
||||||
governmentField3 = NSComboBox;
|
governmentField3 = NSComboBox;
|
||||||
governmentField4 = NSComboBox;
|
governmentField4 = NSComboBox;
|
||||||
introDelayForm = NSForm;
|
introDelayForm = NSForm;
|
||||||
introImageView = NSImageView;
|
introImageView = NSButton;
|
||||||
introPictField1 = NSComboBox;
|
introPictField1 = NSComboBox;
|
||||||
introPictField2 = NSComboBox;
|
introPictField2 = NSComboBox;
|
||||||
introPictField3 = NSComboBox;
|
introPictField3 = NSComboBox;
|
||||||
|
@ -23,7 +28,7 @@
|
||||||
monthField = NSTextField;
|
monthField = NSTextField;
|
||||||
monthStepper = NSStepper;
|
monthStepper = NSStepper;
|
||||||
ncbForm = NSForm;
|
ncbForm = NSForm;
|
||||||
principalChar = NSButton;
|
principalCharButton = NSButton;
|
||||||
shipField = NSComboBox;
|
shipField = NSComboBox;
|
||||||
startField1 = NSComboBox;
|
startField1 = NSComboBox;
|
||||||
startField2 = NSComboBox;
|
startField2 = NSComboBox;
|
||||||
|
|
14
NovaTools/char/English.lproj/char.nib/info.nib
generated
14
NovaTools/char/English.lproj/char.nib/info.nib
generated
|
@ -1,11 +1,11 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="0.9">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>IBDocumentLocation</key>
|
<key>IBDocumentLocation</key>
|
||||||
<string>47 148 356 240 0 0 1600 1002 </string>
|
<string>308 330 356 240 0 0 1024 746 </string>
|
||||||
<key>IBFramework Version</key>
|
<key>IBFramework Version</key>
|
||||||
<string>248.0</string>
|
<string>283.0</string>
|
||||||
<key>IBGroupedObjects</key>
|
<key>IBGroupedObjects</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>2</key>
|
<key>2</key>
|
||||||
|
@ -20,11 +20,7 @@
|
||||||
</dict>
|
</dict>
|
||||||
<key>IBLastGroupID</key>
|
<key>IBLastGroupID</key>
|
||||||
<string>3</string>
|
<string>3</string>
|
||||||
<key>IBOpenObjects</key>
|
|
||||||
<array>
|
|
||||||
<integer>137</integer>
|
|
||||||
</array>
|
|
||||||
<key>IBSystem Version</key>
|
<key>IBSystem Version</key>
|
||||||
<string>5S66</string>
|
<string>6G30</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
BIN
NovaTools/char/English.lproj/char.nib/objects.nib
generated
BIN
NovaTools/char/English.lproj/char.nib/objects.nib
generated
Binary file not shown.
|
@ -736,12 +736,6 @@
|
||||||
path = "ResKnife-rsrcfork.rsrc";
|
path = "ResKnife-rsrcfork.rsrc";
|
||||||
refType = 4;
|
refType = 4;
|
||||||
};
|
};
|
||||||
F54627050291767E01A8010C = {
|
|
||||||
fileRef = F54627040291767E01A8010C;
|
|
||||||
isa = PBXBuildFile;
|
|
||||||
settings = {
|
|
||||||
};
|
|
||||||
};
|
|
||||||
F546270B02917D1501A8010C = {
|
F546270B02917D1501A8010C = {
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
@ -2656,7 +2650,7 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
F5B588CF0156D6D901000001,
|
F5B588CF0156D6D901000001,
|
||||||
F54627050291767E01A8010C,
|
F7634BC703B90A220107CC6F,
|
||||||
);
|
);
|
||||||
isa = PBXRezBuildPhase;
|
isa = PBXRezBuildPhase;
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -4087,6 +4081,7 @@
|
||||||
F5EDC61D025BFB8E01A8010C,
|
F5EDC61D025BFB8E01A8010C,
|
||||||
F5EDC620025BFBB501A8010C,
|
F5EDC620025BFBB501A8010C,
|
||||||
F543AFF1027C716E01A8010C,
|
F543AFF1027C716E01A8010C,
|
||||||
|
F7C028FE03BBB39D017A2919,
|
||||||
);
|
);
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -4126,6 +4121,7 @@
|
||||||
};
|
};
|
||||||
F5DF1C0F0254C78801A80001 = {
|
F5DF1C0F0254C78801A80001 = {
|
||||||
children = (
|
children = (
|
||||||
|
F7C028FD03BBB39D017A2919,
|
||||||
F58F6B82025BC73001A8010C,
|
F58F6B82025BC73001A8010C,
|
||||||
F58F6B83025BC73001A8010C,
|
F58F6B83025BC73001A8010C,
|
||||||
F58F6B7E025BC3A501A8010C,
|
F58F6B7E025BC3A501A8010C,
|
||||||
|
@ -4417,6 +4413,33 @@
|
||||||
//F52
|
//F52
|
||||||
//F53
|
//F53
|
||||||
//F54
|
//F54
|
||||||
|
//F70
|
||||||
|
//F71
|
||||||
|
//F72
|
||||||
|
//F73
|
||||||
|
//F74
|
||||||
|
F7634BC703B90A220107CC6F = {
|
||||||
|
fileRef = F5B588A50156D6D901000001;
|
||||||
|
isa = PBXBuildFile;
|
||||||
|
settings = {
|
||||||
|
};
|
||||||
|
};
|
||||||
|
F7C028FD03BBB39D017A2919 = {
|
||||||
|
isa = PBXFileReference;
|
||||||
|
path = novabible.html;
|
||||||
|
refType = 4;
|
||||||
|
};
|
||||||
|
F7C028FE03BBB39D017A2919 = {
|
||||||
|
fileRef = F7C028FD03BBB39D017A2919;
|
||||||
|
isa = PBXBuildFile;
|
||||||
|
settings = {
|
||||||
|
};
|
||||||
|
};
|
||||||
|
//F70
|
||||||
|
//F71
|
||||||
|
//F72
|
||||||
|
//F73
|
||||||
|
//F74
|
||||||
//FD0
|
//FD0
|
||||||
//FD1
|
//FD1
|
||||||
//FD2
|
//FD2
|
||||||
|
|
Loading…
Reference in New Issue
Block a user