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, see <https://www.gnu.org/licenses/>.
20 */
21
23#include <advanced_config.h>
24#include <gestfich.h>
25#include <sch_screen.h>
26#include <sch_edit_frame.h>
27#include <widgets/wx_infobar.h>
28#include <project.h>
29#include <kiface_base.h>
30#include <reporter.h>
32#include <sch_marker.h>
33#include <connection_graph.h>
34#include <tools/sch_actions.h>
36#include <dialog_erc.h>
37#include <erc/erc.h>
38#include <erc/erc_report.h>
39#include <id.h>
40#include <confirm.h>
44#include <string_utils.h>
45#include <kiplatform/ui.h>
46#include <confirm.h>
47
48#include <wx/ffile.h>
49#include <wx/filedlg.h>
50#include <wx/hyperlink.h>
51#include <wx/msgdlg.h>
52#include <sch_edit_tool.h>
53
54
55wxDEFINE_EVENT( EDA_EVT_CLOSE_ERC_DIALOG, wxCommandEvent );
56
57
58// wxWidgets spends *far* too long calculating column widths (most of it, believe it or
59// not, in repeatedly creating/destroying a wxDC to do the measurement in).
60// Use default column widths instead.
61static int DEFAULT_SINGLE_COL_WIDTH = 660;
62
63
64static SCHEMATIC* g_lastERCSchematic = nullptr;
65static bool g_lastERCRun = false;
66
67static std::vector<std::pair<wxString, int>> g_lastERCIgnored;
68
69
71 DIALOG_ERC_BASE( parent ),
73 m_parent( parent ),
74 m_markerTreeModel( nullptr ),
75 m_running( false ),
76 m_ercRun( false ),
77 m_centerMarkerOnIdle( nullptr ),
78 m_crossprobe( true ),
80 m_showAllErrors( false )
81{
82 m_currentSchematic = &parent->Schematic();
83
84 SetName( DIALOG_ERC_WINDOW_NAME ); // Set a window name to be able to find it
86
87 m_bMenu->SetBitmap( KiBitmapBundle( BITMAPS::config ) );
88
89 m_messages->SetImmediateMode();
90
91 m_markerProvider = std::make_shared<SHEETLIST_ERC_ITEMS_PROVIDER>( &m_parent->Schematic() );
92
94 m_markerDataView->AssociateModel( m_markerTreeModel );
96
97 // Prevent RTL locales from mirroring the text in the data views
98 m_markerDataView->SetLayoutDirection( wxLayout_LeftToRight );
99 m_ignoredList->SetLayoutDirection( wxLayout_LeftToRight );
100
101 m_ignoredList->InsertColumn( 0, wxEmptyString, wxLIST_FORMAT_LEFT, DEFAULT_SINGLE_COL_WIDTH );
102
104 {
106
107 for( const auto& [ str, code ] : g_lastERCIgnored )
108 {
109 wxListItem listItem;
110 listItem.SetId( m_ignoredList->GetItemCount() );
111 listItem.SetText( str );
112 listItem.SetData( code );
113
114 m_ignoredList->InsertItem( listItem );
115 }
116 }
117
118 m_notebook->SetSelection( 0 );
119
120 SetupStandardButtons( { { wxID_OK, _( "Run ERC" ) },
121 { wxID_CANCEL, _( "Close" ) } } );
122
123 m_violationsTitleTemplate = m_notebook->GetPageText( 0 );
124 m_ignoredTitleTemplate = m_notebook->GetPageText( 1 );
125
126 m_errorsBadge->SetMaximumNumber( 999 );
127 m_warningsBadge->SetMaximumNumber( 999 );
128 m_exclusionsBadge->SetMaximumNumber( 999 );
129
131
132 Layout();
133
134 SetFocus();
135
137 {
138 m_crossprobe = cfg->m_ERCDialog.crossprobe;
139 m_scroll_on_crossprobe = cfg->m_ERCDialog.scroll_on_crossprobe;
140 m_showAllErrors = cfg->m_ERCDialog.show_all_errors;
141 }
142
143 // Now all widgets have the size fixed, call FinishDialogSettings
145}
146
147
149{
152
153 g_lastERCIgnored.clear();
154
155 for( int ii = 0; ii < m_ignoredList->GetItemCount(); ++ii )
156 g_lastERCIgnored.push_back( { m_ignoredList->GetItemText( ii ), m_ignoredList->GetItemData( ii ) } );
157
159 {
160 cfg->m_ERCDialog.crossprobe = m_crossprobe;
161 cfg->m_ERCDialog.scroll_on_crossprobe = m_scroll_on_crossprobe;
162 cfg->m_ERCDialog.show_all_errors = m_showAllErrors;
163 }
164
165 m_markerTreeModel->DecRef();
166}
167
168
170{
171 if( m_parent->CheckAnnotate(
172 []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* )
173 {
174 },
176 true,
178 {
179 if( !m_infoBar->IsShownOnScreen() )
180 {
181 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( m_infoBar, wxID_ANY, _( "Show Annotation dialog" ),
182 wxEmptyString );
183
184 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
185 [&]( wxHyperlinkEvent& aEvent )
186 {
187 wxHtmlLinkEvent htmlEvent( aEvent.GetId(), wxHtmlLinkInfo( aEvent.GetURL() ) );
188 OnLinkClicked( htmlEvent );
189 } ) );
190
191 m_infoBar->RemoveAllButtons();
192 m_infoBar->AddButton( button );
193 m_infoBar->ShowMessage( _( "Schematic is not fully annotated. ERC results will be incomplete." ) );
194 }
195 }
196 else
197 {
198 if( m_infoBar->IsShownOnScreen() )
199 {
200 m_infoBar->RemoveAllButtons();
201 m_infoBar->Hide();
202 }
203 }
204}
205
206
208{
209 int severities = 0;
210
211 if( m_showErrors->GetValue() )
212 severities |= RPT_SEVERITY_ERROR;
213
214 if( m_showWarnings->GetValue() )
215 severities |= RPT_SEVERITY_WARNING;
216
217 if( m_showExclusions->GetValue() )
218 severities |= RPT_SEVERITY_EXCLUSION;
219
220 return severities;
221}
222
223
224void DIALOG_ERC::OnMenu( wxCommandEvent& event )
225{
226 // Build a pop menu:
227 wxMenu menu;
228
229 menu.Append( 4206, _( "Cross-probe Selected Items" ),
230 _( "Highlight corresponding items on canvas when selected in the ERC list" ),
231 wxITEM_CHECK );
232 menu.Check( 4206, m_crossprobe );
233
234 menu.Append( 4207, _( "Center on Cross-probe" ),
235 _( "When cross-probing, scroll the canvas so that the item is visible" ),
236 wxITEM_CHECK );
237 menu.Check( 4207, m_scroll_on_crossprobe );
238
239 menu.Append( 4208, _( "Show all errors" ),
240 _( "Show duplicate ERC markers on all applicable pins" ),
241 wxITEM_CHECK );
242 menu.Check( 4208, m_showAllErrors );
243
244 // menu_id is the selected submenu id from the popup menu or wxID_NONE
245 int menu_id = m_bMenu->GetPopupMenuSelectionFromUser( menu );
246
247 if( menu_id == 0 || menu_id == 4206 )
248 {
250 }
251 else if( menu_id == 1 || menu_id == 4207 )
252 {
254 }
255 else if( menu_id == 2 || menu_id == 4208 )
256 {
258 }
259}
260
261
262void DIALOG_ERC::OnCharHook( wxKeyEvent& aEvt )
263{
264 if( int hotkey = aEvt.GetKeyCode() )
265 {
266 if( aEvt.ControlDown() )
267 hotkey |= MD_CTRL;
268 if( aEvt.ShiftDown() )
269 hotkey |= MD_SHIFT;
270 if( aEvt.AltDown() )
271 hotkey |= MD_ALT;
272
273 if( hotkey == ACTIONS::excludeMarker.GetHotKey() )
274 {
276 return;
277 }
278 }
279
281}
282
283
285{
286 UpdateData();
287 return true;
288}
289
290
292{
293 // If ERC checks ever get slow enough we'll want a progress indicator...
294 //
295 // double cur = (double) m_progress.load() / m_maxProgress;
296 // cur = std::max( 0.0, std::min( cur, 1.0 ) );
297 //
298 // m_gauge->SetValue( KiROUND( cur * 1000.0 ) );
299 // wxSafeYield( this );
300
301 return !m_cancelled;
302}
303
304
305void DIALOG_ERC::AdvancePhase( const wxString& aMessage )
306{
307 // Will also call Report( aMessage ):
309 SetCurrentProgress( 0.0 );
310}
311
312
313void DIALOG_ERC::Report( const wxString& aMessage )
314{
315 m_messages->Report( aMessage );
316}
317
318
324
325
327{
328 int numErrors = 0;
329 int numWarnings = 0;
330 int numExcluded = 0;
331
332 int numMarkers = 0;
333
334 if( m_markerProvider )
335 {
336 numMarkers += m_markerProvider->GetCount();
337 numErrors += m_markerProvider->GetCount( RPT_SEVERITY_ERROR );
338 numWarnings += m_markerProvider->GetCount( RPT_SEVERITY_WARNING );
339 numExcluded += m_markerProvider->GetCount( RPT_SEVERITY_EXCLUSION );
340 }
341
342 bool markersOverflowed = false;
343
344 // We don't currently have a limit on ERC violations, so the above is always false.
345
346 wxString num;
347 wxString msg;
348
349 if( m_ercRun )
350 {
351 num.Printf( markersOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numMarkers );
352 msg.Printf( m_violationsTitleTemplate, num );
353 }
354 else
355 {
357 msg.Replace( wxT( "(%s)" ), wxEmptyString );
358 }
359
360 m_notebook->SetPageText( 0, msg );
361
362 if( m_ercRun )
363 {
364 num.Printf( wxT( "%d" ), m_ignoredList->GetItemCount() );
365 msg.sprintf( m_ignoredTitleTemplate, num );
366 }
367 else
368 {
370 msg.Replace( wxT( "(%s)" ), wxEmptyString );
371 }
372
373 m_notebook->SetPageText( 1, msg );
374
375 if( !m_ercRun && numErrors == 0 )
376 numErrors = -1;
377
378 if( !m_ercRun && numWarnings == 0 )
379 numWarnings = -1;
380
381 m_errorsBadge->UpdateNumber( numErrors, RPT_SEVERITY_ERROR );
382 m_warningsBadge->UpdateNumber( numWarnings, RPT_SEVERITY_WARNING );
383 m_exclusionsBadge->UpdateNumber( numExcluded, RPT_SEVERITY_EXCLUSION );
384}
385
386
387void DIALOG_ERC::OnDeleteOneClick( wxCommandEvent& aEvent )
388{
389 if( m_notebook->GetSelection() == 0 )
390 {
391 // Clear the selection. It may be the selected ERC marker.
392 m_parent->GetToolManager()->RunAction( ACTIONS::selectionClear );
393
394 m_markerTreeModel->DeleteCurrentItem( true );
395
396 // redraw the schematic
398 }
399
401}
402
403
404void DIALOG_ERC::OnDeleteAllClick( wxCommandEvent& event )
405{
406 bool includeExclusions = false;
407 int numExcluded = 0;
408
409 if( m_markerProvider )
410 numExcluded += m_markerProvider->GetCount( RPT_SEVERITY_EXCLUSION );
411
412 if( numExcluded > 0 )
413 {
414 KICAD_MESSAGE_DIALOG dlg( this, _( "Delete exclusions too?" ), _( "Delete All Markers" ),
415 wxYES_NO | wxCANCEL | wxCENTER | wxICON_QUESTION );
416 dlg.SetYesNoLabels( _( "Errors and Warnings Only" ),
417 _( "Errors, Warnings and Exclusions" ) );
418
419 int ret = dlg.ShowModal();
420
421 if( ret == wxID_CANCEL )
422 return;
423 else if( ret == wxID_NO )
424 includeExclusions = true;
425 }
426
427 deleteAllMarkers( includeExclusions );
428 m_ercRun = false;
429
430 // redraw the schematic
433}
434
435
436void DIALOG_ERC::OnCancelClick( wxCommandEvent& aEvent )
437{
438 if( m_running )
439 {
440 m_cancelled = true;
441 return;
442 }
443
444 m_parent->ClearFocus();
445
446 aEvent.Skip();
447}
448
449
450void DIALOG_ERC::OnCloseErcDialog( wxCloseEvent& aEvent )
451{
452 m_parent->ClearFocus();
453
454 // Dialog is mode-less so let the parent know that it needs to be destroyed.
455 if( !IsModal() && !IsQuasiModal() )
456 {
457 if( wxWindow* parent = GetParent() )
458 wxQueueEvent( parent, new wxCommandEvent( EDA_EVT_CLOSE_ERC_DIALOG, wxID_ANY ) );
459 }
460
461 aEvent.Skip();
462}
463
464
465void DIALOG_ERC::OnLinkClicked( wxHtmlLinkEvent& event )
466{
467 m_parent->OnAnnotate();
468}
469
470
471void DIALOG_ERC::OnRunERCClick( wxCommandEvent& event )
472{
473 wxBusyCursor busy;
474
475 SCHEMATIC* sch = &m_parent->Schematic();
476
478
479 sch->RecordERCExclusions();
480 deleteAllMarkers( true );
481
482 std::vector<std::reference_wrapper<RC_ITEM>> violations = ERC_ITEM::GetItemsWithSeverities();
483 m_ignoredList->DeleteAllItems();
484
485 for( std::reference_wrapper<RC_ITEM>& item : violations )
486 {
487 if( sch->ErcSettings().GetSeverity( item.get().GetErrorCode() ) == RPT_SEVERITY_IGNORE )
488 {
489 wxListItem listItem;
490 listItem.SetId( m_ignoredList->GetItemCount() );
491 listItem.SetText( wxT( " • " ) + item.get().GetErrorText( true ) );
492 listItem.SetData( item.get().GetErrorCode() );
493
494 m_ignoredList->InsertItem( listItem );
495 }
496 }
497
498 m_ignoredList->SetColumnWidth( 0, m_ignoredList->GetParent()->GetClientSize().x - 20 );
499
500 m_cancelled = false;
501 Raise();
502
503 m_runningResultsBook->ChangeSelection( 0 ); // Display the "Tests Running..." tab
504 m_messages->Clear();
505 Update(); // Repaint only, don't enter the full event loop
506
507 m_running = true;
508 m_sdbSizer1Cancel->SetLabel( _( "Cancel" ) );
509 m_sdbSizer1OK->Enable( false );
510 m_deleteOneMarker->Enable( false );
511 m_deleteAllMarkers->Enable( false );
512 m_saveReport->Enable( false );
513
514 int itemsNotAnnotated = m_parent->CheckAnnotate(
515 []( ERCE_T aType, const wxString& aMsg, SCH_REFERENCE* aItemA, SCH_REFERENCE* aItemB )
516 {
517 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aType );
518 ercItem->SetErrorMessage( aMsg );
519
520 if( aItemB )
521 ercItem->SetItems( aItemA->GetSymbol(), aItemB->GetSymbol() );
522 else
523 ercItem->SetItems( aItemA->GetSymbol() );
524
525 SCH_MARKER* marker = new SCH_MARKER( std::move( ercItem ), aItemA->GetSymbol()->GetPosition() );
526 aItemA->GetSheetPath().LastScreen()->Append( marker );
527 },
529 true,
531
532 testErc();
533
534 if( itemsNotAnnotated )
535 {
536 m_messages->ReportHead( wxString::Format( _( "%d symbol(s) require annotation.<br><br>" ),
537 itemsNotAnnotated ),
539 }
540
541 if( m_cancelled )
542 m_messages->Report( _( "-------- ERC cancelled by user.<br><br>" ), RPT_SEVERITY_INFO );
543 else
544 m_messages->Report( _( "Done.<br><br>" ), RPT_SEVERITY_INFO );
545
546 Raise();
547 Update(); // Repaint only, don't enter the full event loop
548
549 m_running = false;
550 m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
551 m_sdbSizer1OK->Enable( true );
552 m_deleteOneMarker->Enable( true );
553 m_deleteAllMarkers->Enable( true );
554 m_saveReport->Enable( true );
555
556 if( !m_cancelled )
557 {
558 m_sdbSizer1Cancel->SetDefault();
559
560 // wxWidgets has a tendency to keep both buttons highlighted without the following:
561 m_sdbSizer1OK->Enable( false );
562
563 wxMilliSleep( 500 );
564 m_runningResultsBook->ChangeSelection( 1 );
566
567 // now re-enable m_sdbSizerOK button
568 m_sdbSizer1OK->Enable( true );
569 }
570
571 m_ercRun = true;
574 // set float level again, it can be lost due to window events during test run
576}
577
578
580{
581 WINDOW_THAWER thawer( m_parent );
582
583 m_parent->GetCanvas()->Refresh();
584}
585
586
588{
589 wxFileName fn;
590
591 SCHEMATIC* sch = &m_parent->Schematic();
592
593 SCH_SCREENS screens( sch->Root() );
594 ERC_TESTER tester( sch, m_showAllErrors );
595
596 {
597 wxBusyCursor dummy;
598 tester.RunTests( m_parent->GetCanvas()->GetView()->GetDrawingSheet(), m_parent,
599 m_parent->Kiway().KiFACE( KIWAY::FACE_CVPCB ), &m_parent->Prj(), this );
600 }
601
602 // Update marker list:
604
605 // Display new markers from the current screen:
606 for( SCH_ITEM* marker : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
607 {
608 m_parent->GetCanvas()->GetView()->Remove( marker );
609 m_parent->GetCanvas()->GetView()->Add( marker );
610 }
611
612 m_parent->GetCanvas()->Refresh();
613}
614
615
616void DIALOG_ERC::OnERCItemSelected( wxDataViewEvent& aEvent )
617{
618 if( !m_crossprobe )
619 {
620 aEvent.Skip();
621 return;
622 }
623
624 const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
625 SCH_SHEET_PATH sheet;
626 SCH_ITEM* item = m_parent->Schematic().ResolveItem( itemID, &sheet, true );
627
629 {
630 // we already came from a cross-probe of the marker in the document; don't go
631 // around in circles
632 }
633 else if( item && item->GetClass() != wxT( "DELETED_SHEET_ITEM" ) )
634 {
635 const RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
636
637 if( node )
638 {
639 // Determine the owning sheet for sheet-specific items
640 std::shared_ptr<ERC_ITEM> ercItem = std::static_pointer_cast<ERC_ITEM>( node->m_RcItem );
641
642 switch( node->m_Type )
643 {
645 if( ercItem->IsSheetSpecific() )
646 sheet = ercItem->GetSpecificSheetPath();
647 break;
649 if( ercItem->MainItemHasSheetPath() )
650 sheet = ercItem->GetMainItemSheetPath();
651 break;
653 if( ercItem->AuxItemHasSheetPath() )
654 sheet = ercItem->GetAuxItemSheetPath();
655 break;
656 default:
657 break;
658 }
659 }
660
661 WINDOW_THAWER thawer( m_parent );
662
663 if( !sheet.empty() && sheet != m_parent->GetCurrentSheet() )
664 {
665 m_parent->GetToolManager()->RunAction<SCH_SHEET_PATH*>( SCH_ACTIONS::changeSheet, &sheet );
666 m_parent->RedrawScreen( m_parent->GetScreen()->m_ScrollCenter, false );
667 }
668
669 m_parent->FocusOnItem( item, m_scroll_on_crossprobe );
671 }
672
673 aEvent.Skip();
674}
675
676
677void DIALOG_ERC::OnERCItemDClick( wxDataViewEvent& aEvent )
678{
679 if( aEvent.GetItem().IsOk() )
680 {
681 // turn control over to m_parent, hide this DIALOG_ERC window,
682 // no destruction so we can preserve listbox cursor
683 if( !IsModal() )
684 Show( false );
685 }
686
687 aEvent.Skip();
688}
689
690
691void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
692{
693 TOOL_MANAGER* toolMgr = m_parent->GetToolManager();
694 SCH_INSPECTION_TOOL* inspectionTool = toolMgr->GetTool<SCH_INSPECTION_TOOL>();
695 SCH_EDIT_TOOL* editTool = toolMgr->GetTool<SCH_EDIT_TOOL>();
696 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
697
698 if( !node )
699 return;
700
701 ERC_SETTINGS& settings = m_parent->Schematic().ErcSettings();
702
703 std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
704 wxString listName;
705 wxMenu menu;
706
707 switch( settings.GetSeverity( rcItem->GetErrorCode() ) )
708 {
709 case RPT_SEVERITY_ERROR: listName = _( "errors" ); break;
710 case RPT_SEVERITY_WARNING: listName = _( "warnings" ); break;
711 default: listName = _( "appropriate" ); break;
712 }
713
714 enum MENU_IDS
715 {
716 ID_EDIT_EXCLUSION_COMMENT = 4467,
717 ID_REMOVE_EXCLUSION,
718 ID_REMOVE_EXCLUSION_ALL,
719 ID_ADD_EXCLUSION,
720 ID_ADD_EXCLUSION_WITH_COMMENT,
721 ID_ADD_EXCLUSION_ALL,
722 ID_INSPECT_VIOLATION,
723 ID_FIX_VIOLATION,
724 ID_EDIT_PIN_CONFLICT_MAP,
725 ID_EDIT_CONNECTION_GRID,
726 ID_SET_SEVERITY_TO_ERROR,
727 ID_SET_SEVERITY_TO_WARNING,
728 ID_SET_SEVERITY_TO_IGNORE,
729 ID_EDIT_SEVERITIES,
730 };
731
732 if( rcItem->GetParent()->IsExcluded() )
733 {
734 menu.Append( ID_REMOVE_EXCLUSION,
735 _( "Remove exclusion for this violation" ),
736 wxString::Format( _( "It will be placed back in the %s list" ), listName ) );
737
738 menu.Append( ID_EDIT_EXCLUSION_COMMENT,
739 _( "Edit exclusion comment..." ) );
740 }
741 else
742 {
743 menu.Append( ID_ADD_EXCLUSION,
744 _( "Exclude this violation" ),
745 wxString::Format( _( "It will be excluded from the %s list" ), listName ) );
746
747 menu.Append( ID_ADD_EXCLUSION_WITH_COMMENT,
748 _( "Exclude with comment..." ),
749 wxString::Format( _( "It will be excluded from the %s list" ), listName ) );
750 }
751
752 menu.AppendSeparator();
753
754 wxString inspectERCErrorMenuText = inspectionTool->InspectERCErrorMenuText( rcItem );
755 wxString fixERCErrorMenuText = editTool->FixERCErrorMenuText( rcItem );
756
757 if( !inspectERCErrorMenuText.IsEmpty() || !fixERCErrorMenuText.IsEmpty() )
758 {
759 if( !inspectERCErrorMenuText.IsEmpty() )
760 menu.Append( ID_INSPECT_VIOLATION, inspectERCErrorMenuText );
761
762 if( !fixERCErrorMenuText.IsEmpty() )
763 menu.Append( ID_FIX_VIOLATION, fixERCErrorMenuText );
764
765 menu.AppendSeparator();
766 }
767
768 if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_WARNING
769 || rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
770 {
771 // Pin to pin severities edited through pin conflict map
772 }
773 else if( settings.GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING )
774 {
775 menu.Append( ID_SET_SEVERITY_TO_ERROR,
776 wxString::Format( _( "Change severity to Error for all '%s' violations" ),
777 rcItem->GetErrorText( true ) ),
778 _( "Violation severities can also be edited in Schematic Setup" ) );
779 }
780 else
781 {
782 menu.Append( ID_SET_SEVERITY_TO_WARNING,
783 wxString::Format( _( "Change severity to Warning for all '%s' violations" ),
784 rcItem->GetErrorText( true ) ),
785 _( "Violation severities can also be edited in Schematic Setup" ) );
786 }
787
788 menu.Append( ID_SET_SEVERITY_TO_IGNORE,
789 wxString::Format( _( "Ignore all '%s' violations" ), rcItem->GetErrorText( true ) ),
790 _( "Violations will not be checked or reported" ) );
791
792 menu.AppendSeparator();
793
794 if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_WARNING
795 || rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
796 {
797 menu.Append( ID_EDIT_PIN_CONFLICT_MAP,
798 _( "Edit pin-to-pin conflict map..." ),
799 _( "Open the Schematic Setup dialog" ) );
800 }
801 else
802 {
803 menu.Append( ID_EDIT_SEVERITIES,
804 _( "Edit violation severities..." ),
805 _( "Open the Schematic Setup dialog" ) );
806 }
807
808 if( rcItem->GetErrorCode() == ERCE_ENDPOINT_OFF_GRID )
809 {
810 menu.Append( ID_EDIT_CONNECTION_GRID,
811 _( "Edit connection grid spacing..." ),
812 _( "Open the Schematic Setup dialog" ) );
813 }
814
815 bool modified = false;
816 int command = GetPopupMenuSelectionFromUser( menu );
817
818 switch( command )
819 {
820 case ID_EDIT_EXCLUSION_COMMENT:
821 if( SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() ) )
822 {
823 WX_TEXT_ENTRY_DIALOG dlg( this, wxEmptyString, _( "Exclusion Comment" ), marker->GetComment(), true );
824
825 if( dlg.ShowModal() == wxID_CANCEL )
826 break;
827
828 marker->SetExcluded( true, dlg.GetValue() );
829
830 // Update view
831 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
832 modified = true;
833 }
834
835 break;
836
837 case ID_REMOVE_EXCLUSION:
838 if( SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() ) )
839 {
840 marker->SetExcluded( false );
841 m_parent->GetCanvas()->GetView()->Update( marker );
842
843 // Update view
844 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
845 modified = true;
846 }
847
848 break;
849
850 case ID_ADD_EXCLUSION:
851 case ID_ADD_EXCLUSION_WITH_COMMENT:
852 if( SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() ) )
853 {
854 wxString comment;
855
856 if( command == ID_ADD_EXCLUSION_WITH_COMMENT )
857 {
858 WX_TEXT_ENTRY_DIALOG dlg( this, wxEmptyString, _( "Exclusion Comment" ), wxEmptyString, true );
859
860 if( dlg.ShowModal() == wxID_CANCEL )
861 break;
862
863 comment = dlg.GetValue();
864 }
865
866 marker->SetExcluded( true, comment );
867
868 m_parent->GetCanvas()->GetView()->Update( marker );
869
870 // Update view
872 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
873 else
874 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->DeleteCurrentItem( false );
875
876 modified = true;
877 }
878
879 break;
880
881 case ID_INSPECT_VIOLATION:
882 inspectionTool->InspectERCError( node->m_RcItem );
883 break;
884
885 case ID_FIX_VIOLATION:
886 editTool->FixERCError( node->m_RcItem );
887 break;
888
889 case ID_SET_SEVERITY_TO_ERROR:
890 settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_ERROR );
891
892 for( SCH_ITEM* item : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
893 {
894 SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
895
896 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
897 m_parent->GetCanvas()->GetView()->Update( marker );
898 }
899
900 // Rebuild model and view
901 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, getSeverities() );
902 modified = true;
903 break;
904
905 case ID_SET_SEVERITY_TO_WARNING:
906 settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_WARNING );
907
908 for( SCH_ITEM* item : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
909 {
910 SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
911
912 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
913 m_parent->GetCanvas()->GetView()->Update( marker );
914 }
915
916 // Rebuild model and view
917 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, getSeverities() );
918 modified = true;
919 break;
920
921 case ID_SET_SEVERITY_TO_IGNORE:
922 {
923 settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_IGNORE );
924
925 if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
927
928 wxListItem listItem;
929 listItem.SetId( m_ignoredList->GetItemCount() );
930 listItem.SetText( wxT( " • " ) + rcItem->GetErrorText( true ) );
931 listItem.SetData( rcItem->GetErrorCode() );
932
933 m_ignoredList->InsertItem( listItem );
934
935 // Clear the selection before deleting markers. It may be some selected ERC markers.
936 // Deleting a selected marker without deselecting it first generates a crash
937 m_parent->GetToolManager()->RunAction( ACTIONS::selectionClear );
938
939 SCH_SCREENS ScreenList( m_parent->Schematic().Root() );
940 ScreenList.DeleteMarkers( MARKER_BASE::MARKER_ERC, rcItem->GetErrorCode() );
941
942 // Rebuild model and view
943 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, getSeverities() );
944 modified = true;
945 break;
946 }
947
948 case ID_EDIT_PIN_CONFLICT_MAP:
949 m_parent->ShowSchematicSetupDialog( _( "Pin Conflicts Map" ) );
950 break;
951
952 case ID_EDIT_SEVERITIES:
953 m_parent->ShowSchematicSetupDialog( _( "Violation Severity" ) );
954 break;
955
956 case ID_EDIT_CONNECTION_GRID:
957 m_parent->ShowSchematicSetupDialog( _( "Formatting" ) );
958 break;
959 }
960
961 if( modified )
962 {
965 m_parent->OnModify();
966 }
967}
968
969
970void DIALOG_ERC::OnIgnoredItemRClick( wxListEvent& event )
971{
972 ERC_SETTINGS& settings = m_parent->Schematic().ErcSettings();
973 int errorCode = (int) event.m_item.GetData();
974 wxMenu menu;
975
976 menu.Append( RPT_SEVERITY_ERROR, _( "Error" ), wxEmptyString, wxITEM_RADIO );
977 menu.Append( RPT_SEVERITY_WARNING, _( "Warning" ), wxEmptyString, wxITEM_RADIO );
978 menu.Append( RPT_SEVERITY_IGNORE, _( "Ignore" ), wxEmptyString, wxITEM_RADIO );
979
980 menu.Check( settings.GetSeverity( errorCode ), true );
981
982 int severity = GetPopupMenuSelectionFromUser( menu );
983
984 if( severity > 0 )
985 {
986 if( settings.GetSeverity( errorCode ) != severity )
987 {
988 settings.SetSeverity( errorCode, (SEVERITY) severity );
989
992 m_parent->OnModify();
993 }
994 }
995}
996
997
999{
1000 if( m_notebook->IsShown() )
1001 {
1002 if( m_notebook->GetSelection() != 0 )
1003 m_notebook->SetSelection( 0 );
1004
1005 m_markerTreeModel->PrevMarker();
1006 }
1007}
1008
1009
1011{
1012 if( m_notebook->IsShown() )
1013 {
1014 if( m_notebook->GetSelection() != 0 )
1015 m_notebook->SetSelection( 0 );
1016
1017 m_markerTreeModel->NextMarker();
1018 }
1019}
1020
1021
1023{
1024 if( m_notebook->IsShown() )
1025 {
1026 m_notebook->SetSelection( 0 );
1027 m_markerTreeModel->SelectMarker( aMarker );
1028
1029 // wxWidgets on some platforms fails to correctly ensure that a selected item is
1030 // visible, so we have to do it in a separate idle event.
1031 m_centerMarkerOnIdle = aMarker;
1032 Bind( wxEVT_IDLE, &DIALOG_ERC::centerMarkerIdleHandler, this );
1033 }
1034}
1035
1036
1037void DIALOG_ERC::centerMarkerIdleHandler( wxIdleEvent& aEvent )
1038{
1039 if( m_markerTreeModel->GetView()->IsFrozen() )
1040 return;
1041
1042 m_markerTreeModel->CenterMarker( m_centerMarkerOnIdle );
1043 m_centerMarkerOnIdle = nullptr;
1044 Unbind( wxEVT_IDLE, &DIALOG_ERC::centerMarkerIdleHandler, this );
1045}
1046
1047
1049{
1050 SCH_MARKER* marker = aMarker;
1051
1052 if( marker != nullptr )
1053 m_markerTreeModel->SelectMarker( marker );
1054
1055 if( m_notebook->GetSelection() != 0 )
1056 return;
1057
1058 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( m_markerDataView->GetCurrentItem() );
1059
1060 if( node && node->m_RcItem )
1061 marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() );
1062
1063 if( node && marker && !marker->IsExcluded() )
1064 {
1065 marker->SetExcluded( true );
1066 m_parent->GetCanvas()->GetView()->Update( marker );
1067
1068 // Update view
1070 m_markerTreeModel->ValueChanged( node );
1071 else
1072 m_markerTreeModel->DeleteCurrentItem( false );
1073
1076 m_parent->OnModify();
1077 }
1078}
1079
1080
1081void DIALOG_ERC::OnEditViolationSeverities( wxHyperlinkEvent& aEvent )
1082{
1083 m_parent->ShowSchematicSetupDialog( _( "Violation Severity" ) );
1084}
1085
1086
1087void DIALOG_ERC::OnSeverity( wxCommandEvent& aEvent )
1088{
1089 if( aEvent.GetEventObject() == m_showAll )
1090 {
1091 m_showErrors->SetValue( true );
1092 m_showWarnings->SetValue( aEvent.IsChecked() );
1093 m_showExclusions->SetValue( aEvent.IsChecked() );
1094 }
1095
1096 UpdateData();
1097}
1098
1099
1100void DIALOG_ERC::deleteAllMarkers( bool aIncludeExclusions )
1101{
1102 // Clear current selection list to avoid selection of deleted items
1103 // Freeze to avoid repainting the dialog, which can cause a RePaint()
1104 // of the screen as well
1105 Freeze();
1106
1107 m_parent->GetToolManager()->RunAction( ACTIONS::selectionClear );
1108
1109 m_markerTreeModel->DeleteItems( false, aIncludeExclusions, false );
1110
1111 SCH_SCREENS screens( m_parent->Schematic().Root() );
1112 screens.DeleteAllMarkers( MARKER_BASE::MARKER_ERC, aIncludeExclusions );
1113
1114 Thaw();
1115}
1116
1117
1118void DIALOG_ERC::OnSaveReport( wxCommandEvent& aEvent )
1119{
1120 wxFileName fn( wxS( "ERC." ) + wxString( FILEEXT::ReportFileExtension ) );
1121
1122 wxFileDialog dlg( this, _( "Save Report File" ), Prj().GetProjectPath(), fn.GetFullName(),
1124 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1125
1127
1128 if( dlg.ShowModal() != wxID_OK )
1129 return;
1130
1131 fn = dlg.GetPath();
1132
1133 if( fn.GetExt().IsEmpty() )
1134 fn.SetExt( FILEEXT::ReportFileExtension );
1135
1136 if( !fn.IsAbsolute() )
1137 {
1138 wxString prj_path = Prj().GetProjectPath();
1139 fn.MakeAbsolute( prj_path );
1140 }
1141
1142 ERC_REPORT reportWriter( &m_parent->Schematic(), m_parent->GetUserUnits(), m_markerProvider );
1143
1144 bool success = false;
1145 if( fn.GetExt() == FILEEXT::JsonFileExtension )
1146 success = reportWriter.WriteJsonReport( fn.GetFullPath() );
1147 else
1148 success = reportWriter.WriteTextReport( fn.GetFullPath() );
1149
1150 if( success )
1151 m_messages->Report( wxString::Format( _( "Report file '%s' created." ), fn.GetFullPath() ) );
1152 else
1153 DisplayErrorMessage( this, wxString::Format( _( "Failed to create file '%s'." ), fn.GetFullPath() ) );
1154}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:106
static TOOL_ACTION excludeMarker
Definition actions.h:125
static TOOL_ACTION selectionClear
Clear the current selection.
Definition actions.h:220
wxButton * m_saveReport
wxButton * m_sdbSizer1Cancel
wxSimplebook * m_runningResultsBook
wxCheckBox * m_showExclusions
NUMBER_BADGE * m_errorsBadge
WX_INFOBAR * m_infoBar
STD_BITMAP_BUTTON * m_bMenu
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
DIALOG_ERC_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Electrical Rules Checker"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
void OnMenu(wxCommandEvent &aEvent) override
void ExcludeMarker(SCH_MARKER *aMarker=nullptr)
Exclude aMarker from the ERC list.
void OnIgnoredItemRClick(wxListEvent &aEvent) override
const SCH_MARKER * m_centerMarkerOnIdle
Definition dialog_erc.h:115
void OnERCItemDClick(wxDataViewEvent &aEvent) override
std::shared_ptr< RC_ITEMS_PROVIDER > m_markerProvider
Definition dialog_erc.h:109
bool TransferDataToWindow() override
bool m_ercRun
Definition dialog_erc.h:113
bool m_crossprobe
Definition dialog_erc.h:117
DIALOG_ERC(SCH_EDIT_FRAME *parent)
bool m_scroll_on_crossprobe
Definition dialog_erc.h:118
void testErc()
void SelectMarker(const SCH_MARKER *aMarker)
bool updateUI() override
SCH_EDIT_FRAME * m_parent
Definition dialog_erc.h:103
wxString m_violationsTitleTemplate
Definition dialog_erc.h:106
void OnERCItemRClick(wxDataViewEvent &aEvent) override
void centerMarkerIdleHandler(wxIdleEvent &aEvent)
void OnDeleteAllClick(wxCommandEvent &event) override
void OnLinkClicked(wxHtmlLinkEvent &event) override
void OnCharHook(wxKeyEvent &aEvt) override
void OnRunERCClick(wxCommandEvent &event) override
void deleteAllMarkers(bool aIncludeExclusions)
wxString m_ignoredTitleTemplate
Definition dialog_erc.h:107
void OnDeleteOneClick(wxCommandEvent &event) override
void UpdateData()
void OnSaveReport(wxCommandEvent &aEvent) override
int getSeverities()
void PrevMarker()
void NextMarker()
SCHEMATIC * m_currentSchematic
Definition dialog_erc.h:104
void OnEditViolationSeverities(wxHyperlinkEvent &aEvent) override
void UpdateAnnotationWarning()
void redrawDrawPanel()
void Report(const wxString &aMessage) override
Display aMessage in the progress bar dialog.
void OnERCItemSelected(wxDataViewEvent &aEvent) override
RC_TREE_MODEL * m_markerTreeModel
Definition dialog_erc.h:110
void updateDisplayedCounts()
void OnSeverity(wxCommandEvent &aEvent) override
bool m_running
Definition dialog_erc.h:112
bool m_showAllErrors
Definition dialog_erc.h:119
void OnCloseErcDialog(wxCloseEvent &event) override
void OnCancelClick(wxCommandEvent &event) override
bool Show(bool show) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
bool IsQuasiModal() const
Definition dialog_shim.h:90
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
virtual void OnCharHook(wxKeyEvent &aEvt)
int ShowModal() override
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition erc_item.cpp:315
static std::vector< std::reference_wrapper< RC_ITEM > > GetItemsWithSeverities()
Definition erc_item.h:72
bool WriteJsonReport(const wxString &aFullFileName)
Writes a JSON formatted ERC Report to the given file path in the c-locale.
bool WriteTextReport(const wxString &aFullFileName)
Writes the text report also available via GetTextReport directly to a given file path.
Container for ERC settings.
SEVERITY GetSeverity(int aErrorCode) const
void SetSeverity(int aErrorCode, SEVERITY aSeverity)
void RunTests(DS_PROXY_VIEW_ITEM *aDrawingSheet, SCH_EDIT_FRAME *aEditFrame, KIFACE *aCvPcb, PROJECT *aProject, PROGRESS_REPORTER *aProgressReporter)
Definition erc.cpp:2276
A specialisation of the RC_TREE_MODEL class to enable ERC errors / warnings to be resolved in a speci...
Definition erc_item.h:34
Definition kiid.h:44
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
@ FACE_CVPCB
Definition kiway.h:320
bool IsExcluded() const
Definition marker_base.h:89
std::shared_ptr< RC_ITEM > GetRCItem() const
void SetExcluded(bool aExcluded, const wxString &aComment=wxEmptyString)
Definition marker_base.h:90
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:183
int GetErrorCode() const
Definition rc_item.h:157
MARKER_BASE * GetParent() const
Definition rc_item.h:132
static RC_TREE_NODE * ToNode(wxDataViewItem aItem)
Definition rc_item.h:267
void ValueChanged(RC_TREE_NODE *aNode)
Definition rc_item.cpp:611
void Update(std::shared_ptr< RC_ITEMS_PROVIDER > aProvider, int aSeverities)
Definition rc_item.cpp:413
void DeleteCurrentItem(bool aDeep)
Definition rc_item.cpp:662
static KIID ToUUID(wxDataViewItem aItem)
Definition rc_item.cpp:223
std::shared_ptr< RC_ITEM > m_RcItem
Definition rc_item.h:246
NODE_TYPE m_Type
Definition rc_item.h:245
Holds all the data relating to one schematic.
Definition schematic.h:90
void RecordERCExclusions()
Scan existing markers and record data from any that are Excluded.
SCH_SHEET & Root() const
Definition schematic.h:134
ERC_SETTINGS & ErcSettings() const
static TOOL_ACTION changeSheet
Schematic editor (Eeschema) main window.
SCHEMATIC & Schematic() const
void InspectERCError(const std::shared_ptr< RC_ITEM > &aERCItem)
wxString InspectERCErrorMenuText(const std::shared_ptr< RC_ITEM > &aERCItem)
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:162
wxString GetClass() const override
Return the class name.
Definition sch_item.h:172
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:746
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)
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:885
Master controller class:
A KICAD version of wxTextEntryDialog which supports the various improvements/work-arounds from DIALOG...
wxString GetValue() const
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:217
This file is part of the common library.
#define KICAD_MESSAGE_DIALOG
Definition confirm.h:48
static bool g_lastERCRun
wxDEFINE_EVENT(EDA_EVT_CLOSE_ERC_DIALOG, wxCommandEvent)
static std::vector< std::pair< wxString, int > > g_lastERCIgnored
static SCHEMATIC * g_lastERCSchematic
#define DIALOG_ERC_WINDOW_NAME
Definition dialog_erc.h:35
#define _(s)
static int DEFAULT_SINGLE_COL_WIDTH
ERCE_T
ERC error codes.
@ ERCE_ENDPOINT_OFF_GRID
Pin or wire-end off grid.
@ ERCE_PIN_TO_PIN_WARNING
@ ERCE_PIN_TO_PIN_ERROR
static const std::string ReportFileExtension
static const std::string JsonFileExtension
static wxString JsonFileWildcard()
static wxString ReportFileWildcard()
void SetFloatLevel(wxWindow *aWindow)
Intended to set the floating window level in macOS on a window.
Definition wxgtk/ui.cpp:437
void ForceFocus(wxWindow *aWindow)
Pass the current focus to the window.
Definition wxgtk/ui.cpp:126
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:448
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_EXCLUSION
@ RPT_SEVERITY_IGNORE
@ RPT_SEVERITY_INFO
@ ANNOTATE_ALL
Annotate the full schematic.
@ SYMBOL_FILTER_NON_POWER
T * GetAppSettings(const char *aFilename)
std::vector< FAB_LAYER_COLOR > dummy
@ MD_ALT
Definition tool_event.h:141
@ MD_CTRL
Definition tool_event.h:140
@ MD_SHIFT
Definition tool_event.h:139
@ SCH_MARKER_T
Definition typeinfo.h:155
Definition of file extensions used in Kicad.