From 9f38b70491518ea9d719f2a29e833ad2be2931d4 Mon Sep 17 00:00:00 2001 From: John Beard Date: Wed, 1 Aug 2018 10:15:05 +0100 Subject: [PATCH] Add a filter box to hotkey dialog and filter using it This uses a simple case-insensitive partial match, which is a good start for the relatively limited number of hotkeys generally present. --- common/dialogs/panel_hotkeys_editor.cpp | 8 ++ common/dialogs/panel_hotkeys_editor_base.cpp | 11 ++- common/dialogs/panel_hotkeys_editor_base.fbp | 96 ++++++++++++++++++++ common/dialogs/panel_hotkeys_editor_base.h | 9 +- common/widgets/widget_hotkey_list.cpp | 72 +++++++++++++-- include/panel_hotkeys_editor.h | 8 ++ include/widgets/widget_hotkey_list.h | 18 ++++ 7 files changed, 212 insertions(+), 10 deletions(-) diff --git a/common/dialogs/panel_hotkeys_editor.cpp b/common/dialogs/panel_hotkeys_editor.cpp index 6059d54659..e747007771 100644 --- a/common/dialogs/panel_hotkeys_editor.cpp +++ b/common/dialogs/panel_hotkeys_editor.cpp @@ -35,6 +35,8 @@ PANEL_HOTKEYS_EDITOR::PANEL_HOTKEYS_EDITOR( EDA_BASE_FRAME* aFrame, wxWindow* aW m_nickname( aNickname ), m_hotkeyStore( aShowHotkeys ) { + m_filterSearch->SetDescriptiveText( _("Type filter text") ); + m_hotkeyListCtrl = new WIDGET_HOTKEY_LIST( m_panelHotkeys, m_hotkeyStore ); m_hotkeyListCtrl->InstallOnPanel( m_panelHotkeys ); } @@ -79,3 +81,9 @@ void PANEL_HOTKEYS_EDITOR::OnImport( wxCommandEvent& aEvent ) { m_frame->ImportHotkeyConfigFromFile( m_hotkeys, m_nickname ); } + +void PANEL_HOTKEYS_EDITOR::OnFilterSearch( wxCommandEvent& aEvent ) +{ + const auto searchStr = aEvent.GetString(); + m_hotkeyListCtrl->ApplyFilterString( searchStr ); +} diff --git a/common/dialogs/panel_hotkeys_editor_base.cpp b/common/dialogs/panel_hotkeys_editor_base.cpp index c944fde747..2f00fd549c 100644 --- a/common/dialogs/panel_hotkeys_editor_base.cpp +++ b/common/dialogs/panel_hotkeys_editor_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jun 5 2018) +// C++ code generated with wxFormBuilder (version Jun 18 2018) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -16,6 +16,13 @@ PANEL_HOTKEYS_EDITOR_BASE::PANEL_HOTKEYS_EDITOR_BASE( wxWindow* parent, wxWindow wxBoxSizer* bMargins; bMargins = new wxBoxSizer( wxVERTICAL ); + m_filterSearch = new wxSearchCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + #ifndef __WXMAC__ + m_filterSearch->ShowSearchButton( false ); + #endif + m_filterSearch->ShowCancelButton( true ); + bMargins->Add( m_filterSearch, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 ); + m_panelHotkeys = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); m_panelHotkeys->SetMinSize( wxSize( -1,350 ) ); @@ -50,6 +57,7 @@ PANEL_HOTKEYS_EDITOR_BASE::PANEL_HOTKEYS_EDITOR_BASE( wxWindow* parent, wxWindow this->Layout(); // Connect Events + m_filterSearch->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::OnFilterSearch ), NULL, this ); m_resetButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::ResetClicked ), NULL, this ); m_defaultButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::DefaultsClicked ), NULL, this ); btnImport->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::OnImport ), NULL, this ); @@ -59,6 +67,7 @@ PANEL_HOTKEYS_EDITOR_BASE::PANEL_HOTKEYS_EDITOR_BASE( wxWindow* parent, wxWindow PANEL_HOTKEYS_EDITOR_BASE::~PANEL_HOTKEYS_EDITOR_BASE() { // Disconnect Events + m_filterSearch->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::OnFilterSearch ), NULL, this ); m_resetButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::ResetClicked ), NULL, this ); m_defaultButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::DefaultsClicked ), NULL, this ); btnImport->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::OnImport ), NULL, this ); diff --git a/common/dialogs/panel_hotkeys_editor_base.fbp b/common/dialogs/panel_hotkeys_editor_base.fbp index b57da33238..f54a83ad67 100644 --- a/common/dialogs/panel_hotkeys_editor_base.fbp +++ b/common/dialogs/panel_hotkeys_editor_base.fbp @@ -93,6 +93,98 @@ bMargins wxVERTICAL none + + 5 + wxBOTTOM|wxEXPAND|wxTOP + 0 + + 1 + 1 + 1 + 1 + + + + + + + 1 + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_filterSearch + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnFilterSearch + + + + 2 wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT @@ -216,6 +308,7 @@ 0 wxID_RESET Reset Hotkeys + 0 0 @@ -304,6 +397,7 @@ 0 wxID_ANY Set to Defaults + 0 0 @@ -402,6 +496,7 @@ 0 wxID_ANY Import... + 0 0 @@ -490,6 +585,7 @@ 0 wxID_ANY Export... + 0 0 diff --git a/common/dialogs/panel_hotkeys_editor_base.h b/common/dialogs/panel_hotkeys_editor_base.h index 88a78905df..c199f8146c 100644 --- a/common/dialogs/panel_hotkeys_editor_base.h +++ b/common/dialogs/panel_hotkeys_editor_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jun 5 2018) +// C++ code generated with wxFormBuilder (version Jun 18 2018) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -11,12 +11,13 @@ #include #include #include -#include +#include +#include #include #include #include #include -#include +#include #include #include @@ -32,6 +33,7 @@ class PANEL_HOTKEYS_EDITOR_BASE : public wxPanel protected: wxBoxSizer* m_mainSizer; + wxSearchCtrl* m_filterSearch; wxPanel* m_panelHotkeys; wxButton* m_resetButton; wxButton* m_defaultButton; @@ -39,6 +41,7 @@ class PANEL_HOTKEYS_EDITOR_BASE : public wxPanel wxButton* btnExport; // Virtual event handlers, overide them in your derived class + virtual void OnFilterSearch( wxCommandEvent& event ) { event.Skip(); } virtual void ResetClicked( wxCommandEvent& event ) { event.Skip(); } virtual void DefaultsClicked( wxCommandEvent& event ) { event.Skip(); } virtual void OnImport( wxCommandEvent& event ) { event.Skip(); } diff --git a/common/widgets/widget_hotkey_list.cpp b/common/widgets/widget_hotkey_list.cpp index 9e38502aaf..af7d759f8f 100644 --- a/common/widgets/widget_hotkey_list.cpp +++ b/common/widgets/widget_hotkey_list.cpp @@ -226,6 +226,52 @@ public: }; +/** + * Class HOTKEY_FILTER + * + * Class to manage logic for filtering hotkeys based on user input + */ +class HOTKEY_FILTER +{ +public: + HOTKEY_FILTER( const wxString& aFilterStr ) + { + m_normalised_filter_str = aFilterStr.Upper(); + m_valid = m_normalised_filter_str.size() > 0; + } + + + /** + * Method FilterMatches + * + * Checks if the filter matches the given hotkey + * + * @return true on match (or if filter is disabled) + */ + bool FilterMatches( const EDA_HOTKEY& aHotkey ) const + { + if( !m_valid ) + return true; + + // Match in the (translated) filter string + const auto normedInfo = wxGetTranslation( aHotkey.m_InfoMsg ).Upper(); + if( normedInfo.Contains( m_normalised_filter_str ) ) + return true; + + const wxString keyName = KeyNameFromKeyCode( aHotkey.m_KeyCode ); + if( keyName.Upper().Contains( m_normalised_filter_str ) ) + return true; + + return false; + } + +private: + + bool m_valid; + wxString m_normalised_filter_str; +}; + + WIDGET_HOTKEY_CLIENT_DATA* WIDGET_HOTKEY_LIST::GetHKClientData( wxTreeListItem aItem ) { if( aItem.IsOk() ) @@ -449,6 +495,12 @@ void WIDGET_HOTKEY_LIST::InstallOnPanel( wxPanel* aPanel ) } +void WIDGET_HOTKEY_LIST::ApplyFilterString( const wxString& aFilterStr ) +{ + updateShownItems( aFilterStr ); +} + + void WIDGET_HOTKEY_LIST::ResetAllHotkeys( bool aResetToDefault ) { Freeze(); @@ -470,13 +522,20 @@ void WIDGET_HOTKEY_LIST::ResetAllHotkeys( bool aResetToDefault ) } - - bool WIDGET_HOTKEY_LIST::TransferDataToControl() +{ + updateShownItems( "" ); + return true; +} + + +void WIDGET_HOTKEY_LIST::updateShownItems( const wxString& aFilterStr ) { Freeze(); DeleteAllItems(); + HOTKEY_FILTER filter( aFilterStr ); + for( auto& section: m_hk_store.GetSections() ) { // Create parent tree item @@ -484,8 +543,11 @@ bool WIDGET_HOTKEY_LIST::TransferDataToControl() for( auto& hotkey: section.m_hotkeys ) { - wxTreeListItem item = AppendItem( parent, wxEmptyString ); - SetItemData( item, new WIDGET_HOTKEY_CLIENT_DATA( hotkey ) ); + if( filter.FilterMatches( hotkey.GetCurrentValue() ) ) + { + wxTreeListItem item = AppendItem( parent, wxEmptyString ); + SetItemData( item, new WIDGET_HOTKEY_CLIENT_DATA( hotkey ) ); + } } Expand( parent ); @@ -493,8 +555,6 @@ bool WIDGET_HOTKEY_LIST::TransferDataToControl() UpdateFromClientData(); Thaw(); - - return true; } diff --git a/include/panel_hotkeys_editor.h b/include/panel_hotkeys_editor.h index 576277f4ec..fd4776c494 100644 --- a/include/panel_hotkeys_editor.h +++ b/include/panel_hotkeys_editor.h @@ -72,6 +72,14 @@ private: void OnExport( wxCommandEvent& aEvent ) override; void OnImport( wxCommandEvent& aEvent ) override; + + /** + * Function OnFilterSearch + * Handle a change in the hoteky filter text + * + * @param aEvent: the search event, used to get the search query + */ + void OnFilterSearch( wxCommandEvent& aEvent ) override; }; diff --git a/include/widgets/widget_hotkey_list.h b/include/widgets/widget_hotkey_list.h index 36f2bb84e1..78a6216b17 100644 --- a/include/widgets/widget_hotkey_list.h +++ b/include/widgets/widget_hotkey_list.h @@ -67,6 +67,15 @@ class WIDGET_HOTKEY_LIST : public TWO_COLUMN_TREE_LIST */ void UpdateFromClientData(); + /** + * Method updateShownItems + * + * Update the items shown in the widget based on a given filter string. + * + * @param aFilterStr the string to filter with. Empty means no filter. + */ + void updateShownItems( const wxString& aFilterStr ); + protected: /** @@ -147,6 +156,15 @@ public: */ void InstallOnPanel( wxPanel* aPanel ); + /** + * Method ApplyFilterString + * Apply a filter string to the hotkey list, selecting which hotkeys + * to show. + * + * @param aFilterStr the string to filter by + */ + void ApplyFilterString( const wxString& aFilterStr ); + /** * Set hotkeys in the control to default or original values. * @param aResetToDefault if true,.reset to the defaults inherent to the