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