From 18df4442bc3259b21d800658ebe2df4767958cf3 Mon Sep 17 00:00:00 2001 From: Mike Williams Date: Thu, 26 Jan 2023 12:35:15 -0500 Subject: [PATCH] Schematic: Find and Replace on Selection Fixes: https://gitlab.com/kicad/code/kicad/-/issues/9293 --- eeschema/dialogs/dialog_schematic_find.cpp | 45 +++---- .../dialogs/dialog_schematic_find_base.cpp | 9 +- .../dialogs/dialog_schematic_find_base.fbp | 92 ++++++++++++- eeschema/dialogs/dialog_schematic_find_base.h | 8 +- eeschema/eeschema_config.cpp | 2 + eeschema/eeschema_settings.h | 1 + eeschema/tools/sch_find_replace_tool.cpp | 122 ++++++++++++------ eeschema/tools/sch_find_replace_tool.h | 2 + include/eda_search_data.h | 4 +- 9 files changed, 210 insertions(+), 75 deletions(-) diff --git a/eeschema/dialogs/dialog_schematic_find.cpp b/eeschema/dialogs/dialog_schematic_find.cpp index 620d781d11..65a746382d 100644 --- a/eeschema/dialogs/dialog_schematic_find.cpp +++ b/eeschema/dialogs/dialog_schematic_find.cpp @@ -46,6 +46,7 @@ DIALOG_SCH_FIND::DIALOG_SCH_FIND( SCH_EDIT_FRAME* aParent, SCH_SEARCH_DATA* aDat m_buttonReplaceAll->Show( true ); m_staticReplace->Show( true ); m_comboReplace->Show( true ); + m_checkSelectedOnly->Show( true ); m_checkReplaceReferences->Show( true ); m_checkWildcardMatch->Show( false ); // Wildcard replace is not implemented. } @@ -59,6 +60,8 @@ DIALOG_SCH_FIND::DIALOG_SCH_FIND( SCH_EDIT_FRAME* aParent, SCH_SEARCH_DATA* aDat m_checkReplaceReferences->SetValue( m_findReplaceData->replaceReferences ); m_checkAllPins->SetValue( m_findReplaceData->searchAllPins ); m_checkCurrentSheetOnly->SetValue( m_findReplaceData->searchCurrentSheetOnly ); + m_checkCurrentSheetOnly->Enable( !m_findReplaceData->searchSelectedOnly ); + m_checkSelectedOnly->SetValue( m_findReplaceData->searchSelectedOnly ); m_buttonFind->SetDefault(); SetInitialFocus( m_comboFind ); @@ -111,8 +114,8 @@ void DIALOG_SCH_FIND::OnCancel( wxCommandEvent& aEvent ) void DIALOG_SCH_FIND::OnUpdateReplaceUI( wxUpdateUIEvent& aEvent ) { - aEvent.Enable( HasFlag( wxFR_REPLACEDIALOG ) && !m_comboFind->GetValue().empty() && - m_findReplaceTool->HasMatch() ); + aEvent.Enable( HasFlag( wxFR_REPLACEDIALOG ) && !m_comboFind->GetValue().empty() + && m_findReplaceTool->HasMatch() ); } @@ -198,11 +201,11 @@ void DIALOG_SCH_FIND::OnOptions( wxCommandEvent& aEvent ) void DIALOG_SCH_FIND::updateFlags() { // Rebuild the search flags in m_findReplaceData from dialog settings - - if( m_checkMatchCase->GetValue() ) - m_findReplaceData->matchCase = true; - else - m_findReplaceData->matchCase = false; + m_findReplaceData->matchCase = m_checkMatchCase->GetValue(); + m_findReplaceData->searchAllFields = m_checkAllFields->GetValue(); + m_findReplaceData->searchAllPins = m_checkAllPins->GetValue(); + m_findReplaceData->searchCurrentSheetOnly = m_checkCurrentSheetOnly->GetValue(); + m_findReplaceData->replaceReferences = m_checkReplaceReferences->GetValue(); if( m_checkWholeWord->GetValue() ) m_findReplaceData->matchMode = EDA_SEARCH_MATCH_MODE::WHOLEWORD; @@ -211,25 +214,17 @@ void DIALOG_SCH_FIND::updateFlags() else m_findReplaceData->matchMode = EDA_SEARCH_MATCH_MODE::PLAIN; - if( m_checkAllFields->GetValue() ) - m_findReplaceData->searchAllFields = true; + if( m_checkSelectedOnly->GetValue() ) + { + m_checkCurrentSheetOnly->SetValue( true ); + m_checkCurrentSheetOnly->Enable( false ); + m_findReplaceData->searchSelectedOnly = true; + } else - m_findReplaceData->searchAllFields = false; - - if( m_checkAllPins->GetValue() ) - m_findReplaceData->searchAllPins = true; - else - m_findReplaceData->searchAllPins = false; - - if( m_checkCurrentSheetOnly->GetValue() ) - m_findReplaceData->searchCurrentSheetOnly = true; - else - m_findReplaceData->searchCurrentSheetOnly = false; - - if( m_checkReplaceReferences->GetValue() ) - m_findReplaceData->replaceReferences = true; - else - m_findReplaceData->replaceReferences = false; + { + m_checkCurrentSheetOnly->Enable( true ); + m_findReplaceData->searchSelectedOnly = false; + } } diff --git a/eeschema/dialogs/dialog_schematic_find_base.cpp b/eeschema/dialogs/dialog_schematic_find_base.cpp index d056772a83..98c7661ee5 100644 --- a/eeschema/dialogs/dialog_schematic_find_base.cpp +++ b/eeschema/dialogs/dialog_schematic_find_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 26 2018) +// C++ code generated with wxFormBuilder (version 3.10.1-133-g388db8e4) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -98,10 +98,13 @@ DIALOG_SCH_FIND_BASE::DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id, con m_checkCurrentSheetOnly = new wxCheckBox( this, wxID_ANY, _("Search the current &sheet only"), wxDefaultPosition, wxDefaultSize, 0 ); gbSizer2->Add( m_checkCurrentSheetOnly, wxGBPosition( 3, 0 ), wxGBSpan( 1, 3 ), wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + m_checkSelectedOnly = new wxCheckBox( this, wxID_ANY, _("Search the current selection &only"), wxDefaultPosition, wxDefaultSize, 0 ); + gbSizer2->Add( m_checkSelectedOnly, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALL, 5 ); + m_checkReplaceReferences = new wxCheckBox( this, wxID_ANY, _("Replace matches in reference designators"), wxDefaultPosition, wxDefaultSize, 0 ); m_checkReplaceReferences->Hide(); - gbSizer2->Add( m_checkReplaceReferences, wxGBPosition( 4, 0 ), wxGBSpan( 1, 3 ), wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + gbSizer2->Add( m_checkReplaceReferences, wxGBPosition( 5, 0 ), wxGBSpan( 1, 3 ), wxBOTTOM|wxRIGHT|wxLEFT, 5 ); leftSizer->Add( gbSizer2, 1, wxEXPAND, 5 ); @@ -160,6 +163,7 @@ DIALOG_SCH_FIND_BASE::DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id, con m_checkAllPins->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnOptions ), NULL, this ); m_checkAllFields->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnOptions ), NULL, this ); m_checkCurrentSheetOnly->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnOptions ), NULL, this ); + m_checkSelectedOnly->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnOptions ), NULL, this ); m_buttonFind->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnFind ), NULL, this ); m_buttonReplace->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnReplace ), NULL, this ); m_buttonReplace->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateReplaceUI ), NULL, this ); @@ -187,6 +191,7 @@ DIALOG_SCH_FIND_BASE::~DIALOG_SCH_FIND_BASE() m_checkAllPins->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnOptions ), NULL, this ); m_checkAllFields->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnOptions ), NULL, this ); m_checkCurrentSheetOnly->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnOptions ), NULL, this ); + m_checkSelectedOnly->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnOptions ), NULL, this ); m_buttonFind->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnFind ), NULL, this ); m_buttonReplace->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnReplace ), NULL, this ); m_buttonReplace->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateReplaceUI ), NULL, this ); diff --git a/eeschema/dialogs/dialog_schematic_find_base.fbp b/eeschema/dialogs/dialog_schematic_find_base.fbp index 5f3dec880c..0ba320e9a3 100644 --- a/eeschema/dialogs/dialog_schematic_find_base.fbp +++ b/eeschema/dialogs/dialog_schematic_find_base.fbp @@ -36,6 +36,7 @@ wxBOTH 1 + 0 1 impl_virtual @@ -122,6 +123,7 @@ Dock 0 Left + 0 1 1 @@ -184,6 +186,7 @@ Dock 0 Left + 0 1 1 @@ -252,6 +255,7 @@ Dock 0 Left + 0 1 1 @@ -314,6 +318,7 @@ Dock 0 Left + 0 1 1 @@ -382,6 +387,7 @@ Dock 0 Left + 0 1 1 @@ -452,6 +458,7 @@ Dock 0 Left + 0 1 1 @@ -516,6 +523,7 @@ Dock 0 Left + 0 1 1 @@ -603,6 +611,7 @@ Dock 0 Left + 0 1 1 @@ -671,6 +680,7 @@ Dock 0 Left + 0 1 1 @@ -739,6 +749,7 @@ Dock 0 Left + 0 1 1 @@ -807,6 +818,7 @@ Dock 0 Left + 0 1 1 @@ -875,6 +887,7 @@ Dock 0 Left + 0 1 1 @@ -943,6 +956,7 @@ Dock 0 Left + 0 1 1 @@ -984,9 +998,9 @@ 5 - 3 + 1 0 - wxBOTTOM|wxRIGHT|wxLEFT + wxALL 4 1 @@ -1011,6 +1025,76 @@ Dock 0 Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Search the current selection &only + + 0 + + + 0 + + 1 + m_checkSelectedOnly + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnOptions + + + + 5 + 3 + 0 + wxBOTTOM|wxRIGHT|wxLEFT + 5 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 1 1 @@ -1092,6 +1176,7 @@ Dock 0 Left + 0 1 1 @@ -1166,6 +1251,7 @@ Dock 0 Left + 0 1 1 @@ -1241,6 +1327,7 @@ Dock 0 Left + 0 1 1 @@ -1316,6 +1403,7 @@ Dock 0 Left + 0 1 1 diff --git a/eeschema/dialogs/dialog_schematic_find_base.h b/eeschema/dialogs/dialog_schematic_find_base.h index cb65703ff4..a112193163 100644 --- a/eeschema/dialogs/dialog_schematic_find_base.h +++ b/eeschema/dialogs/dialog_schematic_find_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 26 2018) +// C++ code generated with wxFormBuilder (version 3.10.1-133-g388db8e4) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -22,10 +22,10 @@ #include #include #include +#include #include #include #include -#include #include /////////////////////////////////////////////////////////////////////////// @@ -52,13 +52,14 @@ class DIALOG_SCH_FIND_BASE : public DIALOG_SHIM wxCheckBox* m_checkAllPins; wxCheckBox* m_checkAllFields; wxCheckBox* m_checkCurrentSheetOnly; + wxCheckBox* m_checkSelectedOnly; wxCheckBox* m_checkReplaceReferences; wxButton* m_buttonFind; wxButton* m_buttonReplace; wxButton* m_buttonReplaceAll; wxButton* m_buttonCancel; - // Virtual event handlers, overide them in your derived class + // Virtual event handlers, override them in your derived class virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); } virtual void OnSearchForSelect( wxCommandEvent& event ) { event.Skip(); } @@ -79,6 +80,7 @@ class DIALOG_SCH_FIND_BASE : public DIALOG_SHIM public: DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Find"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~DIALOG_SCH_FIND_BASE(); }; diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index 39ee825596..35012c8e2d 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -174,6 +174,7 @@ void SCH_EDIT_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg ) searchData->searchAllFields = eeconfig()->m_FindReplaceExtra.search_all_fields; searchData->searchAllPins = eeconfig()->m_FindReplaceExtra.search_all_pins; searchData->searchCurrentSheetOnly = eeconfig()->m_FindReplaceExtra.search_current_sheet_only; + searchData->searchSelectedOnly = eeconfig()->m_FindReplaceExtra.search_selected_only; } GetRenderSettings()->m_ShowPinsElectricalType = false; @@ -205,6 +206,7 @@ void SCH_EDIT_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg ) eeconfig()->m_FindReplaceExtra.search_all_pins = searchData->searchAllPins; eeconfig()->m_FindReplaceExtra.search_current_sheet_only = searchData->searchCurrentSheetOnly; + eeconfig()->m_FindReplaceExtra.search_selected_only = searchData->searchSelectedOnly; } } } diff --git a/eeschema/eeschema_settings.h b/eeschema/eeschema_settings.h index f7d0151e43..70daf8ee8a 100644 --- a/eeschema/eeschema_settings.h +++ b/eeschema/eeschema_settings.h @@ -252,6 +252,7 @@ public: bool search_all_fields; bool search_all_pins; bool search_current_sheet_only; + bool search_selected_only; bool replace_references; }; diff --git a/eeschema/tools/sch_find_replace_tool.cpp b/eeschema/tools/sch_find_replace_tool.cpp index d097b559fb..002879fd22 100644 --- a/eeschema/tools/sch_find_replace_tool.cpp +++ b/eeschema/tools/sch_find_replace_tool.cpp @@ -39,6 +39,8 @@ int SCH_FIND_REPLACE_TOOL::FindAndReplace( const TOOL_EVENT& aEvent ) int SCH_FIND_REPLACE_TOOL::UpdateFind( const TOOL_EVENT& aEvent ) { EDA_SEARCH_DATA& data = m_frame->GetFindReplaceData(); + SCH_SEARCH_DATA* schSearchData = dynamic_cast( &data ); + bool selectedOnly = schSearchData ? schSearchData->searchSelectedOnly : false; auto visit = [&]( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheet ) @@ -48,7 +50,8 @@ int SCH_FIND_REPLACE_TOOL::UpdateFind( const TOOL_EVENT& aEvent ) // closed....so we need to double check the dialog is open. if( m_frame->m_findReplaceDialog != nullptr && !data.findString.IsEmpty() - && aItem->Matches( data, aSheet ) ) + && aItem->Matches( data, aSheet ) + && ( !selectedOnly || aItem->IsSelected() ) ) { aItem->SetForceVisible( true ); m_selectionTool->BrightenItem( aItem ); @@ -65,7 +68,6 @@ int SCH_FIND_REPLACE_TOOL::UpdateFind( const TOOL_EVENT& aEvent ) || aEvent.IsAction( &ACTIONS::updateFind ) ) { m_foundItemHighlighted = false; - m_selectionTool->ClearSelection(); for( SCH_ITEM* item : m_frame->GetScreen()->Items() ) { @@ -78,8 +80,17 @@ int SCH_FIND_REPLACE_TOOL::UpdateFind( const TOOL_EVENT& aEvent ) } ); } } - else if( aEvent.Matches( EVENTS::SelectedItemsModified ) ) + else if( aEvent.Matches( EVENTS::SelectedItemsModified ) + || aEvent.Matches( EVENTS::PointSelectedEvent ) + || aEvent.Matches( EVENTS::SelectedEvent ) + || aEvent.Matches( EVENTS::UnselectedEvent ) ) { + // Normal find modifies the selection, but selection-based find does + // not so we want to start over in the items we are searching through when + // the selection changes + if( selectedOnly ) + m_afterItem = nullptr; + for( EDA_ITEM* item : m_selectionTool->GetSelection() ) visit( item, &m_frame->GetCurrentSheet() ); } @@ -111,35 +122,45 @@ SCH_ITEM* SCH_FIND_REPLACE_TOOL::nextMatch( SCH_SCREEN* aScreen, SCH_SHEET_PATH* SCH_ITEM* aAfter, EDA_SEARCH_DATA& aData, bool reversed ) { + SCH_SEARCH_DATA* schSearchData = dynamic_cast( &aData ); + bool selectedOnly = schSearchData ? schSearchData->searchSelectedOnly : false; bool past_item = !aAfter; std::vector sorted_items; - for( SCH_ITEM* item : aScreen->Items() ) - { - sorted_items.push_back( item ); + auto addItem = + [&](SCH_ITEM* item) + { + sorted_items.push_back( item ); - if( item->Type() == SCH_SYMBOL_T ) - { - SCH_SYMBOL* cmp = static_cast( item ); + if( item->Type() == SCH_SYMBOL_T ) + { + SCH_SYMBOL* cmp = static_cast( item ); - for( SCH_FIELD& field : cmp->GetFields() ) - sorted_items.push_back( &field ); + for( SCH_FIELD& field : cmp->GetFields() ) + sorted_items.push_back( &field ); - for( SCH_PIN* pin : cmp->GetPins() ) - sorted_items.push_back( pin ); - } + for( SCH_PIN* pin : cmp->GetPins() ) + sorted_items.push_back( pin ); + } - if( item->Type() == SCH_SHEET_T ) - { - SCH_SHEET* sheet = static_cast( item ); + if( item->Type() == SCH_SHEET_T ) + { + SCH_SHEET* sheet = static_cast( item ); - for( SCH_FIELD& field : sheet->GetFields() ) - sorted_items.push_back( &field ); + for( SCH_FIELD& field : sheet->GetFields() ) + sorted_items.push_back( &field ); - for( SCH_SHEET_PIN* pin : sheet->GetPins() ) - sorted_items.push_back( pin ); - } - } + for( SCH_SHEET_PIN* pin : sheet->GetPins() ) + sorted_items.push_back( pin ); + } + }; + + if( selectedOnly ) + for( EDA_ITEM* item : m_selectionTool->GetSelection() ) + addItem( static_cast( item ) ); + else + for( SCH_ITEM* item : aScreen->Items() ) + addItem( item ); std::sort( sorted_items.begin(), sorted_items.end(), [&]( SCH_ITEM* a, SCH_ITEM* b ) @@ -181,14 +202,18 @@ SCH_ITEM* SCH_FIND_REPLACE_TOOL::nextMatch( SCH_SCREEN* aScreen, SCH_SHEET_PATH* int SCH_FIND_REPLACE_TOOL::FindNext( const TOOL_EVENT& aEvent ) { - EDA_SEARCH_DATA& data = m_frame->GetFindReplaceData(); + EDA_SEARCH_DATA& data = m_frame->GetFindReplaceData(); bool searchAllSheets = false; - bool isReversed = aEvent.IsAction( &ACTIONS::findPrevious ); + bool selectedOnly = false; + bool isReversed = aEvent.IsAction( &ACTIONS::findPrevious ); + SCH_ITEM* item = nullptr; + SCH_SHEET_PATH* afterSheet = &m_frame->GetCurrentSheet(); try { const SCH_SEARCH_DATA& schSearchData = dynamic_cast( data ); searchAllSheets = !( schSearchData.searchCurrentSheetOnly ); + selectedOnly = schSearchData.searchSelectedOnly; } catch( const std::bad_cast& ) { @@ -199,24 +224,16 @@ int SCH_FIND_REPLACE_TOOL::FindNext( const TOOL_EVENT& aEvent ) else if( data.findString.IsEmpty() ) return FindAndReplace( ACTIONS::find.MakeEvent() ); - EE_SELECTION& selection = m_selectionTool->GetSelection(); - SCH_ITEM* afterItem = dynamic_cast( selection.Front() ); - SCH_ITEM* item = nullptr; - - SCH_SHEET_PATH* afterSheet = &m_frame->GetCurrentSheet(); - if( m_wrapAroundTimer.IsRunning() ) { afterSheet = nullptr; - afterItem = nullptr; + m_afterItem = nullptr; m_wrapAroundTimer.Stop(); m_frame->ClearFindReplaceStatus(); } - m_selectionTool->ClearSelection(); - if( afterSheet || !searchAllSheets ) - item = nextMatch( m_frame->GetScreen(), &m_frame->GetCurrentSheet(), afterItem, data, + item = nextMatch( m_frame->GetScreen(), &m_frame->GetCurrentSheet(), m_afterItem, data, isReversed ); if( !item && searchAllSheets ) @@ -272,6 +289,8 @@ int SCH_FIND_REPLACE_TOOL::FindNext( const TOOL_EVENT& aEvent ) if( item ) { + m_afterItem = item; + if( !item->IsBrightened() ) { // Clear any previous brightening @@ -283,7 +302,12 @@ int SCH_FIND_REPLACE_TOOL::FindNext( const TOOL_EVENT& aEvent ) m_foundItemHighlighted = true; } - m_selectionTool->AddItemToSel( item ); + if( !selectedOnly ) + { + m_selectionTool->ClearSelection(); + m_selectionTool->AddItemToSel( item ); + } + m_frame->FocusOnLocation( item->GetBoundingBox().GetCenter() ); m_frame->GetCanvas()->Refresh(); } @@ -301,26 +325,34 @@ int SCH_FIND_REPLACE_TOOL::FindNext( const TOOL_EVENT& aEvent ) return 0; } +EDA_ITEM* SCH_FIND_REPLACE_TOOL::getCurrentMatch() +{ + EDA_SEARCH_DATA& data = m_frame->GetFindReplaceData(); + SCH_SEARCH_DATA* schSearchData = dynamic_cast( &data ); + bool selectedOnly = schSearchData ? schSearchData->searchSelectedOnly : false; + + return selectedOnly ? m_afterItem : m_selectionTool->GetSelection().Front(); +} bool SCH_FIND_REPLACE_TOOL::HasMatch() { EDA_SEARCH_DATA& data = m_frame->GetFindReplaceData(); - EDA_ITEM* item = m_selectionTool->GetSelection().Front(); + EDA_ITEM* match = getCurrentMatch(); - return item && item->Matches( data, &m_frame->GetCurrentSheet() ); + return match && match->Matches( data, &m_frame->GetCurrentSheet() ); } int SCH_FIND_REPLACE_TOOL::ReplaceAndFindNext( const TOOL_EVENT& aEvent ) { EDA_SEARCH_DATA& data = m_frame->GetFindReplaceData(); - EDA_ITEM* item = m_selectionTool->GetSelection().Front(); + EDA_ITEM* item = getCurrentMatch(); SCH_SHEET_PATH* sheet = &m_frame->GetCurrentSheet(); if( data.findString.IsEmpty() ) return FindAndReplace( ACTIONS::find.MakeEvent() ); - if( item && item->Matches( data, sheet ) ) + if( item && HasMatch() ) { SCH_ITEM* sch_item = static_cast( item ); @@ -344,11 +376,13 @@ int SCH_FIND_REPLACE_TOOL::ReplaceAll( const TOOL_EVENT& aEvent ) { EDA_SEARCH_DATA& data = m_frame->GetFindReplaceData(); bool currentSheetOnly = false; + bool selectedOnly = false; try { const SCH_SEARCH_DATA& schSearchData = dynamic_cast( data ); currentSheetOnly = schSearchData.searchCurrentSheetOnly; + selectedOnly = schSearchData.searchSelectedOnly; } catch( const std::bad_cast& ) { @@ -372,7 +406,7 @@ int SCH_FIND_REPLACE_TOOL::ReplaceAll( const TOOL_EVENT& aEvent ) } }; - if( currentSheetOnly ) + if( currentSheetOnly || selectedOnly ) { SCH_SHEET_PATH* currentSheet = &m_frame->GetCurrentSheet(); @@ -380,7 +414,9 @@ int SCH_FIND_REPLACE_TOOL::ReplaceAll( const TOOL_EVENT& aEvent ) while( item ) { - doReplace( item, currentSheet, data ); + if( !selectedOnly || item->IsSelected() ) + doReplace( item, currentSheet, data ); + item = nextMatch( m_frame->GetScreen(), currentSheet, item, data, false ); } } @@ -454,4 +490,6 @@ void SCH_FIND_REPLACE_TOOL::setTransitions() Go( &SCH_FIND_REPLACE_TOOL::UpdateFind, EVENTS::SelectedItemsModified ); Go( &SCH_FIND_REPLACE_TOOL::UpdateFind, EVENTS::PointSelectedEvent ); Go( &SCH_FIND_REPLACE_TOOL::UpdateFind, EVENTS::SelectedEvent ); + Go( &SCH_FIND_REPLACE_TOOL::UpdateFind, EVENTS::UnselectedEvent ); + Go( &SCH_FIND_REPLACE_TOOL::UpdateFind, EVENTS::ClearedEvent ); } diff --git a/eeschema/tools/sch_find_replace_tool.h b/eeschema/tools/sch_find_replace_tool.h index ec60473c00..9d0a12376d 100644 --- a/eeschema/tools/sch_find_replace_tool.h +++ b/eeschema/tools/sch_find_replace_tool.h @@ -83,8 +83,10 @@ private: */ SCH_ITEM* nextMatch( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aSheet, SCH_ITEM* aAfter, EDA_SEARCH_DATA& aData, bool reverse ); + EDA_ITEM* getCurrentMatch(); private: + SCH_ITEM* m_afterItem = nullptr; bool m_foundItemHighlighted; wxTimer m_wrapAroundTimer; // A timer during which a subsequent FindNext will // result in a wrap-around diff --git a/include/eda_search_data.h b/include/eda_search_data.h index 22bb22555e..0b112b0573 100644 --- a/include/eda_search_data.h +++ b/include/eda_search_data.h @@ -62,6 +62,7 @@ struct SCH_SEARCH_DATA : public EDA_SEARCH_DATA bool searchAllFields; bool searchAllPins; bool searchCurrentSheetOnly; + bool searchSelectedOnly; bool replaceReferences; @@ -70,9 +71,10 @@ struct SCH_SEARCH_DATA : public EDA_SEARCH_DATA searchAllFields( false ), searchAllPins( false ), searchCurrentSheetOnly( false ), + searchSelectedOnly( false ), replaceReferences( false ) { } }; -#endif \ No newline at end of file +#endif