Simplify locking to just be another filter now that we don't have a dialog.

This commit is contained in:
Jeff Young 2025-08-20 14:18:06 +01:00
parent 105b9fcfe8
commit 1ceac1dafd
10 changed files with 122 additions and 128 deletions

View File

@ -476,8 +476,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignCenterY( const TOOL_EVENT& aEvent )
int ALIGN_DISTRIBUTE_TOOL::DistributeItems( const TOOL_EVENT& aEvent ) int ALIGN_DISTRIBUTE_TOOL::DistributeItems( const TOOL_EVENT& aEvent )
{ {
PCB_SELECTION& selection = m_selectionTool->RequestSelection( PCB_SELECTION& selection = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
PCB_SELECTION_TOOL* sTool )
{ {
sTool->FilterCollectorForMarkers( aCollector ); sTool->FilterCollectorForMarkers( aCollector );
sTool->FilterCollectorForHierarchy( aCollector, true ); sTool->FilterCollectorForHierarchy( aCollector, true );
@ -485,9 +484,9 @@ int ALIGN_DISTRIBUTE_TOOL::DistributeItems( const TOOL_EVENT& aEvent )
// Don't filter for free pads. We want to allow for distributing other // Don't filter for free pads. We want to allow for distributing other
// items (such as a via) between two pads. // items (such as a via) between two pads.
// sTool->FilterCollectorForFreePads( aCollector ); // sTool->FilterCollectorForFreePads( aCollector );
},
m_frame->IsType( FRAME_PCB_EDITOR ) /* prompt user regarding locked items */ sTool->FilterCollectorForLockedItems( aCollector );
); } );
// Need at least 3 items to distribute - one at each end and at least on in the middle // Need at least 3 items to distribute - one at each end and at least on in the middle
if( selection.Size() < 3 ) if( selection.Size() < 3 )

View File

@ -1619,8 +1619,9 @@ int BOARD_EDITOR_CONTROL::AssignNetclass( const TOOL_EVENT& aEvent )
if( !dynamic_cast<BOARD_CONNECTED_ITEM*>( aCollector[ i ] ) ) if( !dynamic_cast<BOARD_CONNECTED_ITEM*>( aCollector[ i ] ) )
aCollector.Remove( aCollector[ i ] ); aCollector.Remove( aCollector[ i ] );
} }
},
true /* prompt user regarding locked items */ ); sTool->FilterCollectorForLockedItems( aCollector );
} );
std::set<wxString> netNames; std::set<wxString> netNames;
std::set<int> netCodes; std::set<int> netCodes;

View File

@ -1578,8 +1578,7 @@ int BOARD_INSPECTION_TOOL::DiffFootprint( const TOOL_EVENT& aEvent )
if( !dynamic_cast<FOOTPRINT*>( item ) ) if( !dynamic_cast<FOOTPRINT*>( item ) )
aCollector.Remove( item ); aCollector.Remove( item );
} }
}, } );
false /* ignore locked flag */ );
if( selection.Size() == 1 ) if( selection.Size() == 1 )
DiffFootprint( static_cast<FOOTPRINT*>( selection.GetItem( 0 ) ) ); DiffFootprint( static_cast<FOOTPRINT*>( selection.GetItem( 0 ) ) );

View File

@ -1335,8 +1335,9 @@ int CONVERT_TOOL::OutsetItems( const TOOL_EVENT& aEvent )
if( !item->IsType( { PCB_PAD_T, PCB_SHAPE_T } ) ) if( !item->IsType( { PCB_PAD_T, PCB_SHAPE_T } ) )
aCollector.Remove( item ); aCollector.Remove( item );
} }
},
true /* prompt user regarding locked items */ ); sTool->FilterCollectorForLockedItems( aCollector );
} );
BOARD_COMMIT commit( this ); BOARD_COMMIT commit( this );

View File

@ -634,8 +634,9 @@ int EDIT_TOOL::Drag( const TOOL_EVENT& aEvent )
} }
} }
} }
},
true /* prompt user regarding locked items */ ); sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Empty() ) if( selection.Empty() )
return 0; return 0;
@ -1021,8 +1022,9 @@ int EDIT_TOOL::ChangeTrackWidth( const TOOL_EVENT& aEvent )
if( !dynamic_cast<PCB_TRACK*>( item ) ) if( !dynamic_cast<PCB_TRACK*>( item ) )
aCollector.Remove( item ); aCollector.Remove( item );
} }
},
true /* prompt user regarding locked items */ ); sTool->FilterCollectorForLockedItems( aCollector );
} );
BOARD_COMMIT commit( this ); BOARD_COMMIT commit( this );
@ -1099,8 +1101,9 @@ int EDIT_TOOL::ChangeTrackLayer( const TOOL_EVENT& aEvent )
if( !dynamic_cast<PCB_TRACK*>( item ) ) if( !dynamic_cast<PCB_TRACK*>( item ) )
aCollector.Remove( item ); aCollector.Remove( item );
} }
},
true /* prompt user regarding locked items */ ); sTool->FilterCollectorForLockedItems( aCollector );
} );
PCB_LAYER_ID origLayer = frame()->GetActiveLayer(); PCB_LAYER_ID origLayer = frame()->GetActiveLayer();
@ -1160,8 +1163,9 @@ int EDIT_TOOL::FilletTracks( const TOOL_EVENT& aEvent )
if( !dynamic_cast<PCB_TRACK*>( item ) ) if( !dynamic_cast<PCB_TRACK*>( item ) )
aCollector.Remove( item ); aCollector.Remove( item );
} }
},
true /* prompt user regarding locked items */ ); sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Size() < 2 ) if( selection.Size() < 2 )
{ {
@ -1459,8 +1463,9 @@ int EDIT_TOOL::ModifyLines( const TOOL_EVENT& aEvent )
aCollector.Remove( item ); aCollector.Remove( item );
} }
} }
},
true /* prompt user regarding locked items */ ); sTool->FilterCollectorForLockedItems( aCollector );
} );
std::set<PCB_SHAPE*> lines_to_add; std::set<PCB_SHAPE*> lines_to_add;
std::vector<PCB_SHAPE*> items_to_remove; std::vector<PCB_SHAPE*> items_to_remove;
@ -1709,8 +1714,9 @@ int EDIT_TOOL::SimplifyPolygons( const TOOL_EVENT& aEvent )
aCollector.Remove( item ); aCollector.Remove( item );
} }
} }
},
true /* prompt user regarding locked items */ ); sTool->FilterCollectorForLockedItems( aCollector );
} );
// Store last used value // Store last used value
static int s_toleranceValue = pcbIUScale.mmToIU( 3 ); static int s_toleranceValue = pcbIUScale.mmToIU( 3 );
@ -1778,8 +1784,9 @@ int EDIT_TOOL::HealShapes( const TOOL_EVENT& aEvent )
aCollector.Remove( item ); aCollector.Remove( item );
} }
} }
},
true /* prompt user regarding locked items */ ); sTool->FilterCollectorForLockedItems( aCollector );
} );
// Store last used value // Store last used value
static int s_toleranceValue = pcbIUScale.mmToIU( 3 ); static int s_toleranceValue = pcbIUScale.mmToIU( 3 );
@ -1856,8 +1863,9 @@ int EDIT_TOOL::BooleanPolygons( const TOOL_EVENT& aEvent )
if( !item->IsType( polygonBooleanTypes ) ) if( !item->IsType( polygonBooleanTypes ) )
aCollector.Remove( item ); aCollector.Remove( item );
} }
},
true /* prompt user regarding locked items */ ); sTool->FilterCollectorForLockedItems( aCollector );
} );
const EDA_ITEM* const last_item = selection.GetLastAddedItem(); const EDA_ITEM* const last_item = selection.GetLastAddedItem();
@ -2102,16 +2110,18 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
// Be sure that there is at least one item that we can modify. If nothing was selected before, // Be sure that there is at least one item that we can modify. If nothing was selected before,
// try looking for the stuff under mouse cursor (i.e. KiCad old-style hover selection) // try looking for the stuff under mouse cursor (i.e. KiCad old-style hover selection)
PCB_SELECTION& selection = m_selectionTool->RequestSelection( PCB_SELECTION& selection = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool ) [&]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{ {
sTool->FilterCollectorForMarkers( aCollector ); sTool->FilterCollectorForMarkers( aCollector );
sTool->FilterCollectorForHierarchy( aCollector, true ); sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector, false ); sTool->FilterCollectorForFreePads( aCollector, false );
sTool->FilterCollectorForTableCells( aCollector ); sTool->FilterCollectorForTableCells( aCollector );
},
// Prompt user regarding locked items if in board editor and in free-pad-mode (if // Filter locked items if in board editor and in free-pad-mode. (If we're not in
// we're not in free-pad mode we delay this until the second RequestSelection()). // free-pad mode we delay this until the second RequestSelection().)
!m_dragging && frame()->GetPcbNewSettings()->m_AllowFreePads && !m_isFootprintEditor ); if( !m_isFootprintEditor && frame()->GetPcbNewSettings()->m_AllowFreePads )
sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Empty() ) if( selection.Empty() )
return 0; return 0;
@ -2134,8 +2144,8 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
sTool->FilterCollectorForHierarchy( aCollector, true ); sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector ); sTool->FilterCollectorForFreePads( aCollector );
sTool->FilterCollectorForTableCells( aCollector ); sTool->FilterCollectorForTableCells( aCollector );
}, sTool->FilterCollectorForLockedItems( aCollector );
!m_dragging /* prompt user regarding locked items */ ); } );
} }
// Did we filter everything out? If so, don't try to operate further // Did we filter everything out? If so, don't try to operate further
@ -2299,8 +2309,8 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
sTool->FilterCollectorForMarkers( aCollector ); sTool->FilterCollectorForMarkers( aCollector );
sTool->FilterCollectorForHierarchy( aCollector, true ); sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector ); sTool->FilterCollectorForFreePads( aCollector );
}, sTool->FilterCollectorForLockedItems( aCollector );
!m_dragging /* prompt user regarding locked items */ ); } );
if( selection.Empty() ) if( selection.Empty() )
return 0; return 0;
@ -2421,8 +2431,8 @@ int EDIT_TOOL::JustifyText( const TOOL_EVENT& aEvent )
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool ) []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{ {
sTool->FilterCollectorForHierarchy( aCollector, true ); sTool->FilterCollectorForHierarchy( aCollector, true );
}, sTool->FilterCollectorForLockedItems( aCollector );
!m_dragging /* prompt user regarding locked items */ ); } );
if( selection.Empty() ) if( selection.Empty() )
return 0; return 0;
@ -2498,8 +2508,8 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
sTool->FilterCollectorForHierarchy( aCollector, true ); sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector ); sTool->FilterCollectorForFreePads( aCollector );
sTool->FilterCollectorForTableCells( aCollector ); sTool->FilterCollectorForTableCells( aCollector );
}, sTool->FilterCollectorForLockedItems( aCollector );
!m_dragging /* prompt user regarding locked items */ ); } );
if( selection.Empty() ) if( selection.Empty() )
return 0; return 0;
@ -2777,15 +2787,17 @@ 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 )
{ {
sTool->FilterCollectorForHierarchy( aCollector, true ); sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForLockedItems( aCollector );
} ); } );
size_t beforeFPCount = selectionCopy.CountType( PCB_FOOTPRINT_T ); size_t beforeFPCount = selectionCopy.CountType( PCB_FOOTPRINT_T );
m_selectionTool->RequestSelection( selectionCopy = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool ) []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{ {
sTool->FilterCollectorForHierarchy( aCollector, true ); sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector ); sTool->FilterCollectorForFreePads( aCollector );
sTool->FilterCollectorForLockedItems( aCollector );
} ); } );
if( !selectionCopy.IsHover() if( !selectionCopy.IsHover()
@ -2799,19 +2811,7 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
// In "alternative" mode, we expand selected track items to their full connection. // In "alternative" mode, we expand selected track items to their full connection.
if( isAlt && ( selectionCopy.HasType( PCB_TRACE_T ) || selectionCopy.HasType( PCB_VIA_T ) ) ) if( isAlt && ( selectionCopy.HasType( PCB_TRACE_T ) || selectionCopy.HasType( PCB_VIA_T ) ) )
{
m_toolMgr->RunAction( PCB_ACTIONS::selectConnection ); m_toolMgr->RunAction( PCB_ACTIONS::selectConnection );
}
// Finally run RequestSelection() one more time to find out what user wants to do about
// locked objects.
selectionCopy = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{
sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector );
},
true /* prompt user regarding locked items */ );
} }
DeleteItems( selectionCopy, isCut ); DeleteItems( selectionCopy, isCut );
@ -2837,8 +2837,8 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
sTool->FilterCollectorForHierarchy( aCollector, true ); sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector, false ); sTool->FilterCollectorForFreePads( aCollector, false );
sTool->FilterCollectorForTableCells( aCollector ); sTool->FilterCollectorForTableCells( aCollector );
}, sTool->FilterCollectorForLockedItems( aCollector );
true /* prompt user regarding locked items */ ); } );
if( selection.Empty() ) if( selection.Empty() )
return 0; return 0;
@ -3069,8 +3069,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
// record the new items as added // record the new items as added
if( !selection.Empty() ) if( !selection.Empty() )
{ {
editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ), editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ), (int) new_items.size() ) );
(int) new_items.size() ) );
// If items were duplicated, pick them up // If items were duplicated, pick them up
if( doMoveSelection( aEvent, &commit, true ) ) if( doMoveSelection( aEvent, &commit, true ) )
@ -3089,7 +3088,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
int EDIT_TOOL::Increment( const TOOL_EVENT& aEvent ) int EDIT_TOOL::Increment( const TOOL_EVENT& aEvent )
{ {
const auto incrementableFilter = PCB_SELECTION& selection = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool ) []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{ {
for( int i = aCollector.GetCount() - 1; i >= 0; i-- ) for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
@ -3104,10 +3103,9 @@ int EDIT_TOOL::Increment( const TOOL_EVENT& aEvent )
break; break;
} }
} }
};
PCB_SELECTION& selection = m_selectionTool->RequestSelection( incrementableFilter, sTool->FilterCollectorForLockedItems( aCollector );
true /* prompt user regarding locked items */ ); } );
if( selection.Empty() ) if( selection.Empty() )
return 0; return 0;
@ -3371,14 +3369,14 @@ int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent )
Activate(); Activate();
PCB_SELECTION& selection = m_selectionTool->RequestSelection( PCB_SELECTION& selection = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool ) [&]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{ {
sTool->FilterCollectorForHierarchy( aCollector, true ); sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForMarkers( aCollector ); sTool->FilterCollectorForMarkers( aCollector );
},
// Prompt user regarding locked items. if( aEvent.IsAction( &ACTIONS::cut ) )
aEvent.IsAction( &ACTIONS::cut ) && !m_isFootprintEditor ); sTool->FilterCollectorForLockedItems( aCollector );
} );
if( !selection.Empty() ) if( !selection.Empty() )
{ {
@ -3395,9 +3393,7 @@ int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent )
if( aEvent.IsAction( &PCB_ACTIONS::copyWithReference ) ) if( aEvent.IsAction( &PCB_ACTIONS::copyWithReference ) )
{ {
if( !pickReferencePoint( _( "Select reference point for the copy..." ), if( !pickReferencePoint( _( "Select reference point for the copy..." ),
_( "Selection copied" ), _( "Selection copied" ), _( "Copy canceled" ), refPoint ) )
_( "Copy canceled" ),
refPoint ) )
{ {
frame()->PopTool( selectReferencePoint ); frame()->PopTool( selectReferencePoint );
return 0; return 0;
@ -3430,9 +3426,7 @@ int EDIT_TOOL::copyToClipboardAsText( const TOOL_EVENT& aEvent )
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool ) []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{ {
// Anything unsupported will just be ignored // Anything unsupported will just be ignored
}, } );
// No prompt for locked items
false );
if( selection.IsHover() ) if( selection.IsHover() )
m_selectionTool->ClearSelection(); m_selectionTool->ClearSelection();

View File

@ -74,8 +74,9 @@ int EDIT_TOOL::Swap( const TOOL_EVENT& aEvent )
if( item->Type() == PCB_TRACE_T ) if( item->Type() == PCB_TRACE_T )
aCollector.Remove( item ); aCollector.Remove( item );
} }
},
true /* prompt user regarding locked items */ ); sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Size() < 2 ) if( selection.Size() < 2 )
return 0; return 0;
@ -177,8 +178,9 @@ int EDIT_TOOL::PackAndMoveFootprints( const TOOL_EVENT& aEvent )
if( !dynamic_cast<FOOTPRINT*>( item ) ) if( !dynamic_cast<FOOTPRINT*>( item ) )
aCollector.Remove( item ); aCollector.Remove( item );
} }
},
true /* prompt user regarding locked items */ ); sTool->FilterCollectorForLockedItems( aCollector );
} );
std::vector<FOOTPRINT*> footprintsToPack; std::vector<FOOTPRINT*> footprintsToPack;
@ -311,8 +313,8 @@ bool EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, BOARD_COMMIT* aCommit
sTool->FilterCollectorForHierarchy( aCollector, true ); sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector ); sTool->FilterCollectorForFreePads( aCollector );
sTool->FilterCollectorForTableCells( aCollector ); sTool->FilterCollectorForTableCells( aCollector );
}, sTool->FilterCollectorForLockedItems( aCollector );
true /* prompt user regarding locked items */ ); } );
if( m_dragging || selection.Empty() ) if( m_dragging || selection.Empty() )
return false; return false;

View File

@ -69,8 +69,7 @@ const SELECTION& PCB_EDIT_TABLE_TOOL::getTableCellSelection()
if( !dynamic_cast<PCB_TABLECELL*>( aCollector[ i ] ) ) if( !dynamic_cast<PCB_TABLECELL*>( aCollector[ i ] ) )
aCollector.Remove( aCollector[ i ] ); aCollector.Remove( aCollector[ i ] );
} }
}, } );
false /* prompt user regarding locked items */ );
} }

View File

@ -634,8 +634,7 @@ PCB_SELECTION& PCB_SELECTION_TOOL::GetSelection()
} }
PCB_SELECTION& PCB_SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aClientFilter, PCB_SELECTION& PCB_SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aClientFilter )
bool aConfirmLockedItems )
{ {
bool selectionEmpty = m_selection.Empty(); bool selectionEmpty = m_selection.Empty();
m_selection.SetIsHover( selectionEmpty ); m_selection.SetIsHover( selectionEmpty );
@ -700,29 +699,6 @@ PCB_SELECTION& PCB_SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aCl
m_frame->GetCanvas()->ForceRefresh(); m_frame->GetCanvas()->ForceRefresh();
} }
if( aConfirmLockedItems && !m_frame->GetOverrideLocks() )
{
for( EDA_ITEM* item : m_selection )
{
if( !item->IsBOARD_ITEM() )
continue;
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( item );
bool lockedDescendant = false;
boardItem->RunOnChildren(
[&]( BOARD_ITEM* curr_item )
{
if( curr_item->IsLocked() )
lockedDescendant = true;
},
RECURSE_MODE::RECURSE );
if( boardItem->IsLocked() || lockedDescendant )
unselect( boardItem );
}
}
return m_selection; return m_selection;
} }
@ -3882,6 +3858,31 @@ void PCB_SELECTION_TOOL::GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector
} }
void PCB_SELECTION_TOOL::FilterCollectorForLockedItems( GENERAL_COLLECTOR& aCollector )
{
if( m_frame && m_frame->IsType( FRAME_PCB_EDITOR ) && !m_frame->GetOverrideLocks() )
{
// Iterate from the back so we don't have to worry about removals.
for( int i = (int) aCollector.GetCount() - 1; i >= 0; --i )
{
BOARD_ITEM* item = aCollector[i];
bool lockedDescendant = false;
item->RunOnChildren(
[&]( BOARD_ITEM* curr_item )
{
if( curr_item->IsLocked() )
lockedDescendant = true;
},
RECURSE_MODE::RECURSE );
if( item->IsLocked() || lockedDescendant )
aCollector.Remove( item );
}
}
}
void PCB_SELECTION_TOOL::FilterCollectorForHierarchy( GENERAL_COLLECTOR& aCollector, bool aMultiselect ) const void PCB_SELECTION_TOOL::FilterCollectorForHierarchy( GENERAL_COLLECTOR& aCollector, bool aMultiselect ) const
{ {
std::unordered_set<EDA_ITEM*> toAdd; std::unordered_set<EDA_ITEM*> toAdd;

View File

@ -97,11 +97,8 @@ public:
* If the set is empty, performs the legacy-style hover selection. * If the set is empty, performs the legacy-style hover selection.
* *
* @param aClientFilter A callback to allow tool- or action-specific filtering. * @param aClientFilter A callback to allow tool- or action-specific filtering.
* @param aConfirmLockedItems [optional] Signals that locked items should be skipped/included
* according PCB_EDIT_FRAME::GetOverrideLocks().
*/ */
PCB_SELECTION& RequestSelection( CLIENT_SELECTION_FILTER aClientFilter, PCB_SELECTION& RequestSelection( CLIENT_SELECTION_FILTER aClientFilter );
bool aConfirmLockedItems = false );
///< Select a single item under cursor event handler. ///< Select a single item under cursor event handler.
int CursorSelection( const TOOL_EVENT& aEvent ); int CursorSelection( const TOOL_EVENT& aEvent );
@ -222,6 +219,11 @@ public:
PCB_LAYER_ID GetActiveLayer() { return m_frame->GetActiveLayer(); } PCB_LAYER_ID GetActiveLayer() { return m_frame->GetActiveLayer(); }
/**
* In the PCB editor strip out any locked items unless the OverrideLocks checkbox is set.
*/
void FilterCollectorForLockedItems( GENERAL_COLLECTOR& aCollector );
/** /**
* In general we don't want to select both a parent and any of it's children. This includes * In general we don't want to select both a parent and any of it's children. This includes
* both footprints and their items, and groups and their members. * both footprints and their items, and groups and their members.

View File

@ -68,19 +68,6 @@ static void moveSelectionBy( const PCB_SELECTION& aSelection, const VECTOR2I& aM
} }
/**
* Position relative tools all use the same filter for selecting items.
*/
static void positionRelativeClientSelectionFilter( const VECTOR2I& aPt,
GENERAL_COLLECTOR& aCollector,
PCB_SELECTION_TOOL* sTool )
{
sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForMarkers( aCollector );
sTool->FilterCollectorForFreePads( aCollector, false );
}
POSITION_RELATIVE_TOOL::POSITION_RELATIVE_TOOL() : POSITION_RELATIVE_TOOL::POSITION_RELATIVE_TOOL() :
PCB_TOOL_BASE( "pcbnew.PositionRelative" ), PCB_TOOL_BASE( "pcbnew.PositionRelative" ),
m_dialog( nullptr ), m_dialog( nullptr ),
@ -111,8 +98,13 @@ int POSITION_RELATIVE_TOOL::PositionRelative( const TOOL_EVENT& aEvent )
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>(); PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
const auto& selection = m_selectionTool->RequestSelection( const auto& selection = m_selectionTool->RequestSelection(
positionRelativeClientSelectionFilter, []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
!m_isFootprintEditor /* prompt user regarding locked items */ ); {
sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForMarkers( aCollector );
sTool->FilterCollectorForFreePads( aCollector, false );
sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Empty() ) if( selection.Empty() )
return 0; return 0;
@ -164,11 +156,15 @@ int POSITION_RELATIVE_TOOL::PositionRelativeInteractively( const TOOL_EVENT& aEv
REENTRANCY_GUARD guard( &m_inInteractivePosition ); REENTRANCY_GUARD guard( &m_inInteractivePosition );
// First, acquire the selection that we will be moving after // First, acquire the selection that we will be moving after we have the new offset vector.
// we have the new offset vector. const PCB_SELECTION& selection = m_selectionTool->RequestSelection(
const auto& selection = m_selectionTool->RequestSelection( []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
positionRelativeClientSelectionFilter, {
!m_isFootprintEditor /* prompt user regarding locked items */ ); sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForMarkers( aCollector );
sTool->FilterCollectorForFreePads( aCollector, false );
sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Empty() ) if( selection.Empty() )
return 0; return 0;