Don't show redundant ERC markers from subsheets

Fixes https://gitlab.com/kicad/code/kicad/-/issues/7016
This commit is contained in:
Jon Evans 2021-01-12 22:18:44 -05:00
parent ac3e677fae
commit 5ceadbda3b
5 changed files with 74 additions and 41 deletions

View File

@ -2743,6 +2743,7 @@ int CONNECTION_GRAPH::ercCheckHierSheets()
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_HIERACHICAL_LABEL );
ercItem->SetItems( unmatched.second );
ercItem->SetErrorMessage( msg );
ercItem->SetIsSheetSpecific();
SCH_MARKER* marker = new SCH_MARKER( ercItem, unmatched.second->GetPosition() );
sheet.LastScreen()->Append( marker );

View File

@ -530,6 +530,7 @@ int ERC_TESTER::TestPinToPin()
ERC_ITEM::Create( erc == PIN_ERROR::WARNING ? ERCE_PIN_TO_PIN_WARNING :
ERCE_PIN_TO_PIN_ERROR );
ercItem->SetItems( refPin, testPin );
ercItem->SetIsSheetSpecific();
ercItem->SetErrorMessage(
wxString::Format( _( "Pins of type %s and %s are connected" ),
@ -602,6 +603,7 @@ int ERC_TESTER::TestMultUnitPinConflicts()
pin->GetNumber(), netName, pinToNetMap[name].first ) );
ercItem->SetItems( pin, pinToNetMap[name].second );
ercItem->SetIsSheetSpecific();
SCH_MARKER* marker = new SCH_MARKER( ercItem,
pin->GetTransformedPosition() );

View File

@ -52,12 +52,16 @@ public:
return allItemTypes;
}
bool IsSheetSpecific() const { return m_sheetSpecific; }
void SetIsSheetSpecific( bool aSpecific = true ) { m_sheetSpecific = aSpecific; }
private:
ERC_ITEM( int aErrorCode = 0, const wxString& aTitle = "", const wxString& aSettingsKey = "" )
{
m_errorCode = aErrorCode;
m_errorTitle = aTitle;
m_settingsKey = aSettingsKey;
m_sheetSpecific = false;
}
/// A list of all ERC_ITEM types which are valid error codes
@ -90,6 +94,9 @@ private:
static ERC_ITEM unresolvedVariable;
static ERC_ITEM wireDangling;
static ERC_ITEM libSymbolIssues;
/// True if this item is specific to a sheet instance (as opposed to applying to all instances)
bool m_sheetSpecific;
};

View File

@ -264,34 +264,60 @@ void ERC_SETTINGS::ResetPinMap()
}
void SHEETLIST_ERC_ITEMS_PROVIDER::visitMarkers( std::function<void( SCH_MARKER* )> aVisitor )
{
SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
std::set<SCH_SCREEN*> seenScreens;
for( unsigned i = 0; i < sheetList.size(); i++ )
{
bool firstTime = seenScreens.count( sheetList[i].LastScreen() ) == 0;
if( firstTime )
seenScreens.insert( sheetList[i].LastScreen() );
for( SCH_ITEM* aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) )
{
SCH_MARKER* marker = static_cast<SCH_MARKER*>( aItem );
if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC )
continue;
// Don't show non-specific markers more than once
if( !firstTime &&
!static_cast<ERC_ITEM*>( marker->GetRCItem().get() )->IsSheetSpecific() )
{
continue;
}
aVisitor( marker );
}
}
}
void SHEETLIST_ERC_ITEMS_PROVIDER::SetSeverities( int aSeverities )
{
m_severities = aSeverities;
m_filteredMarkers.clear();
SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
ERC_SETTINGS& settings = m_schematic->ErcSettings();
for( unsigned i = 0; i < sheetList.size(); i++ )
visitMarkers(
[&]( SCH_MARKER* aMarker )
{
for( SCH_ITEM* aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) )
{
SCH_MARKER* marker = static_cast<SCH_MARKER*>( aItem );
SEVERITY markerSeverity;
if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC )
continue;
if( marker->IsExcluded() )
if( aMarker->IsExcluded() )
markerSeverity = RPT_SEVERITY_EXCLUSION;
else
markerSeverity = settings.GetSeverity( marker->GetRCItem()->GetErrorCode() );
markerSeverity = settings.GetSeverity( aMarker->GetRCItem()->GetErrorCode() );
if( markerSeverity & m_severities )
m_filteredMarkers.push_back( marker );
}
}
m_filteredMarkers.push_back( aMarker );
} );
}
@ -302,28 +328,21 @@ int SHEETLIST_ERC_ITEMS_PROVIDER::GetCount( int aSeverity )
int count = 0;
SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
ERC_SETTINGS& settings = m_schematic->ErcSettings();
for( unsigned i = 0; i < sheetList.size(); i++ )
visitMarkers(
[&]( SCH_MARKER* aMarker )
{
for( SCH_ITEM* aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) )
{
SCH_MARKER* marker = static_cast<SCH_MARKER*>( aItem );
SEVERITY markerSeverity;
if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC )
continue;
if( marker->IsExcluded() )
if( aMarker->IsExcluded() )
markerSeverity = RPT_SEVERITY_EXCLUSION;
else
markerSeverity = settings.GetSeverity( marker->GetRCItem()->GetErrorCode() );
markerSeverity = settings.GetSeverity( aMarker->GetRCItem()->GetErrorCode() );
if( markerSeverity == aSeverity )
count++;
}
}
} );
return count;
}

View File

@ -194,6 +194,10 @@ public:
void DeleteItem( int aIndex, bool aDeep ) override;
void DeleteAllItems( bool aIncludeExclusions, bool aDeep ) override;
private:
void visitMarkers( std::function<void( SCH_MARKER* )> aVisitor );
};