Audacity  2.2.2
KeyConfigPrefs.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  KeyConfigPrefs.cpp
6 
7  Brian Gunlogson
8  Dominic Mazzoni
9  James Crook
10 
11 *******************************************************************//*********************************************************************/
21 
22 #include "../Audacity.h"
23 #include "../Experimental.h"
24 #include "KeyConfigPrefs.h"
25 
26 #include <wx/defs.h>
27 #include <wx/ffile.h>
28 #include <wx/intl.h>
29 #include <wx/filedlg.h>
30 #include <wx/button.h>
31 
32 #include "../Prefs.h"
33 #include "../Project.h"
34 #include "../commands/CommandManager.h"
35 #include "../commands/Keyboard.h"
36 #include "../xml/XMLFileReader.h"
37 
38 #include "../Internat.h"
39 #include "../ShuttleGui.h"
40 
41 #include "../FileNames.h"
42 
43 #include "../widgets/KeyView.h"
44 #include "../widgets/ErrorDialog.h"
45 
46 #if wxUSE_ACCESSIBILITY
47 #include "../widgets/WindowAccessible.h"
48 #endif
49 
50 //
51 // KeyConfigPrefs
52 //
53 #define AssignDefaultsButtonID 17001
54 #define CurrentComboID 17002
55 #define SetButtonID 17003
56 #define ClearButtonID 17004
57 #define CommandsListID 17005
58 #define ExportButtonID 17006
59 #define ImportButtonID 17007
60 #define FilterID 17008
61 #define ViewByTreeID 17009
62 #define ViewByNameID 17010
63 #define ViewByKeyID 17011
64 #define FilterTimerID 17012
65 
66 BEGIN_EVENT_TABLE(KeyConfigPrefs, PrefsPanel)
72  EVT_LISTBOX(CommandsListID, KeyConfigPrefs::OnSelected)
73  EVT_RADIOBUTTON(ViewByTreeID, KeyConfigPrefs::OnViewBy)
74  EVT_RADIOBUTTON(ViewByNameID, KeyConfigPrefs::OnViewBy)
75  EVT_RADIOBUTTON(ViewByKeyID, KeyConfigPrefs::OnViewBy)
76  EVT_TIMER(FilterTimerID, KeyConfigPrefs::OnFilterTimer)
78 
79 KeyConfigPrefs::KeyConfigPrefs(wxWindow * parent, wxWindowID winid,
80  const wxString &name)
81 /* i18n-hint: as in computer keyboard (not musical!) */
82 : PrefsPanel(parent, winid, _("Keyboard")),
83  mView(NULL),
84  mKey(NULL),
85  mFilter(NULL),
86  mFilterTimer(this, FilterTimerID),
87  mFilterPending(false)
88 {
89  Populate();
90  if (!name.empty()) {
91  auto index = mView->GetIndexByName(name);
92  mView->SelectNode(index);
93  }
94 }
95 
97 {
99  AudacityProject *project = GetActiveProject();
100 
101  if (!project) {
102  S.StartVerticalLay(true);
103  {
104  S.StartStatic( {}, true);
105  {
106  S.AddTitle(_("Keyboard preferences currently unavailable."));
107  S.AddTitle(_("Open a new project to modify keyboard shortcuts."));
108  }
109  S.EndStatic();
110  }
111  S.EndVerticalLay();
112 
113  return;
114  }
115 
117 
118  mCommandSelected = wxNOT_FOUND;
119 
120  mManager = project->GetCommandManager();
121 
122  // For speed, don't sort here. We're just creating.
123  // Instead sort when we do SetView later in this function.
124  RefreshBindings(false);
125 
126  if (mViewByTree->GetValue()) {
128  }
129  else if (mViewByName->GetValue()) {
131  }
132  else if (mViewByKey->GetValue()) {
134  mFilterLabel->SetLabel(_("&Hotkey:"));
135  mFilter->SetName(wxStripMenuCodes(mFilterLabel->GetLabel()));
136  }
137 
139 }
140 
146 {
147  S.SetBorder(2);
148 
149  S.StartStatic(_("Key Bindings"), 1);
150  {
151  S.StartMultiColumn(3, wxEXPAND);
152  {
153  S.SetStretchyCol(1);
154 
155  S.StartHorizontalLay(wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
156  {
157  S.AddTitle(_("View by:"));
158  S.StartRadioButtonGroup(wxT("/Prefs/KeyConfig/ViewBy"), wxT("tree"));
159  {
160  mViewByTree = S.Id(ViewByTreeID).TieRadioButton(_("&Tree"), wxT("tree"));
161  if( mViewByTree ) mViewByTree->SetName(_("View by tree"));
162  mViewByName = S.Id(ViewByNameID).TieRadioButton(_("&Name"), wxT("name"));
163  if( mViewByName ) mViewByName->SetName(_("View by name"));
164  mViewByKey = S.Id(ViewByKeyID).TieRadioButton(_("&Key"), wxT("key"));
165  if( mViewByKey ) mViewByKey->SetName(_("View by key"));
166 #if wxUSE_ACCESSIBILITY
167  // so that name can be set on a standard control
171 #endif
172  }
174  }
175  S.EndHorizontalLay();
176 
177  S.StartHorizontalLay(wxALIGN_CENTER|wxALIGN_CENTER_VERTICAL, 0);
178  {
179  // just a spacer
180  }
181  S.EndHorizontalLay();
182 
183  S.StartHorizontalLay(wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 0);
184  {
185  mFilterLabel = S.AddVariableText(_("Searc&h:"));
186 
187  if (!mFilter) {
188  mFilter = safenew wxTextCtrl(this,
189  FilterID,
190  wxT(""),
191  wxDefaultPosition,
192 #if defined(__WXMAC__)
193  wxSize(300, -1),
194 #else
195  wxSize(210, -1),
196 #endif
197  wxTE_PROCESS_ENTER);
198  mFilter->SetName(wxStripMenuCodes(mFilterLabel->GetLabel()));
199  mFilter->Bind(wxEVT_KEY_DOWN,
201  this);
202  mFilter->Bind(wxEVT_CHAR,
204  this);
205  }
206  S.AddWindow(mFilter, wxALIGN_NOT | wxALIGN_LEFT);
207  }
208  S.EndHorizontalLay();
209  }
210  S.EndThreeColumn();
211  S.AddSpace(-1, 2);
212 
213  S.StartHorizontalLay(wxEXPAND, 1);
214  {
215  if (!mView) {
217  mView->SetName(_("Bindings"));
218  }
219  S.Prop(true);
220  S.AddWindow(mView, wxEXPAND);
221  }
222  S.EndHorizontalLay();
223 
224  S.StartThreeColumn();
225  {
226  if (!mKey) {
227  mKey = safenew wxTextCtrl(this,
229  wxT(""),
230  wxDefaultPosition,
231 #if defined(__WXMAC__)
232  wxSize(300, -1),
233 #else
234  wxSize(210, -1),
235 #endif
236  wxTE_PROCESS_ENTER);
237 #if wxUSE_ACCESSIBILITY
238  // so that name can be set on a standard control
239  mKey->SetAccessible(safenew WindowAccessible(mKey));
240 #endif
241  mKey->SetName(_("Short cut"));
242  mKey->Bind(wxEVT_KEY_DOWN,
244  this);
245  mKey->Bind(wxEVT_CHAR,
247  this);
248  mKey->Bind(wxEVT_KILL_FOCUS,
250  this);
251  }
252  S.AddWindow(mKey);
253 
254  /* i18n-hint: (verb)*/
255  mSet = S.Id(SetButtonID).AddButton(_("&Set"));
256  mClear = S.Id(ClearButtonID).AddButton(_("Cl&ear"));
257  }
258  S.EndThreeColumn();
259 
260 #if defined(__WXMAC__)
261  S.AddFixedText(_("Note: Pressing Cmd+Q will quit. All other keys are valid."));
262 #endif
263 
264  S.StartThreeColumn();
265  {
266  S.Id(ImportButtonID).AddButton(_("&Import..."));
267  S.Id(ExportButtonID).AddButton(_("&Export..."));
268  S.Id(AssignDefaultsButtonID).AddButton(_("&Defaults"));
269  }
270  S.EndThreeColumn();
271  }
272  S.EndStatic();
273 
274 
275  // Need to layout so that the KeyView is properly sized before populating.
276  // Otherwise, the initial selection is not scrolled into view.
277  Layout();
278 }
279 
281 {
282  wxArrayString Labels;
283  wxArrayString Categories;
284  wxArrayString Prefixes;
285 
286  mNames.Clear();
287  mKeys.clear();
288  mDefaultKeys.clear();
289  mStandardDefaultKeys.clear();
291  mNames,
292  mKeys,
293  mDefaultKeys,
294  Labels,
295  Categories,
296  Prefixes,
297  true); // True to include effects (list items), false otherwise.
298 
301 
303  Categories,
304  Prefixes,
305  Labels,
306  mKeys,
307  bSort);
308  //Not needed as NEW nodes are already shown expanded.
309  //mView->ExpandAll();
310 
311  mNewKeys = mKeys;
312 }
313 
314 void KeyConfigPrefs::OnImport(wxCommandEvent & WXUNUSED(event))
315 {
316  wxString file = wxT("Audacity-keys.xml");
317 
319  _("Select an XML file containing Audacity keyboard shortcuts..."),
320  wxEmptyString,
321  file,
322  wxT(""),
323  _("XML files (*.xml)|*.xml|All files|*"),
324  wxRESIZE_BORDER,
325  this);
326 
327  if (!file) {
328  return;
329  }
330 
331  XMLFileReader reader;
332  if (!reader.Parse(mManager, file)) {
334  _("Error Importing Keyboard Shortcuts"),
335  wxOK | wxCENTRE, this);
336  }
337 
338  RefreshBindings(true);
339 }
340 
341 void KeyConfigPrefs::OnExport(wxCommandEvent & WXUNUSED(event))
342 {
343  wxString file = wxT("Audacity-keys.xml");
344 
346  _("Export Keyboard Shortcuts As:"),
347  wxEmptyString,
348  file,
349  wxT("xml"),
350  _("XML files (*.xml)|*.xml|All files|*"),
351  wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
352  this);
353 
354  if (!file) {
355  return;
356  }
357 
358  GuardedCall( [&] {
359  XMLFileWriter prefFile{ file, _("Error Exporting Keyboard Shortcuts") };
360  mManager->WriteXML(prefFile);
361  prefFile.Commit();
362  } );
363 }
364 
365 
366 
367 // There currently is only one clickable AButton
368 // so we just do what it needs.
369 void KeyConfigPrefs::OnDefaults(wxCommandEvent & WXUNUSED(event))
370 {
371  wxMenu Menu;
372  Menu.Append( 1, _("Standard") );
373  Menu.Append( 2, _("Full") );
374  Menu.Bind( wxEVT_COMMAND_MENU_SELECTED, &KeyConfigPrefs::OnImportDefaults, this );
375  // Pop it up where the mouse is.
376  PopupMenu(&Menu);//, wxPoint(0, 0));
377 }
378 
379 void KeyConfigPrefs::FilterKeys( std::vector<NormalizedKeyString> & arr )
380 {
381  const auto &MaxListOnly = CommandManager::ExcludedList();
382 
383  // Remove items that are in MaxList.
384  for (size_t i = 0; i < arr.size(); i++) {
385  if( std::binary_search(MaxListOnly.begin(), MaxListOnly.end(), arr[i]) )
386  arr[i] = {};
387  }
388 }
389 
390 void KeyConfigPrefs::OnImportDefaults(wxCommandEvent & event)
391 {
392  gPrefs->DeleteEntry(wxT("/GUI/Shortcuts/FullDefaults"));
393  gPrefs->Flush();
394 
396  if( event.GetId() == 1 )
397  FilterKeys( mNewKeys );
398 
399  for (size_t i = 0; i < mNewKeys.size(); i++) {
401  }
402 
403  RefreshBindings(true);
404 }
405 
407 {
408  wxTextCtrl *t = (wxTextCtrl *)e.GetEventObject();
409 
410  // Make sure we can navigate away from the hotkey textctrl.
411  // On Linux and OSX, it can get stuck, but it doesn't hurt
412  // to do it for Windows as well.
413  //
414  // Mac note: Don't waste time trying to figure out why the
415  // focus goes back to the prefs tree. Unless Voiceover is
416  // active, buttons on the Mac do not accept focus and all the
417  // controls between this one and the tree control are buttons.
418  if (e.GetKeyCode() == WXK_TAB) {
419  NavigateIn(e.ShiftDown()
420  ? wxNavigationKeyEvent::IsBackward
421  : wxNavigationKeyEvent::IsForward);
422  return;
423  }
424 
425  t->SetValue(KeyEventToKeyString(e).Display());
426 }
427 
428 void KeyConfigPrefs::OnHotkeyChar(wxKeyEvent & WXUNUSED(e))
429 {
430  // event.Skip() not performed, so event will not be processed further.
431 }
432 
433 void KeyConfigPrefs::OnHotkeyKillFocus(wxFocusEvent & e)
434 {
435  if (mKey->GetValue().IsEmpty() && mCommandSelected != wxNOT_FOUND) {
436  mKey->AppendText(mView->GetKey(mCommandSelected).Display());
437  }
438 
439  e.Skip();
440 }
441 
442 void KeyConfigPrefs::OnFilterTimer(wxTimerEvent & WXUNUSED(e))
443 {
444  // The filter timer has expired, so set the filter
445  if (mFilterPending)
446  {
447  // Do not reset mFilterPending here...possible race
448  mView->SetFilter(mFilter->GetValue());
449  }
450 }
451 
453 {
454  wxTextCtrl *t = (wxTextCtrl *)e.GetEventObject();
455  int keycode = e.GetKeyCode();
456 
457  // Make sure we can navigate away from the hotkey textctrl.
458  // On Linux and OSX, it an get stuck, but it doesn't hurt
459  // to do it for Windows as well.
460  if (keycode == WXK_TAB) {
461  wxNavigationKeyEvent nevent;
462  nevent.SetWindowChange(e.ControlDown());
463  nevent.SetDirection(!e.ShiftDown());
464  nevent.SetEventObject(t);
465  nevent.SetCurrentFocus(t);
466  t->GetParent()->GetEventHandler()->ProcessEvent(nevent);
467 
468  return;
469  }
470 
471  if (mViewType == ViewByKey) {
472  wxString key = KeyEventToKeyString(e).Display();
473  t->SetValue(key);
474 
475  if (key != wxEmptyString) {
476  mView->SetFilter(t->GetValue());
477  }
478  }
479  else
480  {
481  if (keycode == WXK_RETURN) {
482  mFilterPending = false;
483  mView->SetFilter(t->GetValue());
484  }
485  else {
486  mFilterPending = true;
487  mFilterTimer.Start(500, wxTIMER_ONE_SHOT);
488 
489  e.Skip();
490  }
491  }
492 }
493 
494 void KeyConfigPrefs::OnFilterChar(wxKeyEvent & e)
495 {
496  if (mViewType != ViewByKey)
497  {
498  e.Skip();
499  }
500 }
501 
502 // Given a hotkey combination, returns the name (description) of the
503 // corresponding command, or the empty string if none is found.
505 {
506  return mView->GetNameByKey(key);
507 }
508 
509 // Sets the selected command to have this key
510 // This is not yet a committed change, which will happen on a save.
512 {
513  wxString name = mView->GetName(mCommandSelected);
514 
516  {
517  AudacityMessageBox(_("You may not assign a key to this entry"),
518  _("Error"), wxICON_ERROR | wxCENTRE, this);
519  return;
520  }
521 
523  mManager->SetKeyFromName(name, key);
524  mNewKeys[mNames.Index(name)] = key;
525 }
526 
527 
528 void KeyConfigPrefs::OnSet(wxCommandEvent & WXUNUSED(event))
529 {
530  if (mCommandSelected == wxNOT_FOUND) {
531  AudacityMessageBox(_("You must select a binding before assigning a shortcut"),
532  _("Error"), wxICON_WARNING | wxCENTRE, this);
533  return;
534  }
535 
536  NormalizedKeyString key { mKey->GetValue() };
537  wxString oldname = mView->GetNameByKey(key);
538  wxString newname = mView->GetName(mCommandSelected);
539 
540  // Just ignore it if they are the same
541  if (oldname == newname) {
542  return;
543  }
544 
545  // Prevent same hotkey combination being used twice.
546  if (!oldname.empty()) {
547  auto oldlabel = wxString::Format( _("%s - %s"),
548  mManager->GetCategoryFromName(oldname),
550  auto newlabel = wxString::Format( _("%s - %s"),
551  mManager->GetCategoryFromName(newname),
553  if (AudacityMessageBox(
554  wxString::Format(
555  _("The keyboard shortcut '%s' is already assigned to:\n\n\t'%s'\n\nClick OK to assign the shortcut to\n\n\t'%s'\n\ninstead. Otherwise, click Cancel."),
556  mKey->GetValue(),
557  oldlabel,
558  newlabel),
559  _("Error"), wxOK | wxCANCEL | wxICON_STOP | wxCENTRE, this) == wxCANCEL)
560  {
561  return;
562  }
563 
564  mView->SetKeyByName(oldname, {});
565  mManager->SetKeyFromName(oldname, {});
566  mNewKeys[mNames.Index(oldname)] = {};
567 
568  }
569 
570  SetKeyForSelected(key);
571 }
572 
573 void KeyConfigPrefs::OnClear(wxCommandEvent& WXUNUSED(event))
574 {
575  mKey->Clear();
576 
577  if (mCommandSelected != wxNOT_FOUND) {
578  SetKeyForSelected({});
579  }
580 }
581 
582 void KeyConfigPrefs::OnSelected(wxCommandEvent & WXUNUSED(e))
583 {
585  mKey->Clear();
586 
587  if (mCommandSelected != wxNOT_FOUND) {
588  bool canset = mView->CanSetKey(mCommandSelected);
589  if (canset) {
590  mKey->AppendText(mView->GetKey(mCommandSelected).Display());
591  }
592 
593  mKey->Enable(canset);
594  mSet->Enable(canset);
595  mClear->Enable(canset);
596  }
597 }
598 
599 void KeyConfigPrefs::OnViewBy(wxCommandEvent & e)
600 {
601  switch (e.GetId())
602  {
603  case ViewByTreeID:
605  mFilterLabel->SetLabel(_("Searc&h:"));
606  break;
607 
608  case ViewByNameID:
610  mFilterLabel->SetLabel(_("Searc&h:"));
611  break;
612 
613  case ViewByKeyID:
615  mFilterLabel->SetLabel(_("&Hotkey:"));
616  break;
617  }
618 
620  mFilter->SetName(wxStripMenuCodes(mFilterLabel->GetLabel()));
621 }
622 
624 {
625  // On the Mac, preferences may be changed without any active
626  // projects. This means that the CommandManager isn't availabe
627  // either. So we can't attempt to save preferences, otherwise
628  // NULL ptr dereferences will happen in ShuttleGui because the
629  // radio buttons are never created. (See Populate() above.)
630  if (!GetActiveProject()) {
631  return true;
632  }
633 
634  ShuttleGui S(this, eIsSavingToPrefs);
636 
637  bool bFull = gPrefs->ReadBool(wxT("/GUI/Shortcuts/FullDefaults"), false);
638  for (size_t i = 0; i < mNames.GetCount(); i++) {
639  const auto &dkey = bFull ? mDefaultKeys[i] : mStandardDefaultKeys[i];
640  wxString name = wxT("/NewKeys/") + mNames[i];
641  const auto &key = mNewKeys[i];
642 
643  if (gPrefs->HasEntry(name)) {
644  if (key != NormalizedKeyString{ gPrefs->Read(name, key.Raw()) } ) {
645  gPrefs->Write(name, key.Raw());
646  }
647  if (key == dkey) {
648  gPrefs->DeleteEntry(name);
649  }
650  }
651  else {
652  if (key != dkey) {
653  gPrefs->Write(name, key.Raw());
654  }
655  }
656  }
657 
658  return gPrefs->Flush();
659 }
660 
662 {
663  // Restore original key values
664  for (size_t i = 0; i < mNames.GetCount(); i++) {
666  }
667 
668  return;
669 }
670 
672 {
673  return "Keyboard_Preferences";
674 }
675 
676 PrefsPanel *KeyConfigPrefsFactory::operator () (wxWindow *parent, wxWindowID winid)
677 {
678  wxASSERT(parent); // to justify safenew
679  auto result = safenew KeyConfigPrefs{ parent, winid, mName };
680  return result;
681 }
CommandManager * mManager
void OnExport(const wxString &Format)
wxRadioButton * mViewByKey
AudacityPrefs * gPrefs
Definition: Prefs.cpp:73
ViewByType mViewType
void EndThreeColumn()
Definition: ShuttleGui.h:139
#define FilterTimerID
wxString GetNameByKey(const NormalizedKeyString &key) const
Definition: KeyView.cpp:181
NormalizedKeyString GetKey(int index) const
Definition: KeyView.cpp:221
void OnDefaults(wxCommandEvent &e)
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:409
void EndRadioButtonGroup()
wxString HelpPageName() override
std::vector< NormalizedKeyString > mStandardDefaultKeys
wxWindow * AddWindow(wxWindow *pWindow, int Flags=wxALIGN_CENTRE|wxALL)
Definition: ShuttleGui.cpp:288
void OnViewBy(wxCommandEvent &e)
void RefreshBindings(const wxArrayString &names, const wxArrayString &categories, const wxArrayString &prefixes, const wxArrayString &labels, const std::vector< NormalizedKeyString > &keys, bool bSort)
Definition: KeyView.cpp:521
wxString GetName() const
Definition: KeyView.cpp:93
void FilterKeys(std::vector< NormalizedKeyString > &arr)
void WriteXML(XMLWriter &xmlFile) const
void OnSelected(wxCommandEvent &e)
void OnFilterTimer(wxTimerEvent &e)
NormalizedKeyString KeyEventToKeyString(const wxKeyEvent &event)
Definition: Keyboard.cpp:78
int GetSelected() const
Definition: KeyView.cpp:84
void OnImport(wxCommandEvent &e)
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
CommandManager * GetCommandManager()
Definition: Project.h:346
#define ViewByTreeID
wxStaticText * mFilterLabel
std::vector< NormalizedKeyString > mNewKeys
bool CanSetKey(int index) const
Definition: KeyView.cpp:237
#define safenew
Definition: Audacity.h:230
void GetAllCommandData(wxArrayString &names, std::vector< NormalizedKeyString > &keys, std::vector< NormalizedKeyString > &default_keys, wxArrayString &labels, wxArrayString &categories, wxArrayString &prefixes, bool includeMultis)
void EndHorizontalLay()
wxTextCtrl * mKey
void OnClear(wxCommandEvent &e)
void SetKeyFromIndex(int i, const NormalizedKeyString &key)
#define ImportButtonID
static const std::vector< NormalizedKeyString > & ExcludedList()
#define AssignDefaultsButtonID
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
void PopulateOrExchange(ShuttleGui &S) override
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:176
#define CurrentComboID
void EndVerticalLay()
void OnFilterKeyDown(wxKeyEvent &e)
bool Parse(XMLTagHandler *baseHandler, const wxString &fname)
wxString GetPrefixedLabelFromName(const wxString &name)
Reads a file and passes the results through an XMLTagHandler.
Definition: XMLFileReader.h:18
#define ViewByKeyID
bool Commit() override
Wrapper to output XML data to files.
Definition: XMLWriter.h:74
void SetView(ViewByType type)
Definition: KeyView.cpp:313
wxString GetCategoryFromName(const wxString &name)
wxRadioButton * mViewByTree
void OnImport(const CommandContext &context)
A PrefsPanel for keybindings.
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
wxTextCtrl * mFilter
ShuttleGui & Id(int id)
void SetFilter(const wxString &filter)
Definition: KeyView.cpp:364
void Cancel() override
void AddFixedText(const wxString &Str, bool bCenter=false)
Definition: ShuttleGui.cpp:397
wxButton * mClear
wxButton * mSet
R GuardedCall(const F1 &body, const F2 &handler=F2::Default(), const F3 &delayedHandler={})
void AddTitle(const wxString &Prompt)
Centred text string.
Definition: ShuttleGui.cpp:274
wxRadioButton * mViewByName
#define ClearButtonID
wxRadioButton * TieRadioButton(const wxString &Prompt, WrappedType &WrappedRef)
void StartThreeColumn()
Definition: ShuttleGui.h:138
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
void RefreshBindings(bool bSort)
#define ExportButtonID
wxArrayString mNames
KeyView * mView
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
void OnFilterChar(wxKeyEvent &e)
static wxString SelectFile(Operation op, const wxString &message, const wxString &default_path, const wxString &default_filename, const wxString &default_extension, const wxString &wildcard, int flags, wxWindow *parent)
Definition: FileNames.cpp:411
#define FilterID
_("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
bool SetKeyByName(const wxString &name, const NormalizedKeyString &key)
Definition: KeyView.cpp:295
#define ViewByNameID
wxString NameFromKey(const NormalizedKeyString &key)
#define CommandsListID
PrefsPanel * operator()(wxWindow *parent, wxWindowID winid) override
std::vector< NormalizedKeyString > mKeys
const wxChar * name
Definition: Distortion.cpp:94
void SetKeyForSelected(const NormalizedKeyString &key)
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:308
std::vector< NormalizedKeyString > mDefaultKeys
wxStaticText * AddVariableText(const wxString &Str, bool bCenter=false, int PositionFlags=0)
Definition: ShuttleGui.cpp:414
wxStaticBox * StartStatic(const wxString &Str, int iProp=0)
Definition: ShuttleGui.cpp:763
bool SetKey(int index, const NormalizedKeyString &key)
Definition: KeyView.cpp:254
ShuttleGui & Prop(int iProp)
Definition: ShuttleGui.h:418
void OnImportDefaults(wxCommandEvent &e)
void SetKeyFromName(const wxString &name, const NormalizedKeyString &key)
void OnHotkeyKeyDown(wxKeyEvent &e)
wxString GetErrorStr()
END_EVENT_TABLE()
wxSizerItem * AddSpace(int width, int height)
void OnHotkeyKillFocus(wxFocusEvent &e)
#define SetButtonID
void SetBorder(int Border)
Definition: ShuttleGui.h:286
void OnSet(wxCommandEvent &e)
wxString Display(bool usesSpecialChars=false) const
Definition: Keyboard.cpp:53
void StartRadioButtonGroup(const wxString &SettingName)
Provides multiple views of keyboard shortcuts.
Definition: KeyView.h:73
wxButton * AddButton(const wxString &Text, int PositionFlags=wxALIGN_CENTRE)
Definition: ShuttleGui.cpp:341
void OnExport(wxCommandEvent &e)
void SetStretchyCol(int i)
Used to modify an already placed FlexGridSizer to make a column stretchy.
Definition: ShuttleGui.cpp:203
void OnHotkeyChar(wxKeyEvent &e)
wxTimer mFilterTimer
void StartVerticalLay(int iProp=1)