35#include <wx/wfstream.h>
59 wxFFileOutputStream stream( aOutFileName );
67 return xdoc.Save( stream, 2 );
114 xroot->AddChild( xchains );
131 wxString description;
133 nlohmann::ordered_map<wxString, wxString> fields;
144 wxString ref = aSymbol->
GetRef( &aSheet );
147 using SOURCE = std::pair<int, KIID>;
149 std::optional<SOURCE> valueSrc;
150 std::optional<SOURCE> footprintSrc;
151 std::optional<SOURCE> datasheetSrc;
152 std::optional<SOURCE> descriptionSrc;
155 std::map<wxString, std::pair<bool, SOURCE>> fieldSrcs;
158 [](
const SOURCE& aNew,
const std::optional<SOURCE>& aOld )
160 return !aOld || aNew < *aOld;
169 wxString ref2 = symbol2->
GetRef( &sheet );
171 if( ref2.CmpNoCase( ref ) != 0 )
181 if( !candidate.IsEmpty() && earlier( src, valueSrc ) )
190 if( !candidate.IsEmpty() && earlier( src, footprintSrc ) )
192 footprint = candidate;
200 if( !candidate.IsEmpty() && earlier( src, datasheetSrc ) )
210 if( !candidate.IsEmpty() && earlier( src, descriptionSrc ) )
212 description = candidate;
213 descriptionSrc = src;
219 if( field.IsMandatory() || field.IsPrivate() )
224 const std::pair<bool, SOURCE> rank{ candidate.IsEmpty(), src };
225 auto known = fieldSrcs.find( field.GetName() );
227 if( known == fieldSrcs.end() || rank < known->second )
229 fields[field.GetName()] = candidate;
230 fieldSrcs.insert_or_assign( field.GetName(), rank );
249 if( field.IsMandatory() || field.IsPrivate() )
264 aNode->AddChild(
node( wxT(
"value" ), wxT(
"~" ) ) );
266 if( footprint.size() )
272 if( description.size() )
276 aNode->AddChild( xfields =
node( wxT(
"fields" ) ) );
278 for(
const auto& [ fieldName, fieldValue ] : fields )
282 xfields->AddChild( xfield );
289 XNODE* xcomps =
node( wxT(
"components" ) );
311 b->GetRef( &sheet,
false ),
true ) < 0 );
314 std::set<
SCH_SYMBOL*,
decltype( cmp )> ordered_symbols( cmp );
315 std::multiset<
SCH_SYMBOL*,
decltype( cmp )> extra_units( cmp );
320 auto test = ordered_symbols.insert( symbol );
324 if( ( *(
test.first ) )->m_Uuid > symbol->
m_Uuid )
326 extra_units.insert( *(
test.first ) );
327 ordered_symbols.erase(
test.first );
328 ordered_symbols.insert( symbol );
332 extra_units.insert( symbol );
337 for(
EDA_ITEM* item : ordered_symbols )
349 if( forBOM && ( sheet.GetExcludedFromBOM(
m_schematic->GetCurrentVariant() )
355 if( forBoard && ( sheet.GetExcludedFromBoard(
m_schematic->GetCurrentVariant() )
366 xcomps->AddChild( xcomp =
node( wxT(
"comp" ) ) );
372 xcomp->AddChild( xlibsource =
node( wxT(
"libsource" ) ) );
400 std::vector<SCH_FIELD>& fields = symbol->
GetFields();
404 if( field.IsMandatory() || field.IsPrivate() )
407 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
408 xproperty->
AddAttribute( wxT(
"name" ), field.GetUntranslatedName() );
414 for(
const SCH_FIELD& sheetField : sheet.Last()->GetFields() )
416 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
417 xproperty->
AddAttribute( wxT(
"name" ), sheetField.GetUntranslatedName() );
429 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
430 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_bom" ) );
436 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
437 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_sim" ) );
443 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
444 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_board" ) );
451 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
452 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_pos_files" ) );
455 const bool baseDnp = symbol->
ResolveDNP( &sheet ) || sheet.GetDNP();
459 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
465 const std::set<wxString>& variantNames =
m_schematic->GetVariantNames();
470 XNODE* xvariants =
nullptr;
472 for(
const auto& variantName : variantNames )
474 XNODE* xvariant =
nullptr;
477 [
this, &xvariant, &variantName](
XNODE* child ) ->
void
484 xvariant =
node( wxT(
"variant" ) );
487 xvariant->AddChild( child );
491 [
this, &addToVariant]( wxString
const&
name,
bool base,
bool effective ) ->
void
493 if( base == effective )
496 XNODE* xvarprop =
node( wxT(
"property" ) );
498 xvarprop->
AddAttribute( wxT(
"value" ), effective ? wxT(
"1" ) : wxT(
"0" ) );
499 addToVariant( xvarprop );
502 bool effectiveDnp = symbol->
ResolveDNP( &sheet, variantName ) || sheet.GetDNP( variantName );
503 addBinaryProp( wxT(
"dnp" ), baseDnp, effectiveDnp );
506 || sheet.GetExcludedFromBOM( variantName );
507 addBinaryProp( wxT(
"exclude_from_bom" ), baseExcludedFromBOM, effectiveExcludedFromBOM );
510 || sheet.GetExcludedFromSim( variantName );
511 addBinaryProp( wxT(
"exclude_from_sim" ), baseExcludedFromSim, effectiveExcludedFromSim );
514 addBinaryProp( wxT(
"exclude_from_pos_files" ), baseExcludedFromPosFiles,
515 effectiveExcludedFromPosFiles );
521 variant = &instance.
m_Variants.at( variantName );
525 XNODE* xprop =
node( wxT(
"property" ) );
526 xprop->
AddAttribute( wxT(
"name" ), wxT(
"symbol_override" ) );
528 addToVariant( xprop );
533 XNODE* xfields =
nullptr;
535 for(
const auto& [fieldName, fieldValue] : variant->
m_Fields )
537 const wxString baseValue = symbol->
GetFieldText( fieldName, &sheet, wxEmptyString );
539 if( fieldValue == baseValue )
543 xfields =
node( wxT(
"fields" ) );
545 wxString resolvedValue = fieldValue;
548 resolvedValue = symbol->
ResolveText( fieldValue, &sheet );
552 xfields->AddChild( xfield );
562 const wxString& fieldName = baseField.GetName();
564 if( variant->
m_Fields.contains( fieldName ) )
567 const wxString baseValue = symbol->
GetFieldText( fieldName, &sheet, wxEmptyString );
568 const wxString variantValue = symbol->
GetFieldText( fieldName, &sheet, variantName );
570 if( variantValue == baseValue )
574 xfields =
node( wxT(
"fields" ) );
576 wxString resolvedValue = variantValue;
579 resolvedValue = symbol->
ResolveText( variantValue, &sheet );
583 xfields->AddChild( xfield );
590 std::vector<SCH_FIELD*> altFields;
591 altSymbol->GetFields( altFields );
593 for(
const SCH_FIELD* altField : altFields )
595 const wxString& fieldName = altField->GetName();
598 || variant->
m_Fields.contains( fieldName )
599 || altField->GetText().IsEmpty() )
605 xfields =
node( wxT(
"fields" ) );
607 wxString resolvedValue = altField->GetText();
610 resolvedValue = symbol->
ResolveText( resolvedValue, &sheet );
614 xfields->AddChild( xfield );
619 addToVariant( xfields );
625 xvariants =
node( wxT(
"variants" ) );
627 xvariants->AddChild( xvariant );
632 xcomp->AddChild( xvariants );
635 if(
const std::unique_ptr<LIB_SYMBOL>& part = symbol->
GetLibSymbolRef() )
637 if( part->GetKeyWords().size() )
639 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
640 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"ki_keywords" ) );
641 xproperty->
AddAttribute( wxT(
"value" ), part->GetKeyWords() );
644 if( !part->GetFPFilters().IsEmpty() )
648 for(
const wxString&
filter : part->GetFPFilters() )
651 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
652 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"ki_fp_filters" ) );
656 if( part->GetDuplicatePinNumbersAreJumpers() )
657 xcomp->AddChild(
node( wxT(
"duplicate_pin_numbers_are_jumpers" ), wxT(
"1" ) ) );
664 xcomp->AddChild( xproperty =
node( wxT(
"jumper_pin_groups" ) ) );
668 xproperty->AddChild( groupNode =
node( wxT(
"group" ) ) );
670 for(
const wxString& pinName :
group.GetNames() )
671 groupNode->AddChild(
node( wxT(
"pin" ), pinName ) );
677 xcomp->AddChild( xsheetpath =
node( wxT(
"sheetpath" ) ) );
679 xsheetpath->
AddAttribute( wxT(
"names" ), sheet.PathHumanReadable() );
680 xsheetpath->
AddAttribute( wxT(
"tstamps" ), sheet.PathAsString() );
685 if( compClassNames.size() > 0 )
687 XNODE* xcompclasslist;
688 xcomp->AddChild( xcompclasslist =
node( wxT(
"component_classes" ) ) );
690 for(
const wxString& compClass : compClassNames )
695 xcomp->AddChild( xunits =
node( wxT(
"tstamps" ) ) );
697 auto range = extra_units.equal_range( symbol );
701 for(
auto it = range.first; it != range.second; ++it )
703 uuid = ( *it )->m_Uuid.AsString();
710 xunits->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, uuid ) );
715 xunits->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, uuid ) );
719 xcomp->AddChild( xunitInfo =
node( wxT(
"units" ) ) );
734 const std::vector<LIB_SYMBOL::UNIT_PIN_INFO>& defaultUnitInfo = libSym->GetUnitPinInfo();
735 std::map<int, SCH_SYMBOL*> symbolByUnit;
743 int unit = aUnitSymbol->GetUnitSelection( &sheet );
746 symbolByUnit.try_emplace( unit, aUnitSymbol );
749 addUnitSymbol( symbol );
751 auto extraUnitRange = extra_units.equal_range( symbol );
755 for(
auto it = extraUnitRange.first; it != extraUnitRange.second; ++it )
756 addUnitSymbol( *it );
760 for(
size_t unitIdx = 0; unitIdx < defaultUnitInfo.size(); ++unitIdx )
763 auto symbolIt = symbolByUnit.find( unitIdx + 1 );
765 if( symbolIt != symbolByUnit.end() )
767 const std::unique_ptr<LIB_SYMBOL>& unitLibSym = symbolIt->second->GetLibSymbolRef();
771 const std::vector<LIB_SYMBOL::UNIT_PIN_INFO>& unitSpecificInfo =
772 unitLibSym->GetUnitPinInfo();
774 if( unitIdx < unitSpecificInfo.size() )
775 unitInfo = unitSpecificInfo[unitIdx];
780 xunitInfo->AddChild( xunit =
node( wxT(
"unit" ) ) );
784 xunit->AddChild( xpins =
node( wxT(
"pins" ) ) );
789 xpins->AddChild( xpin =
node( wxT(
"pin" ) ) );
813 std::map<SCH_SCREEN*, int> screenVisits;
816 screenVisits[sheet.LastScreen()]++;
824 wxString instancePrefix = sheet.PathAsString();
829 wxString groupName =
group->GetName();
831 if( screenVisits[sheet.LastScreen()] > 1 )
832 groupName = wxString::Format( wxT(
"%s (%s)" ), groupName, sheet.PathHumanReadable() );
835 xcomps->AddChild( xgroup =
node( wxT(
"group" ) ) );
838 xgroup->
AddAttribute( wxT(
"uuid" ), instancePrefix +
group->m_Uuid.AsString() );
842 xgroup->AddChild( xmembers =
node( wxT(
"members" ) ) );
849 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
850 xmember->
AddAttribute( wxT(
"uuid" ), instancePrefix + member->m_Uuid.AsString() );
856 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
857 xmember->
AddAttribute( wxT(
"uuid" ), instancePrefix + member->m_Uuid.AsString() );
862 std::vector<SCH_SHEET_PATH> descendantSheets;
872 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
874 descendantSheet.PathAsString() + descendantItem->m_Uuid.AsString() );
890 XNODE* xvariants =
node( wxT(
"variants" ) );
892 std::set<wxString> variantNames =
m_schematic->GetVariantNames();
894 for(
const wxString& variantName : variantNames )
897 xvariants->AddChild( xvariant =
node( wxT(
"variant" ) ) );
900 wxString description =
m_schematic->GetVariantDescription( variantName );
902 if( !description.IsEmpty() )
903 xvariant->
AddAttribute( wxT(
"description" ), description );
913 std::vector<SCH_SHEET_PATH> symbolSheets;
914 symbolSheets.push_back( aSymbolSheet );
921 const wxString ref = aSymbol->
GetRef( &aSymbolSheet );
929 wxString ref2 = symbol2->
GetRef( &sheet );
932 if( ref2.CmpNoCase( ref ) != 0 )
935 if( otherUnit == primaryUnit )
938 symbolSheets.push_back( sheet );
942 compClassNames.insert( otherClassNames.begin(), otherClassNames.end() );
952 if( symbolSheetPath.IsContainedWithin( sheetPath ) )
953 compClassNames.insert( sheetCompClasses.begin(), sheetCompClasses.end() );
957 std::vector<wxString> sortedCompClassNames( compClassNames.begin(), compClassNames.end() );
958 std::sort( sortedCompClassNames.begin(), sortedCompClassNames.end(),
959 [](
const wxString& str1,
const wxString& str2 )
961 return str1.Cmp( str2 ) < 0;
964 return sortedCompClassNames;
971 XNODE* xdesign =
node( wxT(
"design" ) );
977 wxFileName sourceFileName;
980 xdesign->AddChild(
node( wxT(
"source" ),
m_schematic->GetFileName() ) );
987 const std::map<wxString, wxString>& properties =
m_schematic->Project().GetTextVars();
989 for(
const std::pair<const wxString, wxString>& prop : properties )
991 xdesign->AddChild( xtextvar =
node( wxT(
"textvar" ), prop.second ) );
998 unsigned sheetIndex = 1;
1002 screen = sheet.LastScreen();
1004 xdesign->AddChild( xsheet =
node( wxT(
"sheet" ) ) );
1007 sheetTxt.Printf( wxT(
"%u" ), sheetIndex++ );
1009 xsheet->
AddAttribute( wxT(
"name" ), sheet.PathHumanReadable() );
1010 xsheet->
AddAttribute( wxT(
"tstamps" ), sheet.PathAsString() );
1015 xsheet->AddChild( xtitleBlock =
node( wxT(
"title_block" ) ) );
1023 sourceFileName = wxFileName( screen->
GetFileName() );
1024 xtitleBlock->AddChild(
node( wxT(
"source" ), sourceFileName.GetFullName() ) );
1026 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1030 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1034 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1038 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1042 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1046 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1050 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1054 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1058 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
1069 XNODE* xlibs =
node( wxT(
"libraries" ) );
1080 xlibs->AddChild( xlibrary =
node( wxT(
"library" ) ) );
1081 xlibrary->
AddAttribute( wxT(
"logical" ), libNickname );
1082 xlibrary->AddChild(
node( wxT(
"uri" ), *uri ) );
1092 XNODE* xlibparts =
node( wxT(
"libparts" ) );
1093 std::vector<SCH_FIELD*> fieldList;
1099 wxString libNickname = lcomp->GetLibId().GetLibNickname();;
1102 if( !libNickname.IsEmpty() )
1106 xlibparts->AddChild( xlibpart =
node( wxT(
"libpart" ) ) );
1108 xlibpart->
AddAttribute( wxT(
"part" ), lcomp->GetName() );
1111 if( !lcomp->GetDescription().IsEmpty() )
1112 xlibpart->AddChild(
node( wxT(
"description" ), lcomp->GetDescription() ) );
1114 if( !lcomp->GetDatasheetField().GetText().IsEmpty() )
1115 xlibpart->AddChild(
node( wxT(
"docs" ), lcomp->GetDatasheetField().GetText() ) );
1118 if( lcomp->GetFPFilters().GetCount() )
1121 xlibpart->AddChild( xfootprints =
node( wxT(
"footprints" ) ) );
1123 for(
unsigned i = 0; i < lcomp->GetFPFilters().GetCount(); ++i )
1125 if( !lcomp->GetFPFilters()[i].IsEmpty() )
1126 xfootprints->AddChild(
node( wxT(
"fp" ), lcomp->GetFPFilters()[i] ) );
1132 lcomp->GetFields( fieldList );
1135 xlibpart->AddChild( xfields =
node(
"fields" ) );
1137 for(
const SCH_FIELD* field : fieldList )
1140 xfields->AddChild( xfield =
node( wxT(
"field" ), field->GetText() ) );
1141 xfield->
AddAttribute( wxT(
"name" ), field->GetUntranslatedName() );
1147 std::vector<SCH_PIN*> pinList = lcomp->GetGraphicalPins( 0, 0 );
1159 for(
int ii = 0; ii < (int)pinList.size()-1; ii++ )
1161 if( pinList[ii]->GetNumber() == pinList[ii+1]->GetNumber() )
1163 pinList.erase(pinList.begin() + ii + 1);
1168 wxLogTrace(
"CVPCB_PINCOUNT",
1169 wxString::Format(
"makeLibParts: lib='%s' part='%s' pinList(size)=%zu",
1170 libNickname, lcomp->GetName(), pinList.size() ) );
1172 if( pinList.size() )
1176 xlibpart->AddChild( pins =
node( wxT(
"pins" ) ) );
1178 for(
unsigned i=0; i<pinList.size(); ++i )
1180 SCH_PIN* basePin = pinList[i];
1182 bool stackedValid =
false;
1186 if( stackedValid && !expandedNums.empty() )
1188 for(
const wxString& num : expandedNums )
1191 pins->AddChild(
pin =
node( wxT(
"pin" ) ) );
1192 pin->AddAttribute( wxT(
"num" ), num );
1196 wxLogTrace(
"CVPCB_PINCOUNT",
1197 wxString::Format(
"makeLibParts: -> pin num='%s' name='%s' (expanded)",
1204 pins->AddChild(
pin =
node( wxT(
"pin" ) ) );
1209 wxLogTrace(
"CVPCB_PINCOUNT",
1210 wxString::Format(
"makeLibParts: -> pin num='%s' name='%s'",
1226 wxString netCodeTxt;
1228 XNODE* xnet =
nullptr;
1250 NET_RECORD(
const wxString& aName ) :
1252 m_HasNoConnect(
false )
1257 bool m_HasNoConnect;
1258 std::vector<NET_NODE> m_Nodes;
1261 std::vector<NET_RECORD*> nets;
1263 std::shared_ptr<NET_SETTINGS> netSettings;
1266 netSettings =
m_schematic->Project().GetProjectFile().NetSettings();
1271 nets.emplace_back(
new NET_RECORD( netName ) );
1272 NET_RECORD* net_record = nets.back();
1273 net_record->m_HasNoConnect = net.hasNoConnect;
1277 if(
const auto netclass = netSettings->GetEffectiveNetClass( net.name ) )
1281 for(
const auto& [
pin, sheet] : net.pins )
1302 net_record->m_Nodes.emplace_back(
pin, sheet );
1307 std::sort( nets.begin(), nets.end(),
1308 [](
const NET_RECORD* a,
const NET_RECORD*b )
1310 return StrNumCmp( a->m_Name, b->m_Name ) < 0;
1313 for(
int i = 0; i < (int) nets.size(); ++i )
1315 NET_RECORD* net_record = nets[i];
1320 std::sort( net_record->m_Nodes.begin(), net_record->m_Nodes.end(),
1323 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
1324 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
1327 return a.m_Pin->GetShownNumber() < b.m_Pin->GetShownNumber();
1338 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
1339 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
1341 return refA == refB && a.m_Pin->GetShownNumber() == b.m_Pin->GetShownNumber();
1346 bool allNetPinsStacked =
true;
1348 if( net_record->m_Nodes.size() > 1 )
1350 SCH_PIN* firstPin = net_record->m_Nodes.begin()->m_Pin;
1351 allNetPinsStacked = std::all_of( net_record->m_Nodes.begin() + 1, net_record->m_Nodes.end(),
1354 return firstPin->GetParent() == node.m_Pin->GetParent()
1355 && firstPin->GetPosition() == node.m_Pin->GetPosition()
1356 && firstPin->GetName() == node.m_Pin->GetName();
1360 for(
const NET_NODE& netNode : net_record->m_Nodes )
1362 wxString refText = netNode.m_Pin->GetParentSymbol()->GetRef( &netNode.m_Sheet );
1365 if( refText[0] == wxChar(
'#' ) )
1371 std::vector<wxString> nums =
resolvePadNumbers( netNode.m_Pin, netNode.m_Sheet );
1377 wxString baseName = netNode.m_Pin->GetShownName();
1378 wxString pinType = netNode.m_Pin->GetCanonicalElectricalTypeName();
1382 netCodeTxt.Printf( wxT(
"%d" ), i + 1 );
1384 xnets->AddChild( xnet =
node( wxT(
"net" ) ) );
1386 xnet->
AddAttribute( wxT(
"name" ), net_record->m_Name );
1387 xnet->
AddAttribute( wxT(
"class" ), net_record->m_Class );
1392 for(
const wxString& num : nums )
1394 xnet->AddChild( xnode =
node( wxT(
"node" ) ) );
1398 wxString fullName = baseName.IsEmpty() ? num : baseName + wxT(
"_" ) + num;
1400 if( !baseName.IsEmpty() || nums.size() > 1 )
1403 wxString typeAttr = pinType;
1405 if( net_record->m_HasNoConnect
1406 && ( net_record->m_Nodes.size() == 1 || allNetPinsStacked ) )
1408 typeAttr += wxT(
"+no_connect" );
1416 for( NET_RECORD* record : nets )
1424 const auto& committed =
m_schematic->NetChains().GetCommittedNetChains();
1426 if( committed.empty() )
1429 XNODE* xchains =
node( wxT(
"net_chains" ) );
1431 for(
const std::unique_ptr<SCH_NETCHAIN>&
chain : committed )
1437 xchains->AddChild( xchain =
node( wxT(
"net_chain" ) ) );
1440 if( !
chain->GetNetClass().IsEmpty() )
1449 const std::shared_ptr<NET_SETTINGS>& ns = pf.
NetSettings();
1453 wxString className = ns->GetNetChainClass(
chain->GetName() );
1455 if( !className.IsEmpty() )
1456 xchain->
AddAttribute( wxT(
"net_chain_class" ), className );
1464 wxString::Format( wxT(
"#%02X%02X%02X%02X" ),
1465 (
int) std::clamp(
KiROUND( c.
r * 255.0 ), 0, 255 ),
1466 (
int) std::clamp(
KiROUND( c.
g * 255.0 ), 0, 255 ),
1467 (
int) std::clamp(
KiROUND( c.
b * 255.0 ), 0, 255 ),
1468 (
int) std::clamp(
KiROUND( c.
a * 255.0 ), 0, 255 ) ) );
1472 xchain->AddChild( xmembers =
node( wxT(
"members" ) ) );
1478 for(
const wxString& net :
chain->GetNets() )
1484 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
1488 if( !
chain->GetTerminalRef( 0 ).IsEmpty() || !
chain->GetTerminalRef( 1 ).IsEmpty() )
1491 xchain->AddChild( xterms =
node( wxT(
"terminal_pins" ) ) );
1493 for(
int i = 0; i < 2; ++i )
1495 if(
chain->GetTerminalRef( i ).IsEmpty() )
1499 xterms->AddChild( xterm =
node( wxT(
"terminal_pin" ) ) );
1512 XNODE* n =
new XNODE( wxXML_ELEMENT_NODE, aName );
1514 if( aTextualContent.Len() > 0 )
1515 n->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, aTextualContent ) );
1534 auto getComponentClassFields =
1535 [&](
const std::vector<SCH_FIELD>& fields,
const SCH_SHEET_PATH* sheetPath )
1537 std::unordered_set<wxString> componentClasses;
1541 if( field.GetUntranslatedName() == wxT(
"Component Class" ) )
1548 return componentClasses;
1556 std::unordered_set<wxString> sheetComponentClasses;
1557 const std::unordered_set<SCH_RULE_AREA*>& sheetRuleAreas = sheetItem->
GetRuleAreaCache();
1563 std::unordered_set<wxString> ruleAreaComponentClasses = getComponentClassFields( label->GetFields(),
1565 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 base class for most all the KiCad significant classes used in schematics and boards.
Represents an (ordered) list of JUMPER_GROUP objects.
const std::vector< JUMPER_GROUP > & GetAll() const
Represents a group of jumper pins or pads, keyed by name.
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.
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
std::vector< wxString > resolvePadNumbers(const SCH_PIN *aPin, const SCH_SHEET_PATH &aSheetPath) const
Resolve aPin to its effective pad number(s) for every netlist path (issue #2282).
UNIQUE_STRINGS m_referencesAlreadyFound
Used for "multiple symbols per package" symbols to avoid processing a lib symbol more than once.
SCH_SHEET_LIST m_exportSheets
std::vector< EXPORT_NET > m_exportNets
wxString m_exportVariant
The schematic we're generating a netlist for.
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.
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.
RESOLUTION_CONTEXT m_resolveTextVars
bool writeNetlist(const wxString &aOutFileName, unsigned aNetlistOptions, REPORTER &aReporter) override
Write generic netlist to aOutFileName.
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.
wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString, int aDepth=0) 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 bool IsPersistableNet(const wxString &aNet)
Synthetic keys do not survive a reload, so only named nets are written out.
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...
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.
std::optional< LIB_ID > m_SymbolOverride
Alternate library symbol to substitute for the base symbol in this variant, if any.
bool UseLibIdLookup() const
wxString GetSchSymbolLibraryName() const
const wxString GetFootprintFieldText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString) const
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
wxString GetShownDescription(RESOLUTION_CONTEXT aContext, int aDepth=0) const override
std::unordered_set< wxString > GetComponentClassNames(const SCH_SHEET_PATH *aPath, const wxString &aVariantName) const
Return the component classes this symbol belongs in.
const LIB_ID & GetLibId() const override
LIB_SYMBOL * GetVariantLibSymbol(const wxString &aVariantName, const SCH_SHEET_PATH &aPath) const
Resolve the alternate library symbol for a given variant.
bool GetInstance(SCH_SYMBOL_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
const wxString GetValue(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString) const override
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()
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
wxString GetFieldText(const SCH_FIELD *aField, const wxString &aFieldName, const SCH_SHEET_PATH *aPath, const wxString &aVariantName) const
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, RESOLUTION_CONTEXT aContext)
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.
static const std::vector< std::string > filters
Class to handle a set of SCH_ITEMs.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
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
One refdes -> net membership row collected from the NETDEF section.
A simple container for schematic symbol instance information.
std::map< wxString, SCH_SYMBOL_VARIANT > m_Variants
A list of symbol variants.
wxString GetDefaultFieldName(FIELD_T aFieldId, TRANSLATION aTranslation)
Return a default symbol field name for a mandatory field type.
@ 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
const SHAPE_LINE_CHAIN chain
wxLogTrace helper definitions.