Fix crash when copying symbol in schematic editor.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/12574
This commit is contained in:
Wayne Stambaugh 2022-10-04 17:45:59 -04:00
parent 2f756d9d23
commit 03d847118a
3 changed files with 17 additions and 18 deletions

View File

@ -409,7 +409,7 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SHEET* aSheet )
{ {
case SCH_SYMBOL_T: case SCH_SYMBOL_T:
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
saveSymbol( static_cast<SCH_SYMBOL*>( item ), nullptr, 1, false ); saveSymbol( static_cast<SCH_SYMBOL*>( item ), *m_schematic, 1, false );
break; break;
case SCH_BITMAP_T: case SCH_BITMAP_T:
@ -499,12 +499,13 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SHEET* aSheet )
void SCH_SEXPR_PLUGIN::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSelectionPath, void SCH_SEXPR_PLUGIN::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSelectionPath,
SCH_SHEET_LIST* aFullSheetHierarchy, const SCHEMATIC& aSchematic, OUTPUTFORMATTER* aFormatter,
OUTPUTFORMATTER* aFormatter, bool aForClipboard ) bool aForClipboard )
{ {
wxCHECK( aSelection && aSelectionPath && aFullSheetHierarchy && aFormatter, /* void */ ); wxCHECK( aSelection && aSelectionPath && aFormatter, /* void */ );
LOCALE_IO toggle; LOCALE_IO toggle;
SCH_SHEET_LIST fullHierarchy = aSchematic.GetSheets();
m_out = aFormatter; m_out = aFormatter;
@ -560,7 +561,7 @@ void SCH_SEXPR_PLUGIN::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSelect
switch( item->Type() ) switch( item->Type() )
{ {
case SCH_SYMBOL_T: case SCH_SYMBOL_T:
saveSymbol( static_cast<SCH_SYMBOL*>( item ), aSelectionPath, 0, aForClipboard ); saveSymbol( static_cast<SCH_SYMBOL*>( item ), aSchematic, 0, aForClipboard );
aSelectionPath->AppendSymbol( selectedSymbols, static_cast<SCH_SYMBOL*>( item ), aSelectionPath->AppendSymbol( selectedSymbols, static_cast<SCH_SYMBOL*>( item ),
true, true ); true, true );
@ -577,9 +578,8 @@ void SCH_SEXPR_PLUGIN::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSelect
SCH_SHEET_PATH subSheetPath = *aSelectionPath; SCH_SHEET_PATH subSheetPath = *aSelectionPath;
subSheetPath.push_back( static_cast<SCH_SHEET*>( item ) ); subSheetPath.push_back( static_cast<SCH_SHEET*>( item ) );
aFullSheetHierarchy->GetSheetsWithinPath( selectedSheets, subSheetPath ); fullHierarchy.GetSheetsWithinPath( selectedSheets, subSheetPath );
aFullSheetHierarchy->GetSymbolsWithinPath( selectedSymbols, subSheetPath, true, fullHierarchy.GetSymbolsWithinPath( selectedSymbols, subSheetPath, true, true );
true );
} }
break; break;
@ -634,7 +634,6 @@ void SCH_SEXPR_PLUGIN::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSelect
"Sheet is not inside the selection path?" ); "Sheet is not inside the selection path?" );
} }
selectedSymbols.SortByReferenceOnly(); selectedSymbols.SortByReferenceOnly();
std::vector<SYMBOL_INSTANCE_REFERENCE> symbolInstances = selectedSymbols.GetSymbolInstances(); std::vector<SYMBOL_INSTANCE_REFERENCE> symbolInstances = selectedSymbols.GetSymbolInstances();
@ -648,7 +647,7 @@ void SCH_SEXPR_PLUGIN::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSelect
} }
void SCH_SEXPR_PLUGIN::saveSymbol( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheetPath, void SCH_SEXPR_PLUGIN::saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSchematic,
int aNestLevel, bool aForClipboard ) int aNestLevel, bool aForClipboard )
{ {
wxCHECK_RET( aSymbol != nullptr && m_out != nullptr, "" ); wxCHECK_RET( aSymbol != nullptr && m_out != nullptr, "" );
@ -797,7 +796,8 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheetPa
m_out->Print( aNestLevel + 1, "(instances\n" ); m_out->Print( aNestLevel + 1, "(instances\n" );
KIID lastProjectUuid; KIID lastProjectUuid;
SCH_SHEET_LIST fullHierarchy = m_schematic->GetSheets(); KIID rootSheetUuid = aSchematic.Root().m_Uuid;
SCH_SHEET_LIST fullHierarchy = aSchematic.GetSheets();
for( size_t i = 0; i < aSymbol->GetInstanceReferences().size(); i++ ) for( size_t i = 0; i < aSymbol->GetInstanceReferences().size(); i++ )
{ {
@ -807,7 +807,7 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheetPa
// //
// Keep all instance data when copying to the clipboard. It may be needed on paste. // Keep all instance data when copying to the clipboard. It may be needed on paste.
if( !aForClipboard if( !aForClipboard
&& ( aSymbol->GetInstanceReferences()[i].m_Path[0] == m_schematic->RootScreen()->GetUuid() ) && ( aSymbol->GetInstanceReferences()[i].m_Path[0] == rootSheetUuid )
&& !fullHierarchy.GetSheetPathByKIIDPath( aSymbol->GetInstanceReferences()[i].m_Path ) ) && !fullHierarchy.GetSheetPathByKIIDPath( aSymbol->GetInstanceReferences()[i].m_Path ) )
{ {
if( ( i + 1 == aSymbol->GetInstanceReferences().size() ) if( ( i + 1 == aSymbol->GetInstanceReferences().size() )
@ -821,8 +821,8 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheetPa
{ {
wxString projectName; wxString projectName;
if( aSymbol->GetInstanceReferences()[i].m_Path[0] == m_schematic->RootScreen()->GetUuid() ) if( aSymbol->GetInstanceReferences()[i].m_Path[0] == rootSheetUuid )
projectName = m_schematic->Prj().GetProjectName(); projectName = aSchematic.Prj().GetProjectName();
else else
projectName = aSymbol->GetInstanceReferences()[i].m_ProjectName; projectName = aSymbol->GetInstanceReferences()[i].m_ProjectName;

View File

@ -108,8 +108,7 @@ public:
void Format( SCH_SHEET* aSheet ); void Format( SCH_SHEET* aSheet );
void Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSelectionPath, void Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSelectionPath,
SCH_SHEET_LIST* aFullSheetHierarchy, OUTPUTFORMATTER* aFormatter, const SCHEMATIC& aSchematic, OUTPUTFORMATTER* aFormatter, bool aForClipboard );
bool aForClipboard );
void EnumerateSymbolLib( wxArrayString& aSymbolNameList, void EnumerateSymbolLib( wxArrayString& aSymbolNameList,
const wxString& aLibraryPath, const wxString& aLibraryPath,
@ -146,7 +145,7 @@ private:
void loadHierarchy( const SCH_SHEET_PATH& aParentSheetPath, SCH_SHEET* aSheet ); void loadHierarchy( const SCH_SHEET_PATH& aParentSheetPath, SCH_SHEET* aSheet );
void loadFile( const wxString& aFileName, SCH_SHEET* aSheet ); void loadFile( const wxString& aFileName, SCH_SHEET* aSheet );
void saveSymbol( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheetPath, int aNestLevel, void saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSchematic, int aNestLevel,
bool aForClipboard ); bool aForClipboard );
void saveField( SCH_FIELD* aField, int aNestLevel ); void saveField( SCH_FIELD* aField, int aNestLevel );
void saveBitmap( SCH_BITMAP* aBitmap, int aNestLevel ); void saveBitmap( SCH_BITMAP* aBitmap, int aNestLevel );

View File

@ -1606,7 +1606,7 @@ bool SCH_EDITOR_CONTROL::doCopy( bool aUseLocalClipboard )
SCH_SHEET_LIST hierarchy = schematic.GetSheets(); SCH_SHEET_LIST hierarchy = schematic.GetSheets();
SCH_SHEET_PATH selPath = m_frame->GetCurrentSheet(); SCH_SHEET_PATH selPath = m_frame->GetCurrentSheet();
plugin.Format( &selection, &selPath, &hierarchy, &formatter, true ); plugin.Format( &selection, &selPath, schematic, &formatter, true );
if( aUseLocalClipboard ) if( aUseLocalClipboard )
{ {