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