Fixes for bug #18494

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@24962 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2007-04-02 12:53:54 +00:00
parent d11b08e6c1
commit ed70a012c1
3 changed files with 409 additions and 260 deletions

View file

@ -1,3 +1,10 @@
2007-04-02 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/AppKit/NSAlert.h: Tidied.
* Source/NSAlert.m: Tidied to more standard gnustep style and added
code to perform gui operations in the main appkit thread where someone
tries to use alerts from another thread.
2007-03-26 Richard Frith-Macdonald <rfm@gnu.org> 2007-03-26 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSAttributedString.m: Wrap excessively long lines * Source/NSAttributedString.m: Wrap excessively long lines

View file

@ -54,73 +54,47 @@ enum {
@interface NSAlert : NSObject @interface NSAlert : NSObject
{ {
@private @private
NSString *_informative_text; NSString *_informative_text;
NSString *_message_text; NSString *_message_text;
NSImage *_icon; NSImage *_icon;
NSMutableArray *_buttons; NSMutableArray *_buttons;
NSString *_help_anchor; NSString *_help_anchor;
NSWindow *_window; NSWindow *_window;
id _delegate; id _delegate;
NSAlertStyle _style; NSAlertStyle _style;
BOOL _shows_help; BOOL _shows_help;
int _result;
} }
+ (NSAlert *)alertWithMessageText:(NSString *)messageTitle + (NSAlert *) alertWithMessageText: (NSString *)messageTitle
defaultButton:(NSString *)defaultButtonTitle defaultButton: (NSString *)defaultButtonTitle
alternateButton:(NSString *)alternateButtonTitle alternateButton: (NSString *)alternateButtonTitle
otherButton:(NSString *)otherButtonTitle otherButton: (NSString *)otherButtonTitle
informativeTextWithFormat:(NSString *)format, ...; informativeTextWithFormat: (NSString *)format, ...;
//
// Alert text
//
- (void)setInformativeText:(NSString *)informativeText;
- (NSString *)informativeText;
- (void)setMessageText:(NSString *)messageText;
- (NSString *)messageText;
// - (NSButton *) addButtonWithTitle: (NSString *)aTitle;
// Alert icon - (NSAlertStyle) alertStyle;
// - (void) beginSheetModalForWindow: (NSWindow *)window
- (void)setIcon:(NSImage *)icon; modalDelegate: (id)delegate
- (NSImage *)icon; didEndSelector: (SEL)didEndSelector
contextInfo: (void *)contextInfo;
// - (NSArray *) buttons;
// Buttons - (id) delegate;
// - (NSString *) helpAnchor;
- (NSButton *)addButtonWithTitle:(NSString *)aTitle; - (NSImage *) icon;
- (NSArray *)buttons; - (NSString *) informativeText;
- (NSString *) messageText;
// - (int) runModal;
// Help - (void) setAlertStyle: (NSAlertStyle)style;
// - (void) setDelegate: (id)delegate;
- (void)setShowsHelp:(BOOL)showsHelp; - (void) setHelpAnchor: (NSString *)anchor;
- (BOOL)showsHelp; - (void) setIcon: (NSImage *)icon;
- (void)setHelpAnchor:(NSString *)anchor; - (void) setInformativeText: (NSString *)informativeText;
- (NSString *)helpAnchor; - (void) setMessageText: (NSString *)messageText;
- (void) setShowsHelp: (BOOL)showsHelp;
// - (BOOL) showsHelp;
// Alert style - (id) window;
//
- (void)setAlertStyle:(NSAlertStyle)style;
- (NSAlertStyle)alertStyle;
//
// Delegate
//
- (void)setDelegate:(id)delegate;
- (id)delegate;
//
// Running the alert
//
- (int)runModal;
- (void)beginSheetModalForWindow:(NSWindow *)window
modalDelegate:(id)delegate
didEndSelector:(SEL)didEndSelector
contextInfo:(void *)contextInfo;
- (id)window;
@end @end
@ -131,7 +105,7 @@ enum {
#ifdef GNUSTEP #ifdef GNUSTEP
@interface NSObject (NSAlertDelegate) @interface NSObject (NSAlertDelegate)
- (BOOL)alertShowHelp:(NSAlert *)alert; - (BOOL) alertShowHelp: (NSAlert *)alert;
@end @end
#endif #endif

View file

@ -35,6 +35,7 @@
#include "config.h" #include "config.h"
#include <Foundation/NSDebug.h>
#include <Foundation/NSBundle.h> #include <Foundation/NSBundle.h>
#include <Foundation/NSString.h> #include <Foundation/NSString.h>
#include "AppKit/NSAlert.h" #include "AppKit/NSAlert.h"
@ -53,6 +54,7 @@
#include "GNUstepGUI/GMAppKit.h" #include "GNUstepGUI/GMAppKit.h"
#include "GNUstepGUI/GMArchiver.h" #include "GNUstepGUI/GMArchiver.h"
extern NSThread *GSAppKitThread;
#ifdef ALERT_TITLE #ifdef ALERT_TITLE
static NSString *defaultTitle = @"Alert"; static NSString *defaultTitle = @"Alert";
@ -76,7 +78,7 @@ static NSString *defaultTitle = @" ";
| s | | | s | |
| s | | | s | |
| ...................s....|......................................... | | ...................s....|......................................... |
| :Message s s ; | | : Message s s ; |
| : s s : | | : s s : |
| : s s : | | : s s : |
|----: s s :----| |----: s s :----|
@ -183,11 +185,13 @@ static GSAlertPanel *criticalAlertPanel = nil;
- (id) _initWithoutGModel; - (id) _initWithoutGModel;
- (int) runModal; - (int) runModal;
- (void) setTitle: (NSString*)title - (void) setTitleBar: (NSString*)titleBar
message: (NSString*)message icon: (NSImage*)icon
def: (NSString*)defaultButton title: (NSString*)title
alt: (NSString*)alternateButton message: (NSString*)message
other: (NSString*)otherButton; def: (NSString*)defaultButton
alt: (NSString*)alternateButton
other: (NSString*)otherButton;
- (void) sizePanelToFit; - (void) sizePanelToFit;
- (void) buttonAction: (id)sender; - (void) buttonAction: (id)sender;
- (int) result; - (int) result;
@ -717,24 +721,46 @@ setControl(NSView* content, id control, NSString *title)
- (int) runModal - (int) runModal
{ {
if (isGreen) if (GSCurrentThread() != GSAppKitThread)
{ {
[self sizePanelToFit]; [self performSelectorOnMainThread: _cmd
withObject: nil
waitUntilDone: YES];
}
else
{
if (isGreen)
{
[self sizePanelToFit];
}
[NSApp runModalForWindow: self];
[self orderOut: self];
} }
[NSApp runModalForWindow: self];
[self orderOut: self];
return result; return result;
} }
- (void) setTitle: (NSString*)title - (void) setTitleBar: (NSString*)titleBar
message: (NSString*)message icon: (NSImage*)icon
def: (NSString*)defaultButton title: (NSString*)title
alt: (NSString*)alternateButton message: (NSString*)message
other: (NSString*)otherButton def: (NSString*)defaultButton
alt: (NSString*)alternateButton
other: (NSString*)otherButton
{ {
NSView *content = [self contentView]; NSView *content = [self contentView];
if (titleBar != nil)
{
[self setTitle: titleBar];
}
if (icon != nil)
{
[icoButton setImage: icon];
}
if (title == nil)
{
title = titleBar; // Fall back to the same text as the title bar
}
setControl(content, titleField, title); setControl(content, titleField, title);
if (useControl(scroll)) if (useControl(scroll))
{ {
@ -790,7 +816,7 @@ setControl(NSView* content, id control, NSString *title)
[defButton setNextKeyView: altButton]; [defButton setNextKeyView: altButton];
else else
{ {
[defButton setPreviousKeyView:nil]; [defButton setPreviousKeyView: nil];
[defButton setNextKeyView: nil]; [defButton setNextKeyView: nil];
} }
} }
@ -803,7 +829,7 @@ setControl(NSView* content, id control, NSString *title)
[othButton setNextKeyView: defButton]; [othButton setNextKeyView: defButton];
else else
{ {
[othButton setPreviousKeyView:nil]; [othButton setPreviousKeyView: nil];
[othButton setNextKeyView: nil]; [othButton setNextKeyView: nil];
} }
} }
@ -816,12 +842,12 @@ setControl(NSView* content, id control, NSString *title)
[altButton setNextKeyView: othButton]; [altButton setNextKeyView: othButton];
else else
{ {
[altButton setPreviousKeyView:nil]; [altButton setPreviousKeyView: nil];
[altButton setNextKeyView: nil]; [altButton setNextKeyView: nil];
} }
} }
} }
[self sizePanelToFit];
isGreen = YES; isGreen = YES;
result = NSAlertErrorReturn; /* If no button was pressed */ result = NSAlertErrorReturn; /* If no button was pressed */
} }
@ -890,18 +916,58 @@ setControl(NSView* content, id control, NSString *title)
for the alert panel, setting its window title to "Alert". for the alert panel, setting its window title to "Alert".
*/ */
static GSAlertPanel* @interface _GSAlertCreation : NSObject
getSomePanel(
GSAlertPanel **instance,
NSString *defaultTitle,
NSString *title,
NSString *message,
NSString *defaultButton,
NSString *alternateButton,
NSString *otherButton)
{ {
GSAlertPanel *panel; GSAlertPanel **instance;
NSString *defaultTitle;
NSString *title;
NSString *message;
NSString *defaultButton;
NSString *alternateButton;
NSString *otherButton;
GSAlertPanel *panel;
}
- (id) initWithInstance: (GSAlertPanel**)_instance
defaultTitle: (NSString*)_defaultTitle
title: (NSString*)_title
message: (NSString*)_message
defaultButton: (NSString*)_defaultButton
alternateButton: (NSString*)_alternateButton
otherButton: (NSString*)_otherButton;
- (void) makePanel;
- (GSAlertPanel*) panel;
@end
@implementation _GSAlertCreation
- (void) dealloc
{
RELEASE(defaultTitle);
RELEASE(title);
RELEASE(defaultButton);
RELEASE(alternateButton);
RELEASE(otherButton);
[super dealloc];
}
- (id) initWithInstance: (GSAlertPanel**)_instance
defaultTitle: (NSString*)_defaultTitle
title: (NSString*)_title
message: (NSString*)_message
defaultButton: (NSString*)_defaultButton
alternateButton: (NSString*)_alternateButton
otherButton: (NSString*)_otherButton
{
instance = _instance;
ASSIGNCOPY(defaultTitle, _defaultTitle);
ASSIGNCOPY(title, _title);
ASSIGNCOPY(defaultButton, _defaultButton);
ASSIGNCOPY(alternateButton, _alternateButton);
ASSIGNCOPY(otherButton, _otherButton);
return self;
}
- (void) makePanel
{
if (*instance != 0) if (*instance != 0)
{ {
if ([*instance isActivePanel]) if ([*instance isActivePanel])
@ -919,21 +985,81 @@ getSomePanel(
*instance = panel; *instance = panel;
} }
if (title == nil) [panel setTitleBar: defaultTitle
{ icon: nil
title = defaultTitle; title: title
} message: message
def: defaultButton
alt: alternateButton
other: otherButton];
}
if (defaultTitle != nil) - (GSAlertPanel*) panel
{
return panel;
}
@end
static GSAlertPanel*
getSomePanel(
GSAlertPanel **instance,
NSString *defaultTitle,
NSString *title,
NSString *message,
NSString *defaultButton,
NSString *alternateButton,
NSString *otherButton)
{
GSAlertPanel *panel;
if (GSCurrentThread() != GSAppKitThread)
{ {
[panel setTitle: defaultTitle]; _GSAlertCreation *c;
NSWarnFLog(@"Alert Panel functionality called from a thread other than"
@" the main one, this may not work on MacOS-X and could therefore be"
@" a portability problem in your code");
c = [_GSAlertCreation alloc];
c = [c initWithInstance: instance
defaultTitle: defaultTitle
title: title
message: message
defaultButton: defaultButton
alternateButton: alternateButton
otherButton: otherButton];
[c performSelectorOnMainThread: @selector(makePanel)
withObject: nil
waitUntilDone: YES];
panel = [c panel];
RELEASE(c);
}
else
{
if (*instance != 0)
{
if ([*instance isActivePanel])
{ // c:
panel = [[GSAlertPanel alloc] init];
}
else
{ // b:
panel = *instance;
}
}
else
{ // a:
panel = [[GSAlertPanel alloc] init];
*instance = panel;
}
[panel setTitleBar: defaultTitle
icon: nil
title: title
message: message
def: defaultButton
alt: alternateButton
other: otherButton];
} }
[panel setTitle: title
message: message
def: defaultButton
alt: alternateButton
other: otherButton];
[panel sizePanelToFit];
return panel; return panel;
} }
@ -1130,8 +1256,8 @@ void
NSReleaseAlertPanel(id panel) NSReleaseAlertPanel(id panel)
{ {
if ((panel != standardAlertPanel) if ((panel != standardAlertPanel)
&& (panel != informationalAlertPanel) && (panel != informationalAlertPanel)
&& (panel != criticalAlertPanel)) && (panel != criticalAlertPanel))
{ {
RELEASE(panel); RELEASE(panel);
} }
@ -1249,7 +1375,7 @@ void NSBeginInformationalAlertSheet(NSString *title,
/* /*
* Class methods * Class methods
*/ */
+ (void)initialize + (void) initialize
{ {
if (self == [NSAlert class]) if (self == [NSAlert class])
{ {
@ -1257,11 +1383,11 @@ void NSBeginInformationalAlertSheet(NSString *title,
} }
} }
+ (NSAlert *)alertWithMessageText:(NSString *)messageTitle + (NSAlert *) alertWithMessageText: (NSString *)messageTitle
defaultButton:(NSString *)defaultButtonTitle defaultButton: (NSString *)defaultButtonTitle
alternateButton:(NSString *)alternateButtonTitle alternateButton: (NSString *)alternateButtonTitle
otherButton:(NSString *)otherButtonTitle otherButton: (NSString *)otherButtonTitle
informativeTextWithFormat:(NSString *)format, ... informativeTextWithFormat: (NSString *)format, ...
{ {
va_list ap; va_list ap;
NSAlert *alert = [[self alloc] init]; NSAlert *alert = [[self alloc] init];
@ -1280,21 +1406,21 @@ void NSBeginInformationalAlertSheet(NSString *title,
if (defaultButtonTitle != nil) if (defaultButtonTitle != nil)
{ {
[alert addButtonWithTitle: defaultButtonTitle]; [alert addButtonWithTitle: defaultButtonTitle];
} }
else else
{ {
[alert addButtonWithTitle: _(@"OK")]; [alert addButtonWithTitle: _(@"OK")];
} }
if (alternateButtonTitle != nil) if (alternateButtonTitle != nil)
{ {
[alert addButtonWithTitle: alternateButtonTitle]; [alert addButtonWithTitle: alternateButtonTitle];
} }
if (otherButtonTitle != nil) if (otherButtonTitle != nil)
{ {
[alert addButtonWithTitle: otherButtonTitle]; [alert addButtonWithTitle: otherButtonTitle];
} }
return AUTORELEASE(alert); return AUTORELEASE(alert);
@ -1318,37 +1444,37 @@ void NSBeginInformationalAlertSheet(NSString *title,
[super dealloc]; [super dealloc];
} }
- (void)setInformativeText:(NSString *)informativeText - (void) setInformativeText: (NSString *)informativeText
{ {
ASSIGN(_informative_text, informativeText); ASSIGN(_informative_text, informativeText);
} }
- (NSString *)informativeText - (NSString *) informativeText
{ {
return _informative_text; return _informative_text;
} }
- (void)setMessageText:(NSString *)messageText - (void) setMessageText: (NSString *)messageText
{ {
ASSIGN(_message_text, messageText); ASSIGN(_message_text, messageText);
} }
- (NSString *)messageText - (NSString *) messageText
{ {
return _message_text; return _message_text;
} }
- (void)setIcon:(NSImage *)icon - (void) setIcon: (NSImage *)icon
{ {
ASSIGN(_icon, icon); ASSIGN(_icon, icon);
} }
- (NSImage *)icon - (NSImage *) icon
{ {
return _icon; return _icon;
} }
- (NSButton *)addButtonWithTitle:(NSString *)aTitle - (NSButton *) addButtonWithTitle: (NSString *)aTitle
{ {
NSButton *button = [[NSButton alloc] init]; NSButton *button = [[NSButton alloc] init];
int count = [_buttons count]; int count = [_buttons count];
@ -1383,110 +1509,134 @@ void NSBeginInformationalAlertSheet(NSString *title,
return button; return button;
} }
- (NSArray *)buttons - (NSArray *) buttons
{ {
return _buttons; return _buttons;
} }
- (void)setShowsHelp:(BOOL)showsHelp - (void) setShowsHelp: (BOOL)showsHelp
{ {
_shows_help = showsHelp; _shows_help = showsHelp;
} }
- (BOOL)showsHelp - (BOOL) showsHelp
{ {
return _shows_help; return _shows_help;
} }
- (void)setHelpAnchor:(NSString *)anchor - (void) setHelpAnchor: (NSString *)anchor
{ {
ASSIGN(_help_anchor, anchor); ASSIGN(_help_anchor, anchor);
} }
- (NSString *)helpAnchor - (NSString *) helpAnchor
{ {
return _help_anchor; return _help_anchor;
} }
- (void)setAlertStyle:(NSAlertStyle)style - (void) setAlertStyle: (NSAlertStyle)style
{ {
_style = style; _style = style;
} }
- (NSAlertStyle)alertStyle - (NSAlertStyle) alertStyle
{ {
return _style; return _style;
} }
- (void)setDelegate:(id)delegate - (void) setDelegate: (id)delegate
{ {
_delegate = delegate; _delegate = delegate;
} }
- (id)delegate - (id) delegate
{ {
return _delegate; return _delegate;
} }
- (void)_setupPanel - (void) _setupPanel
{ {
GSAlertPanel *panel; if (GSCurrentThread() != GSAppKitThread)
NSString *title;
panel = [[GSAlertPanel alloc] init];
_window = panel;
switch (_style)
{ {
case NSCriticalAlertStyle: [self performSelectorOnMainThread: _cmd
title = @"Critical"; withObject: nil
break; waitUntilDone: YES];
case NSInformationalAlertStyle: }
title = @"Information"; else
break; {
case NSWarningAlertStyle: GSAlertPanel *panel;
default: NSString *title;
title = @"Alert";
break; panel = [[GSAlertPanel alloc] init];
_window = panel;
switch (_style)
{
case NSCriticalAlertStyle:
title = @"Critical";
break;
case NSInformationalAlertStyle:
title = @"Information";
break;
case NSWarningAlertStyle:
default:
title = @"Alert";
break;
}
[panel setTitleBar: title
icon: _icon
title: _informative_text
message: _message_text
def: [[_buttons objectAtIndex: 0] title]
alt: [[_buttons objectAtIndex: 1] title]
other: [[_buttons objectAtIndex: 2] title]];
} }
[panel setTitle: title];
// FIXME: Should also set the icon
[panel setTitle: _informative_text
message: _message_text
def: [[_buttons objectAtIndex: 0] title]
alt: [[_buttons objectAtIndex: 1] title]
other: [[_buttons objectAtIndex: 2] title]];
[panel sizePanelToFit];
} }
- (int)runModal - (int) runModal
{ {
int result; if (GSCurrentThread() != GSAppKitThread)
{
[self _setupPanel]; [self performSelectorOnMainThread: _cmd
[NSApp runModalForWindow: _window]; withObject: nil
[_window orderOut: self]; waitUntilDone: YES];
result = [(GSAlertPanel*)_window result]; return _result;
DESTROY(_window); }
else
return result; {
[self _setupPanel];
[NSApp runModalForWindow: _window];
[_window orderOut: self];
_result = [(GSAlertPanel*)_window result];
DESTROY(_window);
return _result;
}
} }
- (void)beginSheetModalForWindow:(NSWindow *)window - (void) beginSheetModalForWindow: (NSWindow *)window
modalDelegate:(id)delegate modalDelegate: (id)delegate
didEndSelector:(SEL)didEndSelector didEndSelector: (SEL)didEndSelector
contextInfo:(void *)contextInfo contextInfo: (void *)contextInfo
{ {
[self _setupPanel]; [self _setupPanel];
[NSApp beginSheet: _window if (GSCurrentThread() != GSAppKitThread)
modalForWindow: window {
modalDelegate: delegate [self performSelectorOnMainThread: _cmd
didEndSelector: didEndSelector withObject: nil
contextInfo: contextInfo]; waitUntilDone: YES];
DESTROY(_window); }
else
{
[NSApp beginSheet: _window
modalForWindow: window
modalDelegate: delegate
didEndSelector: didEndSelector
contextInfo: contextInfo];
DESTROY(_window);
}
} }
- (id)window - (id) window
{ {
return _window; return _window;
} }
@ -1499,8 +1649,8 @@ void NSBeginInformationalAlertSheet(NSString *title,
NSDictionary *_userInfo; NSDictionary *_userInfo;
NSPanel *_userInfoPanel; NSPanel *_userInfoPanel;
} }
- (void) setUserInfo:(NSDictionary *)userInfo; - (void) setUserInfo: (NSDictionary *)userInfo;
- (NSPanel *)userInfoPanel; - (NSPanel *) userInfoPanel;
@end @end
int GSRunExceptionPanel( int GSRunExceptionPanel(
@ -1514,7 +1664,7 @@ int GSRunExceptionPanel(
GSExceptionPanel *panel; GSExceptionPanel *panel;
int result; int result;
message = [NSString stringWithFormat:@"%@: %@", message = [NSString stringWithFormat: @"%@: %@",
[exception name], [exception name],
[exception reason]]; [exception reason]];
if (defaultButton == nil) if (defaultButton == nil)
@ -1529,14 +1679,16 @@ int GSRunExceptionPanel(
title = @"Exception"; title = @"Exception";
} }
[panel setTitle: title [panel setTitleBar: nil
message: message icon: nil
def: defaultButton title: title
alt: alternateButton message: message
other: otherButton]; def: defaultButton
alt: alternateButton
other: otherButton];
[panel setUserInfo: [exception userInfo]]; [panel setUserInfo: [exception userInfo]];
result = [panel runModal]; result = [panel runModal];
[[panel userInfoPanel] orderOut:nil]; [[panel userInfoPanel] orderOut: nil];
[panel setUserInfo: nil]; [panel setUserInfo: nil];
RELEASE(panel); RELEASE(panel);
@ -1551,100 +1703,109 @@ int GSRunExceptionPanel(
RELEASE(_userInfoPanel); RELEASE(_userInfoPanel);
[super dealloc]; [super dealloc];
} }
- (id) init - (id) init
{ {
if ((self = [super init])) if ((self = [super init]))
{ {
[icoButton setEnabled:YES]; [icoButton setEnabled: YES];
[icoButton setTarget:self]; [icoButton setTarget: self];
[icoButton setAction:@selector(_icoAction:)]; [icoButton setAction: @selector(_icoAction:)];
} }
return self; return self;
} }
- (NSPanel *) userInfoPanel - (NSPanel *) userInfoPanel
{ {
return _userInfoPanel; return _userInfoPanel;
} }
- (void) setUserInfo:(NSDictionary *)userInfo; - (void) setUserInfo: (NSDictionary *)userInfo;
{ {
ASSIGN(_userInfo, userInfo); ASSIGN(_userInfo, userInfo);
[_browser reloadColumn:0]; [_browser reloadColumn: 0];
} }
- (void) _icoAction:(id)sender - (void) _icoAction: (id)sender
{ {
NSRect fr; NSRect fr;
if (_userInfoPanel) if (_userInfoPanel)
{ {
[_browser reloadColumn:0]; [_browser reloadColumn: 0];
return; return;
} }
fr = NSMakeRect(_frame.origin.x, _frame.origin.y + _frame.size.height + 15, fr = NSMakeRect(_frame.origin.x, _frame.origin.y + _frame.size.height + 15,
_frame.size.width, 108); _frame.size.width, 108);
_userInfoPanel = [[NSPanel alloc] initWithContentRect:fr _userInfoPanel = [[NSPanel alloc] initWithContentRect: fr
styleMask:NSTitledWindowMask styleMask: NSTitledWindowMask | NSResizableWindowMask
| NSResizableWindowMask backing: NSBackingStoreBuffered
backing:NSBackingStoreBuffered defer: NO];
defer:NO]; [_userInfoPanel setTitle: @"User Info Inspector"];
[_userInfoPanel setTitle:@"User Info Inspector"]; [_userInfoPanel setWorksWhenModal: YES];
[_userInfoPanel setWorksWhenModal:YES];
fr = NSMakeRect(8, 8, _frame.size.width - 16, 100); fr = NSMakeRect(8, 8, _frame.size.width - 16, 100);
_browser = [[NSBrowser alloc] initWithFrame:fr]; _browser = [[NSBrowser alloc] initWithFrame: fr];
[_browser setMaxVisibleColumns:2]; [_browser setMaxVisibleColumns: 2];
[_browser setDelegate:self]; [_browser setDelegate: self];
[_browser setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [_browser setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
[_browser reloadColumn:0]; [_browser reloadColumn: 0];
[[_userInfoPanel contentView] addSubview:_browser]; [[_userInfoPanel contentView] addSubview:_browser];
[_userInfoPanel makeKeyAndOrderFront:self]; [_userInfoPanel makeKeyAndOrderFront: self];
} }
- (int) browser:(id)browser - (int) browser: (id)browser
numberOfRowsInColumn:(int)col numberOfRowsInColumn: (int)col
{ {
if (col == 0) if (col == 0)
return [[_userInfo allKeys] count]; return [[_userInfo allKeys] count];
else else
{ {
id val = [[(NSCell *)[browser selectedCellInColumn:col - 1] representedObject] description]; id val;
volatile id foo = nil; volatile id foo = nil;
val = [[(NSCell *)[browser selectedCellInColumn: col - 1]
representedObject] description];
NS_DURING NS_DURING
foo = [val propertyList]; foo = [val propertyList];
val = foo; val = foo;
NS_HANDLER NS_HANDLER
NS_ENDHANDLER NS_ENDHANDLER
if ([val isKindOfClass:[NSArray class]]) if ([val isKindOfClass: [NSArray class]])
return [val count]; return [val count];
else if ([val isKindOfClass:[NSDictionary class]]) else if ([val isKindOfClass: [NSDictionary class]])
return [[val allKeys] count]; return [[val allKeys] count];
else return val != nil; else return val != nil;
} }
return 0; return 0;
} }
- (void) browser:(NSBrowser *)browser willDisplayCell:(NSBrowserCell *)cell atRow:(int)row - (void) browser: (NSBrowser *)browser
column:(int)column willDisplayCell: (NSBrowserCell *)cell
atRow: (int)row
column: (int)column
{ {
if (column == 0) if (column == 0)
{ {
id key = [[_userInfo allKeys] objectAtIndex:row]; id key = [[_userInfo allKeys] objectAtIndex: row];
id val = [_userInfo objectForKey:key]; id val = [_userInfo objectForKey: key];
[cell setLeaf:NO]; [cell setLeaf: NO];
[cell setStringValue:[key description]]; [cell setStringValue: [key description]];
[cell setRepresentedObject: val]; [cell setRepresentedObject: val];
} }
else else
{ {
volatile id val = [(NSCell *)[browser selectedCellInColumn:column - 1] representedObject]; volatile id val;
BOOL flag; BOOL flag;
if (!([val isKindOfClass:[NSArray class]] || [val isKindOfClass:[NSArray class]])) val = [(NSCell *)[browser selectedCellInColumn: column - 1]
representedObject];
if (!([val isKindOfClass: [NSArray class]]
|| [val isKindOfClass: [NSArray class]]))
{ {
volatile id foo = nil; volatile id foo = nil;
val = [val description]; val = [val description];
@ -1654,17 +1815,17 @@ column:(int)column
NS_HANDLER NS_HANDLER
NS_ENDHANDLER NS_ENDHANDLER
} }
flag = (!([val isKindOfClass:[NSArray class]] flag = (!([val isKindOfClass: [NSArray class]]
|| [val isKindOfClass:[NSDictionary class]])); || [val isKindOfClass: [NSDictionary class]]));
[cell setLeaf: flag];
if ([val isKindOfClass: [NSArray class]])
[cell setLeaf:flag];
if ([val isKindOfClass:[NSArray class]])
{ {
volatile id obj = [val objectAtIndex:row]; volatile id obj = [val objectAtIndex: row];
if (!([obj isKindOfClass:[NSArray class]] || [obj isKindOfClass:[NSArray class]]))
if (!([obj isKindOfClass: [NSArray class]]
|| [obj isKindOfClass: [NSArray class]]))
{ {
volatile id foo; volatile id foo;
obj = [[obj description] propertyList]; obj = [[obj description] propertyList];
@ -1675,28 +1836,30 @@ column:(int)column
NS_ENDHANDLER NS_ENDHANDLER
} }
if ([obj isKindOfClass:[NSArray class]]) if ([obj isKindOfClass: [NSArray class]])
{ {
[cell setRepresentedObject:obj]; [cell setRepresentedObject: obj];
[cell setLeaf:NO]; [cell setLeaf: NO];
[cell setStringValue:[NSString stringWithFormat:@"%@ %p", [obj class], obj]]; [cell setStringValue:
[NSString stringWithFormat: @"%@ %p", [obj class], obj]];
} }
else if ([obj isKindOfClass:[NSDictionary class]]) else if ([obj isKindOfClass: [NSDictionary class]])
{ {
[cell setRepresentedObject:obj]; [cell setRepresentedObject: obj];
[cell setLeaf:NO]; [cell setLeaf: NO];
[cell setStringValue:[NSString stringWithFormat:@"%@ %p", [obj class], obj]]; [cell setStringValue:
[NSString stringWithFormat: @"%@ %p", [obj class], obj]];
} }
else else
{ {
[cell setLeaf:YES]; [cell setLeaf: YES];
[cell setStringValue:[obj description]]; [cell setStringValue: [obj description]];
[cell setRepresentedObject:nil]; [cell setRepresentedObject: nil];
} }
} }
else if ([val isKindOfClass:[NSDictionary class]]) else if ([val isKindOfClass: [NSDictionary class]])
{ {
id key = [[val allKeys] objectAtIndex:row]; id key = [[val allKeys] objectAtIndex: row];
volatile id it = [(NSDictionary *)val objectForKey: key]; volatile id it = [(NSDictionary *)val objectForKey: key];
volatile id foo; volatile id foo;
foo = [it description]; foo = [it description];
@ -1705,22 +1868,27 @@ column:(int)column
it = foo; it = foo;
NS_HANDLER NS_HANDLER
NS_ENDHANDLER NS_ENDHANDLER
[cell setStringValue:[key description]]; [cell setStringValue: [key description]];
[cell setRepresentedObject:it]; [cell setRepresentedObject: it];
} }
else else
{ {
[cell setLeaf:YES]; [cell setLeaf: YES];
[cell setStringValue:[val description]]; [cell setStringValue: [val description]];
} }
} }
} }
- (id) browser:(NSBrowser *)browser titleOfColumn:(int)column
- (id) browser: (NSBrowser *)browser titleOfColumn: (int)column
{ {
if (column == 0) return @"userInfo"; id val;
id val = [(NSCell *)[browser selectedCellInColumn:column - 1] representedObject]; NSString *title;
NSString *title = [NSString stringWithFormat:@"%@ %p", [val class], val];
if (column == 0)
return @"userInfo";
val = [(NSCell *)[browser selectedCellInColumn: column - 1]
representedObject];
title = [NSString stringWithFormat: @"%@ %p", [val class], val];
return title; return title;
} }
@end @end