// // CSTheme.m // XSchemeEncoder // // Created by Colin Cornaby on Mon Jan 27 2003. // Copyright (c) 2003 Conundrum Software. All rights reserved. // #import "CSTheme.h" @implementation CSTheme +(id)theme{ return [[[[self class] alloc] init] autorelease]; } +(id)themeWithDLTAFromFile:(NSString *)thePath theTags:(NSArray *)tags{ return [[[[self class] alloc] initWithDLTAFromFile:thePath theTags:tags] autorelease]; } +(id)themeWithThemeFromFile:(NSString *)thePath{ return [[[[self class] alloc] initWithContentsOfFile:thePath] autorelease]; } +(id)themeWithXMLBundle:(NSString *)thePath forLanguage:(NSString *)theLanguage{ return [[[[self class] alloc] initWithXMLBundle:thePath forLanguage:theLanguage] autorelease]; } -(id)initWithNewAquaTheme{ //fill the dictionary with a fresh empty one theFiles = [[NSMutableDictionary alloc] init]; theUncompressedFiles = [[NSMutableDictionary alloc] init]; theThemeNames = [[NSMutableDictionary alloc] init]; theLinkedFiles = [[NSMutableDictionary alloc] init]; runOptimized = NO; //set ourself to be an Aqua backup theCurrentType = CSBackupStyleTheme; [self CSNicelySetupTheme]; return self; } -(void)dealloc{ [theUncompressedFiles release]; [theFiles release]; [theLinkedFiles release]; [theThemeNames release]; [super dealloc]; } -(id)init{ runOptimized = NO; //fill the dictionary with a fresh empty one theUncompressedFiles = [[NSMutableDictionary alloc] init]; theFiles = [[NSMutableDictionary alloc] init]; theLinkedFiles = [[NSMutableDictionary alloc] init]; theThemeNames = [[NSMutableDictionary alloc] init]; //set ourself to be an normal theme theCurrentType = CSDeploymentStyleTheme; [self CSNicelySetupTheme]; return self; } -(NSString *)theName{ return theCollectionName; } -(void)setName:(NSString *)theName{ theCollectionName = theName; } -(id)initWithContentsOfFile:(NSString *)thePath{ int i,j; runOptimized = NO; NSDictionary *themeContents = [[NSDictionary alloc] initWithContentsOfFile:thePath]; NSDictionary *variationFiles; if([themeContents objectForKey:@"name"]!=nil){ theCollectionName = [[themeContents objectForKey:@"name"] retain]; }else{ theCollectionName = [[thePath lastPathComponent] retain]; } theFiles = [[NSMutableDictionary alloc] initWithDictionary:[themeContents objectForKey:@"files"]]; theLinkedFiles = [[NSMutableDictionary alloc] init]; theUncompressedFiles = [[NSMutableDictionary alloc] init]; theThemeNames = [[NSMutableDictionary alloc] initWithDictionary:[themeContents objectForKey:@"variations"]]; theCurrentType = [[themeContents objectForKey:@"themeContents"] intValue]; for(i=0; i<[theThemeNames count]; i++){ variationFiles = [[theThemeNames objectForKey:[[theThemeNames allKeys] objectAtIndex:i]] objectForKey:@"links"]; for(j=0; j<[variationFiles count]; j++){ [[[theThemeNames objectForKey:[[theThemeNames allKeys] objectAtIndex:i]] objectForKey:@"links"] setObject:[[variationFiles objectForKey:[[variationFiles allKeys] objectAtIndex:j]] stringByResolvingSymlinksInPath] forKey:[[variationFiles allKeys] objectAtIndex:j]]; } } [themeContents release]; return self; } + (id)getFirstDLTAArgument:(id)line{ char * str; char * pch; NSString *temp; NSString *linevar; str=calloc(1024,1); linevar = line; [linevar getCString:str]; pch=strstr(str," -"); temp = [line substringWithRange:NSMakeRange(pch-str+2, [linevar length]-(pch-str+2))]; [temp getCString:str]; pch=strstr(str," -"); temp = [temp substringWithRange:NSMakeRange(0, (pch-str))]; free(str); return temp; } + (id)getSecondDLTAArgument:(id)line{ char * str; char * pch; NSString *temp; NSString *linevar; str=calloc(1024,1); linevar = line; [linevar getCString:str]; pch=strstr(str," -"); temp = [line substringWithRange:NSMakeRange(pch-str+2, [linevar length]-(pch-str+2))]; [temp getCString:str]; pch=strstr(str," -"); temp = [temp substringWithRange:NSMakeRange(pch-str+2, [temp length]-(pch-str+2))]; free(str); return temp; } + (id)getDynamicLink:(id)link{ NSString *linkvar; linkvar = link; if([[link substringWithRange:NSMakeRange(0,9)] isEqualToString:@"@carbonhr"]==YES){ linkvar =[NSString stringWithFormat:@"/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HiToolbox.framework/Versions/A/Resources/%@", [linkvar substringWithRange:NSMakeRange(10,[linkvar length]-10)]]; } if([[link substringWithRange:NSMakeRange(0,4)] isEqualToString:@"@sys"]==YES){ linkvar =[NSString stringWithFormat:@"/System/Library/%@", [linkvar substringWithRange:NSMakeRange(4,[linkvar length]-4)]]; } if([[link substringWithRange:NSMakeRange(0,10)] isEqualToString:@"@coreserve"]==YES){ linkvar =[NSString stringWithFormat:@"/System/Library/CoreServices/%@", [linkvar substringWithRange:NSMakeRange(10,[linkvar length]-10)]]; } if([[link substringWithRange:NSMakeRange(0,5)] isEqualToString:@"@dock"]==YES){ linkvar =[NSString stringWithFormat:@"/System/Library/CoreServices/Dock.app/Contents/%@", [linkvar substringWithRange:NSMakeRange(5,[linkvar length]-5)]]; } if([[link substringWithRange:NSMakeRange(0,9)] isEqualToString:@"@loginwin"]==YES){ linkvar =[NSString stringWithFormat:@"/System/Library/CoreServices/loginwindow.app/Resources/%@", [linkvar substringWithRange:NSMakeRange(9,[linkvar length]-9)]]; } return linkvar; } -(id)initWithDLTAFromFile:(NSString *)thePath theTags:(NSArray *)tags{ runOptimized = NO; int i; int j; BOOL exe; NSString *themescode; NSString *currline; NSString *currtag = @""; NSString *name = @""; NSString *descrip = @""; NSString *preview = @""; NSString *temp; NSMutableDictionary *filesToAdd = [[NSMutableDictionary alloc] init]; theLinkedFiles = [[NSMutableDictionary alloc] init]; int currIndex; //NSLog(thePath); theFiles = [[NSMutableDictionary alloc] init]; theUncompressedFiles = [[NSMutableDictionary alloc] init]; theLinkedFiles = [[NSMutableDictionary alloc] init]; theThemeNames = [[NSMutableDictionary alloc] init]; theCurrentType = CSDeploymentStyleTheme; [self CSNicelySetupTheme]; theCollectionName = [thePath lastPathComponent]; currIndex = 0; themescode = [NSString stringWithContentsOfFile:[NSString stringWithFormat:@"%@/Main.themescript", thePath]]; exe = YES; int x = [CSTextReader linetotal:themescode]; for(i=0; i=10){ if([[currline substringWithRange:NSMakeRange(0,9)] isEqualToString:@"thename ="]){ name = [currline substringWithRange:NSMakeRange(10,[currline length]-10)]; } } if([currline length]>=13){ if([[currline substringWithRange:NSMakeRange(0,12)] isEqualToString:@"thedescrip ="]){ descrip = [currline substringWithRange:NSMakeRange(13,[currline length]-13)]; } } if([currline length]>=9){ if([[currline substringWithRange:NSMakeRange(0,9)] isEqualToString:@"preview ="]){ preview = [currline substringWithRange:NSMakeRange(10,[currline length]-10)]; } } if([currline length]>=3){ if([[currline substringWithRange:NSMakeRange(0,3)] isEqualToString:@"%sf"]==YES){ [filesToAdd setObject:[CSTheme getDynamicLink:[CSTheme getSecondDLTAArgument:currline]] forKey:[CSTheme getFirstDLTAArgument:currline]]; } } } } if([name isEqualToString:@""]==NO) [self addVariationWithName:name]; if([preview isEqualToString:@""]==NO) [self addPreviewFromFile:[NSString stringWithFormat:@"%@/%@", thePath, preview] forVariation:name]; if([descrip isEqualToString:@""]==NO) [self setVariationDescriptionWithString:descrip forVariation:name]; for(i=0; i<[[filesToAdd allValues] count]; i++){ [self addFileFromFile:[NSString stringWithFormat:@"%@/%@", thePath, [[filesToAdd allKeys] objectAtIndex:i] ] fileName:[[filesToAdd allKeys] objectAtIndex:i]]; if([[[filesToAdd allValues] objectAtIndex:i] hasSuffix:@"/"]){ [self addLinkForVariation:name forFile:[[filesToAdd allKeys] objectAtIndex:i] forDestination:[NSString stringWithFormat:@"%@/%@", [[filesToAdd allValues] objectAtIndex:i], [[[filesToAdd allKeys] objectAtIndex:i] lastPathComponent]]]; }else{ [self addLinkForVariation:name forFile:[[filesToAdd allKeys] objectAtIndex:i] forDestination:[[filesToAdd allValues] objectAtIndex:i]]; } } [filesToAdd release]; [self compressFiles]; [theCollectionName retain]; return self; } - (id)CSGetMMXPath:(id)line{ char * str; char * pch; NSString *temp; NSString *linevar; str=calloc(1024,1); linevar = line; [linevar getCString:str]; pch=strstr(str,".theme/"); temp = [line substringWithRange:NSMakeRange(pch-str+7, [linevar length]-(pch-str+7))]; free(str); return temp; } -(id)initWithXMLBundle:(NSString *)thePath forLanguage:(NSString *)theLanguage{ runOptimized = YES; NSDictionary *plistReader; NSString *themeName = @""; int i; //NSLog(thePath); plistReader = [[NSDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/Info.plist", thePath]]; theFiles = [[NSMutableDictionary alloc] init]; theUncompressedFiles = [[NSMutableDictionary alloc] init]; theLinkedFiles = [[NSMutableDictionary alloc] init]; theThemeNames = [[NSMutableDictionary alloc] init]; theCurrentType = CSDeploymentStyleTheme; [self CSNicelySetupTheme]; theCollectionName = [thePath lastPathComponent]; if([plistReader objectForKey:@"name"] != nil){ //[self addVariationWithName:[plistReader objectForKey:@"name"]]; if([[plistReader objectForKey:@"name"] objectForKey:theLanguage] != nil){ [self addVariationWithName:[[plistReader objectForKey:@"name"] objectForKey:theLanguage]]; if([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/preview/%@.tiff", thePath, theLanguage]]){ [self addPreviewFromFile:[NSString stringWithFormat:@"%@/preview/%@.tiff", thePath, theLanguage] forVariation:[[plistReader objectForKey:@"name"] objectForKey:theLanguage]]; } [self setVariationDescriptionWithString:[[plistReader objectForKey:@"description"] objectForKey:theLanguage] forVariation:[[plistReader objectForKey:@"name"] objectForKey:theLanguage]]; [self setOSTag:[plistReader objectForKey:@"os"] forVariation:[[plistReader objectForKey:@"name"] objectForKey:theLanguage]]; themeName = [[plistReader objectForKey:@"name"] objectForKey:theLanguage]; } } for(i=0; i<[[plistReader objectForKey:@"objects"] count]; i++){ //NSLog([NSString stringWithFormat:@"%@/%@", thePath, [self CSGetMMXPath:[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"]]]); [self addFileFromFile:[NSString stringWithFormat:@"%@/%@", thePath, [self CSGetMMXPath:[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"]]] fileName:[[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"] lastPathComponent]]; //NSLog([[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"] rangeOfString:@".theme" if([[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"prospectivePath"] hasSuffix:@"/"]){ [self addLinkForVariation:themeName forFile:[[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"] lastPathComponent] forDestination:[NSString stringWithFormat:@"%@/%@", [[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"prospectivePath"], [[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"] lastPathComponent]]]; }else{ [self addLinkForVariation:themeName forFile:[[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"] lastPathComponent] forDestination:[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"prospectivePath"]]; } } [plistReader release]; [self compressFiles]; [theCollectionName retain]; return self; } -(int)currentThemeType; { return theCurrentType; } -(void)addVariationWithName:(NSString *)theName{ [theThemeNames setObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"", @"themestep", [NSMutableDictionary dictionary], [NSData data], nil] forKeys:[NSArray arrayWithObjects:@"description", @"legacyOSTag", @"links", @"preview", nil]] forKey:theName]; } -(void)addPreviewFromFile:(NSString *)thePath forVariation:(NSString *)theVariationName{ [[theThemeNames objectForKey:theVariationName] setObject:[RAZipper compressedDataForData:[NSData dataWithContentsOfFile:thePath]] forKey:@"preview"]; } -(void)addPreviewFromData:(NSData *)theData forVariation:(NSString *)theVariationName{ [[theThemeNames objectForKey:theVariationName] setObject:[RAZipper compressedDataForData:theData] forKey:@"preview"]; } -(NSDictionary *)dictionaryForVariation:(NSString *)theVariationName{ return [theThemeNames objectForKey:theVariationName]; } -(void)removeVariationWithName:(NSString *)theName{ [theThemeNames removeObjectForKey:theName]; } -(void)removeFileWithName:(NSString *)theName{ [self compressFiles]; [theFiles removeObjectForKey:theName]; } -(void)setVariationDescriptionWithString:(NSString *)theDescription forVariation:(NSString *)theVariationName{ [[theThemeNames objectForKey:theVariationName] setObject:theDescription forKey:@"description"]; } -(NSString *)descriptionForVariation:(NSString *)theVariationName{ return [[theThemeNames objectForKey:theVariationName] objectForKey:@"description"]; } -(NSData *)previewForVariation:(NSString *)theVariationName{ if([(NSData *)[[theThemeNames objectForKey:theVariationName] objectForKey:@"preview"] length]>0){ return [RAZipper dataForCompressedData:[[theThemeNames objectForKey:theVariationName] objectForKey:@"preview"]]; }else{ return nil; } } -(void)addLinkForVariation:(NSString *)theVariationName forFile:(NSString *)fileName forDestination:(NSString *)theDestination{ [[[theThemeNames objectForKey:theVariationName] objectForKey:@"links"] setObject:fileName forKey:[theDestination stringByResolvingSymlinksInPath]]; } -(NSArray *)allDestinationsForVariation:(NSString *)theVariationName{ return [[[theThemeNames objectForKey:theVariationName] objectForKey:@"links"] allKeys]; } -(NSArray *)allFilesForVariation:(NSString *)theVariationName{ return [[[theThemeNames objectForKey:theVariationName] objectForKey:@"links"] allValues]; } -(void)removeLinkForVariation:(NSString *)theVariationName forDestination:(NSString *)theDestination{ [[[theThemeNames objectForKey:theVariationName] objectForKey:@"links"] removeObjectForKey:theDestination]; } -(void)CSNicelySetupTheme{ theCollectionName = @"New Theme"; theFiles = [[NSMutableDictionary alloc] init]; } -(void)addFileFromFile:(NSString *)theLocation fileName:(NSString *)theName{ BOOL isDir; //if([self currentThemeType] != CSBackupStyleTheme){ if([[NSFileManager defaultManager] fileExistsAtPath:theLocation]){ if([[NSFileManager defaultManager] fileExistsAtPath:theLocation isDirectory:&isDir] && isDir==NO){ if(runOptimized == YES){ [theLinkedFiles setObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:theLocation, [NSMutableData data], nil] forKeys:[NSArray arrayWithObjects:@"link", @"hash", nil]] forKey:theName]; }else{ [theUncompressedFiles setObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[NSData dataWithContentsOfFile:theLocation], [NSMutableData data], nil] forKeys:[NSArray arrayWithObjects:@"data", @"hash", nil]] forKey:theName]; } }else{ NSLog(@"addFileFromFile: File %@ is a directory, not added", theLocation); } }else{ NSLog(@"addFileFromFile: File %@ does not exist", theLocation); } //}else{ //NSLog(@"CSBackupThemes must use hashes when adding files, file not added"); //} } -(void)addFileFromData:(NSData *)theData fileName:(NSString *)theName{ [theUncompressedFiles setObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:theData, [NSMutableData data], nil] forKeys:[NSArray arrayWithObjects:@"data", @"hash", nil]] forKey:theName]; } - (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag{ [self writeAsThemeToPath:path atomically:flag]; return YES; } -(void)writeAsThemeToPath:(NSString *)thePath atomically:(BOOL)atomYN{ NSMutableDictionary *finalDict = [[NSMutableDictionary alloc] init]; [self compressFiles]; [finalDict setObject:theFiles forKey:@"files"]; [finalDict setObject:theCollectionName forKey:@"name"]; [finalDict setObject:theThemeNames forKey:@"variations"]; [finalDict setObject:[NSNumber numberWithInt:theCurrentType] forKey:@"themeContents"]; if([finalDict writeToFile:thePath atomically:atomYN]){ }else{ NSLog(@"There was a problem saving the theme"); } [finalDict release]; } -(NSData *)dataForFile:(NSString *)theName{ id returnValue; if([[theFiles allKeys] containsObject:theName]){ returnValue = [RAZipper dataForCompressedData:[[theFiles objectForKey:theName] objectForKey:@"data"]]; } else if([[theUncompressedFiles allKeys] containsObject:theName]){ returnValue = [[theUncompressedFiles objectForKey:theName] objectForKey:@"data"]; } else if([[theLinkedFiles allKeys] containsObject:theName]){ returnValue = [NSData dataWithContentsOfFile:[[theLinkedFiles objectForKey:theName] objectForKey:@"link"]]; } else { NSLog(@"dataForFile: File %@ was not found within CSTheme", theName); returnValue= nil; } return returnValue; } -(void)changeNameOfVariation:(NSString *)variationName toName:(NSString*)newName{ [theThemeNames setObject:[theThemeNames objectForKey:variationName] forKey:newName]; if([variationName isEqualToString:newName]==NO){ [theThemeNames removeObjectForKey:variationName]; } } -(NSArray *)variations{ return [theThemeNames allKeys]; } -(void)addFileFromFile:(NSString *)thePath fileName:(NSString *)theName withHashForFile:(NSString *)hashFile{ if([[NSFileManager defaultManager] fileExistsAtPath:hashFile]){ [self addFileFromFile:thePath fileName:theName]; [self setHashForThemeFile:theName forFile:hashFile]; } } -(void)addFileFromFile:(NSString *)thePath fileName:(NSString *)theName withHashForData:(NSData *)hashFile{ [self addFileFromFile:thePath fileName:theName]; [self setHashForThemeFile:theName forData:hashFile]; } -(void)setHashForThemeFile:(NSString *)theThemeFile forFile:(NSString *)thePath{ [self compressFiles]; [[theFiles objectForKey:theThemeFile] setObject:[CSCheckSum hashForFile:thePath] forKey:@"hash"]; } -(BOOL)fileHasHash:(NSString *)theThemeFile{ BOOL returnValue; [self compressFiles]; //NSLog([[[theFiles objectForKey:theThemeFile] objectForKey:@"hash"] description]); if([[[theFiles objectForKey:theThemeFile] objectForKey:@"hash"] isEqualToData:[NSData data]]){ returnValue = NO; }else{ returnValue = YES; } return returnValue; } -(void)setHashForThemeFile:(NSString *)theThemeFile forData:(NSData *)thePath{ [self compressFiles]; [[theFiles objectForKey:theThemeFile] setObject:[CSCheckSum hashForData:thePath] forKey:@"hash"]; } -(BOOL)compareHashForThemeFile:(NSString *)theThemeFile forFile:(NSString *)thePath{ BOOL returnValue; [self compressFiles]; //NSLog(@"External hash: %@", [[CSCheckSum hashForFile:thePath] description]); //NSLog(@"Submitted hash: %@", [[[theFiles objectForKey:theThemeFile] objectForKey:@"hash"] description]); if([[CSCheckSum hashForFile:thePath] isEqualToData:[[theFiles objectForKey:theThemeFile] objectForKey:@"hash"]]){ returnValue = YES; }else{ returnValue = NO; } return returnValue; } -(void)compressFiles{ int i; [self compressLinkedFiles]; for(i=0; i<[theUncompressedFiles count]; i++){ [theFiles setObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[RAZipper compressedDataForData:[[[theUncompressedFiles allValues] objectAtIndex:i] objectForKey:@"data"]], [[[theUncompressedFiles allValues] objectAtIndex:i] objectForKey:@"hash"], nil] forKeys:[NSArray arrayWithObjects:@"data", @"hash", nil]] forKey:[[theUncompressedFiles allKeys] objectAtIndex:i]]; } [theUncompressedFiles removeAllObjects]; } -(void)compressLinkedFiles{ int i; for(i=0; i<[theLinkedFiles count]; i++){ [theUncompressedFiles setObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[NSData dataWithContentsOfFile:[[[theLinkedFiles allValues] objectAtIndex:i] objectForKey:@"link"]], [[[theLinkedFiles allValues] objectAtIndex:i] objectForKey:@"hash"], nil] forKeys:[NSArray arrayWithObjects:@"data", @"hash", nil]] forKey:[[theLinkedFiles allKeys] objectAtIndex:i]]; } [theLinkedFiles removeAllObjects]; } -(void)setOSTag:(NSString *)theTag forVariation:(NSString *)theVariation{ [[theThemeNames objectForKey:theVariation] setObject:theTag forKey:@"legacyOSTag"]; } -(NSString *)getOSTagForVariation:(NSString *)theVariation{ return [[theThemeNames objectForKey:theVariation] objectForKey:@"legacyOSTag"]; } -(void)runOptimized:(BOOL)ryn{ runOptimized = ryn; } -(NSArray *)files{ return [theFiles allKeys]; } - (void)encodeWithCoder:(NSCoder *)coder { //[super encodeWithCoder:coder]; [coder encodeObject:theFiles forKey:@"files"]; [coder encodeObject:theCollectionName forKey:@"name"]; [coder encodeObject:theThemeNames forKey:@"variations"]; [coder encodeObject:[NSNumber numberWithInt:theCurrentType] forKey:@"themeContents"]; } - (id)initWithCoder:(NSCoder *)coder { int i,j; //self = [super initWithCoder:coder]; NSDictionary *variationFiles; if([coder decodeObjectForKey:@"name"]!=nil){ theCollectionName = [[coder decodeObjectForKey:@"name"] retain]; }else{ theCollectionName = @"Unknown Name"; } theFiles = [[[NSMutableDictionary alloc] initWithDictionary:[coder decodeObjectForKey:@"files"]] retain]; theLinkedFiles = [[[NSMutableDictionary alloc] init] retain]; theUncompressedFiles = [[[NSMutableDictionary alloc] init] retain]; theThemeNames = [[[NSMutableDictionary alloc] initWithDictionary:[coder decodeObjectForKey:@"variations"]] retain]; theCurrentType = [[coder decodeObjectForKey:@"themeContents"] intValue]; for(i=0; i<[theThemeNames count]; i++){ variationFiles = [[theThemeNames objectForKey:[[theThemeNames allKeys] objectAtIndex:i]] objectForKey:@"links"]; for(j=0; j<[variationFiles count]; j++){ [[[theThemeNames objectForKey:[[theThemeNames allKeys] objectAtIndex:i]] objectForKey:@"links"] setObject:[[variationFiles objectForKey:[[variationFiles allKeys] objectAtIndex:j]] stringByResolvingSymlinksInPath] forKey:[[variationFiles allKeys] objectAtIndex:j]]; } } return self; } @end