Files
wxWidgets/src/generic/preferencesg.cpp
Vadim Zeitlin 654c4b7b14 Allow to specify the title used by wxPreferencesEditor window.
Customize the title is useful for "Settings"-style windows which are used for
editing the properties of the given object, that should be identified in the
window title, as opposed to the global program preferences.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74006 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2013-05-16 14:42:56 +00:00

237 lines
6.0 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Name: src/generic/preferencesg.cpp
// Purpose: Implementation of wxPreferencesEditor.
// Author: Vaclav Slavik
// Created: 2013-02-19
// RCS-ID: $Id$
// Copyright: (c) 2013 Vaclav Slavik <vslavik@fastmail.fm>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// for compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "wx/private/preferences.h"
#ifndef wxHAS_PREF_EDITOR_NATIVE
#include "wx/dialog.h"
#include "wx/notebook.h"
#include "wx/sizer.h"
#include "wx/sharedptr.h"
#include "wx/scopedptr.h"
#include "wx/vector.h"
namespace
{
class wxGenericPrefsDialog : public wxDialog
{
public:
wxGenericPrefsDialog(wxWindow *parent, const wxString& title)
: wxDialog(parent, wxID_ANY, title,
wxDefaultPosition, wxDefaultSize,
wxDEFAULT_FRAME_STYLE & ~(wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX))
{
SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
m_notebook = new wxNotebook(this, wxID_ANY);
sizer->Add(m_notebook, wxSizerFlags(1).Expand().DoubleBorder());
#ifdef __WXGTK__
SetEscapeId(wxID_CLOSE);
sizer->Add(CreateButtonSizer(wxCLOSE), wxSizerFlags().Expand().DoubleBorder(wxBOTTOM));
#else
sizer->Add(CreateButtonSizer(wxOK | wxCANCEL),
wxSizerFlags().Expand().DoubleBorder(wxLEFT|wxRIGHT|wxBOTTOM));
#endif
SetSizer(sizer);
}
void AddPage(wxPreferencesPage *page)
{
wxWindow *win = page->CreateWindow(m_notebook);
m_notebook->AddPage(win, page->GetName());
}
int GetSelectedPage() const
{
return m_notebook->GetSelection();
}
void SelectPage(int page)
{
m_notebook->ChangeSelection(page);
}
private:
wxNotebook *m_notebook;
};
class wxGenericPreferencesEditorImplBase : public wxPreferencesEditorImpl
{
public:
void SetTitle(const wxString& title)
{
m_title = title;
}
virtual void AddPage(wxPreferencesPage* page)
{
m_pages.push_back(wxSharedPtr<wxPreferencesPage>(page));
}
protected:
wxGenericPrefsDialog *CreateDialog(wxWindow *parent)
{
if ( m_title.empty() )
m_title = _("Preferences");
wxGenericPrefsDialog *dlg = new wxGenericPrefsDialog(parent, m_title);
// TODO: Don't create all pages immediately like this, do it on demand
// when a page is selected in the notebook (as is done on OS X).
//
// Currently, creating all pages is necessary so that the notebook
// can determine its best size. We'll need to extend
// wxPreferencesPage with a GetBestSize() virtual method to make
// it possible to defer the creation.
for ( Pages::const_iterator i = m_pages.begin();
i != m_pages.end();
++i )
{
dlg->AddPage(i->get());
}
return dlg;
}
typedef wxVector< wxSharedPtr<wxPreferencesPage> > Pages;
Pages m_pages;
private:
wxString m_title;
};
#ifdef wxHAS_PREF_EDITOR_MODELESS
class wxModelessPreferencesEditorImpl : public wxGenericPreferencesEditorImplBase
{
public:
virtual ~wxModelessPreferencesEditorImpl()
{
// m_win may already be destroyed if this destructor is called from
// wxApp's destructor. In that case, all windows -- including this
// one -- would already be destroyed by now.
if ( m_win )
m_win->Destroy();
}
virtual void Show(wxWindow* parent)
{
if ( !m_win )
{
wxWindow *win = CreateDialog(parent);
win->Show();
m_win = win;
}
else
{
// Ideally, we'd reparent the dialog under 'parent', but it's
// probably not worth the hassle. We know the old parent is still
// valid, because otherwise Dismiss() would have been called and
// m_win cleared.
m_win->Raise();
}
}
virtual void Dismiss()
{
if ( m_win )
{
m_win->Close(/*force=*/true);
m_win = NULL;
}
}
private:
wxWeakRef<wxWindow> m_win;
};
inline
wxGenericPreferencesEditorImplBase* NewGenericImpl()
{
return new wxModelessPreferencesEditorImpl;
}
#else // !wxHAS_PREF_EDITOR_MODELESS
class wxModalPreferencesEditorImpl : public wxGenericPreferencesEditorImplBase
{
public:
wxModalPreferencesEditorImpl()
{
m_currentPage = -1;
}
virtual void Show(wxWindow* parent)
{
wxScopedPtr<wxGenericPrefsDialog> dlg(CreateDialog(parent));
dlg->Fit();
// Restore the previously selected page, if any.
if ( m_currentPage != -1 )
dlg->SelectPage(m_currentPage);
// Don't remember the last selected page if the dialog was cancelled.
if ( dlg->ShowModal() != wxID_CANCEL )
m_currentPage = dlg->GetSelectedPage();
}
virtual void Dismiss()
{
// nothing to do
}
private:
int m_currentPage;
};
inline
wxGenericPreferencesEditorImplBase* NewGenericImpl()
{
return new wxModalPreferencesEditorImpl;
}
#endif // !wxHAS_PREF_EDITOR_MODELESS
} // anonymous namespace
/*static*/
wxPreferencesEditorImpl* wxPreferencesEditorImpl::Create(const wxString& title)
{
wxGenericPreferencesEditorImplBase* const impl = NewGenericImpl();
impl->SetTitle(title);
return impl;
}
#endif // !wxHAS_PREF_EDITOR_NATIVE