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>
* Source/NSAttributedString.m: Wrap excessively long lines

View file

@ -63,6 +63,7 @@ enum {
id _delegate;
NSAlertStyle _style;
BOOL _shows_help;
int _result;
}
+ (NSAlert *) alertWithMessageText: (NSString *)messageTitle
@ -71,55 +72,28 @@ enum {
otherButton: (NSString *)otherButtonTitle
informativeTextWithFormat: (NSString *)format, ...;
//
// Alert text
//
- (void)setInformativeText:(NSString *)informativeText;
- (NSString *)informativeText;
- (void)setMessageText:(NSString *)messageText;
- (NSString *)messageText;
//
// Alert icon
//
- (void)setIcon:(NSImage *)icon;
- (NSImage *)icon;
//
// Buttons
//
- (NSButton *) addButtonWithTitle: (NSString *)aTitle;
- (NSArray *)buttons;
//
// Help
//
- (void)setShowsHelp:(BOOL)showsHelp;
- (BOOL)showsHelp;
- (void)setHelpAnchor:(NSString *)anchor;
- (NSString *)helpAnchor;
//
// Alert style
//
- (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;
- (NSArray *) buttons;
- (id) delegate;
- (NSString *) helpAnchor;
- (NSImage *) icon;
- (NSString *) informativeText;
- (NSString *) messageText;
- (int) runModal;
- (void) setAlertStyle: (NSAlertStyle)style;
- (void) setDelegate: (id)delegate;
- (void) setHelpAnchor: (NSString *)anchor;
- (void) setIcon: (NSImage *)icon;
- (void) setInformativeText: (NSString *)informativeText;
- (void) setMessageText: (NSString *)messageText;
- (void) setShowsHelp: (BOOL)showsHelp;
- (BOOL) showsHelp;
- (id) window;
@end

View file

@ -35,6 +35,7 @@
#include "config.h"
#include <Foundation/NSDebug.h>
#include <Foundation/NSBundle.h>
#include <Foundation/NSString.h>
#include "AppKit/NSAlert.h"
@ -53,6 +54,7 @@
#include "GNUstepGUI/GMAppKit.h"
#include "GNUstepGUI/GMArchiver.h"
extern NSThread *GSAppKitThread;
#ifdef ALERT_TITLE
static NSString *defaultTitle = @"Alert";
@ -183,7 +185,9 @@ static GSAlertPanel *criticalAlertPanel = nil;
- (id) _initWithoutGModel;
- (int) runModal;
- (void) setTitle: (NSString*)title
- (void) setTitleBar: (NSString*)titleBar
icon: (NSImage*)icon
title: (NSString*)title
message: (NSString*)message
def: (NSString*)defaultButton
alt: (NSString*)alternateButton
@ -716,18 +720,28 @@ setControl(NSView* content, id control, NSString *title)
}
- (int) runModal
{
if (GSCurrentThread() != GSAppKitThread)
{
[self performSelectorOnMainThread: _cmd
withObject: nil
waitUntilDone: YES];
}
else
{
if (isGreen)
{
[self sizePanelToFit];
}
[NSApp runModalForWindow: self];
[self orderOut: self];
}
return result;
}
- (void) setTitle: (NSString*)title
- (void) setTitleBar: (NSString*)titleBar
icon: (NSImage*)icon
title: (NSString*)title
message: (NSString*)message
def: (NSString*)defaultButton
alt: (NSString*)alternateButton
@ -735,6 +749,18 @@ setControl(NSView* content, id control, NSString *title)
{
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);
if (useControl(scroll))
{
@ -821,7 +847,7 @@ setControl(NSView* content, id control, NSString *title)
}
}
}
[self sizePanelToFit];
isGreen = YES;
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".
*/
static GSAlertPanel*
getSomePanel(
GSAlertPanel **instance,
NSString *defaultTitle,
NSString *title,
NSString *message,
NSString *defaultButton,
NSString *alternateButton,
NSString *otherButton)
@interface _GSAlertCreation : NSObject
{
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 isActivePanel])
@ -919,21 +985,81 @@ getSomePanel(
*instance = panel;
}
if (title == nil)
{
title = defaultTitle;
}
if (defaultTitle != nil)
{
[panel setTitle: defaultTitle];
}
[panel setTitle: title
[panel setTitleBar: defaultTitle
icon: nil
title: title
message: message
def: defaultButton
alt: alternateButton
other: otherButton];
[panel sizePanelToFit];
}
- (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)
{
_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];
}
return panel;
}
@ -1429,6 +1555,14 @@ void NSBeginInformationalAlertSheet(NSString *title,
}
- (void) _setupPanel
{
if (GSCurrentThread() != GSAppKitThread)
{
[self performSelectorOnMainThread: _cmd
withObject: nil
waitUntilDone: YES];
}
else
{
GSAlertPanel *panel;
NSString *title;
@ -1449,27 +1583,34 @@ void NSBeginInformationalAlertSheet(NSString *title,
title = @"Alert";
break;
}
[panel setTitle: title];
// FIXME: Should also set the icon
[panel setTitle: _informative_text
[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 sizePanelToFit];
}
}
- (int) runModal
{
int result;
if (GSCurrentThread() != GSAppKitThread)
{
[self performSelectorOnMainThread: _cmd
withObject: nil
waitUntilDone: YES];
return _result;
}
else
{
[self _setupPanel];
[NSApp runModalForWindow: _window];
[_window orderOut: self];
result = [(GSAlertPanel*)_window result];
_result = [(GSAlertPanel*)_window result];
DESTROY(_window);
return result;
return _result;
}
}
- (void) beginSheetModalForWindow: (NSWindow *)window
@ -1478,6 +1619,14 @@ void NSBeginInformationalAlertSheet(NSString *title,
contextInfo: (void *)contextInfo
{
[self _setupPanel];
if (GSCurrentThread() != GSAppKitThread)
{
[self performSelectorOnMainThread: _cmd
withObject: nil
waitUntilDone: YES];
}
else
{
[NSApp beginSheet: _window
modalForWindow: window
modalDelegate: delegate
@ -1485,6 +1634,7 @@ void NSBeginInformationalAlertSheet(NSString *title,
contextInfo: contextInfo];
DESTROY(_window);
}
}
- (id) window
{
@ -1529,7 +1679,9 @@ int GSRunExceptionPanel(
title = @"Exception";
}
[panel setTitle: title
[panel setTitleBar: nil
icon: nil
title: title
message: message
def: defaultButton
alt: alternateButton
@ -1551,6 +1703,7 @@ int GSRunExceptionPanel(
RELEASE(_userInfoPanel);
[super dealloc];
}
- (id) init
{
if ((self = [super init]))
@ -1562,6 +1715,7 @@ int GSRunExceptionPanel(
return self;
}
- (NSPanel *) userInfoPanel
{
return _userInfoPanel;
@ -1586,8 +1740,7 @@ int GSRunExceptionPanel(
fr = NSMakeRect(_frame.origin.x, _frame.origin.y + _frame.size.height + 15,
_frame.size.width, 108);
_userInfoPanel = [[NSPanel alloc] initWithContentRect: fr
styleMask:NSTitledWindowMask
| NSResizableWindowMask
styleMask: NSTitledWindowMask | NSResizableWindowMask
backing: NSBackingStoreBuffered
defer: NO];
[_userInfoPanel setTitle: @"User Info Inspector"];
@ -1610,8 +1763,11 @@ numberOfRowsInColumn:(int)col
return [[_userInfo allKeys] count];
else
{
id val = [[(NSCell *)[browser selectedCellInColumn:col - 1] representedObject] description];
id val;
volatile id foo = nil;
val = [[(NSCell *)[browser selectedCellInColumn: col - 1]
representedObject] description];
NS_DURING
foo = [val propertyList];
val = foo;
@ -1627,7 +1783,9 @@ numberOfRowsInColumn:(int)col
return 0;
}
- (void) browser:(NSBrowser *)browser willDisplayCell:(NSBrowserCell *)cell atRow:(int)row
- (void) browser: (NSBrowser *)browser
willDisplayCell: (NSBrowserCell *)cell
atRow: (int)row
column: (int)column
{
if (column == 0)
@ -1641,10 +1799,13 @@ column:(int)column
}
else
{
volatile id val = [(NSCell *)[browser selectedCellInColumn:column - 1] representedObject];
volatile id val;
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;
val = [val description];
@ -1657,14 +1818,14 @@ column:(int)column
flag = (!([val isKindOfClass: [NSArray class]]
|| [val isKindOfClass: [NSDictionary class]]));
[cell setLeaf: flag];
if ([val isKindOfClass: [NSArray class]])
{
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;
obj = [[obj description] propertyList];
@ -1679,13 +1840,15 @@ column:(int)column
{
[cell setRepresentedObject: obj];
[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]])
{
[cell setRepresentedObject: obj];
[cell setLeaf: NO];
[cell setStringValue:[NSString stringWithFormat:@"%@ %p", [obj class], obj]];
[cell setStringValue:
[NSString stringWithFormat: @"%@ %p", [obj class], obj]];
}
else
{
@ -1713,14 +1876,19 @@ column:(int)column
[cell setLeaf: YES];
[cell setStringValue: [val description]];
}
}
}
}
}
- (id) browser: (NSBrowser *)browser titleOfColumn: (int)column
{
if (column == 0) return @"userInfo";
id val = [(NSCell *)[browser selectedCellInColumn:column - 1] representedObject];
NSString *title = [NSString stringWithFormat:@"%@ %p", [val class], val];
id val;
NSString *title;
if (column == 0)
return @"userInfo";
val = [(NSCell *)[browser selectedCellInColumn: column - 1]
representedObject];
title = [NSString stringWithFormat: @"%@ %p", [val class], val];
return title;
}
@end