Be more explicit about extent of schematic cleanups.

The new connectivity algorithm had a tendency to cleanup
globally, but that could insert undo records from other sheets
into the current screen's undo stack.  Needless to say, this
was a recipie for segfaults.

Fixes: lp:1846247
* https://bugs.launchpad.net/kicad/+bug/1846247
This commit is contained in:
Jeff Young 2019-11-10 23:24:27 +00:00
parent 1b14a38b01
commit 9d288968e7
9 changed files with 30 additions and 37 deletions

View File

@ -251,18 +251,6 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( SCH_SCREEN* aScreen )
}
void SCH_EDIT_FRAME::NormalizeSchematicOnFirstLoad( bool recalculateConnections )
{
SCH_SHEET_LIST list( g_RootSheet );
for( const auto& sheet : list )
SchematicCleanUp( sheet.LastScreen() );
if( recalculateConnections )
RecalculateConnections( false );
}
bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint,
SCH_LINE** aNewSegment, SCH_SCREEN* aScreen )
{

View File

@ -515,7 +515,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
TestConflictingBusAliases();
// The connection graph has a whole set of ERC checks it can run
m_parent->RecalculateConnections();
m_parent->RecalculateConnections( NO_CLEANUP );
g_ConnectionGraph->RunERC( m_settings );
// Test is all units of each multiunit component have the same footprint assigned.

View File

@ -96,7 +96,7 @@ DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS( SCH_
// TODO(JE) remove once real-time connectivity is a given
if( !ADVANCED_CFG::GetCfg().m_realTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
m_parent->RecalculateConnections();
m_parent->RecalculateConnections( NO_CLEANUP );
m_sdbSizerButtonsOK->SetDefault();

View File

@ -391,12 +391,6 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
SetScreen( g_CurrentSheet->LastScreen() );
// Ensure the schematic is fully segmented on first display
NormalizeSchematicOnFirstLoad( true );
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
// Migrate conflicting bus definitions
// TODO(JE) This should only run once based on schematic file version
if( g_ConnectionGraph->GetBusesNeedingMigration().size() > 0 )
@ -404,10 +398,14 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
DIALOG_MIGRATE_BUSES dlg( this );
dlg.ShowQuasiModal();
RecalculateConnections();
OnModify();
}
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
RecalculateConnections( GLOBAL_CLEANUP );
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
GetScreen()->m_Initialized = true;
}
@ -646,9 +644,6 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
SCH_SCREENS schematic;
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
// Ensure the schematic is fully segmented on first display
NormalizeSchematicOnFirstLoad( false );
GetScreen()->m_Initialized = true;
EE_TYPE_COLLECTOR components;
@ -675,11 +670,11 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
}
}
}
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
// Only perform the dangling end test on root sheet.
GetScreen()->TestDanglingEnds();
RecalculateConnections();
RecalculateConnections( GLOBAL_CLEANUP );
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );

View File

@ -238,7 +238,7 @@ NETLIST_OBJECT_LIST* SCH_EDIT_FRAME::CreateNetlist( bool aSilent,
NETLIST_OBJECT_LIST* SCH_EDIT_FRAME::BuildNetListBase( bool updateStatusText )
{
// Ensure netlist is up to date
RecalculateConnections();
RecalculateConnections( NO_CLEANUP );
// I own this list until I return it to the new owner.
std::unique_ptr<NETLIST_OBJECT_LIST> ret( new NETLIST_OBJECT_LIST() );

View File

@ -623,7 +623,7 @@ void SCH_EDIT_FRAME::OnModify()
GetScreen()->SetSave();
if( ADVANCED_CFG::GetCfg().m_realTimeConnectivity && CONNECTION_GRAPH::m_allowRealTime )
RecalculateConnections( false );
RecalculateConnections( NO_CLEANUP );
GetCanvas()->Refresh();
}
@ -987,7 +987,7 @@ void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_ITEM* aItem, bool aUndoAppe
// Update connectivity info for new item
if( !aItem->IsMoving() )
RecalculateConnections();
RecalculateConnections( LOCAL_CLEANUP );
}
else
{
@ -1056,14 +1056,17 @@ void SCH_EDIT_FRAME::UpdateTitle()
}
void SCH_EDIT_FRAME::RecalculateConnections( bool aDoCleanup )
void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
{
SCH_SHEET_LIST list( g_RootSheet );
PROF_COUNTER timer;
PROF_COUNTER timer;
// Ensure schematic graph is accurate
if( aDoCleanup )
if( aCleanupFlags == LOCAL_CLEANUP )
{
SchematicCleanUp( GetScreen() );
}
else if( aCleanupFlags == GLOBAL_CLEANUP )
{
for( const auto& sheet : list )
SchematicCleanUp( sheet.LastScreen() );

View File

@ -94,6 +94,13 @@ enum SCH_SEARCH_T {
};
enum SCH_CLEANUP_FLAGS {
NO_CLEANUP,
LOCAL_CLEANUP,
GLOBAL_CLEANUP
};
/**
* Schematic editor (Eeschema) main window.
*/
@ -1004,7 +1011,7 @@ public:
/**
* Generates the connection data for the entire schematic hierarchy.
*/
void RecalculateConnections( bool aDoCleanup = true );
void RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags );
/**
* Allows Eeschema to install its preferences panels into the preferences dialog.

View File

@ -782,7 +782,7 @@ int SCH_EDITOR_CONTROL::HighlightNetCursor( const TOOL_EVENT& aEvent )
{
// TODO(JE) remove once real-time connectivity is a given
if( !ADVANCED_CFG::GetCfg().m_realTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
m_frame->RecalculateConnections();
m_frame->RecalculateConnections( NO_CLEANUP );
std::string tool = aEvent.GetCommandStr().get();
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();

View File

@ -81,7 +81,7 @@ private:
// TODO(JE) remove once real-time is enabled
if( !ADVANCED_CFG::GetCfg().m_realTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
{
frame->RecalculateConnections();
frame->RecalculateConnections( NO_CLEANUP );
// Pick up the pointer again because it may have been changed by SchematicCleanUp
selection = selTool->RequestSelection( busType );