]> git.saurik.com Git - wxWidgets.git/blame - src/generic/preferencesg.cpp
Don't crash in wxGridCellAutoWrapStringRenderer when the column is hidden.
[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
2aab96f5
VS
6// Copyright: (c) 2013 Vaclav Slavik <vslavik@fastmail.fm>
7// Licence: wxWindows licence
8///////////////////////////////////////////////////////////////////////////////
9
10// ============================================================================
11// declarations
12// ============================================================================
13
14// ----------------------------------------------------------------------------
15// headers
16// ----------------------------------------------------------------------------
17
18// for compilers that support precompilation, includes "wx.h".
19#include "wx/wxprec.h"
20
21#ifdef __BORLANDC__
22 #pragma hdrstop
23#endif
24
a9452957
VZ
25#if wxUSE_PREFERENCES_EDITOR
26
2aab96f5
VS
27#include "wx/private/preferences.h"
28
29#ifndef wxHAS_PREF_EDITOR_NATIVE
30
dc5d118e 31#include "wx/app.h"
2aab96f5
VS
32#include "wx/dialog.h"
33#include "wx/notebook.h"
34#include "wx/sizer.h"
35#include "wx/sharedptr.h"
36#include "wx/scopedptr.h"
615f9ff0 37#include "wx/scopeguard.h"
2aab96f5
VS
38#include "wx/vector.h"
39
654c4b7b
VZ
40namespace
41{
42
2aab96f5
VS
43class wxGenericPrefsDialog : public wxDialog
44{
45public:
654c4b7b
VZ
46 wxGenericPrefsDialog(wxWindow *parent, const wxString& title)
47 : wxDialog(parent, wxID_ANY, title,
2aab96f5
VS
48 wxDefaultPosition, wxDefaultSize,
49 wxDEFAULT_FRAME_STYLE & ~(wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX))
50 {
51 SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
52
53 wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
54
55 m_notebook = new wxNotebook(this, wxID_ANY);
56 sizer->Add(m_notebook, wxSizerFlags(1).Expand().DoubleBorder());
57
58#ifdef __WXGTK__
59 SetEscapeId(wxID_CLOSE);
60 sizer->Add(CreateButtonSizer(wxCLOSE), wxSizerFlags().Expand().DoubleBorder(wxBOTTOM));
61#else
62 sizer->Add(CreateButtonSizer(wxOK | wxCANCEL),
63 wxSizerFlags().Expand().DoubleBorder(wxLEFT|wxRIGHT|wxBOTTOM));
64#endif
65 SetSizer(sizer);
66 }
67
68 void AddPage(wxPreferencesPage *page)
69 {
70 wxWindow *win = page->CreateWindow(m_notebook);
71 m_notebook->AddPage(win, page->GetName());
72 }
73
f3c0bcfa
VZ
74 int GetSelectedPage() const
75 {
76 return m_notebook->GetSelection();
77 }
78
79 void SelectPage(int page)
80 {
81 m_notebook->ChangeSelection(page);
82 }
83
2aab96f5
VS
84private:
85 wxNotebook *m_notebook;
86};
87
88
89class wxGenericPreferencesEditorImplBase : public wxPreferencesEditorImpl
90{
91public:
654c4b7b
VZ
92 void SetTitle(const wxString& title)
93 {
94 m_title = title;
95 }
96
2aab96f5
VS
97 virtual void AddPage(wxPreferencesPage* page)
98 {
99 m_pages.push_back(wxSharedPtr<wxPreferencesPage>(page));
100 }
101
102protected:
2c544b40 103 wxGenericPrefsDialog *CreateDialog(wxWindow *parent)
2aab96f5 104 {
654c4b7b 105 if ( m_title.empty() )
dc5d118e
VZ
106 {
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());
111 }
654c4b7b
VZ
112
113 wxGenericPrefsDialog *dlg = new wxGenericPrefsDialog(parent, m_title);
2aab96f5
VS
114
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).
117 //
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();
123 i != m_pages.end();
124 ++i )
125 {
126 dlg->AddPage(i->get());
127 }
128
48e05747
VZ
129 dlg->Fit();
130
2aab96f5
VS
131 return dlg;
132 }
133
134 typedef wxVector< wxSharedPtr<wxPreferencesPage> > Pages;
135 Pages m_pages;
136
654c4b7b
VZ
137private:
138 wxString m_title;
2aab96f5
VS
139};
140
141
142#ifdef wxHAS_PREF_EDITOR_MODELESS
143
144class wxModelessPreferencesEditorImpl : public wxGenericPreferencesEditorImplBase
145{
146public:
147 virtual ~wxModelessPreferencesEditorImpl()
148 {
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.
152 if ( m_win )
153 m_win->Destroy();
154 }
155
156 virtual void Show(wxWindow* parent)
157 {
158 if ( !m_win )
159 {
2c544b40 160 wxWindow *win = CreateDialog(parent);
2aab96f5
VS
161 win->Show();
162 m_win = win;
163 }
164 else
165 {
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
169 // m_win cleared.
170 m_win->Raise();
171 }
172 }
173
174 virtual void Dismiss()
175 {
176 if ( m_win )
177 {
178 m_win->Close(/*force=*/true);
179 m_win = NULL;
180 }
181 }
182
183private:
184 wxWeakRef<wxWindow> m_win;
185};
186
654c4b7b
VZ
187inline
188wxGenericPreferencesEditorImplBase* NewGenericImpl()
189{
190 return new wxModelessPreferencesEditorImpl;
191}
192
2aab96f5
VS
193#else // !wxHAS_PREF_EDITOR_MODELESS
194
195class wxModalPreferencesEditorImpl : public wxGenericPreferencesEditorImplBase
196{
197public:
f3c0bcfa
VZ
198 wxModalPreferencesEditorImpl()
199 {
615f9ff0 200 m_dlg = NULL;
f3c0bcfa
VZ
201 m_currentPage = -1;
202 }
203
2aab96f5
VS
204 virtual void Show(wxWindow* parent)
205 {
2c544b40 206 wxScopedPtr<wxGenericPrefsDialog> dlg(CreateDialog(parent));
615f9ff0
VZ
207
208 // Store it for Dismiss() but ensure that the pointer is reset to NULL
209 // when the dialog is destroyed on leaving this function.
210 m_dlg = dlg.get();
211 wxON_BLOCK_EXIT_NULL(m_dlg);
212
f3c0bcfa
VZ
213 // Restore the previously selected page, if any.
214 if ( m_currentPage != -1 )
215 dlg->SelectPage(m_currentPage);
216
217 // Don't remember the last selected page if the dialog was cancelled.
218 if ( dlg->ShowModal() != wxID_CANCEL )
219 m_currentPage = dlg->GetSelectedPage();
2aab96f5
VS
220 }
221
222 virtual void Dismiss()
223 {
615f9ff0
VZ
224 if ( m_dlg )
225 {
226 m_dlg->EndModal(wxID_CANCEL);
227 m_dlg = NULL;
228 }
2aab96f5 229 }
f3c0bcfa
VZ
230
231private:
615f9ff0 232 wxGenericPrefsDialog* m_dlg;
f3c0bcfa 233 int m_currentPage;
615f9ff0
VZ
234
235 wxDECLARE_NO_COPY_CLASS(wxModalPreferencesEditorImpl);
2aab96f5
VS
236};
237
654c4b7b
VZ
238inline
239wxGenericPreferencesEditorImplBase* NewGenericImpl()
240{
241 return new wxModalPreferencesEditorImpl;
242}
243
2aab96f5
VS
244#endif // !wxHAS_PREF_EDITOR_MODELESS
245
654c4b7b 246} // anonymous namespace
2aab96f5
VS
247
248/*static*/
654c4b7b 249wxPreferencesEditorImpl* wxPreferencesEditorImpl::Create(const wxString& title)
2aab96f5 250{
654c4b7b
VZ
251 wxGenericPreferencesEditorImplBase* const impl = NewGenericImpl();
252
253 impl->SetTitle(title);
254
255 return impl;
2aab96f5
VS
256}
257
258#endif // !wxHAS_PREF_EDITOR_NATIVE
a9452957
VZ
259
260#endif // wxUSE_PREFERENCES_EDITOR