KiCad PCB EDA Suite
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 <stambaughw@gmail.com>
6  * Copyright (C) 1992-2021 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 <gestfich.h>
27 #include <sch_screen.h>
28 #include <sch_edit_frame.h>
29 #include <schematic.h>
30 #include <project.h>
31 #include <kiface_i.h>
32 #include <bitmaps.h>
33 #include <reporter.h>
35 #include <sch_view.h>
36 #include <sch_marker.h>
37 #include <connection_graph.h>
38 #include <tools/ee_actions.h>
40 #include <tool/tool_manager.h>
41 #include <dialog_erc.h>
42 #include <erc.h>
43 #include <id.h>
44 #include <confirm.h>
45 #include <widgets/infobar.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 <kicad_string.h>
53 #include <kiplatform/ui.h>
54 
56  DIALOG_ERC_BASE( parent ),
57  PROGRESS_REPORTER( 1 ),
58  m_parent( parent ),
59  m_running( false ),
60  m_ercRun( false ),
62 {
63  EESCHEMA_SETTINGS* settings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
65 
67 
70  m_markerDataView->AssociateModel( m_markerTreeModel );
71 
76 
77  // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
78  // that requires us to correct the button labels here.
79  m_sdbSizer1OK->SetLabel( _( "Run ERC" ) );
80  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
81  m_sdbSizer1->Layout();
82 
83  m_sdbSizer1OK->SetDefault();
84 
88 
89  if( m_parent->CheckAnnotate( []( ERCE_T, const wxString&, SCH_REFERENCE*,
90  SCH_REFERENCE* ) {} ) )
91  {
92  wxHyperlinkCtrl* button = new wxHyperlinkCtrl( m_infoBar, wxID_ANY,
93  _("Show Annotation dialog"),
94  wxEmptyString );
95 
96  button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
97  [&]( wxHyperlinkEvent& aEvent )
98  {
99  wxHtmlLinkEvent htmlEvent( aEvent.GetId(),
100  wxHtmlLinkInfo( aEvent.GetURL() ) );
101  OnLinkClicked( htmlEvent );
102  } ) );
103 
105  m_infoBar->AddButton( button );
106  m_infoBar->ShowMessage( _( "Schematic is not fully annotated. "
107  "ERC results will be incomplete." ) );
108  }
109 
110  // Now all widgets have the size fixed, call FinishDialogSettings
112 }
113 
114 
116 {
117  EESCHEMA_SETTINGS* settings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
118  wxASSERT( settings );
119 
120  if( settings )
122 
123  m_markerTreeModel->DecRef();
124 }
125 
126 
127 // PROGRESS_REPORTER calls
128 
130 {
131  // If ERC checks ever get slow enough we'll want a progress indicator...
132  //
133  // double cur = (double) m_progress.load() / m_maxProgress;
134  // cur = std::max( 0.0, std::min( cur, 1.0 ) );
135  //
136  // m_gauge->SetValue( KiROUND( cur * 1000.0 ) );
137  // wxSafeYield( this );
138 
139  return !m_cancelled;
140 }
141 
142 
143 void DIALOG_ERC::AdvancePhase( const wxString& aMessage )
144 {
145  // Will also call Report( aMessage ):
147  SetCurrentProgress( 0.0 );
148 }
149 
150 
151 void DIALOG_ERC::Report( const wxString& aMessage )
152 {
153  m_messages->Report( aMessage );
154 }
155 
156 
158 {
159  int numErrors = 0;
160  int numWarnings = 0;
161  int numExcluded = 0;
162 
163  if( m_markerProvider )
164  {
168  }
169 
170  if( !m_ercRun )
171  {
172  numErrors = -1;
173  numWarnings = -1;
174  }
175 
179 }
180 
181 
182 /* Delete the old ERC markers, over the whole hierarchy
183  */
184 void DIALOG_ERC::OnEraseDrcMarkersClick( wxCommandEvent& event )
185 {
186  bool includeExclusions = false;
187  int numExcluded = 0;
188 
189  if( m_markerProvider )
191 
192  if( numExcluded > 0 )
193  {
194  wxMessageDialog dlg( this, _( "Delete exclusions too?" ), _( "Delete All Markers" ),
195  wxYES_NO | wxCANCEL | wxCENTER | wxICON_QUESTION );
196  dlg.SetYesNoLabels( _( "Errors and Warnings Only" ) , _( "Errors, Warnings and Exclusions" ) );
197 
198  int ret = dlg.ShowModal();
199 
200  if( ret == wxID_CANCEL )
201  return;
202  else if( ret == wxID_NO )
203  includeExclusions = true;
204  }
205 
206  deleteAllMarkers( includeExclusions );
207 
208  m_ercRun = false;
210  m_parent->GetCanvas()->Refresh();
211 }
212 
213 
214 // This is a modeless dialog so we have to handle these ourselves.
215 void DIALOG_ERC::OnCancelClick( wxCommandEvent& aEvent )
216 {
217  if( m_running )
218  {
219  m_cancelled = true;
220  return;
221  }
222 
223  m_parent->FocusOnItem( nullptr );
224 
225  Close();
226 }
227 
228 
229 void DIALOG_ERC::OnCloseErcDialog( wxCloseEvent& event )
230 {
231  m_parent->FocusOnItem( nullptr );
232 
233  m_parent->GetToolManager()->GetTool<EE_INSPECTION_TOOL>()->DestroyERCDialog();
234 }
235 
236 
238 
239 
241 {
242  m_showAll->SetValue( m_severities == RPT_SEVERITY_ALL );
246 }
247 
248 
249 void DIALOG_ERC::OnLinkClicked( wxHtmlLinkEvent& event )
250 {
251  wxCommandEvent dummy;
253 
254  // We don't actually get notified when the annotation error is resolved, but we can assume
255  // that the user will take corrective action. If they don't, we can just show the infobar
256  // again.
257  m_infoBar->Hide();
258 }
259 
260 
261 void DIALOG_ERC::OnRunERCClick( wxCommandEvent& event )
262 {
263  wxBusyCursor busy;
264 
265  SCHEMATIC* sch = &m_parent->Schematic();
266 
267  m_infoBar->Hide();
268 
270  deleteAllMarkers( true );
271 
272  m_notebook->ChangeSelection( 0 ); // Display the "Tests Running..." tab
273  m_messages->Clear();
274  wxYield(); // Allow time slice to refresh Messages
275 
276  m_running = true;
277  m_sdbSizer1Cancel->SetLabel( _( "Cancel" ) );
278  m_sdbSizer1OK->Enable( false );
279  m_buttondelmarkers->Enable( false );
280  m_saveReport->Enable( false );
281 
283 
284  int itemsNotAnnotated = m_parent->CheckAnnotate(
285  []( ERCE_T aType, const wxString& aMsg, SCH_REFERENCE* aItemA, SCH_REFERENCE* aItemB )
286  {
287  std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aType );
288  ercItem->SetErrorMessage( aMsg );
289 
290  if( aItemB )
291  ercItem->SetItems( aItemA->GetSymbol(), aItemB->GetSymbol() );
292  else
293  ercItem->SetItems( aItemA->GetSymbol() );
294 
295  SCH_MARKER* marker = new SCH_MARKER( ercItem, aItemA->GetSymbol()->GetPosition() );
296  aItemA->GetSheetPath().LastScreen()->Append( marker );
297  } );
298 
299  testErc();
300 
301  if( itemsNotAnnotated )
302  m_messages->ReportHead( wxString::Format( _( "%d symbol(s) require annotation.<br><br>" ),
303  itemsNotAnnotated ), RPT_SEVERITY_INFO );
304 
305  if( m_cancelled )
306  m_messages->Report( _( "-------- ERC cancelled by user.<br><br>" ), RPT_SEVERITY_INFO );
307  else
308  m_messages->Report( _( "ERC completed.<br><br>" ), RPT_SEVERITY_INFO );
309 
310  Raise();
311  wxYield(); // Allow time slice to refresh Messages
312 
313  m_running = false;
314  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
315  m_sdbSizer1OK->Enable( true );
316  m_buttondelmarkers->Enable( true );
317  m_saveReport->Enable( true );
318 
319  if( !m_cancelled )
320  {
321  wxMilliSleep( 500 );
322  m_notebook->ChangeSelection( 1 );
324  }
325 
326  m_ercRun = true;
328 }
329 
330 
332 {
333  WINDOW_THAWER thawer( m_parent );
334 
335  m_parent->GetCanvas()->Refresh();
336 }
337 
338 
340 {
341  wxFileName fn;
342 
343  SCHEMATIC* sch = &m_parent->Schematic();
344 
345  // Build the whole sheet list in hierarchy (sheet, not screen)
347 
348  SCH_SCREENS screens( sch->Root() );
349  ERC_SETTINGS& settings = sch->ErcSettings();
350  ERC_TESTER tester( sch );
351 
352  // Test duplicate sheet names inside a given sheet. While one can have multiple references
353  // to the same file, each must have a unique name.
354  if( settings.IsTestEnabled( ERCE_DUPLICATE_SHEET_NAME ) )
355  {
356  AdvancePhase( _( "Checking sheet names..." ) );
357  tester.TestDuplicateSheetNames( true );
358  }
359 
360  if( settings.IsTestEnabled( ERCE_BUS_ALIAS_CONFLICT ) )
361  {
362  AdvancePhase( _( "Checking bus conflicts..." ) );
363  tester.TestConflictingBusAliases();
364  }
365 
366  // The connection graph has a whole set of ERC checks it can run
367  AdvancePhase( _( "Checking conflicts..." ) );
369  sch->ConnectionGraph()->RunERC();
370 
371  // Test is all units of each multiunit symbol have the same footprint assigned.
372  if( settings.IsTestEnabled( ERCE_DIFFERENT_UNIT_FP ) )
373  {
374  AdvancePhase( _( "Checking footprints..." ) );
375  tester.TestMultiunitFootprints();
376  }
377 
378  AdvancePhase( _( "Checking pins..." ) );
379 
380  if( settings.IsTestEnabled( ERCE_DIFFERENT_UNIT_NET ) )
381  tester.TestMultUnitPinConflicts();
382 
383  // Test pins on each net against the pin connection table
384  if( settings.IsTestEnabled( ERCE_PIN_TO_PIN_ERROR ) )
385  tester.TestPinToPin();
386 
387  // Test similar labels (i;e. labels which are identical when
388  // using case insensitive comparisons)
389  if( settings.IsTestEnabled( ERCE_SIMILAR_LABELS ) )
390  {
391  AdvancePhase( _( "Checking labels..." ) );
392  tester.TestSimilarLabels();
393  }
394 
395  if( settings.IsTestEnabled( ERCE_UNRESOLVED_VARIABLE ) )
396  {
397  AdvancePhase( _( "Checking for unresolved variables..." ) );
399  }
400 
401  if( settings.IsTestEnabled( ERCE_NOCONNECT_CONNECTED ) )
402  {
403  AdvancePhase( _( "Checking no connect pins for connections..." ) );
404  tester.TestNoConnectPins();
405  }
406 
407  if( settings.IsTestEnabled( ERCE_LIB_SYMBOL_ISSUES ) )
408  {
409  AdvancePhase( _( "Checking for library symbol issues..." ) );
410  tester.TestLibSymbolIssues();
411  }
412 
414 
415  // Display diags:
417 
418  // Display new markers from the current screen:
419  for( SCH_ITEM* marker : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
420  {
421  m_parent->GetCanvas()->GetView()->Remove( marker );
422  m_parent->GetCanvas()->GetView()->Add( marker );
423  }
424 
425  m_parent->GetCanvas()->Refresh();
426 }
427 
428 
429 void DIALOG_ERC::OnERCItemSelected( wxDataViewEvent& aEvent )
430 {
431  const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
432  SCH_SHEET_PATH sheet;
433  SCH_ITEM* item = m_parent->Schematic().GetSheets().GetItem( itemID, &sheet );
434 
435  if( item && item->GetClass() != wxT( "DELETED_SHEET_ITEM" ) )
436  {
437  WINDOW_THAWER thawer( m_parent );
438 
439  if( !sheet.empty() && sheet != m_parent->GetCurrentSheet() )
440  {
443 
444  m_parent->SetCurrentSheet( sheet );
446  m_parent->RedrawScreen( (wxPoint) m_parent->GetScreen()->m_ScrollCenter, false );
447  }
448 
449  m_parent->FocusOnItem( item );
450  redrawDrawPanel();
451  }
452 
453  aEvent.Skip();
454 }
455 
456 
457 void DIALOG_ERC::OnERCItemDClick( wxDataViewEvent& aEvent )
458 {
459  if( aEvent.GetItem().IsOk() )
460  {
461  // turn control over to m_parent, hide this DIALOG_ERC window,
462  // no destruction so we can preserve listbox cursor
463  if( !IsModal() )
464  Show( false );
465  }
466 
467  aEvent.Skip();
468 }
469 
470 
471 void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
472 {
473  RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
474 
475  if( !node )
476  return;
477 
478  ERC_SETTINGS& settings = m_parent->Schematic().ErcSettings();
479 
480  std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
481  wxString listName;
482  wxMenu menu;
483  wxString msg;
484 
485  switch( settings.GetSeverity( rcItem->GetErrorCode() ) )
486  {
487  case RPT_SEVERITY_ERROR: listName = _( "errors" ); break;
488  case RPT_SEVERITY_WARNING: listName = _( "warnings" ); break;
489  default: listName = _( "appropriate" ); break;
490  }
491 
492  if( rcItem->GetParent()->IsExcluded() )
493  {
494  menu.Append( 1, _( "Remove exclusion for this violation" ),
495  wxString::Format( _( "It will be placed back in the %s list" ), listName ) );
496  }
497  else
498  {
499  menu.Append( 2, _( "Exclude this violation" ),
500  wxString::Format( _( "It will be excluded from the %s list" ), listName ) );
501  }
502 
503  menu.AppendSeparator();
504 
505  if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_WARNING
506  || rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
507  {
508  // Pin to pin severities edited through pin conflict map
509  }
510  else if( settings.GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING )
511  {
512  menu.Append( 4, wxString::Format( _( "Change severity to Error for all '%s' violations" ),
513  rcItem->GetErrorText() ),
514  _( "Violation severities can also be edited in the Board Setup... dialog" ) );
515  }
516  else
517  {
518  menu.Append( 5, wxString::Format( _( "Change severity to Warning for all '%s' violations" ),
519  rcItem->GetErrorText() ),
520  _( "Violation severities can also be edited in the Board Setup... dialog" ) );
521  }
522 
523  menu.Append( 6, wxString::Format( _( "Ignore all '%s' violations" ), rcItem->GetErrorText() ),
524  _( "Violations will not be checked or reported" ) );
525 
526  menu.AppendSeparator();
527 
528  if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_WARNING
529  || rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
530  {
531  menu.Append( 7, _( "Edit pin-to-pin conflict map..." ) );
532  }
533  else
534  {
535  menu.Append( 8, _( "Edit violation severities..." ),
536  _( "Open the Schematic Setup... dialog" ) );
537  }
538 
539  bool modified = false;
540 
541  switch( GetPopupMenuSelectionFromUser( menu ) )
542  {
543  case 1:
544  {
545  SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() );
546 
547  if( marker )
548  {
549  marker->SetExcluded( false );
550  m_parent->GetCanvas()->GetView()->Update( marker );
551 
552  // Update view
553  static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
554  modified = true;
555  }
556  }
557  break;
558 
559  case 2:
560  {
561  SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() );
562 
563  if( marker )
564  {
565  marker->SetExcluded( true );
566  m_parent->GetCanvas()->GetView()->Update( marker );
567 
568  // Update view
570  static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
571  else
572  static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->DeleteCurrentItem( false );
573 
574  modified = true;
575  }
576  }
577  break;
578 
579  case 4:
580  settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_ERROR );
581 
582  for( SCH_ITEM* item : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
583  {
584  SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
585 
586  if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
587  m_parent->GetCanvas()->GetView()->Update( marker );
588  }
589 
590  // Rebuild model and view
591  static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->SetProvider( m_markerProvider );
592  modified = true;
593  break;
594 
595  case 5:
596  settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_WARNING );
597 
598  for( SCH_ITEM* item : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
599  {
600  SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
601 
602  if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
603  m_parent->GetCanvas()->GetView()->Update( marker );
604  }
605 
606  // Rebuild model and view
607  static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->SetProvider( m_markerProvider );
608  modified = true;
609  break;
610 
611  case 6:
612  {
613  settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_IGNORE );
614 
615  if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
617 
618  SCH_SCREENS ScreenList( m_parent->Schematic().Root() );
619  ScreenList.DeleteMarkers( MARKER_BASE::MARKER_ERC, rcItem->GetErrorCode() );
620 
621  // Rebuild model and view
622  static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->SetProvider( m_markerProvider );
623  modified = true;
624  }
625  break;
626 
627  case 7:
628  m_parent->ShowSchematicSetupDialog( _( "Pin Conflicts Map" ) );
629  break;
630 
631  case 8:
632  m_parent->ShowSchematicSetupDialog( _( "Violation Severity" ) );
633  break;
634  }
635 
636  if( modified )
637  {
639  redrawDrawPanel();
640  m_parent->OnModify();
641  }
642 }
643 
644 
646 {
647  if( m_notebook->GetSelection() != 1 )
648  m_notebook->SetSelection( 1 );
649 
651 }
652 
653 
655 {
656  if( m_notebook->GetSelection() != 1 )
657  m_notebook->SetSelection( 1 );
658 
660 }
661 
662 
664 {
665  if( m_notebook->GetSelection() != 1 )
666  return;
667 
668  RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( m_markerDataView->GetCurrentItem() );
669  SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() );
670 
671  if( marker && !marker->IsExcluded() )
672  {
673  marker->SetExcluded( true );
674  m_parent->GetCanvas()->GetView()->Update( marker );
675 
676  // Update view
679  else
681 
683  redrawDrawPanel();
684  m_parent->OnModify();
685  }
686 }
687 
688 
689 void DIALOG_ERC::OnSeverity( wxCommandEvent& aEvent )
690 {
691  int flag = 0;
692 
693  if( aEvent.GetEventObject() == m_showAll )
695  else if( aEvent.GetEventObject() == m_showErrors )
697  else if( aEvent.GetEventObject() == m_showWarnings )
699  else if( aEvent.GetEventObject() == m_showExclusions )
701 
702  if( aEvent.IsChecked() )
703  m_severities |= flag;
704  else if( aEvent.GetEventObject() == m_showAll )
706  else
707  m_severities &= ~flag;
708 
709  syncCheckboxes();
710 
711  // Set the provider's severity levels through the TreeModel so that the old tree
712  // can be torn down before the severity changes.
713  //
714  // It's not clear this is required, but we've had a lot of issues with wxDataView
715  // being cranky on various platforms.
716 
718 
720 }
721 
722 
723 void DIALOG_ERC::deleteAllMarkers( bool aIncludeExclusions )
724 {
725  // Clear current selection list to avoid selection of deleted items
727 
728  m_markerTreeModel->DeleteItems( false, aIncludeExclusions, true );
729 }
730 
731 
732 void DIALOG_ERC::OnSaveReport( wxCommandEvent& aEvent )
733 {
734  wxFileName fn( "erc." + ReportFileExtension );
735 
736  wxFileDialog dlg( this, _( "Save Report to File" ), Prj().GetProjectPath(), fn.GetFullName(),
737  ReportFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
738 
739  if( dlg.ShowModal() != wxID_OK )
740  return;
741 
742  fn = dlg.GetPath();
743 
744  if( fn.GetExt().IsEmpty() )
745  fn.SetExt( ReportFileExtension );
746 
747  if( !fn.IsAbsolute() )
748  {
749  wxString prj_path = Prj().GetProjectPath();
750  fn.MakeAbsolute( prj_path );
751  }
752 
753  if( writeReport( fn.GetFullPath() ) )
754  {
755  m_messages->Report( wxString::Format( _( "Report file '%s' created\n" ),
756  fn.GetFullPath() ) );
757  }
758  else
759  {
760  DisplayError( this, wxString::Format( _( "Unable to create report file '%s'" ),
761  fn.GetFullPath() ) );
762  }
763 }
764 
765 
766 bool DIALOG_ERC::writeReport( const wxString& aFullFileName )
767 {
768  wxFFile file( aFullFileName, wxT( "wt" ) );
769 
770  if( !file.IsOpened() )
771  return false;
772 
773  wxString msg = wxString::Format( _( "ERC report (%s, Encoding UTF8)\n" ), DateAndTime() );
774 
775  std::map<KIID, EDA_ITEM*> itemMap;
776 
777  int err_count = 0;
778  int warn_count = 0;
779  int total_count = 0;
780  SCH_SHEET_LIST sheetList = m_parent->Schematic().GetSheets();
781 
782  sheetList.FillItemMap( itemMap );
783 
784  ERC_SETTINGS& settings = m_parent->Schematic().ErcSettings();
785 
786  for( unsigned i = 0; i < sheetList.size(); i++ )
787  {
788  msg << wxString::Format( _( "\n***** Sheet %s\n" ), sheetList[i].PathHumanReadable() );
789 
790  for( SCH_ITEM* aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) )
791  {
792  const SCH_MARKER* marker = static_cast<const SCH_MARKER*>( aItem );
793  RC_ITEM* item = marker->GetRCItem().get();
794  SEVERITY severity = settings.GetSeverity( item->GetErrorCode() );
795 
796  if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC )
797  continue;
798 
799  total_count++;
800 
801  switch( severity )
802  {
803  case RPT_SEVERITY_ERROR: err_count++; break;
804  case RPT_SEVERITY_WARNING: warn_count++; break;
805  default: break;
806  }
807 
808  msg << marker->GetRCItem()->ShowReport( GetUserUnits(), severity, itemMap );
809  }
810  }
811 
812  msg << wxString::Format( _( "\n ** ERC messages: %d Errors %d Warnings %d\n" ),
813  total_count, err_count, warn_count );
814 
815  // Currently: write report using UTF8 (as usual in Kicad).
816  // TODO: see if we can use the current encoding page (mainly for Windows users),
817  // Or other format (HTML?)
818  file.Write( msg );
819 
820  // wxFFile dtor will close the file.
821 
822  return true;
823 }
824 
825 
void SetCurrentSheet(const SCH_SHEET_PATH &aSheet)
virtual void AdvancePhase()
Uses the next available virtual zone of the dialog progress bar.
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:252
void DeleteItems(bool aCurrentOnly, bool aIncludeExclusions, bool aDeep)
Deletes the current item or all items.
Definition: rc_item.cpp:463
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:216
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
Definition: infobar.cpp:134
void deleteAllMarkers(bool aIncludeExclusions)
Definition: dialog_erc.cpp:723
void NextMarker()
Definition: rc_item.cpp:573
void OnERCItemRClick(wxDataViewEvent &aEvent) override
Definition: dialog_erc.cpp:471
void AddButton(wxButton *aButton)
Add an already created button to the infobar.
Definition: infobar.cpp:246
void OnCancelClick(wxCommandEvent &event) override
Definition: dialog_erc.cpp:215
wxButton * m_buttondelmarkers
void DeleteMarkers(enum MARKER_BASE::TYPEMARKER aMarkerTyp, int aErrorCode, bool aIncludeExclusions=true)
Delete all markers of a particular type and error code.
Different units of the same symbol have different footprints assigned.
Definition: erc_settings.h:51
virtual void RedrawScreen(const wxPoint &aCenterPoint, bool aWarpPointer)
NUMBER_BADGE * m_errorsBadge
void SetProvider(RC_ITEMS_PROVIDER *aProvider)
Definition: rc_item.cpp:289
This file is part of the common library TODO brief description.
void RecalculateConnections(SCH_CLEANUP_FLAGS aCleanupFlags)
Generate the connection data for the entire schematic hierarchy.
int TestMultUnitPinConflicts()
Checks if shared pins on multi-unit symbols have been connected to different nets.
Definition: erc.cpp:562
RC_TREE_MODEL * m_markerTreeModel
Definition: dialog_erc.h:81
Holds all the data relating to one schematic.
Definition: schematic.h:59
CONNECTION_GRAPH * ConnectionGraph() const override
Definition: schematic.h:129
bool m_running
Definition: dialog_erc.h:83
This file is part of the common library.
void Clear()
Delete the stored messages.
void TestTextVars(DS_PROXY_VIEW_ITEM *aDrawingSheet)
Check for any unresolved text variable references.
Definition: erc.cpp:164
void ExcludeMarker()
Definition: dialog_erc.cpp:663
void syncCheckboxes()
Definition: dialog_erc.cpp:240
const SCH_SHEET_PATH & GetSheetPath() const
Class DIALOG_ERC_BASE.
SEVERITY
Definition: ui_common.h:83
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:194
A progress reporter for use in multi-threaded environments.
void OnLinkClicked(wxHtmlLinkEvent &event) override
Definition: dialog_erc.cpp:249
A holder for a rule check item, DRC in Pcbnew or ERC in Eeschema.
Definition: rc_item.h:74
bool writeReport(const wxString &aFullFileName)
Definition: dialog_erc.cpp:766
void OnEraseDrcMarkersClick(wxCommandEvent &event) override
Definition: dialog_erc.cpp:184
void PrevMarker()
Definition: dialog_erc.cpp:645
void UpdateNumber(int aNumber, SEVERITY aSeverity)
Update the number displayed on the badge.
static TOOL_ACTION cancelInteractive
Definition: actions.h:62
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:352
RC_ITEMS_PROVIDER * m_markerProvider
Definition: dialog_erc.h:80
void ResolveERCExclusions()
Update markers to match recorded exclusions.
wxCheckBox * m_showExclusions
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:143
void updateDisplayedCounts()
Definition: dialog_erc.cpp:157
Definition: erc.h:47
Schematic editor (Eeschema) main window.
static KIID ToUUID(wxDataViewItem aItem)
Definition: rc_item.cpp:144
SCH_SYMBOL * GetSymbol() const
void DisplayCurrentSheet()
Draw the current sheet on the display.
Definition: hierarch.cpp:285
void OnSeverity(wxCommandEvent &aEvent) override
Definition: dialog_erc.cpp:689
virtual int GetCount(int aSeverity=-1) const =0
An implementation of the RC_ITEM_LIST interface which uses the global SHEETLIST to fulfill the contra...
Definition: erc_settings.h:183
int CheckAnnotate(ANNOTATION_ERROR_HANDLER aErrorHandler, ANNOTATE_SCOPE_T aAnnotateScope=ANNOTATE_ALL)
Check for annotation errors.
Definition: annotate.cpp:334
void SetSeverity(int aErrorCode, SEVERITY aSeverity)
wxButton * m_sdbSizer1Cancel
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:123
static int RPT_SEVERITY_ALL
Definition: dialog_erc.cpp:237
Library symbol changed from current symbol in schematic or the library symbol link no longer valid.
Definition: erc_settings.h:66
void DeleteCurrentItem(bool aDeep)
Definition: rc_item.cpp:457
void SetSeverities(int aSeverities)
Definition: rc_item.cpp:295
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:119
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:70
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void FillItemMap(std::map< KIID, EDA_ITEM * > &aMap)
Fill an item cache for temporary use when many items need to be fetched.
void Report(const wxString &aMessage) override
Display aMessage in the progress bar dialog.
Definition: dialog_erc.cpp:151
Definition: kiid.h:44
virtual void SetCurrentProgress(double aProgress)
Set the progress value to aProgress (0..1)
void SetImmediateMode()
In immediate mode, messages are flushed as they are added.
wxCheckBox * m_showAll
void SetExcluded(bool aExcluded)
Definition: marker_base.h:95
int TestConflictingBusAliases()
Check that there are no conflicting bus alias definitions in the schematic.
Definition: erc.cpp:282
std::shared_ptr< RC_ITEM > m_RcItem
Definition: rc_item.h:190
wxButton * m_sdbSizer1OK
static RC_TREE_NODE * ToNode(wxDataViewItem aItem)
Definition: rc_item.h:205
wxString ReportFileWildcard()
int TestMultiunitFootprints()
Test if all units of each multiunit symbol have the same footprint assigned.
Definition: erc.cpp:323
wxStdDialogButtonSizer * m_sdbSizer1
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
std::atomic_bool m_cancelled
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Shared pin in a multi-unit symbol is connected to more than one net.
Definition: erc_settings.h:53
2 labels are equal for case insensitive comparisons.
Definition: erc_settings.h:50
int GetErrorCode() const
Definition: rc_item.h:137
SCHEMATIC & Schematic() const
Definition of file extensions used in Kicad.
int m_severities
Definition: dialog_erc.h:86
DIALOG_ERC(SCH_EDIT_FRAME *parent)
Definition: dialog_erc.cpp:55
#define _(s)
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:53
wxNotebook * m_notebook
Container for ERC settings.
Definition: erc_settings.h:106
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void OnERCItemSelected(wxDataViewEvent &aEvent) override
Definition: dialog_erc.cpp:429
ERCE_T
ERC error codes.
Definition: erc_settings.h:36
void PrevMarker()
Definition: rc_item.cpp:552
wxButton * m_saveReport
SCH_EDIT_FRAME * m_parent
Definition: dialog_erc.h:78
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: infobar.cpp:287
bool Show(bool show) override
void OnCloseErcDialog(wxCloseEvent &event) override
Definition: dialog_erc.cpp:229
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
NUMBER_BADGE * m_warningsBadge
void testErc()
Definition: dialog_erc.cpp:339
void OnERCItemDClick(wxDataViewEvent &aEvent) override
Definition: dialog_erc.cpp:457
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
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:102
void OnAnnotate(wxCommandEvent &event)
SCH_ITEM * GetItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr) const
Fetch a SCH_ITEM by ID.
wxCheckBox * m_showWarnings
A text variable could not be resolved.
Definition: erc_settings.h:64
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
WX_INFOBAR * m_infoBar
A no connect symbol is connected to more than 1 pin.
Definition: erc_settings.h:47
int TestLibSymbolIssues()
Test symbols for changed library symbols and broken symbol library links.
Definition: erc.cpp:675
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:87
wxCheckBox * m_showErrors
SCH_SHEET & Root() const
Definition: schematic.h:92
bool updateUI() override
Definition: dialog_erc.cpp:129
NUMBER_BADGE * m_exclusionsBadge
SCH_SCREEN * LastScreen()
wxDataViewCtrl * m_markerDataView
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:144
enum TYPEMARKER GetMarkerType() const
Definition: marker_base.h:92
const std::string ReportFileExtension
void ForceFocus(wxWindow *aWindow)
Pass the current focus to the window.
Definition: gtk/ui.cpp:44
int TestPinToPin()
Checks the full netlist against the pin-to-pin connectivity requirements.
Definition: erc.cpp:431
EE_RTREE & Items()
Definition: sch_screen.h:102
Conflicting bus alias definitions across sheets.
Definition: erc_settings.h:55
void NextMarker()
Definition: dialog_erc.cpp:654
wxPoint GetPosition() const override
Definition: sch_symbol.h:641
void OnSaveReport(wxCommandEvent &aEvent) override
Definition: dialog_erc.cpp:732
bool m_ercRun
Definition: dialog_erc.h:84
virtual wxString GetClass() const override
Return the class name.
Definition: sch_item.h:206
WX_HTML_REPORT_BOX * m_messages
SCH_SHEET_PATH & GetCurrentSheet() const
void FocusOnItem(SCH_ITEM *aItem)
void AnnotatePowerSymbols()
Silently annotate the not yet annotated power symbols of the entire hierarchy of the sheet path list.
void ValueChanged(const RC_TREE_NODE *aNode)
Definition: rc_item.cpp:440
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:322
VECTOR2D m_ScrollCenter
Current scroll center point in logical units.
Definition: base_screen.h:100
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:54
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
Definition: sch_view.h:97
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current screen and u...
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:136
int TestSimilarLabels()
Checks for labels that differ only in capitalization.
Definition: erc.cpp:621
Duplicate sheet names within a given sheet.
Definition: erc_settings.h:40
void ShowSchematicSetupDialog(const wxString &aInitialPage=wxEmptyString)
void SetMaximumNumber(int aMax)
Set the maximum number to be shown on the badge.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:197
int TestNoConnectPins()
In KiCad 5 and earlier, you could connect stuff up to pins with NC electrical type.
Definition: erc.cpp:389
void RecordERCExclusions()
Scan existing markers and record data from any that are Excluded.
void redrawDrawPanel()
Definition: dialog_erc.cpp:331
int RunERC()
Runs electrical rule checks on the connectivity graph.
std::shared_ptr< RC_ITEM > GetRCItem() const
Definition: marker_base.h:100
A helper to define a symbol's reference designator in a schematic.
wxString DateAndTime()
Definition: string.cpp:492
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:551
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:1504
int TestDuplicateSheetNames(bool aCreateMarker)
Inside a given sheet, one cannot have sheets with duplicate names (file names can be duplicated).
Definition: erc.cpp:118
SEVERITY GetSeverity(int aErrorCode) const
void OnRunERCClick(wxCommandEvent &event) override
Definition: dialog_erc.cpp:261