Schematic import bug fix.

Check for already loaded schematics in the current sheet path as well
as the current project root sheet path to prevent multiple loads of
shared schematic.  This bug was causing shared sheets to be loaded more
than once which caused instance data to get separated by each copy rather
than saved in one copy of the schematic which would result in all instance
data being lost except the last saved copy of the schematic.  This bug has
been around forever and may be the cause of some unexplained schematic
instance data corruption issues.  This bug does not apply when opening
the full project.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/11076
This commit is contained in:
Wayne Stambaugh 2022-12-15 09:57:53 -05:00
parent 1e812b8b69
commit 84f927d057
4 changed files with 25 additions and 7 deletions

View File

@ -39,6 +39,7 @@ const wxChar* const kicadTraceCoroutineStack = wxT( "KICAD_COROUTINE_STACK" );
const wxChar* const traceSchLibMem = wxT( "KICAD_SCH_LIB_MEM" ); const wxChar* const traceSchLibMem = wxT( "KICAD_SCH_LIB_MEM" );
const wxChar* const traceFindItem = wxT( "KICAD_FIND_ITEM" ); const wxChar* const traceFindItem = wxT( "KICAD_FIND_ITEM" );
const wxChar* const traceSchLegacyPlugin = wxT( "KICAD_SCH_LEGACY_PLUGIN" ); const wxChar* const traceSchLegacyPlugin = wxT( "KICAD_SCH_LEGACY_PLUGIN" );
const wxChar* const traceSchPlugin = wxT( "KICAD_SCH_PLUGIN" );
const wxChar* const traceGedaPcbPlugin = wxT( "KICAD_GEDA_PLUGIN" ); const wxChar* const traceGedaPcbPlugin = wxT( "KICAD_GEDA_PLUGIN" );
const wxChar* const traceKicadPcbPlugin = wxT( "KICAD_PCB_PLUGIN" ); const wxChar* const traceKicadPcbPlugin = wxT( "KICAD_PCB_PLUGIN" );
const wxChar* const tracePrinting = wxT( "KICAD_PRINT" ); const wxChar* const tracePrinting = wxT( "KICAD_PRINT" );

View File

@ -115,7 +115,7 @@ SCH_SHEET* SCH_SEXPR_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchema
if( aAppendToMe ) if( aAppendToMe )
{ {
m_appending = true; m_appending = true;
wxLogTrace( traceSchLegacyPlugin, "Append \"%s\" to sheet \"%s\".", wxLogTrace( traceSchPlugin, "Append \"%s\" to sheet \"%s\".",
aFileName, aAppendToMe->GetFileName() ); aFileName, aAppendToMe->GetFileName() );
wxFileName normedFn = aAppendToMe->GetFileName(); wxFileName normedFn = aAppendToMe->GetFileName();
@ -129,7 +129,7 @@ SCH_SHEET* SCH_SEXPR_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchema
if( m_path.IsEmpty() ) if( m_path.IsEmpty() )
m_path = aSchematic->Prj().GetProjectPath(); m_path = aSchematic->Prj().GetProjectPath();
wxLogTrace( traceSchLegacyPlugin, "Normalized append path \"%s\".", m_path ); wxLogTrace( traceSchPlugin, "Normalized append path \"%s\".", m_path );
} }
else else
{ {
@ -178,6 +178,8 @@ SCH_SHEET* SCH_SEXPR_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchema
void SCH_SEXPR_PLUGIN::loadHierarchy( const SCH_SHEET_PATH& aParentSheetPath, SCH_SHEET* aSheet ) void SCH_SEXPR_PLUGIN::loadHierarchy( const SCH_SHEET_PATH& aParentSheetPath, SCH_SHEET* aSheet )
{ {
m_currentSheetPath.push_back( aSheet );
SCH_SCREEN* screen = nullptr; SCH_SCREEN* screen = nullptr;
if( !aSheet->GetScreen() ) if( !aSheet->GetScreen() )
@ -193,10 +195,10 @@ void SCH_SEXPR_PLUGIN::loadHierarchy( const SCH_SHEET_PATH& aParentSheetPath, SC
// Save the current path so that it gets restored when descending and ascending the // Save the current path so that it gets restored when descending and ascending the
// sheet hierarchy which allows for sheet schematic files to be nested in folders // sheet hierarchy which allows for sheet schematic files to be nested in folders
// relative to the last path a schematic was loaded from. // relative to the last path a schematic was loaded from.
wxLogTrace( traceSchLegacyPlugin, "Saving path '%s'", m_currentPath.top() ); wxLogTrace( traceSchPlugin, "Saving path '%s'", m_currentPath.top() );
m_currentPath.push( fileName.GetPath() ); m_currentPath.push( fileName.GetPath() );
wxLogTrace( traceSchLegacyPlugin, "Current path '%s'", m_currentPath.top() ); wxLogTrace( traceSchPlugin, "Current path '%s'", m_currentPath.top() );
wxLogTrace( traceSchLegacyPlugin, "Loading '%s'", fileName.GetFullPath() ); wxLogTrace( traceSchPlugin, "Loading '%s'", fileName.GetFullPath() );
SCH_SHEET_PATH ancestorSheetPath = aParentSheetPath; SCH_SHEET_PATH ancestorSheetPath = aParentSheetPath;
@ -221,7 +223,12 @@ void SCH_SEXPR_PLUGIN::loadHierarchy( const SCH_SHEET_PATH& aParentSheetPath, SC
} }
if( ancestorSheetPath.empty() ) if( ancestorSheetPath.empty() )
m_rootSheet->SearchHierarchy( fileName.GetFullPath(), &screen ); {
// Existing schematics could be either in the root sheet path or the current sheet
// load path so we have to check both.
if( !m_rootSheet->SearchHierarchy( fileName.GetFullPath(), &screen ) )
m_currentSheetPath.at( 0 )->SearchHierarchy( fileName.GetFullPath(), &screen );
}
if( screen ) if( screen )
{ {
@ -278,8 +285,10 @@ void SCH_SEXPR_PLUGIN::loadHierarchy( const SCH_SHEET_PATH& aParentSheetPath, SC
} }
m_currentPath.pop(); m_currentPath.pop();
wxLogTrace( traceSchLegacyPlugin, "Restoring path \"%s\"", m_currentPath.top() ); wxLogTrace( traceSchPlugin, "Restoring path \"%s\"", m_currentPath.top() );
} }
m_currentSheetPath.pop_back();
} }

View File

@ -174,6 +174,7 @@ protected:
wxString m_path; ///< Root project path for loading child sheets. wxString m_path; ///< Root project path for loading child sheets.
std::stack<wxString> m_currentPath; ///< Stack to maintain nested sheet paths std::stack<wxString> m_currentPath; ///< Stack to maintain nested sheet paths
SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded. SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded.
SCH_SHEET_PATH m_currentSheetPath;
SCHEMATIC* m_schematic; SCHEMATIC* m_schematic;
OUTPUTFORMATTER* m_out; ///< The formatter for saving SCH_SCREEN objects. OUTPUTFORMATTER* m_out; ///< The formatter for saving SCH_SCREEN objects.
SCH_SEXPR_PLUGIN_CACHE* m_cache; SCH_SEXPR_PLUGIN_CACHE* m_cache;

View File

@ -106,6 +106,13 @@ extern const wxChar* const traceAutoSave;
*/ */
extern const wxChar* const traceSchLibMem; extern const wxChar* const traceSchLibMem;
/**
* Flag to enable legacy schematic plugin debug output.
*
* Use "KICAD_SCH_PLUGIN" to enable.
*/
extern const wxChar* const traceSchPlugin;
/** /**
* Flag to enable legacy schematic plugin debug output. * Flag to enable legacy schematic plugin debug output.
* *