Audacity  2.2.2
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 #include "Audacity.h"
54 
55 #include <wx/defs.h>
56 #include <wx/app.h>
57 #include <wx/config.h>
58 #include <wx/intl.h>
59 #include <wx/fileconf.h>
60 #include <wx/filename.h>
61 #include <wx/stdpaths.h>
62 
63 #include "AudacityApp.h"
64 #include "FileNames.h"
65 #include "Languages.h"
66 
67 #include "Prefs.h"
68 #include "widgets/ErrorDialog.h"
69 #include "Internat.h"
70 
71 std::unique_ptr<wxFileConfig> ugPrefs {};
72 wxFileConfig *gPrefs = NULL;
73 int gMenusDirty = 0;
74 
75 #if 0
76 // Copy one entry from one wxConfig object to another
77 static void CopyEntry(wxString path, wxConfigBase *src, wxConfigBase *dst, wxString entry)
78 {
79  switch(src->GetEntryType(entry)) {
80  case wxConfigBase::Type_Unknown:
81  case wxConfigBase::Type_String: {
82  wxString value = src->Read(entry, wxT(""));
83  dst->Write(path + entry, value);
84  break;
85  }
86  case wxConfigBase::Type_Boolean: {
87  bool value = false;
88  src->Read(entry, &value, value);
89  dst->Write(path + entry, value);
90  break;
91  }
92  case wxConfigBase::Type_Integer: {
93  long value = false;
94  src->Read(entry, &value, value);
95  dst->Write(path + entry, value);
96  break;
97  }
98  case wxConfigBase::Type_Float: {
99  double value = false;
100  src->Read(entry, &value, value);
101  dst->Write(path + entry, value);
102  break;
103  }
104  }
105 }
106 
107 
108 // Recursive routine to copy all groups and entries from one wxConfig object to another
109 static void CopyEntriesRecursive(wxString path, wxConfigBase *src, wxConfigBase *dst)
110 {
111  wxString entryName;
112  long entryIndex;
113  bool entryKeepGoing;
114 
115  entryKeepGoing = src->GetFirstEntry(entryName, entryIndex);
116  while (entryKeepGoing) {
117  CopyEntry(path, src, dst, entryName);
118  entryKeepGoing = src->GetNextEntry(entryName, entryIndex);
119  }
120 
121  wxString groupName;
122  long groupIndex;
123  bool groupKeepGoing;
124 
125  groupKeepGoing = src->GetFirstGroup(groupName, groupIndex);
126  while (groupKeepGoing) {
127  wxString subPath = path+groupName+wxT("/");
128  src->SetPath(subPath);
129  CopyEntriesRecursive(subPath, src, dst);
130  src->SetPath(path);
131  groupKeepGoing = src->GetNextGroup(groupName, groupIndex);
132  }
133 }
134 #endif
135 
137 {
138  wxString appName = wxTheApp->GetAppName();
139 
140  wxFileName configFileName(FileNames::DataDir(), wxT("audacity.cfg"));
141 
142  ugPrefs = std::make_unique<wxFileConfig>
143  (appName, wxEmptyString,
144  configFileName.GetFullPath(),
145  wxEmptyString, wxCONFIG_USE_LOCAL_FILE);
146  gPrefs = ugPrefs.get();
147 
148  wxConfigBase::Set(gPrefs);
149 
150  bool resetPrefs = false;
151  wxString langCode = gPrefs->Read(wxT("/Locale/Language"), wxEmptyString);
152  bool writeLang = false;
153 
154  const wxFileName fn(
156  wxT("FirstTime.ini"));
157  if (fn.FileExists()) // it will exist if the (win) installer put it there
158  {
159  const wxString fullPath{fn.GetFullPath()};
160 
161  wxFileConfig ini(wxEmptyString,
162  wxEmptyString,
163  fullPath,
164  wxEmptyString,
165  wxCONFIG_USE_LOCAL_FILE);
166 
167  wxString lang;
168  if (ini.Read(wxT("/FromInno/Language"), &lang))
169  {
170  // Only change "langCode" if the language was actually specified in the ini file.
171  langCode = lang;
172  writeLang = true;
173 
174  // Inno Setup doesn't allow special characters in the Name values, so "0" is used
175  // to represent the "@" character.
176  langCode.Replace(wxT("0"), wxT("@"));
177  }
178 
179  ini.Read(wxT("/FromInno/ResetPrefs"), &resetPrefs, false);
180 
181  bool gone = wxRemoveFile(fullPath); // remove FirstTime.ini
182  if (!gone)
183  {
184  AudacityMessageBox(wxString::Format(_("Failed to remove %s"), fullPath), _("Failed!"));
185  }
186  }
187 
188  // Use the system default language if one wasn't specified or if the user selected System.
189  if (langCode.IsEmpty())
190  {
191  langCode = GetSystemLanguageCode();
192  }
193 
194  // Initialize the language
195  langCode = wxGetApp().InitLang(langCode);
196 
197  // User requested that the preferences be completely reset
198  if (resetPrefs)
199  {
200  // pop up a dialogue
201  wxString prompt = _("Reset Preferences?\n\nThis is a one-time question, after an 'install' where you asked to have the Preferences reset.");
202  int action = AudacityMessageBox(prompt, _("Reset Audacity Preferences"),
203  wxYES_NO, NULL);
204  if (action == wxYES) // reset
205  {
206  gPrefs->DeleteAll();
207  writeLang = true;
208  }
209  }
210 
211  // Save the specified language
212  if (writeLang)
213  {
214  gPrefs->Write(wxT("/Locale/Language"), langCode);
215  }
216 
217  // In AUdacity 2.1.0 support for the legacy 1.2.x preferences (depreciated since Audacity
218  // 1.3.1) is dropped. As a result we can drop the import flag
219  // first time this version of Audacity is run we try to migrate
220  // old preferences.
221  bool newPrefsInitialized = false;
222  gPrefs->Read(wxT("/NewPrefsInitialized"), &newPrefsInitialized, false);
223  if (newPrefsInitialized) {
224  gPrefs->DeleteEntry(wxT("/NewPrefsInitialized"), true); // take group as well if empty
225  }
226 
227  // record the Prefs version for future checking (this has not been used for a very
228  // long time).
229  gPrefs->Write(wxT("/PrefsVersion"), wxString(wxT(AUDACITY_PREFS_VERSION_STRING)));
230 
231  // Check if some prefs updates need to happen based on audacity version.
232  // Unfortunately we can't use the PrefsVersion prefs key because that resets things.
233  // In the future we may want to integrate that better.
234  // these are done on a case-by-case basis for now so they must be backwards compatible
235  // (meaning the changes won't mess audacity up if the user goes back to an earlier version)
236  int vMajor = gPrefs->Read(wxT("/Version/Major"), (long) 0);
237  int vMinor = gPrefs->Read(wxT("/Version/Minor"), (long) 0);
238  int vMicro = gPrefs->Read(wxT("/Version/Micro"), (long) 0);
239 
240  wxGetApp().SetVersionKeysInit(vMajor, vMinor, vMicro); // make a note of these initial values
241  // for use by ToolManager::ReadConfig()
242 
243  // These integer version keys were introduced april 4 2011 for 1.3.13
244  // The device toolbar needs to be enabled due to removal of source selection features in
245  // the mixer toolbar.
246  if ((vMajor < 1) ||
247  (vMajor == 1 && vMinor < 3) ||
248  (vMajor == 1 && vMinor == 3 && vMicro < 13)) {
249 
250 
251  // Do a full reset of the Device Toolbar to get it on the screen.
252  if (gPrefs->Exists(wxT("/GUI/ToolBars/Device")))
253  gPrefs->DeleteGroup(wxT("/GUI/ToolBars/Device"));
254 
255  // We keep the mixer toolbar prefs (shown/not shown)
256  // the width of the mixer toolbar may have shrunk, the prefs will keep the larger value
257  // if the user had a device that had more than one source.
258  if (gPrefs->Exists(wxT("/GUI/ToolBars/Mixer"))) {
259  // Use the default width
260  gPrefs->Write(wxT("/GUI/ToolBars/Mixer/W"), -1);
261  }
262  }
263 
264  // In 2.1.0, the Meter toolbar was split and lengthened, but strange arrangements happen
265  // if upgrading due to the extra length. So, if a user is upgrading, use the pre-2.1.0
266  // lengths, but still use the NEW split versions.
267  if (gPrefs->Exists(wxT("/GUI/ToolBars/Meter")) &&
268  !gPrefs->Exists(wxT("/GUI/ToolBars/CombinedMeter"))) {
269 
270  // Read in all of the existing values
271  long dock, order, show, x, y, w, h;
272  gPrefs->Read(wxT("/GUI/ToolBars/Meter/Dock"), &dock, -1);
273  gPrefs->Read(wxT("/GUI/ToolBars/Meter/Order"), &order, -1);
274  gPrefs->Read(wxT("/GUI/ToolBars/Meter/Show"), &show, -1);
275  gPrefs->Read(wxT("/GUI/ToolBars/Meter/X"), &x, -1);
276  gPrefs->Read(wxT("/GUI/ToolBars/Meter/Y"), &y, -1);
277  gPrefs->Read(wxT("/GUI/ToolBars/Meter/W"), &w, -1);
278  gPrefs->Read(wxT("/GUI/ToolBars/Meter/H"), &h, -1);
279 
280  // "Order" must be adjusted since we're inserting two NEW toolbars
281  if (dock > 0) {
282  wxString oldPath = gPrefs->GetPath();
283  gPrefs->SetPath(wxT("/GUI/ToolBars"));
284 
285  wxString bar;
286  long ndx = 0;
287  bool cont = gPrefs->GetFirstGroup(bar, ndx);
288  while (cont) {
289  long o;
290  if (gPrefs->Read(bar + wxT("/Order"), &o) && o >= order) {
291  gPrefs->Write(bar + wxT("/Order"), o + 2);
292  }
293  cont = gPrefs->GetNextGroup(bar, ndx);
294  }
295  gPrefs->SetPath(oldPath);
296 
297  // And override the height
298  h = 27;
299  }
300 
301  // Write the split meter bar values
302  gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/Dock"), dock);
303  gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/Order"), order);
304  gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/Show"), show);
305  gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/X"), -1);
306  gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/Y"), -1);
307  gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/W"), w);
308  gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/H"), h);
309  gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/Dock"), dock);
310  gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/Order"), order + 1);
311  gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/Show"), show);
312  gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/X"), -1);
313  gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/Y"), -1);
314  gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/W"), w);
315  gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/H"), h);
316 
317  // And hide the old combined meter bar
318  gPrefs->Write(wxT("/GUI/ToolBars/Meter/Dock"), -1);
319  }
320 
321  // Upgrading pre 2.2.0 configs we assume extended set of defaults.
322  if ((0<vMajor && vMajor < 2) ||
323  (vMajor == 2 && vMinor < 2))
324  {
325  gPrefs->Write(wxT("/GUI/Shortcuts/FullDefaults"),1);
326  }
327 
328  // write out the version numbers to the prefs file for future checking
329  gPrefs->Write(wxT("/Version/Major"), AUDACITY_VERSION);
330  gPrefs->Write(wxT("/Version/Minor"), AUDACITY_RELEASE);
331  gPrefs->Write(wxT("/Version/Micro"), AUDACITY_REVISION);
332 
333  gPrefs->Flush();
334 }
335 
337 {
338  if (gPrefs) {
339  wxConfigBase::Set(NULL);
340  ugPrefs.reset();
341  gPrefs = NULL;
342  }
343 }
void FinishPreferences()
Definition: Prefs.cpp:336
#define AUDACITY_REVISION
Definition: Audacity.h:65
std::unique_ptr< wxFileConfig > ugPrefs
Definition: Prefs.cpp:71
int AudacityMessageBox(const wxString &message, const wxString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: ErrorDialog.h:92
#define AUDACITY_PREFS_VERSION_STRING
Definition: Audacity.h:104
#define AUDACITY_VERSION
Definition: Audacity.h:63
wxString InitLang(const wxString &lang)
wxFileConfig * gPrefs
Definition: Prefs.cpp:72
#define AUDACITY_RELEASE
Definition: Audacity.h:64
void InitPreferences()
Definition: Prefs.cpp:136
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
wxString GetSystemLanguageCode()
Definition: Languages.cpp:78
static wxString ResourcesDir()
Definition: FileNames.cpp:168
std::unordered_set< ConstBlockFilePtr > Set
Definition: UndoManager.cpp:44
static wxString DataDir()
Audacity user data directory.
Definition: FileNames.cpp:130
void SetVersionKeysInit(int major, int minor, int micro)
Definition: AudacityApp.h:172
AudacityApp & wxGetApp()
int gMenusDirty
Definition: Prefs.cpp:73