Index: trunk/ICeCoffEE/ICeCoffEE/ICeCoffEEKeyEquivalents.m
===================================================================
--- trunk/ICeCoffEE/ICeCoffEE/ICeCoffEEKeyEquivalents.m	(revision 430)
+++ trunk/ICeCoffEE/ICeCoffEE/ICeCoffEEKeyEquivalents.m	(revision 431)
@@ -140,2 +140,20 @@
     return keyEquivalentAttributedString;
 }
+
+// converts NSUserKeyEquivalents prefixes into modifier flags
+NSAttributedString *ICCF_KeyEquivalentAttributedString(NSString *self, unsigned count) {
+    unsigned modifierFlags = 0;
+    int i;
+    for (i = 0 ; i < [self length] - 1; i++) {
+	switch ([self characterAtIndex: i]) {
+	    case '@': modifierFlags |= NSCommandKeyMask; break;
+	    case '~': modifierFlags |= NSAlternateKeyMask; break;
+	    case '^': modifierFlags |= NSControlKeyMask; break;
+	    case '$': modifierFlags |= NSShiftKeyMask; break;
+	    default:
+		return nil;
+	}
+    }
+    return ICCF_KeyEquivalentAttributedStringWithModifierFlags([self substringFromIndex: i], modifierFlags, count);
+}
+
Index: trunk/ICeCoffEE/ICeCoffEE/ICeCoffEEServicePrefController.m
===================================================================
--- trunk/ICeCoffEE/ICeCoffEE/ICeCoffEEServicePrefController.m	(revision 430)
+++ trunk/ICeCoffEE/ICeCoffEE/ICeCoffEEServicePrefController.m	(revision 431)
@@ -29,4 +29,5 @@
 
 static NSMutableDictionary *keyEquivalents;
+static NSDictionary *userKeyEquivalents;
 
 static void ICCF_RemoveSingleKeyEquivalents() {
@@ -75,4 +76,5 @@
 
 static inline void ICCF_UpdateKeyEquivalentForItem(NSMenuItem *item, int state) {
+    return; // XXX disabled until we can affect menubar Services menu(s)
     int oldState = ICCF_GetServiceState(item);
     if ((oldState == ICCF_SERVICE_UNKNOWN || oldState == ICCF_SERVICE_SHOWN) && state == ICCF_SERVICE_HIDDEN)
@@ -204,4 +206,16 @@
 	} else {
 	    NSString *keyEquivalent = (NSString *)[itemInfo objectForKey: (NSString *)kICServiceShortcut];
+	    if (keyEquivalent == nil) {
+		keyEquivalent = [userKeyEquivalents objectForKey: [menuItem title]];
+	    } else if ([keyEquivalent length] != 1) {
+		keyEquivalent = nil;
+	    } else {
+		// XXX Inconsistency between Cocoa and Carbon: always command-shift in Carbon, not in Cocoa.  Since we only patch Cocoa for the moment, keep as is.
+		unichar key = [keyEquivalent characterAtIndex: 0];
+		if ([[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember: key])
+		    keyEquivalent = [NSString stringWithFormat: @"$@%c", key];
+		else
+		    keyEquivalent = [NSString stringWithFormat: @"@%c", key];
+	    }
 	    if (keyEquivalent != nil) {
 		[menuItem setToolTip: keyEquivalent];
@@ -274,10 +288,11 @@
 - (void)dealloc;
 {
-    [keyEquivalents release];
-    [servicesMenu release];
-    [closedTriangle release];
-    [selectedClosedTriangle release];
-    [openTriangle release];
-    [selectedOpenTriangle release];
+    [keyEquivalents release]; keyEquivalents = nil;
+    [userKeyEquivalents release]; userKeyEquivalents = nil;
+    [servicesMenu release]; servicesMenu = nil;
+    [closedTriangle release]; closedTriangle = nil;
+    [selectedClosedTriangle release]; selectedClosedTriangle = nil;
+    [openTriangle release]; openTriangle = nil;
+    [selectedOpenTriangle release]; selectedOpenTriangle = nil;
     [super dealloc];
 }
@@ -336,4 +351,5 @@
     if (servicesMenu == nil) {
 	keyEquivalents = [[NSMutableDictionary alloc] init];
+	userKeyEquivalents = [[[NSUserDefaults standardUserDefaults] dictionaryForKey: @"NSUserKeyEquivalents"] retain];
 	servicesMenu = [[NSMenu alloc] initWithTitle: @""];
 	ICCF_SetServicesMenu(servicesMenu);
@@ -359,5 +375,5 @@
 }
 
-NSAttributedString *ICCF_KeyEquivalentAttributedStringWithModifierFlags(NSString *self, unsigned int modifierFlags, unsigned count);
+NSAttributedString *ICCF_KeyEquivalentAttributedString(NSString *self, unsigned count);
 
 - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item;
@@ -380,7 +396,7 @@
     } else if ([[tableColumn identifier] isEqualToString: @"key"]) {
         NSString *equivalent = [item toolTip];
-        if (equivalent == nil || [equivalent length] != 1) return nil;
-        // XXX Inconsistency between Cocoa and Carbon: always command-shift in Carbon, not in Cocoa.  Since we only patch Cocoa for the moment, keep as is.
-        return ICCF_KeyEquivalentAttributedStringWithModifierFlags(equivalent, [item keyEquivalentModifierMask] | ([[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember: [equivalent characterAtIndex: 0]] ? NSShiftKeyMask : 0), ICCF_CountForKeyEquivalent(equivalent));
+        if (equivalent == nil)
+	    return nil;
+        return ICCF_KeyEquivalentAttributedString(equivalent, ICCF_CountForKeyEquivalent(equivalent));
     }
     return nil;
