Search sheets in hierarchy-order

Also fixes an issue where multiple sub-sheets were skipped in certain
cases

Fixes https://gitlab.com/kicad/code/kicad/issues/8972
This commit is contained in:
Seth Hillbrand 2021-08-27 13:02:25 -07:00
parent 10247c268e
commit 871bdbc952
2 changed files with 43 additions and 22 deletions

View File

@ -1165,8 +1165,8 @@ int SCH_SHEET::ComparePageNum( const wxString& aPageNumberA, const wxString& aPa
else if( isIntegerPageB ) else if( isIntegerPageB )
return 1; // A > B return 1; // A > B
// If not numeric, then sort as strings // If not numeric, then sort as strings using natural sort
int result = aPageNumberA.Cmp( aPageNumberB ); int result = StrNumCmp( aPageNumberA, aPageNumberB );
if( result > 0 ) if( result > 0 )
return 1; // A > B return 1; // A > B

View File

@ -402,13 +402,14 @@ int SCH_EDITOR_CONTROL::FindNext( const TOOL_EVENT& aEvent )
bool searchAllSheets = !( data.GetFlags() & FR_CURRENT_SHEET_ONLY ); bool searchAllSheets = !( data.GetFlags() & FR_CURRENT_SHEET_ONLY );
EE_SELECTION& selection = m_selectionTool->GetSelection(); EE_SELECTION& selection = m_selectionTool->GetSelection();
SCH_SCREEN* afterScreen = m_frame->GetScreen();
SCH_ITEM* afterItem = dynamic_cast<SCH_ITEM*>( selection.Front() ); SCH_ITEM* afterItem = dynamic_cast<SCH_ITEM*>( selection.Front() );
SCH_ITEM* item = nullptr; SCH_ITEM* item = nullptr;
SCH_SHEET_PATH* afterSheet = &m_frame->GetCurrentSheet();
if( wrapAroundTimer.IsRunning() ) if( wrapAroundTimer.IsRunning() )
{ {
afterScreen = nullptr; afterSheet = nullptr;
afterItem = nullptr; afterItem = nullptr;
wrapAroundTimer.Stop(); wrapAroundTimer.Stop();
m_frame->ClearFindReplaceStatus(); m_frame->ClearFindReplaceStatus();
@ -416,42 +417,62 @@ int SCH_EDITOR_CONTROL::FindNext( const TOOL_EVENT& aEvent )
m_selectionTool->ClearSelection(); m_selectionTool->ClearSelection();
if( afterScreen || !searchAllSheets ) if( afterSheet || !searchAllSheets )
item = nextMatch( m_frame->GetScreen(), &m_frame->GetCurrentSheet(), afterItem, data ); item = nextMatch( m_frame->GetScreen(), &m_frame->GetCurrentSheet(), afterItem, data );
if( !item && searchAllSheets ) if( !item && searchAllSheets )
{ {
SCH_SHEET_LIST schematic = m_frame->Schematic().GetSheets(); SCH_SCREENS screens( m_frame->Schematic().Root() );
SCH_SCREENS screens( m_frame->Schematic().Root() ); std::vector<SCH_SHEET_PATH*> paths;
screens.BuildClientSheetPathList(); screens.BuildClientSheetPathList();
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() ) for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
{ {
if( afterScreen )
for( SCH_SHEET_PATH& sheet : screen->GetClientSheetPaths() )
{ {
if( afterScreen == screen ) paths.push_back( &sheet );
afterScreen = nullptr; }
}
std::sort( paths.begin(), paths.end(), [] ( const SCH_SHEET_PATH* lhs, const SCH_SHEET_PATH* rhs ) -> bool
{
int retval = lhs->ComparePageNumAndName( *rhs );
if( retval < 0 )
return true;
else if( retval > 0 )
return false;
else /// Enforce strict ordering. If the name and number are the same, we use UUIDs
return lhs->GetCurrentHash() < rhs->GetCurrentHash();
} );
for( SCH_SHEET_PATH* sheet : paths )
{
if( afterSheet )
{
if( afterSheet->GetPageNumber() == sheet->GetPageNumber() )
afterSheet = nullptr;
continue; continue;
} }
for( SCH_SHEET_PATH sheet : screen->GetClientSheetPaths() ) SCH_SCREEN* screen = sheet->LastScreen();
item = nextMatch( screen, sheet, nullptr, data );
if( item )
{ {
item = nextMatch( screen, &sheet, nullptr, data ); m_frame->Schematic().SetCurrentSheet( *sheet );
m_frame->GetCurrentSheet().UpdateAllScreenReferences();
if( item ) screen->TestDanglingEnds();
{
m_frame->Schematic().SetCurrentSheet( sheet );
m_frame->GetCurrentSheet().UpdateAllScreenReferences();
screen->TestDanglingEnds(); m_frame->SetScreen( screen );
UpdateFind( ACTIONS::updateFind.MakeEvent() );
m_frame->SetScreen( screen ); break;
UpdateFind( ACTIONS::updateFind.MakeEvent() );
break;
}
} }
if( item ) if( item )