1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/preferencesg.cpp
3 // Purpose: Implementation of wxPreferencesEditor.
4 // Author: Vaclav Slavik
6 // Copyright: (c) 2013 Vaclav Slavik <vslavik@fastmail.fm>
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
10 // ============================================================================
12 // ============================================================================
14 // ----------------------------------------------------------------------------
16 // ----------------------------------------------------------------------------
18 // for compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
25 #if wxUSE_PREFERENCES_EDITOR
27 #include "wx/private/preferences.h"
29 #ifndef wxHAS_PREF_EDITOR_NATIVE
32 #include "wx/dialog.h"
33 #include "wx/notebook.h"
35 #include "wx/sharedptr.h"
36 #include "wx/scopedptr.h"
37 #include "wx/scopeguard.h"
38 #include "wx/vector.h"
43 class wxGenericPrefsDialog
: public wxDialog
46 wxGenericPrefsDialog(wxWindow
*parent
, const wxString
& title
)
47 : wxDialog(parent
, wxID_ANY
, title
,
48 wxDefaultPosition
, wxDefaultSize
,
49 wxDEFAULT_FRAME_STYLE
& ~(wxRESIZE_BORDER
| wxMAXIMIZE_BOX
| wxMINIMIZE_BOX
))
51 SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY
);
53 wxSizer
*sizer
= new wxBoxSizer(wxVERTICAL
);
55 m_notebook
= new wxNotebook(this, wxID_ANY
);
56 sizer
->Add(m_notebook
, wxSizerFlags(1).Expand().DoubleBorder());
59 SetEscapeId(wxID_CLOSE
);
60 sizer
->Add(CreateButtonSizer(wxCLOSE
), wxSizerFlags().Expand().DoubleBorder(wxBOTTOM
));
62 sizer
->Add(CreateButtonSizer(wxOK
| wxCANCEL
),
63 wxSizerFlags().Expand().DoubleBorder(wxLEFT
|wxRIGHT
|wxBOTTOM
));
68 void AddPage(wxPreferencesPage
*page
)
70 wxWindow
*win
= page
->CreateWindow(m_notebook
);
71 m_notebook
->AddPage(win
, page
->GetName());
74 int GetSelectedPage() const
76 return m_notebook
->GetSelection();
79 void SelectPage(int page
)
81 m_notebook
->ChangeSelection(page
);
85 wxNotebook
*m_notebook
;
89 class wxGenericPreferencesEditorImplBase
: public wxPreferencesEditorImpl
92 void SetTitle(const wxString
& title
)
97 virtual void AddPage(wxPreferencesPage
* page
)
99 m_pages
.push_back(wxSharedPtr
<wxPreferencesPage
>(page
));
103 wxGenericPrefsDialog
*CreateDialog(wxWindow
*parent
)
105 if ( m_title
.empty() )
107 // Use the default title, which should include the application name
108 // under both MSW and GTK (and OSX uses its own native
109 // implementation anyhow).
110 m_title
.Printf(_("%s Preferences"), wxTheApp
->GetAppDisplayName());
113 wxGenericPrefsDialog
*dlg
= new wxGenericPrefsDialog(parent
, m_title
);
115 // TODO: Don't create all pages immediately like this, do it on demand
116 // when a page is selected in the notebook (as is done on OS X).
118 // Currently, creating all pages is necessary so that the notebook
119 // can determine its best size. We'll need to extend
120 // wxPreferencesPage with a GetBestSize() virtual method to make
121 // it possible to defer the creation.
122 for ( Pages::const_iterator i
= m_pages
.begin();
126 dlg
->AddPage(i
->get());
134 typedef wxVector
< wxSharedPtr
<wxPreferencesPage
> > Pages
;
142 #ifdef wxHAS_PREF_EDITOR_MODELESS
144 class wxModelessPreferencesEditorImpl
: public wxGenericPreferencesEditorImplBase
147 virtual ~wxModelessPreferencesEditorImpl()
149 // m_win may already be destroyed if this destructor is called from
150 // wxApp's destructor. In that case, all windows -- including this
151 // one -- would already be destroyed by now.
156 virtual void Show(wxWindow
* parent
)
160 wxWindow
*win
= CreateDialog(parent
);
166 // Ideally, we'd reparent the dialog under 'parent', but it's
167 // probably not worth the hassle. We know the old parent is still
168 // valid, because otherwise Dismiss() would have been called and
174 virtual void Dismiss()
178 m_win
->Close(/*force=*/true);
184 wxWeakRef
<wxWindow
> m_win
;
188 wxGenericPreferencesEditorImplBase
* NewGenericImpl()
190 return new wxModelessPreferencesEditorImpl
;
193 #else // !wxHAS_PREF_EDITOR_MODELESS
195 class wxModalPreferencesEditorImpl
: public wxGenericPreferencesEditorImplBase
198 wxModalPreferencesEditorImpl()
204 virtual void Show(wxWindow
* parent
)
206 wxScopedPtr
<wxGenericPrefsDialog
> dlg(CreateDialog(parent
));
208 // Store it for Dismiss() but ensure that the pointer is reset to NULL
209 // when the dialog is destroyed on leaving this function.
211 wxON_BLOCK_EXIT_NULL(m_dlg
);
213 // Restore the previously selected page, if any.
214 if ( m_currentPage
!= -1 )
215 dlg
->SelectPage(m_currentPage
);
217 // Don't remember the last selected page if the dialog was cancelled.
218 if ( dlg
->ShowModal() != wxID_CANCEL
)
219 m_currentPage
= dlg
->GetSelectedPage();
222 virtual void Dismiss()
226 m_dlg
->EndModal(wxID_CANCEL
);
232 wxGenericPrefsDialog
* m_dlg
;
235 wxDECLARE_NO_COPY_CLASS(wxModalPreferencesEditorImpl
);
239 wxGenericPreferencesEditorImplBase
* NewGenericImpl()
241 return new wxModalPreferencesEditorImpl
;
244 #endif // !wxHAS_PREF_EDITOR_MODELESS
246 } // anonymous namespace
249 wxPreferencesEditorImpl
* wxPreferencesEditorImpl::Create(const wxString
& title
)
251 wxGenericPreferencesEditorImplBase
* const impl
= NewGenericImpl();
253 impl
->SetTitle(title
);
258 #endif // !wxHAS_PREF_EDITOR_NATIVE
260 #endif // wxUSE_PREFERENCES_EDITOR