From 724999ee872d741f182af4eac6c137c5120fdd79 Mon Sep 17 00:00:00 2001 From: Kevin Ollivier Date: Thu, 5 Mar 2009 19:19:28 +0000 Subject: [PATCH] Use sheets for native file dialogs if the dialog has its parent set. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59346 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/osx/cocoa/private.h | 18 ++++++++++++ src/osx/cocoa/filedlg.mm | 50 +++++++++++++++++++++++++++++++--- src/osx/cocoa/utils.mm | 39 ++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 4 deletions(-) diff --git a/include/wx/osx/cocoa/private.h b/include/wx/osx/cocoa/private.h index 80845cfd8c..2e7de760b9 100644 --- a/include/wx/osx/cocoa/private.h +++ b/include/wx/osx/cocoa/private.h @@ -277,6 +277,24 @@ protected : void WXDLLIMPEXP_CORE wxOSXCocoaClassAddWXMethods(Class c); + /* + We need this for ShowModal, as the sheet just disables the parent window and + returns control to the app, whereas we don't want to return from ShowModal + until the sheet has been dismissed. + */ + @interface ModalDialogDelegate : NSObject + { + BOOL sheetFinished; + int resultCode; + } + + - (BOOL)finished; + - (int)code; + - (void)waitForSheetToFinish; + - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; + @end + + #endif // __OBJC__ // NSCursor diff --git a/src/osx/cocoa/filedlg.mm b/src/osx/cocoa/filedlg.mm index 462ee154e4..a509c1bb63 100644 --- a/src/osx/cocoa/filedlg.mm +++ b/src/osx/cocoa/filedlg.mm @@ -51,7 +51,6 @@ wxFileDialog::wxFileDialog( { } - NSArray* GetTypesFromFilter( const wxString filter ) { NSMutableArray* types = nil; @@ -149,6 +148,14 @@ int wxFileDialog::ShowModal() m_path = wxEmptyString; m_fileNames.Clear(); + + wxNonOwnedWindow* parentWindow = NULL; + int returnCode = -1; + + if (GetParent()) + { + parentWindow = dynamic_cast(wxGetTopLevelParent(GetParent())); + } if (HasFlag(wxFD_SAVE)) { @@ -164,8 +171,25 @@ int wxFileDialog::ShowModal() if ( HasFlag(wxFD_OVERWRITE_PROMPT) ) { } - - if ( [sPanel runModalForDirectory:dir.AsNSString() file:file.AsNSString() ] == NSOKButton ) + + if (parentWindow) + { + NSWindow* nativeParent = parentWindow->GetWXWindow(); + ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init]; + [sPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString() + modalForWindow: nativeParent modalDelegate: sheetDelegate + didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo: nil]; + [sheetDelegate waitForSheetToFinish]; + result = [sheetDelegate code]; + [sheetDelegate release]; + } + else + { + result = [sPanel runModalForDirectory:dir.AsNSString() file:file.AsNSString() ]; + } + + if (result == NSOKButton ) { panel = sPanel; result = wxID_OK; @@ -187,7 +211,25 @@ int wxFileDialog::ShowModal() [oPanel setCanChooseFiles:YES]; [oPanel setMessage:cf.AsNSString()]; - if ( [oPanel runModalForDirectory:dir.AsNSString() file:file.AsNSString() types:types] == NSOKButton ) + if (parentWindow) + { + NSWindow* nativeParent = parentWindow->GetWXWindow(); + ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init]; + [oPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString() + types: types modalForWindow: nativeParent + modalDelegate: sheetDelegate + didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo: nil]; + [sheetDelegate waitForSheetToFinish]; + result = [sheetDelegate code]; + [sheetDelegate release]; + } + else + { + result = [oPanel runModalForDirectory:dir.AsNSString() + file:file.AsNSString() types:types]; + } + if (result == NSOKButton ) { panel = oPanel; result = wxID_OK; diff --git a/src/osx/cocoa/utils.mm b/src/osx/cocoa/utils.mm index 48bc5c9a96..39d2287aa2 100644 --- a/src/osx/cocoa/utils.mm +++ b/src/osx/cocoa/utils.mm @@ -138,6 +138,45 @@ void wxMacWakeUp() } @end +/* + allows ShowModal to work when using sheets. + see include/wx/osx/cocoa/private.h for more info +*/ +@implementation ModalDialogDelegate +- (id)init +{ + [super init]; + sheetFinished = NO; + resultCode = -1; + return self; +} + +- (BOOL)finished +{ + return sheetFinished; +} + +- (int)code +{ + return resultCode; +} + +- (void)waitForSheetToFinish +{ + while (!sheetFinished) + { + wxSafeYield(); + } +} + +- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +{ + resultCode = returnCode; + sheetFinished = YES; + [sheet orderOut: self]; +} +@end + bool wxApp::DoInitGui() { [NSApplication sharedApplication]; -- 2.45.2