Fixes to avoid crashes

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@5275 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 1999-11-25 11:54:08 +00:00
parent d2759567a5
commit 1708e6cfe8
5 changed files with 291 additions and 267 deletions

View file

@ -1,3 +1,13 @@
Thu Nov 25 11:44:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSMenu.m: Tidying, performnce tweaks, memory leak fixes.
* Source/NSPopUpButton.m: Tidied.
* Headers/AppKit/NSPopUpButtonCell.h: Use _selectedItem ivar rather
than _selectedIndex.
* Source/NSPopUpButtonCell.m: Use _selectedItem ivar rather than
_selectedIndex, fix memory leaks, and various hacks to stop things
crashing.
Thu Nov 25 1999 Nicola Pero <n.pero@mi.flashnet.it> Thu Nov 25 1999 Nicola Pero <n.pero@mi.flashnet.it>
* Source/NSMenuView.m ([-trackWithEvent:]): Fixed bug which was * Source/NSMenuView.m ([-trackWithEvent:]): Fixed bug which was

View file

@ -12,7 +12,7 @@ typedef enum {
@interface NSPopUpButtonCell : NSMenuItemCell @interface NSPopUpButtonCell : NSMenuItemCell
{ {
NSMenu *_menu; NSMenu *_menu;
int _selectedIndex; NSMenuItem *_selectedItem;
struct __pbcFlags { struct __pbcFlags {
unsigned int pullsDown:1; unsigned int pullsDown:1;
unsigned int preferredEdge:3; unsigned int preferredEdge:3;

View file

@ -96,6 +96,21 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
menu_is_beholdenToPopUpButton = flag; menu_is_beholdenToPopUpButton = flag;
} }
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver: self];
RELEASE(menu_notifications);
RELEASE(menu_title);
RELEASE(menu_items);
RELEASE(menu_view);
RELEASE(aWindow);
RELEASE(bWindow);
RELEASE(titleView);
[super dealloc];
}
- (id) initWithTitle: (NSString *)aTitle - (id) initWithTitle: (NSString *)aTitle
{ {
NSNotificationCenter *theCenter = [NSNotificationCenter defaultCenter]; NSNotificationCenter *theCenter = [NSNotificationCenter defaultCenter];
@ -248,7 +263,7 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
- (void) removeItem: (id <NSMenuItem>)anItem - (void) removeItem: (id <NSMenuItem>)anItem
{ {
[self removeItemAtIndex:[menu_items indexOfObject: anItem]]; [self removeItemAtIndex: [menu_items indexOfObjectIdenticalTo: anItem]];
} }
- (void) removeItemAtIndex: (int)index - (void) removeItemAtIndex: (int)index
@ -367,7 +382,7 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
// //
- (int) indexOfItem: (id <NSMenuItem>)anObject - (int) indexOfItem: (id <NSMenuItem>)anObject
{ {
return [menu_items indexOfObject: anObject]; return [menu_items indexOfObjectIdenticalTo: anObject];
} }
- (int) indexOfItemWithTitle: (NSString *)aTitle - (int) indexOfItemWithTitle: (NSString *)aTitle
@ -375,7 +390,7 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
id anItem; id anItem;
if ((anItem = [self itemWithTitle: aTitle])) if ((anItem = [self itemWithTitle: aTitle]))
return [menu_items indexOfObject: anItem]; return [menu_items indexOfObjectIdenticalTo: anItem];
else else
return -1; return -1;
} }
@ -385,7 +400,7 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
id anItem; id anItem;
if ((anItem = [self itemWithTag: aTag])) if ((anItem = [self itemWithTag: aTag]))
return [menu_items indexOfObject: anItem]; return [menu_items indexOfObjectIdenticalTo: anItem];
else else
return -1; return -1;
} }

View file

@ -40,6 +40,12 @@
@end @end
@implementation NSPopUpButtonCell @implementation NSPopUpButtonCell
- (void) dealloc
{
RELEASE(_menu);
[super dealloc];
}
- (id) initTextCell: (NSString *)stringValue - (id) initTextCell: (NSString *)stringValue
{ {
return [self initTextCell: stringValue pullsDown: NO]; return [self initTextCell: stringValue pullsDown: NO];
@ -65,7 +71,7 @@
[anItem setAction: @selector(_popUpItemAction:)]; [anItem setAction: @selector(_popUpItemAction:)];
} }
_menu = [NSMenu initWithTitle:@""]; _menu = [[NSMenu alloc] initWithTitle: @""];
[_menu _setOwnedByPopUp: YES]; [_menu _setOwnedByPopUp: YES];
return self; return self;
@ -156,13 +162,15 @@
[anItem setAction: @selector(_popUpItemAction:)]; [anItem setAction: @selector(_popUpItemAction:)];
[_menu insertItem: anItem atIndex: [_menu numberOfItems]]; [_menu insertItem: anItem atIndex: [_menu numberOfItems]];
RELEASE(anItem);
} }
- (void) addItemsWithTitles: (NSArray *)itemTitles - (void) addItemsWithTitles: (NSArray *)itemTitles
{ {
int i; unsigned c = [itemTitles count];
unsigned i;
for (i=0; i<[itemTitles count]; i++) for (i = 0; i < c; i++)
{ {
[self addItemWithTitle: [itemTitles objectAtIndex: i]]; [self addItemWithTitle: [itemTitles objectAtIndex: i]];
} }
@ -172,26 +180,35 @@
{ {
NSMenuItem *anItem = [NSMenuItem new]; NSMenuItem *anItem = [NSMenuItem new];
if (index < 0)
index = 0;
if (index > [_menu numberOfItems])
index = [_menu numberOfitems];
[anItem setTitle: title]; [anItem setTitle: title];
[anItem setTarget: self]; [anItem setTarget: self];
[anItem setAction: @selector(_popUpItemAction:)]; [anItem setAction: @selector(_popUpItemAction:)];
[[_menu itemArray] insertObject: anItem atIndex: index]; [_menu insertItem: anItem atIndex: index];
RELEASE(anItem);
} }
- (void) removeItemWithTitle: (NSString *)title - (void) removeItemWithTitle: (NSString *)title
{ {
[_menu removeItemWithTitle: title]; [_menu removeItemAtIndex: [_menu indexOfItemWithTitle: title]];
} }
- (void) removeItemAtIndex: (int)index - (void) removeItemAtIndex: (int)index
{ {
[[_menu itemArray] removeObjectAtIndex: index]; [_menu removeItemAtIndex: index];
} }
- (void) removeAllItems - (void) removeAllItems
{ {
[_menu removeAllItems]; while ([_menu numberOfItems] > 0)
{
[_menu removeItemAtIndex: 0];
}
} }
// Accessing the items // Accessing the items
@ -215,9 +232,9 @@
return [_menu indexOfItemWithTitle: title]; return [_menu indexOfItemWithTitle: title];
} }
- (int)indexOfItemWithTag:(int)tag - (int) indexOfItemWithTag: (int)aTag
{ {
return [_menu indexOfItemWithTag: tag]; return [_menu indexOfItemWithTag: aTag];
} }
- (int) indexOfItemWithRepresentedObject: (id)obj - (int) indexOfItemWithRepresentedObject: (id)obj
@ -225,9 +242,9 @@
return [_menu indexOfItemWithRepresentedObject: obj]; return [_menu indexOfItemWithRepresentedObject: obj];
} }
- (int)indexOfItemWithTarget:(id)target andAction:(SEL)actionSelector - (int) indexOfItemWithTarget: (id)aTarget andAction: (SEL)actionSelector
{ {
return [_menu indexOfItemWithTarget: target andAction: actionSelector]; return [_menu indexOfItemWithTarget: aTarget andAction: actionSelector];
} }
- (id <NSMenuItem>) itemAtIndex: (int)index - (id <NSMenuItem>) itemAtIndex: (int)index
@ -242,7 +259,11 @@
- (id <NSMenuItem>) lastItem - (id <NSMenuItem>) lastItem
{ {
return [_menu lastItem]; int end = [_menu numberOfItems] - 1;
if (end < 0)
return nil;
return [_menu itemAtIndex: end];
} }
// Dealing with selection // Dealing with selection
@ -251,101 +272,73 @@
if (!item) if (!item)
{ {
if (_pbcFlags.altersStateOfSelectedItem) if (_pbcFlags.altersStateOfSelectedItem)
[[self itemAtIndex: _selectedIndex] setState: NSOffState]; [_selectedItem setState: NSOffState];
_selectedIndex = -1; _selectedItem = nil;
} }
else else
{ {
int aIndex = [self indexOfItem: item];
if (_pbcFlags.altersStateOfSelectedItem) if (_pbcFlags.altersStateOfSelectedItem)
{ {
[[self itemAtIndex: _selectedIndex] setState: NSOffState]; [_selectedItem setState: NSOffState];
[[self itemAtIndex: aIndex] setState: NSOnState]; }
_selectedItem = item;
if (_pbcFlags.altersStateOfSelectedItem)
{
[_selectedItem setState: NSOnState];
} }
_selectedIndex = aIndex;
} }
} }
- (void) selectItemAtIndex: (int)index - (void) selectItemAtIndex: (int)index
{ {
if (index == -1) NSMenuItem *anItem = (index == -1) ? nil : [self itemAtIndex: index];
{
if (_pbcFlags.altersStateOfSelectedItem)
[[self itemAtIndex: _selectedIndex] setState: NSOffState];
_selectedIndex = -1; [self selectItem: anItem];
}
else
{
if (_pbcFlags.altersStateOfSelectedItem)
{
[[self itemAtIndex: _selectedIndex] setState: NSOffState];
[[self itemAtIndex: index] setState: NSOnState];
}
_selectedIndex = index;
}
} }
- (void) selectItemWithTitle: (NSString *)title - (void) selectItemWithTitle: (NSString *)title
{ {
NSMenuItem *anItem = [self itemWithTitle: title];
if ([title length] < 1) [self selectItem: anItem];
{
if (_pbcFlags.altersStateOfSelectedItem)
[[self itemAtIndex: _selectedIndex] setState: NSOffState];
_selectedIndex = -1;
}
else
{
int aIndex = [self indexOfItemWithTitle: title];
if (_pbcFlags.altersStateOfSelectedItem)
{
[[self itemAtIndex: _selectedIndex] setState: NSOffState];
[[self itemAtIndex: aIndex] setState: NSOnState];
}
_selectedIndex = aIndex;
}
} }
- (void) setTitle: (NSString *)aString - (void) setTitle: (NSString *)aString
{ {
NSMenuItem *anItem;
if (_pbcFlags.pullsDown) if (_pbcFlags.pullsDown)
{ {
if ([_menu numberOfItems] == 0)
{
anItem = nil;
} }
else else
{ {
int aIndex; anItem = [_menu itemAtIndex: 0];
}
if (aIndex = [self indexOfItemWithTitle: aString])
{
[self selectItemAtIndex: aIndex];
} }
else else
{
anItem = [_menu itemWithTitle: aString];
if (anItem == nil)
{ {
[self addItemWithTitle: aString]; [self addItemWithTitle: aString];
[self selectItemWithTitle: aString]; anItem = [_menu itemWithTitle: aString];
} }
} }
[self selectItem: anItem];
} }
- (id <NSMenuItem>) selectedItem - (id <NSMenuItem>) selectedItem
{ {
if (_selectedIndex != -1) return _selectedItem;
return [self itemAtIndex: _selectedIndex];
else
return nil;
} }
- (int) indexOfSelectedItem - (int) indexOfSelectedItem
{ {
return _selectedIndex; return [_menu indexOfItem: _selectedItem];
} }
- (void) synchronizeTitleAndSelectedItem - (void) synchronizeTitleAndSelectedItem
@ -353,18 +346,21 @@
if (!_pbcFlags.usesItemFromMenu) if (!_pbcFlags.usesItemFromMenu)
return; return;
// Add test for null menus. if ([_menu numberOfItems] == 0)
{
if (_pbcFlags.pullsDown) _selectedItem = nil;
}
else if (_pbcFlags.pullsDown)
{ {
[self selectItem: [self itemAtIndex: 0]]; [self selectItem: [self itemAtIndex: 0]];
} }
else else
{ {
if (_selectedIndex >= 0) int index = [[_menu menuRepresentation] highlightedItemIndex];
[self selectItem: [self itemAtIndex: _selectedIndex]];
else if (index < 0)
[self selectItem: [self itemAtIndex: 0]]; index = 0;
[self selectItemAtIndex: index];
} }
} }
@ -376,21 +372,23 @@
- (NSArray *) itemTitles - (NSArray *) itemTitles
{ {
NSMutableArray *anArray = [NSMutableArray new]; unsigned count = [_menu numberOfItems];
int i; id items[count];
unsigned i;
for (i=0; i<[[_menu itemArray] count]; i++) [[_menu itemArray] getObjects: items];
for (i = 0; i < count; i++)
{ {
[anArray addObject: [[[_menu itemArray] objectAtIndex: i] title]]; items[i] = [items[i] title];
} }
return (NSArray *)anArray; return [NSArray arrayWithObjects: items count: count];
} }
- (NSString *) titleOfSelectedItem - (NSString *) titleOfSelectedItem
{ {
if (_selectedIndex >= 0) if (_selectedItem != nil)
return [[self itemAtIndex: _selectedIndex] title]; return [_selectedItem title];
else else
return @""; return @"";
} }
@ -417,7 +415,8 @@
[_aCenter postNotification: _aNotif]; [_aCenter postNotification: _aNotif];
scratchRect.origin = [[controlView window] convertBaseToScreen: cellFrame.origin]; scratchRect.origin
= [[controlView window] convertBaseToScreen: cellFrame.origin];
[[_menu menuRepresentation] _setCellSize: cellFrame.size]; [[_menu menuRepresentation] _setCellSize: cellFrame.size];
[_menu sizeToFit]; [_menu sizeToFit];
@ -443,7 +442,7 @@
if (!_pbcFlags.pullsDown) if (!_pbcFlags.pullsDown)
{ {
winf.origin.y += (_selectedIndex * scratchRect.size.height); winf.origin.y += ([self indexOfSelectedItem] * scratchRect.size.height);
} }
NSLog(@"winf %@", NSStringFromRect(winf)); NSLog(@"winf %@", NSStringFromRect(winf));