Add Eeschema replace code.

* Enable replace toolbar button and menu entry.
* Improve find replace logging granularity.
* Fix find and replace dialog control hiding and disabling.
* Minor improvements to the SCH_FIND_REPLACE_DATA object.
* Move find collector list iterator into the collector object.
* Add visibility override flag to EDA_ITEM to temporarily show items that
  are hidden during find and replace.
This commit is contained in:
Wayne Stambaugh 2011-12-13 10:37:33 -05:00
parent 5465966c7b
commit a63a2006f0
25 changed files with 434 additions and 103 deletions

View File

@ -194,6 +194,16 @@ bool EDA_ITEM::Matches( const wxString& aText, wxFindReplaceData& aSearchData )
} }
bool EDA_ITEM::Replace( wxFindReplaceData& aSearchData, wxString& aText )
{
wxCHECK_MSG( IsReplaceable(), false,
wxT( "Attempt to replace text in <" ) + GetClass() + wxT( "> item." ) );
return aText.Replace( aSearchData.GetFindString(),
aSearchData.GetReplaceString(), false ) != 0;
}
bool EDA_ITEM::operator<( const EDA_ITEM& aItem ) const bool EDA_ITEM::operator<( const EDA_ITEM& aItem ) const
{ {
wxFAIL_MSG( wxString::Format( wxT( "Less than operator not defined for item type %s." ), wxFAIL_MSG( wxString::Format( wxT( "Less than operator not defined for item type %s." ),

View File

@ -42,6 +42,8 @@
const wxString traceFindReplace( wxT( "KicadFindReplace" ) ); const wxString traceFindReplace( wxT( "KicadFindReplace" ) );
const wxString traceFindItem( wxT( "KicadFindItem" ) );
bool sort_schematic_items( const SCH_ITEM* aItem1, const SCH_ITEM* aItem2 ) bool sort_schematic_items( const SCH_ITEM* aItem1, const SCH_ITEM* aItem2 )
{ {

View File

@ -1047,8 +1047,8 @@
</object> </object>
</object> </object>
<object class="sizeritem" expanded="0"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">6</property>
<property name="flag">wxALL</property> <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxButton" expanded="0"> <object class="wxButton" expanded="0">
<property name="bg"></property> <property name="bg"></property>
@ -1104,8 +1104,8 @@
</object> </object>
</object> </object>
<object class="sizeritem" expanded="0"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">6</property>
<property name="flag">wxALL</property> <property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxButton" expanded="0"> <object class="wxButton" expanded="0">
<property name="bg"></property> <property name="bg"></property>

View File

@ -17,6 +17,8 @@ DIALOG_SCH_FIND::DIALOG_SCH_FIND( wxWindow* aParent, wxFindReplaceData* aData,
if( aStyle & wxFR_REPLACEDIALOG ) if( aStyle & wxFR_REPLACEDIALOG )
{ {
SetTitle( _( "Find and Replace" ) ); SetTitle( _( "Find and Replace" ) );
m_buttonReplace->Show( true );
m_buttonReplaceAll->Show( true );
m_staticReplace->Show( true ); m_staticReplace->Show( true );
m_comboReplace->Show( true ); m_comboReplace->Show( true );
m_checkWildcardMatch->Show( false ); // Wildcard replace is not implemented. m_checkWildcardMatch->Show( false ); // Wildcard replace is not implemented.
@ -60,7 +62,7 @@ void DIALOG_SCH_FIND::OnUpdateFindUI( wxUpdateUIEvent& aEvent )
void DIALOG_SCH_FIND::OnUpdateReplaceUI( wxUpdateUIEvent& aEvent ) void DIALOG_SCH_FIND::OnUpdateReplaceUI( wxUpdateUIEvent& aEvent )
{ {
aEvent.Enable( HasFlag( wxFR_REPLACEDIALOG ) && !m_comboFind->GetValue().empty() && aEvent.Enable( HasFlag( wxFR_REPLACEDIALOG ) && !m_comboFind->GetValue().empty() &&
(m_findReplaceData->GetFlags() | FR_REPLACE_ITEM_FOUND) ); (m_findReplaceData->GetFlags() & FR_REPLACE_ITEM_FOUND) );
} }
@ -114,7 +116,10 @@ void DIALOG_SCH_FIND::OnReplace( wxCommandEvent& aEvent )
m_comboReplace->SetSelection( 0 ); m_comboReplace->SetSelection( 0 );
} }
SendEvent( wxEVT_COMMAND_FIND ); if( aEvent.GetId() == wxID_REPLACE )
SendEvent( wxEVT_COMMAND_FIND_REPLACE );
else if( aEvent.GetId() == wxID_REPLACE_ALL )
SendEvent( wxEVT_COMMAND_FIND_REPLACE_ALL );
} }

View File

@ -53,6 +53,14 @@ enum SchematicFindReplaceFlags
}; };
/**
* Definition FR_MASK_NON_SEARCH_FLAGS
* is used to mask find/replace flag bits that do not effect the search results.
*/
#define FR_MASK_NON_SEARCH_FLAGS ~( wxFR_DOWN | FR_SEARCH_WRAP | FR_NO_WARP_CURSOR | \
FR_REPLACE_ITEM_FOUND )
/** /**
* Class SCH_FIND_REPLACE_DATA * Class SCH_FIND_REPLACE_DATA
* adds missing useful comparison and assignment operators to the wxFindReplaceData object. * adds missing useful comparison and assignment operators to the wxFindReplaceData object.
@ -84,6 +92,32 @@ public:
{ {
return !( *this == aFindReplaceData ); return !( *this == aFindReplaceData );
} }
/**
* Function ChangesSearch
* tests \a aFindReplaceData to see if it would result in a change in the search
* results.
*
* @param aFindReplaceData A reference to a #SCH_FIND_REPLACE_DATA object to compare
* against.
* @return True if \a aFindReplaceData would result in a search and/or replace change,
* otherwise false.
*/
bool ChangesSearch( SCH_FIND_REPLACE_DATA& aFindReplaceData )
{
return ( (GetFindString() != aFindReplaceData.GetFindString())
|| (GetSearchFlags() != aFindReplaceData.GetSearchFlags()) );
}
bool IsReplacing() const { return (GetFlags() & FR_SEARCH_REPLACE) != 0; }
private:
/**
* Function GetSearchFlags
* @return The flags that only effect the search result.
*/
wxUint32 GetSearchFlags() const { return GetFlags() & FR_MASK_NON_SEARCH_FLAGS; }
}; };

View File

@ -104,12 +104,12 @@ DIALOG_SCH_FIND_BASE::DIALOG_SCH_FIND_BASE( wxWindow* parent, wxWindowID id, con
m_buttonReplace = new wxButton( this, wxID_REPLACE, _("&Replace"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonReplace = new wxButton( this, wxID_REPLACE, _("&Replace"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonReplace->Hide(); m_buttonReplace->Hide();
rightSizer->Add( m_buttonReplace, 0, wxALL, 5 ); rightSizer->Add( m_buttonReplace, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 6 );
m_buttonReplaceAll = new wxButton( this, wxID_REPLACE_ALL, _("Replace &All"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonReplaceAll = new wxButton( this, wxID_REPLACE_ALL, _("Replace &All"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonReplaceAll->Hide(); m_buttonReplaceAll->Hide();
rightSizer->Add( m_buttonReplaceAll, 0, wxALL, 5 ); rightSizer->Add( m_buttonReplaceAll, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 6 );
m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
rightSizer->Add( m_buttonCancel, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 6 ); rightSizer->Add( m_buttonCancel, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 6 );

View File

@ -24,8 +24,7 @@
#include "dialogs/dialog_color_config.h" #include "dialogs/dialog_color_config.h"
#include "dialogs/dialog_eeschema_config.h" #include "dialogs/dialog_eeschema_config.h"
#include "dialogs/dialog_eeschema_options.h" #include "dialogs/dialog_eeschema_options.h"
#include "dialogs/dialog_schematic_find.h"
#include <wx/fdrepdlg.h>
#define HOTKEY_FILENAME wxT( "eeschema" ) #define HOTKEY_FILENAME wxT( "eeschema" )
@ -565,7 +564,7 @@ void SCH_EDIT_FRAME::LoadSettings()
wxASSERT_MSG( m_findReplaceData, wxASSERT_MSG( m_findReplaceData,
wxT( "Find dialog data settings object not created. Bad programmer!" ) ); wxT( "Find dialog data settings object not created. Bad programmer!" ) );
cfg->Read( FindReplaceFlagsEntry, &tmp, (long) wxFR_DOWN ); cfg->Read( FindReplaceFlagsEntry, &tmp, (long) wxFR_DOWN );
m_findReplaceData->SetFlags( (wxUint32) tmp ); m_findReplaceData->SetFlags( (wxUint32) tmp & ~FR_REPLACE_ITEM_FOUND );
m_findReplaceData->SetFindString( cfg->Read( FindStringEntry, wxEmptyString ) ); m_findReplaceData->SetFindString( cfg->Read( FindStringEntry, wxEmptyString ) );
m_findReplaceData->SetReplaceString( cfg->Read( ReplaceStringEntry, wxEmptyString ) ); m_findReplaceData->SetReplaceString( cfg->Read( ReplaceStringEntry, wxEmptyString ) );
@ -643,7 +642,8 @@ void SCH_EDIT_FRAME::SaveSettings()
cfg->Write( FindDialogHeightEntry, m_findDialogSize.GetHeight() ); cfg->Write( FindDialogHeightEntry, m_findDialogSize.GetHeight() );
wxASSERT_MSG( m_findReplaceData, wxASSERT_MSG( m_findReplaceData,
wxT( "Find dialog data settings object not created. Bad programmer!" ) ); wxT( "Find dialog data settings object not created. Bad programmer!" ) );
cfg->Write( FindReplaceFlagsEntry, (long) m_findReplaceData->GetFlags() ); cfg->Write( FindReplaceFlagsEntry,
(long) m_findReplaceData->GetFlags() & ~FR_REPLACE_ITEM_FOUND );
cfg->Write( FindStringEntry, m_findReplaceData->GetFindString() ); cfg->Write( FindStringEntry, m_findReplaceData->GetFindString() );
cfg->Write( ReplaceStringEntry, m_findReplaceData->GetReplaceString() ); cfg->Write( ReplaceStringEntry, m_findReplaceData->GetReplaceString() );

View File

@ -303,12 +303,13 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent )
wxString msg; wxString msg;
SCH_FIND_REPLACE_DATA searchCriteria; SCH_FIND_REPLACE_DATA searchCriteria;
bool warpCursor = !( aEvent.GetFlags() & FR_NO_WARP_CURSOR ); bool warpCursor = !( aEvent.GetFlags() & FR_NO_WARP_CURSOR );
SCH_FIND_COLLECTOR_DATA data;
searchCriteria.SetFlags( aEvent.GetFlags() ); searchCriteria.SetFlags( aEvent.GetFlags() );
searchCriteria.SetFindString( aEvent.GetFindString() ); searchCriteria.SetFindString( aEvent.GetFindString() );
searchCriteria.SetReplaceString( aEvent.GetReplaceString() ); searchCriteria.SetReplaceString( aEvent.GetReplaceString() );
if( searchCriteria != m_foundItems.GetFindReplaceData() ) if( m_foundItems.GetFindReplaceData().ChangesSearch( searchCriteria ) )
{ {
if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE ) if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE )
{ {
@ -316,69 +317,62 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent )
} }
else if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 ) else if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
{ {
m_foundItemIndex = 0;
m_foundItems.Collect( searchCriteria, m_CurrentSheet ); m_foundItems.Collect( searchCriteria, m_CurrentSheet );
} }
else else
{ {
m_foundItemIndex = 0;
m_foundItems.Collect( searchCriteria ); m_foundItems.Collect( searchCriteria );
} }
} }
else else
{ {
if( searchCriteria.GetFlags() & wxFR_DOWN ) EDA_ITEM* currentItem = m_foundItems.GetItem( data );
{
if( !(searchCriteria.GetFlags() & FR_SEARCH_WRAP)
&& (m_foundItemIndex == (m_foundItems.GetCount() - 1)) )
return;
m_foundItemIndex += 1; if( currentItem != NULL )
currentItem->SetForceVisible( false );
if( (m_foundItemIndex >= m_foundItems.GetCount()) m_foundItems.UpdateIndex();
&& (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( m_foundItems.GetCount() != 0 ) if( m_foundItems.GetItem( data ) != NULL )
{ {
SCH_FIND_COLLECTOR_DATA data = m_foundItems.GetFindData( m_foundItemIndex ); wxLogTrace( traceFindReplace, wxT( "Found " ) + m_foundItems.GetText() );
wxLogTrace( traceFindReplace, wxT( "Found " ) + m_foundItems.GetText( m_foundItemIndex ) );
SCH_SHEET_PATH* sheet = schematic.GetSheet( data.GetSheetPath() ); SCH_SHEET_PATH* sheet = schematic.GetSheet( data.GetSheetPath() );
wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " ) + wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " ) +
data.GetSheetPath() ); data.GetSheetPath() );
// Make the item temporarily visible just in case it's hide flag is set. This
// has no effect on objects that don't support hiding. If this is a close find
// dialog event, clear the temporary visibility flag.
if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE )
m_foundItems.GetItem( data )->SetForceVisible( false );
else
m_foundItems.GetItem( data )->SetForceVisible( true );
if( sheet->PathHumanReadable() != m_CurrentSheet->PathHumanReadable() ) if( sheet->PathHumanReadable() != m_CurrentSheet->PathHumanReadable() )
{ {
sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() ); sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
*m_CurrentSheet = *sheet; *m_CurrentSheet = *sheet;
m_CurrentSheet->UpdateAllScreenReferences(); m_CurrentSheet->UpdateAllScreenReferences();
SetScreen( sheet->LastScreen() );
} }
sheet->LastScreen()->SetCrossHairPosition( data.GetPosition() ); sheet->LastScreen()->SetCrossHairPosition( data.GetPosition() );
RedrawScreen( data.GetPosition(), warpCursor ); RedrawScreen( data.GetPosition(), warpCursor );
msg = m_foundItems.GetText();
if( aEvent.GetFlags() & FR_SEARCH_REPLACE )
aEvent.SetFlags( aEvent.GetFlags() | FR_REPLACE_ITEM_FOUND ); aEvent.SetFlags( aEvent.GetFlags() | FR_REPLACE_ITEM_FOUND );
msg = m_foundItems.GetText( m_foundItemIndex );
} }
else else
{ {
if( aEvent.GetFlags() & FR_SEARCH_REPLACE )
aEvent.SetFlags( aEvent.GetFlags() & ~FR_REPLACE_ITEM_FOUND ); aEvent.SetFlags( aEvent.GetFlags() & ~FR_REPLACE_ITEM_FOUND );
msg.Printf( _( "No item found matching %s." ), GetChars( aEvent.GetFindString() ) ); msg.Printf( _( "No item found matching %s." ), GetChars( aEvent.GetFindString() ) );
} }
@ -388,23 +382,57 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent )
void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent ) void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent )
{ {
wxCHECK_RET( m_foundItems.IsValidIndex( m_foundItemIndex ), SCH_FIND_COLLECTOR_DATA data;
wxT( "No last find item to replace text." ) );
SCH_FIND_COLLECTOR_DATA data = m_foundItems.GetFindData( m_foundItemIndex ); bool warpCursor = !( aEvent.GetFlags() & FR_NO_WARP_CURSOR );
SCH_ITEM* item = (SCH_ITEM*) m_foundItems.GetItem( data );
wxCHECK_RET( item != NULL, wxT( "Invalid replace item in find collector list." ) );
wxLogTrace( traceFindReplace, wxT( "Replacing %s with %s in item %s" ), wxLogTrace( traceFindReplace, wxT( "Replacing %s with %s in item %s" ),
GetChars( aEvent.GetFindString() ), GetChars( aEvent.GetReplaceString() ), GetChars( aEvent.GetFindString() ), GetChars( aEvent.GetReplaceString() ),
GetChars( m_foundItems.GetText( m_foundItemIndex ) ) ); GetChars( m_foundItems.GetText() ) );
SCH_ITEM* undoItem = data.GetParent();
if( undoItem == NULL )
undoItem = item;
SetUndoItem( undoItem );
if( m_foundItems.ReplaceItem() )
{
SaveUndoItemInUndoList( undoItem );
RedrawScreen( data.GetPosition(), warpCursor );
}
OnFindSchematicItem( aEvent ); OnFindSchematicItem( aEvent );
if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_REPLACE_ALL ) if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_REPLACE_ALL )
{
item = (SCH_ITEM*) m_foundItems.GetItem( data );
while( item != NULL )
{ {
wxLogTrace( traceFindReplace, wxT( "Replacing %s with %s in item %s" ), wxLogTrace( traceFindReplace, wxT( "Replacing %s with %s in item %s" ),
GetChars( aEvent.GetFindString() ), GetChars( aEvent.GetReplaceString() ), GetChars( aEvent.GetFindString() ), GetChars( aEvent.GetReplaceString() ),
GetChars( m_foundItems.GetText( m_foundItemIndex ) ) ); GetChars( m_foundItems.GetText() ) );
SCH_ITEM* undoItem = data.GetParent();
// Don't save child items in undo list.
if( undoItem == NULL )
undoItem = item;
SetUndoItem( undoItem );
if( m_foundItems.ReplaceItem() )
{
SaveUndoItemInUndoList( undoItem );
RedrawScreen( data.GetPosition(), warpCursor );
}
OnFindSchematicItem( aEvent ); OnFindSchematicItem( aEvent );
} }
}
} }

View File

@ -2138,13 +2138,15 @@ wxString LIB_PIN::GetSelectMenuText() const
bool LIB_PIN::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ) bool LIB_PIN::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation )
{ {
wxLogTrace( traceFindReplace, wxT( " item " ) + GetSelectMenuText() ); wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText() );
// Note: this will have to be modified if we add find and replace capability to the
// compoment library editor. Otherwise, you wont be able to replace pin text.
if( !( aSearchData.GetFlags() & FR_SEARCH_ALL_PINS ) if( !( aSearchData.GetFlags() & FR_SEARCH_ALL_PINS )
&& !( aSearchData.GetFlags() & FR_SEARCH_REPLACE ) ) || ( aSearchData.GetFlags() & FR_SEARCH_REPLACE ) )
return false; return false;
wxLogTrace( traceFindReplace, wxT( " child item " ) + GetSelectMenuText() ); wxLogTrace( traceFindItem, wxT( " child item " ) + GetSelectMenuText() );
if( EDA_ITEM::Matches( GetName(), aSearchData ) if( EDA_ITEM::Matches( GetName(), aSearchData )
|| EDA_ITEM::Matches( GetNumberString(), aSearchData ) ) || EDA_ITEM::Matches( GetNumberString(), aSearchData ) )

View File

@ -218,8 +218,8 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
AddMenuItem( editMenu, ID_FIND_ITEMS, text, HELP_FIND, KiBitmap( find_xpm ) ); AddMenuItem( editMenu, ID_FIND_ITEMS, text, HELP_FIND, KiBitmap( find_xpm ) );
// Find/Replace // Find/Replace
// AddMenuItem( editMenu, wxID_REPLACE, _( "Find and Re&place\tCtrl+Shift+F" ), HELP_REPLACE, AddMenuItem( editMenu, wxID_REPLACE, _( "Find and Re&place\tCtrl+Shift+F" ), HELP_REPLACE,
// KiBitmap( find_replace_xpm ) ); KiBitmap( find_replace_xpm ) );
// Backannotate // Backannotate
editMenu->AppendSeparator(); editMenu->AppendSeparator();

View File

@ -26,6 +26,8 @@
* @file sch_collectors.cpp * @file sch_collectors.cpp
*/ */
#include "macros.h"
#include "general.h" #include "general.h"
#include "transform.h" #include "transform.h"
#include "sch_collectors.h" #include "sch_collectors.h"
@ -316,6 +318,79 @@ bool SCH_COLLECTOR::IsDraggableJunction() const
} }
bool SCH_FIND_COLLECTOR::atEnd() const
{
bool retv = false;
wxUint32 flags = m_findReplaceData.GetFlags();
if( GetCount() == 0 )
return true;
if( !(flags & FR_SEARCH_WRAP) )
{
if( flags & wxFR_DOWN )
{
if( m_foundIndex >= (GetCount() - 1) )
retv = true;
}
else
{
if( m_foundIndex == 0 )
retv = true;
}
}
return retv;
}
#if defined(DEBUG)
void SCH_FIND_COLLECTOR::dump()
{
int tmp = m_foundIndex;
wxLogTrace( traceFindReplace, wxT( "%d items found to replace %s with %s." ),
GetCount(), GetChars( m_findReplaceData.GetFindString() ),
GetChars( m_findReplaceData.GetReplaceString() ) );
for( m_foundIndex = 0; m_foundIndex < GetCount(); m_foundIndex++ )
wxLogTrace( traceFindReplace, wxT( " " ) + GetText() );
m_foundIndex = tmp;
}
#endif
void SCH_FIND_COLLECTOR::UpdateIndex()
{
wxUint32 flags = m_findReplaceData.GetFlags();
if( flags & wxFR_DOWN )
{
if( !(flags & FR_SEARCH_WRAP) && (m_foundIndex == (GetCount() - 1)) )
return;
m_foundIndex += 1;
if( (m_foundIndex >= GetCount()) && (flags & FR_SEARCH_WRAP) )
m_foundIndex = 0;
}
else
{
if( !(flags & FR_SEARCH_WRAP) && (m_foundIndex == 0) )
return;
m_foundIndex -= 1;
if( (m_foundIndex < 0) && (flags & FR_SEARCH_WRAP) )
m_foundIndex = GetCount() - 1;
}
}
SCH_FIND_COLLECTOR_DATA SCH_FIND_COLLECTOR::GetFindData( int aIndex ) SCH_FIND_COLLECTOR_DATA SCH_FIND_COLLECTOR::GetFindData( int aIndex )
{ {
wxCHECK_MSG( (unsigned) aIndex < m_data.size(), SCH_FIND_COLLECTOR_DATA(), wxCHECK_MSG( (unsigned) aIndex < m_data.size(), SCH_FIND_COLLECTOR_DATA(),
@ -325,13 +400,13 @@ SCH_FIND_COLLECTOR_DATA SCH_FIND_COLLECTOR::GetFindData( int aIndex )
} }
wxString SCH_FIND_COLLECTOR::GetText( int aIndex ) wxString SCH_FIND_COLLECTOR::GetText()
{ {
wxCHECK_MSG( IsValidIndex( aIndex ), wxEmptyString, wxCHECK_MSG( (GetCount() != 0) && IsValidIndex( m_foundIndex ), wxEmptyString,
wxT( "Cannot get found item at invalid index." ) ); wxT( "Cannot get found item at invalid index." ) );
SCH_FIND_COLLECTOR_DATA data = m_data[ aIndex ]; SCH_FIND_COLLECTOR_DATA data = m_data[ m_foundIndex ];
EDA_ITEM* foundItem = m_List[ aIndex ]; EDA_ITEM* foundItem = m_List[ m_foundIndex ];
wxCHECK_MSG( foundItem != NULL, wxEmptyString, wxT( "Inavalid found item pointer." ) ); wxCHECK_MSG( foundItem != NULL, wxEmptyString, wxT( "Inavalid found item pointer." ) );
@ -353,6 +428,40 @@ wxString SCH_FIND_COLLECTOR::GetText( int aIndex )
} }
EDA_ITEM* SCH_FIND_COLLECTOR::GetItem( SCH_FIND_COLLECTOR_DATA& aData )
{
if( atEnd() )
return NULL;
aData = m_data[ m_foundIndex ];
return m_List[ m_foundIndex ];
}
bool SCH_FIND_COLLECTOR::ReplaceItem()
{
if( atEnd() )
return false;
wxCHECK_MSG( IsValidIndex( m_foundIndex ), false,
wxT( "Invalid replace list index in SCH_FIND_COLLECTOR." ) );
EDA_ITEM* item = m_List[ m_foundIndex ];
bool replaced = item->Replace( m_findReplaceData );
// If the replace was successful, remove the item from the find list to prevent
// iterating back over it again.
if( replaced )
{
Remove( m_foundIndex );
m_data.erase( m_data.begin() + m_foundIndex );
}
return replaced;
}
SEARCH_RESULT SCH_FIND_COLLECTOR::Inspect( EDA_ITEM* aItem, const void* aTestData ) SEARCH_RESULT SCH_FIND_COLLECTOR::Inspect( EDA_ITEM* aItem, const void* aTestData )
{ {
wxPoint position; wxPoint position;
@ -364,8 +473,9 @@ SEARCH_RESULT SCH_FIND_COLLECTOR::Inspect( EDA_ITEM* aItem, const void* aTestDat
wxCHECK_MSG( aTestData && ( (EDA_ITEM*) aTestData )->Type() == SCH_COMPONENT_T, wxCHECK_MSG( aTestData && ( (EDA_ITEM*) aTestData )->Type() == SCH_COMPONENT_T,
SEARCH_CONTINUE, wxT( "Cannot inspect invalid data. Bad programmer!" ) ); SEARCH_CONTINUE, wxT( "Cannot inspect invalid data. Bad programmer!" ) );
// Pin hit testing is relative to the components position and orientation in the // Pin positions are relative to their parent component's position and
// schematic. The hit test position must be converted to library coordinates. // orientation in the schematic. The pin's position must be converted
// schematic coordinates.
SCH_COMPONENT* component = (SCH_COMPONENT*) aTestData; SCH_COMPONENT* component = (SCH_COMPONENT*) aTestData;
TRANSFORM transform = component->GetTransform(); TRANSFORM transform = component->GetTransform();
position.y = -position.y; position.y = -position.y;
@ -384,12 +494,13 @@ SEARCH_RESULT SCH_FIND_COLLECTOR::Inspect( EDA_ITEM* aItem, const void* aTestDat
void SCH_FIND_COLLECTOR::Collect( SCH_FIND_REPLACE_DATA& aFindReplaceData, void SCH_FIND_COLLECTOR::Collect( SCH_FIND_REPLACE_DATA& aFindReplaceData,
SCH_SHEET_PATH* aSheetPath ) SCH_SHEET_PATH* aSheetPath )
{ {
if( m_findReplaceData == aFindReplaceData ) if( !m_findReplaceData.ChangesSearch( aFindReplaceData ) )
return; return;
m_findReplaceData = aFindReplaceData; m_findReplaceData = aFindReplaceData;
Empty(); // empty the collection just in case Empty(); // empty the collection just in case
m_data.clear(); m_data.clear();
m_foundIndex = 0;
if( aSheetPath ) if( aSheetPath )
{ {
@ -408,15 +519,14 @@ void SCH_FIND_COLLECTOR::Collect( SCH_FIND_REPLACE_DATA& aFindReplaceData,
} }
} }
#if defined(DEBUG)
dump();
#endif
if( m_List.size() != m_data.size() ) if( m_List.size() != m_data.size() )
{ {
wxFAIL_MSG( wxT( "List size mismatch." ) ); wxFAIL_MSG( wxT( "List size mismatch." ) );
m_List.clear(); m_List.clear();
m_data.clear(); m_data.clear();
} }
for( unsigned i = 0; i < m_List.size(); i++ )
{
wxLogTrace( traceFindReplace, GetText( i ) );
}
} }

View File

@ -218,6 +218,26 @@ class SCH_FIND_COLLECTOR : public COLLECTOR
/// The path of the sheet currently being iterated over. /// The path of the sheet currently being iterated over.
SCH_SHEET_PATH* m_sheetPath; SCH_SHEET_PATH* m_sheetPath;
/// The current found item list index.
int m_foundIndex;
/**
* Function atEnd
* tests if #m_foundIndex is at the end of the list give the current find/replace
* criterial in #m_findReplaceData.
*
* @return True if #m_foundIndex is at the end of the found item list.
*/
bool atEnd() const;
/**
* Function dump
* is a helper to dump the items in the find list for debugging purposes.
*/
#if defined(DEBUG)
void dump();
#endif
public: public:
/** /**
@ -226,8 +246,15 @@ public:
SCH_FIND_COLLECTOR( const KICAD_T* aScanTypes = SCH_COLLECTOR::AllItems ) SCH_FIND_COLLECTOR( const KICAD_T* aScanTypes = SCH_COLLECTOR::AllItems )
{ {
SetScanTypes( aScanTypes ); SetScanTypes( aScanTypes );
m_foundIndex = 0;
} }
/**
* Function UpdateIndex
* updates the list index according to the current find and replace criteria.
*/
void UpdateIndex();
/** /**
* Function GetFindData * Function GetFindData
* returns the data associated with the item found at \a aIndex. * returns the data associated with the item found at \a aIndex.
@ -246,7 +273,33 @@ public:
*/ */
SCH_FIND_REPLACE_DATA& GetFindReplaceData() { return m_findReplaceData; } SCH_FIND_REPLACE_DATA& GetFindReplaceData() { return m_findReplaceData; }
wxString GetText( int aIndex ); /**
* Function GetText()
* @return A wxString object containing the description of the item found at the
* current index or a wxEmptyString if the list is empty or the index is
* invalid.
*/
wxString GetText();
/**
* Function GetItem
* returns the item and associated data of the current index.
*
* @param aFindData A reference to a #SCH_FIND_COLLECTOR_DATA object to place the
* associated data for the current item into if the current item
* index is valid.
* @return A pointer to the current #EDA_ITEM in the list if the list index is valid
* Otherwise NULL is returned and the \a aFindData object is not updated.
*/
EDA_ITEM* GetItem( SCH_FIND_COLLECTOR_DATA& aFindData );
/**
* Function ReplaceItem
* performs a string replace of the item at the current index.
*
* @return True if the text replace occurred otherwise false.
*/
bool ReplaceItem();
/** /**
* @copydoc INSPECTOR::Inspect() * @copydoc INSPECTOR::Inspect()

View File

@ -1557,7 +1557,7 @@ void SCH_COMPONENT::Rotate( wxPoint rotationPoint )
bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData,
wxPoint* aFindLocation ) wxPoint* aFindLocation )
{ {
wxLogTrace( traceFindReplace, wxT( " item " ) + GetSelectMenuText() ); wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText() );
// Components are searchable via the child field and pin item text. // Components are searchable via the child field and pin item text.
return false; return false;

View File

@ -365,14 +365,7 @@ public:
virtual void Rotate( wxPoint rotationPoint ); virtual void Rotate( wxPoint rotationPoint );
/** /**
* Function Matches * @copydoc EDA_ITEM::Matches()
* compares component reference and value fields against \a aSearchData.
*
* @param aSearchData Criteria to search against.
* @param aAuxData Pointer to auxiliary data, if needed.
* Used when searching string in REFERENCE field we must know the sheet path
* @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL.
* @return True if this component reference or value field matches the search criteria.
*/ */
virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ); virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );

View File

@ -147,13 +147,12 @@ void SCH_FIELD::Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
// Clip pen size for small texts: // Clip pen size for small texts:
LineWidth = Clamp_Text_PenSize( LineWidth, m_Size, m_Bold ); LineWidth = Clamp_Text_PenSize( LineWidth, m_Size, m_Bold );
if( ( m_Attributs & TEXT_NO_VISIBLE ) || IsVoid() ) if( ((m_Attributs & TEXT_NO_VISIBLE) && !m_forceVisible) || IsVoid() )
return; return;
GRSetDrawMode( DC, DrawMode ); GRSetDrawMode( DC, DrawMode );
/* Calculate the text orientation, according to the component // Calculate the text orientation according to the component orientation.
* orientation/mirror */
orient = m_Orient; orient = m_Orient;
if( parentComponent->GetTransform().y1 ) // Rotate component 90 degrees. if( parentComponent->GetTransform().y1 ) // Rotate component 90 degrees.
@ -178,12 +177,19 @@ void SCH_FIELD::Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
EDA_RECT boundaryBox = GetBoundingBox(); EDA_RECT boundaryBox = GetBoundingBox();
textpos = boundaryBox.Centre(); textpos = boundaryBox.Centre();
if( m_forceVisible )
{
color = DARKGRAY;
}
else
{
if( m_id == REFERENCE ) if( m_id == REFERENCE )
color = ReturnLayerColor( LAYER_REFERENCEPART ); color = ReturnLayerColor( LAYER_REFERENCEPART );
else if( m_id == VALUE ) else if( m_id == VALUE )
color = ReturnLayerColor( LAYER_VALUEPART ); color = ReturnLayerColor( LAYER_VALUEPART );
else else
color = ReturnLayerColor( LAYER_FIELDS ); color = ReturnLayerColor( LAYER_FIELDS );
}
DrawGraphicText( panel, DC, textpos, color, GetText(), orient, m_Size, DrawGraphicText( panel, DC, textpos, color, GetText(), orient, m_Size,
GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
@ -361,7 +367,7 @@ bool SCH_FIELD::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint
if( (m_id > VALUE) && !(aSearchData.GetFlags() & FR_SEARCH_ALL_FIELDS) ) if( (m_id > VALUE) && !(aSearchData.GetFlags() & FR_SEARCH_ALL_FIELDS) )
return false; return false;
wxLogTrace( traceFindReplace, wxT( " child item " ) + GetSelectMenuText() ); wxLogTrace( traceFindItem, wxT( " child item " ) + GetSelectMenuText() );
// Take sheet path into account which effects the reference field and the unit for // Take sheet path into account which effects the reference field and the unit for
// components with multiple parts. // components with multiple parts.

View File

@ -202,6 +202,14 @@ public:
virtual bool Matches( wxFindReplaceData& aSearchData, virtual bool Matches( wxFindReplaceData& aSearchData,
void* aAuxData, wxPoint* aFindLocation ); void* aAuxData, wxPoint* aFindLocation );
/**
* @copydoc EDA_ITEM::Replace(wxFindReplaceData&)
*/
virtual bool Replace( wxFindReplaceData& aSearchData )
{
return EDA_ITEM::Replace( aSearchData, m_Text );
}
virtual wxString GetSelectMenuText() const; virtual wxString GetSelectMenuText() const;
virtual BITMAP_DEF GetMenuImage() const; virtual BITMAP_DEF GetMenuImage() const;

View File

@ -931,9 +931,11 @@ void SCH_SHEET::Resize( const wxSize& aSize )
bool SCH_SHEET::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ) bool SCH_SHEET::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation )
{ {
wxLogTrace( traceFindReplace, wxT( " item " ) + GetSelectMenuText() ); wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText() );
if( SCH_ITEM::Matches( m_fileName, aSearchData ) ) // Ignore the sheet file name if searching to replace.
if( !(aSearchData.GetFlags() & FR_SEARCH_REPLACE)
&& SCH_ITEM::Matches( m_fileName, aSearchData ) )
{ {
if( aFindLocation ) if( aFindLocation )
*aFindLocation = GetFileNamePosition(); *aFindLocation = GetFileNamePosition();
@ -953,6 +955,12 @@ bool SCH_SHEET::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint
} }
bool SCH_SHEET::Replace( wxFindReplaceData& aSearchData )
{
return EDA_ITEM::Replace( aSearchData, m_name );
}
void SCH_SHEET::renumberPins() void SCH_SHEET::renumberPins()
{ {
int id = 2; int id = 2;

View File

@ -208,6 +208,19 @@ public:
*/ */
virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ); virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
/**
* @copydoc EDA_ITEM::Replace(wxFindReplaceData&)
*/
virtual bool Replace( wxFindReplaceData& aSearchData )
{
return EDA_ITEM::Replace( aSearchData, m_Text );
}
/**
* @copydoc EDA_ITEM::IsReplaceable()
*/
virtual bool IsReplaceable() const { return true; }
virtual void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList ); virtual void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList );
virtual bool IsConnectable() const { return true; } virtual bool IsConnectable() const { return true; }
@ -568,6 +581,16 @@ public:
*/ */
virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ); virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
/**
* @copydoc EDA_ITEM::Replace(wxFindReplaceData&)
*/
virtual bool Replace( wxFindReplaceData& aSearchData );
/**
* @copydoc EDA_ITEM::IsReplaceable()
*/
virtual bool IsReplaceable() const { return true; }
/** /**
* Resize this sheet to aSize and adjust all of the labels accordingly. * Resize this sheet to aSize and adjust all of the labels accordingly.
* *
@ -609,11 +632,6 @@ public:
virtual void GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems, virtual void GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems,
SCH_SHEET_PATH* aSheetPath ); SCH_SHEET_PATH* aSheetPath );
/**
* @copydoc EDA_ITEM::IsReplaceable()
*/
virtual bool IsReplaceable() const { return true; }
#if defined(DEBUG) #if defined(DEBUG)
// comment inherited by Doxygen from Base_Struct // comment inherited by Doxygen from Base_Struct

View File

@ -399,7 +399,7 @@ bool SCH_SHEET_PIN::Matches( wxFindReplaceData& aSearchData,
wxCHECK_MSG( GetParent() != NULL, false, wxCHECK_MSG( GetParent() != NULL, false,
wxT( "Sheet pin " ) + m_Text + wxT( " does not have a parent sheet!" ) ); wxT( "Sheet pin " ) + m_Text + wxT( " does not have a parent sheet!" ) );
wxLogTrace( traceFindReplace, wxT( " child item " ) + GetSelectMenuText() ); wxLogTrace( traceFindItem, wxT( " child item " ) + GetSelectMenuText() );
if( SCH_ITEM::Matches( m_Text, aSearchData ) ) if( SCH_ITEM::Matches( m_Text, aSearchData ) )
{ {

View File

@ -167,7 +167,7 @@ wxPoint SCH_TEXT::GetSchematicTextOffset() const
bool SCH_TEXT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint * aFindLocation ) bool SCH_TEXT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint * aFindLocation )
{ {
wxLogTrace( traceFindReplace, wxT( " item " ) + GetSelectMenuText() ); wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText() );
if( SCH_ITEM::Matches( m_Text, aSearchData ) ) if( SCH_ITEM::Matches( m_Text, aSearchData ) )
{ {

View File

@ -206,6 +206,19 @@ public:
*/ */
virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ); virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
/**
* @copydoc EDA_ITEM::Replace(wxFindReplaceData&)
*/
virtual bool Replace( wxFindReplaceData& aSearchData )
{
return EDA_ITEM::Replace( aSearchData, m_Text );
}
/**
* @copydoc EDA_ITEM::IsReplaceable()
*/
virtual bool IsReplaceable() const { return true; }
virtual void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList ); virtual void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList );
virtual bool IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList ); virtual bool IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList );

View File

@ -204,7 +204,6 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( wxWindow* father,
m_findReplaceData = new wxFindReplaceData( wxFR_DOWN ); m_findReplaceData = new wxFindReplaceData( wxFR_DOWN );
m_undoItem = NULL; m_undoItem = NULL;
m_hasAutoSave = true; m_hasAutoSave = true;
m_foundItemIndex = 0;
CreateScreens(); CreateScreens();

View File

@ -77,9 +77,9 @@ void SCH_EDIT_FRAME::ReCreateHToolbar()
msg = AddHotkeyName( HELP_FIND, s_Schematic_Hokeys_Descr, HK_FIND_ITEM, IS_COMMENT ); msg = AddHotkeyName( HELP_FIND, s_Schematic_Hokeys_Descr, HK_FIND_ITEM, IS_COMMENT );
m_HToolBar->AddTool( ID_FIND_ITEMS, wxEmptyString, KiBitmap( find_xpm ), msg ); m_HToolBar->AddTool( ID_FIND_ITEMS, wxEmptyString, KiBitmap( find_xpm ), msg );
// m_HToolBar->AddTool( wxID_REPLACE, wxEmptyString, KiBitmap( find_replace_xpm ), m_HToolBar->AddTool( wxID_REPLACE, wxEmptyString, KiBitmap( find_replace_xpm ),
// wxNullBitmap, wxITEM_NORMAL, _( "Find and replace text" ), wxNullBitmap, wxITEM_NORMAL, _( "Find and replace text" ),
// HELP_REPLACE, NULL ); HELP_REPLACE, NULL );
m_HToolBar->AddSeparator(); m_HToolBar->AddSeparator();

View File

@ -374,6 +374,9 @@ protected:
EDA_ITEM* m_Son; /* Linked list: Link (son struct) */ EDA_ITEM* m_Son; /* Linked list: Link (son struct) */
unsigned long m_TimeStamp; ///< Time stamp used for logical links unsigned long m_TimeStamp; ///< Time stamp used for logical links
/// Set to true to override the visibility setting of the item.
bool m_forceVisible;
public: public:
int m_Flags; // flags for editing and other uses. int m_Flags; // flags for editing and other uses.
@ -465,6 +468,16 @@ public:
void ClearFlags( int aMask = EDA_ITEM_ALL_FLAGS ) { m_Flags &= ~aMask; } void ClearFlags( int aMask = EDA_ITEM_ALL_FLAGS ) { m_Flags &= ~aMask; }
int GetFlags() const { return m_Flags; } int GetFlags() const { return m_Flags; }
/**
* Function SetForceVisible
* is used to set and cleag force visible flag used to force the item to be drawn
* even if it's draw attribute is set to not visible.
*
* @param aEnable True forces the item to be drawn. False uses the item's visibility
* setting to determine if the item is to be drawn.
*/
void SetForceVisible( bool aEnable ) { m_forceVisible = aEnable; }
/** /**
* Function DisplayInfo * Function DisplayInfo
* has knowledge about the frame and how and where to put status * has knowledge about the frame and how and where to put status
@ -614,9 +627,8 @@ public:
* @param aAuxData A pointer to optional data required for the search or NULL * @param aAuxData A pointer to optional data required for the search or NULL
* if not used. * if not used.
* @param aFindLocation A pointer to a wxPoint object to store the location of * @param aFindLocation A pointer to a wxPoint object to store the location of
* matched item. The pointer can be NULL is not used. * matched item. The pointer can be NULL if it is not used.
* @return True if this schematic text item matches the search criteria in * @return True if the item's text matches the search criteria in \a aSearchData.
* \a aSearchData.
*/ */
virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation ) virtual bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation )
{ {
@ -633,6 +645,32 @@ public:
*/ */
bool Matches( const wxString& aText, wxFindReplaceData& aSearchData ); bool Matches( const wxString& aText, wxFindReplaceData& aSearchData );
/**
* Function Replace
* performs a text replace on \a aText using the find and replace criteria in
* \a aSearchData on items that support text find and replace.
*
* @param aSearchData A reference to a wxFindReplaceData object containing the
* search and replace criteria.
* @param aText A reference to a wxString object containing the text to be
* replaced.
* @return True if \a aText was modified, otherwise false.
*/
bool Replace( wxFindReplaceData& aSearchData, wxString& aText );
/**
* Function Replace
* performs a text replace using the find and replace criteria in \a aSearchData
* on items that support text find and replace.
*
* This function must be overridden for items that support text replace.
*
* @param aSearchData A reference to a wxFindReplaceData object containing the
* search and replace criteria.
* @return True if the item text was modified, otherwise false.
*/
virtual bool Replace( wxFindReplaceData& aSearchData ) { return false; }
/** /**
* Function IsReplaceable * Function IsReplaceable
* <p> * <p>

View File

@ -64,6 +64,10 @@ typedef vector< SCH_ITEMS_ITR > SCH_ITEMS_ITRS;
/// Flag to enable find and replace tracing using the WXTRACE environment variable. /// Flag to enable find and replace tracing using the WXTRACE environment variable.
extern const wxString traceFindReplace; extern const wxString traceFindReplace;
/// Flag to enable find item tracing using the WXTRACE environment variable. This
/// flag generates a lot of debug output.
extern const wxString traceFindItem;
enum DANGLING_END_T { enum DANGLING_END_T {
UNKNOWN = 0, UNKNOWN = 0,