Eeschema: fix infinite loop in replace all caused by previous find fix.

* Only check for search cache update on close dialog event instead of every
  update of the find/replace view which caused an infinite loop when replace
  all was called.
* Check for dirty search cache for each find/replace event.
* Add code to save and restore last replace index on cache refresh.
This commit is contained in:
Wayne Stambaugh 2015-09-30 14:02:31 -04:00
parent 3d38a7b252
commit 5a4c663682
2 changed files with 46 additions and 17 deletions

View File

@ -321,6 +321,20 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent )
{
if( m_foundItems.GetCount() == 0 )
return;
// Refresh the search cache in case something has changed. This prevents any stale
// pointers from crashing Eeschema when the wxEVT_FIND_CLOSE event is handled.
if( IsSearchCacheObsolete( searchCriteria ) )
{
if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
{
m_foundItems.Collect( searchCriteria, m_CurrentSheet );
}
else
{
m_foundItems.Collect( searchCriteria );
}
}
}
else if( IsSearchCacheObsolete( searchCriteria ) )
{
@ -349,10 +363,32 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent )
void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent )
{
static int nextFoundIndex = 0;
SCH_ITEM* item;
SCH_SHEET_PATH* sheet;
SCH_SHEET_LIST schematic;
SCH_FIND_COLLECTOR_DATA data;
SCH_FIND_REPLACE_DATA searchCriteria;
searchCriteria.SetFlags( aEvent.GetFlags() );
searchCriteria.SetFindString( aEvent.GetFindString() );
searchCriteria.SetReplaceString( aEvent.GetReplaceString() );
if( IsSearchCacheObsolete( searchCriteria ) )
{
if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
{
m_foundItems.Collect( searchCriteria, m_CurrentSheet );
}
else
{
m_foundItems.Collect( searchCriteria );
}
// Restore the next found index on cache refresh. Prevents single replace events
// from starting back at the beginning of the cache.
m_foundItems.SetFoundIndex( nextFoundIndex );
}
if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_REPLACE_ALL )
{
@ -385,7 +421,7 @@ void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent )
}
else
{
SCH_ITEM* item = (SCH_ITEM*) m_foundItems.GetItem( data );
item = (SCH_ITEM*) m_foundItems.GetItem( data );
wxCHECK_RET( item != NULL, wxT( "Invalid replace item in find collector list." ) );
@ -408,6 +444,7 @@ void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent )
}
m_foundItems.IncrementIndex();
nextFoundIndex = m_foundItems.GetFoundIndex();
}
// End the replace if we are at the end if the list. This prevents an infinite loop if
@ -430,20 +467,6 @@ void SCH_EDIT_FRAME::updateFindReplaceView( wxFindDialogEvent& aEvent )
searchCriteria.SetFindString( aEvent.GetFindString() );
searchCriteria.SetReplaceString( aEvent.GetReplaceString() );
// Refresh the search cache in case something has changed. This prevents any stale
// pointers.
if( IsSearchCacheObsolete( searchCriteria ) )
{
if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
{
m_foundItems.Collect( searchCriteria, m_CurrentSheet );
}
else
{
m_foundItems.Collect( searchCriteria );
}
}
if( m_foundItems.GetItem( data ) != NULL )
{
wxLogTrace( traceFindReplace, wxT( "Found " ) + m_foundItems.GetText() );

View File

@ -272,8 +272,14 @@ public:
void SetForceSearch( bool doSearch = true ) { m_forceSearch = doSearch; }
int GetLibHash() const { return m_lib_hash; }
void SetLibHash( int aHash ) { m_lib_hash = aHash; }
int GetLibHash() const { return m_lib_hash; }
void SetLibHash( int aHash ) { m_lib_hash = aHash; }
int GetFoundIndex() const { return m_foundIndex; }
void SetFoundIndex( int aIndex )
{
m_foundIndex = ( (unsigned) aIndex < m_data.size() ) ? aIndex : 0;
}
/**
* Function PassedEnd