KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_erc.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) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2012 Wayne Stambaugh <[email protected]>
6 * Copyright The 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 <advanced_config.h>
27#include <gestfich.h>
28#include <sch_screen.h>
29#include <sch_edit_frame.h>
30#include <schematic.h>
31#include <project.h>
32#include <kiface_base.h>
33#include <reporter.h>
35#include <sch_marker.h>
36#include <connection_graph.h>
37#include <tools/ee_actions.h>
39#include <dialog_erc.h>
40#include <erc/erc.h>
41#include <erc/erc_report.h>
42#include <id.h>
43#include <confirm.h>
44#include <common.h>
47#include <erc/erc_item.h>
48#include <eeschema_settings.h>
49#include <string_utils.h>
50#include <kiplatform/ui.h>
51
52#include <wx/ffile.h>
53#include <wx/filedlg.h>
54#include <wx/hyperlink.h>
55#include <wx/msgdlg.h>
56
57
58wxDEFINE_EVENT( EDA_EVT_CLOSE_ERC_DIALOG, wxCommandEvent );
59
60
61// wxWidgets spends *far* too long calculating column widths (most of it, believe it or
62// not, in repeatedly creating/destroying a wxDC to do the measurement in).
63// Use default column widths instead.
64static int DEFAULT_SINGLE_COL_WIDTH = 660;
65
66
67static SCHEMATIC* g_lastERCSchematic = nullptr;
68static bool g_lastERCRun = false;
69
70static std::vector<std::pair<wxString, int>> g_lastERCIgnored;
71
72
74 DIALOG_ERC_BASE( parent ),
76 m_parent( parent ),
77 m_markerTreeModel( nullptr ),
78 m_running( false ),
79 m_ercRun( false ),
80 m_centerMarkerOnIdle( nullptr ),
81 m_severities( 0 )
82{
83 m_currentSchematic = &parent->Schematic();
84
85 SetName( DIALOG_ERC_WINDOW_NAME ); // Set a window name to be able to find it
87
88 EESCHEMA_SETTINGS* settings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
90
92
93 m_markerProvider = std::make_shared<SHEETLIST_ERC_ITEMS_PROVIDER>( &m_parent->Schematic() );
94
96 m_markerDataView->AssociateModel( m_markerTreeModel );
98
99 m_ignoredList->InsertColumn( 0, wxEmptyString, wxLIST_FORMAT_LEFT, DEFAULT_SINGLE_COL_WIDTH );
100
102 {
104
105 for( const auto& [ str, code ] : g_lastERCIgnored )
106 {
107 wxListItem listItem;
108 listItem.SetId( m_ignoredList->GetItemCount() );
109 listItem.SetText( str );
110 listItem.SetData( code );
111
112 m_ignoredList->InsertItem( listItem );
113 }
114 }
115
116 m_notebook->SetSelection( 0 );
117
118 SetupStandardButtons( { { wxID_OK, _( "Run ERC" ) },
119 { wxID_CANCEL, _( "Close" ) } } );
120
121 m_violationsTitleTemplate = m_notebook->GetPageText( 0 );
122 m_ignoredTitleTemplate = m_notebook->GetPageText( 1 );
123
127
129
130 Layout();
131
132 SetFocus();
133
136
137 // Now all widgets have the size fixed, call FinishDialogSettings
139}
140
141
143{
146
147 g_lastERCIgnored.clear();
148
149 for( int ii = 0; ii < m_ignoredList->GetItemCount(); ++ii )
150 {
151 g_lastERCIgnored.push_back( { m_ignoredList->GetItemText( ii ),
152 m_ignoredList->GetItemData( ii ) } );
153 }
154
155 EESCHEMA_SETTINGS* settings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
156 wxASSERT( settings );
157
158 if( settings )
160
161 m_markerTreeModel->DecRef();
162}
163
164
166{
167 if( m_parent->CheckAnnotate( []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* )
168 { } ) )
169 {
170 if( !m_infoBar->IsShownOnScreen() )
171 {
172 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( m_infoBar, wxID_ANY,
173 _( "Show Annotation dialog" ),
174 wxEmptyString );
175
176 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
177 [&]( wxHyperlinkEvent& aEvent )
178 {
179 wxHtmlLinkEvent htmlEvent( aEvent.GetId(),
180 wxHtmlLinkInfo( aEvent.GetURL() ) );
181 OnLinkClicked( htmlEvent );
182 } ) );
183
185 m_infoBar->AddButton( button );
186 m_infoBar->ShowMessage( _( "Schematic is not fully annotated. "
187 "ERC results will be incomplete." ) );
188 }
189 }
190 else
191 {
192 if( m_infoBar->IsShownOnScreen() )
193 {
195 m_infoBar->Hide();
196 }
197 }
198}
199
200
202{
203 // If ERC checks ever get slow enough we'll want a progress indicator...
204 //
205 // double cur = (double) m_progress.load() / m_maxProgress;
206 // cur = std::max( 0.0, std::min( cur, 1.0 ) );
207 //
208 // m_gauge->SetValue( KiROUND( cur * 1000.0 ) );
209 // wxSafeYield( this );
210
211 return !m_cancelled;
212}
213
214
215void DIALOG_ERC::AdvancePhase( const wxString& aMessage )
216{
217 // Will also call Report( aMessage ):
219 SetCurrentProgress( 0.0 );
220}
221
222
223void DIALOG_ERC::Report( const wxString& aMessage )
224{
225 m_messages->Report( aMessage );
226}
227
228
230{
231 int numErrors = 0;
232 int numWarnings = 0;
233 int numExcluded = 0;
234
235 int numMarkers = 0;
236
237 if( m_markerProvider )
238 {
239 numMarkers += m_markerProvider->GetCount();
240 numErrors += m_markerProvider->GetCount( RPT_SEVERITY_ERROR );
241 numWarnings += m_markerProvider->GetCount( RPT_SEVERITY_WARNING );
242 numExcluded += m_markerProvider->GetCount( RPT_SEVERITY_EXCLUSION );
243 }
244
245 bool markersOverflowed = false;
246
247 // We don't currently have a limit on ERC violations, so the above is always false.
248
249 wxString num;
250 wxString msg;
251
252 if( m_ercRun )
253 {
254 num.Printf( markersOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numMarkers );
255 msg.Printf( m_violationsTitleTemplate, num );
256 }
257 else
258 {
260 msg.Replace( wxT( "(%s)" ), wxEmptyString );
261 }
262
263 m_notebook->SetPageText( 0, msg );
264
265 if( m_ercRun )
266 {
267 num.Printf( wxT( "%d" ), m_ignoredList->GetItemCount() );
268 msg.sprintf( m_ignoredTitleTemplate, num );
269 }
270 else
271 {
273 msg.Replace( wxT( "(%s)" ), wxEmptyString );
274 }
275
276 m_notebook->SetPageText( 1, msg );
277
278 if( !m_ercRun && numErrors == 0 )
279 numErrors = -1;
280
281 if( !m_ercRun && numWarnings == 0 )
282 numWarnings = -1;
283
287}
288
289
290void DIALOG_ERC::OnDeleteOneClick( wxCommandEvent& aEvent )
291{
292 if( m_notebook->GetSelection() == 0 )
293 {
294 // Clear the selection. It may be the selected ERC marker.
296
298
299 // redraw the schematic
301 }
302
304}
305
306
307void DIALOG_ERC::OnDeleteAllClick( wxCommandEvent& event )
308{
309 bool includeExclusions = false;
310 int numExcluded = 0;
311
312 if( m_markerProvider )
313 numExcluded += m_markerProvider->GetCount( RPT_SEVERITY_EXCLUSION );
314
315 if( numExcluded > 0 )
316 {
317 wxMessageDialog dlg( this, _( "Delete exclusions too?" ), _( "Delete All Markers" ),
318 wxYES_NO | wxCANCEL | wxCENTER | wxICON_QUESTION );
319 dlg.SetYesNoLabels( _( "Errors and Warnings Only" ),
320 _( "Errors, Warnings and Exclusions" ) );
321
322 int ret = dlg.ShowModal();
323
324 if( ret == wxID_CANCEL )
325 return;
326 else if( ret == wxID_NO )
327 includeExclusions = true;
328 }
329
330 deleteAllMarkers( includeExclusions );
331
332 // redraw the schematic
335}
336
337
338void DIALOG_ERC::OnCancelClick( wxCommandEvent& aEvent )
339{
340 if( m_running )
341 {
342 m_cancelled = true;
343 return;
344 }
345
346 m_parent->FocusOnItem( nullptr );
347
348 aEvent.Skip();
349}
350
351
352void DIALOG_ERC::OnCloseErcDialog( wxCloseEvent& aEvent )
353{
354 m_parent->FocusOnItem( nullptr );
355
356 // Dialog is mode-less so let the parent know that it needs to be destroyed.
357 if( !IsModal() && !IsQuasiModal() )
358 {
359 wxCommandEvent* evt = new wxCommandEvent( EDA_EVT_CLOSE_ERC_DIALOG, wxID_ANY );
360
361 wxWindow* parent = GetParent();
362
363 if( parent )
364 wxQueueEvent( parent, evt );
365 }
366
367 aEvent.Skip();
368}
369
370
372
373
375{
380}
381
382
383void DIALOG_ERC::OnLinkClicked( wxHtmlLinkEvent& event )
384{
386}
387
388
389void DIALOG_ERC::OnRunERCClick( wxCommandEvent& event )
390{
391 wxBusyCursor busy;
392
393 SCHEMATIC* sch = &m_parent->Schematic();
394
396
397 sch->RecordERCExclusions();
398 deleteAllMarkers( true );
399
400 std::vector<std::reference_wrapper<RC_ITEM>> violations = ERC_ITEM::GetItemsWithSeverities();
401 m_ignoredList->DeleteAllItems();
402
403 for( std::reference_wrapper<RC_ITEM>& item : violations )
404 {
405 if( sch->ErcSettings().GetSeverity( item.get().GetErrorCode() ) == RPT_SEVERITY_IGNORE )
406 {
407 wxListItem listItem;
408 listItem.SetId( m_ignoredList->GetItemCount() );
409 listItem.SetText( wxT( " • " ) + item.get().GetErrorText() );
410 listItem.SetData( item.get().GetErrorCode() );
411
412 m_ignoredList->InsertItem( listItem );
413 }
414 }
415
416 m_ignoredList->SetColumnWidth( 0, m_ignoredList->GetParent()->GetClientSize().x - 20 );
417
418 m_cancelled = false;
419 Raise();
420
421 m_runningResultsBook->ChangeSelection( 0 ); // Display the "Tests Running..." tab
422 m_messages->Clear();
423 wxYield(); // Allow time slice to refresh Messages
424
425 m_running = true;
426 m_sdbSizer1Cancel->SetLabel( _( "Cancel" ) );
427 m_sdbSizer1OK->Enable( false );
428 m_deleteOneMarker->Enable( false );
429 m_deleteAllMarkers->Enable( false );
430 m_saveReport->Enable( false );
431
432 int itemsNotAnnotated = m_parent->CheckAnnotate(
433 []( ERCE_T aType, const wxString& aMsg, SCH_REFERENCE* aItemA, SCH_REFERENCE* aItemB )
434 {
435 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aType );
436 ercItem->SetErrorMessage( aMsg );
437
438 if( aItemB )
439 ercItem->SetItems( aItemA->GetSymbol(), aItemB->GetSymbol() );
440 else
441 ercItem->SetItems( aItemA->GetSymbol() );
442
443 SCH_MARKER* marker = new SCH_MARKER( ercItem, aItemA->GetSymbol()->GetPosition() );
444 aItemA->GetSheetPath().LastScreen()->Append( marker );
445 } );
446
447 testErc();
448
449 if( itemsNotAnnotated )
450 m_messages->ReportHead( wxString::Format( _( "%d symbol(s) require annotation.<br><br>" ),
451 itemsNotAnnotated ), RPT_SEVERITY_INFO );
452
453 if( m_cancelled )
454 // @spellingerror
455 m_messages->Report( _( "-------- ERC cancelled by user.<br><br>" ), RPT_SEVERITY_INFO );
456 else
457 m_messages->Report( _( "Done.<br><br>" ), RPT_SEVERITY_INFO );
458
459 Raise();
460 wxYield(); // Allow time slice to refresh Messages
461
462 m_running = false;
463 m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
464 m_sdbSizer1OK->Enable( true );
465 m_deleteOneMarker->Enable( true );
466 m_deleteAllMarkers->Enable( true );
467 m_saveReport->Enable( true );
468
469 if( !m_cancelled )
470 {
471 m_sdbSizer1Cancel->SetDefault();
472
473 // wxWidgets has a tendency to keep both buttons highlighted without the following:
474 m_sdbSizer1OK->Enable( false );
475
476 wxMilliSleep( 500 );
477 m_runningResultsBook->ChangeSelection( 1 );
479
480 // now re-enable m_sdbSizerOK button
481 m_sdbSizer1OK->Enable( true );
482 }
483
484 m_ercRun = true;
487 // set float level again, it can be lost due to window events during test run
489}
490
491
493{
494 WINDOW_THAWER thawer( m_parent );
495
497}
498
499
501{
502 wxFileName fn;
503
504 SCHEMATIC* sch = &m_parent->Schematic();
505
506 SCH_SCREENS screens( sch->Root() );
507 ERC_TESTER tester( sch );
508
509 {
510 wxBusyCursor dummy;
513 }
514
515 // Update marker list:
517
518 // Display new markers from the current screen:
519 for( SCH_ITEM* marker : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
520 {
521 m_parent->GetCanvas()->GetView()->Remove( marker );
522 m_parent->GetCanvas()->GetView()->Add( marker );
523 }
524
526}
527
528
529void DIALOG_ERC::OnERCItemSelected( wxDataViewEvent& aEvent )
530{
531 const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
532 SCH_SHEET_PATH sheet;
533 SCH_ITEM* item = m_parent->Schematic().GetItem( itemID, &sheet );
534
536 {
537 // we already came from a cross-probe of the marker in the document; don't go
538 // around in circles
539 }
540 else if( item && item->GetClass() != wxT( "DELETED_SHEET_ITEM" ) )
541 {
542 const RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
543
544 if( node )
545 {
546 // Determine the owning sheet for sheet-specific items
547 std::shared_ptr<ERC_ITEM> ercItem =
548 std::static_pointer_cast<ERC_ITEM>( node->m_RcItem );
549 switch( node->m_Type )
550 {
552 if( ercItem->IsSheetSpecific() )
553 sheet = ercItem->GetSpecificSheetPath();
554 break;
556 if( ercItem->MainItemHasSheetPath() )
557 sheet = ercItem->GetMainItemSheetPath();
558 break;
560 if( ercItem->AuxItemHasSheetPath() )
561 sheet = ercItem->GetAuxItemSheetPath();
562 break;
563 default:
564 break;
565 }
566 }
567
568 WINDOW_THAWER thawer( m_parent );
569
570 if( !sheet.empty() && sheet != m_parent->GetCurrentSheet() )
571 {
574
575 // Store the current zoom level into the current screen before switching
577
578 m_parent->SetCurrentSheet( sheet );
581 }
582
583 m_parent->FocusOnItem( item );
585 }
586
587 aEvent.Skip();
588}
589
590
591void DIALOG_ERC::OnERCItemDClick( wxDataViewEvent& aEvent )
592{
593 if( aEvent.GetItem().IsOk() )
594 {
595 // turn control over to m_parent, hide this DIALOG_ERC window,
596 // no destruction so we can preserve listbox cursor
597 if( !IsModal() )
598 Show( false );
599 }
600
601 aEvent.Skip();
602}
603
604
605void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
606{
608 EE_INSPECTION_TOOL* inspectionTool = toolMgr->GetTool<EE_INSPECTION_TOOL>();
609 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
610
611 if( !node )
612 return;
613
615
616 std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
617 wxString listName;
618 wxMenu menu;
619
620 switch( settings.GetSeverity( rcItem->GetErrorCode() ) )
621 {
622 case RPT_SEVERITY_ERROR: listName = _( "errors" ); break;
623 case RPT_SEVERITY_WARNING: listName = _( "warnings" ); break;
624 default: listName = _( "appropriate" ); break;
625 }
626
627 enum MENU_IDS
628 {
629 ID_EDIT_EXCLUSION_COMMENT = 4467,
630 ID_REMOVE_EXCLUSION,
631 ID_REMOVE_EXCLUSION_ALL,
632 ID_ADD_EXCLUSION,
633 ID_ADD_EXCLUSION_WITH_COMMENT,
634 ID_ADD_EXCLUSION_ALL,
635 ID_INSPECT_VIOLATION,
636 ID_EDIT_PIN_CONFLICT_MAP,
637 ID_EDIT_CONNECTION_GRID,
638 ID_SET_SEVERITY_TO_ERROR,
639 ID_SET_SEVERITY_TO_WARNING,
640 ID_SET_SEVERITY_TO_IGNORE,
641 ID_EDIT_SEVERITIES,
642 };
643
644 if( rcItem->GetParent()->IsExcluded() )
645 {
646 menu.Append( ID_REMOVE_EXCLUSION,
647 _( "Remove exclusion for this violation" ),
648 wxString::Format( _( "It will be placed back in the %s list" ), listName ) );
649
650 menu.Append( ID_EDIT_EXCLUSION_COMMENT,
651 _( "Edit exclusion comment..." ) );
652 }
653 else
654 {
655 menu.Append( ID_ADD_EXCLUSION,
656 _( "Exclude this violation" ),
657 wxString::Format( _( "It will be excluded from the %s list" ), listName ) );
658
659 menu.Append( ID_ADD_EXCLUSION_WITH_COMMENT,
660 _( "Exclude with comment..." ),
661 wxString::Format( _( "It will be excluded from the %s list" ), listName ) );
662 }
663
664 wxString inspectERCErrorMenuText = inspectionTool->InspectERCErrorMenuText( rcItem );
665
666 if( !inspectERCErrorMenuText.IsEmpty() )
667 menu.Append( ID_INSPECT_VIOLATION, inspectERCErrorMenuText );
668
669 menu.AppendSeparator();
670
671 if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_WARNING
672 || rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
673 {
674 // Pin to pin severities edited through pin conflict map
675 }
676 else if( settings.GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING )
677 {
678 menu.Append( ID_SET_SEVERITY_TO_ERROR,
679 wxString::Format( _( "Change severity to Error for all '%s' violations" ),
680 rcItem->GetErrorText() ),
681 _( "Violation severities can also be edited in the Schematic Setup... dialog" ) );
682 }
683 else
684 {
685 menu.Append( ID_SET_SEVERITY_TO_WARNING,
686 wxString::Format( _( "Change severity to Warning for all '%s' violations" ),
687 rcItem->GetErrorText() ),
688 _( "Violation severities can also be edited in the Schematic Setup... "
689 "dialog" ) );
690 }
691
692 menu.Append( ID_SET_SEVERITY_TO_IGNORE,
693 wxString::Format( _( "Ignore all '%s' violations" ), rcItem->GetErrorText() ),
694 _( "Violations will not be checked or reported" ) );
695
696 menu.AppendSeparator();
697
698 if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_WARNING
699 || rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
700 {
701 menu.Append( ID_EDIT_PIN_CONFLICT_MAP,
702 _( "Edit pin-to-pin conflict map..." ),
703 _( "Open the Schematic Setup... dialog" ) );
704 }
705 else
706 {
707 menu.Append( ID_EDIT_SEVERITIES,
708 _( "Edit violation severities..." ),
709 _( "Open the Schematic Setup... dialog" ) );
710 }
711
712 if( rcItem->GetErrorCode() == ERCE_ENDPOINT_OFF_GRID )
713 {
714 menu.Append( ID_EDIT_CONNECTION_GRID,
715 _( "Edit connection grid spacing..." ),
716 _( "Open the Schematic Setup... dialog" ) );
717 }
718
719 bool modified = false;
720 int command = GetPopupMenuSelectionFromUser( menu );
721
722 switch( command )
723 {
724 case ID_EDIT_EXCLUSION_COMMENT:
725 if( SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() ) )
726 {
727 WX_TEXT_ENTRY_DIALOG dlg( this, wxEmptyString, _( "Exclusion Comment" ),
728 marker->GetComment(), true );
729
730 if( dlg.ShowModal() == wxID_CANCEL )
731 break;
732
733 marker->SetExcluded( true, dlg.GetValue() );
734
735 // Update view
736 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
737 modified = true;
738 }
739
740 break;
741
742 case ID_REMOVE_EXCLUSION:
743 if( SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() ) )
744 {
745 marker->SetExcluded( false );
746 m_parent->GetCanvas()->GetView()->Update( marker );
747
748 // Update view
749 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
750 modified = true;
751 }
752
753 break;
754
755 case ID_ADD_EXCLUSION:
756 case ID_ADD_EXCLUSION_WITH_COMMENT:
757 if( SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() ) )
758 {
759 wxString comment;
760
761 if( command == ID_ADD_EXCLUSION_WITH_COMMENT )
762 {
763 WX_TEXT_ENTRY_DIALOG dlg( this, wxEmptyString, _( "Exclusion Comment" ),
764 wxEmptyString, true );
765
766 if( dlg.ShowModal() == wxID_CANCEL )
767 break;
768
769 comment = dlg.GetValue();
770 }
771
772 marker->SetExcluded( true, comment );
773
774 m_parent->GetCanvas()->GetView()->Update( marker );
775
776 // Update view
778 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
779 else
780 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->DeleteCurrentItem( false );
781
782 modified = true;
783 }
784
785 break;
786
787 case ID_INSPECT_VIOLATION:
788 inspectionTool->InspectERCError( node->m_RcItem );
789 break;
790
791 case ID_SET_SEVERITY_TO_ERROR:
792 settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_ERROR );
793
794 for( SCH_ITEM* item : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
795 {
796 SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
797
798 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
799 m_parent->GetCanvas()->GetView()->Update( marker );
800 }
801
802 // Rebuild model and view
803 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, m_severities );
804 modified = true;
805 break;
806
807 case ID_SET_SEVERITY_TO_WARNING:
808 settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_WARNING );
809
810 for( SCH_ITEM* item : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
811 {
812 SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
813
814 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
815 m_parent->GetCanvas()->GetView()->Update( marker );
816 }
817
818 // Rebuild model and view
819 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, m_severities );
820 modified = true;
821 break;
822
823 case ID_SET_SEVERITY_TO_IGNORE:
824 {
825 settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_IGNORE );
826
827 if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
829
830 wxListItem listItem;
831 listItem.SetId( m_ignoredList->GetItemCount() );
832 listItem.SetText( wxT( " • " ) + rcItem->GetErrorText() );
833 listItem.SetData( rcItem->GetErrorCode() );
834
835 m_ignoredList->InsertItem( listItem );
836
837 // Clear the selection before deleting markers. It may be some selected ERC markers.
838 // Deleting a selected marker without deselecting it first generates a crash
840
841 SCH_SCREENS ScreenList( m_parent->Schematic().Root() );
842 ScreenList.DeleteMarkers( MARKER_BASE::MARKER_ERC, rcItem->GetErrorCode() );
843
844 // Rebuild model and view
845 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, m_severities );
846 modified = true;
847 }
848 break;
849
850 case ID_EDIT_PIN_CONFLICT_MAP:
851 m_parent->ShowSchematicSetupDialog( _( "Pin Conflicts Map" ) );
852 break;
853
854 case ID_EDIT_SEVERITIES:
855 m_parent->ShowSchematicSetupDialog( _( "Violation Severity" ) );
856 break;
857
858 case ID_EDIT_CONNECTION_GRID:
859 m_parent->ShowSchematicSetupDialog( _( "Formatting" ) );
860 break;
861 }
862
863 if( modified )
864 {
868 }
869}
870
871
872void DIALOG_ERC::OnIgnoredItemRClick( wxListEvent& event )
873{
875 int errorCode = (int) event.m_item.GetData();
876 wxMenu menu;
877
878 menu.Append( RPT_SEVERITY_ERROR, _( "Error" ), wxEmptyString, wxITEM_CHECK );
879 menu.Append( RPT_SEVERITY_WARNING, _( "Warning" ), wxEmptyString, wxITEM_CHECK );
880 menu.Append( RPT_SEVERITY_IGNORE, _( "Ignore" ), wxEmptyString, wxITEM_CHECK );
881
882 menu.Check( settings.GetSeverity( errorCode ), true );
883
884 int severity = GetPopupMenuSelectionFromUser( menu );
885
886 if( severity > 0 )
887 {
888 if( settings.GetSeverity( errorCode ) != severity )
889 {
890 settings.SetSeverity( errorCode, (SEVERITY) severity );
891
895 }
896 }
897}
898
899
901{
902 if( m_notebook->IsShown() )
903 {
904 if( m_notebook->GetSelection() != 0 )
905 m_notebook->SetSelection( 0 );
906
908 }
909}
910
911
913{
914 if( m_notebook->IsShown() )
915 {
916 if( m_notebook->GetSelection() != 0 )
917 m_notebook->SetSelection( 0 );
918
920 }
921}
922
923
925{
926 if( m_notebook->IsShown() )
927 {
928 m_notebook->SetSelection( 0 );
930
931 // wxWidgets on some platforms fails to correctly ensure that a selected item is
932 // visible, so we have to do it in a separate idle event.
933 m_centerMarkerOnIdle = aMarker;
934 Bind( wxEVT_IDLE, &DIALOG_ERC::centerMarkerIdleHandler, this );
935 }
936}
937
938
939void DIALOG_ERC::centerMarkerIdleHandler( wxIdleEvent& aEvent )
940{
942 m_centerMarkerOnIdle = nullptr;
943 Unbind( wxEVT_IDLE, &DIALOG_ERC::centerMarkerIdleHandler, this );
944}
945
946
948{
949 SCH_MARKER* marker = aMarker;
950
951 if( marker != nullptr )
953
954 if( m_notebook->GetSelection() != 0 )
955 return;
956
957 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( m_markerDataView->GetCurrentItem() );
958
959 if( node && node->m_RcItem )
960 marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() );
961
962 if( node && marker && !marker->IsExcluded() )
963 {
964 marker->SetExcluded( true );
965 m_parent->GetCanvas()->GetView()->Update( marker );
966
967 // Update view
970 else
972
976 }
977}
978
979
980void DIALOG_ERC::OnEditViolationSeverities( wxHyperlinkEvent& aEvent )
981{
982 m_parent->ShowSchematicSetupDialog( _( "Violation Severity" ) );
983}
984
985
986void DIALOG_ERC::OnSeverity( wxCommandEvent& aEvent )
987{
988 int flag = 0;
989
990 if( aEvent.GetEventObject() == m_showAll )
992 else if( aEvent.GetEventObject() == m_showErrors )
994 else if( aEvent.GetEventObject() == m_showWarnings )
996 else if( aEvent.GetEventObject() == m_showExclusions )
998
999 if( aEvent.IsChecked() )
1000 m_severities |= flag;
1001 else if( aEvent.GetEventObject() == m_showAll )
1003 else
1004 m_severities &= ~flag;
1005
1007
1010}
1011
1012
1013void DIALOG_ERC::deleteAllMarkers( bool aIncludeExclusions )
1014{
1015 // Clear current selection list to avoid selection of deleted items
1016 // Freeze to avoid repainting the dialog, which can cause a RePaint()
1017 // of the screen as well
1018 Freeze();
1020
1021 m_markerTreeModel->DeleteItems( false, aIncludeExclusions, false );
1022
1023 SCH_SCREENS screens( m_parent->Schematic().Root() );
1024 screens.DeleteAllMarkers( MARKER_BASE::MARKER_ERC, aIncludeExclusions );
1025 Thaw();
1026}
1027
1028
1029void DIALOG_ERC::OnSaveReport( wxCommandEvent& aEvent )
1030{
1031 wxFileName fn( wxS( "ERC." ) + wxString( FILEEXT::ReportFileExtension ) );
1032
1033 wxFileDialog dlg( this, _( "Save Report File" ), Prj().GetProjectPath(), fn.GetFullName(),
1035 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1036
1037 if( dlg.ShowModal() != wxID_OK )
1038 return;
1039
1040 fn = dlg.GetPath();
1041
1042 if( fn.GetExt().IsEmpty() )
1043 fn.SetExt( FILEEXT::ReportFileExtension );
1044
1045 if( !fn.IsAbsolute() )
1046 {
1047 wxString prj_path = Prj().GetProjectPath();
1048 fn.MakeAbsolute( prj_path );
1049 }
1050
1051 ERC_REPORT reportWriter( &m_parent->Schematic(), m_parent->GetUserUnits() );
1052
1053 bool success = false;
1054 if( fn.GetExt() == FILEEXT::JsonFileExtension )
1055 success = reportWriter.WriteJsonReport( fn.GetFullPath() );
1056 else
1057 success = reportWriter.WriteTextReport( fn.GetFullPath() );
1058
1059 if( success )
1060 {
1061 m_messages->Report( wxString::Format( _( "Report file '%s' created." ),
1062 fn.GetFullPath() ) );
1063 }
1064 else
1065 {
1066 DisplayErrorMessage( this, wxString::Format( _( "Failed to create file '%s'." ),
1067 fn.GetFullPath() ) );
1068 }
1069}
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
VECTOR2D m_ScrollCenter
Current scroll center point in logical units.
Definition: base_screen.h:100
Class DIALOG_ERC_BASE.
wxButton * m_saveReport
wxButton * m_sdbSizer1Cancel
wxSimplebook * m_runningResultsBook
wxCheckBox * m_showExclusions
NUMBER_BADGE * m_errorsBadge
WX_INFOBAR * m_infoBar
wxCheckBox * m_showErrors
wxNotebook * m_notebook
wxCheckBox * m_showAll
NUMBER_BADGE * m_exclusionsBadge
wxListCtrl * m_ignoredList
WX_HTML_REPORT_BOX * m_messages
wxDataViewCtrl * m_markerDataView
wxButton * m_deleteAllMarkers
NUMBER_BADGE * m_warningsBadge
wxButton * m_deleteOneMarker
wxCheckBox * m_showWarnings
wxButton * m_sdbSizer1OK
void ExcludeMarker(SCH_MARKER *aMarker=nullptr)
Exclude aMarker from the ERC list.
Definition: dialog_erc.cpp:947
void OnIgnoredItemRClick(wxListEvent &aEvent) override
Definition: dialog_erc.cpp:872
const SCH_MARKER * m_centerMarkerOnIdle
Definition: dialog_erc.h:115
void OnERCItemDClick(wxDataViewEvent &aEvent) override
Definition: dialog_erc.cpp:591
std::shared_ptr< RC_ITEMS_PROVIDER > m_markerProvider
Definition: dialog_erc.h:109
void syncCheckboxes()
Definition: dialog_erc.cpp:374
bool m_ercRun
Definition: dialog_erc.h:113
DIALOG_ERC(SCH_EDIT_FRAME *parent)
Definition: dialog_erc.cpp:73
void testErc()
Definition: dialog_erc.cpp:500
void SelectMarker(const SCH_MARKER *aMarker)
Definition: dialog_erc.cpp:924
bool updateUI() override
Definition: dialog_erc.cpp:201
SCH_EDIT_FRAME * m_parent
Definition: dialog_erc.h:103
wxString m_violationsTitleTemplate
Definition: dialog_erc.h:106
void OnERCItemRClick(wxDataViewEvent &aEvent) override
Definition: dialog_erc.cpp:605
void centerMarkerIdleHandler(wxIdleEvent &aEvent)
Definition: dialog_erc.cpp:939
void OnDeleteAllClick(wxCommandEvent &event) override
Definition: dialog_erc.cpp:307
void OnLinkClicked(wxHtmlLinkEvent &event) override
Definition: dialog_erc.cpp:383
int m_severities
Definition: dialog_erc.h:117
void OnRunERCClick(wxCommandEvent &event) override
Definition: dialog_erc.cpp:389
void deleteAllMarkers(bool aIncludeExclusions)
wxString m_ignoredTitleTemplate
Definition: dialog_erc.h:107
void OnDeleteOneClick(wxCommandEvent &event) override
Definition: dialog_erc.cpp:290
void OnSaveReport(wxCommandEvent &aEvent) override
void PrevMarker()
Definition: dialog_erc.cpp:900
void NextMarker()
Definition: dialog_erc.cpp:912
SCHEMATIC * m_currentSchematic
Definition: dialog_erc.h:104
void OnEditViolationSeverities(wxHyperlinkEvent &aEvent) override
Definition: dialog_erc.cpp:980
void UpdateAnnotationWarning()
Definition: dialog_erc.cpp:165
void redrawDrawPanel()
Definition: dialog_erc.cpp:492
void Report(const wxString &aMessage) override
Display aMessage in the progress bar dialog.
Definition: dialog_erc.cpp:223
void OnERCItemSelected(wxDataViewEvent &aEvent) override
Definition: dialog_erc.cpp:529
RC_TREE_MODEL * m_markerTreeModel
Definition: dialog_erc.h:110
void updateDisplayedCounts()
Definition: dialog_erc.cpp:229
void OnSeverity(wxCommandEvent &aEvent) override
Definition: dialog_erc.cpp:986
bool m_running
Definition: dialog_erc.h:112
void OnCloseErcDialog(wxCloseEvent &event) override
Definition: dialog_erc.cpp:352
void OnCancelClick(wxCommandEvent &event) override
Definition: dialog_erc.cpp:338
bool Show(bool show) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
bool IsQuasiModal() const
Definition: dialog_shim.h:113
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
int ShowModal() override
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:56
void InspectERCError(const std::shared_ptr< RC_ITEM > &aERCItem)
wxString InspectERCErrorMenuText(const std::shared_ptr< RC_ITEM > &aERCItem)
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:238
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:299
static std::vector< std::reference_wrapper< RC_ITEM > > GetItemsWithSeverities()
Definition: erc_item.h:76
bool WriteJsonReport(const wxString &aFullFileName)
Writes a JSON formatted ERC Report to the given file path.
Definition: erc_report.cpp:109
bool WriteTextReport(const wxString &aFullFileName)
Writes the text report also available via GetTextReport directly to a given file path.
Definition: erc_report.cpp:95
Container for ERC settings.
Definition: erc_settings.h:135
SEVERITY GetSeverity(int aErrorCode) const
void SetSeverity(int aErrorCode, SEVERITY aSeverity)
Definition: erc.h:52
void RunTests(DS_PROXY_VIEW_ITEM *aDrawingSheet, SCH_EDIT_FRAME *aEditFrame, KIFACE *aCvPcb, PROJECT *aProject, PROGRESS_REPORTER *aProgressReporter)
Definition: erc.cpp:1771
A specialisation of the RC_TREE_MODEL class to enable ERC errors / warnings to be resolved in a speci...
Definition: erc_item.h:38
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_base.h:95
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
Definition: sch_view.h:120
double GetScale() const
Definition: view.h:272
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:297
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:332
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1673
Definition: kiid.h:49
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:55
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition: kiway.cpp:201
@ FACE_CVPCB
Definition: kiway.h:294
bool IsExcluded() const
Definition: marker_base.h:98
std::shared_ptr< RC_ITEM > GetRCItem() const
Definition: marker_base.h:112
void SetExcluded(bool aExcluded, const wxString &aComment=wxEmptyString)
Definition: marker_base.h:99
void SetMaximumNumber(int aMax)
Set the maximum number to be shown on the badge.
void UpdateNumber(int aNumber, SEVERITY aSeverity)
Update the number displayed on the badge.
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:146
void PrevMarker()
Definition: rc_item.cpp:689
void SelectMarker(const MARKER_BASE *aMarker)
Definition: rc_item.cpp:738
static RC_TREE_NODE * ToNode(wxDataViewItem aItem)
Definition: rc_item.h:238
void ValueChanged(RC_TREE_NODE *aNode)
Definition: rc_item.cpp:517
void Update(std::shared_ptr< RC_ITEMS_PROVIDER > aProvider, int aSeverities)
Definition: rc_item.cpp:364
void DeleteItems(bool aCurrentOnly, bool aIncludeExclusions, bool aDeep)
Delete the current item or all items.
Definition: rc_item.cpp:572
void DeleteCurrentItem(bool aDeep)
Definition: rc_item.cpp:566
void CenterMarker(const MARKER_BASE *aMarker)
Definition: rc_item.cpp:751
static KIID ToUUID(wxDataViewItem aItem)
Definition: rc_item.cpp:220
void NextMarker()
Definition: rc_item.cpp:710
std::shared_ptr< RC_ITEM > m_RcItem
Definition: rc_item.h:223
NODE_TYPE m_Type
Definition: rc_item.h:222
virtual REPORTER & ReportHead(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Places the report at the beginning of the list for objects that support ordering.
Definition: reporter.h:109
Holds all the data relating to one schematic.
Definition: schematic.h:82
void RecordERCExclusions()
Scan existing markers and record data from any that are Excluded.
Definition: schematic.cpp:833
SCH_ITEM * GetItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr) const
Definition: schematic.h:125
SCH_SHEET & Root() const
Definition: schematic.h:130
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:319
virtual void RedrawScreen(const VECTOR2I &aCenterPoint, bool aWarpPointer)
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
Schematic editor (Eeschema) main window.
void ShowSchematicSetupDialog(const wxString &aInitialPage=wxEmptyString)
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag and update other data struc...
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
SCH_SHEET_PATH & GetCurrentSheet() const
SCHEMATIC & Schematic() const
int CheckAnnotate(ANNOTATION_ERROR_HANDLER aErrorHandler, ANNOTATE_SCOPE_T aAnnotateScope=ANNOTATE_ALL, bool aRecursive=true)
Check for annotation errors.
Definition: annotate.cpp:460
void SetCurrentSheet(const SCH_SHEET_PATH &aSheet)
void DisplayCurrentSheet()
Draw the current sheet on the display.
void FocusOnItem(SCH_ITEM *aItem)
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:167
wxString GetClass() const override
Return the class name.
Definition: sch_item.h:177
A helper to define a symbol's reference designator in a schematic.
const SCH_SHEET_PATH & GetSheetPath() const
SCH_SYMBOL * GetSymbol() const
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:712
void DeleteMarkers(enum MARKER_BASE::MARKER_T aMarkerTyp, int aErrorCode, bool aIncludeExclusions=true)
Delete all markers of a particular type and error code.
void DeleteAllMarkers(enum MARKER_BASE::MARKER_T aMarkerType, bool aIncludeExclusions)
Delete all electronic rules check markers of aMarkerType from all the screens in the list.
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Definition: sch_screen.cpp:153
double m_LastZoomLevel
last value for the zoom level, useful in Eeschema when changing the current displayed sheet to reuse ...
Definition: sch_screen.h:636
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:108
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
bool empty() const
Forwarded method from std::vector.
SCH_SCREEN * LastScreen()
VECTOR2I GetPosition() const override
Definition: sch_symbol.h:774
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
Master controller class:
Definition: tool_manager.h:62
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:150
EDA_UNITS GetUserUnits() const
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 RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: wx_infobar.cpp:320
void AddButton(wxButton *aButton)
Add an already created button to the infobar.
Definition: wx_infobar.cpp:278
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
Definition: wx_infobar.cpp:153
A KICAD version of wxTextEntryDialog which supports the various improvements/work-arounds from DIALOG...
wxString GetValue() const
The common library.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:195
This file is part of the common library.
static int RPT_SEVERITY_ALL
Definition: dialog_erc.cpp:371
static int DEFAULT_SINGLE_COL_WIDTH
Definition: dialog_erc.cpp:64
static bool g_lastERCRun
Definition: dialog_erc.cpp:68
wxDEFINE_EVENT(EDA_EVT_CLOSE_ERC_DIALOG, wxCommandEvent)
static std::vector< std::pair< wxString, int > > g_lastERCIgnored
Definition: dialog_erc.cpp:70
static SCHEMATIC * g_lastERCSchematic
Definition: dialog_erc.cpp:67
#define DIALOG_ERC_WINDOW_NAME
Definition: dialog_erc.h:40
#define _(s)
static int DEFAULT_SINGLE_COL_WIDTH
ERCE_T
ERC error codes.
Definition: erc_settings.h:37
@ ERCE_ENDPOINT_OFF_GRID
Pin or wire-end off grid.
Definition: erc_settings.h:41
@ ERCE_PIN_TO_PIN_WARNING
Definition: erc_settings.h:97
@ ERCE_PIN_TO_PIN_ERROR
Definition: erc_settings.h:98
static const std::string ReportFileExtension
static const std::string JsonFileExtension
static wxString JsonFileWildcard()
static wxString ReportFileWildcard()
Common command IDs shared by more than one of the KiCad applications.
void SetFloatLevel(wxWindow *aWindow)
Intended to set the floating window level in macOS on a window.
Definition: wxgtk/ui.cpp:395
void ForceFocus(wxWindow *aWindow)
Pass the current focus to the window.
Definition: wxgtk/ui.cpp:124
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_EXCLUSION
@ RPT_SEVERITY_IGNORE
@ RPT_SEVERITY_INFO
std::vector< FAB_LAYER_COLOR > dummy
@ SCH_MARKER_T
Definition: typeinfo.h:158
Definition of file extensions used in Kicad.
static int RPT_SEVERITY_ALL