From 63d734295bdb3a7bbbaf9d7ae480458140ea30e8 Mon Sep 17 00:00:00 2001 From: Allan Odgaard Date: Sun, 20 Jan 2013 10:54:07 +0100 Subject: [PATCH] Cache custom icon images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also fix it so that a file named ‘gen_html’ doesn’t get the HTML icon (as we no longer use path::rank for finding the best icon). --- Frameworks/OakAppKit/src/OakFileIconImage.mm | 42 +++++++++++++++----- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/Frameworks/OakAppKit/src/OakFileIconImage.mm b/Frameworks/OakAppKit/src/OakFileIconImage.mm index ee1da1ed..005c8b56 100644 --- a/Frameworks/OakAppKit/src/OakFileIconImage.mm +++ b/Frameworks/OakAppKit/src/OakFileIconImage.mm @@ -12,17 +12,41 @@ static NSImage* CustomIconForPath (NSString* path, struct stat const& buf) if(!S_ISREG(buf.st_mode) && !S_ISLNK(buf.st_mode)) return nil; - std::multimap ordering; - NSDictionary* bindings = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle bundleForClass:[OakFileIconImage class]] pathForResource:@"bindings" ofType:@"plist"]]; - for(NSString* key in bindings) - { - for(NSString* ext in bindings[key]) + static NSMutableDictionary* bindings = [NSMutableDictionary new]; + + static dispatch_once_t onceToken = 0; + dispatch_once(&onceToken, ^{ + NSDictionary* map = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle bundleForClass:[OakFileIconImage class]] pathForResource:@"bindings" ofType:@"plist"]]; + for(NSString* key in map) { - if(ssize_t rank = path::rank([path UTF8String], [ext UTF8String])) - ordering.insert(std::make_pair(rank, key)); + for(NSString* ext in map[key]) + bindings[ext] = key; + } + }); + + NSString* pathName = [[path lastPathComponent] lowercaseString]; + NSString* imageName = bindings[pathName]; + + NSRange range = [pathName rangeOfString:@"."]; + if(range.location != NSNotFound) + { + imageName = bindings[[pathName substringFromIndex:NSMaxRange(range)]]; + imageName = imageName ?: bindings[[pathName pathExtension]]; + } + + NSImage* res = nil; + if(imageName) + { + static NSMutableDictionary* images = [NSMutableDictionary new]; + @synchronized(images) { + if(!(res = images[imageName])) + { + if(res = [NSImage imageNamed:imageName inSameBundleAsClass:[OakFileIconImage class]]) + images[imageName] = res; + } } } - return ordering.empty() ? nil : [NSImage imageNamed:ordering.begin()->second inSameBundleAsClass:[OakFileIconImage class]]; + return res; } static NSImage* IconBadgeForPath (NSString* path, struct stat const& buf) @@ -186,4 +210,4 @@ static NSArray* ImageStackForPath (NSString* path) + (id)fileIconImageWithPath:(NSString*)aPath isModified:(BOOL)flag size:(NSSize)aSize { return [[[self alloc] initWithWithPath:aPath isModified:flag size:aSize] autorelease]; } + (id)fileIconImageWithPath:(NSString*)aPath isModified:(BOOL)flag { return [self fileIconImageWithPath:aPath isModified:flag size:NSMakeSize(16, 16)]; } + (id)fileIconImageWithPath:(NSString*)aPath size:(NSSize)aSize { return [self fileIconImageWithPath:aPath isModified:NO size:aSize]; } -@end \ No newline at end of file +@end