KiCad PCB EDA Suite
dialog_drc.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2009-2016 Dick Hollenbeck, [email protected]
6 * Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <confirm.h>
27#include <dialog_drc.h>
29#include <kiface_base.h>
30#include <macros.h>
31#include <pad.h>
32#include <drc/drc_item.h>
36#include <pcb_edit_frame.h>
37#include <pcbnew_settings.h>
38#include <tool/tool_manager.h>
39#include <tools/pcb_actions.h>
41#include <pcb_marker.h>
42#include <wx/filedlg.h>
43#include <wx/wupdlock.h>
45#include <widgets/ui_common.h>
49#include <tools/drc_tool.h>
52#include <kiplatform/ui.h>
53
54// wxWidgets spends *far* too long calcuating column widths (most of it, believe it or
55// not, in repeatedly creating/destroying a wxDC to do the measurement in).
56// Use default column widths instead.
57static int DEFAULT_SINGLE_COL_WIDTH = 660;
58
59static BOARD* g_lastDRCBoard = nullptr;
60static bool g_lastDRCRun = false;
61static bool g_lastFootprintTestsRun = false;
62static std::vector<wxString> g_lastIgnored;
63
64
65DIALOG_DRC::DIALOG_DRC( PCB_EDIT_FRAME* aEditorFrame, wxWindow* aParent ) :
66 DIALOG_DRC_BASE( aParent ),
68 m_running( false ),
69 m_cancelled( false ),
70 m_drcRun( false ),
71 m_footprintTestsRun( false ),
72 m_markersTreeModel( nullptr ),
73 m_unconnectedTreeModel( nullptr ),
74 m_fpWarningsTreeModel( nullptr ),
75 m_centerMarkerOnIdle( nullptr ),
77{
78 SetName( DIALOG_DRC_WINDOW_NAME ); // Set a window name to be able to find it
79
80 m_frame = aEditorFrame;
82
84
87
88 m_markersProvider = std::make_shared<DRC_ITEMS_PROVIDER>( m_currentBoard,
91
92 m_ratsnestProvider = std::make_shared<DRC_ITEMS_PROVIDER>( m_currentBoard,
94
95 m_fpWarningsProvider = std::make_shared<DRC_ITEMS_PROVIDER>( m_currentBoard,
97
99 m_markerDataView->AssociateModel( m_markersTreeModel );
101
105
109
110 m_ignoredList->InsertColumn( 0, wxEmptyString, wxLIST_FORMAT_LEFT, DEFAULT_SINGLE_COL_WIDTH );
111
113 {
116
117 for( const wxString& str : g_lastIgnored )
118 m_ignoredList->InsertItem( m_ignoredList->GetItemCount(), str );
119 }
120
121 m_Notebook->SetSelection( 0 );
122
123 if( Kiface().IsSingle() )
124 m_cbTestFootprints->Hide();
125
126 SetupStandardButtons( { { wxID_OK, _( "Run DRC" ) },
127 { wxID_CANCEL, _( "Close" ) } } );
128
129 m_markersTitleTemplate = m_Notebook->GetPageText( 0 );
130 m_unconnectedTitleTemplate = m_Notebook->GetPageText( 1 );
131 m_footprintsTitleTemplate = m_Notebook->GetPageText( 2 );
132 m_ignoredTitleTemplate = m_Notebook->GetPageText( 3 );
133
134 m_cbRefillZones->SetValue( cfg->m_DrcDialog.refill_zones );
136
137 if( !Kiface().IsSingle() )
139
140 Layout(); // adding the units above expanded Clearance text, now resize.
141
142 SetFocus();
143
145
147}
148
149
151{
152 m_frame->FocusOnItem( nullptr );
153
157
158 g_lastIgnored.clear();
159
160 for( int ii = 0; ii < m_ignoredList->GetItemCount(); ++ii )
161 g_lastIgnored.push_back( m_ignoredList->GetItemText( ii ) );
162
164 settings->m_DrcDialog.refill_zones = m_cbRefillZones->GetValue();
166
167 if( !Kiface().IsSingle() )
168 settings->m_DrcDialog.test_footprints = m_cbTestFootprints->GetValue();
169
171
172 m_markersTreeModel->DecRef();
173 m_unconnectedTreeModel->DecRef();
174 m_fpWarningsTreeModel->DecRef();
175}
176
177
178void DIALOG_DRC::OnActivateDlg( wxActivateEvent& aEvent )
179{
181 {
182 // If m_currentBoard is not the current board, (for instance because a new board
183 // was loaded), close the dialog, because many pointers are now invalid in lists
184 SetReturnCode( wxID_CANCEL );
185 Close();
186
188 drcTool->DestroyDRCDialog();
189 }
190}
191
192
193// PROGRESS_REPORTER calls
194
196{
197 double cur = (double) m_progress.load() / m_maxProgress;
198 cur = std::max( 0.0, std::min( cur, 1.0 ) );
199
200 m_gauge->SetValue( KiROUND( cur * 1000.0 ) );
201 wxSafeYield( this );
202
203 return !m_cancelled;
204}
205
206
207void DIALOG_DRC::AdvancePhase( const wxString& aMessage )
208{
210 SetCurrentProgress( 0.0 );
211
212 m_messages->Report( aMessage );
213}
214
215
216// Don't globally define this; different facilities use different definitions of "ALL"
218
219
221{
226}
227
228
229void DIALOG_DRC::OnErrorLinkClicked( wxHtmlLinkEvent& event )
230{
231 m_frame->ShowBoardSetupDialog( _( "Custom Rules" ) );
232}
233
234
235void DIALOG_DRC::OnRunDRCClick( wxCommandEvent& aEvent )
236{
237 TOOL_MANAGER* toolMgr = m_frame->GetToolManager();
238 DRC_TOOL* drcTool = toolMgr->GetTool<DRC_TOOL>();
239 ZONE_FILLER_TOOL* zoneFillerTool = toolMgr->GetTool<ZONE_FILLER_TOOL>();
240 bool refillZones = m_cbRefillZones->GetValue();
241 bool reportAllTrackErrors = m_cbReportAllTrackErrors->GetValue();
242 bool testFootprints = m_cbTestFootprints->GetValue();
243
244 if( zoneFillerTool->IsBusy() )
245 {
246 wxBell();
247 return;
248 }
249
250 // This is not the time to have stale or buggy rules. Ensure they're up-to-date
251 // and that they at least parse.
252 try
253 {
254 drcTool->GetDRCEngine()->InitEngine( m_frame->GetDesignRulesPath() );
255 }
256 catch( PARSE_ERROR& )
257 {
258 m_runningResultsBook->ChangeSelection( 0 ); // Display the "Tests Running..." tab
259 m_DeleteCurrentMarkerButton->Enable( false );
260 m_DeleteAllMarkersButton->Enable( false );
261 m_saveReport->Enable( false );
262
263 m_messages->Clear();
264 m_messages->Report( _( "DRC incomplete: could not compile custom design rules. " )
265 + wxT( "<a href='boardsetup'>" )
266 + _( "Show design rules." )
267 + wxT( "</a>" ) );
268 m_messages->Flush();
269
270 Raise();
271 return;
272 }
273
274 m_footprintTestsRun = false;
275 m_cancelled = false;
276
278 deleteAllMarkers( true );
279
280 std::vector<std::reference_wrapper<RC_ITEM>> violations = DRC_ITEM::GetItemsWithSeverities();
281 m_ignoredList->DeleteAllItems();
282
283 for( std::reference_wrapper<RC_ITEM>& item : violations )
284 {
285 if( bds().GetSeverity( item.get().GetErrorCode() ) == RPT_SEVERITY_IGNORE )
286 {
287 m_ignoredList->InsertItem( m_ignoredList->GetItemCount(),
288 wxT( " • " ) + item.get().GetErrorText() );
289 }
290 }
291
292 Raise();
293
294 m_runningResultsBook->ChangeSelection( 0 ); // Display the "Tests Running..." tab
295 m_messages->Clear();
296 wxYield(); // Allow time slice to refresh Messages
297
298 m_running = true;
299 m_sdbSizerCancel->SetLabel( _( "Cancel" ) );
300 m_sdbSizerOK->Enable( false );
301 m_DeleteCurrentMarkerButton->Enable( false );
302 m_DeleteAllMarkersButton->Enable( false );
303 m_saveReport->Enable( false );
304
305 {
306 wxBusyCursor dummy;
307 drcTool->RunTests( this, refillZones, reportAllTrackErrors, testFootprints );
308 }
309
310 if( m_cancelled )
311 m_messages->Report( _( "-------- DRC cancelled by user.<br><br>" ) );
312 else
313 m_messages->Report( _( "Done.<br><br>" ) );
314
315 Raise();
316 wxYield(); // Allow time slice to refresh Messages
317
318 m_running = false;
319 m_sdbSizerCancel->SetLabel( _( "Close" ) );
320 m_sdbSizerOK->Enable( true );
321 m_DeleteCurrentMarkerButton->Enable( true );
322 m_DeleteAllMarkersButton->Enable( true );
323 m_saveReport->Enable( true );
324
325 if( !m_cancelled )
326 {
327 wxMilliSleep( 500 );
328 m_runningResultsBook->ChangeSelection( 1 );
330 }
331
333}
334
335
337{
341
343}
344
345
346void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
347{
348 BOARD* board = m_frame->GetBoard();
349 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
350
351 auto getActiveLayers =
352 []( BOARD_ITEM* aItem ) -> LSET
353 {
354 if( aItem->Type() == PCB_PAD_T )
355 {
356 PAD* pad = static_cast<PAD*>( aItem );
357 LSET layers;
358
359 for( int layer : aItem->GetLayerSet().Seq() )
360 {
361 if( pad->FlashLayer( layer ) )
362 layers.set( layer );
363 }
364
365 return layers;
366 }
367 else
368 {
369 return aItem->GetLayerSet();
370 }
371 };
372
373 if( !node )
374 {
375 // list is being freed; don't do anything with null ptrs
376
377 aEvent.Skip();
378 return;
379 }
380
382 {
383 // we already came from a cross-probe of the marker in the document; don't go
384 // around in circles
385
386 aEvent.Skip();
387 return;
388 }
389
390 std::shared_ptr<RC_ITEM> rc_item = node->m_RcItem;
391
392 if( rc_item->GetErrorCode() == DRCE_UNRESOLVED_VARIABLE
393 && rc_item->GetParent()->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
394 {
395 m_frame->FocusOnLocation( node->m_RcItem->GetParent()->GetPos() );
396
397 aEvent.Skip();
398 return;
399 }
400
401 const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
402 BOARD_ITEM* item = board->GetItem( itemID );
403
404 if( !item || item == DELETED_BOARD_ITEM::GetInstance() )
405 {
406 // nothing to highlight / focus on
407
408 aEvent.Skip();
409 return;
410 }
411
412 PCB_LAYER_ID principalLayer;
413 LSET violationLayers;
414 BOARD_ITEM* a = board->GetItem( rc_item->GetMainItemID() );
415 BOARD_ITEM* b = board->GetItem( rc_item->GetAuxItemID() );
416 BOARD_ITEM* c = board->GetItem( rc_item->GetAuxItem2ID() );
417 BOARD_ITEM* d = board->GetItem( rc_item->GetAuxItem3ID() );
418
419 if( rc_item->GetErrorCode() == DRCE_MALFORMED_COURTYARD )
420 {
421 if( a && ( a->GetFlags() & MALFORMED_B_COURTYARD ) > 0
422 && ( a->GetFlags() & MALFORMED_F_COURTYARD ) == 0 )
423 {
424 principalLayer = B_CrtYd;
425 }
426 else
427 {
428 principalLayer = F_CrtYd;
429 }
430 }
431 else if (rc_item->GetErrorCode() == DRCE_INVALID_OUTLINE )
432 {
433 principalLayer = Edge_Cuts;
434 }
435 else
436 {
437 principalLayer = UNDEFINED_LAYER;
438
439 if( a || b || c || d )
440 violationLayers = LSET::AllLayersMask();
441
442 // Try to initialize principalLayer to a valid layer. Note that some markers have
443 // a layer set to UNDEFINED_LAYER, so we may need to keep looking.
444
445 for( BOARD_ITEM* it: { a, b, c, d } )
446 {
447 if( !it )
448 continue;
449
450 LSET layersList = getActiveLayers( it );
451 violationLayers &= layersList;
452
453 if( principalLayer <= UNDEFINED_LAYER && layersList.count() )
454 principalLayer = layersList.Seq().front();
455 }
456 }
457
458 if( violationLayers.count() )
459 principalLayer = violationLayers.Seq().front();
460 else if( !(principalLayer <= UNDEFINED_LAYER ) )
461 violationLayers.set( principalLayer );
462
463 WINDOW_THAWER thawer( m_frame );
464
465 if( principalLayer > UNDEFINED_LAYER && ( violationLayers & board->GetVisibleLayers() ) == 0 )
466 m_frame->GetAppearancePanel()->SetLayerVisible( principalLayer, true );
467
468 if( principalLayer > UNDEFINED_LAYER && board->GetVisibleLayers().test( principalLayer ) )
469 m_frame->SetActiveLayer( principalLayer );
470
471 if( rc_item->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
472 {
475
476 if( item->Type() == PCB_ZONE_T )
477 {
478 m_frame->GetBoard()->GetConnectivity()->RunOnUnconnectedEdges(
479 [&]( CN_EDGE& edge )
480 {
481 if( edge.GetSourceNode()->Parent() == a
482 && edge.GetTargetNode()->Parent() == b )
483 {
484 if( item == a )
485 m_frame->FocusOnLocation( edge.GetSourcePos() );
486 else
487 m_frame->FocusOnLocation( edge.GetTargetPos() );
488
489 return false;
490 }
491
492 return true;
493 } );
494 }
495 else
496 {
497 m_frame->FocusOnItem( item, principalLayer );
498 }
499 }
500 else if( rc_item->GetErrorCode() == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG )
501 {
502 BOARD_CONNECTED_ITEM* track = dynamic_cast<PCB_TRACK*>( item );
503 std::vector<BOARD_ITEM*> items;
504
505 if( track )
506 {
507 int net = track->GetNetCode();
508
509 wxASSERT( net > 0 ); // Without a net how can it be a diff-pair?
510
511 for( const KIID& id : rc_item->GetIDs() )
512 {
513 auto* candidate = dynamic_cast<BOARD_CONNECTED_ITEM*>( board->GetItem( id ) );
514
515 if( candidate && candidate->GetNetCode() == net )
516 items.push_back( candidate );
517 }
518 }
519 else
520 {
521 items.push_back( item );
522 }
523
524 m_frame->FocusOnItems( items, principalLayer );
525 }
526 else
527 {
528 m_frame->FocusOnItem( item, principalLayer );
529 }
530
531 aEvent.Skip();
532}
533
534
535void DIALOG_DRC::OnDRCItemDClick( wxDataViewEvent& aEvent )
536{
537 if( aEvent.GetItem().IsOk() )
538 {
539 // turn control over to m_frame, hide this DIALOG_DRC window,
540 // no destruction so we can preserve listbox cursor
541 if( !IsModal() )
542 Show( false );
543 }
544
545 // Do not skip aEvent here: this is not useful, and Pcbnew crashes
546 // if skipped (at least on Windows)
547}
548
549
550void DIALOG_DRC::OnDRCItemRClick( wxDataViewEvent& aEvent )
551{
552 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
553
554 if( !node )
555 return;
556
557 std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
558 DRC_ITEM* drcItem = static_cast<DRC_ITEM*>( rcItem.get() );
559 std::shared_ptr<CONNECTIVITY_DATA> conn = m_currentBoard->GetConnectivity();
560 wxString listName;
561 wxMenu menu;
562 wxString msg;
563
564 switch( bds().m_DRCSeverities[ rcItem->GetErrorCode() ] )
565 {
566 case RPT_SEVERITY_ERROR: listName = _( "errors" ); break;
567 case RPT_SEVERITY_WARNING: listName = _( "warnings" ); break;
568 default: listName = _( "appropriate" ); break;
569 }
570
571 if( rcItem->GetParent()->IsExcluded() )
572 {
573 menu.Append( 1, _( "Remove exclusion for this violation" ),
574 wxString::Format( _( "It will be placed back in the %s list" ), listName ) );
575
576 if( drcItem->GetViolatingRule() && !drcItem->GetViolatingRule()->m_Implicit )
577 {
578 msg.Printf( _( "Remove all exclusions for violations of rule '%s'" ),
579 drcItem->GetViolatingRule()->m_Name );
580 menu.Append( 11, msg );
581 }
582 }
583 else
584 {
585 menu.Append( 2, _( "Exclude this violation" ),
586 wxString::Format( _( "It will be excluded from the %s list" ), listName ) );
587
588 if( drcItem->GetViolatingRule() && !drcItem->GetViolatingRule()->m_Implicit )
589 {
590 msg.Printf( _( "Exclude all violations of rule '%s'" ),
591 drcItem->GetViolatingRule()->m_Name );
592 menu.Append( 21, msg );
593 }
594 }
595
596 if( rcItem->GetErrorCode() == DRCE_CLEARANCE
597 || rcItem->GetErrorCode() == DRCE_EDGE_CLEARANCE
598 || rcItem->GetErrorCode() == DRCE_HOLE_CLEARANCE
599 || rcItem->GetErrorCode() == DRCE_DRILLED_HOLES_TOO_CLOSE )
600 {
601 menu.Append( 3, _( "Run clearance resolution tool..." ) );
602 }
603 else if( rcItem->GetErrorCode() == DRCE_TEXT_HEIGHT
604 || rcItem->GetErrorCode() == DRCE_TEXT_THICKNESS
605 || rcItem->GetErrorCode() == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG
606 || rcItem->GetErrorCode() == DRCE_TRACK_WIDTH
607 || rcItem->GetErrorCode() == DRCE_VIA_DIAMETER
608 || rcItem->GetErrorCode() == DRCE_ANNULAR_WIDTH
609 || rcItem->GetErrorCode() == DRCE_DRILL_OUT_OF_RANGE
610 || rcItem->GetErrorCode() == DRCE_MICROVIA_DRILL_OUT_OF_RANGE
611 || rcItem->GetErrorCode() == DRCE_CONNECTION_WIDTH )
612 {
613 menu.Append( 3, _( "Run constraints resolution tool..." ) );
614 }
615
616 menu.AppendSeparator();
617
618 if( bds().m_DRCSeverities[ rcItem->GetErrorCode() ] == RPT_SEVERITY_WARNING )
619 {
620 msg.Printf( _( "Change severity to Error for all '%s' violations" ),
621 rcItem->GetErrorText(),
622 _( "Violation severities can also be edited in the Board Setup... dialog" ) );
623 menu.Append( 4, msg );
624 }
625 else
626 {
627 msg.Printf( _( "Change severity to Warning for all '%s' violations" ),
628 rcItem->GetErrorText(),
629 _( "Violation severities can also be edited in the Board Setup... dialog" ) );
630 menu.Append( 5, msg );
631 }
632
633 msg.Printf( _( "Ignore all '%s' violations" ),
634 rcItem->GetErrorText(),
635 _( "Violations will not be checked or reported" ) );
636 menu.Append( 6, msg );
637
638 menu.AppendSeparator();
639
640 menu.Append( 7, _( "Edit violation severities..." ), _( "Open the Board Setup... dialog" ) );
641
642 bool modified = false;
643
644 switch( GetPopupMenuSelectionFromUser( menu ) )
645 {
646 case 1:
647 {
648 PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( rcItem->GetParent() );
649
650 if( marker )
651 {
652 marker->SetExcluded( false );
653
654 if( rcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
655 {
658 }
659 else
660 {
661 m_frame->GetCanvas()->GetView()->Update( marker );
662 }
663
664 // Update view
665 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
666 modified = true;
667 }
668
669 break;
670 }
671
672 case 2:
673 {
674 PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( rcItem->GetParent() );
675
676 if( marker )
677 {
678 marker->SetExcluded( true );
679
680 if( rcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
681 {
684 }
685 else
686 {
687 m_frame->GetCanvas()->GetView()->Update( marker );
688 }
689
690 // Update view
692 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
693 else
694 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->DeleteCurrentItem( false );
695
696 modified = true;
697 }
698
699 break;
700 }
701
702 case 11:
703 {
704 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
705 {
706 DRC_ITEM* candidateDrcItem = static_cast<DRC_ITEM*>( marker->GetRCItem().get() );
707
708 if( candidateDrcItem->GetViolatingRule() == drcItem->GetViolatingRule() )
709 marker->SetExcluded( false );
710 }
711
712 // Rebuild model and view
713 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
714 modified = true;
715 break;
716 }
717
718 case 21:
719 {
720 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
721 {
722 DRC_ITEM* candidateDrcItem = static_cast<DRC_ITEM*>( marker->GetRCItem().get() );
723
724 if( candidateDrcItem->GetViolatingRule() == drcItem->GetViolatingRule() )
725 marker->SetExcluded( true );
726 }
727
728 // Rebuild model and view
729 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
730 modified = true;
731 break;
732 }
733
734 case 3:
735 {
736 TOOL_MANAGER* toolMgr = m_frame->GetToolManager();
737 BOARD_INSPECTION_TOOL* inspectionTool = toolMgr->GetTool<BOARD_INSPECTION_TOOL>();
738
739 inspectionTool->InspectDRCError( node->m_RcItem );
740 break;
741 }
742
743 case 4:
744 bds().m_DRCSeverities[ rcItem->GetErrorCode() ] = RPT_SEVERITY_ERROR;
745
746 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
747 {
748 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
749 m_frame->GetCanvas()->GetView()->Update( marker );
750 }
751
752 // Rebuild model and view
753 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
754 modified = true;
755 break;
756
757 case 5:
758 bds().m_DRCSeverities[ rcItem->GetErrorCode() ] = RPT_SEVERITY_WARNING;
759
760 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
761 {
762 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
763 m_frame->GetCanvas()->GetView()->Update( marker );
764 }
765
766 // Rebuild model and view
767 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
768 modified = true;
769 break;
770
771 case 6:
772 {
773 bds().m_DRCSeverities[ rcItem->GetErrorCode() ] = RPT_SEVERITY_IGNORE;
774
775 m_ignoredList->InsertItem( m_ignoredList->GetItemCount(),
776 wxT( " • " ) + rcItem->GetErrorText() );
777
778 std::vector<PCB_MARKER*>& markers = m_frame->GetBoard()->Markers();
779
780 for( unsigned i = 0; i < markers.size(); )
781 {
782 if( markers[i]->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
783 {
784 m_frame->GetCanvas()->GetView()->Remove( markers.at( i ) );
785 markers.erase( markers.begin() + i );
786 }
787 else
788 {
789 ++i;
790 }
791 }
792
793 if( rcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
795
796 // Rebuild model and view
797 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
798 modified = true;
799 break;
800 }
801
802 case 7:
803 m_frame->ShowBoardSetupDialog( _( "Violation Severity" ) );
804 break;
805 }
806
807 if( modified )
808 {
811 m_frame->OnModify();
812 }
813}
814
815
816void DIALOG_DRC::OnEditViolationSeverities( wxHyperlinkEvent& aEvent )
817{
818 m_frame->ShowBoardSetupDialog( _( "Violation Severity" ) );
819}
820
821
822void DIALOG_DRC::OnSeverity( wxCommandEvent& aEvent )
823{
824 int flag = 0;
825
826 if( aEvent.GetEventObject() == m_showAll )
828 else if( aEvent.GetEventObject() == m_showErrors )
830 else if( aEvent.GetEventObject() == m_showWarnings )
832 else if( aEvent.GetEventObject() == m_showExclusions )
834
835 if( aEvent.IsChecked() )
837 else if( aEvent.GetEventObject() == m_showAll )
839 else
840 m_severities &= ~flag;
841
843 UpdateData();
844}
845
846
847void DIALOG_DRC::OnSaveReport( wxCommandEvent& aEvent )
848{
849 wxFileName fn( "DRC." + ReportFileExtension );
850
851 wxFileDialog dlg( this, _( "Save Report to File" ), Prj().GetProjectPath(), fn.GetFullName(),
852 ReportFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
853
854 if( dlg.ShowModal() != wxID_OK )
855 return;
856
857 fn = dlg.GetPath();
858
859 if( fn.GetExt().IsEmpty() )
860 fn.SetExt( ReportFileExtension );
861
862 if( !fn.IsAbsolute() )
863 {
864 wxString prj_path = Prj().GetProjectPath();
865 fn.MakeAbsolute( prj_path );
866 }
867
868 if( writeReport( fn.GetFullPath() ) )
869 {
870 m_messages->Report( wxString::Format( _( "Report file '%s' created<br>" ),
871 fn.GetFullPath() ) );
872 }
873 else
874 {
875 DisplayError( this, wxString::Format( _( "Failed to create file '%s'." ),
876 fn.GetFullPath() ) );
877 }
878}
879
880
881void DIALOG_DRC::OnClose( wxCloseEvent& aEvent )
882{
883 if( m_running )
884 aEvent.Veto();
885
886 wxCommandEvent dummy;
887
889}
890
891
892void DIALOG_DRC::OnCancelClick( wxCommandEvent& aEvent )
893{
894 if( m_running )
895 {
896 m_cancelled = true;
897 return;
898 }
899
900 m_frame->FocusOnItem( nullptr );
901
902 SetReturnCode( wxID_CANCEL );
903
904 // The dialog can be modal or not modal.
905 // Leave the DRC caller destroy (or not) the dialog
907 drcTool->DestroyDRCDialog();
908}
909
910
911void DIALOG_DRC::OnChangingNotebookPage( wxNotebookEvent& aEvent )
912{
913 // Shouldn't be necessary, but is on at least OSX
914 if( aEvent.GetSelection() >= 0 )
915 m_Notebook->ChangeSelection( (unsigned) aEvent.GetSelection() );
916
917 m_markerDataView->UnselectAll();
918 m_unconnectedDataView->UnselectAll();
919 m_footprintsDataView->UnselectAll();
920}
921
922
924{
925 WINDOW_THAWER thawer( m_frame );
926
928}
929
930
932{
933 if( m_Notebook->IsShown() )
934 {
935 switch( m_Notebook->GetSelection() )
936 {
937 case 0: m_markersTreeModel->PrevMarker(); break;
938 case 1: m_unconnectedTreeModel->PrevMarker(); break;
939 case 2: m_fpWarningsTreeModel->PrevMarker(); break;
940 case 3: break;
941 }
942 }
943}
944
945
947{
948 if( m_Notebook->IsShown() )
949 {
950 switch( m_Notebook->GetSelection() )
951 {
952 case 0: m_markersTreeModel->NextMarker(); break;
953 case 1: m_unconnectedTreeModel->NextMarker(); break;
954 case 2: m_fpWarningsTreeModel->NextMarker(); break;
955 case 3: break;
956 }
957 }
958}
959
960
962{
963 if( m_Notebook->IsShown() )
964 {
965 m_Notebook->SetSelection( 0 );
967
968 // wxWidgets on some platforms fails to correctly ensure that a selected item is
969 // visible, so we have to do it in a separate idle event.
970 m_centerMarkerOnIdle = aMarker;
971 Bind( wxEVT_IDLE, &DIALOG_DRC::centerMarkerIdleHandler, this );
972 }
973}
974
975
976void DIALOG_DRC::centerMarkerIdleHandler( wxIdleEvent& aEvent )
977{
979 m_centerMarkerOnIdle = nullptr;
980 Unbind( wxEVT_IDLE, &DIALOG_DRC::centerMarkerIdleHandler, this );
981}
982
983
985{
986 if( !m_Notebook->IsShown() || m_Notebook->GetSelection() != 0 )
987 return;
988
989 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( m_markerDataView->GetCurrentItem() );
990 PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( node->m_RcItem->GetParent() );
991
992 if( marker && marker->GetSeverity() != RPT_SEVERITY_EXCLUSION )
993 {
994 marker->SetExcluded( true );
995 m_frame->GetCanvas()->GetView()->Update( marker );
996
997 // Update view
1000 else
1002
1004 refreshEditor();
1005 m_frame->OnModify();
1006 }
1007}
1008
1009
1010void DIALOG_DRC::deleteAllMarkers( bool aIncludeExclusions )
1011{
1012 // Clear current selection list to avoid selection of deleted items
1014
1015 m_markersTreeModel->DeleteItems( false, aIncludeExclusions, false );
1016 m_unconnectedTreeModel->DeleteItems( false, aIncludeExclusions, false );
1017 m_fpWarningsTreeModel->DeleteItems( false, aIncludeExclusions, false );
1018
1019 m_frame->GetBoard()->DeleteMARKERs( true, aIncludeExclusions );
1020}
1021
1022
1023bool DIALOG_DRC::writeReport( const wxString& aFullFileName )
1024{
1025 FILE* fp = wxFopen( aFullFileName, wxT( "w" ) );
1026
1027 if( fp == nullptr )
1028 return false;
1029
1030 std::map<KIID, EDA_ITEM*> itemMap;
1031 m_frame->GetBoard()->FillItemMap( itemMap );
1032
1034 UNITS_PROVIDER unitsProvider( pcbIUScale, GetUserUnits() );
1035 int count;
1036
1037 fprintf( fp, "** Drc report for %s **\n", TO_UTF8( m_frame->GetBoard()->GetFileName() ) );
1038
1039 wxDateTime now = wxDateTime::Now();
1040
1041 fprintf( fp, "** Created on %s **\n", TO_UTF8( now.Format( wxT( "%F %T" ) ) ) );
1042
1043 count = m_markersProvider->GetCount();
1044
1045 fprintf( fp, "\n** Found %d DRC violations **\n", count );
1046
1047 for( int i = 0; i < count; ++i )
1048 {
1049 const std::shared_ptr<RC_ITEM>& item = m_markersProvider->GetItem( i );
1050 SEVERITY severity = item->GetParent()->GetSeverity();
1051
1052 if( severity == RPT_SEVERITY_EXCLUSION )
1053 severity = bds.GetSeverity( item->GetErrorCode() );
1054
1055 fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
1056 }
1057
1058 count = m_ratsnestProvider->GetCount();
1059
1060 fprintf( fp, "\n** Found %d unconnected pads **\n", count );
1061
1062 for( int i = 0; i < count; ++i )
1063 {
1064 const std::shared_ptr<RC_ITEM>& item = m_ratsnestProvider->GetItem( i );
1065 SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
1066
1067 fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
1068 }
1069
1070 count = m_fpWarningsProvider->GetCount();
1071
1072 fprintf( fp, "\n** Found %d Footprint errors **\n", count );
1073
1074 for( int i = 0; i < count; ++i )
1075 {
1076 const std::shared_ptr<RC_ITEM>& item = m_fpWarningsProvider->GetItem( i );
1077 SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
1078
1079 fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
1080 }
1081
1082
1083 fprintf( fp, "\n** End of Report **\n" );
1084
1085 fclose( fp );
1086
1087 return true;
1088}
1089
1090
1091void DIALOG_DRC::OnDeleteOneClick( wxCommandEvent& aEvent )
1092{
1093 if( m_Notebook->GetSelection() == 0 )
1094 {
1095 // Clear the selection. It may be the selected DRC marker.
1097
1099
1100 // redraw the pcb
1101 refreshEditor();
1102 }
1103 else if( m_Notebook->GetSelection() == 1 )
1104 {
1106 }
1107 else if( m_Notebook->GetSelection() == 2 )
1108 {
1110 }
1111
1113}
1114
1115
1116void DIALOG_DRC::OnDeleteAllClick( wxCommandEvent& aEvent )
1117{
1118 static bool s_includeExclusions = false;
1119
1120 int numExcluded = 0;
1121
1122 if( m_markersProvider )
1123 numExcluded += m_markersProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1124
1125 if( m_ratsnestProvider )
1126 numExcluded += m_ratsnestProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1127
1129 numExcluded += m_fpWarningsProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1130
1131 if( numExcluded > 0 )
1132 {
1133 wxRichMessageDialog dlg( this, _( "Do you wish to delete excluded markers as well?" ),
1134 _( "Delete All Markers" ),
1135 wxOK | wxCANCEL | wxCENTER | wxICON_QUESTION );
1136 dlg.ShowCheckBox( _( "Delete exclusions" ), s_includeExclusions );
1137
1138 int ret = dlg.ShowModal();
1139
1140 if( ret == wxID_CANCEL )
1141 return;
1142 else
1143 s_includeExclusions = dlg.IsCheckBoxChecked();
1144 }
1145
1146 deleteAllMarkers( s_includeExclusions );
1147
1148 refreshEditor();
1150}
1151
1152
1154{
1157 DRC_ENGINE* drcEngine = drcTool->GetDRCEngine().get();
1158
1159 // Collect counts:
1160
1161 int numMarkers = 0;
1162 int numUnconnected = 0;
1163 int numFootprints = 0;
1164
1165 int numErrors = 0;
1166 int numWarnings = 0;
1167 int numExcluded = 0;
1168
1169 if( m_markersProvider )
1170 {
1171 numMarkers += m_markersProvider->GetCount();
1172 numErrors += m_markersProvider->GetCount( RPT_SEVERITY_ERROR );
1173 numWarnings += m_markersProvider->GetCount( RPT_SEVERITY_WARNING );
1174 numExcluded += m_markersProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1175 }
1176
1177 if( m_ratsnestProvider )
1178 {
1179 numUnconnected += m_ratsnestProvider->GetCount();
1180 numErrors += m_ratsnestProvider->GetCount( RPT_SEVERITY_ERROR );
1181 numWarnings += m_ratsnestProvider->GetCount( RPT_SEVERITY_WARNING );
1182 numExcluded += m_ratsnestProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1183 }
1184
1186 {
1187 numFootprints += m_fpWarningsProvider->GetCount();
1188 numErrors += m_fpWarningsProvider->GetCount( RPT_SEVERITY_ERROR );
1189 numWarnings += m_fpWarningsProvider->GetCount( RPT_SEVERITY_WARNING );
1190 numExcluded += m_fpWarningsProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1191 }
1192
1193 bool showErrors = m_showErrors->GetValue();
1194 bool showWarnings = m_showWarnings->GetValue();
1195 bool errorsOverflowed = false;
1196 bool warningsOverflowed = false;
1197 bool markersOverflowed = false;
1198 bool unconnectedOverflowed = false;
1199 bool footprintsOverflowed = false;
1200
1201 for( int ii = DRCE_FIRST; ii < DRCE_LAST; ++ii )
1202 {
1203 if( drcEngine->IsErrorLimitExceeded( ii ) )
1204 {
1205 if( bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1206 errorsOverflowed = true;
1207 else if( bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1208 warningsOverflowed = true;
1209
1210 if( ii == DRCE_UNCONNECTED_ITEMS )
1211 {
1212 if( showWarnings && bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1213 unconnectedOverflowed = true;
1214 else if( showErrors && bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1215 unconnectedOverflowed = true;
1216 }
1217 else if( ii == DRCE_MISSING_FOOTPRINT
1219 || ii == DRCE_EXTRA_FOOTPRINT
1220 || ii == DRCE_NET_CONFLICT )
1221 {
1222 if( showWarnings && bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1223 footprintsOverflowed = true;
1224 else if( showErrors && bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1225 footprintsOverflowed = true;
1226 }
1227 else
1228 {
1229 if( showWarnings && bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1230 markersOverflowed = true;
1231 else if( showErrors && bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1232 markersOverflowed = true;
1233 }
1234 }
1235 }
1236
1237 wxString msg;
1238 wxString num;
1239
1240 // Update tab headers:
1241
1242 if( m_drcRun )
1243 {
1244 num.Printf( markersOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numMarkers );
1245 msg.Printf( m_markersTitleTemplate, num );
1246 }
1247 else
1248 {
1250 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1251 }
1252
1253 m_Notebook->SetPageText( 0, msg );
1254
1255 if( m_drcRun )
1256 {
1257 num.Printf( unconnectedOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numUnconnected );
1258 msg.sprintf( m_unconnectedTitleTemplate, num );
1259 }
1260 else
1261 {
1263 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1264 }
1265
1266 m_Notebook->SetPageText( 1, msg );
1267
1269 {
1270 num.Printf( footprintsOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numFootprints );
1271 msg.sprintf( m_footprintsTitleTemplate, num );
1272 }
1273 else if( m_drcRun )
1274 {
1276 msg.Replace( wxT( "%s" ), _( "not run" ) );
1277 }
1278 else
1279 {
1281 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1282 }
1283
1284 m_Notebook->SetPageText( 2, msg );
1285
1286 if( m_drcRun )
1287 {
1288 num.Printf( wxT( "%d" ), m_ignoredList->GetItemCount() );
1289 msg.sprintf( m_ignoredTitleTemplate, num );
1290 }
1291 else
1292 {
1294 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1295 }
1296
1297 m_Notebook->SetPageText( 3, msg );
1298
1299 // Update badges:
1300
1301 if( !m_drcRun && numErrors == 0 )
1302 numErrors = -1;
1303
1304 if( !m_drcRun && numWarnings == 0 )
1305 numWarnings = -1;
1306
1307 m_errorsBadge->SetMaximumNumber( numErrors );
1308 m_errorsBadge->UpdateNumber( errorsOverflowed ? numErrors + 1 : numErrors,
1310
1311 m_warningsBadge->SetMaximumNumber( numWarnings );
1312 m_warningsBadge->UpdateNumber( warningsOverflowed ? numWarnings + 1 : numWarnings,
1314
1315 m_exclusionsBadge->SetMaximumNumber( numExcluded );
1317}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
void SetLayerVisible(int aLayer, bool isVisible)
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
Container for design settings for a BOARD object.
std::map< int, SEVERITY > m_DRCSeverities
SEVERITY GetSeverity(int aDRCErrorCode)
Tool for pcb inspection.
void InspectDRCError(const std::shared_ptr< RC_ITEM > &aDRCItem)
Show the clearance resolution for two selected items.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:50
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:265
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:514
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:932
MARKERS & Markers()
Definition: board.h:316
const wxString & GetFileName() const
Definition: board.h:302
void FillItemMap(std::map< KIID, EDA_ITEM * > &aMap)
Definition: board.cpp:1011
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:617
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition: board.cpp:239
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:891
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:424
CN_EDGE represents a point-to-point connection, whether realized or unrealized (ie: tracks etc.
std::shared_ptr< CN_ANCHOR > GetTargetNode() const
std::shared_ptr< CN_ANCHOR > GetSourceNode() const
static DELETED_BOARD_ITEM * GetInstance()
Definition: board_item.h:356
Class DIALOG_DRC_BASE.
wxCheckBox * m_cbRefillZones
wxCheckBox * m_showAll
wxButton * m_DeleteAllMarkersButton
wxCheckBox * m_showExclusions
wxNotebook * m_Notebook
wxCheckBox * m_showErrors
wxDataViewCtrl * m_unconnectedDataView
wxDataViewCtrl * m_footprintsDataView
NUMBER_BADGE * m_warningsBadge
wxCheckBox * m_cbReportAllTrackErrors
NUMBER_BADGE * m_exclusionsBadge
wxSimplebook * m_runningResultsBook
wxButton * m_DeleteCurrentMarkerButton
wxButton * m_sdbSizerCancel
wxButton * m_saveReport
wxCheckBox * m_cbTestFootprints
wxCheckBox * m_showWarnings
wxButton * m_sdbSizerOK
wxListCtrl * m_ignoredList
NUMBER_BADGE * m_errorsBadge
WX_HTML_REPORT_BOX * m_messages
wxDataViewCtrl * m_markerDataView
void centerMarkerIdleHandler(wxIdleEvent &aEvent)
Definition: dialog_drc.cpp:976
bool updateUI() override
Definition: dialog_drc.cpp:195
void OnDRCItemSelected(wxDataViewEvent &aEvent) override
Definition: dialog_drc.cpp:346
wxString m_footprintsTitleTemplate
Definition: dialog_drc.h:129
void UpdateData()
Rebuild the contents of the violation tabs based on the current markers and severties.
Definition: dialog_drc.cpp:336
const PCB_MARKER * m_centerMarkerOnIdle
Definition: dialog_drc.h:140
std::shared_ptr< RC_ITEMS_PROVIDER > m_ratsnestProvider
Definition: dialog_drc.h:133
wxString m_markersTitleTemplate
Definition: dialog_drc.h:127
int m_severities
Definition: dialog_drc.h:142
bool m_footprintTestsRun
Definition: dialog_drc.h:125
DIALOG_DRC(PCB_EDIT_FRAME *aEditorFrame, wxWindow *aParent)
Constructors.
Definition: dialog_drc.cpp:65
void OnEditViolationSeverities(wxHyperlinkEvent &aEvent) override
Definition: dialog_drc.cpp:816
void OnDeleteOneClick(wxCommandEvent &aEvent) override
RC_TREE_MODEL * m_fpWarningsTreeModel
Definition: dialog_drc.h:138
bool m_running
Definition: dialog_drc.h:122
void OnDeleteAllClick(wxCommandEvent &aEvent) override
void OnErrorLinkClicked(wxHtmlLinkEvent &event) override
Definition: dialog_drc.cpp:229
BOARD_DESIGN_SETTINGS & bds()
Definition: dialog_drc.h:118
void SelectMarker(const PCB_MARKER *aMarker)
Definition: dialog_drc.cpp:961
std::atomic< bool > m_cancelled
Definition: dialog_drc.h:123
void OnClose(wxCloseEvent &event) override
Definition: dialog_drc.cpp:881
bool writeReport(const wxString &aFullFileName)
Function writeReport outputs the MARKER items with commentary to an open text file.
void syncCheckboxes()
Definition: dialog_drc.cpp:220
BOARD * m_currentBoard
Definition: dialog_drc.h:120
void OnDRCItemRClick(wxDataViewEvent &aEvent) override
Definition: dialog_drc.cpp:550
void PrevMarker()
Definition: dialog_drc.cpp:931
void OnRunDRCClick(wxCommandEvent &aEvent) override
Definition: dialog_drc.cpp:235
wxString m_ignoredTitleTemplate
Definition: dialog_drc.h:130
void OnDRCItemDClick(wxDataViewEvent &aEvent) override
Definition: dialog_drc.cpp:535
void deleteAllMarkers(bool aIncludeExclusions)
void updateDisplayedCounts()
RC_TREE_MODEL * m_unconnectedTreeModel
Definition: dialog_drc.h:137
void refreshEditor()
Definition: dialog_drc.cpp:923
wxString m_unconnectedTitleTemplate
Definition: dialog_drc.h:128
std::shared_ptr< RC_ITEMS_PROVIDER > m_fpWarningsProvider
Definition: dialog_drc.h:134
std::shared_ptr< RC_ITEMS_PROVIDER > m_markersProvider
Definition: dialog_drc.h:132
void OnSeverity(wxCommandEvent &aEvent) override
Definition: dialog_drc.cpp:822
PCB_EDIT_FRAME * m_frame
Definition: dialog_drc.h:121
bool m_drcRun
Definition: dialog_drc.h:124
void OnCancelClick(wxCommandEvent &aEvent) override
Definition: dialog_drc.cpp:892
void NextMarker()
Definition: dialog_drc.cpp:946
void OnActivateDlg(wxActivateEvent &aEvent) override
Definition: dialog_drc.cpp:178
void OnChangingNotebookPage(wxNotebookEvent &aEvent) override
Definition: dialog_drc.cpp:911
void OnSaveReport(wxCommandEvent &aEvent) override
Definition: dialog_drc.cpp:847
void ExcludeMarker()
Definition: dialog_drc.cpp:984
RC_TREE_MODEL * m_markersTreeModel
Definition: dialog_drc.h:136
bool Show(bool show) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:121
Design Rule Checker object that performs all the DRC tests.
Definition: drc_engine.h:83
static std::vector< std::reference_wrapper< RC_ITEM > > GetItemsWithSeverities()
Definition: drc_item.h:122
DRC_RULE * GetViolatingRule() const
Definition: drc_item.h:128
bool m_Implicit
Definition: drc_rule.h:109
wxString m_Name
Definition: drc_rule.h:110
void DestroyDRCDialog()
Close and free the DRC dialog.
Definition: drc_tool.cpp:121
std::shared_ptr< DRC_ENGINE > GetDRCEngine()
Definition: drc_tool.h:78
void RunTests(PROGRESS_REPORTER *aProgressReporter, bool aRefillZones, bool aReportAllTrackErrors, bool aTestFootprints)
Run the DRC tests.
Definition: drc_tool.cpp:131
void FocusOnLocation(const VECTOR2I &aPos)
Useful to focus on a particular location, in find functions.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
EDA_ITEM_FLAGS GetFlags() const
Definition: eda_item.h:144
bool IsSingle() const
Is this KIFACE running under single_top?
Definition: kiface_base.h:105
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: pcb_view.cpp:92
virtual void Remove(VIEW_ITEM *aItem) override
Remove a VIEW_ITEM from the view.
Definition: pcb_view.cpp:75
Definition: kiid.h:47
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:530
static LSET AllLayersMask()
Definition: lset.cpp:808
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
@ MARKER_DRAWING_SHEET
Definition: marker_base.h:55
void SetExcluded(bool aExcluded)
Definition: marker_base.h:98
void SetMaximumNumber(int aMax)
Set the maximum number to be shown on the badge.
void UpdateNumber(int aNumber, SEVERITY aSeverity)
Update the number displayed on the badge.
Definition: pad.h:58
DISPLAY_OPTIONS m_Display
DIALOG_DRC m_DrcDialog
static TOOL_ACTION showRatsnest
Definition: pcb_actions.h:267
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:59
wxString GetDesignRulesPath()
Return the absolute path to the design rules file for the currently-loaded board.
APPEARANCE_CONTROLS * GetAppearancePanel()
void FocusOnItems(std::vector< BOARD_ITEM * > aItems, PCB_LAYER_ID aLayer=UNDEFINED_LAYER)
PCBNEW_SETTINGS * GetPcbNewSettings() const
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
BOARD * GetBoard() const
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Returns the BOARD_DESIGN_SETTINGS for the open project.
void FocusOnItem(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer=UNDEFINED_LAYER)
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
void RedrawRatsnest()
Return the bounding box of the view that should be used if model is not valid.
The main frame for Pcbnew.
void ShowBoardSetupDialog(const wxString &aInitialPage=wxEmptyString)
void SetActiveLayer(PCB_LAYER_ID aLayer) override
Change the currently active layer to aLayer and also update the APPEARANCE_CONTROLS.
void OnModify() override
Must be called after a board change to set the modified flag.
void RecordDRCExclusions()
Scan existing markers and record data from any that are Excluded.
SEVERITY GetSeverity() const override
Definition: pcb_marker.cpp:253
This implements all the tricky bits for thread safety, but the GUI is left to derived classes.
virtual void AdvancePhase() override
Use the next available virtual zone of the dialog progress bar.
virtual void SetCurrentProgress(double aProgress) override
Set the progress value to aProgress (0..1).
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:125
void PrevMarker()
Definition: rc_item.cpp:558
void SelectMarker(const MARKER_BASE *aMarker)
Definition: rc_item.cpp:607
static RC_TREE_NODE * ToNode(wxDataViewItem aItem)
Definition: rc_item.h:209
void Update(std::shared_ptr< RC_ITEMS_PROVIDER > aProvider, int aSeverities)
Definition: rc_item.cpp:289
void DeleteItems(bool aCurrentOnly, bool aIncludeExclusions, bool aDeep)
Deletes the current item or all items.
Definition: rc_item.cpp:469
void DeleteCurrentItem(bool aDeep)
Definition: rc_item.cpp:463
void CenterMarker(const MARKER_BASE *aMarker)
Definition: rc_item.cpp:620
static KIID ToUUID(wxDataViewItem aItem)
Definition: rc_item.cpp:149
void NextMarker()
Definition: rc_item.cpp:579
void ValueChanged(const RC_TREE_NODE *aNode)
Definition: rc_item.cpp:446
std::shared_ptr< RC_ITEM > m_RcItem
Definition: rc_item.h:194
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:54
Master controller class:
Definition: tool_manager.h:55
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:142
void Clear()
Delete the stored messages.
void SetImmediateMode()
In immediate mode, messages are flushed as they are added.
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
void Flush()
Build the HTML messages page.
Handle actions specific to filling copper zones.
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:280
This file is part of the common library.
static bool g_lastDRCRun
Definition: dialog_drc.cpp:60
static std::vector< wxString > g_lastIgnored
Definition: dialog_drc.cpp:62
static int RPT_SEVERITY_ALL
Definition: dialog_drc.cpp:217
static int DEFAULT_SINGLE_COL_WIDTH
Definition: dialog_drc.cpp:57
static BOARD * g_lastDRCBoard
Definition: dialog_drc.cpp:59
static bool g_lastFootprintTestsRun
Definition: dialog_drc.cpp:61
#define DIALOG_DRC_WINDOW_NAME
Definition: dialog_drc.h:41
@ DRCE_HOLE_CLEARANCE
Definition: drc_item.h:53
@ DRCE_VIA_DIAMETER
Definition: drc_item.h:58
@ DRCE_UNCONNECTED_ITEMS
Definition: drc_item.h:39
@ DRCE_TRACK_WIDTH
Definition: drc_item.h:54
@ DRCE_INVALID_OUTLINE
Definition: drc_item.h:68
@ DRCE_DRILL_OUT_OF_RANGE
Definition: drc_item.h:57
@ DRCE_EDGE_CLEARANCE
Definition: drc_item.h:45
@ DRCE_CLEARANCE
Definition: drc_item.h:43
@ DRCE_DRILLED_HOLES_TOO_CLOSE
Definition: drc_item.h:51
@ DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG
Definition: drc_item.h:99
@ DRCE_MICROVIA_DRILL_OUT_OF_RANGE
Definition: drc_item.h:60
@ DRCE_MALFORMED_COURTYARD
Definition: drc_item.h:63
@ DRCE_FIRST
Definition: drc_item.h:38
@ DRCE_UNRESOLVED_VARIABLE
Definition: drc_item.h:81
@ DRCE_DUPLICATE_FOOTPRINT
Definition: drc_item.h:71
@ DRCE_TEXT_HEIGHT
Definition: drc_item.h:91
@ DRCE_EXTRA_FOOTPRINT
Definition: drc_item.h:72
@ DRCE_LAST
Definition: drc_item.h:101
@ DRCE_NET_CONFLICT
Definition: drc_item.h:73
@ DRCE_MISSING_FOOTPRINT
Definition: drc_item.h:70
@ DRCE_TEXT_THICKNESS
Definition: drc_item.h:92
@ DRCE_CONNECTION_WIDTH
Definition: drc_item.h:56
@ DRCE_ANNULAR_WIDTH
Definition: drc_item.h:55
#define _(s)
#define MALFORMED_F_COURTYARD
#define MALFORMED_B_COURTYARD
const std::string ReportFileExtension
wxString ReportFileWildcard()
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ F_CrtYd
Definition: layer_ids.h:117
@ Edge_Cuts
Definition: layer_ids.h:113
@ B_CrtYd
Definition: layer_ids.h:116
@ UNDEFINED_LAYER
Definition: layer_ids.h:60
This file contains miscellaneous commonly used macros and functions.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
void ForceFocus(wxWindow *aWindow)
Pass the current focus to the window.
Definition: gtk/ui.cpp:44
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_EXCLUSION
@ RPT_SEVERITY_IGNORE
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:74
A filename or source description, a problem input line, a line number, a byte offset,...
Definition: ki_exception.h:119
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition: typeinfo.h:112
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
Functions to provide common constants and other functions to assist in making a consistent UI.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:80
Definition of file extensions used in Kicad.