54#include <api/schematic/schematic_rules.pb.h>
86 m_netChains = std::make_unique<SCH_CONNECTIVITY::NETCHAIN_MANAGER>(
this );
111 if( !symbol || aProperty->
Name() !=
_HKI(
"Text" ) )
117 wxString newValue = aItem->
Get<wxString>( aProperty );
121 symbol->
SetRef( &sheetPath, newValue );
129 wxString ref = symbol->
GetRef( &sheetPath );
135 std::vector<SCH_SYMBOL*> otherUnits;
141 switch( field->
GetId() )
148 aCommit->
Modify( otherUnit, sheet.LastScreen() );
150 otherUnit->GetField( field->
GetId() )->SetText( newValue );
206 if(
project.m_ErcSettings && !
project.m_ErcSettings->m_ErcExclusionsLegacy.empty() )
211 project.m_ErcSettings =
nullptr;
214 delete project.m_SchematicSettings;
215 project.m_SchematicSettings =
nullptr;
227 project.m_SchematicSettings->LoadFromFile();
228 project.m_SchematicSettings->m_NgspiceSettings->LoadFromFile();
229 project.m_ErcSettings->LoadFromFile();
241 std::shared_ptr<REFDES_TRACKER> refdesTracker =
m_project->GetProjectFile().m_SchematicSettings->m_refDesTracker;
250 refdesTracker->Insert( ref.GetCanonicalRef(
false ).ToStdString() );
266 return std::any_of( references.
begin(), references.
end(),
269 return ref.GetCanonicalRef( true ) == aRef.GetCanonicalRef( true );
324 rootSheetPath.push_back( rootSheet );
325 rootSheetPath.SetPageNumber( wxT(
"1" ) );
350 if( aResetConnectionGraph )
364 m_variantNames.insert( variantNames.begin(), variantNames.end() );
371 for(
const auto& [
name, description] :
Settings().m_VariantDescriptions )
379 wxCHECK_RET( !aSheets.empty(), wxS(
"Cannot set empty top-level sheets!" ) );
385 std::vector<SCH_SHEET*> validSheets;
386 validSheets.reserve( aSheets.size() );
391 if( sheet && sheet->m_Uuid !=
niluuid )
392 validSheets.push_back( sheet );
395 if( validSheets.empty() )
398 if( !wasAlreadySetting )
407 std::set<SCH_SHEET*> desiredSheets( validSheets.begin(), validSheets.end() );
415 if( sheet && !desiredSheets.contains( sheet ) )
446 wxCHECK_RET( aContent.connectionGraph && aContent.connectionGraph->m_ownedNetChains,
447 wxS(
"AdoptContent requires a staged graph with its own netchain manager" ) );
454 wxCHECK_RET( !aContent.screen || aContent.topLevelSheets.empty(),
455 wxS(
"AdoptContent cannot replace both the screen and the top level sheets" ) );
459 wxCHECK_RET( !aContent.screen || target !=
m_rootSheet,
460 wxS(
"AdoptContent cannot replace the virtual root screen" ) );
464 wxCHECK_RET( aContent.topLevelSheets.empty() || target ==
m_rootSheet,
465 wxS(
"AdoptContent can only replace the top level sheets through the virtual root" ) );
469 if( aContent.screen )
473 aContent.screen->m_uuid = target->
m_Uuid;
474 aContent.screen->IncRefCount();
475 outgoingScreen = std::exchange( target->
m_screen, aContent.screen.release() );
479 screen->m_rtree = std::move( aContent.screenItems );
481 if( aContent.screenLibSymbols )
482 screen->m_libSymbols.swap( aContent.screenLibSymbols->m_libSymbols );
484 --screen->m_modification_sync;
485 screen->BumpConnectivityRevision();
488 for( std::unique_ptr<SCH_ITEM>& item : aContent.itemOwners )
492 std::vector<SCH_SHEET*> outgoingTopLevelSheets;
494 if( !aContent.topLevelSheets.empty() )
505 if( aContent.currentSheet )
513 std::unique_ptr<SCH_CONNECTIVITY::NETCHAIN_MANAGER> outgoingNetChains;
515 if( aContent.preserveNetChains )
525 for(
SCH_SHEET* sheet : outgoingTopLevelSheets )
533 delete outgoingScreen;
536 if( aContent.embeddedFiles )
539 Settings().m_SchDrawingSheetFileName.swap( aContent.drawingSheetFileName );
550 for(
SCH_ITEM* item : screen->Items() )
556 for( std::unique_ptr<SCH_PIN>&
pin : symbol->GetRawPins() )
567 delete outgoingGraph;
605 auto add = [&](
const wxString& aVar )
608 aVars->push_back( aVar );
613 add( wxT(
"SHEETPATH" ) );
614 add( wxT(
"SHEETNAME" ) );
615 add( wxT(
"FILENAME" ) );
616 add( wxT(
"FILEPATH" ) );
617 add( wxT(
"PROJECTNAME" ) );
618 add( wxT(
"VARIANT" ) );
619 add( wxT(
"VARIANT_DESC" ) );
624 for( std::pair<wxString, wxString> entry :
m_project->GetTextVars() )
631 wxCHECK( aSheetPath,
false );
633 if( token->IsSameAs( wxT(
"#" ) ) )
638 else if( token->IsSameAs( wxT(
"##" ) ) )
643 i += sheet->CountSheets();
645 *token = wxString::Format(
"%i", i );
648 else if( token->IsSameAs( wxT(
"SHEETPATH" ) ) )
653 else if( token->IsSameAs( wxT(
"SHEETNAME" ) ) )
658 else if( token->IsSameAs( wxT(
"FILENAME" ) ) )
661 *token = fn.GetFullName();
664 else if( token->IsSameAs( wxT(
"FILEPATH" ) ) )
667 *token = fn.GetFullPath();
670 else if( token->IsSameAs( wxT(
"PROJECTNAME" ) ) )
675 else if( token->IsSameAs( wxT(
"VARIANTNAME" ) ) || token->IsSameAs( wxT(
"VARIANT" ) ) )
680 else if( token->IsSameAs( wxT(
"VARIANT_DESC" ) ) )
693 if(
m_project->TextVarResolver( token ) )
705 return wxString( wxEmptyString );
710 return wxString( wxEmptyString );
719 return defaultSettings;
722 return *
m_project->GetProjectFile().m_SchematicSettings;
729 return *
m_project->GetProjectFile().m_ErcSettings;
753 if( !inserted && !comment.empty() && it->GetComment().empty() )
765 using GROUP_ANCHOR = std::variant<KIID, std::pair<int, int>>;
766 using GROUP_KEY = std::tuple<int, KIID_PATH, GROUP_ANCHOR>;
767 std::map<GROUP_KEY, SCH_MARKER*> groupMarkers;
770 std::optional<NC_GROUPS> ncGroups;
771 std::optional<std::map<GROUP_KEY, KIID>> ncFlagGroups;
772 std::optional<std::map<GROUP_KEY, KIID>> hierarchyGroups;
773 std::optional<std::vector<SCH_CONNECTIVITY::LABEL_WIRE_CONFLICT>> labelWireGroups;
774 std::optional<std::vector<SCH_CONNECTIVITY::FOUR_WAY_JUNCTION>> fourWayGroups;
775 const auto groupKey = [&](
const SCH_MARKER& aMarker ) -> std::optional<GROUP_KEY>
777 const auto error = std::static_pointer_cast<ERC_ITEM>( aMarker.GetRCItem() );
780 && !error->MainItemHasSheetPath() && !error->AuxItemHasSheetPath();
788 if( !
ADVANCED_CFG::GetCfg().m_ConnectivityEngine || !groupedCodes.contains( error->GetErrorCode() )
789 || !error->IsSheetSpecific() )
796 if( error->MainItemHasSheetPath() || error->AuxItemHasSheetPath() )
802 const KIID_PATH&
path = error->GetSpecificSheetPath().PathRef();
803 const VECTOR2I position = aMarker.GetPosition();
804 const auto group = std::lower_bound( fourWayGroups->begin(), fourWayGroups->end(),
805 std::tie(
path, position.
x, position.
y ),
806 [](
const auto& junction,
const auto&
location )
808 return std::tie( junction.sheet, junction.position.x, junction.position.y ) < location;
814 for(
const KIID&
id : error->GetIDs() )
816 if( !std::binary_search(
group->equivalentItems.begin(),
group->equivalentItems.end(),
id ) )
825 if( !
main ||
main->GetPosition() != aMarker.GetPosition() )
834 if(
static_cast<const SCH_PIN*
>(
main )->GetParentSymbol()->IsPower() )
838 const KIID_PATH&
path = error->GetSpecificSheetPath().PathRef();
848 || error->MainItemHasSheetPath() || error->AuxItemHasSheetPath() )
851 if( !labelWireGroups )
854 const auto group = std::find_if( labelWireGroups->begin(), labelWireGroups->end(),
855 [&](
const auto& conflict )
857 return conflict.sheet == path && conflict.position == aMarker.GetPosition();
860 if(
group == labelWireGroups->end() )
863 for(
const KIID&
id : error->GetIDs() )
865 if(
id !=
main->m_Uuid && !std::binary_search(
group->wires.begin(),
group->wires.end(),
id ) )
874 if( !error->MainItemHasSheetPath() || error->AuxItemHasSheetPath()
875 || error->GetMainItemSheetPath().PathRef() !=
path )
878 if( !hierarchyGroups )
880 hierarchyGroups.emplace();
882 for(
const auto& diagnostic :
m_connectivity->Engine().HierarchyErrors() )
884 for(
const KIID&
id : diagnostic.equivalentItems )
892 if( found == hierarchyGroups->end() )
905 ncGroups->emplace( std::make_pair(
group.sheet,
group.position ), std::move(
group ) );
908 const auto found = ncGroups->find( {
path, aMarker.GetPosition() } );
910 if( found == ncGroups->end() )
913 const auto&
group = found->second;
914 const auto isPin = [&](
const KIID& id )
916 return std::binary_search(
group.pins.begin(),
group.pins.end(),
id );
919 if( !isPin( error->GetMainItemID() ) )
922 for(
const KIID&
id : error->GetIDs() )
928 || ( !isPin(
id ) && !std::binary_search(
group.others.begin(),
group.others.end(),
id ) ) )
932 return GROUP_KEY{ error->GetErrorCode(),
path,
group.pins.front() };
938 if( !error->MainItemHasSheetPath() || error->AuxItemHasSheetPath()
939 || error->GetMainItemSheetPath().PathRef() !=
path )
944 for(
const KIID&
id : error->GetIDs() )
952 const auto& islandOf =
m_connectivity->Published().Auxiliary().IslandOf();
953 const auto flagIsland = islandOf.find( {
flag, *instance } );
955 if( flagIsland == islandOf.end() )
960 ncFlagGroups.emplace();
962 for(
const auto& diagnostic :
m_connectivity->Engine().NoConnectFlagErrors() )
964 const auto inst =
m_connectivity->Keys().FindInstance( diagnostic.sheet );
965 const auto record = inst ? islandOf.find( { diagnostic.flag, *inst } ) : islandOf.end();
967 if( record == islandOf.end() )
971 ncFlagGroups->emplace( GROUP_KEY{ code, diagnostic.sheet, record->second.anchor },
976 const auto group = ncFlagGroups->find( { error->GetErrorCode(),
path, flagIsland->second.anchor } );
978 if(
group == ncFlagGroups->end() )
982 const auto flagRow = rows.find( {
flag, *instance } );
984 if( flagRow == rows.end() )
987 for(
const KIID&
id : error->GetIDs() )
993 const auto row = rows.find( { id, *instance } );
996 || row->second.component != flagRow->second.component
1001 return GROUP_KEY{ error->GetErrorCode(),
path,
group->second };
1004 const auto& islands =
m_connectivity->Published().Auxiliary().IslandOf();
1005 std::optional<GROUP_KEY> key;
1007 for(
const KIID&
id : error->GetIDs() )
1012 const auto island = islands.find( { id, *instance } );
1015 || ( key && std::get<2>( *key ) != GROUP_ANCHOR{ island->second.anchor } ) )
1016 return std::nullopt;
1018 key = GROUP_KEY{ error->GetErrorCode(),
path, island->second.anchor };
1024 std::set<ERC_EXCLUSION, ERC_EXCLUSION_COMPARE> legacyPathlessExclusions;
1025 std::optional<std::vector<SCH_CONNECTIVITY::OFF_GRID_ENDPOINT>> offGridEndpoints;
1026 const auto findPathless = [&](
const ERC_EXCLUSION& aLookup )
1028 auto legacy = aLookup.ToProto();
1029 legacy.mutable_marker()->clear_sheet_specific_path();
1030 legacy.mutable_marker()->clear_main_item_sheet_path();
1031 legacy.mutable_marker()->clear_aux_item_sheet_path();
1035 legacyPathlessExclusions.insert( *found );
1048 const auto error = std::static_pointer_cast<ERC_ITEM>( marker->
GetRCItem() );
1051 && error->GetSpecificSheetPath().PathRef() == sheet.PathRef() )
1054 const bool hasMain = error->MainItemHasSheetPath();
1055 const bool hasAux = error->AuxItemHasSheetPath();
1056 const bool mainHere = hasMain && error->GetMainItemSheetPath().PathRef() == sheet.PathRef();
1057 const bool auxHere = hasAux && error->GetAuxItemSheetPath().PathRef() == sheet.PathRef();
1059 switch( error->GetErrorCode() )
1062 if( engine && !hasMain && !hasAux && sheet.Last()->IsTopLevelSheet() )
1068 it = findPathless( lookup );
1078 if( !marker->
IsExcluded() && mainHere && !hasAux )
1081 auto previous = lookup.
ToProto();
1082 previous.mutable_marker()->clear_main_item_sheet_path();
1097 if( !marker->
IsExcluded() && mainHere && !hasAux )
1098 it = findPathless( lookup );
1100 if( it == settings.
m_ErcExclusions.end() && engine && mainHere && !hasAux
1103 if( !offGridEndpoints )
1109 for(
const auto& endpoint : *offGridEndpoints )
1111 if( endpoint.sheet != sheet.PathRef() || endpoint.item != error->GetMainItemID()
1115 for(
const auto& [
pin, position] : endpoint.equivalentPins )
1118 alternate->SetItems( std::vector<KIID>{
pin } );
1119 alternate->SetSheetSpecificPath( sheet );
1120 alternate->SetItemsSheetPaths( sheet );
1121 SCH_MARKER witness( std::move( alternate ), position );
1126 it = findPathless( candidate );
1140 if( !marker->
IsExcluded() && mainHere && auxHere )
1141 it = findPathless( lookup );
1147 if( hasMain && auxHere )
1148 it = findPathless( lookup );
1161 if( !legacyPathlessExclusions.contains( *it ) )
1166 if(
const auto key = groupKey( *marker ) )
1167 groupMarkers.emplace( *key, marker );
1172 for(
const ERC_EXCLUSION& exclusion : legacyPathlessExclusions )
1175 std::vector<SCH_MARKER*> newMarkers;
1184 if(
const auto key = groupKey( *marker ) )
1186 const auto current = groupMarkers.find( *key );
1187 const auto itemCount = [](
const SCH_MARKER& aMarker )
1189 const auto ids = aMarker.GetRCItem()->GetIDs();
1190 return std::count_if( ids.begin(), ids.end(), [](
const KIID&
id ) { return id != niluuid; } );
1193 if( current != groupMarkers.end()
1194 && itemCount( *current->second ) == itemCount( *marker ) )
1196 current->second->SetExcluded(
true, exclusion.
GetComment() );
1197 groupMarkers.erase( current );
1204 newMarkers.push_back( marker );
1222 const auto& alias = *it;
1224 if( alias && alias->GetName() == aLabel )
1237 auto sameDefinition = [&](
const std::shared_ptr<BUS_ALIAS>& candidate ) ->
bool
1239 return candidate && candidate->GetName() == aAlias->GetName() && candidate->Members() == aAlias->Members();
1245 std::rotate( it, std::next( it ),
m_busAliases.end() );
1255 std::vector<std::shared_ptr<BUS_ALIAS>> aliases;
1257 for(
const std::shared_ptr<BUS_ALIAS>& alias : aAliases )
1262 std::shared_ptr<BUS_ALIAS> clone = alias->Clone();
1264 auto sameDefinition = [&](
const std::shared_ptr<BUS_ALIAS>& candidate ) ->
bool
1266 return candidate && candidate->GetName() == clone->GetName() && candidate->Members() == clone->Members();
1269 auto it = std::find_if( aliases.begin(), aliases.end(), sameDefinition );
1271 if( it != aliases.end() )
1272 std::rotate( it, std::next( it ), aliases.end() );
1274 aliases.push_back( clone );
1281 m_project->GetProjectFile().m_BusAliasesDefined =
true;
1298 const auto& projectAliases =
m_project->GetProjectFile().m_BusAliases;
1300 for(
const auto& alias : projectAliases )
1302 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>();
1304 busAlias->SetName( alias.first );
1305 busAlias->SetMembers( alias.second );
1317 auto& projectAliases =
m_project->GetProjectFile().m_BusAliases;
1319 projectAliases.clear();
1321 for(
const std::shared_ptr<BUS_ALIAS>& alias :
m_busAliases )
1326 projectAliases.insert_or_assign( alias->GetName(), alias->Members() );
1333 std::set<wxString> names;
1340 if( std::ranges::all_of(
group.instances, [](
const auto& net ) { return net.Items().empty(); } ) )
1343 const auto& net =
group.instances.front();
1348 names.insert(
group.name );
1362 names.insert( key.Name );
1387 wxString ref = token->BeforeFirst(
':', &remainder );
1393 if(
path.size() > 1 )
1402 wxString variantName;
1403 wxString fieldName = remainder;
1404 int colonPos = remainder.Find(
':' );
1406 if( colonPos != wxNOT_FOUND )
1408 fieldName = remainder.Left( colonPos );
1409 variantName = remainder.Mid( colonPos + 1 );
1421 if( refSymbol->
ResolveTextVar( &sheetPath, &fieldName, variantName, aDepth + 1 ) )
1423 *token = std::move( fieldName );
1428 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ),
1429 refSymbol->
GetRef( &sheetPath,
false ),
1441 if( refSheet->
ResolveTextVar( &sheetPath, &remainder, aDepth + 1 ) )
1443 *token = std::move( remainder );
1448 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ),
1466 for(
int ii = 0; ii < (int) refs.
GetCount(); ii++ )
1472 if( symbolRef == ref )
1480 if( symbolRef.StartsWith( ref ) && symbolRef.Length() == ref.Length() + 1 )
1482 wxChar lastChar = symbolRef.Last();
1483 if( lastChar >=
'A' && lastChar <=
'Z' )
1494 if( foundSymbol->
ResolveTextVar( &foundPath, &fieldName, variantName, aDepth + 1 ) )
1496 *token = std::move( fieldName );
1501 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ),
1502 foundSymbol->
GetRef( &foundPath,
false ),
1510 *token = wxString::Format( wxT(
"<Unresolved: %s>" ), ref );
1515 *token = wxString::Format( wxT(
"<Unknown reference: %s>" ), ref );
1522 std::map<int, wxString> namesMap;
1526 if( sheet.size() == 1 )
1527 namesMap[sheet.GetVirtualPageNumber()] =
_(
"<root sheet>" );
1529 namesMap[sheet.GetVirtualPageNumber()] = sheet.Last()->GetName();
1538 std::map<int, wxString> pagesMap;
1541 pagesMap[sheet.GetVirtualPageNumber()] = sheet.GetPageNumber();
1550 size_t sourceLen = aSource.length();
1552 for(
size_t i = 0; i < sourceLen; ++i )
1556 if( aSource[i] ==
'\\' && i + 2 < sourceLen && aSource[i + 2] ==
'{' &&
1557 ( aSource[i + 1] ==
'$' || aSource[i + 1] ==
'@' ) )
1560 newbuf.append( aSource[i] );
1561 newbuf.append( aSource[i + 1] );
1562 newbuf.append( aSource[i + 2] );
1567 for( i = i + 1; i < sourceLen && braceDepth > 0; ++i )
1569 if( aSource[i] ==
'{' )
1571 else if( aSource[i] ==
'}' )
1574 newbuf.append( aSource[i] );
1580 if( aSource[i] ==
'$' && i + 1 < sourceLen && aSource[i + 1] ==
'{' )
1583 bool isCrossRef =
false;
1586 for( i = i + 2; i < sourceLen; ++i )
1588 if( aSource[i] ==
'{' && ( aSource[i - 1] ==
'_' || aSource[i - 1] ==
'^' || aSource[i - 1] ==
'~' ) )
1593 if( aSource[i] ==
'}' )
1601 if( aSource[i] ==
':' )
1604 token.append( aSource[i] );
1610 wxString ref = token.BeforeFirst(
':', &remainder );
1615 for(
size_t jj = 0; jj < references.
GetCount(); jj++ )
1617 SCH_SYMBOL* refSymbol = references[jj].GetSymbol();
1619 if( ref == refSymbol->
GetRef( &references[jj].GetSheetPath(),
true ) )
1624 token =
path.AsString() + wxS(
":" ) + remainder;
1630 newbuf.append( wxS(
"${" ) + token + wxS(
"}" ) );
1634 newbuf.append( aSource[i] );
1645 size_t sourceLen = aSource.length();
1647 for(
size_t i = 0; i < sourceLen; ++i )
1651 if( aSource[i] ==
'\\' && i + 2 < sourceLen && aSource[i + 2] ==
'{' &&
1652 ( aSource[i + 1] ==
'$' || aSource[i + 1] ==
'@' ) )
1655 newbuf.append( aSource[i] );
1656 newbuf.append( aSource[i + 1] );
1657 newbuf.append( aSource[i + 2] );
1662 for( i = i + 1; i < sourceLen && braceDepth > 0; ++i )
1664 if( aSource[i] ==
'{' )
1666 else if( aSource[i] ==
'}' )
1669 newbuf.append( aSource[i] );
1675 if( aSource[i] ==
'$' && i + 1 < sourceLen && aSource[i + 1] ==
'{' )
1678 bool isCrossRef =
false;
1680 for( i = i + 2; i < sourceLen; ++i )
1682 if( aSource[i] ==
'}' )
1685 if( aSource[i] ==
':' )
1688 token.append( aSource[i] );
1694 wxString ref = token.BeforeFirst(
':', &remainder );
1700 if(
path.size() > 1 )
1709 token = refSymbol->
GetRef( &sheetPath,
true ) + wxS(
":" ) + remainder;
1713 newbuf.append( wxS(
"${" ) + token + wxS(
"}" ) );
1717 newbuf.append( aSource[i] );
1740 size_t startIdx = 0;
1746 return wxEmptyString;
1752 wxString topFileName;
1757 if( topFileName.IsEmpty() )
1760 wxFileName rootFn( topFileName );
1761 wxString filename = rootFn.GetName();
1787 sheet_count += topSheet->CountSheets();
1796 int sheet_number = 1;
1800 for( screen = s_list.
GetFirst(); screen !=
nullptr; screen = s_list.
GetNext() )
1818 if( sheet.Path() == current_sheetpath )
1824 for( screen = s_list.
GetFirst(); screen !=
nullptr; screen = s_list.
GetNext() )
1835 std::map<wxString, std::set<int>>& pageRefsMap =
GetPageRefsMap();
1837 pageRefsMap.clear();
1846 pageRefsMap[resolvedLabel].insert( sheet.GetVirtualPageNumber() );
1855 std::vector<SCH_GLOBALLABEL*> currentSheetGlobalLabels;
1858 currentSheetGlobalLabels.push_back(
static_cast<SCH_GLOBALLABEL*
>( item ) );
1862 std::vector<SCH_FIELD>& fields = globalLabel->GetFields();
1864 fields[0].SetVisible( show );
1868 if( fields.size() == 1 && fields[0].GetTextPos() == globalLabel->GetPosition() )
1873 for(
SCH_FIELD& field : globalLabel->GetFields() )
1874 field.ClearBoundingBoxCache();
1876 globalLabel->ClearBoundingBoxCache();
1892 auto it = screen->GetLibSymbols().find( aSchLibSymbolName );
1894 if( it != screen->GetLibSymbols().end() && it->second && it->second != &aSource )
1896 it->second->SetPinMaps( aSource.
GetPinMaps() );
1919 aCommit->
Modify( symbol, screen );
1930 wxString spiceNetName( aNetName );
1932 spiceNetName.MakeLower();
1934 if( spiceNetName == wxS(
"gnd" ) || spiceNetName == wxS(
"0" ) )
1935 return wxEmptyString;
1955 std::deque<EDA_ITEM*> allItems;
1957 for(
SCH_ITEM* item : screen->Items() )
1958 allItems.push_back( item );
1961 for(
const VECTOR2I& point : screen->GetNeededJunctions( allItems ) )
1966 screen->Append( junction );
1969 for(
SCH_LINE* wire : screen->GetBusesAndWires( point,
true ) )
1972 screen->Append( newSegment );
1975 aOnSplit( wire, newSegment );
2046 exclusion.
ToProto().marker().error_type() ) != aErrorCode )
2064 for(
unsigned i = 0; i < sheetList.size(); i++ )
2118 for(
auto& [
name, libSym] : screen->GetLibSymbols() )
2119 aFunction( libSym->GetEmbeddedFiles() );
2126 std::set<KIFONT::OUTLINE_FONT*>
fonts;
2132 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
2144 if( outline->GetEmbeddingPermission() == EMBEDDING_PERMISSION::EDITABLE
2145 || outline->GetEmbeddingPermission() == EMBEDDING_PERMISSION::INSTALLABLE )
2147 fonts.insert( outline );
2167 wxLogTrace(
"EMBED",
"Failed to add font file: %s", font->GetFileName() );
2178 std::set<const SCH_SCREEN*> retv;
2191 const std::vector<SCH_SYMBOL_INSTANCE> symbolInstances = symbol->
GetInstances();
2195 if( !hierarchy.
HasPath( instance.m_Path ) )
2197 retv.insert( screen );
2202 if( retv.count( screen ) )
2219 wxCHECK2( screen,
continue );
2221 if( screen->GetRefCount() > 1 )
2232 std::vector<SCH_LINE*> lines;
2233 std::vector<SCH_JUNCTION*> junctions;
2234 std::vector<SCH_NO_CONNECT*> ncs;
2235 std::vector<SCH_ITEM*> items_to_remove;
2236 std::unordered_set<SCH_LINE*> generatedLines;
2237 std::vector<std::unique_ptr<SCH_LINE>> retiredLines;
2238 bool changed =
true;
2240 if( aScreen ==
nullptr )
2243 auto remove_item = [&](
SCH_ITEM* aItem ) ->
void
2251 if( aItem->IsSelected() && selectionTool )
2260 aScreen->
Remove( aItem );
2265 if( aItem->Type() ==
SCH_LINE_T && generatedLines.erase(
static_cast<SCH_LINE*
>( aItem ) )
2266 && !aCommit->
GetStatus( aItem, aScreen ) )
2269 retiredLines.emplace_back(
static_cast<SCH_LINE*
>( aItem ) );
2282 items_to_remove.push_back( item );
2285 junctions.push_back(
static_cast<SCH_JUNCTION*
>( item ) );
2288 for(
SCH_ITEM* item : items_to_remove )
2289 remove_item( item );
2297 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
2298 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
2304 remove_item( aSecond );
2310 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
2311 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
2317 remove_item( aSecond );
2321 auto minX = [](
const SCH_LINE* l )
2323 return std::min( l->GetStartPoint().x, l->GetEndPoint().x );
2326 auto maxX = [](
const SCH_LINE* l )
2328 return std::max( l->GetStartPoint().x, l->GetEndPoint().x );
2331 auto minY = [](
const SCH_LINE* l )
2333 return std::min( l->GetStartPoint().y, l->GetEndPoint().y );
2336 auto maxY = [](
const SCH_LINE* l )
2338 return std::max( l->GetStartPoint().y, l->GetEndPoint().y );
2351 lines.push_back(
static_cast<SCH_LINE*
>( item ) );
2355 std::sort( lines.begin(), lines.end(),
2358 return minX( a ) < minX( b );
2361 for(
auto it1 = lines.begin(); it1 != lines.end(); ++it1 )
2368 if( firstLine->
IsNull() )
2370 remove_item( firstLine );
2374 int firstRightXEdge = maxX( firstLine );
2377 for( ++it2; it2 != lines.end(); ++it2 )
2380 int secondLeftXEdge = minX( secondLine );
2383 if( secondLeftXEdge > firstRightXEdge )
2387 if( !( std::max( minY( firstLine ), minY( secondLine ) )
2388 <= std::min( maxY( firstLine ), maxY( secondLine ) ) ) )
2406 remove_item( secondLine );
2414 if( mergedLine !=
nullptr )
2416 remove_item( firstLine );
2417 remove_item( secondLine );
2419 if( m_schematicHolder )
2421 m_schematicHolder->AddToScreen( mergedLine, aScreen );
2425 aScreen->Append( mergedLine );
2428 generatedLines.insert( mergedLine );
2429 aCommit->Added( mergedLine, aScreen );
2432 selectionTool->AddItemToSel( mergedLine,
true );
2443 const std::set<SCH_SCREEN*>& aLocalScreens )
2450 if( aLocalScreens.empty() )
2460 std::unordered_set<SCH_SCREEN*> cleanedScreens;
2466 if( cleanedScreens.insert( screen ).second )
2475 wxLogTrace(
"CONN_PROFILE",
"SchematicCleanUp() %0.4f ms", timer.
msecs() );
2477 if(
Settings().m_IntersheetRefsShow )
2491 m_project->GetProjectFile().NetSettings()->ClearAllCaches();
2492 std::unordered_set<SCH_SCREEN*> screens;
2497 screens.insert( screen );
2505 aChangedItemHandler ? *aChangedItemHandler
2506 : std::function<
void(
SCH_ITEM* )>() );
2518 std::function<
void(
SCH_ITEM* )>* aChangedItemHandler,
2524 aCommit = &localCommit;
2535 if( !localCommit.
Empty() )
2542 std::unordered_set<SCH_SCREEN*> screens;
2545 screens.insert(
path.LastScreen() );
2550 if( !localCommit.
Empty() )
2553 m_connectivity->Recalculate( *
this,
false, aChangedItemHandler ? *aChangedItemHandler
2554 : std::function<
void(
SCH_ITEM* )>() );
2561 if( !localCommit.
Empty() )
2577 std::set<SCH_ITEM*> changed_items;
2578 std::set<VECTOR2I> pts;
2579 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> item_paths;
2582 std::unordered_set<SCH_SCREEN*> changed_screens;
2583 std::set<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> changed_rule_areas;
2584 std::vector<CHANGED_ITEM> changed_connectable_items;
2587 auto addItemToChangeSet =
2588 [&changed_items, &pts, &item_paths]( CHANGED_ITEM itemData )
2590 std::vector<SCH_SHEET_PATH>& paths = itemData.screen->GetClientSheetPaths();
2592 std::vector<VECTOR2I> tmp_pts = itemData.item->GetConnectionPoints();
2593 pts.insert( tmp_pts.begin(), tmp_pts.end() );
2594 changed_items.insert( itemData.item );
2597 item_paths.insert( std::make_pair(
path, itemData.item ) );
2599 if( !itemData.linked_item || !itemData.linked_item->IsConnectable() )
2602 tmp_pts = itemData.linked_item->GetConnectionPoints();
2603 pts.insert( tmp_pts.begin(), tmp_pts.end() );
2604 changed_items.insert( itemData.linked_item );
2611 changed_items.insert( pins.begin(), pins.end() );
2615 item_paths.insert( std::make_pair(
path, itemData.linked_item ) );
2619 for(
unsigned ii = 0; ii < aLastChangeList->
GetCount(); ++ii )
2637 changed_screens.insert( screen );
2642 changed_rule_areas.insert( { ruleArea, screen } );
2647 changed_connectable_items.push_back( { item, linked_item, screen } );
2653 std::vector<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> forceUpdateRuleAreas =
2656 std::for_each( forceUpdateRuleAreas.begin(), forceUpdateRuleAreas.end(),
2657 [&]( std::pair<SCH_RULE_AREA*, SCH_SCREEN*>& updatedRuleArea )
2659 changed_rule_areas.insert( updatedRuleArea );
2664 std::map<KIID, EDA_ITEM*> itemMap;
2665 list.FillItemMap( itemMap );
2667 auto addPastAndPresentContainedItems =
2672 if( itemMap.contains( pastItem ) )
2673 addItemToChangeSet( {
static_cast<SCH_ITEM*
>( itemMap[pastItem] ),
nullptr, screen } );
2677 addItemToChangeSet( { containedItem,
nullptr, screen } );
2680 for(
const auto& [changedRuleArea, screen] : changed_rule_areas )
2681 addPastAndPresentContainedItems( changedRuleArea, screen );
2684 for( CHANGED_ITEM& changed_item : changed_connectable_items )
2686 addItemToChangeSet( changed_item );
2692 const std::vector<VECTOR2I> labelConnectionPoints = changed_item.item->GetConnectionPoints();
2694 auto candidateRuleAreas = changed_item.screen->Items()
2697 for(
SCH_ITEM* candidateRuleArea : candidateRuleAreas )
2702 addPastAndPresentContainedItems( ruleArea, changed_item.screen );
2712 if( !item->IsConnectable() )
2720 if( item->HitTest( pt ) )
2722 changed_items.insert( item );
2725 item_paths.insert( std::make_pair(
path, item ) );
2728 else if( item->Type() ==
SCH_SYMBOL_T && item->IsConnected( pt ) )
2733 changed_items.insert( pins.begin(), pins.end() );
2738 item_paths.insert( std::make_pair(
path,
pin ) );
2745 wxCHECK2( sheet,
continue );
2747 std::vector<SCH_SHEET_PIN*> sheetPins = sheet->
GetPins();
2748 changed_items.insert( sheetPins.begin(), sheetPins.end() );
2753 item_paths.insert( std::make_pair(
path,
pin ) );
2758 if( item->IsConnected( pt ) )
2760 changed_items.insert( item );
2763 item_paths.insert( std::make_pair(
path, item ) );
2769 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> all_items =
2772 all_items.insert( item_paths.begin(), item_paths.end() );
2778 std::shared_ptr<NET_SETTINGS> netSettings =
m_project->GetProjectFile().NetSettings();
2780 std::set<wxString> affectedNets;
2782 for(
auto& [
path, item] : all_items )
2784 wxCHECK2( item,
continue );
2785 item->SetConnectivityDirty();
2789 affectedNets.insert( conn->
Name() );
2794 for(
const CHANGED_ITEM& changedItem : changed_connectable_items )
2798 const wxString& driverName = label->GetCachedDriverName();
2800 if( !driverName.IsEmpty() )
2801 affectedNets.insert( driverName );
2806 const wxString& driverName = linkedLabel->GetCachedDriverName();
2808 if( !driverName.IsEmpty() )
2809 affectedNets.insert( driverName );
2814 for(
const wxString& netName : affectedNets )
2815 netSettings->ClearCacheForNet( netName );
2817 new_graph.
Recalculate( list,
false, aChangedItemHandler, aProgressReporter );
2821 if( !localCommit.
Empty() )
2862 size_t index =
static_cast<size_t>( aIndex );
2882 if( sheet && sheet->m_Uuid == aUuid )
2911 wxCHECK_RET( aSheet, wxS(
"Cannot add null sheet!" ) );
2912 wxCHECK_RET( aSheet->
GetScreen(), wxS(
"Cannot add virtual root as top-level sheet!" ) );
2945 m_rootSheet->GetScreen()->Remove( aSheet,
false );
2972 wxLogTrace(
traceSchSheetPaths,
"BuildSheetListSortedByPageNumbers: %zu top-level sheets",
2984 wxLogTrace(
traceSchSheetPaths,
" Top-level sheet: '%s' (UUID=%s, isVirtualRoot=%d)", sheet->GetName(),
2985 sheet->m_Uuid.AsString(), sheet->m_Uuid ==
niluuid ? 1 : 0 );
2994 hierarchy.push_back(
path );
3020 sheets.push_back(
path );
3031 wxArrayString variantNames;
3037 variantNames.Add(
name );
3041 return variantNames;
3048 return wxEmptyString;
3058 if(
name.CmpNoCase( aVariantName ) == 0 )
3068 wxString newVariant;
3072 newVariant = aVariantName;
3087 for(
SCH_ITEM* item : screen->Items() )
3088 item->ClearCaches();
3107 if( descriptions.find( aVariantName ) == descriptions.end() )
3108 descriptions[aVariantName] = wxEmptyString;
3134 wxCHECK( !aOldName.IsEmpty() && !aNewName.IsEmpty(), );
3142 if( descriptions.count( aOldName ) )
3144 descriptions[aNewName] = descriptions[aOldName];
3145 descriptions.erase( aOldName );
3162 wxCHECK( !aSourceVariant.IsEmpty() && !aNewVariant.IsEmpty(), );
3170 if( descriptions.count( aSourceVariant ) )
3171 descriptions[aNewVariant] = descriptions[aSourceVariant];
3174 allScreens.
CopyVariant( aSourceVariant, aNewVariant, aCommit );
3181 auto it = descriptions.find( aVariantName );
3183 if( it != descriptions.end() )
3186 return wxEmptyString;
3194 if( aDescription.IsEmpty() )
3195 descriptions.erase( aVariantName );
3197 descriptions[aVariantName] = aDescription;
3207 m_variantNames.insert( variantNames.begin(), variantNames.end() );
3212 for(
const wxString&
name : variantNames )
3214 if( descriptions.find(
name ) == descriptions.end() )
3215 descriptions[
name] = wxEmptyString;
3220 for(
const auto& [
name, description] : descriptions )
3231 wxString projPath =
m_project->GetProjectPath();
3233 if( projPath.IsEmpty() )
3237 if( !projPath.IsSameAs( aProjectPath ) )
3239 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver skipping - project path mismatch: %s vs %s" ), projPath,
3244 if( !projPath.EndsWith( wxFILE_SEP_PATH ) )
3245 projPath += wxFILE_SEP_PATH;
3251 KICAD_FORMAT::FORMAT_MODE mode = KICAD_FORMAT::FORMAT_MODE::NORMAL;
3254 mode = KICAD_FORMAT::FORMAT_MODE::COMPACT_TEXT_PROPERTIES;
3267 if( !sheet || !screen )
3278 wxString absPath = abs.GetFullPath();
3280 if( absPath.IsEmpty() || !absPath.StartsWith( projPath ) )
3283 wxString rel = absPath.Mid( projPath.length() );
3295 aFileData.push_back( std::move( entry ) );
3298 wxS(
"[history] sch saver serialized %zu bytes for '%s' -> '%s'" ),
3299 aFileData.back().content.size(), absPath, rel );
3303 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver serialize failed for '%s': %s" ),
3304 absPath, wxString::FromUTF8( ioe.
What() ) );
KICOMMON_API KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
void SetPageCount(int aPageCount)
void SetPageNumber(const wxString &aPageNumber)
bool IsContentModified() const
void SetVirtualPageNumber(int aPageNumber)
Represent a set of changes (additions, deletions or modifications) of a data model (e....
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
int GetStatus(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Returns status of an item.
bool AutosaveUsesLocalHistory() const
The backup format is the single switch that selects the autosave mechanism: the incremental format re...
Calculate the connectivity of a schematic and generate netlists.
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Update the connection graph for the given list of sheets.
std::set< std::pair< SCH_SHEET_PATH, SCH_ITEM * > > ExtractAffectedItems(const std::set< SCH_ITEM * > &aItems)
For a set of items, this will remove the connected items and their associated data including subgraph...
void SetLastCodes(const CONNECTION_GRAPH *aOther)
void Merge(CONNECTION_GRAPH &aGraph)
Combine the input graph contents into the current graph.
A subgraph is a set of items that are electrically connected on a single sheet.
static PRIORITY GetDriverPriority(SCH_ITEM *aDriver)
Return the priority (higher is more important) of a candidate driver.
const SCH_CONNECTION * GetDriverConnection() const
EDA_ITEM_FLAGS GetEditFlags() const
KICAD_T Type() const
Returns the type of object.
EDA_ITEM * GetParent() const
virtual void SetParent(EDA_ITEM *aParent)
EDA_ITEM_FLAGS GetFlags() const
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
SHAPE_POLY_SET & GetPolyShape()
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
EE_TYPE OfType(KICAD_T aType) const
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
Container for an ERC exclusion, which is a SCH_MARKER plus an optional comment.
static ERC_EXCLUSION FromLegacyStrings(const SCH_SHEET_LIST &aSheetList, const wxString &aMarkerData, const wxString &aComment)
const kiapi::schematic::ErcExclusion & ToProto() const
void SetComment(const wxString &aComment)
static ERC_EXCLUSION FromMarker(const SCH_MARKER &aMarker)
wxString GetComment() const
std::string GetSortKey() const
static ERC_EXCLUSION FromProto(const kiapi::schematic::ErcExclusion &aMessage)
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Container for ERC settings.
std::set< std::pair< wxString, wxString > > m_ErcExclusionsLegacy
std::set< ERC_EXCLUSION, ERC_EXCLUSION_COMPARE > m_ErcExclusions
Class that other classes need to inherit from, in order to be inspectable.
wxAny Get(PROPERTY_BASE *aProperty) const
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
FONT is an abstract base class for both outline and stroke fonts.
virtual bool IsStroke() const
Implement outline font drawing.
A logical library item identifier and consists of various portions much like a URI.
Define a library symbol object.
const PIN_MAP_SET & GetPinMaps() const
Pin-to-pad mapping (issue #2282).
const std::vector< ASSOCIATED_FOOTPRINT > & GetAssociatedFootprints() const
std::shared_ptr< RC_ITEM > GetRCItem() const
void SetExcluded(bool aExcluded, const wxString &aComment=wxEmptyString)
static void ConvertToSpiceMarkup(wxString *aNetName)
Convert an escaped schematic net name to SPICE, preserving literal slashes when mapping ground names.
virtual COMMON_SETTINGS * GetCommonSettings() const
A holder to handle information on schematic or board items.
UNDO_REDO GetPickedItemStatus(unsigned int aIdx) const
EDA_ITEM * GetPickedItemLink(unsigned int aIdx) const
unsigned GetCount() const
BASE_SCREEN * GetScreenForItem(unsigned int aIdx) const
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
A small class to help profiling.
void Stop()
Save the time when this function was called, and set the counter stane to stop.
double msecs(bool aSinceLast=false)
A progress reporter interface for use in multi-threaded environments.
The backing store for a PROJECT, in JSON format.
Container for project specific data.
const wxString & Name() const
static PROPERTY_MANAGER & Instance()
class PROPERTY_LISTENER_SUBSCRIPTION RegisterListener(TYPE_ID aType, PROPERTY_LISTENER aListenerFunc)
Register a listener for the given type and return a move-only subscription that auto-unregisters in i...
virtual void OnSchItemsRemoved(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
virtual void OnSchItemsChanged(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
virtual void OnSchSelectionChanged(SCHEMATIC &aSch)
virtual void OnSchSheetChanged(SCHEMATIC &aSch)
virtual void OnSchItemsAdded(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
These are loaded from Eeschema settings but then overwritten by the project settings.
bool m_IntersheetRefsShow
std::map< wxString, wxString > m_VariantDescriptions
A map of variant names to their descriptions.
void SetCurrentVariant(const wxString &aVariantName)
bool m_settingTopLevelSheets
Re-entry guard to prevent infinite recursion between ensureDefaultTopLevelSheet and RefreshHierarchy ...
std::unique_ptr< SCH_CONNECTIVITY::NETCHAIN_MANAGER > m_netChains
void Reset()
Initialize this schematic to a blank one, unloading anything existing.
std::set< const SCH_SCREEN * > GetSchematicsSharedByMultipleProjects() const
Return a list of schematic files in the current project that contain instance data for multiple proje...
void CreateDefaultScreens()
void SetLegacySymbolInstanceData()
Update the symbol value and footprint instance data for legacy designs.
void OnItemsAdded(std::vector< SCH_ITEM * > &aNewItems)
Must be used if Add() is used using a BULK_x ADD_MODE to generate a change event for listeners.
CONNECTION_GRAPH * m_connectionGraph
Hold and calculate connectivity information of this schematic.
bool IsTopLevelSheet(const SCH_SHEET *aSheet) const
Check if a sheet is a top-level sheet (direct child of virtual root).
void loadBusAliasesFromProject()
void AddTopLevelSheet(SCH_SHEET *aSheet)
Add a new top-level sheet to the schematic.
SCH_SHEET_LIST m_hierarchy
Cache of the entire schematic hierarchy sorted by sheet page number.
void rebuildHierarchyState(bool aResetConnectionGraph)
void ResolveERCExclusionsPostUpdate()
Update markers to match recorded exclusions.
void DeleteVariant(const wxString &aVariantName, SCH_COMMIT *aCommit=nullptr)
Delete all information for aVariantName.
void RecomputeIntersheetRefs()
Update the schematic's page reference map for all global labels, and refresh the labels so that they ...
void CacheExistingAnnotation()
Store all existing annotations in the REFDES_TRACKER.
wxString GetVariantDescription(const wxString &aVariantName) const
Return the description for a variant.
void LoadVariants()
This is a throw away method for variant testing.
SCH_SHEET_LIST BuildSheetListSortedByPageNumbers() const
void RemoveListener(SCHEMATIC_LISTENER *aListener)
Remove the specified listener.
bool HasVariant(const wxString &aVariantName) const
Return true if a variant with this name exists in the schematic (case-insensitively).
bool resolveCrossReference(wxString *aToken, int aDepth) const
bool IsComplexHierarchy() const
Test if the schematic is a complex hierarchy.
void OnSchSheetChanged()
Notify the schematic and its listeners that the current sheet has been changed.
wxString GetFileName() const
Helper to retrieve the filename from the root sheet screen.
SCH_SHEET_PATH * m_currentSheet
The sheet path of the sheet currently being edited or displayed.
std::vector< SCH_SHEET * > m_topLevelSheets
List of top-level sheets (direct children of virtual root)
wxString GetOperatingPoint(const wxString &aNetName, int aPrecision, const wxString &aRange)
void CleanUp(SCH_COMMIT *aCommit, SCH_SCREEN *aScreen=nullptr)
Perform routine schematic cleaning including breaking wire and buses and deleting identical objects s...
bool IsTopLevelSheetUuid(const KIID &aUuid) const
Check if a UUID names one of this schematic's top level sheets.
void OnItemsRemoved(std::vector< SCH_ITEM * > &aRemovedItems)
Must be used if Remove() is used using a BULK_x REMOVE_MODE to generate a change event for listeners.
void AddVariant(const wxString &aVariantName)
void OnSchSelectionChanged()
Notify the schematic and its listeners that the editor selection has changed.
void AdoptContent(SCHEMATIC_CONTENT &&aContent) noexcept
Take a staged schematic over from an importer in one indivisible step.
std::shared_ptr< BUS_ALIAS > GetBusAlias(const wxString &aLabel) const
Return a pointer to a bus alias object for the given label, or null if one doesn't exist.
void CopyVariant(const wxString &aSourceVariant, const wxString &aNewVariant, SCH_COMMIT *aCommit=nullptr)
Copy a variant from aSourceVariant to aNewVariant.
std::vector< SCH_MARKER * > ResolveERCExclusions()
void SaveToHistory(const wxString &aProjectPath, std::vector< HISTORY_FILE_DATA > &aFileData)
Serialize schematic sheets into HISTORY_FILE_DATA for non-blocking history commit.
void EmbedFonts() override
Embed fonts in the schematic.
SCHEMATIC_SETTINGS & Settings() const
SCH_SCREEN * GetCurrentScreen() const
wxString ConvertKIIDsToRefs(const wxString &aSource) const
SCH_ITEM * ResolveItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr, bool aAllowNullptrReturn=false) const
void ensureCurrentSheetIsTopLevel()
void SyncLibSymbolPinMaps(const wxString &aSchLibSymbolName, const LIB_SYMBOL &aSource, SCH_COMMIT *aCommit)
void RecordERCExclusions()
Scan existing markers and record data from any that are Excluded.
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
wxString m_currentVariant
std::map< wxString, std::set< int > > & GetPageRefsMap()
SCH_SHEET_LIST BuildUnorderedSheetList() const
void RenameVariant(const wxString &aOldName, const wxString &aNewName, SCH_COMMIT *aCommit=nullptr)
Rename a variant from aOldName to aNewName.
std::map< wxString, std::set< int > > m_labelToPageRefsMap
Holds a map of labels to the page sequence (virtual page number) that they appear on.
std::set< KIFONT::OUTLINE_FONT * > GetFonts() const override
Get a set of fonts used in the schematic.
SCH_SHEET * GetTopLevelSheet(int aIndex=0) const
bool RemoveTopLevelSheet(SCH_SHEET *aSheet)
Remove a top-level sheet from the schematic.
std::optional< IMPORT_NET_MAP > m_importNetMap
bool Contains(const SCH_REFERENCE &aRef) const
Check if the schematic contains the specified reference.
void ClearUnresolvedERCExclusions(int aErrorCode=-1)
std::vector< ERC_EXCLUSION > m_unresolvedErcExclusions
Exclusions whose saved identity cannot currently be reconstructed as a marker.
SCH_CONNECTIVITY::FACADE & Connectivity() const
wxString ConvertRefsToKIIDs(const wxString &aSource) const
void SetProject(PROJECT *aPrj)
wxString GetCurrentVariant() const
Return the current variant being edited.
void AddListener(SCHEMATIC_LISTENER *aListener)
Add a listener to the schematic to receive calls whenever something on the schematic has been modifie...
void CleanUpConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags, const std::set< SCH_SCREEN * > &aLocalScreens={})
std::map< int, wxString > GetVirtualPageToSheetPagesMap() const
EMBEDDED_FILES * GetEmbeddedFiles() override
CONNECTION_GRAPH * ConnectionGraph() const
SCH_SCREEN * RootScreen() const
Helper to retrieve the screen of the root sheet.
bool ResolveTextVar(const SCH_SHEET_PATH *aSheetPath, wxString *token, int aDepth) const
std::set< wxString > GetNetClassAssignmentCandidates()
Return the set of netname candidates for netclass assignment.
std::vector< std::shared_ptr< BUS_ALIAS > > m_busAliases
void InvokeListeners(Func &&aFunc, Args &&... args)
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
void updateProjectBusAliases()
void SetVariantDescription(const wxString &aVariantName, const wxString &aDescription)
Set the description for a variant.
void RemoveAllListeners()
Remove all listeners.
void SetTopLevelSheets(const std::vector< SCH_SHEET * > &aSheets)
Replace the top level sheets, rebuilding the hierarchy and connectivity around them.
void RebuildConnectivity(std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr, KIGFX::SCH_VIEW *aSchView=nullptr)
std::unique_ptr< class SCHEMATIC_TEXT_VAR_ADAPTER > m_textVarAdapter
Reactive text-variable dependency adapter.
bool HasProjectBusAliases() const
PROPERTY_LISTENER_SUBSCRIPTION m_fieldListenerSubscription
PROPERTY_MANAGER listener subscription installed in the ctor.
void GetContextualTextVars(wxArrayString *aVars) const
void ensureDefaultTopLevelSheet()
std::map< int, wxString > GetVirtualPageToSheetNamesMap() const
void RecalculateConnections(SCH_COMMIT *aCommit, SCH_CLEANUP_FLAGS aCleanupFlags, TOOL_MANAGER *aToolManager, PROGRESS_REPORTER *aProgressReporter=nullptr, KIGFX::SCH_VIEW *aSchView=nullptr, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PICKED_ITEMS_LIST *aLastChangeList=nullptr, bool aCleanupDone=false)
Generate the connection data for the entire schematic hierarchy.
void AddBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
std::vector< SCH_SHEET * > GetTopLevelSheets() const
Get the list of top-level sheets.
wxArrayString GetVariantNamesForUI() const
Return an array of variant names for using in wxWidgets UI controls.
void RunOnNestedEmbeddedFiles(const std::function< void(EMBEDDED_FILES *)> &aFunction) override
Provide access to nested embedded files, such as symbols in schematics and footprints in boards.
std::unique_ptr< SCH_CONNECTIVITY::FACADE > m_connectivity
SCHEMATIC_HOLDER * m_schematicHolder
What currently "Holds" the schematic, i.e.
wxString GetUniqueFilenameForCurrentSheet()
Get the unique file name for the current sheet.
void SetSheetNumberAndCount()
Set the m_ScreenNumber and m_NumberOfScreens members for screens.
void SetBusAliases(const std::vector< std::shared_ptr< BUS_ALIAS > > &aAliases)
std::vector< SCHEMATIC_LISTENER * > m_listeners
Currently installed listeners.
SCH_SHEET_PATH & CurrentSheet() const
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
int FixupJunctionsAfterImport(const std::function< void(SCH_LINE *, SCH_LINE *)> &aOnSplit={})
Add junctions to this schematic where required.
KIID_PATH NormalizeInstancePath(const KIID_PATH &aPath) const
Strip the leading virtual root from a stored instance path, which SCH_SHEET_PATH::Path() omits but st...
std::map< wxString, double > m_operatingPoints
Simulation operating points for text variable substitution.
ERC_SETTINGS & ErcSettings() const
std::set< wxString > m_variantNames
void OnItemsChanged(std::vector< SCH_ITEM * > &aItems)
Notify the schematic and its listeners that an item on the schematic has been modified in some way.
SCH_SHEET * m_rootSheet
The virtual root sheet (has no screen, contains all top-level sheets)
bool IsInstancePathInProject(const KIID_PATH &aPath) const
Test whether an instance path is rooted in this schematic's top level sheets.
Commit for the schematic and symbol editors.
void RemovedForCleanup(SCH_ITEM *aItem, SCH_SCREEN *aScreen)
Retain the pre-edit state of an item already removed from its screen by cleanup.
void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
wxString Name(bool aIgnoreSheet=false) const
A SCH_IO derivation for loading schematic files using the new s-expression file format.
void FormatSchematicToFormatter(OUTPUTFORMATTER *aOut, SCH_SHEET *aSheet, SCHEMATIC *aSchematic, const std::map< std::string, UTF8 > *aProperties=nullptr)
Serialize a schematic sheet to an OUTPUTFORMATTER without file I/O or Prettify.
Base class for any item which can be embedded within the SCHEMATIC container class,...
virtual bool IsConnectable() const
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
VECTOR2I GetPosition() const override
wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, int aDepth=0) const override
Segment description base class to describe items which have 2 end points (track, wire,...
SCH_LINE * NonGroupAware_BreakAt(const VECTOR2I &aPoint)
This version should only be used when importing files.
bool IsParallel(const SCH_LINE *aLine) const
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
SCH_LINE * MergeOverlap(SCH_SCREEN *aScreen, SCH_LINE *aLine, bool aCheckJunctions)
Check line against aLine to see if it overlaps and merge if it does.
bool IsStrokeEquivalent(const SCH_LINE *aLine)
bool IsEndPoint(const VECTOR2I &aPoint) const override
Test if aPt is an end point of this schematic object.
static SCH_MARKER * FromProto(const kiapi::schematic::ErcMarker &aMsg, const SCH_SHEET_LIST &aSheetList)
VECTOR2I GetPosition() const override
VECTOR2I GetPosition() const override
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
A helper to define a symbol's reference designator in a schematic.
const SCH_SHEET_PATH & GetSheetPath() const
SCH_SYMBOL * GetSymbol() const
const std::unordered_set< SCH_ITEM * > & GetContainedItems() const
Return a set of all items contained within the rule area.
static std::vector< std::pair< SCH_RULE_AREA *, SCH_SCREEN * > > UpdateRuleAreasInScreens(std::unordered_set< SCH_SCREEN * > &screens, KIGFX::SCH_VIEW *view)
Update all rule area connectvity / caches in the given sheet paths.
const std::unordered_set< KIID > & GetPastContainedItems() const
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
void CopyVariant(const wxString &aSourceVariant, const wxString &aNewVariant, SCH_COMMIT *aCommit=nullptr)
void RenameVariant(const wxString &aOldName, const wxString &aNewName, SCH_COMMIT *aCommit=nullptr)
std::set< wxString > GetVariantNames() const
void DeleteVariant(const wxString &aVariantName, SCH_COMMIT *aCommit=nullptr)
void SetLegacySymbolInstanceData()
Update the symbol value and footprint instance data for legacy designs.
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
std::vector< SCH_SHEET_PATH > & GetClientSheetPaths()
Return the number of times this screen is used.
EE_RTREE & Items()
Get the full RTree, usually for iterating.
const wxString & GetFileName() const
bool IsExplicitJunctionAllowed(const VECTOR2I &aPosition) const
Indicate that a junction dot may be placed at the given location.
void BumpConnectivityRevision(KICAD_T aChangedType=TYPE_NOT_INIT)
Increment the connectivity revisions of this screen.
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
bool Remove(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Remove aItem from the schematic associated with this screen.
TITLE_BLOCK & GetTitleBlock()
void Update(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Refresh a changed item in the tree and invalidate connectivity.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
std::optional< SCH_SHEET_PATH > GetSheetPathByKIIDPath(const KIID_PATH &aPath, bool aIncludeLastSheet=true) const
Finds a SCH_SHEET_PATH that matches the provided KIID_PATH.
SCH_ITEM * ResolveItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr, bool aAllowNullptrReturn=false) const
Fetch a SCH_ITEM by ID.
void SortByPageNumbers(bool aUpdateVirtualPageNums=true)
Sort the list of sheets by page number.
void BuildSheetList(SCH_SHEET *aSheet, bool aCheckIntegrity)
Build the list of sheets and their sheet path from aSheet.
bool HasPath(const KIID_PATH &aPath) const
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...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCH_SCREEN * LastScreen()
wxString GetPageNumber() const
SCH_SHEET * at(size_t aIndex) const
Forwarded method from std::vector.
void SetVirtualPageNumber(int aPageNumber)
Set the sheet instance virtual page number.
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false, bool aEscapeSheetNames=false) const
Return the sheet path in a human readable form made from the sheet names.
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
size_t size() const
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
wxString GetFileName() const
Return the filename corresponding to this sheet.
void SyncUuidToScreen()
Take the identity of the screen this sheet owns.
int CountSheets() const
Count the number of sheets found in "this" sheet including all of the subsheets.
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
std::vector< SCH_SHEET_PIN * > & GetPins()
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the sheet.
const std::vector< SCH_SYMBOL_INSTANCE > & GetInstances() const
wxString GetSchSymbolLibraryName() const
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the symbol.
const LIB_ID & GetLibId() const override
std::vector< SCH_PIN * > GetGraphicalPins(int aUnit, int aBodyStyle) const override
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
bool CollideEdge(const VECTOR2I &aPoint, VERTEX_INDEX *aClosestVertex=nullptr, int aClearance=0) const
Check whether aPoint collides with any edge of any of the contours of the polygon.
Helper class to handle Spice way of expressing values (e.g. 10.5 Meg)
wxString ToString() const
Return string value as when converting double to string (e.g.
A text evaluation frame with one frozen clock and memoized external queries.
bool IsCollectingSources() const
static ENVIRONMENT * Current()
void RecordCrossReference(const CROSS_REFERENCE_KEY &aKey, const CROSS_REFERENCE_VALUE &aValue)
std::pair< wxString, int > CROSS_REFERENCE_KEY
bool TextVarResolver(wxString *aToken, const PROJECT *aProject, RESOLUTION_CONTEXT aContext) const
static void GetContextualTextVars(wxArrayString *aVars)
static bool empty(const wxTextEntryBase *aCtrl)
#define SELECTED_BY_DRAG
Item was algorithmically selected as a dragged item.
#define STRUCT_DELETED
flag indication structures to be erased
@ ERCE_VARIANT_SYMBOL_INCOMPATIBLE
Variant symbol override fails pin compatibility.
@ ERCE_ENDPOINT_OFF_GRID
Pin or wire-end off grid.
@ ERCE_BUS_TO_BUS_CONFLICT
A connection between bus objects doesn't share at least one net.
@ ERCE_FOOTPRINT_LINK_ISSUES
The footprint link is invalid, or points to a missing (or inactive) footprint or library.
@ ERCE_BUS_TO_NET_CONFLICT
A bus wire is graphically connected to a net port/pin (or vice versa).
@ ERCE_NOCONNECT_NOT_CONNECTED
A no connect symbol is not connected to anything.
@ ERCE_FOUR_WAY_JUNCTION
A four-way junction was found.
@ ERCE_PIN_NOT_CONNECTED
Pin not connected and not no connect symbol.
@ ERCE_UNDEFINED_NETCLASS
A netclass was referenced but not defined.
@ ERCE_UNRESOLVED_VARIABLE
A text variable could not be resolved.
@ ERCE_SIMULATION_MODEL
An error was found in the simulation model.
@ ERCE_LIB_SYMBOL_MISMATCH
Symbol doesn't match copy in library.
@ ERCE_DIFFERENT_UNIT_FP
Different units of the same symbol have different footprints assigned.
@ ERCE_NOCONNECT_CONNECTED
A no connect symbol is connected to more than 1 pin.
@ ERCE_DUPLICATE_SHEET_NAME
Duplicate sheet names within a given sheet.
@ ERCE_LIB_SYMBOL_ISSUES
Symbol not found in active libraries.
@ ERCE_FOOTPRINT_FILTERS
The assigned footprint doesn't match the footprint filters.
@ ERCE_HIERACHICAL_LABEL
Mismatch between hierarchical labels and pins sheets.
@ ERCE_WIRE_DANGLING
Some wires are not connected to anything else.
@ ERCE_VARIANT_SYMBOL_INVALID
Variant symbol override LIB_ID cannot be resolved.
@ ERCE_PIN_MAP_UNMAPPED_PIN
A connected pin resolves to no footprint pad.
@ ERCE_LABEL_MULTIPLE_WIRES
A label is connected to more than one wire.
bool m_ConnectivityEngine
Use the schematic connectivity engine instead of CONNECTION_GRAPH.
const wxChar *const traceAutoSave
Flag to enable auto save feature debug tracing.
const wxChar *const traceSchSheetPaths
Flag to enable debug output of schematic symbol sheet path manipulation code.
void ignore_unused(const T &)
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
void for_all_pairs(_InputIterator __first, _InputIterator __last, _Function __f)
Apply a function to every possible pair of elements of a sequence.
PGM_BASE & Pgm()
The global program "get" accessor.
#define TYPE_HASH(x)
Macro to generate unique identifier for a type.
void CollectOtherUnits(const wxString &aRef, int aUnit, const LIB_ID &aLibId, SCH_SHEET_PATH &aSheet, std::vector< SCH_SYMBOL * > *otherUnits)
#define SKIP_CONNECTIVITY
#define DELETE_REMOVED_ITEMS
@ SYMBOL_FILTER_NON_POWER
wxString GetDefaultVariantName()
int SortVariantNames(const wxString &aLhs, const wxString &aRhs)
Data produced by a registered saver on the UI thread, consumed by either the background local-history...
std::string content
Serialized content (mutually exclusive with sourcePath)
KICAD_FORMAT::FORMAT_MODE formatMode
wxString relativePath
Destination path relative to the project root.
A schematic staged off to the side by an importer, ready to be swapped into a live SCHEMATIC in one s...
Pins of type no-connect that touch other items at one position.
A simple container for schematic symbol instance information.
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ DATASHEET
name of datasheet
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
wxLogTrace helper definitions.
VECTOR2< int32_t > VECTOR2I