Fix crash on save after pasting symbols in schematic editor.
This was caused by pasting zero length instance paths which are not valid. Fixes https://gitlab.com/kicad/code/kicad/-/issues/16300
This commit is contained in:
parent
7554e629a8
commit
484491aaea
|
@ -1387,21 +1387,19 @@ void SCH_EDITOR_CONTROL::updatePastedSymbol( SCH_SYMBOL* aSymbol, SCH_SCREEN* aP
|
||||||
const KIID_PATH& aClipPath,
|
const KIID_PATH& aClipPath,
|
||||||
bool aForceKeepAnnotations )
|
bool aForceKeepAnnotations )
|
||||||
{
|
{
|
||||||
wxCHECK( aSymbol && aPasteScreen, /* void */ );
|
wxCHECK( m_frame && aSymbol && aPasteScreen, /* void */ );
|
||||||
|
|
||||||
KIID_PATH clipItemPath = aClipPath;
|
SCH_SYMBOL_INSTANCE instance;
|
||||||
|
KIID_PATH pasteLookupPath = aClipPath;
|
||||||
|
|
||||||
wxString reference, value, footprint;
|
m_pastedSymbols.insert( aSymbol );
|
||||||
int unit;
|
|
||||||
|
|
||||||
clipItemPath.push_back( aSymbol->m_Uuid );
|
// The pasted symbol look up paths include the symbol UUID.
|
||||||
|
pasteLookupPath.push_back( aSymbol->m_Uuid );
|
||||||
|
|
||||||
if( m_clipboardSymbolInstances.count( clipItemPath ) > 0 )
|
if( m_clipboardSymbolInstances.count( pasteLookupPath ) > 0 )
|
||||||
{
|
{
|
||||||
SCH_SYMBOL_INSTANCE instance = m_clipboardSymbolInstances.at( clipItemPath );
|
instance = m_clipboardSymbolInstances.at( pasteLookupPath );
|
||||||
|
|
||||||
unit = instance.m_Unit;
|
|
||||||
reference = instance.m_Reference;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1412,20 +1410,20 @@ void SCH_EDITOR_CONTROL::updatePastedSymbol( SCH_SYMBOL* aSymbol, SCH_SCREEN* aP
|
||||||
|
|
||||||
// Pasted from notepad or an older instance of eeschema. Use the values in the fields
|
// Pasted from notepad or an older instance of eeschema. Use the values in the fields
|
||||||
// instead.
|
// instead.
|
||||||
reference = aSymbol->GetField( REFERENCE_FIELD )->GetText();
|
instance.m_Reference = aSymbol->GetField( REFERENCE_FIELD )->GetText();
|
||||||
value = aSymbol->GetField( VALUE_FIELD )->GetText();
|
instance.m_Unit = aSymbol->GetUnit();
|
||||||
footprint = aSymbol->GetField( FOOTPRINT_FIELD )->GetText();
|
|
||||||
unit = aSymbol->GetUnit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( aForceKeepAnnotations && !reference.IsEmpty() )
|
instance.m_Path = aPastePath.Path() + aClipPath;
|
||||||
aSymbol->SetRef( &aPastePath, reference );
|
instance.m_ProjectName = m_frame->Prj().GetProjectName();
|
||||||
else
|
|
||||||
|
aSymbol->AddHierarchicalReference( instance );
|
||||||
|
|
||||||
|
if( !aForceKeepAnnotations )
|
||||||
aSymbol->ClearAnnotation( &aPastePath, false );
|
aSymbol->ClearAnnotation( &aPastePath, false );
|
||||||
|
|
||||||
// We might clear annotations but always leave the original unit number from the paste.
|
// We might clear annotations but always leave the original unit number from the paste.
|
||||||
aSymbol->SetUnitSelection( &aPastePath, unit );
|
aSymbol->SetUnit( instance.m_Unit );
|
||||||
aSymbol->SetUnit( unit );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1531,6 +1529,29 @@ void SCH_EDITOR_CONTROL::setPastedSymbolInstances( SCH_SCREENS& aScreenList )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_EDITOR_CONTROL::prunePastedSymbolInstances()
|
||||||
|
{
|
||||||
|
wxCHECK( m_frame, /* void */ );
|
||||||
|
|
||||||
|
for( SCH_SYMBOL* symbol : m_pastedSymbols )
|
||||||
|
{
|
||||||
|
wxCHECK2( symbol, continue );
|
||||||
|
|
||||||
|
std::vector<KIID_PATH> instancePathsToRemove;
|
||||||
|
|
||||||
|
for( const SCH_SYMBOL_INSTANCE& instance : symbol->GetInstanceReferences() )
|
||||||
|
{
|
||||||
|
if( ( instance.m_ProjectName != m_frame->Prj().GetProjectName() )
|
||||||
|
|| instance.m_Path.empty() )
|
||||||
|
instancePathsToRemove.emplace_back( instance.m_Path );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( const KIID_PATH& path : instancePathsToRemove )
|
||||||
|
symbol->RemoveInstance( path );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wxWindow::FindFocus() );
|
wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( wxWindow::FindFocus() );
|
||||||
|
@ -1581,6 +1602,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
SCH_SCREENS tempScreens( tempSheet );
|
SCH_SCREENS tempScreens( tempSheet );
|
||||||
|
|
||||||
|
m_pastedSymbols.clear();
|
||||||
m_clipboardSheetInstances.clear();
|
m_clipboardSheetInstances.clear();
|
||||||
m_clipboardSymbolInstances.clear();
|
m_clipboardSymbolInstances.clear();
|
||||||
|
|
||||||
|
@ -1934,6 +1956,8 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
m_frame->GetCurrentSheet().UpdateAllScreenReferences();
|
m_frame->GetCurrentSheet().UpdateAllScreenReferences();
|
||||||
|
|
||||||
|
prunePastedSymbolInstances();
|
||||||
|
|
||||||
// The copy operation creates instance paths that are not valid for the current project or
|
// The copy operation creates instance paths that are not valid for the current project or
|
||||||
// saved as part of another project. Prune them now so they do not accumulate in the saved
|
// saved as part of another project. Prune them now so they do not accumulate in the saved
|
||||||
// schematic file.
|
// schematic file.
|
||||||
|
|
|
@ -194,6 +194,16 @@ private:
|
||||||
void setPastedSheetInstances( const SCH_SHEET* aPastedSheet );
|
void setPastedSheetInstances( const SCH_SHEET* aPastedSheet );
|
||||||
void setPastedSymbolInstances( SCH_SCREENS& aScreenList );
|
void setPastedSymbolInstances( SCH_SCREENS& aScreenList );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all pasted symbol instances that do not belong to the current project.
|
||||||
|
*
|
||||||
|
* @warning This should **only** be called when cleaning up after a paste. Otherwise it
|
||||||
|
* could clobber symbol instances for schematics shared across projects. Use
|
||||||
|
* SCH_SCREENS::PruneOrphanedSymbolInstances() to clean up invalid instance for
|
||||||
|
* the current project.
|
||||||
|
*/
|
||||||
|
void prunePastedSymbolInstances();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the footprint info from each line in the stuff file by reference designator.
|
* Read the footprint info from each line in the stuff file by reference designator.
|
||||||
*
|
*
|
||||||
|
@ -238,6 +248,8 @@ private:
|
||||||
|
|
||||||
// A map of KIID_PATH --> sheet instances for the clipboard contents.
|
// A map of KIID_PATH --> sheet instances for the clipboard contents.
|
||||||
std::map<KIID_PATH, SCH_SHEET_INSTANCE> m_clipboardSheetInstances;
|
std::map<KIID_PATH, SCH_SHEET_INSTANCE> m_clipboardSheetInstances;
|
||||||
|
|
||||||
|
std::set<SCH_SYMBOL*> m_pastedSymbols;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020 Ian McInerney <ian.s.mcinerney@ieee.org>
|
* Copyright (C) 2020 Ian McInerney <ian.s.mcinerney@ieee.org>
|
||||||
* Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
* Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.TXT for contributors.
|
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.TXT for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -191,6 +191,20 @@ public:
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KIID_PATH& operator+=( const KIID_PATH& aRhs )
|
||||||
|
{
|
||||||
|
for( const KIID& kiid : aRhs )
|
||||||
|
emplace_back( kiid );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend KIID_PATH operator+( KIID_PATH aLhs, const KIID_PATH& aRhs )
|
||||||
|
{
|
||||||
|
aLhs += aRhs;
|
||||||
|
return aLhs;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue