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;
612 [&](
const wxString& aVar )
615 aVars->push_back( aVar );
620 add( wxT(
"SHEETPATH" ) );
621 add( wxT(
"SHEETNAME" ) );
622 add( wxT(
"FILENAME" ) );
623 add( wxT(
"FILEPATH" ) );
624 add( wxT(
"PROJECTNAME" ) );
625 add( wxT(
"VARIANT" ) );
626 add( wxT(
"VARIANT_DESC" ) );
631 for( std::pair<wxString, wxString> entry :
m_project->GetTextVars() )
638 wxCHECK( aSheetPath,
false );
640 if( token->IsSameAs( wxT(
"#" ) ) )
645 else if( token->IsSameAs( wxT(
"##" ) ) )
650 i += sheet->CountSheets();
652 *token = wxString::Format(
"%i", i );
655 else if( token->IsSameAs( wxT(
"SHEETPATH" ) ) )
660 else if( token->IsSameAs( wxT(
"SHEETNAME" ) ) )
665 else if( token->IsSameAs( wxT(
"FILENAME" ) ) )
668 *token = fn.GetFullName();
671 else if( token->IsSameAs( wxT(
"FILEPATH" ) ) )
674 *token = fn.GetFullPath();
677 else if( token->IsSameAs( wxT(
"PROJECTNAME" ) ) )
682 else if( token->IsSameAs( wxT(
"VARIANTNAME" ) ) || token->IsSameAs( wxT(
"VARIANT" ) ) )
687 else if( token->IsSameAs( wxT(
"VARIANT_DESC" ) ) )
700 if(
m_project->TextVarResolver( token ) )
712 return wxString( wxEmptyString );
717 return wxString( wxEmptyString );
726 return defaultSettings;
729 return *
m_project->GetProjectFile().m_SchematicSettings;
736 return *
m_project->GetProjectFile().m_ErcSettings;
760 if( !inserted && !comment.empty() && it->GetComment().empty() )
772 using GROUP_ANCHOR = std::variant<KIID, std::pair<int, int>>;
773 using GROUP_KEY = std::tuple<int, KIID_PATH, GROUP_ANCHOR>;
774 std::map<GROUP_KEY, SCH_MARKER*> groupMarkers;
777 std::optional<NC_GROUPS> ncGroups;
778 std::optional<std::map<GROUP_KEY, KIID>> ncFlagGroups;
779 std::optional<std::map<GROUP_KEY, KIID>> hierarchyGroups;
780 std::optional<std::vector<SCH_CONNECTIVITY::LABEL_WIRE_CONFLICT>> labelWireGroups;
781 std::optional<std::vector<SCH_CONNECTIVITY::FOUR_WAY_JUNCTION>> fourWayGroups;
783 const auto groupKey =
784 [&](
const SCH_MARKER& aMarker ) -> std::optional<GROUP_KEY>
786 const auto error = std::static_pointer_cast<ERC_ITEM>( aMarker.GetRCItem() );
789 && !error->MainItemHasSheetPath() && !error->AuxItemHasSheetPath();
797 if( !
ADVANCED_CFG::GetCfg().m_ConnectivityEngine || !groupedCodes.contains( error->GetErrorCode() )
798 || !error->IsSheetSpecific() )
805 if( error->MainItemHasSheetPath() || error->AuxItemHasSheetPath() )
811 const KIID_PATH&
path = error->GetSpecificSheetPath().PathRef();
812 const VECTOR2I position = aMarker.GetPosition();
813 const auto group = std::lower_bound( fourWayGroups->begin(), fourWayGroups->end(),
814 std::tie(
path, position.
x, position.
y ),
815 [](
const auto& junction,
const auto&
location )
817 return std::tie( junction.sheet, junction.position.x, junction.position.y ) < location;
823 for(
const KIID&
id : error->GetIDs() )
825 if( !std::binary_search(
group->equivalentItems.begin(),
group->equivalentItems.end(),
id ) )
834 if( !
main ||
main->GetPosition() != aMarker.GetPosition() )
843 if(
static_cast<const SCH_PIN*
>(
main )->GetParentSymbol()->IsPower() )
847 const KIID_PATH&
path = error->GetSpecificSheetPath().PathRef();
858 || error->MainItemHasSheetPath()
859 || error->AuxItemHasSheetPath() )
864 if( !labelWireGroups )
867 const auto group = std::find_if( labelWireGroups->begin(), labelWireGroups->end(),
868 [&](
const auto& conflict )
870 return conflict.sheet == path
871 && conflict.position == aMarker.GetPosition();
874 if(
group == labelWireGroups->end() )
877 for(
const KIID&
id : error->GetIDs() )
879 if(
id !=
main->m_Uuid && !std::binary_search(
group->wires.begin(),
group->wires.end(),
id ) )
888 if( !error->MainItemHasSheetPath()
889 || error->AuxItemHasSheetPath()
890 || error->GetMainItemSheetPath().PathRef() !=
path )
895 if( !hierarchyGroups )
897 hierarchyGroups.emplace();
899 for(
const auto& diagnostic :
m_connectivity->Engine().HierarchyErrors() )
901 for(
const KIID&
id : diagnostic.equivalentItems )
911 if( found == hierarchyGroups->end() )
924 ncGroups->emplace( std::make_pair(
group.sheet,
group.position ), std::move(
group ) );
927 const auto found = ncGroups->find( {
path, aMarker.GetPosition() } );
929 if( found == ncGroups->end() )
932 const auto&
group = found->second;
934 [&](
const KIID& id )
936 return std::binary_search(
group.pins.begin(),
group.pins.end(),
id );
939 if( !isPin( error->GetMainItemID() ) )
942 for(
const KIID&
id : error->GetIDs() )
948 || ( !isPin(
id ) && !std::binary_search(
group.others.begin(),
group.others.end(),
id ) ) )
954 return GROUP_KEY{ error->GetErrorCode(),
path,
group.pins.front() };
960 if( !error->MainItemHasSheetPath()
961 || error->AuxItemHasSheetPath()
962 || error->GetMainItemSheetPath().PathRef() !=
path )
969 for(
const KIID&
id : error->GetIDs() )
977 const auto& islandOf =
m_connectivity->Published().Auxiliary().IslandOf();
978 const auto flagIsland = islandOf.find( {
flag, *instance } );
980 if( flagIsland == islandOf.end() )
985 ncFlagGroups.emplace();
987 for(
const auto& diagnostic :
m_connectivity->Engine().NoConnectFlagErrors() )
989 const auto inst =
m_connectivity->Keys().FindInstance( diagnostic.sheet );
990 const auto record = inst ? islandOf.find( { diagnostic.flag, *inst } ) : islandOf.end();
992 if( record == islandOf.end() )
997 ncFlagGroups->emplace( GROUP_KEY{ code, diagnostic.sheet, record->second.anchor },
1002 const auto group = ncFlagGroups->find( { error->GetErrorCode(),
path, flagIsland->second.anchor } );
1004 if(
group == ncFlagGroups->end() )
1005 return std::nullopt;
1008 const auto flagRow = rows.find( {
flag, *instance } );
1010 if( flagRow == rows.end() )
1011 return std::nullopt;
1013 for(
const KIID&
id : error->GetIDs() )
1019 const auto row = rows.find( { id, *instance } );
1022 || row == rows.end()
1023 || row->second.component != flagRow->second.component
1026 return std::nullopt;
1030 return GROUP_KEY{ error->GetErrorCode(),
path,
group->second };
1033 const auto& islands =
m_connectivity->Published().Auxiliary().IslandOf();
1034 std::optional<GROUP_KEY> key;
1036 for(
const KIID&
id : error->GetIDs() )
1041 const auto island = islands.find( { id, *instance } );
1044 || island == islands.end()
1045 || ( key && std::get<2>( *key ) != GROUP_ANCHOR{ island->second.anchor } ) )
1047 return std::nullopt;
1050 key = GROUP_KEY{ error->GetErrorCode(),
path, island->second.anchor };
1056 std::set<ERC_EXCLUSION, ERC_EXCLUSION_COMPARE> legacyPathlessExclusions;
1057 std::optional<std::vector<SCH_CONNECTIVITY::OFF_GRID_ENDPOINT>> offGridEndpoints;
1059 const auto findPathless =
1062 kiapi::schematic::ErcExclusion legacy = aLookup.ToProto();
1063 legacy.mutable_marker()->clear_sheet_specific_path();
1064 legacy.mutable_marker()->clear_main_item_sheet_path();
1065 legacy.mutable_marker()->clear_aux_item_sheet_path();
1069 legacyPathlessExclusions.insert( *found );
1082 const auto error = std::static_pointer_cast<ERC_ITEM>( marker->
GetRCItem() );
1086 && error->IsSheetSpecific()
1087 && error->GetSpecificSheetPath().PathRef() == sheet.PathRef() )
1090 const bool hasMain = error->MainItemHasSheetPath();
1091 const bool hasAux = error->AuxItemHasSheetPath();
1092 const bool mainHere = hasMain && error->GetMainItemSheetPath().PathRef() == sheet.PathRef();
1093 const bool auxHere = hasAux && error->GetAuxItemSheetPath().PathRef() == sheet.PathRef();
1095 switch( error->GetErrorCode() )
1098 if( engine && !hasMain && !hasAux && sheet.Last()->IsTopLevelSheet() )
1104 it = findPathless( lookup );
1114 if( !marker->
IsExcluded() && mainHere && !hasAux )
1117 kiapi::schematic::ErcExclusion previous = lookup.
ToProto();
1118 previous.mutable_marker()->clear_main_item_sheet_path();
1133 if( !marker->
IsExcluded() && mainHere && !hasAux )
1134 it = findPathless( lookup );
1142 if( !offGridEndpoints )
1150 if( endpoint.sheet != sheet.PathRef()
1151 || endpoint.item != error->GetMainItemID()
1157 for(
const auto& [
pin, position] : endpoint.equivalentPins )
1160 alternate->SetItems( std::vector<KIID>{
pin } );
1161 alternate->SetSheetSpecificPath( sheet );
1162 alternate->SetItemsSheetPaths( sheet );
1163 SCH_MARKER witness( std::move( alternate ), position );
1168 it = findPathless( candidate );
1182 if( !marker->
IsExcluded() && mainHere && auxHere )
1183 it = findPathless( lookup );
1189 if( hasMain && auxHere )
1190 it = findPathless( lookup );
1203 if( !legacyPathlessExclusions.contains( *it ) )
1208 if(
const std::optional<GROUP_KEY> key = groupKey( *marker ) )
1209 groupMarkers.emplace( *key, marker );
1214 for(
const ERC_EXCLUSION& exclusion : legacyPathlessExclusions )
1217 std::vector<SCH_MARKER*> newMarkers;
1226 if(
const std::optional<GROUP_KEY> key = groupKey( *marker ) )
1228 const auto current = groupMarkers.find( *key );
1229 const auto itemCount =
1232 return std::ranges::count_if( aMarker.GetRCItem()->GetIDs(),
1233 [](
const KIID&
id )
1235 return id != niluuid;
1239 if( current != groupMarkers.end()
1240 && itemCount( *current->second ) == itemCount( *marker ) )
1242 current->second->SetExcluded(
true, exclusion.
GetComment() );
1243 groupMarkers.erase( current );
1250 newMarkers.push_back( marker );
1268 const auto& alias = *it;
1270 if( alias && alias->GetName() == aLabel )
1283 auto sameDefinition =
1284 [&](
const std::shared_ptr<BUS_ALIAS>& candidate ) ->
bool
1287 && candidate->GetName() == aAlias->GetName()
1288 && candidate->Members() == aAlias->Members();
1294 std::rotate( it, std::next( it ),
m_busAliases.end() );
1304 std::vector<std::shared_ptr<BUS_ALIAS>> aliases;
1306 for(
const std::shared_ptr<BUS_ALIAS>& alias : aAliases )
1311 std::shared_ptr<BUS_ALIAS> clone = alias->Clone();
1313 auto sameDefinition =
1314 [&](
const std::shared_ptr<BUS_ALIAS>& candidate ) ->
bool
1317 && candidate->GetName() == clone->GetName()
1318 && candidate->Members() == clone->Members();
1321 auto it = std::find_if( aliases.begin(), aliases.end(), sameDefinition );
1323 if( it != aliases.end() )
1324 std::rotate( it, std::next( it ), aliases.end() );
1326 aliases.push_back( clone );
1333 m_project->GetProjectFile().m_BusAliasesDefined =
true;
1350 const std::map<wxString, std::vector<wxString>>& projectAliases =
m_project->GetProjectFile().m_BusAliases;
1352 for(
const auto& [
name, members] : projectAliases )
1354 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>();
1356 busAlias->SetName(
name );
1357 busAlias->SetMembers( members );
1369 std::map<wxString, std::vector<wxString>>& projectAliases =
m_project->GetProjectFile().m_BusAliases;
1371 projectAliases.clear();
1373 for(
const std::shared_ptr<BUS_ALIAS>& alias :
m_busAliases )
1378 projectAliases.insert_or_assign( alias->GetName(), alias->Members() );
1385 std::set<wxString> names;
1392 if( std::ranges::all_of(
group.instances,
1395 return net.Items().empty();
1401 const auto& net =
group.instances.front();
1406 names.insert(
group.name );
1420 names.insert( key.Name );
1445 wxString ref = token->BeforeFirst(
':', &remainder );
1449 if(
path.size() > 1 )
1455 if(
path.size() > 1 )
1463 wxString variantName;
1464 wxString fieldName = remainder;
1465 int colonPos = remainder.Find(
':' );
1467 if( colonPos != wxNOT_FOUND )
1469 fieldName = remainder.Left( colonPos );
1470 variantName = remainder.Mid( colonPos + 1 );
1482 if( refSymbol->
ResolveTextVar( &sheetPath, &fieldName, variantName, aDepth + 1 ) )
1484 *token = std::move( fieldName );
1489 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ),
1490 refSymbol->
GetRef( &sheetPath,
false ),
1502 if( refSheet->
ResolveTextVar( &sheetPath, &remainder, aDepth + 1 ) )
1504 *token = std::move( remainder );
1509 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ),
1527 for(
int ii = 0; ii < (int) refs.
GetCount(); ii++ )
1533 if( symbolRef == ref )
1541 if( symbolRef.StartsWith( ref ) && symbolRef.Length() == ref.Length() + 1 )
1543 wxChar lastChar = symbolRef.Last();
1544 if( lastChar >=
'A' && lastChar <=
'Z' )
1555 if( foundSymbol->
ResolveTextVar( &foundPath, &fieldName, variantName, aDepth + 1 ) )
1557 *token = std::move( fieldName );
1562 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ),
1563 foundSymbol->
GetRef( &foundPath,
false ),
1571 *token = wxString::Format( wxT(
"<Unresolved: %s>" ), ref );
1576 *token = wxString::Format( wxT(
"<Unknown reference: %s>" ), ref );
1583 std::map<int, wxString> namesMap;
1587 if( sheet.size() == 1 )
1588 namesMap[sheet.GetVirtualPageNumber()] =
_(
"<root sheet>" );
1590 namesMap[sheet.GetVirtualPageNumber()] = sheet.Last()->GetName();
1599 std::map<int, wxString> pagesMap;
1602 pagesMap[sheet.GetVirtualPageNumber()] = sheet.GetPageNumber();
1611 size_t sourceLen = aSource.length();
1613 for(
size_t i = 0; i < sourceLen; ++i )
1617 if( aSource[i] ==
'\\' && i + 2 < sourceLen && aSource[i + 2] ==
'{' &&
1618 ( aSource[i + 1] ==
'$' || aSource[i + 1] ==
'@' ) )
1621 newbuf.append( aSource[i] );
1622 newbuf.append( aSource[i + 1] );
1623 newbuf.append( aSource[i + 2] );
1628 for( i = i + 1; i < sourceLen && braceDepth > 0; ++i )
1630 if( aSource[i] ==
'{' )
1632 else if( aSource[i] ==
'}' )
1635 newbuf.append( aSource[i] );
1641 if( aSource[i] ==
'$' && i + 1 < sourceLen && aSource[i + 1] ==
'{' )
1644 bool isCrossRef =
false;
1647 for( i = i + 2; i < sourceLen; ++i )
1649 if( aSource[i] ==
'{' && ( aSource[i - 1] ==
'_' || aSource[i - 1] ==
'^' || aSource[i - 1] ==
'~' ) )
1654 if( aSource[i] ==
'}' )
1662 if( aSource[i] ==
':' )
1665 token.append( aSource[i] );
1671 wxString ref = token.BeforeFirst(
':', &remainder );
1676 for(
size_t jj = 0; jj < references.
GetCount(); jj++ )
1678 SCH_SYMBOL* refSymbol = references[jj].GetSymbol();
1680 if( ref == refSymbol->
GetRef( &references[jj].GetSheetPath(),
true ) )
1685 token =
path.AsString() + wxS(
":" ) + remainder;
1691 newbuf.append( wxS(
"${" ) + token + wxS(
"}" ) );
1695 newbuf.append( aSource[i] );
1706 size_t sourceLen = aSource.length();
1708 for(
size_t i = 0; i < sourceLen; ++i )
1712 if( aSource[i] ==
'\\' && i + 2 < sourceLen && aSource[i + 2] ==
'{' &&
1713 ( aSource[i + 1] ==
'$' || aSource[i + 1] ==
'@' ) )
1716 newbuf.append( aSource[i] );
1717 newbuf.append( aSource[i + 1] );
1718 newbuf.append( aSource[i + 2] );
1723 for( i = i + 1; i < sourceLen && braceDepth > 0; ++i )
1725 if( aSource[i] ==
'{' )
1727 else if( aSource[i] ==
'}' )
1730 newbuf.append( aSource[i] );
1736 if( aSource[i] ==
'$' && i + 1 < sourceLen && aSource[i + 1] ==
'{' )
1739 bool isCrossRef =
false;
1741 for( i = i + 2; i < sourceLen; ++i )
1743 if( aSource[i] ==
'}' )
1746 if( aSource[i] ==
':' )
1749 token.append( aSource[i] );
1755 wxString ref = token.BeforeFirst(
':', &remainder );
1761 if(
path.size() > 1 )
1770 token = refSymbol->
GetRef( &sheetPath,
true ) + wxS(
":" ) + remainder;
1774 newbuf.append( wxS(
"${" ) + token + wxS(
"}" ) );
1778 newbuf.append( aSource[i] );
1801 size_t startIdx = 0;
1807 return wxEmptyString;
1813 wxString topFileName;
1818 if( topFileName.IsEmpty() )
1821 wxFileName rootFn( topFileName );
1822 wxString filename = rootFn.GetName();
1848 sheet_count += topSheet->CountSheets();
1857 int sheet_number = 1;
1861 for( screen = s_list.
GetFirst(); screen !=
nullptr; screen = s_list.
GetNext() )
1879 if( sheet.Path() == current_sheetpath )
1885 for( screen = s_list.
GetFirst(); screen !=
nullptr; screen = s_list.
GetNext() )
1896 std::map<wxString, std::set<int>>& pageRefsMap =
GetPageRefsMap();
1898 pageRefsMap.clear();
1907 pageRefsMap[resolvedLabel].insert( sheet.GetVirtualPageNumber() );
1916 std::vector<SCH_GLOBALLABEL*> currentSheetGlobalLabels;
1919 currentSheetGlobalLabels.push_back(
static_cast<SCH_GLOBALLABEL*
>( item ) );
1923 std::vector<SCH_FIELD>& fields = globalLabel->GetFields();
1925 fields[0].SetVisible( show );
1929 if( fields.size() == 1 && fields[0].GetTextPos() == globalLabel->GetPosition() )
1934 for(
SCH_FIELD& field : globalLabel->GetFields() )
1935 field.ClearBoundingBoxCache();
1937 globalLabel->ClearBoundingBoxCache();
1953 auto it = screen->GetLibSymbols().find( aSchLibSymbolName );
1955 if( it != screen->GetLibSymbols().end() && it->second && it->second != &aSource )
1957 it->second->SetPinMaps( aSource.
GetPinMaps() );
1980 aCommit->
Modify( symbol, screen );
1991 wxString spiceNetName( aNetName );
1993 spiceNetName.MakeLower();
1995 if( spiceNetName == wxS(
"gnd" ) || spiceNetName == wxS(
"0" ) )
1996 return wxEmptyString;
2016 std::deque<EDA_ITEM*> allItems;
2018 for(
SCH_ITEM* item : screen->Items() )
2019 allItems.push_back( item );
2022 for(
const VECTOR2I& point : screen->GetNeededJunctions( allItems ) )
2027 screen->Append( junction );
2030 for(
SCH_LINE* wire : screen->GetBusesAndWires( point,
true ) )
2033 screen->Append( newSegment );
2036 aOnSplit( wire, newSegment );
2105 if( aErrorCode >= 0 )
2107 kiapi::schematic::ErcErrorType error = exclusion.
ToProto().marker().error_type();
2128 for(
unsigned i = 0; i < sheetList.size(); i++ )
2182 for(
auto& [
name, libSym] : screen->GetLibSymbols() )
2183 aFunction( libSym->GetEmbeddedFiles() );
2190 std::set<KIFONT::OUTLINE_FONT*>
fonts;
2196 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
2211 fonts.insert( outline );
2231 wxLogTrace(
"EMBED",
"Failed to add font file: %s", font->GetFileName() );
2242 std::set<const SCH_SCREEN*> retv;
2255 const std::vector<SCH_SYMBOL_INSTANCE> symbolInstances = symbol->
GetInstances();
2259 if( !hierarchy.
HasPath( instance.m_Path ) )
2261 retv.insert( screen );
2266 if( retv.count( screen ) )
2283 wxCHECK2( screen,
continue );
2285 if( screen->GetRefCount() > 1 )
2296 std::vector<SCH_LINE*> lines;
2297 std::vector<SCH_JUNCTION*> junctions;
2298 std::vector<SCH_NO_CONNECT*> ncs;
2299 std::vector<SCH_ITEM*> items_to_remove;
2300 std::unordered_set<SCH_LINE*> generatedLines;
2301 std::vector<std::unique_ptr<SCH_LINE>> retiredLines;
2302 bool changed =
true;
2304 if( aScreen ==
nullptr )
2316 if( aItem->IsSelected() && selectionTool )
2322 aScreen->
Remove( aItem );
2326 if( aItem->Type() ==
SCH_LINE_T && generatedLines.erase(
static_cast<SCH_LINE*
>( aItem ) )
2327 && !aCommit->
GetStatus( aItem, aScreen ) )
2330 retiredLines.emplace_back(
static_cast<SCH_LINE*
>( aItem ) );
2342 items_to_remove.push_back( item );
2345 junctions.push_back(
static_cast<SCH_JUNCTION*
>( item ) );
2348 for(
SCH_ITEM* item : items_to_remove )
2349 remove_item( item );
2357 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
2358 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
2364 remove_item( aSecond );
2370 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
2371 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
2377 remove_item( aSecond );
2384 return std::min( l->GetStartPoint().x, l->GetEndPoint().x );
2390 return std::max( l->GetStartPoint().x, l->GetEndPoint().x );
2396 return std::min( l->GetStartPoint().y, l->GetEndPoint().y );
2402 return std::max( l->GetStartPoint().y, l->GetEndPoint().y );
2415 lines.push_back(
static_cast<SCH_LINE*
>( item ) );
2419 std::sort( lines.begin(), lines.end(),
2422 return minX( a ) < minX( b );
2425 for(
auto it1 = lines.begin(); it1 != lines.end(); ++it1 )
2432 if( firstLine->
IsNull() )
2434 remove_item( firstLine );
2438 int firstRightXEdge = maxX( firstLine );
2441 for( ++it2; it2 != lines.end(); ++it2 )
2444 int secondLeftXEdge = minX( secondLine );
2447 if( secondLeftXEdge > firstRightXEdge )
2451 if( !( std::max( minY( firstLine ), minY( secondLine ) )
2452 <= std::min( maxY( firstLine ), maxY( secondLine ) ) ) )
2470 remove_item( secondLine );
2478 if( mergedLine !=
nullptr )
2480 remove_item( firstLine );
2481 remove_item( secondLine );
2483 if( m_schematicHolder )
2485 m_schematicHolder->AddToScreen( mergedLine, aScreen );
2489 aScreen->Append( mergedLine );
2492 generatedLines.insert( mergedLine );
2493 aCommit->Added( mergedLine, aScreen );
2496 selectionTool->AddItemToSel( mergedLine,
true );
2507 const std::set<SCH_SCREEN*>& aLocalScreens )
2514 if( aLocalScreens.empty() )
2524 std::unordered_set<SCH_SCREEN*> cleanedScreens;
2530 if( cleanedScreens.insert( screen ).second )
2539 wxLogTrace(
"CONN_PROFILE",
"SchematicCleanUp() %0.4f ms", timer.
msecs() );
2541 if(
Settings().m_IntersheetRefsShow )
2555 m_project->GetProjectFile().NetSettings()->ClearAllCaches();
2556 std::unordered_set<SCH_SCREEN*> screens;
2561 screens.insert( screen );
2569 aChangedItemHandler ? *aChangedItemHandler
2570 : std::function<
void(
SCH_ITEM* )>() );
2582 std::function<
void(
SCH_ITEM* )>* aChangedItemHandler,
2588 aCommit = &localCommit;
2599 if( !localCommit.
Empty() )
2606 std::unordered_set<SCH_SCREEN*> screens;
2609 screens.insert(
path.LastScreen() );
2614 if( !localCommit.
Empty() )
2617 m_connectivity->Recalculate( *
this,
false, aChangedItemHandler ? *aChangedItemHandler
2618 : std::function<
void(
SCH_ITEM* )>() );
2625 if( !localCommit.
Empty() )
2641 std::set<SCH_ITEM*> changed_items;
2642 std::set<VECTOR2I> pts;
2643 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> item_paths;
2646 std::unordered_set<SCH_SCREEN*> changed_screens;
2647 std::set<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> changed_rule_areas;
2648 std::vector<CHANGED_ITEM> changed_connectable_items;
2651 auto addItemToChangeSet =
2652 [&changed_items, &pts, &item_paths]( CHANGED_ITEM itemData )
2654 std::vector<SCH_SHEET_PATH>& paths = itemData.screen->GetClientSheetPaths();
2656 std::vector<VECTOR2I> tmp_pts = itemData.item->GetConnectionPoints();
2657 pts.insert( tmp_pts.begin(), tmp_pts.end() );
2658 changed_items.insert( itemData.item );
2661 item_paths.insert( std::make_pair(
path, itemData.item ) );
2663 if( !itemData.linked_item || !itemData.linked_item->IsConnectable() )
2666 tmp_pts = itemData.linked_item->GetConnectionPoints();
2667 pts.insert( tmp_pts.begin(), tmp_pts.end() );
2668 changed_items.insert( itemData.linked_item );
2675 changed_items.insert( pins.begin(), pins.end() );
2679 item_paths.insert( std::make_pair(
path, itemData.linked_item ) );
2683 for(
unsigned ii = 0; ii < aLastChangeList->
GetCount(); ++ii )
2701 changed_screens.insert( screen );
2706 changed_rule_areas.insert( { ruleArea, screen } );
2711 changed_connectable_items.push_back( { item, linked_item, screen } );
2717 std::vector<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> forceUpdateRuleAreas =
2720 std::for_each( forceUpdateRuleAreas.begin(), forceUpdateRuleAreas.end(),
2721 [&]( std::pair<SCH_RULE_AREA*, SCH_SCREEN*>& updatedRuleArea )
2723 changed_rule_areas.insert( updatedRuleArea );
2728 std::unordered_map<KIID, EDA_ITEM*> itemMap;
2729 list.FillItemMap( itemMap );
2731 auto addPastAndPresentContainedItems =
2736 if( itemMap.contains( pastItem ) )
2737 addItemToChangeSet( {
static_cast<SCH_ITEM*
>( itemMap[pastItem] ),
nullptr, screen } );
2741 addItemToChangeSet( { containedItem,
nullptr, screen } );
2744 for(
const auto& [changedRuleArea, screen] : changed_rule_areas )
2745 addPastAndPresentContainedItems( changedRuleArea, screen );
2748 for( CHANGED_ITEM& changed_item : changed_connectable_items )
2750 addItemToChangeSet( changed_item );
2756 const std::vector<VECTOR2I> labelConnectionPoints = changed_item.item->GetConnectionPoints();
2758 auto candidateRuleAreas = changed_item.screen->Items()
2761 for(
SCH_ITEM* candidateRuleArea : candidateRuleAreas )
2766 addPastAndPresentContainedItems( ruleArea, changed_item.screen );
2776 if( !item->IsConnectable() )
2784 if( item->HitTest( pt ) )
2786 changed_items.insert( item );
2789 item_paths.insert( std::make_pair(
path, item ) );
2792 else if( item->Type() ==
SCH_SYMBOL_T && item->IsConnected( pt ) )
2797 changed_items.insert( pins.begin(), pins.end() );
2802 item_paths.insert( std::make_pair(
path,
pin ) );
2809 wxCHECK2( sheet,
continue );
2811 std::vector<SCH_SHEET_PIN*> sheetPins = sheet->
GetPins();
2812 changed_items.insert( sheetPins.begin(), sheetPins.end() );
2817 item_paths.insert( std::make_pair(
path,
pin ) );
2822 if( item->IsConnected( pt ) )
2824 changed_items.insert( item );
2827 item_paths.insert( std::make_pair(
path, item ) );
2833 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> all_items =
2836 all_items.insert( item_paths.begin(), item_paths.end() );
2842 std::shared_ptr<NET_SETTINGS> netSettings =
m_project->GetProjectFile().NetSettings();
2844 std::set<wxString> affectedNets;
2846 for(
auto& [
path, item] : all_items )
2848 wxCHECK2( item,
continue );
2849 item->SetConnectivityDirty();
2853 affectedNets.insert( conn->
Name() );
2858 for(
const CHANGED_ITEM& changedItem : changed_connectable_items )
2862 const wxString& driverName = label->GetCachedDriverName();
2864 if( !driverName.IsEmpty() )
2865 affectedNets.insert( driverName );
2870 const wxString& driverName = linkedLabel->GetCachedDriverName();
2872 if( !driverName.IsEmpty() )
2873 affectedNets.insert( driverName );
2878 for(
const wxString& netName : affectedNets )
2879 netSettings->ClearCacheForNet( netName );
2881 new_graph.
Recalculate( list,
false, aChangedItemHandler, aProgressReporter );
2885 if( !localCommit.
Empty() )
2926 size_t index =
static_cast<size_t>( aIndex );
2946 if( sheet && sheet->m_Uuid == aUuid )
2975 wxCHECK_RET( aSheet, wxS(
"Cannot add null sheet!" ) );
2976 wxCHECK_RET( aSheet->
GetScreen(), wxS(
"Cannot add virtual root as top-level sheet!" ) );
3009 m_rootSheet->GetScreen()->Remove( aSheet,
false );
3036 wxLogTrace(
traceSchSheetPaths,
"BuildSheetListSortedByPageNumbers: %zu top-level sheets",
3048 wxLogTrace(
traceSchSheetPaths,
" Top-level sheet: '%s' (UUID=%s, isVirtualRoot=%d)", sheet->GetName(),
3049 sheet->m_Uuid.AsString(), sheet->m_Uuid ==
niluuid ? 1 : 0 );
3058 hierarchy.push_back(
path );
3084 sheets.push_back(
path );
3095 wxArrayString variantNames;
3101 variantNames.Add(
name );
3105 return variantNames;
3112 return wxEmptyString;
3122 if(
name.CmpNoCase( aVariantName ) == 0 )
3132 wxString newVariant;
3136 newVariant = aVariantName;
3148 for(
SCH_ITEM* item : screen->Items() )
3149 item->ClearCaches();
3168 if( descriptions.find( aVariantName ) == descriptions.end() )
3169 descriptions[aVariantName] = wxEmptyString;
3195 wxCHECK( !aOldName.IsEmpty() && !aNewName.IsEmpty(), );
3203 if( descriptions.count( aOldName ) )
3205 descriptions[aNewName] = descriptions[aOldName];
3206 descriptions.erase( aOldName );
3223 wxCHECK( !aSourceVariant.IsEmpty() && !aNewVariant.IsEmpty(), );
3231 if( descriptions.count( aSourceVariant ) )
3232 descriptions[aNewVariant] = descriptions[aSourceVariant];
3235 allScreens.
CopyVariant( aSourceVariant, aNewVariant, aCommit );
3242 auto it = descriptions.find( aVariantName );
3244 if( it != descriptions.end() )
3247 return wxEmptyString;
3255 if( aDescription.IsEmpty() )
3256 descriptions.erase( aVariantName );
3258 descriptions[aVariantName] = aDescription;
3271 m_variantNames.insert( variantNames.begin(), variantNames.end() );
3276 for(
const wxString&
name : variantNames )
3278 if( descriptions.find(
name ) == descriptions.end() )
3279 descriptions[
name] = wxEmptyString;
3284 for(
const auto& [
name, description] : descriptions )
3295 wxString projPath =
m_project->GetProjectPath();
3297 if( projPath.IsEmpty() )
3301 if( !projPath.IsSameAs( aProjectPath ) )
3303 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver skipping - project path mismatch: %s vs %s" ), projPath,
3308 if( !projPath.EndsWith( wxFILE_SEP_PATH ) )
3309 projPath += wxFILE_SEP_PATH;
3315 KICAD_FORMAT::FORMAT_MODE mode = KICAD_FORMAT::FORMAT_MODE::NORMAL;
3318 mode = KICAD_FORMAT::FORMAT_MODE::COMPACT_TEXT_PROPERTIES;
3331 if( !sheet || !screen )
3342 wxString absPath = abs.GetFullPath();
3344 if( absPath.IsEmpty() || !absPath.StartsWith( projPath ) )
3347 wxString rel = absPath.Mid( projPath.length() );
3359 aFileData.push_back( std::move( entry ) );
3362 wxS(
"[history] sch saver serialized %zu bytes for '%s' -> '%s'" ),
3363 aFileData.back().content.size(), absPath, rel );
3367 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver serialize failed for '%s': %s" ),
3368 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.
EMBEDDING_PERMISSION GetEmbeddingPermission() const
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)
bool IsHierarchyModified() const
True when any sheet in the hierarchy has unsaved changes.
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
SCH_ITEM * Driver() 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 wire end, a bus entry end or a symbol pin that is not on the connection grid.
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