1//
2// NSAlert+SynchronousSheet.h
3//
4// Created by Philipp Mayerhofer on 6/10/11.
5// Copyright 2011 Incredible Bee Ltd. Released under the New BSD License.
6//
7
8#import "alert_sheet.h"
9
10
11// Private methods -- use prefixes to avoid collisions with Apple's methods
12@interface NSAlert ()
13-(IBAction) BE_stopSynchronousSheet:(id)sender; // hide sheet & stop modal
14-(void) BE_beginSheetModalForWindow:(NSWindow *)aWindow;
15@end
16
17
18@implementation NSAlert (SynchronousSheet)
19
20-(NSInteger) runModalSheetForWindow:(NSWindow *)aWindow {
21// Set ourselves as the target for button clicks
22for (NSButton *button in [self buttons]) {
23[button setTarget:self];
24[button setAction:@selector(BE_stopSynchronousSheet:)];
25}
26
27// Bring up the sheet and wait until stopSynchronousSheet is triggered by a button click
28[self performSelectorOnMainThread:@selector(BE_beginSheetModalForWindow:) withObject:aWindow waitUntilDone:YES];
29NSInteger modalCode = [NSApp runModalForWindow:[self window]];
30
31// This is called only after stopSynchronousSheet is called (that is,
32// one of the buttons is clicked)
33[NSApp performSelectorOnMainThread:@selector(endSheet:) withObject:[self window] waitUntilDone:YES];
34
35// Remove the sheet from the screen
36[[self window] performSelectorOnMainThread:@selector(orderOut:) withObject:self waitUntilDone:YES];
37
38return modalCode;
39}
40
41-(NSInteger) runModalSheet {
42return [self runModalSheetForWindow:[NSApp mainWindow]];
43}
44
45
46#pragma mark Private methods
47
48-(IBAction) BE_stopSynchronousSheet:(id)sender {
49// See which of the buttons was clicked
50NSUInteger clickedButtonIndex = [[self buttons] indexOfObject:sender];
51
52// Be consistent with Apple's documentation (see NSAlert's addButtonWithTitle) so that
53// the fourth button is numbered NSAlertThirdButtonReturn + 1, and so on
54//
55// TODO: handle case when alert created with alertWithMessageText:... where the buttons
56// have values NSAlertDefaultReturn, NSAlertAlternateReturn, ... instead (see also
57// the documentation for the runModal method)
58NSInteger modalCode = 0;
59if (clickedButtonIndex == NSAlertFirstButtonReturn)
60modalCode = NSAlertFirstButtonReturn;
61else if (clickedButtonIndex == NSAlertSecondButtonReturn)
62modalCode = NSAlertSecondButtonReturn;
63else if (clickedButtonIndex == NSAlertThirdButtonReturn)
64modalCode = NSAlertThirdButtonReturn;
65else
66modalCode = NSAlertThirdButtonReturn + (clickedButtonIndex - 2);
67
68[NSApp stopModalWithCode:modalCode];
69}
70
71-(void) BE_beginSheetModalForWindow:(NSWindow *)aWindow {
72[self beginSheetModalForWindow:aWindow modalDelegate:nil didEndSelector:nil contextInfo:nil];
73}
74
75@end
76