Support ESC & Cancel for DRC.

Fixes https://gitlab.com/kicad/code/kicad/issues/5698
This commit is contained in:
Jeff Young 2020-09-18 20:57:54 +01:00
parent 73fc00ee69
commit 67b5d24995
23 changed files with 155 additions and 85 deletions

View File

@ -41,11 +41,13 @@
#include <widgets/progress_reporter.h>
#include <drc/drc_engine.h>
#include <tools/drc_tool.h>
#include <kiplatform/ui.h>
DIALOG_DRC::DIALOG_DRC( PCB_EDIT_FRAME* aEditorFrame, wxWindow* aParent ) :
DIALOG_DRC_BASE( aParent ),
PROGRESS_REPORTER( 1 ),
m_running( false ),
m_cancelled( false ),
m_drcRun( false ),
m_footprintTestsRun( false ),
m_markersProvider( nullptr ),
@ -160,8 +162,9 @@ bool DIALOG_DRC::updateUI()
int cur = std::max( 0, std::min( m_progress.load(), 10000 ) );
m_gauge->SetValue( cur );
wxSafeYield( this );
return true; // No cancel button on a wxGauge
return !m_cancelled;
}
@ -170,18 +173,12 @@ void DIALOG_DRC::AdvancePhase( const wxString& aMessage )
PROGRESS_REPORTER::AdvancePhase( aMessage );
m_Messages->AppendText( aMessage + "\n" );
KeepRefreshing( false );
wxSafeYield( this );
}
void DIALOG_DRC::SetCurrentProgress( double aProgress )
{
PROGRESS_REPORTER::SetCurrentProgress( aProgress );
KeepRefreshing( false );
wxSafeYield( this );
}
@ -208,6 +205,7 @@ void DIALOG_DRC::OnRunDRCClick( wxCommandEvent& aEvent )
m_drcRun = false;
m_footprintTestsRun = false;
m_cancelled = false;
m_brdEditor->RecordDRCExclusions();
deleteAllMarkers( true );
@ -218,19 +216,33 @@ void DIALOG_DRC::OnRunDRCClick( wxCommandEvent& aEvent )
m_runningResultsBook->ChangeSelection( 0 ); // Display the "Tests Running..." tab
m_Messages->Clear();
wxYield(); // Allows time slice to refresh Messages
wxYield(); // Allow time slice to refresh Messages
m_running = true;
m_sdbSizer1Cancel->SetLabel( _( "Cancel" ) );
drcTool->RunTests( this, testTracksAgainstZones, refillZones, reportAllTrackErrors,
testFootprints );
refreshBoardEditor();
if( m_cancelled )
m_Messages->AppendText( _( "-------- DRC cancelled by user.\n\n" ) );
else
m_Messages->AppendText( _( "Done.\n\n" ) );
wxYield();
Raise();
wxYield(); // Allow time slice to refresh Messages
m_runningResultsBook->ChangeSelection( 1 ); // display the results tabs
m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
m_running = false;
m_Notebook->GetPage( m_Notebook->GetSelection() )->SetFocus();
if( !m_cancelled )
{
wxMilliSleep( 500 );
m_runningResultsBook->ChangeSelection( 1 );
KIPLATFORM::UI::ForceFocus( m_markerDataView );
}
refreshBoardEditor();
}
@ -551,8 +563,25 @@ void DIALOG_DRC::OnSaveReport( wxCommandEvent& aEvent )
}
void DIALOG_DRC::OnClose( wxCloseEvent& aEvent )
{
if( m_running )
aEvent.Veto();
wxCommandEvent dummy;
OnCancelClick( dummy );
}
void DIALOG_DRC::OnCancelClick( wxCommandEvent& aEvent )
{
if( m_running )
{
m_cancelled = true;
return;
}
m_brdEditor->FocusOnItem( nullptr );
SetReturnCode( wxID_CANCEL );

View File

@ -81,10 +81,12 @@ private:
void OnDeleteOneClick( wxCommandEvent& aEvent ) override;
void OnDeleteAllClick( wxCommandEvent& aEvent ) override;
void OnRunDRCClick( wxCommandEvent& aEvent ) override;
void OnCancelClick( wxCommandEvent& aEvent ) override;
/// handler for activate event, updating data which can be modified outside the dialog
/// (DRC parameters)
// These require special handling while the DRC tests are running.
void OnCancelClick( wxCommandEvent& aEvent ) override;
void OnClose( wxCloseEvent& event ) override;
// Updates data which can be modified outside the dialog
void OnActivateDlg( wxActivateEvent& aEvent ) override;
void OnChangingNotebookPage( wxNotebookEvent& aEvent ) override;
@ -101,6 +103,8 @@ private:
BOARD* m_currentBoard; // the board currently on test
PCB_EDIT_FRAME* m_brdEditor;
bool m_running;
std::atomic<bool> m_cancelled;
bool m_drcRun;
bool m_footprintTestsRun;

View File

@ -221,6 +221,7 @@ DIALOG_DRC_BASE::DIALOG_DRC_BASE( wxWindow* parent, wxWindowID id, const wxStrin
// Connect Events
this->Connect( wxEVT_ACTIVATE, wxActivateEventHandler( DIALOG_DRC_BASE::OnActivateDlg ) );
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_DRC_BASE::OnClose ) );
m_Notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_DRC_BASE::OnChangingNotebookPage ), NULL, this );
m_markerDataView->Connect( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler( DIALOG_DRC_BASE::OnDRCItemDClick ), NULL, this );
m_markerDataView->Connect( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, wxDataViewEventHandler( DIALOG_DRC_BASE::OnDRCItemRClick ), NULL, this );
@ -244,6 +245,7 @@ DIALOG_DRC_BASE::~DIALOG_DRC_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_ACTIVATE, wxActivateEventHandler( DIALOG_DRC_BASE::OnActivateDlg ) );
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_DRC_BASE::OnClose ) );
m_Notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_DRC_BASE::OnChangingNotebookPage ), NULL, this );
m_markerDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, wxDataViewEventHandler( DIALOG_DRC_BASE::OnDRCItemDClick ), NULL, this );
m_markerDataView->Disconnect( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, wxDataViewEventHandler( DIALOG_DRC_BASE::OnDRCItemRClick ), NULL, this );

View File

@ -54,6 +54,7 @@
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnActivate">OnActivateDlg</event>
<event name="OnClose">OnClose</event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">m_MainSizer</property>

View File

@ -82,6 +82,7 @@ class DIALOG_DRC_BASE : public DIALOG_SHIM
// Virtual event handlers, overide them in your derived class
virtual void OnActivateDlg( wxActivateEvent& event ) { event.Skip(); }
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnChangingNotebookPage( wxNotebookEvent& event ) { event.Skip(); }
virtual void OnDRCItemDClick( wxDataViewEvent& event ) { event.Skip(); }
virtual void OnDRCItemRClick( wxDataViewEvent& event ) { event.Skip(); }

View File

@ -421,7 +421,9 @@ void DRC_ENGINE::RunTests( EDA_UNITS aUnits, bool aTestTracksAgainstZones,
drc_dbg( 0, "Running test provider: '%s'\n", provider->GetName() );
ReportAux( wxString::Format( "Run DRC provider: '%s'", provider->GetName() ) );
provider->Run();
if( !provider->Run() )
break;
}
}
@ -646,21 +648,23 @@ void DRC_ENGINE::ReportAux ( const wxString& aStr )
}
void DRC_ENGINE::ReportProgress( double aProgress )
bool DRC_ENGINE::ReportProgress( double aProgress )
{
if( !m_progressReporter )
return;
return true;
m_progressReporter->SetCurrentProgress( aProgress );
return m_progressReporter->KeepRefreshing( false );
}
void DRC_ENGINE::ReportPhase( const wxString& aMessage )
bool DRC_ENGINE::ReportPhase( const wxString& aMessage )
{
if( !m_progressReporter )
return;
return true;
m_progressReporter->AdvancePhase( aMessage );
return m_progressReporter->KeepRefreshing( false );
}

View File

@ -157,8 +157,8 @@ public:
bool CompileRules();
void ReportViolation( const std::shared_ptr<DRC_ITEM>& aItem, wxPoint aPos );
void ReportProgress( double aProgress );
void ReportPhase( const wxString& aMessage );
bool ReportProgress( double aProgress );
bool ReportPhase( const wxString& aMessage );
void ReportAux( const wxString& aStr );
bool QueryWorstConstraint( DRC_CONSTRAINT_TYPE_T aRuleId, DRC_CONSTRAINT& aConstraint,

View File

@ -46,16 +46,22 @@ void DRC_TEST_PROVIDER::reportViolation( std::shared_ptr<DRC_ITEM>& item, wxPoin
}
void DRC_TEST_PROVIDER::reportProgress( double aProgress )
bool DRC_TEST_PROVIDER::reportProgress( int aCount, int aSize, int aDelta )
{
m_drcEngine->ReportProgress( aProgress );
if( ( aCount % aDelta ) == 0 || aCount == aSize - 1 )
{
if( !m_drcEngine->ReportProgress( (double) aCount / (double) aSize ) )
return false;
}
return true;
}
void DRC_TEST_PROVIDER::reportPhase( const wxString& aMessage )
bool DRC_TEST_PROVIDER::reportPhase( const wxString& aMessage )
{
m_drcEngine->ReportPhase( aMessage );
reportAux( aMessage );
return m_drcEngine->ReportPhase( aMessage );
}

View File

@ -103,8 +103,8 @@ protected:
virtual void reportAux( wxString fmt, ... );
virtual void reportViolation( std::shared_ptr<DRC_ITEM>& item, wxPoint aMarkerPos );
virtual void reportProgress( double aProgress );
virtual void reportPhase( const wxString& aStageName );
virtual bool reportProgress( int aCount, int aSize, int aDelta );
virtual bool reportPhase( const wxString& aStageName );
virtual void reportRuleStatistics();
virtual void accountCheck( const DRC_RULE* ruleToTest );

View File

@ -76,7 +76,8 @@ bool DRC_TEST_PROVIDER_ANNULUS::Run()
return false;
}
reportPhase( _( "Checking via annular rings..." ));
if( !reportPhase( _( "Checking via annular rings..." ) ) )
return false;
auto checkAnnulus =
[&]( BOARD_ITEM* item ) -> bool
@ -137,10 +138,8 @@ bool DRC_TEST_PROVIDER_ANNULUS::Run()
for( TRACK* item : board->Tracks() )
{
if( (ii % delta) == 0 || ii >= (int) board->Tracks().size() - 1 )
reportProgress( (double) ii / (double) board->Tracks().size() );
ii++;
if( !reportProgress( ii++, board->Tracks().size(), delta ) )
break;
if( !checkAnnulus( item ) )
break;

View File

@ -72,7 +72,8 @@ public:
bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
{
reportPhase( _( "Checking dangling pads & vias..." ));
if( !reportPhase( _( "Checking dangling pads & vias..." ) ) )
return false;
BOARD* board = m_drcEngine->GetBoard();
@ -105,7 +106,8 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
}
}
reportPhase( _( "Checking starved zones..." ));
if( !reportPhase( _( "Checking starved zones..." ) ) )
return false;
/* test starved zones */
for( ZONE_CONTAINER* zone : board->Zones() )
@ -130,7 +132,8 @@ bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
}
}
reportPhase( _( "Checking net connections..." ));
if( !reportPhase( _( "Checking net connections..." ) ) )
return false;
connectivity->RecalculateRatsnest();
std::vector<CN_EDGE> edges;

View File

@ -122,16 +122,24 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
reportAux( "Worst clearance : %d nm", m_largestClearance );
reportPhase( _( "Checking pad clearances..." ));
if( !reportPhase( _( "Checking pad clearances..." ) ) )
return false;
testPadClearances();
reportPhase( _( "Checking track & via clearances..." ));
if( !reportPhase( _( "Checking track & via clearances..." ) ) )
return false;
testTrackClearances();
reportPhase( _( "Checking copper graphic & text clearances..." ));
if( !reportPhase( _( "Checking copper graphic & text clearances..." ) ) )
return false;
testCopperTextAndGraphics();
reportPhase( _( "Checking copper zone clearances..." ));
if( !reportPhase( _( "Checking copper zone clearances..." ) ) )
return false;
testZones();
reportRuleStatistics();
@ -295,17 +303,14 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
const int delta = m_drcEngine->GetTestTracksAgainstZones() ? 25 : 100;
int count = m_board->Tracks().size();
reportProgress( 0.0 );
reportAux( "Testing %d tracks...", count );
int ii = 0;
for( auto seg_it = m_board->Tracks().begin(); seg_it != m_board->Tracks().end(); seg_it++ )
{
if( (ii % delta) == 0 || ii >= (int) m_board->Tracks().size() - 1 )
reportProgress( (double) ii / (double) m_board->Tracks().size() );
ii++;
if( !reportProgress( ii++, m_board->Tracks().size(), delta ) )
break;
// Test segment against tracks and pads, optionally against copper zones
for( PCB_LAYER_ID layer : (*seg_it)->GetLayerSet().Seq() )
@ -552,8 +557,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( )
{
D_PAD* pad = sortedPads[idx];
if( idx % delta == 0 || idx == (int) sortedPads.size() - 1 )
reportProgress( (double) idx / (double) sortedPads.size() );
if( !reportProgress( idx, sortedPads.size(), delta ) )
break;
int x_limit = pad->GetPosition().x + pad->GetBoundingRadius() + max_size;
@ -667,6 +672,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::doPadToPadsDrc( int aRefPadIdx,
void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
{
const int delta = 50; // This is the number of tests between 2 calls to the progress bar
// Test copper areas for valid netcodes -> fixme, goes to connectivity checks
std::vector<SHAPE_POLY_SET> smoothed_polys;
@ -682,6 +689,9 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
// iterate through all areas
for( int ia = 0; ia < m_board->GetAreaCount(); ia++ )
{
if( !reportProgress( ia, m_board->GetAreaCount(), delta ) )
break;
ZONE_CONTAINER* zoneRef = m_board->GetArea( ia );
if( !zoneRef->IsOnCopperLayer() )

View File

@ -78,16 +78,15 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions()
const int delta = 100; // This is the number of tests between 2 calls to the progress bar
// Detects missing (or malformed) footprint courtyards
reportPhase( _( "Checking footprint courtyard definitions..." ));
if( !reportPhase( _( "Checking footprint courtyard definitions..." ) ) )
return;
int ii = 0;
for( MODULE* footprint : m_board->Modules() )
{
if( (ii % delta) == 0 || ii >= (int) m_board->Modules().size() - 1 )
reportProgress( (double) ii / (double) m_board->Modules().size() );
ii++;
if( !reportProgress( ii++, m_board->Modules().size(), delta ) )
return;
if( footprint->BuildPolyCourtyard() )
{
@ -128,16 +127,15 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testOverlappingComponentCourtyards()
{
const int delta = 100; // This is the number of tests between 2 calls to the progress bar
reportPhase( _( "Checking footprint courtyard overlap..." ));
if( !reportPhase( _( "Checking footprint courtyard overlap..." ) ) )
return;
int ii = 0;
for( auto it1 = m_board->Modules().begin(); it1 != m_board->Modules().end(); it1++ )
{
if( (ii % delta) == 0 || ii >= (int) m_board->Modules().size() - 1 )
reportProgress( (double) ii / (double) m_board->Modules().size() );
ii++;
if( !reportProgress( ii++, m_board->Modules().size(), delta ) )
break;
if( m_drcEngine->IsErrorLimitExceeded( DRCE_OVERLAPPING_FOOTPRINTS) )
break;

View File

@ -70,7 +70,8 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
return false;
}
reportPhase( _( "Checking keepouts & disallow constraints..." ));
if( !reportPhase( _( "Checking keepouts & disallow constraints..." ) ) )
return false;
auto checkItem = [&]( BOARD_ITEM *item ) -> bool
{

View File

@ -89,7 +89,8 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
reportAux( "Worst clearance : %d nm", m_largestClearance );
reportPhase( _( "Checking board edge clearances..." ));
if( !reportPhase( _( "Checking board edge clearances..." ) ) )
return false;
std::vector<DRAWSEGMENT*> boardOutline;
std::vector<BOARD_ITEM*> boardItems;

View File

@ -124,10 +124,14 @@ bool DRC_TEST_PROVIDER_HOLE_CLEARANCE::Run()
buildDrilledHoleList();
reportPhase( _( "Checking hole to pad clearances..." ));
if( !reportPhase( _( "Checking hole to pad clearances..." ) ) )
return false;
testPads2Holes();
reportPhase( _( "Checking hole to hole clearances..." ));
if( !reportPhase( _( "Checking hole to hole clearances..." ) ) )
return false;
testHoles2Holes();
reportRuleStatistics();
@ -202,8 +206,8 @@ void DRC_TEST_PROVIDER_HOLE_CLEARANCE::testPads2Holes()
drc_dbg( 10, "-> %p\n", pad );
if( idx % delta == 0 || idx == (int) sortedPads.size() - 1 )
reportProgress( (double) idx / (double) sortedPads.size() );
if( !reportProgress( idx, sortedPads.size(), delta ) )
break;
doPadToPadHoleDrc( idx, sortedPads, x_limit );
}
@ -369,8 +373,8 @@ void DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
for( size_t ii = 0; ii < m_drilledHoles.size(); ++ii )
{
if( ii % delta == 0 || ii == m_drilledHoles.size() - 1 )
reportProgress( (double) ii / (double) m_drilledHoles.size() );
if( !reportProgress( ii, m_drilledHoles.size(), delta ) )
break;
if( m_drcEngine->IsErrorLimitExceeded( DRCE_DRILLED_HOLES_TOO_CLOSE ) )
break;

View File

@ -76,7 +76,8 @@ private:
bool DRC_TEST_PROVIDER_HOLE_SIZE::Run()
{
reportPhase( _( "Checking pad holes..." ));
if( !reportPhase( _( "Checking pad holes..." ) ) )
return false;
m_board = m_drcEngine->GetBoard();
@ -94,7 +95,8 @@ bool DRC_TEST_PROVIDER_HOLE_SIZE::Run()
}
}
reportPhase( _( "Checking via holes..." ));
if( !reportPhase( _( "Checking via holes..." ) ) )
return false;
std::vector<VIA*> vias;

View File

@ -208,7 +208,8 @@ bool DRC_TEST_PROVIDER_LVS::Run()
{
if( m_drcEngine->GetTestFootprints() )
{
reportPhase( _( "Checking PCB to schematic parity..." ));
if( !reportPhase( _( "Checking PCB to schematic parity..." ) ) )
return false;
if( m_drcEngine->GetSchematicNetlist() )
testFootprints( *m_drcEngine->GetSchematicNetlist() );

View File

@ -191,13 +191,19 @@ bool DRC_TEST_PROVIDER_MISC::Run()
{
m_board = m_drcEngine->GetBoard();
reportPhase( _( "Checking board outline..." ));
if( !reportPhase( _( "Checking board outline..." ) ) )
return false;
testOutline();
reportPhase( _( "Checking disabled layers..." ));
if( !reportPhase( _( "Checking disabled layers..." ) ) )
return false;
testDisabledLayers();
reportPhase( _( "Checking text variables..." ));
if( !reportPhase( _( "Checking text variables..." ) ) )
return false;
testTextVars();
return true;

View File

@ -74,7 +74,8 @@ bool DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
return false;
}
reportPhase( _( "Checking track widths..." ));
if( !reportPhase( _( "Checking track widths..." ) ) )
return false;
auto checkTrackWidth =
[&]( BOARD_ITEM* item ) -> bool
@ -142,10 +143,8 @@ bool DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
for( TRACK* item : m_drcEngine->GetBoard()->Tracks() )
{
if( (ii % delta) == 0 || ii >= (int) m_drcEngine->GetBoard()->Tracks().size() - 1 )
reportProgress( (double) ii / (double) m_drcEngine->GetBoard()->Tracks().size() );
ii++;
if( !reportProgress( ii++, m_drcEngine->GetBoard()->Tracks().size(), delta ) )
break;
if( !checkTrackWidth( item ) )
break;

View File

@ -72,7 +72,8 @@ bool DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
return false;
}
reportPhase( _( "Checking via diameters..." ) );
if( !reportPhase( _( "Checking via diameters..." ) ) )
return false;
auto checkViaDiameter =
[&]( BOARD_ITEM* item ) -> bool
@ -129,10 +130,8 @@ bool DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
for( TRACK* item : m_drcEngine->GetBoard()->Tracks() )
{
if( (ii % delta) == 0 || ii >= (int) m_drcEngine->GetBoard()->Tracks().size() - 1 )
reportProgress( (double) ii / (double) m_drcEngine->GetBoard()->Tracks().size() );
ii++;
if( !reportProgress( ii++, m_drcEngine->GetBoard()->Tracks().size(), delta ) )
break;
if( !checkViaDiameter( item ) )
break;

View File

@ -217,8 +217,6 @@ void DRC_TOOL::RunTests( PROGRESS_REPORTER* aProgressReporter, bool aTestTracksA
// update the m_drcDialog listboxes
updatePointers();
aProgressReporter->AdvancePhase( _( "Done." ) );
}

View File

@ -82,6 +82,9 @@ private:
bool test::DRC_TEST_PROVIDER_SILK_TO_PAD::Run()
{
if( !reportPhase( _( "Checking pad to silkscreen clearances..." ) ) )
return false;
m_board = m_drcEngine->GetBoard();
DRC_CONSTRAINT worstClearanceConstraint;
@ -94,7 +97,6 @@ bool test::DRC_TEST_PROVIDER_SILK_TO_PAD::Run()
}
reportAux( "Worst clearance : %d nm", m_largestClearance );
reportPhase( _( "Checking pad to silkscreen clearances..." ) );
std::vector<DRAWSEGMENT*> boardOutline;
std::vector<BOARD_ITEM*> boardItems;