2
* resourcetreeitem.m - item of the resource tree
5
* Christian Vogelgsang <chris@vogelgsang.org>
7
* This file is part of VICE, the Versatile Commodore Emulator.
8
* See README for copyright notice.
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27
#import "resourcetreeitem.h"
28
#import "resourceeditorcontroller.h"
30
@implementation ResourceTreeItem
32
-(id)initWithTitle:(NSString *)t
62
return children == nil;
65
-(ResourceTreeItem *)childAtIndex:(int)index
67
return (ResourceTreeItem *)[children objectAtIndex:index];
75
return [children count];
78
-(BOOL)addFromDictionary:(NSDictionary *)dict
80
NSMutableArray *a = [[NSMutableArray alloc] init];
81
NSEnumerator *enumerator = [dict keyEnumerator];
83
while((key = [enumerator nextObject])) {
84
ResourceTreeItem *item = [[ResourceTreeItem alloc] initWithTitle:key];
87
id value = [dict objectForKey:key];
89
// its a dictionary itself
90
if([value isKindOfClass:[NSDictionary class]]) {
91
if(![item addFromDictionary:value])
95
else if([value isKindOfClass:[NSString class]]) {
96
if(![item parseResourceString:(NSString *)value])
101
NSLog(@"Invalid Class in Dictionary: %@",[value class]);
106
// sort array and keep
107
children = [a sortedArrayUsingSelector:@selector(compare:)];
113
-(BOOL)parseResourceString:(NSString *)string
115
args = [string componentsSeparatedByString:@","];
117
numArgs = [args count];
119
NSLog(@"ERROR: resource string invalid: %@",string);
123
resource = (NSString *)[args objectAtIndex:0];
126
NSString *typeStr = (NSString *)[args objectAtIndex:1];
127
unichar ch = [typeStr characterAtIndex:0];
130
type = ResourceTreeItemTypeInteger;
131
hint = ResourceTreeItemHintNone;
134
type = ResourceTreeItemTypeInteger;
135
hint = ResourceTreeItemHintBoolean;
138
type = ResourceTreeItemTypeInteger;
139
hint = ResourceTreeItemHintEnum;
141
case 'E': // enum direct
142
type = ResourceTreeItemTypeInteger;
143
hint = ResourceTreeItemHintEnumDirect;
146
type = ResourceTreeItemTypeInteger;
147
hint = ResourceTreeItemHintRange;
150
type = ResourceTreeItemTypeString;
151
hint = ResourceTreeItemHintNone;
153
case 'm': // map string to integer
154
type = ResourceTreeItemTypeInteger;
155
hint = ResourceTreeItemHintMapInteger;
159
unichar mode = [typeStr characterAtIndex:1];
160
type = ResourceTreeItemTypeString;
163
hint = ResourceTreeItemHintFileOpen;
166
hint = ResourceTreeItemHintFileSave;
169
hint = ResourceTreeItemHintFileDir;
172
NSLog(@"ERROR: Invalid file resource mode: %@",typeStr);
178
NSLog(@"ERROR: Invalid resource type: %@",typeStr);
190
-(int)parseIntFromString:(NSString *)string
192
int len = [string length];
197
const char *str = [string cStringUsingEncoding:NSUTF8StringEncoding];
199
sscanf(str+1,"%x",&value);
201
sscanf(str,"%d",&value);
206
-(id)getValue:(id)ctl
208
ResourceEditorController *controller = (ResourceEditorController *)ctl;
210
if(cacheValue == nil) {
211
if(type == ResourceTreeItemTypeInteger) {
212
int value = [controller getIntResource:resource];
213
// NSLog(@"read integer: %@ %d",resource,value);
216
if(hint == ResourceTreeItemHintEnum) {
217
cacheValue = [[args objectAtIndex:value+2] retain];
220
else if(hint == ResourceTreeItemHintEnumDirect) {
222
for(i=2;i<numArgs;i++) {
223
NSString *argString = (NSString *)[args objectAtIndex:i];
224
int argValue = [self parseIntFromString:argString];
225
if(argValue == value) {
226
cacheValue = [argString retain];
231
// map string to ineger: txt=value
232
else if(hint == ResourceTreeItemHintMapInteger) {
234
for(i=2;i<numArgs;i++) {
235
NSString *argString = (NSString *)[args objectAtIndex:i];
236
NSArray *pair = [argString componentsSeparatedByString:@"="];
237
if([pair count]>=2) {
238
NSString *keyStr = (NSString *)[pair objectAtIndex:0];
239
NSString *valueStr = (NSString *)[pair objectAtIndex:1];
240
if(keyStr && valueStr) {
241
if([self parseIntFromString:valueStr]==value) {
242
cacheValue = [keyStr retain];
251
cacheValue = [[NSNumber alloc] initWithInt:value];
255
NSString *value = [controller getStringResource:resource];
256
// NSLog(@"read string: %@ %@",resource,value);
257
cacheValue = [value retain];
266
-(void)setIntResourceToValue:(int)value withController:(id)ctl
268
ResourceEditorController *controller = (ResourceEditorController *)ctl;
269
[controller setIntResource:resource toValue:value];
270
[self invalidateCache];
271
[controller reloadItem:self];
272
// NSLog(@"set int resource %@ %d",resource,value);
275
-(void)setStringResourceToValue:(NSString *)value withController:(id)ctl
277
ResourceEditorController *controller = (ResourceEditorController *)ctl;
278
[controller setStringResource:resource toValue:value];
279
[self invalidateCache];
280
[controller reloadItem:self];
281
// NSLog(@"set string resource %@ %d",resource,value);
284
-(void)setValue:(id)ctl toObject:(id)object
286
NSString *string = (NSString *)object;
287
if(type == ResourceTreeItemTypeInteger) {
290
if(hint==ResourceTreeItemHintEnum ||
291
hint==ResourceTreeItemHintEnumDirect) {
293
for(i=2;i<numArgs;i++) {
294
NSString *argVal = (NSString *)[args objectAtIndex:i];
295
if([argVal isEqualToString:string]) {
296
if(hint==ResourceTreeItemHintEnum)
299
value = [self parseIntFromString:argVal];
305
else if(hint==ResourceTreeItemHintMapInteger) {
307
for(i=2;i<numArgs;i++) {
308
NSString *argString = (NSString *)[args objectAtIndex:i];
309
NSArray *pair = [argString componentsSeparatedByString:@"="];
310
if([pair count]>=2) {
311
NSString *keyStr = (NSString *)[pair objectAtIndex:0];
312
NSString *valueStr = (NSString *)[pair objectAtIndex:1];
313
if(keyStr && valueStr) {
314
if([keyStr isEqualToString:string]) {
315
value = [self parseIntFromString:valueStr];
323
else if(hint==ResourceTreeItemHintRange) {
325
int min = [[args objectAtIndex:2] intValue];
326
int max = [[args objectAtIndex:3] intValue];
332
NSLog(@"ERROR: range invalid: %@",args);
337
value = [string intValue];
339
[self setIntResourceToValue:value withController:ctl];
341
[self setStringResourceToValue:string withController:ctl];
345
-(void)setValueExtra:(id)ctl
347
ResourceEditorController *controller = (ResourceEditorController *)ctl;
349
case ResourceTreeItemHintFileOpen:
351
NSString *file = [controller pickOpenFileWithTitle:title types:nil];
353
[self setStringResourceToValue:file withController:ctl];
356
case ResourceTreeItemHintFileSave:
358
NSString *file = [controller pickSaveFileWithTitle:title types:nil];
360
[self setStringResourceToValue:file withController:ctl];
363
case ResourceTreeItemHintFileDir:
365
NSString *file = [controller pickDirectoryWithTitle:title];
367
[self setStringResourceToValue:file withController:ctl];
373
-(NSCell *)dataCell:(NSCell *)colCell
381
case ResourceTreeItemHintBoolean:
383
NSButtonCell *bcell = [[NSButtonCell alloc] initTextCell:@""];
384
[bcell setButtonType:NSSwitchButton];
388
case ResourceTreeItemHintEnum:
389
case ResourceTreeItemHintEnumDirect:
391
NSComboBoxCell *ccell = [[NSComboBoxCell alloc] initTextCell:@""];
393
[ccell setButtonBordered:FALSE];
394
for(i=2;i<numArgs;i++) {
395
[ccell addItemWithObjectValue:[args objectAtIndex:i]];
400
case ResourceTreeItemHintMapInteger:
402
NSComboBoxCell *ccell = [[NSComboBoxCell alloc] initTextCell:@""];
404
[ccell setButtonBordered:FALSE];
405
for(i=2;i<numArgs;i++) {
406
NSString *argString = (NSString *)[args objectAtIndex:i];
407
NSArray *pair = [argString componentsSeparatedByString:@"="];
408
if([pair count]>=2) {
409
NSString *keyStr = (NSString *)[pair objectAtIndex:0];
410
NSString *valueStr = (NSString *)[pair objectAtIndex:1];
411
[ccell addItemWithObjectValue:keyStr];
420
// reuse default font
421
[dataCell setFont:[colCell font]];
427
-(NSCell *)extraCell:(NSCell *)colCell
436
case ResourceTreeItemHintFileOpen:
437
case ResourceTreeItemHintFileSave:
438
case ResourceTreeItemHintFileDir:
440
NSButtonCell *bcell = [[NSButtonCell alloc] initTextCell:@""];
441
[bcell setButtonType:NSMomentaryLightButton];
442
[bcell setTitle:@"..."];
449
[extraCell setFont:[colCell font]];
455
-(NSComparisonResult)compare:(ResourceTreeItem *)item
457
return [title caseInsensitiveCompare:[item title]];
460
-(void)invalidateCache
463
[cacheValue release];
466
int num = [children count];
469
[(ResourceTreeItem *)[children objectAtIndex:i] invalidateCache];