35#include <wx/wfstream.h>
51 wxFFileOutputStream stream( aOutFileName );
59 return xdoc.Save( stream, 2 );
67 xroot->AddAttribute( wxT(
"version" ), wxT(
"E" ) );
100 std::map<wxString, wxString> userFields;
111 wxString ref = aSymbol->
GetRef( aSheet );
116 for(
unsigned i = 0; i < sheetList.size(); i++ )
122 wxString ref2 = symbol2->
GetRef( &sheetList[i] );
124 if( ref2.CmpNoCase( ref ) != 0 )
132 if( !candidate.IsEmpty() && ( unit < minUnit || value.IsEmpty() ) )
137 if( !candidate.IsEmpty() && ( unit < minUnit || footprint.IsEmpty() ) )
138 footprint = candidate;
143 if( !candidate.IsEmpty() && ( unit < minUnit ||
datasheet.IsEmpty() ) )
151 && ( unit < minUnit || userFields.count( f.
GetName() ) == 0 ) )
160 minUnit = std::min( unit, minUnit );
192 aNode->AddChild(
node( wxT(
"value" ), wxT(
"~" ) ) );
194 if( footprint.size() )
200 if( userFields.size() )
203 aNode->AddChild( xfields =
node( wxT(
"fields" ) ) );
206 for(
const std::pair<const wxString, wxString>& f : userFields )
210 xfields->AddChild( xfield );
218 XNODE* xcomps =
node( wxT(
"components" ) );
228 for(
unsigned ii = 0; ii < sheetList.size(); ii++ )
235 b->GetRef( &sheet,
false ),
true ) < 0 );
238 std::set<
SCH_SYMBOL*,
decltype( cmp )> ordered_symbols( cmp );
239 std::multiset<
SCH_SYMBOL*,
decltype( cmp )> extra_units( cmp );
244 auto test = ordered_symbols.insert( symbol );
248 if( ( *(
test.first ) )->m_Uuid > symbol->
m_Uuid )
250 extra_units.insert( *(
test.first ) );
251 ordered_symbols.erase(
test.first );
252 ordered_symbols.insert( symbol );
256 extra_units.insert( symbol );
261 for(
EDA_ITEM* item : ordered_symbols )
277 xcomps->AddChild( xcomp =
node( wxT(
"comp" ) ) );
279 xcomp->AddAttribute( wxT(
"ref" ), symbol->
GetRef( &sheet ) );
283 xcomp->AddChild( xlibsource =
node( wxT(
"libsource" ) ) );
301 xlibsource->AddAttribute( wxT(
"lib" ), libName );
304 xlibsource->AddAttribute( wxT(
"part" ), partName );
306 xlibsource->AddAttribute( wxT(
"description" ), symbol->
GetDescription() );
310 std::vector<SCH_FIELD>& fields = symbol->
GetFields();
314 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
315 xproperty->AddAttribute( wxT(
"name" ), fields[jj].GetCanonicalName() );
318 xproperty->AddAttribute( wxT(
"value" ), fields[jj].GetShownText() );
320 xproperty->AddAttribute( wxT(
"value" ), fields[jj].
GetText() );
325 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
326 xproperty->AddAttribute( wxT(
"name" ), sheetField.GetCanonicalName() );
331 xproperty->AddAttribute( wxT(
"value" ), sheetField.GetShownText( 0,
false ) );
333 xproperty->AddAttribute( wxT(
"value" ), sheetField.GetText() );
338 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
339 xproperty->AddAttribute( wxT(
"name" ), wxT(
"exclude_from_bom" ) );
344 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
345 xproperty->AddAttribute( wxT(
"name" ), wxT(
"exclude_from_board" ) );
350 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
351 xproperty->AddAttribute( wxT(
"name" ), wxT(
"dnp" ) );
354 if(
const std::unique_ptr<LIB_SYMBOL>& part = symbol->
GetLibSymbolRef() )
356 if( part->GetDescription().size() )
358 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
359 xproperty->AddAttribute( wxT(
"name" ), wxT(
"ki_description" ) );
360 xproperty->AddAttribute( wxT(
"value" ), part->GetDescription() );
363 if( part->GetKeyWords().size() )
365 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
366 xproperty->AddAttribute( wxT(
"name" ), wxT(
"ki_keywords" ) );
367 xproperty->AddAttribute( wxT(
"value" ), part->GetKeyWords() );
372 xcomp->AddChild( xsheetpath =
node( wxT(
"sheetpath" ) ) );
375 xsheetpath->AddAttribute( wxT(
"tstamps" ), sheet.
PathAsString() );
378 xcomp->AddChild( xunits =
node( wxT(
"tstamps" ) ) );
380 auto range = extra_units.equal_range( symbol );
384 for(
auto it = range.first; it != range.second; ++it )
386 uuid = ( *it )->m_Uuid.AsString();
393 xunits->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, uuid ) );
398 xunits->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, uuid ) );
409 XNODE* xdesign =
node( wxT(
"design" ) );
415 wxFileName sourceFileName;
427 for(
const std::pair<const wxString, wxString>& prop : properties )
429 xdesign->AddChild( xtextvar =
node( wxT(
"textvar" ), prop.second ) );
430 xtextvar->AddAttribute( wxT(
"name" ), prop.first );
438 for(
unsigned i = 0; i < sheetList.size(); i++ )
440 screen = sheetList[i].LastScreen();
442 xdesign->AddChild( xsheet =
node( wxT(
"sheet" ) ) );
447 sheetTxt.Printf( wxT(
"%u" ), i + 1 );
448 xsheet->AddAttribute( wxT(
"number" ), sheetTxt );
449 xsheet->AddAttribute( wxT(
"name" ), sheetList[i].PathHumanReadable() );
450 xsheet->AddAttribute( wxT(
"tstamps" ), sheetList[i].PathAsString() );
455 xsheet->AddChild( xtitleBlock =
node( wxT(
"title_block" ) ) );
463 sourceFileName = wxFileName( screen->
GetFileName() );
464 xtitleBlock->AddChild(
node( wxT(
"source" ), sourceFileName.GetFullName() ) );
466 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
467 xcomment->AddAttribute( wxT(
"number" ), wxT(
"1" ) );
470 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
471 xcomment->AddAttribute( wxT(
"number" ), wxT(
"2" ) );
474 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
475 xcomment->AddAttribute( wxT(
"number" ), wxT(
"3" ) );
478 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
479 xcomment->AddAttribute( wxT(
"number" ), wxT(
"4" ) );
482 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
483 xcomment->AddAttribute( wxT(
"number" ), wxT(
"5" ) );
486 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
487 xcomment->AddAttribute( wxT(
"number" ), wxT(
"6" ) );
490 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
491 xcomment->AddAttribute( wxT(
"number" ), wxT(
"7" ) );
494 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
495 xcomment->AddAttribute( wxT(
"number" ), wxT(
"8" ) );
498 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
499 xcomment->AddAttribute( wxT(
"number" ), wxT(
"9" ) );
509 XNODE* xlibs =
node( wxT(
"libraries" ) );
514 wxString libNickname = *it;
517 if( symbolLibTable->
HasLibrary( libNickname ) )
519 xlibs->AddChild( xlibrary =
node( wxT(
"library" ) ) );
520 xlibrary->AddAttribute( wxT(
"logical" ), libNickname );
521 xlibrary->AddChild(
node( wxT(
"uri" ), symbolLibTable->
GetFullURI( libNickname ) ) );
533 XNODE* xlibparts =
node( wxT(
"libparts" ) );
536 std::vector<LIB_FIELD*> fieldList;
542 wxString libNickname = lcomp->GetLibId().GetLibNickname();;
545 if( !libNickname.IsEmpty() )
549 xlibparts->AddChild( xlibpart =
node( wxT(
"libpart" ) ) );
550 xlibpart->AddAttribute( wxT(
"lib" ), libNickname );
551 xlibpart->AddAttribute( wxT(
"part" ), lcomp->GetName() );
554 if( !lcomp->GetDescription().IsEmpty() )
555 xlibpart->AddChild(
node( wxT(
"description" ), lcomp->GetDescription() ) );
557 if( !lcomp->GetDatasheetField().GetText().IsEmpty() )
558 xlibpart->AddChild(
node( wxT(
"docs" ), lcomp->GetDatasheetField().GetText() ) );
561 if( lcomp->GetFPFilters().GetCount() )
564 xlibpart->AddChild( xfootprints =
node( wxT(
"footprints" ) ) );
566 for(
unsigned i = 0; i < lcomp->GetFPFilters().GetCount(); ++i )
567 xfootprints->AddChild(
node( wxT(
"fp" ), lcomp->GetFPFilters()[i] ) );
572 lcomp->GetFields( fieldList );
575 xlibpart->AddChild( xfields =
node(
"fields" ) );
577 for(
const LIB_FIELD* field : fieldList )
579 if( !field->GetText().IsEmpty() )
582 xfields->AddChild( xfield =
node( wxT(
"field" ), field->GetText() ) );
583 xfield->AddAttribute( wxT(
"name" ), field->GetCanonicalName() );
589 lcomp->GetPins( pinList, 0, 0 );
600 for(
int ii = 0; ii < (int)pinList.size()-1; ii++ )
602 if( pinList[ii]->GetNumber() == pinList[ii+1]->GetNumber() )
604 pinList.erase(pinList.begin() + ii + 1);
613 xlibpart->AddChild( pins =
node( wxT(
"pins" ) ) );
614 for(
unsigned i=0; i<pinList.size(); ++i )
618 pins->AddChild(
pin =
node( wxT(
"pin" ) ) );
619 pin->AddAttribute( wxT(
"num" ), pinList[i]->GetShownNumber() );
620 pin->AddAttribute( wxT(
"name" ), pinList[i]->GetShownName() );
621 pin->AddAttribute( wxT(
"type" ), pinList[i]->GetCanonicalElectricalTypeName() );
639 XNODE* xnet =
nullptr;
653 m_NoConnect( aNoConnect )
663 NET_RECORD(
const wxString& aName ) :
668 std::vector<NET_NODE> m_Nodes;
671 std::vector<NET_RECORD*> nets;
675 wxString net_name = key.Name;
676 NET_RECORD* net_record =
nullptr;
678 if( subgraphs.empty() )
681 nets.emplace_back(
new NET_RECORD( net_name ) );
682 net_record = nets.back();
686 bool nc = subgraph->m_no_connect && subgraph->m_no_connect->Type() ==
SCH_NO_CONNECT_T;
689 for(
SCH_ITEM* item : subgraph->m_items )
703 net_record->m_Nodes.emplace_back(
pin, sheet, nc );
710 std::sort( nets.begin(), nets.end(),
711 [](
const NET_RECORD* a,
const NET_RECORD*b )
713 return StrNumCmp( a->m_Name, b->m_Name ) < 0;
716 for(
int i = 0; i < (int) nets.size(); ++i )
718 NET_RECORD* net_record = nets[i];
723 std::sort( net_record->m_Nodes.begin(), net_record->m_Nodes.end(),
724 [](
const NET_NODE& a,
const NET_NODE& b )
726 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
727 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
730 return a.m_Pin->GetShownNumber() < b.m_Pin->GetShownNumber();
739 [](
const NET_NODE& a,
const NET_NODE& b )
741 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
742 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
744 return refA == refB && a.m_Pin->GetShownNumber() == b.m_Pin->GetShownNumber();
747 for(
const NET_NODE& netNode : net_record->m_Nodes )
749 wxString refText = netNode.m_Pin->GetParentSymbol()->GetRef( &netNode.m_Sheet );
750 wxString pinText = netNode.m_Pin->GetShownNumber();
753 if( refText[0] == wxChar(
'#' ) )
758 netCodeTxt.Printf( wxT(
"%d" ), i + 1 );
760 xnets->AddChild( xnet =
node( wxT(
"net" ) ) );
761 xnet->AddAttribute( wxT(
"code" ), netCodeTxt );
762 xnet->AddAttribute( wxT(
"name" ), net_record->m_Name );
767 xnet->AddChild( xnode =
node( wxT(
"node" ) ) );
768 xnode->AddAttribute( wxT(
"ref" ), refText );
769 xnode->AddAttribute( wxT(
"pin" ), pinText );
771 wxString pinName = netNode.m_Pin->GetShownName();
772 wxString pinType = netNode.m_Pin->GetCanonicalElectricalTypeName();
774 if( !pinName.IsEmpty() )
775 xnode->AddAttribute( wxT(
"pinfunction" ), pinName );
777 if( netNode.m_NoConnect )
778 pinType += wxT(
"+no_connect" );
780 xnode->AddAttribute( wxT(
"pintype" ), pinType );
784 for( NET_RECORD* record : nets )
792 const wxString& aTextualContent )
794 XNODE* n =
new XNODE( wxXML_ELEMENT_NODE, aName );
796 if( aTextualContent.Len() > 0 )
797 n->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, aTextualContent ) );
wxString GetBuildVersion()
Get the full KiCad version string.
const NET_MAP & GetNetMap() const
A subgraph is a set of items that are electrically connected on a single sheet.
A base class for most all the KiCad significant classes used in schematics and boards.
KICAD_T Type() const
Returns the type of object.
virtual const wxString & GetText() const
Return the string associated with the text object.
EE_TYPE OfType(KICAD_T aType) const
wxString AsString() const
Field object used in symbol libraries.
const UTF8 & GetLibItemName() const
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
wxString GetShownNumber() const
Define a library symbol object.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
wxString GetFullURI(const wxString &aLibNickname, bool aExpandEnvVars=true) const
Return the full URI of the library mapped to aLibNickname.
std::set< LIB_SYMBOL *, LIB_SYMBOL_LESS_THAN > m_libParts
unique library symbols used. LIB_SYMBOL items are sorted by names
UNIQUE_STRINGS m_referencesAlreadyFound
Used for "multiple symbols per package" symbols to avoid processing a lib symbol more than once.
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 * makeDesignHeader()
Fill out a project "design" header into an XML node.
XNODE * makeLibraries()
Fill out an XML node with a list of used libraries and returns it.
bool WriteNetlist(const wxString &aOutFileName, unsigned aNetlistOptions, REPORTER &aReporter) override
Write generic netlist to aOutFileName.
XNODE * node(const wxString &aName, const wxString &aTextualContent=wxEmptyString)
A convenience function that creates a new XNODE with an optional textual child.
XNODE * makeListOfNets(unsigned aCtl)
Fill out an XML node with a list of nets and returns it.
XNODE * makeSymbols(unsigned aCtl)
XNODE * makeRoot(unsigned aCtl=GNL_ALL)
Build the entire document tree for the generic export.
void addSymbolFields(XNODE *aNode, SCH_SYMBOL *aSymbol, SCH_SHEET_PATH *aSheet)
Holder for multi-unit symbol fields.
std::set< wxString > m_libraries
XNODE * makeLibParts()
Fill out an XML node with the unique library parts and returns it.
Container for project specific data.
virtual std::map< wxString, wxString > & GetTextVars() const
A pure virtual class used to derive REPORTER objects from.
virtual wxString GetFileName() const =0
virtual CONNECTION_GRAPH * ConnectionGraph() const =0
virtual SCH_SHEET_LIST GetSheets() const =0
virtual PROJECT & Prj() const =0
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
wxString GetShownText(int aDepth=0, bool aAllowExtraText=true) const override
Return the string actually shown after processing of the base text.
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
Base class for any item which can be embedded within the SCHEMATIC container class,...
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
const wxString & GetFileName() const
const TITLE_BLOCK & GetTitleBlock() const
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false) const
Return the sheet path in a human readable form made from the sheet names.
SCH_SCREEN * LastScreen()
wxString PathAsString() const
Return the path of time stamps which do not changes even when editing sheet parameters.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
std::vector< SCH_FIELD > & GetFields()
int GetUnitCount() const
Return the number of units per package of the symbol.
int GetFieldCount() const
Return the number of fields in this symbol.
bool UseLibIdLookup() const
wxString GetSchSymbolLibraryName() const
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
bool GetIncludeOnBoard() const
bool GetIncludeInBom() const
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
const wxString GetFootprintFieldText(bool aResolve) const
wxString GetDescription() const
const wxString GetValueFieldText(bool aResolve) const
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
const LIB_ID & GetLibId() const
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Hold the information shown in the lower right corner of a plot, printout, or editing view.
const wxString & GetCompany() const
const wxString & GetRevision() const
const wxString & GetDate() const
const wxString & GetComment(int aIdx) const
const wxString & GetTitle() const
void Clear()
Erase the record.
Hold an XML or S-expression element.
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject)
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
wxString GetText(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
void remove_duplicates(_Container &__c)
Deletes all duplicate values from __c.
static bool sortPinsByNumber(LIB_PIN *aPin1, LIB_PIN *aPin2)
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
wxString UnescapeString(const wxString &aSource)
Definition for symbol library class.
@ DATASHEET_FIELD
name of datasheet
@ MANDATORY_FIELDS
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.