📄 keyconfigprefs.cpp
字号:
/********************************************************************** Audacity: A Digital Audio Editor KeyConfigPrefs.cpp Brian Gunlogson Dominic Mazzoni**********************************************************************/#include <wx/defs.h>#include <wx/ffile.h>#include <wx/statbox.h>#include <wx/sizer.h>#include <wx/stattext.h>#include <wx/button.h>#include <wx/textctrl.h>#include <wx/listctrl.h>#include <wx/choice.h>#include <wx/intl.h>#include <wx/filedlg.h>#include <wx/msgdlg.h>#include <wx/menuitem.h>#include "../Prefs.h"#include "../commands/CommandManager.h"#include "../commands/Keyboard.h"#include "../xml/XMLFileReader.h"#include "KeyConfigPrefs.h"#include "../Internat.h"#define AssignDefaultsButtonID 7001#define CurrentComboID 7002#define SetButtonID 7003#define ClearButtonID 7004#define CommandsListID 7005#define SaveButtonID 7006#define LoadButtonID 7007// The numbers of the columns of the mList.enum { BlankColumn=0, CommandColumn=1, KeyComboColumn=2};BEGIN_EVENT_TABLE(KeyConfigPrefs, wxPanel) EVT_BUTTON(AssignDefaultsButtonID, KeyConfigPrefs::OnDefaults) EVT_BUTTON(SetButtonID, KeyConfigPrefs::OnSet) EVT_BUTTON(ClearButtonID, KeyConfigPrefs::OnClear) EVT_BUTTON(SaveButtonID, KeyConfigPrefs::OnSave) EVT_BUTTON(LoadButtonID, KeyConfigPrefs::OnLoad) EVT_LIST_ITEM_SELECTED(CommandsListID, KeyConfigPrefs::OnItemSelected)END_EVENT_TABLE()KeyConfigPrefs::KeyConfigPrefs(wxWindow * parent):PrefsPanel(parent){ AudacityProject *project = GetActiveProject(); if (!project) return; mManager = project->GetCommandManager(); topSizer = new wxBoxSizer( wxVERTICAL ); // This code for displaying keybindings is similar to code in MousePrefs. // Would be nice to create a new 'Bindings' class which both // KeyConfigPrefs and MousePrefs use. mList = new wxListCtrl( this, CommandsListID , wxDefaultPosition, wxSize(500,250), wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxSUNKEN_BORDER ); wxASSERT( mList ); //An empty first column is a workaround - under Win98 the first column //can't be right aligned. mList->InsertColumn(BlankColumn, wxT(""), wxLIST_FORMAT_LEFT ); mList->InsertColumn(CommandColumn, _("Command"), wxLIST_FORMAT_RIGHT ); mList->InsertColumn(KeyComboColumn, _("Key Combination"), wxLIST_FORMAT_LEFT ); RepopulateBindingsList(); mList->SetColumnWidth( BlankColumn, 0 ); // First column width is zero, to hide it. // Would like to use wxLIST_AUTOSIZE but // wxWindows does not look at the size of column heading.// mList->SetColumnWidth( CommandColumn, 250 ); mList->SetColumnWidth( CommandColumn, wxLIST_AUTOSIZE ); mList->SetColumnWidth( KeyComboColumn, 115 ); topSizer->Add( mList, 1, wxGROW | wxALL, GENERIC_CONTROL_BORDER); //Add key combo text box mCurrentComboText = new SysKeyTextCtrl( this, CurrentComboID, wxT(""), wxDefaultPosition, wxSize(115, -1), 0 ); wxButton *pSetButton = new wxButton(this, SetButtonID, _("Set")); wxButton *pClearButton = new wxButton(this, ClearButtonID, _("Clear")); wxBoxSizer * pComboLabelSizer = new wxBoxSizer( wxHORIZONTAL ); pComboLabelSizer->Add( mCurrentComboText, 0, wxALL, GENERIC_CONTROL_BORDER); pComboLabelSizer->Add( pSetButton, 0, wxALL, GENERIC_CONTROL_BORDER); pComboLabelSizer->Add( pClearButton, 0, wxALL, GENERIC_CONTROL_BORDER); topSizer->Add(pComboLabelSizer, 0, wxALL, GENERIC_CONTROL_BORDER); #ifdef __WXMAC__ wxBoxSizer * pMacSizer = new wxBoxSizer( wxHORIZONTAL ); wxString warningStr = _("Note: Pressing Cmd+Q will quit. All other keys are valid."); pMacSizer->Add(new wxStaticText(this, -1, warningStr), 0, wxALL, GENERIC_CONTROL_BORDER); topSizer->Add(pMacSizer, 0, wxALL, GENERIC_CONTROL_BORDER); #endif wxButton *pDefaultsButton = new wxButton(this, AssignDefaultsButtonID, _("Defaults")); wxButton *pSaveButton = new wxButton(this, SaveButtonID, _("Save...")); wxButton *pLoadButton = new wxButton(this, LoadButtonID, _("Load...")); pComboLabelSizer = new wxBoxSizer( wxHORIZONTAL ); pComboLabelSizer->Add( pDefaultsButton, 0, wxALL, GENERIC_CONTROL_BORDER); pComboLabelSizer->Add( pSaveButton, 0, wxALL, GENERIC_CONTROL_BORDER); pComboLabelSizer->Add( pLoadButton, 0, wxALL, GENERIC_CONTROL_BORDER); topSizer->Add(pComboLabelSizer, 0, wxALL, GENERIC_CONTROL_BORDER); outSizer = new wxBoxSizer( wxVERTICAL ); outSizer->Add(topSizer, 0, wxGROW|wxALL, TOP_LEVEL_BORDER); SetAutoLayout(true); SetSizer(outSizer); outSizer->Fit(this); outSizer->SetSizeHints(this); mCommandSelected = -1;}void KeyConfigPrefs::OnSave(wxCommandEvent& event){ Apply(); wxString fName = wxT("Audacity-keys.xml"); wxString path = gPrefs->Read(wxT("/DefaultExportPath"), FROMFILENAME(::wxGetCwd())); fName = wxFileSelector(_("Export Keyboard Shortcuts As:"), NULL, fName, wxT("xml"), wxT("*.xml"), wxSAVE | wxOVERWRITE_PROMPT, this); if (!fName) return; path = wxPathOnly(fName); gPrefs->Write(wxT("/DefaultExportPath"), path); wxFFile prefFile(FILENAME(fName).c_str(), wxT("wb")); if (!prefFile.IsOpened()) { wxMessageBox(_("Couldn't write to file: ") + fName, _("Error saving keyboard shortcuts"), wxOK | wxCENTRE, this); return; } mManager->WriteXML(0, prefFile.fp()); prefFile.Close();}void KeyConfigPrefs::OnLoad(wxCommandEvent& event){ wxString path = gPrefs->Read(wxT("/DefaultOpenPath"), FROMFILENAME(::wxGetCwd())); wxString fileName = wxFileSelector(_("Select an XML file containing Audacity keyboard shortcuts..."), path, // Path wxT(""), // Name wxT(""), // Extension _("XML files (*.xml)|*.xml|All files (*.*)|*.*"), 0, // Flags this); // Parent if (!fileName) return; path = wxPathOnly(fileName); gPrefs->Write(wxT("/DefaultOpenPath"), path); XMLFileReader reader; if (!reader.Parse(mManager, fileName)) wxMessageBox(reader.GetErrorStr(), _("Error loading keyboard shortcuts"), wxOK | wxCENTRE, this); RepopulateBindingsList();}void KeyConfigPrefs::OnSet(wxCommandEvent& event){ if (mCommandSelected < 0 || mCommandSelected >= (int)mNames.GetCount()) return; mList->SetItem( mCommandSelected, KeyComboColumn, mCurrentComboText->GetValue() );}void KeyConfigPrefs::OnClear(wxCommandEvent& event){ mCurrentComboText->Clear(); if (mCommandSelected < 0 || mCommandSelected >= (int)mNames.GetCount()) return; mList->SetItem( mCommandSelected, KeyComboColumn, wxT("") );}void KeyConfigPrefs::OnItemSelected(wxListEvent &event){ mCommandSelected = event.GetIndex(); if (mCommandSelected < 0 || mCommandSelected >= (int)mNames.GetCount()) { mCurrentComboText->SetLabel(wxT("")); return; } wxString key = mManager->GetKeyFromName(mNames[mCommandSelected]); mCurrentComboText->Clear(); mCurrentComboText->AppendText(key); // JKC: July-2004 // Under Windows 98 setting the focus to the combo box whilst // we are still processing an OnItemSelected event can lead // to a crash (try clicking on an item in the list and dragging it). // It's OK under WinXP. TODO: Is there a #define that only excludes // WIN_98 that we could use here instead??#ifndef __WXMSW__ mCurrentComboText->SetFocus();#else //JKC Something like the following might do what we want under Win98? //mCurrentComboText->GetEventHandler()->AddPendingEvent( wxFocusEvent(wxEVT_SET_FOCUS));#endif}void KeyConfigPrefs::RepopulateBindingsList(){ mList->DeleteAllItems(); // Delete contents, but not the column headers. mNames.Clear(); mManager->GetAllCommandNames(mNames, false); unsigned int i; for(i=0; i<mNames.GetCount(); i++) { mList->InsertItem( i, wxT("") ); wxString label = mManager->GetLabelFromName(mNames[i]); label = wxMenuItem::GetLabelFromText(label.BeforeFirst('\t')); wxString key = mManager->GetKeyFromName(mNames[i]); #ifdef __WXMAC__ // Replace Ctrl with Cmd if (key.Length() >= 5 && key.Left(5)==wxT("Ctrl+")) { key = wxT("Cmd+")+key.Right(key.Length()-5); } #endif mList->SetItem( i, CommandColumn, label ); mList->SetItem( i, KeyComboColumn, key ); }}void KeyConfigPrefs::OnDefaults(wxCommandEvent& event){ unsigned int i; for(i=0; i<mNames.GetCount(); i++) { mList->SetItem( i, KeyComboColumn, mManager->GetDefaultKeyFromName(mNames[i]) ); }}bool KeyConfigPrefs::Apply(){ unsigned int i; wxListItem item; gPrefs->SetPath(wxT("/NewKeys")); // // Only store the key in the preferences if it's different // than the default value. // item.m_col = KeyComboColumn; item.m_mask = wxLIST_MASK_TEXT; for(i=0; i<mNames.GetCount(); i++) { item.SetId( i ); mList->GetItem(item); wxString name = mNames[i]; wxString key = item.m_text; #ifdef __WXMAC__ // Replace Cmd with Ctrl if (key.Length() >= 4 && key.Left(4)==wxT("Cmd+")) { key = wxT("Ctrl+")+key.Right(key.Length()-4); } #endif wxString defaultKey = mManager->GetDefaultKeyFromName(name); if (gPrefs->HasEntry(name)) { wxString oldKey = gPrefs->Read(name, key); if (oldKey != key) { gPrefs->Write(name, key); } if (key == defaultKey) { gPrefs->DeleteEntry(name); } } else { if (key != defaultKey){ gPrefs->Write(name, key); } } } gPrefs->SetPath(wxT("/")); for(i=0; i<gAudacityProjects.GetCount(); i++) if(gAudacityProjects[i]) gAudacityProjects[i]->RebuildMenuBar(); return true;}KeyConfigPrefs::~KeyConfigPrefs(){}//BG: A quick and dirty override of wxTextCtrl to capture keys like Ctrl, AltBEGIN_EVENT_TABLE(SysKeyTextCtrl, wxTextCtrl) EVT_KEY_DOWN(SysKeyTextCtrl::OnKey) EVT_CHAR(SysKeyTextCtrl::OnChar)END_EVENT_TABLE()SysKeyTextCtrl::SysKeyTextCtrl(wxWindow *parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name): wxTextCtrl(parent, id, value, pos, size, style, validator, name){}SysKeyTextCtrl::~SysKeyTextCtrl(){}//BG: It works on Windows, but we need to trap WM_CHAR//DM: On Linux, now it works except for Ctrl+3...Ctrl+8 (April/2003)void SysKeyTextCtrl::OnKey(wxKeyEvent& event){ SetValue(KeyEventToKeyString(event));}//BG: Trap WM_CHARvoid SysKeyTextCtrl::OnChar(wxKeyEvent& event){}// Indentation settings for Vim and Emacs and unique identifier for Arch, a// version control system. Please do not modify past this point.//// Local Variables:// c-basic-offset: 3// indent-tabs-mode: nil// End://// vim: et sts=3 sw=3// arch-tag: f09afeeb-9805-463a-b3ca-e3e3bfe05549
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -