1/////////////////////////////////////////////////////////////////////////////
2// Name:        src/gtk/dialog.cpp
3// Purpose:
4// Author:      Robert Roebling
5// Id:          $Id: dialog.cpp 45606 2007-04-23 20:11:11Z VZ $
6// Copyright:   (c) 1998 Robert Roebling
7// Licence:     wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
13#include "wx/dialog.h"
14
15#ifndef WX_PRECOMP
16    #include "wx/app.h"
17    #include "wx/frame.h"
18    #include "wx/cursor.h"
19#endif // WX_PRECOMP
20
21#include "wx/evtloop.h"
22
23#include <gdk/gdk.h>
24#include <gtk/gtk.h>
25#include <gdk/gdkkeysyms.h>
26
27#include "wx/gtk/win_gtk.h"
28
29//-----------------------------------------------------------------------------
30// global data
31//-----------------------------------------------------------------------------
32
33extern int g_openDialogs;
34
35//-----------------------------------------------------------------------------
36// wxDialog
37//-----------------------------------------------------------------------------
38
39IMPLEMENT_DYNAMIC_CLASS(wxDialog,wxTopLevelWindow)
40
41void wxDialog::Init()
42{
43    m_returnCode = 0;
44    m_sizeSet = false;
45    m_modalShowing = false;
46    m_themeEnabled = true;
47}
48
49wxDialog::wxDialog( wxWindow *parent,
50                    wxWindowID id, const wxString &title,
51                    const wxPoint &pos, const wxSize &size,
52                    long style, const wxString &name )
53{
54    Init();
55
56    (void)Create( parent, id, title, pos, size, style, name );
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
72bool wxDialog::Show( bool show )
73{
74    if (!show && IsModal())
75    {
76        EndModal( wxID_CANCEL );
77    }
78
79    if (show && !m_sizeSet)
80    {
81        /* by calling GtkOnSize here, we don't have to call
82           either after showing the frame, which would entail
83           much ugly flicker nor from within the size_allocate
84           handler, because GTK 1.1.X forbids that. */
85
86        GtkOnSize();
87    }
88
89    bool ret = wxWindow::Show( show );
90
91    if (show) InitDialog();
92
93    return ret;
94}
95
96bool wxDialog::IsModal() const
97{
98    return m_modalShowing;
99}
100
101void wxDialog::SetModal( bool WXUNUSED(flag) )
102{
103    wxFAIL_MSG( wxT("wxDialog:SetModal obsolete now") );
104}
105
106int wxDialog::ShowModal()
107{
108    if (IsModal())
109    {
110       wxFAIL_MSG( wxT("wxDialog:ShowModal called twice") );
111       return GetReturnCode();
112    }
113
114    // use the apps top level window as parent if none given unless explicitly
115    // forbidden
116    if ( !GetParent() && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) )
117    {
118        extern WXDLLIMPEXP_DATA_CORE(wxList) wxPendingDelete;
119
120        wxWindow * const parent = wxTheApp->GetTopWindow();
121
122        if ( parent &&
123                parent != this &&
124                    parent->IsShownOnScreen() &&
125                        !parent->IsBeingDeleted() &&
126                            !wxPendingDelete.Member(parent) &&
127                                !(parent->GetExtraStyle() & wxWS_EX_TRANSIENT) )
128        {
129            m_parent = parent;
130            gtk_window_set_transient_for( GTK_WINDOW(m_widget),
131                                          GTK_WINDOW(parent->m_widget) );
132        }
133    }
134
135    wxBusyCursorSuspender cs; // temporarily suppress the busy cursor
136
137    Show( true );
138
139    m_modalShowing = true;
140
141    g_openDialogs++;
142
143    // NOTE: gtk_window_set_modal internally calls gtk_grab_add() !
144    gtk_window_set_modal(GTK_WINDOW(m_widget), TRUE);
145
146    wxEventLoop().Run();
147
148    gtk_window_set_modal(GTK_WINDOW(m_widget), FALSE);
149
150    g_openDialogs--;
151
152    return GetReturnCode();
153}
154
155void wxDialog::EndModal( int retCode )
156{
157    SetReturnCode( retCode );
158
159    if (!IsModal())
160    {
161        wxFAIL_MSG( wxT("wxDialog:EndModal called twice") );
162        return;
163    }
164
165    m_modalShowing = false;
166
167    gtk_main_quit();
168
169    Show( false );
170}
171