Audacity 3.2.0
TracksPrefs.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 TracksPrefs.cpp
6
7 Brian Gunlogson
8 Joshua Haberman
9 Dominic Mazzoni
10 James Crook
11
12
13*******************************************************************//*******************************************************************/
19
20
21#include "TracksPrefs.h"
22#include "MemoryX.h"
23
24//#include <algorithm>
25//#include <wx/defs.h>
26
27#include "Prefs.h"
28#include "Project.h"
29#include "ShuttleGui.h"
30#include "UndoManager.h"
31#include "Viewport.h"
32#include "WaveTrack.h"
33
35
37 "/GUI/TracksFitVerticallyZoomed", false };
38
39namespace {
41 {
42 return wxT("/AudioIO/PinnedHead");
43 }
44
46 {
47 return false;
48 }
49
51 {
52 return wxT("/AudioIO/PinnedHeadPosition");
53 }
54
56 {
57 return 0.5;
58 }
59}
60
61
62namespace {
63 const auto waveformScaleKey = wxT("/GUI/DefaultWaveformScaleChoice");
64 const auto dbLogValueString = wxT("dB");
65 const auto dbLinValueString = wxT("dBLin");
66}
67
70 {
71 { wxT("Linear"), XO("Linear (amp)") },
72 { dbLogValueString, XO("Logarithmic (dB)") },
73 { dbLinValueString, XO("Linear (dB)") },
74 },
75
76 0, // linear
77
78 {
82 }
83};
84
86// There is a complicated migration history here!
87namespace {
88 const auto key0 = wxT("/GUI/DefaultViewMode");
89 const auto key1 = wxT("/GUI/DefaultViewModeNew");
90 const auto key2 = wxT("/GUI/DefaultViewModeChoice");
91 const auto key3 = wxT("/GUI/DefaultViewModeChoiceNew");
92
93 const wxString obsoleteValue{ wxT("WaveformDB") };
94};
95
97 : public EnumSetting<WaveChannelViewConstants::Display> {
98public:
100
101 void Migrate( wxString &value ) override
102 {
103 // Special logic for this preference which was three times migrated!
104
105 // PRL: Bugs 1043, 1044
106 // 2.1.1 writes a NEW key for this preference, which got NEW values,
107 // to avoid confusing version 2.1.0 if it reads the preference file afterwards.
108 // Prefer the NEW preference key if it is present
109
110 static const EnumValueSymbol waveformSymbol{ XO("Waveform") };
111 static const EnumValueSymbol spectrumSymbol{ XO("Spectrogram") };
112
114 int oldMode;
115 wxString newValue;
116 auto stringValue =
118 switch (display) {
120 return spectrumSymbol.Internal();
122 return obsoleteValue;
123 default:
124 return waveformSymbol.Internal();
125 }
126 };
127
128 if (gPrefs->Read(key0, // The very old key
129 &oldMode,
132 newValue = stringValue(viewMode);
133 }
134 else if ( gPrefs->Read(key1,
135 &oldMode,
137 viewMode = static_cast<WaveChannelViewConstants::Display>(oldMode);
138 newValue = stringValue(viewMode);
139 }
140 else
141 gPrefs->Read( key2, &newValue );
142
143 if ( !gPrefs->Read( key3, &value ) ) {
144 if (newValue == obsoleteValue) {
145 newValue = waveformSymbol.Internal();
147 }
148
149 Write( value = newValue );
150 gPrefs->Flush();
151 return;
152 }
153 }
154};
155
157{
158 // Do a delayed computation, so that registration of sub-view types completes
159 // first
160 const auto &types = WaveChannelSubViewType::All();
161 auto symbols = transform_container< EnumValueSymbols >(
162 types, std::mem_fn(&WaveChannelSubViewType::name));
163 auto ids = transform_container<std::vector<WaveChannelSubViewType::Display>>(
164 types, std::mem_fn(&WaveChannelSubViewType::id));
165
166 // Special entry for multi
169
170 return {
171 key3,
172 symbols,
173 0, // Waveform
174 ids
175 };
176}
177
179{
180 return ViewModeSetting().ReadEnum();
181}
182
184{
185 return waveformScaleSetting.ReadEnum();
186}
187
191 wxT("/GUI/SampleViewChoice"),
192 {
193 { wxT("ConnectDots"), XO("Connect dots") },
194 { wxT("StemPlot"), XO("Stem plot") }
195 },
196 1, // StemPlot
197
198 // for migrating old preferences:
199 {
202 },
203 wxT("/GUI/SampleView")
204};
205
207{
208 return sampleDisplaySetting.ReadEnum();
209}
210
212static const std::initializer_list<EnumValueSymbol> choicesZoom{
213 { wxT("FitToWidth"), XO("Fit to Width") },
214 { wxT("ZoomToSelection"), XO("Zoom to Selection") },
215 { wxT("ZoomDefault"), XO("Zoom Default") },
216 { XO("Minutes") },
217 { XO("Seconds") },
218 { wxT("FifthsOfSeconds"), XO("5ths of Seconds") },
219 { wxT("TenthsOfSeconds"), XO("10ths of Seconds") },
220 { wxT("TwentiethsOfSeconds"), XO("20ths of Seconds") },
221 { wxT("FiftiethsOfSeconds"), XO("50ths of Seconds") },
222 { wxT("HundredthsOfSeconds"), XO("100ths of Seconds") },
223 { wxT("FiveHundredthsOfSeconds"), XO("500ths of Seconds") },
224 { XO("MilliSeconds") },
225 { XO("Samples") },
226 { wxT("FourPixelsPerSample"), XO("4 Pixels per Sample") },
227 { wxT("MaxZoom"), XO("Max Zoom") },
228};
229static auto enumChoicesZoom = {
245};
246
248 wxT("/GUI/ZoomPreset1Choice"),
250 2, // kZoomDefault
251
252 // for migrating old preferences:
254 wxT("/GUI/ZoomPreset1")
255};
256
258 wxT("/GUI/ZoomPreset2Choice"),
260 13, // kZoom4To1
261
262 // for migrating old preferences:
264 wxT("/GUI/ZoomPreset2")
265};
266
268{
269 return zoom1Setting.ReadEnum();
270}
271
273{
274 return zoom2Setting.ReadEnum();
275}
276
278TracksPrefs::TracksPrefs(wxWindow * parent, wxWindowID winid)
279/* i18n-hint: "Tracks" include audio recordings but also other collections of
280 * data associated with a time line, such as sequences of labels, and musical
281 * notes */
282: PrefsPanel(parent, winid, XO("Tracks"))
283{
284 Populate();
285}
286
288{
289}
290
292{
294}
295
297{
298 return XO("Preferences for Tracks");
299}
300
302{
303 return "Tracks_Preferences";
304}
305
307{
308 // Keep view choices and codes in proper correspondence --
309 // we don't display them by increasing integer values.
310
311
312 // How samples are displayed when zoomed in:
313
314
315 //------------------------- Main section --------------------
316 // Now construct the GUI itself.
317 // Use 'eIsCreatingFromPrefs' so that the GUI is
318 // initialised with values from gPrefs.
321 // ----------------------- End of main section --------------
322}
323
325{
326 auto viewModeSetting = ViewModeSetting();
327
328 S.SetBorder(2);
329 S.StartScroller();
330
331 S.StartStatic(XO("Display"));
332 {
333 S.TieCheckBox(XXO("Auto-&fit track height"), TracksFitVerticallyZoomed);
334 S.TieCheckBox(XXO("Sho&w track name as overlay"),
335 {wxT("/GUI/ShowTrackNameInWaveform"),
336 false});
337 S.TieCheckBox(XXO("Use &half-wave display when collapsed"),
338 {wxT("/GUI/CollapseToHalfWave"),
339 false});
340#ifdef SHOW_PINNED_UNPINNED_IN_PREFS
341 S.TieCheckBox(XXO("&Pinned Recording/Playback head"),
344#endif
345 S.TieCheckBox(XXO("A&uto-scroll if head unpinned"),
346 {wxT("/GUI/AutoScroll"),
347 true});
348
349 S.AddSpace(10);
350
351 S.StartMultiColumn(2);
352 {
353#ifdef SHOW_PINNED_POSITION_IN_PREFS
354 S.TieNumericTextBox(
355 XXO("Pinned &head position"),
358 30
359 );
360#endif
361
362 S.TieChoice(XXO("Default &view mode:"),
363 viewModeSetting );
364
365 S.TieChoice(XXO("Default Waveform scale:"),
367
368 S.TieChoice(XXO("Display &samples:"),
370
371 S.TieTextBox(XXO("Default audio track &name:"),
373 30);
374 }
375 S.EndMultiColumn();
376 }
377 S.EndStatic();
378
379 S.StartStatic(XO("Zoom Toggle"));
380 {
381 S.StartMultiColumn(4);
382 {
383 S.TieChoice(XXO("Preset 1:"),
384 zoom1Setting );
385
386 S.TieChoice(XXO("Preset 2:"),
387 zoom2Setting );
388 }
389 }
390 S.EndStatic();
391 S.EndScroller();
392}
393
395{
396 // JKC: Cache this setting as it is read many times during drawing, and otherwise causes screen flicker.
397 // Correct solution would be to re-write wxFileConfig to be efficient.
398 if( iPreferencePinned >= 0 )
399 return iPreferencePinned == 1;
401 iPreferencePinned = bResult ? 1: 0;
402 return bResult;
403}
404
405void TracksPrefs::SetPinnedHeadPreference(bool value, bool flush)
406{
407 iPreferencePinned = value ? 1 :0;
409 if(flush)
410 gPrefs->Flush();
411}
412
414{
415 auto value = gPrefs->ReadDouble(
418 return std::max(0.0, std::min(1.0, value));
419}
420
422{
423 value = std::max(0.0, std::min(1.0, value));
425 if(flush)
426 gPrefs->Flush();
427}
428
430{
431 // Bug 1583: Clear the caching of the preference pinned state.
435
436 // Bug 1661: Don't store the name for new tracks if the name is the
437 // default in that language.
441 gPrefs->Flush();
442 }
443
446 return true;
447}
448
449namespace{
451 [](wxWindow *parent, wxWindowID winid, AudacityProject *)
452 {
453 wxASSERT(parent); // to justify safenew
454 return safenew TracksPrefs(parent, winid);
455 }
456};
457
460 explicit Handler(AudacityProject &project) : mProject{ project }
461 , mUndoSubscription{ UndoManager::Get(mProject)
462 .Subscribe([this](const UndoRedoMessage &message){
463 if (message.type == UndoRedoMessage::Pushed &&
465 )
466 Viewport::Get(mProject).ZoomFitVertically(); })}
467 {}
468
469 Handler(const Handler &) = delete;
470 Handler &operator=(const Handler &) = delete;
471
474}; // struct Handler
475
477 Callable::UniqueMaker<Handler, AudacityProject &>()
478};
479}
wxT("CloseDown"))
int min(int a, int b)
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define safenew
Definition: MemoryX.h:9
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
@ eIsCreatingFromPrefs
Definition: ShuttleGui.h:46
@ eIsSavingToPrefs
Definition: ShuttleGui.h:47
const auto project
#define S(N)
Definition: ToChars.cpp:64
static EnumSetting< WaveChannelViewConstants::ZoomPresets > zoom2Setting
static const std::initializer_list< EnumValueSymbol > choicesZoom
static EnumSetting< WaveChannelViewConstants::ZoomPresets > zoom1Setting
static EnumSetting< WaveChannelViewConstants::SampleDisplay > sampleDisplaySetting
static TracksViewModeEnumSetting ViewModeSetting()
static EnumSetting< WaveformSettings::ScaleTypeValues > waveformScaleSetting
Definition: TracksPrefs.cpp:68
static auto enumChoicesZoom
#define TRACKS_PREFS_PLUGIN_SYMBOL
Definition: TracksPrefs.h:25
StringSetting AudioTrackNameSetting
Definition: WaveTrack.cpp:3371
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
This specialization of Setting for bool adds a Toggle method to negate the saved value.
Definition: Prefs.h:346
bool Write(const wxString &value)
Definition: Prefs.cpp:424
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
Definition: ClientData.h:275
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Adapts EnumSettingBase to a particular enumeration type.
Definition: Prefs.h:514
Enum ReadEnum() const
Definition: Prefs.h:534
A move-only handle representing a connection to a Publisher.
Definition: Observer.h:70
Base class for a panel in the PrefsDialog. Classes derived from this class include BatchPrefs,...
Definition: PrefsPanel.h:51
bool Delete()
Delete the key if present, and return true iff it was.
Definition: Prefs.cpp:549
void Invalidate() override
Definition: Prefs.h:289
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:207
const T & GetDefault() const
Definition: Prefs.h:199
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:640
A PrefsPanel for track display and behavior properties.
Definition: TracksPrefs.h:28
static WaveformSettings::ScaleTypeValues WaveformScaleChoice()
static WaveChannelViewConstants::ZoomPresets Zoom1Choice()
TracksPrefs(wxWindow *parent, wxWindowID winid)
static void SetPinnedHeadPreference(bool value, bool flush=false)
static bool GetPinnedHeadPreference()
TranslatableString GetDescription() const override
ManualPageID HelpPageName() override
If not empty string, the Help button is added below the panel.
static WaveChannelViewConstants::ZoomPresets Zoom2Choice()
static double GetPinnedHeadPositionPreference()
static WaveChannelViewConstants::SampleDisplay SampleViewChoice()
void PopulateOrExchange(ShuttleGui &S) override
static BoolSetting TracksFitVerticallyZoomed
Definition: TracksPrefs.h:30
static WaveChannelViewConstants::Display ViewModeChoice()
static void SetPinnedHeadPositionPreference(double value, bool flush=false)
void Populate()
static int iPreferencePinned
Definition: TracksPrefs.h:56
bool Commit() override
ComponentInterfaceSymbol GetSymbol() const override
void Migrate(wxString &value) override
Holds a msgid for the translation catalog; may also bind format arguments.
Maintain a non-persistent list of states of the project, to support undo and redo commands.
Definition: UndoManager.h:155
void ZoomFitVertically()
Definition: Viewport.cpp:695
static Viewport & Get(AudacityProject &project)
Definition: Viewport.cpp:33
static wxString GetDefaultAudioTrackNamePreference()
Definition: WaveTrack.cpp:375
virtual bool Flush() noexcept=0
double ReadDouble(const wxString &key, double defaultValue) const
virtual bool Write(const wxString &key, bool value)=0
bool ReadBool(const wxString &key, bool defaultValue) const
virtual bool Read(const wxString &key, bool *value) const =0
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:196
Display ConvertLegacyDisplayValue(int oldValue)
@ MultiView
"Multi" is special, not really a view type on par with the others.
AUDACITY_DLL_API const EnumValueSymbol MultiViewSymbol
String identifier for a preference for one of each type of view.
const wxChar * PinnedHeadPositionPreferenceKey()
Definition: TracksPrefs.cpp:50
static const AudacityProject::AttachedObjects::RegisteredFactory key
PrefsPanel::Registration sAttachment
A convenient default parameter for class template Site.
Definition: ClientData.h:29
Type of message published by UndoManager.
Definition: UndoManager.h:55
static const std::vector< WaveChannelSubViewType > & All()
Discover all registered types.
Observer attached to each project applies the vertical zoom fit preference.
const Observer::Subscription mUndoSubscription
Handler & operator=(const Handler &)=delete