27#include <boost/property_tree/ptree.hpp>
51#include <fmt/ranges.h>
56 const std::map<wxString, wxString>& aNetByPin )
58 std::vector<wxString> nets;
62 for(
const wxString& pinNum : aPins )
64 auto it = aNetByPin.find( pinNum );
65 nets.push_back( it != aNetByPin.end() ? it->second : wxString() );
70 for(
const std::pair<const wxString, wxString>&
kv : aNetByPin )
71 nets.push_back(
kv.second );
79 const std::vector<BACKANNOTATE_UNIT_SWAP_CANDIDATE>& aCandidates,
80 const std::map<wxString, wxString>& aPcbPinMap )
84 if( aCandidates.size() < 2 )
90 std::map<size_t, size_t> desiredTarget;
91 std::set<size_t> usedTargets;
93 for(
size_t candidateIdx = 0; candidateIdx < aCandidates.size(); ++candidateIdx )
96 std::map<wxString, wxString> pcbNetsByPin;
100 auto it = aPcbPinMap.find( pinNum );
101 pcbNetsByPin[pinNum] = ( it != aPcbPinMap.end() ) ? it->second : wxString();
105 bool matched =
false;
107 for(
size_t matchIdx = 0; matchIdx < aCandidates.size(); ++matchIdx )
109 if( usedTargets.count( matchIdx ) )
113 std::vector<wxString> schNets =
116 if( pcbNets == schNets )
118 desiredTarget[candidateIdx] = matchIdx;
119 usedTargets.insert( matchIdx );
132 for(
size_t candidateIdx = 0; candidateIdx < aCandidates.size(); ++candidateIdx )
134 auto it = desiredTarget.find( candidateIdx );
136 if( it == desiredTarget.end() || it->second != candidateIdx )
146 std::set<size_t> visited;
148 for(
size_t startIdx = 0; startIdx < aCandidates.size(); ++startIdx )
150 if( visited.count( startIdx ) )
153 std::vector<size_t> cycle;
154 size_t curIdx = startIdx;
156 while( !visited.count( curIdx ) )
158 visited.insert( curIdx );
159 cycle.push_back( curIdx );
161 auto nextIt = desiredTarget.find( curIdx );
163 if( nextIt == desiredTarget.end() || nextIt->second == curIdx )
166 curIdx = nextIt->second;
169 if( cycle.size() < 2 )
172 for(
size_t i = cycle.size() - 1; i > 0; --i )
174 size_t firstIdx = cycle[i - 1];
175 size_t secondIdx = cycle[i];
177 plan.
m_steps.push_back( { firstIdx, secondIdx,
178 aCandidates[firstIdx].m_currentUnit,
179 aCandidates[secondIdx].m_currentUnit } );
190 bool aProcessFootprints,
bool aProcessValues,
bool aProcessReferences,
191 bool aProcessNetNames,
bool aProcessAttributes,
bool aProcessOtherFields,
192 bool aPreferUnitSwaps,
bool aPreferPinSwaps,
bool aDryRun ) :
239 "stand-alone mode.\n"
240 "You must launch the KiCad project manager and create a project." ) );
248 wxFileName fn(
m_frame->Prj().GetProjectFullName() );
249 fn.SetExt( FILEEXT::PcbFileExtension );
262 std::string nullPayload;
270 auto getStr = [](
const PTREE& pt ) -> wxString
272 return UTF8( pt.front().first );
282 Scan( &doc, &lexer );
284 PTREE& tree = doc.get_child(
"pcb_netlist" );
288 for(
const std::pair<const std::string, PTREE>& item : tree )
290 wxString
path, value, footprint;
291 bool dnp =
false, exBOM =
false, exPosFiles =
false;
292 std::map<wxString, wxString> pinNetMap, fieldsMap;
293 wxASSERT( item.first ==
"ref" );
294 wxString ref = getStr( item.second );
301 path = getStr( item.second.get_child(
"timestamp" ) );
305 msg.Printf(
_(
"Footprint '%s' has no assigned symbol." ),
DescribeRef( ref ) );
310 footprint = getStr( item.second.get_child(
"fpid" ) );
311 value = getStr( item.second.get_child(
"value" ) );
314 boost::optional<const PTREE&> fields = item.second.get_child_optional(
"fields" );
319 for(
const std::pair<const std::string, PTREE>& field : fields.get() )
321 if( field.first !=
"field" )
325 const auto& fieldName = field.second.get_child_optional(
"name" );
326 const std::string& fieldValue = field.second.back().first;
331 fieldsMap[getStr( fieldName.get() )] = wxString::FromUTF8( fieldValue );
338 for(
const auto& child : item.second )
340 if( child.first !=
"property" )
343 auto property = child.second;
344 auto name =
property.get_child_optional(
"name" );
349 if(
name.get().front().first ==
"dnp" )
351 else if(
name.get().front().first ==
"exclude_from_bom" )
353 else if(
name.get().front().first ==
"exclude_from_pos_files" )
357 boost::optional<const PTREE&> nets = item.second.get_child_optional(
"nets" );
361 for(
const std::pair<const std::string, PTREE>& pin_net : nets.get() )
363 wxASSERT( pin_net.first ==
"pin_net" );
364 wxString pinNumber =
UTF8( pin_net.second.front().first );
365 wxString netName =
UTF8( pin_net.second.back().first );
366 pinNetMap[ pinNumber ] = netName;
372 wxLogWarning(
"Cannot parse PCB netlist for back-annotation." );
381 msg.Printf(
_(
"Footprints '%s' and '%s' linked to same symbol." ),
389 std::shared_ptr<PCB_FP_DATA> data = std::make_shared<PCB_FP_DATA>( ref, footprint, value, dnp, exBOM,
390 exPosFiles, pinNetMap, fieldsMap );
402 bool foundInMultiunit =
false;
407 refIndex = refList.FindRef( pcbPath );
409 refIndex = refList.FindRefByFullPath( pcbPath );
415 foundInMultiunit =
true;
417 for(
size_t i = 0; i < refList.GetCount(); ++i )
419 refList[ i ].GetSymbol()->ClearFlags(
SKIP_STRUCT );
427 if( foundInMultiunit )
431 refIndex =
m_refs.FindRef( pcbPath );
433 refIndex =
m_refs.FindRefByFullPath( pcbPath );
443 m_reporter.ReportTail( wxString::Format(
_(
"Cannot find symbol for footprint '%s'." ),
457 return SCH_REFERENCE_LIST::sortByTimeStamp( a.first, b.first );
466 while( i <
m_refs.GetCount() &&
m_refs[i].GetPath() != item.first.GetPath() )
472 m_reporter.ReportTail( wxString::Format(
_(
"Footprint '%s' is not present on PCB. "
473 "Corresponding symbols in schematic must be "
474 "manually deleted (if desired)." ),
486 "annotated schematic." ) ) )
498 std::set<CHANGELIST_ITEM*> unitSwapItems;
508 std::map<std::shared_ptr<PCB_FP_DATA>, std::vector<CHANGELIST_ITEM*>> changesPerFp;
510 msg.Printf( wxT(
"DEBUG(unit-swap): grouped changelist into %zu footprint(s) for unit-swap processing:" ),
511 changesPerFp.size() );
518 changesPerFp[item.second].push_back( &item );
519 msg += wxT(
" " ) + item.first.GetRef();
525 for(
auto& fpChangelistPair : changesPerFp )
527 std::set<SCH_SYMBOL*> swappedSymbols;
528 std::set<CHANGELIST_ITEM*> swappedItems;
529 std::shared_ptr<PCB_FP_DATA> fp = fpChangelistPair.first;
530 auto& changedFpItems = fpChangelistPair.second;
543 std::map<wxString, wxString> schNetsByPin;
544 std::map<wxString, wxString> pcbNetsByPin;
545 std::vector<wxString> unitPinNumbers;
546 std::vector<wxString> schNetsInUnitOrder;
547 std::vector<wxString> pcbNetsInUnitOrder;
551 std::vector<SYM_UNIT> symbolUnits;
553 std::map<LIB_SYMBOL*, std::vector<LIB_SYMBOL::UNIT_PIN_INFO>> unitPinsByLibSymbol;
556 [&](
SCH_SYMBOL* symbol,
int unitNumber ) -> std::vector<wxString>
558 if( unitNumber <= 0 )
569 auto found = unitPinsByLibSymbol.find( libSymbol );
571 if( found == unitPinsByLibSymbol.end() )
572 found = unitPinsByLibSymbol.emplace( libSymbol, libSymbol->
GetUnitPinInfo() ).first;
574 const std::vector<LIB_SYMBOL::UNIT_PIN_INFO>& unitInfos = found->second;
576 if( unitNumber >
static_cast<int>( unitInfos.size() ) )
579 return unitInfos[unitNumber - 1].m_pinNumbers;
594 symbolUnit.sym = symbol;
595 symbolUnit.screen = screen;
598 symbolUnit.changeItem = changedItem;
600 int currentUnit = ref.
GetUnit();
602 if( currentUnit <= 0 )
605 if( currentUnit <= 0 )
606 currentUnit = symbol->
GetUnit();
608 symbolUnit.currentUnit = currentUnit;
609 symbolUnit.unitPinNumbers = getUnitPins( symbol, symbolUnit.currentUnit );
615 const wxString& pinNum =
pin->GetNumber();
618 auto it = fp->m_pinMap.find( pinNum );
619 symbolUnit.pcbNetsByPin[pinNum] = ( it != fp->m_pinMap.end() ) ? it->second : wxString();
625 symbolUnit.schNetsByPin[pinNum] = connection->Name(
true );
627 symbolUnit.schNetsByPin[pinNum] = wxString();
630 symbolUnit.schNetsByPin[pinNum] = wxString();
633 symbolUnit.pcbNetsInUnitOrder =
netsInUnitOrder( symbolUnit.unitPinNumbers, symbolUnit.pcbNetsByPin );
634 symbolUnit.schNetsInUnitOrder =
netsInUnitOrder( symbolUnit.unitPinNumbers, symbolUnit.schNetsByPin );
636 symbolUnits.push_back( symbolUnit );
639 auto vectorToString =
640 [](
const std::vector<wxString>& values ) -> wxString
642 return fmt::format(
L"{}", fmt::join( values,
L", " ) );
646 [vectorToString](
const std::map<wxString, wxString>& pinMap ) -> wxString
648 std::vector<wxString> entries;
650 for(
const std::pair<const wxString, wxString>&
pin : pinMap )
651 entries.push_back(
pin.first +
'=' +
pin.second );
653 return vectorToString( entries );
656 msg.Printf( wxT(
"DEBUG(unit-swap): footprint %s processed (%zu units, dryRun=%d)." ), fp->m_ref,
657 symbolUnits.size(),
m_dryRun ? 1 : 0 );
661 std::sort( symbolUnits.begin(), symbolUnits.end(),
662 [](
const SYM_UNIT& a,
const SYM_UNIT& b )
664 return a.ref < b.ref;
667 for(
const SYM_UNIT& su : symbolUnits )
669 wxString pcbPins = mapToString( su.pcbNetsByPin );
670 wxString schPins = mapToString( su.schNetsByPin );
671 wxString unitPins = vectorToString( su.unitPinNumbers );
672 wxString pcbUnitNetSeq = vectorToString( su.pcbNetsInUnitOrder );
673 wxString schUnitNetSeq = vectorToString( su.schNetsInUnitOrder );
675 msg.Printf( wxT(
"DEBUG(unit-swap): unit %d: %s pcbPins[%s] schPins[%s] unitPins[%s] pcbUnitNets[%s] "
676 "schUnitNets[%s]." ),
677 su.currentUnit, su.ref, pcbPins, schPins, unitPins, pcbUnitNetSeq, schUnitNetSeq );
681 if( symbolUnits.size() < 2 )
684 std::vector<BACKANNOTATE_UNIT_SWAP_CANDIDATE> candidates;
686 for(
const SYM_UNIT& symbolUnit : symbolUnits )
689 candidate.
m_ref = symbolUnit.ref;
693 candidates.push_back( candidate );
700 msg.Printf( wxT(
"DEBUG(unit-swap): mapping failed for footprint %s." ), fp->m_ref );
707 msg.Printf( wxT(
"DEBUG(unit-swap): footprint %s already aligned (identity mapping)." ), fp->m_ref );
715 commit.
Modify( symbolUnits[candidateIdx].sym, symbolUnits[candidateIdx].screen );
722 int aUnit = a.currentUnit;
723 int bUnit = b.currentUnit;
727 a.sym->SetUnit( bUnit );
728 b.sym->SetUnit( aUnit );
731 a.sym->SetUnitSelection( sheet, bUnit );
734 b.sym->SetUnitSelection( sheet, aUnit );
737 a.currentUnit = bUnit;
738 b.currentUnit = aUnit;
740 swappedSymbols.insert( a.sym );
741 swappedSymbols.insert( b.sym );
745 swappedItems.insert( a.changeItem );
746 unitSwapItems.insert( a.changeItem );
751 swappedItems.insert( b.changeItem );
752 unitSwapItems.insert( b.changeItem );
755 wxString baseRef = a.sym->GetRef( a.sheetPath,
false );
756 wxString unitAString = a.sym->SubReference( aUnit,
false );
757 wxString unitBString = b.sym->SubReference( bUnit,
false );
759 if( unitAString.IsEmpty() )
760 unitAString.Printf( wxT(
"%d" ), aUnit );
762 if( unitBString.IsEmpty() )
763 unitBString.Printf( wxT(
"%d" ), bUnit );
765 msg.Printf(
_(
"Swap %s unit %s with unit %s." ),
773 msg.Printf( wxT(
"DEBUG(unit-swap): applied %zu swap steps for footprint %s." ),
774 plan.
m_steps.size(), fp->m_ref );
782 SCH_SYMBOL* symbol = changedItem->first.GetSymbol();
787 if( swappedItems.count( changedItem ) || swappedSymbols.count( symbol ) )
790 int updatedUnit = symbol->
GetUnitSelection( &changedItem->first.GetSheetPath() );
791 changedItem->first.SetUnit( updatedUnit );
810 bool skip = ( ref.
GetSymbol()->GetFlags() &
SKIP_STRUCT ) > 0 || unitSwapItems.count( &item ) > 0;
813 [](
bool b ) -> wxString
815 return b ?
_(
"true" ) :
_(
"false" );
825 msg.Printf(
_(
"Change %s reference designator to '%s'." ),
839 msg.Printf(
_(
"Change %s footprint assignment from '%s' to '%s'." ),
854 msg.Printf(
_(
"Change %s value from '%s' to '%s'." ),
868 msg.Printf(
_(
"Change %s 'Do not populate' from '%s' to '%s'." ),
870 boolString( oldDNP ),
871 boolString( fpData.
m_DNP ) );
882 msg.Printf(
_(
"Change %s 'Exclude from bill of materials' from '%s' to '%s'." ),
884 boolString( oldExBOM ),
896 msg.Printf(
_(
"Change %s 'Exclude from position files' from '%s' to '%s'." ),
DescribeRef( ref.
GetRef() ),
905 std::set<wxString> swappedPins;
913 for(
const std::pair<const wxString, wxString>& entry : fpData.
m_pinMap )
915 const wxString& pinNumber = entry.first;
916 const wxString& shortNetName = entry.second;
920 if( swappedPins.count( pinNumber ) > 0 )
925 msg.Printf(
_(
"Cannot find %s pin '%s'." ),
935 if( connection && connection->
Name(
true ) != shortNetName )
938 connection->
Name(
true ), shortNetName );
946 for(
const std::pair<const wxString, wxString>& field : fpData.
m_fieldsMap )
948 const wxString& fpFieldName = field.first;
949 const wxString& fpFieldValue = field.second;
968 msg.Printf(
_(
"Change %s field '%s' value to '%s'." ),
974 symField->
SetText( fpFieldValue );
980 if( symField ==
nullptr )
983 msg.Printf(
_(
"Add %s field '%s' with value '%s'." ),
991 newField.
SetText( fpFieldValue );
1004 std::vector<wxString> fieldsToDelete;
1008 if( field.IsMandatory() )
1014 msg.Printf(
_(
"Delete %s field '%s.'" ),
1018 fieldsToDelete.push_back( field.GetName() );
1025 for(
const wxString& fieldName : fieldsToDelete )
1033 unitSwapItems.erase( &item );
1041 m_frame->UpdateNetHighlightStatus();
1043 commit.
Push(
_(
"Update Schematic from PCB" ) );
1086 ORIENT o = orientations[ 0 ];
1095 for(
const ORIENT& i : orientations )
1097 if( i.flag == symbolOrientation )
1104 for(
int i = 0; i < o.n_rots; i++ )
1119 if( connectedItems.insert( aItem ).second )
1132 std::set<wxString> swappedPins;
1142 wxCHECK(
m_frame, swappedPins );
1149 wxString currentNet;
1153 std::vector<PIN_CHANGE> mismatches;
1156 std::map<wxString, std::vector<size_t>> pinsByCurrentNet;
1159 for(
const std::pair<const wxString, wxString>& entry : aFpData.
m_pinMap )
1161 const wxString& pinNumber = entry.first;
1162 const wxString& desiredNet = entry.second;
1171 if( !
pin ||
pin->IsPower() || !
pin->IsConnectable() )
1175 wxString currentNet = connection ? connection->
Name(
true ) : wxString();
1177 if( desiredNet.IsEmpty() || currentNet.IsEmpty() )
1180 if( desiredNet == currentNet )
1183 size_t idx = mismatches.size();
1184 mismatches.push_back( {
pin, pinNumber, currentNet, desiredNet } );
1185 pinsByCurrentNet[currentNet].push_back( idx );
1188 if( mismatches.size() < 2 )
1193 std::vector<bool> handled( mismatches.size(),
false );
1194 std::vector<SCH_PIN*> swappedPinObjects;
1195 bool swappedLibPins =
false;
1198 bool allowPinSwaps =
false;
1199 wxString currentProjectName =
m_frame->Prj().GetProjectName();
1202 allowPinSwaps =
m_frame->eeconfig()->m_Input.allow_unconstrained_pin_swaps;
1204 std::set<wxString> sharedSheetPaths;
1205 std::set<wxString> sharedProjectNames;
1207 &sharedSheetPaths, &sharedProjectNames );
1209 std::set<wxString> friendlySheetNames;
1211 if( sharedSheetSymbol && !sharedSheetPaths.empty() )
1216 for(
size_t i = 0; i < mismatches.size(); ++i )
1222 PIN_CHANGE& change = mismatches[i];
1225 auto range = pinsByCurrentNet.find( change.targetNet );
1228 if( range == pinsByCurrentNet.end() )
1232 size_t partnerIdx = std::numeric_limits<size_t>::max();
1235 for(
size_t candidateIdx : range->second )
1237 if( candidateIdx == i || handled[candidateIdx] )
1240 PIN_CHANGE& candidate = mismatches[candidateIdx];
1244 if( candidate.targetNet == change.currentNet )
1246 partnerIdx = candidateIdx;
1253 if( partnerIdx == std::numeric_limits<size_t>::max() )
1256 PIN_CHANGE&
partner = mismatches[partnerIdx];
1260 if( change.pin->GetParentSymbol() !=
partner.pin->GetParentSymbol() )
1263 if( !allowPinSwaps || sharedSheetSymbol )
1265 if( !sharedProjectNames.empty() )
1267 std::vector<wxString> otherProjects;
1269 for(
const wxString&
name : sharedProjectNames )
1271 if( !currentProjectName.IsEmpty() &&
name.IsSameAs( currentProjectName ) )
1274 otherProjects.push_back(
name );
1279 if( projects.IsEmpty() )
1281 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but the symbol is shared across other projects." ),
1288 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but the symbol is shared across other "
1294 else if( !friendlySheetNames.empty() )
1298 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but the symbol is used by multiple sheet "
1299 "instances (%s)." ),
1304 else if( sharedSheetSymbol )
1306 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but the symbol is shared." ),
1313 msg.Printf(
_(
"Would swap %s pins %s and %s to match PCB, but unconstrained pin swaps are disabled in "
1314 "the schematic preferences." ),
1322 handled[partnerIdx] =
true;
1328 wxCHECK2( aCommit,
continue );
1339 handled[partnerIdx] =
true;
1342 swappedPins.insert( change.pinNumber );
1343 swappedPins.insert(
partner.pinNumber );
1344 swappedPinObjects.push_back( change.pin );
1345 swappedPinObjects.push_back(
partner.pin );
1349 msg.Printf(
_(
"Swap %s pins %s and %s to match PCB." ),
1357 if( swappedPinObjects.empty() )
1362 if( swappedLibPins )
1365 m_frame->UpdateItem( aSymbol,
false,
true );
1374 for(
SCH_PIN* swappedPin : swappedPinObjects )
1375 cleanupSelection.
Add( swappedPin );
1377 lwbTool->TrimOverLappingWires( aCommit, &cleanupSelection );
1378 lwbTool->AddJunctionsIfNeeded( aCommit, &cleanupSelection );
1382 m_frame->Schematic().CleanUp( aCommit );
1391 const wxString& aOldName,
const wxString& aNewName )
1399 std::set<SCH_ITEM*> connectedItems;
1405 for(
SCH_ITEM* item : connectedItems )
1409 if( priority > driverPriority )
1412 driverPriority = priority;
1416 switch( driver->
Type() )
1424 msg.Printf(
_(
"Change %s pin %s net label from '%s' to '%s'." ),
1440 if(
static_cast<SCH_PIN*
>( driver )->IsPower() )
1442 msg.Printf(
_(
"Net %s cannot be changed to %s because it is driven by a power pin." ),
1462 msg.Printf(
_(
"Change %s pin %s net label from '%s' to '%s'." ),
DescribeRef( aRef ),
1478 static_cast<SCH_LABEL_BASE*
>( resolvedDriver )->SetText( aNewName );
1488 msg.Printf(
_(
"Add label '%s' to %s pin %s net." ),
1503 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
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
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.