1 /**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 GUIPrefs.cpp
6
7 Brian Gunlogson
8 Joshua Haberman
9 Dominic Mazzoni
10 James Crook
11
12
13 *******************************************************************//**
14
15 \class GUIPrefs
16 \brief A PrefsPanel for general GUI preferences.
17
18 *//*******************************************************************/
19
20
21 #include "GUIPrefs.h"
22
23 #include <wx/app.h>
24 #include <wx/defs.h>
25
26 #include "FileNames.h"
27 #include "Languages.h"
28 #include "Theme.h"
29 #include "Prefs.h"
30 #include "../ShuttleGui.h"
31
32 #include "Decibels.h"
33
34 #include "ThemePrefs.h"
35 #include "AColor.h"
36 #include "../widgets/AudacityMessageBox.h"
37
GUIPrefs(wxWindow * parent,wxWindowID winid)38 GUIPrefs::GUIPrefs(wxWindow * parent, wxWindowID winid)
39 /* i18n-hint: refers to Audacity's user interface settings */
40 : PrefsPanel(parent, winid, XC("Interface", "GUI"))
41 {
42 Populate();
43 }
44
~GUIPrefs()45 GUIPrefs::~GUIPrefs()
46 {
47 }
48
GetSymbol()49 ComponentInterfaceSymbol GUIPrefs::GetSymbol()
50 {
51 return GUI_PREFS_PLUGIN_SYMBOL;
52 }
53
GetDescription()54 TranslatableString GUIPrefs::GetDescription()
55 {
56 return XO("Preferences for GUI");
57 }
58
HelpPageName()59 ManualPageID GUIPrefs::HelpPageName()
60 {
61 return "Interface_Preferences";
62 }
63
GetRangeChoices(TranslatableStrings * pChoices,wxArrayStringEx * pCodes,int * pDefaultRangeIndex)64 void GUIPrefs::GetRangeChoices(
65 TranslatableStrings *pChoices,
66 wxArrayStringEx *pCodes,
67 int *pDefaultRangeIndex
68 )
69 {
70 static const auto sCodes = {
71 wxT("36") ,
72 wxT("48") ,
73 wxT("60") ,
74 wxT("72") ,
75 wxT("84") ,
76 wxT("96") ,
77 wxT("120") ,
78 wxT("145") ,
79 };
80 if (pCodes)
81 *pCodes = sCodes;
82
83 static const std::initializer_list<TranslatableString> sChoices = {
84 XO("-36 dB (shallow range for high-amplitude editing)") ,
85 XO("-48 dB (PCM range of 8 bit samples)") ,
86 XO("-60 dB (PCM range of 10 bit samples)") ,
87 XO("-72 dB (PCM range of 12 bit samples)") ,
88 XO("-84 dB (PCM range of 14 bit samples)") ,
89 XO("-96 dB (PCM range of 16 bit samples)") ,
90 XO("-120 dB (approximate limit of human hearing)") ,
91 XO("-145 dB (PCM range of 24 bit samples)") ,
92 };
93
94 if (pChoices)
95 *pChoices = sChoices;
96
97 if (pDefaultRangeIndex)
98 *pDefaultRangeIndex = 2; // 60 == ENV_DB_RANGE
99 }
100
Populate()101 void GUIPrefs::Populate()
102 {
103 // First any pre-processing for constructing the GUI.
104 Languages::GetLanguages(
105 FileNames::AudacityPathList(), mLangCodes, mLangNames);
106
107 GetRangeChoices(&mRangeChoices, &mRangeCodes, &mDefaultRangeIndex);
108
109 #if 0
110 mLangCodes.insert( mLangCodes.end(), {
111 // only for testing...
112 "kg" ,
113 "ep" ,
114 } );
115
116 mLangNames.insert( mLangNames.end(), {
117 "Klingon" ,
118 "Esperanto" ,
119 } );
120 #endif
121
122 //------------------------- Main section --------------------
123 // Now construct the GUI itself.
124 // Use 'eIsCreatingFromPrefs' so that the GUI is
125 // initialised with values from gPrefs.
126 ShuttleGui S(this, eIsCreatingFromPrefs);
127 PopulateOrExchange(S);
128 // ----------------------- End of main section --------------
129 }
130
131 ChoiceSetting GUIManualLocation{
132 wxT("/GUI/Help"),
133 {
134 ByColumns,
135 { XO("Local") , XO("From Internet") , },
136 { wxT("Local") , wxT("FromInternet") , }
137 },
138 0 // "Local"
139 };
140
PopulateOrExchange(ShuttleGui & S)141 void GUIPrefs::PopulateOrExchange(ShuttleGui & S)
142 {
143 S.SetBorder(2);
144 S.StartScroller();
145
146 S.StartStatic(XO("Display"));
147 {
148 S.StartMultiColumn(2);
149 {
150
151 S.TieChoice( XXO("&Language:"),
152 {
153 wxT("/Locale/Language"),
154 { ByColumns, mLangNames, mLangCodes }
155 }
156 );
157
158 S.TieChoice( XXO("Location of &Manual:"), GUIManualLocation);
159
160 S.TieChoice( XXO("Th&eme:"), GUITheme());
161
162 S.TieChoice( XXO("Meter dB &range:"),
163 {
164 DecibelScaleCutoff.GetPath(),
165 { ByColumns, mRangeChoices, mRangeCodes },
166 mDefaultRangeIndex
167 }
168 );
169 }
170 S.EndMultiColumn();
171
172 }
173 S.EndStatic();
174
175 S.StartStatic(XO("Options"));
176 {
177 // Start wording of options with a verb, if possible.
178 S.TieCheckBox(XXO("Show 'How to Get &Help' at launch"),
179 {wxT("/GUI/ShowSplashScreen"),
180 true});
181 S.TieCheckBox(XXO("Show e&xtra menus"),
182 {wxT("/GUI/ShowExtraMenus"),
183 false});
184 #ifdef EXPERIMENTAL_THEME_PREFS
185 // We do not want to make this option mainstream. It's a
186 // convenience for developers.
187 S.TieCheckBox(XXO("Show alternative &styling (Mac vs PC)"),
188 {wxT("/GUI/ShowMac"),
189 false});
190 #endif
191 S.TieCheckBox(XXO("&Beep on completion of longer activities"),
192 {wxT("/GUI/BeepOnCompletion"),
193 false});
194 S.TieCheckBox(XXO("Re&tain labels if selection snaps to a label"),
195 {wxT("/GUI/RetainLabels"),
196 false});
197 S.TieCheckBox(XXO("B&lend system and Audacity theme"),
198 GUIBlendThemes);
199 #ifndef __WXMAC__
200 /* i18n-hint: RTL stands for 'Right to Left' */
201 S.TieCheckBox(XXO("Use mostly Left-to-Right layouts in RTL languages"),
202 {"/GUI/RtlWorkaround",
203 true});
204 #endif
205 #ifdef EXPERIMENTAL_CEE_NUMBERS_OPTION
206 S.TieCheckBox(XXO("Never use comma as decimal point"),
207 {wxT("/Locale/CeeNumberFormat"),
208 false});
209 #endif
210 }
211 S.EndStatic();
212
213 S.StartStatic(XO("Timeline"));
214 {
215 S.TieCheckBox(XXO("Show Timeline Tooltips"),
216 {wxT("/QuickPlay/ToolTips"),
217 true});
218 S.TieCheckBox(XXO("Show Scrub Ruler"),
219 {wxT("/QuickPlay/ScrubbingEnabled"),
220 false});
221 }
222 S.EndStatic();
223
224 S.EndScroller();
225 }
226
Commit()227 bool GUIPrefs::Commit()
228 {
229 ShuttleGui S(this, eIsSavingToPrefs);
230 PopulateOrExchange(S);
231
232 // If language has changed, we want to change it now, not on the next reboot.
233 wxString lang = gPrefs->Read(wxT("/Locale/Language"), wxT(""));
234 wxString usedLang = SetLang(lang);
235 // Bug 1523: Previously didn't check no-language (=System Language)
236 if (!(lang.empty() || lang == L"System") && (lang != usedLang)) {
237 // lang was not usable and is not system language. We got overridden.
238 gPrefs->Write(wxT("/Locale/Language"), usedLang);
239 gPrefs->Flush();
240 }
241
242 // Reads preference GUITheme
243 {
244 wxBusyCursor busy;
245 theTheme.LoadPreferredTheme();
246 }
247 ThemePrefs::ApplyUpdatedImages();
248
249 return true;
250 }
251
SetLang(const wxString & lang)252 wxString GUIPrefs::SetLang( const wxString & lang )
253 {
254 auto result = Languages::SetLang(FileNames::AudacityPathList(), lang);
255 if (!(lang.empty() || lang == L"System") && result != lang)
256 ::AudacityMessageBox(
257 XO("Language \"%s\" is unknown").Format( lang ) );
258
259 #ifdef EXPERIMENTAL_CEE_NUMBERS_OPTION
260 bool forceCeeNumbers;
261 gPrefs->Read(wxT("/Locale/CeeNumberFormat"), &forceCeeNumbers, false);
262 if( forceCeeNumbers )
263 Internat::SetCeeNumberFormat();
264 #endif
265
266 #ifdef __WXMAC__
267 wxApp::s_macHelpMenuTitleName = _("&Help");
268 #endif
269
270 return result;
271 }
272
ShowClippingPrefsID()273 int ShowClippingPrefsID()
274 {
275 static int value = wxNewId();
276 return value;
277 }
278
ShowTrackNameInWaveformPrefsID()279 int ShowTrackNameInWaveformPrefsID()
280 {
281 static int value = wxNewId();
282 return value;
283 }
284
285 namespace{
286 PrefsPanel::Registration sAttachment{ "GUI",
287 [](wxWindow *parent, wxWindowID winid, AudacityProject *)
__anonf6f73c4e0202() 288 {
289 wxASSERT(parent); // to justify safenew
290 return safenew GUIPrefs(parent, winid);
291 }
292 };
293 }
294