X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/440e5cb2fa76b5a722c14065f5d3e87f499daf33..cd0f218cdd3114dc6770bc9f6703225aabb5a2de:/src/osx/cocoa/msgdlg.mm diff --git a/src/osx/cocoa/msgdlg.mm b/src/osx/cocoa/msgdlg.mm index ab6ffb99e6..40ed938450 100644 --- a/src/osx/cocoa/msgdlg.mm +++ b/src/osx/cocoa/msgdlg.mm @@ -4,7 +4,7 @@ // Author: Stefan Csomor // Modified by: // Created: 04/01/98 -// RCS-ID: $Id: msgdlg.cpp 54129 2008-06-11 19:30:52Z SC $ +// RCS-ID: $Id$ // Copyright: (c) Stefan Csomor // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -18,41 +18,61 @@ #include "wx/app.h" #endif +#include "wx/control.h" #include "wx/thread.h" +#include "wx/evtloop.h" +#include "wx/modalhook.h" #include "wx/osx/private.h" IMPLEMENT_CLASS(wxMessageDialog, wxDialog) +namespace +{ + NSAlertStyle GetAlertStyleFromWXStyle( long style ) + { + NSAlertStyle alertType = NSWarningAlertStyle; + if (style & wxICON_EXCLAMATION) + alertType = NSCriticalAlertStyle; + else if (style & wxICON_HAND) + alertType = NSWarningAlertStyle; + else if (style & wxICON_INFORMATION) + alertType = NSInformationalAlertStyle; + else if (style & wxICON_QUESTION) + alertType = NSInformationalAlertStyle; + return alertType; + } +} + wxMessageDialog::wxMessageDialog(wxWindow *parent, const wxString& message, const wxString& caption, long style, const wxPoint& WXUNUSED(pos)) - : wxMessageDialogWithCustomLabels(parent, message, caption, style) + : wxMessageDialogBase(parent, message, caption, style) +{ + m_sheetDelegate = [[ModalDialogDelegate alloc] init]; + [(ModalDialogDelegate*)m_sheetDelegate setImplementation: this]; +} + +wxMessageDialog::~wxMessageDialog() { + [m_sheetDelegate release]; } int wxMessageDialog::ShowModal() { + WX_HOOK_MODAL_DIALOG(); + + wxCFEventLoopPauseIdleEvents pause; + int resultbutton = wxID_CANCEL; const long style = GetMessageDialogStyle(); wxASSERT_MSG( (style & 0x3F) != wxYES, wxT("this style is not supported on Mac") ); - NSAlertStyle alertType = NSWarningAlertStyle; - if (style & wxICON_EXCLAMATION) - alertType = NSCriticalAlertStyle; - else if (style & wxICON_HAND) - alertType = NSWarningAlertStyle; - else if (style & wxICON_INFORMATION) - alertType = NSInformationalAlertStyle; - else if (style & wxICON_QUESTION) - alertType = NSInformationalAlertStyle; - - // work out what to display // if the extended text is empty then we use the caption as the title // and the message as the text (for backwards compatibility) @@ -81,12 +101,14 @@ int wxMessageDialog::ShowModal() wxCFStringRef cfTitle( msgtitle, GetFont().GetEncoding() ); wxCFStringRef cfText( msgtext, GetFont().GetEncoding() ); - wxCFStringRef cfNoString( GetNoLabel(), GetFont().GetEncoding() ); - wxCFStringRef cfYesString( GetYesLabel(), GetFont().GetEncoding() ); - wxCFStringRef cfOKString( GetOKLabel(), GetFont().GetEncoding()) ; - wxCFStringRef cfCancelString( GetCancelLabel(), GetFont().GetEncoding() ); + wxCFStringRef cfNoString( wxControl::GetLabelText(GetNoLabel()), GetFont().GetEncoding() ); + wxCFStringRef cfYesString( wxControl::GetLabelText(GetYesLabel()), GetFont().GetEncoding() ); + wxCFStringRef cfOKString( wxControl::GetLabelText(GetOKLabel()), GetFont().GetEncoding()) ; + wxCFStringRef cfCancelString( wxControl::GetLabelText(GetCancelLabel()), GetFont().GetEncoding() ); - int buttonId[4] = { 0, 0, 0, wxID_CANCEL /* time-out */ }; + NSAlertStyle alertType = GetAlertStyleFromWXStyle(style); + + int m_buttonId[4] = { 0, 0, 0, wxID_CANCEL /* time-out */ }; if (style & wxYES_NO) { @@ -94,133 +116,193 @@ int wxMessageDialog::ShowModal() { defaultButtonTitle = cfNoString; alternateButtonTitle = cfYesString; - buttonId[0] = wxID_NO; - buttonId[1] = wxID_YES; + m_buttonId[0] = wxID_NO; + m_buttonId[1] = wxID_YES; } else { defaultButtonTitle = cfYesString; alternateButtonTitle = cfNoString; - buttonId[0] = wxID_YES; - buttonId[1] = wxID_NO; + m_buttonId[0] = wxID_YES; + m_buttonId[1] = wxID_NO; } if (style & wxCANCEL) { otherButtonTitle = cfCancelString; - buttonId[2] = wxID_CANCEL; + m_buttonId[2] = wxID_CANCEL; } } else { // the MSW implementation even shows an OK button if it is not specified, we'll do the same - buttonId[0] = wxID_OK; + m_buttonId[0] = wxID_OK; // using null as default title does not work on earlier systems defaultButtonTitle = cfOKString; if (style & wxCANCEL) { alternateButtonTitle = cfCancelString; - buttonId[1] = wxID_CANCEL; + m_buttonId[1] = wxID_CANCEL; } } + wxASSERT_MSG( !(style & wxHELP), "wxHELP not supported in non-GUI thread" ); + CFOptionFlags exitButton; OSStatus err = CFUserNotificationDisplayAlert( 0, alertType, NULL, NULL, NULL, cfTitle, cfText, defaultButtonTitle, alternateButtonTitle, otherButtonTitle, &exitButton ); if (err == noErr) - resultbutton = buttonId[exitButton]; + resultbutton = m_buttonId[exitButton]; } else { - NSAlert* alert = [[NSAlert alloc] init]; - - wxCFStringRef cfNoString( GetNoLabel(), GetFont().GetEncoding() ); - wxCFStringRef cfYesString( GetYesLabel(), GetFont().GetEncoding() ); - wxCFStringRef cfOKString( GetOKLabel(), GetFont().GetEncoding() ); - wxCFStringRef cfCancelString( GetCancelLabel(), GetFont().GetEncoding() ); + NSAlert* alert = (NSAlert*)ConstructNSAlert(); - wxCFStringRef cfTitle( msgtitle, GetFont().GetEncoding() ); - wxCFStringRef cfText( msgtext, GetFont().GetEncoding() ); + int button = -1; + button = [alert runModal]; + [alert release]; + ModalFinishedCallback(alert, button); + } - [alert setMessageText:cfTitle.AsNSString()]; - [alert setInformativeText:cfText.AsNSString()]; - - int buttonId[3] = { 0, 0, 0 }; - int buttonCount = 0; + return GetReturnCode(); +} - if (style & wxYES_NO) - { - if ( style & wxNO_DEFAULT ) - { - [alert addButtonWithTitle:cfNoString.AsNSString()]; - buttonId[ buttonCount++ ] = wxID_NO; - [alert addButtonWithTitle:cfYesString.AsNSString()]; - buttonId[ buttonCount++ ] = wxID_YES; - } - else - { - [alert addButtonWithTitle:cfYesString.AsNSString()]; - buttonId[ buttonCount++ ] = wxID_YES; - [alert addButtonWithTitle:cfNoString.AsNSString()]; - buttonId[ buttonCount++ ] = wxID_NO; - } +void wxMessageDialog::ShowWindowModal() +{ + NSAlert* alert = (NSAlert*)ConstructNSAlert(); - if (style & wxCANCEL) - { - [alert addButtonWithTitle:cfCancelString.AsNSString()]; - buttonId[ buttonCount++ ] = wxID_CANCEL; - } - } - // the MSW implementation even shows an OK button if it is not specified, we'll do the same + wxNonOwnedWindow* parentWindow = NULL; + + m_modality = wxDIALOG_MODALITY_WINDOW_MODAL; + + if (GetParent()) + parentWindow = dynamic_cast(wxGetTopLevelParent(GetParent())); + + wxASSERT_MSG(parentWindow, "Window modal display requires parent."); + + if (parentWindow) + { + NSWindow* nativeParent = parentWindow->GetWXWindow(); + [alert beginSheetModalForWindow: nativeParent modalDelegate: m_sheetDelegate + didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo: nil]; + } +} + +void wxMessageDialog::ModalFinishedCallback(void* WXUNUSED(panel), int resultCode) +{ + int resultbutton = wxID_CANCEL; + if ( resultCode < NSAlertFirstButtonReturn ) + resultbutton = wxID_CANCEL; + else + { + if ( resultCode - NSAlertFirstButtonReturn < m_buttonCount ) + resultbutton = m_buttonId[ resultCode - NSAlertFirstButtonReturn ]; else - { - [alert addButtonWithTitle:cfOKString.AsNSString()]; - buttonId[ buttonCount++ ] = wxID_OK; - if (style & wxCANCEL) - { - [alert addButtonWithTitle:cfCancelString.AsNSString()]; - buttonId[ buttonCount++ ] = wxID_CANCEL; - } - } + resultbutton = wxID_CANCEL; + } + SetReturnCode(resultbutton); + + if (GetModality() == wxDIALOG_MODALITY_WINDOW_MODAL) + SendWindowModalDialogEvent ( wxEVT_WINDOW_MODAL_DIALOG_CLOSED ); +} +void* wxMessageDialog::ConstructNSAlert() +{ + const long style = GetMessageDialogStyle(); - wxNonOwnedWindow* parentWindow = NULL; - int button = -1; - - if (GetParent()) + wxASSERT_MSG( (style & 0x3F) != wxYES, wxT("this style is not supported on Mac") ); + + // work out what to display + // if the extended text is empty then we use the caption as the title + // and the message as the text (for backwards compatibility) + // but if the extended message is not empty then we use the message as the title + // and the extended message as the text because that makes more sense + + wxString msgtitle,msgtext; + if(m_extendedMessage.IsEmpty()) + { + msgtitle = m_caption; + msgtext = m_message; + } + else + { + msgtitle = m_message; + msgtext = m_extendedMessage; + } + + NSAlert* alert = [[NSAlert alloc] init]; + NSAlertStyle alertType = GetAlertStyleFromWXStyle(style); + + wxCFStringRef cfNoString( wxControl::GetLabelText(GetNoLabel()), GetFont().GetEncoding() ); + wxCFStringRef cfYesString( wxControl::GetLabelText(GetYesLabel()), GetFont().GetEncoding() ); + wxCFStringRef cfOKString( wxControl::GetLabelText(GetOKLabel()), GetFont().GetEncoding() ); + wxCFStringRef cfCancelString( wxControl::GetLabelText(GetCancelLabel()), GetFont().GetEncoding() ); + + wxCFStringRef cfTitle( msgtitle, GetFont().GetEncoding() ); + wxCFStringRef cfText( msgtext, GetFont().GetEncoding() ); + + [alert setMessageText:cfTitle.AsNSString()]; + [alert setInformativeText:cfText.AsNSString()]; + [alert setAlertStyle:alertType]; + + m_buttonCount = 0; + + if (style & wxYES_NO) + { + if ( style & wxNO_DEFAULT ) { - parentWindow = dynamic_cast(wxGetTopLevelParent(GetParent())); + [alert addButtonWithTitle:cfNoString.AsNSString()]; + m_buttonId[ m_buttonCount++ ] = wxID_NO; + [alert addButtonWithTitle:cfYesString.AsNSString()]; + m_buttonId[ m_buttonCount++ ] = wxID_YES; } - - /* - if (parentWindow) + else { - NSWindow* nativeParent = parentWindow->GetWXWindow(); - ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init]; - [alert beginSheetModalForWindow: nativeParent modalDelegate: sheetDelegate - didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:) - contextInfo: nil]; - [sheetDelegate waitForSheetToFinish]; - button = [sheetDelegate code]; - [sheetDelegate release]; + [alert addButtonWithTitle:cfYesString.AsNSString()]; + m_buttonId[ m_buttonCount++ ] = wxID_YES; + [alert addButtonWithTitle:cfNoString.AsNSString()]; + m_buttonId[ m_buttonCount++ ] = wxID_NO; } - else -*/ + + if (style & wxCANCEL) { - button = [alert runModal]; + [alert addButtonWithTitle:cfCancelString.AsNSString()]; + m_buttonId[ m_buttonCount++ ] = wxID_CANCEL; } - [alert release]; - - if ( button < NSAlertFirstButtonReturn ) - resultbutton = wxID_CANCEL; - else + } + // the MSW implementation even shows an OK button if it is not specified, we'll do the same + else + { + if ( style & wxCANCEL_DEFAULT ) { - if ( button - NSAlertFirstButtonReturn < buttonCount ) - resultbutton = buttonId[ button - NSAlertFirstButtonReturn ]; - else - resultbutton = wxID_CANCEL; + [alert addButtonWithTitle:cfCancelString.AsNSString()]; + m_buttonId[ m_buttonCount++ ] = wxID_CANCEL; + + [alert addButtonWithTitle:cfOKString.AsNSString()]; + m_buttonId[ m_buttonCount++ ] = wxID_OK; } + else + { + [alert addButtonWithTitle:cfOKString.AsNSString()]; + m_buttonId[ m_buttonCount++ ] = wxID_OK; + if (style & wxCANCEL) + { + [alert addButtonWithTitle:cfCancelString.AsNSString()]; + m_buttonId[ m_buttonCount++ ] = wxID_CANCEL; + } + } + + } + + if ( style & wxHELP ) + { + wxCFStringRef cfHelpString( GetHelpLabel(), GetFont().GetEncoding() ); + [alert addButtonWithTitle:cfHelpString.AsNSString()]; + m_buttonId[ m_buttonCount++ ] = wxID_HELP; } - return resultbutton; + wxASSERT_MSG( m_buttonCount <= WXSIZEOF(m_buttonId), "Too many buttons" ); + + return alert; }