]> git.saurik.com Git - wxWidgets.git/blame - src/os2/dialog.cpp
implemented Alex's <object_ref> symlinks in XRC
[wxWidgets.git] / src / os2 / dialog.cpp
CommitLineData
0e320a79
DW
1/////////////////////////////////////////////////////////////////////////////
2// Name: dialog.cpp
3// Purpose: wxDialog class
fb46a9a6 4// Author: David Webster
0e320a79 5// Modified by:
fb46a9a6 6// Created: 10/14/99
0e320a79 7// RCS-ID: $Id$
fb46a9a6
DW
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
27476f73
DW
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
0e320a79 14
27476f73 15#ifndef WX_PRECOMP
0e320a79
DW
16#include "wx/dialog.h"
17#include "wx/utils.h"
18#include "wx/frame.h"
19#include "wx/app.h"
20#include "wx/settings.h"
27476f73
DW
21#include "wx/intl.h"
22#include "wx/log.h"
23#endif
24
25#include "wx/os2/private.h"
26#include "wx/log.h"
27
27476f73
DW
28#define wxDIALOG_DEFAULT_X 300
29#define wxDIALOG_DEFAULT_Y 300
0e320a79 30
c9cb56f7
DW
31#define wxDIALOG_DEFAULT_WIDTH 500
32#define wxDIALOG_DEFAULT_HEIGHT 500
33
27476f73 34wxWindowList wxModalDialogs;
0e320a79 35
5d44b24e 36IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxTopLevelWindow)
27476f73 37
d491523b 38BEGIN_EVENT_TABLE(wxDialog, wxDialogBase)
5d44b24e
DW
39 EVT_BUTTON(wxID_OK, wxDialog::OnOK)
40 EVT_BUTTON(wxID_APPLY, wxDialog::OnApply)
41 EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel)
42 EVT_CHAR_HOOK(wxDialog::OnCharHook)
43 EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
44 EVT_CLOSE(wxDialog::OnCloseWindow)
45END_EVENT_TABLE()
0e320a79 46
c9cb56f7 47void wxDialog::Init()
0e320a79 48{
c9cb56f7 49 m_pOldFocus = (wxWindow *)NULL;
27476f73 50 m_isShown = FALSE;
c9cb56f7 51 m_pWindowDisabler = (wxWindowDisabler *)NULL;
a756f210 52 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
c9cb56f7
DW
53} // end of wxDialog::Init
54
55bool wxDialog::Create(
56 wxWindow* pParent
57, wxWindowID vId
58, const wxString& rsTitle
59, const wxPoint& rPos
60, const wxSize& rSize
61, long lStyle
62, const wxString& rsName
63)
0e320a79 64{
c9cb56f7
DW
65 long lX = rPos.x;
66 long lY = rPos.y;
67 long lWidth = rSize.x;
68 long lHeight = rSize.y;
69 const char* zDlg;
70 WXDWORD dwExtendedStyle = 0L;
71 HWND hWnd;
72
73 Init();
5d44b24e 74 SetExtraStyle(GetExtraStyle() | wxTOPLEVEL_EX_DIALOG);
c9cb56f7
DW
75
76 //
5d44b24e 77 // Save focus before doing anything which can potentially change it
c9cb56f7 78 //
5d44b24e 79 m_pOldFocus = FindFocus();
c9cb56f7
DW
80
81 //
5d44b24e 82 // All dialogs should really have this style
c9cb56f7 83 //
5d44b24e
DW
84 lStyle |= wxTAB_TRAVERSAL;
85
86 if (!wxTopLevelWindow::Create( pParent
87 ,vId
88 ,rsTitle
89 ,rPos
90 ,rSize
91 ,lStyle
92 ,rsName
93 ))
c9cb56f7 94 return FALSE;
a756f210 95 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
27476f73 96 return TRUE;
c9cb56f7 97} // end of wxDialog::Create
0e320a79 98
c9cb56f7
DW
99void wxDialog::SetModal(
100 bool bFlag
101)
0e320a79 102{
c9cb56f7 103 if (bFlag)
5d44b24e 104 {
27476f73 105 m_windowStyle |= wxDIALOG_MODAL ;
5d44b24e
DW
106 wxModelessWindows.DeleteObject(this);
107 }
108 else
109 {
110 m_windowStyle &= ~wxDIALOG_MODAL ;
111 wxModelessWindows.Append(this);
112 }
c9cb56f7 113} // end of wxDialog::SetModal
0e320a79
DW
114
115wxDialog::~wxDialog()
116{
27476f73 117 m_isBeingDeleted = TRUE;
27476f73 118 Show(FALSE);
c9cb56f7 119} // end of wxDialog::~wxDialog
0e320a79 120
c9cb56f7 121//
0e320a79 122// By default, pressing escape cancels the dialog
c9cb56f7
DW
123//
124void wxDialog::OnCharHook(
125 wxKeyEvent& rEvent
126)
0e320a79 127{
27476f73
DW
128 if (GetHWND())
129 {
c9cb56f7 130 if (rEvent.m_keyCode == WXK_ESCAPE)
27476f73 131 {
c9cb56f7 132 //
27476f73
DW
133 // Behaviour changed in 2.0: we'll send a Cancel message
134 // to the dialog instead of Close.
c9cb56f7
DW
135 //
136 wxCommandEvent vCancelEvent( wxEVT_COMMAND_BUTTON_CLICKED
137 ,wxID_CANCEL
138 );
139
140 vCancelEvent.SetEventObject( this );
141 GetEventHandler()->ProcessEvent(vCancelEvent);
142
143 //
144 // Ensure that there is another message for this window so the
145 // ShowModal loop will exit and won't get stuck in GetMessage().
146 //
147 ::WinPostMsg(GetHwnd(), WM_NULL, 0, 0);
27476f73
DW
148 return;
149 }
150 }
151 // We didn't process this event.
c9cb56f7 152 rEvent.Skip();
27476f73
DW
153}
154
5d44b24e
DW
155// ----------------------------------------------------------------------------
156// showing the dialogs
157// ----------------------------------------------------------------------------
27476f73
DW
158
159bool wxDialog::IsModal() const
160{
c9cb56f7
DW
161 return (GetWindowStyleFlag() & wxDIALOG_MODAL) != 0;
162} // end of wxDialog::IsModal
0e320a79 163
c9cb56f7 164bool wxDialog::IsModalShowing() const
0e320a79 165{
c9cb56f7
DW
166 return wxModalDialogs.Find((wxDialog *)this) != NULL; // const_cast
167} // end of wxDialog::IsModalShowing
0e320a79 168
c9cb56f7 169void wxDialog::DoShowModal()
0e320a79 170{
c9cb56f7
DW
171 wxWindow* pParent = GetParent();
172 wxWindow* pOldFocus = m_pOldFocus;
173 HWND hWndOldFocus = 0;
0e320a79 174
c9cb56f7
DW
175 wxCHECK_RET( !IsModalShowing(), _T("DoShowModal() called twice") );
176 wxCHECK_RET( IsModal(), _T("can't DoShowModal() modeless dialog") );
177
178 wxModalDialogs.Append(this);
179 if (pOldFocus)
180 hWndOldFocus = (HWND)pOldFocus->GetHWND();
0e320a79 181
c9cb56f7
DW
182 //
183 // Remember where the focus was
184 //
185 if (!pOldFocus)
186 {
187 pOldFocus = pParent;
188 if (pParent)
189 hWndOldFocus = GetHwndOf(pParent);
190 }
191
192 //
193 // Disable all other app windows
194 //
195 wxASSERT_MSG(!m_pWindowDisabler, _T("disabling windows twice?"));
196
197 m_pWindowDisabler = new wxWindowDisabler(this);
198
199 //
200 // Enter the modal loop
201 //
202 while ( IsModalShowing() )
203 {
204#if wxUSE_THREADS
205 wxMutexGuiLeaveOrEnter();
206#endif // wxUSE_THREADS
207
208 while ( !wxTheApp->Pending() && wxTheApp->ProcessIdle() )
209 ;
210
211 // a message came or no more idle processing to do
212 wxTheApp->DoMessage();
213 }
214
215 //
216 // Snd restore focus
217 // Note that this code MUST NOT access the dialog object's data
218 // in case the object has been deleted (which will be the case
219 // for a modal dialog that has been destroyed before calling EndModal).
220 //
221 if (pOldFocus && (pOldFocus != this) && ::WinIsWindow(vHabmain, hWndOldFocus))
222 {
223 //
224 // This is likely to prove that the object still exists
225 //
226 if (wxFindWinFromHandle((WXHWND) hWndOldFocus) == pOldFocus)
227 pOldFocus->SetFocus();
228 }
229} // end of wxDialog::DoShowModal
230
231bool wxDialog::Show(
232 bool bShow
233)
0e320a79 234{
c9cb56f7
DW
235 if (!bShow)
236 {
237 //
238 // If we had disabled other app windows, reenable them back now because
239 // if they stay disabled Windows will activate another window (one
240 // which is enabled, anyhow) and we will lose activation
241 //
242 if (m_pWindowDisabler)
243 {
244 delete m_pWindowDisabler;
245 m_pWindowDisabler = NULL;
246 }
247 }
0e320a79 248
c9cb56f7
DW
249 //
250 // ShowModal() may be called for already shown dialog
251 //
252 if (!wxDialogBase::Show(bShow) && !(bShow && IsModal()))
253 {
254 //
255 // Nothing to do
256 //
257 return FALSE;
258 }
259
260 if (bShow)
261 {
262 //
263 // Usually will result in TransferDataToWindow() being called
264 //
265 InitDialog();
266 }
267
268 if (IsModal())
269 {
270 if (bShow)
271 {
272 //
273 // Modal dialog needs a parent window, so try to find one
274 //
275 if (!GetParent())
276 {
277 wxWindow* pParent = wxTheApp->GetTopWindow();
278
279 if ( pParent && pParent != this && pParent->IsShown() )
280 {
281 //
282 // Use it
283 //
284 m_parent = pParent;
285
286 }
287 }
288 DoShowModal();
289 }
290 else // end of modal dialog
291 {
292 //
293 // This will cause IsModalShowing() return FALSE and our local
294 // message loop will terminate
295 //
296 wxModalDialogs.DeleteObject(this);
297 }
298 }
5d44b24e 299 return TRUE;
c9cb56f7
DW
300} // end of wxDialog::Show
301
302//
0e320a79 303// Replacement for Show(TRUE) for modal dialogs - returns return code
c9cb56f7 304//
0e320a79
DW
305int wxDialog::ShowModal()
306{
c9cb56f7
DW
307 if (!IsModal())
308 {
309 SetModal(TRUE);
310 }
27476f73
DW
311 Show(TRUE);
312 return GetReturnCode();
c9cb56f7 313} // end of wxDialog::ShowModal
0e320a79 314
c9cb56f7
DW
315void wxDialog::EndModal(
316 int nRetCode
317)
0e320a79 318{
c9cb56f7 319 SetReturnCode(nRetCode);
27476f73 320 Show(FALSE);
c9cb56f7 321} // end of wxDialog::EndModal
0e320a79 322
5d44b24e
DW
323// ----------------------------------------------------------------------------
324// wxWin event handlers
325// ----------------------------------------------------------------------------
326
c9cb56f7
DW
327void wxDialog::OnApply(
328 wxCommandEvent& rEvent
329)
27476f73 330{
c9cb56f7
DW
331 if (Validate())
332 TransferDataFromWindow();
333} // end of wxDialog::OnApply
334
0e320a79 335// Standard buttons
c9cb56f7
DW
336void wxDialog::OnOK(
337 wxCommandEvent& rEvent
338)
0e320a79 339{
27476f73
DW
340 if ( Validate() && TransferDataFromWindow() )
341 {
c9cb56f7 342 EndModal(wxID_OK);
27476f73 343 }
c9cb56f7 344} // end of wxDialog::OnOK
0e320a79 345
c9cb56f7
DW
346void wxDialog::OnCancel(
347 wxCommandEvent& rEvent
348)
0e320a79 349{
c9cb56f7
DW
350 EndModal(wxID_CANCEL);
351} // end of wxDialog::OnCancel
0e320a79 352
c9cb56f7
DW
353void wxDialog::OnCloseWindow(
354 wxCloseEvent& rEvent
355)
0e320a79 356{
c9cb56f7 357 //
0e320a79
DW
358 // We'll send a Cancel message by default,
359 // which may close the dialog.
360 // Check for looping if the Cancel event handler calls Close().
c9cb56f7 361 //
0e320a79
DW
362 // Note that if a cancel button and handler aren't present in the dialog,
363 // nothing will happen when you close the dialog via the window manager, or
364 // via Close().
365 // We wouldn't want to destroy the dialog by default, since the dialog may have been
366 // created on the stack.
367 // However, this does mean that calling dialog->Close() won't delete the dialog
368 // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
369 // sure to destroy the dialog.
370 // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
c9cb56f7 371 //
0e320a79 372
c9cb56f7
DW
373 //
374 // Ugh??? This is not good but until I figure out a global list it'll have to do
375 //
0e320a79 376 static wxList closing;
c3d43472 377
0e320a79
DW
378 if ( closing.Member(this) )
379 return;
c3d43472 380
0e320a79 381 closing.Append(this);
c3d43472 382
c9cb56f7
DW
383 wxCommandEvent vCancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
384
385 vCancelEvent.SetEventObject( this );
386 GetEventHandler()->ProcessEvent(vCancelEvent); // This may close the dialog
0e320a79
DW
387
388 closing.DeleteObject(this);
c9cb56f7 389} // end of wxDialog::OnCloseWindow
0e320a79 390
c9cb56f7
DW
391void wxDialog::OnSysColourChanged(
392 wxSysColourChangedEvent& rEvent
393)
27476f73 394{
a756f210 395 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
c9cb56f7
DW
396 Refresh();
397} // end of wxDialog::OnSysColourChanged
398
399MRESULT wxDialog::OS2WindowProc(
400 WXUINT uMessage
401, WXWPARAM wParam
402, WXLPARAM lParam
403)
0e320a79 404{
c9cb56f7
DW
405 MRESULT rc = 0;
406 bool bProcessed = FALSE;
27476f73 407
c9cb56f7 408 switch (uMessage)
27476f73
DW
409 {
410 case WM_CLOSE:
c9cb56f7
DW
411 //
412 // If we can't close, tell the system that we processed the
27476f73 413 // message - otherwise it would close us
c9cb56f7
DW
414 //
415 bProcessed = !Close();
27476f73
DW
416 break;
417 }
418
c9cb56f7
DW
419 if (!bProcessed)
420 rc = wxWindow::OS2WindowProc( uMessage
421 ,wParam
422 ,lParam
423 );
27476f73 424 return rc;
c9cb56f7 425} // end of wxDialog::OS2WindowProc
27476f73 426