39#include <wx/wfstream.h>
61 wxFFileOutputStream stream( aOutFileName );
69 return xdoc.Save( stream, 2 );
112 xroot->AddChild( xchains );
130 wxString description;
132 nlohmann::ordered_map<wxString, wxString> fields;
143 wxString ref = aSymbol->
GetRef( &aSheet );
153 wxString ref2 = symbol2->
GetRef( &sheet );
155 if( ref2.CmpNoCase( ref ) != 0 )
165 if( !candidate.IsEmpty() && ( unit < minUnit || value.IsEmpty() ) )
171 if( !candidate.IsEmpty() && ( unit < minUnit || footprint.IsEmpty() ) )
172 footprint = candidate;
178 if( !candidate.IsEmpty() && ( unit < minUnit ||
datasheet.IsEmpty() ) )
185 if( !candidate.IsEmpty() && ( unit < minUnit || description.IsEmpty() ) )
186 description = candidate;
191 if( field.IsMandatory() || field.IsPrivate() )
194 if( unit < minUnit || fields.count( field.GetName() ) == 0 )
197 fields[field.GetName()] = field.GetShownText( &aSheet,
false );
199 fields[field.GetName()] = field.GetText();
203 minUnit = std::min( unit, minUnit );
223 description = descriptionField->
GetShownText( &aSheet,
false );
225 description = descriptionField->
GetText();
229 if( field.IsMandatory() || field.IsPrivate() )
233 fields[field.GetName()] = field.GetShownText( &aSheet,
false );
235 fields[field.GetName()] = field.GetText();
247 aNode->AddChild(
node( wxT(
"value" ), wxT(
"~" ) ) );
249 if( footprint.size() )
255 if( description.size() )
259 aNode->AddChild( xfields =
node( wxT(
"fields" ) ) );
261 for(
const auto& [ fieldName, fieldValue ] : fields )
265 xfields->AddChild( xfield );
272 XNODE* xcomps =
node( wxT(
"components" ) );
294 b->GetRef( &sheet,
false ),
true ) < 0 );
297 std::set<
SCH_SYMBOL*,
decltype( cmp )> ordered_symbols( cmp );
298 std::multiset<
SCH_SYMBOL*,
decltype( cmp )> extra_units( cmp );
303 auto test = ordered_symbols.insert( symbol );
307 if( ( *(
test.first ) )->m_Uuid > symbol->
m_Uuid )
309 extra_units.insert( *(
test.first ) );
310 ordered_symbols.erase(
test.first );
311 ordered_symbols.insert( symbol );
315 extra_units.insert( symbol );
320 for(
EDA_ITEM* item : ordered_symbols )
340 xcomps->AddChild( xcomp =
node( wxT(
"comp" ) ) );
346 xcomp->AddChild( xlibsource =
node( wxT(
"libsource" ) ) );
377 std::vector<SCH_FIELD>& fields = symbol->
GetFields();
381 if( field.IsMandatory() || field.IsPrivate() )
384 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
385 xproperty->
AddAttribute( wxT(
"name" ), field.GetCanonicalName() );
388 xproperty->
AddAttribute( wxT(
"value" ), field.GetShownText( &sheet,
false ) );
390 xproperty->
AddAttribute( wxT(
"value" ), field.GetText() );
393 for(
const SCH_FIELD& sheetField : sheet.Last()->GetFields() )
395 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
396 xproperty->
AddAttribute( wxT(
"name" ), sheetField.GetCanonicalName() );
401 xproperty->
AddAttribute( wxT(
"value" ), sheetField.GetShownText( &sheet,
false ) );
403 xproperty->
AddAttribute( wxT(
"value" ), sheetField.GetText() );
408 if( baseExcludedFromBOM )
410 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
411 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_bom" ) );
416 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
417 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_board" ) );
422 if( baseExcludedFromPosFiles )
424 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
425 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_pos_files" ) );
428 const bool baseDnp = symbol->
ResolveDNP( &sheet ) || sheet.GetDNP();
432 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
438 const std::set<wxString>& variantNames =
m_schematic->GetVariantNames();
440 if( !variantNames.empty() )
443 XNODE* xvariants =
nullptr;
445 for(
const auto& variantName : variantNames )
447 XNODE* xvariant =
nullptr;
449 auto addToVariant = [
this, &xvariant, &variantName](
XNODE* child ) ->
void
456 xvariant =
node( wxT(
"variant" ) );
459 xvariant->AddChild( child );
462 auto addBinaryProp = [
this, &addToVariant]( wxString
const&
name,
bool base,
463 bool effective ) ->
void
465 if( base == effective )
468 XNODE* xvarprop =
node( wxT(
"property" ) );
470 xvarprop->
AddAttribute( wxT(
"value" ), effective ? wxT(
"1" ) : wxT(
"0" ) );
471 addToVariant( xvarprop );
474 bool effectiveDnp = symbol->
ResolveDNP( &sheet, variantName ) || sheet.GetDNP( variantName );
475 addBinaryProp( wxT(
"dnp" ), baseDnp, effectiveDnp );
478 || sheet.GetExcludedFromBOM( variantName );
479 addBinaryProp( wxT(
"exclude_from_bom" ), baseExcludedFromBOM, effectiveExcludedFromBOM );
482 || sheet.GetExcludedFromSim( variantName );
483 addBinaryProp( wxT(
"exclude_from_sim" ), baseExcludedFromSim, effectiveExcludedFromSim );
486 addBinaryProp( wxT(
"exclude_from_pos_files" ), baseExcludedFromPosFiles,
487 effectiveExcludedFromPosFiles );
493 variant = &instance.
m_Variants.at( variantName );
495 if( variant && !variant->
m_Fields.empty() )
497 XNODE* xfields =
nullptr;
499 for(
const auto& [fieldName, fieldValue] : variant->
m_Fields )
501 const wxString baseValue =
502 symbol->
GetFieldText( fieldName, &sheet, wxEmptyString );
504 if( fieldValue == baseValue )
508 xfields =
node( wxT(
"fields" ) );
510 wxString resolvedValue = fieldValue;
513 resolvedValue = symbol->
ResolveText( fieldValue, &sheet );
517 xfields->AddChild( xfield );
520 addToVariant( xfields );
526 xvariants =
node( wxT(
"variants" ) );
528 xvariants->AddChild( xvariant );
533 xcomp->AddChild( xvariants );
536 if(
const std::unique_ptr<LIB_SYMBOL>& part = symbol->
GetLibSymbolRef() )
538 if( part->GetKeyWords().size() )
540 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
541 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"ki_keywords" ) );
542 xproperty->
AddAttribute( wxT(
"value" ), part->GetKeyWords() );
545 if( !part->GetFPFilters().IsEmpty() )
549 for(
const wxString&
filter : part->GetFPFilters() )
552 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
553 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"ki_fp_filters" ) );
554 xproperty->
AddAttribute( wxT(
"value" ), filters.Trim(
false ) );
557 if( part->GetDuplicatePinNumbersAreJumpers() )
558 xcomp->AddChild(
node( wxT(
"duplicate_pin_numbers_are_jumpers" ), wxT(
"1" ) ) );
560 const std::vector<std::set<wxString>>& jumperGroups = part->JumperPinGroups();
562 if( !jumperGroups.empty() )
565 xcomp->AddChild( xproperty =
node( wxT(
"jumper_pin_groups" ) ) );
567 for(
const std::set<wxString>&
group : jumperGroups )
569 xproperty->AddChild( groupNode =
node( wxT(
"group" ) ) );
571 for(
const wxString& pinName :
group )
572 groupNode->AddChild(
node( wxT(
"pin" ), pinName ) );
578 xcomp->AddChild( xsheetpath =
node( wxT(
"sheetpath" ) ) );
580 xsheetpath->
AddAttribute( wxT(
"names" ), sheet.PathHumanReadable() );
581 xsheetpath->
AddAttribute( wxT(
"tstamps" ), sheet.PathAsString() );
584 std::vector<wxString> compClassNames =
587 if( compClassNames.size() > 0 )
589 XNODE* xcompclasslist;
590 xcomp->AddChild( xcompclasslist =
node( wxT(
"component_classes" ) ) );
592 for(
const wxString& compClass : compClassNames )
599 xcomp->AddChild( xunits =
node( wxT(
"tstamps" ) ) );
601 auto range = extra_units.equal_range( symbol );
605 for(
auto it = range.first; it != range.second; ++it )
607 uuid = ( *it )->m_Uuid.AsString();
614 xunits->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, uuid ) );
619 xunits->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, uuid ) );
623 xcomp->AddChild( xunitInfo =
node( wxT(
"units" ) ) );
638 const std::vector<LIB_SYMBOL::UNIT_PIN_INFO>& defaultUnitInfo = libSym->GetUnitPinInfo();
639 std::map<int, SCH_SYMBOL*> symbolByUnit;
647 int unit = aUnitSymbol->GetUnitSelection( &sheet );
650 symbolByUnit.try_emplace( unit, aUnitSymbol );
653 addUnitSymbol( symbol );
655 auto extraUnitRange = extra_units.equal_range( symbol );
659 for(
auto it = extraUnitRange.first; it != extraUnitRange.second; ++it )
660 addUnitSymbol( *it );
664 for(
size_t unitIdx = 0; unitIdx < defaultUnitInfo.size(); ++unitIdx )
667 auto symbolIt = symbolByUnit.find( unitIdx + 1 );
669 if( symbolIt != symbolByUnit.end() )
671 const std::unique_ptr<LIB_SYMBOL>& unitLibSym = symbolIt->second->GetLibSymbolRef();
675 const std::vector<LIB_SYMBOL::UNIT_PIN_INFO>& unitSpecificInfo =
676 unitLibSym->GetUnitPinInfo();
678 if( unitIdx < unitSpecificInfo.size() )
679 unitInfo = unitSpecificInfo[unitIdx];
684 xunitInfo->AddChild( xunit =
node( wxT(
"unit" ) ) );
688 xunit->AddChild( xpins =
node( wxT(
"pins" ) ) );
693 xpins->AddChild( xpin =
node( wxT(
"pin" ) ) );
729 xcomps->AddChild( xgroup =
node( wxT(
"group" ) ) );
736 xgroup->AddChild( xmembers =
node( wxT(
"members" ) ) );
743 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
744 xmember->
AddAttribute( wxT(
"uuid" ), member->m_Uuid.AsString() );
749 std::vector<SCH_SHEET_PATH> descendantSheets;
759 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
760 xmember->
AddAttribute( wxT(
"uuid" ), descendantItem->m_Uuid.AsString() );
776 XNODE* xvariants =
node( wxT(
"variants" ) );
778 std::set<wxString> variantNames =
m_schematic->GetVariantNames();
780 for(
const wxString& variantName : variantNames )
783 xvariants->AddChild( xvariant =
node( wxT(
"variant" ) ) );
786 wxString description =
m_schematic->GetVariantDescription( variantName );
788 if( !description.IsEmpty() )
789 xvariant->
AddAttribute( wxT(
"description" ), description );
799 std::vector<SCH_SHEET_PATH> symbolSheets;
800 symbolSheets.push_back( aSymbolSheet );
807 const wxString ref = aSymbol->
GetRef( &aSymbolSheet );
815 wxString ref2 = symbol2->
GetRef( &sheet );
818 if( ref2.CmpNoCase( ref ) != 0 )
821 if( otherUnit == primaryUnit )
824 symbolSheets.push_back( sheet );
826 std::unordered_set<wxString> otherClassNames =
828 compClassNames.insert( otherClassNames.begin(), otherClassNames.end() );
838 if( symbolSheetPath.IsContainedWithin( sheetPath ) )
840 compClassNames.insert( sheetCompClasses.begin(), sheetCompClasses.end() );
845 std::vector<wxString> sortedCompClassNames( compClassNames.begin(), compClassNames.end() );
846 std::sort( sortedCompClassNames.begin(), sortedCompClassNames.end(),
847 [](
const wxString& str1,
const wxString& str2 )
849 return str1.Cmp( str2 ) < 0;
852 return sortedCompClassNames;
859 XNODE* xdesign =
node( wxT(
"design" ) );
865 wxFileName sourceFileName;
868 xdesign->AddChild(
node( wxT(
"source" ),
m_schematic->GetFileName() ) );
875 const std::map<wxString, wxString>& properties =
m_schematic->Project().GetTextVars();
877 for(
const std::pair<const wxString, wxString>& prop : properties )
879 xdesign->AddChild( xtextvar =
node( wxT(
"textvar" ), prop.second ) );
886 unsigned sheetIndex = 1;
890 screen = sheet.LastScreen();
892 xdesign->AddChild( xsheet =
node( wxT(
"sheet" ) ) );
895 sheetTxt.Printf( wxT(
"%u" ), sheetIndex++ );
897 xsheet->
AddAttribute( wxT(
"name" ), sheet.PathHumanReadable() );
898 xsheet->
AddAttribute( wxT(
"tstamps" ), sheet.PathAsString() );
903 xsheet->AddChild( xtitleBlock =
node( wxT(
"title_block" ) ) );
911 sourceFileName = wxFileName( screen->
GetFileName() );
912 xtitleBlock->AddChild(
node( wxT(
"source" ), sourceFileName.GetFullName() ) );
914 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
918 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
922 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
926 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
930 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
934 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
938 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
942 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
946 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
957 XNODE* xlibs =
node( wxT(
"libraries" ) );
962 wxString libNickname = *it;
969 xlibs->AddChild( xlibrary =
node( wxT(
"library" ) ) );
970 xlibrary->
AddAttribute( wxT(
"logical" ), libNickname );
971 xlibrary->AddChild(
node( wxT(
"uri" ), *uri ) );
983 XNODE* xlibparts =
node( wxT(
"libparts" ) );
984 std::vector<SCH_FIELD*> fieldList;
990 wxString libNickname = lcomp->GetLibId().GetLibNickname();;
993 if( !libNickname.IsEmpty() )
997 xlibparts->AddChild( xlibpart =
node( wxT(
"libpart" ) ) );
999 xlibpart->
AddAttribute( wxT(
"part" ), lcomp->GetName() );
1002 if( !lcomp->GetDescription().IsEmpty() )
1003 xlibpart->AddChild(
node( wxT(
"description" ), lcomp->GetDescription() ) );
1005 if( !lcomp->GetDatasheetField().GetText().IsEmpty() )
1006 xlibpart->AddChild(
node( wxT(
"docs" ), lcomp->GetDatasheetField().GetText() ) );
1009 if( lcomp->GetFPFilters().GetCount() )
1012 xlibpart->AddChild( xfootprints =
node( wxT(
"footprints" ) ) );
1014 for(
unsigned i = 0; i < lcomp->GetFPFilters().GetCount(); ++i )
1016 if( !lcomp->GetFPFilters()[i].IsEmpty() )
1017 xfootprints->AddChild(
node( wxT(
"fp" ), lcomp->GetFPFilters()[i] ) );
1023 lcomp->GetFields( fieldList );
1026 xlibpart->AddChild( xfields =
node(
"fields" ) );
1028 for(
const SCH_FIELD* field : fieldList )
1031 xfields->AddChild( xfield =
node( wxT(
"field" ), field->GetText() ) );
1032 xfield->
AddAttribute( wxT(
"name" ), field->GetCanonicalName() );
1038 std::vector<SCH_PIN*> pinList = lcomp->GetGraphicalPins( 0, 0 );
1050 for(
int ii = 0; ii < (int)pinList.size()-1; ii++ )
1052 if( pinList[ii]->GetNumber() == pinList[ii+1]->GetNumber() )
1054 pinList.erase(pinList.begin() + ii + 1);
1059 wxLogTrace(
"CVPCB_PINCOUNT",
1060 wxString::Format(
"makeLibParts: lib='%s' part='%s' pinList(size)=%zu",
1061 libNickname, lcomp->GetName(), pinList.size() ) );
1063 if( pinList.size() )
1067 xlibpart->AddChild( pins =
node( wxT(
"pins" ) ) );
1069 for(
unsigned i=0; i<pinList.size(); ++i )
1071 SCH_PIN* basePin = pinList[i];
1073 bool stackedValid =
false;
1077 if( stackedValid && !expandedNums.empty() )
1079 for(
const wxString& num : expandedNums )
1082 pins->AddChild(
pin =
node( wxT(
"pin" ) ) );
1083 pin->AddAttribute( wxT(
"num" ), num );
1087 wxLogTrace(
"CVPCB_PINCOUNT",
1088 wxString::Format(
"makeLibParts: -> pin num='%s' name='%s' (expanded)",
1095 pins->AddChild(
pin =
node( wxT(
"pin" ) ) );
1100 wxLogTrace(
"CVPCB_PINCOUNT",
1101 wxString::Format(
"makeLibParts: -> pin num='%s' name='%s'",
1117 wxString netCodeTxt;
1119 XNODE* xnet =
nullptr;
1141 NET_RECORD(
const wxString& aName ) :
1143 m_HasNoConnect(
false )
1148 bool m_HasNoConnect;
1149 std::vector<NET_NODE> m_Nodes;
1152 std::vector<NET_RECORD*> nets;
1154 for(
const auto& [ key, subgraphs ] :
m_schematic->ConnectionGraph()->GetNetMap() )
1156 wxString net_name = key.Name;
1157 NET_RECORD* net_record =
nullptr;
1162 if( subgraphs.empty() )
1165 nets.emplace_back(
new NET_RECORD( net_name ) );
1166 net_record = nets.back();
1170 bool nc = subgraph->GetNoConnect() && subgraph->GetNoConnect()->Type() ==
SCH_NO_CONNECT_T;
1173 if( net_record->m_Class.IsEmpty() && subgraph->GetDriver() )
1175 if( subgraph->GetDriver()->GetEffectiveNetClass() )
1177 net_record->m_Class = subgraph->GetDriver()->GetEffectiveNetClass()->GetName();
1183 net_record->m_HasNoConnect =
true;
1185 for(
SCH_ITEM* item : subgraph->GetItems() )
1203 net_record->m_Nodes.emplace_back(
pin, sheet );
1210 std::sort( nets.begin(), nets.end(),
1211 [](
const NET_RECORD* a,
const NET_RECORD*b )
1213 return StrNumCmp( a->m_Name, b->m_Name ) < 0;
1216 for(
int i = 0; i < (int) nets.size(); ++i )
1218 NET_RECORD* net_record = nets[i];
1223 std::sort( net_record->m_Nodes.begin(), net_record->m_Nodes.end(),
1224 [](
const NET_NODE& a,
const NET_NODE& b )
1226 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
1227 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
1230 return a.m_Pin->GetShownNumber() < b.m_Pin->GetShownNumber();
1239 [](
const NET_NODE& a,
const NET_NODE& b )
1241 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
1242 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
1244 return refA == refB && a.m_Pin->GetShownNumber() == b.m_Pin->GetShownNumber();
1249 bool allNetPinsStacked =
true;
1251 if( net_record->m_Nodes.size() > 1 )
1253 SCH_PIN* firstPin = net_record->m_Nodes.begin()->m_Pin;
1255 std::all_of( net_record->m_Nodes.begin() + 1, net_record->m_Nodes.end(),
1258 return firstPin->GetParent() == node.m_Pin->GetParent()
1259 && firstPin->GetPosition() == node.m_Pin->GetPosition()
1260 && firstPin->GetName() == node.m_Pin->GetName();
1264 for(
const NET_NODE& netNode : net_record->m_Nodes )
1266 wxString refText = netNode.m_Pin->GetParentSymbol()->GetRef( &netNode.m_Sheet );
1269 if( refText[0] == wxChar(
'#' ) )
1274 netCodeTxt.Printf( wxT(
"%d" ), i + 1 );
1276 xnets->AddChild( xnet =
node( wxT(
"net" ) ) );
1278 xnet->
AddAttribute( wxT(
"name" ), net_record->m_Name );
1279 xnet->
AddAttribute( wxT(
"class" ), net_record->m_Class );
1284 std::vector<wxString> nums = netNode.m_Pin->GetStackedPinNumbers();
1285 wxString baseName = netNode.m_Pin->GetShownName();
1286 wxString pinType = netNode.m_Pin->GetCanonicalElectricalTypeName();
1289 wxString::Format(
"XML: net='%s' ref='%s' base='%s' shownNum='%s' expand=%zu",
1290 net_record->m_Name, refText, baseName,
1291 netNode.m_Pin->GetShownNumber(), nums.size() ) );
1293 for(
const wxString& num : nums )
1295 xnet->AddChild( xnode =
node( wxT(
"node" ) ) );
1299 wxString fullName = baseName.IsEmpty() ? num : baseName + wxT(
"_" ) + num;
1301 if( !baseName.IsEmpty() || nums.size() > 1 )
1304 wxString typeAttr = pinType;
1306 if( net_record->m_HasNoConnect
1307 && ( net_record->m_Nodes.size() == 1 || allNetPinsStacked ) )
1309 typeAttr += wxT(
"+no_connect" );
1311 wxString::Format(
"XML: marking node ref='%s' pin='%s' as no_connect",
1320 for( NET_RECORD* record : nets )
1328 const auto& committed =
m_schematic->ConnectionGraph()->GetCommittedNetChains();
1330 if( committed.empty() )
1333 XNODE* xchains =
node( wxT(
"net_chains" ) );
1335 for(
const std::unique_ptr<SCH_NETCHAIN>&
chain : committed )
1341 xchains->AddChild( xchain =
node( wxT(
"net_chain" ) ) );
1344 if( !
chain->GetNetClass().IsEmpty() )
1353 const std::shared_ptr<NET_SETTINGS>& ns = pf.
NetSettings();
1357 wxString className = ns->GetNetChainClass(
chain->GetName() );
1359 if( !className.IsEmpty() )
1360 xchain->
AddAttribute( wxT(
"net_chain_class" ), className );
1368 wxString::Format( wxT(
"#%02X%02X%02X%02X" ),
1369 (
int) std::clamp(
KiROUND( c.
r * 255.0 ), 0, 255 ),
1370 (
int) std::clamp(
KiROUND( c.
g * 255.0 ), 0, 255 ),
1371 (
int) std::clamp(
KiROUND( c.
b * 255.0 ), 0, 255 ),
1372 (
int) std::clamp(
KiROUND( c.
a * 255.0 ), 0, 255 ) ) );
1376 xchain->AddChild( xmembers =
node( wxT(
"members" ) ) );
1382 for(
const wxString& net :
chain->GetNets() )
1388 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
1392 if( !
chain->GetTerminalRef( 0 ).IsEmpty() || !
chain->GetTerminalRef( 1 ).IsEmpty() )
1395 xchain->AddChild( xterms =
node( wxT(
"terminal_pins" ) ) );
1397 for(
int i = 0; i < 2; ++i )
1399 if(
chain->GetTerminalRef( i ).IsEmpty() )
1403 xterms->AddChild( xterm =
node( wxT(
"terminal_pin" ) ) );
1415 const wxString& aTextualContent )
1417 XNODE* n =
new XNODE( wxXML_ELEMENT_NODE, aName );
1419 if( aTextualContent.Len() > 0 )
1420 n->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, aTextualContent ) );
1437 auto getComponentClassFields = [&](
const std::vector<SCH_FIELD>& fields,
const SCH_SHEET_PATH* sheetPath )
1439 std::unordered_set<wxString> componentClasses;
1443 if( field.GetCanonicalName() == wxT(
"Component Class" ) )
1445 if( field.GetShownText( sheetPath,
false ) != wxEmptyString )
1446 componentClasses.insert( field.GetShownText( sheetPath,
false ) );
1450 return componentClasses;
1458 std::unordered_set<wxString> sheetComponentClasses;
1459 const std::unordered_set<SCH_RULE_AREA*>& sheetRuleAreas = sheetItem->
GetRuleAreaCache();
1465 std::unordered_set<wxString> ruleAreaComponentClasses =
1466 getComponentClassFields( label->GetFields(), &sheet );
1467 sheetComponentClasses.insert( ruleAreaComponentClasses.begin(), ruleAreaComponentClasses.end() );
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
wxString GetBuildVersion()
Get the full KiCad version string.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
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.
A color representation with 4 components: red, green, blue, alpha.
wxString AsString() const
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false)
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
const wxString GetUniStringLibItemName() const
Get strings for display messages in dialogs.
const wxString GetUniStringLibNickname() const
Define a library symbol object.
SCHEMATIC * m_schematic
The schematic we're generating a netlist for.
SCH_SYMBOL * findNextSymbol(EDA_ITEM *aItem, const SCH_SHEET_PATH &aSheetPath)
Check if the given symbol should be processed for netlisting.
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.
void getSheetComponentClasses()
std::map< SCH_SHEET_PATH, std::unordered_set< wxString > > m_sheetComponentClasses
Map of all sheets to component classes covering the whole sheet.
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.
void addSymbolFields(XNODE *aNode, SCH_SYMBOL *aSymbol, const SCH_SHEET_PATH &aSheet, const SCH_SHEET_LIST &aSheetList)
Holder for multi-unit symbol fields.
std::vector< wxString > getComponentClassNamesForAllSymbolUnits(SCH_SYMBOL *aSymbol, const SCH_SHEET_PATH &aSymbolSheet, const SCH_SHEET_LIST &aSheetList)
Finds all component class names attached to any sub-unit of a given symbol.
XNODE * makeSymbols(unsigned aCtl)
XNODE * makeRoot(unsigned aCtl=GNL_ALL)
Build the entire document tree for the generic export.
std::set< wxString > m_libraries
XNODE * makeLibParts()
Fill out an XML node with the unique library parts and returns it.
virtual LIBRARY_MANAGER & GetLibraryManager() const
The backing store for a PROJECT, in JSON format.
std::shared_ptr< NET_SETTINGS > & NetSettings()
Container for project specific data.
A pure virtual class used to derive REPORTER objects from.
virtual const wxString & GetText() const override
Return the string associated with the text object.
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0, const wxString &aVariantName=wxEmptyString) const
A set of SCH_ITEMs (i.e., without duplicates).
Base class for any item which can be embedded within the SCHEMATIC container class,...
bool ResolveExcludedFromPosFiles(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const
const std::unordered_set< SCH_RULE_AREA * > & GetRuleAreaCache() const
Get the cache of rule areas enclosing this item.
bool ResolveExcludedFromBOM(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const
wxString ResolveText(const wxString &aText, const SCH_SHEET_PATH *aPath, int aDepth=0) const
bool ResolveExcludedFromBoard(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const
bool ResolveDNP(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const
bool ResolveExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const
static constexpr char SYNTHETIC_NET_PREFIX[]
Prefix used when synthesising net names for unnamed subgraphs.
std::vector< wxString > GetStackedPinNumbers(bool *aValid=nullptr) const
wxString GetCanonicalElectricalTypeName() const
const wxString & GetShownName() const
const wxString & GetShownNumber() const
const wxString & GetFileName() const
TITLE_BLOCK & GetTitleBlock()
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void GetSheetsWithinPath(std::vector< SCH_SHEET_PATH > &aSheets, const SCH_SHEET_PATH &aSheetPath) const
Add a SCH_SHEET_PATH object to aSheets for each sheet in the list that are contained within aSheetPat...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
bool GetExcludedFromBOM() const
const SCH_SHEET * GetSheet(unsigned aIndex) const
bool GetExcludedFromBoard() const
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Variant information for a schematic symbol.
wxString GetDescription() const override
bool UseLibIdLookup() const
wxString GetFieldText(const wxString &aFieldName, const SCH_SHEET_PATH *aPath=nullptr, const wxString &aVariantName=wxEmptyString) const
wxString GetSchSymbolLibraryName() const
const wxString GetValue(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText, const wxString &aVariantName=wxEmptyString) const override
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
const wxString GetFootprintFieldText(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText, const wxString &aVariantName=wxEmptyString) const
wxString GetShownDescription(int aDepth=0) const override
const LIB_ID & GetLibId() const override
bool GetInstance(SCH_SYMBOL_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
int GetUnitCount() const override
Return the number of units per package of the symbol.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
std::unordered_set< wxString > GetComponentClassNames(const SCH_SHEET_PATH *aPath) const
Return the component classes this symbol belongs in.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
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
std::map< wxString, wxString > m_Fields
An extension of wxXmlNode that can format its contents as KiCad-style s-expressions.
void AddAttribute(const wxString &aName, const wxString &aValue) override
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, int aFlags)
const wxChar *const traceStackedPins
Flag to enable debug output for stacked pins handling in symbol/pin code.
void remove_duplicates(_Container &__c)
Deletes all duplicate values from __c.
static bool sortPinsByNumber(SCH_PIN *aPin1, SCH_PIN *aPin2)
PGM_BASE & Pgm()
The global program "get" accessor.
Class to handle a set of SCH_ITEMs.
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
wxString UnescapeString(const wxString &aSource)
wxString GetISO8601CurrentDateTime()
std::vector< wxString > m_pinNumbers
A simple container for schematic symbol instance information.
std::map< wxString, SCH_SYMBOL_VARIANT > m_Variants
A list of symbol variants.
@ DESCRIPTION
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ DATASHEET
name of datasheet
wxString GetCanonicalFieldName(FIELD_T aFieldType)
const SHAPE_LINE_CHAIN chain
wxLogTrace helper definitions.