From e09147db30f2d0d43dbd911d68999f9d5ef7302d Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 17 Apr 2022 00:22:27 +0100 Subject: [PATCH] Cross-probing for ERC dialog. Fixes https://gitlab.com/kicad/code/kicad/issues/11411 --- eeschema/dialogs/dialog_erc.cpp | 31 ++++++++++++++++++++++++++- eeschema/dialogs/dialog_erc.h | 5 +++++ eeschema/tools/ee_inspection_tool.cpp | 21 ++++++++++++++++++ eeschema/tools/ee_inspection_tool.h | 1 + pcbnew/dialogs/dialog_drc.cpp | 12 +++++------ 5 files changed, 63 insertions(+), 7 deletions(-) diff --git a/eeschema/dialogs/dialog_erc.cpp b/eeschema/dialogs/dialog_erc.cpp index c1ba455fac..b1982296e7 100644 --- a/eeschema/dialogs/dialog_erc.cpp +++ b/eeschema/dialogs/dialog_erc.cpp @@ -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; diff --git a/eeschema/dialogs/dialog_erc.h b/eeschema/dialogs/dialog_erc.h index 49af5dd41f..bd9b1d2e79 100644 --- a/eeschema/dialogs/dialog_erc.h +++ b/eeschema/dialogs/dialog_erc.h @@ -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; }; diff --git a/eeschema/tools/ee_inspection_tool.cpp b/eeschema/tools/ee_inspection_tool.cpp index ec396268de..8c120434f6 100644 --- a/eeschema/tools/ee_inspection_tool.cpp +++ b/eeschema/tools/ee_inspection_tool.cpp @@ -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& 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( selection.Front() ) ); + } + } + + return 0; +} + + int EE_INSPECTION_TOOL::ExcludeMarker( const TOOL_EVENT& aEvent ) { EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool(); @@ -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() ); diff --git a/eeschema/tools/ee_inspection_tool.h b/eeschema/tools/ee_inspection_tool.h index d09b3e783a..d6d3b42ad2 100644 --- a/eeschema/tools/ee_inspection_tool.h +++ b/eeschema/tools/ee_inspection_tool.h @@ -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 ); diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp index 3b049fd347..ec7125b459 100644 --- a/pcbnew/dialogs/dialog_drc.cpp +++ b/pcbnew/dialogs/dialog_drc.cpp @@ -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 );