wxTOPLEVEL_EX_DIALOG is a better name than wxTLW_EX_DIALOG
[wxWidgets.git] / src / gtk1 / dialog.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: dialog.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 #ifdef __GNUG__
11 #pragma implementation "dialog.h"
12 #endif
13
14 #include "wx/dialog.h"
15 #include "wx/frame.h"
16 #include "wx/app.h"
17 #include "wx/cursor.h"
18
19 #include <gdk/gdk.h>
20 #include <gtk/gtk.h>
21 #include <gdk/gdkkeysyms.h>
22
23 #include "wx/gtk/win_gtk.h"
24
25 //-----------------------------------------------------------------------------
26 // idle system
27 //-----------------------------------------------------------------------------
28
29 extern void wxapp_install_idle_handler();
30 extern bool g_isIdle;
31 extern int g_openDialogs;
32
33
34
35 //-----------------------------------------------------------------------------
36 // wxDialog
37 //-----------------------------------------------------------------------------
38
39 BEGIN_EVENT_TABLE(wxDialog,wxDialogBase)
40 EVT_BUTTON (wxID_OK, wxDialog::OnOK)
41 EVT_BUTTON (wxID_CANCEL, wxDialog::OnCancel)
42 EVT_BUTTON (wxID_APPLY, wxDialog::OnApply)
43 EVT_CLOSE (wxDialog::OnCloseWindow)
44 END_EVENT_TABLE()
45
46 IMPLEMENT_DYNAMIC_CLASS(wxDialog,wxTopLevelWindow)
47
48 void wxDialog::Init()
49 {
50 m_returnCode = 0;
51 m_sizeSet = FALSE;
52 m_modalShowing = FALSE;
53 m_themeEnabled = TRUE;
54 }
55
56 wxDialog::wxDialog( wxWindow *parent,
57 wxWindowID id, const wxString &title,
58 const wxPoint &pos, const wxSize &size,
59 long style, const wxString &name )
60 {
61 Init();
62
63 // all dialogs should have tab traversal enabled
64 style |= wxTAB_TRAVERSAL;
65
66 Create( parent, id, title, pos, size, style, name );
67 }
68
69 bool wxDialog::Create( wxWindow *parent,
70 wxWindowID id, const wxString &title,
71 const wxPoint &pos, const wxSize &size,
72 long style, const wxString &name )
73 {
74 SetExtraStyle(GetExtraStyle() | wxTOPLEVEL_EX_DIALOG);
75
76 return wxTopLevelWindow::Create(parent, id, title, pos, size, style, name);
77 }
78
79 void wxDialog::OnApply( wxCommandEvent &WXUNUSED(event) )
80 {
81 if (Validate()) TransferDataFromWindow();
82 }
83
84 void wxDialog::OnCancel( wxCommandEvent &WXUNUSED(event) )
85 {
86 if (IsModal())
87 {
88 EndModal(wxID_CANCEL);
89 }
90 else
91 {
92 SetReturnCode(wxID_CANCEL);
93 Show(FALSE);
94 }
95 }
96
97 void wxDialog::OnOK( wxCommandEvent &WXUNUSED(event) )
98 {
99 if (Validate() && TransferDataFromWindow())
100 {
101 if (IsModal())
102 {
103 EndModal(wxID_OK);
104 }
105 else
106 {
107 SetReturnCode(wxID_OK);
108 Show(FALSE);
109 }
110 }
111 }
112
113 void wxDialog::OnPaint( wxPaintEvent& WXUNUSED(event) )
114 {
115 // yes
116 }
117
118 void wxDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
119 {
120 // We'll send a Cancel message by default,
121 // which may close the dialog.
122 // Check for looping if the Cancel event handler calls Close().
123
124 // Note that if a cancel button and handler aren't present in the dialog,
125 // nothing will happen when you close the dialog via the window manager, or
126 // via Close().
127 // We wouldn't want to destroy the dialog by default, since the dialog may have been
128 // created on the stack.
129 // However, this does mean that calling dialog->Close() won't delete the dialog
130 // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
131 // sure to destroy the dialog.
132 // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
133
134 static wxList s_closing;
135
136 if (s_closing.Member(this))
137 return; // no loops
138
139 s_closing.Append(this);
140
141 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
142 cancelEvent.SetEventObject( this );
143 GetEventHandler()->ProcessEvent(cancelEvent);
144 s_closing.DeleteObject(this);
145 }
146
147 bool wxDialog::Show( bool show )
148 {
149 if (!show && IsModal())
150 {
151 EndModal( wxID_CANCEL );
152 }
153
154 if (show && !m_sizeSet)
155 {
156 /* by calling GtkOnSize here, we don't have to call
157 either after showing the frame, which would entail
158 much ugly flicker nor from within the size_allocate
159 handler, because GTK 1.1.X forbids that. */
160
161 GtkOnSize( m_x, m_y, m_width, m_height );
162 }
163
164 bool ret = wxWindow::Show( show );
165
166 if (show) InitDialog();
167
168 return ret;
169 }
170
171 bool wxDialog::IsModal() const
172 {
173 return m_modalShowing;
174 }
175
176 void wxDialog::SetModal( bool WXUNUSED(flag) )
177 {
178 /*
179 if (flag)
180 m_windowStyle |= wxDIALOG_MODAL;
181 else
182 if (m_windowStyle & wxDIALOG_MODAL) m_windowStyle -= wxDIALOG_MODAL;
183 */
184 wxFAIL_MSG( wxT("wxDialog:SetModal obsolete now") );
185 }
186
187 int wxDialog::ShowModal()
188 {
189 if (IsModal())
190 {
191 wxFAIL_MSG( wxT("wxDialog:ShowModal called twice") );
192 return GetReturnCode();
193 }
194
195 // use the apps top level window as parent if none given unless explicitly
196 // forbidden
197 if ( !GetParent() && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) )
198 {
199 wxWindow *parent = wxTheApp->GetTopWindow();
200 if ( parent && parent != this )
201 {
202 m_parent = parent;
203 gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(parent->m_widget) );
204 }
205 }
206
207 wxBusyCursorSuspender cs; // temporarily suppress the busy cursor
208
209 Show( TRUE );
210
211 m_modalShowing = TRUE;
212
213 g_openDialogs++;
214
215 gtk_grab_add( m_widget );
216 gtk_main();
217 gtk_grab_remove( m_widget );
218
219 g_openDialogs--;
220
221 return GetReturnCode();
222 }
223
224 void wxDialog::EndModal( int retCode )
225 {
226 SetReturnCode( retCode );
227
228 if (!IsModal())
229 {
230 wxFAIL_MSG( wxT("wxDialog:EndModal called twice") );
231 return;
232 }
233
234 m_modalShowing = FALSE;
235
236 gtk_main_quit();
237
238 Show( FALSE );
239 }