Audacity  3.0.3
Prefs.h
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  Prefs.h
6 
7  Dominic Mazzoni
8  Markus Meyer
9 
10  Audacity uses wxWidgets' wxFileConfig class to handle preferences.
11  In Audacity versions prior to 1.3.1, it used wxConfig, which would
12  store the prefs in a platform-dependent way (e.g. in the registry
13  on Windows). Now it always stores the settings in a configuration file
14  in the Audacity Data Directory.
15 
16  Every time we read a preference, we need to specify the default
17  value for that preference, to be used if the preference hasn't
18  been set before.
19 
20  So, to avoid code duplication, we provide functions in this file
21  to read and write preferences which have a nonobvious default
22  value, so that if we later want to change this value, we only
23  have to change it in one place.
24 
25  See Prefs.cpp for a (complete?) list of preferences we keep
26  track of...
27 
28 **********************************************************************/
29 #ifndef __AUDACITY_PREFS__
30 #define __AUDACITY_PREFS__
31 
32 // Increment this every time the prefs need to be reset
33 // the first part (before the r) indicates the version the reset took place
34 // the second part (after the r) indicates the number of times the prefs have been reset within the same version
35 #define AUDACITY_PREFS_VERSION_STRING "1.1.1r1"
36 
37 #include <functional>
38 
40 #include "wxArrayStringEx.h"
41 #include "FileConfig.h"
42 
43 #include <memory>
44 #include <wx/event.h> // to declare custom event types
45 
46 class wxFileName;
47 
48 PREFERENCES_API void InitPreferences( std::unique_ptr<FileConfig> uPrefs );
50 
54 PREFERENCES_API void ResetPreferences();
55 PREFERENCES_API void FinishPreferences();
56 
57 extern PREFERENCES_API FileConfig *gPrefs;
58 extern int gMenusDirty;
59 
60 
61 struct ByColumns_t{};
62 extern PREFERENCES_API ByColumns_t ByColumns;
63 
65 /* The constructors are non-explicit for convenience */
66 class PREFERENCES_API SettingBase
67 {
68 public:
69  SettingBase( const char *path ) : mPath{ path } {}
70  SettingBase( const wxChar *path ) : mPath{ path } {}
71  SettingBase( const wxString &path ) : mPath{ path } {}
72 
73  wxConfigBase *GetConfig() const;
74 
75  const wxString &GetPath() const { return mPath; }
76 
78  bool Delete();
79 
80 protected:
81  SettingBase( const SettingBase& ) = default;
83 };
84 
86 template< typename T >
88 {
89 public:
90  explicit CachingSettingBase( const SettingBase &path )
91  : SettingBase{ path } {}
92 protected:
93  CachingSettingBase( const CachingSettingBase & ) = default;
94  mutable T mCurrentValue{};
95  mutable bool mValid{false};
96 };
97 
99 template< typename T >
100 class Setting : public CachingSettingBase< T >
101 {
102 public:
104 
105  using DefaultValueFunction = std::function< T() >;
106 
108  Setting( const SettingBase &path, const T &defaultValue )
109  : CachingSettingBase< T >{ path }
110  , mDefaultValue{ defaultValue }
111  {}
112 
114  Setting( const SettingBase &path, DefaultValueFunction function )
115  : CachingSettingBase< T >{ path }
116  , mFunction{ function }
117  {}
118 
119 
120  const T& GetDefault() const
121  {
122  if ( mFunction )
124  return mDefaultValue;
125  }
126 
128  bool Read( T *pVar ) const
129  {
130  return ReadWithDefault( pVar, GetDefault() );
131  }
132 
134  bool ReadWithDefault( T *pVar, const T& defaultValue ) const
135  {
136  if ( pVar )
137  *pVar = defaultValue;
138  if ( pVar && this->mValid ) {
139  *pVar = this->mCurrentValue;
140  return true;
141  }
142  const auto config = this->GetConfig();
143  if ( pVar && config ) {
144  if ((this->mValid = config->Read( this->mPath, &this->mCurrentValue )))
145  *pVar = this->mCurrentValue;
146  return this->mValid;
147  }
148  return (this->mValid = false);
149  }
150 
152 
154  T Read() const
155  {
156  return ReadWithDefault( GetDefault() );
157  }
158 
160 
162  T ReadWithDefault( const T &defaultValue ) const
163  {
164  const auto config = this->GetConfig();
165  return config
166  ? ( this->mValid = true, this->mCurrentValue =
167  config->ReadObject( this->mPath, defaultValue ) )
168  : T{};
169  }
170 
172  bool Write( const T &value )
173  {
174  const auto config = this->GetConfig();
175  if ( config ) {
176  this->mCurrentValue = value;
177  return DoWrite();
178  }
179  return false;
180  }
181 
183  bool Reset()
184  {
185  return Write( GetDefault() );
186  }
187 
188 protected:
190 
191  bool DoWrite( )
192  {
193  const auto config = this->GetConfig();
194  return this->mValid =
195  config ? config->Write( this->mPath, this->mCurrentValue ) : false;
196  }
197 
198  mutable T mDefaultValue{};
200 };
201 
203 class PREFERENCES_API BoolSetting final : public Setting< bool >
204 {
205 public:
206  using Setting::Setting;
207 
209  bool Toggle();
210 };
211 
213 class IntSetting final : public Setting< int >
214 {
215 public:
216  using Setting::Setting;
217 };
218 
220 class DoubleSetting final : public Setting< double >
221 {
222 public:
223  using Setting::Setting;
224 };
225 
227 class StringSetting final : public Setting< wxString >
228 {
229 public:
230  using Setting::Setting;
231 };
232 
234 
238 class PREFERENCES_API EnumValueSymbols : public std::vector< EnumValueSymbol >
239 {
240 public:
241  EnumValueSymbols() = default;
242  EnumValueSymbols( std::initializer_list<EnumValueSymbol> symbols )
243  : vector( symbols )
244  {}
245  EnumValueSymbols( std::vector< EnumValueSymbol > symbols )
246  : vector( symbols )
247  {}
248 
249  // columnwise constructor; arguments must have same size
250  // (Implicit constructor takes initial tag argument to avoid unintended
251  // overload resolution to the inherited constructor taking
252  // initializer_list, in the case that each column has exactly two strings)
254  ByColumns_t,
255  const TranslatableStrings &msgids,
256  wxArrayStringEx internals
257  );
258 
259  const TranslatableStrings &GetMsgids() const;
260  const wxArrayStringEx &GetInternals() const;
261 
262 private:
265 };
266 
269 class PREFERENCES_API ChoiceSetting
270 {
271 public:
273  const SettingBase &key,
274  EnumValueSymbols symbols,
275  long defaultSymbol = -1
276  )
277  : mKey{ key.GetPath() }
278 
279  , mSymbols{ std::move( symbols ) }
280 
281  , mDefaultSymbol{ defaultSymbol }
282  {
283  wxASSERT( defaultSymbol < (long)mSymbols.size() );
284  }
285 
286  const wxString &Key() const { return mKey; }
287  const EnumValueSymbol &Default() const;
288  const EnumValueSymbols &GetSymbols() const { return mSymbols; }
289 
290  wxString Read() const;
291 
292  // new direct use is discouraged but it may be needed in legacy code:
293  // use a default in case the preference is not defined, which may not be
294  // the default-default stored in this object.
295  wxString ReadWithDefault( const wxString & ) const;
296 
297  bool Write( const wxString &value ); // you flush gPrefs afterward
298 
299  void SetDefault( long value );
300 
301 protected:
302  size_t Find( const wxString &value ) const;
303  virtual void Migrate( wxString& );
304 
305  const wxString mKey;
306 
308 
309  // stores an internal value
310  mutable bool mMigrated { false };
311 
313 };
314 
319 class PREFERENCES_API EnumSettingBase : public ChoiceSetting
320 {
321 public:
323  const SettingBase &key,
324  EnumValueSymbols symbols,
325  long defaultSymbol,
326 
327  std::vector<int> intValues, // must have same size as symbols
328  const wxString &oldKey = {}
329  );
330 
331 protected:
332 
333  // Read and write the encoded values
334  int ReadInt() const;
335 
336  // new direct use is discouraged but it may be needed in legacy code:
337  // use a default in case the preference is not defined, which may not be
338  // the default-default stored in this object.
339  int ReadIntWithDefault( int defaultValue ) const;
340 
341  bool WriteInt( int code ); // you flush gPrefs afterward
342 
343  size_t FindInt( int code ) const;
344  void Migrate( wxString& ) override;
345 
346 private:
347  std::vector<int> mIntValues;
348  const wxString mOldKey;
349 };
350 
352 template< typename Enum >
354 {
355 public:
356 
358  const SettingBase &key,
359  EnumValueSymbols symbols,
360  long defaultSymbol,
361 
362  std::vector< Enum > values, // must have same size as symbols
363  const wxString &oldKey = {}
364  )
365  : EnumSettingBase{
366  key, symbols, defaultSymbol,
367  { values.begin(), values.end() },
368  oldKey
369  }
370  {}
371 
372  // Wrap ReadInt() and ReadIntWithDefault() and WriteInt()
373  Enum ReadEnum() const
374  { return static_cast<Enum>( ReadInt() ); }
375 
376  // new direct use is discouraged but it may be needed in legacy code:
377  // use a default in case the preference is not defined, which may not be
378  // the default-default stored in this object.
379  Enum ReadEnumWithDefault( Enum defaultValue ) const
380  {
381  auto integer = static_cast<int>(defaultValue);
382  return static_cast<Enum>( ReadIntWithDefault( integer ) );
383  }
384 
385  bool WriteEnum( Enum value )
386  { return WriteInt( static_cast<int>( value ) ); }
387 
388 };
389 
391 class PREFERENCES_API PrefsListener
392 {
393 public:
395 
402  static void Broadcast(int id = 0);
403 
404  PrefsListener();
405  virtual ~PrefsListener();
406 
407  // Called when all preferences should be updated.
408  virtual void UpdatePrefs() = 0;
409 
410 protected:
411  // Called when only selected preferences are to be updated.
412  // id is some value generated by wxNewId() that identifies the portion
413  // of preferences.
414  // Default function does nothing.
415  virtual void UpdateSelectedPrefs( int id );
416 
417 private:
418  struct Impl;
419  std::unique_ptr<Impl> mpImpl;
420 };
421 
425 PREFERENCES_API
426 wxString WarningDialogKey(const wxString &internalDialogName);
427 
432 struct PREFERENCES_API PreferenceInitializer {
434  virtual ~PreferenceInitializer();
435  virtual void operator () () = 0;
436 
437  static void ReinitializeAll();
438 };
439 
440 // Special extra-sticky settings
441 extern PREFERENCES_API BoolSetting DefaultUpdatesCheckingFlag;
442 
443 #endif
SettingBase
Base class for settings objects. It holds a configuration key path.
Definition: Prefs.h:67
CachingSettingBase::CachingSettingBase
CachingSettingBase(const SettingBase &path)
Definition: Prefs.h:90
Setting::DoWrite
bool DoWrite()
Write cached value to config and return true if successful.
Definition: Prefs.h:191
Setting::ReadWithDefault
T ReadWithDefault(const T &defaultValue) const
new direct use is discouraged but it may be needed in legacy code
Definition: Prefs.h:162
IntSetting
Specialization of Setting for int.
Definition: Prefs.h:214
SettingBase::GetPath
const wxString & GetPath() const
Definition: Prefs.h:75
EnumSettingBase
Definition: Prefs.h:320
EnumSettingBase::mIntValues
std::vector< int > mIntValues
Definition: Prefs.h:347
TranslatableStrings
std::vector< TranslatableString > TranslatableStrings
Definition: TranslatableString.h:295
ChoiceSetting::ChoiceSetting
ChoiceSetting(const SettingBase &key, EnumValueSymbols symbols, long defaultSymbol=-1)
Definition: Prefs.h:272
ChoiceSetting::Key
const wxString & Key() const
Definition: Prefs.h:286
gPrefs
PREFERENCES_API FileConfig * gPrefs
Definition: Prefs.cpp:70
EnumValueSymbols::EnumValueSymbols
EnumValueSymbols()=default
Setting::Write
bool Write(const T &value)
Write value to config and return true if successful.
Definition: Prefs.h:172
SettingBase::SettingBase
SettingBase(const wxChar *path)
Definition: Prefs.h:70
WarningDialogKey
PREFERENCES_API wxString WarningDialogKey(const wxString &internalDialogName)
Definition: Prefs.cpp:415
BoolSetting
This specialization of Setting for bool adds a Toggle method to negate the saved value.
Definition: Prefs.h:204
FileConfig.h
EnumSetting::EnumSetting
EnumSetting(const SettingBase &key, EnumValueSymbols symbols, long defaultSymbol, std::vector< Enum > values, const wxString &oldKey={})
Definition: Prefs.h:357
CachingSettingBase::CachingSettingBase
CachingSettingBase(const CachingSettingBase &)=default
EnumValueSymbols::EnumValueSymbols
EnumValueSymbols(std::initializer_list< EnumValueSymbol > symbols)
Definition: Prefs.h:242
ComponentInterfaceSymbol.h
wxArrayStringEx
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
Definition: wxArrayStringEx.h:18
EnumValueSymbols::mMsgids
TranslatableStrings mMsgids
Definition: Prefs.h:263
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterfaceSymbol.h:27
Setting::Read
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:128
PrefsListener
A listener notified of changes in preferences.
Definition: Prefs.h:392
SettingBase::mPath
const RegistryPath mPath
Definition: Prefs.h:82
EnumValueSymbols
Definition: Prefs.h:239
StringSetting
Specialization of Setting for strings.
Definition: Prefs.h:228
ByColumns_t
Definition: Prefs.h:61
SettingBase::SettingBase
SettingBase(const SettingBase &)=default
ChoiceSetting
Definition: Prefs.h:270
Setting::Setting
Setting(const SettingBase &path, const T &defaultValue)
Usual overload supplies a default value.
Definition: Prefs.h:108
EnumValueSymbols::EnumValueSymbols
EnumValueSymbols(std::vector< EnumValueSymbol > symbols)
Definition: Prefs.h:245
Setting::Read
T Read() const
overload of Read, always returning a value
Definition: Prefs.h:154
EnumSettingBase::mOldKey
const wxString mOldKey
Definition: Prefs.h:348
SettingBase::SettingBase
SettingBase(const wxString &path)
Definition: Prefs.h:71
gMenusDirty
int gMenusDirty
Definition: Prefs.cpp:71
Setting
Class template adds default value, read, and write methods to CachingSetingBase.
Definition: Prefs.h:101
Setting::GetDefault
const T & GetDefault() const
Definition: Prefs.h:120
EnumSetting::ReadEnumWithDefault
Enum ReadEnumWithDefault(Enum defaultValue) const
Definition: Prefs.h:379
ChoiceSetting::mDefaultSymbol
long mDefaultSymbol
Definition: Prefs.h:312
ByColumns
PREFERENCES_API ByColumns_t ByColumns
Definition: Prefs.cpp:420
Setting::ReadWithDefault
bool ReadWithDefault(T *pVar, const T &defaultValue) const
overload of ReadWithDefault returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:134
ChoiceSetting::GetSymbols
const EnumValueSymbols & GetSymbols() const
Definition: Prefs.h:288
ActiveProjects::Find
wxString Find(const FilePath &path)
CachingSettingBase::mCurrentValue
T mCurrentValue
Definition: Prefs.h:94
InitPreferences
PREFERENCES_API void InitPreferences(std::unique_ptr< FileConfig > uPrefs)
Definition: Prefs.cpp:202
ChoiceSetting::mKey
const wxString mKey
Definition: Prefs.h:305
RegistryPath
wxString RegistryPath
Definition: Identifier.h:218
EnumValueSymbols::mInternals
wxArrayStringEx mInternals
Definition: Prefs.h:264
FileConfig
Definition: FileConfig.h:21
anonymous_namespace{ProjectSerializer.cpp}::ReadInt
static const auto ReadInt
Definition: ProjectSerializer.cpp:179
wxArrayStringEx.h
Setting::mDefaultValue
T mDefaultValue
Definition: Prefs.h:198
PrefsListener::Impl
Definition: Prefs.cpp:87
Setting::Setting
Setting(const SettingBase &path, DefaultValueFunction function)
This overload causes recomputation of the default each time it is needed.
Definition: Prefs.h:114
SettingBase::SettingBase
SettingBase(const char *path)
Definition: Prefs.h:69
EnumSetting::ReadEnum
Enum ReadEnum() const
Definition: Prefs.h:373
Read
gPrefs Read(wxT("/GUI/VerticalZooming"), &bVZoom, false)
key
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: CommandManager.cpp:201
Setting::mFunction
const DefaultValueFunction mFunction
Definition: Prefs.h:199
ChoiceSetting::Migrate
virtual void Migrate(wxString &)
Definition: Prefs.cpp:313
CachingSettingBase::mValid
bool mValid
Definition: Prefs.h:95
anonymous_namespace{ProjectSerializer.cpp}::WriteInt
static const auto WriteInt
Definition: ProjectSerializer.cpp:168
SettingBase::GetConfig
wxConfigBase * GetConfig() const
Definition: Prefs.cpp:449
FinishPreferences
PREFERENCES_API void FinishPreferences()
Definition: Prefs.cpp:228
Setting::Reset
bool Reset()
Reset to the default value.
Definition: Prefs.h:183
EnumSetting
Adapts EnumSettingBase to a particular enumeration type.
Definition: Prefs.h:354
PrefsListener::UpdatePrefs
virtual void UpdatePrefs()=0
DefaultUpdatesCheckingFlag
PREFERENCES_API BoolSetting DefaultUpdatesCheckingFlag
Definition: Prefs.cpp:65
PrefsListener::mpImpl
std::unique_ptr< Impl > mpImpl
Definition: Prefs.h:418
ResetPreferences
PREFERENCES_API void ResetPreferences()
Call this to reset preferences to an (almost)-"new" default state.
Definition: Prefs.cpp:209
PreferenceInitializer
Definition: Prefs.h:432
values
const wxChar * values
Definition: Equalization.cpp:472
ChoiceSetting::mSymbols
const EnumValueSymbols mSymbols
Definition: Prefs.h:307
DoubleSetting
Specialization of Setting for double.
Definition: Prefs.h:221
EnumSetting::WriteEnum
bool WriteEnum(Enum value)
Definition: Prefs.h:385
CachingSettingBase
Class template adds an in-memory cache of a value to SettingBase.
Definition: Prefs.h:88
Setting::DefaultValueFunction
std::function< T() > DefaultValueFunction
Definition: Prefs.h:105