Add wxTEST_DIALOG for testing of modal dialogs.
[wxWidgets.git] / src / osx / carbon / msgdlg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/msgdlg.cpp
3 // Purpose: wxMessageDialog
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
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
21 #include "wx/thread.h"
22 #include "wx/testing.h"
23 #include "wx/osx/uma.h"
24
25
26 IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
27
28
29 wxMessageDialog::wxMessageDialog(wxWindow *parent,
30 const wxString& message,
31 const wxString& caption,
32 long style,
33 const wxPoint& WXUNUSED(pos))
34 : wxMessageDialogBase(parent, message, caption, style)
35 {
36 }
37
38 int wxMessageDialog::ShowModal()
39 {
40 WX_TESTING_SHOW_MODAL_HOOK();
41
42 int resultbutton = wxID_CANCEL;
43
44 const long style = GetMessageDialogStyle();
45
46 wxASSERT_MSG( (style & 0x3F) != wxYES,
47 "this style is not supported on Mac" );
48
49 AlertType alertType = kAlertPlainAlert;
50
51 switch ( GetEffectiveIcon() )
52 {
53 case wxICON_ERROR:
54 alertType = kAlertStopAlert;
55 break;
56
57 case wxICON_WARNING:
58 alertType = kAlertCautionAlert;
59 break;
60
61 case wxICON_QUESTION:
62 case wxICON_INFORMATION:
63 alertType = kAlertNoteAlert;
64 break;
65 }
66
67 // (the standard alert has two slots [title, text]
68 // for the three wxStrings [caption, message, extended message])
69 //
70 // if the extended text is empty we use the caption and
71 // the message (for backwards compatibility)
72 //
73 // if the extended text is not empty we ignore the caption
74 // and use the message and the extended message
75
76
77 wxString msgtitle,msgtext;
78 if(m_extendedMessage.IsEmpty())
79 {
80 if ( m_caption.IsEmpty() )
81 msgtitle = m_message;
82 else
83 {
84 msgtitle = m_caption;
85 msgtext = m_message;
86 }
87 }
88 else
89 {
90 msgtitle = m_message;
91 msgtext = m_extendedMessage;
92 }
93
94
95 if ( !wxIsMainThread() )
96 {
97 CFStringRef defaultButtonTitle = NULL;
98 CFStringRef alternateButtonTitle = NULL;
99 CFStringRef otherButtonTitle = NULL;
100
101 wxCFStringRef cfTitle( msgtitle, GetFont().GetEncoding() );
102 wxCFStringRef cfText( msgtext, GetFont().GetEncoding() );
103
104 wxCFStringRef cfNoString( GetNoLabel().c_str(), GetFont().GetEncoding() );
105 wxCFStringRef cfYesString( GetYesLabel().c_str(), GetFont().GetEncoding() );
106 wxCFStringRef cfOKString( GetOKLabel().c_str() , GetFont().GetEncoding()) ;
107 wxCFStringRef cfCancelString( GetCancelLabel().c_str(), GetFont().GetEncoding() );
108
109 int buttonId[4] = { 0, 0, 0, wxID_CANCEL /* time-out */ };
110
111 if (style & wxYES_NO)
112 {
113 if ( style & wxNO_DEFAULT )
114 {
115 defaultButtonTitle = cfNoString;
116 alternateButtonTitle = cfYesString;
117 buttonId[0] = wxID_NO;
118 buttonId[1] = wxID_YES;
119 }
120 else
121 {
122 defaultButtonTitle = cfYesString;
123 alternateButtonTitle = cfNoString;
124 buttonId[0] = wxID_YES;
125 buttonId[1] = wxID_NO;
126 }
127 if (style & wxCANCEL)
128 {
129 otherButtonTitle = cfCancelString;
130 buttonId[2] = wxID_CANCEL;
131 }
132 }
133 else
134 {
135 // the MSW implementation even shows an OK button if it is not specified, we'll do the same
136 buttonId[0] = wxID_OK;
137 // using null as default title does not work on earlier systems
138 defaultButtonTitle = cfOKString;
139 if (style & wxCANCEL)
140 {
141 alternateButtonTitle = cfCancelString;
142 buttonId[1] = wxID_CANCEL;
143 }
144 }
145
146 CFOptionFlags exitButton;
147 OSStatus err = CFUserNotificationDisplayAlert(
148 0, alertType, NULL, NULL, NULL, cfTitle, cfText,
149 defaultButtonTitle, alternateButtonTitle, otherButtonTitle, &exitButton );
150 if (err == noErr)
151 resultbutton = buttonId[exitButton];
152 }
153 else
154 {
155 short result;
156
157 AlertStdCFStringAlertParamRec param;
158 wxCFStringRef cfNoString( GetNoLabel().c_str(), GetFont().GetEncoding() );
159 wxCFStringRef cfYesString( GetYesLabel().c_str(), GetFont().GetEncoding() );
160 wxCFStringRef cfOKString( GetOKLabel().c_str(), GetFont().GetEncoding() );
161 wxCFStringRef cfCancelString( GetCancelLabel().c_str(), GetFont().GetEncoding() );
162
163 wxCFStringRef cfTitle( msgtitle, GetFont().GetEncoding() );
164 wxCFStringRef cfText = msgtext.IsEmpty() ? NULL : wxCFStringRef( msgtext, GetFont().GetEncoding() );
165
166 param.movable = true;
167 param.flags = 0;
168 param.version = kStdCFStringAlertVersionOne;
169
170 bool skipDialog = false;
171
172 if (style & wxYES_NO)
173 {
174 if (style & wxCANCEL)
175 {
176 param.defaultText = cfYesString;
177 param.cancelText = cfCancelString;
178 param.otherText = cfNoString;
179 param.helpButton = false;
180 param.defaultButton = style & wxNO_DEFAULT ? kAlertStdAlertOtherButton : kAlertStdAlertOKButton;
181 param.cancelButton = kAlertStdAlertCancelButton;
182 }
183 else
184 {
185 param.defaultText = cfYesString;
186 param.cancelText = NULL;
187 param.otherText = cfNoString;
188 param.helpButton = false;
189 param.defaultButton = style & wxNO_DEFAULT ? kAlertStdAlertOtherButton : kAlertStdAlertOKButton;
190 param.cancelButton = 0;
191 }
192 }
193 // the MSW implementation even shows an OK button if it is not specified, we'll do the same
194 else
195 {
196 if (style & wxCANCEL)
197 {
198 // that's a cancel missing
199 param.defaultText = cfOKString;
200 param.cancelText = cfCancelString;
201 param.otherText = NULL;
202 param.helpButton = false;
203 param.defaultButton = kAlertStdAlertOKButton;
204 param.cancelButton = 0;
205 }
206 else
207 {
208 param.defaultText = cfOKString;
209 param.cancelText = NULL;
210 param.otherText = NULL;
211 param.helpButton = false;
212 param.defaultButton = kAlertStdAlertOKButton;
213 param.cancelButton = 0;
214 }
215 }
216
217 param.position = kWindowDefaultPosition;
218 if ( !skipDialog )
219 {
220 DialogRef alertRef;
221 CreateStandardAlert( alertType, cfTitle, cfText, &param, &alertRef );
222 wxDialog::OSXBeginModalDialog();
223 RunStandardAlert( alertRef, NULL, &result );
224 wxDialog::OSXEndModalDialog();
225 }
226 else
227 {
228 return wxID_CANCEL;
229 }
230
231 if (style & wxOK)
232 {
233 switch ( result )
234 {
235 case 1:
236 resultbutton = wxID_OK;
237 break;
238
239 case 2:
240 // TODO: add Cancel button
241 // if (style & wxCANCEL)
242 // resultbutton = wxID_CANCEL;
243 break;
244
245 case 3:
246 default:
247 break;
248 }
249 }
250 else if (style & wxYES_NO)
251 {
252 switch ( result )
253 {
254 case 1:
255 resultbutton = wxID_YES;
256 break;
257
258 case 2:
259 if (!(style & wxCANCEL))
260 resultbutton = wxID_CANCEL;
261 break;
262
263 case 3:
264 resultbutton = wxID_NO;
265 break;
266
267 default:
268 break;
269 }
270 }
271 }
272
273 SetReturnCode(resultbutton);
274
275 return resultbutton;
276 }