- Timestamp:
- 06/11/07 01:21:55 (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ICeCoffEE/ICeCoffEE/ICeCoffEEServicePrefController.m
r182 r319 12 12 #import "ICeCoffEENonHighlightingButtonCell.h" 13 13 #import "ICeCoffEENonHighlightingTextFieldCell.h" 14 #import "ICeCoffEELabeledIconCell.h" 14 15 #import <objc/objc.h> 15 16 #import <ApplicationEnhancer/ApplicationEnhancer.h> … … 22 23 } 23 24 24 static inline NSCellStateValue ICCF_ServiceItemState(id <NSMenuItem> item) { 25 static NSMutableDictionary *keyEquivalents; 26 27 static void ICCF_RemoveSingleKeyEquivalents() { 28 NSMutableArray *singleKeys = [[NSMutableArray alloc] init]; 29 NSEnumerator *e = [[keyEquivalents allKeys] objectEnumerator]; 30 NSString *keyEquivalent; 31 ICLog(@"before ICCF_RemoveSingleKeyEquivalents: %@", keyEquivalents); 32 while ( (keyEquivalent = [e nextObject]) != nil) { 33 if ([[keyEquivalents objectForKey: keyEquivalent] count] == 1) 34 [singleKeys addObject: keyEquivalent]; 35 } 36 [keyEquivalents removeObjectsForKeys: singleKeys]; 37 [singleKeys release]; 38 ICLog(@"after ICCF_RemoveSingleKeyEquivalents: %@", keyEquivalents); 39 } 40 41 static inline unsigned ICCF_CountForKeyEquivalent(NSString *keyEquivalent) { 42 if (keyEquivalent == nil) return 0; 43 NSMutableSet *setOrNil = (NSMutableSet *)[keyEquivalents objectForKey: keyEquivalent]; 44 return (setOrNil == nil) ? nil : [setOrNil count]; 45 } 46 47 static inline void ICCF_AddKeyEquivalentForItem(NSMenuItem *item) { 48 NSString *keyEquivalent = [item toolTip]; 49 if (keyEquivalent == nil) return; 50 NSMutableSet *setOrNil = (NSMutableSet *)[keyEquivalents objectForKey: keyEquivalent]; 51 if (setOrNil == nil) return; 52 [setOrNil addObject: item]; 53 } 54 55 static inline void ICCF_RemoveKeyEquivalentForItem(NSMenuItem *item) { 56 NSString *keyEquivalent = [item toolTip]; 57 if (keyEquivalent == nil) return; 58 NSMutableSet *setOrNil = (NSMutableSet *)[keyEquivalents objectForKey: keyEquivalent]; 59 if (setOrNil == nil) return; 60 [setOrNil removeObject: item]; 61 } 62 63 static inline void ICCF_UpdateKeyEquivalentForItem(NSMenuItem *item, id state) { 64 NSNumber *oldState = [item representedObject]; 65 if ((oldState == nil || oldState == ICCF_SERVICE_SHOWN) && state == ICCF_SERVICE_HIDDEN) 66 ICCF_RemoveKeyEquivalentForItem(item); 67 else if (oldState == ICCF_SERVICE_HIDDEN && (state == ICCF_SERVICE_SHOWN || state == nil)) 68 ICCF_AddKeyEquivalentForItem(item); 69 } 70 71 static inline NSCellStateValue ICCF_ServiceItemState(NSMenuItem *item) { 25 72 id state = [item representedObject]; 26 73 return (state == nil) ? NSOnState : [state intValue]; … … 34 81 while ( (item = [e nextObject]) != nil) { 35 82 submenu = [item submenu]; 36 if (submenu != nil) { 37 ICCF_PropagateServiceStateChange(submenu, state); 38 [item setRepresentedObject: (state == nil) ? ICCF_SERVICE_SHOWN : state]; 39 } 40 [item setRepresentedObject: state]; 41 } 42 } 43 44 static NSCellStateValue ICCF_PropagateServiceState(id <NSMenuItem> item, NSMenuItem *changedItem) { 83 if (submenu != nil) 84 ICCF_PropagateServiceStateChange(submenu, state); 85 else 86 ICCF_UpdateKeyEquivalentForItem(item, state); 87 88 [item setRepresentedObject: state]; 89 } 90 } 91 92 static NSCellStateValue ICCF_PropagateServiceState(NSMenuItem *item, NSMenuItem *changedItem) { 45 93 NSMenu *submenu = [item submenu]; 46 94 if (submenu == nil) return ICCF_ServiceItemState(item); … … 102 150 NSString *itemTitle; 103 151 NSDictionary *subDict, *submenuDict; 104 id <NSMenuItem>item;152 NSMenuItem *item; 105 153 NSMenu *submenu; 106 154 107 155 // XXX handle exceptions 108 156 while ( (itemTitle = [e nextObject]) != nil) { 109 item = [menu itemWithTitle: itemTitle];157 item = (NSMenuItem *)[menu itemWithTitle: itemTitle]; 110 158 if (item == nil) continue; 111 159 subDict = [dict objectForKey: itemTitle]; 112 160 if ([[subDict objectForKey: (NSString *)kICServiceHidden] boolValue]) { 113 161 [item setRepresentedObject: ICCF_SERVICE_HIDDEN]; 162 ICCF_RemoveKeyEquivalentForItem(item); 114 163 } 115 164 if ( (submenu = [item submenu]) != nil) { … … 123 172 } 124 173 174 static void ICCF_AddServiceKeyEquivalentsAndIcons(NSMenu *menu, NSDictionary *serviceInfo) { 175 if (serviceInfo == nil) return; 176 NSEnumerator *enumerator = [[menu itemArray] objectEnumerator]; 177 NSMenuItem *menuItem; 178 NSMenu *submenu; 179 NSDictionary *itemInfo = nil; 180 while ( (menuItem = [enumerator nextObject]) != nil) { 181 itemInfo = [serviceInfo objectForKey: [menuItem title]]; 182 if (itemInfo == nil) continue; 183 184 if ( (submenu = [menuItem submenu]) != nil) { 185 ICCF_AddServiceKeyEquivalentsAndIcons(submenu, itemInfo); 186 } else { 187 NSString *keyEquivalent = (NSString *)[itemInfo objectForKey: (NSString *)kICServiceShortcut]; 188 if (keyEquivalent != nil) { 189 [menuItem setToolTip: keyEquivalent]; 190 NSMutableSet *equivalentItems = (NSMutableSet *)[keyEquivalents objectForKey: keyEquivalent]; 191 if (equivalentItems == nil) { 192 equivalentItems = [[NSMutableSet alloc] initWithObjects: menuItem, nil]; 193 [keyEquivalents setObject: equivalentItems forKey: keyEquivalent]; 194 [equivalentItems release]; 195 } else { 196 [equivalentItems addObject: menuItem]; 197 } 198 } 199 } 200 201 NSString *bundlePath = (NSString *)[itemInfo objectForKey: (NSString *)kICServiceBundlePath]; 202 if (bundlePath == NULL) continue; 203 IconRef serviceIcon = ICCF_CopyIconRefForPath(bundlePath); 204 if (serviceIcon == NULL) continue; 205 [menuItem _setIconRef: serviceIcon]; 206 ReleaseIconRef(serviceIcon); 207 } 208 } 209 125 210 @implementation ICeCoffEEServicePrefController 126 211 … … 141 226 if ( (self = [self initWithWindowNibName: @"Select services"])) { 142 227 NSWindow *window = [self window]; // connect outlets 228 [serviceOutline setAutoresizesOutlineColumn: NO]; 229 143 230 NSButtonCell *checkBoxCell = [[ICeCoffEENonHighlightingButtonCell alloc] init]; 144 231 [checkBoxCell setButtonType: NSSwitchButton]; … … 149 236 150 237 NSTextFieldCell *textFieldCell = [[serviceOutline tableColumnWithIdentifier: @"service"] dataCell]; 151 ((struct objc_object *)textFieldCell)->isa = [ICeCoffEENonHighlightingTextFieldCell class]; 238 [textFieldCell setWraps: YES]; 239 [[serviceOutline tableColumnWithIdentifier: @"service"] setDataCell: 240 [ICeCoffEELabeledIconCell copyFromTextFieldCell: textFieldCell]]; 152 241 153 242 textFieldCell = [[serviceOutline tableColumnWithIdentifier: @"key"] dataCell]; … … 167 256 - (void)dealloc; 168 257 { 258 [keyEquivalents release]; 169 259 [servicesMenu release]; 170 260 [super dealloc]; … … 223 313 { 224 314 if (servicesMenu == nil) { 315 keyEquivalents = [[NSMutableDictionary alloc] init]; 225 316 servicesMenu = [[NSMenu alloc] initWithTitle: @""]; 226 317 ICCF_SetServicesMenu(servicesMenu); 227 [servicesMenu update]; // XXX necessary on 10.3? or anywhere? 318 ICCF_AddServiceKeyEquivalentsAndIcons(servicesMenu, ICCF_GetServicesInfo()); 319 ICCF_RemoveSingleKeyEquivalents(); 320 228 321 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 229 322 NSDictionary *icDefaults = [defaults persistentDomainForName: (NSString *)kICBundleIdentifier]; … … 244 337 } 245 338 246 NSAttributedString *ICCF_KeyEquivalentAttributedStringWithModifierFlags(NSString *self, unsigned int modifierFlags );339 NSAttributedString *ICCF_KeyEquivalentAttributedStringWithModifierFlags(NSString *self, unsigned int modifierFlags, unsigned count); 247 340 248 341 - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item; 249 342 { 250 343 if ([[tableColumn identifier] isEqualToString: @"service"]) { 251 return [item title]; 344 static NSDictionary *attrDict = nil; 345 if (attrDict == nil) { // XXX we leak this, but so does the Apple sample code... 346 NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 347 [style setLineBreakMode: NSLineBreakByTruncatingMiddle]; 348 attrDict = [[NSDictionary alloc] initWithObjectsAndKeys: style, NSParagraphStyleAttributeName, nil]; 349 [style release]; 350 } 351 return [[[NSAttributedString alloc] initWithString: [item title] attributes: attrDict] autorelease]; 252 352 } else if ([[tableColumn identifier] isEqualToString: @"show"]) { 253 353 id state = [item representedObject]; … … 257 357 return (state == nil) ? ICCF_SERVICE_SHOWN : state; 258 358 } else if ([[tableColumn identifier] isEqualToString: @"key"]) { 259 [item setKeyEquivalent: @"#"]; 260 NSString *equivalent = [item keyEquivalent]; 359 NSString *equivalent = [item toolTip]; 261 360 if (equivalent == nil || [equivalent length] != 1) return nil; 262 361 // 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. 263 return ICCF_KeyEquivalentAttributedStringWithModifierFlags(equivalent, [item keyEquivalentModifierMask] | ([[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember: [equivalent characterAtIndex: 0]] ? NSShiftKeyMask : 0) );362 return ICCF_KeyEquivalentAttributedStringWithModifierFlags(equivalent, [item keyEquivalentModifierMask] | ([[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember: [equivalent characterAtIndex: 0]] ? NSShiftKeyMask : 0), ICCF_CountForKeyEquivalent(equivalent)); 264 363 } 265 364 return nil; … … 269 368 { 270 369 if ([[tableColumn identifier] isEqualToString: @"show"]) { 271 [item setRepresentedObject: [object boolValue] ? nil : ICCF_SERVICE_HIDDEN]; 370 NSNumber *newState = [object boolValue] ? nil : ICCF_SERVICE_HIDDEN; 371 ICCF_UpdateKeyEquivalentForItem(item, newState); 372 [item setRepresentedObject: newState]; 272 373 273 374 NSMenu *submenu = [item menu]; … … 279 380 submenu = supermenu; 280 381 } 281 ICCF_PropagateServiceState( [supermenu itemAtIndex: [supermenu indexOfItemWithSubmenu: submenu]], item);382 ICCF_PropagateServiceState((NSMenuItem *)[supermenu itemAtIndex: [supermenu indexOfItemWithSubmenu: submenu]], item); 282 383 } 283 384 [outlineView reloadData]; 284 385 } 386 } 387 388 @end 389 390 @implementation ICeCoffEEServicePrefController (NSOutlineViewDelegate) 391 392 - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item; 393 { 394 if (![[tableColumn identifier] isEqualToString: @"service"]) 395 return; 396 [(ICeCoffEELabeledIconCell *)cell setIconRef: [item _iconRef]]; 285 397 } 286 398
Note:
See TracChangeset
for help on using the changeset viewer.