23#include <boost/property_tree/ptree.hpp>
47#include <fmt/ranges.h>
52 const std::map<wxString, wxString>& aNetByPin )
54 std::vector<wxString> nets;
58 for(
const wxString& pinNum : aPins )
60 auto it = aNetByPin.find( pinNum );
61 nets.push_back( it != aNetByPin.end() ? it->second : wxString() );
66 for(
const std::pair<const wxString, wxString>&
kv : aNetByPin )
67 nets.push_back(
kv.second );
75 const std::vector<BACKANNOTATE_UNIT_SWAP_CANDIDATE>& aCandidates,
76 const std::map<wxString, wxString>& aPcbPinMap )
80 if( aCandidates.size() < 2 )
86 std::map<size_t, size_t> desiredTarget;
87 std::set<size_t> usedTargets;
89 for(
size_t candidateIdx = 0; candidateIdx < aCandidates.size(); ++candidateIdx )
92 std::map<wxString, wxString> pcbNetsByPin;
96 auto it = aPcbPinMap.find( pinNum );
97 pcbNetsByPin[pinNum] = ( it != aPcbPinMap.end() ) ? it->second : wxString();
101 bool matched =
false;
103 for(
size_t matchIdx = 0; matchIdx < aCandidates.size(); ++matchIdx )
105 if( usedTargets.count( matchIdx ) )
109 std::vector<wxString> schNets =
112 if( pcbNets == schNets )
114 desiredTarget[candidateIdx] = matchIdx;
115 usedTargets.insert( matchIdx );
128 for(
size_t candidateIdx = 0; candidateIdx < aCandidates.size(); ++candidateIdx )
130 auto it = desiredTarget.find( candidateIdx );
132 if( it == desiredTarget.end() || it->second != candidateIdx )
142 std::set<size_t> visited;
144 for(
size_t startIdx = 0; startIdx < aCandidates.size(); ++startIdx )
146 if( visited.count( startIdx ) )
149 std::vector<size_t> cycle;
150 size_t curIdx = startIdx;
152 while( !visited.count( curIdx ) )
154 visited.insert( curIdx );
155 cycle.push_back( curIdx );
157 auto nextIt = desiredTarget.find( curIdx );
159 if( nextIt == desiredTarget.end() || nextIt->second == curIdx )
162 curIdx = nextIt->second;
165 if( cycle.size() < 2 )
168 for(
size_t i = cycle.size() - 1; i > 0; --i )
170 size_t firstIdx = cycle[i - 1];
171 size_t secondIdx = cycle[i];
173 plan.
m_steps.push_back( { firstIdx, secondIdx,
174 aCandidates[firstIdx].m_currentUnit,
175 aCandidates[secondIdx].m_currentUnit } );
186 bool aProcessFootprints,
bool aProcessValues,
bool aProcessReferences,
187 bool aProcessNetNames,
bool aProcessAttributes,
bool aProcessOtherFields,
188 bool aPreferUnitSwaps,
bool aPreferPinSwaps,
bool aDryRun ) :
235 "stand-alone mode.\n"
236 "You must launch the KiCad project manager and create a project." ) );
244 wxFileName fn(
m_frame->Prj().GetProjectFullName() );
245 fn.SetExt( FILEEXT::PcbFileExtension );
258 std::string nullPayload;
266 auto getStr = [](
const PTREE& pt ) -> wxString
268 return UTF8( pt.front().first );
278 Scan( &doc, &lexer );
280 PTREE& tree = doc.get_child(
"pcb_netlist" );
284 for(
const std::pair<const std::string, PTREE>& item : tree )
286 wxString
path, value, footprint;
287 bool dnp =
false, exBOM =
false, exPosFiles =
false;
288 std::map<wxString, wxString> pinNetMap, fieldsMap;
289 wxASSERT( item.first ==
"ref" );
290 wxString ref = getStr( item.second );
297 path = getStr( item.second.get_child(
"timestamp" ) );
301 msg.Printf(
_(
"Footprint '%s' has no assigned symbol." ),
DescribeRef( ref ) );
306 footprint = getStr( item.second.get_child(
"fpid" ) );
307 value = getStr( item.second.get_child(
"value" ) );
310 boost::optional<const PTREE&> fields = item.second.get_child_optional(
"fields" );
315 for(
const std::pair<const std::string, PTREE>& field : fields.get() )
317 if( field.first !=
"field" )
321 const auto& fieldName = field.second.get_child_optional(
"name" );
322 const std::string& fieldValue = field.second.back().first;
327 fieldsMap[getStr( fieldName.get() )] = wxString::FromUTF8( fieldValue );
334 for(
const auto& child : item.second )
336 if( child.first !=
"property" )
339 auto property = child.second;
340 auto name =
property.get_child_optional(
"name" );
345 if(
name.get().front().first ==
"dnp" )
347 else if(
name.get().front().first ==
"exclude_from_bom" )
349 else if(
name.get().front().first ==
"exclude_from_pos_files" )
353 boost::optional<const PTREE&> nets = item.second.get_child_optional(
"nets" );
357 for(
const std::pair<const std::string, PTREE>& pin_net : nets.get() )
359 wxASSERT( pin_net.first ==
"pin_net" );
360 wxString pinNumber =
UTF8( pin_net.second.front().first );
361 wxString netName =
UTF8( pin_net.second.back().first );
362 pinNetMap[ pinNumber ] = netName;
368 wxLogWarning(
"Cannot parse PCB netlist for back-annotation." );
377 msg.Printf(
_(
"Footprints '%s' and '%s' linked to same symbol." ),
385 std::shared_ptr<PCB_FP_DATA> data = std::make_shared<PCB_FP_DATA>( ref, footprint, value, dnp, exBOM,
386 exPosFiles, pinNetMap, fieldsMap );
398 bool foundInMultiunit =
false;
403 refIndex = refList.FindRef( pcbPath );
405 refIndex = refList.FindRefByFullPath( pcbPath );
411 foundInMultiunit =
true;
413 for(
size_t i = 0; i < refList.GetCount(); ++i )
415 refList[ i ].GetSymbol()->ClearFlags(
SKIP_STRUCT );
423 if( foundInMultiunit )
427 refIndex =
m_refs.FindRef( pcbPath );
429 refIndex =
m_refs.FindRefByFullPath( pcbPath );
439 m_reporter.ReportTail( wxString::Format(
_(
"Cannot find symbol for footprint '%s'." ),
453 return SCH_REFERENCE_LIST::sortByTimeStamp( a.first, b.first );
462 while( i <
m_refs.GetCount() &&
m_refs[i].GetPath() != item.first.GetPath() )
468 m_reporter.ReportTail( wxString::Format(
_(
"Footprint '%s' is not present on PCB. "
469 "Corresponding symbols in schematic must be "
470 "manually deleted (if desired)." ),
482 "annotated schematic." ) ) )
494 std::set<CHANGELIST_ITEM*> unitSwapItems;
504 std::map<std::shared_ptr<PCB_FP_DATA>, std::vector<CHANGELIST_ITEM*>> changesPerFp;
506 msg.Printf( wxT(
"DEBUG(unit-swap): grouped changelist into %zu footprint(s) for unit-swap processing:" ),
507 changesPerFp.size() );
514 changesPerFp[item.second].push_back( &item );
515 msg += wxT(
" " ) + item.first.GetRef();
521 for(
auto& fpChangelistPair : changesPerFp )
523 std::set<SCH_SYMBOL*> swappedSymbols;
524 std::set<CHANGELIST_ITEM*> swappedItems;
525 std::shared_ptr<PCB_FP_DATA> fp = fpChangelistPair.first;
526 auto& changedFpItems = fpChangelistPair.second;
539 std::map<wxString, wxString> schNetsByPin;
540 std::map<wxString, wxString> pcbNetsByPin;
541 std::vector<wxString> unitPinNumbers;
542 std::vector<wxString> schNetsInUnitOrder;
543 std::vector<wxString> pcbNetsInUnitOrder;
547 std::vector<SYM_UNIT> symbolUnits;
549 std::map<LIB_SYMBOL*, std::vector<LIB_SYMBOL::UNIT_PIN_INFO>> unitPinsByLibSymbol;
552 [&](
SCH_SYMBOL* symbol,
int unitNumber ) -> std::vector<wxString>
554 if( unitNumber <= 0 )
565 auto found = unitPinsByLibSymbol.find( libSymbol );
567 if( found == unitPinsByLibSymbol.end() )
568 found = unitPinsByLibSymbol.emplace( libSymbol, libSymbol->
GetUnitPinInfo() ).first;
570 const std::vector<LIB_SYMBOL::UNIT_PIN_INFO>& unitInfos = found->second;
572 if( unitNumber >
static_cast<int>( unitInfos.size() ) )
575 return unitInfos[unitNumber - 1].m_pinNumbers;
590 symbolUnit.sym = symbol;
591 symbolUnit.screen = screen;
594 symbolUnit.changeItem = changedItem;
596 int currentUnit = ref.
GetUnit();
598 if( currentUnit <= 0 )
601 if( currentUnit <= 0 )
602 currentUnit = symbol->
GetUnit();
604 symbolUnit.currentUnit = currentUnit;
605 symbolUnit.unitPinNumbers = getUnitPins( symbol, symbolUnit.currentUnit );
611 const wxString& pinNum =
pin->GetNumber();
614 auto it = fp->m_pinMap.find( pinNum );
615 symbolUnit.pcbNetsByPin[pinNum] = ( it != fp->m_pinMap.end() ) ? it->second : wxString();
621 symbolUnit.schNetsByPin[pinNum] = connection->Name(
true );
623 symbolUnit.schNetsByPin[pinNum] = wxString();
626 symbolUnit.schNetsByPin[pinNum] = wxString();
629 symbolUnit.pcbNetsInUnitOrder =
netsInUnitOrder( symbolUnit.unitPinNumbers, symbolUnit.pcbNetsByPin );
630 symbolUnit.schNetsInUnitOrder =
netsInUnitOrder( symbolUnit.unitPinNumbers, symbolUnit.schNetsByPin );
632 symbolUnits.push_back( symbolUnit );
635 auto vectorToString =
636 [](
const std::vector<wxString>& values ) -> wxString
638 return fmt::format(
L"{}", fmt::join( values,
L", " ) );
642 [vectorToString](
const std::map<wxString, wxString>& pinMap ) -> wxString
644 std::vector<wxString> entries;
646 for(
const std::pair<const wxString, wxString>&
pin : pinMap )
647 entries.push_back(
pin.first +
'=' +
pin.second );
649 return vectorToString( entries );
652 msg.Printf( wxT(
"DEBUG(unit-swap): footprint %s processed (%zu units, dryRun=%d)." ), fp->m_ref,
653 symbolUnits.size(),
m_dryRun ? 1 : 0 );
657 std::sort( symbolUnits.begin(), symbolUnits.end(),
658 [](
const SYM_UNIT& a,
const SYM_UNIT& b )
660 return a.ref < b.ref;
663 for(
const SYM_UNIT& su : symbolUnits )
665 wxString pcbPins = mapToString( su.pcbNetsByPin );
666 wxString schPins = mapToString( su.schNetsByPin );
667 wxString unitPins = vectorToString( su.unitPinNumbers );
668 wxString pcbUnitNetSeq = vectorToString( su.pcbNetsInUnitOrder );
669 wxString schUnitNetSeq = vectorToString( su.schNetsInUnitOrder );
671 msg.Printf( wxT(
"DEBUG(unit-swap): unit %d: %s pcbPins[%s] schPins[%s] unitPins[%s] pcbUnitNets[%s] "
672 "schUnitNets[%s]." ),
673 su.currentUnit, su.ref, pcbPins, schPins, unitPins, pcbUnitNetSeq, schUnitNetSeq );
677 if( symbolUnits.size() < 2 )
680 std::vector<BACKANNOTATE_UNIT_SWAP_CANDIDATE> candidates;
682 for(
const SYM_UNIT& symbolUnit : symbolUnits )
685 candidate.
m_ref = symbolUnit.ref;
689 candidates.push_back( candidate );
696 msg.Printf( wxT(
"DEBUG(unit-swap): mapping failed for footprint %s." ), fp->m_ref );
703 msg.Printf( wxT(
"DEBUG(unit-swap): footprint %s already aligned (identity mapping)." ), fp->m_ref );
711 commit.
Modify( symbolUnits[candidateIdx].sym, symbolUnits[candidateIdx].screen );
718 int aUnit = a.currentUnit;
719 int bUnit = b.currentUnit;
723 a.sym->SetUnit( bUnit );
724 b.sym->SetUnit( aUnit );
727 a.sym->SetUnitSelection( sheet, bUnit );
730 b.sym->SetUnitSelection( sheet, aUnit );
733 a.currentUnit = bUnit;
734 b.currentUnit = aUnit;
736 swappedSymbols.insert( a.sym );
737 swappedSymbols.insert( b.sym );
741 swappedItems.insert( a.changeItem );
742 unitSwapItems.insert( a.changeItem );
747 swappedItems.insert( b.changeItem );
748 unitSwapItems.insert( b.changeItem );
751 wxString baseRef = a.sym->GetRef( a.sheetPath,
false );
752 wxString unitAString = a.sym->SubReference( aUnit,
false );
753 wxString unitBString = b.sym->SubReference( bUnit,
false );
755 if( unitAString.IsEmpty() )
756 unitAString.Printf( wxT(
"%d" ), aUnit );
758 if( unitBString.IsEmpty() )
759 unitBString.Printf( wxT(
"%d" ), bUnit );
761 msg.Printf(
_(
"Swap %s unit %s with unit %s." ),
769 msg.Printf( wxT(
"DEBUG(unit-swap): applied %zu swap steps for footprint %s." ),
770 plan.
m_steps.size(), fp->m_ref );
778 SCH_SYMBOL* symbol = changedItem->first.GetSymbol();
783 if( swappedItems.count( changedItem ) || swappedSymbols.count( symbol ) )
786 int updatedUnit = symbol->
GetUnitSelection( &changedItem->first.GetSheetPath() );
787 changedItem->first.SetUnit( updatedUnit );
806 bool skip = ( ref.
GetSymbol()->GetFlags() &
SKIP_STRUCT ) > 0 || unitSwapItems.count( &item ) > 0;
809 [](
bool b ) -> wxString
811 return b ?
_(
"true" ) :
_(
"false" );
821 msg.Printf(
_(
"Change %s reference designator to '%s'." ),
835 msg.Printf(
_(
"Change %s footprint assignment from '%s' to '%s'." ),
850 msg.Printf(
_(
"Change %s value from '%s' to '%s'." ),
864 msg.Printf(
_(
"Change %s 'Do not populate' from '%s' to '%s'." ),
866 boolString( oldDNP ),
867 boolString( fpData.
m_DNP ) );
878 msg.Printf(
_(
"Change %s 'Exclude from bill of materials' from '%s' to '%s'." ),
880 boolString( oldExBOM ),
892 msg.Printf(
_(
"Change %s 'Exclude from position files' from '%s' to '%s'." ),
DescribeRef( ref.
GetRef() ),
901 std::set<wxString> swappedPins;
909 for(
const std::pair<const wxString, wxString>& entry : fpData.
m_pinMap )
911 const wxString& pinNumber = entry.first;
912 const wxString& shortNetName = entry.second;
916 if( swappedPins.count( pinNumber ) > 0 )
921 msg.Printf(
_(
"Cannot find %s pin '%s'." ),
931 if( connection && connection->
Name(
true ) != shortNetName )
934 connection->
Name(
true ), shortNetName );
942 for(
const std::pair<const wxString, wxString>& field : fpData.
m_fieldsMap )
944 const wxString& fpFieldName = field.first;
945 const wxString& fpFieldValue = field.second;
964 msg.Printf(
_(
"Change %s field '%s' value to '%s'." ),
970 symField->
SetText( fpFieldValue );
976 if( symField ==
nullptr )
979 msg.Printf(
_(
"Add %s field '%s' with value '%s'." ),
987 newField.
SetText( fpFieldValue );
1000 std::vector<wxString> fieldsToDelete;
1004 if( field.IsMandatory() )
1010 msg.Printf(
_(
"Delete %s field '%s.'" ),
1014 fieldsToDelete.push_back( field.GetName() );
1021 for(
const wxString& fieldName : fieldsToDelete )
1029 unitSwapItems.erase( &item );
1037 m_frame->UpdateNetHighlightStatus();
1039 commit.
Push(
_(
"Update Schematic from PCB" ) );
1082 ORIENT o = orientations[ 0 ];
1091 for(
const ORIENT& i : orientations )
1093 if( i.flag == symbolOrientation )
1100 for(
int i = 0; i < o.n_rots; i++ )
1115 if( connectedItems.insert( aItem ).second )
1128 std::set<wxString> swappedPins;
1138 wxCHECK(
m_frame, swappedPins );
1145 wxString currentNet;
1149 std::vector<PIN_CHANGE> mismatches;
1152 std::map<wxString, std::vector<size_t>> pinsByCurrentNet;
1155 for(
const std::pair<const wxString, wxString>& entry : aFpData.
m_pinMap )
1157 const wxString& pinNumber = entry.first;
1158 const wxString& desiredNet = entry.second;
1167 if( !
pin ||
pin->IsPower() || !
pin->IsConnectable() )
1171 wxString currentNet = connection ? connection->
Name(
true ) : wxString();
1173 if( desiredNet.IsEmpty() || currentNet.IsEmpty() )
1176 if( desiredNet == currentNet )
1179 size_t idx = mismatches.size();
1180 mismatches.push_back( {
pin, pinNumber, currentNet, desiredNet } );
1181 pinsByCurrentNet[currentNet].push_back( idx );
1184 if( mismatches.size() < 2 )
1189 std::vector<bool> handled( mismatches.size(),
false );
1190 std::vector<SCH_PIN*> swappedPinObjects;
1191 bool swappedLibPins =
false;
1194 bool allowPinSwaps =
false;
1195 wxString currentProjectName =
m_frame->Prj().GetProjectName();
1198 allowPinSwaps =
m_frame->eeconfig()->m_Input.allow_unconstrained_pin_swaps;
1200 std::set<wxString> sharedSheetPaths;
1201 std::set<wxString> sharedProjectNames;
1203 &sharedSheetPaths, &sharedProjectNames );
1205 std::set<wxString> friendlySheetNames;
1207 if( sharedSheetSymbol && !sharedSheetPaths.empty() )
1212 for(
size_t i = 0; i < mismatches.size(); ++i )
1218 PIN_CHANGE& change = mismatches[i];
1221 auto range = pinsByCurrentNet.find( change.targetNet );
1224 if( range == pinsByCurrentNet.end() )
1228 size_t partnerIdx = std::numeric_limits<size_t>::max();
1231 for(
size_t candidateIdx : range->second )
1233 if( candidateIdx == i || handled[candidateIdx] )
1236 PIN_CHANGE& candidate = mismatches[candidateIdx];
1240 if( candidate.targetNet == change.currentNet )
1242 partnerIdx = candidateIdx;
1249 if( partnerIdx == std::numeric_limits<size_t>::max() )
1252 PIN_CHANGE&
partner = mismatches[partnerIdx];
1256 if( change.pin->GetParentSymbol() !=
partner.pin->GetParentSymbol() )
1259 if( !allowPinSwaps || sharedSheetSymbol )
1261 if( !sharedProjectNames.empty() )
1263 std::vector<wxString> otherProjects;
1265 for(
const wxString&
name : sharedProjectNames )
1267 if( !currentProjectName.IsEmpty() &&
name.IsSameAs( currentProjectName ) )
1270 otherProjects.push_back(
name );
1275 if( projects.IsEmpty() )
1277 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but the symbol is shared across other projects." ),
1284 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but the symbol is shared across other "
1290 else if( !friendlySheetNames.empty() )
1294 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but the symbol is used by multiple sheet "
1295 "instances (%s)." ),
1300 else if( sharedSheetSymbol )
1302 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but the symbol is shared." ),
1309 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but unconstrained pin swaps are disabled in "
1310 "the schematic preferences." ),
1318 handled[partnerIdx] =
true;
1324 wxCHECK2( aCommit,
continue );
1335 handled[partnerIdx] =
true;
1338 swappedPins.insert( change.pinNumber );
1339 swappedPins.insert(
partner.pinNumber );
1340 swappedPinObjects.push_back( change.pin );
1341 swappedPinObjects.push_back(
partner.pin );
1345 msg.Printf(
_(
"Swap %s pins %s and %s to match PCB." ),
1353 if( swappedPinObjects.empty() )
1358 if( swappedLibPins )
1361 m_frame->UpdateItem( aSymbol,
false,
true );
1370 for(
SCH_PIN* swappedPin : swappedPinObjects )
1371 cleanupSelection.
Add( swappedPin );
1373 lwbTool->TrimOverLappingWires( aCommit, &cleanupSelection );
1374 lwbTool->AddJunctionsIfNeeded( aCommit, &cleanupSelection );
1378 m_frame->Schematic().CleanUp( aCommit );
1387 const wxString& aOldName,
const wxString& aNewName )
1395 std::set<SCH_ITEM*> connectedItems;
1401 for(
SCH_ITEM* item : connectedItems )
1405 if( priority > driverPriority )
1408 driverPriority = priority;
1412 switch( driver->
Type() )
1420 msg.Printf(
_(
"Change %s pin %s net label from '%s' to '%s'." ),
1436 if(
static_cast<SCH_PIN*
>( driver )->IsPower() )
1438 msg.Printf(
_(
"Net %s cannot be changed to %s because it is driven by a power pin." ),
1458 msg.Printf(
_(
"Change %s pin %s net label from '%s' to '%s'." ),
DescribeRef( aRef ),
1474 static_cast<SCH_LABEL_BASE*
>( resolvedDriver )->SetText( aNewName );
1484 msg.Printf(
_(
"Add label '%s' to %s pin %s net." ),
1499 aCommit->
Add( label, screen );
static std::vector< wxString > netsInUnitOrder(const std::vector< wxString > &aPins, const std::map< wxString, wxString > &aNetByPin)
void addConnections(SCH_ITEM *aItem, const SCH_SHEET_PATH &aSheetPath, std::set< SCH_ITEM * > &connectedItems)
static SPIN_STYLE orientLabel(SCH_PIN *aPin)
BACKANNOTATE_UNIT_SWAP_PLAN PlanBackannotateUnitSwaps(const std::vector< BACKANNOTATE_UNIT_SWAP_CANDIDATE > &aCandidates, const std::map< wxString, wxString > &aPcbPinMap)
Compute a pure unit-swap plan from schematic-side unit definitions and the final PCB pin map.
BACKANNOTATE_UNIT_SWAP_PLAN PlanBackannotateUnitSwaps(const std::vector< BACKANNOTATE_UNIT_SWAP_CANDIDATE > &aCandidates, const std::map< wxString, wxString > &aPcbPinMap)
Compute a pure unit-swap plan from schematic-side unit definitions and the final PCB pin map.
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
bool BackAnnotateSymbols(const std::string &aNetlist)
Run back annotation algorithm.
SCH_MULTI_UNIT_REFERENCE_MAP m_multiUnitsRefs
std::deque< CHANGELIST_ITEM > m_changelist
std::pair< SCH_REFERENCE, std::shared_ptr< PCB_FP_DATA > > CHANGELIST_ITEM
bool m_processOtherFields
void getPcbModulesFromString(const std::string &aPayload)
Parse netlist sent over KiWay express mail interface and fill m_pcbModules.
void checkForUnusedSymbols()
Check if some symbols are not represented in PCB footprints and vice versa.
SCH_REFERENCE_LIST m_refs
bool FetchNetlistFromPCB(std::string &aNetlist)
Get netlist from the Pcbnew.
PCB_FOOTPRINTS_MAP m_pcbFootprints
void processNetNameChange(SCH_COMMIT *aCommit, const wxString &aRef, SCH_PIN *aPin, const SCH_CONNECTION *aConnection, const wxString &aOldName, const wxString &aNewName)
BACK_ANNOTATE(SCH_EDIT_FRAME *aFrame, REPORTER &aReporter, bool aRelinkFootprints, bool aProcessFootprints, bool aProcessValues, bool aProcessReferences, bool aProcessNetNames, bool aProcessAttributes, bool aProcessOtherFields, bool aPreferUnitSwaps, bool aPreferPinSwaps, bool aDryRun)
std::set< wxString > applyPinSwaps(SCH_SYMBOL *aSymbol, const SCH_REFERENCE &aReference, const PCB_FP_DATA &aFpData, SCH_COMMIT *aCommit)
Handle footprint pad net swaps with symbol pin swaps where possible.
void applyChangelist()
Apply changelist to the schematic.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
Calculate the connectivity of a schematic and generates netlists.
CONNECTION_SUBGRAPH * GetSubgraphForItem(SCH_ITEM *aItem) const
A subgraph is a set of items that are electrically connected on a single sheet.
PRIORITY GetDriverPriority()
const SCH_ITEM * GetDriver() const
static PRIORITY GetDriverPriority(SCH_ITEM *aDriver)
Return the priority (higher is more important) of a candidate driver.
const SCH_SHEET_PATH & GetSheet() const
Implement a lexical analyzer for the SPECCTRA DSN file format.
virtual VECTOR2I GetPosition() const
void SetFlags(EDA_ITEM_FLAGS aMask)
KICAD_T Type() const
Returns the type of object.
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
virtual void SetParent(EDA_ITEM *aParent)
EDA_ITEM_FLAGS GetFlags() const
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual void SetTextPos(const VECTOR2I &aPoint)
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
virtual void SetVisible(bool aVisible)
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
virtual bool OpenProjectFiles(const std::vector< wxString > &aFileList, int aCtl=0)
Open a project or set of files given by aFileList.
Define a library symbol object.
std::vector< UNIT_PIN_INFO > GetUnitPinInfo() const
Return pin-number lists for each unit, ordered consistently for gate swapping.
static REPORTER & GetInstance()
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & ReportHead(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Places the report at the beginning of the list for objects that support ordering.
These are loaded from Eeschema settings but then overwritten by the project settings.
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
SCH_SHEET_PATH Sheet() const
wxString Name(bool aIgnoreSheet=false) const
Schematic editor (Eeschema) main window.
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0, const wxString &aVariantName=wxEmptyString) const
void SetText(const wxString &aText) override
Base class for any item which can be embedded within the SCHEMATIC container class,...
const SYMBOL * GetParentSymbol() const
const std::vector< SCH_ITEM * > & ConnectedItems(const SCH_SHEET_PATH &aPath)
Retrieve the set of items connected to this item on the given sheet.
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
SCH_PIN * GetLibPin() const
PIN_ORIENTATION GetOrientation() const
const wxString & GetShownNumber() const
A helper to define a symbol's reference designator in a schematic.
const SCH_SHEET_PATH & GetSheetPath() const
const wxString GetFootprint() const
SCH_SYMBOL * GetSymbol() const
const wxString GetValue() const
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void GetMultiUnitSymbols(SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, SYMBOL_FILTER aSymbolFilter) const
Add a SCH_REFERENCE_LIST object to aRefList for each same-reference set of multi-unit parts in the li...
void GetSymbols(SCH_REFERENCE_LIST &aReferences, SYMBOL_FILTER aSymbolFilter, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SCREEN * LastScreen()
virtual void SetDNP(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
void RemoveField(const wxString &aFieldName)
Remove a user field from the symbol.
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
bool GetExcludedFromBOM(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
void UpdatePins()
Updates the cache of SCH_PIN objects for each pin.
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
void SetFootprintFieldText(const wxString &aFootprint)
VECTOR2I GetPosition() const override
void SetExcludedFromPosFiles(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
void SetValueFieldText(const wxString &aValue, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString)
bool GetExcludedFromPosFiles(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
bool GetExcludedFromBoard(const SCH_SHEET_PATH *aInstance=nullptr, 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.
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
int GetOrientation() const override
Get the display symbol orientation.
void SetExcludedFromBOM(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear the exclude from schematic bill of materials flag.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
virtual bool GetDNP(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Set or clear the 'Do Not Populate' flag.
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.
virtual void Add(EDA_ITEM *aItem)
SPIN_STYLE MirrorX()
Mirror the label spin style across the X axis or simply swaps up and bottom.
SPIN_STYLE MirrorY()
Mirror the label spin style across the Y axis or simply swaps left and right.
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
wxString DescribeRef(const wxString &aRef)
Returns a user-visible HTML string describing a footprint reference designator.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
#define IS_NEW
New item, just created.
#define SKIP_STRUCT
flag indicating that the structure should be ignored
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
@ PIN_RIGHT
The pin extends rightwards from the connection point.
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
void Scan(PTREE *aTree, DSNLEXER *aLexer)
Fill an empty PTREE with information from a KiCad s-expression stream.
boost::property_tree::ptree PTREE
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
@ SYMBOL_FILTER_NON_POWER
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
wxString From_UTF8(const char *cstring)
void AccumulateDescriptions(wxString &aDesc, const T &aItemCollection)
Build a comma-separated list from a collection of wxStrings.
std::vector< wxString > m_unitPinNumbers
std::map< wxString, wxString > m_schNetsByPin
std::vector< BACKANNOTATE_UNIT_SWAP_STEP > m_steps
std::set< size_t > m_swappedCandidateIndices
Container for Pcbnew footprint data.Map to hold NETLIST footprints data.
std::map< wxString, wxString > m_pinMap
bool m_excludeFromPosFiles
std::map< wxString, wxString > m_fieldsMap
@ USER
The field ID hasn't been set yet; field is invalid.
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
wxString GetCanonicalFieldName(FIELD_T aFieldType)
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.