Cross-probing for ERC dialog.

Fixes https://gitlab.com/kicad/code/kicad/issues/11411
This commit is contained in:
Jeff Young 2022-04-17 00:22:27 +01:00
parent 7f4f5f2882
commit e09147db30
5 changed files with 63 additions and 7 deletions

View File

@ -61,6 +61,7 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
m_parent( parent ),
m_running( false ),
m_ercRun( false ),
m_centerMarkerOnIdle( nullptr ),
m_severities( RPT_SEVERITY_ERROR | RPT_SEVERITY_WARNING )
{
SetName( DIALOG_ERC_WINDOW_NAME ); // Set a window name to be able to find it
@ -523,7 +524,12 @@ void DIALOG_ERC::OnERCItemSelected( wxDataViewEvent& aEvent )
SCH_SHEET_PATH sheet;
SCH_ITEM* item = m_parent->Schematic().GetSheets().GetItem( itemID, &sheet );
if( item && item->GetClass() != wxT( "DELETED_SHEET_ITEM" ) )
if( m_centerMarkerOnIdle )
{
// we already came from a cross-probe of the marker in the document; don't go
// around in circles
}
else if( item && item->GetClass() != wxT( "DELETED_SHEET_ITEM" ) )
{
WINDOW_THAWER thawer( m_parent );
@ -757,6 +763,29 @@ void DIALOG_ERC::NextMarker()
}
void DIALOG_ERC::SelectMarker( const SCH_MARKER* aMarker )
{
if( m_notebook->IsShown() )
{
m_notebook->SetSelection( 0 );
m_markerTreeModel->SelectMarker( aMarker );
// wxWidgets on some platforms fails to correctly ensure that a selected item is
// visible, so we have to do it in a separate idle event.
m_centerMarkerOnIdle = aMarker;
Bind( wxEVT_IDLE, &DIALOG_ERC::centerMarkerIdleHandler, this );
}
}
void DIALOG_ERC::centerMarkerIdleHandler( wxIdleEvent& aEvent )
{
m_markerTreeModel->CenterMarker( m_centerMarkerOnIdle );
m_centerMarkerOnIdle = nullptr;
Unbind( wxEVT_IDLE, &DIALOG_ERC::centerMarkerIdleHandler, this );
}
void DIALOG_ERC::ExcludeMarker( SCH_MARKER* aMarker )
{
SCH_MARKER* marker = aMarker;

View File

@ -53,6 +53,7 @@ public:
void PrevMarker();
void NextMarker();
void SelectMarker( const SCH_MARKER* aMarker );
/**
* Exclude aMarker from the ERC list. If aMarker is nullptr, exclude the selected marker
@ -81,6 +82,8 @@ private:
void OnSaveReport( wxCommandEvent& aEvent ) override;
void OnCancelClick( wxCommandEvent& event ) override;
void centerMarkerIdleHandler( wxIdleEvent& aEvent );
void redrawDrawPanel();
void testErc();
@ -104,6 +107,8 @@ private:
bool m_running;
bool m_ercRun;
const SCH_MARKER* m_centerMarkerOnIdle;
int m_severities;
};

View File

@ -151,6 +151,26 @@ int EE_INSPECTION_TOOL::NextMarker( const TOOL_EVENT& aEvent )
}
int EE_INSPECTION_TOOL::CrossProbe( const TOOL_EVENT& aEvent )
{
if( m_ercDialog )
{
EE_SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
EE_SELECTION& selection = selectionTool->GetSelection();
if( selection.GetSize() == 1 && selection.Front()->Type() == SCH_MARKER_T )
{
if( !m_ercDialog->IsShown() )
m_ercDialog->Show( true );
m_ercDialog->SelectMarker( static_cast<SCH_MARKER*>( selection.Front() ) );
}
}
return 0;
}
int EE_INSPECTION_TOOL::ExcludeMarker( const TOOL_EVENT& aEvent )
{
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
@ -311,6 +331,7 @@ void EE_INSPECTION_TOOL::setTransitions()
Go( &EE_INSPECTION_TOOL::RunERC, EE_ACTIONS::runERC.MakeEvent() );
Go( &EE_INSPECTION_TOOL::PrevMarker, EE_ACTIONS::prevMarker.MakeEvent() );
Go( &EE_INSPECTION_TOOL::NextMarker, EE_ACTIONS::nextMarker.MakeEvent() );
Go( &EE_INSPECTION_TOOL::CrossProbe, EVENTS::SelectedEvent );
Go( &EE_INSPECTION_TOOL::ExcludeMarker, EE_ACTIONS::excludeMarker.MakeEvent() );
Go( &EE_INSPECTION_TOOL::CheckSymbol, EE_ACTIONS::checkSymbol.MakeEvent() );

View File

@ -51,6 +51,7 @@ public:
int PrevMarker( const TOOL_EVENT& aEvent );
int NextMarker( const TOOL_EVENT& aEvent );
int CrossProbe( const TOOL_EVENT& aEvent );
int ExcludeMarker( const TOOL_EVENT& aEvent );
int CheckSymbol( const TOOL_EVENT& aEvent );

View File

@ -357,7 +357,12 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
}
};
if( node && item && item != DELETED_BOARD_ITEM::GetInstance() )
if( m_centerMarkerOnIdle )
{
// we already came from a cross-probe of the marker in the document; don't go
// around in circles
}
else if( node && item && item != DELETED_BOARD_ITEM::GetInstance() )
{
PCB_LAYER_ID principalLayer;
LSET violationLayers;
@ -466,11 +471,6 @@ void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
m_frame->FocusOnItems( items, principalLayer );
}
else if( m_centerMarkerOnIdle )
{
// we already came from a cross-probe of the marker in the document; don't go
// around in circles
}
else
{
m_frame->FocusOnItem( item, principalLayer );