From d9e0ab02416e5168aa16cb2f8678a3e88bdaa5a0 Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Thu, 1 Dec 2011 11:49:28 -0500 Subject: [PATCH] Improve Eeschema find code and add initial replace plumbing. * Replace Eeschema find code with a collector based implementation. * Fixed a search bug when all subsequent searches of an item would ignore the remaining valid child items when an item had more than one child item that matched the search criteria. * Add SCH_FIND_COLLECTOR class to find all items that meet the specified search criteria. * Add SCH_FIND_COLLECT0R_DATA to keep track of information for all matching items. * Use collector to iterate over the list of items that match the search criteria rather than trying to start at the last matched item. * Remove unused searching methods from sheet path and sheet path list objects. * Add replace and replace all functionality to Eeschema find dialog. * Push matching methods down to EDA_ITEM class so they can be used by other derived objects. * Add method to EDA_ITEM to test if item supports replacing. * Add flag to find/replace data to support replace feature. * Disable wild card matching check box when dialog is in replace mode as wild card replacement is not supported at this time. * The usual Doxygen comment and coding policy fixes. --- common/common.cpp | 21 +-- common/sch_item_struct.cpp | 3 +- eeschema/dialogs/dialog_sch_find.fbp | 12 +- eeschema/dialogs/dialog_schematic_find.cpp | 40 +++++- eeschema/dialogs/dialog_schematic_find.h | 41 +++++- .../dialogs/dialog_schematic_find_base.cpp | 12 +- eeschema/dialogs/dialog_schematic_find_base.h | 2 + eeschema/find.cpp | 103 +++++++++++---- eeschema/help_common_strings.h | 2 +- eeschema/lib_pin.cpp | 23 ++++ eeschema/lib_pin.h | 7 +- eeschema/menubar.cpp | 4 + eeschema/sch_collectors.cpp | 114 ++++++++++++++++- eeschema/sch_collectors.h | 117 +++++++++++++++-- eeschema/sch_component.cpp | 68 +--------- eeschema/sch_component.h | 5 + eeschema/sch_field.cpp | 5 + eeschema/sch_field.h | 5 + eeschema/sch_sheet.cpp | 8 +- eeschema/sch_sheet.h | 5 + eeschema/sch_sheet_path.cpp | 120 +----------------- eeschema/sch_sheet_path.h | 31 +---- eeschema/sch_sheet_pin.cpp | 16 ++- eeschema/sch_text.cpp | 2 + eeschema/sch_text.h | 5 + eeschema/schframe.cpp | 26 ++-- eeschema/tool_sch.cpp | 3 + include/base_struct.h | 120 +++++++++++------- include/class_collector.h | 84 ++++++------ include/common.h | 2 +- include/sch_item_struct.h | 4 + include/wxEeschemaStruct.h | 4 + pcbnew/block.cpp | 2 +- 33 files changed, 627 insertions(+), 389 deletions(-) diff --git a/common/common.cpp b/common/common.cpp index 65a9be0c62..804e0ee5cb 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -410,39 +410,32 @@ int ReturnValueFromString( EDA_UNITS_T aUnit, const wxString& TextValue, int Int } -/** - * Function wxStringSplit - * Split a String to a String List when founding 'splitter' - * @return the list - * @param txt : wxString : a String text - * @param splitter : wxChar : the 'split' character - */ -wxArrayString* wxStringSplit( wxString txt, wxChar splitter ) +wxArrayString* wxStringSplit( wxString aString, wxChar aSplitter ) { wxArrayString* list = new wxArrayString(); while( 1 ) { - int index = txt.Find( splitter ); + int index = aString.Find( aSplitter ); + if( index == wxNOT_FOUND ) break; wxString tmp; - tmp = txt.Mid( 0, index ); - txt = txt.Mid( index + 1, txt.size() - index ); + tmp = aString.Mid( 0, index ); + aString = aString.Mid( index + 1, aString.size() - index ); list->Add( tmp ); } - if( !txt.IsEmpty() ) + if( !aString.IsEmpty() ) { - list->Add( txt ); + list->Add( aString ); } return list; } - /** * Function To_User_Unit * Convert in inch or mm the variable "val" (double)given in internal units diff --git a/common/sch_item_struct.cpp b/common/sch_item_struct.cpp index b1edf1d07d..9a1c2af65a 100644 --- a/common/sch_item_struct.cpp +++ b/common/sch_item_struct.cpp @@ -39,7 +39,8 @@ #include "general.h" #include "protos.h" -#include "../eeschema/dialogs/dialog_schematic_find.h" + +const wxString traceFindReplace( wxT( "KicadFindReplace" ) ); bool sort_schematic_items( const SCH_ITEM* aItem1, const SCH_ITEM* aItem2 ) diff --git a/eeschema/dialogs/dialog_sch_find.fbp b/eeschema/dialogs/dialog_sch_find.fbp index b12bf2a5b8..eedab154d4 100644 --- a/eeschema/dialogs/dialog_sch_find.fbp +++ b/eeschema/dialogs/dialog_sch_find.fbp @@ -1059,7 +1059,7 @@ 1 - wxID_ANY + wxID_REPLACE &Replace @@ -1077,7 +1077,7 @@ - + OnReplace @@ -1100,7 +1100,7 @@ - + OnUpdateReplaceUI @@ -1116,7 +1116,7 @@ 1 - wxID_ANY + wxID_REPLACE_ALL Replace &All @@ -1134,7 +1134,7 @@ - + OnReplace @@ -1157,7 +1157,7 @@ - + OnUpdateReplaceUI diff --git a/eeschema/dialogs/dialog_schematic_find.cpp b/eeschema/dialogs/dialog_schematic_find.cpp index 4df84ee76c..9f221664af 100644 --- a/eeschema/dialogs/dialog_schematic_find.cpp +++ b/eeschema/dialogs/dialog_schematic_find.cpp @@ -16,8 +16,10 @@ DIALOG_SCH_FIND::DIALOG_SCH_FIND( wxWindow* aParent, wxFindReplaceData* aData, if( aStyle & wxFR_REPLACEDIALOG ) { + SetTitle( _( "Find and Replace" ) ); m_staticReplace->Show( true ); m_comboReplace->Show( true ); + m_checkWildcardMatch->Show( false ); // Wildcard replace is not implemented. } int flags = m_findReplaceData->GetFlags(); @@ -55,6 +57,13 @@ void DIALOG_SCH_FIND::OnUpdateFindUI( wxUpdateUIEvent& aEvent ) } +void DIALOG_SCH_FIND::OnUpdateReplaceUI( wxUpdateUIEvent& aEvent ) +{ + aEvent.Enable( HasFlag( wxFR_REPLACEDIALOG ) && !m_comboFind->GetValue().empty() && + (m_findReplaceData->GetFlags() | FR_REPLACE_ITEM_FOUND) ); +} + + void DIALOG_SCH_FIND::OnUpdateWholeWordUI( wxUpdateUIEvent& aEvent ) { aEvent.Enable( !m_checkWildcardMatch->GetValue() ); @@ -88,6 +97,27 @@ void DIALOG_SCH_FIND::OnFind( wxCommandEvent& aEvent ) } +void DIALOG_SCH_FIND::OnReplace( wxCommandEvent& aEvent ) +{ + int index = m_comboReplace->FindString( m_comboReplace->GetValue(), true ); + + if( index == wxNOT_FOUND ) + { + m_comboReplace->Insert( m_comboReplace->GetValue(), 0 ); + } + else if( index != 0 ) + { + /* Move the search string to the top of the list if it isn't already there. */ + wxString tmp = m_comboReplace->GetValue(); + m_comboReplace->Delete( index ); + m_comboReplace->Insert( tmp, 0 ); + m_comboReplace->SetSelection( 0 ); + } + + SendEvent( wxEVT_COMMAND_FIND ); +} + + void DIALOG_SCH_FIND::OnCancel( wxCommandEvent& aEvent ) { SendEvent( wxEVT_COMMAND_FIND_CLOSE ); @@ -101,13 +131,14 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType ) event.SetEventObject( this ); event.SetFindString( m_comboFind->GetValue() ); + int flags = 0; + if ( HasFlag( wxFR_REPLACEDIALOG ) ) { event.SetReplaceString( m_comboReplace->GetValue() ); + flags |= FR_SEARCH_REPLACE; } - int flags = 0; - if( m_radioForward->GetValue() ) flags |= wxFR_DOWN; @@ -117,7 +148,7 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType ) if( m_checkWholeWord->GetValue() ) flags |= wxFR_WHOLEWORD; - if( m_checkWildcardMatch->GetValue() ) + if( m_checkWildcardMatch->IsShown() && m_checkWildcardMatch->GetValue() ) flags |= FR_MATCH_WILDCARD; if( m_checkAllFields->GetValue() ) @@ -152,6 +183,9 @@ void DIALOG_SCH_FIND::SendEvent( const wxEventType& aEventType ) { GetParent()->GetEventHandler()->ProcessEvent( event ); } + + if( event.GetFlags() != flags ) + m_findReplaceData->SetFlags( event.GetFlags() ); } diff --git a/eeschema/dialogs/dialog_schematic_find.h b/eeschema/dialogs/dialog_schematic_find.h index 3771946a1d..0c17a37453 100644 --- a/eeschema/dialogs/dialog_schematic_find.h +++ b/eeschema/dialogs/dialog_schematic_find.h @@ -20,7 +20,7 @@ /** * Define schematic specific find and replace dialog flags based on the enum entries * in wxFindReplaceFlags. These flags are intended to be used as bit masks in the - * wxFindReplaceData::m_Flags member variable. The varialble is defined as a wxUint32. + * wxFindReplaceData::m_Flags member variable. The variable is defined as a wxUint32. */ enum SchematicFindReplaceFlags { @@ -44,7 +44,7 @@ enum SchematicFindReplaceFlags /// Don't warp cursor to found item until the dialog is closed. FR_NO_WARP_CURSOR = wxFR_MATCHCASE << 6, - /// Perform a search for a item that has repaceable text. + /// Perform a search for a item that has replaceable text. FR_SEARCH_REPLACE = wxFR_MATCHCASE << 7, /// Used by the search event handler to let the dialog know that a replaceable @@ -53,6 +53,40 @@ enum SchematicFindReplaceFlags }; +/** + * Class SCH_FIND_REPLACE_DATA + * adds missing useful comparison and assignment operators to the wxFindReplaceData object. + */ +class SCH_FIND_REPLACE_DATA : public wxFindReplaceData +{ +public: + + SCH_FIND_REPLACE_DATA& operator =( SCH_FIND_REPLACE_DATA& aFindReplaceData ) + { + if( this == &aFindReplaceData ) + return *this; + + SetFlags( aFindReplaceData.GetFlags() ); + SetFindString( aFindReplaceData.GetFindString() ); + SetReplaceString( aFindReplaceData.GetReplaceString() ); + + return *this; + } + + bool operator ==( SCH_FIND_REPLACE_DATA& aFindReplaceData ) + { + return ( (GetFlags() == aFindReplaceData.GetFlags()) + && (GetFindString() == aFindReplaceData.GetFindString()) + && (GetReplaceString() == aFindReplaceData.GetReplaceString()) ); + } + + bool operator !=( SCH_FIND_REPLACE_DATA& aFindReplaceData ) + { + return !( *this == aFindReplaceData ); + } +}; + + /** Implementing DIALOG_SCH_FIND_BASE */ class DIALOG_SCH_FIND : public DIALOG_SCH_FIND_BASE { @@ -60,9 +94,12 @@ protected: // Handlers for DIALOG_SCH_FIND_BASE events. void OnClose( wxCloseEvent& aEvent ); void OnUpdateFindUI( wxUpdateUIEvent& aEvent ); + void OnUpdateReplaceUI( wxUpdateUIEvent& aEvent ); void OnUpdateWholeWordUI( wxUpdateUIEvent& aEvent ); void OnUpdateWildcardUI( wxUpdateUIEvent& aEvent ); + void OnFind( wxCommandEvent& aEvent ); + void OnReplace( wxCommandEvent& aEvent ); void OnCancel( wxCommandEvent& aEvent ); void SendEvent( const wxEventType& aEventType ); diff --git a/eeschema/dialogs/dialog_schematic_find_base.cpp b/eeschema/dialogs/dialog_schematic_find_base.cpp index deeb628051..c2c47caa98 100644 --- a/eeschema/dialogs/dialog_schematic_find_base.cpp +++ b/eeschema/dialogs/dialog_schematic_find_base.cpp @@ -101,12 +101,12 @@ DIALOG_SCH_FIND_BASE::DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id, con m_buttonFind->SetDefault(); rightSizer->Add( m_buttonFind, 0, wxALL|wxEXPAND, 6 ); - m_buttonReplace = new wxButton( this, wxID_ANY, _("&Replace"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonReplace = new wxButton( this, wxID_REPLACE, _("&Replace"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonReplace->Hide(); rightSizer->Add( m_buttonReplace, 0, wxALL, 5 ); - m_buttonReplaceAll = new wxButton( this, wxID_ANY, _("Replace &All"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonReplaceAll = new wxButton( this, wxID_REPLACE_ALL, _("Replace &All"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonReplaceAll->Hide(); rightSizer->Add( m_buttonReplaceAll, 0, wxALL, 5 ); @@ -130,6 +130,10 @@ DIALOG_SCH_FIND_BASE::DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id, con m_checkWildcardMatch->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateWildcardUI ), NULL, this ); m_buttonFind->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnFind ), NULL, this ); m_buttonFind->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateFindUI ), 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 ); + m_buttonReplaceAll->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnReplace ), NULL, this ); + m_buttonReplaceAll->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateReplaceUI ), NULL, this ); m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnCancel ), NULL, this ); } @@ -143,6 +147,10 @@ DIALOG_SCH_FIND_BASE::~DIALOG_SCH_FIND_BASE() m_checkWildcardMatch->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateWildcardUI ), NULL, this ); m_buttonFind->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnFind ), NULL, this ); m_buttonFind->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateFindUI ), 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 ); + m_buttonReplaceAll->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnReplace ), NULL, this ); + m_buttonReplaceAll->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_FIND_BASE::OnUpdateReplaceUI ), NULL, this ); m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_FIND_BASE::OnCancel ), NULL, this ); } diff --git a/eeschema/dialogs/dialog_schematic_find_base.h b/eeschema/dialogs/dialog_schematic_find_base.h index 18ef2e1e8e..f095ae5f12 100644 --- a/eeschema/dialogs/dialog_schematic_find_base.h +++ b/eeschema/dialogs/dialog_schematic_find_base.h @@ -61,6 +61,8 @@ class DIALOG_SCH_FIND_BASE : public wxDialog virtual void OnUpdateWildcardUI( wxUpdateUIEvent& event ) { event.Skip(); } virtual void OnFind( wxCommandEvent& event ) { event.Skip(); } virtual void OnUpdateFindUI( wxUpdateUIEvent& event ) { event.Skip(); } + virtual void OnReplace( wxCommandEvent& event ) { event.Skip(); } + virtual void OnUpdateReplaceUI( wxUpdateUIEvent& event ) { event.Skip(); } virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); } diff --git a/eeschema/find.cpp b/eeschema/find.cpp index 9d2b53292f..dd885ba049 100644 --- a/eeschema/find.cpp +++ b/eeschema/find.cpp @@ -297,60 +297,88 @@ SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& aReference, void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent ) { - static SCH_ITEM* lastItem = NULL; /* last item found when searching a match - * note: the actual matched item can be a - * part of lastItem (for instance a field in a component - */ - static wxString sheetFoundIn; - static wxPoint lastItemPosition; // the actual position of the matched sub item + static wxPoint itemPosition; // the actual position of the matched item. - SCH_SHEET_LIST schematic; - wxString msg; - wxFindReplaceData searchCriteria; - bool warpCursor = !( aEvent.GetFlags() & FR_NO_WARP_CURSOR ); + SCH_SHEET_LIST schematic; + wxString msg; + SCH_FIND_REPLACE_DATA searchCriteria; + bool warpCursor = !( aEvent.GetFlags() & FR_NO_WARP_CURSOR ); searchCriteria.SetFlags( aEvent.GetFlags() ); searchCriteria.SetFindString( aEvent.GetFindString() ); searchCriteria.SetReplaceString( aEvent.GetReplaceString() ); - if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE ) + if( searchCriteria != m_foundItems.GetFindReplaceData() ) { - sheetFoundIn = m_CurrentSheet->PathHumanReadable(); - warpCursor = true; - } - else if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 ) - { - sheetFoundIn = m_CurrentSheet->PathHumanReadable(); - lastItem = m_CurrentSheet->MatchNextItem( searchCriteria, lastItem, &lastItemPosition ); + if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE ) + { + warpCursor = true; + } + else if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 ) + { + m_foundItemIndex = 0; + m_foundItems.Collect( searchCriteria, m_CurrentSheet ); + } + else + { + m_foundItemIndex = 0; + m_foundItems.Collect( searchCriteria ); + } } else { - lastItem = schematic.MatchNextItem( searchCriteria, sheetFoundIn, lastItem, - &lastItemPosition ); + if( searchCriteria.GetFlags() & wxFR_DOWN ) + { + if( !(searchCriteria.GetFlags() & FR_SEARCH_WRAP) + && (m_foundItemIndex == (m_foundItems.GetCount() - 1)) ) + return; + + m_foundItemIndex += 1; + + if( (m_foundItemIndex >= m_foundItems.GetCount()) + && (searchCriteria.GetFlags() & FR_SEARCH_WRAP) ) + m_foundItemIndex = 0; + } + else + { + if( !(searchCriteria.GetFlags() & FR_SEARCH_WRAP) && (m_foundItemIndex == 0) ) + return; + + m_foundItemIndex -= 1; + + if( (m_foundItemIndex < 0) && (searchCriteria.GetFlags() & FR_SEARCH_WRAP) ) + m_foundItemIndex = m_foundItems.GetCount() - 1; + } } - if( lastItem != NULL ) + if( m_foundItems.GetCount() != 0 ) { - SCH_SHEET_PATH* sheet = schematic.GetSheet( sheetFoundIn ); + SCH_FIND_COLLECTOR_DATA data = m_foundItems.GetFindData( m_foundItemIndex ); - wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " + sheetFoundIn ) ); + wxLogTrace( traceFindReplace, wxT( "Found " ) + m_foundItems.GetText( m_foundItemIndex ) ); - if( sheet != GetSheet() ) + SCH_SHEET_PATH* sheet = schematic.GetSheet( data.GetSheetPath() ); + + wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " ) + + data.GetSheetPath() ); + + if( sheet->PathHumanReadable() != GetSheet()->PathHumanReadable() ) { sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() ); *m_CurrentSheet = *sheet; m_CurrentSheet->UpdateAllScreenReferences(); } - sheet->LastScreen()->SetCrossHairPosition( lastItemPosition ); + sheet->LastScreen()->SetCrossHairPosition( data.GetPosition() ); - RedrawScreen( lastItemPosition, warpCursor ); + RedrawScreen( data.GetPosition(), warpCursor ); - msg = lastItem->GetSelectMenuText() + _( " found in sheet " ) + sheetFoundIn; + aEvent.SetFlags( aEvent.GetFlags() | FR_REPLACE_ITEM_FOUND ); + msg = m_foundItems.GetText( m_foundItemIndex ); } else { - sheetFoundIn = wxEmptyString; + aEvent.SetFlags( aEvent.GetFlags() & ~FR_REPLACE_ITEM_FOUND ); msg.Printf( _( "No item found matching %s." ), GetChars( aEvent.GetFindString() ) ); } @@ -360,4 +388,23 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent ) void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent ) { + wxCHECK_RET( m_foundItems.IsValidIndex( m_foundItemIndex ), + wxT( "No last find item to replace text." ) ); + + SCH_FIND_COLLECTOR_DATA data = m_foundItems.GetFindData( m_foundItemIndex ); + + wxLogTrace( traceFindReplace, wxT( "Replacing %s with %s in item %s" ), + GetChars( aEvent.GetFindString() ), GetChars( aEvent.GetReplaceString() ), + GetChars( m_foundItems.GetText( m_foundItemIndex ) ) ); + + OnFindSchematicItem( aEvent ); + + if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_REPLACE_ALL ) + { + wxLogTrace( traceFindReplace, wxT( "Replacing %s with %s in item %s" ), + GetChars( aEvent.GetFindString() ), GetChars( aEvent.GetReplaceString() ), + GetChars( m_foundItems.GetText( m_foundItemIndex ) ) ); + + OnFindSchematicItem( aEvent ); + } } diff --git a/eeschema/help_common_strings.h b/eeschema/help_common_strings.h index d6c03ea4e4..6ab4e28728 100644 --- a/eeschema/help_common_strings.h +++ b/eeschema/help_common_strings.h @@ -25,7 +25,7 @@ // Schematic editor: #define HELP_FIND _( "Find components and texts" ) - +#define HELP_REPLACE _( "Find and replace text in schematic items" ) #define HELP_PLACE_COMPONENTS _( "Place a component" ) #define HELP_PLACE_POWERPORT _( "Place a power port" ) #define HELP_PLACE_WIRE _( "Place a wire" ) diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp index 57af8b39c6..3d15a9d1c6 100644 --- a/eeschema/lib_pin.cpp +++ b/eeschema/lib_pin.cpp @@ -2142,6 +2142,29 @@ wxString LIB_PIN::GetSelectMenuText() const } +bool LIB_PIN::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ) +{ + wxLogTrace( traceFindReplace, wxT( " item " ) + GetSelectMenuText() ); + + if( !( aSearchData.GetFlags() & FR_SEARCH_ALL_PINS ) + && !( aSearchData.GetFlags() & FR_SEARCH_REPLACE ) ) + return false; + + wxLogTrace( traceFindReplace, wxT( " child item " ) + GetSelectMenuText() ); + + if( EDA_ITEM::Matches( GetName(), aSearchData ) + || EDA_ITEM::Matches( GetNumberString(), aSearchData ) ) + { + if( aFindLocation ) + *aFindLocation = GetBoundingBox().Centre(); + + return true; + } + + return false; +} + + #if defined(DEBUG) void LIB_PIN::Show( int nestLevel, std::ostream& os ) diff --git a/eeschema/lib_pin.h b/eeschema/lib_pin.h index a9e655af9e..4dcdaca4e8 100644 --- a/eeschema/lib_pin.h +++ b/eeschema/lib_pin.h @@ -134,7 +134,7 @@ public: char m_PinNamePositionOpt; public: - LIB_PIN( LIB_COMPONENT * aParent ); + LIB_PIN( LIB_COMPONENT* aParent ); LIB_PIN( const LIB_PIN& aPin ); ~LIB_PIN() { } @@ -185,6 +185,11 @@ public: */ virtual void DisplayInfo( EDA_DRAW_FRAME* aFrame ); + /** + * @copydoc EDA_ITEM::Matches() + */ + virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ); + /** * Function GetBoundingBox * @return the boundary box for the pin in schematic coordinates. diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp index a95a49c075..58e8d4ea8f 100644 --- a/eeschema/menubar.cpp +++ b/eeschema/menubar.cpp @@ -217,6 +217,10 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() text = AddHotkeyName( _( "&Find" ), s_Schematic_Hokeys_Descr, HK_FIND_ITEM ); AddMenuItem( editMenu, ID_FIND_ITEMS, text, HELP_FIND, KiBitmap( find_xpm ) ); + // Find/Replace + // AddMenuItem( editMenu, wxID_REPLACE, _( "Find and Re&place\tCtrl+Shift+F" ), HELP_REPLACE, + // KiBitmap( find_replace_xpm ) ); + // Backannotate editMenu->AppendSeparator(); AddMenuItem( editMenu, diff --git a/eeschema/sch_collectors.cpp b/eeschema/sch_collectors.cpp index 2be6d553db..2cbded5d93 100644 --- a/eeschema/sch_collectors.cpp +++ b/eeschema/sch_collectors.cpp @@ -1,7 +1,3 @@ -/** - * @file sch_collectors.cpp - */ - /* * This program source code file is part of KiCad, a free EDA CAD application. * @@ -26,6 +22,10 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * @file sch_collectors.cpp + */ + #include "general.h" #include "transform.h" #include "sch_collectors.h" @@ -314,3 +314,109 @@ bool SCH_COLLECTOR::IsDraggableJunction() const return (wireEndCount >= 3) || ((wireEndCount >= 1) && (wireMidPoint == 1)) || ((wireMidPoint >= 2) && (junctionCount == 1)); } + + +SCH_FIND_COLLECTOR_DATA SCH_FIND_COLLECTOR::GetFindData( int aIndex ) +{ + wxCHECK_MSG( (unsigned) aIndex < m_data.size(), SCH_FIND_COLLECTOR_DATA(), + wxT( "Attempt to get find data outside of list boundary." ) ); + + return m_data[ aIndex ]; +} + + +wxString SCH_FIND_COLLECTOR::GetText( int aIndex ) +{ + wxCHECK_MSG( IsValidIndex( aIndex ), wxEmptyString, + wxT( "Cannot get found item at invalid index." ) ); + + SCH_FIND_COLLECTOR_DATA data = m_data[ aIndex ]; + EDA_ITEM* foundItem = m_List[ aIndex ]; + + wxCHECK_MSG( foundItem != NULL, wxEmptyString, wxT( "Inavalid found item pointer." ) ); + + wxString msg; + + if( data.GetParent() ) + { + msg = _( "Child item " ) + foundItem->GetSelectMenuText() + + _( " of parent item " ) + data.GetParent()->GetSelectMenuText() + + _( " found in sheet " ) + data.GetSheetPath(); + } + else + { + msg = _( "Item " ) + foundItem->GetSelectMenuText() + _( " found in sheet " ) + + data.GetSheetPath(); + } + + return msg; +} + + +SEARCH_RESULT SCH_FIND_COLLECTOR::Inspect( EDA_ITEM* aItem, const void* aTestData ) +{ + wxPoint position; + + if( aItem->Matches( m_findReplaceData, m_sheetPath, &position ) ) + { + if( aItem->Type() == LIB_PIN_T ) + { + wxCHECK_MSG( aTestData && ( (EDA_ITEM*) aTestData )->Type() == SCH_COMPONENT_T, + SEARCH_CONTINUE, wxT( "Cannot inspect invalid data. Bad programmer!" ) ); + + // Pin hit testing is relative to the components position and orientation in the + // schematic. The hit test position must be converted to library coordinates. + SCH_COMPONENT* component = (SCH_COMPONENT*) aTestData; + TRANSFORM transform = component->GetTransform(); + position.y = -position.y; + position = transform.TransformCoordinate( position ) + component->GetPosition(); + } + + Append( aItem ); + m_data.push_back( SCH_FIND_COLLECTOR_DATA( position, m_sheetPath->PathHumanReadable(), + (SCH_ITEM*) aTestData ) ); + } + + return SEARCH_CONTINUE; +} + + +void SCH_FIND_COLLECTOR::Collect( SCH_FIND_REPLACE_DATA& aFindReplaceData, + SCH_SHEET_PATH* aSheetPath ) +{ + if( m_findReplaceData == aFindReplaceData ) + return; + + m_findReplaceData = aFindReplaceData; + Empty(); // empty the collection just in case + m_data.clear(); + + if( aSheetPath ) + { + m_sheetPath = aSheetPath; + EDA_ITEM::IterateForward( aSheetPath->LastDrawList(), this, NULL, m_ScanTypes ); + } + else + { + SCH_SHEET_LIST schematic; + m_sheetPath = schematic.GetFirst(); + + while( m_sheetPath != NULL ) + { + EDA_ITEM::IterateForward( m_sheetPath->LastDrawList(), this, NULL, m_ScanTypes ); + m_sheetPath = schematic.GetNext(); + } + } + + if( m_List.size() != m_data.size() ) + { + wxFAIL_MSG( wxT( "List size mismatch." ) ); + m_List.clear(); + m_data.clear(); + } + + for( unsigned i = 0; i < m_List.size(); i++ ) + { + wxLogTrace( traceFindReplace, GetText( i ) ); + } +} diff --git a/eeschema/sch_collectors.h b/eeschema/sch_collectors.h index 35ab99807d..4136561842 100644 --- a/eeschema/sch_collectors.h +++ b/eeschema/sch_collectors.h @@ -1,7 +1,3 @@ -/** - * @file sch_collectors.h - */ - /* * This program source code file is part of KiCad, a free EDA CAD application. * @@ -26,12 +22,17 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/** + * @file sch_collectors.h + */ + #ifndef _SCH_COLLECTORS_H_ #define _SCH_COLLECTORS_H_ #include "class_collector.h" #include "sch_item_struct.h" +#include "dialogs/dialog_schematic_find.h" /** @@ -120,14 +121,7 @@ public: } /** - * Function Inspect - * is the examining function within the INSPECTOR which is passed to the - * Iterate function. - * - * @param aItem An EDA_ITEM to examine. - * @param aTestData is not used in this class. - * @return SEARCH_RESULT #SEARCH_QUIT if the iterator is to stop the scan, - * else #SEARCH_CONTINUE; + * @copydoc INSPECTOR::Inspect() */ SEARCH_RESULT Inspect( EDA_ITEM* aItem, const void* aTestData = NULL ); @@ -162,7 +156,7 @@ public: * Function IsDraggableJunction * tests to see if the collected items form a draggable junction. *

- * Daggable juntions are defined as: + * Daggable junctions are defined as: *