Fix symbol annotation when pasting nested hierarchical sheets.

This commit is contained in:
Wayne Stambaugh 2024-01-25 16:34:49 -05:00
parent 9e9dfb38d1
commit 4d6bbc8caa
2 changed files with 87 additions and 43 deletions

View File

@ -1422,27 +1422,41 @@ int SCH_EDITOR_CONTROL::Copy( const TOOL_EVENT& aEvent )
}
void SCH_EDITOR_CONTROL::updatePastedSymbol( SCH_SYMBOL* aSymbol, SCH_SCREEN* aPasteScreen,
void SCH_EDITOR_CONTROL::updatePastedSymbol( SCH_SYMBOL* aSymbol,
const SCH_SHEET_PATH& aPastePath,
const KIID_PATH& aClipPath,
bool aForceKeepAnnotations )
{
wxCHECK( m_frame && aSymbol && aPasteScreen, /* void */ );
wxCHECK( m_frame && aSymbol, /* void */ );
SCH_SYMBOL_INSTANCE instance;
SCH_SYMBOL_INSTANCE newInstance;
bool instanceFound = false;
KIID_PATH pasteLookupPath = aClipPath;
m_pastedSymbols.insert( aSymbol );
for( const SCH_SYMBOL_INSTANCE& tmp : aSymbol->GetInstances() )
{
if( tmp.m_Path.EndsWith( aClipPath ) )
{
newInstance = tmp;
instanceFound = true;
wxLogDebug( wxS( "Pasting found symbol instance:\n\tpath: %s\n\tuuid: %s." ),
aClipPath.AsString(), aSymbol->m_Uuid.AsString() );
break;
}
}
// The pasted symbol look up paths include the symbol UUID.
pasteLookupPath.push_back( aSymbol->m_Uuid );
if( m_clipboardSymbolInstances.count( pasteLookupPath ) > 0 )
{
instance = m_clipboardSymbolInstances.at( pasteLookupPath );
}
else
if( !instanceFound )
{
wxLogDebug( wxS( "Clipboard symbol instance **not** found:\n\tpath: %s\n\tuuid: %s." ),
aClipPath.AsString(), aSymbol->m_Uuid.AsString() );
// Some legacy versions saved value fields escaped. While we still do in the symbol
// editor, we don't anymore in the schematic, so be sure to unescape them.
SCH_FIELD* valueField = aSymbol->GetField( VALUE_FIELD );
@ -1450,36 +1464,36 @@ 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
// instead.
instance.m_Reference = aSymbol->GetField( REFERENCE_FIELD )->GetText();
instance.m_Unit = aSymbol->GetUnit();
newInstance.m_Reference = aSymbol->GetField( REFERENCE_FIELD )->GetText();
newInstance.m_Unit = aSymbol->GetUnit();
}
instance.m_Path = aPastePath.Path() + aClipPath;
instance.m_ProjectName = m_frame->Prj().GetProjectName();
newInstance.m_Path = aPastePath.Path();
newInstance.m_ProjectName = m_frame->Prj().GetProjectName();
aSymbol->AddHierarchicalReference( instance );
aSymbol->AddHierarchicalReference( newInstance );
if( !aForceKeepAnnotations )
aSymbol->ClearAnnotation( &aPastePath, false );
// We might clear annotations but always leave the original unit number from the paste.
aSymbol->SetUnit( instance.m_Unit );
aSymbol->SetUnit( newInstance.m_Unit );
}
SCH_SHEET_PATH SCH_EDITOR_CONTROL::updatePastedSheet( const SCH_SHEET_PATH& aPastePath,
SCH_SHEET_PATH SCH_EDITOR_CONTROL::updatePastedSheet( SCH_SHEET* aSheet,
const SCH_SHEET_PATH& aPastePath,
const KIID_PATH& aClipPath,
SCH_SHEET* aSheet,
bool aForceKeepAnnotations,
SCH_SHEET_LIST* aPastedSheetsSoFar,
SCH_REFERENCE_LIST* aPastedSymbolsSoFar )
SCH_SHEET_LIST* aPastedSheets,
std::map<SCH_SHEET_PATH, SCH_REFERENCE_LIST>& aPastedSymbols )
{
wxCHECK( aSheet && aPastedSheetsSoFar && aPastedSymbolsSoFar, aPastePath );
wxCHECK( aSheet && aPastedSheets, aPastePath );
SCH_SHEET_PATH sheetPath = aPastePath;
sheetPath.push_back( aSheet );
aPastedSheetsSoFar->push_back( sheetPath );
aPastedSheets->push_back( sheetPath );
if( aSheet->GetScreen() == nullptr )
return sheetPath; // We can only really set the page number but not load any items
@ -1505,8 +1519,7 @@ SCH_SHEET_PATH SCH_EDITOR_CONTROL::updatePastedSheet( const SCH_SHEET_PATH& aPas
}
}
updatePastedSymbol( symbol, aSheet->GetScreen(), sheetPath, aClipPath,
aForceKeepAnnotations );
updatePastedSymbol( symbol, sheetPath, aClipPath, aForceKeepAnnotations );
}
else if( item->Type() == SCH_SHEET_T )
{
@ -1515,7 +1528,7 @@ SCH_SHEET_PATH SCH_EDITOR_CONTROL::updatePastedSheet( const SCH_SHEET_PATH& aPas
wxCHECK2( subsheet, continue );
// Make sure pins get a new UUID and set the dirty connectivity flag.
if( !aPastedSheetsSoFar->ContainsSheet( subsheet ) )
if( !aPastedSheets->ContainsSheet( subsheet ) )
{
for( SCH_SHEET_PIN* pin : subsheet->GetPins() )
{
@ -1527,16 +1540,13 @@ SCH_SHEET_PATH SCH_EDITOR_CONTROL::updatePastedSheet( const SCH_SHEET_PATH& aPas
KIID_PATH newClipPath = aClipPath;
newClipPath.push_back( subsheet->m_Uuid );
updatePastedSheet( sheetPath, newClipPath, subsheet, aForceKeepAnnotations,
aPastedSheetsSoFar, aPastedSymbolsSoFar );
SCH_SHEET_PATH subSheetPath = sheetPath;
subSheetPath.push_back( subsheet );
subSheetPath.GetSymbols( *aPastedSymbolsSoFar );
updatePastedSheet( subsheet, sheetPath, newClipPath, aForceKeepAnnotations,
aPastedSheets, aPastedSymbols );
}
}
sheetPath.GetSymbols( aPastedSymbols[aPastePath] );
return sheetPath;
}
@ -1615,7 +1625,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
eventPos = getViewControls()->GetCursorPosition( false );
STRING_LINE_READER reader( content, "Clipboard" );
SCH_IO_KICAD_SEXPR plugin;
SCH_IO_KICAD_SEXPR plugin;
SCH_SHEET tempSheet;
SCH_SCREEN* tempScreen = new SCH_SCREEN( &m_frame->Schematic() );
@ -1787,7 +1797,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
}
for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
updatePastedSymbol( symbol, tempScreen, sheetPath, clipPath, forceKeepAnnotations );
updatePastedSymbol( symbol, sheetPath, clipPath, forceKeepAnnotations );
// Assign a new KIID
const_cast<KIID&>( item->m_Uuid ) = KIID();
@ -1892,12 +1902,10 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
// reset the annotations or copy "kept" annotations from the supplementary clipboard.
for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen )
{
SCH_SHEET_PATH subPath = updatePastedSheet( sheetPath, clipPath, sheet,
SCH_SHEET_PATH subPath = updatePastedSheet( sheet, sheetPath, clipPath,
( forceKeepAnnotations && annotate.automatic ),
&pastedSheets[sheetPath],
&pastedSymbols[sheetPath] );
subPath.GetSymbols( pastedSymbols[sheetPath] );
pastedSymbols );
}
}
else
@ -1995,6 +2003,19 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
annotatedSymbols[sheetPath].AddItem( pastedSymbols[sheetPath][i] );
}
}
for( const SCH_SHEET_PATH& pastedSheetPath : pastedSheets[sheetPath] )
{
for( size_t i = 0; i < pastedSymbols[pastedSheetPath].GetCount(); i++ )
{
if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS
|| pasteMode == PASTE_MODE::RESPECT_OPTIONS
|| pastedSymbols[pastedSheetPath][i].AlwaysAnnotate() )
{
annotatedSymbols[pastedSheetPath].AddItem( pastedSymbols[pastedSheetPath][i] );
}
}
}
}
if( !annotatedSymbols.empty() )
@ -2020,6 +2041,30 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
// Update existing refs for next iteration
for( size_t i = 0; i < annotatedSymbols[path].GetCount(); i++ )
existingRefs.AddItem( annotatedSymbols[path][i] );
for( const SCH_SHEET_PATH& pastedSheetPath : pastedSheets[path] )
{
annotatedSymbols[pastedSheetPath].SortByReferenceOnly();
if( pasteMode == PASTE_MODE::UNIQUE_ANNOTATIONS )
{
annotatedSymbols[pastedSheetPath].ReannotateDuplicates( existingRefs );
}
else
{
annotatedSymbols[pastedSheetPath].ReannotateByOptions( (ANNOTATE_ORDER_T) annotate.sort_order,
(ANNOTATE_ALGO_T) annotate.method,
annotateStartNum, existingRefs,
false,
&hierarchy );
}
annotatedSymbols[pastedSheetPath].UpdateAnnotation();
// Update existing refs for next iteration
for( size_t i = 0; i < annotatedSymbols[pastedSheetPath].GetCount(); i++ )
existingRefs.AddItem( annotatedSymbols[pastedSheetPath][i] );
}
}
}

View File

@ -182,14 +182,13 @@ private:
void doCrossProbeSchToPcb( const TOOL_EVENT& aEvent, bool aForce );
void updatePastedSymbol( SCH_SYMBOL* aSymbol, SCH_SCREEN* aPasteScreen,
const SCH_SHEET_PATH& aPastePath, const KIID_PATH& aClipPath,
bool aForceKeepAnnotations );
void updatePastedSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_PATH& aPastePath,
const KIID_PATH& aClipPath, bool aForceKeepAnnotations );
SCH_SHEET_PATH updatePastedSheet( const SCH_SHEET_PATH& aPastePath, const KIID_PATH& aClipPath,
SCH_SHEET* aSheet, bool aForceKeepAnnotations,
SCH_SHEET_LIST* aPastedSheetsSoFar,
SCH_REFERENCE_LIST* aPastedSymbolsSoFar );
SCH_SHEET_PATH updatePastedSheet( SCH_SHEET* aSheet, const SCH_SHEET_PATH& aPastePath,
const KIID_PATH& aClipPath, bool aForceKeepAnnotations,
SCH_SHEET_LIST* aPastedSheets,
std::map<SCH_SHEET_PATH, SCH_REFERENCE_LIST>& aPastedSymbols );
void setPastedSymbolInstances( const SCH_SCREEN* aScreen );