]> git.saurik.com Git - wxWidgets.git/blame - src/generic/preferencesg.cpp
missing commit
[wxWidgets.git] / src / generic / preferencesg.cpp
CommitLineData
2aab96f5
VS
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/generic/preferencesg.cpp
3// Purpose: Implementation of wxPreferencesEditor.
4// Author: Vaclav Slavik
5// Created: 2013-02-19
6// RCS-ID: $Id$
7// Copyright: (c) 2013 Vaclav Slavik <vslavik@fastmail.fm>
8// Licence: wxWindows licence
9///////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19// for compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#include "wx/private/preferences.h"
27
28#ifndef wxHAS_PREF_EDITOR_NATIVE
29
dc5d118e 30#include "wx/app.h"
2aab96f5
VS
31#include "wx/dialog.h"
32#include "wx/notebook.h"
33#include "wx/sizer.h"
34#include "wx/sharedptr.h"
35#include "wx/scopedptr.h"
615f9ff0 36#include "wx/scopeguard.h"
2aab96f5
VS
37#include "wx/vector.h"
38
654c4b7b
VZ
39namespace
40{
41
2aab96f5
VS
42class wxGenericPrefsDialog : public wxDialog
43{
44public:
654c4b7b
VZ
45 wxGenericPrefsDialog(wxWindow *parent, const wxString& title)
46 : wxDialog(parent, wxID_ANY, title,
2aab96f5
VS
47 wxDefaultPosition, wxDefaultSize,
48 wxDEFAULT_FRAME_STYLE & ~(wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX))
49 {
50 SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
51
52 wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
53
54 m_notebook = new wxNotebook(this, wxID_ANY);
55 sizer->Add(m_notebook, wxSizerFlags(1).Expand().DoubleBorder());
56
57#ifdef __WXGTK__
58 SetEscapeId(wxID_CLOSE);
59 sizer->Add(CreateButtonSizer(wxCLOSE), wxSizerFlags().Expand().DoubleBorder(wxBOTTOM));
60#else
61 sizer->Add(CreateButtonSizer(wxOK | wxCANCEL),
62 wxSizerFlags().Expand().DoubleBorder(wxLEFT|wxRIGHT|wxBOTTOM));
63#endif
64 SetSizer(sizer);
65 }
66
67 void AddPage(wxPreferencesPage *page)
68 {
69 wxWindow *win = page->CreateWindow(m_notebook);
70 m_notebook->AddPage(win, page->GetName());
71 }
72
f3c0bcfa
VZ
73 int GetSelectedPage() const
74 {
75 return m_notebook->GetSelection();
76 }
77
78 void SelectPage(int page)
79 {
80 m_notebook->ChangeSelection(page);
81 }
82
2aab96f5
VS
83private:
84 wxNotebook *m_notebook;
85};
86
87
88class wxGenericPreferencesEditorImplBase : public wxPreferencesEditorImpl
89{
90public:
654c4b7b
VZ
91 void SetTitle(const wxString& title)
92 {
93 m_title = title;
94 }
95
2aab96f5
VS
96 virtual void AddPage(wxPreferencesPage* page)
97 {
98 m_pages.push_back(wxSharedPtr<wxPreferencesPage>(page));
99 }
100
101protected:
2c544b40 102 wxGenericPrefsDialog *CreateDialog(wxWindow *parent)
2aab96f5 103 {
654c4b7b 104 if ( m_title.empty() )
dc5d118e
VZ
105 {
106 // Use the default title, which should include the application name
107 // under both MSW and GTK (and OSX uses its own native
108 // implementation anyhow).
109 m_title.Printf(_("%s Preferences"), wxTheApp->GetAppDisplayName());
110 }
654c4b7b
VZ
111
112 wxGenericPrefsDialog *dlg = new wxGenericPrefsDialog(parent, m_title);
2aab96f5
VS
113
114 // TODO: Don't create all pages immediately like this, do it on demand
115 // when a page is selected in the notebook (as is done on OS X).
116 //
117 // Currently, creating all pages is necessary so that the notebook
118 // can determine its best size. We'll need to extend
119 // wxPreferencesPage with a GetBestSize() virtual method to make
120 // it possible to defer the creation.
121 for ( Pages::const_iterator i = m_pages.begin();
122 i != m_pages.end();
123 ++i )
124 {
125 dlg->AddPage(i->get());
126 }
127
48e05747
VZ
128 dlg->Fit();
129
2aab96f5
VS
130 return dlg;
131 }
132
133 typedef wxVector< wxSharedPtr<wxPreferencesPage> > Pages;
134 Pages m_pages;
135
654c4b7b
VZ
136private:
137 wxString m_title;
2aab96f5
VS
138};
139
140
141#ifdef wxHAS_PREF_EDITOR_MODELESS
142
143class wxModelessPreferencesEditorImpl : public wxGenericPreferencesEditorImplBase
144{
145public:
146 virtual ~wxModelessPreferencesEditorImpl()
147 {
148 // m_win may already be destroyed if this destructor is called from
149 // wxApp's destructor. In that case, all windows -- including this
150 // one -- would already be destroyed by now.
151 if ( m_win )
152 m_win->Destroy();
153 }
154
155 virtual void Show(wxWindow* parent)
156 {
157 if ( !m_win )
158 {
2c544b40 159 wxWindow *win = CreateDialog(parent);
2aab96f5
VS
160 win->Show();
161 m_win = win;
162 }
163 else
164 {
165 // Ideally, we'd reparent the dialog under 'parent', but it's
166 // probably not worth the hassle. We know the old parent is still
167 // valid, because otherwise Dismiss() would have been called and
168 // m_win cleared.
169 m_win->Raise();
170 }
171 }
172
173 virtual void Dismiss()
174 {
175 if ( m_win )
176 {
177 m_win->Close(/*force=*/true);
178 m_win = NULL;
179 }
180 }
181
182private:
183 wxWeakRef<wxWindow> m_win;
184};
185
654c4b7b
VZ
186inline
187wxGenericPreferencesEditorImplBase* NewGenericImpl()
188{
189 return new wxModelessPreferencesEditorImpl;
190}
191
2aab96f5
VS
192#else // !wxHAS_PREF_EDITOR_MODELESS
193
194class wxModalPreferencesEditorImpl : public wxGenericPreferencesEditorImplBase
195{
196public:
f3c0bcfa
VZ
197 wxModalPreferencesEditorImpl()
198 {
615f9ff0 199 m_dlg = NULL;
f3c0bcfa
VZ
200 m_currentPage = -1;
201 }
202
2aab96f5
VS
203 virtual void Show(wxWindow* parent)
204 {
2c544b40 205 wxScopedPtr<wxGenericPrefsDialog> dlg(CreateDialog(parent));
615f9ff0
VZ
206
207 // Store it for Dismiss() but ensure that the pointer is reset to NULL
208 // when the dialog is destroyed on leaving this function.
209 m_dlg = dlg.get();
210 wxON_BLOCK_EXIT_NULL(m_dlg);
211
f3c0bcfa
VZ
212 // Restore the previously selected page, if any.
213 if ( m_currentPage != -1 )
214 dlg->SelectPage(m_currentPage);
215
216 // Don't remember the last selected page if the dialog was cancelled.
217 if ( dlg->ShowModal() != wxID_CANCEL )
218 m_currentPage = dlg->GetSelectedPage();
2aab96f5
VS
219 }
220
221 virtual void Dismiss()
222 {
615f9ff0
VZ
223 if ( m_dlg )
224 {
225 m_dlg->EndModal(wxID_CANCEL);
226 m_dlg = NULL;
227 }
2aab96f5 228 }
f3c0bcfa
VZ
229
230private:
615f9ff0 231 wxGenericPrefsDialog* m_dlg;
f3c0bcfa 232 int m_currentPage;
615f9ff0
VZ
233
234 wxDECLARE_NO_COPY_CLASS(wxModalPreferencesEditorImpl);
2aab96f5
VS
235};
236
654c4b7b
VZ
237inline
238wxGenericPreferencesEditorImplBase* NewGenericImpl()
239{
240 return new wxModalPreferencesEditorImpl;
241}
242
2aab96f5
VS
243#endif // !wxHAS_PREF_EDITOR_MODELESS
244
654c4b7b 245} // anonymous namespace
2aab96f5
VS
246
247/*static*/
654c4b7b 248wxPreferencesEditorImpl* wxPreferencesEditorImpl::Create(const wxString& title)
2aab96f5 249{
654c4b7b
VZ
250 wxGenericPreferencesEditorImplBase* const impl = NewGenericImpl();
251
252 impl->SetTitle(title);
253
254 return impl;
2aab96f5
VS
255}
256
257#endif // !wxHAS_PREF_EDITOR_NATIVE