Changeset 319 for trunk/ICeCoffEE/ICeCoffEE/ICeCoffEESetServicesMenu.m
- Timestamp:
- 06/11/07 01:21:55 (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ICeCoffEE/ICeCoffEE/ICeCoffEESetServicesMenu.m
r182 r319 8 8 9 9 #import "ICeCoffEESetServicesMenu.h" 10 #import "ICeCoffEEShared.h" 11 12 // XXX rename me to something like "ICeCoffEEServicesMenu.m" 13 14 // an approximate clone of HIToolbox's CreateServicesLocalizedDictKey 15 static CFStringRef preferredLocalization(CFDictionaryRef localizations) { 16 if (localizations == NULL) 17 return NULL; 18 19 CFIndex localizationCount = CFDictionaryGetCount(localizations); 20 if (localizationCount == 0) 21 return NULL; 22 23 const void **locales = malloc(localizationCount * sizeof(void *)); 24 if (locales == NULL) 25 return NULL; 26 27 CFDictionaryGetKeysAndValues(localizations, locales, NULL); 28 CFArrayRef availableLocales = CFArrayCreate(NULL, locales, localizationCount, NULL); 29 if (availableLocales == NULL) 30 return NULL; 31 32 // XXX does this actually work in a localized app? 33 CFArrayRef preferredLocales = CFBundleCopyPreferredLocalizationsFromArray(availableLocales); 34 // NSLog(@"%@ => %@", availableLocales, preferredLocales); 35 CFRelease(availableLocales); 36 CFStringRef preferredLocalization; 37 if (preferredLocales != NULL) { 38 if (CFArrayGetCount(preferredLocales) > 0) { 39 CFStringRef preferredLocale = CFArrayGetValueAtIndex(preferredLocales, 0); 40 preferredLocalization = (CFStringRef)CFDictionaryGetValue(localizations, preferredLocale); 41 } 42 CFRelease(preferredLocales); 43 } 44 if (preferredLocalization == NULL) { 45 preferredLocalization = (CFStringRef)CFDictionaryGetValue(localizations, CFSTR("default")); 46 if (preferredLocalization == NULL) 47 preferredLocalization = (CFStringRef)CFDictionaryGetValue(localizations, (CFStringRef)locales[0]); 48 } 49 50 free(locales); 51 // NSLog(@"%@", preferredLocalization); 52 return preferredLocalization; 53 } 54 55 NSArray *CFServiceControllerCopyServicesEntries(void); 56 57 NSDictionary *ICCF_GetServicesInfo(void) { 58 NSArray *services = CFServiceControllerCopyServicesEntries(); 59 // NSLog(@"%@", services); 60 61 NSEnumerator *e = [services objectEnumerator]; 62 NSDictionary *serviceEntry; 63 NSMutableDictionary *serviceDict = [[NSMutableDictionary alloc] init]; 64 while ( (serviceEntry = (NSDictionary *)[e nextObject]) != nil) { 65 // XXX once tested, redo all this with CF, and no autoreleasing 66 // XXX items named the same as submenus (figure out how Cocoa itself does it, too) 67 // XXX use kICServiceSubmenu (recursion?) 68 NSString *itemPath = (NSString *)preferredLocalization((CFDictionaryRef)[serviceEntry objectForKey: @"NSMenuItem"]); 69 if (itemPath == nil) continue; 70 71 NSString *bundlePath = [serviceEntry objectForKey: @"NSBundlePath"]; 72 BOOL bubbledUp = (bundlePath == nil); 73 NSArray *itemComponents = [itemPath componentsSeparatedByString: @"/"]; 74 NSEnumerator *ce = [itemComponents objectEnumerator]; 75 NSString *itemComponent; 76 NSMutableDictionary *levelDict = serviceDict; 77 NSMutableDictionary *itemDict = nil; 78 while ( (itemComponent = (NSString *)[ce nextObject]) != nil) { 79 // itemDict is nil if just created 80 if (itemDict != nil && !bubbledUp) { 81 NSString *oldBundlePath = [levelDict objectForKey: (NSString *)kICServiceBundlePath]; 82 if ([oldBundlePath isEqualToString: bundlePath]) 83 bubbledUp = YES; 84 else if (oldBundlePath != nil) { 85 [oldBundlePath retain]; 86 [levelDict removeObjectForKey: (NSString *)kICServiceBundlePath]; 87 NSEnumerator *be = [levelDict objectEnumerator]; 88 while ( (itemDict = (NSMutableDictionary *)[be nextObject]) != nil) 89 [itemDict setObject: oldBundlePath forKey: (NSString *)kICServiceBundlePath]; 90 [oldBundlePath release]; 91 } 92 } 93 itemDict = [levelDict objectForKey: itemComponent]; 94 if (itemDict == nil) { 95 itemDict = [[NSMutableDictionary alloc] init]; 96 if (!bubbledUp) { 97 [itemDict setObject: bundlePath forKey: (NSString *)kICServiceBundlePath]; 98 bubbledUp = YES; 99 } 100 [levelDict setObject: itemDict forKey: itemComponent]; 101 levelDict = itemDict; 102 [itemDict release]; 103 itemDict = nil; 104 } else { 105 levelDict = itemDict; 106 } 107 } 108 109 if (!bubbledUp) 110 [levelDict setObject: bundlePath forKey: (NSString *)kICServiceBundlePath]; 111 112 NSString *keyEquivalent = (NSString *)preferredLocalization((CFDictionaryRef)[serviceEntry objectForKey: @"NSKeyEquivalent"]); 113 if (keyEquivalent == nil) continue; 114 115 [levelDict setObject: keyEquivalent forKey: (NSString *)kICServiceShortcut]; 116 } 117 [services release]; 118 119 return [serviceDict autorelease]; 120 } 10 121 11 122 … … 31 142 } 32 143 } 144 145 IconRef ICCF_CopyIconRefForPath(NSString *path) { 146 IconRef icon; 147 FSRef fsr; 148 SInt16 label; 149 OSStatus err = noErr; 150 151 err = FSPathMakeRef((const UInt8 *)[path fileSystemRepresentation], &fsr, NULL); 152 if (err != noErr) return NULL; 153 154 err = GetIconRefFromFileInfo(&fsr, 0, NULL, kFSCatInfoNone, NULL, kIconServicesNormalUsageFlag, &icon, &label); 155 if (err != noErr) return NULL; 156 157 return icon; 158 }
Note:
See TracChangeset
for help on using the changeset viewer.