]> git.saurik.com Git - wxWidgets.git/blob - src/motif/msgdlg.cpp
Only give capture to wxPopupTransientWindow child if it's the only one.
[wxWidgets.git] / src / motif / msgdlg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/motif/msgdlg.cpp
3 // Purpose: wxMessageDialog
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __VMS
23 #pragma message disable nosimpint
24 #include "wx/vms_x_fix.h"
25 #endif
26 #include <X11/Xlib.h>
27
28 #include <Xm/Xm.h>
29 #include <Xm/MessageB.h>
30 #ifdef __VMS
31 #pragma message enable nosimpint
32 #endif
33
34 #include "wx/msgdlg.h"
35
36 #ifndef WX_PRECOMP
37 #include "wx/intl.h"
38 #include "wx/app.h"
39 #include "wx/settings.h"
40 #endif
41
42 #include "wx/modalhook.h"
43 #include "wx/motif/private.h"
44
45 // ----------------------------------------------------------------------------
46 // macros
47 // ----------------------------------------------------------------------------
48
49 IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
50
51 // ============================================================================
52 // implementation
53 // ============================================================================
54
55 // ----------------------------------------------------------------------------
56 // the callbacks for message box buttons
57 // ----------------------------------------------------------------------------
58
59 // the common part
60 static void msgboxCallBack(Widget w, void* client_data, int id)
61 {
62 // close the dialog
63 XtUnmanageChild(w);
64
65 wxMessageDialog *dlg = (wxMessageDialog *)client_data;
66 dlg->SetResult(id);
67 }
68
69 static void msgboxCallBackOk(Widget w,
70 void* client_data,
71 XmAnyCallbackStruct *WXUNUSED(call_data))
72 {
73 msgboxCallBack(w, client_data, wxID_OK);
74 }
75
76 static void msgboxCallBackCancel(Widget w,
77 void* client_data,
78 XmAnyCallbackStruct *WXUNUSED(call_data))
79 {
80 msgboxCallBack(w, client_data, wxID_CANCEL);
81 }
82
83 static void msgboxCallBackHelp(Widget w,
84 void* client_data,
85 XmAnyCallbackStruct *WXUNUSED(call_data))
86 {
87 msgboxCallBack(w, client_data, wxID_HELP);
88 }
89
90 static void msgboxCallBackClose(Widget w,
91 void* client_data,
92 XmAnyCallbackStruct *WXUNUSED(call_data))
93 {
94 msgboxCallBack(w, client_data, wxID_CANCEL);
95 }
96
97 // ----------------------------------------------------------------------------
98 // wxMessageDialog
99 // ----------------------------------------------------------------------------
100
101 extern "C"
102 {
103 typedef Widget (*DialogCreateFunction)(Widget, String, ArgList, Cardinal);
104 }
105
106 int wxMessageDialog::ShowModal()
107 {
108 WX_HOOK_MODAL_DIALOG();
109
110 const long style = GetMessageDialogStyle();
111
112 DialogCreateFunction dialogCreateFunction;
113 if ( style & wxYES_NO )
114 {
115 // if we have [Yes], it must be a question
116 dialogCreateFunction = XmCreateQuestionDialog;
117 }
118 else if ( style & wxICON_STOP )
119 {
120 // error dialog is the one with error icon...
121 dialogCreateFunction = XmCreateErrorDialog;
122 }
123 else if ( style & wxICON_EXCLAMATION )
124 {
125 // ...and the warning dialog too
126 dialogCreateFunction = XmCreateWarningDialog;
127 }
128 else
129 {
130 // finally, use the info dialog by default
131 dialogCreateFunction = XmCreateInformationDialog;
132 }
133
134 Widget wParent = m_parent ? GetWidget(m_parent) : (Widget) 0;
135 if ( !wParent )
136 {
137 wxWindow *window = wxTheApp->GetTopWindow();
138 if ( !window )
139 {
140 wxFAIL_MSG("can't show message box without parent window");
141
142 return wxID_CANCEL;
143 }
144
145 wParent = GetWidget(window);
146 }
147
148 // prepare the arg list
149 Arg args[10];
150 int ac = 0;
151
152 wxXmString text(GetFullMessage());
153 wxXmString title(m_caption);
154 XtSetArg(args[ac], XmNmessageString, text()); ac++;
155 XtSetArg(args[ac], XmNdialogTitle, title()); ac++;
156
157 Display* dpy = XtDisplay(wParent);
158
159 if (m_backgroundColour.IsOk())
160 {
161 wxComputeColours (dpy, & m_backgroundColour, NULL);
162
163 XtSetArg(args[ac], XmNbackground, g_itemColors[wxBACK_INDEX].pixel); ac++;
164 XtSetArg(args[ac], XmNtopShadowColor, g_itemColors[wxTOPS_INDEX].pixel); ac++;
165 XtSetArg(args[ac], XmNbottomShadowColor, g_itemColors[wxBOTS_INDEX].pixel); ac++;
166 XtSetArg(args[ac], XmNforeground, g_itemColors[wxFORE_INDEX].pixel); ac++;
167 }
168
169 wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
170
171 #if __WXMOTIF20__ && !__WXLESSTIF__
172 XtSetArg(args[ac], XmNbuttonRenderTable, font.GetFontTypeC(dpy)); ac++;
173 XtSetArg(args[ac], XmNlabelRenderTable, font.GetFontTypeC(dpy)); ac++;
174 XtSetArg(args[ac], XmNtextRenderTable, font.GetFontTypeC(dpy)); ac++;
175 #else
176 XtSetArg(args[ac], XmNbuttonFontList, font.GetFontTypeC(dpy)); ac++;
177 XtSetArg(args[ac], XmNlabelFontList, font.GetFontTypeC(dpy)); ac++;
178 XtSetArg(args[ac], XmNtextFontList, font.GetFontTypeC(dpy)); ac++;
179 #endif
180
181 // do create message box
182
183 Widget wMsgBox = (*dialogCreateFunction)(wParent, wxMOTIF_STR(""), args, ac);
184
185 wxCHECK_MSG( wMsgBox, wxID_CANCEL, "msg box creation failed" );
186
187 // get the buttons which we might either remove or rename
188 // depending on the requested style
189 //
190 Widget wBtnOk = XmMessageBoxGetChild(wMsgBox, XmDIALOG_OK_BUTTON);
191 Widget wBtnHelp = XmMessageBoxGetChild(wMsgBox, XmDIALOG_HELP_BUTTON);
192 Widget wBtnCancel = XmMessageBoxGetChild(wMsgBox, XmDIALOG_CANCEL_BUTTON);
193
194 if ( style & wxYES_NO )
195 {
196 wxXmString yes(_("Yes")), no(_("No")), cancel(_("Cancel"));
197
198 if ( style & wxCANCEL )
199 {
200 // use the cancel button for No and the help button for
201 // Cancel Yuk :-) MB
202 //
203 XtVaSetValues(wBtnOk, XmNlabelString, yes(), NULL);
204 XtVaSetValues(wBtnCancel, XmNlabelString, no(), NULL);
205 XtVaSetValues(wBtnHelp, XmNlabelString, cancel(), NULL);
206 }
207 else
208 {
209 // no cancel button requested...
210 // remove the help button and use cancel for no
211 //
212 XtVaSetValues(wBtnCancel, XmNlabelString, no(), NULL);
213 XtUnmanageChild(wBtnHelp);
214 }
215 }
216 else
217 {
218 // remove the help button and the cancel button (unless it was
219 // requested)
220 //
221 XtUnmanageChild(wBtnHelp);
222 if ( !(style & wxCANCEL ) ) XtUnmanageChild(wBtnCancel);
223 }
224
225 // set the callbacks for the message box buttons
226 XtAddCallback(wMsgBox, XmNokCallback,
227 (XtCallbackProc)msgboxCallBackOk, (XtPointer)this);
228 XtAddCallback(wMsgBox, XmNcancelCallback,
229 (XtCallbackProc)msgboxCallBackCancel, (XtPointer)this);
230 XtAddCallback(wMsgBox, XmNhelpCallback,
231 (XtCallbackProc)msgboxCallBackHelp, (XtPointer)this);
232 XtAddCallback(wMsgBox, XmNunmapCallback,
233 (XtCallbackProc)msgboxCallBackClose, (XtPointer)this);
234
235 // show it as a modal dialog
236 XtManageChild(wMsgBox);
237 XtAddGrab(wMsgBox, True, False);
238
239 // the m_result will be changed when message box goes away
240 m_result = -1;
241
242 // local message loop
243 XtAppContext context = XtWidgetToApplicationContext(wParent);
244 XEvent event;
245 while ( m_result == -1 )
246 {
247 XtAppNextEvent(context, &event);
248 XtDispatchEvent(&event);
249 }
250
251 // translate the result if necessary
252 if ( style & wxYES_NO )
253 {
254 if ( m_result == wxID_OK )
255 m_result = wxID_YES;
256 else if ( m_result == wxID_CANCEL )
257 m_result = wxID_NO;
258 else if ( m_result == wxID_HELP )
259 m_result = wxID_CANCEL;
260 }
261
262 return m_result;
263 }