From 2e5be574996cff2fc923937f4b51bc6e35b1427e Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Thu, 24 Jul 2025 13:13:42 -0700 Subject: [PATCH] Pass hotkeys from search pane to frame If the search pane doesn't handle the key, push it through the frame hotkey handling system Fixes https://gitlab.com/kicad/code/kicad/-/issues/12474 (cherry picked from commit 322c08d5f0de3b9fc37c93c69db79b3f2a26efdf) --- common/widgets/search_pane.cpp | 26 +++++++ common/widgets/search_pane_tab.cpp | 111 +++++++++++++++++++++++------ include/widgets/search_pane.h | 2 + 3 files changed, 118 insertions(+), 21 deletions(-) diff --git a/common/widgets/search_pane.cpp b/common/widgets/search_pane.cpp index e6fec4ddbe..51dac6e9bd 100644 --- a/common/widgets/search_pane.cpp +++ b/common/widgets/search_pane.cpp @@ -21,6 +21,8 @@ #include #include +#include +#include #include #include #include @@ -120,6 +122,7 @@ SEARCH_PANE::SEARCH_PANE( EDA_DRAW_FRAME* aFrame ) : } ); m_frame->Bind( wxEVT_AUI_PANE_CLOSE, &SEARCH_PANE::OnClosed, this ); + Bind( wxEVT_CHAR_HOOK, &SEARCH_PANE::OnCharHook, this ); } @@ -127,6 +130,7 @@ SEARCH_PANE::~SEARCH_PANE() { m_frame->Unbind( wxEVT_AUI_PANE_CLOSE, &SEARCH_PANE::OnClosed, this ); m_frame->Unbind( EDA_LANG_CHANGED, &SEARCH_PANE::OnLanguageChange, this ); + Unbind( wxEVT_CHAR_HOOK, &SEARCH_PANE::OnCharHook, this ); m_handlers.clear(); @@ -216,3 +220,25 @@ SEARCH_PANE_TAB* SEARCH_PANE::GetCurrentTab() const { return dynamic_cast( m_notebook->GetCurrentPage() ); } + + +void SEARCH_PANE::OnCharHook( wxKeyEvent& aEvent ) +{ + // Check if the event is from a child window of the search pane + wxWindow* eventObject = dynamic_cast( aEvent.GetEventObject() ); + + if( !eventObject || !IsDescendant( eventObject ) ) + { + aEvent.Skip(); + return; + } + + // Try to let the tool framework handle the event + if( m_frame->GetToolDispatcher() ) + { + m_frame->GetToolDispatcher()->DispatchWxEvent( aEvent ); + return; + } + + aEvent.Skip(); +} diff --git a/common/widgets/search_pane_tab.cpp b/common/widgets/search_pane_tab.cpp index bea60cac4c..f837f0c61c 100644 --- a/common/widgets/search_pane_tab.cpp +++ b/common/widgets/search_pane_tab.cpp @@ -150,42 +150,111 @@ void SEARCH_PANE_LISTVIEW::OnColClicked( wxListEvent& aEvent ) void SEARCH_PANE_LISTVIEW::OnChar( wxKeyEvent& aEvent ) { - if( aEvent.GetKeyCode() == WXK_CONTROL_A ) + bool handled = false; + + switch( aEvent.GetKeyCode() ) { - // Select All - for( int row = 0; row < GetItemCount(); row++ ) - SetItemState( row, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED ); - } - else if( aEvent.GetKeyCode() == WXK_CONTROL_C ) - { - // Copy to clipboard the selected rows - if( wxTheClipboard->Open() ) + case WXK_CONTROL_A: { - wxString txt; - + // Select All for( int row = 0; row < GetItemCount(); row++ ) + SetItemState( row, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED ); + + handled = true; + break; + } + + case WXK_CONTROL_C: + { + // Copy to clipboard the selected rows + if( wxTheClipboard->Open() ) { - if( GetItemState( row, wxLIST_STATE_SELECTED ) == wxLIST_STATE_SELECTED ) + wxString txt; + + for( int row = 0; row < GetItemCount(); row++ ) { - for( int col = 0; col < GetColumnCount(); col++ ) + if( GetItemState( row, wxLIST_STATE_SELECTED ) == wxLIST_STATE_SELECTED ) { - if( GetColumnWidth( col ) > 0 ) + for( int col = 0; col < GetColumnCount(); col++ ) { - txt += GetItemText( row, col ); + if( GetColumnWidth( col ) > 0 ) + { + txt += GetItemText( row, col ); - if( row <= GetItemCount() - 1 ) - txt += wxT( "\t" ); + if( row <= GetItemCount() - 1 ) + txt += wxT( "\t" ); + } } - } - txt += wxT( "\n" ); + txt += wxT( "\n" ); + } } + + wxTheClipboard->SetData( new wxTextDataObject( txt ) ); + wxTheClipboard->Close(); } - wxTheClipboard->SetData( new wxTextDataObject( txt ) ); - wxTheClipboard->Close(); + handled = true; + break; + } + + case WXK_DOWN: + case WXK_NUMPAD_DOWN: + { + // Move selection down + long focused = GetFocusedItem(); + if( focused < 0 ) + focused = 0; + + if( focused < GetItemCount() - 1 ) + { + if( !(aEvent.GetModifiers() & wxMOD_SHIFT) ) + { + int next = -1; + + while( ( next = GetNextSelected( next ) ) != wxNOT_FOUND ) + Select( next, false ); + } + + ++focused; + Focus( focused ); + Select( focused ); + } + + handled = true; + break; + } + case WXK_UP: + case WXK_NUMPAD_UP: + { + // Move selection up + long focused = GetFocusedItem(); + + if( focused < 0 ) + focused = 0; + + if( focused > 0 ) + { + if( !(aEvent.GetModifiers() & wxMOD_SHIFT) ) + { + int next = -1; + + while( ( next = GetNextSelected( next ) ) != wxNOT_FOUND ) + Select( next, false ); + } + + --focused; + Focus( focused ); + Select( focused ); + } + + handled = true; + break; } } + + if( !handled ) + aEvent.Skip(); } diff --git a/include/widgets/search_pane.h b/include/widgets/search_pane.h index 19aa5974ca..c098d42095 100644 --- a/include/widgets/search_pane.h +++ b/include/widgets/search_pane.h @@ -81,6 +81,8 @@ public: void FocusSearch(); void ClearAllResults(); + void OnCharHook( wxKeyEvent& aEvent ); + protected: void OnLanguageChange( wxCommandEvent& aEvent ); SEARCH_PANE_TAB* GetCurrentTab() const;