diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index 7f7df24dd..4a9e63021 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -92,6 +92,7 @@ It handles initialization and termination by subclassing wxApp. #include "ondemand/ODManager.h" #include "commands/Keyboard.h" #include "widgets/ErrorDialog.h" +#include "prefs/DirectoriesPrefs.h" //temporarilly commented out till it is added to all projects //#include "Profiler.h" @@ -1605,8 +1606,11 @@ bool AudacityApp::InitTempDir() // Failed wxMessageBox(_("Audacity could not find a place to store temporary files.\nPlease enter an appropriate directory in the preferences dialog.")); - PrefsDialog dialog(NULL); - dialog.ShowTempDirPage(); + // Only want one page of the preferences + DirectoriesPrefsFactory directoriesPrefsFactory; + PrefsDialog::Factories factories; + factories.push_back(&directoriesPrefsFactory); + GlobalPrefsDialog dialog(NULL, factories); dialog.ShowModal(); wxMessageBox(_("Audacity is now going to exit. Please launch Audacity again to use the new temporary directory.")); @@ -2132,7 +2136,7 @@ void AudacityApp::OnMenuPreferences(wxCommandEvent & event) // all platforms. if(gAudacityProjects.GetCount() == 0) { - PrefsDialog dialog(NULL /* parent */ ); + GlobalPrefsDialog dialog(NULL /* parent */ ); dialog.ShowModal(); } else diff --git a/src/DirManager.cpp b/src/DirManager.cpp index 8104f56b1..691915c5a 100644 --- a/src/DirManager.cpp +++ b/src/DirManager.cpp @@ -101,7 +101,6 @@ #include "widgets/Warning.h" #include "widgets/MultiDialog.h" -#include "prefs/PrefsDialog.h" #include "ondemand/ODManager.h" #if defined(__WXMAC__) diff --git a/src/Menus.cpp b/src/Menus.cpp index 5ecfcce68..92c00da52 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -3586,7 +3586,7 @@ void AudacityProject::OnExportMultiple() void AudacityProject::OnPreferences() { - PrefsDialog dialog(this /* parent */ ); + GlobalPrefsDialog dialog(this /* parent */ ); if (!dialog.ShowModal()) { // Canceled diff --git a/src/prefs/BatchPrefs.cpp b/src/prefs/BatchPrefs.cpp index 8f7664d2c..94ce27880 100644 --- a/src/prefs/BatchPrefs.cpp +++ b/src/prefs/BatchPrefs.cpp @@ -82,3 +82,8 @@ bool BatchPrefs::Apply() BatchPrefs::~BatchPrefs() { } + +PrefsPanel *BatchPrefsFactory::Create(wxWindow *parent) +{ + return new BatchPrefs(parent); +} diff --git a/src/prefs/BatchPrefs.h b/src/prefs/BatchPrefs.h index 427e7233c..98210b973 100644 --- a/src/prefs/BatchPrefs.h +++ b/src/prefs/BatchPrefs.h @@ -34,4 +34,9 @@ private: DECLARE_EVENT_TABLE(); }; +class BatchPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/DevicePrefs.cpp b/src/prefs/DevicePrefs.cpp index 24e5fa502..c0663c84c 100644 --- a/src/prefs/DevicePrefs.cpp +++ b/src/prefs/DevicePrefs.cpp @@ -373,3 +373,8 @@ bool DevicePrefs::Apply() return true; } + +PrefsPanel *DevicePrefsFactory::Create(wxWindow *parent) +{ + return new DevicePrefs(parent); +} diff --git a/src/prefs/DevicePrefs.h b/src/prefs/DevicePrefs.h index 67d3bef24..bb3bc7b65 100644 --- a/src/prefs/DevicePrefs.h +++ b/src/prefs/DevicePrefs.h @@ -54,4 +54,10 @@ class DevicePrefs :public PrefsPanel DECLARE_EVENT_TABLE(); }; +class DevicePrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; + #endif diff --git a/src/prefs/DirectoriesPrefs.cpp b/src/prefs/DirectoriesPrefs.cpp index 606e3891b..1a48313ff 100644 --- a/src/prefs/DirectoriesPrefs.cpp +++ b/src/prefs/DirectoriesPrefs.cpp @@ -242,3 +242,8 @@ bool DirectoriesPrefs::Apply() return true; } + +PrefsPanel *DirectoriesPrefsFactory::Create(wxWindow *parent) +{ + return new DirectoriesPrefs(parent); +} diff --git a/src/prefs/DirectoriesPrefs.h b/src/prefs/DirectoriesPrefs.h index 404071857..423fd005d 100644 --- a/src/prefs/DirectoriesPrefs.h +++ b/src/prefs/DirectoriesPrefs.h @@ -38,4 +38,9 @@ class DirectoriesPrefs :public PrefsPanel DECLARE_EVENT_TABLE(); }; +class DirectoriesPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/EffectsPrefs.cpp b/src/prefs/EffectsPrefs.cpp index cf5ae326e..e8a36f1f8 100644 --- a/src/prefs/EffectsPrefs.cpp +++ b/src/prefs/EffectsPrefs.cpp @@ -165,3 +165,8 @@ bool EffectsPrefs::Apply() return true; } + +PrefsPanel *EffectsPrefsFactory::Create(wxWindow *parent) +{ + return new EffectsPrefs(parent); +} diff --git a/src/prefs/EffectsPrefs.h b/src/prefs/EffectsPrefs.h index 0d096c042..484913352 100644 --- a/src/prefs/EffectsPrefs.h +++ b/src/prefs/EffectsPrefs.h @@ -34,4 +34,9 @@ class EffectsPrefs :public PrefsPanel void PopulateOrExchange(ShuttleGui & S); }; +class EffectsPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/ExtImportPrefs.cpp b/src/prefs/ExtImportPrefs.cpp index 9e6550cb7..26c1b6593 100644 --- a/src/prefs/ExtImportPrefs.cpp +++ b/src/prefs/ExtImportPrefs.cpp @@ -780,3 +780,8 @@ void ExtImportPrefsDropTarget::SetDataObject(wxDataObject* data) { this->m_dataObject = data; } + +PrefsPanel *ExtImportPrefsFactory::Create(wxWindow *parent) +{ + return new ExtImportPrefs(parent); +} diff --git a/src/prefs/ExtImportPrefs.h b/src/prefs/ExtImportPrefs.h index d97f29b69..38670d8e3 100644 --- a/src/prefs/ExtImportPrefs.h +++ b/src/prefs/ExtImportPrefs.h @@ -107,4 +107,10 @@ class ExtImportPrefs:public PrefsPanel DECLARE_EVENT_TABLE() }; + +class ExtImportPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/GUIPrefs.cpp b/src/prefs/GUIPrefs.cpp index c6fc5aa04..61e54f1f1 100644 --- a/src/prefs/GUIPrefs.cpp +++ b/src/prefs/GUIPrefs.cpp @@ -158,3 +158,8 @@ bool GUIPrefs::Apply() return true; } + +PrefsPanel *GUIPrefsFactory::Create(wxWindow *parent) +{ + return new GUIPrefs(parent); +} diff --git a/src/prefs/GUIPrefs.h b/src/prefs/GUIPrefs.h index e3af2b7f3..7f114f53a 100644 --- a/src/prefs/GUIPrefs.h +++ b/src/prefs/GUIPrefs.h @@ -43,4 +43,9 @@ class GUIPrefs :public PrefsPanel wxArrayString mRangeChoices; }; +class GUIPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/ImportExportPrefs.cpp b/src/prefs/ImportExportPrefs.cpp index f6e9538f2..609689cc9 100644 --- a/src/prefs/ImportExportPrefs.cpp +++ b/src/prefs/ImportExportPrefs.cpp @@ -109,3 +109,8 @@ bool ImportExportPrefs::Apply() return true; } + +PrefsPanel *ImportExportPrefsFactory::Create(wxWindow *parent) +{ + return new ImportExportPrefs(parent); +} diff --git a/src/prefs/ImportExportPrefs.h b/src/prefs/ImportExportPrefs.h index 9ba891ea7..9ffe03541 100644 --- a/src/prefs/ImportExportPrefs.h +++ b/src/prefs/ImportExportPrefs.h @@ -33,4 +33,9 @@ class ImportExportPrefs :public PrefsPanel void PopulateOrExchange(ShuttleGui & S); }; +class ImportExportPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/KeyConfigPrefs.cpp b/src/prefs/KeyConfigPrefs.cpp index dbd71e275..07e088512 100644 --- a/src/prefs/KeyConfigPrefs.cpp +++ b/src/prefs/KeyConfigPrefs.cpp @@ -1211,3 +1211,8 @@ void KeyConfigPrefs::Cancel() } #endif + +PrefsPanel *KeyConfigPrefsFactory::Create(wxWindow *parent) +{ + return new KeyConfigPrefs(parent); +} diff --git a/src/prefs/KeyConfigPrefs.h b/src/prefs/KeyConfigPrefs.h index 36f869ec4..e6b2e942a 100644 --- a/src/prefs/KeyConfigPrefs.h +++ b/src/prefs/KeyConfigPrefs.h @@ -141,6 +141,12 @@ class KeyConfigPrefs:public PrefsPanel DECLARE_EVENT_TABLE(); }; -#endif #endif + +class KeyConfigPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; +#endif diff --git a/src/prefs/LibraryPrefs.cpp b/src/prefs/LibraryPrefs.cpp index b1b42ec33..d3632c582 100644 --- a/src/prefs/LibraryPrefs.cpp +++ b/src/prefs/LibraryPrefs.cpp @@ -235,3 +235,8 @@ bool LibraryPrefs::Apply() return true; } + +PrefsPanel *LibraryPrefsFactory::Create(wxWindow *parent) +{ + return new LibraryPrefs(parent); +} diff --git a/src/prefs/LibraryPrefs.h b/src/prefs/LibraryPrefs.h index 15e54a98f..f3a35417d 100644 --- a/src/prefs/LibraryPrefs.h +++ b/src/prefs/LibraryPrefs.h @@ -46,4 +46,9 @@ class LibraryPrefs :public PrefsPanel DECLARE_EVENT_TABLE(); }; +class LibraryPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/MidiIOPrefs.cpp b/src/prefs/MidiIOPrefs.cpp index d541e6ec3..382876e1b 100644 --- a/src/prefs/MidiIOPrefs.cpp +++ b/src/prefs/MidiIOPrefs.cpp @@ -284,4 +284,9 @@ bool MidiIOPrefs::Validate() return true; } +PrefsPanel *MidiIOPrefsFactory::Create(wxWindow *parent) +{ + return new MidiIOPrefs(parent); +} + #endif diff --git a/src/prefs/MidiIOPrefs.h b/src/prefs/MidiIOPrefs.h index 81da992c3..1970b7061 100644 --- a/src/prefs/MidiIOPrefs.h +++ b/src/prefs/MidiIOPrefs.h @@ -62,6 +62,11 @@ class MidiIOPrefs:public PrefsPanel DECLARE_EVENT_TABLE(); }; +class MidiIOPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif #endif diff --git a/src/prefs/ModulePrefs.cpp b/src/prefs/ModulePrefs.cpp index a9a2d9c30..01544b50b 100644 --- a/src/prefs/ModulePrefs.cpp +++ b/src/prefs/ModulePrefs.cpp @@ -161,5 +161,9 @@ void ModulePrefs::SetModuleStatus( wxString fname, int iStatus ){ gPrefs->Flush(); } +PrefsPanel *ModulePrefsFactory::Create(wxWindow *parent) +{ + return new ModulePrefs(parent); +} diff --git a/src/prefs/ModulePrefs.h b/src/prefs/ModulePrefs.h index 9014e96a5..09d80a1d2 100644 --- a/src/prefs/ModulePrefs.h +++ b/src/prefs/ModulePrefs.h @@ -50,4 +50,9 @@ class ModulePrefs:public PrefsPanel wxArrayString mPaths; }; +class ModulePrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/MousePrefs.cpp b/src/prefs/MousePrefs.cpp index 4618ddf39..42d99f78c 100644 --- a/src/prefs/MousePrefs.cpp +++ b/src/prefs/MousePrefs.cpp @@ -196,3 +196,8 @@ bool MousePrefs::Apply() // PopulateOrExchange(S); return true; } + +PrefsPanel *MousePrefsFactory::Create(wxWindow *parent) +{ + return new MousePrefs(parent); +} diff --git a/src/prefs/MousePrefs.h b/src/prefs/MousePrefs.h index 33f5254ea..df8803732 100644 --- a/src/prefs/MousePrefs.h +++ b/src/prefs/MousePrefs.h @@ -38,4 +38,9 @@ class MousePrefs :public PrefsPanel wxListCtrl * mList; }; +class MousePrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/PlaybackPrefs.cpp b/src/prefs/PlaybackPrefs.cpp index 997d9be13..d3c56e5c3 100644 --- a/src/prefs/PlaybackPrefs.cpp +++ b/src/prefs/PlaybackPrefs.cpp @@ -122,3 +122,8 @@ bool PlaybackPrefs::Apply() return true; } + +PrefsPanel *PlaybackPrefsFactory::Create(wxWindow *parent) +{ + return new PlaybackPrefs(parent); +} diff --git a/src/prefs/PlaybackPrefs.h b/src/prefs/PlaybackPrefs.h index 8384fb584..057b51d84 100644 --- a/src/prefs/PlaybackPrefs.h +++ b/src/prefs/PlaybackPrefs.h @@ -32,4 +32,10 @@ class PlaybackPrefs :public PrefsPanel void PopulateOrExchange(ShuttleGui & S); }; +class PlaybackPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; + #endif diff --git a/src/prefs/PrefsDialog.cpp b/src/prefs/PrefsDialog.cpp index 91f18bc65..71a63fe5b 100644 --- a/src/prefs/PrefsDialog.cpp +++ b/src/prefs/PrefsDialog.cpp @@ -15,6 +15,7 @@ *//*******************************************************************/ #include "../Audacity.h" +#include "PrefsDialog.h" #include #include @@ -41,7 +42,6 @@ #include "../Prefs.h" #include "../ShuttleGui.h" -#include "PrefsDialog.h" #include "PrefsPanel.h" #include "BatchPrefs.h" @@ -81,11 +81,14 @@ class wxTreebookExt : public wxTreebook { public: wxTreebookExt( wxWindow *parent, - wxWindowID id) : wxTreebook( parent, id ) + wxWindowID id, const wxString &titlePrefix) + : wxTreebook( parent, id ) + , mTitlePrefix(titlePrefix) {;}; ~wxTreebookExt(){;}; virtual int ChangeSelection(size_t n); virtual int SetSelection(size_t n); + const wxString mTitlePrefix; }; @@ -100,7 +103,7 @@ int wxTreebookExt::ChangeSelection(size_t n) { int wxTreebookExt::SetSelection(size_t n) { int i = wxTreebook::SetSelection(n); - wxString Temp = wxString(_("Preferences: ")) + GetPageText( n ); + wxString Temp = wxString(mTitlePrefix) + GetPageText( n ); ((wxDialog*)GetParent())->SetTitle( Temp ); ((wxDialog*)GetParent())->SetName( Temp ); return i; @@ -108,11 +111,84 @@ int wxTreebookExt::SetSelection(size_t n) -PrefsDialog::PrefsDialog(wxWindow * parent) +PrefsDialog::Factories +&PrefsDialog::DefaultFactories() +{ + // To do, perhaps: create this table by registration, without including each PrefsPanel + // class... and thus allowing a plug-in protocol + static DevicePrefsFactory devicePrefsFactory; + static PlaybackPrefsFactory playbackPrefsFactory; + static RecordingPrefsFactory recordingPrefsFactory; +#ifdef EXPERIMENTAL_MIDI_OUT + static MidiIOPrefsFactory midiIOPrefsFactory; +#endif + static QualityPrefsFactory qualityPrefsFactory; + static GUIPrefsFactory guiPrefsFactory; + static TracksPrefsFactory tracksPrefsFactory; + static ImportExportPrefsFactory importExportPrefsFactory; + static ExtImportPrefsFactory extImportPrefsFactory; + static ProjectsPrefsFactory projectsPrefsFactory; +#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || !defined(DISABLE_DYNAMIC_LOADING_LAME) + static LibraryPrefsFactory libraryPrefsFactory; +#endif + static SpectrumPrefsFactory spectrumPrefsFactory; + static DirectoriesPrefsFactory directoriesPrefsFactory; + static WarningsPrefsFactory warningsPrefsFactory; + static EffectsPrefsFactory effectsPrefsFactory; +#ifdef EXPERIMENTAL_THEME_PREFS + static ThemePrefsFactory themePrefsFactory; +#endif + // static BatchPrefsFactory batchPrefsFactory; + static KeyConfigPrefsFactory keyConfigPrefsFactory; + static MousePrefsFactory mousePrefsFactory; +#ifdef EXPERIMENTAL_MODULE_PREFS + static ModulePrefsFactory modulePrefsFactory; +#endif + + static PrefsNode nodes[] = { + &devicePrefsFactory, + &playbackPrefsFactory, + &recordingPrefsFactory, +#ifdef EXPERIMENTAL_MIDI_OUT + &midiIOPrefsFactory, +#endif + &qualityPrefsFactory, + &guiPrefsFactory, + &tracksPrefsFactory, + &importExportPrefsFactory, + &extImportPrefsFactory, + &projectsPrefsFactory, +#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || !defined(DISABLE_DYNAMIC_LOADING_LAME) + &libraryPrefsFactory, +#endif + &spectrumPrefsFactory, + &directoriesPrefsFactory, + &warningsPrefsFactory, + &effectsPrefsFactory, +#ifdef EXPERIMENTAL_THEME_PREFS + &themePrefsFactory, +#endif + // &batchPrefsFactory, + &keyConfigPrefsFactory, + &mousePrefsFactory, +#ifdef EXPERIMENTAL_MODULE_PREFS + &modulePrefsFactory, +#endif + }; + + static Factories factories(nodes, nodes + sizeof(nodes) / sizeof(nodes[0])); + return factories; +} + + +PrefsDialog::PrefsDialog + (wxWindow * parent, const wxString &titlePrefix, Factories &factories) : wxDialog(parent, wxID_ANY, wxString(_("Audacity Preferences")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +, mFactories(factories) +, mTitlePrefix(titlePrefix) { ShuttleGui S(this, eIsCreating); @@ -120,42 +196,36 @@ PrefsDialog::PrefsDialog(wxWindow * parent) { S.StartHorizontalLay(wxALIGN_LEFT | wxEXPAND, true); { - mCategories = new wxTreebookExt(this, wxID_ANY); + mCategories = new wxTreebookExt(this, wxID_ANY, mTitlePrefix); S.Prop(1); S.AddWindow(mCategories, wxEXPAND); - wxWindow *w; - // Parameters are: AddPage(page, name, IsSelected, imageId). - w = new DevicePrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); - w = new PlaybackPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); - w = new RecordingPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); -#ifdef EXPERIMENTAL_MIDI_OUT - w = new MidiIOPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); -#endif - w = new QualityPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); - w = new GUIPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); - w = new TracksPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); - w = new ImportExportPrefs(mCategories);mCategories->AddPage(w, w->GetName(), false, 0); - w = new ExtImportPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); - w = new ProjectsPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); -#if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || !defined(DISABLE_DYNAMIC_LOADING_LAME) - w = new LibraryPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); -#endif - w = new SpectrumPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); - w = new DirectoriesPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); - w = new WarningsPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); - w = new EffectsPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); - -#ifdef EXPERIMENTAL_THEME_PREFS - w = new ThemePrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); -#endif - -// w = new BatchPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); - w = new KeyConfigPrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); - w = new MousePrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); -#ifdef EXPERIMENTAL_MODULE_PREFS - w = new ModulePrefs(mCategories); mCategories->AddPage(w, w->GetName(), false, 0); -#endif + { + typedef std::pair IntPair; + std::vector stack; + int iPage = 0; + for (Factories::const_iterator it = factories.begin(), end = factories.end(); + it != end; ++it, ++iPage) + { + const PrefsNode &node = *it; + PrefsPanelFactory &factory = *node.pFactory; + wxWindow *const w = factory.Create(mCategories); + if (stack.empty()) + // Parameters are: AddPage(page, name, IsSelected, imageId). + mCategories->AddPage(w, w->GetName(), false, 0); + else { + IntPair &top = *stack.rbegin(); + mCategories->InsertSubPage(top.first, w, w->GetName(), false, 0); + if (--top.second == 0) { + // Expand all nodes before the layout calculation + mCategories->ExpandNode(top.first, true); + stack.pop_back(); + } + } + if (node.nChildren > 0) + stack.push_back(IntPair(iPage, node.nChildren)); + } + } } S.EndHorizontalLay(); } @@ -163,23 +233,6 @@ PrefsDialog::PrefsDialog(wxWindow * parent) S.AddStandardButtons(eOkButton | eCancelButton); - /* long is signed, size_t is unsigned. On some platforms they are different - * lengths as well. So we must check that the stored category is both > 0 - * and within the possible range of categories, making the first check on the - * _signed_ value to avoid issues when converting an unsigned one. - */ - size_t selected; - long prefscat = gPrefs->Read(wxT("/Prefs/PrefsCategory"), 0L); - if (prefscat > 0L ) - selected = prefscat; // only assign if number will fit - else - selected = 0; // use 0 if value can't be assigned - - if (selected >= mCategories->GetPageCount()) - selected = 0; // clamp to available range of tabs - - mCategories->SetSelection(selected); - #if defined(__WXGTK__) mCategories->GetTreeCtrl()->EnsureVisible(mCategories->GetTreeCtrl()->GetRootItem()); #endif @@ -189,6 +242,14 @@ PrefsDialog::PrefsDialog(wxWindow * parent) Fit(); wxSize sz = GetSize(); + // Collapse nodes only after layout so the tree is wide enough + { + int iPage = 0; + for (Factories::const_iterator it = factories.begin(), end = factories.end(); + it != end; ++it, ++iPage) + mCategories->ExpandNode(iPage, it->expanded); + } + // This ASSERT used to limit us to 800 x 600. // However, we think screens have got bigger now, and that was a bit too restrictive. // The impetus for increasing the limit (before we ASSERT) was that this ASSERT @@ -219,8 +280,25 @@ PrefsDialog::~PrefsDialog() { } +int PrefsDialog::ShowModal() +{ + /* long is signed, size_t is unsigned. On some platforms they are different + * lengths as well. So we must check that the stored category is both > 0 + * and within the possible range of categories, making the first check on the + * _signed_ value to avoid issues when converting an unsigned one. + */ + long selected = GetPreferredPage(); + if (selected < 0 || size_t(selected) >= mCategories->GetPageCount()) + selected = 0; // clamp to available range of tabs + mCategories->SetSelection(selected); + + return wxDialog::ShowModal(); +} + void PrefsDialog::OnCancel(wxCommandEvent & WXUNUSED(event)) { + RecordExpansionState(); + for (size_t i = 0; i < mCategories->GetPageCount(); i++) { ((PrefsPanel *) mCategories->GetPage(i))->Cancel(); } @@ -238,6 +316,8 @@ void PrefsDialog::OnTreeKeyDown(wxTreeEvent & event) void PrefsDialog::OnOK(wxCommandEvent & WXUNUSED(event)) { + RecordExpansionState(); + // Validate all pages first for (size_t i = 0; i < mCategories->GetPageCount(); i++) { PrefsPanel *panel = (PrefsPanel *) mCategories->GetPage(i); @@ -256,8 +336,7 @@ void PrefsDialog::OnOK(wxCommandEvent & WXUNUSED(event)) panel->Apply(); } - gPrefs->Write(wxT("/Prefs/PrefsCategory"), (long)mCategories->GetSelection()); - gPrefs->Flush(); + SavePreferredPage(); #if USE_PORTMIXER if (gAudioIO) { @@ -307,7 +386,39 @@ void PrefsDialog::SelectPageByName(wxString pageName) } } -void PrefsDialog::ShowTempDirPage() +int PrefsDialog::GetSelectedPage() const { - SelectPageByName(_("Directories")); + return mCategories->GetSelection(); +} + +GlobalPrefsDialog::GlobalPrefsDialog(wxWindow * parent, Factories &factories) + : PrefsDialog(parent, _("Preferences: "), factories) +{ +} + +GlobalPrefsDialog::~GlobalPrefsDialog() +{ +} + +long GlobalPrefsDialog::GetPreferredPage() +{ + long prefscat = gPrefs->Read(wxT("/Prefs/PrefsCategory"), 0L); + return prefscat; +} + +void GlobalPrefsDialog::SavePreferredPage() +{ + gPrefs->Write(wxT("/Prefs/PrefsCategory"), (long)GetSelectedPage()); + gPrefs->Flush(); +} + +void PrefsDialog::RecordExpansionState() +{ + // Remember expansion state of the tree control + { + int iPage = 0; + for (Factories::iterator it = mFactories.begin(), end = mFactories.end(); + it != end; ++it, ++iPage) + it->expanded = mCategories->IsNodeExpanded(iPage); + } } diff --git a/src/prefs/PrefsDialog.h b/src/prefs/PrefsDialog.h index 13f3d3e0c..a4b468921 100644 --- a/src/prefs/PrefsDialog.h +++ b/src/prefs/PrefsDialog.h @@ -12,6 +12,7 @@ #ifndef __AUDACITY_PREFS_DIALOG__ #define __AUDACITY_PREFS_DIALOG__ +#include #include #include #include @@ -19,24 +20,74 @@ #include #include +class PrefsPanelFactory; + +#ifdef __GNUC__ +#define CONST +#else +#define CONST const +#endif + class PrefsDialog:public wxDialog { public: - PrefsDialog(wxWindow * parent); + // An array of PrefsNode specifies the tree of pages in pre-order traversal. + struct PrefsNode { + PrefsPanelFactory * CONST pFactory; + CONST int nChildren; + bool expanded; + + PrefsNode(PrefsPanelFactory *pFactory_, int nChildren_ = 0) + : pFactory(pFactory_), nChildren(nChildren_), expanded(false) + {} + }; + typedef std::vector Factories; + static Factories &DefaultFactories(); + + PrefsDialog(wxWindow * parent, + const wxString &titlePrefix = _("Preferences: "), + Factories &factories = DefaultFactories()); virtual ~PrefsDialog(); + // Defined this so a protected virtual can be invoked after the constructor + virtual int ShowModal(); + void OnCategoryChange(wxCommandEvent & e); void OnOK(wxCommandEvent & e); void OnCancel(wxCommandEvent & e); void OnTreeKeyDown(wxTreeEvent & e); // Used to dismiss the dialog when enter is pressed with focus on tree void SelectPageByName(wxString pageName); - void ShowTempDirPage(); - private: + // Accessor to help implementations of SavePreferredPage(), + // such as by saving a preference after DoModal() returns + int GetSelectedPage() const; + + protected: + // Decide which page to open first; return -1 for undecided + virtual long GetPreferredPage() = 0; + + // Called after OK is clicked and all pages validate + virtual void SavePreferredPage() = 0; + +private: + void RecordExpansionState(); wxTreebook *mCategories; + Factories &mFactories; + const wxString mTitlePrefix; DECLARE_EVENT_TABLE() }; +// This adds code appropriate only to the original use of PrefsDialog for +// global settings -- not its reuses elsewhere as in View Settings +class GlobalPrefsDialog : public PrefsDialog +{ +public: + GlobalPrefsDialog(wxWindow * parent, Factories &factories = DefaultFactories()); + virtual ~GlobalPrefsDialog(); + virtual long GetPreferredPage(); + virtual void SavePreferredPage(); +}; + #endif diff --git a/src/prefs/PrefsPanel.h b/src/prefs/PrefsPanel.h index e35eacf44..2af21079a 100644 --- a/src/prefs/PrefsPanel.h +++ b/src/prefs/PrefsPanel.h @@ -61,4 +61,10 @@ class PrefsPanel:public wxPanel } }; +class PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent) = 0; +}; + #endif diff --git a/src/prefs/ProjectsPrefs.cpp b/src/prefs/ProjectsPrefs.cpp index 56f22f8c8..fc1e07630 100644 --- a/src/prefs/ProjectsPrefs.cpp +++ b/src/prefs/ProjectsPrefs.cpp @@ -79,3 +79,8 @@ bool ProjectsPrefs::Apply() return true; } + +PrefsPanel *ProjectsPrefsFactory::Create(wxWindow *parent) +{ + return new ProjectsPrefs(parent); +} diff --git a/src/prefs/ProjectsPrefs.h b/src/prefs/ProjectsPrefs.h index 3f1a00791..480a49f71 100644 --- a/src/prefs/ProjectsPrefs.h +++ b/src/prefs/ProjectsPrefs.h @@ -33,4 +33,9 @@ class ProjectsPrefs :public PrefsPanel void PopulateOrExchange(ShuttleGui & S); }; +class ProjectsPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/QualityPrefs.cpp b/src/prefs/QualityPrefs.cpp index 10c5fb1b0..243d0c419 100644 --- a/src/prefs/QualityPrefs.cpp +++ b/src/prefs/QualityPrefs.cpp @@ -228,3 +228,8 @@ bool QualityPrefs::Apply() return true; } + +PrefsPanel *QualityPrefsFactory::Create(wxWindow *parent) +{ + return new QualityPrefs(parent); +} diff --git a/src/prefs/QualityPrefs.h b/src/prefs/QualityPrefs.h index 726da2490..778417a2c 100644 --- a/src/prefs/QualityPrefs.h +++ b/src/prefs/QualityPrefs.h @@ -53,4 +53,9 @@ class QualityPrefs :public PrefsPanel DECLARE_EVENT_TABLE(); }; +class QualityPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/RecordingPrefs.cpp b/src/prefs/RecordingPrefs.cpp index 01e3db2a4..393f2f113 100644 --- a/src/prefs/RecordingPrefs.cpp +++ b/src/prefs/RecordingPrefs.cpp @@ -202,3 +202,8 @@ bool RecordingPrefs::Apply() #endif return gPrefs->Flush(); } + +PrefsPanel *RecordingPrefsFactory::Create(wxWindow *parent) +{ + return new RecordingPrefs(parent); +} diff --git a/src/prefs/RecordingPrefs.h b/src/prefs/RecordingPrefs.h index d4f1dd122..f3f8b9ee1 100644 --- a/src/prefs/RecordingPrefs.h +++ b/src/prefs/RecordingPrefs.h @@ -32,4 +32,9 @@ class RecordingPrefs :public PrefsPanel void PopulateOrExchange(ShuttleGui & S); }; +class RecordingPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/SpectrumPrefs.cpp b/src/prefs/SpectrumPrefs.cpp index 118df5a38..79f2fe238 100644 --- a/src/prefs/SpectrumPrefs.cpp +++ b/src/prefs/SpectrumPrefs.cpp @@ -342,6 +342,11 @@ BEGIN_EVENT_TABLE(SpectrumPrefs, PrefsPanel) EVT_CHOICE(ID_WINDOW_SIZE, SpectrumPrefs::OnWindowSize) END_EVENT_TABLE() +PrefsPanel *SpectrumPrefsFactory::Create(wxWindow *parent) +{ + return new SpectrumPrefs(parent); +} + SpectrogramSettings::SpectrogramSettings() : hFFT(0) , window(0) diff --git a/src/prefs/SpectrumPrefs.h b/src/prefs/SpectrumPrefs.h index 20a1e7385..a2be08dda 100644 --- a/src/prefs/SpectrumPrefs.h +++ b/src/prefs/SpectrumPrefs.h @@ -124,4 +124,10 @@ public: #endif }; +class SpectrumPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; + #endif diff --git a/src/prefs/ThemePrefs.cpp b/src/prefs/ThemePrefs.cpp index 2cbfd7ba3..f6d947b3e 100644 --- a/src/prefs/ThemePrefs.cpp +++ b/src/prefs/ThemePrefs.cpp @@ -205,3 +205,8 @@ bool ThemePrefs::Apply() return true; } + +PrefsPanel *ThemePrefsFactory::Create(wxWindow *parent) +{ + return new ThemePrefs(parent); +} diff --git a/src/prefs/ThemePrefs.h b/src/prefs/ThemePrefs.h index 40d080c8c..7668289d0 100644 --- a/src/prefs/ThemePrefs.h +++ b/src/prefs/ThemePrefs.h @@ -41,4 +41,9 @@ class ThemePrefs :public PrefsPanel DECLARE_EVENT_TABLE(); }; +class ThemePrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/TracksPrefs.cpp b/src/prefs/TracksPrefs.cpp index 925c20888..7bed5d735 100644 --- a/src/prefs/TracksPrefs.cpp +++ b/src/prefs/TracksPrefs.cpp @@ -165,3 +165,8 @@ bool TracksPrefs::Apply() return true; } + +PrefsPanel *TracksPrefsFactory::Create(wxWindow *parent) +{ + return new TracksPrefs(parent); +} diff --git a/src/prefs/TracksPrefs.h b/src/prefs/TracksPrefs.h index aa0f54272..be1baeaa0 100644 --- a/src/prefs/TracksPrefs.h +++ b/src/prefs/TracksPrefs.h @@ -39,4 +39,9 @@ class TracksPrefs :public PrefsPanel wxArrayString mViewChoices; }; +class TracksPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif diff --git a/src/prefs/WarningsPrefs.cpp b/src/prefs/WarningsPrefs.cpp index 68d344593..c0cb5b47b 100644 --- a/src/prefs/WarningsPrefs.cpp +++ b/src/prefs/WarningsPrefs.cpp @@ -83,3 +83,8 @@ bool WarningsPrefs::Apply() return true; } + +PrefsPanel *WarningsPrefsFactory::Create(wxWindow *parent) +{ + return new WarningsPrefs(parent); +} diff --git a/src/prefs/WarningsPrefs.h b/src/prefs/WarningsPrefs.h index 8f789e163..97e9605b6 100644 --- a/src/prefs/WarningsPrefs.h +++ b/src/prefs/WarningsPrefs.h @@ -33,4 +33,9 @@ class WarningsPrefs :public PrefsPanel void PopulateOrExchange(ShuttleGui & S); }; +class WarningsPrefsFactory : public PrefsPanelFactory +{ +public: + virtual PrefsPanel *Create(wxWindow *parent); +}; #endif