Added new template editor (NuTemplateEditor) to repository.

This commit is contained in:
Uli Kusterer 2003-08-06 19:40:46 +02:00
parent d07a120cf1
commit 9fc37c7d86
32 changed files with 1309 additions and 20 deletions

View File

@ -200,6 +200,16 @@ NSString *RKResourcePboardType = @"RKResourcePboardType";
}
}
-(NSString*) nameForEditorWindow
{
if( [name length] > 0 )
return [NSString stringWithFormat: @"%@: '%@' ID=%@ \"%@\"", [document displayName], type, resID, name];
else
return [NSString stringWithFormat: @"%@: '%@' ID=%@", [document displayName], type, resID];
}
- (NSString *)type
{
return type;

View File

@ -10,6 +10,8 @@
{
ACTIONS = {
deselectAll = id;
exportResourceToFile = id;
exportResourceToImageFile = id;
findNext = id;
findPrevious = id;
findWithSelection = id;
@ -36,6 +38,31 @@
LANGUAGE = ObjC;
OUTLETS = {forkTableView = NSTableView; };
SUPERCLASS = NSObject;
},
{
ACTIONS = {
clear = id;
copy = id;
creatorChanged = id;
exportResourceToFile = id;
exportResourceToImageFile = id;
openResources = id;
openResourcesAsHex = id;
openResourcesInTemplate = id;
paste = id;
playSound = id;
showCreateResourceSheet = id;
showSelectTemplateSheet = id;
typeChanged = id;
};
CLASS = ResourceDocument;
LANGUAGE = ObjC;
OUTLETS = {
dataSource = ResourceDataSource;
mainWindow = NSWindow;
outlineView = NSOutlineView;
};
SUPERCLASS = NSDocument;
}
);
IBVersion = 1;

View File

@ -3,22 +3,22 @@
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>535 90 432 426 0 0 1600 1002 </string>
<string>434 99 432 426 0 0 1024 746 </string>
<key>IBEditorPositions</key>
<dict>
<key>246</key>
<string>630 582 340 222 0 0 1600 1002 </string>
<string>12 513 340 222 0 0 1024 746 </string>
<key>29</key>
<string>92 528 347 44 0 0 1600 1002 </string>
<string>28 222 347 44 0 0 1024 746 </string>
</dict>
<key>IBFramework Version</key>
<string>286.0</string>
<string>326.0</string>
<key>IBOpenObjects</key>
<array>
<integer>29</integer>
<integer>246</integer>
<integer>29</integer>
</array>
<key>IBSystem Version</key>
<string>6G30</string>
<string>7A202</string>
</dict>
</plist>

Binary file not shown.

View File

@ -1,16 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>58 46 387 357 0 0 832 602 </string>
<key>IBFramework Version</key>
<string>248.0</string>
<key>IBOpenObjects</key>
<array>
<integer>20</integer>
</array>
<string>326.0</string>
<key>IBSystem Version</key>
<string>5Q45</string>
<string>7A202</string>
</dict>
</plist>

View File

@ -7,7 +7,7 @@
SUPERCLASS = NSObject;
},
{
ACTIONS = {attributesChanged = id; };
ACTIONS = {attributesChanged = id; nameChanged = id; };
CLASS = InfoWindowController;
LANGUAGE = ObjC;
OUTLETS = {
@ -21,6 +21,7 @@
};
SUPERCLASS = NSWindowController;
},
{CLASS = NSWindowController; LANGUAGE = ObjC; SUPERCLASS = NSResponder; },
{CLASS = SizeFormatter; LANGUAGE = ObjC; SUPERCLASS = NSNumberFormatter; }
);
IBVersion = 1;

View File

@ -1,16 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>142 473 384 240 0 0 1024 746 </string>
<key>IBFramework Version</key>
<string>263.2</string>
<string>326.0</string>
<key>IBOpenObjects</key>
<array>
<integer>35</integer>
<integer>5</integer>
<integer>50</integer>
</array>
<key>IBSystem Version</key>
<string>5Q125</string>
<string>7A202</string>
</dict>
</plist>

Binary file not shown.

View File

@ -1,5 +1,5 @@
#import "PictWindowController.h"
#import "Element.h"
//#import "Element.h"
#import <stdarg.h>
@implementation PictWindowController

View File

@ -0,0 +1,12 @@
{
IBClasses = (
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
{
CLASS = NuTemplateWindowController;
LANGUAGE = ObjC;
OUTLETS = {dataList = NSOutlineView; displayList = NSOutlineView; resource = id; };
SUPERCLASS = NSWindowController;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>235 41 356 240 0 0 1024 746 </string>
<key>IBEditorPositions</key>
<dict>
<key>23</key>
<string>412 326 270 342 0 0 1024 746 </string>
</dict>
<key>IBFramework Version</key>
<string>326.0</string>
<key>IBLockedObjects</key>
<array/>
<key>IBOpenObjects</key>
<array>
<integer>21</integer>
<integer>23</integer>
</array>
<key>IBSystem Version</key>
<string>7A202</string>
</dict>
</plist>

Binary file not shown.

View File

@ -0,0 +1,22 @@
//
// NuTemplateDWRDElement.h
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplateElement.h"
@interface NuTemplateDWRDElement : NuTemplateElement
{
short shortValue;
}
-(void) setShortValue: (short)n;
-(short) shortValue;
-(NSString*) stringValue;
@end

View File

@ -0,0 +1,68 @@
//
// NuTemplateDWRDElement.m
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplateDWRDElement.h"
@implementation NuTemplateDWRDElement
-(id) initForType: (NSString*)t withLabel: (NSString*)l
{
if( self = [super initForType:t withLabel:l] )
shortValue = 0;
return self;
}
-(id) copyWithZone: (NSZone*)zone
{
NuTemplateDWRDElement* el = [super copyWithZone: zone];
if( el )
[el setShortValue: shortValue];
return el;
}
-(void) readDataFrom: (NuTemplateStream*)stream containingArray: (NSMutableArray*)containing
{
[stream readAmount:2 toBuffer: &shortValue];
}
-(unsigned int) sizeOnDisk
{
return 2;
}
-(void) writeDataTo: (NuTemplateStream*)stream
{
[stream writeAmount:2 fromBuffer: &shortValue];
}
-(void) setShortValue: (short)d
{
shortValue = d;
}
-(short) shortValue
{
return shortValue;
}
-(NSString*) stringValue
{
return [NSString stringWithFormat: @"%d", shortValue];
}
@end

View File

@ -0,0 +1,58 @@
//
// NuTemplateElement.h
// ResKnife (PB2)
//
// Created by Uli Kusterer on Mon Aug 04 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "NuTemplateStream.h"
/*
This is the base class for all template field types. Subclass this to
define a field type of your own.
Note that subclasses *must* implement the NSCopying protocol, which means
if you have instance variables, you must provide your own copyWithZone:
implementation that calls through to the superclass and then copies its
own variables' values (or retains references to them, if that is more
effective and the object in question isn't mutable).
*/
@interface NuTemplateElement : NSObject <NSCopying>
{
NSString* type;
NSString* label;
}
+(id) elementForType: (NSString*)type withLabel: (NSString*)label;
-(id) initForType: (NSString*)type withLabel: (NSString*)label;
// Accessors:
-(void) setType:(NSString*)t;
-(NSString*) type;
-(void) setLabel:(NSString*)l;
-(NSString*) label;
-(NSString*) stringValue; // Used to display your data in the list.
// Items that have sub-items (like LSTB, LSTZ, LSTC and other lists) should implement these:
-(int) subElementCount;
-(NuTemplateElement*) subElementAtIndex: (int)n;
-(void) readSubElementsFrom: (NuTemplateStream*)stream;
// This is called on an item of your class when displaying resource data using a template that uses your field:
-(void) readDataFrom: (NuTemplateStream*)stream containingArray: (NSMutableArray*)containing;
// This is used to instantiate copies of the item from the template for storing data of the resource. A copy created with this is then sent readDataFrom:.
-(id) copyWithZone: (NSZone*)zone;
// The following are used to write resource data back out:
-(unsigned int) sizeOnDisk;
-(void) writeDataTo: (NuTemplateStream*)stream;
@end

View File

@ -0,0 +1,115 @@
//
// NuTemplateElement.m
// ResKnife (PB2)
//
// Created by Uli Kusterer on Mon Aug 04 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplateElement.h"
@implementation NuTemplateElement
+(id) elementForType: (NSString*)t withLabel: (NSString*)l
{
return [[[self alloc] autorelease] initForType:t withLabel:l];
}
-(id) initForType: (NSString*)t withLabel: (NSString*)l
{
if( self = [super init] )
{
label = [l retain];
type = [t retain];
}
return self;
}
-(void) dealloc
{
[label release];
[type release];
[super dealloc];
}
-(id) copyWithZone: (NSZone*)zone
{
NuTemplateElement* el = [[[self class] allocWithZone: zone] initForType: type withLabel: label];
return el;
}
-(void) setType:(NSString*)t
{
[t retain];
[type release];
type = t;
}
-(NSString*) type
{
return type;
}
-(void) setLabel:(NSString*)l
{
[l retain];
[label release];
label = l;
}
-(NSString*) label
{
return label;
}
-(int) subElementCount
{
return 0;
}
-(NuTemplateElement*) subElementAtIndex: (int)n
{
return nil;
}
-(void) readSubElementsFrom: (NuTemplateStream*)stream
{
// By default, items don't read any sub-elements.
}
-(void) readDataFrom: (NuTemplateStream*)stream containingArray: (NSMutableArray*)containing
{
// You should read whatever kind of data your template field stands for from "stream"
// and store it in an instance variable.
}
// Before writeDataTo: is called, this is called to calculate the final resource size:
// Items with sub-elements should return the sizes of all their sub-elements here as well.
-(unsigned int) sizeOnDisk
{
return 0;
}
-(void) writeDataTo: (NuTemplateStream*)stream
{
// You should write out your data here.
}
-(NSString*) stringValue
{
return @"<unknown>";
}
@end

View File

@ -0,0 +1,20 @@
//
// NuTemplateGroupElement.h
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplateElement.h"
@interface NuTemplateGroupElement : NuTemplateElement
{
NSMutableArray* subElements;
}
-(void) setSubElements: (NSMutableArray*)a;
-(NSMutableArray*) subElements;
@end

View File

@ -0,0 +1,98 @@
//
// NuTemplateGroupElement.m
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplateGroupElement.h"
@implementation NuTemplateGroupElement
-(id) initForType: (NSString*)t withLabel: (NSString*)l
{
if( self = [super initForType:t withLabel:l] )
subElements = [[NSMutableArray alloc] init];
return self;
}
-(void) dealloc
{
[subElements release];
[super dealloc];
}
-(id) copyWithZone: (NSZone*)zone
{
NuTemplateGroupElement* el = [super copyWithZone: zone];
if( el )
{
NSMutableArray* arr = [[[NSMutableArray allocWithZone:zone] autorelease] initWithArray:subElements copyItems:YES];
[el setSubElements: arr];
}
return el;
}
-(void) setSubElements: (NSMutableArray*)a
{
[a retain];
[subElements release];
subElements = a;
}
-(NSMutableArray*) subElements
{
return subElements;
}
-(int) subElementCount
{
return [subElements count];
}
-(NuTemplateElement*) subElementAtIndex: (int)n
{
return [subElements objectAtIndex: n];
}
-(void) readSubElementsFrom: (NuTemplateStream*)stream
{
NSLog(@"Code for reading this object's sub-elements is missing.");
}
// Before writeDataTo: is called, this is called to calculate the final resource size:
// This returns the sizes of all our sub-elements. If you subclass, add to that the size
// of this element itself.
-(unsigned int) sizeOnDisk
{
unsigned int theSize = 0;
NSEnumerator* enny = [subElements objectEnumerator];
NuTemplateElement* obj;
while( obj = [enny nextObject] )
theSize += [obj sizeOnDisk];
return theSize;
}
// Writes out the data of all our sub-elements here:
-(void) writeDataTo: (NuTemplateStream*)stream
{
NSEnumerator* enny = [subElements objectEnumerator];
NuTemplateElement* obj;
while( obj = [enny nextObject] )
[obj writeDataTo: stream];
}
@end

View File

@ -0,0 +1,17 @@
//
// NuTemplateLSTBElement.h
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplateGroupElement.h"
@interface NuTemplateLSTBElement : NuTemplateGroupElement
{
}
@end

View File

@ -0,0 +1,58 @@
//
// NuTemplateLSTBElement.m
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplateLSTBElement.h"
#import "NuTemplateLSTEElement.h"
@implementation NuTemplateLSTBElement
-(void) readSubElementsFrom: (NuTemplateStream*)stream
{
while( [stream bytesToGo] > 0 )
{
NuTemplateElement* obj = [stream readOneElement];
if( [[obj type] isEqualToString: @"LSTE"] )
break;
[subElements addObject: obj];
}
}
-(void) readDataFrom: (NuTemplateStream*)stream containingArray: (NSMutableArray*)containing
{
NSEnumerator *enny = [subElements objectEnumerator];
NuTemplateElement *el, *nextItem;
// Fill this first list element with data:
while( el = [enny nextObject] )
{
[el readDataFrom: stream containingArray: subElements];
}
// Read additional elements until we have enough items:
if( containing != nil )
{
while( [stream bytesToGo] > 0 )
{
nextItem = [self copy]; // Make another list item just like this one.
[containing addObject: nextItem]; // Add it below ourselves.
[nextItem readDataFrom:stream containingArray:nil]; // Read it the same way we were.
}
// Now add a terminating 'LSTE' item:
NuTemplateLSTEElement* tlee;
tlee = [NuTemplateLSTEElement elementForType:@"LSTE" withLabel:label];
[containing addObject: tlee];
[tlee setSubElements: [subElements copy]];
}
}
@end

View File

@ -0,0 +1,17 @@
//
// NuTemplateLSTEElement.h
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplateGroupElement.h"
@interface NuTemplateLSTEElement : NuTemplateGroupElement
{
}
@end

View File

@ -0,0 +1,54 @@
//
// NuTemplateLSTEElement.m
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplateLSTEElement.h"
@implementation NuTemplateLSTEElement
-(void) readSubElementsFrom: (NuTemplateStream*)stream
{
}
-(void) readDataFrom: (NuTemplateStream*)stream containingArray: (NSMutableArray*)containing
{
NSEnumerator* enny = [subElements objectEnumerator];
NuTemplateElement* el;
while( el = [enny nextObject] )
{
[el readDataFrom: stream containingArray: subElements];
}
}
// Doesn't write any sub-elements because this is simply a placeholder to allow for empty lists:
-(unsigned int) sizeOnDisk
{
return 0;
}
-(void) writeDataTo: (NuTemplateStream*)stream
{
}
-(int) subElementCount
{
return 0; // We don't want the user to be able to uncollapse us to see our sub-items.
}
@end

View File

@ -0,0 +1,20 @@
//
// NuTemplatePSTRElement.h
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplateElement.h"
@interface NuTemplatePSTRElement : NuTemplateElement
{
NSString* stringValue;
}
-(void) setStringValue: (NSString*)d;
-(NSString*) stringValue;
@end

View File

@ -0,0 +1,105 @@
//
// NuTemplatePSTRElement.m
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplatePSTRElement.h"
@implementation NuTemplatePSTRElement
-(id) initForType: (NSString*)t withLabel: (NSString*)l
{
if( self = [super initForType:t withLabel:l] )
stringValue = [[NSString alloc] init];
return self;
}
-(void) dealloc
{
[stringValue release];
[super dealloc];
}
-(id) copyWithZone: (NSZone*)zone
{
NuTemplatePSTRElement* el = [super copyWithZone: zone];
if( el )
[el setStringValue: stringValue];
return el;
}
-(void) readDataFrom: (NuTemplateStream*)stream containingArray: (NSMutableArray*)containing
{
char buf[256] = { 0 };
if( [type isEqualToString: @"PSTR"] ) // Packed, variable-length string.
{
[stream readAmount:1 toBuffer: buf];
[stream readAmount:buf[0] toBuffer: (buf +1)];
}
else if( [type isEqualToString: @"P100"] ) // Constant-size string. Resourcerer-style P100, not ResEdit-style P0FF.
[stream readAmount:256 toBuffer: buf];
else if( [type isEqualToString: @"P020"] ) // Constant-size string. Resourcerer-style P020, not ResEdit-style P01F.
[stream readAmount:32 toBuffer: buf];
else if( [type isEqualToString: @"P040"] ) // Constant-size string. Resourcerer-style P040, not ResEdit-style P03F.
[stream readAmount:64 toBuffer: buf];
[self setStringValue: [NSString stringWithCString:(buf +1) length:buf[0]]];
NSLog(@"PSTR: %@", stringValue);
}
// Before writeDataTo: is called, this is called to calculate the final resource size:
-(unsigned int) sizeOnDisk
{
if( [type isEqualToString: @"PSTR"] )
return [stringValue length] +1;
else if( [type isEqualToString: @"P100"] ) // Str255
return 256;
else if( [type isEqualToString: @"P020"] ) // Str31
return 32;
else if( [type isEqualToString: @"P040"] ) // Str63
return 64;
else
return 1;
}
-(void) writeDataTo: (NuTemplateStream*)stream
{
unsigned char buf[257] = { 0 }; // 256 + terminating zero-byte (which isn't written, but generated by getCString)
[stringValue getCString:(buf +1) maxLength:255];
buf[0] = [stringValue length];
if( [type isEqualToString: @"PSTR"] )
[stream writeAmount:([stringValue length] +1) fromBuffer:buf];
else
[stream writeAmount:[self sizeOnDisk] fromBuffer:buf];
}
-(void) setStringValue: (NSString*)d
{
[d retain];
[stringValue release];
stringValue = d;
}
-(NSString*) stringValue
{
return stringValue;
}
@end

View File

@ -0,0 +1,37 @@
//
// NuTemplateStream.h
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import <Foundation/Foundation.h>
@class NuTemplateElement;
@interface NuTemplateStream : NSObject
{
unsigned int bytesToGo;
char* data;
}
+(NSMutableDictionary*) fieldRegistry;
+(id) streamWithBytes: (char*)d length: (unsigned int)l;
+(id) substreamWithStream: (NuTemplateStream*)s length: (unsigned int)l;
-(id) initStreamWithBytes: (char*)d length: (unsigned int)l;
-(id) initWithStream: (NuTemplateStream*)s length: (unsigned int)l;
-(unsigned int) bytesToGo;
-(char*) data;
-(NuTemplateElement*) readOneElement; // For parsing of 'TMPL' resource as template.
-(void) readAmount: (unsigned int)l toBuffer: (void*)buf; // For reading data from the resource.
-(void) writeAmount: (unsigned int)l fromBuffer: (void*)buf; // For writing data back to the resource.
@end

View File

@ -0,0 +1,125 @@
//
// NuTemplateStream.m
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplateStream.h"
#import "NuTemplateElement.h"
@implementation NuTemplateStream
+(NSMutableDictionary*) fieldRegistry
{
static NSMutableDictionary* sFieldRegistry = nil;
if( !sFieldRegistry )
sFieldRegistry = [[NSMutableDictionary alloc] init];
return sFieldRegistry;
}
+(id) streamWithBytes: (char*)d length: (unsigned int)l
{
return [[[self alloc] autorelease] initStreamWithBytes:d length:l];
}
+(id) substreamWithStream: (NuTemplateStream*)s length: (unsigned int)l
{
return [[[self alloc] autorelease] initWithStream:s length:l];
}
-(id) initStreamWithBytes: (char*)d length: (unsigned int)l
{
if( self = [super init] )
{
data = d;
bytesToGo = l;
}
return self;
}
-(id) initWithStream: (NuTemplateStream*)s length: (unsigned int)l
{
if( self = [super init] )
{
data = [s data];
if( l > [s bytesToGo] )
bytesToGo = [s bytesToGo];
else
bytesToGo = l;
}
return self;
}
-(unsigned int) bytesToGo
{
return bytesToGo;
}
-(char*) data
{
return data;
}
-(NuTemplateElement*) readOneElement
{
NSString* label = [NSString stringWithCString: data +1 length: *data];
unsigned long labelLen = (*data) +1;
NuTemplateElement* obj = nil;
data += labelLen;
// Get type (4 characters after that):
NSString* type = [NSString stringWithCString: data length: 4];
data += 4;
// Update number of bytes left: (termination criterion!)
bytesToGo -= labelLen +4;
// TODO: We should really look up the class for an entry of this type in a dictionary:
Class theClass = [[NuTemplateStream fieldRegistry] objectForKey:type];
obj = (NuTemplateElement*) [theClass elementForType:type withLabel:label];
[obj readSubElementsFrom: self];
return obj;
}
-(void) readAmount: (unsigned int)l toBuffer: (void*)buf
{
if( l > bytesToGo )
l = bytesToGo;
if( l > 0 )
{
memmove( buf, data, l );
data += l;
bytesToGo -= l;
}
}
-(void) writeAmount: (unsigned int)l fromBuffer: (void*)buf
{
if( l > bytesToGo )
l = bytesToGo;
if( l > 0 )
{
memmove( data, buf, l );
data += l;
bytesToGo -= l;
}
}
@end

View File

@ -0,0 +1,20 @@
//
// NuTemplateTNAMElement.h
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplateElement.h"
@interface NuTemplateTNAMElement : NuTemplateElement
{
NSString* stringValue;
}
-(void) setStringValue: (NSString*)d;
-(NSString*) stringValue;
@end

View File

@ -0,0 +1,82 @@
//
// NuTemplateTNAMElement.m
// ResKnife (PB2)
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
#import "NuTemplateTNAMElement.h"
@implementation NuTemplateTNAMElement
-(id) initForType: (NSString*)t withLabel: (NSString*)l
{
if( self = [super initForType:t withLabel:l] )
stringValue = [[NSString alloc] init];
return self;
}
-(void) dealloc
{
[stringValue release];
[super dealloc];
}
-(id) copyWithZone: (NSZone*)zone
{
NuTemplateTNAMElement* el = [super copyWithZone: zone];
if( el )
[el setStringValue: stringValue];
return el;
}
-(void) readDataFrom: (NuTemplateStream*)stream containingArray: (NSMutableArray*)containing
{
char buf[4] = { ' ', ' ', ' ', ' ' };
[stream readAmount:4 toBuffer: buf];
[self setStringValue: [NSString stringWithCString:buf length:4]];
NSLog(@"PSTR: %@", stringValue);
}
// Before writeDataTo: is called, this is called to calculate the final resource size:
-(unsigned int) sizeOnDisk
{
return 4;
}
-(void) writeDataTo: (NuTemplateStream*)stream
{
char buf[5] = { ' ', ' ', ' ', ' ', 0 };
[stringValue getCString:buf maxLength:4];
[stream writeAmount:4 fromBuffer:buf];
}
-(void) setStringValue: (NSString*)d
{
[d retain];
[stringValue release];
stringValue = d;
}
-(NSString*) stringValue
{
return stringValue;
}
@end

View File

@ -0,0 +1,51 @@
/* =============================================================================
PROJECT: ResKnife
FILE: NuTemplateWindowController.h
PURPOSE: This is the main class of our template editor. Every
resource editor's main class implements the
ResKnifePluginProtocol. Every editor should implement
initWithResource:. Only implement initWithResources: if you feel
like writing a template editor.
Note that your plugin is responsible for committing suicide
after its window has been closed. If you subclass it from
NSWindowController, the controller will take care of that
for you, according to a guy named Doug.
AUTHORS: M. Uli Kusterer, witness(at)zathras.de, (c) 2003.
REVISIONS:
2003-07-31 UK Created.
========================================================================== */
/* -----------------------------------------------------------------------------
Headers:
-------------------------------------------------------------------------- */
#import <Cocoa/Cocoa.h>
#import "ResKnifePluginProtocol.h"
#import "ResKnifeResourceProtocol.h"
/* -----------------------------------------------------------------------------
Interface:
-------------------------------------------------------------------------- */
@interface NuTemplateWindowController : NSWindowController <ResKnifeTemplatePluginProtocol>
{
IBOutlet NSOutlineView* displayList; // template display (debug only).
IBOutlet NSOutlineView* dataList; // Data display.
NSMutableArray* templateStructure; // Pre-parsed form of our template.
NSMutableArray* resourceStructure; // Parsed form of our resource.
id <ResKnifeResourceProtocol> resource; // The resource we operate on.
}
-(void) readTemplate: (id <ResKnifeResourceProtocol>)tmplRes;
-(void) reloadResData;
-(void) resourceDataDidChange: (NSNotification*)notification;
-(void) writeResData;
@end

View File

@ -0,0 +1,250 @@
/* =============================================================================
PROJECT: ResKnife
FILE: NuTemplateWindowController.h
PURPOSE: This is the main class of our template editor. Every
resource editor's main class implements the
ResKnifePluginProtocol. Every editor should implement
initWithResource:. Only implement initWithResources: if you feel
like writing a template editor.
Note that your plugin is responsible for committing suicide
after its window has been closed. If you subclass it from
NSWindowController, the controller will take care of that
for you, according to a guy named Doug.
AUTHORS: M. Uli Kusterer, witness(at)zathras.de, (c) 2003.
REVISIONS:
2003-07-31 UK Created.
========================================================================== */
/* -----------------------------------------------------------------------------
Headers:
-------------------------------------------------------------------------- */
#import "NuTemplateWindowController.h"
#import "NuTemplateElement.h"
#import "NuTemplateLSTBElement.h"
#import "NuTemplateLSTEElement.h"
#import "NuTemplateTNAMElement.h"
#import "NuTemplatePSTRElement.h"
#import "NuTemplateDWRDElement.h"
#import "NuTemplateStream.h"
@implementation NuTemplateWindowController
/* -----------------------------------------------------------------------------
initWithResource:
This is it! This is the constructor. Create your window here and
do whatever else makes you happy. A new instance is created for each
resource. Note that you are responsible for keeping track of your
resource.
-------------------------------------------------------------------------- */
- (id)initWithResource:(id)newResource
{
return [self initWithResources:newResource, nil];
}
- (id)initWithResources:(id)newResource, ...
{
id currentResource;
va_list resourceList;
va_start( resourceList, newResource );
self = [self initWithWindowNibName:@"NuTemplateWindow"];
if( !self )
{
va_end( resourceList );
return self;
}
resource = [newResource retain];
templateStructure = [[NSMutableArray alloc] init];
resourceStructure = [[NSMutableArray alloc] init];
currentResource = va_arg( resourceList, id );
[self readTemplate:currentResource]; // 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 ) )
NSLog( @"too many params passed to -initWithResources: %@", [currentResource description] );
va_end( resourceList );
// load the window from the nib
[self window];
return self;
}
/* -----------------------------------------------------------------------------
* DESTRUCTOR
-------------------------------------------------------------------------- */
-(void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[(id)resource autorelease];
[templateStructure release];
[resourceStructure release];
[super dealloc];
}
/* -----------------------------------------------------------------------------
windowDidLoad:
Our window is there, stuff the image in it.
-------------------------------------------------------------------------- */
-(void) windowDidLoad
{
[super windowDidLoad];
// set the window's title
[[self window] setTitle:[resource nameForEditorWindow]];
[self reloadResData];
// 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(resourceDataDidChange:) name:ResourceDataDidChangeNotification object:resource];
// finally, show the window
[self showWindow:self];
[displayList reloadData];
}
/* -----------------------------------------------------------------------------
resourceDataDidChange:
Notification that someone changed our resource's data and we should
update our display.
-------------------------------------------------------------------------- */
-(void) resourceDataDidChange: (NSNotification*)notification
{
// ensure it's our resource which got changed (should always be true, we don't register for notifications on other resource objects)
if( [notification object] == (id)resource )
[self reloadResData];
}
-(void) reloadResData
{
char* theData = (char*) [[resource data] bytes];
unsigned long bytesToGo = [[resource data] length];
NuTemplateStream* stream = [NuTemplateStream streamWithBytes: theData length: bytesToGo];
NSEnumerator* enny = [templateStructure objectEnumerator];
NuTemplateElement* currElement;
[resourceStructure removeAllObjects]; // Get rid of old parsed resource.
// Loop over template and read each field:
while( currElement = [enny nextObject] )
{
currElement = [currElement copy]; // Copy the template object.
[resourceStructure addObject: currElement]; // Add it to our parsed resource data list. Do this right away so the element can append other items should it desire to.
[currElement readDataFrom: stream containingArray: resourceStructure]; // Fill it with resource data.
}
[dataList reloadData]; // Make sure our outline view displays the new data.
}
-(void) writeResData
{
unsigned int theSize = 0;
NSEnumerator* enny = [resourceStructure objectEnumerator];
NuTemplateElement* obj;
while( obj = [enny nextObject] )
theSize += [obj sizeOnDisk];
NSMutableData* newData = [NSMutableData dataWithLength: theSize];
NuTemplateStream* stream = [NuTemplateStream streamWithBytes: [newData bytes] length: theSize];
enny = [resourceStructure objectEnumerator];
while( obj = [enny nextObject] )
[obj writeDataTo: stream];
[resource setData: newData];
}
-(void) readTemplate: (id <ResKnifeResourceProtocol>)tmplRes
{
char* theData = (char*) [[tmplRes data] bytes];
unsigned long bytesToGo = [[tmplRes data] length];
NuTemplateStream* stream = [NuTemplateStream streamWithBytes: theData length: bytesToGo];
NSMutableDictionary* fieldReg = [NuTemplateStream fieldRegistry];
// Registry empty? Add field types we support:
if( [fieldReg count] == 0 )
{
[fieldReg setObject: [NuTemplateLSTBElement class] forKey: @"LSTB"];
[fieldReg setObject: [NuTemplateLSTEElement class] forKey: @"LSTE"];
[fieldReg setObject: [NuTemplateTNAMElement class] forKey: @"TNAM"];
[fieldReg setObject: [NuTemplatePSTRElement class] forKey: @"PSTR"];
[fieldReg setObject: [NuTemplatePSTRElement class] forKey: @"P100"];
[fieldReg setObject: [NuTemplatePSTRElement class] forKey: @"P020"];
[fieldReg setObject: [NuTemplatePSTRElement class] forKey: @"P040"];
[fieldReg setObject: [NuTemplateDWRDElement class] forKey: @"DWRD"];
}
// Read new fields from the template and add them to our list:
while( [stream bytesToGo] > 0 )
{
NuTemplateElement* obj = [stream readOneElement];
[templateStructure addObject: obj];
}
[displayList reloadData];
}
-(id) outlineView:(NSOutlineView*)outlineView child:(int)index ofItem:(id)item
{
if( (item == nil) && (outlineView == displayList) )
return [templateStructure objectAtIndex:index];
else if( (item == nil) && (outlineView == dataList) )
return [resourceStructure objectAtIndex:index];
else
return [item subElementAtIndex: index];
}
-(BOOL) outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
return ([item subElementCount] > 0);
}
-(int) outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
if( (item == nil) && (outlineView == displayList) )
return [templateStructure count];
else if( (item == nil) && (outlineView == dataList) )
return [resourceStructure count];
else
return [item subElementCount];
}
-(id) outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
return [item valueForKey:[tableColumn identifier]];
}
-(BOOL) windowShouldClose: (id)sender // Window delegate.
{
[self writeResData]; // Save resource.
return YES;
}
@end