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 //
47 // KeyConfigPrefs
48 //
49 #define AssignDefaultsButtonID 17001
50 #define CurrentComboID 17002
51 #define SetButtonID 17003
52 #define ClearButtonID 17004
53 #define CommandsListID 17005
54 #define ExportButtonID 17006
55 #define ImportButtonID 17007
56 #define FilterID 17008
57 #define ViewByTreeID 17009
58 #define ViewByNameID 17010
59 #define ViewByKeyID 17011
60 #define FilterTimerID 17012
61 
62 BEGIN_EVENT_TABLE(KeyConfigPrefs, PrefsPanel)
68  EVT_LISTBOX(CommandsListID, KeyConfigPrefs::OnSelected)
69  EVT_RADIOBUTTON(ViewByTreeID, KeyConfigPrefs::OnViewBy)
70  EVT_RADIOBUTTON(ViewByNameID, KeyConfigPrefs::OnViewBy)
71  EVT_RADIOBUTTON(ViewByKeyID, KeyConfigPrefs::OnViewBy)
72  EVT_TIMER(FilterTimerID, KeyConfigPrefs::OnFilterTimer)
74 
75 KeyConfigPrefs::KeyConfigPrefs(wxWindow * parent, const wxString &name)
76 /* i18n-hint: as in computer keyboard (not musical!) */
77 : PrefsPanel(parent, _("Keyboard")),
78  mView(NULL),
79  mKey(NULL),
80  mFilter(NULL),
81  mFilterTimer(this, FilterTimerID),
82  mFilterPending(false)
83 {
84  Populate();
85  if (!name.empty()) {
86  auto index = mView->GetIndexByName(name);
87  mView->SelectNode(index);
88  }
89 }
90 
92 {
93  if (mKey)
94  {
95  mKey->Disconnect(wxEVT_KEY_DOWN,
96  wxKeyEventHandler(KeyConfigPrefs::OnHotkeyKeyDown),
97  NULL,
98  this);
99  mKey->Disconnect(wxEVT_CHAR,
100  wxKeyEventHandler(KeyConfigPrefs::OnHotkeyChar),
101  NULL,
102  this);
103  mKey->Disconnect(wxEVT_KILL_FOCUS,
104  wxFocusEventHandler(KeyConfigPrefs::OnHotkeyKillFocus),
105  NULL,
106  this);
107  }
108 
109  if (mFilter)
110  {
111  mKey->Disconnect(wxEVT_KEY_DOWN,
112  wxKeyEventHandler(KeyConfigPrefs::OnFilterKeyDown),
113  NULL,
114  this);
115  mKey->Disconnect(wxEVT_CHAR,
116  wxKeyEventHandler(KeyConfigPrefs::OnFilterChar),
117  NULL,
118  this);
119  }
120 }
121 
123 {
125  AudacityProject *project = GetActiveProject();
126 
127  if (!project) {
128  S.StartVerticalLay(true);
129  {
130  S.StartStatic( {}, true);
131  {
132  S.AddTitle(_("Keyboard preferences currently unavailable."));
133  S.AddTitle(_("Open a new project to modify keyboard shortcuts."));
134  }
135  S.EndStatic();
136  }
137  S.EndVerticalLay();
138 
139  return;
140  }
141 
143 
144  mCommandSelected = wxNOT_FOUND;
145 
146  mManager = project->GetCommandManager();
147 
148  // For speed, don't sort here. We're just creating.
149  // Instead sort when we do SetView later in this function.
150  RefreshBindings(false);
151 
152  if (mViewByTree->GetValue()) {
154  }
155  else if (mViewByName->GetValue()) {
157  }
158  else if (mViewByKey->GetValue()) {
160  mFilterLabel->SetLabel(_("&Hotkey:"));
161  mFilter->SetName(wxStripMenuCodes(mFilterLabel->GetLabel()));
162  }
163 
165 }
166 
172 {
173  S.SetBorder(2);
174 
175  S.StartStatic(_("Key Bindings"), 1);
176  {
177  S.StartMultiColumn(3, wxEXPAND);
178  {
179  S.SetStretchyCol(1);
180 
181  S.StartHorizontalLay(wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
182  {
183  S.AddTitle(_("View by:"));
184  S.StartRadioButtonGroup(wxT("/Prefs/KeyConfig/ViewBy"), wxT("tree"));
185  {
186  mViewByTree = S.Id(ViewByTreeID).TieRadioButton(_("&Tree"), wxT("tree"));
187  mViewByTree->SetName(_("View by tree"));
188  mViewByName = S.Id(ViewByNameID).TieRadioButton(_("&Name"), wxT("name"));
189  mViewByName->SetName(_("View by name"));
190  mViewByKey = S.Id(ViewByKeyID).TieRadioButton(_("&Key"), wxT("key"));
191  mViewByKey->SetName(_("View by key"));
192  }
194  }
195  S.EndHorizontalLay();
196 
197  S.StartHorizontalLay(wxALIGN_CENTER|wxALIGN_CENTER_VERTICAL, 0);
198  {
199  // just a spacer
200  }
201  S.EndHorizontalLay();
202 
203  S.StartHorizontalLay(wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 0);
204  {
205  mFilterLabel = S.AddVariableText(_("Searc&h:"));
206 
207  if (!mFilter) {
208  mFilter = safenew wxTextCtrl(this,
209  FilterID,
210  wxT(""),
211  wxDefaultPosition,
212 #if defined(__WXMAC__)
213  wxSize(300, -1),
214 #else
215  wxSize(210, -1),
216 #endif
217  wxTE_PROCESS_ENTER);
218  mFilter->SetName(wxStripMenuCodes(mFilterLabel->GetLabel()));
219  mFilter->Connect(wxEVT_KEY_DOWN,
220  wxKeyEventHandler(KeyConfigPrefs::OnFilterKeyDown),
221  NULL,
222  this);
223  mFilter->Connect(wxEVT_CHAR,
224  wxKeyEventHandler(KeyConfigPrefs::OnFilterChar),
225  NULL,
226  this);
227  }
228  S.AddWindow(mFilter, wxALIGN_NOT | wxALIGN_LEFT);
229  }
230  S.EndHorizontalLay();
231  }
232  S.EndThreeColumn();
233  S.AddSpace(-1, 2);
234 
235  S.StartHorizontalLay(wxEXPAND, 1);
236  {
237  if (!mView) {
239  mView->SetName(_("Bindings"));
240  }
241  S.Prop(true);
242  S.AddWindow(mView, wxEXPAND);
243  }
244  S.EndHorizontalLay();
245 
246  S.StartThreeColumn();
247  {
248  if (!mKey) {
249  mKey = safenew wxTextCtrl(this,
251  wxT(""),
252  wxDefaultPosition,
253 #if defined(__WXMAC__)
254  wxSize(300, -1),
255 #else
256  wxSize(210, -1),
257 #endif
258  wxTE_PROCESS_ENTER);
259 
260  mKey->SetName(_("Short cut"));
261  mKey->Connect(wxEVT_KEY_DOWN,
262  wxKeyEventHandler(KeyConfigPrefs::OnHotkeyKeyDown),
263  NULL,
264  this);
265  mKey->Connect(wxEVT_CHAR,
266  wxKeyEventHandler(KeyConfigPrefs::OnHotkeyChar),
267  NULL,
268  this);
269  mKey->Connect(wxEVT_KILL_FOCUS,
270  wxFocusEventHandler(KeyConfigPrefs::OnHotkeyKillFocus),
271  NULL,
272  this);
273  }
274  S.AddWindow(mKey);
275 
276  /* i18n-hint: (verb)*/
277  mSet = S.Id(SetButtonID).AddButton(_("&Set"));
278  mClear = S.Id(ClearButtonID).AddButton(_("Cl&ear"));
279  }
280  S.EndThreeColumn();
281 
282 #if defined(__WXMAC__)
283  S.AddFixedText(_("Note: Pressing Cmd+Q will quit. All other keys are valid."));
284 #endif
285 
286  S.StartThreeColumn();
287  {
288  S.Id(ImportButtonID).AddButton(_("&Import..."));
289  S.Id(ExportButtonID).AddButton(_("&Export..."));
290  S.Id(AssignDefaultsButtonID).AddButton(_("&Defaults"));
291  }
292  S.EndThreeColumn();
293  }
294  S.EndStatic();
295 
296 
297  // Need to layout so that the KeyView is properly sized before populating.
298  // Otherwise, the initial selection is not scrolled into view.
299  Layout();
300 }
301 
303 {
304  wxArrayString Labels;
305  wxArrayString Categories;
306  wxArrayString Prefixes;
307 
308  mNames.Clear();
309  mKeys.Clear();
310  mDefaultKeys.Clear();
311  mStandardDefaultKeys.Clear();
313  mNames,
314  mKeys,
315  mDefaultKeys,
316  Labels,
317  Categories,
318  Prefixes,
319  true); // True to include effects (list items), false otherwise.
320 
323 
325  Categories,
326  Prefixes,
327  Labels,
328  mKeys,
329  bSort);
330  //Not needed as NEW nodes are already shown expanded.
331  //mView->ExpandAll();
332 
333  mNewKeys = mKeys;
334 }
335 
336 void KeyConfigPrefs::OnImport(wxCommandEvent & WXUNUSED(event))
337 {
338  wxString file = wxT("Audacity-keys.xml");
339 
341  _("Select an XML file containing Audacity keyboard shortcuts..."),
342  wxEmptyString,
343  file,
344  wxT(""),
345  _("XML files (*.xml)|*.xml|All files|*"),
346  wxRESIZE_BORDER,
347  this);
348 
349  if (!file) {
350  return;
351  }
352 
353  XMLFileReader reader;
354  if (!reader.Parse(mManager, file)) {
356  _("Error Importing Keyboard Shortcuts"),
357  wxOK | wxCENTRE, this);
358  }
359 
360  RefreshBindings(true);
361 }
362 
363 void KeyConfigPrefs::OnExport(wxCommandEvent & WXUNUSED(event))
364 {
365  wxString file = wxT("Audacity-keys.xml");
366 
368  _("Export Keyboard Shortcuts As:"),
369  wxEmptyString,
370  file,
371  wxT("xml"),
372  _("XML files (*.xml)|*.xml|All files|*"),
373  wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
374  this);
375 
376  if (!file) {
377  return;
378  }
379 
380  GuardedCall( [&] {
381  XMLFileWriter prefFile{ file, _("Error Exporting Keyboard Shortcuts") };
382  mManager->WriteXML(prefFile);
383  prefFile.Commit();
384  } );
385 }
386 
387 
388 
389 // There currently is only one clickable AButton
390 // so we just do what it needs.
391 void KeyConfigPrefs::OnDefaults(wxCommandEvent & WXUNUSED(event))
392 {
393  wxMenu Menu;
394  Menu.Append( 1, _("Standard") );
395  Menu.Append( 2, _("Full") );
396  Menu.Bind( wxEVT_COMMAND_MENU_SELECTED, &KeyConfigPrefs::OnImportDefaults, this );
397  // Pop it up where the mouse is.
398  PopupMenu(&Menu);//, wxPoint(0, 0));
399 }
400 
401 void KeyConfigPrefs::FilterKeys( wxArrayString & arr )
402 {
403  wxSortedArrayString MaxListOnly;
404 
405  // These short cuts are for the max list only....
406  //MaxListOnly.Add( "Ctrl+I" );
407  MaxListOnly.Add( "Ctrl+Alt+I" );
408  MaxListOnly.Add( "Ctrl+J" );
409  MaxListOnly.Add( "Ctrl+Alt+J" );
410  MaxListOnly.Add( "Ctrl+Alt+V" );
411  MaxListOnly.Add( "Alt+X" );
412  MaxListOnly.Add( "Alt+K" );
413  MaxListOnly.Add( "Shift+Alt+X" );
414  MaxListOnly.Add( "Shift+Alt+K" );
415  MaxListOnly.Add( "Alt+L" );
416  MaxListOnly.Add( "Shift+Alt+C" );
417  MaxListOnly.Add( "Alt+I" );
418  MaxListOnly.Add( "Alt+J" );
419  MaxListOnly.Add( "Shift+Alt+J" );
420  MaxListOnly.Add( "Ctrl+Shift+A" );
421  MaxListOnly.Add( "Q" );
422  //MaxListOnly.Add( "Shift+J" );
423  //MaxListOnly.Add( "Shift+K" );
424  //MaxListOnly.Add( "Shift+Home" );
425  //MaxListOnly.Add( "Shift+End" );
426  MaxListOnly.Add( "Ctrl+[" );
427  MaxListOnly.Add( "Ctrl+]" );
428  MaxListOnly.Add( "1" );
429  MaxListOnly.Add( "Shift+F5" );
430  MaxListOnly.Add( "Shift+F6" );
431  MaxListOnly.Add( "Shift+F7" );
432  MaxListOnly.Add( "Shift+F8" );
433  MaxListOnly.Add( "Ctrl+Shift+F5" );
434  MaxListOnly.Add( "Ctrl+Shift+F7" );
435  MaxListOnly.Add( "Ctrl+Shift+N" );
436  MaxListOnly.Add( "Ctrl+Shift+M" );
437  MaxListOnly.Add( "Ctrl+Home" );
438  MaxListOnly.Add( "Ctrl+End" );
439  MaxListOnly.Add( "Shift+C" );
440  MaxListOnly.Add( "Alt+Shift+Up" );
441  MaxListOnly.Add( "Alt+Shift+Down" );
442  MaxListOnly.Add( "Shift+P" );
443  MaxListOnly.Add( "Alt+Shift+Left" );
444  MaxListOnly.Add( "Alt+Shift+Right" );
445  MaxListOnly.Add( "Ctrl+Shift+T" );
446  //MaxListOnly.Add( "Command+M" );
447  //MaxListOnly.Add( "Option+Command+M" );
448  MaxListOnly.Add( "Shift+H" );
449  MaxListOnly.Add( "Shift+O" );
450  MaxListOnly.Add( "Shift+I" );
451  MaxListOnly.Add( "Shift+N" );
452  MaxListOnly.Add( "D" );
453  MaxListOnly.Add( "A" );
454  MaxListOnly.Add( "Alt+Shift+F6" );
455  MaxListOnly.Add( "Alt+F6" );
456 
457  std::transform( MaxListOnly.begin(), MaxListOnly.end(), MaxListOnly.begin(),
459  MaxListOnly.Sort();
460  // Remove items that are in MaxList.
461  for (size_t i = 0; i < arr.GetCount(); i++) {
462  if( MaxListOnly.Index( arr[i] ) != wxNOT_FOUND )
463  arr[i]= wxT("");
464  }
465 }
466 
467 void KeyConfigPrefs::OnImportDefaults(wxCommandEvent & event)
468 {
469  gPrefs->DeleteEntry(wxT("/GUI/Shortcuts/FullDefaults"));
470  gPrefs->Flush();
471 
473  if( event.GetId() == 1 )
474  FilterKeys( mNewKeys );
475 
476  for (size_t i = 0; i < mNewKeys.GetCount(); i++) {
478  }
479 
480  RefreshBindings(true);
481 }
482 
484 {
485  wxTextCtrl *t = (wxTextCtrl *)e.GetEventObject();
486 
487  // Make sure we can navigate away from the hotkey textctrl.
488  // On Linux and OSX, it can get stuck, but it doesn't hurt
489  // to do it for Windows as well.
490  //
491  // Mac note: Don't waste time trying to figure out why the
492  // focus goes back to the prefs tree. Unless Voiceover is
493  // active, buttons on the Mac do not accept focus and all the
494  // controls between this one and the tree control are buttons.
495  if (e.GetKeyCode() == WXK_TAB) {
496  NavigateIn(e.ShiftDown()
497  ? wxNavigationKeyEvent::IsBackward
498  : wxNavigationKeyEvent::IsForward);
499  return;
500  }
501 
502  t->SetValue(KeyStringDisplay(KeyEventToKeyString(e)));
503 }
504 
505 void KeyConfigPrefs::OnHotkeyChar(wxKeyEvent & WXUNUSED(e))
506 {
507  // event.Skip() not performed, so event will not be processed further.
508 }
509 
510 void KeyConfigPrefs::OnHotkeyKillFocus(wxFocusEvent & e)
511 {
512  if (mKey->GetValue().IsEmpty() && mCommandSelected != wxNOT_FOUND) {
513  mKey->AppendText(mView->GetKey(mCommandSelected));
514  }
515 
516  e.Skip();
517 }
518 
519 void KeyConfigPrefs::OnFilterTimer(wxTimerEvent & WXUNUSED(e))
520 {
521  // The filter timer has expired, so set the filter
522  if (mFilterPending)
523  {
524  // Do not reset mFilterPending here...possible race
525  mView->SetFilter(mFilter->GetValue());
526  }
527 }
528 
530 {
531  wxTextCtrl *t = (wxTextCtrl *)e.GetEventObject();
532  int keycode = e.GetKeyCode();
533 
534  // Make sure we can navigate away from the hotkey textctrl.
535  // On Linux and OSX, it an get stuck, but it doesn't hurt
536  // to do it for Windows as well.
537  if (keycode == WXK_TAB) {
538  wxNavigationKeyEvent nevent;
539  nevent.SetWindowChange(e.ControlDown());
540  nevent.SetDirection(!e.ShiftDown());
541  nevent.SetEventObject(t);
542  nevent.SetCurrentFocus(t);
543  t->GetParent()->GetEventHandler()->ProcessEvent(nevent);
544 
545  return;
546  }
547 
548  if (mViewType == ViewByKey) {
549  wxString key = KeyStringDisplay(KeyEventToKeyString(e));
550  t->SetValue(key);
551 
552  if (key != wxEmptyString) {
553  mView->SetFilter(t->GetValue());
554  }
555  }
556  else
557  {
558  if (keycode == WXK_RETURN) {
559  mFilterPending = false;
560  mView->SetFilter(t->GetValue());
561  }
562  else {
563  mFilterPending = true;
564  mFilterTimer.Start(500, wxTIMER_ONE_SHOT);
565 
566  e.Skip();
567  }
568  }
569 }
570 
571 void KeyConfigPrefs::OnFilterChar(wxKeyEvent & e)
572 {
573  if (mViewType != ViewByKey)
574  {
575  e.Skip();
576  }
577 }
578 
579 // Given a hotkey combination, returns the name (description) of the
580 // corresponding command, or the empty string if none is found.
581 wxString KeyConfigPrefs::NameFromKey(const wxString & key)
582 {
583  return mView->GetNameByKey(key);
584 }
585 
586 // Sets the selected command to have this key
587 // This is not yet a committed change, which will happen on a save.
588 void KeyConfigPrefs::SetKeyForSelected(const wxString & key)
589 {
590  wxString name = mView->GetName(mCommandSelected);
591 
593  {
594  AudacityMessageBox(_("You may not assign a key to this entry"),
595  _("Error"), wxICON_ERROR | wxCENTRE, this);
596  return;
597  }
598 
600  mManager->SetKeyFromName(name, key);
601  mNewKeys[mNames.Index(name)] = key;
602 }
603 
604 
605 void KeyConfigPrefs::OnSet(wxCommandEvent & WXUNUSED(event))
606 {
607  if (mCommandSelected == wxNOT_FOUND) {
608  AudacityMessageBox(_("You must select a binding before assigning a shortcut"),
609  _("Error"), wxICON_WARNING | wxCENTRE, this);
610  return;
611  }
612 
613  wxString key = mKey->GetValue();
614  wxString oldname = mView->GetNameByKey(key);
615  wxString newname = mView->GetName(mCommandSelected);
616 
617  // Just ignore it if they are the same
618  if (oldname == newname) {
619  return;
620  }
621 
622  // Prevent same hotkey combination being used twice.
623  if (!oldname.empty()) {
624  auto oldlabel = wxString::Format( _("%s - %s"),
625  mManager->GetCategoryFromName(oldname),
627  auto newlabel = wxString::Format( _("%s - %s"),
628  mManager->GetCategoryFromName(newname),
630  if (AudacityMessageBox(
631  wxString::Format(
632  _("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."),
633  key,
634  oldlabel,
635  newlabel),
636  _("Error"), wxOK | wxCANCEL | wxICON_STOP | wxCENTRE, this) == wxCANCEL)
637  {
638  return;
639  }
640 
641  mView->SetKeyByName(oldname, wxEmptyString);
642  mManager->SetKeyFromName(oldname, wxEmptyString);
643  mNewKeys[mNames.Index(oldname)].Empty();
644 
645  }
646 
647  SetKeyForSelected(key);
648 }
649 
650 void KeyConfigPrefs::OnClear(wxCommandEvent& WXUNUSED(event))
651 {
652  mKey->Clear();
653 
654  if (mCommandSelected != wxNOT_FOUND) {
655  SetKeyForSelected(wxEmptyString);
656  }
657 }
658 
659 void KeyConfigPrefs::OnSelected(wxCommandEvent & WXUNUSED(e))
660 {
662  mKey->Clear();
663 
664  if (mCommandSelected != wxNOT_FOUND) {
665  bool canset = mView->CanSetKey(mCommandSelected);
666  if (canset) {
667  mKey->AppendText(mView->GetKey(mCommandSelected));
668  }
669 
670  mKey->Enable(canset);
671  mSet->Enable(canset);
672  mClear->Enable(canset);
673  }
674 }
675 
676 void KeyConfigPrefs::OnViewBy(wxCommandEvent & e)
677 {
678  switch (e.GetId())
679  {
680  case ViewByTreeID:
682  mFilterLabel->SetLabel(_("Searc&h:"));
683  break;
684 
685  case ViewByNameID:
687  mFilterLabel->SetLabel(_("Searc&h:"));
688  break;
689 
690  case ViewByKeyID:
692  mFilterLabel->SetLabel(_("&Hotkey:"));
693  break;
694  }
695 
697  mFilter->SetName(wxStripMenuCodes(mFilterLabel->GetLabel()));
698 }
699 
701 {
702  // On the Mac, preferences may be changed without any active
703  // projects. This means that the CommandManager isn't availabe
704  // either. So we can't attempt to save preferences, otherwise
705  // NULL ptr dereferences will happen in ShuttleGui because the
706  // radio buttons are never created. (See Populate() above.)
707  if (!GetActiveProject()) {
708  return true;
709  }
710 
711  ShuttleGui S(this, eIsSavingToPrefs);
713 
714  for (size_t i = 0; i < mNames.GetCount(); i++) {
715  wxString dkey = KeyStringNormalize(mStandardDefaultKeys[i]);
716  wxString name = wxT("/NewKeys/") + mNames[i];
717  wxString key = KeyStringNormalize(mNewKeys[i]);
718 
719  if (gPrefs->HasEntry(name)) {
720  if (key != KeyStringNormalize(gPrefs->Read(name, key))) {
721  gPrefs->Write(name, key);
722  }
723  if (key == dkey) {
724  gPrefs->DeleteEntry(name);
725  }
726  }
727  else {
728  if (key != dkey) {
729  gPrefs->Write(name, key);
730  }
731  }
732  }
733 
734  return gPrefs->Flush();
735 }
736 
738 {
739  // Restore original key values
740  for (size_t i = 0; i < mNames.GetCount(); i++) {
742  }
743 
744  return;
745 }
746 
748 {
749  return "Keyboard_Preferences";
750 }
751 
753 {
754  wxASSERT(parent); // to justify safenew
755  auto result = safenew KeyConfigPrefs{ parent, mName };
756  return result;
757 }
CommandManager * mManager
void OnExport(const wxString &Format)
wxRadioButton * mViewByKey
PrefsPanel * Create(wxWindow *parent) override
ViewByType mViewType
void EndThreeColumn()
Definition: ShuttleGui.h:128
#define FilterTimerID
void OnDefaults(wxCommandEvent &e)
wxString GetNameByKey(const wxString &key) const
Definition: KeyView.cpp:184
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:366
void EndRadioButtonGroup()
wxString HelpPageName() override
void SetKeyFromIndex(int i, const wxString &key)
wxWindow * AddWindow(wxWindow *pWindow, int Flags=wxALIGN_CENTRE|wxALL)
Definition: ShuttleGui.cpp:257
void OnViewBy(wxCommandEvent &e)
wxString GetName() const
Definition: KeyView.cpp:96
wxArrayString mDefaultKeys
void WriteXML(XMLWriter &xmlFile) const
void OnSelected(wxCommandEvent &e)
void OnFilterTimer(wxTimerEvent &e)
int GetSelected() const
Definition: KeyView.cpp:87
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
void SetKeyForSelected(const wxString &key)
CommandManager * GetCommandManager()
Definition: Project.h:331
#define ViewByTreeID
void GetAllCommandData(wxArrayString &names, wxArrayString &keys, wxArrayString &default_keys, wxArrayString &labels, wxArrayString &categories, wxArrayString &prefixes, bool includeMultis)
wxStaticText * mFilterLabel
wxArrayString mKeys
bool CanSetKey(int index) const
Definition: KeyView.cpp:240
#define safenew
Definition: Audacity.h:223
void EndHorizontalLay()
Definition: ShuttleGui.cpp:975
wxTextCtrl * mKey
void OnClear(wxCommandEvent &e)
#define ImportButtonID
#define AssignDefaultsButtonID
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:161
#define CurrentComboID
void EndVerticalLay()
Definition: ShuttleGui.cpp:991
void OnFilterKeyDown(wxKeyEvent &e)
bool Parse(XMLTagHandler *baseHandler, const wxString &fname)
wxFileConfig * gPrefs
Definition: Prefs.cpp:72
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:316
wxString KeyStringNormalize(const wxString &key)
Definition: Keyboard.cpp:16
wxString GetCategoryFromName(const wxString &name)
wxRadioButton * mViewByTree
A PrefsPanel for keybindings.
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
Definition: ShuttleGui.cpp:966
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:998
void SetKeyFromName(const wxString &name, const wxString &key)
wxTextCtrl * mFilter
ShuttleGui & Id(int id)
void SetFilter(const wxString &filter)
Definition: KeyView.cpp:376
void Cancel() override
void OnImport(const CommandContext &)
void RefreshBindings(const wxArrayString &names, const wxArrayString &categories, const wxArrayString &prefixes, const wxArrayString &labels, const wxArrayString &keys, bool bSort)
Definition: KeyView.cpp:533
void AddFixedText(const wxString &Str, bool bCenter=false)
Definition: ShuttleGui.cpp:356
wxButton * mClear
wxButton * mSet
R GuardedCall(const F1 &body, const F2 &handler=F2::Default(), const F3 &delayedHandler={})
wxString GetKey(int index) const
Definition: KeyView.cpp:224
wxString KeyStringDisplay(const wxString &key, bool usesSpecialChars)
Definition: Keyboard.cpp:53
void AddTitle(const wxString &Prompt)
Centred text string.
Definition: ShuttleGui.cpp:243
wxRadioButton * mViewByName
wxArrayString mNewKeys
#define ClearButtonID
wxRadioButton * TieRadioButton(const wxString &Prompt, WrappedType &WrappedRef)
void StartThreeColumn()
Definition: ShuttleGui.h:127
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:43
_("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 &)
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:405
#define FilterID
#define ViewByNameID
#define CommandsListID
void PopulateOrExchange(ShuttleGui &S)
const wxChar * name
Definition: Distortion.cpp:94
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:302
wxStaticText * AddVariableText(const wxString &Str, bool bCenter=false, int PositionFlags=0)
Definition: ShuttleGui.cpp:373
bool SetKey(int index, const wxString &key)
Definition: KeyView.cpp:257
wxStaticBox * StartStatic(const wxString &Str, int iProp=0)
Definition: ShuttleGui.cpp:701
wxArrayString mStandardDefaultKeys
ShuttleGui & Prop(int iProp)
Definition: ShuttleGui.h:374
wxString KeyEventToKeyString(const wxKeyEvent &event)
Definition: Keyboard.cpp:78
void OnImportDefaults(wxCommandEvent &e)
void OnHotkeyKeyDown(wxKeyEvent &e)
wxString GetErrorStr()
wxString NameFromKey(const wxString &key)
END_EVENT_TABLE()
wxSizerItem * AddSpace(int width, int height)
void OnHotkeyKillFocus(wxFocusEvent &e)
void FilterKeys(wxArrayString &arr)
#define SetButtonID
void SetBorder(int Border)
Definition: ShuttleGui.h:251
void OnSet(wxCommandEvent &e)
void StartRadioButtonGroup(const wxString &SettingName)
bool SetKeyByName(const wxString &name, const wxString &key)
Definition: KeyView.cpp:298
Provides multiple views of keyboard shortcuts.
Definition: KeyView.h:71
wxButton * AddButton(const wxString &Text, int PositionFlags=wxALIGN_CENTRE)
Definition: ShuttleGui.cpp:301
void OnExport(wxCommandEvent &e)
void SetStretchyCol(int i)
Used to modify an already placed FlexGridSizer to make a column stretchy.
Definition: ShuttleGui.cpp:192
void OnHotkeyChar(wxKeyEvent &e)
wxTimer mFilterTimer
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:982