From 84b0848a1e0647139628bd72742f42f3da30ac37 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Thu, 26 Oct 2023 13:06:59 +0100 Subject: [PATCH] Make sure that current sheet's units and dangling states are correct. We used to store the symbol units of the current sheet and then restore them, but we didn't handle the dangling states. The new code uses a different strategy and just makes sure that if any of the sheets are going to modify the current screen, the current sheet gets to go last so that its modifications will "stick". Fixes https://gitlab.com/kicad/code/kicad/-/issues/15392 --- eeschema/connection_graph.cpp | 41 +++++++++++++++++++---------------- eeschema/sch_edit_frame.cpp | 6 ++++- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/eeschema/connection_graph.cpp b/eeschema/connection_graph.cpp index f71ab4c6b8..4f81bc3efd 100644 --- a/eeschema/connection_graph.cpp +++ b/eeschema/connection_graph.cpp @@ -613,13 +613,30 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco m_sheetList = aSheetList; std::set dirty_items; + // If we update a sheet which shares the current sheet's SCH_SCREEN, then we're going to + // potentially mess up the current units, dangling states, etc. So we have to make sure that + // the current sheet is done last so that its updates to its SCH_SCREEN will "stick". + SCH_SCREEN* currentScreen = m_schematic->CurrentSheet().LastScreen(); + bool currentScreenMatched = false; + SCH_SHEET_LIST orderedSheetList; + for( const SCH_SHEET_PATH& sheet : aSheetList ) { - std::vector items; + if( sheet.LastScreen() == currentScreen ) + currentScreenMatched = true; + + // If anything matches the current screen we're going to add the current sheet at the + // end, so don't bother adding it here (there's no point in updating it twice). + if( sheet != m_schematic->CurrentSheet() ) + orderedSheetList.push_back( sheet ); + } + + if( currentScreenMatched ) + orderedSheetList.push_back( m_schematic->CurrentSheet() ); - // Store current unit value, to regenerate it after calculations - // (useful in complex hierarchies) - std::vector> symbolsChanged; + for( const SCH_SHEET_PATH& sheet : orderedSheetList ) + { + std::vector items; for( SCH_ITEM* item : sheet.LastScreen()->Items() ) { @@ -636,14 +653,7 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco if( item->Type() == SCH_SYMBOL_T ) { SCH_SYMBOL* symbol = static_cast( item ); - int new_unit = symbol->GetUnitSelection( &sheet ); - - // Store the initial unit value, to regenerate it after calculations, - // if modified - if( symbol->GetUnit() != new_unit ) - symbolsChanged.push_back( { symbol, symbol->GetUnit() } ); - - symbol->UpdateUnit( new_unit ); + symbol->UpdateUnit( symbol->GetUnitSelection( &sheet ) ); } } @@ -653,13 +663,6 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco // UpdateDanglingState() also adds connected items for SCH_TEXT sheet.LastScreen()->TestDanglingEnds( &sheet, aChangedItemHandler ); - - // Restore the m_unit member, to avoid changes in current active sheet path - // after calculations - for( auto& item : symbolsChanged ) - { - item.first->UpdateUnit( item.second ); - } } for( SCH_ITEM* item : dirty_items ) diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 33a15fdfae..f214e2a7ef 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -2138,8 +2138,12 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet() m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); - // update the References + // update the references, units, and intersheet-refs GetCurrentSheet().UpdateAllScreenReferences(); + + // dangling state can also have changed if different units with different pin locations are + // used + GetCurrentSheet().LastScreen()->TestDanglingEnds(); SetSheetNumberAndCount(); RefreshOperatingPointDisplay();