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