diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 1ffc6742d1..542984ed25 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -1722,6 +1722,18 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) return 0; } + auto isSelectedForDelete = + []( BOARD_ITEM* aItem ) + { + for( BOARD_ITEM* item = aItem; item; item = item->GetParentGroup() ) + { + if( item->IsSelected() ) + return true; + } + + return false; + }; + std::vector lockedItems; Activate(); @@ -1729,6 +1741,7 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) PCB_SELECTION selectionCopy; bool isCut = aEvent.Parameter() == PCB_ACTIONS::REMOVE_FLAGS::CUT; bool isAlt = aEvent.Parameter() == PCB_ACTIONS::REMOVE_FLAGS::ALT; + std::vector disallowedPads; // If we are in a "Cut" operation, then the copied selection exists already and we want to // delete exactly that; no more, no fewer. Any filtering for locked items must be done in @@ -1743,7 +1756,35 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool ) { }, - !m_isFootprintEditor /* prompt user regarding locked items */ ); + false /* ignore locked items until after we filter out non-free pads */ ); + + if( !IsFootprintEditor() && !frame()->Settings().m_AllowFreePads ) + { + for( EDA_ITEM* item : m_selectionTool->GetSelection() ) + { + PAD* pad = dynamic_cast( item ); + + if( pad && !isSelectedForDelete( pad->GetParent() ) ) + { + disallowedPads.push_back( pad ); + m_selectionTool->RemoveItemFromSel( pad, true /* quiet mode */ ); + } + } + + if( m_selectionTool->GetSelection().Empty() ) + { + wxBell(); + m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &disallowedPads ); + canvas()->Refresh(); + return 0; + } + } + + selectionCopy = m_selectionTool->RequestSelection( + []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool ) + { + }, + true /* prompt user regarding locked items */ ); } bool isHover = selectionCopy.IsHover(); @@ -1756,9 +1797,6 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( PCB_ACTIONS::selectConnection, true ); } - if( selectionCopy.Empty() ) - return 0; - // As we are about to remove items, they have to be removed from the selection first m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); @@ -1790,15 +1828,17 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) } case PCB_PAD_T: - { - PAD* pad = static_cast( item ); - FOOTPRINT* parent = static_cast( item->GetParent() ); + if( IsFootprintEditor() || frame()->Settings().m_AllowFreePads ) + { + PAD* pad = static_cast( item ); + FOOTPRINT* parent = static_cast( item->GetParent() ); + + m_commit->Modify( parent ); + getView()->Remove( pad ); + parent->Remove( pad ); + } - m_commit->Modify( parent ); - getView()->Remove( pad ); - parent->Remove( pad ); break; - } case PCB_FP_ZONE_T: { @@ -1852,27 +1892,35 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) { PCB_GROUP* group = static_cast( item ); - auto removeItem = [&]( BOARD_ITEM* bItem ) - { - if( bItem->GetParent() && bItem->GetParent()->Type() == PCB_FOOTPRINT_T ) - { - // Silently ignore delete of Reference or Value if they happen to be in - // group. - if( bItem->Type() == PCB_FP_TEXT_T ) + auto removeItem = + [&]( BOARD_ITEM* bItem ) { - if( static_cast( bItem )->GetType() != FP_TEXT::TEXT_is_DIVERS ) - return; - } + if( bItem->GetParent() && bItem->GetParent()->Type() == PCB_FOOTPRINT_T ) + { + // Silently ignore delete of Reference or Value if they happen to be + // in group. + if( bItem->Type() == PCB_FP_TEXT_T ) + { + FP_TEXT* textItem = static_cast( bItem ); - m_commit->Modify( bItem->GetParent() ); - getView()->Remove( bItem ); - bItem->GetParent()->Remove( bItem ); - } - else - { - m_commit->Remove( bItem ); - } - }; + if( textItem->GetType() != FP_TEXT::TEXT_is_DIVERS ) + return; + } + else if( bItem->Type() == PCB_PAD_T ) + { + if( !IsFootprintEditor() && !frame()->Settings().m_AllowFreePads ) + return; + } + + m_commit->Modify( bItem->GetParent() ); + getView()->Remove( bItem ); + bItem->GetParent()->Remove( bItem ); + } + else + { + m_commit->Remove( bItem ); + } + }; removeItem( group ); @@ -1900,6 +1948,9 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) else m_commit->Push( _( "Delete" ) ); + if( !disallowedPads.empty() ) + m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &disallowedPads ); + return 0; } diff --git a/pcbnew/tools/pcb_selection_tool.cpp b/pcbnew/tools/pcb_selection_tool.cpp index 53594846a0..342e2a0086 100644 --- a/pcbnew/tools/pcb_selection_tool.cpp +++ b/pcbnew/tools/pcb_selection_tool.cpp @@ -1042,8 +1042,11 @@ void PCB_SELECTION_TOOL::RemoveItemFromSel( BOARD_ITEM* aItem, bool aQuietMode ) { unselect( aItem ); - // Inform other potentially interested tools - m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent ); + if( !aQuietMode ) + { + // Inform other potentially interested tools + m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent ); + } } }