92 if( !symbol || aProperty->
Name() !=
_HKI(
"Text" ) )
98 wxString newValue = aItem->
Get<wxString>( aProperty );
102 symbol->
SetRef( &sheetPath, newValue );
110 wxString ref = symbol->
GetRef( &sheetPath );
116 std::vector<SCH_SYMBOL*> otherUnits;
122 switch( field->
GetId() )
129 aCommit->
Modify( otherUnit, sheet.LastScreen() );
131 otherUnit->GetField( field->
GetId() )->SetText( newValue );
182 project.m_ErcSettings =
nullptr;
185 delete project.m_SchematicSettings;
186 project.m_SchematicSettings =
nullptr;
197 project.m_SchematicSettings->LoadFromFile();
198 project.m_SchematicSettings->m_NgspiceSettings->LoadFromFile();
199 project.m_ErcSettings->LoadFromFile();
211 std::shared_ptr<REFDES_TRACKER> refdesTracker =
m_project->GetProjectFile().m_SchematicSettings->m_refDesTracker;
220 refdesTracker->Insert( ref.GetFullRef(
false ).ToStdString() );
236 return std::any_of( references.
begin(), references.
end(),
239 return ref.GetFullRef( true ) == aRef.GetFullRef( true );
294 rootSheetPath.push_back( rootSheet );
295 rootSheetPath.SetPageNumber( wxT(
"1" ) );
325 m_variantNames.insert( variantNames.begin(), variantNames.end() );
332 wxCHECK_RET( !aSheets.empty(), wxS(
"Cannot set empty top-level sheets!" ) );
338 std::vector<SCH_SHEET*> validSheets;
339 validSheets.reserve( aSheets.size() );
344 if( sheet && sheet->m_Uuid !=
niluuid )
345 validSheets.push_back( sheet );
348 if( validSheets.empty() )
351 if( !wasAlreadySetting )
360 std::set<SCH_SHEET*> desiredSheets( validSheets.begin(), validSheets.end() );
368 if( sheet && !desiredSheets.contains( sheet ) )
423 auto add = [&](
const wxString& aVar )
426 aVars->push_back( aVar );
431 add( wxT(
"SHEETPATH" ) );
432 add( wxT(
"SHEETNAME" ) );
433 add( wxT(
"FILENAME" ) );
434 add( wxT(
"FILEPATH" ) );
435 add( wxT(
"PROJECTNAME" ) );
436 add( wxT(
"VARIANT" ) );
437 add( wxT(
"VARIANT_DESC" ) );
442 for( std::pair<wxString, wxString> entry :
m_project->GetTextVars() )
449 wxCHECK( aSheetPath,
false );
451 if( token->IsSameAs( wxT(
"#" ) ) )
456 else if( token->IsSameAs( wxT(
"##" ) ) )
458 *token = wxString::Format(
"%i",
Root().CountSheets() );
461 else if( token->IsSameAs( wxT(
"SHEETPATH" ) ) )
466 else if( token->IsSameAs( wxT(
"SHEETNAME" ) ) )
471 else if( token->IsSameAs( wxT(
"FILENAME" ) ) )
474 *token = fn.GetFullName();
477 else if( token->IsSameAs( wxT(
"FILEPATH" ) ) )
480 *token = fn.GetFullPath();
483 else if( token->IsSameAs( wxT(
"PROJECTNAME" ) ) )
488 else if( token->IsSameAs( wxT(
"VARIANTNAME" ) ) || token->IsSameAs( wxT(
"VARIANT" ) ) )
493 else if( token->IsSameAs( wxT(
"VARIANT_DESC" ) ) )
503 if(
m_project->TextVarResolver( token ) )
515 return wxString( wxEmptyString );
520 return wxString( wxEmptyString );
529 return defaultSettings;
532 return *
m_project->GetProjectFile().m_SchematicSettings;
539 return *
m_project->GetProjectFile().m_ErcSettings;
553 std::set<wxString> migratedExclusions;
569 if( settingsKey != wxT(
"pin_to_pin" ) && settingsKey != wxT(
"hier_label_mismatch" )
570 && settingsKey != wxT(
"different_unit_net" ) )
585 settings.
m_ErcExclusions.insert( migratedExclusions.begin(), migratedExclusions.end() );
595 std::set<wxString>::iterator it = settings.
m_ErcExclusions.find( serialized );
605 std::vector<SCH_MARKER*> newMarkers;
614 newMarkers.push_back( marker );
626 for(
const std::shared_ptr<BUS_ALIAS>& alias :
m_busAliases )
628 if( alias && alias->GetName() == aLabel )
641 auto sameDefinition = [&](
const std::shared_ptr<BUS_ALIAS>& candidate ) ->
bool
643 return candidate && candidate->GetName() == aAlias->GetName() && candidate->Members() == aAlias->Members();
661 for(
const std::shared_ptr<BUS_ALIAS>& alias : aAliases )
666 std::shared_ptr<BUS_ALIAS> clone = alias->Clone();
668 auto sameDefinition = [&](
const std::shared_ptr<BUS_ALIAS>& candidate ) ->
bool
670 return candidate && candidate->GetName() == clone->GetName() && candidate->Members() == clone->Members();
690 const auto& projectAliases =
m_project->GetProjectFile().m_BusAliases;
692 for(
const auto& alias : projectAliases )
694 std::shared_ptr<BUS_ALIAS> busAlias = std::make_shared<BUS_ALIAS>();
696 busAlias->SetName( alias.first );
697 busAlias->Members() = alias.second;
709 auto& projectAliases =
m_project->GetProjectFile().m_BusAliases;
711 projectAliases.clear();
713 std::set<wxString> seen;
715 for(
const std::shared_ptr<BUS_ALIAS>& alias :
m_busAliases )
720 if( !seen.insert( alias->GetName() ).second )
723 projectAliases.emplace( alias->GetName(), alias->Members() );
730 std::set<wxString> names;
739 names.insert( key.Name );
750 wxString ref = token->BeforeFirst(
':', &remainder );
756 if(
path.size() > 1 )
764 wxString variantName;
765 wxString fieldName = remainder;
766 int colonPos = remainder.Find(
':' );
768 if( colonPos != wxNOT_FOUND )
770 fieldName = remainder.Left( colonPos );
771 variantName = remainder.Mid( colonPos + 1 );
783 bool resolved = refSymbol->
ResolveTextVar( &sheetPath, &fieldName, variantName, aDepth + 1 );
787 *token = std::move( fieldName );
792 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ), refSymbol->
GetRef( &sheetPath,
false ), fieldName );
803 wxString remainderBefore = remainder;
805 if( refSheet->
ResolveTextVar( &sheetPath, &remainder, aDepth + 1 ) )
806 *token = std::move( remainder );
810 if( remainderBefore.Contains( wxT(
"${" ) ) || remainderBefore.Contains( wxT(
"@{" ) ) )
826 for(
int ii = 0; ii < (int) refs.
GetCount(); ii++ )
832 if( symbolRef == ref )
840 if( symbolRef.StartsWith( ref ) && symbolRef.Length() == ref.Length() + 1 )
842 wxChar lastChar = symbolRef.Last();
843 if( lastChar >=
'A' && lastChar <=
'Z' )
854 bool resolved = foundSymbol->
ResolveTextVar( &foundPath, &fieldName, variantName, aDepth + 1 );
858 *token = std::move( fieldName );
863 *token = wxString::Format( wxT(
"<Unresolved: %s:%s>" ), foundSymbol->
GetRef( &foundPath,
false ),
871 *token = wxString::Format( wxT(
"<Unresolved: %s>" ), ref );
876 *token = wxString::Format( wxT(
"<Unknown reference: %s>" ), ref );
883 std::map<int, wxString> namesMap;
887 if( sheet.size() == 1 )
888 namesMap[sheet.GetVirtualPageNumber()] =
_(
"<root sheet>" );
890 namesMap[sheet.GetVirtualPageNumber()] = sheet.Last()->GetName();
899 std::map<int, wxString> pagesMap;
902 pagesMap[sheet.GetVirtualPageNumber()] = sheet.GetPageNumber();
911 size_t sourceLen = aSource.length();
913 for(
size_t i = 0; i < sourceLen; ++i )
917 if( aSource[i] ==
'\\' && i + 2 < sourceLen && aSource[i + 2] ==
'{' &&
918 ( aSource[i + 1] ==
'$' || aSource[i + 1] ==
'@' ) )
921 newbuf.append( aSource[i] );
922 newbuf.append( aSource[i + 1] );
923 newbuf.append( aSource[i + 2] );
928 for( i = i + 1; i < sourceLen && braceDepth > 0; ++i )
930 if( aSource[i] ==
'{' )
932 else if( aSource[i] ==
'}' )
935 newbuf.append( aSource[i] );
941 if( aSource[i] ==
'$' && i + 1 < sourceLen && aSource[i + 1] ==
'{' )
944 bool isCrossRef =
false;
947 for( i = i + 2; i < sourceLen; ++i )
949 if( aSource[i] ==
'{' && ( aSource[i - 1] ==
'_' || aSource[i - 1] ==
'^' || aSource[i - 1] ==
'~' ) )
954 if( aSource[i] ==
'}' )
962 if( aSource[i] ==
':' )
965 token.append( aSource[i] );
971 wxString ref = token.BeforeFirst(
':', &remainder );
976 for(
size_t jj = 0; jj < references.
GetCount(); jj++ )
978 SCH_SYMBOL* refSymbol = references[jj].GetSymbol();
980 if( ref == refSymbol->
GetRef( &references[jj].GetSheetPath(),
true ) )
985 token =
path.AsString() + wxS(
":" ) + remainder;
991 newbuf.append( wxS(
"${" ) + token + wxS(
"}" ) );
995 newbuf.append( aSource[i] );
1006 size_t sourceLen = aSource.length();
1008 for(
size_t i = 0; i < sourceLen; ++i )
1012 if( aSource[i] ==
'\\' && i + 2 < sourceLen && aSource[i + 2] ==
'{' &&
1013 ( aSource[i + 1] ==
'$' || aSource[i + 1] ==
'@' ) )
1016 newbuf.append( aSource[i] );
1017 newbuf.append( aSource[i + 1] );
1018 newbuf.append( aSource[i + 2] );
1023 for( i = i + 1; i < sourceLen && braceDepth > 0; ++i )
1025 if( aSource[i] ==
'{' )
1027 else if( aSource[i] ==
'}' )
1030 newbuf.append( aSource[i] );
1036 if( aSource[i] ==
'$' && i + 1 < sourceLen && aSource[i + 1] ==
'{' )
1039 bool isCrossRef =
false;
1041 for( i = i + 2; i < sourceLen; ++i )
1043 if( aSource[i] ==
'}' )
1046 if( aSource[i] ==
':' )
1049 token.append( aSource[i] );
1055 wxString ref = token.BeforeFirst(
':', &remainder );
1061 if(
path.size() > 1 )
1070 token = refSymbol->
GetRef( &sheetPath,
true ) + wxS(
":" ) + remainder;
1074 newbuf.append( wxS(
"${" ) + token + wxS(
"}" ) );
1078 newbuf.append( aSource[i] );
1101 size_t startIdx = 0;
1107 return wxEmptyString;
1110 wxString filename = rootFn.GetName();
1136 sheet_count += topSheet->CountSheets();
1145 int sheet_number = 1;
1152 if( sheet.Path() == current_sheetpath )
1158 for( screen = s_list.
GetFirst(); screen !=
nullptr; screen = s_list.
GetNext() )
1169 std::map<wxString, std::set<int>>& pageRefsMap =
GetPageRefsMap();
1171 pageRefsMap.clear();
1178 wxString resolvedLabel = global->
GetShownText( &sheet,
false );
1180 pageRefsMap[resolvedLabel].insert( sheet.GetVirtualPageNumber() );
1189 std::vector<SCH_GLOBALLABEL*> currentSheetGlobalLabels;
1192 currentSheetGlobalLabels.push_back(
static_cast<SCH_GLOBALLABEL*
>( item ) );
1196 std::vector<SCH_FIELD>& fields = globalLabel->GetFields();
1198 fields[0].SetVisible( show );
1202 if( fields.size() == 1 && fields[0].GetTextPos() == globalLabel->GetPosition() )
1207 for(
SCH_FIELD& field : globalLabel->GetFields() )
1208 field.ClearBoundingBoxCache();
1210 globalLabel->ClearBoundingBoxCache();
1221 wxString spiceNetName( aNetName.Lower() );
1224 if( spiceNetName == wxS(
"gnd" ) || spiceNetName == wxS(
"0" ) )
1225 return wxEmptyString;
1244 std::deque<EDA_ITEM*> allItems;
1246 for(
SCH_ITEM* item : screen->Items() )
1247 allItems.push_back( item );
1250 for(
const VECTOR2I& point : screen->GetNeededJunctions( allItems ) )
1253 screen->Append( junction );
1256 for(
SCH_LINE* wire : screen->GetBusesAndWires( point,
true ) )
1259 screen->Append( newSegment );
1324 for(
unsigned i = 0; i < sheetList.size(); i++ )
1380 for(
auto& [
name, libSym] : screen->GetLibSymbols() )
1381 aFunction( libSym->GetEmbeddedFiles() );
1388 std::set<KIFONT::OUTLINE_FONT*>
fonts;
1394 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
1406 if( outline->GetEmbeddingPermission() == EMBEDDING_PERMISSION::EDITABLE
1407 || outline->GetEmbeddingPermission() == EMBEDDING_PERMISSION::INSTALLABLE )
1409 fonts.insert( outline );
1429 wxLogTrace(
"EMBED",
"Failed to add font file: %s", font->GetFileName() );
1440 std::set<const SCH_SCREEN*> retv;
1453 const std::vector<SCH_SYMBOL_INSTANCE> symbolInstances = symbol->
GetInstances();
1457 if( !hierarchy.
HasPath( instance.m_Path ) )
1459 retv.insert( screen );
1464 if( retv.count( screen ) )
1481 wxCHECK2( screen,
continue );
1483 if( screen->GetRefCount() > 1 )
1494 std::vector<SCH_LINE*> lines;
1495 std::vector<SCH_JUNCTION*> junctions;
1496 std::vector<SCH_NO_CONNECT*> ncs;
1497 std::vector<SCH_ITEM*> items_to_remove;
1498 bool changed =
true;
1500 if( aScreen ==
nullptr )
1503 auto remove_item = [&](
SCH_ITEM* aItem ) ->
void
1511 if( aItem->IsSelected() && selectionTool )
1518 aCommit->
Removed( aItem, aScreen );
1530 items_to_remove.push_back( item );
1533 junctions.push_back(
static_cast<SCH_JUNCTION*
>( item ) );
1536 for(
SCH_ITEM* item : items_to_remove )
1537 remove_item( item );
1545 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
1546 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
1552 remove_item( aSecond );
1558 if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
1559 || ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
1565 remove_item( aSecond );
1569 auto minX = [](
const SCH_LINE* l )
1571 return std::min( l->GetStartPoint().x, l->GetEndPoint().x );
1574 auto maxX = [](
const SCH_LINE* l )
1576 return std::max( l->GetStartPoint().x, l->GetEndPoint().x );
1579 auto minY = [](
const SCH_LINE* l )
1581 return std::min( l->GetStartPoint().y, l->GetEndPoint().y );
1584 auto maxY = [](
const SCH_LINE* l )
1586 return std::max( l->GetStartPoint().y, l->GetEndPoint().y );
1599 lines.push_back(
static_cast<SCH_LINE*
>( item ) );
1603 std::sort( lines.begin(), lines.end(),
1606 return minX( a ) < minX( b );
1609 for(
auto it1 = lines.begin(); it1 != lines.end(); ++it1 )
1616 if( firstLine->
IsNull() )
1618 remove_item( firstLine );
1622 int firstRightXEdge = maxX( firstLine );
1625 for( ++it2; it2 != lines.end(); ++it2 )
1628 int secondLeftXEdge = minX( secondLine );
1631 if( secondLeftXEdge > firstRightXEdge )
1635 if( !( std::max( minY( firstLine ), minY( secondLine ) )
1636 <= std::min( maxY( firstLine ), maxY( secondLine ) ) ) )
1654 remove_item( secondLine );
1662 if( mergedLine !=
nullptr )
1664 remove_item( firstLine );
1665 remove_item( secondLine );
1667 if( m_schematicHolder )
1669 m_schematicHolder->AddToScreen( mergedLine, aScreen );
1672 aCommit->Added( mergedLine, aScreen );
1675 selectionTool->AddItemToSel( mergedLine,
true );
1688 std::function<
void(
SCH_ITEM* )>* aChangedItemHandler,
1697 aCommit = &localCommit;
1709 CleanUp( aCommit, sheet.LastScreen() );
1713 wxLogTrace(
"CONN_PROFILE",
"SchematicCleanUp() %0.4f ms", timer.
msecs() );
1722 m_project->GetProjectFile().NetSettings()->ClearAllCaches();
1725 std::unordered_set<SCH_SCREEN*> all_screens;
1728 all_screens.insert(
path.LastScreen() );
1745 std::set<SCH_ITEM*> changed_items;
1746 std::set<VECTOR2I> pts;
1747 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> item_paths;
1750 std::unordered_set<SCH_SCREEN*> changed_screens;
1751 std::set<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> changed_rule_areas;
1752 std::vector<CHANGED_ITEM> changed_connectable_items;
1755 auto addItemToChangeSet = [&changed_items, &pts, &item_paths]( CHANGED_ITEM itemData )
1757 std::vector<SCH_SHEET_PATH>& paths = itemData.screen->GetClientSheetPaths();
1759 std::vector<VECTOR2I> tmp_pts = itemData.item->GetConnectionPoints();
1760 pts.insert( tmp_pts.begin(), tmp_pts.end() );
1761 changed_items.insert( itemData.item );
1764 item_paths.insert( std::make_pair(
path, itemData.item ) );
1766 if( !itemData.linked_item || !itemData.linked_item->IsConnectable() )
1769 tmp_pts = itemData.linked_item->GetConnectionPoints();
1770 pts.insert( tmp_pts.begin(), tmp_pts.end() );
1771 changed_items.insert( itemData.linked_item );
1777 std::vector<SCH_PIN*> pins = symbol->GetPins();
1778 changed_items.insert( pins.begin(), pins.end() );
1782 item_paths.insert( std::make_pair(
path, itemData.linked_item ) );
1786 for(
unsigned ii = 0; ii < aLastChangeList->
GetCount(); ++ii )
1804 changed_screens.insert( screen );
1809 changed_rule_areas.insert( { ruleArea, screen } );
1814 changed_connectable_items.push_back( { item, linked_item, screen } );
1820 std::vector<std::pair<SCH_RULE_AREA*, SCH_SCREEN*>> forceUpdateRuleAreas =
1823 std::for_each( forceUpdateRuleAreas.begin(), forceUpdateRuleAreas.end(),
1824 [&]( std::pair<SCH_RULE_AREA*, SCH_SCREEN*>& updatedRuleArea )
1826 changed_rule_areas.insert( updatedRuleArea );
1831 std::map<KIID, EDA_ITEM*> itemMap;
1832 list.FillItemMap( itemMap );
1838 if( itemMap.contains( pastItem ) )
1839 addItemToChangeSet( {
static_cast<SCH_ITEM*
>( itemMap[pastItem] ),
nullptr, screen } );
1843 addItemToChangeSet( { containedItem,
nullptr, screen } );
1846 for(
const auto& [changedRuleArea, screen] : changed_rule_areas )
1847 addPastAndPresentContainedItems( changedRuleArea, screen );
1850 for( CHANGED_ITEM& changed_item_data : changed_connectable_items )
1852 addItemToChangeSet( changed_item_data );
1858 const std::vector<VECTOR2I> labelConnectionPoints = changed_item_data.item->GetConnectionPoints();
1860 auto candidateRuleAreas = changed_item_data.screen->Items().Overlapping(
1863 for(
SCH_ITEM* candidateRuleArea : candidateRuleAreas )
1869 addPastAndPresentContainedItems( ruleArea, changed_item_data.screen );
1879 if( !item->IsConnectable() )
1884 if( item->HitTest( pt ) )
1885 changed_items.insert( item );
1887 else if( item->Type() ==
SCH_SYMBOL_T && item->IsConnected( pt ) )
1890 std::vector<SCH_PIN*> pins = symbol->
GetPins();
1892 changed_items.insert( pins.begin(), pins.end() );
1898 wxCHECK2( sheet,
continue );
1900 std::vector<SCH_SHEET_PIN*> sheetPins = sheet->
GetPins();
1901 changed_items.insert( sheetPins.begin(), sheetPins.end() );
1905 if( item->IsConnected( pt ) )
1906 changed_items.insert( item );
1911 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> all_items =
1914 all_items.insert( item_paths.begin(), item_paths.end() );
1920 std::shared_ptr<NET_SETTINGS> netSettings =
m_project->GetProjectFile().NetSettings();
1922 std::set<wxString> affectedNets;
1924 for(
auto& [
path, item] : all_items )
1926 wxCHECK2( item,
continue );
1927 item->SetConnectivityDirty();
1931 affectedNets.insert( conn->
Name() );
1936 for(
const CHANGED_ITEM& changedItem : changed_connectable_items )
1940 const wxString& driverName = label->GetCachedDriverName();
1942 if( !driverName.IsEmpty() )
1943 affectedNets.insert( driverName );
1948 const wxString& driverName = linkedLabel->GetCachedDriverName();
1950 if( !driverName.IsEmpty() )
1951 affectedNets.insert( driverName );
1956 for(
const wxString& netName : affectedNets )
1957 netSettings->ClearCacheForNet( netName );
1959 new_graph.
Recalculate( list,
false, aChangedItemHandler, aProgressReporter );
1963 if( !localCommit.
Empty() )
1964 localCommit.
Push(
_(
"Schematic Cleanup" ) );
2003 size_t index =
static_cast<size_t>( aIndex );
2013 wxCHECK_RET( aSheet, wxS(
"Cannot add null sheet!" ) );
2014 wxCHECK_RET( aSheet->
GetScreen(), wxS(
"Cannot add virtual root as top-level sheet!" ) );
2047 m_rootSheet->GetScreen()->Items().remove( aSheet );
2074 wxLogTrace(
traceSchSheetPaths,
"BuildSheetListSortedByPageNumbers: %zu top-level sheets",
2086 wxLogTrace(
traceSchSheetPaths,
" Top-level sheet: '%s' (UUID=%s, isVirtualRoot=%d)", sheet->GetName(),
2087 sheet->m_Uuid.AsString(), sheet->m_Uuid ==
niluuid ? 1 : 0 );
2096 hierarchy.push_back(
path );
2122 sheets.push_back(
path );
2133 wxArrayString variantNames;
2139 variantNames.Add(
name );
2143 return variantNames;
2150 return wxEmptyString;
2173 if( descriptions.find( aVariantName ) == descriptions.end() )
2174 descriptions[aVariantName] = wxEmptyString;
2195 wxCHECK( !aOldName.IsEmpty() && !aNewName.IsEmpty(), );
2203 if( descriptions.count( aOldName ) )
2205 descriptions[aNewName] = descriptions[aOldName];
2206 descriptions.erase( aOldName );
2221 wxCHECK( !aSourceVariant.IsEmpty() && !aNewVariant.IsEmpty(), );
2229 if( descriptions.count( aSourceVariant ) )
2230 descriptions[aNewVariant] = descriptions[aSourceVariant];
2233 allScreens.
CopyVariant( aSourceVariant, aNewVariant, aCommit );
2240 auto it = descriptions.find( aVariantName );
2242 if( it != descriptions.end() )
2245 return wxEmptyString;
2253 if( aDescription.IsEmpty() )
2254 descriptions.erase( aVariantName );
2256 descriptions[aVariantName] = aDescription;
2266 m_variantNames.insert( variantNames.begin(), variantNames.end() );
2271 for(
const wxString&
name : variantNames )
2273 if( descriptions.find(
name ) == descriptions.end() )
2274 descriptions[
name] = wxEmptyString;
2282 wxString projPath =
m_project->GetProjectPath();
2284 if( projPath.IsEmpty() )
2288 if( !projPath.IsSameAs( aProjectPath ) )
2290 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver skipping - project path mismatch: %s vs %s" ), projPath,
2296 if( !projPath.EndsWith( wxFILE_SEP_PATH ) )
2297 projPath += wxFILE_SEP_PATH;
2299 wxFileName historyRoot( projPath, wxEmptyString );
2300 historyRoot.AppendDir( wxS(
".history" ) );
2301 wxString historyRootPath = historyRoot.GetPath();
2314 if( !sheet || !screen )
2322 wxString absPath = abs.GetFullPath();
2324 if( absPath.IsEmpty() || !absPath.StartsWith( projPath ) )
2327 wxString rel = absPath.Mid( projPath.length() );
2330 wxFileName dst( rel );
2332 if( dst.IsRelative() )
2333 dst.MakeAbsolute( historyRootPath );
2335 dst.SetPath( historyRootPath );
2338 wxFileName dstDir( dst );
2339 dstDir.SetFullName( wxEmptyString );
2341 if( !dstDir.DirExists() )
2342 wxFileName::Mkdir( dstDir.GetPath(), 0777, wxPATH_MKDIR_FULL );
2346 pi->SaveSchematicFile( dst.GetFullPath(), sheet,
this );
2347 aFiles.push_back( dst.GetFullPath() );
2348 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver exported sheet '%s' -> '%s'" ), absPath,
2349 dst.GetFullPath() );
2353 wxLogTrace(
traceAutoSave, wxS(
"[history] sch saver export failed for '%s': %s" ), absPath,
2354 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.
virtual void SetParent(EDA_ITEM *aParent)
EDA_ITEM * GetParent() const
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)
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.
void FixupJunctionsAfterImport()
Add junctions to this schematic where required.
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)
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...
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false) const
Return the sheet path in a human readable form made from the sheet names.
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.
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.
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
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.
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
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