~ubuntu-branches/ubuntu/raring/vice/raring

« back to all changes in this revision

Viewing changes to src/arch/unix/macosx/cocoa/dialog/resourcetreeitem.m

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2009-03-31 00:37:15 UTC
  • mfrom: (1.1.7 upstream) (9.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20090331003715-i5yisvcfv7mgz3eh
Tags: 2.1.dfsg-1
* New major upstream release (closes: #495937).
* Add desktop files (closes: #501181).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * resourcetreeitem.m - item of the resource tree
 
3
 *
 
4
 * Written by
 
5
 *  Christian Vogelgsang <chris@vogelgsang.org>
 
6
 *
 
7
 * This file is part of VICE, the Versatile Commodore Emulator.
 
8
 * See README for copyright notice.
 
9
 *
 
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.
 
14
 *
 
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.
 
19
 *
 
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
 
23
 *  02111-1307  USA.
 
24
 *
 
25
 */
 
26
 
 
27
#import "resourcetreeitem.h"
 
28
#import "resourceeditorcontroller.h"
 
29
 
 
30
@implementation ResourceTreeItem
 
31
 
 
32
-(id)initWithTitle:(NSString *)t
 
33
{
 
34
    self = [super init];
 
35
    if(self == nil)
 
36
        return nil;
 
37
    
 
38
    title = [t retain];
 
39
    resource = nil;
 
40
    children = nil;
 
41
    cacheValue = nil;
 
42
    dataCell = nil;
 
43
    extraCell = nil;
 
44
    
 
45
    return self;
 
46
}
 
47
 
 
48
-(void)dealloc
 
49
{
 
50
    [title release];
 
51
    [resource release];
 
52
    [children release];
 
53
    [cacheValue release];
 
54
    [dataCell release];
 
55
    [extraCell release];
 
56
    [args release];
 
57
    [super dealloc];
 
58
}
 
59
 
 
60
-(BOOL)isLeaf
 
61
{
 
62
    return children == nil;
 
63
}
 
64
 
 
65
-(ResourceTreeItem *)childAtIndex:(int)index
 
66
{
 
67
    return (ResourceTreeItem *)[children objectAtIndex:index];
 
68
}
 
69
 
 
70
-(int)numChildren
 
71
{
 
72
    if(children==nil)
 
73
        return 0;
 
74
    else
 
75
        return [children count];
 
76
}
 
77
 
 
78
-(BOOL)addFromDictionary:(NSDictionary *)dict
 
79
{
 
80
    NSMutableArray *a = [[NSMutableArray alloc] init];
 
81
    NSEnumerator *enumerator = [dict keyEnumerator];
 
82
    id key;
 
83
    while((key = [enumerator nextObject])) {
 
84
        ResourceTreeItem *item = [[ResourceTreeItem alloc] initWithTitle:key];
 
85
        [a addObject:item];
 
86
        
 
87
        id value = [dict objectForKey:key];
 
88
        
 
89
        // its a dictionary itself
 
90
        if([value isKindOfClass:[NSDictionary class]]) {
 
91
            if(![item addFromDictionary:value])
 
92
                return FALSE;
 
93
        }
 
94
        // its a string
 
95
        else if([value isKindOfClass:[NSString class]]) {
 
96
            if(![item parseResourceString:(NSString *)value])
 
97
                return FALSE;
 
98
        }
 
99
        // unknown
 
100
        else {
 
101
            NSLog(@"Invalid Class in Dictionary: %@",[value class]);
 
102
            return FALSE;
 
103
        }
 
104
    }
 
105
    
 
106
    // sort array and keep
 
107
    children = [a sortedArrayUsingSelector:@selector(compare:)];
 
108
    [children retain];
 
109
    [a release];
 
110
    return TRUE;
 
111
}
 
112
 
 
113
-(BOOL)parseResourceString:(NSString *)string
 
114
{
 
115
    args = [string componentsSeparatedByString:@","];
 
116
    [args retain];
 
117
    numArgs = [args count];
 
118
    if(numArgs < 2) {
 
119
        NSLog(@"ERROR: resource string invalid: %@",string);
 
120
        return FALSE;
 
121
    }
 
122
    
 
123
    resource = (NSString *)[args objectAtIndex:0];
 
124
    [resource retain];
 
125
 
 
126
    NSString *typeStr = (NSString *)[args objectAtIndex:1];
 
127
    unichar ch = [typeStr characterAtIndex:0];
 
128
    switch(ch) {
 
129
    case 'i': // integer
 
130
        type = ResourceTreeItemTypeInteger;
 
131
        hint = ResourceTreeItemHintNone;
 
132
        break;
 
133
    case 'b': // boolean
 
134
        type = ResourceTreeItemTypeInteger;
 
135
        hint = ResourceTreeItemHintBoolean;
 
136
        break;
 
137
    case 'e': // enum
 
138
        type = ResourceTreeItemTypeInteger;
 
139
        hint = ResourceTreeItemHintEnum;
 
140
        break;
 
141
    case 'E': // enum direct
 
142
        type = ResourceTreeItemTypeInteger;
 
143
        hint = ResourceTreeItemHintEnumDirect;
 
144
        break;
 
145
    case 'r': // range
 
146
        type = ResourceTreeItemTypeInteger;
 
147
        hint = ResourceTreeItemHintRange;
 
148
        break;
 
149
    case 's': // string
 
150
        type = ResourceTreeItemTypeString;
 
151
        hint = ResourceTreeItemHintNone;
 
152
        break;
 
153
    case 'm': // map string to integer
 
154
        type = ResourceTreeItemTypeInteger;
 
155
        hint = ResourceTreeItemHintMapInteger;
 
156
        break;
 
157
    case 'f': // file
 
158
        {
 
159
            unichar mode = [typeStr characterAtIndex:1];
 
160
            type = ResourceTreeItemTypeString;
 
161
            switch(mode) {
 
162
            case 'o':
 
163
                hint = ResourceTreeItemHintFileOpen;
 
164
                break;
 
165
            case 's':
 
166
                hint = ResourceTreeItemHintFileSave;
 
167
                break;
 
168
            case 'd':
 
169
                hint = ResourceTreeItemHintFileDir;
 
170
                break;
 
171
            default:
 
172
                NSLog(@"ERROR: Invalid file resource mode: %@",typeStr);
 
173
                return false;
 
174
            }
 
175
        }
 
176
        break;
 
177
    default:
 
178
        NSLog(@"ERROR: Invalid resource type: %@",typeStr);
 
179
        return FALSE;
 
180
    }
 
181
 
 
182
    return TRUE;
 
183
}
 
184
 
 
185
-(NSString *)title
 
186
{
 
187
    return title;
 
188
}
 
189
 
 
190
-(int)parseIntFromString:(NSString *)string
 
191
{
 
192
    int len = [string length];
 
193
    if(len==0)
 
194
        return 0;
 
195
 
 
196
    int value = 0;
 
197
    const char *str = [string cStringUsingEncoding:NSUTF8StringEncoding];
 
198
    if(*str=='$') {
 
199
        sscanf(str+1,"%x",&value);
 
200
    } else {
 
201
        sscanf(str,"%d",&value);
 
202
    }
 
203
    return value;
 
204
}
 
205
 
 
206
-(id)getValue:(id)ctl
 
207
{
 
208
    ResourceEditorController *controller = (ResourceEditorController *)ctl;
 
209
    if([self isLeaf]) {
 
210
        if(cacheValue == nil) {
 
211
            if(type == ResourceTreeItemTypeInteger) {
 
212
                int value = [controller getIntResource:resource];
 
213
//                NSLog(@"read integer: %@ %d",resource,value);
 
214
                
 
215
                // enum
 
216
                if(hint == ResourceTreeItemHintEnum) {
 
217
                    cacheValue = [[args objectAtIndex:value+2] retain];
 
218
                } 
 
219
                // direct enum
 
220
                else if(hint == ResourceTreeItemHintEnumDirect) {
 
221
                    int i;
 
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];
 
227
                            break;
 
228
                        }
 
229
                    }
 
230
                }
 
231
                // map string to ineger:   txt=value
 
232
                else if(hint == ResourceTreeItemHintMapInteger) {
 
233
                    int i;
 
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];
 
243
                                    break;
 
244
                                }
 
245
                            }
 
246
                        }
 
247
                    }
 
248
                }
 
249
                // integer
 
250
                else {
 
251
                    cacheValue = [[NSNumber alloc] initWithInt:value];
 
252
                }
 
253
            }
 
254
            else {
 
255
                NSString *value = [controller getStringResource:resource];
 
256
//                NSLog(@"read string: %@ %@",resource,value);
 
257
                cacheValue = [value retain];
 
258
            }
 
259
        }
 
260
        return cacheValue; 
 
261
    }
 
262
    else
 
263
        return @"";
 
264
}
 
265
 
 
266
-(void)setIntResourceToValue:(int)value withController:(id)ctl
 
267
{
 
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);
 
273
}
 
274
 
 
275
-(void)setStringResourceToValue:(NSString *)value withController:(id)ctl
 
276
{
 
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);    
 
282
}
 
283
 
 
284
-(void)setValue:(id)ctl toObject:(id)object
 
285
{
 
286
    NSString *string = (NSString *)object;
 
287
    if(type == ResourceTreeItemTypeInteger) {
 
288
        int value = 0;
 
289
        // enum resource
 
290
        if(hint==ResourceTreeItemHintEnum ||
 
291
           hint==ResourceTreeItemHintEnumDirect) {
 
292
            int i;
 
293
            for(i=2;i<numArgs;i++) {
 
294
                NSString *argVal = (NSString *)[args objectAtIndex:i];
 
295
                if([argVal isEqualToString:string]) {
 
296
                    if(hint==ResourceTreeItemHintEnum)
 
297
                        value = i-2;
 
298
                    else 
 
299
                        value = [self parseIntFromString:argVal];
 
300
                    break;
 
301
                }
 
302
            }
 
303
        }
 
304
        // map
 
305
        else if(hint==ResourceTreeItemHintMapInteger) {
 
306
            int i;
 
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];
 
316
                             break;
 
317
                         }
 
318
                     }
 
319
                 }
 
320
             }
 
321
        } 
 
322
        // range
 
323
        else if(hint==ResourceTreeItemHintRange) {
 
324
            if(numArgs==4) {
 
325
                int min = [[args objectAtIndex:2] intValue];
 
326
                int max = [[args objectAtIndex:3] intValue];
 
327
                if(value<min)
 
328
                    value = min;
 
329
                else if(value>max)
 
330
                    value = max;
 
331
            } else {
 
332
                NSLog(@"ERROR: range invalid: %@",args);
 
333
            }
 
334
        }
 
335
        // integer resource
 
336
        else {
 
337
            value = [string intValue];
 
338
        }
 
339
        [self setIntResourceToValue:value withController:ctl];
 
340
    } else {
 
341
        [self setStringResourceToValue:string withController:ctl];
 
342
    }
 
343
}
 
344
 
 
345
-(void)setValueExtra:(id)ctl
 
346
{
 
347
    ResourceEditorController *controller = (ResourceEditorController *)ctl;
 
348
    switch(hint) {
 
349
    case ResourceTreeItemHintFileOpen:
 
350
        {
 
351
            NSString *file = [controller pickOpenFileWithTitle:title types:nil];
 
352
            if(file!=nil)
 
353
                [self setStringResourceToValue:file withController:ctl];
 
354
            break;
 
355
        }
 
356
    case ResourceTreeItemHintFileSave:
 
357
        {
 
358
            NSString *file = [controller pickSaveFileWithTitle:title types:nil];
 
359
            if(file!=nil)
 
360
                [self setStringResourceToValue:file withController:ctl];
 
361
            break;
 
362
        }
 
363
    case ResourceTreeItemHintFileDir:
 
364
        {
 
365
            NSString *file = [controller pickDirectoryWithTitle:title];
 
366
            if(file!=nil)
 
367
                [self setStringResourceToValue:file withController:ctl];
 
368
            break;
 
369
        }
 
370
    }
 
371
}
 
372
 
 
373
-(NSCell *)dataCell:(NSCell *)colCell
 
374
{
 
375
    if([self isLeaf]) {
 
376
        if(dataCell!=nil)
 
377
            return dataCell;
 
378
            
 
379
        switch(hint) {
 
380
        // boolean cell
 
381
        case ResourceTreeItemHintBoolean:
 
382
            {
 
383
                NSButtonCell *bcell = [[NSButtonCell alloc] initTextCell:@""];
 
384
                [bcell setButtonType:NSSwitchButton];
 
385
                dataCell = bcell;
 
386
                break;
 
387
            }
 
388
        case ResourceTreeItemHintEnum:
 
389
        case ResourceTreeItemHintEnumDirect:
 
390
            {
 
391
                NSComboBoxCell *ccell = [[NSComboBoxCell alloc] initTextCell:@""];
 
392
                int i;
 
393
                [ccell setButtonBordered:FALSE];
 
394
                for(i=2;i<numArgs;i++) {
 
395
                    [ccell addItemWithObjectValue:[args objectAtIndex:i]];
 
396
                }
 
397
                dataCell = ccell;
 
398
                break;
 
399
            }
 
400
        case ResourceTreeItemHintMapInteger:
 
401
            {
 
402
                NSComboBoxCell *ccell = [[NSComboBoxCell alloc] initTextCell:@""];
 
403
                int i;
 
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];
 
412
                    }
 
413
                }
 
414
                dataCell = ccell;
 
415
                break;
 
416
            }
 
417
        default:
 
418
            return colCell;
 
419
        }
 
420
        // reuse default font
 
421
        [dataCell setFont:[colCell font]];
 
422
        return dataCell;
 
423
    }
 
424
    return colCell;
 
425
}
 
426
 
 
427
-(NSCell *)extraCell:(NSCell *)colCell
 
428
{
 
429
    if([self isLeaf]) {
 
430
        if(extraCell!=nil) {
 
431
            return extraCell;
 
432
        }
 
433
        
 
434
        switch(hint) {
 
435
        // file name cell
 
436
        case ResourceTreeItemHintFileOpen:
 
437
        case ResourceTreeItemHintFileSave:
 
438
        case ResourceTreeItemHintFileDir:
 
439
            {
 
440
                NSButtonCell *bcell = [[NSButtonCell alloc] initTextCell:@""];
 
441
                [bcell setButtonType:NSMomentaryLightButton];
 
442
                [bcell setTitle:@"..."];
 
443
                extraCell = bcell;                
 
444
                break;
 
445
            }
 
446
        default:
 
447
            return colCell;
 
448
        }
 
449
        [extraCell setFont:[colCell font]];
 
450
        return extraCell;
 
451
    }
 
452
    return colCell;
 
453
}
 
454
 
 
455
-(NSComparisonResult)compare:(ResourceTreeItem *)item
 
456
{
 
457
    return [title caseInsensitiveCompare:[item title]];
 
458
}
 
459
 
 
460
-(void)invalidateCache
 
461
{
 
462
    if([self isLeaf]) {
 
463
        [cacheValue release];
 
464
        cacheValue = nil;
 
465
    } else {
 
466
        int num = [children count];
 
467
        int i;
 
468
        for(i=0;i<num;i++) {
 
469
            [(ResourceTreeItem *)[children objectAtIndex:i] invalidateCache];
 
470
        }
 
471
    }
 
472
}
 
473
 
 
474
@end