diff --git a/ChangeLog b/ChangeLog index 9c6a2f659..f63945267 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Thu Dec 17 22:55:00 1998 Richard Frith-Macdonald + + * NSMenu.m: ([-update]) removed code to search responder chain - + get NSApplication to do it for us. + * NSApplication.m: Implemented more of the windows menu stuff. + Almost complete barring wierd glitches due to the menu implementation. + 1998-12-17 Matthias Klose * {,*}/GNUmakefile: Include Version and GNUmakefile.local. diff --git a/Source/NSApplication.m b/Source/NSApplication.m index 5ba277812..82909b574 100644 --- a/Source/NSApplication.m +++ b/Source/NSApplication.m @@ -98,6 +98,7 @@ static NSString *NSAbortModalException = @"NSAbortModalException"; @interface NSApplication (Private) +- (BOOL) validateMenuItem: (id)item; - (void) _windowWillClose: (NSNotification*)n; - (void) _windowWillOpen: (NSWindow*)win; @end @@ -1338,14 +1339,15 @@ NSWindow *w; if ([aWindow isKindOfClass: [NSMenu class]]) return; - /* - * If this was the first window then make it the main and key window. - */ - if ([window_list count] == 1) - { - [aWindow becomeMainWindow]; - [aWindow becomeKeyWindow]; - } +/* + * FIXME - the following five lines shouldn't be here - but the X stuff + * terminates if I take them out! + */ +if ([window_list count] == 1) + { + [aWindow becomeKeyWindow]; + [aWindow becomeMainWindow]; + } /* * Can't permit an untitled window in the window menu. @@ -1376,6 +1378,7 @@ NSWindow *w; if ([item target] == aWindow) { [menu removeItem: item]; + windows_menu_count--; break; } } @@ -1419,6 +1422,7 @@ NSWindow *w; action: @selector(makeKeyAndOrderFront:) keyEquivalent: @"" atIndex: i]; + windows_menu_count++; [item setTarget: aWindow]; [menu sizeToFit]; [menu update]; @@ -1444,6 +1448,7 @@ NSWindow *w; if ([item target] == aWindow) { [menu removeItem: item]; + windows_menu_count--; [menu sizeToFit]; [menu update]; break; @@ -1455,11 +1460,123 @@ NSWindow *w; - (void) setWindowsMenu: (NSMenu*)aMenu { if (windows_menu) - [main_menu setSubmenu: aMenu forItem: (id)windows_menu]; + { + NSMutableArray *windows; + NSMenu *menu; + id win; + + menu = [self windowsMenu]; + if (menu == aMenu) + return; + + /* + * Remove all the windows from the old windows menu and store + * them in a temporary array for insertion into the new menu. + */ + windows = [NSMutableArray arrayWithCapacity: windows_menu_count]; + if (menu) + { + NSArray *itemArray; + unsigned count; + unsigned i; + + itemArray = [menu itemArray]; + count = [itemArray count]; + for (i = 0; i < count; i++) + { + id item = [itemArray objectAtIndex: i]; + + win = [item target]; + if ([win isKindOfClass: [NSWindow class]]) + { + [windows addObject: win]; + [menu removeItem: item]; + windows_menu_count--; + } + } + } + + /* + * Now use [-changeWindowsItem:title:filename:] to build the new menu. + */ + windows_menu_count = 0; + [main_menu setSubmenu: aMenu forItem: (id)windows_menu]; + while ((win = [windows lastObject]) != nil) + { + [self changeWindowsItem: win + title: [win title] + filename: [win representedFilename] != nil]; + [windows removeLastObject]; + } + [aMenu sizeToFit]; + [aMenu update]; + } } - (void) updateWindowsItem: aWindow { + NSMenu *menu; + + menu = [self windowsMenu]; + if (menu) + { + NSArray *itemArray; + unsigned count; + unsigned i; + + itemArray = [menu itemArray]; + count = [itemArray count]; + for (i = 0; i < count; i++) + { + id item = [itemArray objectAtIndex: i]; + + if ([item target] == aWindow) + { + NSCellImagePosition oldPos = [item imagePosition]; + NSImage *oldImage = [item image]; + BOOL changed = NO; + + if ([aWindow representedFilename] == nil) + { + if (oldPos != NSNoImage) + { + [item setImagePosition: NSNoImage]; + changed = YES; + } + } + else + { + NSImage *newImage = oldImage; + + if (oldPos != NSImageLeft) + { + [item setImagePosition: NSImageLeft]; + changed = YES; + } + if ([aWindow isDocumentEdited]) + { + newImage = [NSImage imageNamed: @"common_CloseBroken"]; + } + else + { + newImage = [NSImage imageNamed: @"common_Close"]; + } + if (newImage != oldImage) + { + [item setImage: newImage]; + changed = YES; + } + } + if (changed) + { + [item sizeToFit]; + [menu sizeToFit]; + [menu update]; + } + break; + } + } + } } - (NSMenu*) windowsMenu @@ -1715,7 +1832,7 @@ BOOL result = YES; + (void)setNullEvent:(NSEvent *)e { - ASSIGN(null_event, e); + ASSIGN(null_event, e); } + (NSEvent *)getNullEvent; @@ -1734,6 +1851,28 @@ BOOL result = YES; @end /* NSApplication */ @implementation NSApplication (Private) + +/* + * Method for automatically enabling or disabling menu items + * 'arrangeInFront:' is only valid if we have something in the windows menu. + */ +- (BOOL) validateMenuItem: (id)item +{ + SEL action = [item action]; + + if (action) + { + if (sel_eq(action, @selector(arrangeinFront:))) + { + if (windows_menu_count) + return YES; + } + else if ([self respondsToSelector: action]) + return YES; + } + return NO; +} + - (void) _windowWillClose: (NSNotification*)n { NSWindow *win = [n object]; diff --git a/Source/NSMenu.m b/Source/NSMenu.m index c7caffa95..8d25da05a 100644 --- a/Source/NSMenu.m +++ b/Source/NSMenu.m @@ -485,94 +485,7 @@ static Class menuCellClass = nil; } else { - /* Search the key window's responder chain */ - keyWindow = [theApp keyWindow]; - responder = [keyWindow firstResponder]; - while (responder) - { - if ([responder respondsToSelector: action]) - { - validator = responder; - break; - } - responder = [responder nextResponder]; - } - - if (validator == nil) - { - /* Search the key window */ - if ([keyWindow respondsToSelector: action]) - { - validator = keyWindow; - } - } - - if (validator == nil) - { - /* Search the key window's delegate */ - delegate = [keyWindow delegate]; - if ([delegate respondsToSelector: action]) - { - validator = delegate; - } - } - - if (validator == nil) - { - mainWindow = [theApp mainWindow]; - if (mainWindow != keyWindow) - { - /* Search the main window's responder chain */ - responder = [mainWindow firstResponder]; - while (responder) - { - if ([responder respondsToSelector: action]) - { - validator = responder; - break; - } - responder = [responder nextResponder]; - } - - if (validator == nil) - { - /* Search the main window */ - if ([mainWindow respondsToSelector: action]) - { - validator = mainWindow; - } - } - - if (validator == nil) - { - /* Search the main window's delegate */ - delegate = [mainWindow delegate]; - if ([delegate respondsToSelector: action]) - { - validator = delegate; - } - } - } - } - - if (validator == nil) - { - /* Search the NSApplication object */ - if ([theApp respondsToSelector: action]) - { - validator = theApp; - } - } - - if (validator == nil) - { - /* Search the NSApplication object's delegate */ - delegate = [theApp delegate]; - if ([delegate respondsToSelector: action]) - { - validator = theApp; - } - } + validator = [theApp targetForAction: action]; } }