Audacity  3.0.3
Prefs.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  Prefs.cpp
6 
7  Dominic Mazzoni
8 
9 *******************************************************************//*******************************************************************/
51 
52 
53 
54 #include "Prefs.h"
55 
56 #include <wx/defs.h>
57 #include <wx/app.h>
58 #include <wx/intl.h>
59 #include <wx/filename.h>
60 #include <wx/stdpaths.h>
61 
62 #include "Internat.h"
63 #include "MemoryX.h"
64 
65 std::unique_ptr<FileConfig> ugPrefs {};
66 
67 FileConfig *gPrefs = nullptr;
68 int gMenusDirty = 0;
69 
70 wxDEFINE_EVENT(EVT_PREFS_UPDATE, wxCommandEvent);
71 
72 struct PrefsListener::Impl : wxEvtHandler
73 {
74  Impl( PrefsListener &owner );
75  ~Impl();
76  void OnEvent(wxCommandEvent&);
78 };
79 
81  : mOwner{ owner }
82 {
83  wxTheApp->Bind(EVT_PREFS_UPDATE, &PrefsListener::Impl::OnEvent, this);
84 }
85 
87 {
88 }
89 
91  : mpImpl{ std::make_unique<Impl>( *this ) }
92 {
93 }
94 
96 {
97 }
98 
100 {
101 }
102 
103 void PrefsListener::Impl::OnEvent( wxCommandEvent &evt )
104 {
105  evt.Skip();
106  auto id = evt.GetId();
107  if (id <= 0)
109  else
111 }
112 
113 #if 0
114 // Copy one entry from one wxConfig object to another
115 static void CopyEntry(wxString path, wxConfigBase *src, wxConfigBase *dst, wxString entry)
116 {
117  switch(src->GetEntryType(entry)) {
118  case wxConfigBase::Type_Unknown:
119  case wxConfigBase::Type_String: {
120  wxString value = src->Read(entry, wxT(""));
121  dst->Write(path + entry, value);
122  break;
123  }
124  case wxConfigBase::Type_Boolean: {
125  bool value = false;
126  src->Read(entry, &value, value);
127  dst->Write(path + entry, value);
128  break;
129  }
130  case wxConfigBase::Type_Integer: {
131  long value = false;
132  src->Read(entry, &value, value);
133  dst->Write(path + entry, value);
134  break;
135  }
136  case wxConfigBase::Type_Float: {
137  double value = false;
138  src->Read(entry, &value, value);
139  dst->Write(path + entry, value);
140  break;
141  }
142  }
143 }
144 
145 
146 // Recursive routine to copy all groups and entries from one wxConfig object to another
147 static void CopyEntriesRecursive(wxString path, wxConfigBase *src, wxConfigBase *dst)
148 {
149  wxString entryName;
150  long entryIndex;
151  bool entryKeepGoing;
152 
153  entryKeepGoing = src->GetFirstEntry(entryName, entryIndex);
154  while (entryKeepGoing) {
155  CopyEntry(path, src, dst, entryName);
156  entryKeepGoing = src->GetNextEntry(entryName, entryIndex);
157  }
158 
159  wxString groupName;
160  long groupIndex;
161  bool groupKeepGoing;
162 
163  groupKeepGoing = src->GetFirstGroup(groupName, groupIndex);
164  while (groupKeepGoing) {
165  wxString subPath = path+groupName+wxT("/");
166  src->SetPath(subPath);
167  CopyEntriesRecursive(subPath, src, dst);
168  src->SetPath(path);
169  groupKeepGoing = src->GetNextGroup(groupName, groupIndex);
170  }
171 }
172 #endif
173 
174 void InitPreferences( std::unique_ptr<FileConfig> uPrefs )
175 {
176  gPrefs = uPrefs.get();
177  ugPrefs = std::move(uPrefs);
178  wxConfigBase::Set(gPrefs);
179 }
180 
182 {
183  if (gPrefs) {
184  wxConfigBase::Set(NULL);
185  ugPrefs.reset();
186  gPrefs = NULL;
187  }
188 }
189 
192  ByColumns_t,
193  const TranslatableStrings &msgids,
194  wxArrayStringEx internals
195 )
196  : mInternals( std::move( internals ) )
197 {
198  auto size = mInternals.size(), size2 = msgids.size();
199  if ( size != size2 ) {
200  wxASSERT( false );
201  size = std::min( size, size2 );
202  }
203  reserve( size );
204  auto iter1 = mInternals.begin();
205  auto iter2 = msgids.begin();
206  while( size-- )
207  emplace_back( *iter1++, *iter2++ );
208 }
209 
211 {
212  if ( mMsgids.empty() )
213  mMsgids = transform_container<TranslatableStrings>( *this,
214  std::mem_fn( &EnumValueSymbol::Msgid ) );
215  return mMsgids;
216 }
217 
219 {
220  if ( mInternals.empty() )
221  mInternals = transform_container<wxArrayStringEx>( *this,
222  std::mem_fn( &EnumValueSymbol::Internal ) );
223  return mInternals;
224 }
225 
228 {
229  if ( mDefaultSymbol >= 0 && mDefaultSymbol < (long)mSymbols.size() )
230  return mSymbols[ mDefaultSymbol ];
231  static EnumValueSymbol empty;
232  return empty;
233 }
234 
235 wxString ChoiceSetting::Read() const
236 {
237  const auto &defaultValue = Default().Internal();
238  return ReadWithDefault( defaultValue );
239 }
240 
241 wxString ChoiceSetting::ReadWithDefault( const wxString &defaultValue ) const
242 {
243  wxString value;
244  if ( !gPrefs->Read(mKey, &value, defaultValue) )
245  if (!mMigrated) {
246  const_cast<ChoiceSetting*>(this)->Migrate( value );
247  mMigrated = true;
248  }
249 
250  // Remap to default if the string is not known -- this avoids surprises
251  // in case we try to interpret config files from future versions
252  auto index = Find( value );
253  if ( index >= mSymbols.size() )
254  value = defaultValue;
255  return value;
256 }
257 
258 size_t ChoiceSetting::Find( const wxString &value ) const
259 {
260  auto start = GetSymbols().begin();
261  return size_t(
262  std::find( start, GetSymbols().end(), EnumValueSymbol{ value, {} } )
263  - start );
264 }
265 
266 void ChoiceSetting::Migrate( wxString &value )
267 {
268  (void)value;// Compiler food
269 }
270 
271 bool ChoiceSetting::Write( const wxString &value )
272 {
273  auto index = Find( value );
274  if (index >= mSymbols.size())
275  return false;
276 
277  auto result = gPrefs->Write( mKey, value );
278  mMigrated = true;
279  return result;
280 }
281 
283  const wxString &key,
284  EnumValueSymbols symbols,
285  long defaultSymbol,
286 
287  std::vector<int> intValues, // must have same size as symbols
288  const wxString &oldKey
289 )
290  : ChoiceSetting{ key, std::move( symbols ), defaultSymbol }
291  , mIntValues{ std::move( intValues ) }
292  , mOldKey{ oldKey }
293 {
294  auto size = mSymbols.size();
295  if( mIntValues.size() != size ) {
296  wxASSERT( false );
297  mIntValues.resize( size );
298  }
299 }
300 
301 void ChoiceSetting::SetDefault( long value )
302 {
303  if ( value < (long)mSymbols.size() )
304  mDefaultSymbol = value;
305  else
306  wxASSERT( false );
307 }
308 
310 {
311  auto index = Find( Read() );
312 
313  wxASSERT( index < mIntValues.size() );
314  return mIntValues[ index ];
315 }
316 
317 int EnumSettingBase::ReadIntWithDefault( int defaultValue ) const
318 {
319  wxString defaultString;
320  auto index0 = FindInt( defaultValue );
321  if ( index0 < mSymbols.size() )
322  defaultString = mSymbols[ index0 ].Internal();
323  else
324  wxASSERT( false );
325 
326  auto index = Find( ReadWithDefault( defaultString ) );
327 
328  wxASSERT( index < mSymbols.size() );
329  return mIntValues[ index ];
330 }
331 
332 size_t EnumSettingBase::FindInt( int code ) const
333 {
334  const auto start = mIntValues.begin();
335  return size_t(
336  std::find( start, mIntValues.end(), code )
337  - start );
338 }
339 
340 void EnumSettingBase::Migrate( wxString &value )
341 {
342  int intValue = 0;
343  if ( !mOldKey.empty() &&
344  gPrefs->Read(mOldKey, &intValue, 0) ) {
345  // Make the migration, only once and persistently.
346  // Do not DELETE the old key -- let that be read if user downgrades
347  // Audacity. But further changes will be stored only to the NEW key
348  // and won't be seen then.
349  auto index = (long) FindInt( intValue );
350  if ( index >= (long)mSymbols.size() )
351  index = mDefaultSymbol;
352  if ( index >= 0 && index < (long)mSymbols.size() ) {
353  value = mSymbols[index].Internal();
354  Write(value);
355  gPrefs->Flush();
356  }
357  }
358 }
359 
360 bool EnumSettingBase::WriteInt( int code ) // you flush gPrefs afterward
361 {
362  auto index = FindInt( code );
363  if ( index >= mSymbols.size() )
364  return false;
365  return Write( mSymbols[index].Internal() );
366 }
367 
368 wxString WarningDialogKey(const wxString &internalDialogName)
369 {
370  return wxT("/Warnings/") + internalDialogName;
371 }
372 
374 
375 #include <set>
376 
377 namespace {
378  using PreferenceInitializers = std::set< PreferenceInitializer* >;
380  {
381  static PreferenceInitializers theSet;
382  return theSet;
383  }
384 }
385 
387 {
388  allInitializers().insert( this );
389 }
390 
392 {
393  allInitializers().erase( this );
394 }
395 
397 {
398  for ( auto pInitializer : allInitializers() )
399  (*pInitializer)();
400 }
EnumSettingBase::Migrate
void Migrate(wxString &) override
Definition: Prefs.cpp:340
PrefsListener::~PrefsListener
virtual ~PrefsListener()
Definition: Prefs.cpp:95
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:67
EnumSettingBase::mIntValues
std::vector< int > mIntValues
Definition: Prefs.h:167
PrefsListener::Impl::OnEvent
void OnEvent(wxCommandEvent &)
Definition: Prefs.cpp:103
ChoiceSetting::Find
size_t Find(const wxString &value) const
Definition: Prefs.cpp:258
EnumValueSymbols::EnumValueSymbols
EnumValueSymbols()=default
ChoiceSetting::Write
bool Write(const wxString &value)
Definition: Prefs.cpp:271
FinishPreferences
void FinishPreferences()
Definition: Prefs.cpp:181
EnumValueSymbols::GetMsgids
const TranslatableStrings & GetMsgids() const
Definition: Prefs.cpp:210
EnumSettingBase::ReadInt
int ReadInt() const
Definition: Prefs.cpp:309
PreferenceInitializer::ReinitializeAll
static void ReinitializeAll()
Definition: Prefs.cpp:396
anonymous_namespace{Prefs.cpp}::allInitializers
PreferenceInitializers & allInitializers()
Definition: Prefs.cpp:379
PrefsListener::Impl::Impl
Impl(PrefsListener &owner)
Definition: Prefs.cpp:80
EnumValueSymbols::GetInternals
const wxArrayStringEx & GetInternals() const
Definition: Prefs.cpp:218
ComponentInterfaceSymbol::Msgid
const TranslatableString & Msgid() const
Definition: ComponentInterface.h:89
wxArrayStringEx
Definition: MemoryX.h:663
EnumValueSymbols::mMsgids
TranslatableStrings mMsgids
Definition: Prefs.h:83
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterface.h:60
PrefsListener
Definition: Prefs.h:216
EnumValueSymbols
Definition: Prefs.h:62
PreferenceInitializer::PreferenceInitializer
PreferenceInitializer()
Definition: Prefs.cpp:386
ugPrefs
std::unique_ptr< FileConfig > ugPrefs
Definition: Prefs.cpp:65
EnumSettingBase::ReadIntWithDefault
int ReadIntWithDefault(int defaultValue) const
Definition: Prefs.cpp:317
ByColumns_t
Definition: Prefs.h:55
PrefsListener::UpdateSelectedPrefs
virtual void UpdateSelectedPrefs(int id)
Definition: Prefs.cpp:99
ChoiceSetting
Definition: Prefs.h:90
TranslatableStrings
std::vector< TranslatableString > TranslatableStrings
Definition: Types.h:547
InitPreferences
void InitPreferences(std::unique_ptr< FileConfig > uPrefs)
Definition: Prefs.cpp:174
PreferenceInitializer::~PreferenceInitializer
virtual ~PreferenceInitializer()
Definition: Prefs.cpp:391
EnumSettingBase::mOldKey
const wxString mOldKey
Definition: Prefs.h:168
wxDEFINE_EVENT
wxDEFINE_EVENT(EVT_PREFS_UPDATE, wxCommandEvent)
EnumSettingBase::WriteInt
bool WriteInt(int code)
Definition: Prefs.cpp:360
ChoiceSetting::mDefaultSymbol
long mDefaultSymbol
Definition: Prefs.h:132
ChoiceSetting::SetDefault
void SetDefault(long value)
Definition: Prefs.cpp:301
ChoiceSetting::ReadWithDefault
wxString ReadWithDefault(const wxString &) const
Definition: Prefs.cpp:241
ChoiceSetting::GetSymbols
const EnumValueSymbols & GetSymbols() const
Definition: Prefs.h:108
ChoiceSetting::mMigrated
bool mMigrated
Definition: Prefs.h:130
ChoiceSetting::mKey
const wxString mKey
Definition: Prefs.h:125
EnumValueSymbols::mInternals
wxArrayStringEx mInternals
Definition: Prefs.h:84
FileConfig
Definition: FileConfig.h:22
Internat.h
PrefsListener::Impl::~Impl
~Impl()
Definition: Prefs.cpp:86
ChoiceSetting::Read
wxString Read() const
Definition: Prefs.cpp:235
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
PrefsListener::Impl
Definition: Prefs.cpp:73
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:151
key
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: CommandManager.cpp:196
ChoiceSetting::Default
const EnumValueSymbol & Default() const
Definition: Prefs.cpp:227
MemoryX.h
ChoiceSetting::Migrate
virtual void Migrate(wxString &)
Definition: Prefs.cpp:266
WarningDialogKey
wxString WarningDialogKey(const wxString &internalDialogName)
Definition: Prefs.cpp:368
EnumSettingBase::EnumSettingBase
EnumSettingBase(const wxString &key, EnumValueSymbols symbols, long defaultSymbol, std::vector< int > intValues, const wxString &oldKey={})
Definition: Prefs.cpp:282
EnumSettingBase::FindInt
size_t FindInt(int code) const
Definition: Prefs.cpp:332
ComponentInterfaceSymbol::Internal
const wxString & Internal() const
Definition: ComponentInterface.h:88
PrefsListener::UpdatePrefs
virtual void UpdatePrefs()=0
PrefsListener::Impl::mOwner
PrefsListener & mOwner
Definition: Prefs.cpp:77
anonymous_namespace{Prefs.cpp}::PreferenceInitializers
std::set< PreferenceInitializer * > PreferenceInitializers
Definition: Prefs.cpp:378
Prefs.h
ByColumns
ByColumns_t ByColumns
Definition: Prefs.cpp:373
PrefsListener::mpImpl
std::unique_ptr< Impl > mpImpl
Definition: Prefs.h:232
PrefsListener::PrefsListener
PrefsListener()
Definition: Prefs.cpp:90
gMenusDirty
int gMenusDirty
Definition: Prefs.cpp:68
ChoiceSetting::mSymbols
const EnumValueSymbols mSymbols
Definition: Prefs.h:127