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>
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 + wxS( "&nbsp;&nbsp;" )
265 + wxS( "<a href='$CUSTOM_RULES'>" ) + _( "Show design rules." ) + wxT( "</a>" ) );
266 m_messages->Flush();
267
268 Raise();
269 return;
270 }
271
272 m_footprintTestsRun = false;
273 m_cancelled = false;
274
276 deleteAllMarkers( true );
277
278 std::vector<std::reference_wrapper<RC_ITEM>> violations = DRC_ITEM::GetItemsWithSeverities();
279 m_ignoredList->DeleteAllItems();
280
281 for( std::reference_wrapper<RC_ITEM>& item : violations )
282 {
283 if( bds().GetSeverity( item.get().GetErrorCode() ) == RPT_SEVERITY_IGNORE )
284 {
285 m_ignoredList->InsertItem( m_ignoredList->GetItemCount(),
286 wxT( " • " ) + item.get().GetErrorText() );
287 }
288 }
289
290 Raise();
291
292 m_runningResultsBook->ChangeSelection( 0 ); // Display the "Tests Running..." tab
293 m_messages->Clear();
294 wxYield(); // Allow time slice to refresh Messages
295
296 m_running = true;
297 m_sdbSizerCancel->SetLabel( _( "Cancel" ) );
298 m_sdbSizerOK->Enable( false );
299 m_DeleteCurrentMarkerButton->Enable( false );
300 m_DeleteAllMarkersButton->Enable( false );
301 m_saveReport->Enable( false );
302
303 {
304 wxBusyCursor dummy;
305 drcTool->RunTests( this, refillZones, reportAllTrackErrors, testFootprints );
306 }
307
308 if( m_cancelled )
309 m_messages->Report( _( "-------- DRC cancelled by user.<br><br>" ) );
310 else
311 m_messages->Report( _( "Done.<br><br>" ) );
312
313 Raise();
314 wxYield(); // Allow time slice to refresh Messages
315
316 m_running = false;
317 m_sdbSizerCancel->SetLabel( _( "Close" ) );
318 m_sdbSizerOK->Enable( true );
319 m_DeleteCurrentMarkerButton->Enable( true );
320 m_DeleteAllMarkersButton->Enable( true );
321 m_saveReport->Enable( true );
322
323 if( !m_cancelled )
324 {
325 wxMilliSleep( 500 );
326 m_runningResultsBook->ChangeSelection( 1 );
328 }
329
331}
332
333
335{
339
341}
342
343
344void DIALOG_DRC::OnDRCItemSelected( wxDataViewEvent& aEvent )
345{
346 BOARD* board = m_frame->GetBoard();
347 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
348
349 auto getActiveLayers =
350 []( BOARD_ITEM* aItem ) -> LSET
351 {
352 if( aItem->Type() == PCB_PAD_T )
353 {
354 PAD* pad = static_cast<PAD*>( aItem );
355 LSET layers;
356
357 for( int layer : aItem->GetLayerSet().Seq() )
358 {
359 if( pad->FlashLayer( layer ) )
360 layers.set( layer );
361 }
362
363 return layers;
364 }
365 else
366 {
367 return aItem->GetLayerSet();
368 }
369 };
370
371 if( !node )
372 {
373 // list is being freed; don't do anything with null ptrs
374
375 aEvent.Skip();
376 return;
377 }
378
380 {
381 // we already came from a cross-probe of the marker in the document; don't go
382 // around in circles
383
384 aEvent.Skip();
385 return;
386 }
387
388 std::shared_ptr<RC_ITEM> rc_item = node->m_RcItem;
389
390 if( rc_item->GetErrorCode() == DRCE_UNRESOLVED_VARIABLE
391 && rc_item->GetParent()->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
392 {
393 m_frame->FocusOnLocation( node->m_RcItem->GetParent()->GetPos() );
394
395 aEvent.Skip();
396 return;
397 }
398
399 const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
400 BOARD_ITEM* item = board->GetItem( itemID );
401
402 if( !item || item == DELETED_BOARD_ITEM::GetInstance() )
403 {
404 // nothing to highlight / focus on
405
406 aEvent.Skip();
407 return;
408 }
409
410 PCB_LAYER_ID principalLayer;
411 LSET violationLayers;
412 BOARD_ITEM* a = board->GetItem( rc_item->GetMainItemID() );
413 BOARD_ITEM* b = board->GetItem( rc_item->GetAuxItemID() );
414 BOARD_ITEM* c = board->GetItem( rc_item->GetAuxItem2ID() );
415 BOARD_ITEM* d = board->GetItem( rc_item->GetAuxItem3ID() );
416
417 if( rc_item->GetErrorCode() == DRCE_MALFORMED_COURTYARD )
418 {
419 if( a && ( a->GetFlags() & MALFORMED_B_COURTYARD ) > 0
420 && ( a->GetFlags() & MALFORMED_F_COURTYARD ) == 0 )
421 {
422 principalLayer = B_CrtYd;
423 }
424 else
425 {
426 principalLayer = F_CrtYd;
427 }
428 }
429 else if (rc_item->GetErrorCode() == DRCE_INVALID_OUTLINE )
430 {
431 principalLayer = Edge_Cuts;
432 }
433 else
434 {
435 principalLayer = UNDEFINED_LAYER;
436
437 if( a || b || c || d )
438 violationLayers = LSET::AllLayersMask();
439
440 // Try to initialize principalLayer to a valid layer. Note that some markers have
441 // a layer set to UNDEFINED_LAYER, so we may need to keep looking.
442
443 for( BOARD_ITEM* it: { a, b, c, d } )
444 {
445 if( !it )
446 continue;
447
448 LSET layersList = getActiveLayers( it );
449 violationLayers &= layersList;
450
451 if( principalLayer <= UNDEFINED_LAYER && layersList.count() )
452 principalLayer = layersList.Seq().front();
453 }
454 }
455
456 if( violationLayers.count() )
457 principalLayer = violationLayers.Seq().front();
458 else if( !(principalLayer <= UNDEFINED_LAYER ) )
459 violationLayers.set( principalLayer );
460
461 WINDOW_THAWER thawer( m_frame );
462
463 if( principalLayer > UNDEFINED_LAYER && ( violationLayers & board->GetVisibleLayers() ) == 0 )
464 m_frame->GetAppearancePanel()->SetLayerVisible( principalLayer, true );
465
466 if( principalLayer > UNDEFINED_LAYER && board->GetVisibleLayers().test( principalLayer ) )
467 m_frame->SetActiveLayer( principalLayer );
468
469 if( rc_item->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
470 {
473
474 if( item->Type() == PCB_ZONE_T )
475 {
476 m_frame->GetBoard()->GetConnectivity()->RunOnUnconnectedEdges(
477 [&]( CN_EDGE& edge )
478 {
479 if( edge.GetSourceNode()->Parent() == a
480 && edge.GetTargetNode()->Parent() == b )
481 {
482 if( item == a )
483 m_frame->FocusOnLocation( edge.GetSourcePos() );
484 else
485 m_frame->FocusOnLocation( edge.GetTargetPos() );
486
487 return false;
488 }
489
490 return true;
491 } );
492 }
493 else
494 {
495 m_frame->FocusOnItem( item, principalLayer );
496 }
497 }
498 else if( rc_item->GetErrorCode() == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG )
499 {
500 BOARD_CONNECTED_ITEM* track = dynamic_cast<PCB_TRACK*>( item );
501 std::vector<BOARD_ITEM*> items;
502
503 if( track )
504 {
505 int net = track->GetNetCode();
506
507 wxASSERT( net > 0 ); // Without a net how can it be a diff-pair?
508
509 for( const KIID& id : rc_item->GetIDs() )
510 {
511 auto* candidate = dynamic_cast<BOARD_CONNECTED_ITEM*>( board->GetItem( id ) );
512
513 if( candidate && candidate->GetNetCode() == net )
514 items.push_back( candidate );
515 }
516 }
517 else
518 {
519 items.push_back( item );
520 }
521
522 m_frame->FocusOnItems( items, principalLayer );
523 }
524 else
525 {
526 m_frame->FocusOnItem( item, principalLayer );
527 }
528
529 aEvent.Skip();
530}
531
532
533void DIALOG_DRC::OnDRCItemDClick( wxDataViewEvent& aEvent )
534{
535 if( aEvent.GetItem().IsOk() )
536 {
537 // turn control over to m_frame, hide this DIALOG_DRC window,
538 // no destruction so we can preserve listbox cursor
539 if( !IsModal() )
540 Show( false );
541 }
542
543 // Do not skip aEvent here: this is not useful, and Pcbnew crashes
544 // if skipped (at least on Windows)
545}
546
547
548void DIALOG_DRC::OnDRCItemRClick( wxDataViewEvent& aEvent )
549{
550 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
551
552 if( !node )
553 return;
554
555 std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
556 DRC_ITEM* drcItem = static_cast<DRC_ITEM*>( rcItem.get() );
557 std::shared_ptr<CONNECTIVITY_DATA> conn = m_currentBoard->GetConnectivity();
558 wxString listName;
559 wxMenu menu;
560 wxString msg;
561
562 switch( bds().m_DRCSeverities[ rcItem->GetErrorCode() ] )
563 {
564 case RPT_SEVERITY_ERROR: listName = _( "errors" ); break;
565 case RPT_SEVERITY_WARNING: listName = _( "warnings" ); break;
566 default: listName = _( "appropriate" ); break;
567 }
568
569 if( rcItem->GetParent()->IsExcluded() )
570 {
571 menu.Append( 1, _( "Remove exclusion for this violation" ),
572 wxString::Format( _( "It will be placed back in the %s list" ), listName ) );
573
574 if( drcItem->GetViolatingRule() && !drcItem->GetViolatingRule()->m_Implicit )
575 {
576 msg.Printf( _( "Remove all exclusions for violations of rule '%s'" ),
577 drcItem->GetViolatingRule()->m_Name );
578 menu.Append( 11, msg );
579 }
580 }
581 else
582 {
583 menu.Append( 2, _( "Exclude this violation" ),
584 wxString::Format( _( "It will be excluded from the %s list" ), listName ) );
585
586 if( drcItem->GetViolatingRule() && !drcItem->GetViolatingRule()->m_Implicit )
587 {
588 msg.Printf( _( "Exclude all violations of rule '%s'" ),
589 drcItem->GetViolatingRule()->m_Name );
590 menu.Append( 21, msg );
591 }
592 }
593
594 if( rcItem->GetErrorCode() == DRCE_CLEARANCE
595 || rcItem->GetErrorCode() == DRCE_EDGE_CLEARANCE
596 || rcItem->GetErrorCode() == DRCE_HOLE_CLEARANCE
597 || rcItem->GetErrorCode() == DRCE_DRILLED_HOLES_TOO_CLOSE )
598 {
599 menu.Append( 3, _( "Run Inspect > Clearance Resolution" ) );
600 }
601 else if( rcItem->GetErrorCode() == DRCE_TEXT_HEIGHT
602 || rcItem->GetErrorCode() == DRCE_TEXT_THICKNESS
603 || rcItem->GetErrorCode() == DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG
604 || rcItem->GetErrorCode() == DRCE_TRACK_WIDTH
605 || rcItem->GetErrorCode() == DRCE_VIA_DIAMETER
606 || rcItem->GetErrorCode() == DRCE_ANNULAR_WIDTH
607 || rcItem->GetErrorCode() == DRCE_DRILL_OUT_OF_RANGE
608 || rcItem->GetErrorCode() == DRCE_MICROVIA_DRILL_OUT_OF_RANGE
609 || rcItem->GetErrorCode() == DRCE_CONNECTION_WIDTH
610 || rcItem->GetErrorCode() == DRCE_ASSERTION_FAILURE )
611 {
612 menu.Append( 3, _( "Run Inspect > Constraints Resolution" ) );
613 }
614 else if( rcItem->GetErrorCode() == DRCE_LIB_FOOTPRINT_MISMATCH )
615 {
616 menu.Append( 3, _( "Run Inspect > Diff Footprint with Library" ) );
617 }
618
619 menu.AppendSeparator();
620
621 if( bds().m_DRCSeverities[ rcItem->GetErrorCode() ] == RPT_SEVERITY_WARNING )
622 {
623 msg.Printf( _( "Change severity to Error for all '%s' violations" ),
624 rcItem->GetErrorText(),
625 _( "Violation severities can also be edited in the Board Setup... dialog" ) );
626 menu.Append( 4, msg );
627 }
628 else
629 {
630 msg.Printf( _( "Change severity to Warning for all '%s' violations" ),
631 rcItem->GetErrorText(),
632 _( "Violation severities can also be edited in the Board Setup... dialog" ) );
633 menu.Append( 5, msg );
634 }
635
636 msg.Printf( _( "Ignore all '%s' violations" ),
637 rcItem->GetErrorText(),
638 _( "Violations will not be checked or reported" ) );
639 menu.Append( 6, msg );
640
641 menu.AppendSeparator();
642
643 menu.Append( 7, _( "Edit violation severities..." ), _( "Open the Board Setup... dialog" ) );
644
645 bool modified = false;
646
647 switch( GetPopupMenuSelectionFromUser( menu ) )
648 {
649 case 1:
650 {
651 PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( rcItem->GetParent() );
652
653 if( marker )
654 {
655 marker->SetExcluded( false );
656
657 if( rcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
658 {
661 }
662 else
663 {
664 m_frame->GetCanvas()->GetView()->Update( marker );
665 }
666
667 // Update view
668 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
669 modified = true;
670 }
671
672 break;
673 }
674
675 case 2:
676 {
677 PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( rcItem->GetParent() );
678
679 if( marker )
680 {
681 marker->SetExcluded( true );
682
683 if( rcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
684 {
687 }
688 else
689 {
690 m_frame->GetCanvas()->GetView()->Update( marker );
691 }
692
693 // Update view
695 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
696 else
697 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->DeleteCurrentItem( false );
698
699 modified = true;
700 }
701
702 break;
703 }
704
705 case 11:
706 {
707 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
708 {
709 DRC_ITEM* candidateDrcItem = static_cast<DRC_ITEM*>( marker->GetRCItem().get() );
710
711 if( candidateDrcItem->GetViolatingRule() == drcItem->GetViolatingRule() )
712 marker->SetExcluded( false );
713 }
714
715 // Rebuild model and view
716 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
717 modified = true;
718 break;
719 }
720
721 case 21:
722 {
723 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
724 {
725 DRC_ITEM* candidateDrcItem = static_cast<DRC_ITEM*>( marker->GetRCItem().get() );
726
727 if( candidateDrcItem->GetViolatingRule() == drcItem->GetViolatingRule() )
728 marker->SetExcluded( true );
729 }
730
731 // Rebuild model and view
732 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
733 modified = true;
734 break;
735 }
736
737 case 3:
738 {
739 TOOL_MANAGER* toolMgr = m_frame->GetToolManager();
740 BOARD_INSPECTION_TOOL* inspectionTool = toolMgr->GetTool<BOARD_INSPECTION_TOOL>();
741
742 inspectionTool->InspectDRCError( node->m_RcItem );
743 break;
744 }
745
746 case 4:
747 bds().m_DRCSeverities[ rcItem->GetErrorCode() ] = RPT_SEVERITY_ERROR;
748
749 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
750 {
751 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
752 m_frame->GetCanvas()->GetView()->Update( marker );
753 }
754
755 // Rebuild model and view
756 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
757 modified = true;
758 break;
759
760 case 5:
761 bds().m_DRCSeverities[ rcItem->GetErrorCode() ] = RPT_SEVERITY_WARNING;
762
763 for( PCB_MARKER* marker : m_frame->GetBoard()->Markers() )
764 {
765 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
766 m_frame->GetCanvas()->GetView()->Update( marker );
767 }
768
769 // Rebuild model and view
770 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
771 modified = true;
772 break;
773
774 case 6:
775 {
776 bds().m_DRCSeverities[ rcItem->GetErrorCode() ] = RPT_SEVERITY_IGNORE;
777
778 m_ignoredList->InsertItem( m_ignoredList->GetItemCount(),
779 wxT( " • " ) + rcItem->GetErrorText() );
780
781 std::vector<PCB_MARKER*>& markers = m_frame->GetBoard()->Markers();
782
783 for( unsigned i = 0; i < markers.size(); )
784 {
785 if( markers[i]->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
786 {
787 m_frame->GetCanvas()->GetView()->Remove( markers.at( i ) );
788 markers.erase( markers.begin() + i );
789 }
790 else
791 {
792 ++i;
793 }
794 }
795
796 if( rcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
798
799 // Rebuild model and view
800 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markersProvider, m_severities );
801 modified = true;
802 break;
803 }
804
805 case 7:
806 m_frame->ShowBoardSetupDialog( _( "Violation Severity" ) );
807 break;
808 }
809
810 if( modified )
811 {
814 m_frame->OnModify();
815 }
816}
817
818
819void DIALOG_DRC::OnEditViolationSeverities( wxHyperlinkEvent& aEvent )
820{
821 m_frame->ShowBoardSetupDialog( _( "Violation Severity" ) );
822}
823
824
825void DIALOG_DRC::OnSeverity( wxCommandEvent& aEvent )
826{
827 int flag = 0;
828
829 if( aEvent.GetEventObject() == m_showAll )
831 else if( aEvent.GetEventObject() == m_showErrors )
833 else if( aEvent.GetEventObject() == m_showWarnings )
835 else if( aEvent.GetEventObject() == m_showExclusions )
837
838 if( aEvent.IsChecked() )
840 else if( aEvent.GetEventObject() == m_showAll )
842 else
843 m_severities &= ~flag;
844
846 UpdateData();
847}
848
849
850void DIALOG_DRC::OnSaveReport( wxCommandEvent& aEvent )
851{
852 wxFileName fn( "DRC." + ReportFileExtension );
853
854 wxFileDialog dlg( this, _( "Save Report to File" ), Prj().GetProjectPath(), fn.GetFullName(),
855 ReportFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
856
857 if( dlg.ShowModal() != wxID_OK )
858 return;
859
860 fn = dlg.GetPath();
861
862 if( fn.GetExt().IsEmpty() )
863 fn.SetExt( ReportFileExtension );
864
865 if( !fn.IsAbsolute() )
866 {
867 wxString prj_path = Prj().GetProjectPath();
868 fn.MakeAbsolute( prj_path );
869 }
870
871 if( writeReport( fn.GetFullPath() ) )
872 {
873 m_messages->Report( wxString::Format( _( "Report file '%s' created<br>" ),
874 fn.GetFullPath() ) );
875 }
876 else
877 {
878 DisplayError( this, wxString::Format( _( "Failed to create file '%s'." ),
879 fn.GetFullPath() ) );
880 }
881}
882
883
884void DIALOG_DRC::OnClose( wxCloseEvent& aEvent )
885{
886 if( m_running )
887 aEvent.Veto();
888
889 wxCommandEvent dummy;
890
892}
893
894
895void DIALOG_DRC::OnCancelClick( wxCommandEvent& aEvent )
896{
897 if( m_running )
898 {
899 m_cancelled = true;
900 return;
901 }
902
903 m_frame->FocusOnItem( nullptr );
904
905 SetReturnCode( wxID_CANCEL );
906
907 // The dialog can be modal or not modal.
908 // Leave the DRC caller destroy (or not) the dialog
910 drcTool->DestroyDRCDialog();
911}
912
913
914void DIALOG_DRC::OnChangingNotebookPage( wxNotebookEvent& aEvent )
915{
916 // Shouldn't be necessary, but is on at least OSX
917 if( aEvent.GetSelection() >= 0 )
918 m_Notebook->ChangeSelection( (unsigned) aEvent.GetSelection() );
919
920 m_markerDataView->UnselectAll();
921 m_unconnectedDataView->UnselectAll();
922 m_footprintsDataView->UnselectAll();
923}
924
925
927{
928 WINDOW_THAWER thawer( m_frame );
929
931}
932
933
935{
936 if( m_Notebook->IsShown() )
937 {
938 switch( m_Notebook->GetSelection() )
939 {
940 case 0: m_markersTreeModel->PrevMarker(); break;
941 case 1: m_unconnectedTreeModel->PrevMarker(); break;
942 case 2: m_fpWarningsTreeModel->PrevMarker(); break;
943 case 3: break;
944 }
945 }
946}
947
948
950{
951 if( m_Notebook->IsShown() )
952 {
953 switch( m_Notebook->GetSelection() )
954 {
955 case 0: m_markersTreeModel->NextMarker(); break;
956 case 1: m_unconnectedTreeModel->NextMarker(); break;
957 case 2: m_fpWarningsTreeModel->NextMarker(); break;
958 case 3: break;
959 }
960 }
961}
962
963
965{
966 if( m_Notebook->IsShown() )
967 {
968 m_Notebook->SetSelection( 0 );
970
971 // wxWidgets on some platforms fails to correctly ensure that a selected item is
972 // visible, so we have to do it in a separate idle event.
973 m_centerMarkerOnIdle = aMarker;
974 Bind( wxEVT_IDLE, &DIALOG_DRC::centerMarkerIdleHandler, this );
975 }
976}
977
978
979void DIALOG_DRC::centerMarkerIdleHandler( wxIdleEvent& aEvent )
980{
982 m_centerMarkerOnIdle = nullptr;
983 Unbind( wxEVT_IDLE, &DIALOG_DRC::centerMarkerIdleHandler, this );
984}
985
986
988{
989 if( !m_Notebook->IsShown() || m_Notebook->GetSelection() != 0 )
990 return;
991
992 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( m_markerDataView->GetCurrentItem() );
993 PCB_MARKER* marker = dynamic_cast<PCB_MARKER*>( node->m_RcItem->GetParent() );
994
995 if( marker && marker->GetSeverity() != RPT_SEVERITY_EXCLUSION )
996 {
997 marker->SetExcluded( true );
998 m_frame->GetCanvas()->GetView()->Update( marker );
999
1000 // Update view
1003 else
1005
1007 refreshEditor();
1008 m_frame->OnModify();
1009 }
1010}
1011
1012
1013void DIALOG_DRC::deleteAllMarkers( bool aIncludeExclusions )
1014{
1015 // Clear current selection list to avoid selection of deleted items
1017
1018 m_markersTreeModel->DeleteItems( false, aIncludeExclusions, false );
1019 m_unconnectedTreeModel->DeleteItems( false, aIncludeExclusions, false );
1020 m_fpWarningsTreeModel->DeleteItems( false, aIncludeExclusions, false );
1021
1022 m_frame->GetBoard()->DeleteMARKERs( true, aIncludeExclusions );
1023}
1024
1025
1026bool DIALOG_DRC::writeReport( const wxString& aFullFileName )
1027{
1028 FILE* fp = wxFopen( aFullFileName, wxT( "w" ) );
1029
1030 if( fp == nullptr )
1031 return false;
1032
1033 std::map<KIID, EDA_ITEM*> itemMap;
1034 m_frame->GetBoard()->FillItemMap( itemMap );
1035
1037 UNITS_PROVIDER unitsProvider( pcbIUScale, GetUserUnits() );
1038 int count;
1039
1040 fprintf( fp, "** Drc report for %s **\n", TO_UTF8( m_frame->GetBoard()->GetFileName() ) );
1041
1042 wxDateTime now = wxDateTime::Now();
1043
1044 fprintf( fp, "** Created on %s **\n", TO_UTF8( now.Format( wxT( "%F %T" ) ) ) );
1045
1046 count = m_markersProvider->GetCount();
1047
1048 fprintf( fp, "\n** Found %d DRC violations **\n", count );
1049
1050 for( int i = 0; i < count; ++i )
1051 {
1052 const std::shared_ptr<RC_ITEM>& item = m_markersProvider->GetItem( i );
1053 SEVERITY severity = item->GetParent()->GetSeverity();
1054
1055 if( severity == RPT_SEVERITY_EXCLUSION )
1056 severity = bds.GetSeverity( item->GetErrorCode() );
1057
1058 fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
1059 }
1060
1061 count = m_ratsnestProvider->GetCount();
1062
1063 fprintf( fp, "\n** Found %d unconnected pads **\n", count );
1064
1065 for( int i = 0; i < count; ++i )
1066 {
1067 const std::shared_ptr<RC_ITEM>& item = m_ratsnestProvider->GetItem( i );
1068 SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
1069
1070 fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
1071 }
1072
1073 count = m_fpWarningsProvider->GetCount();
1074
1075 fprintf( fp, "\n** Found %d Footprint errors **\n", count );
1076
1077 for( int i = 0; i < count; ++i )
1078 {
1079 const std::shared_ptr<RC_ITEM>& item = m_fpWarningsProvider->GetItem( i );
1080 SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
1081
1082 fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
1083 }
1084
1085
1086 fprintf( fp, "\n** End of Report **\n" );
1087
1088 fclose( fp );
1089
1090 return true;
1091}
1092
1093
1094void DIALOG_DRC::OnDeleteOneClick( wxCommandEvent& aEvent )
1095{
1096 if( m_Notebook->GetSelection() == 0 )
1097 {
1098 // Clear the selection. It may be the selected DRC marker.
1100
1102
1103 // redraw the pcb
1104 refreshEditor();
1105 }
1106 else if( m_Notebook->GetSelection() == 1 )
1107 {
1109 }
1110 else if( m_Notebook->GetSelection() == 2 )
1111 {
1113 }
1114
1116}
1117
1118
1119void DIALOG_DRC::OnDeleteAllClick( wxCommandEvent& aEvent )
1120{
1121 static bool s_includeExclusions = false;
1122
1123 int numExcluded = 0;
1124
1125 if( m_markersProvider )
1126 numExcluded += m_markersProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1127
1128 if( m_ratsnestProvider )
1129 numExcluded += m_ratsnestProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1130
1132 numExcluded += m_fpWarningsProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1133
1134 if( numExcluded > 0 )
1135 {
1136 wxRichMessageDialog dlg( this, _( "Do you wish to delete excluded markers as well?" ),
1137 _( "Delete All Markers" ),
1138 wxOK | wxCANCEL | wxCENTER | wxICON_QUESTION );
1139 dlg.ShowCheckBox( _( "Delete exclusions" ), s_includeExclusions );
1140
1141 int ret = dlg.ShowModal();
1142
1143 if( ret == wxID_CANCEL )
1144 return;
1145 else
1146 s_includeExclusions = dlg.IsCheckBoxChecked();
1147 }
1148
1149 deleteAllMarkers( s_includeExclusions );
1150
1151 refreshEditor();
1153}
1154
1155
1157{
1160 DRC_ENGINE* drcEngine = drcTool->GetDRCEngine().get();
1161
1162 // Collect counts:
1163
1164 int numMarkers = 0;
1165 int numUnconnected = 0;
1166 int numFootprints = 0;
1167
1168 int numErrors = 0;
1169 int numWarnings = 0;
1170 int numExcluded = 0;
1171
1172 if( m_markersProvider )
1173 {
1174 numMarkers += m_markersProvider->GetCount();
1175 numErrors += m_markersProvider->GetCount( RPT_SEVERITY_ERROR );
1176 numWarnings += m_markersProvider->GetCount( RPT_SEVERITY_WARNING );
1177 numExcluded += m_markersProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1178 }
1179
1180 if( m_ratsnestProvider )
1181 {
1182 numUnconnected += m_ratsnestProvider->GetCount();
1183 numErrors += m_ratsnestProvider->GetCount( RPT_SEVERITY_ERROR );
1184 numWarnings += m_ratsnestProvider->GetCount( RPT_SEVERITY_WARNING );
1185 numExcluded += m_ratsnestProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1186 }
1187
1189 {
1190 numFootprints += m_fpWarningsProvider->GetCount();
1191 numErrors += m_fpWarningsProvider->GetCount( RPT_SEVERITY_ERROR );
1192 numWarnings += m_fpWarningsProvider->GetCount( RPT_SEVERITY_WARNING );
1193 numExcluded += m_fpWarningsProvider->GetCount( RPT_SEVERITY_EXCLUSION );
1194 }
1195
1196 bool showErrors = m_showErrors->GetValue();
1197 bool showWarnings = m_showWarnings->GetValue();
1198 bool errorsOverflowed = false;
1199 bool warningsOverflowed = false;
1200 bool markersOverflowed = false;
1201 bool unconnectedOverflowed = false;
1202 bool footprintsOverflowed = false;
1203
1204 for( int ii = DRCE_FIRST; ii < DRCE_LAST; ++ii )
1205 {
1206 if( drcEngine->IsErrorLimitExceeded( ii ) )
1207 {
1208 if( bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1209 errorsOverflowed = true;
1210 else if( bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1211 warningsOverflowed = true;
1212
1213 if( ii == DRCE_UNCONNECTED_ITEMS )
1214 {
1215 if( showWarnings && bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1216 unconnectedOverflowed = true;
1217 else if( showErrors && bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1218 unconnectedOverflowed = true;
1219 }
1220 else if( ii == DRCE_MISSING_FOOTPRINT
1222 || ii == DRCE_EXTRA_FOOTPRINT
1223 || ii == DRCE_NET_CONFLICT )
1224 {
1225 if( showWarnings && bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1226 footprintsOverflowed = true;
1227 else if( showErrors && bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1228 footprintsOverflowed = true;
1229 }
1230 else
1231 {
1232 if( showWarnings && bds.GetSeverity( ii ) == RPT_SEVERITY_WARNING )
1233 markersOverflowed = true;
1234 else if( showErrors && bds.GetSeverity( ii ) == RPT_SEVERITY_ERROR )
1235 markersOverflowed = true;
1236 }
1237 }
1238 }
1239
1240 wxString msg;
1241 wxString num;
1242
1243 // Update tab headers:
1244
1245 if( m_drcRun )
1246 {
1247 num.Printf( markersOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numMarkers );
1248 msg.Printf( m_markersTitleTemplate, num );
1249 }
1250 else
1251 {
1253 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1254 }
1255
1256 m_Notebook->SetPageText( 0, msg );
1257
1258 if( m_drcRun )
1259 {
1260 num.Printf( unconnectedOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numUnconnected );
1261 msg.sprintf( m_unconnectedTitleTemplate, num );
1262 }
1263 else
1264 {
1266 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1267 }
1268
1269 m_Notebook->SetPageText( 1, msg );
1270
1272 {
1273 num.Printf( footprintsOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numFootprints );
1274 msg.sprintf( m_footprintsTitleTemplate, num );
1275 }
1276 else if( m_drcRun )
1277 {
1279 msg.Replace( wxT( "%s" ), _( "not run" ) );
1280 }
1281 else
1282 {
1284 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1285 }
1286
1287 m_Notebook->SetPageText( 2, msg );
1288
1289 if( m_drcRun )
1290 {
1291 num.Printf( wxT( "%d" ), m_ignoredList->GetItemCount() );
1292 msg.sprintf( m_ignoredTitleTemplate, num );
1293 }
1294 else
1295 {
1297 msg.Replace( wxT( "(%s)" ), wxEmptyString );
1298 }
1299
1300 m_Notebook->SetPageText( 3, msg );
1301
1302 // Update badges:
1303
1304 if( !m_drcRun && numErrors == 0 )
1305 numErrors = -1;
1306
1307 if( !m_drcRun && numWarnings == 0 )
1308 numWarnings = -1;
1309
1310 m_errorsBadge->SetMaximumNumber( numErrors );
1311 m_errorsBadge->UpdateNumber( errorsOverflowed ? numErrors + 1 : numErrors,
1313
1314 m_warningsBadge->SetMaximumNumber( numWarnings );
1315 m_warningsBadge->UpdateNumber( warningsOverflowed ? numWarnings + 1 : numWarnings,
1317
1318 m_exclusionsBadge->SetMaximumNumber( numExcluded );
1320}
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:71
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:270
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:625
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:1069
MARKERS & Markers()
Definition: board.h:321
const wxString & GetFileName() const
Definition: board.h:307
void FillItemMap(std::map< KIID, EDA_ITEM * > &aMap)
Definition: board.cpp:1148
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:728
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
Definition: board.cpp:275
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:1028
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:432
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:384
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:979
bool updateUI() override
Definition: dialog_drc.cpp:194
void OnDRCItemSelected(wxDataViewEvent &aEvent) override
Definition: dialog_drc.cpp:344
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:334
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:819
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:964
void OnClose(wxCloseEvent &event) override
Definition: dialog_drc.cpp:884
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:548
void PrevMarker()
Definition: dialog_drc.cpp:934
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:533
void deleteAllMarkers(bool aIncludeExclusions)
void updateDisplayedCounts()
RC_TREE_MODEL * m_unconnectedTreeModel
Definition: dialog_drc.h:136
void refreshEditor()
Definition: dialog_drc.cpp:926
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:825
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:895
void NextMarker()
Definition: dialog_drc.cpp:949
void OnActivateDlg(wxActivateEvent &aEvent) override
Definition: dialog_drc.cpp:177
void OnChangingNotebookPage(wxNotebookEvent &aEvent) override
Definition: dialog_drc.cpp:914
void OnSaveReport(wxCommandEvent &aEvent) override
Definition: dialog_drc.cpp:850
void ExcludeMarker()
Definition: dialog_drc.cpp:987
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
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: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:536
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 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:126
void PrevMarker()
Definition: rc_item.cpp:548
void SelectMarker(const MARKER_BASE *aMarker)
Definition: rc_item.cpp:597
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:459
void DeleteCurrentItem(bool aDeep)
Definition: rc_item.cpp:453
void CenterMarker(const MARKER_BASE *aMarker)
Definition: rc_item.cpp:610
static KIID ToUUID(wxDataViewItem aItem)
Definition: rc_item.cpp:149
void NextMarker()
Definition: rc_item.cpp:569
void ValueChanged(const RC_TREE_NODE *aNode)
Definition: rc_item.cpp:436
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:283
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_ASSERTION_FAILURE
Definition: drc_item.h:82
@ DRCE_EXTRA_FOOTPRINT
Definition: drc_item.h:72
@ DRCE_LAST
Definition: drc_item.h:101
@ DRCE_LIB_FOOTPRINT_MISMATCH
Definition: drc_item.h:77
@ 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
static int DEFAULT_SINGLE_COL_WIDTH
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
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:103
@ 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