KiCad PCB EDA Suite
netlist_exporter_generic.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) 1992-2013 jp.charras at wanadoo.fr
5  * Copyright (C) 2013-2017 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 1992-2020 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 
27 
28 #include <build_version.h>
29 #include <sch_base_frame.h>
30 #include <class_library.h>
31 #include <connection_graph.h>
32 #include <refdes_utils.h>
33 
34 #include <symbol_lib_table.h>
35 
36 
37 static bool sortPinsByNumber( LIB_PIN* aPin1, LIB_PIN* aPin2 );
38 
39 bool NETLIST_EXPORTER_GENERIC::WriteNetlist( const wxString& aOutFileName,
40  unsigned aNetlistOptions )
41 {
42  // output the XML format netlist.
43  wxXmlDocument xdoc;
44 
45  xdoc.SetRoot( makeRoot( GNL_ALL ) );
46 
47  return xdoc.Save( aOutFileName, 2 /* indent bug, today was ignored by wxXml lib */ );
48 }
49 
50 
52 {
53  XNODE* xroot = node( "export" );
54 
55  xroot->AddAttribute( "version", "D" );
56 
57  if( aCtl & GNL_HEADER )
58  // add the "design" header
59  xroot->AddChild( makeDesignHeader() );
60 
61  if( aCtl & GNL_COMPONENTS )
62  xroot->AddChild( makeComponents( aCtl ) );
63 
64  if( aCtl & GNL_PARTS )
65  xroot->AddChild( makeLibParts() );
66 
67  if( aCtl & GNL_LIBRARIES )
68  // must follow makeGenericLibParts()
69  xroot->AddChild( makeLibraries() );
70 
71  if( aCtl & GNL_NETS )
72  xroot->AddChild( makeListOfNets() );
73 
74  return xroot;
75 }
76 
77 
80 {
81  wxString value;
82  wxString datasheet;
83  wxString footprint;
84 
85  std::map< wxString, wxString > f;
86 };
87 
88 
90  SCH_SHEET_PATH* aSheet )
91 {
92  COMP_FIELDS fields;
93 
94  if( comp->GetUnitCount() > 1 )
95  {
96  // Sadly, each unit of a component can have its own unique fields. This
97  // block finds the unit with the lowest number having a non blank field
98  // value and records it. Therefore user is best off setting fields
99  // into only the first unit. But this scavenger algorithm will find
100  // any non blank fields in all units and use the first non-blank field
101  // for each unique field name.
102 
103  wxString ref = comp->GetRef( aSheet );
104 
105  SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
106  int minUnit = comp->GetUnit();
107 
108  for( unsigned i = 0; i < sheetList.size(); i++ )
109  {
110  for( auto item : sheetList[i].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
111  {
112  SCH_COMPONENT* comp2 = (SCH_COMPONENT*) item;
113 
114  wxString ref2 = comp2->GetRef( &sheetList[i] );
115 
116  if( ref2.CmpNoCase( ref ) != 0 )
117  continue;
118 
119  int unit = comp2->GetUnit();
120 
121  // The lowest unit number wins. User should only set fields in any one unit.
122  // remark: IsVoid() returns true for empty strings or the "~" string (empty
123  // field value)
124  if( !comp2->GetField( VALUE )->IsVoid()
125  && ( unit < minUnit || fields.value.IsEmpty() ) )
126  fields.value = comp2->GetField( VALUE )->GetText();
127 
128  if( !comp2->GetField( FOOTPRINT )->IsVoid()
129  && ( unit < minUnit || fields.footprint.IsEmpty() ) )
130  fields.footprint = comp2->GetField( FOOTPRINT )->GetText();
131 
132  if( !comp2->GetField( DATASHEET )->IsVoid()
133  && ( unit < minUnit || fields.datasheet.IsEmpty() ) )
134  fields.datasheet = comp2->GetField( DATASHEET )->GetText();
135 
136  for( int fldNdx = MANDATORY_FIELDS; fldNdx < comp2->GetFieldCount(); ++fldNdx )
137  {
138  SCH_FIELD* f = comp2->GetField( fldNdx );
139 
140  if( f->GetText().size()
141  && ( unit < minUnit || fields.f.count( f->GetName() ) == 0 ) )
142  {
143  fields.f[ f->GetName() ] = f->GetText();
144  }
145  }
146 
147  minUnit = std::min( unit, minUnit );
148  }
149  }
150 
151  }
152  else
153  {
154  fields.value = comp->GetField( VALUE )->GetText();
155  fields.footprint = comp->GetField( FOOTPRINT )->GetText();
156  fields.datasheet = comp->GetField( DATASHEET )->GetText();
157 
158  for( int fldNdx = MANDATORY_FIELDS; fldNdx < comp->GetFieldCount(); ++fldNdx )
159  {
160  SCH_FIELD* f = comp->GetField( fldNdx );
161 
162  if( f->GetText().size() )
163  fields.f[ f->GetName() ] = f->GetText();
164  }
165  }
166 
167  // Do not output field values blank in netlist:
168  if( fields.value.size() )
169  xcomp->AddChild( node( "value", fields.value ) );
170  else // value field always written in netlist
171  xcomp->AddChild( node( "value", "~" ) );
172 
173  if( fields.footprint.size() )
174  xcomp->AddChild( node( "footprint", fields.footprint ) );
175 
176  if( fields.datasheet.size() )
177  xcomp->AddChild( node( "datasheet", fields.datasheet ) );
178 
179  if( fields.f.size() )
180  {
181  XNODE* xfields;
182  xcomp->AddChild( xfields = node( "fields" ) );
183 
184  // non MANDATORY fields are output alphabetically
185  for( std::map< wxString, wxString >::const_iterator it = fields.f.begin();
186  it != fields.f.end(); ++it )
187  {
188  XNODE* xfield;
189  xfields->AddChild( xfield = node( "field", it->second ) );
190  xfield->AddAttribute( "name", it->first );
191  }
192  }
193 }
194 
195 
197 {
198  XNODE* xcomps = node( "components" );
199 
201  m_LibParts.clear();
202 
203  SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
204 
205  // Output is xml, so there is no reason to remove spaces from the field values.
206  // And XML element names need not be translated to various languages.
207 
208  for( unsigned i = 0; i < sheetList.size(); i++ )
209  {
210  SCH_SHEET_PATH sheet = sheetList[i];
211 
212  auto cmp =
213  [sheet]( SCH_COMPONENT* a, SCH_COMPONENT* b )
214  {
215  return ( UTIL::RefDesStringCompare( a->GetRef( &sheet ),
216  b->GetRef( &sheet ) ) < 0 );
217  };
218 
219  std::set<SCH_COMPONENT*, decltype( cmp )> ordered_components( cmp );
220 
221  for( auto item : sheetList[i].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
222  {
223  auto comp = static_cast<SCH_COMPONENT*>( item );
224  auto test = ordered_components.insert( comp );
225 
226  if( !test.second )
227  {
228  if( ( *( test.first ) )->GetUnit() > comp->GetUnit() )
229  {
230  ordered_components.erase( test.first );
231  ordered_components.insert( comp );
232  }
233  }
234  }
235 
236  for( auto item : ordered_components )
237  {
238  SCH_COMPONENT* comp = findNextComponent( item, &sheet );
239 
240  if( !comp
241  || ( ( aCtl & GNL_OPT_BOM ) && !comp->GetIncludeInBom() )
242  || ( ( aCtl & GNL_OPT_KICAD ) && !comp->GetIncludeOnBoard() ) )
243  continue;
244 
245  XNODE* xcomp; // current component being constructed
246 
247  // Output the component's elements in order of expected access frequency.
248  // This may not always look best, but it will allow faster execution
249  // under XSL processing systems which do sequential searching within
250  // an element.
251 
252  xcomps->AddChild( xcomp = node( "comp" ) );
253  xcomp->AddAttribute( "ref", comp->GetRef( &sheet ) );
254 
255  addComponentFields( xcomp, comp, &sheetList[i] );
256 
257  XNODE* xlibsource;
258  xcomp->AddChild( xlibsource = node( "libsource" ) );
259 
260  // "logical" library name, which is in anticipation of a better search
261  // algorithm for parts based on "logical_lib.part" and where logical_lib
262  // is merely the library name minus path and extension.
263  if( comp->GetPartRef() )
264  xlibsource->AddAttribute( "lib", comp->GetPartRef()->GetLibId().GetLibNickname() );
265 
266  // We only want the symbol name, not the full LIB_ID.
267  xlibsource->AddAttribute( "part", comp->GetLibId().GetLibItemName() );
268 
269  xlibsource->AddAttribute( "description", comp->GetDescription() );
270 
271  XNODE* xsheetpath;
272 
273  xcomp->AddChild( xsheetpath = node( "sheetpath" ) );
274  xsheetpath->AddAttribute( "names", sheet.PathHumanReadable() );
275  xsheetpath->AddAttribute( "tstamps", sheet.PathAsString() );
276  xcomp->AddChild( node( "tstamp", comp->m_Uuid.AsString() ) );
277  }
278  }
279 
280  return xcomps;
281 }
282 
283 
285 {
286  SCH_SCREEN* screen;
287  XNODE* xdesign = node( "design" );
288  XNODE* xtitleBlock;
289  XNODE* xsheet;
290  XNODE* xcomment;
291  wxString sheetTxt;
292  wxFileName sourceFileName;
293 
294  // the root sheet is a special sheet, call it source
295  xdesign->AddChild( node( "source", m_schematic->GetFileName() ) );
296 
297  xdesign->AddChild( node( "date", DateAndTime() ) );
298 
299  // which Eeschema tool
300  xdesign->AddChild( node( "tool", wxString( "Eeschema " ) + GetBuildVersion() ) );
301 
302  /*
303  Export the sheets information
304  */
305  SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
306 
307  for( unsigned i = 0; i < sheetList.size(); i++ )
308  {
309  screen = sheetList[i].LastScreen();
310 
311  xdesign->AddChild( xsheet = node( "sheet" ) );
312 
313  // get the string representation of the sheet index number.
314  // Note that sheet->GetIndex() is zero index base and we need to increment the
315  // number by one to make it human readable
316  sheetTxt.Printf( "%u", i + 1 );
317  xsheet->AddAttribute( "number", sheetTxt );
318  xsheet->AddAttribute( "name", sheetList[i].PathHumanReadable() );
319  xsheet->AddAttribute( "tstamps", sheetList[i].PathAsString() );
320 
321 
322  TITLE_BLOCK tb = screen->GetTitleBlock();
323 
324  xsheet->AddChild( xtitleBlock = node( "title_block" ) );
325 
326  xtitleBlock->AddChild( node( "title", tb.GetTitle() ) );
327  xtitleBlock->AddChild( node( "company", tb.GetCompany() ) );
328  xtitleBlock->AddChild( node( "rev", tb.GetRevision() ) );
329  xtitleBlock->AddChild( node( "date", tb.GetDate() ) );
330 
331  // We are going to remove the fileName directories.
332  sourceFileName = wxFileName( screen->GetFileName() );
333  xtitleBlock->AddChild( node( "source", sourceFileName.GetFullName() ) );
334 
335  xtitleBlock->AddChild( xcomment = node( "comment" ) );
336  xcomment->AddAttribute( "number", "1" );
337  xcomment->AddAttribute( "value", tb.GetComment( 0 ) );
338 
339  xtitleBlock->AddChild( xcomment = node( "comment" ) );
340  xcomment->AddAttribute( "number", "2" );
341  xcomment->AddAttribute( "value", tb.GetComment( 1 ) );
342 
343  xtitleBlock->AddChild( xcomment = node( "comment" ) );
344  xcomment->AddAttribute( "number", "3" );
345  xcomment->AddAttribute( "value", tb.GetComment( 2 ) );
346 
347  xtitleBlock->AddChild( xcomment = node( "comment" ) );
348  xcomment->AddAttribute( "number", "4" );
349  xcomment->AddAttribute( "value", tb.GetComment( 3 ) );
350 
351  xtitleBlock->AddChild( xcomment = node( "comment" ) );
352  xcomment->AddAttribute( "number", "5" );
353  xcomment->AddAttribute( "value", tb.GetComment( 4 ) );
354 
355  xtitleBlock->AddChild( xcomment = node( "comment" ) );
356  xcomment->AddAttribute( "number", "6" );
357  xcomment->AddAttribute( "value", tb.GetComment( 5 ) );
358 
359  xtitleBlock->AddChild( xcomment = node( "comment" ) );
360  xcomment->AddAttribute( "number", "7" );
361  xcomment->AddAttribute( "value", tb.GetComment( 6 ) );
362 
363  xtitleBlock->AddChild( xcomment = node( "comment" ) );
364  xcomment->AddAttribute( "number", "8" );
365  xcomment->AddAttribute( "value", tb.GetComment( 7 ) );
366 
367  xtitleBlock->AddChild( xcomment = node( "comment" ) );
368  xcomment->AddAttribute( "number", "9" );
369  xcomment->AddAttribute( "value", tb.GetComment( 8 ) );
370  }
371 
372  return xdesign;
373 }
374 
375 
377 {
378  XNODE* xlibs = node( "libraries" ); // auto_ptr
379 
380  for( std::set<wxString>::iterator it = m_libraries.begin(); it!=m_libraries.end(); ++it )
381  {
382  wxString libNickname = *it;
383  XNODE* xlibrary;
384 
385  if( m_schematic->Prj().SchSymbolLibTable()->HasLibrary( libNickname ) )
386  {
387  xlibs->AddChild( xlibrary = node( "library" ) );
388  xlibrary->AddAttribute( "logical", libNickname );
389  xlibrary->AddChild( node(
390  "uri", m_schematic->Prj().SchSymbolLibTable()->GetFullURI( libNickname ) ) );
391  }
392 
393  // @todo: add more fun stuff here
394  }
395 
396  return xlibs;
397 }
398 
399 
401 {
402  XNODE* xlibparts = node( "libparts" ); // auto_ptr
403 
404  LIB_PINS pinList;
405  LIB_FIELDS fieldList;
406 
407  m_libraries.clear();
408 
409  for( auto lcomp : m_LibParts )
410  {
411  wxString libNickname = lcomp->GetLibId().GetLibNickname();;
412 
413  // The library nickname will be empty if the cache library is used.
414  if( !libNickname.IsEmpty() )
415  m_libraries.insert( libNickname ); // inserts component's library if unique
416 
417  XNODE* xlibpart;
418  xlibparts->AddChild( xlibpart = node( "libpart" ) );
419  xlibpart->AddAttribute( "lib", libNickname );
420  xlibpart->AddAttribute( "part", lcomp->GetName() );
421 
422  //----- show the important properties -------------------------
423  if( !lcomp->GetDescription().IsEmpty() )
424  xlibpart->AddChild( node( "description", lcomp->GetDescription() ) );
425 
426  if( !lcomp->GetDatasheetField().GetText().IsEmpty() )
427  xlibpart->AddChild( node( "docs", lcomp->GetDatasheetField().GetText() ) );
428 
429  // Write the footprint list
430  if( lcomp->GetFootprints().GetCount() )
431  {
432  XNODE* xfootprints;
433  xlibpart->AddChild( xfootprints = node( "footprints" ) );
434 
435  for( unsigned i=0; i<lcomp->GetFootprints().GetCount(); ++i )
436  {
437  xfootprints->AddChild( node( "fp", lcomp->GetFootprints()[i] ) );
438  }
439  }
440 
441  //----- show the fields here ----------------------------------
442  fieldList.clear();
443  lcomp->GetFields( fieldList );
444 
445  XNODE* xfields;
446  xlibpart->AddChild( xfields = node( "fields" ) );
447 
448  for( unsigned i=0; i<fieldList.size(); ++i )
449  {
450  if( !fieldList[i].GetText().IsEmpty() )
451  {
452  XNODE* xfield;
453  xfields->AddChild( xfield = node( "field", fieldList[i].GetText() ) );
454  xfield->AddAttribute( "name", fieldList[i].GetCanonicalName() );
455  }
456  }
457 
458  //----- show the pins here ------------------------------------
459  pinList.clear();
460  lcomp->GetPins( pinList, 0, 0 );
461 
462  /* we must erase redundant Pins references in pinList
463  * These redundant pins exist because some pins
464  * are found more than one time when a component has
465  * multiple parts per package or has 2 representations (DeMorgan conversion)
466  * For instance, a 74ls00 has DeMorgan conversion, with different pin shapes,
467  * and therefore each pin appears 2 times in the list.
468  * Common pins (VCC, GND) can also be found more than once.
469  */
470  sort( pinList.begin(), pinList.end(), sortPinsByNumber );
471  for( int ii = 0; ii < (int)pinList.size()-1; ii++ )
472  {
473  if( pinList[ii]->GetNumber() == pinList[ii+1]->GetNumber() )
474  { // 2 pins have the same number, remove the redundant pin at index i+1
475  pinList.erase(pinList.begin() + ii + 1);
476  ii--;
477  }
478  }
479 
480  if( pinList.size() )
481  {
482  XNODE* pins;
483 
484  xlibpart->AddChild( pins = node( "pins" ) );
485  for( unsigned i=0; i<pinList.size(); ++i )
486  {
487  XNODE* pin;
488 
489  pins->AddChild( pin = node( "pin" ) );
490  pin->AddAttribute( "num", pinList[i]->GetNumber() );
491  pin->AddAttribute( "name", pinList[i]->GetName() );
492  pin->AddAttribute( "type", pinList[i]->GetCanonicalElectricalTypeName() );
493 
494  // caution: construction work site here, drive slowly
495  }
496  }
497  }
498 
499  return xlibparts;
500 }
501 
502 
504 {
505  XNODE* xnets = node( "nets" ); // auto_ptr if exceptions ever get used.
506  wxString netCodeTxt;
507  wxString netName;
508  wxString ref;
509 
510  XNODE* xnet = 0;
511 
512  /* output:
513  <net code="123" name="/cfcard.sch/WAIT#">
514  <node ref="R23" pin="1"/>
515  <node ref="U18" pin="12"/>
516  </net>
517  */
518 
519  int code = 0;
520 
521  for( const auto& it : m_schematic->ConnectionGraph()->GetNetMap() )
522  {
523  bool added = false;
524  wxString net_name = it.first.first;
525  auto subgraphs = it.second;
526 
527  // Code starts at 1
528  code++;
529 
530  XNODE* xnode;
531  std::vector<std::pair<SCH_PIN*, SCH_SHEET_PATH>> sorted_items;
532 
533  for( auto subgraph : subgraphs )
534  {
535  auto sheet = subgraph->m_sheet;
536 
537  for( auto item : subgraph->m_items )
538  if( item->Type() == SCH_PIN_T )
539  sorted_items.emplace_back(
540  std::make_pair( static_cast<SCH_PIN*>( item ), sheet ) );
541  }
542 
543  // Netlist ordering: Net name, then ref des, then pin name
544  std::sort( sorted_items.begin(), sorted_items.end(), [] ( auto a, auto b ) {
545  auto ref_a = a.first->GetParentComponent()->GetRef( &a.second );
546  auto ref_b = b.first->GetParentComponent()->GetRef( &b.second );
547 
548  if( ref_a == ref_b )
549  return a.first->GetNumber() < b.first->GetNumber();
550 
551  return ref_a < ref_b;
552  } );
553 
554  // Some duplicates can exist, for example on multi-unit parts with duplicated
555  // pins across units. If the user connects the pins on each unit, they will
556  // appear on separate subgraphs. Remove those here:
557  sorted_items.erase( std::unique( sorted_items.begin(), sorted_items.end(),
558  [] ( auto a, auto b ) {
559  auto ref_a = a.first->GetParentComponent()->GetRef( &a.second );
560  auto ref_b = b.first->GetParentComponent()->GetRef( &b.second );
561 
562  return ref_a == ref_b && a.first->GetNumber() == b.first->GetNumber();
563  } ), sorted_items.end() );
564 
565  for( const auto& pair : sorted_items )
566  {
567  SCH_PIN* pin = pair.first;
568  SCH_SHEET_PATH sheet = pair.second;
569 
570  auto refText = pin->GetParentComponent()->GetRef( &sheet );
571  const auto& pinText = pin->GetNumber();
572 
573  // Skip power symbols and virtual components
574  if( refText[0] == wxChar( '#' ) )
575  continue;
576 
577  if( !added )
578  {
579  xnets->AddChild( xnet = node( "net" ) );
580  netCodeTxt.Printf( "%d", code );
581  xnet->AddAttribute( "code", netCodeTxt );
582  xnet->AddAttribute( "name", net_name );
583 
584  added = true;
585  }
586 
587  xnet->AddChild( xnode = node( "node" ) );
588  xnode->AddAttribute( "ref", refText );
589  xnode->AddAttribute( "pin", pinText );
590 
591  wxString pinName;
592 
593  if( pin->GetName() != "~" ) // ~ is a char used to code empty strings in libs.
594  pinName = pin->GetName();
595 
596  if( !pinName.IsEmpty() )
597  xnode->AddAttribute( "pinfunction", pinName );
598  }
599  }
600 
601  return xnets;
602 }
603 
604 
605 XNODE* NETLIST_EXPORTER_GENERIC::node( const wxString& aName,
606  const wxString& aTextualContent /* = wxEmptyString*/ )
607 {
608  XNODE* n = new XNODE( wxXML_ELEMENT_NODE, aName );
609 
610  if( aTextualContent.Len() > 0 ) // excludes wxEmptyString, the parameter's default value
611  n->AddChild( new XNODE( wxXML_TEXT_NODE, wxEmptyString, aTextualContent ) );
612 
613  return n;
614 }
615 
616 
617 static bool sortPinsByNumber( LIB_PIN* aPin1, LIB_PIN* aPin2 )
618 {
619  // return "lhs < rhs"
620  return UTIL::RefDesStringCompare( aPin1->GetNumber(), aPin2->GetNumber() ) < 0;
621 }
SCH_SHEET_LIST.
bool WriteNetlist(const wxString &aOutFileName, unsigned aNetlistOptions) override
Write generic netlist to aOutFileName.
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:52
const wxString & GetFileName() const
Definition: sch_screen.h:185
const UTF8 & GetLibItemName() const
Definition: lib_id.h:114
name of datasheet
SCH_SHEET_LIST GetSheets() const
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:92
const wxString & GetName() const
Definition: sch_pin.h:104
UNIQUE_STRINGS m_ReferencesAlreadyFound
Used for "multi parts per package" components, avoids processing a lib component more than once.
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
A convenience function that creates a new XNODE with an optional textual child.
SCHEMATIC * m_schematic
The schematic we're generating a netlist for.
CONNECTION_GRAPH * ConnectionGraph() const
Definition: schematic.h:132
bool GetIncludeOnBoard() const
const wxString & GetComment(int aIdx) const
Definition: title_block.h:110
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
Definition: lib_item.h:55
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
int GetUnitCount() const
Return the number of units per package of the symbol.
Collection of utility functions for component reference designators (refdes)
wxString AsString() const
Definition: common.cpp:165
const TITLE_BLOCK & GetTitleBlock() const
Definition: sch_screen.h:190
wxString PathAsString() const
Function PathAsString the path uses the time stamps which do not changes even when editing sheet para...
wxString GetDescription() const
Return information about the aliased parts.
void Clear()
Function Clear erases the record.
SCH_COMPONENT * findNextComponent(EDA_ITEM *aItem, SCH_SHEET_PATH *aSheetPath)
Checks if the given component should be processed for netlisting.
wxString GetFileName() const
Helper to retrieve the filename from the root sheet screen.
Definition: schematic.cpp:132
TITLE_BLOCK holds the information shown in the lower right corner of a plot, printout,...
Definition: title_block.h:40
Field Name Module PCB, i.e. "16DIP300".
bool IsVoid() const
Function IsVoid returns true if the field is either empty or holds "~".
Definition: sch_field.cpp:311
int RefDesStringCompare(const wxString &aFirst, const wxString &aSecond)
Acts just like the strcmp function but treats numbers within the string text correctly for sorting.
XNODE * makeRoot(int aCtl=GNL_ALL)
Build the entire document tree for the generic export.
const wxString & GetNumber() const
Definition: sch_pin.h:106
std::set< LIB_PART *, LIB_PART_LESS_THAN > m_LibParts
unique library parts used.
std::set< wxString > m_libraries
Set of library nicknames.
int GetUnit() const
void addComponentFields(XNODE *xcomp, SCH_COMPONENT *comp, SCH_SHEET_PATH *aSheet)
wxString GetBuildVersion()
Get the full KiCad version string.
const wxString & GetRevision() const
Definition: title_block.h:89
const wxString & GetCompany() const
Definition: title_block.h:99
XNODE * makeDesignHeader()
Fills out a project "design" header into an XML node.
const NET_MAP & GetNetMap() const
Holder for multi-unit component fields.
SCH_SHEET_PATH.
std::unique_ptr< LIB_PART > & GetPartRef()
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false)
Return the reference for the given sheet path.
bool GetIncludeInBom() const
int GetFieldCount() const
Return the number of fields in this symbol.
XNODE * makeComponents(unsigned aCtl)
const KIID m_Uuid
Definition: base_struct.h:162
XNODE holds an XML or S-expression element.
Definition: xnode.h:43
SCH_FIELD * GetField(int aFieldNdx)
Returns a field in this symbol.
Field Value of part, i.e. "3.3K".
const wxString & GetDate() const
Definition: title_block.h:79
const wxString & GetNumber() const
Definition: lib_pin.h:192
std::vector< LIB_FIELD > LIB_FIELDS
Definition: lib_field.h:218
wxString GetName(bool aUseDefaultName=true) const
Function GetName returns the field name.
Definition: sch_field.cpp:438
#define GNL_ALL
Schematic symbol object.
Definition: sch_component.h:88
PROJECT & Prj() const
Return a reference to the project this schematic is part of.
Definition: schematic.h:77
XNODE * makeLibraries()
Fill out an XML node with a list of used libraries and returns it.
std::map< wxString, wxString > f
const wxString & GetTitle() const
Definition: title_block.h:65
Definition for part library class.
wxString PathHumanReadable() const
Function PathHumanReadable returns the sheet path in a human readable form, i.e.
static bool sortPinsByNumber(LIB_PIN *aPin1, LIB_PIN *aPin2)
const LIB_ID & GetLibId() const
SCH_COMPONENT * GetParentComponent() const
Definition: sch_pin.cpp:81
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:127
XNODE * makeListOfNets()
Fill out an XML node with a list of nets and returns it.
wxString DateAndTime()
Definition: string.cpp:373
XNODE * makeLibParts()
Fill out an XML node with the unique library parts and returns it.