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_drcRun( false ),
70 m_footprintTestsRun( false ),
71 m_markersTreeModel( nullptr ),
72 m_unconnectedTreeModel( nullptr ),
73 m_fpWarningsTreeModel( nullptr ),
74 m_centerMarkerOnIdle( nullptr ),
76{
77 SetName( DIALOG_DRC_WINDOW_NAME ); // Set a window name to be able to find it
78
79 m_frame = aEditorFrame;
81
83
86
87 m_markersProvider = std::make_shared<DRC_ITEMS_PROVIDER>( m_currentBoard,
90
91 m_ratsnestProvider = std::make_shared<DRC_ITEMS_PROVIDER>( m_currentBoard,
93
94 m_fpWarningsProvider = std::make_shared<DRC_ITEMS_PROVIDER>( m_currentBoard,
96
98 m_markerDataView->AssociateModel( m_markersTreeModel );
100
104
108
109 m_ignoredList->InsertColumn( 0, wxEmptyString, wxLIST_FORMAT_LEFT, DEFAULT_SINGLE_COL_WIDTH );
110
112 {
115
116 for( const wxString& str : g_lastIgnored )
117 m_ignoredList->InsertItem( m_ignoredList->GetItemCount(), str );
118 }
119
120 m_Notebook->SetSelection( 0 );
121
122 if( Kiface().IsSingle() )
123 m_cbTestFootprints->Hide();
124
125 SetupStandardButtons( { { wxID_OK, _( "Run DRC" ) },
126 { wxID_CANCEL, _( "Close" ) } } );
127
128 m_markersTitleTemplate = m_Notebook->GetPageText( 0 );
129 m_unconnectedTitleTemplate = m_Notebook->GetPageText( 1 );
130 m_footprintsTitleTemplate = m_Notebook->GetPageText( 2 );
131 m_ignoredTitleTemplate = m_Notebook->GetPageText( 3 );
132
133 m_cbRefillZones->SetValue( cfg->m_DrcDialog.refill_zones );
135
136 if( !Kiface().IsSingle() )
138
139 Layout(); // adding the units above expanded Clearance text, now resize.
140
141 SetFocus();
142
144
146}
147
148
150{
151 m_frame->FocusOnItem( nullptr );
152
156
157 g_lastIgnored.clear();
158
159 for( int ii = 0; ii < m_ignoredList->GetItemCount(); ++ii )
160 g_lastIgnored.push_back( m_ignoredList->GetItemText( ii ) );
161
163 settings->m_DrcDialog.refill_zones = m_cbRefillZones->GetValue();
165
166 if( !Kiface().IsSingle() )
167 settings->m_DrcDialog.test_footprints = m_cbTestFootprints->GetValue();
168
170
171 m_markersTreeModel->DecRef();
172 m_unconnectedTreeModel->DecRef();
173 m_fpWarningsTreeModel->DecRef();
174}
175
176
177void DIALOG_DRC::OnActivateDlg( wxActivateEvent& aEvent )
178{
180 {
181 // If m_currentBoard is not the current board, (for instance because a new board
182 // was loaded), close the dialog, because many pointers are now invalid in lists
183 SetReturnCode( wxID_CANCEL );
184 Close();
185
187 drcTool->DestroyDRCDialog();
188 }
189}
190
191
192// PROGRESS_REPORTER calls
193
195{
196 double cur = (double) m_progress.load() / m_maxProgress;
197 cur = std::max( 0.0, std::min( cur, 1.0 ) );
198
199 m_gauge->SetValue( KiROUND( cur * 1000.0 ) );
200 wxSafeYield( this );
201
202 return !m_cancelled;
203}
204
205
206void DIALOG_DRC::AdvancePhase( const wxString& aMessage )
207{
209 SetCurrentProgress( 0.0 );
210
211 m_messages->Report( aMessage );
212}
213
214
215// Don't globally define this; different facilities use different definitions of "ALL"
217
218
220{
225}
226
227
228void DIALOG_DRC::OnErrorLinkClicked( wxHtmlLinkEvent& event )
229{
230 m_frame->ShowBoardSetupDialog( _( "Custom Rules" ) );
231}
232
233
234void DIALOG_DRC::OnRunDRCClick( wxCommandEvent& aEvent )
235{
236 TOOL_MANAGER* toolMgr = m_frame->GetToolManager();
237 DRC_TOOL* drcTool = toolMgr->GetTool<DRC_TOOL>();
238 ZONE_FILLER_TOOL* zoneFillerTool = toolMgr->GetTool<ZONE_FILLER_TOOL>();
239 bool refillZones = m_cbRefillZones->GetValue();
240 bool reportAllTrackErrors = m_cbReportAllTrackErrors->GetValue();
241 bool testFootprints = m_cbTestFootprints->GetValue();
242
243 if( zoneFillerTool->IsBusy() )
244 {
245 wxBell();
246 return;
247 }
248
249 // This is not the time to have stale or buggy rules. Ensure they're up-to-date
250 // and that they at least parse.
251 try
252 {
253 drcTool->GetDRCEngine()->InitEngine( m_frame->GetDesignRulesPath() );
254 }
255 catch( PARSE_ERROR& )
256 {
257 m_runningResultsBook->ChangeSelection( 0 ); // Display the "Tests Running..." tab
258 m_DeleteCurrentMarkerButton->Enable( false );
259 m_DeleteAllMarkersButton->Enable( false );
260 m_saveReport->Enable( false );
261
262 m_messages->Clear();
263 m_messages->Report( _( "DRC incomplete: could not compile custom design rules. " )
264 + wxT( "<a href='boardsetup'>" )
265 + _( "Show design rules." )
266 + wxT( "</a>" ) );
267 m_messages->Flush();
268
269 Raise();
270 return;
271 }
272
273 m_footprintTestsRun = false;
274 m_cancelled = false;
275
277 deleteAllMarkers( true );
278
279 std::vector<std::reference_wrapper<RC_ITEM>> violations = DRC_ITEM::GetItemsWithSeverities();
280 m_ignoredList->DeleteAllItems();
281
282 for( std::reference_wrapper<RC_ITEM>& item : violations )
283 {
284 if( bds().GetSeverity( item.get().GetErrorCode() ) == RPT_SEVERITY_IGNORE )
285 {
286 m_ignoredList->InsertItem( m_ignoredList->GetItemCount(),
287 wxT( " • " ) + item.get().GetErrorText() );
288 }
289 }
290
291 Raise();
292
293 m_runningResultsBook->ChangeSelection( 0 ); // Display the "Tests Running..." tab
294 m_messages->Clear();
295 wxYield(); // Allow time slice to refresh Messages
296
297 m_running = true;
298 m_sdbSizerCancel->SetLabel( _( "Cancel" ) );
299 m_sdbSizerOK->Enable( false );
300 m_DeleteCurrentMarkerButton->Enable( false );
301 m_DeleteAllMarkersButton->Enable( false );
302 m_saveReport->Enable( false );
303
304 {
305 wxBusyCursor dummy;
306 drcTool->RunTests( this, refillZones, reportAllTrackErrors, testFootprints );
307 }
308
309 if( m_cancelled )
310 m_messages->Report( _( "-------- DRC cancelled by user.<br><br>" ) );
311 else
312 m_messages->Report( _( "Done.<br><br>" ) );
313
314 Raise();
315 wxYield(); // Allow time slice to refresh Messages
316
317 m_running = false;
318 m_sdbSizerCancel->SetLabel( _( "Close" ) );
319 m_sdbSizerOK->Enable( true );
320 m_DeleteCurrentMarkerButton->Enable( true );
321 m_DeleteAllMarkersButton->Enable( true );
322 m_saveReport->Enable( true );
323
324 if( !m_cancelled )
325 {
326 wxMilliSleep( 500 );
327 m_runningResultsBook->ChangeSelection( 1 );
329 }
330
332}
333
334
336{
340
342}
343
344
345void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
346{
347 BOARD* board = m_frame->GetBoard();
348 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
349
350 auto getActiveLayers =
351 []( BOARD_ITEM* aItem ) -> LSET
352 {
353 if( aItem->Type() == PCB_PAD_T )
354 {
355 PAD* pad = static_cast<PAD*>( aItem );
356 LSET layers;
357
358 for( int layer : aItem->GetLayerSet().Seq() )
359 {
360 if( pad->FlashLayer( layer ) )
361 layers.set( layer );
362 }
363
364 return layers;
365 }
366 else
367 {
368 return aItem->GetLayerSet();
369 }
370 };
371
372 if( !node )
373 {
374 // list is being freed; don't do anything with null ptrs
375
376 aEvent.Skip();
377 return;
378 }
379
381 {
382 // we already came from a cross-probe of the marker in the document; don't go
383 // around in circles
384
385 aEvent.Skip();
386 return;
387 }
388
389 std::shared_ptr<RC_ITEM> rc_item = node->m_RcItem;
390
391 if( rc_item->GetErrorCode() == DRCE_UNRESOLVED_VARIABLE
392 && rc_item->GetParent()->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
393 {
394 m_frame->FocusOnLocation( node->m_RcItem->GetParent()->GetPos() );
395
396 aEvent.Skip();
397 return;
398 }
399
400 const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
401 BOARD_ITEM* item = board->GetItem( itemID );
402
403 if( !item || item == DELETED_BOARD_ITEM::GetInstance() )
404 {
405 // nothing to highlight / focus on
406
407 aEvent.Skip();
408 return;
409 }
410
411 PCB_LAYER_ID principalLayer;
412 LSET violationLayers;
413 BOARD_ITEM* a = board->GetItem( rc_item->GetMainItemID() );
414 BOARD_ITEM* b = board->GetItem( rc_item->GetAuxItemID() );
415 BOARD_ITEM* c = board->GetItem( rc_item->GetAuxItem2ID() );
416 BOARD_ITEM* d = board->GetItem( rc_item->GetAuxItem3ID() );
417
418 if( rc_item->GetErrorCode() == DRCE_MALFORMED_COURTYARD )
419 {
420 if( a && ( a->GetFlags() & MALFORMED_B_COURTYARD ) > 0
421 && ( a->GetFlags() & MALFORMED_F_COURTYARD ) == 0 )
422 {
423 principalLayer = B_CrtYd;
424 }
425 else
426 {
427 principalLayer = F_CrtYd;
428 }
429 }
430 else if (rc_item->GetErrorCode() == DRCE_INVALID_OUTLINE )
431 {
432 principalLayer = Edge_Cuts;
433 }
434 else
435 {
436 principalLayer = UNDEFINED_LAYER;
437
438 if( a || b || c || d )
439 violationLayers = LSET::AllLayersMask();
440
441 // Try to initialize principalLayer to a valid layer. Note that some markers have
442 // a layer set to UNDEFINED_LAYER, so we may need to keep looking.
443
444 for( BOARD_ITEM* it: { a, b, c, d } )
445 {
446 if( !it )
447 continue;
448
449 LSET layersList = getActiveLayers( it );
450 violationLayers &= layersList;
451
452 if( principalLayer <= UNDEFINED_LAYER && layersList.count() )
453 principalLayer = layersList.Seq().front();
454 }
455 }
456
457 if( violationLayers.count() )
458 principalLayer = violationLayers.Seq().front();
459 else if( !(principalLayer <= UNDEFINED_LAYER ) )
460 violationLayers.set( principalLayer );
461
462 WINDOW_THAWER thawer( m_frame );
463
464 if( principalLayer > UNDEFINED_LAYER && ( violationLayers & board->GetVisibleLayers() ) == 0 )
465 m_frame->GetAppearancePanel()->SetLayerVisible( principalLayer, true );
466
467 if( principalLayer > UNDEFINED_LAYER && board->GetVisibleLayers().test( principalLayer ) )
468 m_frame->SetActiveLayer( principalLayer );
469
470 if( rc_item->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
471 {
474
475 if( item->Type() == PCB_ZONE_T )
476 {
477 m_frame->GetBoard()->GetConnectivity()->RunOnUnconnectedEdges(
478 [&]( CN_EDGE& edge )
479 {
480 if( edge.GetSourceNode()->Parent() == a
481 && edge.GetTargetNode()->Parent() == b )
482 {
483 if( item == a )
484 m_frame->FocusOnLocation( edge.GetSourcePos() );
485 else
486 m_frame->FocusOnLocation( edge.GetTargetPos() );
487
488 return false;
489 }
490
491 return true;
492 } );
493 }
494 else
495 {
496 m_frame->FocusOnItem( item, principalLayer );
497 }
498 }
499 else if( rc_item->GetErrorCode() == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG )
500 {
501 BOARD_CONNECTED_ITEM* track = dynamic_cast<PCB_TRACK*>( item );
502 std::vector<BOARD_ITEM*> items;
503
504 if( track )
505 {
506 int net = track->GetNetCode();
507
508 wxASSERT( net > 0 ); // Without a net how can it be a diff-pair?
509
510 for( const KIID& id : rc_item->GetIDs() )
511 {
512 auto* candidate = dynamic_cast<BOARD_CONNECTED_ITEM*>( board->GetItem( id ) );
513
514 if( candidate && candidate->GetNetCode() == net )
515 items.push_back( candidate );
516 }
517 }
518 else
519 {
520 items.push_back( item );
521 }
522
523 m_frame->FocusOnItems( items, principalLayer );
524 }
525 else
526 {
527 m_frame->FocusOnItem( item, principalLayer );
528 }
529
530 aEvent.Skip();
531}
532
533
534void DIALOG_DRC::OnDRCItemDClick( wxDataViewEvent& aEvent )
535{
536 if( aEvent.GetItem().IsOk() )
537 {
538 // turn control over to m_frame, hide this DIALOG_DRC window,
539 // no destruction so we can preserve listbox cursor
540 if( !IsModal() )
541 Show( false );
542 }
543
544 // Do not skip aEvent here: this is not useful, and Pcbnew crashes
545 // if skipped (at least on Windows)
546}
547
548
549void DIALOG_DRC::OnDRCItemRClick( wxDataViewEvent& aEvent )
550{
551 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
552
553 if( !node )
554 return;
555
556 std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
557 DRC_ITEM* drcItem = static_cast<DRC_ITEM*>( rcItem.get() );
558 std::shared_ptr<CONNECTIVITY_DATA> conn = m_currentBoard->GetConnectivity();
559 wxString listName;
560 wxMenu menu;
561 wxString msg;
562
563 switch( bds().m_DRCSeverities[ rcItem->GetErrorCode() ] )
564 {
565 case RPT_SEVERITY_ERROR: listName = _( "errors" ); break;
566 case RPT_SEVERITY_WARNING: listName = _( "warnings" ); break;
567 default: listName = _( "appropriate" ); break;
568 }
569
570 if( rcItem->GetParent()->IsExcluded() )
571 {
572 menu.Append( 1, _( "Remove exclusion for this violation" ),
573 wxString::Format( _( "It will be placed back in the %s list" ), listName ) );
574
575 if( drcItem->GetViolatingRule() && !drcItem->GetViolatingRule()->m_Implicit )
576 {
577 msg.Printf( _( "Remove all exclusions for violations of rule '%s'" ),
578 drcItem->GetViolatingRule()->m_Name );
579 menu.Append( 11, msg );
580 }
581 }
582 else
583 {
584 menu.Append( 2, _( "Exclude this violation" ),
585 wxString::Format( _( "It will be excluded from the %s list" ), listName ) );
586
587 if( drcItem->GetViolatingRule() && !drcItem->GetViolatingRule()->m_Implicit )
588 {
589 msg.Printf( _( "Exclude all violations of rule '%s'" ),
590 drcItem->GetViolatingRule()->m_Name );
591 menu.Append( 21, msg );
592 }
593 }
594
595 if( rcItem->GetErrorCode() == DRCE_CLEARANCE
596 || rcItem->GetErrorCode() == DRCE_EDGE_CLEARANCE
597 || rcItem->GetErrorCode() == DRCE_HOLE_CLEARANCE
598 || rcItem->GetErrorCode() == DRCE_DRILLED_HOLES_TOO_CLOSE )
599 {
600 menu.Append( 3, _( "Run clearance resolution tool..." ) );
601 }
602 else if( rcItem->GetErrorCode() == DRCE_TEXT_HEIGHT
603 || rcItem->GetErrorCode() == DRCE_TEXT_THICKNESS
604 || rcItem->GetErrorCode() == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG
605 || rcItem->GetErrorCode() == DRCE_TRACK_WIDTH
606 || rcItem->GetErrorCode() == DRCE_VIA_DIAMETER
607 || rcItem->GetErrorCode() == DRCE_ANNULAR_WIDTH
608 || rcItem->GetErrorCode() == DRCE_DRILL_OUT_OF_RANGE
609 || rcItem->GetErrorCode() == DRCE_MICROVIA_DRILL_OUT_OF_RANGE
610 || rcItem->GetErrorCode() == DRCE_CONNECTION_WIDTH )
611 {
612 menu.Append( 3, _( "Run constraints resolution tool..." ) );
613 }
614
615 menu.AppendSeparator();
616
617 if( bds().m_DRCSeverities[ rcItem->GetErrorCode() ] == RPT_SEVERITY_WARNING )
618 {
619 msg.Printf( _( "Change severity to Error for all '%s' violations" ),
620 rcItem->GetErrorText(),
621 _( "Violation severities can also be edited in the Board Setup... dialog" ) );
622 menu.Append( 4, msg );
623 }
624 else
625 {
626 msg.Printf( _( "Change severity to Warning for all '%s' violations" ),
627 rcItem->GetErrorText(),
628 _( "Violation severities can also be edited in the Board Setup... dialog" ) );
629 menu.Append( 5, msg );
630 }
631
632 msg.Printf( _( "Ignore all '%s' violations" ),
633 rcItem->GetErrorText(),
634 _( "Violations will not be checked or reported" ) );
635 menu.Append( 6, msg );
636
637 menu.AppendSeparator();
638
639 menu.Append( 7, _( "Edit violation severities..." ), _( "Open the Board Setup... dialog" ) );
640
641 bool modified = false;
642
643 switch( GetPopupMenuSelectionFromUser( menu ) )
644 {
645 case 1:
646 {
647 PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( rcItem->GetParent() );
648
649 if( marker )
650 {
651 marker->SetExcluded( false );
652
653 if( rcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
654 {
657 }
658 else
659 {
660 m_frame->GetCanvas()->GetView()->Update( marker );
661 }
662
663 // Update view
664 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
665 modified = true;
666 }
667
668 break;
669 }
670
671 case 2:
672 {
673 PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( rcItem->GetParent() );
674
675 if( marker )
676 {
677 marker->SetExcluded( true );
678
679 if( rcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
680 {
683 }
684 else
685 {
686 m_frame->GetCanvas()->GetView()->Update( marker );
687 }
688
689 // Update view
691 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
692 else
693 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->DeleteCurrentItem( false );
694
695 modified = true;
696 }
697
698 break;
699 }
700
701 case 11:
702 {
703 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
704 {
705 DRC_ITEM* candidateDrcItem = static_cast<DRC_ITEM*>( marker->GetRCItem().get() );
706
707 if( candidateDrcItem->GetViolatingRule() == drcItem->GetViolatingRule() )
708 marker->SetExcluded( false );
709 }
710
711 // Rebuild model and view
712 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
713 modified = true;
714 break;
715 }
716
717 case 21:
718 {
719 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
720 {
721 DRC_ITEM* candidateDrcItem = static_cast<DRC_ITEM*>( marker->GetRCItem().get() );
722
723 if( candidateDrcItem->GetViolatingRule() == drcItem->GetViolatingRule() )
724 marker->SetExcluded( true );
725 }
726
727 // Rebuild model and view
728 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
729 modified = true;
730 break;
731 }
732
733 case 3:
734 {
735 TOOL_MANAGER* toolMgr = m_frame->GetToolManager();
736 BOARD_INSPECTION_TOOL* inspectionTool = toolMgr->GetTool<BOARD_INSPECTION_TOOL>();
737
738 inspectionTool->InspectDRCError( node->m_RcItem );
739 break;
740 }
741
742 case 4:
743 bds().m_DRCSeverities[ rcItem->GetErrorCode() ] = RPT_SEVERITY_ERROR;
744
745 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
746 {
747 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
748 m_frame->GetCanvas()->GetView()->Update( marker );
749 }
750
751 // Rebuild model and view
752 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
753 modified = true;
754 break;
755
756 case 5:
757 bds().m_DRCSeverities[ rcItem->GetErrorCode() ] = RPT_SEVERITY_WARNING;
758
759 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
760 {
761 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
762 m_frame->GetCanvas()->GetView()->Update( marker );
763 }
764
765 // Rebuild model and view
766 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
767 modified = true;
768 break;
769
770 case 6:
771 {
772 bds().m_DRCSeverities[ rcItem->GetErrorCode() ] = RPT_SEVERITY_IGNORE;
773
774 m_ignoredList->InsertItem( m_ignoredList->GetItemCount(),
775 wxT( " • " ) + rcItem->GetErrorText() );
776
777 std::vector<PCB_MARKER*>& markers = m_frame->GetBoard()->Markers();
778
779 for( unsigned i = 0; i < markers.size(); )
780 {
781 if( markers[i]->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
782 {
783 m_frame->GetCanvas()->GetView()->Remove( markers.at( i ) );
784 markers.erase( markers.begin() + i );
785 }
786 else
787 {
788 ++i;
789 }
790 }
791
792 if( rcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
794
795 // Rebuild model and view
796 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
797 modified = true;
798 break;
799 }
800
801 case 7:
802 m_frame->ShowBoardSetupDialog( _( "Violation Severity" ) );
803 break;
804 }
805
806 if( modified )
807 {
810 m_frame->OnModify();
811 }
812}
813
814
815void DIALOG_DRC::OnEditViolationSeverities( wxHyperlinkEvent& aEvent )
816{
817 m_frame->ShowBoardSetupDialog( _( "Violation Severity" ) );
818}
819
820
821void DIALOG_DRC::OnSeverity( wxCommandEvent& aEvent )
822{
823 int flag = 0;
824
825 if( aEvent.GetEventObject() == m_showAll )
827 else if( aEvent.GetEventObject() == m_showErrors )
829 else if( aEvent.GetEventObject() == m_showWarnings )
831 else if( aEvent.GetEventObject() == m_showExclusions )
833
834 if( aEvent.IsChecked() )
836 else if( aEvent.GetEventObject() == m_showAll )
838 else
839 m_severities &= ~flag;
840
842 UpdateData();
843}
844
845
846void DIALOG_DRC::OnSaveReport( wxCommandEvent& aEvent )
847{
848 wxFileName fn( "DRC." + ReportFileExtension );
849
850 wxFileDialog dlg( this, _( "Save Report to File" ), Prj().GetProjectPath(), fn.GetFullName(),
851 ReportFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
852
853 if( dlg.ShowModal() != wxID_OK )
854 return;
855
856 fn = dlg.GetPath();
857
858 if( fn.GetExt().IsEmpty() )
859 fn.SetExt( ReportFileExtension );
860
861 if( !fn.IsAbsolute() )
862 {
863 wxString prj_path = Prj().GetProjectPath();
864 fn.MakeAbsolute( prj_path );
865 }
866
867 if( writeReport( fn.GetFullPath() ) )
868 {
869 m_messages->Report( wxString::Format( _( "Report file '%s' created<br>" ),
870 fn.GetFullPath() ) );
871 }
872 else
873 {
874 DisplayError( this, wxString::Format( _( "Failed to create file '%s'." ),
875 fn.GetFullPath() ) );
876 }
877}
878
879
880void DIALOG_DRC::OnClose( wxCloseEvent& aEvent )
881{
882 if( m_running )
883 aEvent.Veto();
884
885 wxCommandEvent dummy;
886
888}
889
890
891void DIALOG_DRC::OnCancelClick( wxCommandEvent& aEvent )
892{
893 if( m_running )
894 {
895 m_cancelled = true;
896 return;
897 }
898
899 m_frame->FocusOnItem( nullptr );
900
901 SetReturnCode( wxID_CANCEL );
902
903 // The dialog can be modal or not modal.
904 // Leave the DRC caller destroy (or not) the dialog
906 drcTool->DestroyDRCDialog();
907}
908
909
910void DIALOG_DRC::OnChangingNotebookPage( wxNotebookEvent& aEvent )
911{
912 // Shouldn't be necessary, but is on at least OSX
913 if( aEvent.GetSelection() >= 0 )
914 m_Notebook->ChangeSelection( (unsigned) aEvent.GetSelection() );
915
916 m_markerDataView->UnselectAll();
917 m_unconnectedDataView->UnselectAll();
918 m_footprintsDataView->UnselectAll();
919}
920
921
923{
924 WINDOW_THAWER thawer( m_frame );
925
927}
928
929
931{
932 if( m_Notebook->IsShown() )
933 {
934 switch( m_Notebook->GetSelection() )
935 {
936 case 0: m_markersTreeModel->PrevMarker(); break;
937 case 1: m_unconnectedTreeModel->PrevMarker(); break;
938 case 2: m_fpWarningsTreeModel->PrevMarker(); break;
939 case 3: break;
940 }
941 }
942}
943
944
946{
947 if( m_Notebook->IsShown() )
948 {
949 switch( m_Notebook->GetSelection() )
950 {
951 case 0: m_markersTreeModel->NextMarker(); break;
952 case 1: m_unconnectedTreeModel->NextMarker(); break;
953 case 2: m_fpWarningsTreeModel->NextMarker(); break;
954 case 3: break;
955 }
956 }
957}
958
959
961{
962 if( m_Notebook->IsShown() )
963 {
964 m_Notebook->SetSelection( 0 );
966
967 // wxWidgets on some platforms fails to correctly ensure that a selected item is
968 // visible, so we have to do it in a separate idle event.
969 m_centerMarkerOnIdle = aMarker;
970 Bind( wxEVT_IDLE, &DIALOG_DRC::centerMarkerIdleHandler, this );
971 }
972}
973
974
975void DIALOG_DRC::centerMarkerIdleHandler( wxIdleEvent& aEvent )
976{
978 m_centerMarkerOnIdle = nullptr;
979 Unbind( wxEVT_IDLE, &DIALOG_DRC::centerMarkerIdleHandler, this );
980}
981
982
984{
985 if( !m_Notebook->IsShown() || m_Notebook->GetSelection() != 0 )
986 return;
987
988 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( m_markerDataView->GetCurrentItem() );
989 PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( node->m_RcItem->GetParent() );
990
991 if( marker && marker->GetSeverity() != RPT_SEVERITY_EXCLUSION )
992 {
993 marker->SetExcluded( true );
994 m_frame->GetCanvas()->GetView()->Update( marker );
995
996 // Update view
999 else
1001
1003 refreshEditor();
1004 m_frame->OnModify();
1005 }
1006}
1007
1008
1009void DIALOG_DRC::deleteAllMarkers( bool aIncludeExclusions )
1010{
1011 // Clear current selection list to avoid selection of deleted items
1013
1014 m_markersTreeModel->DeleteItems( false, aIncludeExclusions, false );
1015 m_unconnectedTreeModel->DeleteItems( false, aIncludeExclusions, false );
1016 m_fpWarningsTreeModel->DeleteItems( false, aIncludeExclusions, false );
1017
1018 m_frame->GetBoard()->DeleteMARKERs( true, aIncludeExclusions );
1019}
1020
1021
1022bool DIALOG_DRC::writeReport( const wxString& aFullFileName )
1023{
1024 FILE* fp = wxFopen( aFullFileName, wxT( "w" ) );
1025
1026 if( fp == nullptr )
1027 return false;
1028
1029 std::map<KIID, EDA_ITEM*> itemMap;
1030 m_frame->GetBoard()->FillItemMap( itemMap );
1031
1033 UNITS_PROVIDER unitsProvider( pcbIUScale, GetUserUnits() );
1034 int count;
1035
1036 fprintf( fp, "** Drc report for %s **\n", TO_UTF8( m_frame->GetBoard()->GetFileName() ) );
1037
1038 wxDateTime now = wxDateTime::Now();
1039
1040 fprintf( fp, "** Created on %s **\n", TO_UTF8( now.Format( wxT( "%F %T" ) ) ) );
1041
1042 count = m_markersProvider->GetCount();
1043
1044 fprintf( fp, "\n** Found %d DRC violations **\n", count );
1045
1046 for( int i = 0; i < count; ++i )
1047 {
1048 const std::shared_ptr<RC_ITEM>& item = m_markersProvider->GetItem( i );
1049 SEVERITY severity = item->GetParent()->GetSeverity();
1050
1051 if( severity == RPT_SEVERITY_EXCLUSION )
1052 severity = bds.GetSeverity( item->GetErrorCode() );
1053
1054 fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
1055 }
1056
1057 count = m_ratsnestProvider->GetCount();
1058
1059 fprintf( fp, "\n** Found %d unconnected pads **\n", count );
1060
1061 for( int i = 0; i < count; ++i )
1062 {
1063 const std::shared_ptr<RC_ITEM>& item = m_ratsnestProvider->GetItem( i );
1064 SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
1065
1066 fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
1067 }
1068
1069 count = m_fpWarningsProvider->GetCount();
1070
1071 fprintf( fp, "\n** Found %d Footprint errors **\n", count );
1072
1073 for( int i = 0; i < count; ++i )
1074 {
1075 const std::shared_ptr<RC_ITEM>& item = m_fpWarningsProvider->GetItem( i );
1076 SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
1077
1078 fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
1079 }
1080
1081
1082 fprintf( fp, "\n** End of Report **\n" );
1083
1084 fclose( fp );
1085
1086 return true;
1087}
1088
1089
1090void DIALOG_DRC::OnDeleteOneClick( wxCommandEvent& aEvent )
1091{
1092 if( m_Notebook->GetSelection() == 0 )
1093 {
1094 // Clear the selection. It may be the selected DRC marker.
1096
1098
1099 // redraw the pcb
1100 refreshEditor();
1101 }
1102 else if( m_Notebook->GetSelection() == 1 )
1103 {
1105 }
1106 else if( m_Notebook->GetSelection() == 2 )
1107 {
1109 }
1110
1112}
1113
1114
1115void DIALOG_DRC::OnDeleteAllClick( wxCommandEvent& aEvent )
1116{
1117 static bool s_includeExclusions = false;
1118
1119 int numExcluded = 0;
1120
1121 if( m_markersProvider )
1122 numExcluded += m_markersProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1123
1124 if( m_ratsnestProvider )
1125 numExcluded += m_ratsnestProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1126
1128 numExcluded += m_fpWarningsProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1129
1130 if( numExcluded > 0 )
1131 {
1132 wxRichMessageDialog dlg( this, _( "Do you wish to delete excluded markers as well?" ),
1133 _( "Delete All Markers" ),
1134 wxOK | wxCANCEL | wxCENTER | wxICON_QUESTION );
1135 dlg.ShowCheckBox( _( "Delete exclusions" ), s_includeExclusions );
1136
1137 int ret = dlg.ShowModal();
1138
1139 if( ret == wxID_CANCEL )
1140 return;
1141 else
1142 s_includeExclusions = dlg.IsCheckBoxChecked();
1143 }
1144
1145 deleteAllMarkers( s_includeExclusions );
1146
1147 refreshEditor();
1149}
1150
1151
1153{
1156 DRC_ENGINE* drcEngine = drcTool->GetDRCEngine().get();
1157
1158 // Collect counts:
1159
1160 int numMarkers = 0;
1161 int numUnconnected = 0;
1162 int numFootprints = 0;
1163
1164 int numErrors = 0;
1165 int numWarnings = 0;
1166 int numExcluded = 0;
1167
1168 if( m_markersProvider )
1169 {
1170 numMarkers += m_markersProvider->GetCount();
1171 numErrors += m_markersProvider->GetCount( RPT_SEVERITY_ERROR );
1172 numWarnings += m_markersProvider->GetCount( RPT_SEVERITY_WARNING );
1173 numExcluded += m_markersProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1174 }
1175
1176 if( m_ratsnestProvider )
1177 {
1178 numUnconnected += m_ratsnestProvider->GetCount();
1179 numErrors += m_ratsnestProvider->GetCount( RPT_SEVERITY_ERROR );
1180 numWarnings += m_ratsnestProvider->GetCount( RPT_SEVERITY_WARNING );
1181 numExcluded += m_ratsnestProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1182 }
1183
1185 {
1186 numFootprints += m_fpWarningsProvider->GetCount();
1187 numErrors += m_fpWarningsProvider->GetCount( RPT_SEVERITY_ERROR );
1188 numWarnings += m_fpWarningsProvider->GetCount( RPT_SEVERITY_WARNING );
1189 numExcluded += m_fpWarningsProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1190 }
1191
1192 bool showErrors = m_showErrors->GetValue();
1193 bool showWarnings = m_showWarnings->GetValue();
1194 bool errorsOverflowed = false;
1195 bool warningsOverflowed = false;
1196 bool markersOverflowed = false;
1197 bool unconnectedOverflowed = false;
1198 bool footprintsOverflowed = false;
1199
1200 for( int ii = DRCE_FIRST; ii < DRCE_LAST; ++ii )
1201 {
1202 if( drcEngine->IsErrorLimitExceeded( ii ) )
1203 {
1204 if( bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1205 errorsOverflowed = true;
1206 else if( bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1207 warningsOverflowed = true;
1208
1209 if( ii == DRCE_UNCONNECTED_ITEMS )
1210 {
1211 if( showWarnings && bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1212 unconnectedOverflowed = true;
1213 else if( showErrors && bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1214 unconnectedOverflowed = true;
1215 }
1216 else if( ii == DRCE_MISSING_FOOTPRINT
1218 || ii == DRCE_EXTRA_FOOTPRINT
1219 || ii == DRCE_NET_CONFLICT )
1220 {
1221 if( showWarnings && bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1222 footprintsOverflowed = true;
1223 else if( showErrors && bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1224 footprintsOverflowed = true;
1225 }
1226 else
1227 {
1228 if( showWarnings && bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1229 markersOverflowed = true;
1230 else if( showErrors && bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1231 markersOverflowed = true;
1232 }
1233 }
1234 }
1235
1236 wxString msg;
1237 wxString num;
1238
1239 // Update tab headers:
1240
1241 if( m_drcRun )
1242 {
1243 num.Printf( markersOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numMarkers );
1244 msg.Printf( m_markersTitleTemplate, num );
1245 }
1246 else
1247 {
1249 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1250 }
1251
1252 m_Notebook->SetPageText( 0, msg );
1253
1254 if( m_drcRun )
1255 {
1256 num.Printf( unconnectedOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numUnconnected );
1257 msg.sprintf( m_unconnectedTitleTemplate, num );
1258 }
1259 else
1260 {
1262 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1263 }
1264
1265 m_Notebook->SetPageText( 1, msg );
1266
1268 {
1269 num.Printf( footprintsOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numFootprints );
1270 msg.sprintf( m_footprintsTitleTemplate, num );
1271 }
1272 else if( m_drcRun )
1273 {
1275 msg.Replace( wxT( "%s" ), _( "not run" ) );
1276 }
1277 else
1278 {
1280 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1281 }
1282
1283 m_Notebook->SetPageText( 2, msg );
1284
1285 if( m_drcRun )
1286 {
1287 num.Printf( wxT( "%d" ), m_ignoredList->GetItemCount() );
1288 msg.sprintf( m_ignoredTitleTemplate, num );
1289 }
1290 else
1291 {
1293 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1294 }
1295
1296 m_Notebook->SetPageText( 3, msg );
1297
1298 // Update badges:
1299
1300 if( !m_drcRun && numErrors == 0 )
1301 numErrors = -1;
1302
1303 if( !m_drcRun && numWarnings == 0 )
1304 numWarnings = -1;
1305
1306 m_errorsBadge->SetMaximumNumber( numErrors );
1307 m_errorsBadge->UpdateNumber( errorsOverflowed ? numErrors + 1 : numErrors,
1309
1310 m_warningsBadge->SetMaximumNumber( numWarnings );
1311 m_warningsBadge->UpdateNumber( warningsOverflowed ? numWarnings + 1 : numWarnings,
1313
1314 m_exclusionsBadge->SetMaximumNumber( numExcluded );
1316}
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:58
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:583
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:1001
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:1080
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:686
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition: board.cpp:270
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:960
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< const CN_ANCHOR > GetSourceNode() const
std::shared_ptr< const CN_ANCHOR > GetTargetNode() const
static DELETED_BOARD_ITEM * GetInstance()
Definition: board_item.h:368
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:975
bool updateUI() override
Definition: dialog_drc.cpp:194
void OnDRCItemSelected(wxDataViewEvent &aEvent) override
Definition: dialog_drc.cpp:345
wxString m_footprintsTitleTemplate
Definition: dialog_drc.h:128
void UpdateData()
Rebuild the contents of the violation tabs based on the current markers and severties.
Definition: dialog_drc.cpp:335
const PCB_MARKER * m_centerMarkerOnIdle
Definition: dialog_drc.h:139
std::shared_ptr< RC_ITEMS_PROVIDER > m_ratsnestProvider
Definition: dialog_drc.h:132
wxString m_markersTitleTemplate
Definition: dialog_drc.h:126
int m_severities
Definition: dialog_drc.h:141
bool m_footprintTestsRun
Definition: dialog_drc.h:124
DIALOG_DRC(PCB_EDIT_FRAME *aEditorFrame, wxWindow *aParent)
Constructors.
Definition: dialog_drc.cpp:65
void OnEditViolationSeverities(wxHyperlinkEvent &aEvent) override
Definition: dialog_drc.cpp:815
void OnDeleteOneClick(wxCommandEvent &aEvent) override
RC_TREE_MODEL * m_fpWarningsTreeModel
Definition: dialog_drc.h:137
bool m_running
Definition: dialog_drc.h:122
void OnDeleteAllClick(wxCommandEvent &aEvent) override
void OnErrorLinkClicked(wxHtmlLinkEvent &event) override
Definition: dialog_drc.cpp:228
BOARD_DESIGN_SETTINGS & bds()
Definition: dialog_drc.h:118
void SelectMarker(const PCB_MARKER *aMarker)
Definition: dialog_drc.cpp:960
void OnClose(wxCloseEvent &event) override
Definition: dialog_drc.cpp:880
bool writeReport(const wxString &aFullFileName)
Function writeReport outputs the MARKER items with commentary to an open text file.
void syncCheckboxes()
Definition: dialog_drc.cpp:219
BOARD * m_currentBoard
Definition: dialog_drc.h:120
void OnDRCItemRClick(wxDataViewEvent &aEvent) override
Definition: dialog_drc.cpp:549
void PrevMarker()
Definition: dialog_drc.cpp:930
void OnRunDRCClick(wxCommandEvent &aEvent) override
Definition: dialog_drc.cpp:234
wxString m_ignoredTitleTemplate
Definition: dialog_drc.h:129
void OnDRCItemDClick(wxDataViewEvent &aEvent) override
Definition: dialog_drc.cpp:534
void deleteAllMarkers(bool aIncludeExclusions)
void updateDisplayedCounts()
RC_TREE_MODEL * m_unconnectedTreeModel
Definition: dialog_drc.h:136
void refreshEditor()
Definition: dialog_drc.cpp:922
wxString m_unconnectedTitleTemplate
Definition: dialog_drc.h:127
std::shared_ptr< RC_ITEMS_PROVIDER > m_fpWarningsProvider
Definition: dialog_drc.h:133
std::shared_ptr< RC_ITEMS_PROVIDER > m_markersProvider
Definition: dialog_drc.h:131
void OnSeverity(wxCommandEvent &aEvent) override
Definition: dialog_drc.cpp:821
PCB_EDIT_FRAME * m_frame
Definition: dialog_drc.h:121
bool m_drcRun
Definition: dialog_drc.h:123
void OnCancelClick(wxCommandEvent &aEvent) override
Definition: dialog_drc.cpp:891
void NextMarker()
Definition: dialog_drc.cpp:945
void OnActivateDlg(wxActivateEvent &aEvent) override
Definition: dialog_drc.cpp:177
void OnChangingNotebookPage(wxNotebookEvent &aEvent) override
Definition: dialog_drc.cpp:910
void OnSaveReport(wxCommandEvent &aEvent) override
Definition: dialog_drc.cpp:846
void ExcludeMarker()
Definition: dialog_drc.cpp:983
RC_TREE_MODEL * m_markersTreeModel
Definition: dialog_drc.h:135
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:110
wxString m_Name
Definition: drc_rule.h:112
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:142
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:48
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:59
DISPLAY_OPTIONS m_Display
DIALOG_DRC m_DrcDialog
static TOOL_ACTION showRatsnest
Definition: pcb_actions.h:275
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:273
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:126
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:300
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:216
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
std::vector< FAB_LAYER_COLOR > dummy
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:85
Definition of file extensions used in Kicad.