103 if( !symbol || aProperty->
Name() !=
_HKI(
"Text" ) )
109 wxString newValue = aItem->
Get<wxString>( aProperty );
113 symbol->
SetRef( &sheetPath, newValue );
121 wxString ref = symbol->
GetRef( &sheetPath );
127 std::vector<SCH_SYMBOL*> otherUnits;
133 switch( field->
GetId() )
140 aCommit->
Modify( otherUnit, sheet.LastScreen() );
142 otherUnit->GetField( field->
GetId() )->SetText( newValue );
194 project.m_ErcSettings =
nullptr;
197 delete project.m_SchematicSettings;
198 project.m_SchematicSettings =
nullptr;
209 project.m_SchematicSettings->LoadFromFile();
210 project.m_SchematicSettings->m_NgspiceSettings->LoadFromFile();
211 project.m_ErcSettings->LoadFromFile();
223 std::shared_ptr<REFDES_TRACKER> refdesTracker =
m_project->GetProjectFile().m_SchematicSettings->m_refDesTracker;
232 refdesTracker->Insert( ref.GetFullRef(
false ).ToStdString() );
248 return std::any_of( references.
begin(), references.
end(),
251 return ref.GetFullRef( true ) == aRef.GetFullRef( true );
306 rootSheetPath.push_back( rootSheet );
307 rootSheetPath.SetPageNumber( wxT(
"1" ) );
337 m_variantNames.insert( variantNames.begin(), variantNames.end() );
344 for(
const auto& [
name, description] :
Settings().m_VariantDescriptions )
352 wxCHECK_RET( !aSheets.empty(), wxS(
"Cannot set empty top-level sheets!" ) );
358 std::vector<SCH_SHEET*> validSheets;
359 validSheets.reserve( aSheets.size() );
364 if( sheet && sheet->m_Uuid !=
niluuid )
365 validSheets.push_back( sheet );
368 if( validSheets.empty() )
371 if( !wasAlreadySetting )
380 std::set<SCH_SHEET*> desiredSheets( validSheets.begin(), validSheets.end() );
388 if( sheet && !desiredSheets.contains( sheet ) )
443 auto add = [&](
const wxString& aVar )
446 aVars->push_back( aVar );
451 add( wxT(
"SHEETPATH" ) );
452 add( wxT(
"SHEETNAME" ) );
453 add( wxT(
"FILENAME" ) );
454 add( wxT(
"FILEPATH" ) );
455 add( wxT(
"PROJECTNAME" ) );
456 add( wxT(
"VARIANT" ) );
457 add( wxT(
"VARIANT_DESC" ) );
462 for( std::pair<wxString, wxString> entry :
m_project->GetTextVars() )
469 wxCHECK( aSheetPath,
false );
471 if( token->IsSameAs( wxT(
"#" ) ) )
476 else if( token->IsSameAs( wxT(
"##" ) ) )
478 *token = wxString::Format(
"%i",
Root().CountSheets() );
481 else if( token->IsSameAs( wxT(
"SHEETPATH" ) ) )
486 else if( token->IsSameAs( wxT(
"SHEETNAME" ) ) )
491 else if( token->IsSameAs( wxT(
"FILENAME" ) ) )
494 *token = fn.GetFullName();
497 else if( token->IsSameAs( wxT(
"FILEPATH" ) ) )
500 *token = fn.GetFullPath();
503 else if( token->IsSameAs( wxT(
"PROJECTNAME" ) ) )
508 else if( token->IsSameAs( wxT(
"VARIANTNAME" ) ) || token->IsSameAs( wxT(
"VARIANT" ) ) )
513 else if( token->IsSameAs( wxT(
"VARIANT_DESC" ) ) )
523 if(
m_project->TextVarResolver( token ) )
535 return wxString( wxEmptyString );
540 return wxString( wxEmptyString );
549 return defaultSettings;
552 return *
m_project->GetProjectFile().m_SchematicSettings;
559 return *
m_project->GetProjectFile().m_ErcSettings;
573 std::set<wxString> migratedExclusions;
589 if( settingsKey != wxT(
"pin_to_pin" ) && settingsKey != wxT(
"hier_label_mismatch" )
590 && settingsKey != wxT(
"different_unit_net" ) )
605 settings.
m_ErcExclusions.insert( migratedExclusions.begin(), migratedExclusions.end() );
615 std::set<wxString>::iterator it = settings.
m_ErcExclusions.find( serialized );
625 std::vector<SCH_MARKER*> newMarkers;
634 newMarkers.push_back( marker );
646 for(
const std::shared_ptr<BUS_ALIAS>& alias :
m_busAliases )
648 if( alias && alias->GetName() == aLabel )
661 auto sameDefinition = [&](
const std::shared_ptr<BUS_ALIAS>& candidate ) ->
bool
663 return candidate && candidate->GetName() == aAlias->GetName() && candidate->Members() == aAlias->Members();
681 for(
const std::shared_ptr<BUS_ALIAS>& alias : aAliases )
686 std::shared_ptr<BUS_ALIAS> clone = alias->Clone();
688 auto sameDefinition = [&](
const std::shared_ptr<BUS_ALIAS>& candidate ) ->
bool
690 return candidate && candidate->GetName() == clone->GetName() && candidate->Members() == clone->Members();
710 const auto& projectAliases =
m_project->GetProjectFile().m_BusAliases;
712 for(
const auto& alias : projectAliases )
714 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>();
716 busAlias->SetName( alias.first );
717 busAlias->SetMembers( alias.second );
729 auto& projectAliases =
m_project->GetProjectFile().m_BusAliases;
731 projectAliases.clear();
733 std::set<wxString> seen;
735 for(
const std::shared_ptr<BUS_ALIAS>& alias :
m_busAliases )
740 if( !seen.insert( alias->GetName() ).second )
743 projectAliases.emplace( alias->GetName(), alias->Members() );
750 std::set<wxString> names;
759 names.insert( key.Name );
770 wxString ref = token->BeforeFirst(
':', &remainder );
776 if(
path.size() > 1 )
784 wxString variantName;
785 wxString fieldName = remainder;
786 int colonPos = remainder.Find(
':' );
788 if( colonPos != wxNOT_FOUND )
790 fieldName = remainder.Left( colonPos );
791 variantName = remainder.Mid( colonPos + 1 );
803 bool resolved = refSymbol->
ResolveTextVar( &sheetPath, &fieldName, variantName, aDepth + 1 );
807 *token = std::move( fieldName );
812 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ), refSymbol->
GetRef( &sheetPath,
false ), fieldName );
823 wxString remainderBefore = remainder;
825 if( refSheet->
ResolveTextVar( &sheetPath, &remainder, aDepth + 1 ) )
826 *token = std::move( remainder );
830 if( remainderBefore.Contains( wxT(
"${" ) ) || remainderBefore.Contains( wxT(
"@{" ) ) )
846 for(
int ii = 0; ii < (int) refs.
GetCount(); ii++ )
852 if( symbolRef == ref )
860 if( symbolRef.StartsWith( ref ) && symbolRef.Length() == ref.Length() + 1 )
862 wxChar lastChar = symbolRef.Last();
863 if( lastChar >=
'A' && lastChar <=
'Z' )
874 bool resolved = foundSymbol->
ResolveTextVar( &foundPath, &fieldName, variantName, aDepth + 1 );
878 *token = std::move( fieldName );
883 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ), foundSymbol->
GetRef( &foundPath,
false ),
891 *token = wxString::Format( wxT(
"<Unresolved: %s>" ), ref );
896 *token = wxString::Format( wxT(
"<Unknown reference: %s>" ), ref );
903 std::map<int, wxString> namesMap;
907 if( sheet.size() == 1 )
908 namesMap[sheet.GetVirtualPageNumber()] =
_(
"<root sheet>" );
910 namesMap[sheet.GetVirtualPageNumber()] = sheet.Last()->GetName();
919 std::map<int, wxString> pagesMap;
922 pagesMap[sheet.GetVirtualPageNumber()] = sheet.GetPageNumber();
931 size_t sourceLen = aSource.length();
933 for(
size_t i = 0; i < sourceLen; ++i )
937 if( aSource[i] ==
'\\' && i + 2 < sourceLen && aSource[i + 2] ==
'{' &&
938 ( aSource[i + 1] ==
'$' || aSource[i + 1] ==
'@' ) )
941 newbuf.append( aSource[i] );
942 newbuf.append( aSource[i + 1] );
943 newbuf.append( aSource[i + 2] );
948 for( i = i + 1; i < sourceLen && braceDepth > 0; ++i )
950 if( aSource[i] ==
'{' )
952 else if( aSource[i] ==
'}' )
955 newbuf.append( aSource[i] );
961 if( aSource[i] ==
'$' && i + 1 < sourceLen && aSource[i + 1] ==
'{' )
964 bool isCrossRef =
false;
967 for( i = i + 2; i < sourceLen; ++i )
969 if( aSource[i] ==
'{' && ( aSource[i - 1] ==
'_' || aSource[i - 1] ==
'^' || aSource[i - 1] ==
'~' ) )
974 if( aSource[i] ==
'}' )
982 if( aSource[i] ==
':' )
985 token.append( aSource[i] );
991 wxString ref = token.BeforeFirst(
':', &remainder );
996 for(
size_t jj = 0; jj < references.
GetCount(); jj++ )
998 SCH_SYMBOL* refSymbol = references[jj].GetSymbol();
1000 if( ref == refSymbol->
GetRef( &references[jj].GetSheetPath(),
true ) )
1005 token =
path.AsString() + wxS(
":" ) + remainder;
1011 newbuf.append( wxS(
"${" ) + token + wxS(
"}" ) );
1015 newbuf.append( aSource[i] );
1026 size_t sourceLen = aSource.length();
1028 for(
size_t i = 0; i < sourceLen; ++i )
1032 if( aSource[i] ==
'\\' && i + 2 < sourceLen && aSource[i + 2] ==
'{' &&
1033 ( aSource[i + 1] ==
'$' || aSource[i + 1] ==
'@' ) )
1036 newbuf.append( aSource[i] );
1037 newbuf.append( aSource[i + 1] );
1038 newbuf.append( aSource[i + 2] );
1043 for( i = i + 1; i < sourceLen && braceDepth > 0; ++i )
1045 if( aSource[i] ==
'{' )
1047 else if( aSource[i] ==
'}' )
1050 newbuf.append( aSource[i] );
1056 if( aSource[i] ==
'$' && i + 1 < sourceLen && aSource[i + 1] ==
'{' )
1059 bool isCrossRef =
false;
1061 for( i = i + 2; i < sourceLen; ++i )
1063 if( aSource[i] ==
'}' )
1066 if( aSource[i] ==
':' )
1069 token.append( aSource[i] );
1075 wxString ref = token.BeforeFirst(
':', &remainder );
1081 if(
path.size() > 1 )
1090 token = refSymbol->
GetRef( &sheetPath,
true ) + wxS(
":" ) + remainder;
1094 newbuf.append( wxS(
"${" ) + token + wxS(
"}" ) );
1098 newbuf.append( aSource[i] );
1121 size_t startIdx = 0;
1127 return wxEmptyString;
1130 wxString filename = rootFn.GetName();
1156 sheet_count += topSheet->CountSheets();
1165 int sheet_number = 1;
1169 for( screen = s_list.
GetFirst(); screen !=
nullptr; screen = s_list.
GetNext() )
1187 if( sheet.Path() == current_sheetpath )
1193 for( screen = s_list.
GetFirst(); screen !=
nullptr; screen = s_list.
GetNext() )
1204 std::map<wxString, std::set<int>>& pageRefsMap =
GetPageRefsMap();
1206 pageRefsMap.clear();
1213 wxString resolvedLabel = global->
GetShownText( &sheet,
false );
1215 pageRefsMap[resolvedLabel].insert( sheet.GetVirtualPageNumber() );
1224 std::vector<SCH_GLOBALLABEL*> currentSheetGlobalLabels;
1227 currentSheetGlobalLabels.push_back(
static_cast<SCH_GLOBALLABEL*
>( item ) );
1231 std::vector<SCH_FIELD>& fields = globalLabel->GetFields();
1233 fields[0].SetVisible( show );
1237 if( fields.size() == 1 && fields[0].GetTextPos() == globalLabel->GetPosition() )
1242 for(
SCH_FIELD& field : globalLabel->GetFields() )
1243 field.ClearBoundingBoxCache();
1245 globalLabel->ClearBoundingBoxCache();
1256 wxString spiceNetName( aNetName.Lower() );
1259 if( spiceNetName == wxS(
"gnd" ) || spiceNetName == wxS(
"0" ) )
1260 return wxEmptyString;
1280 std::deque<EDA_ITEM*> allItems;
1282 for(
SCH_ITEM* item : screen->Items() )
1283 allItems.push_back( item );
1286 for(
const VECTOR2I& point : screen->GetNeededJunctions( allItems ) )
1291 screen->Append( junction );
1294 for(
SCH_LINE* wire : screen->GetBusesAndWires( point,
true ) )
1297 screen->Append( newSegment );
1364 for(
unsigned i = 0; i < sheetList.size(); i++ )
1420 for(
auto& [
name, libSym] : screen->GetLibSymbols() )
1421 aFunction( libSym->GetEmbeddedFiles() );
1428 std::set<KIFONT::OUTLINE_FONT*>
fonts;
1434 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
1446 if( outline->GetEmbeddingPermission() == EMBEDDING_PERMISSION::EDITABLE
1447 || outline->GetEmbeddingPermission() == EMBEDDING_PERMISSION::INSTALLABLE )
1449 fonts.insert( outline );
1469 wxLogTrace(
"EMBED",
"Failed to add font file: %s", font->GetFileName() );
1480 std::set<const SCH_SCREEN*> retv;
1493 const std::vector<SCH_SYMBOL_INSTANCE> symbolInstances = symbol->
GetInstances();
1497 if( !hierarchy.
HasPath( instance.m_Path ) )
1499 retv.insert( screen );
1504 if( retv.count( screen ) )
1521 wxCHECK2( screen,
continue );
1523 if( screen->GetRefCount() > 1 )
1534 std::vector<SCH_LINE*> lines;
1535 std::vector<SCH_JUNCTION*> junctions;
1536 std::vector<SCH_NO_CONNECT*> ncs;
1537 std::vector<SCH_ITEM*> items_to_remove;
1538 bool changed =
true;
1540 if( aScreen ==
nullptr )
1543 auto remove_item = [&](
SCH_ITEM* aItem ) ->
void
1551 if( aItem->IsSelected() && selectionTool )
1558 aCommit->
Removed( aItem, aScreen );
1570 items_to_remove.push_back( item );
1573 junctions.push_back(
static_cast<SCH_JUNCTION*
>( item ) );
1576 for(
SCH_ITEM* item : items_to_remove )
1577 remove_item( item );
1585 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
1586 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
1592 remove_item( aSecond );
1598 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
1599 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
1605 remove_item( aSecond );
1609 auto minX = [](
const SCH_LINE* l )
1611 return std::min( l->GetStartPoint().x, l->GetEndPoint().x );
1614 auto maxX = [](
const SCH_LINE* l )
1616 return std::max( l->GetStartPoint().x, l->GetEndPoint().x );
1619 auto minY = [](
const SCH_LINE* l )
1621 return std::min( l->GetStartPoint().y, l->GetEndPoint().y );
1624 auto maxY = [](
const SCH_LINE* l )
1626 return std::max( l->GetStartPoint().y, l->GetEndPoint().y );
1639 lines.push_back(
static_cast<SCH_LINE*
>( item ) );
1643 std::sort( lines.begin(), lines.end(),
1646 return minX( a ) < minX( b );
1649 for(
auto it1 = lines.begin(); it1 != lines.end(); ++it1 )
1656 if( firstLine->
IsNull() )
1658 remove_item( firstLine );
1662 int firstRightXEdge = maxX( firstLine );
1665 for( ++it2; it2 != lines.end(); ++it2 )
1668 int secondLeftXEdge = minX( secondLine );
1671 if( secondLeftXEdge > firstRightXEdge )
1675 if( !( std::max( minY( firstLine ), minY( secondLine ) )
1676 <= std::min( maxY( firstLine ), maxY( secondLine ) ) ) )
1694 remove_item( secondLine );
1702 if( mergedLine !=
nullptr )
1704 remove_item( firstLine );
1705 remove_item( secondLine );
1707 if( m_schematicHolder )
1709 m_schematicHolder->AddToScreen( mergedLine, aScreen );
1712 aCommit->Added( mergedLine, aScreen );
1715 selectionTool->AddItemToSel( mergedLine,
true );
1728 std::function<
void(
SCH_ITEM* )>* aChangedItemHandler,
1737 aCommit = &localCommit;
1749 CleanUp( aCommit, sheet.LastScreen() );
1753 wxLogTrace(
"CONN_PROFILE",
"SchematicCleanUp() %0.4f ms", timer.
msecs() );
1762 m_project->GetProjectFile().NetSettings()->ClearAllCaches();
1765 std::unordered_set<SCH_SCREEN*> all_screens;
1768 all_screens.insert(
path.LastScreen() );
1785 std::set<SCH_ITEM*> changed_items;
1786 std::set<VECTOR2I> pts;
1787 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> item_paths;
1790 std::unordered_set<SCH_SCREEN*> changed_screens;
1791 std::set<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> changed_rule_areas;
1792 std::vector<CHANGED_ITEM> changed_connectable_items;
1795 auto addItemToChangeSet = [&changed_items, &pts, &item_paths]( CHANGED_ITEM itemData )
1797 std::vector<SCH_SHEET_PATH>& paths = itemData.screen->GetClientSheetPaths();
1799 std::vector<VECTOR2I> tmp_pts = itemData.item->GetConnectionPoints();
1800 pts.insert( tmp_pts.begin(), tmp_pts.end() );
1801 changed_items.insert( itemData.item );
1804 item_paths.insert( std::make_pair(
path, itemData.item ) );
1806 if( !itemData.linked_item || !itemData.linked_item->IsConnectable() )
1809 tmp_pts = itemData.linked_item->GetConnectionPoints();
1810 pts.insert( tmp_pts.begin(), tmp_pts.end() );
1811 changed_items.insert( itemData.linked_item );
1817 std::vector<SCH_PIN*> pins = symbol->GetPins();
1818 changed_items.insert( pins.begin(), pins.end() );
1822 item_paths.insert( std::make_pair(
path, itemData.linked_item ) );
1826 for(
unsigned ii = 0; ii < aLastChangeList->
GetCount(); ++ii )
1844 changed_screens.insert( screen );
1849 changed_rule_areas.insert( { ruleArea, screen } );
1854 changed_connectable_items.push_back( { item, linked_item, screen } );
1860 std::vector<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> forceUpdateRuleAreas =
1863 std::for_each( forceUpdateRuleAreas.begin(), forceUpdateRuleAreas.end(),
1864 [&]( std::pair<SCH_RULE_AREA*, SCH_SCREEN*>& updatedRuleArea )
1866 changed_rule_areas.insert( updatedRuleArea );
1871 std::map<KIID, EDA_ITEM*> itemMap;
1872 list.FillItemMap( itemMap );
1878 if( itemMap.contains( pastItem ) )
1879 addItemToChangeSet( {
static_cast<SCH_ITEM*
>( itemMap[pastItem] ),
nullptr, screen } );
1883 addItemToChangeSet( { containedItem,
nullptr, screen } );
1886 for(
const auto& [changedRuleArea, screen] : changed_rule_areas )
1887 addPastAndPresentContainedItems( changedRuleArea, screen );
1890 for( CHANGED_ITEM& changed_item_data : changed_connectable_items )
1892 addItemToChangeSet( changed_item_data );
1898 const std::vector<VECTOR2I> labelConnectionPoints = changed_item_data.item->GetConnectionPoints();
1900 auto candidateRuleAreas = changed_item_data.screen->Items().Overlapping(
1903 for(
SCH_ITEM* candidateRuleArea : candidateRuleAreas )
1909 addPastAndPresentContainedItems( ruleArea, changed_item_data.screen );
1919 if( !item->IsConnectable() )
1927 if( item->HitTest( pt ) )
1929 changed_items.insert( item );
1932 item_paths.insert( std::make_pair(
path, item ) );
1935 else if( item->Type() ==
SCH_SYMBOL_T && item->IsConnected( pt ) )
1938 std::vector<SCH_PIN*> pins = symbol->
GetPins();
1940 changed_items.insert( pins.begin(), pins.end() );
1945 item_paths.insert( std::make_pair(
path,
pin ) );
1952 wxCHECK2( sheet,
continue );
1954 std::vector<SCH_SHEET_PIN*> sheetPins = sheet->
GetPins();
1955 changed_items.insert( sheetPins.begin(), sheetPins.end() );
1960 item_paths.insert( std::make_pair(
path,
pin ) );
1965 if( item->IsConnected( pt ) )
1967 changed_items.insert( item );
1970 item_paths.insert( std::make_pair(
path, item ) );
1976 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> all_items =
1979 all_items.insert( item_paths.begin(), item_paths.end() );
1985 std::shared_ptr<NET_SETTINGS> netSettings =
m_project->GetProjectFile().NetSettings();
1987 std::set<wxString> affectedNets;
1989 for(
auto& [
path, item] : all_items )
1991 wxCHECK2( item,
continue );
1992 item->SetConnectivityDirty();
1996 affectedNets.insert( conn->
Name() );
2001 for(
const CHANGED_ITEM& changedItem : changed_connectable_items )
2005 const wxString& driverName = label->GetCachedDriverName();
2007 if( !driverName.IsEmpty() )
2008 affectedNets.insert( driverName );
2013 const wxString& driverName = linkedLabel->GetCachedDriverName();
2015 if( !driverName.IsEmpty() )
2016 affectedNets.insert( driverName );
2021 for(
const wxString& netName : affectedNets )
2022 netSettings->ClearCacheForNet( netName );
2024 new_graph.
Recalculate( list,
false, aChangedItemHandler, aProgressReporter );
2028 if( !localCommit.
Empty() )
2029 localCommit.
Push(
_(
"Schematic Cleanup" ) );
2068 size_t index =
static_cast<size_t>( aIndex );
2078 wxCHECK_RET( aSheet, wxS(
"Cannot add null sheet!" ) );
2079 wxCHECK_RET( aSheet->
GetScreen(), wxS(
"Cannot add virtual root as top-level sheet!" ) );
2112 m_rootSheet->GetScreen()->Items().remove( aSheet );
2139 wxLogTrace(
traceSchSheetPaths,
"BuildSheetListSortedByPageNumbers: %zu top-level sheets",
2151 wxLogTrace(
traceSchSheetPaths,
" Top-level sheet: '%s' (UUID=%s, isVirtualRoot=%d)", sheet->GetName(),
2152 sheet->m_Uuid.AsString(), sheet->m_Uuid ==
niluuid ? 1 : 0 );
2161 hierarchy.push_back(
path );
2187 sheets.push_back(
path );
2198 wxArrayString variantNames;
2204 variantNames.Add(
name );
2208 return variantNames;
2215 return wxEmptyString;
2223 wxString newVariant;
2227 newVariant = aVariantName;
2242 for(
SCH_ITEM* item : screen->Items() )
2243 item->ClearCaches();
2262 if( descriptions.find( aVariantName ) == descriptions.end() )
2263 descriptions[aVariantName] = wxEmptyString;
2284 wxCHECK( !aOldName.IsEmpty() && !aNewName.IsEmpty(), );
2292 if( descriptions.count( aOldName ) )
2294 descriptions[aNewName] = descriptions[aOldName];
2295 descriptions.erase( aOldName );
2310 wxCHECK( !aSourceVariant.IsEmpty() && !aNewVariant.IsEmpty(), );
2318 if( descriptions.count( aSourceVariant ) )
2319 descriptions[aNewVariant] = descriptions[aSourceVariant];
2322 allScreens.
CopyVariant( aSourceVariant, aNewVariant, aCommit );
2329 auto it = descriptions.find( aVariantName );
2331 if( it != descriptions.end() )
2334 return wxEmptyString;
2342 if( aDescription.IsEmpty() )
2343 descriptions.erase( aVariantName );
2345 descriptions[aVariantName] = aDescription;
2355 m_variantNames.insert( variantNames.begin(), variantNames.end() );
2360 for(
const wxString&
name : variantNames )
2362 if( descriptions.find(
name ) == descriptions.end() )
2363 descriptions[
name] = wxEmptyString;
2368 for(
const auto& [
name, description] : descriptions )
2379 wxString projPath =
m_project->GetProjectPath();
2381 if( projPath.IsEmpty() )
2385 if( !projPath.IsSameAs( aProjectPath ) )
2387 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver skipping - project path mismatch: %s vs %s" ), projPath,
2392 if( !projPath.EndsWith( wxFILE_SEP_PATH ) )
2393 projPath += wxFILE_SEP_PATH;
2399 KICAD_FORMAT::FORMAT_MODE mode = KICAD_FORMAT::FORMAT_MODE::NORMAL;
2402 mode = KICAD_FORMAT::FORMAT_MODE::COMPACT_TEXT_PROPERTIES;
2415 if( !sheet || !screen )
2426 wxString absPath = abs.GetFullPath();
2428 if( absPath.IsEmpty() || !absPath.StartsWith( projPath ) )
2431 wxString rel = absPath.Mid( projPath.length() );
2443 aFileData.push_back( std::move( entry ) );
2446 wxS(
"[history] sch saver serialized %zu bytes for '%s' -> '%s'" ),
2447 aFileData.back().content.size(), absPath, rel );
2451 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver serialize failed for '%s': %s" ),
2452 absPath, wxString::FromUTF8( ioe.
What() ) );
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.
COMMIT & Removed(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Calculate the connectivity of a schematic and generates 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 ERC settings.
std::map< wxString, wxString > m_ErcExclusionComments
std::set< wxString > 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
Class OUTLINE_FONT implements outline font drawing.
A logical library item identifier and consists of various portions much like a URI.
std::shared_ptr< RC_ITEM > GetRCItem() const
void SetExcluded(bool aExcluded, const wxString &aComment=wxEmptyString)
wxString GetComment() const
static void ConvertToSpiceMarkup(wxString *aNetName)
Remove formatting wrappers and replace illegal spice net name characters with underscores.
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()
void UnregisterListeners(TYPE_ID aType)
void RegisterListener(TYPE_ID aType, PROPERTY_LISTENER aListenerFunc)
Registers a listener for the given type.
wxString GetSettingsKey() const
virtual void OnSchItemsRemoved(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
virtual void OnSchItemsChanged(SCHEMATIC &aSch, std::vector< SCH_ITEM * > &aSchItem)
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 ...
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 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...
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)
int FixupJunctionsAfterImport()
Add junctions to this schematic where required.
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 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::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.
bool Contains(const SCH_REFERENCE &aRef) const
Check if the schematic contains the specified reference.
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...
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.
static bool m_IsSchematicExists
True if a SCHEMATIC exists, false if not.
void RemoveAllListeners()
Remove all listeners.
void SetTopLevelSheets(const std::vector< SCH_SHEET * > &aSheets)
std::unique_ptr< class SCHEMATIC_TEXT_VAR_ADAPTER > m_textVarAdapter
Reactive text-variable dependency adapter.
void GetContextualTextVars(wxArrayString *aVars) const
void ensureDefaultTopLevelSheet()
std::map< int, wxString > GetVirtualPageToSheetNamesMap() const
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.
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.
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)
Generate the connection data for the entire schematic hierarchy.
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)
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
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, bool aAllowExtraText, 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 * DeserializeFromString(const SCH_SHEET_LIST &aSheetList, const wxString &data)
wxString SerializeToString() const
bool IsLegacyMarker() const
Determine if this marker is legacy (i.e.
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
virtual std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const override
Make a set of SHAPE objects representing the EDA_SHAPE.
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.
bool IsExplicitJunction(const VECTOR2I &aPosition) const
Indicate that a junction dot is necessary at the given location.
EE_RTREE & Items()
Get the full RTree, usually for iterating.
const wxString & GetFileName() const
const KIID & GetUuid() const
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
TITLE_BLOCK & GetTitleBlock()
void Update(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Update aItem's bounding box in the tree.
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.
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
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
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
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 recognize Spice formatted values.
wxString ToString() const
Return string value as when converting double to string (e.g.
bool TextVarResolver(wxString *aToken, const PROJECT *aProject, int aFlags=0) const
static void GetContextualTextVars(wxArrayString *aVars)
@ ZIP
Zip archive snapshots; autosave uses recovery files.
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
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.
void CollectOtherUnits(const wxString &aRef, int aUnit, const LIB_ID &aLibId, SCH_SHEET_PATH &aSheet, std::vector< SCH_SYMBOL * > *otherUnits)
wxString GetDefaultVariantName()
int SortVariantNames(const wxString &aLhs, const wxString &aRhs)
BACKUP_FORMAT format
Backup format (incremental git history vs zip archives)
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 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