Audacity 3.2.0
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#include <functional>
33#include <set>
34
35// Increment this every time the prefs need to be reset
36// the first part (before the r) indicates the version the reset took place
37// the second part (after the r) indicates the number of times the prefs have been reset within the same version
38#define AUDACITY_PREFS_VERSION_STRING "1.1.1r1"
39
40#include <functional>
41
43#include "wxArrayStringEx.h"
44#include "FileConfig.h"
45
46#include <memory>
47
48class wxFileName;
49
50PREFERENCES_API void InitPreferences( std::unique_ptr<FileConfig> uPrefs );
52
56PREFERENCES_API void ResetPreferences();
57PREFERENCES_API void FinishPreferences();
58
59extern PREFERENCES_API FileConfig *gPrefs;
60extern int gMenusDirty;
61
62
63struct ByColumns_t{};
64extern PREFERENCES_API ByColumns_t ByColumns;
65
67/* The constructors are non-explicit for convenience */
68class PREFERENCES_API SettingBase
69{
70public:
71 SettingBase( const char *path ) : mPath{ path } {}
72 SettingBase( const wxChar *path ) : mPath{ path } {}
73 SettingBase( const wxString &path ) : mPath{ path } {}
74
75 wxConfigBase *GetConfig() const;
76
77 const wxString &GetPath() const { return mPath; }
78
80 bool Delete();
81
82protected:
83 SettingBase( const SettingBase& ) = default;
85};
86
88{
89public:
91
93 virtual bool Commit() = 0;
94 virtual void Rollback() noexcept = 0;
95};
96
98
99class PREFERENCES_API SettingScope /* not final */
100{
101public:
102 SettingScope();
103 ~SettingScope() noexcept;
104 SettingScope(const SettingScope&) = delete;
106
113 enum AddResult{ NotAdded, Added, PreviouslyAdded };
114 static AddResult Add( TransactionalSettingBase& setting );
115
116protected:
118 std::set< TransactionalSettingBase * > mPending;
119 bool mCommitted = false;
120};
121
123
129class PREFERENCES_API SettingTransaction final : public SettingScope
130{
131public:
133
135 bool Commit();
136};
137
141template< typename T >
143{
144public:
145 using TransactionalSettingBase::TransactionalSettingBase;
146 explicit CachingSettingBase( const SettingBase &path )
147 : TransactionalSettingBase{ path.GetPath() } {}
148
149protected:
151 mutable T mCurrentValue{};
152 mutable bool mValid{false};
153};
154
156template< typename T >
157class Setting : public CachingSettingBase< T >
158{
159public:
161
162 using DefaultValueFunction = std::function< T() >;
163
165 Setting( const SettingBase &path, const T &defaultValue )
166 : CachingSettingBase< T >{ path }
167 , mDefaultValue{ defaultValue }
168 {}
169
171 Setting( const SettingBase &path, DefaultValueFunction function )
172 : CachingSettingBase< T >{ path }
173 , mFunction{ function }
174 {}
175
176
177 const T& GetDefault() const
178 {
179 if ( mFunction )
180 mDefaultValue = mFunction();
181 return mDefaultValue;
182 }
183
185 bool Read( T *pVar ) const
186 {
187 return ReadWithDefault( pVar, GetDefault() );
188 }
189
191 bool ReadWithDefault( T *pVar, const T& defaultValue ) const
192 {
193 if ( pVar )
194 *pVar = defaultValue;
195 if ( pVar && this->mValid ) {
196 *pVar = this->mCurrentValue;
197 return true;
198 }
199 const auto config = this->GetConfig();
200 if ( pVar && config ) {
201 if ((this->mValid = config->Read( this->mPath, &this->mCurrentValue )))
202 *pVar = this->mCurrentValue;
203 return this->mValid;
204 }
205 return (this->mValid = false);
206 }
207
209
211 T Read() const
212 {
213 return ReadWithDefault( GetDefault() );
214 }
215
217
219 T ReadWithDefault( const T &defaultValue ) const
220 {
221 const auto config = this->GetConfig();
222 return config
223 ? ( this->mValid = true, this->mCurrentValue =
224 config->ReadObject( this->mPath, defaultValue ) )
225 : T{};
226 }
227
229 bool Write( const T &value )
230 {
231 switch ( SettingScope::Add( *this ) ) {
232 // Eager writes, but not flushed, when there is no transaction
233 default:
235 const auto config = this->GetConfig();
236 if ( config ) {
237 this->mCurrentValue = value;
238 return DoWrite();
239 }
240 return false;
241 }
242
243 // Deferred writes, with flush, if there is a commit later
245 this->mPreviousValue = Read();
246 [[fallthrough]];
248 this->mCurrentValue = value;
249 return true;
250 }
251 }
252
254 bool Reset()
255 {
256 return Write( GetDefault() );
257 }
258
259 bool Commit() override
260 {
261 return DoWrite();
262 }
263
264 void Rollback() noexcept override
265 {
266 this->mCurrentValue = this->mPreviousValue;
267 }
268
269protected:
271
272 bool DoWrite( )
273 {
274 const auto config = this->GetConfig();
275 return this->mValid =
276 config ? config->Write( this->mPath, this->mCurrentValue ) : false;
277 }
278
280 mutable T mDefaultValue{};
281 T mPreviousValue{};
282};
283
285class PREFERENCES_API BoolSetting final : public Setting< bool >
286{
287public:
288 using Setting::Setting;
289
291 bool Toggle();
292};
293
295class IntSetting final : public Setting< int >
296{
297public:
298 using Setting::Setting;
299};
300
302class DoubleSetting final : public Setting< double >
303{
304public:
305 using Setting::Setting;
306};
307
309class StringSetting final : public Setting< wxString >
310{
311public:
312 using Setting::Setting;
313};
314
316
320class PREFERENCES_API EnumValueSymbols : public std::vector< EnumValueSymbol >
321{
322public:
323 EnumValueSymbols() = default;
324 EnumValueSymbols( std::initializer_list<EnumValueSymbol> symbols )
325 : vector( symbols )
326 {}
327 EnumValueSymbols( std::vector< EnumValueSymbol > symbols )
328 : vector( symbols )
329 {}
330
331 // columnwise constructor; arguments must have same size
332 // (Implicit constructor takes initial tag argument to avoid unintended
333 // overload resolution to the inherited constructor taking
334 // initializer_list, in the case that each column has exactly two strings)
337 const TranslatableStrings &msgids,
338 wxArrayStringEx internals
339 );
340
341 const TranslatableStrings &GetMsgids() const;
342 const wxArrayStringEx &GetInternals() const;
343
344private:
347};
348
351class PREFERENCES_API ChoiceSetting
352{
353public:
355 const SettingBase &key,
356 EnumValueSymbols symbols,
357 long defaultSymbol = -1
358 )
359 : mKey{ key.GetPath() }
360
361 , mSymbols{ std::move( symbols ) }
362
363 , mDefaultSymbol{ defaultSymbol }
364 {
365 wxASSERT( defaultSymbol < (long)mSymbols.size() );
366 }
367
368 const wxString &Key() const { return mKey; }
369 const EnumValueSymbol &Default() const;
370 const EnumValueSymbols &GetSymbols() const { return mSymbols; }
371
372 wxString Read() const;
373
374 // new direct use is discouraged but it may be needed in legacy code:
375 // use a default in case the preference is not defined, which may not be
376 // the default-default stored in this object.
377 wxString ReadWithDefault( const wxString & ) const;
378
379 bool Write( const wxString &value ); // you flush gPrefs afterward
380
381 void SetDefault( long value );
382
383protected:
384 size_t Find( const wxString &value ) const;
385 virtual void Migrate( wxString& );
386
387 const wxString mKey;
388
390
391 // stores an internal value
392 mutable bool mMigrated { false };
393
395};
396
401class PREFERENCES_API EnumSettingBase : public ChoiceSetting
402{
403public:
405 const SettingBase &key,
406 EnumValueSymbols symbols,
407 long defaultSymbol,
408
409 std::vector<int> intValues, // must have same size as symbols
410 const wxString &oldKey = {}
411 );
412
413protected:
414
415 // Read and write the encoded values
416 int ReadInt() const;
417
418 // new direct use is discouraged but it may be needed in legacy code:
419 // use a default in case the preference is not defined, which may not be
420 // the default-default stored in this object.
421 int ReadIntWithDefault( int defaultValue ) const;
422
423 bool WriteInt( int code ); // you flush gPrefs afterward
424
425 size_t FindInt( int code ) const;
426 void Migrate( wxString& ) override;
427
428private:
429 std::vector<int> mIntValues;
430 const wxString mOldKey;
431};
432
434template< typename Enum >
436{
437public:
438
440 const SettingBase &key,
441 EnumValueSymbols symbols,
442 long defaultSymbol,
443
444 std::vector< Enum > values, // must have same size as symbols
445 const wxString &oldKey = {}
446 )
448 key, symbols, defaultSymbol,
449 { values.begin(), values.end() },
450 oldKey
451 }
452 {}
453
454 // Wrap ReadInt() and ReadIntWithDefault() and WriteInt()
455 Enum ReadEnum() const
456 { return static_cast<Enum>( ReadInt() ); }
457
458 // new direct use is discouraged but it may be needed in legacy code:
459 // use a default in case the preference is not defined, which may not be
460 // the default-default stored in this object.
461 Enum ReadEnumWithDefault( Enum defaultValue ) const
462 {
463 auto integer = static_cast<int>(defaultValue);
464 return static_cast<Enum>( ReadIntWithDefault( integer ) );
465 }
466
467 bool WriteEnum( Enum value )
468 { return WriteInt( static_cast<int>( value ) ); }
469
470};
471
473class PREFERENCES_API PrefsListener
474{
475public:
477
484 static void Broadcast(int id = 0);
485
487 virtual ~PrefsListener();
488
489 // Called when all preferences should be updated.
490 virtual void UpdatePrefs() = 0;
491
492protected:
493 // Called when only selected preferences are to be updated.
494 // id is some value generated by wxNewId() that identifies the portion
495 // of preferences.
496 // Default function does nothing.
497 virtual void UpdateSelectedPrefs( int id );
498
499private:
500 struct Impl;
501 std::unique_ptr<Impl> mpImpl;
502};
503
507PREFERENCES_API
508wxString WarningDialogKey(const wxString &internalDialogName);
509
514struct PREFERENCES_API PreferenceInitializer {
516 virtual ~PreferenceInitializer();
517 virtual void operator () () = 0;
518
519 static void ReinitializeAll();
520};
521
522// Special extra-sticky settings
523extern PREFERENCES_API BoolSetting DefaultUpdatesCheckingFlag;
524
525#endif
static const AudacityProject::AttachedObjects::RegisteredFactory key
const wxChar * values
wxString RegistryPath
Definition: Identifier.h:218
gPrefs Read(wxT("/GUI/VerticalZooming"), &bVZoom, false)
PREFERENCES_API void InitPreferences(std::unique_ptr< FileConfig > uPrefs)
Definition: Prefs.cpp:197
PREFERENCES_API BoolSetting DefaultUpdatesCheckingFlag
Definition: Prefs.cpp:66
PREFERENCES_API FileConfig * gPrefs
Definition: Prefs.cpp:71
PREFERENCES_API wxString WarningDialogKey(const wxString &internalDialogName)
Definition: Prefs.cpp:456
PREFERENCES_API void FinishPreferences()
Definition: Prefs.cpp:223
PREFERENCES_API void ResetPreferences()
Call this to reset preferences to an (almost)-"new" default state.
Definition: Prefs.cpp:204
PREFERENCES_API ByColumns_t ByColumns
Definition: Prefs.cpp:461
int gMenusDirty
Definition: Prefs.cpp:72
std::vector< TranslatableString > TranslatableStrings
This specialization of Setting for bool adds a Toggle method to negate the saved value.
Definition: Prefs.h:286
Class template adds an in-memory cache of a value to SettingBase and support for SettingTransaction.
Definition: Prefs.h:143
CachingSettingBase(const CachingSettingBase &)=default
CachingSettingBase(const SettingBase &path)
Definition: Prefs.h:146
const wxString & Key() const
Definition: Prefs.h:368
const wxString mKey
Definition: Prefs.h:387
ChoiceSetting(const SettingBase &key, EnumValueSymbols symbols, long defaultSymbol=-1)
Definition: Prefs.h:354
const EnumValueSymbols mSymbols
Definition: Prefs.h:389
const EnumValueSymbols & GetSymbols() const
Definition: Prefs.h:370
long mDefaultSymbol
Definition: Prefs.h:394
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Specialization of Setting for double.
Definition: Prefs.h:303
const wxString mOldKey
Definition: Prefs.h:430
std::vector< int > mIntValues
Definition: Prefs.h:429
Adapts EnumSettingBase to a particular enumeration type.
Definition: Prefs.h:436
bool WriteEnum(Enum value)
Definition: Prefs.h:467
Enum ReadEnumWithDefault(Enum defaultValue) const
Definition: Prefs.h:461
Enum ReadEnum() const
Definition: Prefs.h:455
EnumSetting(const SettingBase &key, EnumValueSymbols symbols, long defaultSymbol, std::vector< Enum > values, const wxString &oldKey={})
Definition: Prefs.h:439
EnumValueSymbols()=default
wxArrayStringEx mInternals
Definition: Prefs.h:346
EnumValueSymbols(std::vector< EnumValueSymbol > symbols)
Definition: Prefs.h:327
EnumValueSymbols(std::initializer_list< EnumValueSymbol > symbols)
Definition: Prefs.h:324
TranslatableStrings mMsgids
Definition: Prefs.h:345
Specialization of Setting for int.
Definition: Prefs.h:296
A listener notified of changes in preferences.
Definition: Prefs.h:474
std::unique_ptr< Impl > mpImpl
Definition: Prefs.h:500
virtual void UpdatePrefs()=0
Base class for settings objects. It holds a configuration key path.
Definition: Prefs.h:69
const RegistryPath mPath
Definition: Prefs.h:84
SettingBase(const wxChar *path)
Definition: Prefs.h:72
const wxString & GetPath() const
Definition: Prefs.h:77
SettingBase(const wxString &path)
Definition: Prefs.h:73
SettingBase(const char *path)
Definition: Prefs.h:71
SettingBase(const SettingBase &)=default
wxConfigBase * GetConfig() const
Definition: Prefs.cpp:490
Class template adds default value, read, and write methods to CachingSetingBase.
Definition: Prefs.h:158
bool Write(const T &value)
Write value to config and return true if successful.
Definition: Prefs.h:229
T Read() const
overload of Read, always returning a value
Definition: Prefs.h:211
Setting(const SettingBase &path, const T &defaultValue)
Usual overload supplies a default value.
Definition: Prefs.h:165
T ReadWithDefault(const T &defaultValue) const
new direct use is discouraged but it may be needed in legacy code
Definition: Prefs.h:219
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:191
void Rollback() noexcept override
Definition: Prefs.h:264
bool Reset()
Reset to the default value.
Definition: Prefs.h:254
bool DoWrite()
Write cached value to config and return true if successful.
Definition: Prefs.h:272
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:185
std::function< T() > DefaultValueFunction
Definition: Prefs.h:162
const T & GetDefault() const
Definition: Prefs.h:177
Setting(const SettingBase &path, DefaultValueFunction function)
This overload causes recomputation of the default each time it is needed.
Definition: Prefs.h:171
bool Commit() override
Definition: Prefs.h:259
const DefaultValueFunction mFunction
Definition: Prefs.h:279
Makes temporary changes to preferences, then rolls them back at destruction.
Definition: Prefs.h:100
static SettingScope * sCurrent
Definition: Prefs.h:117
static AddResult Add(TransactionalSettingBase &setting)
Definition: Prefs.cpp:254
SettingScope(const SettingScope &)=delete
SettingScope & operator=(const SettingScope &)=delete
@ NotAdded
Definition: Prefs.h:113
@ PreviouslyAdded
Definition: Prefs.h:113
std::set< TransactionalSettingBase * > mPending
Definition: Prefs.h:118
Extend SettingScope with Commit() which flushes updates in a batch.
Definition: Prefs.h:130
Specialization of Setting for strings.
Definition: Prefs.h:310
virtual void Rollback() noexcept=0
virtual bool Commit()=0
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
wxString Find(const FilePath &path)
void Add(const FilePath &path)
bool GetConfig(const EffectDefinitionInterface &ident, ConfigurationType type, const RegistryPath &group, const RegistryPath &key, Value &var, const Value &defval)
STL namespace.