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 <[email protected]>
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_base.h>
32 #include <bitmaps.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 <id.h>
42 #include <confirm.h>
44 #include <wx/ffile.h>
45 #include <wx/filedlg.h>
46 #include <wx/hyperlink.h>
47 #include <erc_item.h>
48 #include <eeschema_settings.h>
49 #include <string_utils.h>
50 #include <kiplatform/ui.h>
51 
53  DIALOG_ERC_BASE( parent ),
55  m_parent( parent ),
56  m_running( false ),
57  m_ercRun( false ),
59 {
60  SetName( DIALOG_ERC_WINDOW_NAME ); // Set a window name to be able to find it
61 
62  EESCHEMA_SETTINGS* settings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
64 
66 
69  m_markerDataView->AssociateModel( m_markerTreeModel );
70 
75 
76  // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
77  // that requires us to correct the button labels here.
78  m_sdbSizer1OK->SetLabel( _( "Run ERC" ) );
79  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
80  m_sdbSizer1->Layout();
81 
82  m_sdbSizer1OK->SetDefault();
83 
87 
89 
90  // Now all widgets have the size fixed, call FinishDialogSettings
92 }
93 
94 
96 {
97  EESCHEMA_SETTINGS* settings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
98  wxASSERT( settings );
99 
100  if( settings )
102 
103  m_markerTreeModel->DecRef();
104 }
105 
106 
108 {
109  if( m_parent->CheckAnnotate( []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* )
110  { } ) )
111  {
112  if( !m_infoBar->IsShown() )
113  {
114  wxHyperlinkCtrl* button = new wxHyperlinkCtrl( m_infoBar, wxID_ANY,
115  _("Show Annotation dialog"),
116  wxEmptyString );
117 
118  button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(
119  [&]( wxHyperlinkEvent& aEvent )
120  {
121  wxHtmlLinkEvent htmlEvent( aEvent.GetId(),
122  wxHtmlLinkInfo( aEvent.GetURL() ) );
123  OnLinkClicked( htmlEvent );
124  } ) );
125 
127  m_infoBar->AddButton( button );
128  m_infoBar->ShowMessage( _( "Schematic is not fully annotated. "
129  "ERC results will be incomplete." ) );
130  }
131  }
132  else
133  {
134  if( m_infoBar->IsShown() )
135  {
137  m_infoBar->Hide();
138  }
139  }
140 }
141 
142 
143 // PROGRESS_REPORTER calls
144 
146 {
147  // If ERC checks ever get slow enough we'll want a progress indicator...
148  //
149  // double cur = (double) m_progress.load() / m_maxProgress;
150  // cur = std::max( 0.0, std::min( cur, 1.0 ) );
151  //
152  // m_gauge->SetValue( KiROUND( cur * 1000.0 ) );
153  // wxSafeYield( this );
154 
155  return !m_cancelled;
156 }
157 
158 
159 void DIALOG_ERC::AdvancePhase( const wxString& aMessage )
160 {
161  // Will also call Report( aMessage ):
163  SetCurrentProgress( 0.0 );
164 }
165 
166 
167 void DIALOG_ERC::Report( const wxString& aMessage )
168 {
169  m_messages->Report( aMessage );
170 }
171 
172 
174 {
175  int numErrors = 0;
176  int numWarnings = 0;
177  int numExcluded = 0;
178 
179  if( m_markerProvider )
180  {
184  }
185 
186  if( !m_ercRun )
187  {
188  numErrors = -1;
189  numWarnings = -1;
190  }
191 
195 }
196 
197 
198 /* Delete the old ERC markers, over the whole hierarchy
199  */
200 void DIALOG_ERC::OnEraseDrcMarkersClick( wxCommandEvent& event )
201 {
202  bool includeExclusions = false;
203  int numExcluded = 0;
204 
205  if( m_markerProvider )
207 
208  if( numExcluded > 0 )
209  {
210  wxMessageDialog dlg( this, _( "Delete exclusions too?" ), _( "Delete All Markers" ),
211  wxYES_NO | wxCANCEL | wxCENTER | wxICON_QUESTION );
212  dlg.SetYesNoLabels( _( "Errors and Warnings Only" ) , _( "Errors, Warnings and Exclusions" ) );
213 
214  int ret = dlg.ShowModal();
215 
216  if( ret == wxID_CANCEL )
217  return;
218  else if( ret == wxID_NO )
219  includeExclusions = true;
220  }
221 
222  deleteAllMarkers( includeExclusions );
223 
224  m_ercRun = false;
226  m_parent->GetCanvas()->Refresh();
227 }
228 
229 
230 // This is a modeless dialog so we have to handle these ourselves.
231 void DIALOG_ERC::OnCancelClick( wxCommandEvent& aEvent )
232 {
233  if( m_running )
234  {
235  m_cancelled = true;
236  return;
237  }
238 
239  m_parent->FocusOnItem( nullptr );
240 
241  Close();
242 }
243 
244 
245 void DIALOG_ERC::OnCloseErcDialog( wxCloseEvent& event )
246 {
247  m_parent->FocusOnItem( nullptr );
248 
249  m_parent->GetToolManager()->GetTool<EE_INSPECTION_TOOL>()->DestroyERCDialog();
250 }
251 
252 
254 
255 
257 {
258  m_showAll->SetValue( m_severities == RPT_SEVERITY_ALL );
262 }
263 
264 
265 void DIALOG_ERC::OnLinkClicked( wxHtmlLinkEvent& event )
266 {
267  wxCommandEvent dummy;
269 }
270 
271 
272 void DIALOG_ERC::OnRunERCClick( wxCommandEvent& event )
273 {
274  wxBusyCursor busy;
275 
276  SCHEMATIC* sch = &m_parent->Schematic();
277 
279 
281  deleteAllMarkers( true );
282 
283  m_notebook->ChangeSelection( 0 ); // Display the "Tests Running..." tab
284  m_messages->Clear();
285  wxYield(); // Allow time slice to refresh Messages
286 
287  m_running = true;
288  m_sdbSizer1Cancel->SetLabel( _( "Cancel" ) );
289  m_sdbSizer1OK->Enable( false );
290  m_buttondelmarkers->Enable( false );
291  m_saveReport->Enable( false );
292 
294 
295  int itemsNotAnnotated = m_parent->CheckAnnotate(
296  []( ERCE_T aType, const wxString& aMsg, SCH_REFERENCE* aItemA, SCH_REFERENCE* aItemB )
297  {
298  std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aType );
299  ercItem->SetErrorMessage( aMsg );
300 
301  if( aItemB )
302  ercItem->SetItems( aItemA->GetSymbol(), aItemB->GetSymbol() );
303  else
304  ercItem->SetItems( aItemA->GetSymbol() );
305 
306  SCH_MARKER* marker = new SCH_MARKER( ercItem, aItemA->GetSymbol()->GetPosition() );
307  aItemA->GetSheetPath().LastScreen()->Append( marker );
308  } );
309 
310  testErc();
311 
312  if( itemsNotAnnotated )
313  m_messages->ReportHead( wxString::Format( _( "%d symbol(s) require annotation.<br><br>" ),
314  itemsNotAnnotated ), RPT_SEVERITY_INFO );
315 
316  if( m_cancelled )
317  m_messages->Report( _( "-------- ERC cancelled by user.<br><br>" ), RPT_SEVERITY_INFO );
318  else
319  m_messages->Report( _( "ERC completed.<br><br>" ), RPT_SEVERITY_INFO );
320 
321  Raise();
322  wxYield(); // Allow time slice to refresh Messages
323 
324  m_running = false;
325  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
326  m_sdbSizer1OK->Enable( true );
327  m_buttondelmarkers->Enable( true );
328  m_saveReport->Enable( true );
329 
330  if( !m_cancelled )
331  {
332  wxMilliSleep( 500 );
333  m_notebook->ChangeSelection( 1 );
335  }
336 
337  m_ercRun = true;
339 }
340 
341 
343 {
344  WINDOW_THAWER thawer( m_parent );
345 
346  m_parent->GetCanvas()->Refresh();
347 }
348 
349 
351 {
352  wxFileName fn;
353 
354  SCHEMATIC* sch = &m_parent->Schematic();
355 
356  // Build the whole sheet list in hierarchy (sheet, not screen)
358 
359  SCH_SCREENS screens( sch->Root() );
360  ERC_SETTINGS& settings = sch->ErcSettings();
361  ERC_TESTER tester( sch );
362 
363  // Test duplicate sheet names inside a given sheet. While one can have multiple references
364  // to the same file, each must have a unique name.
365  if( settings.IsTestEnabled( ERCE_DUPLICATE_SHEET_NAME ) )
366  {
367  AdvancePhase( _( "Checking sheet names..." ) );
368  tester.TestDuplicateSheetNames( true );
369  }
370 
371  if( settings.IsTestEnabled( ERCE_BUS_ALIAS_CONFLICT ) )
372  {
373  AdvancePhase( _( "Checking bus conflicts..." ) );
374  tester.TestConflictingBusAliases();
375  }
376 
377  // The connection graph has a whole set of ERC checks it can run
378  AdvancePhase( _( "Checking conflicts..." ) );
380  sch->ConnectionGraph()->RunERC();
381 
382  // Test is all units of each multiunit symbol have the same footprint assigned.
383  if( settings.IsTestEnabled( ERCE_DIFFERENT_UNIT_FP ) )
384  {
385  AdvancePhase( _( "Checking footprints..." ) );
386  tester.TestMultiunitFootprints();
387  }
388 
389  AdvancePhase( _( "Checking pins..." ) );
390 
391  if( settings.IsTestEnabled( ERCE_DIFFERENT_UNIT_NET ) )
392  tester.TestMultUnitPinConflicts();
393 
394  // Test pins on each net against the pin connection table
395  if( settings.IsTestEnabled( ERCE_PIN_TO_PIN_ERROR )
396  || settings.IsTestEnabled( ERCE_POWERPIN_NOT_DRIVEN )
397  || settings.IsTestEnabled( ERCE_PIN_NOT_DRIVEN ) )
398  {
399  tester.TestPinToPin();
400  }
401 
402  // Test similar labels (i;e. labels which are identical when
403  // using case insensitive comparisons)
404  if( settings.IsTestEnabled( ERCE_SIMILAR_LABELS ) )
405  {
406  AdvancePhase( _( "Checking labels..." ) );
407  tester.TestSimilarLabels();
408  }
409 
410  if( settings.IsTestEnabled( ERCE_UNRESOLVED_VARIABLE ) )
411  {
412  AdvancePhase( _( "Checking for unresolved variables..." ) );
414  }
415 
416  if( settings.IsTestEnabled( ERCE_NOCONNECT_CONNECTED ) )
417  {
418  AdvancePhase( _( "Checking no connect pins for connections..." ) );
419  tester.TestNoConnectPins();
420  }
421 
422  if( settings.IsTestEnabled( ERCE_LIB_SYMBOL_ISSUES ) )
423  {
424  AdvancePhase( _( "Checking for library symbol issues..." ) );
425  tester.TestLibSymbolIssues();
426  }
427 
429 
430  // Display diags:
432 
433  // Display new markers from the current screen:
434  for( SCH_ITEM* marker : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
435  {
436  m_parent->GetCanvas()->GetView()->Remove( marker );
437  m_parent->GetCanvas()->GetView()->Add( marker );
438  }
439 
440  m_parent->GetCanvas()->Refresh();
441 }
442 
443 
444 void DIALOG_ERC::OnERCItemSelected( wxDataViewEvent& aEvent )
445 {
446  const KIID& itemID = RC_TREE_MODEL::ToUUID( aEvent.GetItem() );
447  SCH_SHEET_PATH sheet;
448  SCH_ITEM* item = m_parent->Schematic().GetSheets().GetItem( itemID, &sheet );
449 
450  if( item && item->GetClass() != wxT( "DELETED_SHEET_ITEM" ) )
451  {
452  WINDOW_THAWER thawer( m_parent );
453 
454  if( !sheet.empty() && sheet != m_parent->GetCurrentSheet() )
455  {
458 
459  m_parent->SetCurrentSheet( sheet );
461  m_parent->RedrawScreen( (wxPoint) m_parent->GetScreen()->m_ScrollCenter, false );
462  }
463 
464  m_parent->FocusOnItem( item );
465  redrawDrawPanel();
466  }
467 
468  aEvent.Skip();
469 }
470 
471 
472 void DIALOG_ERC::OnERCItemDClick( wxDataViewEvent& aEvent )
473 {
474  if( aEvent.GetItem().IsOk() )
475  {
476  // turn control over to m_parent, hide this DIALOG_ERC window,
477  // no destruction so we can preserve listbox cursor
478  if( !IsModal() )
479  Show( false );
480  }
481 
482  aEvent.Skip();
483 }
484 
485 
486 void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
487 {
488  RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aEvent.GetItem() );
489 
490  if( !node )
491  return;
492 
493  ERC_SETTINGS& settings = m_parent->Schematic().ErcSettings();
494 
495  std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
496  wxString listName;
497  wxMenu menu;
498  wxString msg;
499 
500  switch( settings.GetSeverity( rcItem->GetErrorCode() ) )
501  {
502  case RPT_SEVERITY_ERROR: listName = _( "errors" ); break;
503  case RPT_SEVERITY_WARNING: listName = _( "warnings" ); break;
504  default: listName = _( "appropriate" ); break;
505  }
506 
507  if( rcItem->GetParent()->IsExcluded() )
508  {
509  menu.Append( 1, _( "Remove exclusion for this violation" ),
510  wxString::Format( _( "It will be placed back in the %s list" ), listName ) );
511  }
512  else
513  {
514  menu.Append( 2, _( "Exclude this violation" ),
515  wxString::Format( _( "It will be excluded from the %s list" ), listName ) );
516  }
517 
518  menu.AppendSeparator();
519 
520  if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_WARNING
521  || rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
522  {
523  // Pin to pin severities edited through pin conflict map
524  }
525  else if( settings.GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING )
526  {
527  menu.Append( 4, wxString::Format( _( "Change severity to Error for all '%s' violations" ),
528  rcItem->GetErrorText() ),
529  _( "Violation severities can also be edited in the Board Setup... dialog" ) );
530  }
531  else
532  {
533  menu.Append( 5, wxString::Format( _( "Change severity to Warning for all '%s' violations" ),
534  rcItem->GetErrorText() ),
535  _( "Violation severities can also be edited in the Board Setup... dialog" ) );
536  }
537 
538  menu.Append( 6, wxString::Format( _( "Ignore all '%s' violations" ), rcItem->GetErrorText() ),
539  _( "Violations will not be checked or reported" ) );
540 
541  menu.AppendSeparator();
542 
543  if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_WARNING
544  || rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
545  {
546  menu.Append( 7, _( "Edit pin-to-pin conflict map..." ) );
547  }
548  else
549  {
550  menu.Append( 8, _( "Edit violation severities..." ),
551  _( "Open the Schematic Setup... dialog" ) );
552  }
553 
554  bool modified = false;
555 
556  switch( GetPopupMenuSelectionFromUser( menu ) )
557  {
558  case 1:
559  {
560  SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() );
561 
562  if( marker )
563  {
564  marker->SetExcluded( false );
565  m_parent->GetCanvas()->GetView()->Update( marker );
566 
567  // Update view
568  static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
569  modified = true;
570  }
571  }
572  break;
573 
574  case 2:
575  {
576  SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() );
577 
578  if( marker )
579  {
580  marker->SetExcluded( true );
581  m_parent->GetCanvas()->GetView()->Update( marker );
582 
583  // Update view
585  static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->ValueChanged( node );
586  else
587  static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->DeleteCurrentItem( false );
588 
589  modified = true;
590  }
591  }
592  break;
593 
594  case 4:
595  settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_ERROR );
596 
597  for( SCH_ITEM* item : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
598  {
599  SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
600 
601  if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
602  m_parent->GetCanvas()->GetView()->Update( marker );
603  }
604 
605  // Rebuild model and view
606  static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->SetProvider( m_markerProvider );
607  modified = true;
608  break;
609 
610  case 5:
611  settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_WARNING );
612 
613  for( SCH_ITEM* item : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
614  {
615  SCH_MARKER* marker = static_cast<SCH_MARKER*>( item );
616 
617  if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
618  m_parent->GetCanvas()->GetView()->Update( marker );
619  }
620 
621  // Rebuild model and view
622  static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->SetProvider( m_markerProvider );
623  modified = true;
624  break;
625 
626  case 6:
627  {
628  settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_IGNORE );
629 
630  if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
632 
633  SCH_SCREENS ScreenList( m_parent->Schematic().Root() );
634  ScreenList.DeleteMarkers( MARKER_BASE::MARKER_ERC, rcItem->GetErrorCode() );
635 
636  // Rebuild model and view
637  static_cast<RC_TREE_MODEL*>( aEvent.GetModel() )->SetProvider( m_markerProvider );
638  modified = true;
639  }
640  break;
641 
642  case 7:
643  m_parent->ShowSchematicSetupDialog( _( "Pin Conflicts Map" ) );
644  break;
645 
646  case 8:
647  m_parent->ShowSchematicSetupDialog( _( "Violation Severity" ) );
648  break;
649  }
650 
651  if( modified )
652  {
654  redrawDrawPanel();
655  m_parent->OnModify();
656  }
657 }
658 
659 
661 {
662  if( m_notebook->GetSelection() != 1 )
663  m_notebook->SetSelection( 1 );
664 
666 }
667 
668 
670 {
671  if( m_notebook->GetSelection() != 1 )
672  m_notebook->SetSelection( 1 );
673 
675 }
676 
677 
679 {
680  SCH_MARKER* marker = aMarker;
681 
682  if( marker != nullptr )
683  m_markerTreeModel->SelectMarker( marker );
684 
685  if( m_notebook->GetSelection() != 1 )
686  return;
687 
688  RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( m_markerDataView->GetCurrentItem() );
689 
690  if( node && node->m_RcItem )
691  marker = dynamic_cast<SCH_MARKER*>( node->m_RcItem->GetParent() );
692 
693  if( node && marker && !marker->IsExcluded() )
694  {
695  marker->SetExcluded( true );
696  m_parent->GetCanvas()->GetView()->Update( marker );
697 
698  // Update view
701  else
703 
705  redrawDrawPanel();
706  m_parent->OnModify();
707  }
708 }
709 
710 
711 void DIALOG_ERC::OnSeverity( wxCommandEvent& aEvent )
712 {
713  int flag = 0;
714 
715  if( aEvent.GetEventObject() == m_showAll )
717  else if( aEvent.GetEventObject() == m_showErrors )
719  else if( aEvent.GetEventObject() == m_showWarnings )
721  else if( aEvent.GetEventObject() == m_showExclusions )
723 
724  if( aEvent.IsChecked() )
725  m_severities |= flag;
726  else if( aEvent.GetEventObject() == m_showAll )
728  else
729  m_severities &= ~flag;
730 
731  syncCheckboxes();
732 
733  // Set the provider's severity levels through the TreeModel so that the old tree
734  // can be torn down before the severity changes.
735  //
736  // It's not clear this is required, but we've had a lot of issues with wxDataView
737  // being cranky on various platforms.
738 
740 
742 }
743 
744 
745 void DIALOG_ERC::deleteAllMarkers( bool aIncludeExclusions )
746 {
747  // Clear current selection list to avoid selection of deleted items
749 
750  m_markerTreeModel->DeleteItems( false, aIncludeExclusions, true );
751 }
752 
753 
754 void DIALOG_ERC::OnSaveReport( wxCommandEvent& aEvent )
755 {
756  wxFileName fn( wxT( "ERC." ) + ReportFileExtension );
757 
758  wxFileDialog dlg( this, _( "Save Report to File" ), Prj().GetProjectPath(), fn.GetFullName(),
759  ReportFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
760 
761  if( dlg.ShowModal() != wxID_OK )
762  return;
763 
764  fn = dlg.GetPath();
765 
766  if( fn.GetExt().IsEmpty() )
767  fn.SetExt( ReportFileExtension );
768 
769  if( !fn.IsAbsolute() )
770  {
771  wxString prj_path = Prj().GetProjectPath();
772  fn.MakeAbsolute( prj_path );
773  }
774 
775  if( writeReport( fn.GetFullPath() ) )
776  {
777  m_messages->Report( wxString::Format( _( "Report file '%s' created." ),
778  fn.GetFullPath() ) );
779  }
780  else
781  {
782  DisplayError( this, wxString::Format( _( "Failed to create file '%s'." ),
783  fn.GetFullPath() ) );
784  }
785 }
786 
787 
788 bool DIALOG_ERC::writeReport( const wxString& aFullFileName )
789 {
790  wxFFile file( aFullFileName, wxT( "wt" ) );
791 
792  if( !file.IsOpened() )
793  return false;
794 
795  wxString msg = wxString::Format( _( "ERC report (%s, Encoding UTF8)\n" ), DateAndTime() );
796 
797  std::map<KIID, EDA_ITEM*> itemMap;
798 
799  int err_count = 0;
800  int warn_count = 0;
801  int total_count = 0;
802  SCH_SHEET_LIST sheetList = m_parent->Schematic().GetSheets();
803 
804  sheetList.FillItemMap( itemMap );
805 
806  ERC_SETTINGS& settings = m_parent->Schematic().ErcSettings();
807 
808  for( unsigned i = 0; i < sheetList.size(); i++ )
809  {
810  msg << wxString::Format( _( "\n***** Sheet %s\n" ), sheetList[i].PathHumanReadable() );
811 
812  for( SCH_ITEM* aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) )
813  {
814  const SCH_MARKER* marker = static_cast<const SCH_MARKER*>( aItem );
815  RC_ITEM* item = marker->GetRCItem().get();
816  SEVERITY severity = settings.GetSeverity( item->GetErrorCode() );
817 
818  if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC )
819  continue;
820 
821  total_count++;
822 
823  switch( severity )
824  {
825  case RPT_SEVERITY_ERROR: err_count++; break;
826  case RPT_SEVERITY_WARNING: warn_count++; break;
827  default: break;
828  }
829 
830  msg << marker->GetRCItem()->ShowReport( GetUserUnits(), severity, itemMap );
831  }
832  }
833 
834  msg << wxString::Format( _( "\n ** ERC messages: %d Errors %d Warnings %d\n" ),
835  total_count, err_count, warn_count );
836 
837  // Currently: write report using UTF8 (as usual in Kicad).
838  // TODO: see if we can use the current encoding page (mainly for Windows users),
839  // Or other format (HTML?)
840  file.Write( msg );
841 
842  // wxFFile dtor will close the file.
843 
844  return true;
845 }
846 
847 
void SetCurrentSheet(const SCH_SHEET_PATH &aSheet)
void ExcludeMarker(SCH_MARKER *aMarker=nullptr)
Exclude aMarker from the ERC list.
Definition: dialog_erc.cpp:678
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:279
void DeleteItems(bool aCurrentOnly, bool aIncludeExclusions, bool aDeep)
Deletes the current item or all items.
Definition: rc_item.cpp:467
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:230
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:142
void deleteAllMarkers(bool aIncludeExclusions)
Definition: dialog_erc.cpp:745
void NextMarker()
Definition: rc_item.cpp:577
void OnERCItemRClick(wxDataViewEvent &aEvent) override
Definition: dialog_erc.cpp:486
void AddButton(wxButton *aButton)
Add an already created button to the infobar.
Definition: infobar.cpp:245
void OnCancelClick(wxCommandEvent &event) override
Definition: dialog_erc.cpp:231
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:294
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:567
Power input pin connected to some others pins but no power out pin to drive it.
Definition: erc_settings.h:44
RC_TREE_MODEL * m_markerTreeModel
Definition: dialog_erc.h:96
Holds all the data relating to one schematic.
Definition: schematic.h:59
CONNECTION_GRAPH * ConnectionGraph() const override
Definition: schematic.h:131
bool m_running
Definition: dialog_erc.h:98
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 syncCheckboxes()
Definition: dialog_erc.cpp:256
const SCH_SHEET_PATH & GetSheetPath() const
virtual void AdvancePhase() override
Use the next available virtual zone of the dialog progress bar.
Class DIALOG_ERC_BASE.
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
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
void OnLinkClicked(wxHtmlLinkEvent &event) override
Definition: dialog_erc.cpp:265
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:788
void OnEraseDrcMarkersClick(wxCommandEvent &event) override
Definition: dialog_erc.cpp:200
void PrevMarker()
Definition: dialog_erc.cpp:660
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:350
RC_ITEMS_PROVIDER * m_markerProvider
Definition: dialog_erc.h:95
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:173
Definition: erc.h:47
Schematic editor (Eeschema) main window.
static KIID ToUUID(wxDataViewItem aItem)
Definition: rc_item.cpp:147
SCH_SYMBOL * GetSymbol() const
void DisplayCurrentSheet()
Draw the current sheet on the display.
Definition: hierarch.cpp:313
void OnSeverity(wxCommandEvent &aEvent) override
Definition: dialog_erc.cpp:711
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:352
void SetSeverity(int aErrorCode, SEVERITY aSeverity)
wxButton * m_sdbSizer1Cancel
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:122
static int RPT_SEVERITY_ALL
Definition: dialog_erc.cpp:253
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:461
void SetSeverities(int aSeverities)
Definition: rc_item.cpp:300
#define DIALOG_ERC_WINDOW_NAME
Definition: dialog_erc.h:37
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:121
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:72
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:167
Definition: kiid.h:44
void SetImmediateMode()
In immediate mode, messages are flushed as they are added.
wxCheckBox * m_showAll
void SetExcluded(bool aExcluded)
Definition: marker_base.h:96
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:197
Pin connected to some others pins but no pin to drive it.
Definition: erc_settings.h:42
wxButton * m_sdbSizer1OK
static RC_TREE_NODE * ToNode(wxDataViewItem aItem)
Definition: rc_item.h:212
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.
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void UpdateAnnotationWarning()
Definition: dialog_erc.cpp:107
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:139
SCHEMATIC & Schematic() const
Definition of file extensions used in Kicad.
void SelectMarker(const MARKER_BASE *aMarker)
Definition: rc_item.cpp:605
int m_severities
Definition: dialog_erc.h:101
DIALOG_ERC(SCH_EDIT_FRAME *parent)
Definition: dialog_erc.cpp:52
#define _(s)
bool IsExcluded() const
Definition: marker_base.h:95
static TOOL_ACTION clearSelection
Clears the current selection.
Definition: ee_actions.h:56
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:444
SEVERITY
ERCE_T
ERC error codes.
Definition: erc_settings.h:36
void PrevMarker()
Definition: rc_item.cpp:556
wxButton * m_saveReport
SCH_EDIT_FRAME * m_parent
Definition: dialog_erc.h:93
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: infobar.cpp:286
bool Show(bool show) override
void OnCloseErcDialog(wxCloseEvent &event) override
Definition: dialog_erc.cpp:245
NUMBER_BADGE * m_warningsBadge
This implements all the tricky bits for thread safety, but the GUI is left to derived classes.
void testErc()
Definition: dialog_erc.cpp:350
void OnERCItemDClick(wxDataViewEvent &aEvent) override
Definition: dialog_erc.cpp:472
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:108
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:680
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:145
NUMBER_BADGE * m_exclusionsBadge
SCH_SCREEN * LastScreen()
wxDataViewCtrl * m_markerDataView
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:146
enum TYPEMARKER GetMarkerType() const
Definition: marker_base.h:93
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()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:110
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
Conflicting bus alias definitions across sheets.
Definition: erc_settings.h:55
void NextMarker()
Definition: dialog_erc.cpp:669
wxPoint GetPosition() const override
Definition: sch_symbol.h:645
void OnSaveReport(wxCommandEvent &aEvent) override
Definition: dialog_erc.cpp:754
bool m_ercRun
Definition: dialog_erc.h:99
virtual wxString GetClass() const override
Return the class name.
Definition: sch_item.h:193
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:444
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:320
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:98
virtual void SetCurrentProgress(double aProgress) override
Set the progress value to aProgress (0..1).
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:174
int TestSimilarLabels()
Checks for labels that differ only in capitalization.
Definition: erc.cpp:626
Duplicate sheet names within a given sheet.
Definition: erc_settings.h:40
void ShowSchematicSetupDialog(const wxString &aInitialPage=wxEmptyString)
wxString DateAndTime()
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:182
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:342
int RunERC()
Runs electrical rule checks on the connectivity graph.
std::shared_ptr< RC_ITEM > GetRCItem() const
Definition: marker_base.h:101
A helper to define a symbol's reference designator in a schematic.
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:593
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:1570
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:272