Browse Source

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
newinvert
Jeff Young 2 years ago
parent
commit
84b0848a1e
  1. 41
      eeschema/connection_graph.cpp
  2. 6
      eeschema/sch_edit_frame.cpp

41
eeschema/connection_graph.cpp

@ -613,13 +613,30 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
m_sheetList = aSheetList;
std::set<SCH_ITEM*> 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<SCH_ITEM*> 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<std::pair<SCH_SYMBOL*, int>> symbolsChanged;
for( const SCH_SHEET_PATH& sheet : orderedSheetList )
{
std::vector<SCH_ITEM*> 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<SCH_SYMBOL*>( 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 )

6
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();

Loading…
Cancel
Save