Introduce new marker type so we can track DRC errors on the drawing sheet.

Fixes https://gitlab.com/kicad/code/kicad/issues/12221
This commit is contained in:
Jeff Young 2022-08-15 17:59:34 +01:00
parent 4b3ac52b1d
commit 1f347582f8
27 changed files with 269 additions and 184 deletions

View File

@ -293,7 +293,7 @@ bool DS_DRAW_ITEM_POLYPOLYGONS::HitTest( const EDA_RECT& aRect, bool aContained,
wxString DS_DRAW_ITEM_POLYPOLYGONS::GetSelectMenuText( EDA_UNITS aUnits ) const wxString DS_DRAW_ITEM_POLYPOLYGONS::GetSelectMenuText( EDA_UNITS aUnits ) const
{ {
return wxString::Format( _( "Imported Shape" ) ); return _( "Imported Shape" );
} }

View File

@ -378,10 +378,17 @@ void RC_TREE_MODEL::GetValue( wxVariant& aVariant,
break; break;
case RC_TREE_NODE::MAIN_ITEM: case RC_TREE_NODE::MAIN_ITEM:
{ if( rcItem->GetParent()->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetMainItemID() ); {
aVariant = item->GetSelectMenuText( m_editFrame->GetUserUnits() ); aVariant = _( "Drawing Sheet" );
} break;
}
else
{
EDA_ITEM* item = m_editFrame->GetItem( rcItem->GetMainItemID() );
aVariant = item->GetSelectMenuText( m_editFrame->GetUserUnits() );
}
break; break;
case RC_TREE_NODE::AUX_ITEM: case RC_TREE_NODE::AUX_ITEM:

View File

@ -191,8 +191,8 @@ SCH_SYMBOL* SCH_PIN::GetParentSymbol() const
wxString SCH_PIN::GetSelectMenuText( EDA_UNITS aUnits ) const wxString SCH_PIN::GetSelectMenuText( EDA_UNITS aUnits ) const
{ {
return wxString::Format( "%s %s", return wxString::Format( "Symbol %s %s",
GetParentSymbol()->GetSelectMenuText( aUnits ), GetParentSymbol()->GetField( REFERENCE_FIELD )->GetShownText(),
m_libPin->GetSelectMenuText( aUnits ) ); m_libPin->GetSelectMenuText( aUnits ) );
} }

View File

@ -53,6 +53,7 @@ public:
MARKER_UNSPEC, MARKER_UNSPEC,
MARKER_ERC, MARKER_ERC,
MARKER_DRC, MARKER_DRC,
MARKER_DRAWING_SHEET,
MARKER_RATSNEST, MARKER_RATSNEST,
MARKER_PARITY, MARKER_PARITY,
MARKER_SIMUL MARKER_SIMUL

View File

@ -32,6 +32,7 @@
#include <drc/drc_item.h> #include <drc/drc_item.h>
#include <connectivity/connectivity_data.h> #include <connectivity/connectivity_data.h>
#include <connectivity/connectivity_algo.h> #include <connectivity/connectivity_algo.h>
#include <drawing_sheet/ds_proxy_view_item.h>
#include <pcb_edit_frame.h> #include <pcb_edit_frame.h>
#include <pcbnew_settings.h> #include <pcbnew_settings.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
@ -352,8 +353,6 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
{ {
BOARD* board = m_frame->GetBoard(); BOARD* board = m_frame->GetBoard();
RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() ); RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
const KIID& itemID = node ? RC_TREE_MODEL::ToUUID( aEvent.GetItem() ) : niluuid;
BOARD_ITEM* item = board->GetItem( itemID );
auto getActiveLayers = auto getActiveLayers =
[]( BOARD_ITEM* aItem ) -> LSET []( BOARD_ITEM* aItem ) -> LSET
@ -377,124 +376,154 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
} }
}; };
if( !node )
{
// list is being freed; don't do anything with null ptrs
aEvent.Skip();
return;
}
if( m_centerMarkerOnIdle ) if( m_centerMarkerOnIdle )
{ {
// we already came from a cross-probe of the marker in the document; don't go // we already came from a cross-probe of the marker in the document; don't go
// around in circles // around in circles
aEvent.Skip();
return;
} }
else if( node && item && item != DELETED_BOARD_ITEM::GetInstance() )
std::shared_ptr<RC_ITEM> rc_item = node->m_RcItem;
if( rc_item->GetErrorCode() == DRCE_UNRESOLVED_VARIABLE
&& rc_item->GetParent()->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
{ {
PCB_LAYER_ID principalLayer; m_frame->FocusOnLocation( node->m_RcItem->GetParent()->GetPos() );
LSET violationLayers;
std::shared_ptr<RC_ITEM> rc_item = node->m_RcItem;
BOARD_ITEM* a = board->GetItem( rc_item->GetMainItemID() );
BOARD_ITEM* b = board->GetItem( rc_item->GetAuxItemID() );
BOARD_ITEM* c = board->GetItem( rc_item->GetAuxItem2ID() );
BOARD_ITEM* d = board->GetItem( rc_item->GetAuxItem3ID() );
if( rc_item->GetErrorCode() == DRCE_MALFORMED_COURTYARD ) aEvent.Skip();
return;
}
const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
BOARD_ITEM* item = board->GetItem( itemID );
if( !item || item == DELETED_BOARD_ITEM::GetInstance() )
{
// nothing to highlight / focus on
aEvent.Skip();
return;
}
PCB_LAYER_ID principalLayer;
LSET violationLayers;
BOARD_ITEM* a = board->GetItem( rc_item->GetMainItemID() );
BOARD_ITEM* b = board->GetItem( rc_item->GetAuxItemID() );
BOARD_ITEM* c = board->GetItem( rc_item->GetAuxItem2ID() );
BOARD_ITEM* d = board->GetItem( rc_item->GetAuxItem3ID() );
if( rc_item->GetErrorCode() == DRCE_MALFORMED_COURTYARD )
{
if( a && ( a->GetFlags() & MALFORMED_B_COURTYARD ) > 0
&& ( a->GetFlags() & MALFORMED_F_COURTYARD ) == 0 )
{ {
if( a && ( a->GetFlags() & MALFORMED_B_COURTYARD ) > 0 principalLayer = B_CrtYd;
&& ( a->GetFlags() & MALFORMED_F_COURTYARD ) == 0 )
{
principalLayer = B_CrtYd;
}
else
{
principalLayer = F_CrtYd;
}
}
else if (rc_item->GetErrorCode() == DRCE_INVALID_OUTLINE )
{
principalLayer = Edge_Cuts;
} }
else else
{ {
principalLayer = UNDEFINED_LAYER; principalLayer = F_CrtYd;
}
}
else if (rc_item->GetErrorCode() == DRCE_INVALID_OUTLINE )
{
principalLayer = Edge_Cuts;
}
else
{
principalLayer = UNDEFINED_LAYER;
if( a || b || c || d ) if( a || b || c || d )
violationLayers = LSET::AllLayersMask(); violationLayers = LSET::AllLayersMask();
// Try to initialize principalLayer to a valid layer. Note that some markers have // Try to initialize principalLayer to a valid layer. Note that some markers have
// a layer set to UNDEFINED_LAYER, so we may need to keep looking. // a layer set to UNDEFINED_LAYER, so we may need to keep looking.
for( BOARD_ITEM* it: { a, b, c, d } ) for( BOARD_ITEM* it: { a, b, c, d } )
{
if( !it )
continue;
LSET layersList = getActiveLayers( it );
violationLayers &= layersList;
if( principalLayer <= UNDEFINED_LAYER && layersList.count() )
principalLayer = layersList.Seq().front();
}
}
if( violationLayers.count() )
principalLayer = violationLayers.Seq().front();
else if( !(principalLayer <= UNDEFINED_LAYER ) )
violationLayers.set( principalLayer );
WINDOW_THAWER thawer( m_frame );
if( principalLayer > UNDEFINED_LAYER && ( violationLayers & board->GetVisibleLayers() ) == 0 )
m_frame->GetAppearancePanel()->SetLayerVisible( principalLayer, true );
if( principalLayer > UNDEFINED_LAYER && board->GetVisibleLayers().test( principalLayer ) )
m_frame->SetActiveLayer( principalLayer );
if( rc_item->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
{
if( !m_frame->GetPcbNewSettings()->m_Display.m_ShowGlobalRatsnest )
m_frame->GetToolManager()->RunAction( PCB_ACTIONS::showRatsnest, true );
std::vector<CN_EDGE> edges;
m_frame->GetBoard()->GetConnectivity()->GetUnconnectedEdges( edges );
for( const CN_EDGE& edge : edges )
{
if( edge.GetSourceNode()->Parent() == a && edge.GetTargetNode()->Parent() == b )
{ {
if( !it ) if( item == a )
continue; m_frame->FocusOnLocation( edge.GetSourcePos() );
else
m_frame->FocusOnLocation( edge.GetTargetPos() );
LSET layersList = getActiveLayers( it ); break;
violationLayers &= layersList;
if( principalLayer <= UNDEFINED_LAYER && layersList.count() )
principalLayer = layersList.Seq().front();
} }
} }
}
else if( rc_item->GetErrorCode() == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG )
{
BOARD_CONNECTED_ITEM* track = dynamic_cast<PCB_TRACK*>( item );
std::vector<BOARD_ITEM*> items;
if( violationLayers.count() ) if( track )
principalLayer = violationLayers.Seq().front();
else if( !(principalLayer <= UNDEFINED_LAYER ) )
violationLayers.set( principalLayer );
WINDOW_THAWER thawer( m_frame );
if( principalLayer > UNDEFINED_LAYER && ( violationLayers & board->GetVisibleLayers() ) == 0 )
m_frame->GetAppearancePanel()->SetLayerVisible( principalLayer, true );
if( principalLayer > UNDEFINED_LAYER && board->GetVisibleLayers().test( principalLayer ) )
m_frame->SetActiveLayer( principalLayer );
if( rc_item->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
{ {
if( !m_frame->GetPcbNewSettings()->m_Display.m_ShowGlobalRatsnest ) int net = track->GetNetCode();
m_frame->GetToolManager()->RunAction( PCB_ACTIONS::showRatsnest, true );
std::vector<CN_EDGE> edges; wxASSERT( net > 0 ); // Without a net how can it be a diff-pair?
m_frame->GetBoard()->GetConnectivity()->GetUnconnectedEdges( edges );
for( const CN_EDGE& edge : edges ) for( const KIID& id : rc_item->GetIDs() )
{ {
if( edge.GetSourceNode()->Parent() == a && edge.GetTargetNode()->Parent() == b ) auto* candidate = dynamic_cast<BOARD_CONNECTED_ITEM*>( board->GetItem( id ) );
{
if( item == a )
m_frame->FocusOnLocation( edge.GetSourcePos() );
else
m_frame->FocusOnLocation( edge.GetTargetPos() );
break; if( candidate && candidate->GetNetCode() == net )
} items.push_back( candidate );
} }
} }
else if( rc_item->GetErrorCode() == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG )
{
BOARD_CONNECTED_ITEM* track = dynamic_cast<PCB_TRACK*>( item );
std::vector<BOARD_ITEM*> items;
if( track )
{
int net = track->GetNetCode();
wxASSERT( net > 0 ); // Without a net how can it be a diff-pair?
for( const KIID& id : rc_item->GetIDs() )
{
auto* candidate = dynamic_cast<BOARD_CONNECTED_ITEM*>( board->GetItem( id ) );
if( candidate && candidate->GetNetCode() == net )
items.push_back( candidate );
}
}
else
{
items.push_back( item );
}
m_frame->FocusOnItems( items, principalLayer );
}
else else
{ {
m_frame->FocusOnItem( item, principalLayer ); items.push_back( item );
} }
m_frame->FocusOnItems( items, principalLayer );
}
else
{
m_frame->FocusOnItem( item, principalLayer );
} }
aEvent.Skip(); aEvent.Skip();

View File

@ -1492,7 +1492,7 @@ bool DRC_ENGINE::IsErrorLimitExceeded( int error_code )
void DRC_ENGINE::ReportViolation( const std::shared_ptr<DRC_ITEM>& aItem, const VECTOR2I& aPos, void DRC_ENGINE::ReportViolation( const std::shared_ptr<DRC_ITEM>& aItem, const VECTOR2I& aPos,
PCB_LAYER_ID aMarkerLayer ) int aMarkerLayer )
{ {
static std::mutex globalLock; static std::mutex globalLock;

View File

@ -63,9 +63,9 @@ class DRC_RULE;
class DRC_CONSTRAINT; class DRC_CONSTRAINT;
typedef typedef std::function<void( const std::shared_ptr<DRC_ITEM>& aItem,
std::function<void( const std::shared_ptr<DRC_ITEM>& aItem, const VECTOR2I& aPos,
const VECTOR2I& aPos, PCB_LAYER_ID aLayer )> DRC_VIOLATION_HANDLER; int aLayer )> DRC_VIOLATION_HANDLER;
/** /**
@ -165,7 +165,7 @@ public:
bool RulesValid() { return m_rulesValid; } bool RulesValid() { return m_rulesValid; }
void ReportViolation( const std::shared_ptr<DRC_ITEM>& aItem, const VECTOR2I& aPos, void ReportViolation( const std::shared_ptr<DRC_ITEM>& aItem, const VECTOR2I& aPos,
PCB_LAYER_ID aMarkerLayer ); int aMarkerLayer );
bool KeepRefreshing( bool aWait = false ); bool KeepRefreshing( bool aWait = false );
void AdvanceProgress(); void AdvanceProgress();

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com * Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com
* Copyright (C) 2015-2021 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 2015-2022 KiCad Developers, see change_log.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -25,6 +25,7 @@
#include "wx/html/m_templ.h" #include "wx/html/m_templ.h"
#include "wx/html/styleparams.h" #include "wx/html/styleparams.h"
#include "core/kicad_algo.h"
#include <drc/drc_item.h> #include <drc/drc_item.h>
#include <drc/drc_rule.h> #include <drc/drc_rule.h>
#include <board.h> #include <board.h>
@ -438,11 +439,11 @@ void DRC_ITEMS_PROVIDER::SetSeverities( int aSeverities )
for( PCB_MARKER* marker : m_board->Markers() ) for( PCB_MARKER* marker : m_board->Markers() )
{ {
if( marker->GetMarkerType() != m_markerType ) if( alg::contains( m_markerTypes, marker->GetMarkerType() )
continue; && ( marker->GetSeverity() & m_severities ) > 0 )
{
if( marker->GetSeverity() & m_severities )
m_filteredMarkers.push_back( marker ); m_filteredMarkers.push_back( marker );
}
} }
} }
@ -456,11 +457,11 @@ int DRC_ITEMS_PROVIDER::GetCount( int aSeverity ) const
for( PCB_MARKER* marker : m_board->Markers() ) for( PCB_MARKER* marker : m_board->Markers() )
{ {
if( marker->GetMarkerType() != m_markerType ) if( alg::contains( m_markerTypes, marker->GetMarkerType() )
continue; && ( marker->GetSeverity() & aSeverity ) > 0 )
{
if( ( marker->GetSeverity() & aSeverity ) > 0 )
count++; count++;
}
} }
return count; return count;

View File

@ -216,11 +216,15 @@ private:
class DRC_ITEMS_PROVIDER : public RC_ITEMS_PROVIDER class DRC_ITEMS_PROVIDER : public RC_ITEMS_PROVIDER
{ {
public: public:
DRC_ITEMS_PROVIDER( BOARD* aBoard, MARKER_BASE::TYPEMARKER aMarkerType ) : DRC_ITEMS_PROVIDER( BOARD* aBoard, MARKER_BASE::TYPEMARKER aMarkerType,
MARKER_BASE::TYPEMARKER otherMarkerType = MARKER_BASE::MARKER_UNSPEC ) :
m_board( aBoard ), m_board( aBoard ),
m_markerType( aMarkerType ),
m_severities( 0 ) m_severities( 0 )
{ {
m_markerTypes.push_back( aMarkerType );
if( otherMarkerType != MARKER_BASE::MARKER_UNSPEC )
m_markerTypes.push_back( otherMarkerType );
} }
void SetSeverities( int aSeverities ) override; void SetSeverities( int aSeverities ) override;
@ -232,11 +236,11 @@ public:
void DeleteItem( int aIndex, bool aDeep ) override; void DeleteItem( int aIndex, bool aDeep ) override;
private: private:
BOARD* m_board; BOARD* m_board;
MARKER_BASE::TYPEMARKER m_markerType; std::vector<MARKER_BASE::TYPEMARKER> m_markerTypes;
int m_severities; int m_severities;
std::vector<PCB_MARKER*> m_filteredMarkers; std::vector<PCB_MARKER*> m_filteredMarkers;
}; };

View File

@ -72,7 +72,7 @@ const wxString DRC_TEST_PROVIDER::GetDescription() const { return wxEmptyString;
void DRC_TEST_PROVIDER::reportViolation( std::shared_ptr<DRC_ITEM>& item, void DRC_TEST_PROVIDER::reportViolation( std::shared_ptr<DRC_ITEM>& item,
const VECTOR2I& aMarkerPos, PCB_LAYER_ID aMarkerLayer ) const VECTOR2I& aMarkerPos, int aMarkerLayer )
{ {
if( item->GetViolatingRule() ) if( item->GetViolatingRule() )
accountCheck( item->GetViolatingRule() ); accountCheck( item->GetViolatingRule() );

View File

@ -97,7 +97,7 @@ protected:
virtual void reportAux( wxString fmt, ... ); virtual void reportAux( wxString fmt, ... );
virtual void reportViolation( std::shared_ptr<DRC_ITEM>& item, const VECTOR2I& aMarkerPos, virtual void reportViolation( std::shared_ptr<DRC_ITEM>& item, const VECTOR2I& aMarkerPos,
PCB_LAYER_ID aMarkerLayer ); int aMarkerLayer );
virtual bool reportProgress( int aCount, int aSize, int aDelta ); virtual bool reportProgress( int aCount, int aSize, int aDelta );
virtual bool reportPhase( const wxString& aStageName ); virtual bool reportPhase( const wxString& aStageName );

View File

@ -324,9 +324,9 @@ void DRC_TEST_PROVIDER_MISC::testTextVars()
if( text && text->GetShownText().Matches( wxT( "*${*}*" ) ) ) if( text && text->GetShownText().Matches( wxT( "*${*}*" ) ) )
{ {
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE ); std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
drcItem->SetItems( text ); drcItem->SetItems( drawingSheet );
reportViolation( drcItem, text->GetPosition(), UNDEFINED_LAYER ); reportViolation( drcItem, text->GetPosition(), LAYER_DRAWINGSHEET );
} }
} }
} }

View File

@ -881,7 +881,12 @@ void PCB_EDIT_FRAME::ResolveDRCExclusions()
BOARD_COMMIT commit( this ); BOARD_COMMIT commit( this );
for( PCB_MARKER* marker : GetBoard()->ResolveDRCExclusions() ) for( PCB_MARKER* marker : GetBoard()->ResolveDRCExclusions() )
{
if( marker->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
marker->GetRCItem()->SetItems( GetCanvas()->GetDrawingSheet() );
commit.Add( marker ); commit.Add( marker );
}
commit.Push( wxEmptyString, SKIP_UNDO | SKIP_SET_DIRTY ); commit.Push( wxEmptyString, SKIP_UNDO | SKIP_SET_DIRTY );

View File

@ -44,31 +44,39 @@
PCB_MARKER::PCB_MARKER( std::shared_ptr<RC_ITEM> aItem, const VECTOR2I& aPosition, PCB_MARKER::PCB_MARKER( std::shared_ptr<RC_ITEM> aItem, const VECTOR2I& aPosition, int aLayer ) :
PCB_LAYER_ID aLayer ) : BOARD_ITEM( nullptr, PCB_MARKER_T, F_Cu ), // parent set during BOARD::Add()
BOARD_ITEM( nullptr, PCB_MARKER_T, aLayer ), // parent set during BOARD::Add() MARKER_BASE( SCALING_FACTOR, aItem )
MARKER_BASE( SCALING_FACTOR, aItem )
{ {
if( m_rcItem ) if( m_rcItem )
{ {
m_rcItem->SetParent( this ); m_rcItem->SetParent( this );
switch( m_rcItem->GetErrorCode() ) if( aLayer == LAYER_DRAWINGSHEET )
{ {
case DRCE_UNCONNECTED_ITEMS: SetMarkerType( MARKER_BASE::MARKER_DRAWING_SHEET );
SetMarkerType( MARKER_BASE::MARKER_RATSNEST ); }
break; else
{
switch( m_rcItem->GetErrorCode() )
{
case DRCE_UNCONNECTED_ITEMS:
SetMarkerType( MARKER_BASE::MARKER_RATSNEST );
break;
case DRCE_MISSING_FOOTPRINT: case DRCE_MISSING_FOOTPRINT:
case DRCE_DUPLICATE_FOOTPRINT: case DRCE_DUPLICATE_FOOTPRINT:
case DRCE_EXTRA_FOOTPRINT: case DRCE_EXTRA_FOOTPRINT:
case DRCE_NET_CONFLICT: case DRCE_NET_CONFLICT:
SetMarkerType( MARKER_BASE::MARKER_PARITY ); SetMarkerType( MARKER_BASE::MARKER_PARITY );
break; break;
default: default:
SetMarkerType( MARKER_BASE::MARKER_DRC ); SetMarkerType( MARKER_BASE::MARKER_DRC );
break; break;
}
SetLayer( ToLAYER_ID( aLayer ) );
} }
} }
@ -89,23 +97,41 @@ wxString PCB_MARKER::Serialize() const
wxString lastItem; wxString lastItem;
if( m_rcItem->GetErrorCode() == DRCE_COPPER_SLIVER ) if( m_rcItem->GetErrorCode() == DRCE_COPPER_SLIVER )
lastItem = LayerName( m_layer ); {
return wxString::Format( wxT( "%s|%d|%d|%s|%s" ),
m_rcItem->GetSettingsKey(),
m_Pos.x,
m_Pos.y,
m_rcItem->GetMainItemID().AsString(),
LayerName( m_layer ) );
}
else if( m_rcItem->GetErrorCode() == DRCE_UNRESOLVED_VARIABLE
&& m_rcItem->GetParent()->GetMarkerType() == MARKER_DRAWING_SHEET )
{
return wxString::Format( wxT( "%s|%d|%d|%s|%s" ),
m_rcItem->GetSettingsKey(),
m_Pos.x,
m_Pos.y,
// Drawing sheet KIIDs aren't preserved between runs
wxEmptyString,
wxEmptyString );
}
else else
lastItem = m_rcItem->GetAuxItemID().AsString(); {
return wxString::Format( wxT( "%s|%d|%d|%s|%s" ),
return wxString::Format( wxT( "%s|%d|%d|%s|%s" ), m_rcItem->GetSettingsKey(),
m_rcItem->GetSettingsKey(), m_Pos.x,
m_Pos.x, m_Pos.y,
m_Pos.y, m_rcItem->GetMainItemID().AsString(),
m_rcItem->GetMainItemID().AsString(), m_rcItem->GetAuxItemID().AsString() );
lastItem ); }
} }
PCB_MARKER* PCB_MARKER::Deserialize( const wxString& data ) PCB_MARKER* PCB_MARKER::Deserialize( const wxString& data )
{ {
wxArrayString props = wxSplit( data, '|' ); wxArrayString props = wxSplit( data, '|' );
PCB_LAYER_ID markerLayer = F_Cu; int markerLayer = F_Cu;
VECTOR2I markerPos( (int) strtol( props[1].c_str(), nullptr, 10 ), VECTOR2I markerPos( (int) strtol( props[1].c_str(), nullptr, 10 ),
(int) strtol( props[2].c_str(), nullptr, 10 ) ); (int) strtol( props[2].c_str(), nullptr, 10 ) );
@ -122,11 +148,17 @@ PCB_MARKER* PCB_MARKER::Deserialize( const wxString& data )
{ {
if( LayerName( ToLAYER_ID( layer ) ) == props[4] ) if( LayerName( ToLAYER_ID( layer ) ) == props[4] )
{ {
markerLayer = ToLAYER_ID( layer ); markerLayer = layer;
break; break;
} }
} }
} }
else if( drcItem->GetErrorCode() == DRCE_UNRESOLVED_VARIABLE
&& props[3].IsEmpty() && props[4].IsEmpty() )
{
// Note: caller must load our item pointer with the drawing sheet proxy item
markerLayer = LAYER_DRAWINGSHEET;
}
else else
{ {
drcItem->SetItems( KIID( props[3] ), KIID( props[4] ) ); drcItem->SetItems( KIID( props[3] ), KIID( props[4] ) );
@ -143,24 +175,31 @@ void PCB_MARKER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_
aList.emplace_back( _( "Severity" ), GetSeverity() == RPT_SEVERITY_ERROR ? _( "Error" ) aList.emplace_back( _( "Severity" ), GetSeverity() == RPT_SEVERITY_ERROR ? _( "Error" )
: _( "Warning" ) ); : _( "Warning" ) );
wxString mainText; if( GetMarkerType() == MARKER_DRAWING_SHEET )
wxString auxText; {
EDA_ITEM* mainItem = nullptr; aList.emplace_back( _( "Drawing Sheet" ), wxEmptyString );
EDA_ITEM* auxItem = nullptr; }
else
{
wxString mainText;
wxString auxText;
EDA_ITEM* mainItem = nullptr;
EDA_ITEM* auxItem = nullptr;
if( m_rcItem->GetMainItemID() != niluuid ) if( m_rcItem->GetMainItemID() != niluuid )
mainItem = aFrame->GetItem( m_rcItem->GetMainItemID() ); mainItem = aFrame->GetItem( m_rcItem->GetMainItemID() );
if( m_rcItem->GetAuxItemID() != niluuid ) if( m_rcItem->GetAuxItemID() != niluuid )
auxItem = aFrame->GetItem( m_rcItem->GetAuxItemID() ); auxItem = aFrame->GetItem( m_rcItem->GetAuxItemID() );
if( mainItem ) if( mainItem )
mainText = mainItem->GetSelectMenuText( aFrame->GetUserUnits() ); mainText = mainItem->GetSelectMenuText( aFrame->GetUserUnits() );
if( auxItem ) if( auxItem )
auxText = auxItem->GetSelectMenuText( aFrame->GetUserUnits() ); auxText = auxItem->GetSelectMenuText( aFrame->GetUserUnits() );
aList.emplace_back( mainText, auxText ); aList.emplace_back( mainText, auxText );
}
} }

View File

@ -41,7 +41,7 @@ class MSG_PANEL_ITEM;
class PCB_MARKER : public BOARD_ITEM, public MARKER_BASE class PCB_MARKER : public BOARD_ITEM, public MARKER_BASE
{ {
public: public:
PCB_MARKER( std::shared_ptr<RC_ITEM> aItem, const VECTOR2I& aPos, PCB_LAYER_ID aLayer = F_Cu ); PCB_MARKER( std::shared_ptr<RC_ITEM> aItem, const VECTOR2I& aPos, int aLayer = F_Cu );
~PCB_MARKER(); ~PCB_MARKER();

View File

@ -486,7 +486,7 @@ bool WriteDRCReport( BOARD* aBoard, const wxString& aFileName, EDA_UNITS aUnits,
engine->SetProgressReporter( nullptr ); engine->SetProgressReporter( nullptr );
engine->SetViolationHandler( engine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2D aPos, PCB_LAYER_ID aLayer ) [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2D aPos, int aLayer )
{ {
if( aItem->GetErrorCode() == DRCE_MISSING_FOOTPRINT if( aItem->GetErrorCode() == DRCE_MISSING_FOOTPRINT
|| aItem->GetErrorCode() == DRCE_DUPLICATE_FOOTPRINT || aItem->GetErrorCode() == DRCE_DUPLICATE_FOOTPRINT

View File

@ -153,7 +153,7 @@ void DRC_TOOL::RunTests( PROGRESS_REPORTER* aProgressReporter, bool aRefillZones
zoneFiller->FillAllZones( m_drcDialog, aProgressReporter ); zoneFiller->FillAllZones( m_drcDialog, aProgressReporter );
} }
m_drcEngine->SetDrawingSheet( m_editFrame->GetCanvas()->GetDrawingSheet()); m_drcEngine->SetDrawingSheet( m_editFrame->GetCanvas()->GetDrawingSheet() );
if( aTestFootprints && !Kiface().IsSingle() ) if( aTestFootprints && !Kiface().IsSingle() )
{ {
@ -172,10 +172,9 @@ void DRC_TOOL::RunTests( PROGRESS_REPORTER* aProgressReporter, bool aRefillZones
m_drcEngine->SetProgressReporter( aProgressReporter ); m_drcEngine->SetProgressReporter( aProgressReporter );
m_drcEngine->SetViolationHandler( m_drcEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, PCB_LAYER_ID aLayer ) [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
{ {
PCB_MARKER* marker = new PCB_MARKER( aItem, aPos ); PCB_MARKER* marker = new PCB_MARKER( aItem, aPos, aLayer );
marker->SetLayer( aLayer );
commit.Add( marker ); commit.Add( marker );
} ); } );
@ -213,7 +212,8 @@ void DRC_TOOL::updatePointers()
if( m_drcDialog ) // Use dialog list boxes only in DRC_TOOL dialog if( m_drcDialog ) // Use dialog list boxes only in DRC_TOOL dialog
{ {
m_drcDialog->SetMarkersProvider( new DRC_ITEMS_PROVIDER( m_pcb, m_drcDialog->SetMarkersProvider( new DRC_ITEMS_PROVIDER( m_pcb,
MARKER_BASE::MARKER_DRC ) ); MARKER_BASE::MARKER_DRC,
MARKER_BASE::MARKER_DRAWING_SHEET ) );
m_drcDialog->SetRatsnestProvider( new DRC_ITEMS_PROVIDER( m_pcb, m_drcDialog->SetRatsnestProvider( new DRC_ITEMS_PROVIDER( m_pcb,
MARKER_BASE::MARKER_RATSNEST ) ); MARKER_BASE::MARKER_RATSNEST ) );
m_drcDialog->SetFootprintsProvider( new DRC_ITEMS_PROVIDER( m_pcb, m_drcDialog->SetFootprintsProvider( new DRC_ITEMS_PROVIDER( m_pcb,

View File

@ -648,8 +648,8 @@ int FOOTPRINT_EDITOR_CONTROL::CheckFootprint( const TOOL_EVENT& aEvent )
} }
else // The dialog is just not visible (because the user has double clicked on an error item) else // The dialog is just not visible (because the user has double clicked on an error item)
{ {
m_checkerDialog->SetMarkersProvider( m_checkerDialog->SetMarkersProvider( new DRC_ITEMS_PROVIDER( m_frame->GetBoard(),
new DRC_ITEMS_PROVIDER( m_frame->GetBoard(), MARKER_BASE::MARKER_DRC ) ); MARKER_BASE::MARKER_DRC ) );
m_checkerDialog->Show( true ); m_checkerDialog->Show( true );
} }

View File

@ -114,7 +114,7 @@ int runDRCProto( PROJECT_CONTEXT project, std::shared_ptr<KIGFX::VIEW_OVERLAY> a
drcEngine->SetProgressReporter( new CONSOLE_PROGRESS_REPORTER ( &consoleLog ) ); drcEngine->SetProgressReporter( new CONSOLE_PROGRESS_REPORTER ( &consoleLog ) );
drcEngine->SetViolationHandler( drcEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, PCB_LAYER_ID aLayer ) [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
{ {
// fixme // fixme
} ); } );

View File

@ -64,7 +64,7 @@ BOOST_FIXTURE_TEST_CASE( DRCCustomRuleSeverityTest, DRC_REGRESSION_TEST_FIXTURE
bds.m_DRCSeverities[ DRCE_FOOTPRINT_TYPE_MISMATCH ] = SEVERITY::RPT_SEVERITY_IGNORE; bds.m_DRCSeverities[ DRCE_FOOTPRINT_TYPE_MISMATCH ] = SEVERITY::RPT_SEVERITY_IGNORE;
bds.m_DRCEngine->SetViolationHandler( bds.m_DRCEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, PCB_LAYER_ID aLayer ) [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
{ {
PCB_MARKER temp( aItem, aPos ); PCB_MARKER temp( aItem, aPos );

View File

@ -75,7 +75,7 @@ BOOST_FIXTURE_TEST_CASE( DRCCopperConn, DRC_REGRESSION_TEST_FIXTURE )
bds.m_DRCSeverities[ DRCE_LIB_FOOTPRINT_MISMATCH ] = SEVERITY::RPT_SEVERITY_IGNORE; bds.m_DRCSeverities[ DRCE_LIB_FOOTPRINT_MISMATCH ] = SEVERITY::RPT_SEVERITY_IGNORE;
bds.m_DRCEngine->SetViolationHandler( bds.m_DRCEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, PCB_LAYER_ID aLayer ) [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
{ {
if( bds.GetSeverity( aItem->GetErrorCode() ) == SEVERITY::RPT_SEVERITY_ERROR ) if( bds.GetSeverity( aItem->GetErrorCode() ) == SEVERITY::RPT_SEVERITY_ERROR )
violations.push_back( *aItem ); violations.push_back( *aItem );

View File

@ -304,7 +304,7 @@ void DoCourtyardInvalidTest( const COURTYARD_INVALID_CASE& aCase,
drcEngine.InitEngine( wxFileName() ); drcEngine.InitEngine( wxFileName() );
drcEngine.SetViolationHandler( drcEngine.SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, PCB_LAYER_ID aLayer ) [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
{ {
if( aItem->GetErrorCode() == DRCE_OVERLAPPING_FOOTPRINTS if( aItem->GetErrorCode() == DRCE_OVERLAPPING_FOOTPRINTS
|| aItem->GetErrorCode() == DRCE_MALFORMED_COURTYARD || aItem->GetErrorCode() == DRCE_MALFORMED_COURTYARD

View File

@ -460,7 +460,7 @@ static void DoCourtyardOverlapTest( const COURTYARD_OVERLAP_TEST_CASE& aCase,
drcEngine.InitEngine( wxFileName() ); drcEngine.InitEngine( wxFileName() );
drcEngine.SetViolationHandler( drcEngine.SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, PCB_LAYER_ID aLayer ) [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
{ {
if( aItem->GetErrorCode() == DRCE_OVERLAPPING_FOOTPRINTS if( aItem->GetErrorCode() == DRCE_OVERLAPPING_FOOTPRINTS
|| aItem->GetErrorCode() == DRCE_MALFORMED_COURTYARD || aItem->GetErrorCode() == DRCE_MALFORMED_COURTYARD

View File

@ -81,7 +81,7 @@ BOOST_FIXTURE_TEST_CASE( DRCFalsePositiveRegressions, DRC_REGRESSION_TEST_FIXTUR
bds.m_DRCSeverities[ DRCE_LIB_FOOTPRINT_MISMATCH ] = SEVERITY::RPT_SEVERITY_IGNORE; bds.m_DRCSeverities[ DRCE_LIB_FOOTPRINT_MISMATCH ] = SEVERITY::RPT_SEVERITY_IGNORE;
bds.m_DRCEngine->SetViolationHandler( bds.m_DRCEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, PCB_LAYER_ID aLayer ) [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
{ {
if( bds.GetSeverity( aItem->GetErrorCode() ) == SEVERITY::RPT_SEVERITY_ERROR ) if( bds.GetSeverity( aItem->GetErrorCode() ) == SEVERITY::RPT_SEVERITY_ERROR )
violations.push_back( *aItem ); violations.push_back( *aItem );
@ -147,7 +147,7 @@ BOOST_FIXTURE_TEST_CASE( DRCFalseNegativeRegressions, DRC_REGRESSION_TEST_FIXTUR
bds.m_DRCSeverities[ DRCE_LIB_FOOTPRINT_MISMATCH ] = SEVERITY::RPT_SEVERITY_IGNORE; bds.m_DRCSeverities[ DRCE_LIB_FOOTPRINT_MISMATCH ] = SEVERITY::RPT_SEVERITY_IGNORE;
bds.m_DRCEngine->SetViolationHandler( bds.m_DRCEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, PCB_LAYER_ID aLayer ) [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
{ {
PCB_MARKER temp( aItem, aPos ); PCB_MARKER temp( aItem, aPos );

View File

@ -57,7 +57,7 @@ BOOST_FIXTURE_TEST_CASE( DRCSolderMaskBridgingTest, DRC_REGRESSION_TEST_FIXTURE
bds.m_DRCSeverities[ DRCE_STARVED_THERMAL ] = SEVERITY::RPT_SEVERITY_IGNORE; bds.m_DRCSeverities[ DRCE_STARVED_THERMAL ] = SEVERITY::RPT_SEVERITY_IGNORE;
bds.m_DRCEngine->SetViolationHandler( bds.m_DRCEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, PCB_LAYER_ID aLayer ) [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
{ {
PCB_MARKER temp( aItem, aPos ); PCB_MARKER temp( aItem, aPos );

View File

@ -179,7 +179,7 @@ BOOST_FIXTURE_TEST_CASE( TrackCleanerRegressionTests, TRACK_CLEANER_TEST_FIXTURE
bds.m_DRCSeverities[ DRCE_STARVED_THERMAL ] = SEVERITY::RPT_SEVERITY_IGNORE; bds.m_DRCSeverities[ DRCE_STARVED_THERMAL ] = SEVERITY::RPT_SEVERITY_IGNORE;
bds.m_DRCEngine->SetViolationHandler( bds.m_DRCEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, PCB_LAYER_ID aLayer ) [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
{ {
if( aItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS ) if( aItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
violations.push_back( *aItem ); violations.push_back( *aItem );

View File

@ -98,7 +98,7 @@ BOOST_FIXTURE_TEST_CASE( BasicZoneFills, ZONE_FILL_TEST_FIXTURE )
bds.m_DRCEngine->InitEngine( wxFileName() ); // Just to be sure to be sure bds.m_DRCEngine->InitEngine( wxFileName() ); // Just to be sure to be sure
bds.m_DRCEngine->SetViolationHandler( bds.m_DRCEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, PCB_LAYER_ID aLayer ) [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
{ {
if( aItem->GetErrorCode() == DRCE_CLEARANCE ) if( aItem->GetErrorCode() == DRCE_CLEARANCE )
{ {
@ -202,8 +202,7 @@ BOOST_FIXTURE_TEST_CASE( RegressionZoneFillTests, ZONE_FILL_TEST_FIXTURE )
std::vector<DRC_ITEM> violations; std::vector<DRC_ITEM> violations;
bds.m_DRCEngine->SetViolationHandler( bds.m_DRCEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
PCB_LAYER_ID aLayer )
{ {
if( aItem->GetErrorCode() == DRCE_CLEARANCE ) if( aItem->GetErrorCode() == DRCE_CLEARANCE )
violations.push_back( *aItem ); violations.push_back( *aItem );