133 bestPosition.
x = pageSize.
x / 2;
134 bestPosition.
y = pageSize.
y / 2;
151 if( aFootprintId.
empty() )
153 msg.Printf(
_(
"Cannot add %s (no footprint assigned)." ),
162 if( footprint ==
nullptr )
164 msg.Printf(
_(
"Cannot add %s (footprint '%s' not found)." ),
173 m_board->GetComponentClassManager().GetNoneComponentClass() );
177 msg.Printf(
_(
"Add %s (footprint '%s')." ),
189 pad->SetLocalRatsnestVisible(
m_frame->GetPcbNewSettings()->m_Display.m_ShowGlobalRatsnest );
192 pad->SetNetCode( 0 );
207 msg.Printf(
_(
"Added %s (footprint '%s')." ),
220 wxString curClassName, newClassName;
224 curClassName = curClass->
GetName();
234 newClass =
m_board->GetComponentClassManager().GetEffectiveStaticComponentClass(
236 newClassName = newClass->
GetName();
239 if( curClassName == newClassName )
248 copy->SetParentGroup(
nullptr );
255 if( curClassName == wxEmptyString && newClassName != wxEmptyString )
257 msg.Printf(
_(
"Change %s component class to '%s'." ),
261 else if( curClassName != wxEmptyString && newClassName == wxEmptyString )
263 msg.Printf(
_(
"Remove %s component class (currently '%s')." ),
269 msg.Printf(
_(
"Change %s component class from '%s' to '%s'." ),
277 wxASSERT_MSG( newClass !=
nullptr,
"Component class should not be nullptr" );
281 if( curClassName == wxEmptyString && newClassName != wxEmptyString )
283 msg.Printf(
_(
"Changed %s component class to '%s'." ),
287 else if( curClassName != wxEmptyString && newClassName == wxEmptyString )
289 msg.Printf(
_(
"Removed %s component class (was '%s')." ),
295 msg.Printf(
_(
"Changed %s component class from '%s' to '%s'." ),
318 msg.Printf(
_(
"Cannot update %s (no footprint assigned)." ),
327 if( newFootprint ==
nullptr )
329 msg.Printf(
_(
"Cannot update %s (footprint '%s' not found)." ),
341 msg.Printf(
_(
"Cannot change %s footprint from '%s' to '%s' (footprint is locked)."),
352 msg.Printf(
_(
"Change %s footprint from '%s' to '%s'."),
366 msg.Printf(
_(
"Could not change %s footprint from '%s' to '%s' (footprint is locked)."),
382 msg.Printf(
_(
"Changed %s footprint from '%s' to '%s'."),
402 if( !
m_commit.GetStatus( aPcbFootprint ) )
405 copy->SetParentGroup(
nullptr );
408 bool changed =
false;
415 msg.Printf(
_(
"Change %s reference designator to %s." ),
421 msg.Printf(
_(
"Changed %s reference designator to %s." ),
437 msg.Printf(
_(
"Change %s value from %s to %s." ),
444 msg.Printf(
_(
"Changed %s value from %s to %s." ),
459 if( !aNetlistComponent->
GetKIIDs().empty() )
460 new_path.push_back( aNetlistComponent->
GetKIIDs().front() );
462 if( aPcbFootprint->
GetPath() != new_path )
466 msg.Printf(
_(
"Update %s symbol association from %s to %s." ),
473 msg.Printf(
_(
"Updated %s symbol association from %s to %s." ),
479 aPcbFootprint->
SetPath( new_path );
485 nlohmann::ordered_map<wxString, wxString> fpFieldsAsMap;
490 if( field->IsReference() || field->IsValue() || field->IsComponentClass() )
495 fpFieldsAsMap[field->GetName()] = field->GetText();
499 nlohmann::ordered_map<wxString, wxString> compFields = aNetlistComponent->
GetFields();
505 compFields.erase( wxT(
"Component Class" ) );
511 bool remove_only =
true;
513 for(
const auto& [
name, value] : compFields )
515 if( fpFieldsAsMap.count(
name ) == 0 || fpFieldsAsMap[
name] != value )
523 for(
const auto& [
name, value] : fpFieldsAsMap )
525 if( compFields.count(
name ) == 0 )
538 msg.Printf(
_(
"Update %s fields." ), aPcbFootprint->
GetReference() );
545 if( field->IsMandatory() )
548 if( compFields.count( field->GetName() ) == 0 )
552 msg.Printf(
_(
"Remove %s footprint fields not in symbol." ),
565 msg.Printf(
_(
"Updated %s fields." ), aPcbFootprint->
GetReference() );
571 for(
auto& [
name, value] : compFields )
580 aPcbFootprint->
Add( newField );
602 std::vector<PCB_FIELD*> fieldList;
603 aPcbFootprint->
GetFields( fieldList,
false );
607 if( field->IsMandatory() )
610 if( compFields.count( field->GetName() ) == 0 )
615 msg.Printf(
_(
"Removed %s footprint fields not in symbol." ),
620 aPcbFootprint->
Remove( field );
623 m_frame->GetCanvas()->GetView()->Remove( field );
638 if( !humanSheetPath.empty() )
639 sheetname = humanSheetPath;
640 else if( aNetlistComponent->
GetProperties().count( wxT(
"Sheetname" ) ) > 0 )
641 sheetname = aNetlistComponent->
GetProperties().at( wxT(
"Sheetname" ) );
643 if( aNetlistComponent->
GetProperties().count( wxT(
"Sheetfile" ) ) > 0 )
644 sheetfile = aNetlistComponent->
GetProperties().at( wxT(
"Sheetfile" ) );
646 if( aNetlistComponent->
GetProperties().count( wxT(
"ki_fp_filters" ) ) > 0 )
647 fpFilters = aNetlistComponent->
GetProperties().at( wxT(
"ki_fp_filters" ) );
653 msg.Printf(
_(
"Update %s sheetname to '%s'." ),
660 msg.Printf(
_(
"Updated %s sheetname to '%s'." ),
672 msg.Printf(
_(
"Update %s sheetfile to '%s'." ),
679 msg.Printf(
_(
"Updated %s sheetfile to '%s'." ),
687 if( fpFilters != aPcbFootprint->
GetFilters() )
691 msg.Printf(
_(
"Update %s footprint filters to '%s'." ),
698 msg.Printf(
_(
"Updated %s footprint filters to '%s'." ),
706 if( ( aNetlistComponent->
GetProperties().count( wxT(
"exclude_from_bom" ) ) > 0 )
711 if( aNetlistComponent->
GetProperties().count( wxT(
"exclude_from_bom" ) ) )
713 msg.Printf(
_(
"Add %s 'exclude from BOM' fabrication attribute." ),
718 msg.Printf(
_(
"Remove %s 'exclude from BOM' fabrication attribute." ),
726 if( aNetlistComponent->
GetProperties().count( wxT(
"exclude_from_bom" ) ) )
729 msg.Printf(
_(
"Added %s 'exclude from BOM' fabrication attribute." ),
735 msg.Printf(
_(
"Removed %s 'exclude from BOM' fabrication attribute." ),
746 if( ( aNetlistComponent->
GetProperties().count( wxT(
"dnp" ) ) > 0 )
751 if( aNetlistComponent->
GetProperties().count( wxT(
"dnp" ) ) )
753 msg.Printf(
_(
"Add %s 'Do not place' fabrication attribute." ),
758 msg.Printf(
_(
"Remove %s 'Do not place' fabrication attribute." ),
766 if( aNetlistComponent->
GetProperties().count( wxT(
"dnp" ) ) )
769 msg.Printf(
_(
"Added %s 'Do not place' fabrication attribute." ),
775 msg.Printf(
_(
"Removed %s 'Do not place' fabrication attribute." ),
786 if( ( aNetlistComponent->
GetProperties().count( wxT(
"exclude_from_pos_files" ) ) > 0 )
791 if( aNetlistComponent->
GetProperties().count( wxT(
"exclude_from_pos_files" ) ) )
793 msg.Printf(
_(
"Add %s 'exclude from position files' fabrication attribute." ),
798 msg.Printf(
_(
"Remove %s 'exclude from position files' fabrication attribute." ),
806 if( aNetlistComponent->
GetProperties().count( wxT(
"exclude_from_pos_files" ) ) )
809 msg.Printf(
_(
"Added %s 'exclude from position files' fabrication attribute." ),
815 msg.Printf(
_(
"Removed %s 'exclude from position files' fabrication attribute." ),
838 msg.Printf(
_(
"Added %s 'duplicate pad numbers are jumpers' attribute." ),
843 msg.Printf(
_(
"Removed %s 'duplicate pad numbers are jumpers' attribute." ),
851 msg.Printf(
_(
"Add %s 'duplicate pad numbers are jumpers' attribute." ),
856 msg.Printf(
_(
"Remove %s 'duplicate pad numbers are jumpers' attribute." ),
870 msg.Printf(
_(
"Updated %s jumper pad groups" ), aPcbFootprint->
GetReference() );
874 msg.Printf(
_(
"Update %s jumper pad groups" ), aPcbFootprint->
GetReference() );
880 if( changed &&
copy )
900 if( !
m_commit.GetStatus( aPcbFootprint ) )
903 copy->SetParentGroup(
nullptr );
906 bool changed =
false;
915 KIID existingGroupKIID = existingGroup ? existingGroup->
m_Uuid : 0;
918 auto it = std::find_if(
m_board->Groups().begin(),
m_board->Groups().end(),
920 return group->m_Uuid == newGroupKIID;
924 if( it !=
m_board->Groups().end() )
928 if( newGroupKIID == existingGroupKIID )
932 if( existingGroupKIID != 0 )
936 msg.Printf(
_(
"Remove %s from group '%s'." ),
942 msg.Printf(
_(
"Removed %s from group '%s'." ),
955 if( newGroupKIID != 0 )
959 msg.Printf(
_(
"Add %s to group '%s'." ),
965 msg.Printf(
_(
"Added %s group '%s'." ),
971 if( newGroup ==
nullptr )
974 const_cast<KIID&
>( newGroup->
m_Uuid ) = newGroupKIID;
987 newGroup->
AddItem( aPcbFootprint );
993 if( changed &&
copy )
1013 copy->SetParentGroup(
nullptr );
1016 bool changed =
false;
1019 std::deque<PAD*> pads = aFootprint->
Pads();
1020 std::set<wxString> padNetnames;
1022 std::sort( pads.begin(), pads.end(),
1025 return a->m_Uuid < b->m_Uuid;
1032 wxLogTrace( wxT(
"NETLIST_UPDATE" ),
1033 wxT(
"Processing pad %s of component %s" ),
1037 wxString pinFunction;
1042 wxLogTrace( wxT(
"NETLIST_UPDATE" ),
1043 wxT(
" Found valid net: %s" ),
1050 wxLogTrace( wxT(
"NETLIST_UPDATE" ),
1051 wxT(
" No net found for pad %s" ),
1057 if(
pad->GetPinFunction() != pinFunction )
1060 pad->SetPinFunction( pinFunction );
1063 if(
pad->GetPinType() != pinType )
1066 pad->SetPinType( pinType );
1075 if( !net.
IsValid() || !
pad->IsOnCopperLayer() )
1077 if( !
pad->GetNetname().IsEmpty() )
1081 msg.Printf(
_(
"Disconnect %s pin %s." ),
1087 msg.Printf(
_(
"Disconnected %s pin %s." ),
1094 else if(
pad->IsOnCopperLayer() && !
pad->GetNumber().IsEmpty() )
1097 msg.Printf(
_(
"No net found for component %s pad %s (no pin %s in symbol)." ),
1112 if(
pad->GetNetname().IsEmpty() )
1113 pad->SetPinFunction( wxEmptyString );
1125 if(
pad->IsNoConnectPad() )
1127 netName = wxString::Format( wxS(
"%s" ), net.
GetNetName() );
1129 for(
int jj = 1; !padNetnames.insert( netName ).second; jj++ )
1131 netName = wxString::Format( wxS(
"%s_%d" ), net.
GetNetName(), jj );
1140 if(
pad->GetNetname() != netName )
1143 if( netinfo ==
nullptr )
1150 if( netinfo ==
nullptr )
1162 msg.Printf(
_(
"Add net %s." ),
1167 if( !
pad->GetNetname().IsEmpty() )
1173 msg.Printf(
_(
"Reconnect %s pin %s from %s to %s."),
1181 msg.Printf(
_(
"Reconnected %s pin %s from %s to %s."),
1192 msg.Printf(
_(
"Connect %s pin %s to %s."),
1199 msg.Printf(
_(
"Connected %s pin %s to %s."),
1211 pad->SetNet( netinfo );
1221 if( changed &&
copy )
1233 std::vector<FOOTPRINT::FP_UNIT_INFO> newUnits;
1236 newUnits.push_back( { u.m_unitName, u.m_pins } );
1238 const std::vector<FOOTPRINT::FP_UNIT_INFO>& curUnits = aFootprint->
GetUnitInfo();
1240 auto unitsEqual = [](
const std::vector<FOOTPRINT::FP_UNIT_INFO>& a,
1241 const std::vector<FOOTPRINT::FP_UNIT_INFO>& b )
1243 if( a.size() != b.size() )
1246 for(
size_t i = 0; i < a.size(); ++i )
1248 if( a[i].m_unitName != b[i].m_unitName )
1251 if( a[i].m_pins != b[i].m_pins )
1258 if( unitsEqual( curUnits, newUnits ) )
1265 msg.Printf(
_(
"Update %s unit metadata." ), aFootprint->
GetReference() );
1273 if( !
m_commit.GetStatus( aFootprint ) )
1276 copy->SetParentGroup(
nullptr );
1281 msg.Printf(
_(
"Updated %s unit metadata." ), aFootprint->
GetReference() );
1292 const std::vector<FOOTPRINT*>& aFootprints,
1293 const LIB_ID& aBaseFpid )
1297 if( variants.empty() )
1300 if( aBaseFpid.
empty() )
1312 std::vector<VARIANT_INFO> variantInfo;
1313 variantInfo.reserve( variants.size() );
1315 for(
const auto& [variantName, variant] : variants )
1317 LIB_ID activeFpid = aBaseFpid;
1319 auto fieldIt = variant.m_fields.find( footprintFieldName );
1321 if( fieldIt != variant.m_fields.end() && !fieldIt->second.IsEmpty() )
1325 if( parsedId.
Parse( fieldIt->second,
true ) >= 0 )
1328 msg.Printf(
_(
"Invalid footprint ID '%s' for variant '%s' on %s." ),
1337 activeFpid = parsedId;
1341 variantInfo.push_back( { variantName, &variant, activeFpid } );
1344 for(
FOOTPRINT* footprint : aFootprints )
1354 copy->SetParentGroup(
nullptr );
1357 bool changed =
false;
1359 for(
const VARIANT_INFO&
info : variantInfo )
1370 bool targetDnp = variant.
m_hasDnp ? variant.
m_dnp : footprint->IsDNP();
1371 bool currentDnp = currentVariant ? currentVariant->
GetDNP() : footprint->IsDNP();
1373 if( currentDnp != targetDnp )
1379 msg.Printf( targetDnp ?
_(
"Add %s:%s 'Do not place' variant attribute." )
1380 :
_(
"Remove %s:%s 'Do not place' variant attribute." ),
1381 footprint->GetReference(),
info.name );
1385 msg.Printf( targetDnp ?
_(
"Added %s:%s 'Do not place' variant attribute." )
1386 :
_(
"Removed %s:%s 'Do not place' variant attribute." ),
1387 footprint->GetReference(),
info.name );
1392 fpVariant->
SetDNP( targetDnp );
1401 : footprint->IsExcludedFromBOM();
1403 : footprint->IsExcludedFromBOM();
1405 if( currentExcludedFromBOM != targetExcludedFromBOM )
1411 msg.Printf( targetExcludedFromBOM
1412 ?
_(
"Add %s:%s 'exclude from BOM' variant attribute." )
1413 :
_(
"Remove %s:%s 'exclude from BOM' variant attribute." ),
1414 footprint->GetReference(),
info.name );
1418 msg.Printf( targetExcludedFromBOM
1419 ?
_(
"Added %s:%s 'exclude from BOM' variant attribute." )
1420 :
_(
"Removed %s:%s 'exclude from BOM' variant attribute." ),
1421 footprint->GetReference(),
info.name );
1435 : footprint->IsExcludedFromPosFiles();
1436 bool currentExcludedFromPosFiles = currentVariant
1438 : footprint->IsExcludedFromPosFiles();
1440 if( currentExcludedFromPosFiles != targetExcludedFromPosFiles )
1446 msg.Printf( targetExcludedFromPosFiles
1447 ?
_(
"Add %s:%s 'exclude from position files' variant attribute." )
1448 :
_(
"Remove %s:%s 'exclude from position files' variant attribute." ),
1449 footprint->GetReference(),
info.name );
1453 msg.Printf( targetExcludedFromPosFiles
1454 ?
_(
"Added %s:%s 'exclude from position files' variant attribute." )
1455 :
_(
"Removed %s:%s 'exclude from position files' variant attribute." ),
1456 footprint->GetReference(),
info.name );
1468 for(
const auto& [fieldName, fieldValue] : variant.
m_fields )
1470 if( fieldName.CmpNoCase( footprintFieldName ) == 0 )
1473 bool hasCurrentValue = currentVariant && currentVariant->
HasFieldValue( fieldName );
1474 wxString currentValue = hasCurrentValue ? currentVariant->
GetFieldValue( fieldName )
1477 if( currentValue != fieldValue )
1483 msg.Printf(
_(
"Change %s:%s field '%s' to '%s'." ),
1484 footprint->GetReference(),
info.name, fieldName, fieldValue );
1488 msg.Printf(
_(
"Changed %s:%s field '%s' to '%s'." ),
1489 footprint->GetReference(),
info.name, fieldName, fieldValue );
1515 if( !zone->IsOnCopperLayer() || zone->GetIsRuleArea() )
1526 std::set<wxString> netlistNetnames;
1528 for(
int ii = 0; ii < (int) aNetlist.
GetCount(); ii++ )
1532 for(
unsigned jj = 0; jj < component->
GetNetCount(); jj++ )
1544 if( netlistNetnames.count(
via->GetNetname() ) == 0 )
1546 wxString updatedNetname = wxEmptyString;
1555 if( !updatedNetname.IsEmpty() )
1559 wxString originalNetname =
via->GetNetname();
1561 msg.Printf(
_(
"Reconnect via from %s to %s." ),
1576 wxString originalNetname =
via->GetNetname();
1579 via->SetNet( netinfo );
1581 msg.Printf(
_(
"Reconnected via from %s to %s." ),
1591 msg.Printf(
_(
"Via connected to unknown net (%s)." ),
1603 auto isInNetlist = [&](
const wxString& aNetName ) ->
bool
1605 if( netlistNetnames.count( aNetName ) )
1610 for(
const wxString& netName : netlistNetnames )
1612 if( aNetName.StartsWith( netName ) )
1622 if( !zone->IsOnCopperLayer() || zone->GetIsRuleArea() )
1625 if( !isInNetlist( zone->GetNetname() ) )
1630 wxString updatedNetname = wxEmptyString;
1643 if( updatedNetname.IsEmpty() &&
m_oldToNewNets.count( zone->GetNetname() ) )
1648 if( !updatedNetname.IsEmpty() )
1652 wxString originalNetname = zone->GetNetname();
1654 if( !zone->GetZoneName().IsEmpty() )
1656 msg.Printf(
_(
"Reconnect copper zone '%s' from %s to %s." ),
1657 zone->GetZoneName(),
1663 msg.Printf(
_(
"Reconnect copper zone from %s to %s." ),
1679 wxString originalNetname = zone->GetNetname();
1682 zone->SetNet( netinfo );
1684 if( !zone->GetZoneName().IsEmpty() )
1686 msg.Printf(
_(
"Reconnected copper zone '%s' from %s to %s." ),
1693 msg.Printf(
_(
"Reconnected copper zone from %s to %s." ),
1704 if( !zone->GetZoneName().IsEmpty() )
1706 msg.Printf(
_(
"Copper zone '%s' has no pads connected." ),
1711 wxString layerNames = zone->LayerMaskDescribe();
1716 if(
m_frame->GetPcbNewSettings()->m_Display.m_DisplayInvertXAxis )
1719 if(
m_frame->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
1723 msg.Printf(
_(
"Copper zone on %s at (%s, %s) has no pads connected to net \"%s\"." ),
1729 zone->GetNetname() );
1751 if( netlistGroup ==
nullptr )
1754 if( netlistGroup->
name != pcbGroup->GetName() )
1759 msg.Printf(
_(
"Change group name to '%s' to '%s'." ),
EscapeHTML( pcbGroup->GetName() ),
1766 msg.Printf(
_(
"Changed group name to '%s' to '%s'." ),
EscapeHTML( pcbGroup->GetName() ),
1769 pcbGroup->SetName( netlistGroup->
name );
1773 if( netlistGroup->
libId != pcbGroup->GetDesignBlockLibId() )
1778 msg.Printf(
_(
"Change group library link to '%s'." ),
1785 msg.Printf(
_(
"Changed group library link to '%s'." ),
1788 pcbGroup->SetDesignBlockLibId( netlistGroup->
libId );
1798 std::map<COMPONENT*, FOOTPRINT*>& aFootprintMap )
1806 for(
int i = 0; i < (int) aNetlist.
GetCount(); i++ )
1809 FOOTPRINT* footprint = aFootprintMap[component];
1815 for(
unsigned jj = 0; jj < component->
GetNetCount(); jj++ )
1819 if( padNumber.IsEmpty() )
1822 msg.Printf(
_(
"Symbol %s has pins with no number. These pins can not be matched "
1832 msg.Printf(
_(
"%s pad %s not found in %s." ),
1848 FOOTPRINT* lastPreexistingFootprint =
nullptr;
1851 std::unordered_set<wxString> sheetPaths;
1852 std::unordered_set<FOOTPRINT*> usedFootprints;
1858 std::map<COMPONENT*, FOOTPRINT*> footprintMap;
1860 if( !
m_board->Footprints().empty() )
1861 lastPreexistingFootprint =
m_board->Footprints().back();
1871 net->SetIsCurrent( net->GetNetCode() == 0 );
1873 m_board->GetComponentClassManager().InitNetlistUpdate();
1879 for(
unsigned i = 0; i < aNetlist.
GetCount(); i++ )
1883 if( component->
GetProperties().count( wxT(
"exclude_from_board" ) ) )
1886 msg.Printf(
_(
"Processing symbol '%s:%s'." ),
1892 const bool hasBaseFpid = !baseFpid.
empty();
1893 std::vector<FOOTPRINT*> matchingFootprints;
1904 base.push_back( uuid );
1906 if( footprint->GetPath() == base )
1915 match = footprint->GetReference().CmpNoCase( component->
GetReference() ) == 0;
1919 matchingFootprints.push_back( footprint );
1921 if( footprint == lastPreexistingFootprint )
1928 std::vector<LIB_ID> expectedFpids;
1929 std::unordered_set<wxString> expectedFpidKeys;
1931 auto addExpectedFpid =
1932 [&](
const LIB_ID& aFpid )
1937 wxString key = aFpid.Format();
1939 if( expectedFpidKeys.insert( key ).second )
1940 expectedFpids.push_back( aFpid );
1943 addExpectedFpid( baseFpid );
1947 for(
const auto& [variantName, variant] : component->
GetVariants() )
1949 auto fieldIt = variant.m_fields.find( footprintFieldName );
1951 if( fieldIt == variant.m_fields.end() || fieldIt->second.IsEmpty() )
1956 if( parsedId.
Parse( fieldIt->second,
true ) >= 0 )
1958 msg.Printf(
_(
"Invalid footprint ID '%s' for variant '%s' on %s." ),
1967 addExpectedFpid( parsedId );
1970 auto isExpectedFpid =
1971 [&](
const LIB_ID& aFpid ) ->
bool
1976 return expectedFpidKeys.count( aFpid.Format() ) > 0;
1979 auto takeMatchingFootprint =
1982 for(
FOOTPRINT* footprint : matchingFootprints )
1984 if( usedFootprints.count( footprint ) )
1987 if( footprint->GetFPID() == aFpid )
1994 std::vector<FOOTPRINT*> componentFootprints;
1995 componentFootprints.reserve( expectedFpids.size() );
1999 baseFootprint = takeMatchingFootprint( baseFpid );
2000 else if( !matchingFootprints.empty() )
2001 baseFootprint = matchingFootprints.front();
2007 for(
FOOTPRINT* footprint : matchingFootprints )
2009 if( usedFootprints.count( footprint ) )
2012 if( isExpectedFpid( footprint->GetFPID() ) )
2015 replaceCandidate = footprint;
2019 if( replaceCandidate )
2024 baseFootprint = replaced;
2026 baseFootprint = replaceCandidate;
2030 if( !baseFootprint && hasBaseFpid )
2035 componentFootprints.push_back( baseFootprint );
2036 usedFootprints.insert( baseFootprint );
2037 footprintMap[ component ] = baseFootprint;
2040 for(
const LIB_ID& fpid : expectedFpids )
2042 if( fpid == baseFpid )
2045 FOOTPRINT* footprint = takeMatchingFootprint( fpid );
2052 componentFootprints.push_back( footprint );
2053 usedFootprints.insert( footprint );
2057 for(
FOOTPRINT* footprint : componentFootprints )
2068 sheetPaths.insert( footprint->GetSheetname() );
2071 if( !componentFootprints.empty() )
2083 bool matched =
false;
2089 bool isStaleVariantFootprint =
false;
2091 if( usedFootprints.count( footprint ) )
2102 if( component && component->
GetProperties().count( wxT(
"exclude_from_board" ) ) == 0 )
2110 isStaleVariantFootprint =
true;
2121 if( isStaleVariantFootprint )
2124 if( doDelete && !matched && footprint->IsLocked() && !
m_overrideLocks )
2128 msg.Printf(
_(
"Cannot remove unused footprint %s (footprint is locked)." ),
2129 footprint->GetReference() );
2133 msg.Printf(
_(
"Could not remove unused footprint %s (footprint is locked)." ),
2134 footprint->GetReference() );
2142 if( doDelete && !matched )
2146 msg.Printf(
_(
"Remove unused footprint %s." ),
2147 footprint->GetReference() );
2152 msg.Printf(
_(
"Removed unused footprint %s." ),
2153 footprint->GetReference() );
2163 for(
PAD*
pad : footprint->Pads() )
2166 pad->GetNet()->SetIsCurrent(
true );
2174 m_board->GetComponentClassManager().FinishNetlistUpdate();
2175 m_board->SynchronizeComponentClasses( sheetPaths );
2182 if( !net->IsCurrent() )
2184 msg.Printf(
_(
"Removed unused net %s." ),
2193 const std::vector<wxString>& netlistVariants = aNetlist.
GetVariantNames();
2195 if( !netlistVariants.empty() || !
m_board->GetVariantNames().empty() )
2199 auto findBoardVariantName =
2200 [&](
const wxString& aVariantName ) -> wxString
2202 for(
const wxString&
name :
m_board->GetVariantNames() )
2204 if(
name.CmpNoCase( aVariantName ) == 0 )
2208 return wxEmptyString;
2211 std::vector<wxString> updatedVariantNames;
2212 updatedVariantNames.reserve( netlistVariants.size() );
2214 for(
const wxString& variantName : netlistVariants )
2216 wxString actualName = findBoardVariantName( variantName );
2218 if( actualName.IsEmpty() )
2220 m_board->AddVariant( variantName );
2221 actualName = findBoardVariantName( variantName );
2223 if( !actualName.IsEmpty() )
2225 msg.Printf(
_(
"Added variant '%s'." ), actualName );
2230 if( actualName.IsEmpty() )
2235 wxString oldDescription =
m_board->GetVariantDescription( actualName );
2237 if( newDescription != oldDescription )
2239 m_board->SetVariantDescription( actualName, newDescription );
2240 msg.Printf(
_(
"Updated description for variant '%s'." ), actualName );
2244 updatedVariantNames.push_back( actualName );
2247 std::vector<wxString> variantsToRemove;
2249 for(
const wxString& existingName :
m_board->GetVariantNames() )
2253 for(
const wxString& variantName : netlistVariants )
2255 if( existingName.CmpNoCase( variantName ) == 0 )
2263 variantsToRemove.push_back( existingName );
2266 for(
const wxString& variantName : variantsToRemove )
2268 m_board->DeleteVariant( variantName );
2269 msg.Printf(
_(
"Removed variant '%s'." ), variantName );
2273 if( !updatedVariantNames.empty() )
2274 m_board->SetVariantNames( updatedVariantNames );
2284 m_board->SynchronizeNetsAndNetClasses(
true );
2295 for(
const std::pair<const wxString, NETINFO_ITEM*>& addedNet :
m_addedNets )
2296 delete addedNet.second;
constexpr EDA_IU_SCALE pcbIUScale
wxString GetNetname() const
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
std::map< PAD *, wxString > m_padNets
bool m_deleteUnusedFootprints
void cacheNetname(PAD *aPad, const wxString &aNetname)
bool UpdateNetlist(NETLIST &aNetlist)
Update the board's components according to the new netlist.
wxString getNetname(PAD *aPad)
wxString getPinFunction(PAD *aPad)
std::vector< FOOTPRINT * > m_addedFootprints
std::map< wxString, wxString > m_oldToNewNets
bool updateFootprintGroup(FOOTPRINT *aPcbFootprint, COMPONENT *aNetlistComponent)
bool updateFootprintParameters(FOOTPRINT *aPcbFootprint, COMPONENT *aNetlistComponent)
std::map< wxString, NETINFO_ITEM * > m_addedNets
bool testConnectivity(NETLIST &aNetlist, std::map< COMPONENT *, FOOTPRINT * > &aFootprintMap)
bool updateCopperZoneNets(NETLIST &aNetlist)
void cachePinFunction(PAD *aPad, const wxString &aPinFunction)
bool updateGroups(NETLIST &aNetlist)
BOARD_NETLIST_UPDATER(PCB_EDIT_FRAME *aFrame, BOARD *aBoard)
bool updateComponentClass(FOOTPRINT *aFootprint, COMPONENT *aNewComponent)
bool updateComponentPadConnections(FOOTPRINT *aFootprint, COMPONENT *aNewComponent)
VECTOR2I estimateFootprintInsertionPosition()
std::map< PAD *, wxString > m_padPinFunctions
void applyComponentVariants(COMPONENT *aComponent, const std::vector< FOOTPRINT * > &aFootprints, const LIB_ID &aBaseFpid)
std::map< ZONE *, std::vector< PAD * > > m_zoneConnectionsCache
FOOTPRINT * replaceFootprint(NETLIST &aNetlist, FOOTPRINT *aFootprint, COMPONENT *aNewComponent)
void cacheCopperZoneConnections()
bool updateComponentUnits(FOOTPRINT *aFootprint, COMPONENT *aNewComponent)
FOOTPRINT * addNewFootprint(COMPONENT *aComponent)
Information pertinent to a Pcbnew printed circuit board.
constexpr size_type GetWidth() const
constexpr Vec Centre() const
constexpr size_type GetHeight() const
constexpr coord_type GetBottom() const
static wxString GetFullClassNameForConstituents(const std::unordered_set< wxString > &classNames)
Gets the full effective class name for the given set of constituent classes.
A lightweight representation of a component class.
const wxString & GetName() const
Fetches the full name of this component class.
Used to store the component pin name to net name (and pin function) associations stored in a netlist.
const wxString & GetNetName() const
const wxString & GetPinFunction() const
const wxString & GetPinName() const
const wxString & GetPinType() const
Store all of the related component information found in a netlist.
const std::vector< UNIT_INFO > & GetUnitInfo() const
const wxString & GetHumanReadablePath() const
const COMPONENT_NET & GetNet(unsigned aIndex) const
const KIID_PATH & GetPath() const
const wxString & GetReference() const
const wxString & GetValue() const
const nlohmann::ordered_map< wxString, wxString > & GetFields() const
const std::map< wxString, wxString > & GetProperties() const
const CASE_INSENSITIVE_MAP< COMPONENT_VARIANT > & GetVariants() const
NETLIST_GROUP * GetGroup() const
const std::vector< KIID > & GetKIIDs() const
bool GetDuplicatePadNumbersAreJumpers() const
const LIB_ID & GetFPID() const
unsigned GetNetCount() const
std::unordered_set< wxString > & GetComponentClassNames()
std::vector< std::set< wxString > > & JumperPadGroups()
void RemoveItem(EDA_ITEM *aItem)
Remove item from group.
void AddItem(EDA_ITEM *aItem)
Add item to group.
void SetName(const wxString &aName)
virtual EDA_GROUP * GetParentGroup() const
virtual void SetParent(EDA_ITEM *aParent)
virtual void SetVisible(bool aVisible)
virtual void SetText(const wxString &aText)
wxString AsString() const
A logical library item identifier and consists of various portions much like a URI.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
wxString GetUniStringLibId() const
Handle the data for a net.
void SetIsCurrent(bool isCurrent)
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
const std::vector< wxString > & GetVariantNames() const
unsigned GetCount() const
COMPONENT * GetComponentByPath(const KIID_PATH &aPath)
Return a COMPONENT by aPath.
COMPONENT * GetComponentByReference(const wxString &aReference)
Return a COMPONENT by aReference.
NETLIST_GROUP * GetGroupByUuid(const KIID &aUuid)
Return a NETLIST_GROUP by aUuid.
COMPONENT * GetComponent(unsigned aIndex)
Return the COMPONENT at aIndex.
wxString GetVariantDescription(const wxString &aVariantName) const
static REPORTER & GetInstance()
const wxString & GetPinFunction() const
The main frame for Pcbnew.
void SetName(const wxString &aName)
A set of BOARD_ITEMs (i.e., without duplicates).
EDA_ITEM * AsEdaItem() override
void StyleFromSettings(const BOARD_DESIGN_SETTINGS &settings, bool aCheckSide) override
virtual void SetPosition(const VECTOR2I &aPos) override
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
Handle a list of polygons defining a copper zone.
KICOMMON_API wxString MessageTextFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A helper to convert the double length aValue to a string in inches, millimeters, or unscaled units.
Class to handle a set of BOARD_ITEMs.
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
wxString UnescapeString(const wxString &aSource)
bool m_excludedFromPosFiles
bool m_hasExcludedFromBOM
bool m_hasExcludedFromPosFiles
nlohmann::ordered_map< wxString, wxString > m_fields
@ 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)
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
VECTOR2< int32_t > VECTOR2I