diff --git a/AppKit/CPMenu/CPMenu.j b/AppKit/CPMenu/CPMenu.j index b5cf9a850..db5aa8e61 100644 --- a/AppKit/CPMenu/CPMenu.j +++ b/AppKit/CPMenu/CPMenu.j @@ -595,8 +595,12 @@ var _CPMenuBarVisible = NO, var items = [self itemArray]; for (var i = 0; i < [items count]; i++) { - var item = [items objectAtIndex:i], - validator = [CPApp targetForAction:[item action] to:[item target] from:item]; + var item = [items objectAtIndex:i]; + + if ([item hasSubmenu]) + continue; + + var validator = [CPApp targetForAction:[item action] to:[item target] from:item]; if (!validator || ![validator respondsToSelector:[item action]]) [item _setEnabled:NO]; diff --git a/Tests/AppKit/CPMenuValidatedUserInterfaceItemTest.j b/Tests/AppKit/CPMenuValidatedUserInterfaceItemTest.j index e4fbb2115..4322239fa 100644 --- a/Tests/AppKit/CPMenuValidatedUserInterfaceItemTest.j +++ b/Tests/AppKit/CPMenuValidatedUserInterfaceItemTest.j @@ -1,38 +1,72 @@ +var CPMenuValidatedUserInterfaceItemTestValidatedItems = []; + @implementation CPMenuValidatedUserInterfaceItemTest : OJTestCase { CPMenu _menu @accessors(property=menu); + + MenuTarget _menuTarget @accessors(property=menuTarget); } - (void)setUp { - [[CPApplication sharedApplication] setDelegate:[[MenuTarget alloc] init]]; + _menuTarget = [[MenuTarget alloc] init]; + [[CPApplication sharedApplication] setDelegate:_menuTarget]; _menu = [[CPMenu alloc] init]; [_menu addItem:[[CPMenuItem alloc] initWithTitle:@"implemented" action:@selector(implementedAction:) keyEquivalent:nil]]; [_menu addItem:[[CPMenuItem alloc] initWithTitle:@"disabled" action:@selector(disabledAction:) keyEquivalent:nil]]; [_menu addItem:[[CPMenuItem alloc] initWithTitle:@"unimplemented" action:@selector(unimplementedAction:) keyEquivalent:nil]]; + + var parentItem = [[CPMenuItem alloc] initWithTitle:@"parent" action:nil keyEquivalent:nil]; + [_menu addItem:parentItem]; + + [parentItem setSubmenu:[[CPMenu alloc] init]]; + [[parentItem submenu] addItem:[[CPMenuItem alloc] initWithTitle:@"Submenu 1" action:nil keyEquivalent:nil]]; + + CPMenuValidatedUserInterfaceItemTestValidatedItems = []; + + // Update is what performs the autoenabling so we need to call it manually. + // It's normally called automatically just before a menu becomes visible. + [_menu update]; } - (void)testAutoenable { - // Update is what actually performs the autoenabling so we need to call it manually. - // It's normally called automatically just before a menu becomes visible. - [[self menu] update]; - [self assertTrue:[[[self menu] itemWithTitle:@"implemented"] isEnabled] message:@"The implemented action should be enabled"]; [self assertFalse:[[[self menu] itemWithTitle:@"disabled"] isEnabled] message:@"The disbabled action should be disabled"]; [self assertFalse:[[[self menu] itemWithTitle:@"unimplemented"] isEnabled] message:@"The unimplemented action should be disabled"]; } +- (void)testThatParentMenusAreNotValidated +{ + var parentItem = [[self menu] itemWithTitle:@"parent"]; + + [self assertTrue:[parentItem isEnabled] message:@"Parent items should never be disabled"]; + [self assertFalse:[[[self menuTarget] validatedItems] containsObject:parent] message:@"Parent items should never be validated"]; +} + @end @implementation MenuTarget : CPObject { + CPArray _validatedItems @accessors(property=validatedItems, readonly); +} + +- (id)init +{ + if (self = [super init]) + { + _validatedItems = []; + } + + return self; } - (BOOL)validateMenuItem:(CPMenuItem)theMenuItem { + [_validatedItems addObject:theMenuItem]; + if ([theMenuItem action] === @selector(disabledAction:)) return NO;