35#include <wx/wfstream.h>
57 wxFFileOutputStream stream( aOutFileName );
65 return xdoc.Save( stream, 2 );
108 xroot->AddChild( xchains );
126 wxString description;
128 nlohmann::ordered_map<wxString, wxString> fields;
139 wxString ref = aSymbol->
GetRef( &aSheet );
149 wxString ref2 = symbol2->
GetRef( &sheet );
151 if( ref2.CmpNoCase( ref ) != 0 )
161 if( !candidate.IsEmpty() && ( unit < minUnit || value.IsEmpty() ) )
167 if( !candidate.IsEmpty() && ( unit < minUnit || footprint.IsEmpty() ) )
168 footprint = candidate;
174 if( !candidate.IsEmpty() && ( unit < minUnit ||
datasheet.IsEmpty() ) )
181 if( !candidate.IsEmpty() && ( unit < minUnit || description.IsEmpty() ) )
182 description = candidate;
187 if( field.IsMandatory() || field.IsPrivate() )
190 if( unit < minUnit || fields.count( field.GetName() ) == 0 )
193 fields[field.GetName()] = field.GetShownText( &aSheet,
false );
195 fields[field.GetName()] = field.GetText();
199 minUnit = std::min( unit, minUnit );
219 description = descriptionField->
GetShownText( &aSheet,
false );
221 description = descriptionField->
GetText();
225 if( field.IsMandatory() || field.IsPrivate() )
229 fields[field.GetName()] = field.GetShownText( &aSheet,
false );
231 fields[field.GetName()] = field.GetText();
243 aNode->AddChild(
node( wxT(
"value" ), wxT(
"~" ) ) );
245 if( footprint.size() )
251 if( description.size() )
255 aNode->AddChild( xfields =
node( wxT(
"fields" ) ) );
257 for(
const auto& [ fieldName, fieldValue ] : fields )
261 xfields->AddChild( xfield );
268 XNODE* xcomps =
node( wxT(
"components" ) );
290 b->GetRef( &sheet,
false ),
true ) < 0 );
293 std::set<
SCH_SYMBOL*,
decltype( cmp )> ordered_symbols( cmp );
294 std::multiset<
SCH_SYMBOL*,
decltype( cmp )> extra_units( cmp );
299 auto test = ordered_symbols.insert( symbol );
303 if( ( *(
test.first ) )->m_Uuid > symbol->
m_Uuid )
305 extra_units.insert( *(
test.first ) );
306 ordered_symbols.erase(
test.first );
307 ordered_symbols.insert( symbol );
311 extra_units.insert( symbol );
316 for(
EDA_ITEM* item : ordered_symbols )
336 xcomps->AddChild( xcomp =
node( wxT(
"comp" ) ) );
342 xcomp->AddChild( xlibsource =
node( wxT(
"libsource" ) ) );
373 std::vector<SCH_FIELD>& fields = symbol->
GetFields();
377 if( field.IsMandatory() || field.IsPrivate() )
380 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
381 xproperty->
AddAttribute( wxT(
"name" ), field.GetCanonicalName() );
384 xproperty->
AddAttribute( wxT(
"value" ), field.GetShownText( &sheet,
false ) );
386 xproperty->
AddAttribute( wxT(
"value" ), field.GetText() );
389 for(
const SCH_FIELD& sheetField : sheet.Last()->GetFields() )
391 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
392 xproperty->
AddAttribute( wxT(
"name" ), sheetField.GetCanonicalName() );
397 xproperty->
AddAttribute( wxT(
"value" ), sheetField.GetShownText( &sheet,
false ) );
399 xproperty->
AddAttribute( wxT(
"value" ), sheetField.GetText() );
404 if( baseExcludedFromBOM )
406 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
407 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_bom" ) );
412 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
413 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_board" ) );
418 if( baseExcludedFromPosFiles )
420 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
421 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"exclude_from_pos_files" ) );
424 const bool baseDnp = symbol->
ResolveDNP( &sheet ) || sheet.GetDNP();
428 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
434 const std::set<wxString>& variantNames =
m_schematic->GetVariantNames();
436 if( !variantNames.empty() )
439 XNODE* xvariants =
nullptr;
441 for(
const auto& variantName : variantNames )
443 XNODE* xvariant =
nullptr;
445 auto addToVariant = [
this, &xvariant, &variantName](
XNODE* child ) ->
void
452 xvariant =
node( wxT(
"variant" ) );
455 xvariant->AddChild( child );
458 auto addBinaryProp = [
this, &addToVariant]( wxString
const&
name,
bool base,
459 bool effective ) ->
void
461 if( base == effective )
464 XNODE* xvarprop =
node( wxT(
"property" ) );
466 xvarprop->
AddAttribute( wxT(
"value" ), effective ? wxT(
"1" ) : wxT(
"0" ) );
467 addToVariant( xvarprop );
470 bool effectiveDnp = symbol->
ResolveDNP( &sheet, variantName ) || sheet.GetDNP( variantName );
471 addBinaryProp( wxT(
"dnp" ), baseDnp, effectiveDnp );
474 || sheet.GetExcludedFromBOM( variantName );
475 addBinaryProp( wxT(
"exclude_from_bom" ), baseExcludedFromBOM, effectiveExcludedFromBOM );
478 || sheet.GetExcludedFromSim( variantName );
479 addBinaryProp( wxT(
"exclude_from_sim" ), baseExcludedFromSim, effectiveExcludedFromSim );
482 addBinaryProp( wxT(
"exclude_from_pos_files" ), baseExcludedFromPosFiles,
483 effectiveExcludedFromPosFiles );
489 variant = &instance.
m_Variants.at( variantName );
491 if( variant && !variant->
m_Fields.empty() )
493 XNODE* xfields =
nullptr;
495 for(
const auto& [fieldName, fieldValue] : variant->
m_Fields )
497 const wxString baseValue =
498 symbol->
GetFieldText( fieldName, &sheet, wxEmptyString );
500 if( fieldValue == baseValue )
504 xfields =
node( wxT(
"fields" ) );
506 wxString resolvedValue = fieldValue;
509 resolvedValue = symbol->
ResolveText( fieldValue, &sheet );
513 xfields->AddChild( xfield );
516 addToVariant( xfields );
522 xvariants =
node( wxT(
"variants" ) );
524 xvariants->AddChild( xvariant );
529 xcomp->AddChild( xvariants );
532 if(
const std::unique_ptr<LIB_SYMBOL>& part = symbol->
GetLibSymbolRef() )
534 if( part->GetKeyWords().size() )
536 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
537 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"ki_keywords" ) );
538 xproperty->
AddAttribute( wxT(
"value" ), part->GetKeyWords() );
541 if( !part->GetFPFilters().IsEmpty() )
545 for(
const wxString&
filter : part->GetFPFilters() )
548 xcomp->AddChild( xproperty =
node( wxT(
"property" ) ) );
549 xproperty->
AddAttribute( wxT(
"name" ), wxT(
"ki_fp_filters" ) );
550 xproperty->
AddAttribute( wxT(
"value" ), filters.Trim(
false ) );
553 if( part->GetDuplicatePinNumbersAreJumpers() )
554 xcomp->AddChild(
node( wxT(
"duplicate_pin_numbers_are_jumpers" ), wxT(
"1" ) ) );
556 const std::vector<std::set<wxString>>& jumperGroups = part->JumperPinGroups();
558 if( !jumperGroups.empty() )
561 xcomp->AddChild( xproperty =
node( wxT(
"jumper_pin_groups" ) ) );
563 for(
const std::set<wxString>&
group : jumperGroups )
565 xproperty->AddChild( groupNode =
node( wxT(
"group" ) ) );
567 for(
const wxString& pinName :
group )
568 groupNode->AddChild(
node( wxT(
"pin" ), pinName ) );
574 xcomp->AddChild( xsheetpath =
node( wxT(
"sheetpath" ) ) );
576 xsheetpath->
AddAttribute( wxT(
"names" ), sheet.PathHumanReadable() );
577 xsheetpath->
AddAttribute( wxT(
"tstamps" ), sheet.PathAsString() );
580 std::vector<wxString> compClassNames =
583 if( compClassNames.size() > 0 )
585 XNODE* xcompclasslist;
586 xcomp->AddChild( xcompclasslist =
node( wxT(
"component_classes" ) ) );
588 for(
const wxString& compClass : compClassNames )
595 xcomp->AddChild( xunits =
node( wxT(
"tstamps" ) ) );
597 auto range = extra_units.equal_range( symbol );
601 for(
auto it = range.first; it != range.second; ++it )
603 uuid = ( *it )->m_Uuid.AsString();
610 xunits->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, uuid ) );
615 xunits->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, uuid ) );
619 xcomp->AddChild( xunitInfo =
node( wxT(
"units" ) ) );
634 const std::vector<LIB_SYMBOL::UNIT_PIN_INFO>& defaultUnitInfo = libSym->GetUnitPinInfo();
635 std::map<int, SCH_SYMBOL*> symbolByUnit;
643 int unit = aUnitSymbol->GetUnitSelection( &sheet );
646 symbolByUnit.try_emplace( unit, aUnitSymbol );
649 addUnitSymbol( symbol );
651 auto extraUnitRange = extra_units.equal_range( symbol );
655 for(
auto it = extraUnitRange.first; it != extraUnitRange.second; ++it )
656 addUnitSymbol( *it );
660 for(
size_t unitIdx = 0; unitIdx < defaultUnitInfo.size(); ++unitIdx )
663 auto symbolIt = symbolByUnit.find( unitIdx + 1 );
665 if( symbolIt != symbolByUnit.end() )
667 const std::unique_ptr<LIB_SYMBOL>& unitLibSym = symbolIt->second->GetLibSymbolRef();
671 const std::vector<LIB_SYMBOL::UNIT_PIN_INFO>& unitSpecificInfo =
672 unitLibSym->GetUnitPinInfo();
674 if( unitIdx < unitSpecificInfo.size() )
675 unitInfo = unitSpecificInfo[unitIdx];
680 xunitInfo->AddChild( xunit =
node( wxT(
"unit" ) ) );
684 xunit->AddChild( xpins =
node( wxT(
"pins" ) ) );
689 xpins->AddChild( xpin =
node( wxT(
"pin" ) ) );
725 xcomps->AddChild( xgroup =
node( wxT(
"group" ) ) );
732 xgroup->AddChild( xmembers =
node( wxT(
"members" ) ) );
739 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
740 xmember->
AddAttribute( wxT(
"uuid" ), member->m_Uuid.AsString() );
745 std::vector<SCH_SHEET_PATH> descendantSheets;
755 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
756 xmember->
AddAttribute( wxT(
"uuid" ), descendantItem->m_Uuid.AsString() );
772 XNODE* xvariants =
node( wxT(
"variants" ) );
774 std::set<wxString> variantNames =
m_schematic->GetVariantNames();
776 for(
const wxString& variantName : variantNames )
779 xvariants->AddChild( xvariant =
node( wxT(
"variant" ) ) );
782 wxString description =
m_schematic->GetVariantDescription( variantName );
784 if( !description.IsEmpty() )
785 xvariant->
AddAttribute( wxT(
"description" ), description );
795 std::vector<SCH_SHEET_PATH> symbolSheets;
796 symbolSheets.push_back( aSymbolSheet );
803 const wxString ref = aSymbol->
GetRef( &aSymbolSheet );
811 wxString ref2 = symbol2->
GetRef( &sheet );
814 if( ref2.CmpNoCase( ref ) != 0 )
817 if( otherUnit == primaryUnit )
820 symbolSheets.push_back( sheet );
822 std::unordered_set<wxString> otherClassNames =
824 compClassNames.insert( otherClassNames.begin(), otherClassNames.end() );
834 if( symbolSheetPath.IsContainedWithin( sheetPath ) )
836 compClassNames.insert( sheetCompClasses.begin(), sheetCompClasses.end() );
841 std::vector<wxString> sortedCompClassNames( compClassNames.begin(), compClassNames.end() );
842 std::sort( sortedCompClassNames.begin(), sortedCompClassNames.end(),
843 [](
const wxString& str1,
const wxString& str2 )
845 return str1.Cmp( str2 ) < 0;
848 return sortedCompClassNames;
855 XNODE* xdesign =
node( wxT(
"design" ) );
861 wxFileName sourceFileName;
864 xdesign->AddChild(
node( wxT(
"source" ),
m_schematic->GetFileName() ) );
871 const std::map<wxString, wxString>& properties =
m_schematic->Project().GetTextVars();
873 for(
const std::pair<const wxString, wxString>& prop : properties )
875 xdesign->AddChild( xtextvar =
node( wxT(
"textvar" ), prop.second ) );
882 unsigned sheetIndex = 1;
886 screen = sheet.LastScreen();
888 xdesign->AddChild( xsheet =
node( wxT(
"sheet" ) ) );
891 sheetTxt.Printf( wxT(
"%u" ), sheetIndex++ );
893 xsheet->
AddAttribute( wxT(
"name" ), sheet.PathHumanReadable() );
894 xsheet->
AddAttribute( wxT(
"tstamps" ), sheet.PathAsString() );
899 xsheet->AddChild( xtitleBlock =
node( wxT(
"title_block" ) ) );
907 sourceFileName = wxFileName( screen->
GetFileName() );
908 xtitleBlock->AddChild(
node( wxT(
"source" ), sourceFileName.GetFullName() ) );
910 xtitleBlock->AddChild( xcomment =
node( wxT(
"comment" ) ) );
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" ) ) );
953 XNODE* xlibs =
node( wxT(
"libraries" ) );
958 wxString libNickname = *it;
965 xlibs->AddChild( xlibrary =
node( wxT(
"library" ) ) );
966 xlibrary->
AddAttribute( wxT(
"logical" ), libNickname );
967 xlibrary->AddChild(
node( wxT(
"uri" ), *uri ) );
979 XNODE* xlibparts =
node( wxT(
"libparts" ) );
980 std::vector<SCH_FIELD*> fieldList;
986 wxString libNickname = lcomp->GetLibId().GetLibNickname();;
989 if( !libNickname.IsEmpty() )
993 xlibparts->AddChild( xlibpart =
node( wxT(
"libpart" ) ) );
995 xlibpart->
AddAttribute( wxT(
"part" ), lcomp->GetName() );
998 if( !lcomp->GetDescription().IsEmpty() )
999 xlibpart->AddChild(
node( wxT(
"description" ), lcomp->GetDescription() ) );
1001 if( !lcomp->GetDatasheetField().GetText().IsEmpty() )
1002 xlibpart->AddChild(
node( wxT(
"docs" ), lcomp->GetDatasheetField().GetText() ) );
1005 if( lcomp->GetFPFilters().GetCount() )
1008 xlibpart->AddChild( xfootprints =
node( wxT(
"footprints" ) ) );
1010 for(
unsigned i = 0; i < lcomp->GetFPFilters().GetCount(); ++i )
1012 if( !lcomp->GetFPFilters()[i].IsEmpty() )
1013 xfootprints->AddChild(
node( wxT(
"fp" ), lcomp->GetFPFilters()[i] ) );
1019 lcomp->GetFields( fieldList );
1022 xlibpart->AddChild( xfields =
node(
"fields" ) );
1024 for(
const SCH_FIELD* field : fieldList )
1027 xfields->AddChild( xfield =
node( wxT(
"field" ), field->GetText() ) );
1028 xfield->
AddAttribute( wxT(
"name" ), field->GetCanonicalName() );
1034 std::vector<SCH_PIN*> pinList = lcomp->GetGraphicalPins( 0, 0 );
1046 for(
int ii = 0; ii < (int)pinList.size()-1; ii++ )
1048 if( pinList[ii]->GetNumber() == pinList[ii+1]->GetNumber() )
1050 pinList.erase(pinList.begin() + ii + 1);
1055 wxLogTrace(
"CVPCB_PINCOUNT",
1056 wxString::Format(
"makeLibParts: lib='%s' part='%s' pinList(size)=%zu",
1057 libNickname, lcomp->GetName(), pinList.size() ) );
1059 if( pinList.size() )
1063 xlibpart->AddChild( pins =
node( wxT(
"pins" ) ) );
1065 for(
unsigned i=0; i<pinList.size(); ++i )
1067 SCH_PIN* basePin = pinList[i];
1069 bool stackedValid =
false;
1073 if( stackedValid && !expandedNums.empty() )
1075 for(
const wxString& num : expandedNums )
1078 pins->AddChild(
pin =
node( wxT(
"pin" ) ) );
1079 pin->AddAttribute( wxT(
"num" ), num );
1083 wxLogTrace(
"CVPCB_PINCOUNT",
1084 wxString::Format(
"makeLibParts: -> pin num='%s' name='%s' (expanded)",
1091 pins->AddChild(
pin =
node( wxT(
"pin" ) ) );
1096 wxLogTrace(
"CVPCB_PINCOUNT",
1097 wxString::Format(
"makeLibParts: -> pin num='%s' name='%s'",
1113 wxString netCodeTxt;
1115 XNODE* xnet =
nullptr;
1137 NET_RECORD(
const wxString& aName ) :
1139 m_HasNoConnect(
false )
1144 bool m_HasNoConnect;
1145 std::vector<NET_NODE> m_Nodes;
1148 std::vector<NET_RECORD*> nets;
1150 std::shared_ptr<NET_SETTINGS> netSettings;
1153 netSettings =
m_schematic->Project().GetProjectFile().NetSettings();
1155 for(
const auto& [ key, subgraphs ] :
m_schematic->ConnectionGraph()->GetNetMap() )
1157 wxString net_name = key.Name;
1158 NET_RECORD* net_record =
nullptr;
1163 if( subgraphs.empty() )
1166 nets.emplace_back(
new NET_RECORD( net_name ) );
1167 net_record = nets.back();
1176 std::shared_ptr<NETCLASS> nc = netSettings->GetEffectiveNetClass( key.Name );
1184 bool nc = subgraph->GetNoConnect() && subgraph->GetNoConnect()->Type() ==
SCH_NO_CONNECT_T;
1188 net_record->m_HasNoConnect =
true;
1190 for(
SCH_ITEM* item : subgraph->GetItems() )
1208 net_record->m_Nodes.emplace_back(
pin, sheet );
1215 std::sort( nets.begin(), nets.end(),
1216 [](
const NET_RECORD* a,
const NET_RECORD*b )
1218 return StrNumCmp( a->m_Name, b->m_Name ) < 0;
1221 for(
int i = 0; i < (int) nets.size(); ++i )
1223 NET_RECORD* net_record = nets[i];
1228 std::sort( net_record->m_Nodes.begin(), net_record->m_Nodes.end(),
1231 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
1232 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
1235 return a.m_Pin->GetShownNumber() < b.m_Pin->GetShownNumber();
1246 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
1247 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
1249 return refA == refB && a.m_Pin->GetShownNumber() == b.m_Pin->GetShownNumber();
1254 bool allNetPinsStacked =
true;
1256 if( net_record->m_Nodes.size() > 1 )
1258 SCH_PIN* firstPin = net_record->m_Nodes.begin()->m_Pin;
1260 std::all_of( net_record->m_Nodes.begin() + 1, net_record->m_Nodes.end(),
1263 return firstPin->GetParent() == node.m_Pin->GetParent()
1264 && firstPin->GetPosition() == node.m_Pin->GetPosition()
1265 && firstPin->GetName() == node.m_Pin->GetName();
1269 for(
const NET_NODE& netNode : net_record->m_Nodes )
1271 wxString refText = netNode.m_Pin->GetParentSymbol()->GetRef( &netNode.m_Sheet );
1274 if( refText[0] == wxChar(
'#' ) )
1279 netCodeTxt.Printf( wxT(
"%d" ), i + 1 );
1281 xnets->AddChild( xnet =
node( wxT(
"net" ) ) );
1283 xnet->
AddAttribute( wxT(
"name" ), net_record->m_Name );
1284 xnet->
AddAttribute( wxT(
"class" ), net_record->m_Class );
1289 std::vector<wxString> nums = netNode.m_Pin->GetStackedPinNumbers();
1290 wxString baseName = netNode.m_Pin->GetShownName();
1291 wxString pinType = netNode.m_Pin->GetCanonicalElectricalTypeName();
1294 wxString::Format(
"XML: net='%s' ref='%s' base='%s' shownNum='%s' expand=%zu",
1295 net_record->m_Name, refText, baseName,
1296 netNode.m_Pin->GetShownNumber(), nums.size() ) );
1298 for(
const wxString& num : nums )
1300 xnet->AddChild( xnode =
node( wxT(
"node" ) ) );
1304 wxString fullName = baseName.IsEmpty() ? num : baseName + wxT(
"_" ) + num;
1306 if( !baseName.IsEmpty() || nums.size() > 1 )
1309 wxString typeAttr = pinType;
1311 if( net_record->m_HasNoConnect
1312 && ( net_record->m_Nodes.size() == 1 || allNetPinsStacked ) )
1314 typeAttr += wxT(
"+no_connect" );
1316 wxString::Format(
"XML: marking node ref='%s' pin='%s' as no_connect",
1325 for( NET_RECORD* record : nets )
1333 const auto& committed =
m_schematic->ConnectionGraph()->GetCommittedNetChains();
1335 if( committed.empty() )
1338 XNODE* xchains =
node( wxT(
"net_chains" ) );
1340 for(
const std::unique_ptr<SCH_NETCHAIN>&
chain : committed )
1346 xchains->AddChild( xchain =
node( wxT(
"net_chain" ) ) );
1349 if( !
chain->GetNetClass().IsEmpty() )
1358 const std::shared_ptr<NET_SETTINGS>& ns = pf.
NetSettings();
1362 wxString className = ns->GetNetChainClass(
chain->GetName() );
1364 if( !className.IsEmpty() )
1365 xchain->
AddAttribute( wxT(
"net_chain_class" ), className );
1373 wxString::Format( wxT(
"#%02X%02X%02X%02X" ),
1374 (
int) std::clamp(
KiROUND( c.
r * 255.0 ), 0, 255 ),
1375 (
int) std::clamp(
KiROUND( c.
g * 255.0 ), 0, 255 ),
1376 (
int) std::clamp(
KiROUND( c.
b * 255.0 ), 0, 255 ),
1377 (
int) std::clamp(
KiROUND( c.
a * 255.0 ), 0, 255 ) ) );
1381 xchain->AddChild( xmembers =
node( wxT(
"members" ) ) );
1387 for(
const wxString& net :
chain->GetNets() )
1393 xmembers->AddChild( xmember =
node( wxT(
"member" ) ) );
1397 if( !
chain->GetTerminalRef( 0 ).IsEmpty() || !
chain->GetTerminalRef( 1 ).IsEmpty() )
1400 xchain->AddChild( xterms =
node( wxT(
"terminal_pins" ) ) );
1402 for(
int i = 0; i < 2; ++i )
1404 if(
chain->GetTerminalRef( i ).IsEmpty() )
1408 xterms->AddChild( xterm =
node( wxT(
"terminal_pin" ) ) );
1420 const wxString& aTextualContent )
1422 XNODE* n =
new XNODE( wxXML_ELEMENT_NODE, aName );
1424 if( aTextualContent.Len() > 0 )
1425 n->AddChild(
new XNODE( wxXML_TEXT_NODE, wxEmptyString, aTextualContent ) );
1442 auto getComponentClassFields = [&](
const std::vector<SCH_FIELD>& fields,
const SCH_SHEET_PATH* sheetPath )
1444 std::unordered_set<wxString> componentClasses;
1448 if( field.GetCanonicalName() == wxT(
"Component Class" ) )
1450 if( field.GetShownText( sheetPath,
false ) != wxEmptyString )
1451 componentClasses.insert( field.GetShownText( sheetPath,
false ) );
1455 return componentClasses;
1463 std::unordered_set<wxString> sheetComponentClasses;
1464 const std::unordered_set<SCH_RULE_AREA*>& sheetRuleAreas = sheetItem->
GetRuleAreaCache();
1470 std::unordered_set<wxString> ruleAreaComponentClasses =
1471 getComponentClassFields( label->GetFields(), &sheet );
1472 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
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.
@ 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.