]> git.saurik.com Git - wxWidgets.git/blame - src/os2/dialog.cpp
added an explicit accessor to query the default key value
[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));
c9b9e020
DW
96
97 //
98 // Must defer setting the title until after dialog is created and sized
99 //
100 if (!rsTitle.IsNull())
101 SetTitle(rsTitle);
27476f73 102 return TRUE;
c9cb56f7 103} // end of wxDialog::Create
0e320a79 104
c9cb56f7
DW
105void wxDialog::SetModal(
106 bool bFlag
107)
0e320a79 108{
c9cb56f7 109 if (bFlag)
5d44b24e 110 {
27476f73 111 m_windowStyle |= wxDIALOG_MODAL ;
5d44b24e
DW
112 wxModelessWindows.DeleteObject(this);
113 }
114 else
115 {
116 m_windowStyle &= ~wxDIALOG_MODAL ;
117 wxModelessWindows.Append(this);
118 }
c9cb56f7 119} // end of wxDialog::SetModal
0e320a79
DW
120
121wxDialog::~wxDialog()
122{
27476f73 123 m_isBeingDeleted = TRUE;
27476f73 124 Show(FALSE);
c9cb56f7 125} // end of wxDialog::~wxDialog
0e320a79 126
c9cb56f7 127//
0e320a79 128// By default, pressing escape cancels the dialog
c9cb56f7
DW
129//
130void wxDialog::OnCharHook(
131 wxKeyEvent& rEvent
132)
0e320a79 133{
27476f73
DW
134 if (GetHWND())
135 {
c9cb56f7 136 if (rEvent.m_keyCode == WXK_ESCAPE)
27476f73 137 {
c9cb56f7 138 //
27476f73
DW
139 // Behaviour changed in 2.0: we'll send a Cancel message
140 // to the dialog instead of Close.
c9cb56f7
DW
141 //
142 wxCommandEvent vCancelEvent( wxEVT_COMMAND_BUTTON_CLICKED
143 ,wxID_CANCEL
144 );
145
146 vCancelEvent.SetEventObject( this );
147 GetEventHandler()->ProcessEvent(vCancelEvent);
148
149 //
150 // Ensure that there is another message for this window so the
151 // ShowModal loop will exit and won't get stuck in GetMessage().
152 //
153 ::WinPostMsg(GetHwnd(), WM_NULL, 0, 0);
27476f73
DW
154 return;
155 }
156 }
157 // We didn't process this event.
c9cb56f7 158 rEvent.Skip();
27476f73
DW
159}
160
5d44b24e
DW
161// ----------------------------------------------------------------------------
162// showing the dialogs
163// ----------------------------------------------------------------------------
27476f73
DW
164
165bool wxDialog::IsModal() const
166{
c9cb56f7
DW
167 return (GetWindowStyleFlag() & wxDIALOG_MODAL) != 0;
168} // end of wxDialog::IsModal
0e320a79 169
c9cb56f7 170bool wxDialog::IsModalShowing() const
0e320a79 171{
c9cb56f7
DW
172 return wxModalDialogs.Find((wxDialog *)this) != NULL; // const_cast
173} // end of wxDialog::IsModalShowing
0e320a79 174
c9cb56f7 175void wxDialog::DoShowModal()
0e320a79 176{
c9cb56f7
DW
177 wxWindow* pParent = GetParent();
178 wxWindow* pOldFocus = m_pOldFocus;
179 HWND hWndOldFocus = 0;
0e320a79 180
c9cb56f7
DW
181 wxCHECK_RET( !IsModalShowing(), _T("DoShowModal() called twice") );
182 wxCHECK_RET( IsModal(), _T("can't DoShowModal() modeless dialog") );
183
184 wxModalDialogs.Append(this);
185 if (pOldFocus)
186 hWndOldFocus = (HWND)pOldFocus->GetHWND();
0e320a79 187
c9cb56f7
DW
188 //
189 // Remember where the focus was
190 //
191 if (!pOldFocus)
192 {
193 pOldFocus = pParent;
194 if (pParent)
195 hWndOldFocus = GetHwndOf(pParent);
196 }
197
198 //
199 // Disable all other app windows
200 //
201 wxASSERT_MSG(!m_pWindowDisabler, _T("disabling windows twice?"));
202
203 m_pWindowDisabler = new wxWindowDisabler(this);
204
205 //
206 // Enter the modal loop
207 //
208 while ( IsModalShowing() )
209 {
210#if wxUSE_THREADS
211 wxMutexGuiLeaveOrEnter();
212#endif // wxUSE_THREADS
213
214 while ( !wxTheApp->Pending() && wxTheApp->ProcessIdle() )
215 ;
216
217 // a message came or no more idle processing to do
218 wxTheApp->DoMessage();
219 }
220
221 //
222 // Snd restore focus
223 // Note that this code MUST NOT access the dialog object's data
224 // in case the object has been deleted (which will be the case
225 // for a modal dialog that has been destroyed before calling EndModal).
226 //
227 if (pOldFocus && (pOldFocus != this) && ::WinIsWindow(vHabmain, hWndOldFocus))
228 {
229 //
230 // This is likely to prove that the object still exists
231 //
232 if (wxFindWinFromHandle((WXHWND) hWndOldFocus) == pOldFocus)
233 pOldFocus->SetFocus();
234 }
235} // end of wxDialog::DoShowModal
236
237bool wxDialog::Show(
238 bool bShow
239)
0e320a79 240{
c9cb56f7
DW
241 if (!bShow)
242 {
243 //
244 // If we had disabled other app windows, reenable them back now because
245 // if they stay disabled Windows will activate another window (one
246 // which is enabled, anyhow) and we will lose activation
247 //
248 if (m_pWindowDisabler)
249 {
250 delete m_pWindowDisabler;
251 m_pWindowDisabler = NULL;
252 }
253 }
0e320a79 254
c9cb56f7
DW
255 //
256 // ShowModal() may be called for already shown dialog
257 //
258 if (!wxDialogBase::Show(bShow) && !(bShow && IsModal()))
259 {
260 //
261 // Nothing to do
262 //
263 return FALSE;
264 }
265
266 if (bShow)
267 {
268 //
269 // Usually will result in TransferDataToWindow() being called
270 //
271 InitDialog();
272 }
273
c9b9e020
DW
274 if (GetTitle().c_str())
275 ::WinSetWindowText((HWND)GetHwnd(), GetTitle().c_str());
c9cb56f7
DW
276 if (IsModal())
277 {
278 if (bShow)
279 {
280 //
281 // Modal dialog needs a parent window, so try to find one
282 //
283 if (!GetParent())
284 {
285 wxWindow* pParent = wxTheApp->GetTopWindow();
286
287 if ( pParent && pParent != this && pParent->IsShown() )
288 {
289 //
290 // Use it
291 //
292 m_parent = pParent;
293
294 }
295 }
296 DoShowModal();
297 }
298 else // end of modal dialog
299 {
300 //
301 // This will cause IsModalShowing() return FALSE and our local
302 // message loop will terminate
303 //
304 wxModalDialogs.DeleteObject(this);
305 }
306 }
5d44b24e 307 return TRUE;
c9cb56f7
DW
308} // end of wxDialog::Show
309
310//
0e320a79 311// Replacement for Show(TRUE) for modal dialogs - returns return code
c9cb56f7 312//
0e320a79
DW
313int wxDialog::ShowModal()
314{
c9cb56f7
DW
315 if (!IsModal())
316 {
317 SetModal(TRUE);
318 }
27476f73
DW
319 Show(TRUE);
320 return GetReturnCode();
c9cb56f7 321} // end of wxDialog::ShowModal
0e320a79 322
c9cb56f7
DW
323void wxDialog::EndModal(
324 int nRetCode
325)
0e320a79 326{
c9cb56f7 327 SetReturnCode(nRetCode);
27476f73 328 Show(FALSE);
c9cb56f7 329} // end of wxDialog::EndModal
0e320a79 330
5d44b24e
DW
331// ----------------------------------------------------------------------------
332// wxWin event handlers
333// ----------------------------------------------------------------------------
334
c9cb56f7
DW
335void wxDialog::OnApply(
336 wxCommandEvent& rEvent
337)
27476f73 338{
c9cb56f7
DW
339 if (Validate())
340 TransferDataFromWindow();
341} // end of wxDialog::OnApply
342
0e320a79 343// Standard buttons
c9cb56f7
DW
344void wxDialog::OnOK(
345 wxCommandEvent& rEvent
346)
0e320a79 347{
27476f73
DW
348 if ( Validate() && TransferDataFromWindow() )
349 {
c9cb56f7 350 EndModal(wxID_OK);
27476f73 351 }
c9cb56f7 352} // end of wxDialog::OnOK
0e320a79 353
c9cb56f7
DW
354void wxDialog::OnCancel(
355 wxCommandEvent& rEvent
356)
0e320a79 357{
c9cb56f7
DW
358 EndModal(wxID_CANCEL);
359} // end of wxDialog::OnCancel
0e320a79 360
c9cb56f7
DW
361void wxDialog::OnCloseWindow(
362 wxCloseEvent& rEvent
363)
0e320a79 364{
c9cb56f7 365 //
0e320a79
DW
366 // We'll send a Cancel message by default,
367 // which may close the dialog.
368 // Check for looping if the Cancel event handler calls Close().
c9cb56f7 369 //
0e320a79
DW
370 // Note that if a cancel button and handler aren't present in the dialog,
371 // nothing will happen when you close the dialog via the window manager, or
372 // via Close().
373 // We wouldn't want to destroy the dialog by default, since the dialog may have been
374 // created on the stack.
375 // However, this does mean that calling dialog->Close() won't delete the dialog
376 // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
377 // sure to destroy the dialog.
378 // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
c9cb56f7 379 //
0e320a79 380
c9cb56f7
DW
381 //
382 // Ugh??? This is not good but until I figure out a global list it'll have to do
383 //
0e320a79 384 static wxList closing;
c3d43472 385
0e320a79
DW
386 if ( closing.Member(this) )
387 return;
c3d43472 388
0e320a79 389 closing.Append(this);
c3d43472 390
c9cb56f7
DW
391 wxCommandEvent vCancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
392
393 vCancelEvent.SetEventObject( this );
394 GetEventHandler()->ProcessEvent(vCancelEvent); // This may close the dialog
0e320a79
DW
395
396 closing.DeleteObject(this);
c9cb56f7 397} // end of wxDialog::OnCloseWindow
0e320a79 398
c9cb56f7
DW
399void wxDialog::OnSysColourChanged(
400 wxSysColourChangedEvent& rEvent
401)
27476f73 402{
a756f210 403 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
c9cb56f7
DW
404 Refresh();
405} // end of wxDialog::OnSysColourChanged
406
407MRESULT wxDialog::OS2WindowProc(
408 WXUINT uMessage
409, WXWPARAM wParam
410, WXLPARAM lParam
411)
0e320a79 412{
c9cb56f7
DW
413 MRESULT rc = 0;
414 bool bProcessed = FALSE;
27476f73 415
c9cb56f7 416 switch (uMessage)
27476f73
DW
417 {
418 case WM_CLOSE:
c9cb56f7
DW
419 //
420 // If we can't close, tell the system that we processed the
27476f73 421 // message - otherwise it would close us
c9cb56f7
DW
422 //
423 bProcessed = !Close();
27476f73
DW
424 break;
425 }
426
c9cb56f7
DW
427 if (!bProcessed)
428 rc = wxWindow::OS2WindowProc( uMessage
429 ,wParam
430 ,lParam
431 );
27476f73 432 return rc;
c9cb56f7 433} // end of wxDialog::OS2WindowProc
27476f73 434