diff --git a/common/advanced_config.cpp b/common/advanced_config.cpp index 452e78b1bb..ef2d56d0d6 100644 --- a/common/advanced_config.cpp +++ b/common/advanced_config.cpp @@ -240,7 +240,7 @@ ADVANCED_CFG::ADVANCED_CFG() m_Use3DConnexionDriver = true; - m_IncrementalConnectivity = false; + m_IncrementalConnectivity = true; m_DisambiguationMenuDelay = 300; diff --git a/eeschema/sch_commit.cpp b/eeschema/sch_commit.cpp index 2dd69e4877..d7d485f4cc 100644 --- a/eeschema/sch_commit.cpp +++ b/eeschema/sch_commit.cpp @@ -183,6 +183,7 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags ) bool itemsDeselected = false; bool selectedModified = false; bool dirtyConnectivity = false; + SCH_CLEANUP_FLAGS connectivityCleanUp = NO_CLEANUP; if( Empty() ) return; @@ -210,8 +211,18 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags ) selectedModified = true; if( !( aCommitFlags & SKIP_CONNECTIVITY ) && schItem->IsConnectable() ) + { 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; + } + switch( changeType ) { case CHT_ADD: @@ -327,7 +338,7 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags ) frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED, false, dirtyConnectivity ); if( dirtyConnectivity ) - frame->RecalculateConnections( this, NO_CLEANUP ); + frame->RecalculateConnections( this, connectivityCleanUp ); } } diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index ad53689839..15fd4d3766 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -1703,21 +1704,23 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_COMMIT* aCommit, SCH_CLEANUP_FL for( unsigned ii = 0; ii < changed_list->GetCount(); ++ii ) { - EDA_ITEM* item = changed_list->GetPickedItem( ii ); + SCH_ITEM* item = static_cast( changed_list->GetPickedItem( ii ) ); - if( !item || !IsEeschemaType( item->Type() ) ) + wxCHECK2( item, continue ); + + // Ignore objects that are not connectable. + if( !item->IsConnectable() ) continue; SCH_SCREEN* screen = static_cast( changed_list->GetScreenForItem( ii ) ); - SCH_ITEM* sch_item = static_cast( item ); SCH_SHEET_PATHS& paths = screen->GetClientSheetPaths(); - std::vector tmp_pts = sch_item->GetConnectionPoints(); + std::vector tmp_pts = item->GetConnectionPoints(); pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() ); - changed_items.insert( sch_item ); + changed_items.insert( item ); for( SCH_SHEET_PATH& path : paths ) - item_paths.insert( std::make_pair( path, sch_item ) ); + item_paths.insert( std::make_pair( path, item ) ); } for( VECTOR2I& pt: pts ) @@ -1736,8 +1739,18 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_COMMIT* aCommit, SCH_CLEANUP_FL changed_items.insert( pins.begin(), pins.end() ); } - else if( item->IsConnectable() ) + else if( item->Type() == SCH_SHEET_T ) { + SCH_SHEET* sheet = static_cast( item ); + + wxCHECK2( sheet, continue ); + + std::vector sheetPins = sheet->GetPins(); + changed_items.insert( sheetPins.begin(), sheetPins.end() ); + } + else + { + // Non-connectable objects have already been pruned. if( item->IsConnected( pt ) ) changed_items.insert( item ); } diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index c17668132b..69a59b2bd8 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -1345,3 +1345,18 @@ bool SCH_SHEET_LIST::HasPath( const KIID_PATH& aPath ) const return false; } + + +bool SCH_SHEET_LIST::ContainsSheet( const SCH_SHEET* aSheet ) const +{ + for( const SCH_SHEET_PATH& path : *this ) + { + for( size_t i = 0; i < path.size(); i++ ) + { + if( path.at( i ) == aSheet ) + return true; + } + } + + return false; +} diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index 3cd5b42a48..cd84dd3a50 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -681,6 +681,8 @@ public: bool HasPath( const KIID_PATH& aPath ) const; + bool ContainsSheet( const SCH_SHEET* aSheet ) const; + private: SCH_SHEET_PATH m_currentSheetPath; }; diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 042e8ed3d6..53864837e8 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -1485,10 +1485,25 @@ SCH_SHEET_PATH SCH_EDITOR_CONTROL::updatePastedSheet( const SCH_SHEET_PATH& aPas for( SCH_ITEM* item : aSheet->GetScreen()->Items() ) { + if( item->IsConnectable() ) + item->SetConnectivityDirty(); + if( item->Type() == SCH_SYMBOL_T ) { SCH_SYMBOL* symbol = static_cast( item ); + wxCHECK2( symbol, continue ); + + // Only do this once if the symbol is shared across multiple sheets. + if( !m_pastedSymbols.count( symbol ) ) + { + for( SCH_PIN* pin : symbol->GetPins() ) + { + const_cast( pin->m_Uuid ) = KIID(); + pin->SetConnectivityDirty(); + } + } + updatePastedSymbol( symbol, aSheet->GetScreen(), sheetPath, aClipPath, aForceKeepAnnotations ); } @@ -1496,6 +1511,18 @@ SCH_SHEET_PATH SCH_EDITOR_CONTROL::updatePastedSheet( const SCH_SHEET_PATH& aPas { SCH_SHEET* subsheet = static_cast( item ); + wxCHECK2( subsheet, continue ); + + // Make sure pins get a new UUID and set the dirty connectivity flag. + if( !aPastedSheetsSoFar->ContainsSheet( subsheet ) ) + { + for( SCH_SHEET_PIN* pin : subsheet->GetPins() ) + { + const_cast( pin->m_Uuid ) = KIID(); + pin->SetConnectivityDirty(); + } + } + KIID_PATH newClipPath = aClipPath; newClipPath.push_back( subsheet->m_Uuid ); @@ -1721,6 +1748,13 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) { KIID_PATH clipPath( wxT( "/" ) ); // clipboard is at root + SCH_ITEM* schItem = static_cast( item ); + + wxCHECK2( schItem, continue ); + + if( schItem->IsConnectable() ) + schItem->SetConnectivityDirty(); + if( item->Type() == SCH_SYMBOL_T ) { SCH_SYMBOL* symbol = static_cast( item ); @@ -1759,7 +1793,10 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) // Make sure pins get a new UUID for( SCH_PIN* pin : symbol->GetPins() ) + { const_cast( pin->m_Uuid ) = KIID(); + pin->SetConnectivityDirty(); + } for( SCH_SHEET_PATH& sheetPath : sheetPathsForScreen ) { @@ -1845,7 +1882,10 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) // Make sure pins get a new UUID for( SCH_SHEET_PIN* pin : sheet->GetPins() ) + { const_cast( pin->m_Uuid ) = KIID(); + pin->SetConnectivityDirty(); + } // Once we have our new KIID we can update all pasted instances. This will either // reset the annotations or copy "kept" annotations from the supplementary clipboard.