]> git.saurik.com Git - wxWidgets.git/blame - src/osx/cocoa/msgdlg.mm
Add wxCALL_FOR_EACH() macro.
[wxWidgets.git] / src / osx / cocoa / msgdlg.mm
CommitLineData
524c47aa
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/osx/cocoa/msgdlg.mm
3// Purpose: wxMessageDialog
4// Author: Stefan Csomor
5// Modified by:
6// Created: 04/01/98
a9a4f229 7// RCS-ID: $Id$
524c47aa
SC
8// Copyright: (c) Stefan Csomor
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#include "wx/msgdlg.h"
15
16#ifndef WX_PRECOMP
17 #include "wx/intl.h"
18 #include "wx/app.h"
19#endif
20
37e48466 21#include "wx/control.h"
524c47aa 22#include "wx/thread.h"
ffbee810 23#include "wx/evtloop.h"
524c47aa
SC
24#include "wx/osx/private.h"
25
26
27IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
28
29
0aeac464
SC
30namespace
31{
32 NSAlertStyle GetAlertStyleFromWXStyle( long style )
33 {
34 NSAlertStyle alertType = NSWarningAlertStyle;
35 if (style & wxICON_EXCLAMATION)
36 alertType = NSCriticalAlertStyle;
37 else if (style & wxICON_HAND)
38 alertType = NSWarningAlertStyle;
39 else if (style & wxICON_INFORMATION)
40 alertType = NSInformationalAlertStyle;
41 else if (style & wxICON_QUESTION)
42 alertType = NSInformationalAlertStyle;
43 return alertType;
44 }
45}
46
524c47aa
SC
47wxMessageDialog::wxMessageDialog(wxWindow *parent,
48 const wxString& message,
49 const wxString& caption,
50 long style,
51 const wxPoint& WXUNUSED(pos))
ede7b017 52 : wxMessageDialogBase(parent, message, caption, style)
524c47aa 53{
4d3e2dc9
SC
54 m_sheetDelegate = [[ModalDialogDelegate alloc] init];
55 [(ModalDialogDelegate*)m_sheetDelegate setImplementation: this];
56}
57
58wxMessageDialog::~wxMessageDialog()
59{
60 [m_sheetDelegate release];
524c47aa
SC
61}
62
63int wxMessageDialog::ShowModal()
64{
c657294b 65 wxCFEventLoopPauseIdleEvents pause;
ffbee810 66
524c47aa
SC
67 int resultbutton = wxID_CANCEL;
68
69 const long style = GetMessageDialogStyle();
70
71 wxASSERT_MSG( (style & 0x3F) != wxYES, wxT("this style is not supported on Mac") );
72
524c47aa
SC
73 // work out what to display
74 // if the extended text is empty then we use the caption as the title
75 // and the message as the text (for backwards compatibility)
76 // but if the extended message is not empty then we use the message as the title
77 // and the extended message as the text because that makes more sense
78
79 wxString msgtitle,msgtext;
80 if(m_extendedMessage.IsEmpty())
81 {
82 msgtitle = m_caption;
83 msgtext = m_message;
84 }
85 else
86 {
87 msgtitle = m_message;
88 msgtext = m_extendedMessage;
89 }
90
91
92 if ( !wxIsMainThread() )
93 {
94 CFStringRef defaultButtonTitle = NULL;
95 CFStringRef alternateButtonTitle = NULL;
96 CFStringRef otherButtonTitle = NULL;
97
98 wxCFStringRef cfTitle( msgtitle, GetFont().GetEncoding() );
99 wxCFStringRef cfText( msgtext, GetFont().GetEncoding() );
100
4d3b8623
SC
101 wxCFStringRef cfNoString( wxControl::GetLabelText(GetNoLabel()), GetFont().GetEncoding() );
102 wxCFStringRef cfYesString( wxControl::GetLabelText(GetYesLabel()), GetFont().GetEncoding() );
103 wxCFStringRef cfOKString( wxControl::GetLabelText(GetOKLabel()), GetFont().GetEncoding()) ;
104 wxCFStringRef cfCancelString( wxControl::GetLabelText(GetCancelLabel()), GetFont().GetEncoding() );
524c47aa 105
0aeac464
SC
106 NSAlertStyle alertType = GetAlertStyleFromWXStyle(style);
107
bfa92264 108 int m_buttonId[4] = { 0, 0, 0, wxID_CANCEL /* time-out */ };
524c47aa
SC
109
110 if (style & wxYES_NO)
111 {
112 if ( style & wxNO_DEFAULT )
113 {
114 defaultButtonTitle = cfNoString;
115 alternateButtonTitle = cfYesString;
bfa92264
KO
116 m_buttonId[0] = wxID_NO;
117 m_buttonId[1] = wxID_YES;
524c47aa
SC
118 }
119 else
120 {
121 defaultButtonTitle = cfYesString;
122 alternateButtonTitle = cfNoString;
bfa92264
KO
123 m_buttonId[0] = wxID_YES;
124 m_buttonId[1] = wxID_NO;
524c47aa
SC
125 }
126 if (style & wxCANCEL)
127 {
128 otherButtonTitle = cfCancelString;
bfa92264 129 m_buttonId[2] = wxID_CANCEL;
524c47aa
SC
130 }
131 }
132 else
133 {
134 // the MSW implementation even shows an OK button if it is not specified, we'll do the same
bfa92264 135 m_buttonId[0] = wxID_OK;
524c47aa
SC
136 // using null as default title does not work on earlier systems
137 defaultButtonTitle = cfOKString;
138 if (style & wxCANCEL)
139 {
140 alternateButtonTitle = cfCancelString;
bfa92264 141 m_buttonId[1] = wxID_CANCEL;
524c47aa
SC
142 }
143 }
144
7112cdd1
VZ
145 wxASSERT_MSG( !(style & wxHELP), "wxHELP not supported in non-GUI thread" );
146
524c47aa
SC
147 CFOptionFlags exitButton;
148 OSStatus err = CFUserNotificationDisplayAlert(
149 0, alertType, NULL, NULL, NULL, cfTitle, cfText,
150 defaultButtonTitle, alternateButtonTitle, otherButtonTitle, &exitButton );
151 if (err == noErr)
bfa92264 152 resultbutton = m_buttonId[exitButton];
524c47aa
SC
153 }
154 else
155 {
bfa92264 156 NSAlert* alert = (NSAlert*)ConstructNSAlert();
03647350 157
bfa92264
KO
158 int button = -1;
159 button = [alert runModal];
160 [alert release];
161 ModalFinishedCallback(alert, button);
162 }
524c47aa 163
bfa92264
KO
164 return GetReturnCode();
165}
524c47aa 166
bfa92264
KO
167void wxMessageDialog::ShowWindowModal()
168{
169 NSAlert* alert = (NSAlert*)ConstructNSAlert();
03647350 170
bfa92264 171 wxNonOwnedWindow* parentWindow = NULL;
524c47aa 172
bfa92264 173 m_modality = wxDIALOG_MODALITY_WINDOW_MODAL;
1e181c7a 174
bfa92264
KO
175 if (GetParent())
176 parentWindow = dynamic_cast<wxNonOwnedWindow*>(wxGetTopLevelParent(GetParent()));
177
178 wxASSERT_MSG(parentWindow, "Window modal display requires parent.");
179
180 if (parentWindow)
181 {
182 NSWindow* nativeParent = parentWindow->GetWXWindow();
4d3e2dc9 183 [alert beginSheetModalForWindow: nativeParent modalDelegate: m_sheetDelegate
bfa92264
KO
184 didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
185 contextInfo: nil];
186 }
187}
188
e7794cf2 189void wxMessageDialog::ModalFinishedCallback(void* WXUNUSED(panel), int resultCode)
bfa92264
KO
190{
191 int resultbutton = wxID_CANCEL;
192 if ( resultCode < NSAlertFirstButtonReturn )
193 resultbutton = wxID_CANCEL;
194 else
195 {
196 if ( resultCode - NSAlertFirstButtonReturn < m_buttonCount )
197 resultbutton = m_buttonId[ resultCode - NSAlertFirstButtonReturn ];
524c47aa 198 else
bfa92264
KO
199 resultbutton = wxID_CANCEL;
200 }
201 SetReturnCode(resultbutton);
202
203 if (GetModality() == wxDIALOG_MODALITY_WINDOW_MODAL)
204 SendWindowModalDialogEvent ( wxEVT_WINDOW_MODAL_DIALOG_CLOSED );
205}
524c47aa 206
bfa92264
KO
207void* wxMessageDialog::ConstructNSAlert()
208{
209 const long style = GetMessageDialogStyle();
ba41a8c6 210
bfa92264 211 wxASSERT_MSG( (style & 0x3F) != wxYES, wxT("this style is not supported on Mac") );
03647350 212
bfa92264
KO
213 // work out what to display
214 // if the extended text is empty then we use the caption as the title
215 // and the message as the text (for backwards compatibility)
216 // but if the extended message is not empty then we use the message as the title
217 // and the extended message as the text because that makes more sense
03647350 218
bfa92264
KO
219 wxString msgtitle,msgtext;
220 if(m_extendedMessage.IsEmpty())
221 {
222 msgtitle = m_caption;
223 msgtext = m_message;
224 }
225 else
226 {
227 msgtitle = m_message;
228 msgtext = m_extendedMessage;
229 }
230
231 NSAlert* alert = [[NSAlert alloc] init];
0aeac464 232 NSAlertStyle alertType = GetAlertStyleFromWXStyle(style);
bfa92264 233
4d3b8623
SC
234 wxCFStringRef cfNoString( wxControl::GetLabelText(GetNoLabel()), GetFont().GetEncoding() );
235 wxCFStringRef cfYesString( wxControl::GetLabelText(GetYesLabel()), GetFont().GetEncoding() );
236 wxCFStringRef cfOKString( wxControl::GetLabelText(GetOKLabel()), GetFont().GetEncoding() );
237 wxCFStringRef cfCancelString( wxControl::GetLabelText(GetCancelLabel()), GetFont().GetEncoding() );
bfa92264
KO
238
239 wxCFStringRef cfTitle( msgtitle, GetFont().GetEncoding() );
240 wxCFStringRef cfText( msgtext, GetFont().GetEncoding() );
241
242 [alert setMessageText:cfTitle.AsNSString()];
243 [alert setInformativeText:cfText.AsNSString()];
0aeac464 244 [alert setAlertStyle:alertType];
bfa92264
KO
245
246 m_buttonCount = 0;
247
248 if (style & wxYES_NO)
249 {
250 if ( style & wxNO_DEFAULT )
ba41a8c6 251 {
bfa92264
KO
252 [alert addButtonWithTitle:cfNoString.AsNSString()];
253 m_buttonId[ m_buttonCount++ ] = wxID_NO;
254 [alert addButtonWithTitle:cfYesString.AsNSString()];
255 m_buttonId[ m_buttonCount++ ] = wxID_YES;
ba41a8c6
KO
256 }
257 else
258 {
bfa92264
KO
259 [alert addButtonWithTitle:cfYesString.AsNSString()];
260 m_buttonId[ m_buttonCount++ ] = wxID_YES;
261 [alert addButtonWithTitle:cfNoString.AsNSString()];
262 m_buttonId[ m_buttonCount++ ] = wxID_NO;
ba41a8c6 263 }
03647350 264
bfa92264 265 if (style & wxCANCEL)
524c47aa 266 {
bfa92264
KO
267 [alert addButtonWithTitle:cfCancelString.AsNSString()];
268 m_buttonId[ m_buttonCount++ ] = wxID_CANCEL;
524c47aa
SC
269 }
270 }
bfa92264
KO
271 // the MSW implementation even shows an OK button if it is not specified, we'll do the same
272 else
273 {
ec46fd5f 274 if ( style & wxCANCEL_DEFAULT )
bfa92264
KO
275 {
276 [alert addButtonWithTitle:cfCancelString.AsNSString()];
277 m_buttonId[ m_buttonCount++ ] = wxID_CANCEL;
ec46fd5f
SC
278
279 [alert addButtonWithTitle:cfOKString.AsNSString()];
280 m_buttonId[ m_buttonCount++ ] = wxID_OK;
281 }
282 else
283 {
284 [alert addButtonWithTitle:cfOKString.AsNSString()];
285 m_buttonId[ m_buttonCount++ ] = wxID_OK;
286 if (style & wxCANCEL)
287 {
288 [alert addButtonWithTitle:cfCancelString.AsNSString()];
289 m_buttonId[ m_buttonCount++ ] = wxID_CANCEL;
290 }
bfa92264 291 }
ec46fd5f 292
bfa92264 293 }
7112cdd1
VZ
294
295 if ( style & wxHELP )
296 {
297 wxCFStringRef cfHelpString( GetHelpLabel(), GetFont().GetEncoding() );
298 [alert addButtonWithTitle:cfHelpString.AsNSString()];
299 m_buttonId[ m_buttonCount++ ] = wxID_HELP;
300 }
301
302 wxASSERT_MSG( m_buttonCount <= WXSIZEOF(m_buttonId), "Too many buttons" );
303
bfa92264 304 return alert;
524c47aa 305}