Fix broken Eagle schematic import.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/12893
This commit is contained in:
Wayne Stambaugh 2022-11-17 09:35:10 -05:00
parent 3960f48b5d
commit db993bc8cc
2 changed files with 35 additions and 27 deletions

View File

@ -478,6 +478,9 @@ SCH_SHEET* SCH_EAGLE_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchema
SCH_SCREEN* screen = new SCH_SCREEN( m_schematic ); SCH_SCREEN* screen = new SCH_SCREEN( m_schematic );
screen->SetFileName( newFilename.GetFullPath() ); screen->SetFileName( newFilename.GetFullPath() );
m_rootSheet->SetScreen( screen ); m_rootSheet->SetScreen( screen );
// Virtual root sheet UUID must be the same as the schematic file UUID.
const_cast<KIID&>( m_rootSheet->m_Uuid ) = screen->GetUuid();
} }
SYMBOL_LIB_TABLE* libTable = m_schematic->Prj().SchSymbolLibTable(); SYMBOL_LIB_TABLE* libTable = m_schematic->Prj().SchSymbolLibTable();
@ -502,7 +505,7 @@ SCH_SHEET* SCH_EAGLE_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchema
// Save project symbol library table. // Save project symbol library table.
wxFileName fn( m_schematic->Prj().GetProjectPath(), wxFileName fn( m_schematic->Prj().GetProjectPath(),
SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() ); SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
// So output formatter goes out of scope and closes the file before reloading. // So output formatter goes out of scope and closes the file before reloading.
{ {
@ -701,50 +704,58 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
// local labels will be used for nets found only on that sheet. // local labels will be used for nets found only on that sheet.
countNets( aSchematicNode ); countNets( aSchematicNode );
// Loop through all the sheets // There is always at least a root sheet.
int sheet_count = countChildren( sheetNode->GetParent(), wxT( "sheet" ) ); m_sheetPath.push_back( m_rootSheet );
// If eagle schematic has multiple sheets then create corresponding subsheets on the root sheet SCH_SHEET_PATH rootPath;
if( sheet_count > 1 ) m_rootSheet->AddInstance( m_sheetPath );
m_rootSheet->SetPageNumber( m_sheetPath, wxT( "1" ) );
int sheetCount = countChildren( sheetNode->GetParent(), wxT( "sheet" ) );
if( sheetCount > 1 )
{ {
int x, y, i; int x, y, i;
i = 2; i = 1;
x = 1; x = 1;
y = 1; y = 1;
m_sheetPath.push_back( m_rootSheet ); // Loop through all the sheets
m_rootSheet->AddInstance( m_sheetPath );
m_sheetPath.SetPageNumber( wxT( "1" ) );
while( sheetNode ) while( sheetNode )
{ {
VECTOR2I pos = VECTOR2I( x * schIUScale.MilsToIU( 1000 ), VECTOR2I pos = VECTOR2I( x * schIUScale.MilsToIU( 1000 ),
y * schIUScale.MilsToIU( 1000 ) ); y * schIUScale.MilsToIU( 1000 ) );
std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>( getCurrentSheet(),
pos );
SCH_SCREEN* screen = new SCH_SCREEN( m_schematic );
wxString pageNo = wxString::Format( wxT( "%d" ), i );
// Eagle schematics are never more than one sheet deep so the parent sheet is
// always the root sheet.
std::unique_ptr<SCH_SHEET> sheet = std::make_unique<SCH_SHEET>( m_rootSheet, pos );
SCH_SCREEN* screen = new SCH_SCREEN( m_schematic );
sheet->SetScreen( screen ); sheet->SetScreen( screen );
sheet->GetScreen()->SetFileName( sheet->GetFileName() ); screen->SetFileName( sheet->GetFileName() );
wxCHECK2( sheet && screen, continue );
wxString pageNo = wxString::Format( wxT( "%d" ), i );
m_sheetPath.push_back( sheet.get() ); m_sheetPath.push_back( sheet.get() );
loadSheet( sheetNode, i ); loadSheet( sheetNode, i );
SCH_SCREEN* currentScreen = getCurrentScreen();
wxCHECK2( currentScreen, continue );
currentScreen->Append( sheet.release() );
sheet->AddInstance( m_sheetPath ); sheet->AddInstance( m_sheetPath );
m_sheetPath.SetPageNumber( pageNo ); m_sheetPath.SetPageNumber( pageNo );
m_rootSheet->AddInstance( m_sheetPath ); m_rootSheet->AddInstance( m_sheetPath );
m_rootSheet->SetPageNumber( m_sheetPath, pageNo ); m_rootSheet->SetPageNumber( m_sheetPath, pageNo );
m_sheetPath.pop_back(); m_sheetPath.pop_back();
SCH_SCREEN* currentScreen = m_rootSheet->GetScreen();
wxCHECK2( currentScreen, continue );
currentScreen->Append( sheet.release() );
sheetNode = sheetNode->GetNext(); sheetNode = sheetNode->GetNext();
x += 2; x += 2;
if( x > 10 ) // start next row if( x > 10 ) // Start next row of sheets.
{ {
x = 1; x = 1;
y += 2; y += 2;
@ -755,14 +766,11 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
} }
else else
{ {
// There is only one sheet so we make that the root schematic.
while( sheetNode ) while( sheetNode )
{ {
m_sheetPath.push_back( m_rootSheet );
loadSheet( sheetNode, 0 ); loadSheet( sheetNode, 0 );
sheetNode = sheetNode->GetNext(); sheetNode = sheetNode->GetNext();
m_rootSheet->AddInstance( m_sheetPath );
m_sheetPath.SetPageNumber( wxT( "1" ) );
} }
} }
@ -1402,7 +1410,7 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
symbol->GetField( REFERENCE_FIELD )->SetText( reference ); symbol->GetField( REFERENCE_FIELD )->SetText( reference );
wxString value = ( epart->value ) ? kisymbolname : *epart->value; wxString value = ( epart->value ) ? *epart->value : kisymbolname;
symbol->GetField( VALUE_FIELD )->SetText( value ); symbol->GetField( VALUE_FIELD )->SetText( value );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2017 CERN * Copyright (C) 2017 CERN
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* @author Alejandro García Montoro <alejandro.garciamontoro@gmail.com> * @author Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>