mirror of
https://github.com/nickshanks/ResKnife.git
synced 2024-12-25 22:31:03 +00:00
363 lines
10 KiB
Objective-C
363 lines
10 KiB
Objective-C
#import "Resource.h"
|
|
#import "ResourceDocument.h"
|
|
#import "ResourceDataSource.h"
|
|
|
|
NSString *RKResourcePboardType = @"RKResourcePboardType";
|
|
|
|
@implementation Resource
|
|
|
|
- (id)init
|
|
{
|
|
self = [super init];
|
|
[self initWithType:@"NULL" andID:[NSNumber numberWithShort:128]];
|
|
return self;
|
|
}
|
|
|
|
- (id)initWithType:(NSString *)typeValue andID:(NSNumber *)resIDValue
|
|
{
|
|
[self initWithType:typeValue andID:resIDValue withName:@"" andAttributes:[NSNumber numberWithUnsignedShort:0]];
|
|
return self;
|
|
}
|
|
|
|
- (id)initWithType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue
|
|
{
|
|
[self initWithType:typeValue andID:resIDValue withName:nameValue andAttributes:attributesValue data:[NSData data]];
|
|
return self;
|
|
}
|
|
|
|
- (id)initWithType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue data:(NSData *)dataValue
|
|
{
|
|
// sets values directly for speed reasons (less messaging overhead)
|
|
self = [super init];
|
|
dirty = NO;
|
|
representedFork = nil;
|
|
name = [nameValue copy];
|
|
type = [typeValue copy];
|
|
resID = [resIDValue copy];
|
|
attributes = [attributesValue copy];
|
|
data = [dataValue retain];
|
|
return self;
|
|
}
|
|
|
|
|
|
+ (id)resourceOfType:(NSString *)typeValue andID:(NSNumber *)resIDValue
|
|
{
|
|
Resource *resource = [[Resource allocWithZone:[self zone]] initWithType:typeValue andID:resIDValue];
|
|
return [resource autorelease];
|
|
}
|
|
|
|
+ (id)resourceOfType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue
|
|
{
|
|
Resource *resource = [[Resource allocWithZone:[self zone]] initWithType:typeValue andID:resIDValue withName:nameValue andAttributes:attributesValue];
|
|
return [resource autorelease];
|
|
}
|
|
|
|
+ (id)resourceOfType:(NSString *)typeValue andID:(NSNumber *)resIDValue withName:(NSString *)nameValue andAttributes:(NSNumber *)attributesValue data:(NSData *)dataValue
|
|
{
|
|
Resource *resource = [[Resource allocWithZone:[self zone]] initWithType:typeValue andID:resIDValue withName:nameValue andAttributes:attributesValue data:dataValue];
|
|
return [resource autorelease];
|
|
}
|
|
|
|
+ (Resource *)getResourceOfType:(NSString *)typeValue andID:(NSNumber *)resIDValue inDocument:(NSDocument *)searchDoc
|
|
{
|
|
NSDocument *doc;
|
|
NSEnumerator *enumerator = [[[NSDocumentController sharedDocumentController] documents] objectEnumerator];
|
|
while(doc = [enumerator nextObject])
|
|
{
|
|
if(searchDoc == nil || searchDoc == doc)
|
|
{
|
|
// parse document for correct resource
|
|
Resource *resource = [[(ResourceDocument *)doc dataSource] resourceOfType:typeValue andID:resIDValue];
|
|
if(resource) return resource;
|
|
}
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
/* ResKnifeResourceProtocol implementation */
|
|
|
|
+ (NSArray *)allResourcesOfType:(NSString *)typeValue inDocument:(NSDocument *)searchDoc
|
|
{
|
|
NSMutableArray *array = [NSMutableArray array];
|
|
NSDocument *doc;
|
|
NSEnumerator *enumerator = [[[NSDocumentController sharedDocumentController] documents] objectEnumerator];
|
|
while(doc = [enumerator nextObject])
|
|
{
|
|
// parse document for resources
|
|
if(searchDoc == nil || searchDoc == doc)
|
|
[array addObjectsFromArray:[[(ResourceDocument *)doc dataSource] allResourcesOfType:typeValue]];
|
|
}
|
|
return [NSArray arrayWithArray:array];
|
|
}
|
|
|
|
+ (Resource *)resourceOfType:(NSString *)typeValue withName:(NSString *)nameValue inDocument:(NSDocument *)searchDoc
|
|
{
|
|
NSDocument *doc;
|
|
NSEnumerator *enumerator = [[[NSDocumentController sharedDocumentController] documents] objectEnumerator];
|
|
while(doc = [enumerator nextObject])
|
|
{
|
|
if(searchDoc == nil || searchDoc == doc)
|
|
{
|
|
// parse document for correct resource
|
|
Resource *resource = [[(ResourceDocument *)doc dataSource] resourceOfType:typeValue withName:nameValue];
|
|
if(resource) return resource;
|
|
}
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
+ (Resource *)resourceOfType:(NSString *)typeValue andID:(NSNumber *)resIDValue inDocument:(NSDocument *)searchDoc
|
|
{
|
|
NSDocument *doc;
|
|
NSEnumerator *enumerator = [[[NSDocumentController sharedDocumentController] documents] objectEnumerator];
|
|
while(doc = [enumerator nextObject])
|
|
{
|
|
if(searchDoc == nil || searchDoc == doc)
|
|
{
|
|
// parse document for correct resource
|
|
Resource *resource = [[(ResourceDocument *)doc dataSource] resourceOfType:typeValue andID:resIDValue];
|
|
if(resource) return resource;
|
|
}
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
// should probably be in resource document, not resource, but it fits in with the above methods quite well
|
|
+ (NSDocument *)documentForResource:(Resource *)resource
|
|
{
|
|
NSDocument *doc;
|
|
NSEnumerator *enumerator = [[[NSDocumentController sharedDocumentController] documents] objectEnumerator];
|
|
while(doc = [enumerator nextObject])
|
|
{
|
|
Resource *res;
|
|
NSEnumerator *enumerator2 = [[(ResourceDocument *)doc resources] objectEnumerator];
|
|
while(res = [enumerator2 nextObject])
|
|
{
|
|
if([res isEqual:resource])
|
|
return doc;
|
|
}
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[representedFork release];
|
|
[name release];
|
|
[type release];
|
|
[resID release];
|
|
[attributes release];
|
|
[data release];
|
|
[_docName release];
|
|
[super dealloc];
|
|
}
|
|
|
|
- (id)copyWithZone:(NSZone *)zone
|
|
{
|
|
Resource *copy = [[Resource alloc] initWithType:type andID:resID withName:name andAttributes:attributes data:[data copy]];
|
|
[copy setDocumentName:_docName];
|
|
return copy;
|
|
}
|
|
|
|
/* accessors */
|
|
|
|
- (void)touch
|
|
{
|
|
[self setDirty:YES];
|
|
}
|
|
|
|
- (BOOL)isDirty
|
|
{
|
|
return dirty;
|
|
}
|
|
|
|
- (void)setDirty:(BOOL)newValue
|
|
{
|
|
dirty = newValue;
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceDidChangeNotification object:self];
|
|
}
|
|
|
|
- (NSDocument *)document
|
|
{
|
|
return [Resource documentForResource:self];
|
|
}
|
|
|
|
- (void)setDocumentName:(NSString *)docName
|
|
{
|
|
_docName = [docName copy];
|
|
}
|
|
|
|
- (NSString *)representedFork
|
|
{
|
|
return representedFork;
|
|
}
|
|
|
|
- (void)setRepresentedFork:(NSString *)forkName
|
|
{
|
|
representedFork = [forkName copy];
|
|
}
|
|
|
|
- (NSString *)name
|
|
{
|
|
return name;
|
|
}
|
|
|
|
// shouldn't need this - it's used by forks to give them alternate names - should use name formatter replacement instead
|
|
- (void)_setName:(NSString *)newName
|
|
{
|
|
id old = name;
|
|
name = [newName copy];
|
|
[old release];
|
|
}
|
|
|
|
- (void)setName:(NSString *)newName
|
|
{
|
|
if(![name isEqualToString:newName])
|
|
{
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWillChangeNotification object:self];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceNameWillChangeNotification object:self];
|
|
|
|
id old = name;
|
|
name = [newName copy];
|
|
[old release];
|
|
|
|
// bug: this line is causing crashes!
|
|
// [[NSNotificationCenter defaultCenter] postNotificationName:ResourceNameDidChangeNotification object:self];
|
|
[self setDirty:YES];
|
|
}
|
|
}
|
|
|
|
- (NSString *)defaultWindowTitle
|
|
{
|
|
if([name length] > 0) return [NSString stringWithFormat: NSLocalizedString(@"%@: %@ %@ '%@'", @"default window title format with resource name"), _docName, type, resID, name];
|
|
else return [NSString stringWithFormat: NSLocalizedString(@"%@: %@ %@", @"default window title format without resource name"), _docName, type, resID];
|
|
}
|
|
|
|
- (NSString *)type
|
|
{
|
|
return type;
|
|
}
|
|
|
|
- (void)setType:(NSString *)newType
|
|
{
|
|
if(![type isEqualToString:newType])
|
|
{
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWillChangeNotification object:self];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceTypeWillChangeNotification object:self];
|
|
|
|
id old = type;
|
|
type = [newType copy];
|
|
[old release];
|
|
|
|
// bug: this line is causing crashes!
|
|
// [[NSNotificationCenter defaultCenter] postNotificationName:ResourceTypeDidChangeNotification object:self];
|
|
[self setDirty:YES];
|
|
}
|
|
}
|
|
|
|
- (NSNumber *)resID
|
|
{
|
|
return resID;
|
|
}
|
|
|
|
- (void)setResID:(NSNumber *)newResID
|
|
{
|
|
if(![resID isEqualToNumber:newResID])
|
|
{
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWillChangeNotification object:self];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceIDWillChangeNotification object:self];
|
|
|
|
id old = resID;
|
|
resID = [newResID copy];
|
|
[old release];
|
|
|
|
// bug: this line is causing crashes!
|
|
// [[NSNotificationCenter defaultCenter] postNotificationName:ResourceIDDidChangeNotification object:self];
|
|
[self setDirty:YES];
|
|
}
|
|
}
|
|
|
|
- (NSNumber *)attributes
|
|
{
|
|
return attributes;
|
|
}
|
|
|
|
- (void)setAttributes:(NSNumber *)newAttributes
|
|
{
|
|
if(![attributes isEqualToNumber:newAttributes])
|
|
{
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWillChangeNotification object:self];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceAttributesWillChangeNotification object:self];
|
|
|
|
id old = attributes;
|
|
attributes = [newAttributes copy];
|
|
[old release];
|
|
|
|
// bug: this line is causing crashes!
|
|
// [[NSNotificationCenter defaultCenter] postNotificationName:ResourceAttributesDidChangeNotification object:self];
|
|
[self setDirty:YES];
|
|
}
|
|
}
|
|
|
|
- (NSNumber *)size
|
|
{
|
|
return [NSNumber numberWithUnsignedLong:[data length]];
|
|
}
|
|
|
|
- (NSData *)data
|
|
{
|
|
return data;
|
|
}
|
|
|
|
- (void)setData:(NSData *)newData
|
|
{
|
|
if(![data isEqualToData:newData])
|
|
{
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceWillChangeNotification object:self];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceDataWillChangeNotification object:self];
|
|
|
|
// note: this function retains, rather than copies, the supplied data
|
|
id old = data;
|
|
data = [newData retain];
|
|
[old release];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:ResourceDataDidChangeNotification object:self];
|
|
[self setDirty:YES];
|
|
}
|
|
}
|
|
|
|
/* encoding */
|
|
|
|
- (id)initWithCoder:(NSCoder *)decoder
|
|
{
|
|
self = [super init];
|
|
if(self)
|
|
{
|
|
dirty = YES;
|
|
name = [[decoder decodeObject] retain];
|
|
type = [[decoder decodeObject] retain];
|
|
resID = [[decoder decodeObject] retain];
|
|
attributes = [[decoder decodeObject] retain];
|
|
data = [[decoder decodeDataObject] retain];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)encodeWithCoder:(NSCoder *)encoder
|
|
{
|
|
[encoder encodeObject:name];
|
|
[encoder encodeObject:type];
|
|
[encoder encodeObject:resID];
|
|
[encoder encodeObject:attributes];
|
|
[encoder encodeDataObject:data];
|
|
}
|
|
|
|
/* description */
|
|
|
|
- (NSString *)description
|
|
{
|
|
return [NSString stringWithFormat:@"\n%@\nName: %@\nType: %@ ID: %@\nSize: %d Modified: %@", [super description], name, type, resID, [data length], dirty? @"YES":@"NO"];
|
|
}
|
|
|
|
@end
|