Fix assertion when pasting schematic sheets.
Pasted sheets do not have assigned SCH_SCREEN objects until after they are loaded. Do not recalculate connectivity unless the SCH_COMMIT object actually has connectable schematic object changes. Fixes https://gitlab.com/kicad/code/kicad/-/issues/16579
This commit is contained in:
parent
ec3bf79c42
commit
d3f40dde3f
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2023-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -209,7 +209,7 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
|
|||
if( schItem->IsSelected() )
|
||||
selectedModified = true;
|
||||
|
||||
if( !( aCommitFlags & SKIP_CONNECTIVITY ) )
|
||||
if( !( aCommitFlags & SKIP_CONNECTIVITY ) && schItem->IsConnectable() )
|
||||
dirtyConnectivity = true;
|
||||
|
||||
switch( changeType )
|
||||
|
@ -325,7 +325,9 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
|
|||
if( frame )
|
||||
{
|
||||
frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED, false, dirtyConnectivity );
|
||||
frame->RecalculateConnections( this, NO_CLEANUP );
|
||||
|
||||
if( dirtyConnectivity )
|
||||
frame->RecalculateConnections( this, NO_CLEANUP );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1513,56 +1513,25 @@ SCH_SHEET_PATH SCH_EDITOR_CONTROL::updatePastedSheet( const SCH_SHEET_PATH& aPas
|
|||
}
|
||||
|
||||
|
||||
void SCH_EDITOR_CONTROL::setPastedSheetInstances( const SCH_SHEET* aPastedSheet )
|
||||
void SCH_EDITOR_CONTROL::setPastedSymbolInstances( const SCH_SCREEN* aScreen )
|
||||
{
|
||||
wxCHECK( aPastedSheet, /* void */ );
|
||||
wxCHECK( aScreen, /* void */ );
|
||||
|
||||
for( const SCH_SHEET_INSTANCE& sheetInstance : aPastedSheet->GetInstances() )
|
||||
for( const SCH_ITEM* item : aScreen->Items() )
|
||||
{
|
||||
KIID_PATH pathWithSheet = sheetInstance.m_Path;
|
||||
|
||||
pathWithSheet.push_back( aPastedSheet->m_Uuid );
|
||||
m_clipboardSheetInstances[pathWithSheet] = sheetInstance;
|
||||
}
|
||||
|
||||
const SCH_SCREEN* screen = aPastedSheet->GetScreen();
|
||||
|
||||
wxCHECK( screen, /* void */ );
|
||||
|
||||
for( SCH_ITEM* item : screen->Items() )
|
||||
{
|
||||
if( item->Type() == SCH_SHEET_T )
|
||||
if( item->Type() == SCH_SYMBOL_T )
|
||||
{
|
||||
const SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
|
||||
const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( item );
|
||||
|
||||
wxCHECK2( sheet, continue );
|
||||
wxCHECK2( symbol, continue );
|
||||
|
||||
setPastedSheetInstances( sheet );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_EDITOR_CONTROL::setPastedSymbolInstances( SCH_SCREENS& aScreenList )
|
||||
{
|
||||
for( SCH_SCREEN* screen = aScreenList.GetFirst(); screen; screen = aScreenList.GetNext() )
|
||||
{
|
||||
for( const SCH_ITEM* item : screen->Items() )
|
||||
{
|
||||
if( item->Type() == SCH_SYMBOL_T )
|
||||
for( const SCH_SYMBOL_INSTANCE& symbolInstance : symbol->GetInstances() )
|
||||
{
|
||||
const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( item );
|
||||
KIID_PATH pathWithSymbol = symbolInstance.m_Path;
|
||||
|
||||
wxCHECK2( symbol, continue );
|
||||
pathWithSymbol.push_back( symbol->m_Uuid );
|
||||
|
||||
for( const SCH_SYMBOL_INSTANCE& symbolInstance : symbol->GetInstances() )
|
||||
{
|
||||
KIID_PATH pathWithSymbol = symbolInstance.m_Path;
|
||||
|
||||
pathWithSymbol.push_back( symbol->m_Uuid );
|
||||
|
||||
m_clipboardSymbolInstances[pathWithSymbol] = symbolInstance;
|
||||
}
|
||||
m_clipboardSymbolInstances[pathWithSymbol] = symbolInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1640,15 +1609,11 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
|||
tempScreen->Append( text_item );
|
||||
}
|
||||
|
||||
SCH_SCREENS tempScreens( tempSheet );
|
||||
|
||||
m_pastedSymbols.clear();
|
||||
m_clipboardSheetInstances.clear();
|
||||
m_clipboardSymbolInstances.clear();
|
||||
|
||||
// Save pasted sheet and symbol instances.
|
||||
setPastedSheetInstances( &tempSheet );
|
||||
setPastedSymbolInstances( tempScreens );
|
||||
// Save pasted symbol instances in case the user chooses to keep existing symbol annotation.
|
||||
setPastedSymbolInstances( tempScreen );
|
||||
|
||||
tempScreen->MigrateSimModels();
|
||||
|
||||
|
@ -1867,6 +1832,9 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
|||
m_frame->InitSheet( sheet, sheet->GetFileName() );
|
||||
}
|
||||
|
||||
// Save the symbol instances in case the user chooses to keep the existing
|
||||
// symbol annotation.
|
||||
setPastedSymbolInstances( sheet->GetScreen() );
|
||||
sheetsPasted = true;
|
||||
|
||||
// Push it to the clipboard path while it still has its old KIID
|
||||
|
@ -1960,7 +1928,6 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
m_frame->SetSheetNumberAndCount();
|
||||
m_frame->UpdateHierarchyNavigator();
|
||||
|
||||
// Get a version with correct sheet numbers since we've pasted sheets,
|
||||
// we'll need this when annotating next
|
||||
|
@ -2124,9 +2091,15 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
if( m_toolMgr->RunSynchronousAction( EE_ACTIONS::move, &commit ) )
|
||||
{
|
||||
// Pushing the commit will update the connectivity.
|
||||
commit.Push( _( "Paste" ) );
|
||||
m_frame->UpdateHierarchyNavigator();
|
||||
}
|
||||
else
|
||||
{
|
||||
commit.Revert();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -191,8 +191,7 @@ private:
|
|||
SCH_SHEET_LIST* aPastedSheetsSoFar,
|
||||
SCH_REFERENCE_LIST* aPastedSymbolsSoFar );
|
||||
|
||||
void setPastedSheetInstances( const SCH_SHEET* aPastedSheet );
|
||||
void setPastedSymbolInstances( SCH_SCREENS& aScreenList );
|
||||
void setPastedSymbolInstances( const SCH_SCREEN* aScreen );
|
||||
|
||||
/**
|
||||
* Remove all pasted symbol instances that do not belong to the current project.
|
||||
|
@ -246,9 +245,6 @@ private:
|
|||
// A map of KIID_PATH --> symbol instances for the clipboard contents.
|
||||
std::map<KIID_PATH, SCH_SYMBOL_INSTANCE> m_clipboardSymbolInstances;
|
||||
|
||||
// A map of KIID_PATH --> sheet instances for the clipboard contents.
|
||||
std::map<KIID_PATH, SCH_SHEET_INSTANCE> m_clipboardSheetInstances;
|
||||
|
||||
std::set<SCH_SYMBOL*> m_pastedSymbols;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue