]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/msgdlg.cpp
Return NULL from wxWindow::GetCapture() when the capture is being lost.
[wxWidgets.git] / src / gtk / msgdlg.cpp
CommitLineData
13a7abf9 1/////////////////////////////////////////////////////////////////////////////
e5b50758 2// Name: src/gtk/msgdlg.cpp
13a7abf9
VS
3// Purpose: wxMessageDialog for GTK+2
4// Author: Vaclav Slavik
5// Modified by:
6// Created: 2003/02/28
13a7abf9 7// Copyright: (c) Vaclav Slavik, 2003
e5b50758 8// Licence: wxWindows licence
13a7abf9
VS
9/////////////////////////////////////////////////////////////////////////////
10
13a7abf9
VS
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
88a7a4e1 15 #pragma hdrstop
13a7abf9
VS
16#endif
17
ff654490 18#if wxUSE_MSGDLG && !defined(__WXGPE__)
13a7abf9 19
e1bf3ad3 20#include "wx/msgdlg.h"
88a7a4e1
WS
21
22#ifndef WX_PRECOMP
23 #include "wx/intl.h"
24#endif
25
691745ab 26#include "wx/modalhook.h"
643e9cf9 27
9dc44eff 28#include <gtk/gtk.h>
13a7abf9 29#include "wx/gtk/private.h"
ce668f29 30#include "wx/gtk/private/messagetype.h"
92763588 31#include "wx/gtk/private/mnemonics.h"
3c2f3a60 32#include "wx/gtk/private/dialogcount.h"
13a7abf9 33
c96d7bec
VZ
34#if wxUSE_LIBHILDON
35 #include <hildon-widgets/hildon-note.h>
36#endif // wxUSE_LIBHILDON
37
426d19f1
JS
38#if wxUSE_LIBHILDON2
39 #include <hildon/hildon.h>
40#endif // wxUSE_LIBHILDON2
41
13a7abf9
VS
42IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
43
44wxMessageDialog::wxMessageDialog(wxWindow *parent,
45 const wxString& message,
46 const wxString& caption,
47 long style,
48 const wxPoint& WXUNUSED(pos))
ede7b017 49 : wxMessageDialogBase
cdc48273
VZ
50 (
51 GetParentForModalDialog(parent, style),
52 message,
53 caption,
54 style
55 )
13a7abf9 56{
2afb9e16 57}
13a7abf9 58
92763588
VZ
59wxString wxMessageDialog::GetDefaultYesLabel() const
60{
61 return GTK_STOCK_YES;
62}
63
64wxString wxMessageDialog::GetDefaultNoLabel() const
65{
66 return GTK_STOCK_NO;
67}
68
69wxString wxMessageDialog::GetDefaultOKLabel() const
70{
71 return GTK_STOCK_OK;
72}
73
74wxString wxMessageDialog::GetDefaultCancelLabel() const
75{
76 return GTK_STOCK_CANCEL;
77}
78
7112cdd1
VZ
79wxString wxMessageDialog::GetDefaultHelpLabel() const
80{
81 return GTK_STOCK_HELP;
82}
83
e08931c0 84void wxMessageDialog::DoSetCustomLabel(wxString& var, const ButtonLabel& label)
92763588 85{
e08931c0
VZ
86 int stockId = label.GetStockId();
87 if ( stockId == wxID_NONE )
88 {
ede7b017 89 wxMessageDialogBase::DoSetCustomLabel(var, label);
e08931c0
VZ
90 var = wxConvertMnemonicsToGTK(var);
91 }
92 else // stock label
93 {
94 var = wxGetStockGtkID(stockId);
95 }
92763588
VZ
96}
97
2afb9e16
VZ
98void wxMessageDialog::GTKCreateMsgDialog()
99{
c96d7bec
VZ
100 GtkWindow * const parent = m_parent ? GTK_WINDOW(m_parent->m_widget) : NULL;
101
426d19f1 102#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
a4578b0c
VZ
103 const char *stockIcon = "";
104
105 switch ( GetEffectiveIcon() )
106 {
107 case wxICON_ERROR:
108 stockIcon = "qgn_note_gene_syserror";
109 break;
110
111 case wxICON_WARNING:
112 stockIcon = "qgn_note_gene_syswarning";
113 break;
114
115 case wxICON_QUESTION:
116 stockIcon = "qgn_note_confirm";
117 break;
118
119 case wxICON_INFORMATION:
120 stockIcon = "qgn_note_info";
121 break;
122 }
c96d7bec
VZ
123
124 // there is no generic note creation function in public API so we have no
125 // choice but to use g_object_new() directly
126 m_widget = (GtkWidget *)g_object_new
127 (
128 HILDON_TYPE_NOTE,
426d19f1 129#if wxUSE_LIBHILDON
c96d7bec 130 "note_type", HILDON_NOTE_CONFIRMATION_BUTTON_TYPE,
426d19f1
JS
131#else // wxUSE_LIBHILDON
132 "note_type", HILDON_NOTE_TYPE_CONFIRMATION_BUTTON,
133#endif // wxUSE_LIBHILDON /wxUSE_LIBHILDON2
c96d7bec
VZ
134 "description", (const char *)GetFullMessage().utf8_str(),
135 "icon", stockIcon,
136 NULL
137 );
426d19f1 138#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
b63b07a8 139 GtkMessageType type = GTK_MESSAGE_ERROR;
92763588 140 GtkButtonsType buttons = GTK_BUTTONS_NONE;
13a7abf9 141
92763588
VZ
142 // when using custom labels, we have to add all the buttons ourselves
143 if ( !HasCustomLabels() )
13a7abf9 144 {
7112cdd1
VZ
145 // "Help" button is not supported by predefined combinations so we
146 // always need to create the buttons manually when it's used.
147 if ( !(m_dialogStyle & wxHELP) )
92763588 148 {
7112cdd1
VZ
149 if ( m_dialogStyle & wxYES_NO )
150 {
151 if ( !(m_dialogStyle & wxCANCEL) )
152 buttons = GTK_BUTTONS_YES_NO;
153 //else: no standard GTK_BUTTONS_YES_NO_CANCEL so leave as NONE
154 }
155 else if ( m_dialogStyle & wxOK )
156 {
157 buttons = m_dialogStyle & wxCANCEL ? GTK_BUTTONS_OK_CANCEL
158 : GTK_BUTTONS_OK;
159 }
92763588 160 }
13a7abf9 161 }
b63b07a8 162
a4578b0c 163 if ( !wxGTKImpl::ConvertMessageTypeFromWX(GetEffectiveIcon(), &type) )
e0ae1a0a 164 {
7e3204b4
VZ
165 // if no style is explicitly specified, detect the suitable icon
166 // ourselves (this can be disabled by using wxICON_NONE)
2afb9e16 167 type = m_dialogStyle & wxYES ? GTK_MESSAGE_QUESTION : GTK_MESSAGE_INFO;
e0ae1a0a 168 }
13a7abf9 169
2afb9e16 170 wxString message;
2afb9e16 171 bool needsExtMessage = false;
4e621d24 172 if (!m_extendedMessage.empty())
2afb9e16
VZ
173 {
174 message = m_message;
175 needsExtMessage = true;
176 }
4e621d24 177 else // extended message not needed
2afb9e16
VZ
178 {
179 message = GetFullMessage();
180 }
181
c96d7bec 182 m_widget = gtk_message_dialog_new(parent,
b2ce5e1b 183 GTK_DIALOG_MODAL,
2afb9e16
VZ
184 type,
185 buttons,
186 "%s",
187 (const char*)wxGTK_CONV(message));
188
2afb9e16
VZ
189 if ( needsExtMessage )
190 {
191 gtk_message_dialog_format_secondary_text
192 (
193 (GtkMessageDialog *)m_widget,
194 "%s",
195 (const char *)wxGTK_CONV(m_extendedMessage)
196 );
197 }
426d19f1 198#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
2afb9e16 199
9ff9d30c
PC
200 g_object_ref(m_widget);
201
13a7abf9 202 if (m_caption != wxMessageBoxCaptionStr)
b2ce5e1b 203 gtk_window_set_title(GTK_WINDOW(m_widget), wxGTK_CONV(m_caption));
13a7abf9 204
c96d7bec 205 GtkDialog * const dlg = GTK_DIALOG(m_widget);
92763588 206
4566dcbe
VZ
207 if ( m_dialogStyle & wxSTAY_ON_TOP )
208 {
209 gtk_window_set_keep_above(GTK_WINDOW(m_widget), TRUE);
210 }
211
92763588
VZ
212 // we need to add buttons manually if we use custom labels or always for
213 // Yes/No/Cancel dialog as GTK+ doesn't support it natively and when using
214 // Hildon we add all the buttons manually as it doesn't support too many of
215 // the combinations we may have
426d19f1 216#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
92763588
VZ
217 static const bool addButtons = true;
218#else // !wxUSE_LIBHILDON
219 const bool addButtons = buttons == GTK_BUTTONS_NONE;
220#endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON
221
7112cdd1
VZ
222
223 if ( addButtons )
92763588 224 {
7112cdd1
VZ
225 if ( m_dialogStyle & wxHELP )
226 {
227 gtk_dialog_add_button(dlg, wxGTK_CONV(GetHelpLabel()),
228 GTK_RESPONSE_HELP);
229 }
230
231 if ( m_dialogStyle & wxYES_NO ) // Yes/No or Yes/No/Cancel dialog
c96d7bec 232 {
5d3056f1
VZ
233 // Add the buttons in the correct order which is, according to
234 // http://library.gnome.org/devel/hig-book/stable/windows-alert.html.en
235 // the following one:
236 //
237 // [Help] [Alternative] [Cancel] [Affirmative]
238
150c8eb9
VZ
239 gtk_dialog_add_button(dlg, wxGTK_CONV(GetNoLabel()),
240 GTK_RESPONSE_NO);
92763588
VZ
241
242 if ( m_dialogStyle & wxCANCEL )
243 {
150c8eb9 244 gtk_dialog_add_button(dlg, wxGTK_CONV(GetCancelLabel()),
92763588
VZ
245 GTK_RESPONSE_CANCEL);
246 }
5d3056f1
VZ
247
248 gtk_dialog_add_button(dlg, wxGTK_CONV(GetYesLabel()),
249 GTK_RESPONSE_YES);
c96d7bec 250 }
7112cdd1 251 else // Ok or Ok/Cancel dialog
150c8eb9 252 {
7112cdd1
VZ
253 gtk_dialog_add_button(dlg, wxGTK_CONV(GetOKLabel()), GTK_RESPONSE_OK);
254 if ( m_dialogStyle & wxCANCEL )
255 {
256 gtk_dialog_add_button(dlg, wxGTK_CONV(GetCancelLabel()),
257 GTK_RESPONSE_CANCEL);
258 }
150c8eb9 259 }
13a7abf9 260 }
24689293 261
7112cdd1 262 gint defaultButton;
24689293 263 if ( m_dialogStyle & wxCANCEL_DEFAULT )
7112cdd1
VZ
264 defaultButton = GTK_RESPONSE_CANCEL;
265 else if ( m_dialogStyle & wxNO_DEFAULT )
266 defaultButton = GTK_RESPONSE_NO;
267 else if ( m_dialogStyle & wxYES_NO )
268 defaultButton = GTK_RESPONSE_YES;
269 else // No need to change the default value, whatever it is.
270 defaultButton = GTK_RESPONSE_NONE;
271
272 if ( defaultButton != GTK_RESPONSE_NONE )
273 gtk_dialog_set_default_response(dlg, defaultButton);
b2ce5e1b 274}
e5b50758 275
b2ce5e1b
RD
276int wxMessageDialog::ShowModal()
277{
691745ab 278 WX_HOOK_MODAL_DIALOG();
643e9cf9 279
7738af59
VZ
280 // break the mouse capture as it would interfere with modal dialog (see
281 // wxDialog::ShowModal)
282 wxWindow * const win = wxWindow::GetCapture();
283 if ( win )
284 win->GTKReleaseMouseAndNotify();
285
2afb9e16
VZ
286 if ( !m_widget )
287 {
288 GTKCreateMsgDialog();
289 wxCHECK_MSG( m_widget, wxID_CANCEL,
9a83f860 290 wxT("failed to create GtkMessageDialog") );
2afb9e16
VZ
291 }
292
3b439e60
RR
293 // This should be necessary, but otherwise the
294 // parent TLW will disappear..
295 if (m_parent)
296 gtk_window_present( GTK_WINDOW(m_parent->m_widget) );
e5b50758 297
3c2f3a60
VZ
298 wxOpenModalDialogLocker modalLocker;
299
b2ce5e1b 300 gint result = gtk_dialog_run(GTK_DIALOG(m_widget));
8ab75332 301 GTKDisconnect(m_widget);
b2ce5e1b 302 gtk_widget_destroy(m_widget);
9ff9d30c 303 g_object_unref(m_widget);
b2ce5e1b 304 m_widget = NULL;
13a7abf9
VS
305
306 switch (result)
307 {
308 default:
9a83f860 309 wxFAIL_MSG(wxT("unexpected GtkMessageDialog return code"));
13a7abf9
VS
310 // fall through
311
b63b07a8 312 case GTK_RESPONSE_CANCEL:
0e4a7045
VS
313 case GTK_RESPONSE_DELETE_EVENT:
314 case GTK_RESPONSE_CLOSE:
13a7abf9
VS
315 return wxID_CANCEL;
316 case GTK_RESPONSE_OK:
317 return wxID_OK;
318 case GTK_RESPONSE_YES:
319 return wxID_YES;
320 case GTK_RESPONSE_NO:
321 return wxID_NO;
7112cdd1
VZ
322 case GTK_RESPONSE_HELP:
323 return wxID_HELP;
13a7abf9
VS
324 }
325}
326
b2ce5e1b 327
ff654490 328#endif // wxUSE_MSGDLG && !defined(__WXGPE__)