KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2023 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>
33#include <drc/drc_report.h>
37#include <pcb_edit_frame.h>
38#include <pcbnew_settings.h>
39#include <tool/tool_manager.h>
40#include <tools/pcb_actions.h>
42#include <pcb_marker.h>
43#include <pgm_base.h>
44#include <wx/filedlg.h>
45#include <wx/wupdlock.h>
47#include <widgets/ui_common.h>
52#include <tools/drc_tool.h>
55#include <kiplatform/ui.h>
56
57// wxWidgets spends *far* too long calcuating column widths (most of it, believe it or
58// not, in repeatedly creating/destroying a wxDC to do the measurement in).
59// Use default column widths instead.
60static int DEFAULT_SINGLE_COL_WIDTH = 660;
61
62static BOARD* g_lastDRCBoard = nullptr;
63static bool g_lastDRCRun = false;
64static bool g_lastFootprintTestsRun = false;
65static std::vector<wxString> g_lastIgnored;
66
67
68DIALOG_DRC::DIALOG_DRC( PCB_EDIT_FRAME* aEditorFrame, wxWindow* aParent ) :
69 DIALOG_DRC_BASE( aParent ),
71 m_running( false ),
72 m_drcRun( false ),
73 m_footprintTestsRun( false ),
74 m_markersTreeModel( nullptr ),
75 m_unconnectedTreeModel( nullptr ),
76 m_fpWarningsTreeModel( nullptr ),
78{
79 SetName( DIALOG_DRC_WINDOW_NAME ); // Set a window name to be able to find it
80
81 m_frame = aEditorFrame;
83
85
88
89 m_markersProvider = std::make_shared<DRC_ITEMS_PROVIDER>( m_currentBoard,
92
93 m_ratsnestProvider = std::make_shared<DRC_ITEMS_PROVIDER>( m_currentBoard,
95
96 m_fpWarningsProvider = std::make_shared<DRC_ITEMS_PROVIDER>( m_currentBoard,
98
100 m_markerDataView->AssociateModel( m_markersTreeModel );
102
106
110
111 m_ignoredList->InsertColumn( 0, wxEmptyString, wxLIST_FORMAT_LEFT, DEFAULT_SINGLE_COL_WIDTH );
112
114 {
117
118 for( const wxString& str : g_lastIgnored )
119 m_ignoredList->InsertItem( m_ignoredList->GetItemCount(), str );
120 }
121
122 m_Notebook->SetSelection( 0 );
123
124 if( Kiface().IsSingle() )
125 m_cbTestFootprints->Hide();
126
127 SetupStandardButtons( { { wxID_OK, _( "Run DRC" ) },
128 { wxID_CANCEL, _( "Close" ) } } );
129
130 m_markersTitleTemplate = m_Notebook->GetPageText( 0 );
131 m_unconnectedTitleTemplate = m_Notebook->GetPageText( 1 );
132 m_footprintsTitleTemplate = m_Notebook->GetPageText( 2 );
133 m_ignoredTitleTemplate = m_Notebook->GetPageText( 3 );
134
135 m_cbRefillZones->SetValue( cfg->m_DrcDialog.refill_zones );
137
138 if( !Kiface().IsSingle() )
140
141 Layout(); // adding the units above expanded Clearance text, now resize.
142
143 SetFocus();
144
146
148}
149
150
152{
153 m_frame->FocusOnItem( nullptr );
154
158
159 g_lastIgnored.clear();
160
161 for( int ii = 0; ii < m_ignoredList->GetItemCount(); ++ii )
162 g_lastIgnored.push_back( m_ignoredList->GetItemText( ii ) );
163
164 PCBNEW_SETTINGS* cfg = nullptr;
165
166 try
167 {
168 cfg = m_frame->GetPcbNewSettings();
169 }
170 catch( const std::runtime_error& e )
171 {
172 wxFAIL_MSG( e.what() );
173 }
174
175 if( cfg )
176 {
177 cfg->m_DrcDialog.refill_zones = m_cbRefillZones->GetValue();
179
180 if( !Kiface().IsSingle() )
182
184 }
185
186 m_markersTreeModel->DecRef();
187 m_unconnectedTreeModel->DecRef();
188 m_fpWarningsTreeModel->DecRef();
189}
190
191
192void DIALOG_DRC::OnActivateDlg( wxActivateEvent& aEvent )
193{
195 {
196 // If m_currentBoard is not the current board, (for instance because a new board
197 // was loaded), close the dialog, because many pointers are now invalid in lists
198 SetReturnCode( wxID_CANCEL );
199 Close();
200
202 drcTool->DestroyDRCDialog();
203 }
204}
205
206
207// PROGRESS_REPORTER calls
208
210{
211 double cur = alg::clamp( 0.0, (double) m_progress.load() / m_maxProgress, 1.0 );
212
213 m_gauge->SetValue( KiROUND( cur * 1000.0 ) );
214 Pgm().App().SafeYieldFor( this, wxEVT_CATEGORY_NATIVE_EVENTS );
215
216 return !m_cancelled;
217}
218
219
220void DIALOG_DRC::AdvancePhase( const wxString& aMessage )
221{
223 SetCurrentProgress( 0.0 );
224
225 m_messages->Report( aMessage );
226}
227
228
229// Don't globally define this; different facilities use different definitions of "ALL"
231
232
234{
239}
240
241
242void DIALOG_DRC::OnErrorLinkClicked( wxHtmlLinkEvent& event )
243{
244 m_frame->ShowBoardSetupDialog( _( "Custom Rules" ) );
245}
246
247
248void DIALOG_DRC::OnRunDRCClick( wxCommandEvent& aEvent )
249{
250 TOOL_MANAGER* toolMgr = m_frame->GetToolManager();
251 DRC_TOOL* drcTool = toolMgr->GetTool<DRC_TOOL>();
252 ZONE_FILLER_TOOL* zoneFillerTool = toolMgr->GetTool<ZONE_FILLER_TOOL>();
253 bool refillZones = m_cbRefillZones->GetValue();
254 bool reportAllTrackErrors = m_cbReportAllTrackErrors->GetValue();
255 bool testFootprints = m_cbTestFootprints->GetValue();
256
257 if( zoneFillerTool->IsBusy() )
258 {
259 wxBell();
260 return;
261 }
262
263 // This is not the time to have stale or buggy rules. Ensure they're up-to-date
264 // and that they at least parse.
265 try
266 {
267 drcTool->GetDRCEngine()->InitEngine( m_frame->GetDesignRulesPath() );
268 }
269 catch( PARSE_ERROR& )
270 {
271 m_runningResultsBook->ChangeSelection( 0 ); // Display the "Tests Running..." tab
272 m_DeleteCurrentMarkerButton->Enable( false );
273 m_DeleteAllMarkersButton->Enable( false );
274 m_saveReport->Enable( false );
275
276 m_messages->Clear();
277 m_messages->Report( _( "DRC incomplete: could not compile custom design rules." )
278 + wxS( "&nbsp;&nbsp;" )
279 + wxS( "<a href='$CUSTOM_RULES'>" ) + _( "Show design rules." ) + wxT( "</a>" ) );
280 m_messages->Flush();
281
282 Raise();
283 return;
284 }
285
286 m_footprintTestsRun = false;
287 m_cancelled = false;
288
290 deleteAllMarkers( true );
291
292 std::vector<std::reference_wrapper<RC_ITEM>> violations = DRC_ITEM::GetItemsWithSeverities();
293 m_ignoredList->DeleteAllItems();
294
295 for( std::reference_wrapper<RC_ITEM>& item : violations )
296 {
297 if( bds().GetSeverity( item.get().GetErrorCode() ) == RPT_SEVERITY_IGNORE )
298 {
299 m_ignoredList->InsertItem( m_ignoredList->GetItemCount(),
300 wxT( " • " ) + item.get().GetErrorText() );
301 }
302 }
303
304 m_ignoredList->SetColumnWidth( 0, m_ignoredList->GetParent()->GetClientSize().x - 20 );
305
306 Raise();
307
308 m_runningResultsBook->ChangeSelection( 0 ); // Display the "Tests Running..." tab
309 m_messages->Clear();
310 wxYield(); // Allow time slice to refresh Messages
311
312 m_running = true;
313 m_sdbSizerCancel->SetLabel( _( "Cancel" ) );
314 m_sdbSizerOK->Enable( false );
315 m_DeleteCurrentMarkerButton->Enable( false );
316 m_DeleteAllMarkersButton->Enable( false );
317 m_saveReport->Enable( false );
318
319 {
320 wxBusyCursor dummy;
321 drcTool->RunTests( this, refillZones, reportAllTrackErrors, testFootprints );
322 }
323
324 if( m_cancelled )
325 m_messages->Report( _( "-------- DRC cancelled by user.<br><br>" ) );
326 else
327 m_messages->Report( _( "Done.<br><br>" ) );
328
329 Raise();
330 wxYield(); // Allow time slice to refresh Messages
331
332 m_running = false;
333 m_sdbSizerCancel->SetLabel( _( "Close" ) );
334 m_sdbSizerOK->Enable( true );
335 m_DeleteCurrentMarkerButton->Enable( true );
336 m_DeleteAllMarkersButton->Enable( true );
337 m_saveReport->Enable( true );
338
339 if( !m_cancelled )
340 {
341 m_sdbSizerCancel->SetDefault();
342 // wxWidgets has a tendency to keep both buttons highlighted without the following:
343 m_sdbSizerOK->Enable( false );
344
345 wxMilliSleep( 500 );
346 m_runningResultsBook->ChangeSelection( 1 );
348
349 // now re-enable m_sdbSizerOK button
350 m_sdbSizerOK->Enable( true );
351 }
352
354}
355
356
358{
362
364}
365
366
367void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
368{
369 BOARD* board = m_frame->GetBoard();
370 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
371
372 auto getActiveLayers =
373 []( BOARD_ITEM* aItem ) -> LSET
374 {
375 if( aItem->Type() == PCB_PAD_T )
376 {
377 PAD* pad = static_cast<PAD*>( aItem );
378 LSET layers;
379
380 for( int layer : aItem->GetLayerSet().Seq() )
381 {
382 if( pad->FlashLayer( layer ) )
383 layers.set( layer );
384 }
385
386 return layers;
387 }
388 else
389 {
390 return aItem->GetLayerSet();
391 }
392 };
393
394 if( !node )
395 {
396 // list is being freed; don't do anything with null ptrs
397
398 aEvent.Skip();
399 return;
400 }
401
402 std::shared_ptr<RC_ITEM> rc_item = node->m_RcItem;
403
404 if( rc_item->GetErrorCode() == DRCE_UNRESOLVED_VARIABLE
405 && rc_item->GetParent()->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
406 {
407 m_frame->FocusOnLocation( node->m_RcItem->GetParent()->GetPos() );
408
409 aEvent.Skip();
410 return;
411 }
412
413 const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
414 BOARD_ITEM* item = board->GetItem( itemID );
415
416 if( !item || item == DELETED_BOARD_ITEM::GetInstance() )
417 {
418 // nothing to highlight / focus on
419
420 aEvent.Skip();
421 return;
422 }
423
424 PCB_LAYER_ID principalLayer;
425 LSET violationLayers;
426 BOARD_ITEM* a = board->GetItem( rc_item->GetMainItemID() );
427 BOARD_ITEM* b = board->GetItem( rc_item->GetAuxItemID() );
428 BOARD_ITEM* c = board->GetItem( rc_item->GetAuxItem2ID() );
429 BOARD_ITEM* d = board->GetItem( rc_item->GetAuxItem3ID() );
430
431 if( rc_item->GetErrorCode() == DRCE_MALFORMED_COURTYARD )
432 {
433 if( a && ( a->GetFlags() & MALFORMED_B_COURTYARD ) > 0
434 && ( a->GetFlags() & MALFORMED_F_COURTYARD ) == 0 )
435 {
436 principalLayer = B_CrtYd;
437 }
438 else
439 {
440 principalLayer = F_CrtYd;
441 }
442 }
443 else if (rc_item->GetErrorCode() == DRCE_INVALID_OUTLINE )
444 {
445 principalLayer = Edge_Cuts;
446 }
447 else
448 {
449 principalLayer = UNDEFINED_LAYER;
450
451 if( a || b || c || d )
452 violationLayers = LSET::AllLayersMask();
453
454 // Try to initialize principalLayer to a valid layer. Note that some markers have
455 // a layer set to UNDEFINED_LAYER, so we may need to keep looking.
456
457 for( BOARD_ITEM* it: { a, b, c, d } )
458 {
459 if( !it )
460 continue;
461
462 LSET layersList = getActiveLayers( it );
463 violationLayers &= layersList;
464
465 if( principalLayer <= UNDEFINED_LAYER && layersList.count() )
466 principalLayer = layersList.Seq().front();
467 }
468 }
469
470 if( violationLayers.count() )
471 principalLayer = violationLayers.Seq().front();
472 else if( !(principalLayer <= UNDEFINED_LAYER ) )
473 violationLayers.set( principalLayer );
474
475 WINDOW_THAWER thawer( m_frame );
476
477 if( principalLayer > UNDEFINED_LAYER && ( violationLayers & board->GetVisibleLayers() ) == 0 )
478 m_frame->GetAppearancePanel()->SetLayerVisible( principalLayer, true );
479
480 if( principalLayer > UNDEFINED_LAYER && board->GetVisibleLayers().test( principalLayer ) )
481 m_frame->SetActiveLayer( principalLayer );
482
483 if( rc_item->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
484 {
487
488 if( item->Type() == PCB_ZONE_T )
489 {
490 m_frame->FocusOnItem( item, principalLayer );
491
492 m_frame->GetBoard()->GetConnectivity()->RunOnUnconnectedEdges(
493 [&]( CN_EDGE& edge )
494 {
495 // Connectivity was valid when DRC was run, but this is a modeless dialog
496 // so it might not be now.
497 if( !edge.GetSourceNode() || edge.GetSourceNode()->Dirty() )
498 return true;
499
500 if( !edge.GetTargetNode() || edge.GetTargetNode()->Dirty() )
501 return true;
502
503 if( edge.GetSourceNode()->Parent() == a
504 && edge.GetTargetNode()->Parent() == b )
505 {
506 VECTOR2I focusPos;
507
508 if( item == a && item == b )
509 {
510 focusPos = ( node->m_Type == RC_TREE_NODE::MAIN_ITEM )
511 ? edge.GetSourcePos()
512 : edge.GetTargetPos();
513 }
514 else
515 {
516 focusPos = ( item == edge.GetSourceNode()->Parent() )
517 ? edge.GetSourcePos()
518 : edge.GetTargetPos();
519 }
520
521 m_frame->FocusOnLocation( focusPos );
523
524 return false;
525 }
526
527 return true;
528 } );
529 }
530 else
531 {
532 m_frame->FocusOnItem( item, principalLayer );
533 }
534 }
535 else if( rc_item->GetErrorCode() == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG )
536 {
537 BOARD_CONNECTED_ITEM* track = dynamic_cast<PCB_TRACK*>( item );
538 std::vector<BOARD_ITEM*> items;
539
540 if( track )
541 {
542 int net = track->GetNetCode();
543
544 wxASSERT( net > 0 ); // Without a net how can it be a diff-pair?
545
546 for( const KIID& id : rc_item->GetIDs() )
547 {
548 auto* candidate = dynamic_cast<BOARD_CONNECTED_ITEM*>( board->GetItem( id ) );
549
550 if( candidate && candidate->GetNetCode() == net )
551 items.push_back( candidate );
552 }
553 }
554 else
555 {
556 items.push_back( item );
557 }
558
559 m_frame->FocusOnItems( items, principalLayer );
560 }
561 else
562 {
563 m_frame->FocusOnItem( item, principalLayer );
564 }
565
566 aEvent.Skip();
567}
568
569
570void DIALOG_DRC::OnDRCItemDClick( wxDataViewEvent& aEvent )
571{
572 if( aEvent.GetItem().IsOk() )
573 {
574 // turn control over to m_frame, hide this DIALOG_DRC window,
575 // no destruction so we can preserve listbox cursor
576 if( !IsModal() )
577 Show( false );
578 }
579
580 // Do not skip aEvent here: this is not useful, and Pcbnew crashes
581 // if skipped (at least on Windows)
582}
583
584
585void DIALOG_DRC::OnDRCItemRClick( wxDataViewEvent& aEvent )
586{
587 TOOL_MANAGER* toolMgr = m_frame->GetToolManager();
588 BOARD_INSPECTION_TOOL* inspectionTool = toolMgr->GetTool<BOARD_INSPECTION_TOOL>();
589 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
590
591 if( !node )
592 return;
593
594 std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
595 DRC_ITEM* drcItem = static_cast<DRC_ITEM*>( rcItem.get() );
596 std::shared_ptr<CONNECTIVITY_DATA> conn = m_currentBoard->GetConnectivity();
597 wxString listName;
598 wxMenu menu;
599
600 switch( bds().m_DRCSeverities[ rcItem->GetErrorCode() ] )
601 {
602 case RPT_SEVERITY_ERROR: listName = _( "errors" ); break;
603 case RPT_SEVERITY_WARNING: listName = _( "warnings" ); break;
604 default: listName = _( "appropriate" ); break;
605 }
606
607 enum MENU_IDS
608 {
609 ID_EDIT_EXCLUSION_COMMENT = 4467,
610 ID_REMOVE_EXCLUSION,
611 ID_REMOVE_EXCLUSION_ALL,
612 ID_ADD_EXCLUSION,
613 ID_ADD_EXCLUSION_ALL,
614 ID_INSPECT_VIOLATION,
615 ID_SET_SEVERITY_TO_ERROR,
616 ID_SET_SEVERITY_TO_WARNING,
617 ID_SET_SEVERITY_TO_IGNORE,
618 ID_EDIT_SEVERITIES
619 };
620
621 if( rcItem->GetParent()->IsExcluded() )
622 {
623 menu.Append( ID_EDIT_EXCLUSION_COMMENT,
624 _( "Edit exclusion comment..." ) );
625
626 menu.Append( ID_REMOVE_EXCLUSION,
627 _( "Remove exclusion for this violation" ),
628 wxString::Format( _( "It will be placed back in the %s list" ), listName ) );
629
630 if( drcItem->GetViolatingRule() && !drcItem->GetViolatingRule()->m_Implicit )
631 {
632 menu.Append( ID_REMOVE_EXCLUSION_ALL,
633 wxString::Format( _( "Remove all exclusions for violations of rule '%s'" ),
634 drcItem->GetViolatingRule()->m_Name ),
635 wxString::Format( _( "They will be placed back in the %s list" ), listName ) );
636 }
637 }
638 else
639 {
640 menu.Append( ID_ADD_EXCLUSION,
641 _( "Exclude this violation..." ),
642 wxString::Format( _( "It will be excluded from the %s list" ), listName ) );
643
644 if( drcItem->GetViolatingRule() && !drcItem->GetViolatingRule()->m_Implicit )
645 {
646 menu.Append( ID_ADD_EXCLUSION_ALL,
647 wxString::Format( _( "Exclude all violations of rule '%s'..." ),
648 drcItem->GetViolatingRule()->m_Name ),
649 wxString::Format( _( "They will be excluded from the %s list" ), listName ) );
650 }
651 }
652
653 wxString inspectDRCErrorMenuText = inspectionTool->InspectDRCErrorMenuText( rcItem );
654
655 if( !inspectDRCErrorMenuText.IsEmpty() )
656 menu.Append( ID_INSPECT_VIOLATION, inspectDRCErrorMenuText );
657
658 menu.AppendSeparator();
659
660 if( bds().m_DRCSeverities[ rcItem->GetErrorCode() ] == RPT_SEVERITY_WARNING )
661 {
662 menu.Append( ID_SET_SEVERITY_TO_ERROR,
663 wxString::Format( _( "Change severity to Error for all '%s' violations" ),
664 rcItem->GetErrorText() ),
665 _( "Violation severities can also be edited in the Board Setup... dialog" ) );
666 }
667 else
668 {
669 menu.Append( ID_SET_SEVERITY_TO_WARNING,
670 wxString::Format( _( "Change severity to Warning for all '%s' violations" ),
671 rcItem->GetErrorText() ),
672 _( "Violation severities can also be edited in the Board Setup... dialog" ) );
673 }
674
675 menu.Append( ID_SET_SEVERITY_TO_IGNORE,
676 wxString::Format( _( "Ignore all '%s' violations" ), rcItem->GetErrorText() ),
677 _( "Violations will not be checked or reported" ) );
678
679 menu.AppendSeparator();
680
681 menu.Append( ID_EDIT_SEVERITIES,
682 _( "Edit violation severities..." ),
683 _( "Open the Board Setup... dialog" ) );
684
685 bool modified = false;
686
687 switch( GetPopupMenuSelectionFromUser( menu ) )
688 {
689 case ID_EDIT_EXCLUSION_COMMENT:
690 if( PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( node->m_RcItem->GetParent() ) )
691 {
692 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Optional comment:" ), _( "Exclusion Comment" ),
693 marker->GetComment(), true );
694
695 if( dlg.ShowModal() == wxID_CANCEL )
696 break;
697
698 marker->SetExcluded( true, dlg.GetValue() );
699
700 wxString serialized = marker->Serialize();
701 m_frame->GetDesignSettings().m_DrcExclusions.insert( serialized );
703
704 // Update view
705 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
706 modified = true;
707 }
708
709 break;
710
711 case ID_REMOVE_EXCLUSION:
712 if( PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( rcItem->GetParent() ) )
713 {
714 marker->SetExcluded( false );
715
716 wxString serialized = marker->Serialize();
717 m_frame->GetDesignSettings().m_DrcExclusions.erase( serialized );
718 m_frame->GetDesignSettings().m_DrcExclusionComments.erase( serialized );
719
720 if( rcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
721 {
724 }
725 else
726 {
727 m_frame->GetCanvas()->GetView()->Update( marker );
728 }
729
730 // Update view
731 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
732 modified = true;
733 }
734
735 break;
736
737 case ID_ADD_EXCLUSION:
738 if( PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( rcItem->GetParent() ) )
739 {
740 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Optional comment:" ), _( "Exclusion Comment" ),
741 wxEmptyString, true );
742
743 if( dlg.ShowModal() == wxID_CANCEL )
744 break;
745
746 marker->SetExcluded( true, dlg.GetValue() );
747
748 wxString serialized = marker->Serialize();
749 m_frame->GetDesignSettings().m_DrcExclusions.insert( serialized );
751
752 if( rcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
753 {
756 }
757 else
758 {
759 m_frame->GetCanvas()->GetView()->Update( marker );
760 }
761
762 // Update view
764 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
765 else
766 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->DeleteCurrentItem( false );
767
768 modified = true;
769 }
770
771 break;
772
773 case ID_REMOVE_EXCLUSION_ALL:
774 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
775 {
776 DRC_ITEM* candidateDrcItem = static_cast<DRC_ITEM*>( marker->GetRCItem().get() );
777
778 if( candidateDrcItem->GetViolatingRule() == drcItem->GetViolatingRule() )
779 {
780 marker->SetExcluded( false );
781
782 wxString serialized = marker->Serialize();
783 m_frame->GetDesignSettings().m_DrcExclusions.erase( serialized );
784 m_frame->GetDesignSettings().m_DrcExclusionComments.erase( serialized );
785 }
786 }
787
788 // Rebuild model and view
789 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
790 modified = true;
791 break;
792
793 case ID_ADD_EXCLUSION_ALL:
794 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
795 {
796 DRC_ITEM* candidateDrcItem = static_cast<DRC_ITEM*>( marker->GetRCItem().get() );
797
798 if( candidateDrcItem->GetViolatingRule() == drcItem->GetViolatingRule() )
799 {
800 marker->SetExcluded( true );
801
802 wxString serialized = marker->Serialize();
803 m_frame->GetDesignSettings().m_DrcExclusions.insert( serialized );
804 }
805 }
806
807 // Rebuild model and view
808 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
809 modified = true;
810 break;
811
812 case ID_INSPECT_VIOLATION:
813 inspectionTool->InspectDRCError( node->m_RcItem );
814 break;
815
816 case ID_SET_SEVERITY_TO_ERROR:
817 bds().m_DRCSeverities[ rcItem->GetErrorCode() ] = RPT_SEVERITY_ERROR;
818
819 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
820 {
821 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
822 m_frame->GetCanvas()->GetView()->Update( marker );
823 }
824
825 // Rebuild model and view
826 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
827 modified = true;
828 break;
829
830 case ID_SET_SEVERITY_TO_WARNING:
831 bds().m_DRCSeverities[ rcItem->GetErrorCode() ] = RPT_SEVERITY_WARNING;
832
833 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
834 {
835 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
836 m_frame->GetCanvas()->GetView()->Update( marker );
837 }
838
839 // Rebuild model and view
840 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
841 modified = true;
842 break;
843
844 case ID_SET_SEVERITY_TO_IGNORE:
845 {
846 bds().m_DRCSeverities[ rcItem->GetErrorCode() ] = RPT_SEVERITY_IGNORE;
847
848 m_ignoredList->InsertItem( m_ignoredList->GetItemCount(),
849 wxT( " • " ) + rcItem->GetErrorText() );
850
851 std::vector<PCB_MARKER*>& markers = m_frame->GetBoard()->Markers();
852
853 for( unsigned i = 0; i < markers.size(); )
854 {
855 if( markers[i]->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
856 {
857 m_frame->GetCanvas()->GetView()->Remove( markers.at( i ) );
858 markers.erase( markers.begin() + i );
859 }
860 else
861 {
862 ++i;
863 }
864 }
865
866 if( rcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
868
869 // Rebuild model and view
870 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
871 modified = true;
872 break;
873 }
874
875 case ID_EDIT_SEVERITIES:
876 m_frame->ShowBoardSetupDialog( _( "Violation Severity" ) );
877 break;
878 }
879
880 if( modified )
881 {
884 m_frame->OnModify();
885 }
886}
887
888
889void DIALOG_DRC::OnEditViolationSeverities( wxHyperlinkEvent& aEvent )
890{
891 m_frame->ShowBoardSetupDialog( _( "Violation Severity" ) );
892}
893
894
895void DIALOG_DRC::OnSeverity( wxCommandEvent& aEvent )
896{
897 int flag = 0;
898
899 if( aEvent.GetEventObject() == m_showAll )
901 else if( aEvent.GetEventObject() == m_showErrors )
903 else if( aEvent.GetEventObject() == m_showWarnings )
905 else if( aEvent.GetEventObject() == m_showExclusions )
907
908 if( aEvent.IsChecked() )
910 else if( aEvent.GetEventObject() == m_showAll )
912 else
913 m_severities &= ~flag;
914
916 UpdateData();
917}
918
919
920void DIALOG_DRC::OnSaveReport( wxCommandEvent& aEvent )
921{
922 wxFileName fn( "DRC." + FILEEXT::ReportFileExtension );
923
924 wxFileDialog dlg( this, _( "Save Report File" ), Prj().GetProjectPath(), fn.GetFullName(),
926 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
927
928 if( dlg.ShowModal() != wxID_OK )
929 return;
930
931 fn = dlg.GetPath();
932
933 if( fn.GetExt().IsEmpty() )
934 fn.SetExt( FILEEXT::ReportFileExtension );
935
936 if( !fn.IsAbsolute() )
937 {
938 wxString prj_path = Prj().GetProjectPath();
939 fn.MakeAbsolute( prj_path );
940 }
941
944
945 bool success = false;
946 if( fn.GetExt() == FILEEXT::JsonFileExtension )
947 success = reportWriter.WriteJsonReport( fn.GetFullPath() );
948 else
949 success = reportWriter.WriteTextReport( fn.GetFullPath() );
950
951 if( success )
952 {
953 m_messages->Report( wxString::Format( _( "Report file '%s' created<br>" ),
954 fn.GetFullPath() ) );
955 }
956 else
957 {
958 DisplayError( this, wxString::Format( _( "Failed to create file '%s'." ),
959 fn.GetFullPath() ) );
960 }
961}
962
963
964void DIALOG_DRC::OnClose( wxCloseEvent& aEvent )
965{
966 if( m_running )
967 aEvent.Veto();
968
969 wxCommandEvent dummy;
970
972}
973
974
975void DIALOG_DRC::OnCancelClick( wxCommandEvent& aEvent )
976{
977 if( m_running )
978 {
979 m_cancelled = true;
980 return;
981 }
982
983 m_frame->FocusOnItem( nullptr );
984
985 SetReturnCode( wxID_CANCEL );
986
987 // The dialog can be modal or not modal.
988 // Leave the DRC caller destroy (or not) the dialog
990 drcTool->DestroyDRCDialog();
991}
992
993
994void DIALOG_DRC::OnChangingNotebookPage( wxNotebookEvent& aEvent )
995{
996 m_markerDataView->UnselectAll();
997 m_unconnectedDataView->UnselectAll();
998 m_footprintsDataView->UnselectAll();
999
1000 aEvent.Skip();
1001}
1002
1003
1005{
1006 WINDOW_THAWER thawer( m_frame );
1007
1009}
1010
1011
1013{
1014 if( m_Notebook->IsShown() )
1015 {
1016 switch( m_Notebook->GetSelection() )
1017 {
1018 case 0: m_markersTreeModel->PrevMarker(); break;
1019 case 1: m_unconnectedTreeModel->PrevMarker(); break;
1020 case 2: m_fpWarningsTreeModel->PrevMarker(); break;
1021 case 3: break;
1022 }
1023 }
1024}
1025
1026
1028{
1029 if( m_Notebook->IsShown() )
1030 {
1031 switch( m_Notebook->GetSelection() )
1032 {
1033 case 0: m_markersTreeModel->NextMarker(); break;
1034 case 1: m_unconnectedTreeModel->NextMarker(); break;
1035 case 2: m_fpWarningsTreeModel->NextMarker(); break;
1036 case 3: break;
1037 }
1038 }
1039}
1040
1041
1043{
1044 if( m_Notebook->IsShown() )
1045 {
1046 m_Notebook->SetSelection( 0 );
1047 m_markersTreeModel->SelectMarker( aMarker );
1048
1049 CallAfter(
1050 [=]
1051 {
1052 m_markersTreeModel->CenterMarker( aMarker );
1053 } );
1054 }
1055}
1056
1057
1059{
1060 if( !m_Notebook->IsShown() || m_Notebook->GetSelection() != 0 )
1061 return;
1062
1063 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( m_markerDataView->GetCurrentItem() );
1064 PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( node->m_RcItem->GetParent() );
1065
1066 if( marker && marker->GetSeverity() != RPT_SEVERITY_EXCLUSION )
1067 {
1068 marker->SetExcluded( true );
1069 m_frame->GetDesignSettings().m_DrcExclusions.insert( marker->Serialize() );
1070 m_frame->GetCanvas()->GetView()->Update( marker );
1071
1072 // Update view
1075 else
1077
1079 refreshEditor();
1080 m_frame->OnModify();
1081 }
1082}
1083
1084
1085void DIALOG_DRC::deleteAllMarkers( bool aIncludeExclusions )
1086{
1087 // Clear current selection list to avoid selection of deleted items
1089
1090 m_markersTreeModel->DeleteItems( false, aIncludeExclusions, false );
1091 m_unconnectedTreeModel->DeleteItems( false, aIncludeExclusions, false );
1092 m_fpWarningsTreeModel->DeleteItems( false, aIncludeExclusions, false );
1093
1094 m_frame->GetBoard()->DeleteMARKERs( true, aIncludeExclusions );
1095}
1096
1097
1098void DIALOG_DRC::OnDeleteOneClick( wxCommandEvent& aEvent )
1099{
1100 if( m_Notebook->GetSelection() == 0 )
1101 {
1102 // Clear the selection. It may be the selected DRC marker.
1104
1106
1107 // redraw the pcb
1108 refreshEditor();
1109 }
1110 else if( m_Notebook->GetSelection() == 1 )
1111 {
1113 }
1114 else if( m_Notebook->GetSelection() == 2 )
1115 {
1117 }
1118
1120}
1121
1122
1123void DIALOG_DRC::OnDeleteAllClick( wxCommandEvent& aEvent )
1124{
1125 static bool s_includeExclusions = false;
1126
1127 int numExcluded = 0;
1128
1129 if( m_markersProvider )
1130 numExcluded += m_markersProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1131
1132 if( m_ratsnestProvider )
1133 numExcluded += m_ratsnestProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1134
1136 numExcluded += m_fpWarningsProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1137
1138 if( numExcluded > 0 )
1139 {
1140 wxMessageDialog dlg( this, _( "Delete exclusions too?" ), _( "Delete All Markers" ),
1141 wxYES_NO | wxCANCEL | wxCENTER | wxICON_QUESTION );
1142 dlg.SetYesNoLabels( _( "Errors and Warnings Only" ),
1143 _( "Errors, Warnings and Exclusions" ) );
1144
1145 int ret = dlg.ShowModal();
1146
1147 if( ret == wxID_CANCEL )
1148 return;
1149 else if( ret == wxID_NO )
1150 s_includeExclusions = true;
1151 }
1152
1153 deleteAllMarkers( s_includeExclusions );
1154
1155 refreshEditor();
1157}
1158
1159
1161{
1164 DRC_ENGINE* drcEngine = drcTool->GetDRCEngine().get();
1165
1166 // Collect counts:
1167
1168 int numMarkers = 0;
1169 int numUnconnected = 0;
1170 int numFootprints = 0;
1171
1172 int numErrors = 0;
1173 int numWarnings = 0;
1174 int numExcluded = 0;
1175
1176 if( m_markersProvider )
1177 {
1178 numMarkers += m_markersProvider->GetCount();
1179 numErrors += m_markersProvider->GetCount( RPT_SEVERITY_ERROR );
1180 numWarnings += m_markersProvider->GetCount( RPT_SEVERITY_WARNING );
1181 numExcluded += m_markersProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1182 }
1183
1184 if( m_ratsnestProvider )
1185 {
1186 numUnconnected += m_ratsnestProvider->GetCount();
1187 numErrors += m_ratsnestProvider->GetCount( RPT_SEVERITY_ERROR );
1188 numWarnings += m_ratsnestProvider->GetCount( RPT_SEVERITY_WARNING );
1189 numExcluded += m_ratsnestProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1190 }
1191
1193 {
1194 numFootprints += m_fpWarningsProvider->GetCount();
1195 numErrors += m_fpWarningsProvider->GetCount( RPT_SEVERITY_ERROR );
1196 numWarnings += m_fpWarningsProvider->GetCount( RPT_SEVERITY_WARNING );
1197 numExcluded += m_fpWarningsProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1198 }
1199
1200 bool showErrors = m_showErrors->GetValue();
1201 bool showWarnings = m_showWarnings->GetValue();
1202 bool errorsOverflowed = false;
1203 bool warningsOverflowed = false;
1204 bool markersOverflowed = false;
1205 bool unconnectedOverflowed = false;
1206 bool footprintsOverflowed = false;
1207
1208 for( int ii = DRCE_FIRST; ii < DRCE_LAST; ++ii )
1209 {
1210 if( drcEngine->IsErrorLimitExceeded( ii ) )
1211 {
1212 if( bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1213 errorsOverflowed = true;
1214 else if( bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1215 warningsOverflowed = true;
1216
1217 if( ii == DRCE_UNCONNECTED_ITEMS )
1218 {
1219 if( showWarnings && bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1220 unconnectedOverflowed = true;
1221 else if( showErrors && bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1222 unconnectedOverflowed = true;
1223 }
1224 else if( ii == DRCE_MISSING_FOOTPRINT
1226 || ii == DRCE_EXTRA_FOOTPRINT
1227 || ii == DRCE_NET_CONFLICT
1229 {
1230 if( showWarnings && bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1231 footprintsOverflowed = true;
1232 else if( showErrors && bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1233 footprintsOverflowed = true;
1234 }
1235 else
1236 {
1237 if( showWarnings && bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1238 markersOverflowed = true;
1239 else if( showErrors && bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1240 markersOverflowed = true;
1241 }
1242 }
1243 }
1244
1245 wxString msg;
1246 wxString num;
1247
1248 // Update tab headers:
1249
1250 if( m_drcRun )
1251 {
1252 num.Printf( markersOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numMarkers );
1253 msg.Printf( m_markersTitleTemplate, num );
1254 }
1255 else
1256 {
1258 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1259 }
1260
1261 m_Notebook->SetPageText( 0, msg );
1262
1263 if( m_drcRun )
1264 {
1265 num.Printf( unconnectedOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numUnconnected );
1266 msg.sprintf( m_unconnectedTitleTemplate, num );
1267 }
1268 else
1269 {
1271 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1272 }
1273
1274 m_Notebook->SetPageText( 1, msg );
1275
1277 {
1278 num.Printf( footprintsOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numFootprints );
1279 msg.sprintf( m_footprintsTitleTemplate, num );
1280 }
1281 else if( m_drcRun )
1282 {
1284 msg.Replace( wxT( "%s" ), _( "not run" ) );
1285 }
1286 else
1287 {
1289 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1290 }
1291
1292 m_Notebook->SetPageText( 2, msg );
1293
1294 if( m_drcRun )
1295 {
1296 num.Printf( wxT( "%d" ), m_ignoredList->GetItemCount() );
1297 msg.sprintf( m_ignoredTitleTemplate, num );
1298 }
1299 else
1300 {
1302 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1303 }
1304
1305 m_Notebook->SetPageText( 3, msg );
1306
1307 // Update badges:
1308
1309 if( !m_drcRun && numErrors == 0 )
1310 numErrors = -1;
1311
1312 if( !m_drcRun && numWarnings == 0 )
1313 numWarnings = -1;
1314
1315 m_errorsBadge->SetMaximumNumber( numErrors );
1316 m_errorsBadge->UpdateNumber( errorsOverflowed ? numErrors + 1 : numErrors,
1318
1319 m_warningsBadge->SetMaximumNumber( numWarnings );
1320 m_warningsBadge->UpdateNumber( warningsOverflowed ? numWarnings + 1 : numWarnings,
1322
1323 m_exclusionsBadge->SetMaximumNumber( numExcluded );
1325}
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< wxString, wxString > m_DrcExclusionComments
std::map< int, SEVERITY > m_DRCSeverities
std::set< wxString > m_DrcExclusions
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.
wxString InspectDRCErrorMenuText(const std::shared_ptr< RC_ITEM > &aDRCItem)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:77
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:276
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:703
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:1166
void RecordDRCExclusions()
Scan existing markers and record data from any that are Excluded.
Definition: board.cpp:329
MARKERS & Markers()
Definition: board.h:330
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition: board.cpp:298
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:1121
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:441
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:427
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
bool updateUI() override
Definition: dialog_drc.cpp:209
void OnDRCItemSelected(wxDataViewEvent &aEvent) override
Definition: dialog_drc.cpp:367
wxString m_footprintsTitleTemplate
Definition: dialog_drc.h:118
void UpdateData()
Rebuild the contents of the violation tabs based on the current markers and severties.
Definition: dialog_drc.cpp:357
std::shared_ptr< RC_ITEMS_PROVIDER > m_ratsnestProvider
Definition: dialog_drc.h:122
wxString m_markersTitleTemplate
Definition: dialog_drc.h:116
int m_severities
Definition: dialog_drc.h:129
bool m_footprintTestsRun
Definition: dialog_drc.h:114
DIALOG_DRC(PCB_EDIT_FRAME *aEditorFrame, wxWindow *aParent)
Constructors.
Definition: dialog_drc.cpp:68
void OnEditViolationSeverities(wxHyperlinkEvent &aEvent) override
Definition: dialog_drc.cpp:889
void OnDeleteOneClick(wxCommandEvent &aEvent) override
RC_TREE_MODEL * m_fpWarningsTreeModel
Definition: dialog_drc.h:127
bool m_running
Definition: dialog_drc.h:112
void OnDeleteAllClick(wxCommandEvent &aEvent) override
void OnErrorLinkClicked(wxHtmlLinkEvent &event) override
Definition: dialog_drc.cpp:242
BOARD_DESIGN_SETTINGS & bds()
Definition: dialog_drc.h:108
void SelectMarker(const PCB_MARKER *aMarker)
void OnClose(wxCloseEvent &event) override
Definition: dialog_drc.cpp:964
void syncCheckboxes()
Definition: dialog_drc.cpp:233
BOARD * m_currentBoard
Definition: dialog_drc.h:110
void OnDRCItemRClick(wxDataViewEvent &aEvent) override
Definition: dialog_drc.cpp:585
void PrevMarker()
void OnRunDRCClick(wxCommandEvent &aEvent) override
Definition: dialog_drc.cpp:248
wxString m_ignoredTitleTemplate
Definition: dialog_drc.h:119
void OnDRCItemDClick(wxDataViewEvent &aEvent) override
Definition: dialog_drc.cpp:570
void deleteAllMarkers(bool aIncludeExclusions)
void updateDisplayedCounts()
RC_TREE_MODEL * m_unconnectedTreeModel
Definition: dialog_drc.h:126
void refreshEditor()
wxString m_unconnectedTitleTemplate
Definition: dialog_drc.h:117
std::shared_ptr< RC_ITEMS_PROVIDER > m_fpWarningsProvider
Definition: dialog_drc.h:123
std::shared_ptr< RC_ITEMS_PROVIDER > m_markersProvider
Definition: dialog_drc.h:121
void OnSeverity(wxCommandEvent &aEvent) override
Definition: dialog_drc.cpp:895
PCB_EDIT_FRAME * m_frame
Definition: dialog_drc.h:111
bool m_drcRun
Definition: dialog_drc.h:113
void OnCancelClick(wxCommandEvent &aEvent) override
Definition: dialog_drc.cpp:975
void NextMarker()
void OnActivateDlg(wxActivateEvent &aEvent) override
Definition: dialog_drc.cpp:192
void OnChangingNotebookPage(wxNotebookEvent &aEvent) override
Definition: dialog_drc.cpp:994
void OnSaveReport(wxCommandEvent &aEvent) override
Definition: dialog_drc.cpp:920
void ExcludeMarker()
RC_TREE_MODEL * m_markersTreeModel
Definition: dialog_drc.h:125
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:122
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:123
DRC_RULE * GetViolatingRule() const
Definition: drc_item.h:129
bool WriteJsonReport(const wxString &aFullFileName)
Definition: drc_report.cpp:114
bool WriteTextReport(const wxString &aFullFileName)
Definition: drc_report.cpp:47
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:122
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:132
void RefreshCanvas() override
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
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
EDA_ITEM_FLAGS GetFlags() const
Definition: eda_item.h:126
bool IsSingle() const
Is this KIFACE running under single_top?
Definition: kiface_base.h:107
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:75
virtual void Remove(VIEW_ITEM *aItem) override
Remove a VIEW_ITEM from the view.
Definition: pcb_view.cpp:66
Definition: kiid.h:49
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:573
static LSET AllLayersMask()
Definition: lset.cpp:898
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:418
@ MARKER_DRAWING_SHEET
Definition: marker_base.h:56
void SetExcluded(bool aExcluded, const wxString &aComment=wxEmptyString)
Definition: marker_base.h:99
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:320
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:68
wxString GetDesignRulesPath()
Return the absolute path to the design rules file for the currently-loaded board.
APPEARANCE_CONTROLS * GetAppearancePanel()
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.
wxString Serialize() const
Definition: pcb_marker.cpp:96
SEVERITY GetSeverity() const override
Definition: pcb_marker.cpp:277
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 void AdvancePhase()=0
Use the next available virtual zone of the dialog progress bar.
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:135
void PrevMarker()
Definition: rc_item.cpp:689
void SelectMarker(const MARKER_BASE *aMarker)
Definition: rc_item.cpp:738
static RC_TREE_NODE * ToNode(wxDataViewItem aItem)
Definition: rc_item.h:236
void ValueChanged(RC_TREE_NODE *aNode)
Definition: rc_item.cpp:517
void Update(std::shared_ptr< RC_ITEMS_PROVIDER > aProvider, int aSeverities)
Definition: rc_item.cpp:364
void DeleteItems(bool aCurrentOnly, bool aIncludeExclusions, bool aDeep)
Deletes the current item or all items.
Definition: rc_item.cpp:572
void DeleteCurrentItem(bool aDeep)
Definition: rc_item.cpp:566
void CenterMarker(const MARKER_BASE *aMarker)
Definition: rc_item.cpp:751
static KIID ToUUID(wxDataViewItem aItem)
Definition: rc_item.cpp:220
void NextMarker()
Definition: rc_item.cpp:710
std::shared_ptr< RC_ITEM > m_RcItem
Definition: rc_item.h:221
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
Master controller class:
Definition: tool_manager.h:57
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:145
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.
A KICAD version of wxTextEntryDialog which supports the various improvements/work-arounds from DIALOG...
wxString GetValue() const
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:63
static std::vector< wxString > g_lastIgnored
Definition: dialog_drc.cpp:65
static int RPT_SEVERITY_ALL
Definition: dialog_drc.cpp:230
static int DEFAULT_SINGLE_COL_WIDTH
Definition: dialog_drc.cpp:60
static BOARD * g_lastDRCBoard
Definition: dialog_drc.cpp:62
static bool g_lastFootprintTestsRun
Definition: dialog_drc.cpp:64
#define DIALOG_DRC_WINDOW_NAME
Definition: dialog_drc.h:41
@ DRCE_UNCONNECTED_ITEMS
Definition: drc_item.h:39
@ DRCE_INVALID_OUTLINE
Definition: drc_item.h:68
@ DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG
Definition: drc_item.h:100
@ DRCE_MALFORMED_COURTYARD
Definition: drc_item.h:63
@ DRCE_FIRST
Definition: drc_item.h:38
@ DRCE_UNRESOLVED_VARIABLE
Definition: drc_item.h:82
@ DRCE_DUPLICATE_FOOTPRINT
Definition: drc_item.h:71
@ DRCE_EXTRA_FOOTPRINT
Definition: drc_item.h:72
@ DRCE_LAST
Definition: drc_item.h:102
@ DRCE_NET_CONFLICT
Definition: drc_item.h:73
@ DRCE_MISSING_FOOTPRINT
Definition: drc_item.h:70
@ DRCE_SCHEMATIC_PARITY_ISSUES
Definition: drc_item.h:74
#define _(s)
#define MALFORMED_F_COURTYARD
#define MALFORMED_B_COURTYARD
static int DEFAULT_SINGLE_COL_WIDTH
static const std::string ReportFileExtension
static const std::string JsonFileExtension
static wxString JsonFileWildcard()
static wxString ReportFileWildcard()
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ F_CrtYd
Definition: layer_ids.h:118
@ Edge_Cuts
Definition: layer_ids.h:114
@ B_CrtYd
Definition: layer_ids.h:117
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
This file contains miscellaneous commonly used macros and functions.
void ForceFocus(wxWindow *aWindow)
Pass the current focus to the window.
Definition: gtk/ui.cpp:67
T clamp(T min, T value, T max)
Definition: kicad_algo.h:205
see class PGM_BASE
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_EXCLUSION
@ RPT_SEVERITY_IGNORE
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:119
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:120
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition: typeinfo.h:107
@ 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.
static int RPT_SEVERITY_ALL