35 #include <wx/wfstream.h> 50 wxFFileOutputStream stream( aOutFileName );
58 return xdoc.Save( stream, 2 );
66 xroot->AddAttribute(
"version",
"E" );
98 std::map<wxString, wxString> userFields;
109 wxString ref = aSymbol->
GetRef( aSheet );
112 int minUnit = aSymbol->
GetUnit();
114 for(
unsigned i = 0; i < sheetList.size(); i++ )
116 for(
auto item : sheetList[i].LastScreen()->Items().OfType(
SCH_SYMBOL_T ) )
120 wxString ref2 = symbol2->
GetRef( &sheetList[i] );
122 if( ref2.CmpNoCase( ref ) != 0 )
131 && ( unit < minUnit || value.IsEmpty() ) )
137 && ( unit < minUnit || footprint.IsEmpty() ) )
143 && ( unit < minUnit ||
datasheet.IsEmpty() ) )
156 && ( unit < minUnit || userFields.count( f.
GetName() ) == 0 ) )
165 minUnit = std::min( unit, minUnit );
197 aNode->AddChild(
node(
"value",
"~" ) );
199 if( footprint.size() )
205 if( userFields.size() )
208 aNode->AddChild( xfields =
node(
"fields" ) );
211 for(
const std::pair<const wxString, wxString>& f : userFields )
215 xfields->AddChild( xfield );
233 for(
unsigned ii = 0; ii < sheetList.size(); ii++ )
241 b->GetRef( &sheet,
false ), true ) < 0 );
244 std::set<
SCH_SYMBOL*, decltype( cmp )> ordered_symbols( cmp );
245 std::multiset<
SCH_SYMBOL*, decltype( cmp )> extra_units( cmp );
249 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
250 auto test = ordered_symbols.insert( symbol );
254 if( ( *(
test.first ) )->m_Uuid > symbol->
m_Uuid )
256 extra_units.insert( *(
test.first ) );
257 ordered_symbols.erase(
test.first );
258 ordered_symbols.insert( symbol );
262 extra_units.insert( symbol );
267 for(
EDA_ITEM* item : ordered_symbols )
283 xcomps->AddChild( xcomp =
node(
"comp" ) );
285 xcomp->AddAttribute(
"ref", symbol->
GetRef( &sheet ) );
289 xcomp->AddChild( xlibsource =
node(
"libsource" ) );
307 xlibsource->AddAttribute(
"lib", libName );
310 xlibsource->AddAttribute(
"part", partName );
312 xlibsource->AddAttribute(
"description", symbol->
GetDescription() );
316 std::vector<SCH_FIELD>& fields = symbol->
GetFields();
320 xcomp->AddChild( xproperty =
node(
"property" ) );
321 xproperty->AddAttribute(
"name", fields[jj].GetCanonicalName() );
322 xproperty->AddAttribute(
"value", fields[jj].GetText() );
327 xcomp->AddChild( xproperty =
node(
"property" ) );
328 xproperty->AddAttribute(
"name", sheetField.GetCanonicalName() );
329 xproperty->AddAttribute(
"value", sheetField.GetText() );
334 xcomp->AddChild( xproperty =
node(
"property" ) );
335 xproperty->AddAttribute(
"name",
"exclude_from_bom" );
340 xcomp->AddChild( xproperty =
node(
"property" ) );
341 xproperty->AddAttribute(
"name",
"exclude_from_board" );
345 xcomp->AddChild( xsheetpath =
node(
"sheetpath" ) );
348 xsheetpath->AddAttribute(
"tstamps", sheet.
PathAsString() );
351 xcomp->AddChild( xunits =
node(
"tstamps" ) );
353 auto range = extra_units.equal_range( symbol );
356 for(
auto it = range.first; it != range.second; ++it )
358 wxString uuid = ( *it )->m_Uuid.AsString();
365 xunits->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, uuid ) );
387 wxFileName sourceFileName;
399 for(
const std::pair<const wxString, wxString>& prop : properties )
401 xdesign->AddChild( xtextvar =
node(
"textvar", prop.second ) );
402 xtextvar->AddAttribute(
"name", prop.first );
410 for(
unsigned i = 0; i < sheetList.size(); i++ )
412 screen = sheetList[i].LastScreen();
414 xdesign->AddChild( xsheet =
node(
"sheet" ) );
419 sheetTxt.Printf(
"%u", i + 1 );
420 xsheet->AddAttribute(
"number", sheetTxt );
421 xsheet->AddAttribute(
"name", sheetList[i].PathHumanReadable() );
422 xsheet->AddAttribute(
"tstamps", sheetList[i].PathAsString() );
427 xsheet->AddChild( xtitleBlock =
node(
"title_block" ) );
435 sourceFileName = wxFileName( screen->
GetFileName() );
436 xtitleBlock->AddChild(
node(
"source", sourceFileName.GetFullName() ) );
438 xtitleBlock->AddChild( xcomment =
node(
"comment" ) );
439 xcomment->AddAttribute(
"number",
"1" );
442 xtitleBlock->AddChild( xcomment =
node(
"comment" ) );
443 xcomment->AddAttribute(
"number",
"2" );
446 xtitleBlock->AddChild( xcomment =
node(
"comment" ) );
447 xcomment->AddAttribute(
"number",
"3" );
450 xtitleBlock->AddChild( xcomment =
node(
"comment" ) );
451 xcomment->AddAttribute(
"number",
"4" );
454 xtitleBlock->AddChild( xcomment =
node(
"comment" ) );
455 xcomment->AddAttribute(
"number",
"5" );
458 xtitleBlock->AddChild( xcomment =
node(
"comment" ) );
459 xcomment->AddAttribute(
"number",
"6" );
462 xtitleBlock->AddChild( xcomment =
node(
"comment" ) );
463 xcomment->AddAttribute(
"number",
"7" );
466 xtitleBlock->AddChild( xcomment =
node(
"comment" ) );
467 xcomment->AddAttribute(
"number",
"8" );
470 xtitleBlock->AddChild( xcomment =
node(
"comment" ) );
471 xcomment->AddAttribute(
"number",
"9" );
486 wxString libNickname = *it;
489 if( symbolLibTable->
HasLibrary( libNickname ) )
491 xlibs->AddChild( xlibrary =
node(
"library" ) );
492 xlibrary->AddAttribute(
"logical", libNickname );
493 xlibrary->AddChild(
node(
"uri", symbolLibTable->
GetFullURI( libNickname ) ) );
508 std::vector<LIB_FIELD*> fieldList;
514 wxString libNickname = lcomp->GetLibId().GetLibNickname();;
517 if( !libNickname.IsEmpty() )
521 xlibparts->AddChild( xlibpart =
node(
"libpart" ) );
522 xlibpart->AddAttribute(
"lib", libNickname );
523 xlibpart->AddAttribute(
"part", lcomp->GetName() );
526 if( !lcomp->GetDescription().IsEmpty() )
527 xlibpart->AddChild(
node(
"description", lcomp->GetDescription() ) );
529 if( !lcomp->GetDatasheetField().GetText().IsEmpty() )
530 xlibpart->AddChild(
node(
"docs", lcomp->GetDatasheetField().GetText() ) );
533 if( lcomp->GetFPFilters().GetCount() )
536 xlibpart->AddChild( xfootprints =
node(
"footprints" ) );
538 for(
unsigned i = 0; i < lcomp->GetFPFilters().GetCount(); ++i )
539 xfootprints->AddChild(
node(
"fp", lcomp->GetFPFilters()[i] ) );
544 lcomp->GetFields( fieldList );
547 xlibpart->AddChild( xfields =
node(
"fields" ) );
549 for(
const LIB_FIELD* field : fieldList )
551 if( !field->GetText().IsEmpty() )
554 xfields->AddChild( xfield =
node(
"field", field->GetText() ) );
555 xfield->AddAttribute(
"name", field->GetCanonicalName() );
561 lcomp->GetPins( pinList, 0, 0 );
572 for(
int ii = 0; ii < (int)pinList.size()-1; ii++ )
574 if( pinList[ii]->GetNumber() == pinList[ii+1]->GetNumber() )
576 pinList.erase(pinList.begin() + ii + 1);
585 xlibpart->AddChild( pins =
node(
"pins" ) );
586 for(
unsigned i=0; i<pinList.size(); ++i )
590 pins->AddChild(
pin =
node(
"pin" ) );
591 pin->AddAttribute(
"num", pinList[i]->GetShownNumber() );
592 pin->AddAttribute(
"name", pinList[i]->GetShownName() );
593 pin->AddAttribute(
"type", pinList[i]->GetCanonicalElectricalTypeName() );
611 XNODE* xnet =
nullptr;
625 m_NoConnect( aNoConnect )
635 NET_RECORD(
const wxString& aName ) :
640 std::vector<NET_NODE> m_Nodes;
643 std::vector<NET_RECORD*> nets;
647 wxString net_name = it.first.first;
648 auto subgraphs = it.second;
649 NET_RECORD* net_record;
651 if( subgraphs.empty() )
654 nets.emplace_back(
new NET_RECORD( net_name ) );
655 net_record = nets.back();
659 bool nc = subgraph->m_no_connect && subgraph->m_no_connect->Type() ==
SCH_NO_CONNECT_T;
662 for(
SCH_ITEM* item : subgraph->m_items )
676 net_record->m_Nodes.emplace_back(
pin, sheet, nc );
683 std::sort( nets.begin(), nets.end(),
684 [](
const NET_RECORD* a,
const NET_RECORD*b )
686 return StrNumCmp( a->m_Name, b->m_Name ) < 0;
689 for(
int i = 0; i < (int) nets.size(); ++i )
691 NET_RECORD* net_record = nets[i];
696 std::sort( net_record->m_Nodes.begin(), net_record->m_Nodes.end(),
697 [](
const NET_NODE& a,
const NET_NODE& b )
699 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
700 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
703 return a.m_Pin->GetShownNumber() < b.m_Pin->GetShownNumber();
711 net_record->m_Nodes.erase(
712 std::unique( net_record->m_Nodes.begin(), net_record->m_Nodes.end(),
713 [](
const NET_NODE& a,
const NET_NODE& b )
715 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
716 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
719 && a.m_Pin->GetShownNumber() == b.m_Pin->GetShownNumber();
721 net_record->m_Nodes.end() );
723 for(
const NET_NODE& netNode : net_record->m_Nodes )
725 wxString refText = netNode.m_Pin->GetParentSymbol()->GetRef( &netNode.m_Sheet );
726 wxString pinText = netNode.m_Pin->GetShownNumber();
729 if( refText[0] == wxChar(
'#' ) )
734 netCodeTxt.Printf(
"%d", i + 1 );
736 xnets->AddChild( xnet =
node(
"net" ) );
737 xnet->AddAttribute(
"code", netCodeTxt );
738 xnet->AddAttribute(
"name", net_record->m_Name );
743 xnet->AddChild( xnode =
node(
"node" ) );
744 xnode->AddAttribute(
"ref", refText );
745 xnode->AddAttribute(
"pin", pinText );
747 wxString pinName = netNode.m_Pin->GetShownName();
748 wxString pinType = netNode.m_Pin->GetCanonicalElectricalTypeName();
750 if( !pinName.IsEmpty() )
751 xnode->AddAttribute(
"pinfunction", pinName );
753 if( netNode.m_NoConnect )
754 pinType +=
"+no_connect";
756 xnode->AddAttribute(
"pintype", pinType );
760 for( NET_RECORD* record : nets )
768 const wxString& aTextualContent )
770 XNODE* n =
new XNODE( wxXML_ELEMENT_NODE, aName );
772 if( aTextualContent.Len() > 0 )
773 n->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, aTextualContent ) );
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
EE_TYPE OfType(KICAD_T aType) const
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
wxString GetShownNumber() const
virtual std::map< wxString, wxString > & GetTextVars() const
const wxString & GetFileName() const
const UTF8 & GetLibItemName() const
virtual wxString GetFileName() const =0
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
Container for project specific data.
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject)
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
const wxString & GetComment(int aIdx) const
int GetUnitCount() const
Return the number of units per package of the symbol.
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
wxString PathHumanReadable(bool aUseShortRootName=true) const
Return the sheet path in a human readable form made from the sheet names.
Field object used in symbol libraries.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
XNODE * makeRoot(unsigned aCtl=GNL_ALL)
Build the entire document tree for the generic export.
bool GetIncludeInBom() const
XNODE * makeLibParts()
Fill out an XML node with the unique library parts and returns it.
wxString AsString() const
const TITLE_BLOCK & GetTitleBlock() const
wxString PathAsString() const
Return the path of time stamps which do not changes even when editing sheet parameters.
virtual CONNECTION_GRAPH * ConnectionGraph() const =0
void Clear()
Erase the record.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Hold the information shown in the lower right corner of a plot, printout, or editing view.
A subgraph is a set of items that are electrically connected on a single sheet.
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
SCH_SYMBOL * findNextSymbol(EDA_ITEM *aItem, SCH_SHEET_PATH *aSheetPath)
Check if the given symbol should be processed for netlisting.
SCHEMATIC_IFACE * m_schematic
The schematic we're generating a netlist for.
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
A convenience function that creates a new XNODE with an optional textual child.
virtual PROJECT & Prj() const =0
UNIQUE_STRINGS m_referencesAlreadyFound
Used for "multiple symbols per package" symbols to avoid processing a lib symbol more than once.
std::vector< SCH_FIELD > & GetFields()
XNODE * makeListOfNets(unsigned aCtl)
Fill out an XML node with a list of nets and returns it.
wxString GetBuildVersion()
Get the full KiCad version string.
const wxString & GetRevision() const
static bool sortPinsByNumber(LIB_PIN *aPin1, LIB_PIN *aPin2)
wxString GetSchSymbolLibraryName() const
wxString GetFullURI(const wxString &aLibNickname, bool aExpandEnvVars=true) const
Return the full URI of the library mapped to aLibNickname.
const wxString & GetCompany() const
int GetFieldCount() const
Return the number of fields in this symbol.
const NET_MAP & GetNetMap() const
Definition for symbol library class.
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
const wxString GetValue(const SCH_SHEET_PATH *sheet, bool aResolve) const
Return the instance-specific value for the given sheet path.
wxString UnescapeString(const wxString &aSource)
virtual void SetCurrentSheet(const SCH_SHEET_PATH &aPath)=0
Hold an XML or S-expression element.
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
void addSymbolFields(XNODE *aNode, SCH_SYMBOL *aSymbol, SCH_SHEET_PATH *aSheet)
Holder for multi-unit symbol fields.
std::set< wxString > m_libraries
const wxString & GetDate() const
XNODE * makeSymbols(unsigned aCtl)
SCH_SCREEN * LastScreen()
bool WriteNetlist(const wxString &aOutFileName, unsigned aNetlistOptions) override
Write generic netlist to aOutFileName.
wxString GetName(bool aUseDefaultName=true) const
Return the field name.
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
A base class for most all the KiCad significant classes used in schematics and boards.
bool GetIncludeOnBoard() const
wxString GetDescription() const
Return information about the aliased parts.
const wxString GetFootprint(const SCH_SHEET_PATH *sheet, bool aResolve) const
Return the instance-specific footprint assignment for the given sheet path.
const wxString & GetTitle() const
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
std::set< LIB_SYMBOL *, LIB_SYMBOL_LESS_THAN > m_libParts
unique library symbols used. LIB_SYMBOL items are sorted by names
virtual SCH_SHEET_LIST GetSheets() const =0
Base class for any item which can be embedded within the SCHEMATIC container class,...
virtual const wxString & GetText() const
Return the string associated with the text object.
XNODE * makeLibraries()
Fill out an XML node with a list of used libraries and returns it.
bool UseLibIdLookup() const
KICAD_T Type() const
Returns the type of object.
const LIB_ID & GetLibId() const
XNODE * makeDesignHeader()
Fill out a project "design" header into an XML node.