93 if( !symbol || aProperty->
Name() !=
_HKI(
"Text" ) )
99 wxString newValue = aItem->
Get<wxString>( aProperty );
103 symbol->
SetRef( &sheetPath, newValue );
111 wxString ref = symbol->
GetRef( &sheetPath );
117 std::vector<SCH_SYMBOL*> otherUnits;
123 switch( field->
GetId() )
130 aCommit->
Modify( otherUnit, sheet.LastScreen() );
132 otherUnit->GetField( field->
GetId() )->SetText( newValue );
183 project.m_ErcSettings =
nullptr;
186 delete project.m_SchematicSettings;
187 project.m_SchematicSettings =
nullptr;
198 project.m_SchematicSettings->LoadFromFile();
199 project.m_SchematicSettings->m_NgspiceSettings->LoadFromFile();
200 project.m_ErcSettings->LoadFromFile();
212 std::shared_ptr<REFDES_TRACKER> refdesTracker =
m_project->GetProjectFile().m_SchematicSettings->m_refDesTracker;
221 refdesTracker->Insert( ref.GetFullRef(
false ).ToStdString() );
237 return std::any_of( references.
begin(), references.
end(),
240 return ref.GetFullRef( true ) == aRef.GetFullRef( true );
295 rootSheetPath.push_back( rootSheet );
296 rootSheetPath.SetPageNumber( wxT(
"1" ) );
326 m_variantNames.insert( variantNames.begin(), variantNames.end() );
333 for(
const auto& [
name, description] :
Settings().m_VariantDescriptions )
341 wxCHECK_RET( !aSheets.empty(), wxS(
"Cannot set empty top-level sheets!" ) );
347 std::vector<SCH_SHEET*> validSheets;
348 validSheets.reserve( aSheets.size() );
353 if( sheet && sheet->m_Uuid !=
niluuid )
354 validSheets.push_back( sheet );
357 if( validSheets.empty() )
360 if( !wasAlreadySetting )
369 std::set<SCH_SHEET*> desiredSheets( validSheets.begin(), validSheets.end() );
377 if( sheet && !desiredSheets.contains( sheet ) )
432 auto add = [&](
const wxString& aVar )
435 aVars->push_back( aVar );
440 add( wxT(
"SHEETPATH" ) );
441 add( wxT(
"SHEETNAME" ) );
442 add( wxT(
"FILENAME" ) );
443 add( wxT(
"FILEPATH" ) );
444 add( wxT(
"PROJECTNAME" ) );
445 add( wxT(
"VARIANT" ) );
446 add( wxT(
"VARIANT_DESC" ) );
451 for( std::pair<wxString, wxString> entry :
m_project->GetTextVars() )
458 wxCHECK( aSheetPath,
false );
460 if( token->IsSameAs( wxT(
"#" ) ) )
465 else if( token->IsSameAs( wxT(
"##" ) ) )
467 *token = wxString::Format(
"%i",
Root().CountSheets() );
470 else if( token->IsSameAs( wxT(
"SHEETPATH" ) ) )
475 else if( token->IsSameAs( wxT(
"SHEETNAME" ) ) )
480 else if( token->IsSameAs( wxT(
"FILENAME" ) ) )
483 *token = fn.GetFullName();
486 else if( token->IsSameAs( wxT(
"FILEPATH" ) ) )
489 *token = fn.GetFullPath();
492 else if( token->IsSameAs( wxT(
"PROJECTNAME" ) ) )
497 else if( token->IsSameAs( wxT(
"VARIANTNAME" ) ) || token->IsSameAs( wxT(
"VARIANT" ) ) )
502 else if( token->IsSameAs( wxT(
"VARIANT_DESC" ) ) )
512 if(
m_project->TextVarResolver( token ) )
524 return wxString( wxEmptyString );
529 return wxString( wxEmptyString );
538 return defaultSettings;
541 return *
m_project->GetProjectFile().m_SchematicSettings;
548 return *
m_project->GetProjectFile().m_ErcSettings;
562 std::set<wxString> migratedExclusions;
578 if( settingsKey != wxT(
"pin_to_pin" ) && settingsKey != wxT(
"hier_label_mismatch" )
579 && settingsKey != wxT(
"different_unit_net" ) )
594 settings.
m_ErcExclusions.insert( migratedExclusions.begin(), migratedExclusions.end() );
604 std::set<wxString>::iterator it = settings.
m_ErcExclusions.find( serialized );
614 std::vector<SCH_MARKER*> newMarkers;
623 newMarkers.push_back( marker );
635 for(
const std::shared_ptr<BUS_ALIAS>& alias :
m_busAliases )
637 if( alias && alias->GetName() == aLabel )
650 auto sameDefinition = [&](
const std::shared_ptr<BUS_ALIAS>& candidate ) ->
bool
652 return candidate && candidate->GetName() == aAlias->GetName() && candidate->Members() == aAlias->Members();
670 for(
const std::shared_ptr<BUS_ALIAS>& alias : aAliases )
675 std::shared_ptr<BUS_ALIAS> clone = alias->Clone();
677 auto sameDefinition = [&](
const std::shared_ptr<BUS_ALIAS>& candidate ) ->
bool
679 return candidate && candidate->GetName() == clone->GetName() && candidate->Members() == clone->Members();
699 const auto& projectAliases =
m_project->GetProjectFile().m_BusAliases;
701 for(
const auto& alias : projectAliases )
703 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>();
705 busAlias->SetName( alias.first );
706 busAlias->SetMembers( alias.second );
718 auto& projectAliases =
m_project->GetProjectFile().m_BusAliases;
720 projectAliases.clear();
722 std::set<wxString> seen;
724 for(
const std::shared_ptr<BUS_ALIAS>& alias :
m_busAliases )
729 if( !seen.insert( alias->GetName() ).second )
732 projectAliases.emplace( alias->GetName(), alias->Members() );
739 std::set<wxString> names;
748 names.insert( key.Name );
759 wxString ref = token->BeforeFirst(
':', &remainder );
765 if(
path.size() > 1 )
773 wxString variantName;
774 wxString fieldName = remainder;
775 int colonPos = remainder.Find(
':' );
777 if( colonPos != wxNOT_FOUND )
779 fieldName = remainder.Left( colonPos );
780 variantName = remainder.Mid( colonPos + 1 );
792 bool resolved = refSymbol->
ResolveTextVar( &sheetPath, &fieldName, variantName, aDepth + 1 );
796 *token = std::move( fieldName );
801 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ), refSymbol->
GetRef( &sheetPath,
false ), fieldName );
812 wxString remainderBefore = remainder;
814 if( refSheet->
ResolveTextVar( &sheetPath, &remainder, aDepth + 1 ) )
815 *token = std::move( remainder );
819 if( remainderBefore.Contains( wxT(
"${" ) ) || remainderBefore.Contains( wxT(
"@{" ) ) )
835 for(
int ii = 0; ii < (int) refs.
GetCount(); ii++ )
841 if( symbolRef == ref )
849 if( symbolRef.StartsWith( ref ) && symbolRef.Length() == ref.Length() + 1 )
851 wxChar lastChar = symbolRef.Last();
852 if( lastChar >=
'A' && lastChar <=
'Z' )
863 bool resolved = foundSymbol->
ResolveTextVar( &foundPath, &fieldName, variantName, aDepth + 1 );
867 *token = std::move( fieldName );
872 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ), foundSymbol->
GetRef( &foundPath,
false ),
880 *token = wxString::Format( wxT(
"<Unresolved: %s>" ), ref );
885 *token = wxString::Format( wxT(
"<Unknown reference: %s>" ), ref );
892 std::map<int, wxString> namesMap;
896 if( sheet.size() == 1 )
897 namesMap[sheet.GetVirtualPageNumber()] =
_(
"<root sheet>" );
899 namesMap[sheet.GetVirtualPageNumber()] = sheet.Last()->GetName();
908 std::map<int, wxString> pagesMap;
911 pagesMap[sheet.GetVirtualPageNumber()] = sheet.GetPageNumber();
920 size_t sourceLen = aSource.length();
922 for(
size_t i = 0; i < sourceLen; ++i )
926 if( aSource[i] ==
'\\' && i + 2 < sourceLen && aSource[i + 2] ==
'{' &&
927 ( aSource[i + 1] ==
'$' || aSource[i + 1] ==
'@' ) )
930 newbuf.append( aSource[i] );
931 newbuf.append( aSource[i + 1] );
932 newbuf.append( aSource[i + 2] );
937 for( i = i + 1; i < sourceLen && braceDepth > 0; ++i )
939 if( aSource[i] ==
'{' )
941 else if( aSource[i] ==
'}' )
944 newbuf.append( aSource[i] );
950 if( aSource[i] ==
'$' && i + 1 < sourceLen && aSource[i + 1] ==
'{' )
953 bool isCrossRef =
false;
956 for( i = i + 2; i < sourceLen; ++i )
958 if( aSource[i] ==
'{' && ( aSource[i - 1] ==
'_' || aSource[i - 1] ==
'^' || aSource[i - 1] ==
'~' ) )
963 if( aSource[i] ==
'}' )
971 if( aSource[i] ==
':' )
974 token.append( aSource[i] );
980 wxString ref = token.BeforeFirst(
':', &remainder );
985 for(
size_t jj = 0; jj < references.
GetCount(); jj++ )
987 SCH_SYMBOL* refSymbol = references[jj].GetSymbol();
989 if( ref == refSymbol->
GetRef( &references[jj].GetSheetPath(),
true ) )
994 token =
path.AsString() + wxS(
":" ) + remainder;
1000 newbuf.append( wxS(
"${" ) + token + wxS(
"}" ) );
1004 newbuf.append( aSource[i] );
1015 size_t sourceLen = aSource.length();
1017 for(
size_t i = 0; i < sourceLen; ++i )
1021 if( aSource[i] ==
'\\' && i + 2 < sourceLen && aSource[i + 2] ==
'{' &&
1022 ( aSource[i + 1] ==
'$' || aSource[i + 1] ==
'@' ) )
1025 newbuf.append( aSource[i] );
1026 newbuf.append( aSource[i + 1] );
1027 newbuf.append( aSource[i + 2] );
1032 for( i = i + 1; i < sourceLen && braceDepth > 0; ++i )
1034 if( aSource[i] ==
'{' )
1036 else if( aSource[i] ==
'}' )
1039 newbuf.append( aSource[i] );
1045 if( aSource[i] ==
'$' && i + 1 < sourceLen && aSource[i + 1] ==
'{' )
1048 bool isCrossRef =
false;
1050 for( i = i + 2; i < sourceLen; ++i )
1052 if( aSource[i] ==
'}' )
1055 if( aSource[i] ==
':' )
1058 token.append( aSource[i] );
1064 wxString ref = token.BeforeFirst(
':', &remainder );
1070 if(
path.size() > 1 )
1079 token = refSymbol->
GetRef( &sheetPath,
true ) + wxS(
":" ) + remainder;
1083 newbuf.append( wxS(
"${" ) + token + wxS(
"}" ) );
1087 newbuf.append( aSource[i] );
1110 size_t startIdx = 0;
1116 return wxEmptyString;
1119 wxString filename = rootFn.GetName();
1145 sheet_count += topSheet->CountSheets();
1154 int sheet_number = 1;
1158 for( screen = s_list.
GetFirst(); screen !=
nullptr; screen = s_list.
GetNext() )
1176 if( sheet.Path() == current_sheetpath )
1182 for( screen = s_list.
GetFirst(); screen !=
nullptr; screen = s_list.
GetNext() )
1193 std::map<wxString, std::set<int>>& pageRefsMap =
GetPageRefsMap();
1195 pageRefsMap.clear();
1202 wxString resolvedLabel = global->
GetShownText( &sheet,
false );
1204 pageRefsMap[resolvedLabel].insert( sheet.GetVirtualPageNumber() );
1213 std::vector<SCH_GLOBALLABEL*> currentSheetGlobalLabels;
1216 currentSheetGlobalLabels.push_back(
static_cast<SCH_GLOBALLABEL*
>( item ) );
1220 std::vector<SCH_FIELD>& fields = globalLabel->GetFields();
1222 fields[0].SetVisible( show );
1226 if( fields.size() == 1 && fields[0].GetTextPos() == globalLabel->GetPosition() )
1231 for(
SCH_FIELD& field : globalLabel->GetFields() )
1232 field.ClearBoundingBoxCache();
1234 globalLabel->ClearBoundingBoxCache();
1245 wxString spiceNetName( aNetName.Lower() );
1248 if( spiceNetName == wxS(
"gnd" ) || spiceNetName == wxS(
"0" ) )
1249 return wxEmptyString;
1269 std::deque<EDA_ITEM*> allItems;
1271 for(
SCH_ITEM* item : screen->Items() )
1272 allItems.push_back( item );
1275 for(
const VECTOR2I& point : screen->GetNeededJunctions( allItems ) )
1280 screen->Append( junction );
1283 for(
SCH_LINE* wire : screen->GetBusesAndWires( point,
true ) )
1286 screen->Append( newSegment );
1353 for(
unsigned i = 0; i < sheetList.size(); i++ )
1409 for(
auto& [
name, libSym] : screen->GetLibSymbols() )
1410 aFunction( libSym->GetEmbeddedFiles() );
1417 std::set<KIFONT::OUTLINE_FONT*>
fonts;
1423 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
1435 if( outline->GetEmbeddingPermission() == EMBEDDING_PERMISSION::EDITABLE
1436 || outline->GetEmbeddingPermission() == EMBEDDING_PERMISSION::INSTALLABLE )
1438 fonts.insert( outline );
1458 wxLogTrace(
"EMBED",
"Failed to add font file: %s", font->GetFileName() );
1469 std::set<const SCH_SCREEN*> retv;
1482 const std::vector<SCH_SYMBOL_INSTANCE> symbolInstances = symbol->
GetInstances();
1486 if( !hierarchy.
HasPath( instance.m_Path ) )
1488 retv.insert( screen );
1493 if( retv.count( screen ) )
1510 wxCHECK2( screen,
continue );
1512 if( screen->GetRefCount() > 1 )
1523 std::vector<SCH_LINE*> lines;
1524 std::vector<SCH_JUNCTION*> junctions;
1525 std::vector<SCH_NO_CONNECT*> ncs;
1526 std::vector<SCH_ITEM*> items_to_remove;
1527 bool changed =
true;
1529 if( aScreen ==
nullptr )
1532 auto remove_item = [&](
SCH_ITEM* aItem ) ->
void
1540 if( aItem->IsSelected() && selectionTool )
1547 aCommit->
Removed( aItem, aScreen );
1559 items_to_remove.push_back( item );
1562 junctions.push_back(
static_cast<SCH_JUNCTION*
>( item ) );
1565 for(
SCH_ITEM* item : items_to_remove )
1566 remove_item( item );
1574 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
1575 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
1581 remove_item( aSecond );
1587 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
1588 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
1594 remove_item( aSecond );
1598 auto minX = [](
const SCH_LINE* l )
1600 return std::min( l->GetStartPoint().x, l->GetEndPoint().x );
1603 auto maxX = [](
const SCH_LINE* l )
1605 return std::max( l->GetStartPoint().x, l->GetEndPoint().x );
1608 auto minY = [](
const SCH_LINE* l )
1610 return std::min( l->GetStartPoint().y, l->GetEndPoint().y );
1613 auto maxY = [](
const SCH_LINE* l )
1615 return std::max( l->GetStartPoint().y, l->GetEndPoint().y );
1628 lines.push_back(
static_cast<SCH_LINE*
>( item ) );
1632 std::sort( lines.begin(), lines.end(),
1635 return minX( a ) < minX( b );
1638 for(
auto it1 = lines.begin(); it1 != lines.end(); ++it1 )
1645 if( firstLine->
IsNull() )
1647 remove_item( firstLine );
1651 int firstRightXEdge = maxX( firstLine );
1654 for( ++it2; it2 != lines.end(); ++it2 )
1657 int secondLeftXEdge = minX( secondLine );
1660 if( secondLeftXEdge > firstRightXEdge )
1664 if( !( std::max( minY( firstLine ), minY( secondLine ) )
1665 <= std::min( maxY( firstLine ), maxY( secondLine ) ) ) )
1683 remove_item( secondLine );
1691 if( mergedLine !=
nullptr )
1693 remove_item( firstLine );
1694 remove_item( secondLine );
1696 if( m_schematicHolder )
1698 m_schematicHolder->AddToScreen( mergedLine, aScreen );
1701 aCommit->Added( mergedLine, aScreen );
1704 selectionTool->AddItemToSel( mergedLine,
true );
1717 std::function<
void(
SCH_ITEM* )>* aChangedItemHandler,
1726 aCommit = &localCommit;
1738 CleanUp( aCommit, sheet.LastScreen() );
1742 wxLogTrace(
"CONN_PROFILE",
"SchematicCleanUp() %0.4f ms", timer.
msecs() );
1751 m_project->GetProjectFile().NetSettings()->ClearAllCaches();
1754 std::unordered_set<SCH_SCREEN*> all_screens;
1757 all_screens.insert(
path.LastScreen() );
1774 std::set<SCH_ITEM*> changed_items;
1775 std::set<VECTOR2I> pts;
1776 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> item_paths;
1779 std::unordered_set<SCH_SCREEN*> changed_screens;
1780 std::set<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> changed_rule_areas;
1781 std::vector<CHANGED_ITEM> changed_connectable_items;
1784 auto addItemToChangeSet = [&changed_items, &pts, &item_paths]( CHANGED_ITEM itemData )
1786 std::vector<SCH_SHEET_PATH>& paths = itemData.screen->GetClientSheetPaths();
1788 std::vector<VECTOR2I> tmp_pts = itemData.item->GetConnectionPoints();
1789 pts.insert( tmp_pts.begin(), tmp_pts.end() );
1790 changed_items.insert( itemData.item );
1793 item_paths.insert( std::make_pair(
path, itemData.item ) );
1795 if( !itemData.linked_item || !itemData.linked_item->IsConnectable() )
1798 tmp_pts = itemData.linked_item->GetConnectionPoints();
1799 pts.insert( tmp_pts.begin(), tmp_pts.end() );
1800 changed_items.insert( itemData.linked_item );
1806 std::vector<SCH_PIN*> pins = symbol->GetPins();
1807 changed_items.insert( pins.begin(), pins.end() );
1811 item_paths.insert( std::make_pair(
path, itemData.linked_item ) );
1815 for(
unsigned ii = 0; ii < aLastChangeList->
GetCount(); ++ii )
1833 changed_screens.insert( screen );
1838 changed_rule_areas.insert( { ruleArea, screen } );
1843 changed_connectable_items.push_back( { item, linked_item, screen } );
1849 std::vector<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> forceUpdateRuleAreas =
1852 std::for_each( forceUpdateRuleAreas.begin(), forceUpdateRuleAreas.end(),
1853 [&]( std::pair<SCH_RULE_AREA*, SCH_SCREEN*>& updatedRuleArea )
1855 changed_rule_areas.insert( updatedRuleArea );
1860 std::map<KIID, EDA_ITEM*> itemMap;
1861 list.FillItemMap( itemMap );
1867 if( itemMap.contains( pastItem ) )
1868 addItemToChangeSet( {
static_cast<SCH_ITEM*
>( itemMap[pastItem] ),
nullptr, screen } );
1872 addItemToChangeSet( { containedItem,
nullptr, screen } );
1875 for(
const auto& [changedRuleArea, screen] : changed_rule_areas )
1876 addPastAndPresentContainedItems( changedRuleArea, screen );
1879 for( CHANGED_ITEM& changed_item_data : changed_connectable_items )
1881 addItemToChangeSet( changed_item_data );
1887 const std::vector<VECTOR2I> labelConnectionPoints = changed_item_data.item->GetConnectionPoints();
1889 auto candidateRuleAreas = changed_item_data.screen->Items().Overlapping(
1892 for(
SCH_ITEM* candidateRuleArea : candidateRuleAreas )
1898 addPastAndPresentContainedItems( ruleArea, changed_item_data.screen );
1908 if( !item->IsConnectable() )
1916 if( item->HitTest( pt ) )
1918 changed_items.insert( item );
1921 item_paths.insert( std::make_pair(
path, item ) );
1924 else if( item->Type() ==
SCH_SYMBOL_T && item->IsConnected( pt ) )
1927 std::vector<SCH_PIN*> pins = symbol->
GetPins();
1929 changed_items.insert( pins.begin(), pins.end() );
1934 item_paths.insert( std::make_pair(
path,
pin ) );
1941 wxCHECK2( sheet,
continue );
1943 std::vector<SCH_SHEET_PIN*> sheetPins = sheet->
GetPins();
1944 changed_items.insert( sheetPins.begin(), sheetPins.end() );
1949 item_paths.insert( std::make_pair(
path,
pin ) );
1954 if( item->IsConnected( pt ) )
1956 changed_items.insert( item );
1959 item_paths.insert( std::make_pair(
path, item ) );
1965 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> all_items =
1968 all_items.insert( item_paths.begin(), item_paths.end() );
1974 std::shared_ptr<NET_SETTINGS> netSettings =
m_project->GetProjectFile().NetSettings();
1976 std::set<wxString> affectedNets;
1978 for(
auto& [
path, item] : all_items )
1980 wxCHECK2( item,
continue );
1981 item->SetConnectivityDirty();
1985 affectedNets.insert( conn->
Name() );
1990 for(
const CHANGED_ITEM& changedItem : changed_connectable_items )
1994 const wxString& driverName = label->GetCachedDriverName();
1996 if( !driverName.IsEmpty() )
1997 affectedNets.insert( driverName );
2002 const wxString& driverName = linkedLabel->GetCachedDriverName();
2004 if( !driverName.IsEmpty() )
2005 affectedNets.insert( driverName );
2010 for(
const wxString& netName : affectedNets )
2011 netSettings->ClearCacheForNet( netName );
2013 new_graph.
Recalculate( list,
false, aChangedItemHandler, aProgressReporter );
2017 if( !localCommit.
Empty() )
2018 localCommit.
Push(
_(
"Schematic Cleanup" ) );
2057 size_t index =
static_cast<size_t>( aIndex );
2067 wxCHECK_RET( aSheet, wxS(
"Cannot add null sheet!" ) );
2068 wxCHECK_RET( aSheet->
GetScreen(), wxS(
"Cannot add virtual root as top-level sheet!" ) );
2101 m_rootSheet->GetScreen()->Items().remove( aSheet );
2128 wxLogTrace(
traceSchSheetPaths,
"BuildSheetListSortedByPageNumbers: %zu top-level sheets",
2140 wxLogTrace(
traceSchSheetPaths,
" Top-level sheet: '%s' (UUID=%s, isVirtualRoot=%d)", sheet->GetName(),
2141 sheet->m_Uuid.AsString(), sheet->m_Uuid ==
niluuid ? 1 : 0 );
2150 hierarchy.push_back(
path );
2176 sheets.push_back(
path );
2187 wxArrayString variantNames;
2193 variantNames.Add(
name );
2197 return variantNames;
2204 return wxEmptyString;
2212 wxString newVariant;
2216 newVariant = aVariantName;
2231 for(
SCH_ITEM* item : screen->Items() )
2232 item->ClearCaches();
2245 if( descriptions.find( aVariantName ) == descriptions.end() )
2246 descriptions[aVariantName] = wxEmptyString;
2267 wxCHECK( !aOldName.IsEmpty() && !aNewName.IsEmpty(), );
2275 if( descriptions.count( aOldName ) )
2277 descriptions[aNewName] = descriptions[aOldName];
2278 descriptions.erase( aOldName );
2293 wxCHECK( !aSourceVariant.IsEmpty() && !aNewVariant.IsEmpty(), );
2301 if( descriptions.count( aSourceVariant ) )
2302 descriptions[aNewVariant] = descriptions[aSourceVariant];
2305 allScreens.
CopyVariant( aSourceVariant, aNewVariant, aCommit );
2312 auto it = descriptions.find( aVariantName );
2314 if( it != descriptions.end() )
2317 return wxEmptyString;
2325 if( aDescription.IsEmpty() )
2326 descriptions.erase( aVariantName );
2328 descriptions[aVariantName] = aDescription;
2338 m_variantNames.insert( variantNames.begin(), variantNames.end() );
2343 for(
const wxString&
name : variantNames )
2345 if( descriptions.find(
name ) == descriptions.end() )
2346 descriptions[
name] = wxEmptyString;
2351 for(
const auto& [
name, description] : descriptions )
2362 wxString projPath =
m_project->GetProjectPath();
2364 if( projPath.IsEmpty() )
2368 if( !projPath.IsSameAs( aProjectPath ) )
2370 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver skipping - project path mismatch: %s vs %s" ), projPath,
2376 if( !projPath.EndsWith( wxFILE_SEP_PATH ) )
2377 projPath += wxFILE_SEP_PATH;
2379 wxFileName historyRoot( projPath, wxEmptyString );
2380 historyRoot.AppendDir( wxS(
".history" ) );
2381 wxString historyRootPath = historyRoot.GetPath();
2394 if( !sheet || !screen )
2402 wxString absPath = abs.GetFullPath();
2404 if( absPath.IsEmpty() || !absPath.StartsWith( projPath ) )
2407 wxString rel = absPath.Mid( projPath.length() );
2410 wxFileName dst( rel );
2412 if( dst.IsRelative() )
2413 dst.MakeAbsolute( historyRootPath );
2415 dst.SetPath( historyRootPath );
2418 wxFileName dstDir( dst );
2419 dstDir.SetFullName( wxEmptyString );
2421 if( !dstDir.DirExists() )
2422 wxFileName::Mkdir( dstDir.GetPath(), 0777, wxPATH_MKDIR_FULL );
2426 pi->SaveSchematicFile( dst.GetFullPath(), sheet,
this );
2427 aFiles.push_back( dst.GetFullPath() );
2428 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver exported sheet '%s' -> '%s'" ), absPath,
2429 dst.GetFullPath() );
2433 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver export failed for '%s': %s" ), absPath,
2434 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)
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.
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 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)
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.
void SaveToHistory(const wxString &aProjectPath, std::vector< wxString > &aFiles)
Save schematic files to the .history directory.
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
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.
const TITLE_BLOCK & GetTitleBlock() const
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 GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
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
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)
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 &)
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
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.
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)
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