From 35749e57c44b54fb743a031f1121c8be3182dade Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Wed, 16 Nov 2011 20:06:08 -0500 Subject: [PATCH] Fix Eeschema find item bugs and other minor changes. * Fix bug in hierarchical searches using sheet path pointers which are destroyed on every search. Use human readable path as last sheet found in test to prevent comparison of deleted pointers. * Fix a bug in SCH_COMPONENT::Matches() that would prevent searching for pins if the search all fields flags was not set. * Fix a bug in SCH_COMPONENT::Matches() to use the sheet path to perform the comparison to the correct reference designator and unit number. * Fix wrapping in sheet path and sheet path list MatchNextItem methods. * Push search methods down to EDA_ITEM object so advanced searching can be performed on all items derived from EDA_ITEM. * Add virtual method to EDA_ITEM object to test if item supports replacing text. * Replace switch statement magic numbers in Eeschema socket connection code with Pcbnew for improved readability. --- common/base_struct.cpp | 54 +++++++++ common/sch_item_struct.cpp | 23 ---- eeschema/cross-probing.cpp | 69 ++++++++---- eeschema/dialogs/dialog_schematic_find.h | 28 +++-- eeschema/find.cpp | 136 +++++++++++++---------- eeschema/sch_component.cpp | 24 ++-- eeschema/sch_field.cpp | 23 +++- eeschema/sch_sheet_path.cpp | 68 +++++++++++- eeschema/sch_sheet_path.h | 40 +++++-- eeschema/schframe.cpp | 1 + include/base_struct.h | 62 +++++++++-- include/sch_item_struct.h | 30 ----- include/wxEeschemaStruct.h | 66 +++++++---- 13 files changed, 416 insertions(+), 208 deletions(-) diff --git a/common/base_struct.cpp b/common/base_struct.cpp index 6858346a1f..6ea8378280 100644 --- a/common/base_struct.cpp +++ b/common/base_struct.cpp @@ -1,3 +1,28 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com + * Copyright (C) 2008-20011 Wayne Stambaugh + * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + /** * @file base_struct.cpp * @brief Implementation of EDA_ITEM and EDA_TEXT base classes for KiCad. @@ -13,6 +38,8 @@ #include "class_base_screen.h" #include "drawtxt.h" +#include "../eeschema/dialogs/dialog_schematic_find.h" + enum textbox { ID_TEXTBOX_LIST = 8010 @@ -133,6 +160,33 @@ wxString EDA_ITEM::GetSelectMenuText() const } +bool EDA_ITEM::Matches( const wxString& aText, wxFindReplaceData& aSearchData ) +{ + wxString text = aText; + wxString searchText = aSearchData.GetFindString(); + + // Don't match if searching for replaceable item and the item doesn't support text replace. + if( (aSearchData.GetFlags() & FR_SEARCH_REPLACE) && !IsReplaceable() ) + return false; + + if( aSearchData.GetFlags() & wxFR_WHOLEWORD ) + return aText.IsSameAs( searchText, aSearchData.GetFlags() & wxFR_MATCHCASE ); + + if( aSearchData.GetFlags() & FR_MATCH_WILDCARD ) + { + if( aSearchData.GetFlags() & wxFR_MATCHCASE ) + return text.Matches( searchText ); + + return text.MakeUpper().Matches( searchText.MakeUpper() ); + } + + if( aSearchData.GetFlags() & wxFR_MATCHCASE ) + return aText.Find( searchText ) != wxNOT_FOUND; + + return text.MakeUpper().Find( searchText.MakeUpper() ) != wxNOT_FOUND; +} + + bool EDA_ITEM::operator<( const EDA_ITEM& aItem ) const { wxFAIL_MSG( wxString::Format( wxT( "Less than operator not defined for item type %s." ), diff --git a/common/sch_item_struct.cpp b/common/sch_item_struct.cpp index 72717eef68..b1edf1d07d 100644 --- a/common/sch_item_struct.cpp +++ b/common/sch_item_struct.cpp @@ -108,29 +108,6 @@ void SCH_ITEM::Place( SCH_EDIT_FRAME* aFrame, wxDC* aDC ) } -bool SCH_ITEM::Matches( const wxString& aText, wxFindReplaceData& aSearchData ) -{ - wxString text = aText; - wxString searchText = aSearchData.GetFindString(); - - if( aSearchData.GetFlags() & wxFR_WHOLEWORD ) - return aText.IsSameAs( searchText, aSearchData.GetFlags() & wxFR_MATCHCASE ); - - if( aSearchData.GetFlags() & FR_MATCH_WILDCARD ) - { - if( aSearchData.GetFlags() & wxFR_MATCHCASE ) - return text.Matches( searchText ); - - return text.MakeUpper().Matches( searchText.MakeUpper() ); - } - - if( aSearchData.GetFlags() & wxFR_MATCHCASE ) - return aText.Find( searchText ) != wxNOT_FOUND; - - return text.MakeUpper().Find( searchText.MakeUpper() ) != wxNOT_FOUND; -} - - bool SCH_ITEM::IsConnected( const wxPoint& aPosition ) const { if( m_Flags & STRUCT_DELETED || m_Flags & SKIP_STRUCT ) diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index 8f65994759..955fc73496 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -1,3 +1,28 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com + * Copyright (C) 2011 Wayne Stambaugh + * Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + /** * @file eeschema/cross-probing.cpp */ @@ -17,17 +42,20 @@ /** - * Read a remote command sent by Pcbnew (via a socket connection) , - * so when user selects a module or pin in Pcbnew, - * Deschema shows that same component or pin. - * The cursor is put on the item - * port KICAD_SCH_PORT_SERVICE_NUMBER (currently 4243) + * Function RemoteCommand + * read a remote command sent by Pcbnew via a socket connection. + *

+ * When user selects a module or pin in Pcbnew, Eeschema shows that same + * component or pin and moves cursor on the item. The socket port used + * is #KICAD_SCH_PORT_SERVICE_NUMBER which defaults to 4243. + * + * Valid commands are: + * \li \c \$PART: \c "reference" Put cursor on component. + * \li \c \$PART: \c "reference" \c \$REF: \c "ref" Put cursor on component reference. + * \li \c \$PART: \c "reference" \c \$VAL: \c "value" Put cursor on component value. + * \li \c \$PART: \c "reference" \c \$PAD: \c "pin name" Put cursor on the component pin. + *

* @param cmdline = received command from Pcbnew - * commands are: - * $PART: "reference" put cursor on component - * $PART: "reference" $REF: "ref" put cursor on reference component - * $PART: "reference" $VAL: "value" put cursor on value component - * $PART: "reference" $PAD: "pin name" put cursor on the component pin */ void RemoteCommand( const char* cmdline ) { @@ -57,7 +85,7 @@ void RemoteCommand( const char* cmdline ) if( idcmd == NULL ) // component only { - frame->FindComponentAndItem( part_ref, true, 0, wxEmptyString, false ); + frame->FindComponentAndItem( part_ref, true, FIND_COMPONENT_ONLY, wxEmptyString, false ); return; } @@ -70,29 +98,24 @@ void RemoteCommand( const char* cmdline ) if( strcmp( idcmd, "$REF:" ) == 0 ) { - frame->FindComponentAndItem( part_ref, true, 2, msg, false ); + frame->FindComponentAndItem( part_ref, true, FIND_REFERENCE, msg, false ); } else if( strcmp( idcmd, "$VAL:" ) == 0 ) { - frame->FindComponentAndItem( part_ref, true, 3, msg, false ); + frame->FindComponentAndItem( part_ref, true, FIND_VALUE, msg, false ); } else if( strcmp( idcmd, "$PAD:" ) == 0 ) { - frame->FindComponentAndItem( part_ref, true, 1, msg, false ); + frame->FindComponentAndItem( part_ref, true, FIND_PIN, msg, false ); } else - frame->FindComponentAndItem( part_ref, true, 0, wxEmptyString, false ); + { + frame->FindComponentAndItem( part_ref, true, FIND_COMPONENT_ONLY, wxEmptyString, false ); + } } -/** Send a remote command to Eeschema via a socket, - * @param objectToSync = item to be located on board (footprint, pad or text) - * @param LibItem = component in lib if objectToSync is a sub item of a component - * Commands are - * $PART: reference put cursor on footprint anchor - * $PIN: number $PART: reference put cursor on the footprint pad - */ -void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* objectToSync, SCH_COMPONENT* LibItem ) +void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* objectToSync, SCH_COMPONENT* LibItem ) { if( objectToSync == NULL ) return; diff --git a/eeschema/dialogs/dialog_schematic_find.h b/eeschema/dialogs/dialog_schematic_find.h index f32312e097..3771946a1d 100644 --- a/eeschema/dialogs/dialog_schematic_find.h +++ b/eeschema/dialogs/dialog_schematic_find.h @@ -17,31 +17,39 @@ #include // Use the wxFindReplaceDialog events, data, and enums. -/* Define schematic specific find and replace dialog flags based on the enum entries +/** + * 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. */ enum SchematicFindReplaceFlags { - /* The last wxFindReplaceFlag enum is wxFR_MATCHCASE. */ + // The last wxFindReplaceFlag enum is wxFR_MATCHCASE. - /* Search the current sheet only. */ + /// Search the current sheet only. FR_CURRENT_SHEET_ONLY = wxFR_MATCHCASE << 1, - /* Search all fields in component, not just the value and reference fields. */ + /// Search all fields in component, not just the value and reference fields. FR_SEARCH_ALL_FIELDS = wxFR_MATCHCASE << 2, - /* Search texts (name and number (a 4 letters text) )in pins. */ - FR_SEARCH_ALL_PINS = wxFR_MATCHCASE << 3, + /// Search texts (name and number (a 4 letters text) )in pins. + FR_SEARCH_ALL_PINS = wxFR_MATCHCASE << 3, - /* Perform search using simple wild card matching (* & ?). */ + /// Perform search using simple wild card matching (* & ?). FR_MATCH_WILDCARD = wxFR_MATCHCASE << 4, - /* Wrap around the beginning or end of search list. */ + /// Wrap around the beginning or end of search list. FR_SEARCH_WRAP = wxFR_MATCHCASE << 5, - /* Don't warp cursor to found item until the dialog is closed. */ - FR_NO_WARP_CURSOR = wxFR_MATCHCASE << 6 + /// 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. + FR_SEARCH_REPLACE = wxFR_MATCHCASE << 7, + + /// Used by the search event handler to let the dialog know that a replaceable + /// item has been found. + FR_REPLACE_ITEM_FOUND = wxFR_MATCHCASE << 8 }; diff --git a/eeschema/find.cpp b/eeschema/find.cpp index 6be102b117..9d2b53292f 100644 --- a/eeschema/find.cpp +++ b/eeschema/find.cpp @@ -110,94 +110,95 @@ void SCH_EDIT_FRAME::OnFindDrcMarker( wxFindDialogEvent& event ) } -SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& component_reference, - bool Find_in_hierarchy, - int SearchType, - const wxString& text_to_find, - bool mouseWarp ) +SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& aReference, + bool aSearchHierarchy, + SCH_SEARCH_T aSearchType, + const wxString& aSearchText, + bool aWarpMouse ) { SCH_SHEET_PATH* sheet; SCH_SHEET_PATH* sheetWithComponentFound = NULL; - SCH_ITEM* DrawList = NULL; - SCH_COMPONENT* Component = NULL; + SCH_ITEM* item = NULL; + SCH_COMPONENT* Component = NULL; wxPoint pos, curpos; - bool DoCenterAndRedraw = false; - bool NotFound = true; + bool centerAndRedraw = false; + bool notFound = true; wxString msg; LIB_PIN* pin; - SCH_SHEET_LIST SheetList; + SCH_SHEET_LIST sheetList; - sheet = SheetList.GetFirst(); + sheet = sheetList.GetFirst(); - if( !Find_in_hierarchy ) + if( !aSearchHierarchy ) sheet = m_CurrentSheet; - for( ; sheet != NULL; sheet = SheetList.GetNext() ) + for( ; sheet != NULL; sheet = sheetList.GetNext() ) { - DrawList = (SCH_ITEM*) sheet->LastDrawList(); + item = (SCH_ITEM*) sheet->LastDrawList(); - for( ; ( DrawList != NULL ) && ( NotFound == true ); DrawList = DrawList->Next() ) + for( ; ( item != NULL ) && ( notFound == true ); item = item->Next() ) { - if( DrawList->Type() != SCH_COMPONENT_T ) + if( item->Type() != SCH_COMPONENT_T ) continue; - SCH_COMPONENT* pSch = (SCH_COMPONENT*) DrawList; + SCH_COMPONENT* pSch = (SCH_COMPONENT*) item; - if( component_reference.CmpNoCase( pSch->GetRef( sheet ) ) == 0 ) + if( aReference.CmpNoCase( pSch->GetRef( sheet ) ) == 0 ) { Component = pSch; sheetWithComponentFound = sheet; - switch( SearchType ) + switch( aSearchType ) { default: - case 0: // Find component only - NotFound = false; + case FIND_COMPONENT_ONLY: // Find component only + notFound = false; pos = pSch->GetPosition(); break; - case 1: // find a pin + case FIND_PIN: // find a pin pos = pSch->GetPosition(); // temporary: will be changed if the pin is found. - pin = pSch->GetPin( text_to_find ); + pin = pSch->GetPin( aSearchText ); if( pin == NULL ) break; - NotFound = false; + notFound = false; pos += pin->GetPosition(); break; - case 2: // find reference - NotFound = false; + case FIND_REFERENCE: // find reference + notFound = false; pos = pSch->GetField( REFERENCE )->GetPosition(); break; - case 3: // find value + case FIND_VALUE: // find value pos = pSch->GetPosition(); - if( text_to_find.CmpNoCase( pSch->GetField( VALUE )->m_Text ) != 0 ) + if( aSearchText.CmpNoCase( pSch->GetField( VALUE )->m_Text ) != 0 ) break; - NotFound = false; + notFound = false; pos = pSch->GetField( VALUE )->GetPosition(); break; } } } - if( (Find_in_hierarchy == false) || (NotFound == false) ) + if( (aSearchHierarchy == false) || (notFound == false) ) break; } if( Component ) { sheet = sheetWithComponentFound; + if( *sheet != *GetSheet() ) { sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() ); *m_CurrentSheet = *sheet; m_CurrentSheet->UpdateAllScreenReferences(); - DoCenterAndRedraw = true; + centerAndRedraw = true; } wxPoint delta; @@ -209,13 +210,13 @@ SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& component_refere /* There may be need to reframe the drawing */ if( ! DrawPanel->IsPointOnDisplay( pos ) ) { - DoCenterAndRedraw = true; + centerAndRedraw = true; } - if( DoCenterAndRedraw ) + if( centerAndRedraw ) { GetScreen()->SetCrossHairPosition(pos); - RedrawScreen( pos, mouseWarp ); + RedrawScreen( pos, aWarpMouse ); } else @@ -224,7 +225,7 @@ SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& component_refere DrawPanel->CrossHairOff( &dc ); - if( mouseWarp ) + if( aWarpMouse ) DrawPanel->MoveCursor( pos ); GetScreen()->SetCrossHairPosition(pos); @@ -236,42 +237,44 @@ SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& component_refere /* Print diag */ wxString msg_item; - msg = component_reference; + msg = aReference; - switch( SearchType ) + switch( aSearchType ) { default: - case 0: - break; // Find component only - - case 1: // find a pin - msg_item = _( "Pin " ) + text_to_find; + case FIND_COMPONENT_ONLY: // Find component only break; - case 2: // find reference - msg_item = _( "Ref " ) + text_to_find; + case FIND_PIN: // find a pin + msg_item = _( "Pin " ) + aSearchText; break; - case 3: // find value - msg_item = _( "Value " ) + text_to_find; + case FIND_REFERENCE: // find reference + msg_item = _( "Ref " ) + aSearchText; break; - case 4: // find field. todo - msg_item = _( "Field " ) + text_to_find; + case FIND_VALUE: // find value + msg_item = _( "Value " ) + aSearchText; + break; + + case FIND_FIELD: // find field. todo + msg_item = _( "Field " ) + aSearchText; break; } if( Component ) { - if( !NotFound ) + if( !notFound ) { if( !msg_item.IsEmpty() ) msg += wxT( " " ) + msg_item; + msg += _( " found" ); } else { msg += _( " found" ); + if( !msg_item.IsEmpty() ) { msg += wxT( " but " ) + msg_item + _( " not found" ); @@ -282,12 +285,13 @@ SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& component_refere { if( !msg_item.IsEmpty() ) msg += wxT( " " ) + msg_item; + msg += _( " not found" ); } SetStatusText( msg ); - return DrawList; + return item; } @@ -297,11 +301,11 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent ) * 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 SCH_SHEET_LIST schematic; wxString msg; - SCH_SHEET_PATH* sheetFoundIn = NULL; wxFindReplaceData searchCriteria; bool warpCursor = !( aEvent.GetFlags() & FR_NO_WARP_CURSOR ); @@ -311,39 +315,49 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent ) if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE ) { - sheetFoundIn = m_CurrentSheet; + sheetFoundIn = m_CurrentSheet->PathHumanReadable(); warpCursor = true; } else if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 ) { - sheetFoundIn = m_CurrentSheet; + sheetFoundIn = m_CurrentSheet->PathHumanReadable(); lastItem = m_CurrentSheet->MatchNextItem( searchCriteria, lastItem, &lastItemPosition ); } else { - lastItem = schematic.MatchNextItem( searchCriteria, &sheetFoundIn, lastItem, + lastItem = schematic.MatchNextItem( searchCriteria, sheetFoundIn, lastItem, &lastItemPosition ); } if( lastItem != NULL ) { - if( sheetFoundIn != GetSheet() ) + SCH_SHEET_PATH* sheet = schematic.GetSheet( sheetFoundIn ); + + wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " + sheetFoundIn ) ); + + if( sheet != GetSheet() ) { - sheetFoundIn->LastScreen()->SetZoom( GetScreen()->GetZoom() ); - *m_CurrentSheet = *sheetFoundIn; + sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() ); + *m_CurrentSheet = *sheet; m_CurrentSheet->UpdateAllScreenReferences(); } - sheetFoundIn->LastScreen()->SetCrossHairPosition( lastItemPosition ); + sheet->LastScreen()->SetCrossHairPosition( lastItemPosition ); RedrawScreen( lastItemPosition, warpCursor ); - msg = aEvent.GetFindString() + _( " found in " ) + sheetFoundIn->PathHumanReadable(); - SetStatusText( msg ); + msg = lastItem->GetSelectMenuText() + _( " found in sheet " ) + sheetFoundIn; } else { + sheetFoundIn = wxEmptyString; msg.Printf( _( "No item found matching %s." ), GetChars( aEvent.GetFindString() ) ); - SetStatusText( msg ); } + + SetStatusText( msg ); +} + + +void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent ) +{ } diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index 3a140c7214..f05c00d407 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -1545,13 +1545,13 @@ bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, if( GetField( VALUE )->Matches( aSearchData, aAuxData, aFindLocation ) ) return true; - if( !( aSearchData.GetFlags() & FR_SEARCH_ALL_FIELDS ) ) - return false; - - for( size_t i = VALUE + 1; i < m_Fields.size(); i++ ) + if( aSearchData.GetFlags() & FR_SEARCH_ALL_FIELDS ) { - if( GetField( i )->Matches( aSearchData, aAuxData, aFindLocation ) ) - return true; + for( size_t i = VALUE + 1; i < m_Fields.size(); i++ ) + { + if( GetField( i )->Matches( aSearchData, aAuxData, aFindLocation ) ) + return true; + } } // Search for a match in pin name or pin number. @@ -1564,7 +1564,13 @@ bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, if( Entry ) { LIB_PINS pinList; - Entry->GetPins( pinList, m_unit, m_convert ); + + int unit = m_unit; + + if( aAuxData != NULL ) + unit = GetUnitSelection( (SCH_SHEET_PATH*) aAuxData ); + + Entry->GetPins( pinList, unit, m_convert ); // Search for a match in pinList for( unsigned ii = 0; ii < pinList.size(); ii ++ ) @@ -1573,8 +1579,8 @@ bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxString pinNum; pin->ReturnPinStringNum( pinNum ); - if( SCH_ITEM::Matches( pin->GetName(), aSearchData ) || - SCH_ITEM::Matches( pinNum, aSearchData ) ) + if( SCH_ITEM::Matches( pin->GetName(), aSearchData ) + || SCH_ITEM::Matches( pinNum, aSearchData ) ) { if( aFindLocation ) { diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index 6cf5030d67..74939c149e 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -99,6 +99,7 @@ wxString SCH_FIELD::GetText() const wxCHECK_MSG( component != NULL, text, wxT( "No component associated with field" ) + text ); + if( component->GetPartCount() > 1 ) text << LIB_COMPONENT::ReturnSubReference( component->GetUnit() ); } @@ -267,6 +268,7 @@ EDA_RECT SCH_FIELD::GetBoundingBox() const wxPoint end = rect.GetEnd() - origin; RotatePoint( &begin, pos, m_Orient ); RotatePoint( &end, pos, m_Orient ); + // Due to the Y axis direction, we must mirror the bounding box, // relative to the text position: begin.y -= pos.y; @@ -275,6 +277,7 @@ EDA_RECT SCH_FIELD::GetBoundingBox() const NEGATE( end.y ); begin.y += pos.y; end.y += pos.y; + // Now, apply the component transform (mirror/rot) begin = parentComponent->GetTransform().TransformCoordinate( begin ); end = parentComponent->GetTransform().TransformCoordinate( end ); @@ -350,11 +353,27 @@ void SCH_FIELD::Place( SCH_EDIT_FRAME* frame, wxDC* DC ) } -bool SCH_FIELD::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint * aFindLocation ) +bool SCH_FIELD::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ) { bool match; + wxString text = GetText(); - match = SCH_ITEM::Matches( GetText(), aSearchData ); + // Take sheet path into account which effects the reference field and the unit for + // components with multiple parts. + if( m_FieldId == REFERENCE && aAuxData != NULL ) + { + SCH_COMPONENT* component = (SCH_COMPONENT*) m_Parent; + + wxCHECK_MSG( component != NULL, false, + wxT( "No component associated with field" ) + text ); + + text = component->GetRef( (SCH_SHEET_PATH*) aAuxData ); + + if( component->GetPartCount() > 1 ) + text << LIB_COMPONENT::ReturnSubReference( component->GetUnit() ); + } + + match = SCH_ITEM::Matches( text, aSearchData ); if( match ) { diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index 5e869a19a1..5063149dc8 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -45,6 +45,9 @@ #include "dialogs/dialog_schematic_find.h" +static const wxString traceFindReplace( wxT( "KicadFindReplace" ) ); + + SCH_SHEET_PATH::SCH_SHEET_PATH() { for( int i = 0; iPathHumanReadable() : sheet->Path(); + + if( sheetPath == aPath ) + return sheet; + + sheet = GetNext(); + } + + return NULL; +} + + void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet ) { if( m_List == NULL ) @@ -707,32 +734,61 @@ SCH_ITEM* SCH_SHEET_LIST::FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aShe SCH_ITEM* SCH_SHEET_LIST::MatchNextItem( wxFindReplaceData& aSearchData, - SCH_SHEET_PATH** aSheetFoundIn, + wxString& aSheetFoundIn, SCH_ITEM* aLastItem, wxPoint* aFindLocation ) { - bool hasWrapped = false; bool firstItemFound = false; + bool hasWrapped = false; bool wrap = ( aSearchData.GetFlags() & FR_SEARCH_WRAP ) != 0; SCH_ITEM* drawItem = NULL; SCH_SHEET_PATH* sheet = GetFirst(); + SCH_SHEET_PATH* sheetFirstItemFoundIn = NULL; + + wxLogTrace( traceFindReplace, wxT( "Searching schematic for " ) + aSearchData.GetFindString() ); while( sheet != NULL ) { + wxLogTrace( traceFindReplace, wxT( "Searching sheet " + sheet->PathHumanReadable() ) ); + drawItem = sheet->LastDrawList(); while( drawItem != NULL ) { if( aLastItem && !firstItemFound ) { - firstItemFound = ( drawItem == aLastItem ); + if( aSheetFoundIn.IsEmpty() ) + firstItemFound = (drawItem == aLastItem); + else + firstItemFound = ( (drawItem == aLastItem) && + (sheet->PathHumanReadable() == aSheetFoundIn) ); + + if( firstItemFound ) + { + sheetFirstItemFoundIn = sheet; + + wxLogTrace( traceFindReplace, wxT( "First item %p found in sheet %s" ), + sheetFirstItemFoundIn, + GetChars( sheetFirstItemFoundIn->PathHumanReadable() ) ); + } } else { + // Search has wrapped all the way around to the first item found so stop. + if( hasWrapped && aLastItem && (aLastItem == drawItem) + && (sheet == sheetFirstItemFoundIn ) ) + { + wxLogTrace( traceFindReplace, + wxT( "Wrapped around to item %p in sheet %s" ), + sheetFirstItemFoundIn, + GetChars( sheetFirstItemFoundIn->PathHumanReadable() ) ); + + return NULL; + } + if( drawItem->Matches( aSearchData, sheet, aFindLocation ) ) { - if( aSheetFoundIn ) - *aSheetFoundIn = sheet; + aSheetFoundIn = sheet->PathHumanReadable(); return drawItem; } diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index a379ec21b2..593bf66f91 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -175,7 +175,7 @@ public: * sheet parameters * a path is something like / (root) or /34005677 or /34005677/00AE4523 */ - wxString Path(); + wxString Path() const; /** * Function PathHumanReadable @@ -361,12 +361,25 @@ public: /** * Function GetSheet - * @return the item (sheet) in aIndex position in m_List or NULL if less - * than index items - * @param aIndex = index in sheet list to get the sheet + * + * @param aIndex A index in sheet list to get the sheet. + * @return the sheet at \a aIndex position in m_List or NULL if \a aIndex is + * outside the bounds of the index list. */ SCH_SHEET_PATH* GetSheet( int aIndex ); + /** + * Function GetSheet + * returns a sheet matching the path name in \a aPath. + * + * @param aPath A wxString object containing path of the sheet to get. + * @param aHumanReadable True uses the human readable path for comparison. + * False uses the timestamp generated path. + * @return The sheet that matches \a aPath or NULL if no sheet matching + * \a aPath is found. + */ + SCH_SHEET_PATH* GetSheet( const wxString aPath, bool aHumanReadable = true ); + /** * Function IsModified * checks the entire hierarchy for any modifications. @@ -377,7 +390,7 @@ public: /** * Function IsAutoSaveRequired * checks the entire hierarchy for any modifications that require auto save. - * @returns True if the hierarchy is modified otherwise false. + * @return True if the hierarchy is modified otherwise false. */ bool IsAutoSaveRequired(); @@ -430,15 +443,18 @@ public: * Function MatchNextItem * searches the entire schematic for the next item that matches the search criteria. * - * @param aSearchData - Criteria to search item against. - * @param aSheetFound - The sheet the item was found in. NULL if the next item - * is not found. - * @param aLastItem - Find next item after aLastItem if not NULL. - * @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL. - * @return If found, Returns the next schematic item. Otherwise, returns NULL. + * @param aSearchData Criteria to search item against. + * @param aSheetFoundIn A reference to the sheet path the last item was found in. Use + * wxEmptyString to search from the beginning of the sheet list. + * This will be set to the human readable sheet path if an item + * is found. + * @param aLastItem Find next item after aLastItem if not NULL. + * @param aFindLocation A pointer to a wxPoint object to put the location of matched + * item into. It can be NULL. + * @return A SCH_ITEM pointer the next schematic item if found. Otherwise, returns NULL. */ SCH_ITEM* MatchNextItem( wxFindReplaceData& aSearchData, - SCH_SHEET_PATH** aSheetFound, + wxString& aSheetFoundIn, SCH_ITEM* aLastItem, wxPoint* aFindLocation ); diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index 9777041960..9b86d62be4 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -172,6 +172,7 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME ) EVT_FIND_CLOSE( wxID_ANY, SCH_EDIT_FRAME::OnFindDialogClose ) EVT_FIND_DRC_MARKER( wxID_ANY, SCH_EDIT_FRAME::OnFindDrcMarker ) EVT_FIND( wxID_ANY, SCH_EDIT_FRAME::OnFindSchematicItem ) + EVT_FIND_REPLACE( wxID_ANY, SCH_EDIT_FRAME::OnFindReplace ) END_EVENT_TABLE() diff --git a/include/base_struct.h b/include/base_struct.h index 0bb8b56c9e..9f24117a6e 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -110,10 +110,13 @@ enum SEARCH_RESULT { }; +class wxFindReplaceData; class EDA_ITEM; class EDA_DRAW_FRAME; class EDA_RECT; class EDA_DRAW_PANEL; +class DHEAD; + /** * Class INSPECTOR @@ -288,17 +291,6 @@ public: }; -/******************************************************/ -/* Basic Classes : used classes are derived from them */ -/******************************************************/ - -class DHEAD; - -/** - * Class EDA_ITEM - * is a base class for most all the KiCad significant classes, used in - * schematics and boards. - */ // These define are used for the .m_Flags and .m_UndoRedoStatus member of the // class EDA_ITEM @@ -332,6 +324,11 @@ class DHEAD; #define EDA_ITEM_ALL_FLAGS -1 +/** + * Class EDA_ITEM + * is a base class for most all the KiCad significant classes, used in + * schematics and boards. + */ class EDA_ITEM { private: @@ -577,6 +574,49 @@ public: */ virtual BITMAP_DEF GetMenuImage() const { return right_xpm; } + /** + * Function Matches + * compares the item against the search criteria in \a aSearchData. + * + * The base class returns false since many of the objects derived from EDA_ITEM + * do not have any text to search. + * + * @param aSearchData A reference to a wxFindReplaceData object containin the + * search criteria. + * @param aAuxData A pointer to optional data required for the search or NULL + * if not used. + * @param aFindLocation A pointer to a wxPoint object to store the location of + * matched item. The pointer can be NULL is not used. + * @return True if this schematic text item matches the search criteria in + * \a aSearchData. + */ + virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ) + { + return false; + } + + /** + * Function Matches + * compares \a aText against search criteria in \a aSearchData. + * + * @param aText A referenc to a wxString object containing the string to test. + * @param aSearchData The criteria to search against. + * @return True if \a aText matches the search criteria in \a aSearchData. + */ + bool Matches( const wxString& aText, wxFindReplaceData& aSearchData ); + + /** + * Function IsReplaceable + *

+ * Override this method in any derived object that supports test find and + * replace. + *

+ * + * @return True if the item has replaceable text that can be modified using + * the find and replace dialog. + */ + virtual bool IsReplaceable() const { return false; } + /** * Test if another item is less than this object. * diff --git a/include/sch_item_struct.h b/include/sch_item_struct.h index 0facba15a0..0546d40c3e 100644 --- a/include/sch_item_struct.h +++ b/include/sch_item_struct.h @@ -201,36 +201,6 @@ public: */ virtual bool Load( LINE_READER& aLine, wxString& aErrorMsg ) { return false; } - /** - * Function Matches - * compares the schematic item against search \a aSearchData. - * - * The base class returns false since many of the objects derived from - * SCH_ITEM do not have any text to search. - * - * @todo - This should probably be pushed down to EDA_ITEM so that - * searches can be done on all of the KiCad applications that use - * objects derived from EDA_ITEM. - * - * @param aSearchData - The search criteria. - * @param aAuxData - a pointer on auxiliary data, if needed (NULL if not used). - * When searching string in REFERENCE field we must know the sheet path - * This param is used in such cases - * @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL. - * @return True if this schematic text item matches the search criteria. - */ - virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ) - { return false; } - - /** - * Compare schematic item against search string. - * - * @param aText - String test. - * @param aSearchData - The criteria to search against. - * @return True if this item matches the search criteria. - */ - bool Matches( const wxString& aText, wxFindReplaceData& aSearchData ); - /** * Function GetEndPoints * adds the schematic item end points to \a aItemList if the item has end points. diff --git a/include/wxEeschemaStruct.h b/include/wxEeschemaStruct.h index 8b1c0d8912..42f503291d 100644 --- a/include/wxEeschemaStruct.h +++ b/include/wxEeschemaStruct.h @@ -97,6 +97,16 @@ enum ANNOTATE_OPTION_T { }; +/// Schematic search type used by the socket link with Pcbnew +enum SCH_SEARCH_T { + FIND_COMPONENT_ONLY, ///< Find a component in the schematic. + FIND_PIN, ///< Find a component pin in the schematic. + FIND_REFERENCE, ///< Find an item by it's reference designator. + FIND_VALUE, ///< Find an item by it's value field. + FIND_FIELD ///< Find a component field. +}; + + /** * Schematic editor (Eeschema) main window. */ @@ -202,7 +212,7 @@ public: /** * Function LoadProjectFile - * soads the KiCad project file (*.pro) settings specific to Eeschema. + * loads the KiCad project file (*.pro) settings specific to Eeschema. * * @param aFileName The project file name to load. * @param aForceReread Force the project file to be reread if true. @@ -265,7 +275,7 @@ public: /** * Function GetConfigurationSettings - * returns the EESchema applications settings. + * returns the Eeschema applications settings. *

* This replaces the old statically define list that had the project file settings and * the application settings mixed together. This was confusing and caused some settings @@ -364,26 +374,31 @@ public: /** * Function FindComponentAndItem - * finds a Component in the schematic, and an item in this component. - * @param component_reference The component reference to find. - * @param text_to_find - The text to search for, either in value, reference - * or elsewhere. - * @param Find_in_hierarchy: false => Search is made in current sheet - * true => the whole hierarchy - * @param SearchType: 0 => find component - * 1 => find pin - * 2 => find ref - * 3 => find value - * >= 4 => unused (same as 0) - * @param mouseWarp If true, then move the mouse cursor to the item. + * finds a component in the schematic and an item in this component. + * @param aReference The component reference designator to find. + * @param aSearchHierarchy If false, search the current sheet only. Otherwise, + * the entire hierarchy + * @param aSearchType A #SCH_SEARCH_T value used to determine what to search for. + * @param aSearchText The text to search for, either in value, reference or elsewhere. + * @param aWarpMouse If true, then move the mouse cursor to the item. */ - SCH_ITEM* FindComponentAndItem( const wxString& component_reference, - bool Find_in_hierarchy, - int SearchType, - const wxString& text_to_find, - bool mouseWarp ); + SCH_ITEM* FindComponentAndItem( const wxString& aReference, + bool aSearchHierarchy, + SCH_SEARCH_T aSearchType, + const wxString& aSearchText, + bool aWarpMouse ); - /* Cross probing with Pcbnew */ + /** + * Function SendMessageToPcbnew + * send a remote to Pcbnew via a socket connection. + * @param objectToSync Item to be located on board (footprint, pad or text) + * @param LibItem Component in library if objectToSync is a sub item of a component + *

+ * Commands are + * $PART: reference put cursor on footprint anchor + * $PIN: number $PART: reference put cursor on the footprint pad + *

+ */ void SendMessageToPCBNEW( EDA_ITEM* objectToSync, SCH_COMPONENT* LibItem ); /* netlist generation */ @@ -421,7 +436,7 @@ public: bool WriteNetListFile( int aFormat, const wxString& aFullFileName, bool aUse_netnames, - bool aUsePrefix ); + bool aUsePrefix ); /** * Function DeleteAnnotation @@ -667,6 +682,15 @@ private: */ void OnFindSchematicItem( wxFindDialogEvent& aEvent ); + /** + * Function OnReplace + * performs a search and replace of text in an item in the schematic matching the + * search and replace criteria in \a aEvent. + * + * @param aEvent - Find dialog event containing the search and replace parameters. + */ + void OnFindReplace( wxFindDialogEvent& aEvent ); + void OnLoadFile( wxCommandEvent& event ); void OnLoadStuffFile( wxCommandEvent& event ); void OnNewProject( wxCommandEvent& event );