1///////////////////////////////////////////////////////////////////////////// 2// Name: src/univ/dialog.cpp 3// Author: Robert Roebling, Vaclav Slavik 4// Id: $Id: dialog.cpp 39273 2006-05-22 20:54:04Z ABX $ 5// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com) 6// Licence: wxWindows licence 7///////////////////////////////////////////////////////////////////////////// 8 9// ============================================================================ 10// declarations 11// ============================================================================ 12 13// ---------------------------------------------------------------------------- 14// headers 15// ---------------------------------------------------------------------------- 16 17// For compilers that support precompilation, includes "wx.h". 18#include "wx/wxprec.h" 19 20#ifdef __BORLANDC__ 21 #pragma hdrstop 22#endif 23 24#include "wx/dialog.h" 25 26#ifndef WX_PRECOMP 27 #include "wx/utils.h" 28 #include "wx/app.h" 29#endif 30 31#include "wx/evtloop.h" 32 33//----------------------------------------------------------------------------- 34// wxDialog 35//----------------------------------------------------------------------------- 36 37BEGIN_EVENT_TABLE(wxDialog,wxDialogBase) 38 EVT_BUTTON (wxID_OK, wxDialog::OnOK) 39 EVT_BUTTON (wxID_CANCEL, wxDialog::OnCancel) 40 EVT_BUTTON (wxID_APPLY, wxDialog::OnApply) 41 EVT_CLOSE (wxDialog::OnCloseWindow) 42END_EVENT_TABLE() 43 44IMPLEMENT_DYNAMIC_CLASS(wxDialog,wxTopLevelWindow) 45 46void wxDialog::Init() 47{ 48 m_returnCode = 0; 49 m_windowDisabler = NULL; 50 m_eventLoop = NULL; 51 m_isShowingModal = false; 52} 53 54wxDialog::~wxDialog() 55{ 56 delete m_eventLoop; 57} 58 59bool wxDialog::Create(wxWindow *parent, 60 wxWindowID id, const wxString &title, 61 const wxPoint &pos, const wxSize &size, 62 long style, const wxString &name) 63{ 64 SetExtraStyle(GetExtraStyle() | wxTOPLEVEL_EX_DIALOG); 65 66 // all dialogs should have tab traversal enabled 67 style |= wxTAB_TRAVERSAL; 68 69 return wxTopLevelWindow::Create(parent, id, title, pos, size, style, name); 70} 71 72void wxDialog::OnApply(wxCommandEvent &WXUNUSED(event)) 73{ 74 if ( Validate() ) 75 TransferDataFromWindow(); 76} 77 78void wxDialog::OnCancel(wxCommandEvent &WXUNUSED(event)) 79{ 80 if ( IsModal() ) 81 { 82 EndModal(wxID_CANCEL); 83 } 84 else 85 { 86 SetReturnCode(wxID_CANCEL); 87 Show(false); 88 } 89} 90 91void wxDialog::OnOK(wxCommandEvent &WXUNUSED(event)) 92{ 93 if ( Validate() && TransferDataFromWindow() ) 94 { 95 if ( IsModal() ) 96 { 97 EndModal(wxID_OK); 98 } 99 else 100 { 101 SetReturnCode(wxID_OK); 102 Show(false); 103 } 104 } 105} 106 107void wxDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event)) 108{ 109 // We'll send a Cancel message by default, 110 // which may close the dialog. 111 // Check for looping if the Cancel event handler calls Close(). 112 113 // Note that if a cancel button and handler aren't present in the dialog, 114 // nothing will happen when you close the dialog via the window manager, or 115 // via Close(). 116 // We wouldn't want to destroy the dialog by default, since the dialog may have been 117 // created on the stack. 118 // However, this does mean that calling dialog->Close() won't delete the dialog 119 // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be 120 // sure to destroy the dialog. 121 // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog. 122 123 static wxList s_closing; 124 125 if (s_closing.Member(this)) 126 return; // no loops 127 128 s_closing.Append(this); 129 130 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL); 131 cancelEvent.SetEventObject(this); 132 GetEventHandler()->ProcessEvent(cancelEvent); 133 s_closing.DeleteObject(this); 134} 135 136bool wxDialog::Show(bool show) 137{ 138 if ( !show ) 139 { 140 // if we had disabled other app windows, reenable them back now because 141 // if they stay disabled Windows will activate another window (one 142 // which is enabled, anyhow) and we will lose activation 143 if ( m_windowDisabler ) 144 { 145 delete m_windowDisabler; 146 m_windowDisabler = NULL; 147 } 148 149 if ( IsModal() ) 150 EndModal(wxID_CANCEL); 151 } 152 153 bool ret = wxDialogBase::Show(show); 154 155 if ( show ) 156 InitDialog(); 157 158 return ret; 159} 160 161bool wxDialog::IsModal() const 162{ 163 return m_isShowingModal; 164} 165 166int wxDialog::ShowModal() 167{ 168 if ( IsModal() ) 169 { 170 wxFAIL_MSG( wxT("wxDialog:ShowModal called twice") ); 171 return GetReturnCode(); 172 } 173 174 // use the apps top level window as parent if none given unless explicitly 175 // forbidden 176 if ( !GetParent() && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) ) 177 { 178 wxWindow *parent = wxTheApp->GetTopWindow(); 179 if ( parent && parent != this ) 180 { 181 m_parent = parent; 182 } 183 } 184 185 Show(true); 186 187 m_isShowingModal = true; 188 189 wxASSERT_MSG( !m_windowDisabler, _T("disabling windows twice?") ); 190 191#if defined(__WXGTK__) || defined(__WXMGL__) 192 wxBusyCursorSuspender suspender; 193 // FIXME (FIXME_MGL) - make sure busy cursor disappears under MSW too 194#endif 195 196 m_windowDisabler = new wxWindowDisabler(this); 197 if ( !m_eventLoop ) 198 m_eventLoop = new wxEventLoop; 199 200 m_eventLoop->Run(); 201 202 return GetReturnCode(); 203} 204 205void wxDialog::EndModal(int retCode) 206{ 207 wxASSERT_MSG( m_eventLoop, _T("wxDialog is not modal") ); 208 209 SetReturnCode(retCode); 210 211 if ( !IsModal() ) 212 { 213 wxFAIL_MSG( wxT("wxDialog:EndModal called twice") ); 214 return; 215 } 216 217 m_isShowingModal = false; 218 219 m_eventLoop->Exit(); 220 221 Show(false); 222} 223