KiCad PCB EDA Suite
BACK_ANNOTATE Class Reference

Back annotation algorithm class used to recieve, check, and apply a NETLIST from PCBNEW. More...

#include <backannotate.h>

Classes

struct  PCB_MODULE_DATA
 Struct to hold PCBnew module data. More...
 

Public Types

using PCB_MODULES_MAP = std::map< wxString, std::shared_ptr< PCB_MODULE_DATA > >
 

Map to hold NETLIST modules data

More...
 
using CHANGELIST_ITEM = std::pair< SCH_REFERENCE, std::shared_ptr< PCB_MODULE_DATA > >
 

Public Member Functions

 BACK_ANNOTATE (SCH_EDIT_FRAME *aFrame, REPORTER &aReporter, bool aProcessFootprints, bool aProcessValues, bool aProcessReferences, bool aProcessNetNames, bool aIgnoreOtherProjects, bool aDryRun)
 
 ~BACK_ANNOTATE ()
 
bool FetchNetlistFromPCB (std::string &aNetlist)
 Get netlist from the PCBnew. More...
 
bool BackAnnotateSymbols (const std::string &aNetlist)
 Run back annotation algorithm. More...
 

Private Member Functions

wxString getTextFromField (const SCH_REFERENCE &aRef, const NumFieldType aField)
 

Get text from symbol's field ( such as Footprint or Value )

More...
 
bool checkReuseViolation (PCB_MODULE_DATA &aFirst, PCB_MODULE_DATA &aSecond)
 Check if modules has different data. More...
 
void getPcbModulesFromString (const std::string &aPayload)
 Parse netlist sent over KiWay epress mail interface and fill m_pcbModules. More...
 
void getChangeList ()
 

Create changelist

More...
 
void checkForUnusedSymbols ()
 Check if some symbols are not represented in PCB modules and vice versa. More...
 
void checkSharedSchematicErrors ()
 Check for errors connected to reusing schematic in project or between projects. More...
 
void applyChangelist ()
 Apply changelist to the schematic. More...
 
void processNetNameChange (SCH_CONNECTION *aConn, const wxString &aOldName, const wxString &aNewName)
 

Private Attributes

REPORTERm_reporter
 
bool m_processFootprints
 
bool m_processValues
 
bool m_processReferences
 
bool m_processNetNames
 
bool m_ignoreOtherProjects
 
bool m_dryRun
 
PCB_MODULES_MAP m_pcbModules
 
SCH_REFERENCE_LIST m_refs
 
SCH_MULTI_UNIT_REFERENCE_MAP m_multiUnitsRefs
 
std::deque< CHANGELIST_ITEMm_changelist
 
SCH_EDIT_FRAMEm_frame
 
int m_changesCount
 

To count number of changes applied to the schematic

More...
 

Detailed Description

Back annotation algorithm class used to recieve, check, and apply a NETLIST from PCBNEW.

The following checks are made:

  • Schematic symbol exists, but linked PCBnew module missing
  • PCBnew module exists but no schematic symbol connected to
  • PCBnew module is standalone
  • Schematic sheet is reused one or more times and user trying to change footprint or value only for few of them.
  • Schematic symbols share same path
  • More than one PCBnew module linked to same path

Definition at line 55 of file backannotate.h.

Member Typedef Documentation

◆ CHANGELIST_ITEM

using BACK_ANNOTATE::CHANGELIST_ITEM = std::pair<SCH_REFERENCE, std::shared_ptr<PCB_MODULE_DATA> >

Definition at line 80 of file backannotate.h.

◆ PCB_MODULES_MAP

using BACK_ANNOTATE::PCB_MODULES_MAP = std::map<wxString, std::shared_ptr<PCB_MODULE_DATA> >

Map to hold NETLIST modules data

Definition at line 78 of file backannotate.h.

Constructor & Destructor Documentation

◆ BACK_ANNOTATE()

BACK_ANNOTATE::BACK_ANNOTATE ( SCH_EDIT_FRAME aFrame,
REPORTER aReporter,
bool  aProcessFootprints,
bool  aProcessValues,
bool  aProcessReferences,
bool  aProcessNetNames,
bool  aIgnoreOtherProjects,
bool  aDryRun 
)

Definition at line 38 of file backannotate.cpp.

41  :
42  m_reporter( aReporter ),
43  m_processFootprints( aProcessFootprints ),
44  m_processValues( aProcessValues ),
45  m_processReferences( aProcessReferences ),
46  m_processNetNames( aProcessNetNames ),
47  m_ignoreOtherProjects( aIgnoreOtherProjects ),
48  m_dryRun( aDryRun ),
49  m_frame( aFrame ),
50  m_changesCount( 0 )
51 {
52 }
SCH_EDIT_FRAME * m_frame
Definition: backannotate.h:116
bool m_processNetNames
Definition: backannotate.h:108
bool m_processFootprints
Definition: backannotate.h:105
bool m_processReferences
Definition: backannotate.h:107
REPORTER & m_reporter
Definition: backannotate.h:103
bool m_processValues
Definition: backannotate.h:106
bool m_ignoreOtherProjects
Definition: backannotate.h:109
int m_changesCount
To count number of changes applied to the schematic
Definition: backannotate.h:119

◆ ~BACK_ANNOTATE()

BACK_ANNOTATE::~BACK_ANNOTATE ( )

Definition at line 55 of file backannotate.cpp.

56 {
57 }

Member Function Documentation

◆ applyChangelist()

void BACK_ANNOTATE::applyChangelist ( )
private

Apply changelist to the schematic.

Definition at line 359 of file backannotate.cpp.

360 {
361  std::set<wxString> handledNetChanges;
362  wxString msg;
363  int leftUnchanged = 0;
364 
365  // Apply changes from change list
366  for( CHANGELIST_ITEM& item : m_changelist )
367  {
368  SCH_REFERENCE& ref = item.first;
369  PCB_MODULE_DATA& module = *item.second;
370  wxString oldFootprint = getTextFromField( ref, FOOTPRINT );
371  wxString oldValue = getTextFromField( ref, VALUE );
372  int changesCountBefore = m_changesCount;
373  bool skip = ( ref.GetComp()->GetFlags() & SKIP_STRUCT ) > 0;
374 
375  if( m_processReferences && ref.GetRef() != module.m_ref && !skip )
376  {
377  ++m_changesCount;
378  msg.Printf( _( "Change \"%s\" reference designator to \"%s\"." ),
379  ref.GetFullRef(),
380  module.m_ref );
381 
382  if( !m_dryRun )
383  ref.GetComp()->SetRef( &ref.GetSheetPath(), module.m_ref );
384 
386  }
387 
388  if( m_processFootprints && oldFootprint != module.m_footprint && !skip )
389  {
390  ++m_changesCount;
391  msg.Printf( _( "Change %s footprint from \"%s\" to \"%s\"." ),
392  ref.GetFullRef(),
393  getTextFromField( ref, FOOTPRINT ),
394  module.m_footprint );
395 
396  if( !m_dryRun )
397  ref.GetComp()->GetField( FOOTPRINT )->SetText( module.m_footprint );
398 
400  }
401 
402  if( m_processValues && oldValue != module.m_value && !skip )
403  {
404  ++m_changesCount;
405  msg.Printf( _( "Change %s value from \"%s\" to \"%s\"." ),
406  ref.GetFullRef(),
407  getTextFromField( ref, VALUE ),
408  module.m_value );
409 
410  if( !m_dryRun )
411  item.first.GetComp()->GetField( VALUE )->SetText( module.m_value );
412 
414  }
415 
416  if( m_processNetNames )
417  {
418  for( const std::pair<const wxString, wxString>& entry : module.m_pinMap )
419  {
420  const wxString& pinNumber = entry.first;
421  const wxString& shortNetName = entry.second;
422  SCH_COMPONENT* comp = ref.GetComp();
423  LIB_PIN* pin = comp->GetPin( pinNumber );
424  SCH_CONNECTION* conn = comp->GetConnectionForPin( pin, ref.GetSheetPath() );
425 
426  wxString key = shortNetName + ref.GetSheetPath().PathAsString();
427 
428  if( handledNetChanges.count( key ) )
429  continue;
430  else
431  handledNetChanges.insert( key );
432 
433  if( conn && conn->Name( true ) != shortNetName )
434  processNetNameChange( conn, conn->Name( true ), shortNetName );
435  }
436  }
437 
438  if( changesCountBefore == m_changesCount )
439  ++leftUnchanged;
440  }
441  msg.Printf( _( "%d symbols left unchanged" ), leftUnchanged );
443 }
wxString getTextFromField(const SCH_REFERENCE &aRef, const NumFieldType aField)
Get text from symbol's field ( such as Footprint or Value )
const SCH_SHEET_PATH & GetSheetPath() const
#define SKIP_STRUCT
flag indicating that the structure should be ignored
Definition: base_struct.h:128
SCH_COMPONENT * GetComp() const
bool m_processNetNames
Definition: backannotate.h:108
bool m_processFootprints
Definition: backannotate.h:105
wxString PathAsString() const
Function PathAsString the path uses the time stamps which do not changes even when editing sheet para...
LIB_PIN * GetPin(const wxString &number)
Find a symbol pin by number.
bool m_processReferences
Definition: backannotate.h:107
Field Name Module PCB, i.e. "16DIP300".
REPORTER & m_reporter
Definition: backannotate.h:103
wxString GetRef() const
bool m_processValues
Definition: backannotate.h:106
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:116
std::pair< SCH_REFERENCE, std::shared_ptr< PCB_MODULE_DATA > > CHANGELIST_ITEM
Definition: backannotate.h:80
void processNetNameChange(SCH_CONNECTION *aConn, const wxString &aOldName, const wxString &aNewName)
SCH_CONNECTION * GetConnectionForPin(LIB_PIN *aPin, const SCH_SHEET_PATH &aSheet)
Retrieves the connection for a given pin of the component.
const wxString & Name(bool aIgnoreSheet=false) const
virtual REPORTER & ReportHead(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Function ReportHead Places the report at the beginning of the list for objects that support ordering.
Definition: reporter.h:103
SCH_FIELD * GetField(int aFieldNdx)
Returns a field in this symbol.
Field Value of part, i.e. "3.3K".
wxString GetFullRef()
Return reference name with unit altogether
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
#define _(s)
Definition: 3d_actions.cpp:33
Schematic symbol object.
Definition: sch_component.h:88
int m_changesCount
To count number of changes applied to the schematic
Definition: backannotate.h:119
std::deque< CHANGELIST_ITEM > m_changelist
Definition: backannotate.h:115
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:234
SCH_REFERENCE is used as a helper to define a component's reference designator in a schematic.

References _, FOOTPRINT, SCH_REFERENCE::GetComp(), SCH_COMPONENT::GetConnectionForPin(), SCH_COMPONENT::GetField(), EDA_ITEM::GetFlags(), SCH_REFERENCE::GetFullRef(), SCH_COMPONENT::GetPin(), SCH_REFERENCE::GetRef(), SCH_REFERENCE::GetSheetPath(), getTextFromField(), m_changelist, m_changesCount, m_dryRun, BACK_ANNOTATE::PCB_MODULE_DATA::m_footprint, BACK_ANNOTATE::PCB_MODULE_DATA::m_pinMap, m_processFootprints, m_processNetNames, m_processReferences, m_processValues, BACK_ANNOTATE::PCB_MODULE_DATA::m_ref, m_reporter, BACK_ANNOTATE::PCB_MODULE_DATA::m_value, SCH_CONNECTION::Name(), SCH_SHEET_PATH::PathAsString(), processNetNameChange(), REPORTER::ReportHead(), RPT_SEVERITY_ACTION, RPT_SEVERITY_INFO, SCH_COMPONENT::SetRef(), EDA_TEXT::SetText(), SKIP_STRUCT, and VALUE.

Referenced by BackAnnotateSymbols().

◆ BackAnnotateSymbols()

bool BACK_ANNOTATE::BackAnnotateSymbols ( const std::string &  aNetlist)

Run back annotation algorithm.

If any errors, back annotation doesn't run. only report

Parameters
aNetlistnetlist to run back annotation from
Returns
true if success

Definition at line 60 of file backannotate.cpp.

61 {
62  m_changesCount = 0;
63  wxString msg;
64 
66  {
67  m_reporter.ReportTail( _( "Select at least one property to back annotate." ),
69  return false;
70  }
71 
72  getPcbModulesFromString( aNetlist );
73 
75  sheets.GetComponents( m_refs, false );
77 
78  getChangeList();
81 
84  m_frame->SetCurrentSheet( current );
85 
86  return true;
87 }
void SetCurrentSheet(const SCH_SHEET_PATH &aSheet)
SCH_SHEET_LIST.
SCH_SHEET_LIST GetSheets() const
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:92
SCH_EDIT_FRAME * m_frame
Definition: backannotate.h:116
bool m_processNetNames
Definition: backannotate.h:108
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Function ReportTail Places the report at the end of the list, for objects that support report orderin...
Definition: reporter.h:94
bool m_processFootprints
Definition: backannotate.h:105
bool m_processReferences
Definition: backannotate.h:107
void getPcbModulesFromString(const std::string &aPayload)
Parse netlist sent over KiWay epress mail interface and fill m_pcbModules.
void GetMultiUnitComponents(SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols=true) const
Function GetMultiUnitComponents adds a SCH_REFERENCE_LIST object to aRefList for each same-reference ...
void checkForUnusedSymbols()
Check if some symbols are not represented in PCB modules and vice versa.
REPORTER & m_reporter
Definition: backannotate.h:103
bool m_processValues
Definition: backannotate.h:106
void GetComponents(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanComponents=false) const
Function GetComponents adds a SCH_REFERENCE() object to aReferences for each component in the list of...
SCHEMATIC & Schematic() const
SCH_SHEET_PATH.
void getChangeList()
Create changelist
void checkSharedSchematicErrors()
Check for errors connected to reusing schematic in project or between projects.
void applyChangelist()
Apply changelist to the schematic.
#define _(s)
Definition: 3d_actions.cpp:33
SCH_SHEET_PATH & GetCurrentSheet() const
SCH_REFERENCE_LIST m_refs
Definition: backannotate.h:113
int m_changesCount
To count number of changes applied to the schematic
Definition: backannotate.h:119
SCH_MULTI_UNIT_REFERENCE_MAP m_multiUnitsRefs
Definition: backannotate.h:114

References _, applyChangelist(), checkForUnusedSymbols(), checkSharedSchematicErrors(), getChangeList(), SCH_SHEET_LIST::GetComponents(), SCH_EDIT_FRAME::GetCurrentSheet(), SCH_SHEET_LIST::GetMultiUnitComponents(), getPcbModulesFromString(), SCHEMATIC::GetSheets(), m_changesCount, m_frame, m_multiUnitsRefs, m_processFootprints, m_processNetNames, m_processReferences, m_processValues, m_refs, m_reporter, REPORTER::ReportTail(), RPT_SEVERITY_ERROR, SCH_EDIT_FRAME::Schematic(), and SCH_EDIT_FRAME::SetCurrentSheet().

Referenced by DIALOG_UPDATE_FROM_PCB::updateData().

◆ checkForUnusedSymbols()

void BACK_ANNOTATE::checkForUnusedSymbols ( )
private

Check if some symbols are not represented in PCB modules and vice versa.

m_refs must be sorted by path

Definition at line 244 of file backannotate.cpp.

245 {
247 
248  std::sort( m_changelist.begin(), m_changelist.end(),
249  []( const CHANGELIST_ITEM& a, const CHANGELIST_ITEM& b )
250  {
251  return SCH_REFERENCE_LIST::sortByTimeStamp( a.first, b.first );
252  } );
253 
254  size_t i = 0;
255 
256  for( auto& item : m_changelist )
257  {
258  // Refs and changelist are both sorted by paths, so we just go over m_refs and
259  // generate errors before we will find m_refs member to which item linked
260  while( i < m_refs.GetCount() && m_refs[i].GetPath() != item.first.GetPath() )
261  {
262  wxString msg;
263  msg.Printf( _( "Cannot find footprint for \"%s\" symbol" ), m_refs[i++].GetFullRef() );
265  }
266 
267  ++i;
268  }
269 }
static bool sortByTimeStamp(const SCH_REFERENCE &item1, const SCH_REFERENCE &item2)
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Function ReportTail Places the report at the end of the list, for objects that support report orderin...
Definition: reporter.h:94
REPORTER & m_reporter
Definition: backannotate.h:103
void SortByTimeStamp()
Function SortComponentsByTimeStamp sort the flat list by Time Stamp (sheet path + timestamp).
std::pair< SCH_REFERENCE, std::shared_ptr< PCB_MODULE_DATA > > CHANGELIST_ITEM
Definition: backannotate.h:80
unsigned GetCount() const
Function GetCount.
#define _(s)
Definition: 3d_actions.cpp:33
SCH_REFERENCE_LIST m_refs
Definition: backannotate.h:113
std::deque< CHANGELIST_ITEM > m_changelist
Definition: backannotate.h:115

References _, SCH_REFERENCE_LIST::GetCount(), m_changelist, m_refs, m_reporter, REPORTER::ReportTail(), RPT_SEVERITY_ERROR, SCH_REFERENCE_LIST::SortByTimeStamp(), and SCH_REFERENCE_LIST::sortByTimeStamp().

Referenced by BackAnnotateSymbols().

◆ checkReuseViolation()

bool BACK_ANNOTATE::checkReuseViolation ( PCB_MODULE_DATA aFirst,
PCB_MODULE_DATA aSecond 
)
private

Check if modules has different data.

Check only if corresponding m_boardAdapter flag is rised

Parameters
aFirstfirst module to compare
aSecondsecond module to compare
Returns
true if no violation

Definition at line 272 of file backannotate.cpp.

273 {
274  if( m_processFootprints && aFirst.m_footprint != aSecond.m_footprint )
275  return false;
276 
277  if( m_processValues && aFirst.m_value != aSecond.m_value )
278  return false;
279 
280  return true;
281 }
bool m_processFootprints
Definition: backannotate.h:105
bool m_processValues
Definition: backannotate.h:106

References BACK_ANNOTATE::PCB_MODULE_DATA::m_footprint, m_processFootprints, m_processValues, and BACK_ANNOTATE::PCB_MODULE_DATA::m_value.

Referenced by checkSharedSchematicErrors().

◆ checkSharedSchematicErrors()

void BACK_ANNOTATE::checkSharedSchematicErrors ( )
private

Check for errors connected to reusing schematic in project or between projects.

Definition at line 289 of file backannotate.cpp.

290 {
291  std::sort( m_changelist.begin(), m_changelist.end(),
292  []( CHANGELIST_ITEM& a, CHANGELIST_ITEM& b )
293  {
294  return a.first.GetComp() > b.first.GetComp();
295  } );
296 
297  // We don't check that if no footprints or values updating
299  return;
300 
301  // We will count how many times every component used in our changelist
302  // Component in this case is SCH_COMPONENT which can be used by more than one symbol
303  int usageCount = 1;
304 
305  for( auto it = m_changelist.begin(); it != m_changelist.end(); ++it )
306  {
307  int compUsage = it->first.GetComp()->GetInstanceReferences().size();
308 
309  if( compUsage == 1 )
310  continue;
311 
312  // If that's not the last reference in list and references share same component
313  if( ( it + 1 ) != m_changelist.end() && it->first.GetComp() == ( it + 1 )->first.GetComp() )
314  {
315  ++usageCount;
316 
317  if( !checkReuseViolation( *it->second, *( it + 1 )->second ) )
318  {
319  // Refs share same component but have different values or footprints
320  it->first.GetComp()->SetFlags( SKIP_STRUCT );
321 
322  wxString msg;
323  msg.Printf( _( "\"%s\" and \"%s\" use the same schematic symbol.\n"
324  "They cannot have different footprints or values." ),
325  ( it + 1 )->second->m_ref,
326  it->second->m_ref );
328  }
329  }
330  else
331  {
332  /* Next ref uses different component, so we count all components number for current
333  one. We compare that number to stored in the component itself. If that differs, it
334  means that this particular component is reused in some other project. */
335  if( !m_ignoreOtherProjects && compUsage > usageCount )
336  {
337  PCB_MODULE_DATA tmp{ "",
338  getTextFromField( it->first, FOOTPRINT ),
339  getTextFromField( it->first, VALUE ),
340  {} };
341 
342  if( !checkReuseViolation( tmp, *it->second ) )
343  {
344  it->first.GetComp()->SetFlags( SKIP_STRUCT );
345 
346  wxString msg;
347  msg.Printf( _( "Unable to change \"%s\" footprint or value because associated"
348  " symbol is reused in the another project" ),
349  it->second->m_ref );
351  }
352  }
353  usageCount = 1;
354  }
355  }
356 }
wxString getTextFromField(const SCH_REFERENCE &aRef, const NumFieldType aField)
Get text from symbol's field ( such as Footprint or Value )
#define SKIP_STRUCT
flag indicating that the structure should be ignored
Definition: base_struct.h:128
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Function ReportTail Places the report at the end of the list, for objects that support report orderin...
Definition: reporter.h:94
bool m_processFootprints
Definition: backannotate.h:105
Field Name Module PCB, i.e. "16DIP300".
REPORTER & m_reporter
Definition: backannotate.h:103
bool checkReuseViolation(PCB_MODULE_DATA &aFirst, PCB_MODULE_DATA &aSecond)
Check if modules has different data.
bool m_processValues
Definition: backannotate.h:106
std::pair< SCH_REFERENCE, std::shared_ptr< PCB_MODULE_DATA > > CHANGELIST_ITEM
Definition: backannotate.h:80
Field Value of part, i.e. "3.3K".
bool m_ignoreOtherProjects
Definition: backannotate.h:109
#define _(s)
Definition: 3d_actions.cpp:33
std::deque< CHANGELIST_ITEM > m_changelist
Definition: backannotate.h:115

References _, checkReuseViolation(), FOOTPRINT, getTextFromField(), m_changelist, m_ignoreOtherProjects, m_processFootprints, m_processValues, m_reporter, REPORTER::ReportTail(), RPT_SEVERITY_ERROR, SKIP_STRUCT, and VALUE.

Referenced by BackAnnotateSymbols().

◆ FetchNetlistFromPCB()

bool BACK_ANNOTATE::FetchNetlistFromPCB ( std::string &  aNetlist)

Get netlist from the PCBnew.

Parameters
aNetlistreference to where netlist will be stored
Returns
true if success

Definition at line 89 of file backannotate.cpp.

90 {
91  if( Kiface().IsSingle() )
92  {
93  DisplayErrorMessage( m_frame, _( "Cannot fetch PCB netlist because eeschema is opened "
94  "in stand-alone mode.\n"
95  "You must launch the KiCad project manager and create "
96  "a project." ) );
97  return false;
98  }
99 
100  KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_PCB_EDITOR, false );
101 
102  if( !frame )
103  {
104  wxFileName fn( m_frame->Prj().GetProjectFullName() );
105  fn.SetExt( PcbFileExtension );
106 
107  frame = m_frame->Kiway().Player( FRAME_PCB_EDITOR, true );
108  frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
109  }
110 
112  return true;
113 }
virtual bool OpenProjectFiles(const std::vector< wxString > &aFileList, int aCtl=0)
Function OpenProjectFiles is abstract, and opens a project or set of files given by aFileList.
Definition: kiway_player.h:118
KIWAY_PLAYER is a wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of ...
Definition: kiway_player.h:59
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_holder.h:56
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:252
SCH_EDIT_FRAME * m_frame
Definition: backannotate.h:116
VTBL_ENTRY KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=NULL)
Function Player returns the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:342
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
#define PcbFileExtension
VTBL_ENTRY const wxString GetProjectFullName() const
Function GetProjectFullName returns the full path and name of the project.
Definition: project.cpp:116
VTBL_ENTRY void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=NULL)
Function ExpressMail send aPayload to aDestination from aSource.
Definition: kiway.cpp:428
#define _(s)
Definition: 3d_actions.cpp:33

References _, DisplayErrorMessage(), KIWAY::ExpressMail(), FRAME_PCB_EDITOR, PROJECT::GetProjectFullName(), Kiface(), KIWAY_HOLDER::Kiway(), m_frame, MAIL_PCB_GET_NETLIST, KIWAY_PLAYER::OpenProjectFiles(), PcbFileExtension, KIWAY::Player(), and KIWAY_HOLDER::Prj().

◆ getChangeList()

void BACK_ANNOTATE::getChangeList ( )
private

Create changelist

Definition at line 195 of file backannotate.cpp.

196 {
197  for( std::pair<const wxString, std::shared_ptr<PCB_MODULE_DATA>>& module : m_pcbModules )
198  {
199  const wxString& pcbPath = module.first;
200  auto& pcbData = module.second;
201  bool foundInMultiunit = false;
202 
203  for( auto& item : m_multiUnitsRefs )
204  {
205  SCH_REFERENCE_LIST& refList = item.second;
206 
207  if( refList.FindRefByPath( pcbPath ) >= 0 )
208  {
209 
210  // If module linked to multi unit symbol, we add all symbol's units to
211  // the change list
212  foundInMultiunit = true;
213 
214  for( size_t i = 0; i < refList.GetCount(); ++i )
215  {
216  refList[i].GetComp()->ClearFlags( SKIP_STRUCT );
217  m_changelist.emplace_back( CHANGELIST_ITEM( refList[i], pcbData ) );
218  }
219 
220  break;
221  }
222  }
223 
224  if( foundInMultiunit )
225  continue;
226 
227  int refIndex = m_refs.FindRefByPath( pcbPath );
228 
229  if( refIndex >= 0 )
230  {
231  m_refs[refIndex].GetComp()->ClearFlags( SKIP_STRUCT );
232  m_changelist.emplace_back( CHANGELIST_ITEM( m_refs[refIndex], pcbData ) );
233  }
234  else
235  {
236  // Haven't found linked symbol in multiunits or common refs. Generate error
237  wxString msg;
238  msg.Printf( _( "Cannot find symbol for \"%s\" footprint" ), pcbData->m_ref );
240  }
241  }
242 }
int FindRefByPath(const wxString &aPath) const
Searches unit with designated path.
#define SKIP_STRUCT
flag indicating that the structure should be ignored
Definition: base_struct.h:128
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Function ReportTail Places the report at the end of the list, for objects that support report orderin...
Definition: reporter.h:94
PCB_MODULES_MAP m_pcbModules
Definition: backannotate.h:112
SCH_REFERENCE_LIST is used to create a flattened list of components because in a complex hierarchy,...
REPORTER & m_reporter
Definition: backannotate.h:103
std::pair< SCH_REFERENCE, std::shared_ptr< PCB_MODULE_DATA > > CHANGELIST_ITEM
Definition: backannotate.h:80
unsigned GetCount() const
Function GetCount.
#define _(s)
Definition: 3d_actions.cpp:33
SCH_REFERENCE_LIST m_refs
Definition: backannotate.h:113
std::deque< CHANGELIST_ITEM > m_changelist
Definition: backannotate.h:115
SCH_MULTI_UNIT_REFERENCE_MAP m_multiUnitsRefs
Definition: backannotate.h:114

References _, SCH_REFERENCE_LIST::FindRefByPath(), SCH_REFERENCE_LIST::GetCount(), m_changelist, m_multiUnitsRefs, m_pcbModules, m_refs, m_reporter, REPORTER::ReportTail(), RPT_SEVERITY_ERROR, and SKIP_STRUCT.

Referenced by BackAnnotateSymbols().

◆ getPcbModulesFromString()

void BACK_ANNOTATE::getPcbModulesFromString ( const std::string &  aPayload)
private

Parse netlist sent over KiWay epress mail interface and fill m_pcbModules.

Parameters
aPayload- netlist from PCBnew
Returns
number of errors during parsing

Definition at line 116 of file backannotate.cpp.

117 {
118  auto getStr = []( const PTREE& pt ) -> wxString
119  {
120  return UTF8( pt.front().first );
121  };
122 
123  DSNLEXER lexer( aPayload, FROM_UTF8( __func__ ) );
124  PTREE doc;
125 
126  // NOTE: KiCad's PTREE scanner constructs a property *name* tree, not a property tree.
127  // Every token in the s-expr is stored as a property name; the property's value is then
128  // either the nested s-exprs or an empty PTREE; there are *no* literal property values.
129 
130  Scan( &doc, &lexer );
131 
132  PTREE& tree = doc.get_child( "pcb_netlist" );
133  wxString msg;
134  m_pcbModules.clear();
135 
136  for( const std::pair<const std::string, PTREE>& item : tree )
137  {
138  wxString path, value, footprint;
139  std::map<wxString, wxString> pinNetMap;
140  wxASSERT( item.first == "ref" );
141  wxString ref = getStr( item.second );
142 
143  try
144  {
145  path = getStr( item.second.get_child( "timestamp" ) );
146 
147  if( path == "" )
148  {
149  msg.Printf( _( "Footprint \"%s\" has no symbol associated." ), ref );
151  continue;
152  }
153 
154  footprint = getStr( item.second.get_child( "fpid" ) );
155  value = getStr( item.second.get_child( "value" ) );
156 
157  boost::optional<const PTREE&> nets = item.second.get_child_optional( "nets" );
158 
159  if( nets )
160  {
161  for( const std::pair<const std::string, PTREE>& pin_net : nets.get() )
162  {
163  wxASSERT( pin_net.first == "pin_net" );
164  wxString pinNumber = UTF8( pin_net.second.front().first );
165  wxString netName = UTF8( pin_net.second.back().first );
166  pinNetMap[ pinNumber ] = netName;
167  }
168  }
169  }
170  catch( ... )
171  {
172  wxLogWarning( "Cannot parse PCB netlist for back-annotation" );
173  }
174 
175  // Use lower_bound for not to iterate over map twice
176  auto nearestItem = m_pcbModules.lower_bound( path );
177 
178  if( nearestItem != m_pcbModules.end() && nearestItem->first == path )
179  {
180  // Module with this path already exists - generate error
181  msg.Printf( _( "Pcb footprints \"%s\" and \"%s\" linked to same symbol" ),
182  nearestItem->second->m_ref, ref );
184  }
185  else
186  {
187  // Add module to the map
188  auto data = std::make_shared<PCB_MODULE_DATA>( ref, footprint, value, pinNetMap );
189  m_pcbModules.insert( nearestItem, std::make_pair( path, data ) );
190  }
191  }
192 }
UTF8 is an 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to...
Definition: utf8.h:73
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:114
void Scan(PTREE *aTree, DSNLEXER *aLexer)
Function Scan fills an empty PTREE with information from a KiCad s-expresion stream.
Definition: ptree.cpp:90
PCB_MODULES_MAP m_pcbModules
Definition: backannotate.h:112
REPORTER & m_reporter
Definition: backannotate.h:103
boost::property_tree::ptree PTREE
Definition: ptree.h:54
virtual REPORTER & ReportHead(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Function ReportHead Places the report at the beginning of the list for objects that support ordering.
Definition: reporter.h:103
#define _(s)
Definition: 3d_actions.cpp:33
DSNLEXER implements a lexical analyzer for the SPECCTRA DSN file format.
Definition: dsnlexer.h:79

References _, FROM_UTF8(), m_pcbModules, m_reporter, REPORTER::ReportHead(), RPT_SEVERITY_ERROR, RPT_SEVERITY_WARNING, and Scan().

Referenced by BackAnnotateSymbols().

◆ getTextFromField()

wxString BACK_ANNOTATE::getTextFromField ( const SCH_REFERENCE aRef,
const NumFieldType  aField 
)
private

Get text from symbol's field ( such as Footprint or Value )

Definition at line 283 of file backannotate.cpp.

284 {
285  return aRef.GetComp()->GetField( aField )->GetText();
286 }
SCH_COMPONENT * GetComp() const
SCH_FIELD * GetField(int aFieldNdx)
Returns a field in this symbol.
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:126

References SCH_REFERENCE::GetComp(), SCH_COMPONENT::GetField(), and EDA_TEXT::GetText().

Referenced by applyChangelist(), and checkSharedSchematicErrors().

◆ processNetNameChange()

void BACK_ANNOTATE::processNetNameChange ( SCH_CONNECTION aConn,
const wxString &  aOldName,
const wxString &  aNewName 
)
private

Definition at line 446 of file backannotate.cpp.

448 {
449  wxString msg;
450  SCH_ITEM* driver = aConn->Driver();
451 
452  auto editMatchingLabels =
453  [this]( SCH_SCREEN* aScreen, KICAD_T aType, const wxString& oldName,
454  const wxString& newName )
455  {
456  for( SCH_ITEM* schItem : aScreen->Items().OfType( aType ) )
457  {
458  SCH_TEXT* label = static_cast<SCH_TEXT*>( schItem );
459 
460  if( EscapeString( label->GetShownText(), CTX_NETNAME ) == oldName )
461  {
463  static_cast<SCH_TEXT*>( label )->SetText( newName );
464  }
465  }
466  };
467 
468  switch( driver->Type() )
469  {
470  case SCH_LABEL_T:
471  ++m_changesCount;
472  msg.Printf( _( "Change \"%s\" labels to \"%s\"." ),
473  aOldName,
474  aNewName );
475 
476  if( !m_dryRun )
477  {
478  m_frame->Schematic().SetCurrentSheet( aConn->Sheet() );
479 
480  for( SCH_ITEM* label : m_frame->GetScreen()->Items().OfType( SCH_LABEL_T ) )
481  {
482  SCH_CONNECTION* conn = label->Connection( aConn->Sheet() );
483 
484  if( conn && conn->Driver() == driver )
485  {
487  static_cast<SCH_TEXT*>( label )->SetText( aNewName );
488  }
489  }
490  }
491 
493  break;
494 
495  case SCH_GLOBAL_LABEL_T:
496  ++m_changesCount;
497  msg.Printf( _( "Change \"%s\" global labels to \"%s\"." ),
498  aConn->Name( true ),
499  aNewName );
500 
501  if( !m_dryRun )
502  {
503  SCH_SHEET_LIST all_sheets = m_frame->Schematic().GetSheets();
504 
505  for( const SCH_SHEET_PATH& sheet : all_sheets )
506  {
507  m_frame->Schematic().SetCurrentSheet( sheet );
508  editMatchingLabels( m_frame->GetScreen(), SCH_GLOBAL_LABEL_T, aOldName, aNewName );
509  }
510  }
511 
513  break;
514 
515  case SCH_HIER_LABEL_T:
516  ++m_changesCount;
517  msg.Printf( _( "Change \"%s\" hierarchical label to \"%s\"." ),
518  aConn->Name( true ),
519  aNewName );
520 
521  if( !m_dryRun )
522  {
523  m_frame->Schematic().SetCurrentSheet( aConn->Sheet() );
524  editMatchingLabels( m_frame->GetScreen(), SCH_HIER_LABEL_T, aOldName, aNewName );
525 
526  SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( driver->GetParent() );
527  m_frame->SetScreen( sheet->GetScreen() );
528 
529  for( SCH_SHEET_PIN* pin : sheet->GetPins() )
530  {
531  if( EscapeString( pin->GetShownText(), CTX_NETNAME ) == aOldName )
532  {
534  static_cast<SCH_TEXT*>( pin )->SetText( aNewName );
535  }
536  }
537  }
538 
540  break;
541 
542  case SCH_SHEET_PIN_T:
543  ++m_changesCount;
544  msg.Printf( _( "Change \"%s\" hierarchical label to \"%s\"." ),
545  aConn->Name( true ),
546  aNewName );
547 
548  if( !m_dryRun )
549  {
550  m_frame->Schematic().SetCurrentSheet( aConn->Sheet() );
552  static_cast<SCH_TEXT*>( driver )->SetText( aNewName );
553 
554  SCH_SHEET* sheet = static_cast<SCH_SHEET_PIN*>( driver )->GetParent();
555  m_frame->SetScreen( sheet->GetScreen() );
556  editMatchingLabels( sheet->GetScreen(), SCH_HIER_LABEL_T, aOldName, aNewName );
557  }
558 
560  break;
561 
562  case LIB_PIN_T:
563  {
564  LIB_PIN* pin = dynamic_cast<LIB_PIN*>( driver );
566 
567  if( pin->IsPowerConnection() )
568  {
569  msg.Printf( _( "Net \"%s\" cannot be changed to \"%s\" because it "
570  "is driven by a power pin." ),
571  aOldName,
572  aNewName );
573 
575  break;
576  }
577 
578  switch( pin->GetOrientation() )
579  {
580  case PIN_UP: spin = LABEL_SPIN_STYLE::UP; break;
581  case PIN_DOWN: spin = LABEL_SPIN_STYLE::BOTTOM; break;
582  case PIN_LEFT: spin = LABEL_SPIN_STYLE::LEFT; break;
583  case PIN_RIGHT: spin = LABEL_SPIN_STYLE::RIGHT; break;
584  }
585 
586  ++m_changesCount;
587  msg.Printf( _( "Add label \"%s\" to net \"%s\"." ),
588  aNewName,
589  aConn->Name( true ) );
590 
591  if( !m_dryRun )
592  {
593  SCHEMATIC_SETTINGS& settings = m_frame->Schematic().Settings();
594  SCH_LABEL* label = new SCH_LABEL( driver->GetPosition(), aNewName );
595  label->SetParent( &m_frame->Schematic() );
596  label->SetTextSize( wxSize( settings.m_DefaultTextSize,
597  settings.m_DefaultTextSize ) );
598  label->SetLabelSpinStyle( spin );
599  label->SetFlags( IS_NEW );
600 
601  m_frame->Schematic().SetCurrentSheet( aConn->Sheet() );
603  }
604 
606  }
607  break;
608 
609  default:
610  break;
611  }
612 
614 }
SCH_SHEET_LIST.
SCH_SHEET_LIST GetSheets() const
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:92
SCH_EDIT_FRAME * m_frame
Definition: backannotate.h:116
int GetOrientation() const
Definition: lib_pin.h:206
void SetScreen(BASE_SCREEN *aScreen) override
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:138
EE_TYPE OfType(KICAD_T aType)
Definition: sch_rtree.h:219
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:237
Definition: lib_pin.h:58
virtual wxPoint GetPosition() const
Definition: base_struct.h:337
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:282
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
virtual void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:196
bool IsPowerConnection() const
Return whether this pin forms an implicit power connection: i.e., is hidden and of type POWER_IN.
Definition: lib_pin.h:351
REPORTER & m_reporter
Definition: backannotate.h:103
#define IS_NEW
New item, just created.
Definition: base_struct.h:117
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:232
void SaveCopyInUndoList(SCH_ITEM *aItemToCopy, UNDO_REDO_T aTypeCommand, bool aAppend=false, const wxPoint &aTransformPoint=wxPoint(0, 0))
Create a copy of the current schematic item, and put it in the undo list.
SCHEMATIC & Schematic() const
SCH_ITEM * Driver() const
EDA_ITEM * GetParent() const
Definition: base_struct.h:195
const wxString & Name(bool aIgnoreSheet=false) const
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:84
SCH_SHEET_PATH.
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: sch_text.cpp:484
SCH_CONNECTION * Connection(const SCH_SHEET_PATH &aPath) const
Retrieve the connection associated with this object in the given sheet.
Definition: sch_item.cpp:150
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:216
virtual REPORTER & ReportHead(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Function ReportHead Places the report at the beginning of the list for objects that support ordering.
Definition: reporter.h:103
SCH_SHEET_PATH Sheet() const
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
#define _(s)
Definition: 3d_actions.cpp:33
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
These Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which ar...
Definition: string.cpp:50
EE_RTREE & Items()
Definition: sch_screen.h:158
These settings were stored in SCH_BASE_FRAME previously.
int m_changesCount
To count number of changes applied to the schematic
Definition: backannotate.h:119
virtual void SetLabelSpinStyle(LABEL_SPIN_STYLE aSpinStyle)
Set a spin or rotation angle, along with specific horizontal and vertical justification styles with e...
Definition: sch_text.cpp:230
void SetCurrentSheet(const SCH_SHEET_PATH &aPath)
Definition: schematic.h:127
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:187
KICAD_T Type() const
Function Type()
Definition: base_struct.h:193
void AddItemToScreenAndUndoList(SCH_ITEM *aItem, bool aUndoAppend=false)
Add an item to the schematic and adds the changes to the undo/redo container.

References _, SCH_EDIT_FRAME::AddItemToScreenAndUndoList(), LABEL_SPIN_STYLE::BOTTOM, CTX_NETNAME, SCH_CONNECTION::Driver(), EscapeString(), LIB_PIN::GetOrientation(), EDA_ITEM::GetParent(), EDA_ITEM::GetPosition(), SCH_EDIT_FRAME::GetScreen(), SCH_SHEET::GetScreen(), SCHEMATIC::GetSheets(), SCH_TEXT::GetShownText(), IS_NEW, LIB_PIN::IsPowerConnection(), SCH_SCREEN::Items(), LABEL_SPIN_STYLE::LEFT, LIB_PIN_T, m_changesCount, SCHEMATIC_SETTINGS::m_DefaultTextSize, m_dryRun, m_frame, m_reporter, SCH_CONNECTION::Name(), EE_RTREE::OfType(), PIN_DOWN, PIN_LEFT, PIN_RIGHT, PIN_UP, REPORTER::ReportHead(), LABEL_SPIN_STYLE::RIGHT, RPT_SEVERITY_ACTION, RPT_SEVERITY_ERROR, SCH_EDIT_FRAME::SaveCopyInUndoList(), SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_LABEL_T, SCH_SHEET_PIN_T, SCH_EDIT_FRAME::Schematic(), SCHEMATIC::SetCurrentSheet(), EDA_ITEM::SetFlags(), SCH_TEXT::SetLabelSpinStyle(), EDA_ITEM::SetParent(), SCH_EDIT_FRAME::SetScreen(), EDA_TEXT::SetTextSize(), SCHEMATIC::Settings(), SCH_CONNECTION::Sheet(), EDA_ITEM::Type(), LABEL_SPIN_STYLE::UP, and UR_CHANGED.

Referenced by applyChangelist().

Member Data Documentation

◆ m_changelist

std::deque<CHANGELIST_ITEM> BACK_ANNOTATE::m_changelist
private

◆ m_changesCount

int BACK_ANNOTATE::m_changesCount
private

To count number of changes applied to the schematic

Definition at line 119 of file backannotate.h.

Referenced by applyChangelist(), BackAnnotateSymbols(), and processNetNameChange().

◆ m_dryRun

bool BACK_ANNOTATE::m_dryRun
private

Definition at line 110 of file backannotate.h.

Referenced by applyChangelist(), and processNetNameChange().

◆ m_frame

SCH_EDIT_FRAME* BACK_ANNOTATE::m_frame
private

Definition at line 116 of file backannotate.h.

Referenced by BackAnnotateSymbols(), FetchNetlistFromPCB(), and processNetNameChange().

◆ m_ignoreOtherProjects

bool BACK_ANNOTATE::m_ignoreOtherProjects
private

Definition at line 109 of file backannotate.h.

Referenced by checkSharedSchematicErrors().

◆ m_multiUnitsRefs

SCH_MULTI_UNIT_REFERENCE_MAP BACK_ANNOTATE::m_multiUnitsRefs
private

Definition at line 114 of file backannotate.h.

Referenced by BackAnnotateSymbols(), and getChangeList().

◆ m_pcbModules

PCB_MODULES_MAP BACK_ANNOTATE::m_pcbModules
private

Definition at line 112 of file backannotate.h.

Referenced by getChangeList(), and getPcbModulesFromString().

◆ m_processFootprints

bool BACK_ANNOTATE::m_processFootprints
private

◆ m_processNetNames

bool BACK_ANNOTATE::m_processNetNames
private

Definition at line 108 of file backannotate.h.

Referenced by applyChangelist(), and BackAnnotateSymbols().

◆ m_processReferences

bool BACK_ANNOTATE::m_processReferences
private

Definition at line 107 of file backannotate.h.

Referenced by applyChangelist(), and BackAnnotateSymbols().

◆ m_processValues

bool BACK_ANNOTATE::m_processValues
private

◆ m_refs

SCH_REFERENCE_LIST BACK_ANNOTATE::m_refs
private

Definition at line 113 of file backannotate.h.

Referenced by BackAnnotateSymbols(), checkForUnusedSymbols(), and getChangeList().

◆ m_reporter


The documentation for this class was generated from the following files: