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