From 2f0337974bfeb5cab4d4b87a65a972f316fe9f2a Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Sat, 27 Jan 2024 12:02:22 -0500 Subject: [PATCH] Update schematic connectivity when redoing changes. Apparently we forgot to handle schematic connectivity changes when redoing undone changes. The same connectivity update logic that was added to the commit object is now used in SCH_EDIT_FRAME::PutDataInPreviousState(). Please note the granularity of connectivity rebuilds on schematic object property changes is at the object level which is overly aggressive. This means that connectivity rebuilds will happen when connectivity changes that have nothing to do with and objects connectivity are changed. Until objects can handle their own connectivity state, this will have to suffice. --- eeschema/schematic_undo_redo.cpp | 80 +++++++++++++++++++-------- eeschema/tools/sch_editor_control.cpp | 4 +- 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/eeschema/schematic_undo_redo.cpp b/eeschema/schematic_undo_redo.cpp index 4fe86bdc76..dffc98566e 100644 --- a/eeschema/schematic_undo_redo.cpp +++ b/eeschema/schematic_undo_redo.cpp @@ -27,9 +27,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -263,6 +265,8 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) std::vector bulkAddedItems; std::vector bulkRemovedItems; std::vector bulkChangedItems; + bool dirtyConnectivity = false; + SCH_CLEANUP_FLAGS connectivityCleanUp = NO_CLEANUP; // Undo in the reverse order of list creation: (this can allow stacked changes like the // same item can be changed and deleted in the same complex command). @@ -279,6 +283,44 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) eda_item->ClearEditFlags(); eda_item->ClearTempFlags(); + SCH_ITEM* schItem = dynamic_cast( eda_item ); + + // Set connectable object connectivity status. + if( schItem && schItem->IsConnectable() ) + { + schItem->SetConnectivityDirty(); + + if( schItem->Type() == SCH_SYMBOL_T ) + { + SCH_SYMBOL* symbol = static_cast( schItem ); + + wxCHECK2( symbol, continue ); + + for( SCH_PIN* pin : symbol->GetPins() ) + pin->SetConnectivityDirty(); + } + else if( schItem->Type() == SCH_SHEET_T ) + { + SCH_SHEET* sheet = static_cast( schItem ); + + wxCHECK2( sheet, continue ); + + for( SCH_SHEET_PIN* pin : sheet->GetPins() ) + pin->SetConnectivityDirty(); + } + + m_highlightedConnChanged = true; + dirtyConnectivity = true; + + // Do a local clean up if there are any connectable objects in the commit. + if( connectivityCleanUp == NO_CLEANUP ) + connectivityCleanUp = LOCAL_CLEANUP; + + // Do a full rebauild of the connectivity if there is a sheet in the commit. + if( schItem->Type() == SCH_SHEET_T ) + connectivityCleanUp = GLOBAL_CLEANUP; + } + if( status == UNDO_REDO::NEWITEM ) { // If we are removing the current sheet, get out first @@ -288,11 +330,6 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) GetToolManager()->PostAction( EE_ACTIONS::leaveSheet ); } - SCH_ITEM* schItem = static_cast( eda_item ); - - if( schItem && schItem->IsConnectable() ) - m_highlightedConnChanged = true; - RemoveFromScreen( eda_item, screen ); aList->SetPickedItemStatus( UNDO_REDO::DELETED, ii ); @@ -300,11 +337,6 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) } else if( status == UNDO_REDO::DELETED ) { - SCH_ITEM* schItem = static_cast( eda_item ); - - if( schItem && schItem->IsConnectable() ) - m_highlightedConnChanged = true; - // deleted items are re-inserted on undo AddToScreen( eda_item, screen ); aList->SetPickedItemStatus( UNDO_REDO::NEWITEM, ii ); @@ -329,9 +361,6 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) } else if( SCH_ITEM* item = dynamic_cast( eda_item ) ) { - if( item->IsConnectable() ) - m_highlightedConnChanged = true; - // everything else is modified in place SCH_ITEM* alt_item = static_cast( aList->GetPickedItemLink( ii ) ); @@ -392,6 +421,20 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList ) if( bulkChangedItems.size() > 0 ) Schematic().OnItemsChanged( bulkChangedItems ); + + if( dirtyConnectivity ) + { + SCH_COMMIT localCommit( m_toolManager ); + + RecalculateConnections( &localCommit, connectivityCleanUp ); + + // Update the hierarchy navigator when there are sheet changes. + if( connectivityCleanUp == GLOBAL_CLEANUP ) + { + SetSheetNumberAndCount(); + UpdateHierarchyNavigator(); + } + } } @@ -414,19 +457,8 @@ void SCH_EDIT_FRAME::RollbackSchematicFromUndo() delete aItem; } ); - // Only rebuild the hierarchy navigator if there are sheet changes. - bool hasSheets = undo->ContainsItemType( SCH_SHEET_T ); - delete undo; - if( hasSheets ) - { - SetSheetNumberAndCount(); - UpdateHierarchyNavigator(); - } - - TestDanglingEnds(); - m_toolManager->GetTool()->RebuildSelection(); } diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index ee9659eae2..b49e80e860 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -2186,7 +2186,9 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) { // Pushing the commit will update the connectivity. commit.Push( _( "Paste" ) ); - m_frame->UpdateHierarchyNavigator(); + + if( sheetsPasted ) + m_frame->UpdateHierarchyNavigator(); } else {