diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index e78f92184..94a8bba91 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -189,11 +189,10 @@ void PopulatePreferences() { const wxString fullPath{fn.GetFullPath()}; - AudacityFileConfig ini(wxEmptyString, - wxEmptyString, - fullPath, - wxEmptyString, - wxCONFIG_USE_LOCAL_FILE); + auto pIni = + AudacityFileConfig::Create({}, {}, fullPath, {}, + wxCONFIG_USE_LOCAL_FILE); + auto &ini = *pIni; wxString lang; if (ini.Read(wxT("/FromInno/Language"), &lang)) @@ -1249,7 +1248,7 @@ bool AudacityApp::OnInit() { wxFileName configFileName(FileNames::DataDir(), wxT("audacity.cfg")); auto appName = wxTheApp->GetAppName(); - InitPreferences( std::make_unique( + InitPreferences( AudacityFileConfig::Create( appName, wxEmptyString, configFileName.GetFullPath(), wxEmptyString, wxCONFIG_USE_LOCAL_FILE) ); diff --git a/src/AudacityFileConfig.cpp b/src/AudacityFileConfig.cpp index b6e4d7bb3..7bc8d8da7 100644 --- a/src/AudacityFileConfig.cpp +++ b/src/AudacityFileConfig.cpp @@ -8,6 +8,35 @@ Paul Licameli split from Prefs.cpp **********************************************************************/ +#include "Audacity.h" #include "AudacityFileConfig.h" +AudacityFileConfig::AudacityFileConfig( + const wxString& appName, + const wxString& vendorName, + const wxString& localFilename, + const wxString& globalFilename, + long style, + const wxMBConv& conv +) +: FileConfig{ appName, vendorName, localFilename, globalFilename, style, conv } +{} + AudacityFileConfig::~AudacityFileConfig() = default; + +std::unique_ptr AudacityFileConfig::Create( + const wxString& appName, + const wxString& vendorName, + const wxString& localFilename, + const wxString& globalFilename, + long style, + const wxMBConv& conv +) +{ + // Private ctor means make_unique can't compile, so this verbosity: + auto result = std::unique_ptr{ + safenew AudacityFileConfig{ + appName, vendorName, localFilename, globalFilename, style, conv } }; + result->Init(); + return result; +} diff --git a/src/AudacityFileConfig.h b/src/AudacityFileConfig.h index 48762d66e..f0b47adf7 100644 --- a/src/AudacityFileConfig.h +++ b/src/AudacityFileConfig.h @@ -12,14 +12,34 @@ Paul Licameli split from Prefs.h #ifndef __AUDACITY_FILE_CONFIG__ #define __AUDACITY_FILE_CONFIG__ +#include #include "widgets/FileConfig.h" // to inherit -/// \brief Our own specialisation of FileConfig. It is essentially a renaming. +/// \brief Our own specialisation of FileConfig. class AUDACITY_DLL_API AudacityFileConfig final : public FileConfig { public: - using FileConfig::FileConfig; + //! Require a call to this factory, to guarantee proper two-phase initialization + static std::unique_ptr Create( + const wxString& appName = {}, + const wxString& vendorName = {}, + const wxString& localFilename = {}, + const wxString& globalFilename = {}, + long style = wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_GLOBAL_FILE, + const wxMBConv& conv = wxConvAuto() + ); ~AudacityFileConfig() override; + +private: + //! Disallow direct constructor call, because a two-phase initialization is required + AudacityFileConfig( + const wxString& appName, + const wxString& vendorName, + const wxString& localFilename, + const wxString& globalFilename, + long style, + const wxMBConv& conv + ); }; #endif diff --git a/src/PluginManager.cpp b/src/PluginManager.cpp index 26741201b..be1542d88 100644 --- a/src/PluginManager.cpp +++ b/src/PluginManager.cpp @@ -1930,8 +1930,9 @@ bool PluginManager::DropFile(const wxString &fileName) void PluginManager::Load() { // Create/Open the registry - AudacityFileConfig registry( + auto pRegistry = AudacityFileConfig::Create( {}, {}, FileNames::PluginRegistry()); + auto ®istry = *pRegistry; // If this group doesn't exist then we have something that's not a registry. // We should probably warn the user, but it's pretty unlikely that this will happen. @@ -2272,8 +2273,9 @@ void PluginManager::LoadGroup(FileConfig *pRegistry, PluginType type) void PluginManager::Save() { // Create/Open the registry - AudacityFileConfig registry( + auto pRegistry = AudacityFileConfig::Create( {}, {}, FileNames::PluginRegistry()); + auto ®istry = *pRegistry; // Clear it out registry.DeleteAll(); @@ -2780,7 +2782,8 @@ FileConfig *PluginManager::GetSettings() { if (!mSettings) { - mSettings = std::make_unique(wxEmptyString, wxEmptyString, FileNames::PluginSettings()); + mSettings = + AudacityFileConfig::Create({}, {}, FileNames::PluginSettings()); // Check for a settings version that we can understand if (mSettings->HasEntry(SETVERKEY)) diff --git a/src/widgets/FileConfig.cpp b/src/widgets/FileConfig.cpp index be8339d4e..3357bf424 100644 --- a/src/widgets/FileConfig.cpp +++ b/src/widgets/FileConfig.cpp @@ -45,6 +45,10 @@ FileConfig::FileConfig(const wxString& appName, : wxFileConfig(appName, vendorName, localFilename, globalFilename, style, conv), mConfigPath(localFilename), mDirty(false) +{ +} + +void FileConfig::Init() { // Prevent wxFileConfig from attempting a Flush() during object deletion. This happens // because we don't use the wxFileConfig::Flush() method and so the wxFileConfig dirty diff --git a/src/widgets/FileConfig.h b/src/widgets/FileConfig.h index 45613a435..e28237bb4 100644 --- a/src/widgets/FileConfig.h +++ b/src/widgets/FileConfig.h @@ -25,6 +25,7 @@ public: const wxString& globalFilename = wxEmptyString, long style = wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_GLOBAL_FILE, const wxMBConv& conv = wxConvAuto()); + void Init(); virtual ~FileConfig(); virtual bool Flush(bool bCurrentOnly = false) wxOVERRIDE;