diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp index 61da265a7d..0ef5ed8e78 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp @@ -473,10 +473,12 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SHEET* aSheet ) } } - // If this is the root sheet, save the virtual root sheet instance information. - if( aSheet->IsRootSheet() ) + if( aSheet->HasRootInstance() ) { - saveInstances( aSheet->GetInstances(), 1 ); + std::vector< SCH_SHEET_INSTANCE> instances; + + instances.emplace_back( aSheet->GetRootInstance() ); + saveInstances( instances, 1 ); } m_out->Print( 0, ")\n" ); @@ -1004,7 +1006,20 @@ void SCH_SEXPR_PLUGIN::saveSheet( SCH_SHEET* aSheet, int aNestLevel ) m_out->Print( aNestLevel + 1, ")\n" ); // Closes pin token. } - if( !aSheet->GetInstances().empty() ) + // We all sheet instances here except the root sheet instance. + std::vector< SCH_SHEET_INSTANCE > sheetInstances = aSheet->GetInstances(); + + auto it = sheetInstances.begin(); + + while( it != sheetInstances.end() ) + { + if( it->m_Path.size() == 0 ) + it = sheetInstances.erase( it ); + else + it++; + } + + if( !sheetInstances.empty() ) { m_out->Print( aNestLevel + 1, "(instances\n" ); @@ -1013,18 +1028,18 @@ void SCH_SEXPR_PLUGIN::saveSheet( SCH_SHEET* aSheet, int aNestLevel ) SCH_SHEET_LIST fullHierarchy = m_schematic->GetSheets(); bool project_open = false; - for( size_t i = 0; i < aSheet->GetInstances().size(); i++ ) + for( size_t i = 0; i < sheetInstances.size(); i++ ) { // If the instance data is part of this design but no longer has an associated sheet // path, don't save it. This prevents large amounts of orphaned instance data for the // current project from accumulating in the schematic files. // // Keep all instance data when copying to the clipboard. It may be needed on paste. - if( ( aSheet->GetInstances()[i].m_Path[0] == rootSheetUuid ) - && !fullHierarchy.GetSheetPathByKIIDPath( aSheet->GetInstances()[i].m_Path ) ) + if( ( sheetInstances[i].m_Path[0] == rootSheetUuid ) + && !fullHierarchy.GetSheetPathByKIIDPath( sheetInstances[i].m_Path ) ) { - if( project_open && ( ( i + 1 == aSheet->GetInstances().size() ) - || lastProjectUuid != aSheet->GetInstances()[i+1].m_Path[0] ) ) + if( project_open && ( ( i + 1 == sheetInstances.size() ) + || lastProjectUuid != sheetInstances[i+1].m_Path[0] ) ) { m_out->Print( aNestLevel + 2, ")\n" ); // Closes `project`. project_open = false; @@ -1033,29 +1048,29 @@ void SCH_SEXPR_PLUGIN::saveSheet( SCH_SHEET* aSheet, int aNestLevel ) continue; } - if( lastProjectUuid != aSheet->GetInstances()[i].m_Path[0] ) + if( lastProjectUuid != sheetInstances[i].m_Path[0] ) { wxString projectName; - if( aSheet->GetInstances()[i].m_Path[0] == rootSheetUuid ) + if( sheetInstances[i].m_Path[0] == rootSheetUuid ) projectName = m_schematic->Prj().GetProjectName(); else - projectName = aSheet->GetInstances()[i].m_ProjectName; + projectName = sheetInstances[i].m_ProjectName; - lastProjectUuid = aSheet->GetInstances()[i].m_Path[0]; + lastProjectUuid = sheetInstances[i].m_Path[0]; m_out->Print( aNestLevel + 2, "(project %s\n", m_out->Quotew( projectName ).c_str() ); project_open = true; } - wxString path = aSheet->GetInstances()[i].m_Path.AsString(); + wxString path = sheetInstances[i].m_Path.AsString(); m_out->Print( aNestLevel + 3, "(path %s (page %s))\n", m_out->Quotew( path ).c_str(), - m_out->Quotew( aSheet->GetInstances()[i].m_PageNumber ).c_str() ); + m_out->Quotew( sheetInstances[i].m_PageNumber ).c_str() ); - if( project_open && ( ( i + 1 == aSheet->GetInstances().size() ) - || lastProjectUuid != aSheet->GetInstances()[i+1].m_Path[0] ) ) + if( project_open && ( ( i + 1 == sheetInstances.size() ) + || lastProjectUuid != sheetInstances[i+1].m_Path[0] ) ) { m_out->Print( aNestLevel + 2, ")\n" ); // Closes `project`. project_open = false; @@ -1345,15 +1360,15 @@ void SCH_SEXPR_PLUGIN::saveBusAlias( std::shared_ptr aAlias, int aNes } -void SCH_SEXPR_PLUGIN::saveInstances( const std::vector& aSheets, +void SCH_SEXPR_PLUGIN::saveInstances( const std::vector& aInstances, int aNestLevel ) { - if( aSheets.size() ) + if( aInstances.size() ) { m_out->Print( 0, "\n" ); m_out->Print( aNestLevel, "(sheet_instances\n" ); - for( const SCH_SHEET_INSTANCE& instance : aSheets ) + for( const SCH_SHEET_INSTANCE& instance : aInstances ) { wxString path = instance.m_Path.AsString(); @@ -1370,7 +1385,8 @@ void SCH_SEXPR_PLUGIN::saveInstances( const std::vector& aSh } -void SCH_SEXPR_PLUGIN::cacheLib( const wxString& aLibraryFileName, const STRING_UTF8_MAP* aProperties ) +void SCH_SEXPR_PLUGIN::cacheLib( const wxString& aLibraryFileName, + const STRING_UTF8_MAP* aProperties ) { if( !m_cache || !m_cache->IsFile( aLibraryFileName ) || m_cache->IsFileChanged() ) { diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp index d4b581df9f..97df9240fc 100644 --- a/eeschema/sch_sheet.cpp +++ b/eeschema/sch_sheet.cpp @@ -1228,6 +1228,34 @@ bool SCH_SHEET::AddInstance( const SCH_SHEET_PATH& aSheetPath ) } +bool SCH_SHEET::HasRootInstance() const +{ + for( const SCH_SHEET_INSTANCE& instance : m_instances ) + { + if( instance.m_Path.size() == 0 ) + return true; + } + + return false; +} + + +const SCH_SHEET_INSTANCE& SCH_SHEET::GetRootInstance() const +{ + for( const SCH_SHEET_INSTANCE& instance : m_instances ) + { + if( instance.m_Path.size() == 0 ) + return instance; + } + + wxFAIL; + + static SCH_SHEET_INSTANCE dummy; + + return dummy; +} + + wxString SCH_SHEET::getPageNumber( const SCH_SHEET_PATH& aSheetPath ) const { wxCHECK( aSheetPath.IsFullPath(), wxEmptyString ); diff --git a/eeschema/sch_sheet.h b/eeschema/sch_sheet.h index 74174f2a15..1cb784ff1c 100644 --- a/eeschema/sch_sheet.h +++ b/eeschema/sch_sheet.h @@ -400,6 +400,27 @@ public: */ bool AddInstance( const SCH_SHEET_PATH& aInstance ); + /** + * Check to see if this sheet has a root sheet instance. + * + * @note It is possible for sheets to contain both sheet instances from other projects as + * well as a root sheet instance for this schematic. This will happen with a + * shared schematic is opened by the schematic editor in stand alone model. + * + * @return true if the instance data contains a root sheet instance. + */ + bool HasRootInstance() const; + + /** + * Return the root sheet instance data. + * + * @note If no root sheet instance data exists, an assertion will be raise in debug builds + * and an empty instance will be returned. + * + * @return the root sheet instance data. + */ + const SCH_SHEET_INSTANCE& GetRootInstance() const; + /** * Compares page numbers of schematic sheets. *