Don't allow deletion of pads when not in allow-free-pads mode.

Fixes https://gitlab.com/kicad/code/kicad/issues/8884
This commit is contained in:
Jeff Young 2021-07-29 13:59:30 +01:00
parent 6aaf4413b3
commit 9271ac1a4f
2 changed files with 86 additions and 32 deletions

View File

@ -1722,6 +1722,18 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
return 0; 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<BOARD_ITEM*> lockedItems; std::vector<BOARD_ITEM*> lockedItems;
Activate(); Activate();
@ -1729,6 +1741,7 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
PCB_SELECTION selectionCopy; PCB_SELECTION selectionCopy;
bool isCut = aEvent.Parameter<PCB_ACTIONS::REMOVE_FLAGS>() == PCB_ACTIONS::REMOVE_FLAGS::CUT; bool isCut = aEvent.Parameter<PCB_ACTIONS::REMOVE_FLAGS>() == PCB_ACTIONS::REMOVE_FLAGS::CUT;
bool isAlt = aEvent.Parameter<PCB_ACTIONS::REMOVE_FLAGS>() == PCB_ACTIONS::REMOVE_FLAGS::ALT; bool isAlt = aEvent.Parameter<PCB_ACTIONS::REMOVE_FLAGS>() == PCB_ACTIONS::REMOVE_FLAGS::ALT;
std::vector<BOARD_ITEM*> disallowedPads;
// If we are in a "Cut" operation, then the copied selection exists already and we want to // 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 // 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 ) []( 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<PAD*>( 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(); bool isHover = selectionCopy.IsHover();
@ -1756,9 +1797,6 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( PCB_ACTIONS::selectConnection, true ); 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 // As we are about to remove items, they have to be removed from the selection first
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
@ -1790,15 +1828,17 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
} }
case PCB_PAD_T: case PCB_PAD_T:
{ if( IsFootprintEditor() || frame()->Settings().m_AllowFreePads )
PAD* pad = static_cast<PAD*>( item ); {
FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() ); PAD* pad = static_cast<PAD*>( item );
FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() );
m_commit->Modify( parent );
getView()->Remove( pad );
parent->Remove( pad );
}
m_commit->Modify( parent );
getView()->Remove( pad );
parent->Remove( pad );
break; break;
}
case PCB_FP_ZONE_T: case PCB_FP_ZONE_T:
{ {
@ -1852,27 +1892,35 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
{ {
PCB_GROUP* group = static_cast<PCB_GROUP*>( item ); PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
auto removeItem = [&]( BOARD_ITEM* bItem ) 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 )
{ {
if( static_cast<FP_TEXT*>( bItem )->GetType() != FP_TEXT::TEXT_is_DIVERS ) if( bItem->GetParent() && bItem->GetParent()->Type() == PCB_FOOTPRINT_T )
return; {
} // 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<FP_TEXT*>( bItem );
m_commit->Modify( bItem->GetParent() ); if( textItem->GetType() != FP_TEXT::TEXT_is_DIVERS )
getView()->Remove( bItem ); return;
bItem->GetParent()->Remove( bItem ); }
} else if( bItem->Type() == PCB_PAD_T )
else {
{ if( !IsFootprintEditor() && !frame()->Settings().m_AllowFreePads )
m_commit->Remove( bItem ); return;
} }
};
m_commit->Modify( bItem->GetParent() );
getView()->Remove( bItem );
bItem->GetParent()->Remove( bItem );
}
else
{
m_commit->Remove( bItem );
}
};
removeItem( group ); removeItem( group );
@ -1900,6 +1948,9 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
else else
m_commit->Push( _( "Delete" ) ); m_commit->Push( _( "Delete" ) );
if( !disallowedPads.empty() )
m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &disallowedPads );
return 0; return 0;
} }

View File

@ -1042,8 +1042,11 @@ void PCB_SELECTION_TOOL::RemoveItemFromSel( BOARD_ITEM* aItem, bool aQuietMode )
{ {
unselect( aItem ); unselect( aItem );
// Inform other potentially interested tools if( !aQuietMode )
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent ); {
// Inform other potentially interested tools
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
}
} }
} }