Remove SetRoot()
Gets rid of the SetRoot() because we don't have roots anymore so this was confusing. We now use SetTopLevelSheets() to add sheets to the virtual root. Ensure that the hierarchy is maintained on each transition
This commit is contained in:
+4
-15
@@ -98,23 +98,12 @@ static std::unique_ptr<SCHEMATIC> readSchematicFromFile( const std::string& aFil
|
||||
manager.LoadProject( "" );
|
||||
schematic->Reset();
|
||||
schematic->SetProject( &manager.Prj() );
|
||||
schematic->SetRoot( pi->LoadSchematicFile( aFilename, schematic.get() ) );
|
||||
SCH_SHEET* rootSheet = pi->LoadSchematicFile( aFilename, schematic.get() );
|
||||
|
||||
// Set current sheet to the first top-level sheet, not the virtual root
|
||||
std::vector<SCH_SHEET*> topLevelSheets = schematic->GetTopLevelSheets();
|
||||
if( !rootSheet )
|
||||
return nullptr;
|
||||
|
||||
if( !topLevelSheets.empty() )
|
||||
{
|
||||
schematic->CurrentSheet().push_back( topLevelSheets[0] );
|
||||
wxLogTrace( traceSchCurrentSheet,
|
||||
"Set current sheet to first top-level sheet: %s, path: %s",
|
||||
topLevelSheets[0]->GetName(),
|
||||
schematic->CurrentSheet().Path().AsString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogWarning( "No top-level sheets found after loading schematic!" );
|
||||
}
|
||||
schematic->SetTopLevelSheets( { rootSheet } );
|
||||
|
||||
SCH_SCREENS screens( schematic->Root() );
|
||||
|
||||
|
||||
@@ -155,7 +155,12 @@ SCHEMATIC* EESCHEMA_HELPERS::LoadSchematic( const wxString& aFileName,
|
||||
|
||||
try
|
||||
{
|
||||
schematic->SetRoot( pi->LoadSchematicFile( schFile.GetFullPath(), schematic ) );
|
||||
SCH_SHEET* rootSheet = pi->LoadSchematicFile( schFile.GetFullPath(), schematic );
|
||||
|
||||
if( rootSheet )
|
||||
schematic->SetTopLevelSheets( { rootSheet } );
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
|
||||
+31
-29
@@ -272,8 +272,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
|
||||
if( !topLevelSheets.empty() )
|
||||
{
|
||||
// New multi-root format: Load all top-level sheets
|
||||
// Note: AddTopLevelSheet will create the virtual root as needed
|
||||
std::vector<SCH_SHEET*> loadedSheets;
|
||||
|
||||
// Load each top-level sheet
|
||||
for( const TOP_LEVEL_SHEET_INFO& sheetInfo : topLevelSheets )
|
||||
@@ -304,9 +303,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
}
|
||||
|
||||
sheet->SetName( sheetInfo.name );
|
||||
|
||||
// Regular top-level sheet, add it normally
|
||||
newSchematic->AddTopLevelSheet( sheet );
|
||||
loadedSheets.push_back( sheet );
|
||||
|
||||
wxLogTrace( tracePathsAndFiles,
|
||||
wxS( "Loaded top-level sheet '%s' (UUID %s) from %s" ),
|
||||
@@ -316,17 +313,9 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
}
|
||||
}
|
||||
|
||||
// Virtual root was already created by AddTopLevelSheet, no need to call SetRoot
|
||||
// Set current sheet to the first top-level sheet
|
||||
if( !newSchematic->GetTopLevelSheets().empty() )
|
||||
if( !loadedSheets.empty() )
|
||||
{
|
||||
newSchematic->CurrentSheet().clear();
|
||||
newSchematic->CurrentSheet().push_back( newSchematic->GetTopLevelSheets()[0] );
|
||||
|
||||
wxLogTrace( tracePathsAndFiles,
|
||||
wxS( "Loaded multi-root schematic with %zu top-level sheets, current sheet set to '%s'" ),
|
||||
newSchematic->GetTopLevelSheets().size(),
|
||||
newSchematic->GetTopLevelSheets()[0]->GetName() );
|
||||
newSchematic->SetTopLevelSheets( loadedSheets );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -338,20 +327,31 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
else
|
||||
{
|
||||
// Legacy single-root format: Load the single root sheet
|
||||
newSchematic->SetRoot( pi->LoadSchematicFile( fullFileName, newSchematic.get() ) );
|
||||
SCH_SHEET* rootSheet = pi->LoadSchematicFile( fullFileName, newSchematic.get() );
|
||||
|
||||
// Make ${SHEETNAME} work on the root sheet until we properly support
|
||||
// naming the root sheet
|
||||
newSchematic->Root().SetName( _( "Root" ) );
|
||||
if( rootSheet )
|
||||
{
|
||||
newSchematic->SetTopLevelSheets( { rootSheet } );
|
||||
|
||||
// Make ${SHEETNAME} work on the root sheet until we properly support
|
||||
// naming the root sheet
|
||||
if( SCH_SHEET* topSheet = newSchematic->GetTopLevelSheet() )
|
||||
topSheet->SetName( _( "Root" ) );
|
||||
|
||||
wxLogTrace( tracePathsAndFiles,
|
||||
wxS( "Loaded schematic with root sheet UUID %s" ),
|
||||
rootSheet->m_Uuid.AsString() );
|
||||
wxLogTrace( traceSchCurrentSheet,
|
||||
"After loading: Current sheet path='%s', size=%zu, empty=%d",
|
||||
newSchematic->CurrentSheet().Path().AsString(),
|
||||
newSchematic->CurrentSheet().size(),
|
||||
newSchematic->CurrentSheet().empty() ? 1 : 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
newSchematic->CreateDefaultScreens();
|
||||
}
|
||||
|
||||
wxLogTrace( tracePathsAndFiles,
|
||||
wxS( "Loaded schematic with root sheet UUID %s" ),
|
||||
newSchematic->Root().m_Uuid.AsString() );
|
||||
wxLogTrace( traceSchCurrentSheet,
|
||||
"After loading: Current sheet path='%s', size=%zu, empty=%d",
|
||||
newSchematic->CurrentSheet().Path().AsString(),
|
||||
newSchematic->CurrentSheet().size(),
|
||||
newSchematic->CurrentSheet().empty() ? 1 : 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1458,7 +1458,7 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
|
||||
|
||||
if( loadedSheet )
|
||||
{
|
||||
Schematic().SetRoot( loadedSheet );
|
||||
Schematic().SetTopLevelSheets( { loadedSheet } );
|
||||
|
||||
if( errorReporter.m_Reporter->HasMessage() )
|
||||
{
|
||||
@@ -1478,7 +1478,9 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
|
||||
|
||||
SetScreen( Schematic().RootScreen() );
|
||||
|
||||
Schematic().Root().SetFileName( newfilename.GetFullName() );
|
||||
if( SCH_SHEET* topSheet = Schematic().GetTopLevelSheet() )
|
||||
topSheet->SetFileName( newfilename.GetFullName() );
|
||||
|
||||
GetScreen()->SetFileName( newfilename.GetFullPath() );
|
||||
GetScreen()->SetContentModified();
|
||||
|
||||
|
||||
@@ -465,14 +465,14 @@ SCH_SHEET* SCH_IO_ALTIUM::LoadSchematicFile( const wxString& aFileName, SCHEMATI
|
||||
if( aAppendToMe )
|
||||
{
|
||||
wxCHECK_MSG( aSchematic->IsValid(), nullptr, "Can't append to a schematic with no root!" );
|
||||
m_rootSheet = &aSchematic->Root();
|
||||
m_rootSheet = aAppendToMe;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rootSheet = new SCH_SHEET( aSchematic );
|
||||
m_rootSheet->SetFileName( fileName.GetFullPath() );
|
||||
|
||||
aSchematic->SetRoot( m_rootSheet );
|
||||
aSchematic->SetTopLevelSheets( { m_rootSheet } );
|
||||
|
||||
SCH_SHEET_PATH sheetpath;
|
||||
sheetpath.push_back( m_rootSheet );
|
||||
|
||||
@@ -79,13 +79,13 @@ SCH_SHEET* SCH_IO_CADSTAR_ARCHIVE::LoadSchematicFile( const wxString& aFi
|
||||
if( aAppendToMe )
|
||||
{
|
||||
wxCHECK_MSG( aSchematic->IsValid(), nullptr, "Can't append to a schematic with no root!" );
|
||||
rootSheet = &aSchematic->Root();
|
||||
rootSheet = aAppendToMe;
|
||||
}
|
||||
else
|
||||
{
|
||||
rootSheet = new SCH_SHEET( aSchematic );
|
||||
rootSheet->SetFileName( aFileName );
|
||||
aSchematic->SetRoot( rootSheet );
|
||||
aSchematic->SetTopLevelSheets( { rootSheet } );
|
||||
}
|
||||
|
||||
if( !rootSheet->GetScreen() )
|
||||
|
||||
@@ -406,7 +406,7 @@ SCH_SHEET* SCH_IO_EAGLE::LoadSchematicFile( const wxString& aFileName, SCHEMATIC
|
||||
m_rootSheet = new SCH_SHEET( aSchematic );
|
||||
const_cast<KIID&>( m_rootSheet->m_Uuid ) = niluuid;
|
||||
m_rootSheet->SetFileName( newFilename.GetFullPath() );
|
||||
aSchematic->SetRoot( m_rootSheet );
|
||||
aSchematic->SetTopLevelSheets( { m_rootSheet } );
|
||||
}
|
||||
|
||||
if( !m_rootSheet->GetScreen() )
|
||||
|
||||
@@ -625,13 +625,13 @@ SCH_SHEET* SCH_IO_EASYEDA::LoadSchematicFile( const wxString& aFileName, SCHEMAT
|
||||
wxCHECK_MSG( aSchematic->IsValid(), nullptr,
|
||||
wxS( "Can't append to a schematic with no root!" ) );
|
||||
|
||||
rootSheet = &aSchematic->Root();
|
||||
rootSheet = aAppendToMe;
|
||||
}
|
||||
else
|
||||
{
|
||||
rootSheet = new SCH_SHEET( aSchematic );
|
||||
rootSheet->SetFileName( aFileName );
|
||||
aSchematic->SetRoot( rootSheet );
|
||||
aSchematic->SetTopLevelSheets( { rootSheet } );
|
||||
}
|
||||
|
||||
if( !rootSheet->GetScreen() )
|
||||
|
||||
@@ -442,13 +442,13 @@ SCH_SHEET* SCH_IO_EASYEDAPRO::LoadSchematicFile( const wxString& aFileName,
|
||||
wxCHECK_MSG( aSchematic->IsValid(), nullptr,
|
||||
wxS( "Can't append to a schematic with no root!" ) );
|
||||
|
||||
rootSheet = &aSchematic->Root();
|
||||
rootSheet = aAppendToMe;
|
||||
}
|
||||
else
|
||||
{
|
||||
rootSheet = new SCH_SHEET( aSchematic );
|
||||
rootSheet->SetFileName( aFileName );
|
||||
aSchematic->SetRoot( rootSheet );
|
||||
aSchematic->SetTopLevelSheets( { rootSheet } );
|
||||
}
|
||||
|
||||
if( !rootSheet->GetScreen() )
|
||||
|
||||
@@ -50,13 +50,13 @@ SCH_SHEET* SCH_IO_LTSPICE::LoadSchematicFile( const wxString& aFileName, SCHEMAT
|
||||
if( aAppendToMe )
|
||||
{
|
||||
wxCHECK_MSG( aSchematic->IsValid(), nullptr, "Can't append to a schematic with no root!" );
|
||||
rootSheet = &aSchematic->Root();
|
||||
rootSheet = aAppendToMe;
|
||||
}
|
||||
else
|
||||
{
|
||||
rootSheet = new SCH_SHEET( aSchematic );
|
||||
rootSheet->SetFileName( aFileName );
|
||||
aSchematic->SetRoot( rootSheet );
|
||||
aSchematic->SetTopLevelSheets( { rootSheet } );
|
||||
}
|
||||
|
||||
if( !rootSheet->GetScreen() )
|
||||
|
||||
+148
-146
@@ -137,6 +137,8 @@ SCHEMATIC::SCHEMATIC( PROJECT* aPrj ) :
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -157,11 +159,15 @@ void SCHEMATIC::Reset()
|
||||
|
||||
m_rootSheet = nullptr;
|
||||
m_topLevelSheets.clear();
|
||||
m_hierarchy.clear();
|
||||
|
||||
m_connectionGraph->Reset();
|
||||
m_currentSheet->clear();
|
||||
|
||||
m_busAliases.clear();
|
||||
|
||||
ensureVirtualRoot();
|
||||
ensureDefaultTopLevelSheet();
|
||||
}
|
||||
|
||||
|
||||
@@ -235,127 +241,139 @@ bool SCHEMATIC::Contains( const SCH_REFERENCE& aRef ) const
|
||||
}
|
||||
|
||||
|
||||
void SCHEMATIC::SetRoot( SCH_SHEET* aRootSheet )
|
||||
void SCHEMATIC::ensureVirtualRoot()
|
||||
{
|
||||
wxCHECK_RET( aRootSheet, wxS( "Call to SetRoot with null SCH_SHEET!" ) );
|
||||
|
||||
// Check if this is a virtual root (has niluuid) or a regular sheet
|
||||
bool isVirtualRoot = ( aRootSheet->m_Uuid == niluuid );
|
||||
|
||||
wxLogTrace( traceSchSheetPaths,
|
||||
"SetRoot called: sheet='%s', UUID=%s, isVirtualRoot=%d, m_topLevelSheets.size()=%zu",
|
||||
aRootSheet->GetName(), aRootSheet->m_Uuid.AsString(), isVirtualRoot ? 1 : 0, m_topLevelSheets.size() );
|
||||
|
||||
for( size_t i = 0; i < m_topLevelSheets.size(); ++i )
|
||||
if( m_rootSheet && m_rootSheet->m_Uuid == niluuid )
|
||||
{
|
||||
SCH_SHEET* sheet = m_topLevelSheets[i];
|
||||
wxLogTrace( traceSchSheetPaths, " m_topLevelSheets[%zu]: '%s' (UUID=%s, isVirtualRoot=%d)", i,
|
||||
sheet ? sheet->GetName() : wxString( "(null)" ),
|
||||
sheet ? sheet->m_Uuid.AsString() : wxString( "(null)" ),
|
||||
sheet && sheet->m_Uuid == niluuid ? 1 : 0 );
|
||||
if( !m_rootSheet->GetScreen() )
|
||||
m_rootSheet->SetScreen( new SCH_SCREEN( this ) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if( isVirtualRoot )
|
||||
SCH_SHEET* previousRoot = m_rootSheet;
|
||||
|
||||
m_rootSheet = new SCH_SHEET( this );
|
||||
const_cast<KIID&>( m_rootSheet->m_Uuid ) = niluuid;
|
||||
m_rootSheet->SetScreen( new SCH_SCREEN( this ) );
|
||||
|
||||
if( previousRoot )
|
||||
{
|
||||
// aRootSheet is already the virtual root, use it directly
|
||||
m_rootSheet = aRootSheet;
|
||||
previousRoot->SetParent( m_rootSheet );
|
||||
|
||||
// Ensure virtual root has a screen to hold top-level sheets
|
||||
// Only create if we have a project (screens need a valid schematic parent)
|
||||
if( !m_rootSheet->GetScreen() && m_project )
|
||||
{
|
||||
m_rootSheet->SetScreen( new SCH_SCREEN( this ) );
|
||||
}
|
||||
|
||||
// Add all existing top-level sheets to the virtual root's screen
|
||||
if( m_rootSheet->GetScreen() )
|
||||
{
|
||||
for( SCH_SHEET* sheet : m_topLevelSheets )
|
||||
{
|
||||
if( sheet && sheet->GetParent() != m_rootSheet )
|
||||
{
|
||||
sheet->SetParent( m_rootSheet );
|
||||
}
|
||||
m_rootSheet->GetScreen()->Append( previousRoot );
|
||||
|
||||
// Add to screen if not already there
|
||||
if( sheet && !m_rootSheet->GetScreen()->Items().contains( sheet ) )
|
||||
{
|
||||
m_rootSheet->GetScreen()->Append( sheet );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Current sheet should point to the first top-level sheet if available
|
||||
m_currentSheet->clear();
|
||||
|
||||
if( !m_topLevelSheets.empty() )
|
||||
{
|
||||
m_currentSheet->push_back( m_topLevelSheets[0] );
|
||||
wxLogTrace( traceSchCurrentSheet,
|
||||
"SetRoot: Set current sheet to first top-level sheet '%s', path='%s', size=%zu",
|
||||
m_topLevelSheets[0]->GetName(), m_currentSheet->Path().AsString(), m_currentSheet->size() );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogTrace( traceSchCurrentSheet, "SetRoot: No top-level sheets, current sheet left empty" );
|
||||
}
|
||||
// If no top-level sheets, leave current sheet empty - it will be set when sheets are added
|
||||
}
|
||||
else
|
||||
{
|
||||
// aRootSheet is a regular sheet, create virtual root and make it a child
|
||||
if( m_rootSheet == nullptr || m_rootSheet->m_Uuid != niluuid )
|
||||
{
|
||||
// Need to create a new virtual root
|
||||
m_rootSheet = new SCH_SHEET( this );
|
||||
const_cast<KIID&>( m_rootSheet->m_Uuid ) = niluuid;
|
||||
// Create screen only if we have a project
|
||||
if( m_project )
|
||||
{
|
||||
m_rootSheet->SetScreen( new SCH_SCREEN( this ) );
|
||||
}
|
||||
}
|
||||
else if( m_project && !m_rootSheet->GetScreen() )
|
||||
{
|
||||
// Virtual root exists but has no screen - create one now
|
||||
m_rootSheet->SetScreen( new SCH_SCREEN( this ) );
|
||||
}
|
||||
|
||||
// Add this sheet as a top-level sheet
|
||||
m_topLevelSheets.clear();
|
||||
m_topLevelSheets.push_back( aRootSheet );
|
||||
aRootSheet->SetParent( m_rootSheet );
|
||||
|
||||
// Clear the virtual root's screen and add only the new sheet
|
||||
if( m_rootSheet->GetScreen() )
|
||||
{
|
||||
// Don't free the sheet being added if it already exists in the screen
|
||||
m_rootSheet->GetScreen()->Items().remove( aRootSheet );
|
||||
m_rootSheet->GetScreen()->Clear();
|
||||
m_rootSheet->GetScreen()->Append( aRootSheet );
|
||||
}
|
||||
|
||||
m_currentSheet->clear();
|
||||
m_currentSheet->push_back( aRootSheet );
|
||||
wxLogTrace( traceSchCurrentSheet, "SetRoot: Set current sheet to root sheet '%s', path='%s', size=%zu",
|
||||
aRootSheet->GetName(), m_currentSheet->Path().AsString(), m_currentSheet->size() );
|
||||
m_topLevelSheets.push_back( previousRoot );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_project )
|
||||
|
||||
void SCHEMATIC::ensureDefaultTopLevelSheet()
|
||||
{
|
||||
ensureVirtualRoot();
|
||||
|
||||
if( !m_topLevelSheets.empty() )
|
||||
return;
|
||||
|
||||
SCH_SHEET* rootSheet = new SCH_SHEET( this );
|
||||
SCH_SCREEN* rootScreen = new SCH_SCREEN( this );
|
||||
|
||||
const_cast<KIID&>( rootSheet->m_Uuid ) = rootScreen->GetUuid();
|
||||
rootSheet->SetScreen( rootScreen );
|
||||
|
||||
SetTopLevelSheets( { rootSheet } );
|
||||
|
||||
SCH_SHEET_PATH rootSheetPath;
|
||||
rootSheetPath.push_back( m_rootSheet );
|
||||
rootSheetPath.push_back( rootSheet );
|
||||
rootSheetPath.SetPageNumber( wxT( "1" ) );
|
||||
}
|
||||
|
||||
|
||||
void SCHEMATIC::ensureCurrentSheetIsTopLevel()
|
||||
{
|
||||
if( m_topLevelSheets.empty() )
|
||||
return;
|
||||
|
||||
if( m_currentSheet->empty() || !IsTopLevelSheet( m_currentSheet->at( 0 ) ) )
|
||||
{
|
||||
m_hierarchy = BuildSheetListSortedByPageNumbers();
|
||||
m_currentSheet->clear();
|
||||
m_currentSheet->push_back( m_topLevelSheets[0] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCHEMATIC::rebuildHierarchyState( bool aResetConnectionGraph )
|
||||
{
|
||||
RefreshHierarchy();
|
||||
|
||||
if( aResetConnectionGraph && m_project )
|
||||
m_connectionGraph->Reset();
|
||||
|
||||
// Build screen list from root (which now has a screen)
|
||||
m_variantNames.clear();
|
||||
m_variantNames.clear();
|
||||
|
||||
if( m_rootSheet && m_rootSheet->GetScreen() )
|
||||
{
|
||||
SCH_SCREENS screens( m_rootSheet );
|
||||
std::set<wxString> variantNames = screens.GetVariantNames();
|
||||
m_variantNames.insert( variantNames.begin(), variantNames.end() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCHEMATIC::SetTopLevelSheets( const std::vector<SCH_SHEET*>& aSheets )
|
||||
{
|
||||
wxCHECK_RET( !aSheets.empty(), wxS( "Cannot set empty top-level sheets!" ) );
|
||||
|
||||
std::vector<SCH_SHEET*> validSheets;
|
||||
validSheets.reserve( aSheets.size() );
|
||||
|
||||
for( SCH_SHEET* sheet : aSheets )
|
||||
{
|
||||
if( sheet )
|
||||
validSheets.push_back( sheet );
|
||||
}
|
||||
|
||||
if( validSheets.empty() )
|
||||
{
|
||||
ensureDefaultTopLevelSheet();
|
||||
return;
|
||||
}
|
||||
|
||||
ensureVirtualRoot();
|
||||
|
||||
std::set<SCH_SHEET*> desiredSheets( validSheets.begin(), validSheets.end() );
|
||||
|
||||
if( m_rootSheet->GetScreen() )
|
||||
{
|
||||
for( SCH_ITEM* item : m_rootSheet->GetScreen()->Items() )
|
||||
{
|
||||
SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( item );
|
||||
|
||||
if( sheet && !desiredSheets.contains( sheet ) )
|
||||
delete sheet;
|
||||
}
|
||||
|
||||
m_rootSheet->GetScreen()->Clear( false );
|
||||
}
|
||||
|
||||
m_currentSheet->clear();
|
||||
m_topLevelSheets.clear();
|
||||
|
||||
for( SCH_SHEET* sheet : validSheets )
|
||||
{
|
||||
sheet->SetParent( m_rootSheet );
|
||||
|
||||
if( m_rootSheet->GetScreen() )
|
||||
{
|
||||
SCH_SCREENS screens( m_rootSheet );
|
||||
std::set<wxString> variantNames = screens.GetVariantNames();
|
||||
m_variantNames.insert( variantNames.begin(), variantNames.end() );
|
||||
}
|
||||
m_rootSheet->GetScreen()->Append( sheet );
|
||||
|
||||
m_topLevelSheets.push_back( sheet );
|
||||
}
|
||||
|
||||
ensureCurrentSheetIsTopLevel();
|
||||
rebuildHierarchyState( true );
|
||||
}
|
||||
|
||||
|
||||
@@ -380,6 +398,7 @@ SCH_SHEET_LIST SCHEMATIC::Hierarchy() const
|
||||
|
||||
void SCHEMATIC::RefreshHierarchy()
|
||||
{
|
||||
ensureDefaultTopLevelSheet();
|
||||
m_hierarchy = BuildSheetListSortedByPageNumbers();
|
||||
}
|
||||
|
||||
@@ -1891,10 +1910,7 @@ void SCHEMATIC::CreateDefaultScreens()
|
||||
{
|
||||
Reset();
|
||||
|
||||
// Create virtual root with niluuid and a screen to hold top-level sheets
|
||||
SCH_SHEET* virtualRoot = new SCH_SHEET( this );
|
||||
const_cast<KIID&>( virtualRoot->m_Uuid ) = niluuid;
|
||||
virtualRoot->SetScreen( new SCH_SCREEN( this ) ); // Virtual root has a screen
|
||||
ensureVirtualRoot();
|
||||
|
||||
// Create the actual first top-level sheet
|
||||
SCH_SHEET* rootSheet = new SCH_SHEET( this );
|
||||
@@ -1905,28 +1921,13 @@ void SCHEMATIC::CreateDefaultScreens()
|
||||
rootScreen->SetFileName( "untitled.kicad_sch" ); // Set default filename to avoid conflicts
|
||||
rootScreen->SetPageNumber( wxT( "1" ) );
|
||||
|
||||
// Set parent to virtual root
|
||||
rootSheet->SetParent( virtualRoot );
|
||||
|
||||
// Add the top-level sheet to the virtual root's screen
|
||||
virtualRoot->GetScreen()->Append( rootSheet );
|
||||
|
||||
// Don't leave root page number empty
|
||||
SCH_SHEET_PATH rootSheetPath;
|
||||
rootSheetPath.push_back( virtualRoot );
|
||||
rootSheetPath.push_back( m_rootSheet );
|
||||
rootSheetPath.push_back( rootSheet );
|
||||
rootSheetPath.SetPageNumber( wxT( "1" ) );
|
||||
|
||||
// Set up the schematic structure
|
||||
m_rootSheet = virtualRoot;
|
||||
m_topLevelSheets.clear();
|
||||
m_topLevelSheets.push_back( rootSheet );
|
||||
|
||||
m_currentSheet->clear();
|
||||
m_currentSheet->push_back( rootSheet );
|
||||
|
||||
// Rehash sheetpaths in hierarchy since we changed the uuid.
|
||||
RefreshHierarchy();
|
||||
SetTopLevelSheets( { rootSheet } );
|
||||
}
|
||||
|
||||
|
||||
@@ -1935,29 +1936,25 @@ std::vector<SCH_SHEET*> SCHEMATIC::GetTopLevelSheets() const
|
||||
return m_topLevelSheets;
|
||||
}
|
||||
|
||||
SCH_SHEET* SCHEMATIC::GetTopLevelSheet( int aIndex ) const
|
||||
{
|
||||
if( aIndex < 0 )
|
||||
return nullptr;
|
||||
|
||||
size_t index = static_cast<size_t>( aIndex );
|
||||
|
||||
if( index >= m_topLevelSheets.size() )
|
||||
return nullptr;
|
||||
|
||||
return m_topLevelSheets[index];
|
||||
}
|
||||
|
||||
void SCHEMATIC::AddTopLevelSheet( SCH_SHEET* aSheet )
|
||||
{
|
||||
wxCHECK_RET( aSheet, wxS( "Cannot add null sheet!" ) );
|
||||
wxCHECK_RET( aSheet->GetScreen(), wxS( "Cannot add virtual root as top-level sheet!" ) );
|
||||
|
||||
// Make sure we have a virtual root
|
||||
if( m_rootSheet == nullptr )
|
||||
{
|
||||
m_rootSheet = new SCH_SHEET( this );
|
||||
const_cast<KIID&>( m_rootSheet->m_Uuid ) = niluuid;
|
||||
// Create screen only if we have a project
|
||||
if( m_project )
|
||||
{
|
||||
m_rootSheet->SetScreen( new SCH_SCREEN( this ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure virtual root has a screen (may have been created before project was set)
|
||||
if( !m_rootSheet->GetScreen() && m_project )
|
||||
{
|
||||
m_rootSheet->SetScreen( new SCH_SCREEN( this ) );
|
||||
}
|
||||
ensureVirtualRoot();
|
||||
|
||||
// Set parent to virtual root
|
||||
aSheet->SetParent( m_rootSheet );
|
||||
@@ -1971,11 +1968,10 @@ void SCHEMATIC::AddTopLevelSheet( SCH_SHEET* aSheet )
|
||||
// Add to our list
|
||||
m_topLevelSheets.push_back( aSheet );
|
||||
|
||||
// Refresh hierarchy
|
||||
RefreshHierarchy();
|
||||
ensureCurrentSheetIsTopLevel();
|
||||
rebuildHierarchyState( true );
|
||||
}
|
||||
|
||||
|
||||
bool SCHEMATIC::RemoveTopLevelSheet( SCH_SHEET* aSheet )
|
||||
{
|
||||
auto it = std::find( m_topLevelSheets.begin(), m_topLevelSheets.end(), aSheet );
|
||||
@@ -1983,8 +1979,14 @@ bool SCHEMATIC::RemoveTopLevelSheet( SCH_SHEET* aSheet )
|
||||
if( it == m_topLevelSheets.end() )
|
||||
return false;
|
||||
|
||||
if( m_topLevelSheets.size() == 1 )
|
||||
return false;
|
||||
|
||||
m_topLevelSheets.erase( it );
|
||||
|
||||
if( m_rootSheet && m_rootSheet->GetScreen() )
|
||||
m_rootSheet->GetScreen()->Items().remove( aSheet );
|
||||
|
||||
// If we're removing the current sheet, switch to another one
|
||||
if( !m_currentSheet->empty() && m_currentSheet->at( 0 ) == aSheet )
|
||||
{
|
||||
@@ -1995,7 +1997,7 @@ bool SCHEMATIC::RemoveTopLevelSheet( SCH_SHEET* aSheet )
|
||||
}
|
||||
}
|
||||
|
||||
RefreshHierarchy();
|
||||
rebuildHierarchyState( true );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+9
-10
@@ -127,16 +127,6 @@ public:
|
||||
return *m_rootSheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the schematic with a new root sheet.
|
||||
*
|
||||
* This is typically done by calling a file loader that returns the new root sheet
|
||||
* As a side-effect, takes care of some post-load initialization.
|
||||
*
|
||||
* @param aRootSheet is the new root sheet for this schematic.
|
||||
*/
|
||||
void SetRoot( SCH_SHEET* aRootSheet );
|
||||
|
||||
/**
|
||||
* Get the list of top-level sheets.
|
||||
*
|
||||
@@ -144,6 +134,10 @@ public:
|
||||
*/
|
||||
std::vector<SCH_SHEET*> GetTopLevelSheets() const;
|
||||
|
||||
SCH_SHEET* GetTopLevelSheet( int aIndex = 0 ) const;
|
||||
|
||||
void SetTopLevelSheets( const std::vector<SCH_SHEET*>& aSheets );
|
||||
|
||||
/**
|
||||
* Add a new top-level sheet to the schematic.
|
||||
*
|
||||
@@ -497,6 +491,11 @@ private:
|
||||
( l->*aFunc )( std::forward<Args>( args )... );
|
||||
}
|
||||
|
||||
void ensureVirtualRoot();
|
||||
void ensureDefaultTopLevelSheet();
|
||||
void ensureCurrentSheetIsTopLevel();
|
||||
void rebuildHierarchyState( bool aResetConnectionGraph );
|
||||
|
||||
PROJECT* m_project;
|
||||
|
||||
/// The virtual root sheet (has no screen, contains all top-level sheets)
|
||||
|
||||
@@ -67,7 +67,14 @@ void KI_TEST::SCHEMATIC_TEST_FIXTURE::LoadSchematic( const wxFileName& aFn )
|
||||
m_manager.Prj().SetElem( PROJECT::ELEM::LEGACY_SYMBOL_LIBS, nullptr );
|
||||
|
||||
m_schematic = std::make_unique<SCHEMATIC>( &m_manager.Prj() );
|
||||
m_schematic->SetRoot( m_pi->LoadSchematicFile( fn.GetFullPath(), m_schematic.get() ) );
|
||||
m_schematic->Reset();
|
||||
SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
|
||||
|
||||
SCH_SHEET* root = m_pi->LoadSchematicFile( fn.GetFullPath(), m_schematic.get() );
|
||||
m_schematic->AddTopLevelSheet( root );
|
||||
|
||||
m_schematic->RemoveTopLevelSheet( defaultSheet );
|
||||
delete defaultSheet;
|
||||
|
||||
BOOST_REQUIRE_EQUAL( m_pi->GetError().IsEmpty(), true );
|
||||
|
||||
|
||||
@@ -109,9 +109,14 @@ std::unique_ptr<SCHEMATIC> LoadHierarchyFromRoot( const std::string& rootFilenam
|
||||
std::unordered_map<std::string, SCH_SCREEN*> parsedScreens;
|
||||
|
||||
schematic->SetProject( project );
|
||||
schematic->Reset();
|
||||
SCH_SHEET* defaultSheet = schematic->GetTopLevelSheet( 0 );
|
||||
|
||||
SCH_SHEET* rootSheet = new SCH_SHEET( schematic.get() );
|
||||
LoadHierarchy( schematic.get(), rootSheet, rootFilename, parsedScreens );
|
||||
schematic->SetRoot( rootSheet ); // Call SetRoot AFTER loading so sheet has a screen
|
||||
schematic->AddTopLevelSheet( rootSheet );
|
||||
schematic->RemoveTopLevelSheet( defaultSheet );
|
||||
delete defaultSheet;
|
||||
|
||||
return schematic;
|
||||
}
|
||||
|
||||
@@ -41,10 +41,15 @@ struct BUS_ENTRY_CONCURRENCY_FIXTURE
|
||||
{
|
||||
m_mgr.LoadProject( "" );
|
||||
m_schematic = std::make_unique<SCHEMATIC>( &m_mgr.Prj() );
|
||||
m_schematic->Reset();
|
||||
SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
|
||||
|
||||
m_screen = new SCH_SCREEN( m_schematic.get() );
|
||||
m_sheet = new SCH_SHEET( m_schematic.get() );
|
||||
m_sheet->SetScreen( m_screen );
|
||||
m_schematic->SetRoot( m_sheet );
|
||||
m_schematic->AddTopLevelSheet( m_sheet );
|
||||
m_schematic->RemoveTopLevelSheet( defaultSheet );
|
||||
delete defaultSheet;
|
||||
}
|
||||
|
||||
SETTINGS_MANAGER m_mgr;
|
||||
|
||||
@@ -17,11 +17,15 @@ BOOST_AUTO_TEST_CASE( LabelDrivesCrossingWires )
|
||||
manager.LoadProject( "" );
|
||||
|
||||
SCHEMATIC schematic( &manager.Prj() );
|
||||
schematic.Reset();
|
||||
SCH_SHEET* defaultSheet = schematic.GetTopLevelSheet( 0 );
|
||||
|
||||
SCH_SCREEN* screen = new SCH_SCREEN( nullptr );
|
||||
SCH_SHEET* sheet = new SCH_SHEET( nullptr, VECTOR2I( 0, 0 ), VECTOR2I( 1000, 1000 ) );
|
||||
sheet->SetScreen( screen );
|
||||
schematic.SetRoot( sheet );
|
||||
schematic.AddTopLevelSheet( sheet );
|
||||
schematic.RemoveTopLevelSheet( defaultSheet );
|
||||
delete defaultSheet;
|
||||
|
||||
CONNECTION_GRAPH graph;
|
||||
graph.SetSchematic( &schematic );
|
||||
|
||||
@@ -79,7 +79,11 @@ BOOST_AUTO_TEST_CASE( TestLoadWithLogging )
|
||||
BOOST_REQUIRE( loadedSheet != nullptr );
|
||||
|
||||
BOOST_TEST_MESSAGE( "=== Setting root sheet" );
|
||||
schematic->SetRoot( loadedSheet );
|
||||
schematic->Reset();
|
||||
SCH_SHEET* defaultSheet = schematic->GetTopLevelSheet( 0 );
|
||||
schematic->AddTopLevelSheet( loadedSheet );
|
||||
schematic->RemoveTopLevelSheet( defaultSheet );
|
||||
delete defaultSheet;
|
||||
|
||||
BOOST_TEST_MESSAGE( "=== Building hierarchy" );
|
||||
schematic->RefreshHierarchy();
|
||||
|
||||
@@ -31,6 +31,20 @@
|
||||
#include <settings/settings_manager.h>
|
||||
#include <pgm_base.h>
|
||||
|
||||
static SCH_SHEET* createTopLevelSheet( SCHEMATIC& aSchematic, const wxString& aName,
|
||||
const wxString& aFileName )
|
||||
{
|
||||
SCH_SHEET* sheet = new SCH_SHEET( &aSchematic );
|
||||
SCH_SCREEN* screen = new SCH_SCREEN( &aSchematic );
|
||||
|
||||
const_cast<KIID&>( sheet->m_Uuid ) = screen->GetUuid();
|
||||
sheet->SetScreen( screen );
|
||||
sheet->SetName( aName );
|
||||
sheet->SetFileName( aFileName );
|
||||
|
||||
return sheet;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE( MultiTopLevelSheets )
|
||||
|
||||
BOOST_AUTO_TEST_CASE( TestVirtualRootCreation )
|
||||
@@ -49,50 +63,30 @@ BOOST_AUTO_TEST_CASE( TestAddTopLevelSheet )
|
||||
{
|
||||
SCHEMATIC schematic( nullptr );
|
||||
|
||||
// Create a virtual root
|
||||
SCH_SHEET* virtualRoot = new SCH_SHEET();
|
||||
const_cast<KIID&>( virtualRoot->m_Uuid ) = niluuid;
|
||||
virtualRoot->SetScreen( nullptr );
|
||||
virtualRoot->SetParent( &schematic );
|
||||
schematic.SetRoot( virtualRoot );
|
||||
SCH_SHEET* sheet1 = createTopLevelSheet( schematic, "Sheet1", "sheet1.kicad_sch" );
|
||||
|
||||
// Create and add a top-level sheet
|
||||
SCH_SHEET* sheet1 = new SCH_SHEET();
|
||||
sheet1->SetName( "Sheet1" );
|
||||
SCH_SCREEN* screen1 = new SCH_SCREEN();
|
||||
screen1->SetParent( &schematic );
|
||||
sheet1->SetScreen( screen1 );
|
||||
sheet1->SetParent( &schematic );
|
||||
|
||||
schematic.AddTopLevelSheet( sheet1 );
|
||||
schematic.SetTopLevelSheets( { sheet1 } );
|
||||
|
||||
// Verify the sheet was added
|
||||
const std::vector<SCH_SHEET*>& topSheets = schematic.GetTopLevelSheets();
|
||||
BOOST_CHECK_EQUAL( topSheets.size(), 1 );
|
||||
BOOST_CHECK_EQUAL( topSheets[0], sheet1 );
|
||||
BOOST_CHECK_EQUAL( topSheets[0]->GetName(), "Sheet1" );
|
||||
BOOST_CHECK_EQUAL( schematic.Hierarchy().size(), 1 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( TestAddMultipleTopLevelSheets )
|
||||
{
|
||||
SCHEMATIC schematic( nullptr );
|
||||
|
||||
// Create a virtual root
|
||||
SCH_SHEET* virtualRoot = new SCH_SHEET();
|
||||
const_cast<KIID&>( virtualRoot->m_Uuid ) = niluuid;
|
||||
virtualRoot->SetScreen( nullptr );
|
||||
virtualRoot->SetParent( &schematic );
|
||||
schematic.SetRoot( virtualRoot );
|
||||
SCH_SHEET* sheet1 = createTopLevelSheet( schematic, "Sheet1", "sheet1.kicad_sch" );
|
||||
schematic.SetTopLevelSheets( { sheet1 } );
|
||||
|
||||
// Create and add multiple top-level sheets
|
||||
for( int i = 1; i <= 3; i++ )
|
||||
for( int i = 2; i <= 3; i++ )
|
||||
{
|
||||
SCH_SHEET* sheet = new SCH_SHEET();
|
||||
sheet->SetName( wxString::Format( "Sheet%d", i ) );
|
||||
SCH_SCREEN* screen = new SCH_SCREEN();
|
||||
screen->SetParent( &schematic );
|
||||
sheet->SetScreen( screen );
|
||||
sheet->SetParent( &schematic );
|
||||
SCH_SHEET* sheet = createTopLevelSheet( schematic, wxString::Format( "Sheet%d", i ),
|
||||
wxString::Format( "sheet%d.kicad_sch", i ) );
|
||||
schematic.AddTopLevelSheet( sheet );
|
||||
}
|
||||
|
||||
@@ -102,34 +96,17 @@ BOOST_AUTO_TEST_CASE( TestAddMultipleTopLevelSheets )
|
||||
BOOST_CHECK_EQUAL( topSheets[0]->GetName(), "Sheet1" );
|
||||
BOOST_CHECK_EQUAL( topSheets[1]->GetName(), "Sheet2" );
|
||||
BOOST_CHECK_EQUAL( topSheets[2]->GetName(), "Sheet3" );
|
||||
BOOST_CHECK_EQUAL( schematic.Hierarchy().size(), 3 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( TestRemoveTopLevelSheet )
|
||||
{
|
||||
SCHEMATIC schematic( nullptr );
|
||||
|
||||
// Create a virtual root
|
||||
SCH_SHEET* virtualRoot = new SCH_SHEET();
|
||||
const_cast<KIID&>( virtualRoot->m_Uuid ) = niluuid;
|
||||
virtualRoot->SetScreen( nullptr );
|
||||
virtualRoot->SetParent( &schematic );
|
||||
schematic.SetRoot( virtualRoot );
|
||||
SCH_SHEET* sheet1 = createTopLevelSheet( schematic, "Sheet1", "sheet1.kicad_sch" );
|
||||
schematic.SetTopLevelSheets( { sheet1 } );
|
||||
|
||||
// Create and add sheets
|
||||
SCH_SHEET* sheet1 = new SCH_SHEET();
|
||||
sheet1->SetName( "Sheet1" );
|
||||
SCH_SCREEN* screen1 = new SCH_SCREEN();
|
||||
screen1->SetParent( &schematic );
|
||||
sheet1->SetScreen( screen1 );
|
||||
sheet1->SetParent( &schematic );
|
||||
schematic.AddTopLevelSheet( sheet1 );
|
||||
|
||||
SCH_SHEET* sheet2 = new SCH_SHEET();
|
||||
sheet2->SetName( "Sheet2" );
|
||||
SCH_SCREEN* screen2 = new SCH_SCREEN();
|
||||
screen2->SetParent( &schematic );
|
||||
sheet2->SetScreen( screen2 );
|
||||
sheet2->SetParent( &schematic );
|
||||
SCH_SHEET* sheet2 = createTopLevelSheet( schematic, "Sheet2", "sheet2.kicad_sch" );
|
||||
schematic.AddTopLevelSheet( sheet2 );
|
||||
|
||||
// Remove first sheet
|
||||
@@ -140,51 +117,62 @@ BOOST_AUTO_TEST_CASE( TestRemoveTopLevelSheet )
|
||||
BOOST_CHECK_EQUAL( topSheets.size(), 1 );
|
||||
BOOST_CHECK_EQUAL( topSheets[0], sheet2 );
|
||||
BOOST_CHECK_EQUAL( topSheets[0]->GetName(), "Sheet2" );
|
||||
BOOST_CHECK_EQUAL( schematic.Hierarchy().size(), 1 );
|
||||
|
||||
// Cannot remove the final remaining sheet
|
||||
BOOST_CHECK( !schematic.RemoveTopLevelSheet( topSheets[0] ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( TestBuildSheetListWithMultipleRoots )
|
||||
{
|
||||
SCHEMATIC schematic( nullptr );
|
||||
|
||||
// Create a virtual root
|
||||
SCH_SHEET* virtualRoot = new SCH_SHEET();
|
||||
const_cast<KIID&>( virtualRoot->m_Uuid ) = niluuid;
|
||||
virtualRoot->SetScreen( nullptr );
|
||||
virtualRoot->SetParent( &schematic );
|
||||
schematic.SetRoot( virtualRoot );
|
||||
SCH_SHEET* top1 = createTopLevelSheet( schematic, "TopSheet1", "top_sheet_1.kicad_sch" );
|
||||
SCH_SHEET* top2 = createTopLevelSheet( schematic, "TopSheet2", "top_sheet_2.kicad_sch" );
|
||||
|
||||
// Create two top-level sheets, each with one child
|
||||
for( int i = 1; i <= 2; i++ )
|
||||
{
|
||||
SCH_SHEET* topSheet = new SCH_SHEET();
|
||||
topSheet->SetName( wxString::Format( "TopSheet%d", i ) );
|
||||
topSheet->SetFileName( wxString::Format( "top_sheet_%d.kicad_sch", i ) );
|
||||
SCH_SCREEN* topScreen = new SCH_SCREEN();
|
||||
topScreen->SetParent( &schematic );
|
||||
topSheet->SetScreen( topScreen );
|
||||
topSheet->SetParent( &schematic );
|
||||
SCH_SHEET* child1 = createTopLevelSheet( schematic, "ChildSheet1", "child_sheet_1.kicad_sch" );
|
||||
child1->SetParent( top1 );
|
||||
top1->GetScreen()->Append( child1 );
|
||||
|
||||
// Add a child sheet
|
||||
SCH_SHEET* childSheet = new SCH_SHEET();
|
||||
childSheet->SetName( wxString::Format( "ChildSheet%d", i ) );
|
||||
childSheet->SetFileName( wxString::Format( "child_sheet_%d.kicad_sch", i ) );
|
||||
SCH_SCREEN* childScreen = new SCH_SCREEN();
|
||||
childScreen->SetParent( &schematic );
|
||||
childSheet->SetScreen( childScreen );
|
||||
childSheet->SetParent( &schematic );
|
||||
topScreen->Append( childSheet );
|
||||
SCH_SHEET* child2 = createTopLevelSheet( schematic, "ChildSheet2", "child_sheet_2.kicad_sch" );
|
||||
child2->SetParent( top2 );
|
||||
top2->GetScreen()->Append( child2 );
|
||||
|
||||
schematic.AddTopLevelSheet( topSheet );
|
||||
}
|
||||
schematic.SetTopLevelSheets( { top1, top2 } );
|
||||
|
||||
// Build sheet list
|
||||
schematic.RefreshHierarchy();
|
||||
SCH_SHEET_LIST sheetList = schematic.Hierarchy();
|
||||
|
||||
// Should have 4 sheet paths: 2 top-level + 2 children
|
||||
BOOST_CHECK_EQUAL( sheetList.size(), 4 );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( TestHierarchyUpdatesOnSheetOperations )
|
||||
{
|
||||
SCHEMATIC schematic( nullptr );
|
||||
|
||||
SCH_SHEET* baseSheet = createTopLevelSheet( schematic, "Base", "base.kicad_sch" );
|
||||
schematic.SetTopLevelSheets( { baseSheet } );
|
||||
|
||||
BOOST_CHECK_EQUAL( schematic.Hierarchy().size(), 1 );
|
||||
|
||||
SCH_SHEET* copiedSheet = createTopLevelSheet( schematic, "Copy", "copy.kicad_sch" );
|
||||
schematic.AddTopLevelSheet( copiedSheet );
|
||||
|
||||
BOOST_CHECK_EQUAL( schematic.Hierarchy().size(), 2 );
|
||||
|
||||
// Move the copied sheet ahead of the base sheet
|
||||
schematic.SetTopLevelSheets( { copiedSheet, baseSheet } );
|
||||
BOOST_CHECK_EQUAL( schematic.GetTopLevelSheet()->GetName(), "Copy" );
|
||||
BOOST_CHECK_EQUAL( schematic.Hierarchy().size(), 2 );
|
||||
|
||||
// Removing one sheet should keep hierarchy valid
|
||||
BOOST_CHECK( schematic.RemoveTopLevelSheet( baseSheet ) );
|
||||
BOOST_CHECK_EQUAL( schematic.Hierarchy().size(), 1 );
|
||||
BOOST_CHECK_EQUAL( schematic.GetTopLevelSheet()->GetName(), "Copy" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( TestTopLevelSheetInfoSerialization )
|
||||
{
|
||||
TOP_LEVEL_SHEET_INFO info1( KIID(), "TestSheet", "test_sheet.kicad_sch" );
|
||||
|
||||
@@ -43,11 +43,15 @@ struct NC_PIN_CONNECTIVITY_FIXTURE
|
||||
m_settingsManager.LoadProject( "" );
|
||||
m_schematic = std::make_unique<SCHEMATIC>( &m_settingsManager.Prj() );
|
||||
m_schematic->Reset();
|
||||
SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
|
||||
|
||||
SCH_SHEET* root = new SCH_SHEET( m_schematic.get() );
|
||||
m_schematic->SetRoot( root );
|
||||
SCH_SCREEN* screen = new SCH_SCREEN( m_schematic.get() );
|
||||
root->SetScreen( screen );
|
||||
|
||||
m_schematic->AddTopLevelSheet( root );
|
||||
m_schematic->RemoveTopLevelSheet( defaultSheet );
|
||||
delete defaultSheet;
|
||||
}
|
||||
|
||||
SETTINGS_MANAGER m_settingsManager;
|
||||
|
||||
@@ -130,6 +130,7 @@ BOOST_AUTO_TEST_CASE( TestSaveLoadSimpleSchematic )
|
||||
|
||||
// Now try to load it back
|
||||
m_schematic->Reset();
|
||||
SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
|
||||
SCH_SHEET* loadedSheet = nullptr;
|
||||
BOOST_CHECK_NO_THROW( loadedSheet = io.LoadSchematicFile( fileName, m_schematic.get() ) );
|
||||
BOOST_CHECK( loadedSheet != nullptr );
|
||||
@@ -137,7 +138,9 @@ BOOST_AUTO_TEST_CASE( TestSaveLoadSimpleSchematic )
|
||||
if( loadedSheet )
|
||||
{
|
||||
// Set it as root (which should create virtual root and make it a top-level sheet)
|
||||
m_schematic->SetRoot( loadedSheet );
|
||||
m_schematic->AddTopLevelSheet( loadedSheet );
|
||||
m_schematic->RemoveTopLevelSheet( defaultSheet );
|
||||
delete defaultSheet;
|
||||
|
||||
// Verify we can access the schematic
|
||||
BOOST_CHECK( m_schematic->IsValid() );
|
||||
@@ -208,13 +211,16 @@ BOOST_AUTO_TEST_CASE( TestSaveLoadHierarchicalSchematic )
|
||||
|
||||
// Load it back
|
||||
m_schematic->Reset();
|
||||
SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
|
||||
SCH_SHEET* loadedSheet = nullptr;
|
||||
BOOST_CHECK_NO_THROW( loadedSheet = io.LoadSchematicFile( mainFileName, m_schematic.get() ) );
|
||||
BOOST_CHECK( loadedSheet != nullptr );
|
||||
|
||||
if( loadedSheet )
|
||||
{
|
||||
m_schematic->SetRoot( loadedSheet );
|
||||
m_schematic->AddTopLevelSheet( loadedSheet );
|
||||
m_schematic->RemoveTopLevelSheet( defaultSheet );
|
||||
delete defaultSheet;
|
||||
|
||||
// Build hierarchy
|
||||
m_schematic->RefreshHierarchy();
|
||||
@@ -267,7 +273,11 @@ BOOST_AUTO_TEST_CASE( TestLoadLegacyHierarchicalSchematic )
|
||||
BOOST_TEST_MESSAGE( "Loaded sheet UUID: " + loadedSheet->m_Uuid.AsString().ToStdString() );
|
||||
BOOST_TEST_MESSAGE( "Loaded sheet name: " + loadedSheet->GetName().ToStdString() );
|
||||
|
||||
m_schematic->SetRoot( loadedSheet );
|
||||
m_schematic->Reset();
|
||||
SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
|
||||
m_schematic->AddTopLevelSheet( loadedSheet );
|
||||
m_schematic->RemoveTopLevelSheet( defaultSheet );
|
||||
delete defaultSheet;
|
||||
|
||||
// Build the hierarchy
|
||||
m_schematic->RefreshHierarchy();
|
||||
|
||||
@@ -59,13 +59,10 @@ public:
|
||||
|
||||
m_manager.LoadProject( "" );
|
||||
m_schematic = std::make_unique<SCHEMATIC>( &m_manager.Prj() );
|
||||
m_schematic->Reset();
|
||||
|
||||
m_screen = new SCH_SCREEN( m_schematic.get() );
|
||||
|
||||
m_sheet = new SCH_SHEET( m_schematic.get() );
|
||||
m_sheet->SetScreen( m_screen );
|
||||
|
||||
m_schematic->SetRoot( m_sheet );
|
||||
m_sheet = m_schematic->GetTopLevelSheet( 0 );
|
||||
m_screen = m_sheet->GetScreen();
|
||||
|
||||
m_parent_part = new LIB_SYMBOL( "parent_part", nullptr );
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
// Code under test
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_sheet_pin.h>
|
||||
#include <sch_screen.h>
|
||||
#include <schematic.h>
|
||||
|
||||
#include <qa_utils/uuid_test_utils.h>
|
||||
@@ -98,12 +99,16 @@ BOOST_AUTO_TEST_CASE( SchematicParent )
|
||||
BOOST_CHECK_EQUAL( m_sheet.IsVirtualRootSheet(), false );
|
||||
BOOST_CHECK_EQUAL( m_sheet.IsTopLevelSheet(), false ); // Not yet a top-level sheet
|
||||
|
||||
m_schematic.SetRoot( &m_sheet );
|
||||
SCH_SCREEN* screen = new SCH_SCREEN( &m_schematic );
|
||||
m_sheet.SetScreen( screen );
|
||||
m_schematic.AddTopLevelSheet( &m_sheet );
|
||||
|
||||
// After SetRoot, the sheet becomes a top-level sheet under the virtual root
|
||||
// After AddTopLevelSheet, the sheet becomes a top-level sheet under the virtual root
|
||||
BOOST_CHECK_EQUAL( m_sheet.IsVirtualRootSheet(), false ); // Sheet is not the virtual root
|
||||
BOOST_CHECK_EQUAL( m_sheet.IsTopLevelSheet(), true ); // Sheet is now a top-level sheet
|
||||
BOOST_CHECK_EQUAL( m_schematic.Root().IsVirtualRootSheet(), true ); // The root is virtual
|
||||
|
||||
m_schematic.RemoveTopLevelSheet( &m_sheet );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -192,12 +192,17 @@ BOOST_AUTO_TEST_CASE( DerivedSymbolEmbeddedFiles )
|
||||
{
|
||||
SCHEMATIC schematic( nullptr );
|
||||
|
||||
SCH_SHEET* rootSheet = new SCH_SHEET( &schematic );
|
||||
schematic.SetRoot( rootSheet );
|
||||
schematic.Reset();
|
||||
SCH_SHEET* defaultSheet = schematic.GetTopLevelSheet( 0 );
|
||||
|
||||
SCH_SHEET* rootSheet = new SCH_SHEET( &schematic );
|
||||
SCH_SCREEN* screen = new SCH_SCREEN( &schematic );
|
||||
rootSheet->SetScreen( screen );
|
||||
|
||||
schematic.AddTopLevelSheet( rootSheet );
|
||||
schematic.RemoveTopLevelSheet( defaultSheet );
|
||||
delete defaultSheet;
|
||||
|
||||
IO_RELEASER<SCH_IO> plugin( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
|
||||
LIB_SYMBOL* loadedParent = plugin->LoadSymbol( GetLibPath(), wxS( "ParentSymbol" ) );
|
||||
LIB_SYMBOL* loadedDerived = plugin->LoadSymbol( GetLibPath(), wxS( "DerivedSymbol" ) );
|
||||
@@ -206,6 +211,7 @@ BOOST_AUTO_TEST_CASE( DerivedSymbolEmbeddedFiles )
|
||||
|
||||
SCH_SHEET_PATH rootPath;
|
||||
rootPath.push_back( &schematic.Root() );
|
||||
rootPath.push_back( rootSheet );
|
||||
|
||||
SCH_SYMBOL* schSymbol = new SCH_SYMBOL( *loadedDerived, LIB_ID( "test_lib", "DerivedSymbol" ),
|
||||
&rootPath, 0 );
|
||||
|
||||
Reference in New Issue
Block a user