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 (C) 1992-2024 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.h>
41#include <erc_report.h>
42#include <id.h>
43#include <confirm.h>
44#include <common.h>
47#include <wx/ffile.h>
48#include <wx/filedlg.h>
49#include <wx/hyperlink.h>
50#include <erc_item.h>
51#include <eeschema_settings.h>
52#include <string_utils.h>
53#include <kiplatform/ui.h>
54
55
56wxDEFINE_EVENT( EDA_EVT_CLOSE_ERC_DIALOG, wxCommandEvent );
57
58
59// wxWidgets spends *far* too long calcuating column widths (most of it, believe it or
60// not, in repeatedly creating/destroying a wxDC to do the measurement in).
61// Use default column widths instead.
62static int DEFAULT_SINGLE_COL_WIDTH = 660;
63
64
65static SCHEMATIC* g_lastERCSchematic = nullptr;
66static bool g_lastERCRun = false;
67static std::vector<wxString> 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_severities( 0 )
79{
80 m_currentSchematic = &parent->Schematic();
81
82 SetName( DIALOG_ERC_WINDOW_NAME ); // Set a window name to be able to find it
83
84 EESCHEMA_SETTINGS* settings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
86
88
89 m_markerProvider = std::make_shared<SHEETLIST_ERC_ITEMS_PROVIDER>( &m_parent->Schematic() );
90
92 m_markerDataView->AssociateModel( m_markerTreeModel );
94
95 m_ignoredList->InsertColumn( 0, wxEmptyString, wxLIST_FORMAT_LEFT, DEFAULT_SINGLE_COL_WIDTH );
96
98 {
100
101 for( const wxString& str : g_lastERCIgnored )
102 m_ignoredList->InsertItem( m_ignoredList->GetItemCount(), str );
103 }
104
105 m_notebook->SetSelection( 0 );
106
107 SetupStandardButtons( { { wxID_OK, _( "Run ERC" ) },
108 { wxID_CANCEL, _( "Close" ) } } );
109
110 m_violationsTitleTemplate = m_notebook->GetPageText( 0 );
111 m_ignoredTitleTemplate = m_notebook->GetPageText( 1 );
112
116
118
119 Layout();
120
121 SetFocus();
122
125
126 // Now all widgets have the size fixed, call FinishDialogSettings
128}
129
130
132{
135
136 g_lastERCIgnored.clear();
137
138 for( int ii = 0; ii < m_ignoredList->GetItemCount(); ++ii )
139 g_lastERCIgnored.push_back( m_ignoredList->GetItemText( ii ) );
140
141 EESCHEMA_SETTINGS* settings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
142 wxASSERT( settings );
143
144 if( settings )
146
147 m_markerTreeModel->DecRef();
148}
149
150
152{
153 if( m_parent->CheckAnnotate( []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* )
154 { } ) )
155 {
156 if( !m_infoBar->IsShownOnScreen() )
157 {
158 wxHyperlinkCtrl* button = new wxHyperlinkCtrl( m_infoBar, wxID_ANY,
159 _( "Show Annotation dialog" ),
160 wxEmptyString );
161
162 button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
163 [&]( wxHyperlinkEvent& aEvent )
164 {
165 wxHtmlLinkEvent htmlEvent( aEvent.GetId(),
166 wxHtmlLinkInfo( aEvent.GetURL() ) );
167 OnLinkClicked( htmlEvent );
168 } ) );
169
171 m_infoBar->AddButton( button );
172 m_infoBar->ShowMessage( _( "Schematic is not fully annotated. "
173 "ERC results will be incomplete." ) );
174 }
175 }
176 else
177 {
178 if( m_infoBar->IsShownOnScreen() )
179 {
181 m_infoBar->Hide();
182 }
183 }
184}
185
186
188{
189 // If ERC checks ever get slow enough we'll want a progress indicator...
190 //
191 // double cur = (double) m_progress.load() / m_maxProgress;
192 // cur = std::max( 0.0, std::min( cur, 1.0 ) );
193 //
194 // m_gauge->SetValue( KiROUND( cur * 1000.0 ) );
195 // wxSafeYield( this );
196
197 return !m_cancelled;
198}
199
200
201void DIALOG_ERC::AdvancePhase( const wxString& aMessage )
202{
203 // Will also call Report( aMessage ):
205 SetCurrentProgress( 0.0 );
206}
207
208
209void DIALOG_ERC::Report( const wxString& aMessage )
210{
211 m_messages->Report( aMessage );
212}
213
214
216{
217 int numErrors = 0;
218 int numWarnings = 0;
219 int numExcluded = 0;
220
221 int numMarkers = 0;
222
223 if( m_markerProvider )
224 {
225 numMarkers += m_markerProvider->GetCount();
226 numErrors += m_markerProvider->GetCount( RPT_SEVERITY_ERROR );
227 numWarnings += m_markerProvider->GetCount( RPT_SEVERITY_WARNING );
228 numExcluded += m_markerProvider->GetCount( RPT_SEVERITY_EXCLUSION );
229 }
230
231 bool markersOverflowed = false;
232
233 // We don't currently have a limit on ERC violations, so the above is always false.
234
235 wxString num;
236 wxString msg;
237
238 if( m_ercRun )
239 {
240 num.Printf( markersOverflowed ? wxT( "%d+" ) : wxT( "%d" ), numMarkers );
241 msg.Printf( m_violationsTitleTemplate, num );
242 }
243 else
244 {
246 msg.Replace( wxT( "(%s)" ), wxEmptyString );
247 }
248
249 m_notebook->SetPageText( 0, msg );
250
251 if( m_ercRun )
252 {
253 num.Printf( wxT( "%d" ), m_ignoredList->GetItemCount() );
254 msg.sprintf( m_ignoredTitleTemplate, num );
255 }
256 else
257 {
259 msg.Replace( wxT( "(%s)" ), wxEmptyString );
260 }
261
262 m_notebook->SetPageText( 1, msg );
263
264 if( !m_ercRun && numErrors == 0 )
265 numErrors = -1;
266
267 if( !m_ercRun && numWarnings == 0 )
268 numWarnings = -1;
269
273}
274
275
276void DIALOG_ERC::OnDeleteOneClick( wxCommandEvent& aEvent )
277{
278 if( m_notebook->GetSelection() == 0 )
279 {
280 // Clear the selection. It may be the selected ERC marker.
282
284
285 // redraw the schematic
287 }
288
290}
291
292
293void DIALOG_ERC::OnDeleteAllClick( wxCommandEvent& event )
294{
295 bool includeExclusions = false;
296 int numExcluded = 0;
297
298 if( m_markerProvider )
299 numExcluded += m_markerProvider->GetCount( RPT_SEVERITY_EXCLUSION );
300
301 if( numExcluded > 0 )
302 {
303 wxMessageDialog dlg( this, _( "Delete exclusions too?" ), _( "Delete All Markers" ),
304 wxYES_NO | wxCANCEL | wxCENTER | wxICON_QUESTION );
305 dlg.SetYesNoLabels( _( "Errors and Warnings Only" ),
306 _( "Errors, Warnings and Exclusions" ) );
307
308 int ret = dlg.ShowModal();
309
310 if( ret == wxID_CANCEL )
311 return;
312 else if( ret == wxID_NO )
313 includeExclusions = true;
314 }
315
316 deleteAllMarkers( includeExclusions );
317
318 // redraw the schematic
321}
322
323
324void DIALOG_ERC::OnCancelClick( wxCommandEvent& aEvent )
325{
326 if( m_running )
327 {
328 m_cancelled = true;
329 return;
330 }
331
332 m_parent->FocusOnItem( nullptr );
333
334 aEvent.Skip();
335}
336
337
338void DIALOG_ERC::OnCloseErcDialog( wxCloseEvent& aEvent )
339{
340 m_parent->FocusOnItem( nullptr );
341
342 // Dialog is mode-less so let the parent know that it needs to be destroyed.
343 if( !IsModal() && !IsQuasiModal() )
344 {
345 wxCommandEvent* evt = new wxCommandEvent( EDA_EVT_CLOSE_ERC_DIALOG, wxID_ANY );
346
347 wxWindow* parent = GetParent();
348
349 if( parent )
350 wxQueueEvent( parent, evt );
351 }
352
353 aEvent.Skip();
354}
355
356
358
359
361{
366}
367
368
369void DIALOG_ERC::OnLinkClicked( wxHtmlLinkEvent& event )
370{
371 wxCommandEvent dummy;
373}
374
375
376void DIALOG_ERC::OnRunERCClick( wxCommandEvent& event )
377{
378 wxBusyCursor busy;
379
380 SCHEMATIC* sch = &m_parent->Schematic();
381
383
384 sch->RecordERCExclusions();
385 deleteAllMarkers( true );
386
387 std::vector<std::reference_wrapper<RC_ITEM>> violations = ERC_ITEM::GetItemsWithSeverities();
388 m_ignoredList->DeleteAllItems();
389
390 for( std::reference_wrapper<RC_ITEM>& item : violations )
391 {
392 if( sch->ErcSettings().GetSeverity( item.get().GetErrorCode() ) == RPT_SEVERITY_IGNORE )
393 {
394 m_ignoredList->InsertItem( m_ignoredList->GetItemCount(),
395 wxT( " • " ) + item.get().GetErrorText() );
396 }
397 }
398
399 m_ignoredList->SetColumnWidth( 0, m_ignoredList->GetParent()->GetClientSize().x - 20 );
400
401 m_cancelled = false;
402 Raise();
403
404 m_runningResultsBook->ChangeSelection( 0 ); // Display the "Tests Running..." tab
405 m_messages->Clear();
406 wxYield(); // Allow time slice to refresh Messages
407
408 m_running = true;
409 m_sdbSizer1Cancel->SetLabel( _( "Cancel" ) );
410 m_sdbSizer1OK->Enable( false );
411 m_deleteOneMarker->Enable( false );
412 m_deleteAllMarkers->Enable( false );
413 m_saveReport->Enable( false );
414
416
417 int itemsNotAnnotated = m_parent->CheckAnnotate(
418 []( ERCE_T aType, const wxString& aMsg, SCH_REFERENCE* aItemA, SCH_REFERENCE* aItemB )
419 {
420 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aType );
421 ercItem->SetErrorMessage( aMsg );
422
423 if( aItemB )
424 ercItem->SetItems( aItemA->GetSymbol(), aItemB->GetSymbol() );
425 else
426 ercItem->SetItems( aItemA->GetSymbol() );
427
428 SCH_MARKER* marker = new SCH_MARKER( ercItem, aItemA->GetSymbol()->GetPosition() );
429 aItemA->GetSheetPath().LastScreen()->Append( marker );
430 } );
431
432 testErc();
433
434 if( itemsNotAnnotated )
435 m_messages->ReportHead( wxString::Format( _( "%d symbol(s) require annotation.<br><br>" ),
436 itemsNotAnnotated ), RPT_SEVERITY_INFO );
437
438 if( m_cancelled )
439 m_messages->Report( _( "-------- ERC cancelled by user.<br><br>" ), RPT_SEVERITY_INFO );
440 else
441 m_messages->Report( _( "Done.<br><br>" ), RPT_SEVERITY_INFO );
442
443 Raise();
444 wxYield(); // Allow time slice to refresh Messages
445
446 m_running = false;
447 m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
448 m_sdbSizer1OK->Enable( true );
449 m_deleteOneMarker->Enable( true );
450 m_deleteAllMarkers->Enable( true );
451 m_saveReport->Enable( true );
452
453 if( !m_cancelled )
454 {
455 m_sdbSizer1Cancel->SetDefault();
456 // wxWidgets has a tendency to keep both buttons highlighted without the following:
457 m_sdbSizer1OK->Enable( false );
458
459 wxMilliSleep( 500 );
460 m_runningResultsBook->ChangeSelection( 1 );
462
463 // now re-enable m_sdbSizerOK button
464 m_sdbSizer1OK->Enable( true );
465 }
466
467 m_ercRun = true;
470}
471
472
474{
475 WINDOW_THAWER thawer( m_parent );
476
478}
479
480
482{
483 wxFileName fn;
484
485 SCHEMATIC* sch = &m_parent->Schematic();
486
487 SCH_SCREENS screens( sch->Root() );
488 ERC_TESTER tester( sch );
489
490 {
491 wxBusyCursor dummy;
494 }
495
496 // Update marker list:
498
499 // Display new markers from the current screen:
500 for( SCH_ITEM* marker : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
501 {
502 m_parent->GetCanvas()->GetView()->Remove( marker );
503 m_parent->GetCanvas()->GetView()->Add( marker );
504 }
505
507}
508
509
510void DIALOG_ERC::OnERCItemSelected( wxDataViewEvent& aEvent )
511{
512 const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
513 SCH_SHEET_PATH sheet;
514 SCH_ITEM* item = m_parent->Schematic().GetSheets().GetItem( itemID, &sheet );
515
517 {
518 // we already came from a cross-probe of the marker in the document; don't go
519 // around in circles
520 }
521 else if( item && item->GetClass() != wxT( "DELETED_SHEET_ITEM" ) )
522 {
523 const RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
524
525 if( node )
526 {
527 // Determine the owning sheet for sheet-specific items
528 std::shared_ptr<ERC_ITEM> ercItem =
529 std::static_pointer_cast<ERC_ITEM>( node->m_RcItem );
530 switch( node->m_Type )
531 {
533 if( ercItem->IsSheetSpecific() )
534 sheet = ercItem->GetSpecificSheetPath();
535 break;
537 if( ercItem->MainItemHasSheetPath() )
538 sheet = ercItem->GetMainItemSheetPath();
539 break;
541 if( ercItem->AuxItemHasSheetPath() )
542 sheet = ercItem->GetAuxItemSheetPath();
543 break;
544 default:
545 break;
546 }
547 }
548
549 WINDOW_THAWER thawer( m_parent );
550
551 if( !sheet.empty() && sheet != m_parent->GetCurrentSheet() )
552 {
555
556 m_parent->SetCurrentSheet( sheet );
559 }
560
561 m_parent->FocusOnItem( item );
563 }
564
565 aEvent.Skip();
566}
567
568
569void DIALOG_ERC::OnERCItemDClick( wxDataViewEvent& aEvent )
570{
571 if( aEvent.GetItem().IsOk() )
572 {
573 // turn control over to m_parent, hide this DIALOG_ERC window,
574 // no destruction so we can preserve listbox cursor
575 if( !IsModal() )
576 Show( false );
577 }
578
579 aEvent.Skip();
580}
581
582
583void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
584{
586 EE_INSPECTION_TOOL* inspectionTool = toolMgr->GetTool<EE_INSPECTION_TOOL>();
587 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
588
589 if( !node )
590 return;
591
593
594 std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
595 wxString listName;
596 wxMenu menu;
597
598 switch( settings.GetSeverity( rcItem->GetErrorCode() ) )
599 {
600 case RPT_SEVERITY_ERROR: listName = _( "errors" ); break;
601 case RPT_SEVERITY_WARNING: listName = _( "warnings" ); break;
602 default: listName = _( "appropriate" ); break;
603 }
604
605 enum MENU_IDS
606 {
607 ID_EDIT_EXCLUSION_COMMENT = 4467,
608 ID_REMOVE_EXCLUSION,
609 ID_REMOVE_EXCLUSION_ALL,
610 ID_ADD_EXCLUSION,
611 ID_ADD_EXCLUSION_ALL,
612 ID_INSPECT_VIOLATION,
613 ID_EDIT_PIN_CONFLICT_MAP,
614 ID_EDIT_CONNECTION_GRID,
615 ID_SET_SEVERITY_TO_ERROR,
616 ID_SET_SEVERITY_TO_WARNING,
617 ID_SET_SEVERITY_TO_IGNORE,
618 ID_EDIT_SEVERITIES,
619 };
620
621 if( rcItem->GetParent()->IsExcluded() )
622 {
623 menu.Append( ID_EDIT_EXCLUSION_COMMENT,
624 _( "Edit exclusion comment..." ) );
625
626 menu.Append( ID_REMOVE_EXCLUSION,
627 _( "Remove exclusion for this violation" ),
628 wxString::Format( _( "It will be placed back in the %s list" ), listName ) );
629 }
630 else
631 {
632 menu.Append( ID_ADD_EXCLUSION,
633 _( "Exclude this violation..." ),
634 wxString::Format( _( "It will be excluded from the %s list" ), listName ) );
635 }
636
637 wxString inspectERCErrorMenuText = inspectionTool->InspectERCErrorMenuText( rcItem );
638
639 if( !inspectERCErrorMenuText.IsEmpty() )
640 menu.Append( ID_INSPECT_VIOLATION, inspectERCErrorMenuText );
641
642 menu.AppendSeparator();
643
644 if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_WARNING
645 || rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
646 {
647 // Pin to pin severities edited through pin conflict map
648 }
649 else if( settings.GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING )
650 {
651 menu.Append( ID_SET_SEVERITY_TO_ERROR,
652 wxString::Format( _( "Change severity to Error for all '%s' violations" ),
653 rcItem->GetErrorText() ),
654 _( "Violation severities can also be edited in the Schematic Setup... dialog" ) );
655 }
656 else
657 {
658 menu.Append( ID_SET_SEVERITY_TO_WARNING,
659 wxString::Format( _( "Change severity to Warning for all '%s' violations" ),
660 rcItem->GetErrorText() ),
661 _( "Violation severities can also be edited in the Schematic Setup... dialog" ) );
662 }
663
664 menu.Append( ID_SET_SEVERITY_TO_IGNORE,
665 wxString::Format( _( "Ignore all '%s' violations" ), rcItem->GetErrorText() ),
666 _( "Violations will not be checked or reported" ) );
667
668 menu.AppendSeparator();
669
670 if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_WARNING
671 || rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
672 {
673 menu.Append( ID_EDIT_PIN_CONFLICT_MAP,
674 _( "Edit pin-to-pin conflict map..." ),
675 _( "Open the Schematic Setup... dialog" ) );
676 }
677 else
678 {
679 menu.Append( ID_EDIT_SEVERITIES,
680 _( "Edit violation severities..." ),
681 _( "Open the Schematic Setup... dialog" ) );
682 }
683
684 if( rcItem->GetErrorCode() == ERCE_ENDPOINT_OFF_GRID )
685 {
686 menu.Append( ID_EDIT_CONNECTION_GRID,
687 _( "Edit connection grid spacing..." ),
688 _( "Open the Schematic Setup... dialog" ) );
689 }
690
691 bool modified = false;
692
693 switch( GetPopupMenuSelectionFromUser( menu ) )
694 {
695 case ID_EDIT_EXCLUSION_COMMENT:
696 if( SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() ) )
697 {
698 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Optional comment:" ), _( "Exclusion Comment" ),
699 marker->GetComment(), true );
700
701 if( dlg.ShowModal() == wxID_CANCEL )
702 break;
703
704 marker->SetExcluded( true, dlg.GetValue() );
705
706 // Update view
707 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
708 modified = true;
709 }
710
711 break;
712
713 case ID_REMOVE_EXCLUSION:
714 if( SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() ) )
715 {
716 marker->SetExcluded( false );
717 m_parent->GetCanvas()->GetView()->Update( marker );
718
719 // Update view
720 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
721 modified = true;
722 }
723
724 break;
725
726 case ID_ADD_EXCLUSION:
727 if( SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() ) )
728 {
729 WX_TEXT_ENTRY_DIALOG dlg( this, _( "Optional comment:" ), _( "Exclusion Comment" ),
730 wxEmptyString, true );
731
732 if( dlg.ShowModal() == wxID_CANCEL )
733 break;
734
735 marker->SetExcluded( true, dlg.GetValue() );
736
737 m_parent->GetCanvas()->GetView()->Update( marker );
738
739 // Update view
741 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
742 else
743 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->DeleteCurrentItem( false );
744
745 modified = true;
746 }
747
748 break;
749
750 case ID_INSPECT_VIOLATION:
751 inspectionTool->InspectERCError( node->m_RcItem );
752 break;
753
754 case ID_SET_SEVERITY_TO_ERROR:
755 settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_ERROR );
756
757 for( SCH_ITEM* item : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
758 {
759 SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
760
761 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
762 m_parent->GetCanvas()->GetView()->Update( marker );
763 }
764
765 // Rebuild model and view
766 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, m_severities );
767 modified = true;
768 break;
769
770 case ID_SET_SEVERITY_TO_WARNING:
771 settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_WARNING );
772
773 for( SCH_ITEM* item : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
774 {
775 SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
776
777 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
778 m_parent->GetCanvas()->GetView()->Update( marker );
779 }
780
781 // Rebuild model and view
782 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, m_severities );
783 modified = true;
784 break;
785
786 case ID_SET_SEVERITY_TO_IGNORE:
787 {
788 settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_IGNORE );
789
790 if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
792
793 // Clear the selection before deleting markers. It may be some selected ERC markers.
794 // Deleting a selected marker without deselecting it first generates a crash
796
797 SCH_SCREENS ScreenList( m_parent->Schematic().Root() );
798 ScreenList.DeleteMarkers( MARKER_BASE::MARKER_ERC, rcItem->GetErrorCode() );
799
800 // Rebuild model and view
801 static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->Update( m_markerProvider, m_severities );
802 modified = true;
803 }
804 break;
805
806 case ID_EDIT_PIN_CONFLICT_MAP:
807 m_parent->ShowSchematicSetupDialog( _( "Pin Conflicts Map" ) );
808 break;
809
810 case ID_EDIT_SEVERITIES:
811 m_parent->ShowSchematicSetupDialog( _( "Violation Severity" ) );
812 break;
813
814 case ID_EDIT_CONNECTION_GRID:
815 m_parent->ShowSchematicSetupDialog( _( "Formatting" ) );
816 break;
817 }
818
819 if( modified )
820 {
824 }
825}
826
827
829{
830 if( m_notebook->IsShown() )
831 {
832 if( m_notebook->GetSelection() != 0 )
833 m_notebook->SetSelection( 0 );
834
836 }
837}
838
839
841{
842 if( m_notebook->IsShown() )
843 {
844 if( m_notebook->GetSelection() != 0 )
845 m_notebook->SetSelection( 0 );
846
848 }
849}
850
851
853{
854 if( m_notebook->IsShown() )
855 {
856 m_notebook->SetSelection( 0 );
858
859 // wxWidgets on some platforms fails to correctly ensure that a selected item is
860 // visible, so we have to do it in a separate idle event.
861 m_centerMarkerOnIdle = aMarker;
862 Bind( wxEVT_IDLE, &DIALOG_ERC::centerMarkerIdleHandler, this );
863 }
864}
865
866
867void DIALOG_ERC::centerMarkerIdleHandler( wxIdleEvent& aEvent )
868{
870 m_centerMarkerOnIdle = nullptr;
871 Unbind( wxEVT_IDLE, &DIALOG_ERC::centerMarkerIdleHandler, this );
872}
873
874
876{
877 SCH_MARKER* marker = aMarker;
878
879 if( marker != nullptr )
881
882 if( m_notebook->GetSelection() != 0 )
883 return;
884
885 RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( m_markerDataView->GetCurrentItem() );
886
887 if( node && node->m_RcItem )
888 marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() );
889
890 if( node && marker && !marker->IsExcluded() )
891 {
892 marker->SetExcluded( true );
893 m_parent->GetCanvas()->GetView()->Update( marker );
894
895 // Update view
898 else
900
904 }
905}
906
907
908void DIALOG_ERC::OnEditViolationSeverities( wxHyperlinkEvent& aEvent )
909{
910 m_parent->ShowSchematicSetupDialog( _( "Violation Severity" ) );
911}
912
913
914void DIALOG_ERC::OnSeverity( wxCommandEvent& aEvent )
915{
916 int flag = 0;
917
918 if( aEvent.GetEventObject() == m_showAll )
920 else if( aEvent.GetEventObject() == m_showErrors )
922 else if( aEvent.GetEventObject() == m_showWarnings )
924 else if( aEvent.GetEventObject() == m_showExclusions )
926
927 if( aEvent.IsChecked() )
929 else if( aEvent.GetEventObject() == m_showAll )
931 else
932 m_severities &= ~flag;
933
935
938}
939
940
941void DIALOG_ERC::deleteAllMarkers( bool aIncludeExclusions )
942{
943 // Clear current selection list to avoid selection of deleted items
945
946 m_markerTreeModel->DeleteItems( false, aIncludeExclusions, false );
947
948 SCH_SCREENS screens( m_parent->Schematic().Root() );
949 screens.DeleteAllMarkers( MARKER_BASE::MARKER_ERC, aIncludeExclusions );
950}
951
952
953void DIALOG_ERC::OnSaveReport( wxCommandEvent& aEvent )
954{
955 wxFileName fn( wxS( "ERC." ) + wxString( FILEEXT::ReportFileExtension ) );
956
957 wxFileDialog dlg( this, _( "Save Report File" ), Prj().GetProjectPath(), fn.GetFullName(),
959 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
960
961 if( dlg.ShowModal() != wxID_OK )
962 return;
963
964 fn = dlg.GetPath();
965
966 if( fn.GetExt().IsEmpty() )
967 fn.SetExt( FILEEXT::ReportFileExtension );
968
969 if( !fn.IsAbsolute() )
970 {
971 wxString prj_path = Prj().GetProjectPath();
972 fn.MakeAbsolute( prj_path );
973 }
974
975 ERC_REPORT reportWriter( &m_parent->Schematic(), m_parent->GetUserUnits() );
976
977 bool success = false;
978 if( fn.GetExt() == FILEEXT::JsonFileExtension )
979 success = reportWriter.WriteJsonReport( fn.GetFullPath() );
980 else
981 success = reportWriter.WriteTextReport( fn.GetFullPath() );
982
983 if( success )
984 {
985 m_messages->Report( wxString::Format( _( "Report file '%s' created." ),
986 fn.GetFullPath() ) );
987 }
988 else
989 {
990 DisplayError( this, wxString::Format( _( "Failed to create file '%s'." ),
991 fn.GetFullPath() ) );
992 }
993}
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
static TOOL_ACTION cancelInteractive
Definition: actions.h:63
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:875
const SCH_MARKER * m_centerMarkerOnIdle
Definition: dialog_erc.h:116
void OnERCItemDClick(wxDataViewEvent &aEvent) override
Definition: dialog_erc.cpp:569
std::shared_ptr< RC_ITEMS_PROVIDER > m_markerProvider
Definition: dialog_erc.h:110
void syncCheckboxes()
Definition: dialog_erc.cpp:360
bool m_ercRun
Definition: dialog_erc.h:114
DIALOG_ERC(SCH_EDIT_FRAME *parent)
Definition: dialog_erc.cpp:70
void testErc()
Definition: dialog_erc.cpp:481
void SelectMarker(const SCH_MARKER *aMarker)
Definition: dialog_erc.cpp:852
bool updateUI() override
Definition: dialog_erc.cpp:187
SCH_EDIT_FRAME * m_parent
Definition: dialog_erc.h:104
wxString m_violationsTitleTemplate
Definition: dialog_erc.h:107
void OnERCItemRClick(wxDataViewEvent &aEvent) override
Definition: dialog_erc.cpp:583
void centerMarkerIdleHandler(wxIdleEvent &aEvent)
Definition: dialog_erc.cpp:867
void OnDeleteAllClick(wxCommandEvent &event) override
Definition: dialog_erc.cpp:293
void OnLinkClicked(wxHtmlLinkEvent &event) override
Definition: dialog_erc.cpp:369
int m_severities
Definition: dialog_erc.h:118
void OnRunERCClick(wxCommandEvent &event) override
Definition: dialog_erc.cpp:376
void deleteAllMarkers(bool aIncludeExclusions)
Definition: dialog_erc.cpp:941
wxString m_ignoredTitleTemplate
Definition: dialog_erc.h:108
void OnDeleteOneClick(wxCommandEvent &event) override
Definition: dialog_erc.cpp:276
void OnSaveReport(wxCommandEvent &aEvent) override
Definition: dialog_erc.cpp:953
void PrevMarker()
Definition: dialog_erc.cpp:828
void NextMarker()
Definition: dialog_erc.cpp:840
SCHEMATIC * m_currentSchematic
Definition: dialog_erc.h:105
void OnEditViolationSeverities(wxHyperlinkEvent &aEvent) override
Definition: dialog_erc.cpp:908
void UpdateAnnotationWarning()
Definition: dialog_erc.cpp:151
void redrawDrawPanel()
Definition: dialog_erc.cpp:473
void Report(const wxString &aMessage) override
Display aMessage in the progress bar dialog.
Definition: dialog_erc.cpp:209
void OnERCItemSelected(wxDataViewEvent &aEvent) override
Definition: dialog_erc.cpp:510
RC_TREE_MODEL * m_markerTreeModel
Definition: dialog_erc.h:111
void updateDisplayedCounts()
Definition: dialog_erc.cpp:215
void OnSeverity(wxCommandEvent &aEvent) override
Definition: dialog_erc.cpp:914
bool m_running
Definition: dialog_erc.h:113
void OnCloseErcDialog(wxCloseEvent &event) override
Definition: dialog_erc.cpp:338
void OnCancelClick(wxCommandEvent &event) override
Definition: dialog_erc.cpp:324
bool Show(bool show) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
bool IsQuasiModal() const
Definition: dialog_shim.h:107
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
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:247
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:119
SEVERITY GetSeverity(int aErrorCode) const
void SetSeverity(int aErrorCode, SEVERITY aSeverity)
Definition: erc.h:46
void RunTests(DS_PROXY_VIEW_ITEM *aDrawingSheet, SCH_EDIT_FRAME *aEditFrame, KIFACE *aCvPcb, PROJECT *aProject, PROGRESS_REPORTER *aProgressReporter)
Definition: erc.cpp:1238
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:103
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:315
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:354
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:1639
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:202
@ FACE_CVPCB
Definition: kiway.h:288
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:135
void PrevMarker()
Definition: rc_item.cpp:689
void SelectMarker(const MARKER_BASE *aMarker)
Definition: rc_item.cpp:738
static RC_TREE_NODE * ToNode(wxDataViewItem aItem)
Definition: rc_item.h:236
void ValueChanged(RC_TREE_NODE *aNode)
Definition: rc_item.cpp:517
void Update(std::shared_ptr< RC_ITEMS_PROVIDER > aProvider, int aSeverities)
Definition: rc_item.cpp:364
void DeleteItems(bool aCurrentOnly, bool aIncludeExclusions, bool aDeep)
Deletes the current item or all items.
Definition: rc_item.cpp:572
void DeleteCurrentItem(bool aDeep)
Definition: rc_item.cpp:566
void CenterMarker(const MARKER_BASE *aMarker)
Definition: rc_item.cpp:751
static KIID ToUUID(wxDataViewItem aItem)
Definition: rc_item.cpp:220
void NextMarker()
Definition: rc_item.cpp:710
std::shared_ptr< RC_ITEM > m_RcItem
Definition: rc_item.h:221
NODE_TYPE m_Type
Definition: rc_item.h:220
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:108
Holds all the data relating to one schematic.
Definition: schematic.h:75
void RecordERCExclusions()
Scan existing markers and record data from any that are Excluded.
Definition: schematic.cpp:798
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:100
SCH_SHEET & Root() const
Definition: schematic.h:105
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:294
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
void OnAnnotate(wxCommandEvent &event)
int CheckAnnotate(ANNOTATION_ERROR_HANDLER aErrorHandler, ANNOTATE_SCOPE_T aAnnotateScope=ANNOTATE_ALL, bool aRecursive=true)
Check for annotation errors.
Definition: annotate.cpp:441
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:172
wxString GetClass() const override
Return the class name.
Definition: sch_item.h:182
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:704
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:150
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:109
SCH_ITEM * GetItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr) const
Fetch a SCH_ITEM by ID.
void AnnotatePowerSymbols()
Silently annotate the not yet annotated power symbols of the entire hierarchy of the sheet path list.
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:772
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
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:301
void AddButton(wxButton *aButton)
Add an already created button to the infobar.
Definition: wx_infobar.cpp:260
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
Definition: wx_infobar.cpp:154
A KICAD version of wxTextEntryDialog which supports the various improvements/work-arounds from DIALOG...
wxString GetValue() const
The common library.
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 int RPT_SEVERITY_ALL
Definition: dialog_erc.cpp:357
static std::vector< wxString > g_lastERCIgnored
Definition: dialog_erc.cpp:67
static int DEFAULT_SINGLE_COL_WIDTH
Definition: dialog_erc.cpp:62
static bool g_lastERCRun
Definition: dialog_erc.cpp:66
wxDEFINE_EVENT(EDA_EVT_CLOSE_ERC_DIALOG, wxCommandEvent)
static SCHEMATIC * g_lastERCSchematic
Definition: dialog_erc.cpp:65
#define DIALOG_ERC_WINDOW_NAME
Definition: dialog_erc.h:42
#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:90
@ ERCE_PIN_TO_PIN_ERROR
Definition: erc_settings.h:91
static const std::string ReportFileExtension
static const std::string JsonFileExtension
static wxString JsonFileWildcard()
static wxString ReportFileWildcard()
void ForceFocus(wxWindow *aWindow)
Pass the current focus to the window.
Definition: gtk/ui.cpp:67
@ 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