Audacity  2.2.2
PrefsDialog.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  PrefsDialog.cpp
6 
7  Joshua Haberman
8  James Crook
9 
10 *******************************************************************//*******************************************************************/
16 
17 #include "../Audacity.h"
18 #include "PrefsDialog.h"
19 
20 #include <wx/defs.h>
21 #include <wx/button.h>
22 #include <wx/dialog.h>
23 #include <wx/event.h>
24 #include <wx/font.h>
25 #include <wx/gdicmn.h>
26 #include <wx/intl.h>
27 #include <wx/listbox.h>
28 #include <wx/sizer.h>
29 
30 #include <wx/listbook.h>
31 
32 #include <wx/treebook.h>
33 
34 #include "../AudioIO.h"
35 #include "../Experimental.h"
36 #include "../Project.h"
37 #include "../Prefs.h"
38 #include "../ShuttleGui.h"
39 
40 #include "PrefsPanel.h"
41 
42 #include "BatchPrefs.h"
43 #include "DevicePrefs.h"
44 #include "DirectoriesPrefs.h"
45 #include "EffectsPrefs.h"
46 #include "GUIPrefs.h"
47 #include "ImportExportPrefs.h"
48 #include "KeyConfigPrefs.h"
49 #include "LibraryPrefs.h"
50 #include "MousePrefs.h"
51 #ifdef EXPERIMENTAL_MODULE_PREFS
52 #include "ModulePrefs.h"
53 #endif
54 #include "PlaybackPrefs.h"
55 #include "ProjectsPrefs.h"
56 #include "QualityPrefs.h"
57 #include "RecordingPrefs.h"
58 #include "SpectrumPrefs.h"
59 #include "ThemePrefs.h"
60 #include "TracksPrefs.h"
61 #include "TracksBehaviorsPrefs.h"
62 #include "WarningsPrefs.h"
63 // #include "WaveformPrefs.h"
64 #include "WaveformSettings.h"
65 #include "ExtImportPrefs.h"
66 
67 #ifdef EXPERIMENTAL_MIDI_OUT
68 #include "MidiIOPrefs.h"
69 #endif
70 
71 #include "../Theme.h"
72 #include "../widgets/HelpSystem.h"
73 
74 #if wxUSE_ACCESSIBILITY
75 #include "../widgets/WindowAccessible.h"
76 #endif
77 
78 BEGIN_EVENT_TABLE(PrefsDialog, wxDialogWrapper)
79  EVT_BUTTON(wxID_OK, PrefsDialog::OnOK)
80  EVT_BUTTON(wxID_CANCEL, PrefsDialog::OnCancel)
81  EVT_BUTTON(wxID_PREVIEW, PrefsDialog::OnPreview)
82  EVT_BUTTON(wxID_HELP, PrefsDialog::OnHelp)
83  EVT_TREE_KEY_DOWN(wxID_ANY, PrefsDialog::OnTreeKeyDown) // Handles key events when tree has focus
85 
86 
87 class wxTreebookExt final : public wxTreebook
88 {
89 public:
90  wxTreebookExt( wxWindow *parent,
91  wxWindowID id, const wxString &titlePrefix)
92  : wxTreebook( parent, id )
93  , mTitlePrefix(titlePrefix)
94  {;};
96  int ChangeSelection(size_t n) override;
97  int SetSelection(size_t n) override;
98  const wxString mTitlePrefix;
99 };
100 
101 
103  int i = wxTreebook::ChangeSelection(n);
104  wxString Temp = GetPageText( n );
105  static_cast<wxDialog*>(GetParent())->SetTitle( Temp );
106  static_cast<wxDialog*>(GetParent())->SetName( Temp );
107  return i;
108 };
109 
111 {
112  int i = wxTreebook::SetSelection(n);
113  wxString Temp = wxString(mTitlePrefix) + GetPageText( n );
114  static_cast<wxDialog*>(GetParent())->SetTitle( Temp );
115  static_cast<wxDialog*>(GetParent())->SetName( Temp );
116 
117  PrefsPanel *const panel = static_cast<PrefsPanel *>(GetPage(n));
118  const bool showHelp = (panel->HelpPageName() != wxEmptyString);
119  const bool showPreview = panel->ShowsPreviewButton();
120  wxWindow *const helpButton = wxWindow::FindWindowById(wxID_HELP, GetParent());
121  wxWindow *const previewButton = wxWindow::FindWindowById(wxID_PREVIEW, GetParent());
122 
123  if (helpButton) {
124  if (showHelp) {
125  wxAcceleratorEntry entries[1];
126 #if defined(__WXMAC__)
127  // Is there a standard shortcut on Mac?
128 #else
129  entries[0].Set(wxACCEL_NORMAL, (int) WXK_F1, wxID_HELP);
130 #endif
131  wxAcceleratorTable accel(1, entries);
132  this->SetAcceleratorTable(accel);
133  }
134  else {
135  this->SetAcceleratorTable(wxNullAcceleratorTable);
136  }
137 
138  const bool changed = helpButton->Show(showHelp);
139  if (changed)
140  GetParent()->Layout();
141  }
142 
143  if (previewButton) { // might still be NULL during population
144  const bool changed = previewButton->Show(showPreview);
145  if (changed)
146  GetParent()->Layout();
147  }
148 
149  return i;
150 }
151 
152 
153 
156 {
157  // To do, perhaps: create this table by registration, without including each PrefsPanel
158  // class... and thus allowing a plug-in protocol
159  static DevicePrefsFactory devicePrefsFactory;
160  static PlaybackPrefsFactory playbackPrefsFactory;
161  static RecordingPrefsFactory recordingPrefsFactory;
162 #ifdef EXPERIMENTAL_MIDI_OUT
163  static MidiIOPrefsFactory midiIOPrefsFactory;
164 #endif
165  static QualityPrefsFactory qualityPrefsFactory;
166  static GUIPrefsFactory guiPrefsFactory;
167  static TracksPrefsFactory tracksPrefsFactory;
168  static ImportExportPrefsFactory importExportPrefsFactory;
169  static ExtImportPrefsFactory extImportPrefsFactory;
170  static ProjectsPrefsFactory projectsPrefsFactory;
171 #if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || !defined(DISABLE_DYNAMIC_LOADING_LAME)
172  static LibraryPrefsFactory libraryPrefsFactory;
173 #endif
174  // static WaveformPrefsFactory waveformPrefsFactory;
175  static TracksBehaviorsPrefsFactory tracksBehaviorsPrefsFactory;
176  static SpectrumPrefsFactory spectrumPrefsFactory;
177  static DirectoriesPrefsFactory directoriesPrefsFactory;
178  static WarningsPrefsFactory warningsPrefsFactory;
179  static EffectsPrefsFactory effectsPrefsFactory;
180 #ifdef EXPERIMENTAL_THEME_PREFS
181  static ThemePrefsFactory themePrefsFactory;
182 #endif
183  // static BatchPrefsFactory batchPrefsFactory;
184  static KeyConfigPrefsFactory keyConfigPrefsFactory;
185  static MousePrefsFactory mousePrefsFactory;
186 #ifdef EXPERIMENTAL_MODULE_PREFS
187  static ModulePrefsFactory modulePrefsFactory;
188 #endif
189 
190  static PrefsNode nodes[] = {
191  &devicePrefsFactory,
192  &playbackPrefsFactory,
193  &recordingPrefsFactory,
194 #ifdef EXPERIMENTAL_MIDI_OUT
195  &midiIOPrefsFactory,
196 #endif
197  &qualityPrefsFactory,
198  &guiPrefsFactory,
199 
200  // Group other page(s)
201  PrefsNode(&tracksPrefsFactory, 2),
202  // &waveformPrefsFactory,
203  &tracksBehaviorsPrefsFactory,
204  &spectrumPrefsFactory,
205 
206  // Group one other page
207  PrefsNode(&importExportPrefsFactory, 1),
208  &extImportPrefsFactory,
209 
210  &projectsPrefsFactory,
211 #if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || !defined(DISABLE_DYNAMIC_LOADING_LAME)
212  &libraryPrefsFactory,
213 #endif
214  &directoriesPrefsFactory,
215  &warningsPrefsFactory,
216  &effectsPrefsFactory,
217 #ifdef EXPERIMENTAL_THEME_PREFS
218  &themePrefsFactory,
219 #endif
220  // &batchPrefsFactory,
221  &keyConfigPrefsFactory,
222  &mousePrefsFactory,
223 #ifdef EXPERIMENTAL_MODULE_PREFS
224  &modulePrefsFactory,
225 #endif
226  };
227 
228  static Factories factories(nodes, nodes + sizeof(nodes) / sizeof(nodes[0]));
229  return factories;
230 }
231 
232 
234  (wxWindow * parent, const wxString &titlePrefix, Factories &factories)
235 : wxDialogWrapper(parent, wxID_ANY, wxString(_("Audacity Preferences")),
236  wxDefaultPosition,
237  wxDefaultSize,
238  wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
239 , mFactories(factories)
240 , mTitlePrefix(titlePrefix)
241 {
242  wxASSERT(factories.size() > 0);
243  const bool uniquePage = (factories.size() == 1);
244 
245  ShuttleGui S(this, eIsCreating);
246 
247  S.StartVerticalLay(true);
248  {
249  wxASSERT(factories.size() > 0);
250  if (!uniquePage) {
251  mCategories = safenew wxTreebookExt(this, wxID_ANY, mTitlePrefix);
252 #if wxUSE_ACCESSIBILITY
253  // so that name can be set on a standard control
254  mCategories->GetTreeCtrl()->SetAccessible(safenew WindowAccessible(mCategories->GetTreeCtrl()));
255 #endif
256  // RJH: Prevent NVDA from reading "treeCtrl"
257  mCategories->GetTreeCtrl()->SetName(_("Category"));
258  S.StartHorizontalLay(wxALIGN_LEFT | wxEXPAND, true);
259  {
260  S.Prop(1);
261  S.AddWindow(mCategories, wxEXPAND);
262 
263  {
264  typedef std::pair<int, int> IntPair;
265  std::vector<IntPair> stack;
266  int iPage = 0;
267  for (Factories::const_iterator it = factories.begin(), end = factories.end();
268  it != end; ++it, ++iPage)
269  {
270  const PrefsNode &node = *it;
271  PrefsPanelFactory &factory = *node.pFactory;
272  wxWindow *const w = factory(mCategories, wxID_ANY);
273  if (stack.empty())
274  // Parameters are: AddPage(page, name, IsSelected, imageId).
275  mCategories->AddPage(w, w->GetName(), false, 0);
276  else {
277  IntPair &top = *stack.rbegin();
278  mCategories->InsertSubPage(top.first, w, w->GetName(), false, 0);
279  if (--top.second == 0) {
280  // Expand all nodes before the layout calculation
281  mCategories->ExpandNode(top.first, true);
282  stack.pop_back();
283  }
284  }
285  if (node.nChildren > 0)
286  stack.push_back(IntPair(iPage, node.nChildren));
287  }
288  }
289  }
290  S.EndHorizontalLay();
291  }
292  else {
293  // TODO: Look into getting rid of mUniquePage and instead
294  // adding into mCategories, so there is just one page in mCategories.
295  // And then hiding the treebook.
296 
297  // Unique page, don't show the factory
298  const PrefsNode &node = factories[0];
299  PrefsPanelFactory &factory = *node.pFactory;
300  mUniquePage = factory(this, wxID_ANY);
301  wxWindow * uniquePageWindow = S.Prop(1).AddWindow(mUniquePage, wxEXPAND);
302  // We're not in the wxTreebook, so add the accelerator here
303  wxAcceleratorEntry entries[1];
304 #if defined(__WXMAC__)
305  // Is there a standard shortcut on Mac?
306 #else
307  entries[0].Set(wxACCEL_NORMAL, (int) WXK_F1, wxID_HELP);
308 #endif
309  wxAcceleratorTable accel(1, entries);
310  uniquePageWindow->SetAcceleratorTable(accel);
311  }
312  }
313  S.EndVerticalLay();
314 
316  static_cast<wxButton*>(wxWindow::FindWindowById(wxID_OK, this))->SetDefault();
317 
318  if (mUniquePage && !mUniquePage->ShowsPreviewButton()) {
319  wxWindow *const previewButton =
320  wxWindow::FindWindowById(wxID_PREVIEW, GetParent());
321  previewButton->Show(false);
322  }
323 
324 #if defined(__WXGTK__)
325  if (mCategories)
326  mCategories->GetTreeCtrl()->EnsureVisible(mCategories->GetTreeCtrl()->GetRootItem());
327 #endif
328 
329 // mCategories->SetSizeHints(-1, -1, 790, 600); // 790 = 800 - (border * 2)
330  Layout();
331  Fit();
332  wxSize sz = GetSize();
333 
334  // Collapse nodes only after layout so the tree is wide enough
335  if (mCategories)
336  {
337  int iPage = 0;
338  for (Factories::const_iterator it = factories.begin(), end = factories.end();
339  it != end; ++it, ++iPage)
340  mCategories->ExpandNode(iPage, it->expanded);
341  }
342 
343  // This ASSERT was originally used to limit us to 800 x 600.
344  // However, the range of screen sizes and dpi of modern (2018) displays
345  // makes pixel dimensions an inadequate measure of usability, so
346  // now we only ASSERT that preferences will fit in the client display
347  // rectangle of the developer / tester's monitor.
348  // Use scrollers when necessary to ensure that preference pages will
349  // be fully visible.
350  wxRect screenRect(wxGetClientDisplayRect());
351  wxASSERT_MSG(sz.x <= screenRect.width && sz.y <= screenRect.height, wxT("Preferences dialog exceeds max size"));
352 
353  sz.DecTo(screenRect.GetSize());
354 
355  if( !mUniquePage ){
356  int prefWidth, prefHeight;
357  gPrefs->Read(wxT("/Prefs/Width"), &prefWidth, sz.x);
358  gPrefs->Read(wxT("/Prefs/Height"), &prefHeight, wxMax(480,sz.y));
359 
360  wxSize prefSize = wxSize(prefWidth, prefHeight);
361  prefSize.DecTo(screenRect.GetSize());
362  SetSize(prefSize);
363  InvalidateBestSize();
364  Layout();
365  }
366  SetMinSize(sz);
367 
368  // Center after all that resizing, but make sure it doesn't end up
369  // off-screen
370  CentreOnParent();
371 }
372 
374 {
375 }
376 
378 {
379  if (mCategories) {
380  /* long is signed, size_t is unsigned. On some platforms they are different
381  * lengths as well. So we must check that the stored category is both > 0
382  * and within the possible range of categories, making the first check on the
383  * _signed_ value to avoid issues when converting an unsigned one.
384  */
385  long selected = GetPreferredPage();
386  if (selected < 0 || size_t(selected) >= mCategories->GetPageCount())
387  selected = 0; // clamp to available range of tabs
388  mCategories->SetSelection(selected);
389  }
390  else {
391  wxString Temp = mTitlePrefix + mUniquePage->GetLabel();
392  SetTitle(Temp);
393  SetName(Temp);
394  }
395 
396  return wxDialogWrapper::ShowModal();
397 }
398 
399 void PrefsDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
400 {
402 
403  if (mCategories) {
404  for (size_t i = 0; i < mCategories->GetPageCount(); i++) {
405  ((PrefsPanel *)mCategories->GetPage(i))->Cancel();
406  }
407  }
408  else
409  mUniquePage->Cancel();
410 
411  // Remember modified dialog size, even if cancelling.
412  if( !mUniquePage ){
413  wxSize sz = GetSize();
414  gPrefs->Write(wxT("/Prefs/Width"), sz.x);
415  gPrefs->Write(wxT("/Prefs/Height"), sz.y);
416  }
417  gPrefs->Flush();
418 
419  EndModal(false);
420 }
421 
423 {
424  if( mCategories)
425  return static_cast<PrefsPanel*>(mCategories->GetCurrentPage());
426  else
427  {
428  wxASSERT( mUniquePage );
429  return mUniquePage;
430  }
431 }
432 
433 void PrefsDialog::OnPreview(wxCommandEvent & WXUNUSED(event))
434 {
436 }
437 
438 void PrefsDialog::OnHelp(wxCommandEvent & WXUNUSED(event))
439 {
440  wxString page = GetCurrentPanel()->HelpPageName();
441  // Currently (May2017) Spectrum Settings is the only preferences
442  // we ever display in a dialog on its own without others.
443  // We do so when it is configuring spectrums for a track.
444  // Because this happens, we want to visit a different help page.
445  // So we change the page name in the case of a page on its own.
446  if( !mCategories)
447  page.Replace( "Spectrograms_Preferences", "Spectrogram_Settings" );
448  HelpSystem::ShowHelp(this, page, true);
449 }
450 
452 {
453  // Validate all pages first
454  if (mCategories) {
455  for (size_t i = 0; i < mCategories->GetPageCount(); i++) {
456  S.ResetId();
457  PrefsPanel *panel = (PrefsPanel *)mCategories->GetPage(i);
458  panel->PopulateOrExchange( S );
459  }
460  }
461  else
462  {
463  S.ResetId();
465  }
466 }
467 
468 void PrefsDialog::OnTreeKeyDown(wxTreeEvent & event)
469 {
470  if(event.GetKeyCode() == WXK_RETURN)
471  OnOK(event);
472  else
473  event.Skip(); // Ensure standard behavior when enter is not pressed
474 }
475 
476 void PrefsDialog::OnOK(wxCommandEvent & WXUNUSED(event))
477 {
479 
480  // Validate all pages first
481  if (mCategories) {
482  for (size_t i = 0; i < mCategories->GetPageCount(); i++) {
483  PrefsPanel *panel = (PrefsPanel *)mCategories->GetPage(i);
484 
485  // The dialog doesn't end until all the input is valid
486  if (!panel->Validate()) {
487  mCategories->SetSelection(i);
488  return;
489  }
490  }
491  }
492  else {
493  if (!mUniquePage->Validate())
494  return;
495  }
496 
497  // flush now so toolbars will know their position.
498  gPrefs->Flush();
499  if (mCategories) {
500  // Now apply the changes
501  // Reverse order - so Track Name is updated before language change
502  // A workaround for Bug 1661
503  for (int i = (int)mCategories->GetPageCount()-1; i>= 0; i--) {
504  PrefsPanel *panel = (PrefsPanel *)mCategories->GetPage(i);
505 
506  panel->Preview();
507  panel->Commit();
508  }
509  }
510  else {
511  mUniquePage->Preview();
512  mUniquePage->Commit();
513  }
514 
515  if( !mUniquePage ){
516  wxSize sz = GetSize();
517  gPrefs->Write(wxT("/Prefs/Width"), sz.x);
518  gPrefs->Write(wxT("/Prefs/Height"), sz.y);
519  }
520  gPrefs->Flush();
521 
522  // Reads preference /GUI/Theme
525 
527 
528 #if USE_PORTMIXER
529  if (gAudioIO) {
530  // We cannot have opened this dialog if gAudioIO->IsAudioTokenActive(),
531  // per the setting of AudioIONotBusyFlag and AudioIOBusyFlag in
532  // AudacityProject::GetUpdateFlags().
533  // However, we can have an invalid audio token (so IsAudioTokenActive()
534  // is false), but be monitoring.
535  // If monitoring, have to stop the stream, so HandleDeviceChange() can work.
536  // We could disable the Preferences command while monitoring, i.e.,
537  // set AudioIONotBusyFlag/AudioIOBusyFlag according to monitoring, as well.
538  // Instead allow it because unlike recording, for example, monitoring
539  // is not clearly something that should prohibit opening prefs.
540  // TODO: We *could* be smarter in this method and call HandleDeviceChange()
541  // only when the device choices actually changed. True of lots of prefs!
542  // As is, we always stop monitoring before handling the device change.
543  if (gAudioIO->IsMonitoring())
544  {
545  gAudioIO->StopStream();
546  while (gAudioIO->IsBusy())
547  wxMilliSleep(100);
548  }
550  }
551 #endif
552 
553  // LL: wxMac can't handle recreating the menus when this dialog is still active,
554  // so AudacityProject::UpdatePrefs() or any of the routines it calls must
555  // not cause AudacityProject::RebuildMenuBar() to be executed.
556  for (size_t i = 0; i < gAudacityProjects.size(); i++) {
557  gAudacityProjects[i]->UpdatePrefs();
558  }
559 
562 
563  if( IsModal() )
564  EndModal(true);
565  else
566  Destroy();
567 }
568 
569 void PrefsDialog::SelectPageByName(const wxString &pageName)
570 {
571  if (mCategories) {
572  size_t n = mCategories->GetPageCount();
573 
574  for (size_t i = 0; i < n; i++) {
575  if (mCategories->GetPageText(i) == pageName) {
576  mCategories->SetSelection(i);
577  return;
578  }
579  }
580  }
581 }
582 
584 {
585  if (mCategories)
586  return mCategories->GetSelection();
587  else
588  return 0;
589 }
590 
591 GlobalPrefsDialog::GlobalPrefsDialog(wxWindow * parent, Factories &factories)
592  : PrefsDialog(parent, _("Preferences: "), factories)
593 {
594 }
595 
597 {
598 }
599 
601 {
602  long prefscat = gPrefs->Read(wxT("/Prefs/PrefsCategory"), 0L);
603  return prefscat;
604 }
605 
607 {
608  gPrefs->Write(wxT("/Prefs/PrefsCategory"), (long)GetSelectedPage());
609  gPrefs->Flush();
610 }
611 
613 {
614  // Remember expansion state of the tree control
615  if (mCategories)
616  {
617  int iPage = 0;
618  for (Factories::iterator it = mFactories.begin(), end = mFactories.end();
619  it != end; ++it, ++iPage)
620  it->expanded = mCategories->IsNodeExpanded(iPage);
621  }
622  else
623  mFactories[0].expanded = true;
624 }
625 
627 {
628 }
629 
631 {
632 }
633 
635 {
636  return false;
637 }
638 
640 {
641  return wxEmptyString;
642 }
~wxTreebookExt()
Definition: PrefsDialog.cpp:95
virtual void SavePreferredPage()=0
AudacityPrefs * gPrefs
Definition: Prefs.cpp:73
void StopStream()
Stop recording, playback or input monitoring.
Definition: AudioIO.cpp:2535
AUDACITY_DLL_API Theme theTheme
Definition: Theme.cpp:209
PrefsPanel * mUniquePage
Definition: PrefsDialog.h:86
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:409
wxWindow * AddWindow(wxWindow *pWindow, int Flags=wxALIGN_CENTRE|wxALL)
Definition: ShuttleGui.cpp:288
void ApplyUpdatedImages() override
Definition: Theme.cpp:250
AProjectArray gAudacityProjects
Definition: Project.cpp:303
void SavePreferredPage() override
virtual ~PrefsPanel()
void OnHelp(wxCommandEvent &e)
void OnTreeKeyDown(wxTreeEvent &e)
virtual ~GlobalPrefsDialog()
void SelectPageByName(const wxString &pageName)
virtual ~PrefsDialog()
Factories & mFactories
Definition: PrefsDialog.h:87
static Factories & DefaultFactories()
Dialog that shows the current PrefsPanel in a tabbed divider.
Definition: PrefsDialog.h:35
void RecordExpansionState()
static WaveformSettings & defaults()
bool IsBusy()
Returns true if audio i/o is busy starting, stopping, playing, or recording.
Definition: AudioIO.cpp:2910
int SetSelection(size_t n) override
wxTreebook * mCategories
Definition: PrefsDialog.h:85
PrefsPanel * GetCurrentPanel()
#define safenew
Definition: Audacity.h:230
virtual long GetPreferredPage()=0
virtual void PopulateOrExchange(ShuttleGui &WXUNUSED(S))
Definition: PrefsPanel.h:64
void EndHorizontalLay()
const wxString mTitlePrefix
Definition: PrefsDialog.cpp:98
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
void EndVerticalLay()
void ShuttleAll(ShuttleGui &S)
PrefsDialog(wxWindow *parent, const wxString &titlePrefix=_("Preferences: "), Factories &factories=DefaultFactories())
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
virtual bool Commit()=0
const wxString mTitlePrefix
Definition: PrefsDialog.h:88
std::vector< PrefsNode > Factories
Definition: PrefsDialog.h:50
void OnCancel(wxCommandEvent &e)
void HandleDeviceChange()
update state after changing what audio devices are selected
Definition: AudioIO.cpp:1426
long GetPreferredPage() override
static void ShowHelp(wxWindow *parent, const wxString &localFileName, const wxString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:194
virtual bool ShowsPreviewButton()
A wxTreebook is a class like wxNotebook, but not yet supported by wxWidgets 2.6.3.
EVT_TREE_KEY_DOWN(wxID_ANY, PrefsDialog::OnTreeKeyDown) class wxTreebookExt final
Definition: PrefsDialog.cpp:83
void OnPreview(wxCommandEvent &e)
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
GlobalPrefsDialog(wxWindow *parent, Factories &factories=DefaultFactories())
Used within the PrefsDialog, classes derived from this class include AudioIOPrefs, BatchPrefs, DirectoriesPrefs, FileFormatPrefs, GUIPrefs, KeyConfigPrefs, MousePrefs, QualityPrefs, SpectrumPrefs and ThemePrefs.
Definition: PrefsPanel.h:45
PrefsPanelFactory *CONST pFactory
Definition: PrefsDialog.h:40
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
void OnOK(wxCommandEvent &e)
AudioIO * gAudioIO
Definition: AudioIO.cpp:482
int ShowModal() override
virtual wxString HelpPageName()
bool IsMonitoring()
Returns true if we're monitoring input (but not recording or playing actual audio) ...
Definition: AudioIO.cpp:2942
int GetSelectedPage() const
int ChangeSelection(size_t n) override
ShuttleGui & Prop(int iProp)
Definition: ShuttleGui.h:418
static bool LoadPreferredTheme()
Definition: Theme.cpp:237
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxButton *extra=NULL)
virtual void Preview()
Definition: PrefsPanel.h:58
END_EVENT_TABLE()
virtual void Cancel()
static SpectrogramSettings & defaults()
void StartVerticalLay(int iProp=1)