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 )
{
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->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
// items (such as a via) between two pads.
// 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
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 ] ) )
aCollector.Remove( aCollector[ i ] );
}
},
true /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
std::set<wxString> netNames;
std::set<int> netCodes;

View File

@ -1578,8 +1578,7 @@ int BOARD_INSPECTION_TOOL::DiffFootprint( const TOOL_EVENT& aEvent )
if( !dynamic_cast<FOOTPRINT*>( item ) )
aCollector.Remove( item );
}
},
false /* ignore locked flag */ );
} );
if( selection.Size() == 1 )
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 } ) )
aCollector.Remove( item );
}
},
true /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
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() )
return 0;
@ -1021,8 +1022,9 @@ int EDIT_TOOL::ChangeTrackWidth( const TOOL_EVENT& aEvent )
if( !dynamic_cast<PCB_TRACK*>( item ) )
aCollector.Remove( item );
}
},
true /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
BOARD_COMMIT commit( this );
@ -1099,8 +1101,9 @@ int EDIT_TOOL::ChangeTrackLayer( const TOOL_EVENT& aEvent )
if( !dynamic_cast<PCB_TRACK*>( item ) )
aCollector.Remove( item );
}
},
true /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
PCB_LAYER_ID origLayer = frame()->GetActiveLayer();
@ -1160,8 +1163,9 @@ int EDIT_TOOL::FilletTracks( const TOOL_EVENT& aEvent )
if( !dynamic_cast<PCB_TRACK*>( item ) )
aCollector.Remove( item );
}
},
true /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Size() < 2 )
{
@ -1459,8 +1463,9 @@ int EDIT_TOOL::ModifyLines( const TOOL_EVENT& aEvent )
aCollector.Remove( item );
}
}
},
true /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
std::set<PCB_SHAPE*> lines_to_add;
std::vector<PCB_SHAPE*> items_to_remove;
@ -1709,8 +1714,9 @@ int EDIT_TOOL::SimplifyPolygons( const TOOL_EVENT& aEvent )
aCollector.Remove( item );
}
}
},
true /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
// Store last used value
static int s_toleranceValue = pcbIUScale.mmToIU( 3 );
@ -1778,8 +1784,9 @@ int EDIT_TOOL::HealShapes( const TOOL_EVENT& aEvent )
aCollector.Remove( item );
}
}
},
true /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
// Store last used value
static int s_toleranceValue = pcbIUScale.mmToIU( 3 );
@ -1856,8 +1863,9 @@ int EDIT_TOOL::BooleanPolygons( const TOOL_EVENT& aEvent )
if( !item->IsType( polygonBooleanTypes ) )
aCollector.Remove( item );
}
},
true /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
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,
// try looking for the stuff under mouse cursor (i.e. KiCad old-style hover selection)
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->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector, false );
sTool->FilterCollectorForTableCells( aCollector );
},
// Prompt user regarding locked items if in board editor and in free-pad-mode (if
// we're not in free-pad mode we delay this until the second RequestSelection()).
!m_dragging && frame()->GetPcbNewSettings()->m_AllowFreePads && !m_isFootprintEditor );
// Filter locked items if in board editor and in free-pad-mode. (If we're not in
// free-pad mode we delay this until the second RequestSelection().)
if( !m_isFootprintEditor && frame()->GetPcbNewSettings()->m_AllowFreePads )
sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Empty() )
return 0;
@ -2134,8 +2144,8 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector );
sTool->FilterCollectorForTableCells( aCollector );
},
!m_dragging /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
}
// 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->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector );
},
!m_dragging /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Empty() )
return 0;
@ -2421,8 +2431,8 @@ int EDIT_TOOL::JustifyText( const TOOL_EVENT& aEvent )
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{
sTool->FilterCollectorForHierarchy( aCollector, true );
},
!m_dragging /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Empty() )
return 0;
@ -2498,8 +2508,8 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector );
sTool->FilterCollectorForTableCells( aCollector );
},
!m_dragging /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Empty() )
return 0;
@ -2777,15 +2787,17 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{
sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForLockedItems( aCollector );
} );
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 )
{
sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector );
sTool->FilterCollectorForLockedItems( aCollector );
} );
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.
if( isAlt && ( selectionCopy.HasType( PCB_TRACE_T ) || selectionCopy.HasType( PCB_VIA_T ) ) )
{
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 );
@ -2837,8 +2837,8 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForFreePads( aCollector, false );
sTool->FilterCollectorForTableCells( aCollector );
},
true /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Empty() )
return 0;
@ -3069,8 +3069,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
// record the new items as added
if( !selection.Empty() )
{
editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
(int) new_items.size() ) );
editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ), (int) new_items.size() ) );
// If items were duplicated, pick them up
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 )
{
const auto incrementableFilter =
PCB_SELECTION& selection = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{
for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
@ -3104,10 +3103,9 @@ int EDIT_TOOL::Increment( const TOOL_EVENT& aEvent )
break;
}
}
};
PCB_SELECTION& selection = m_selectionTool->RequestSelection( incrementableFilter,
true /* prompt user regarding locked items */ );
sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Empty() )
return 0;
@ -3371,14 +3369,14 @@ int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent )
Activate();
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->FilterCollectorForMarkers( aCollector );
},
// Prompt user regarding locked items.
aEvent.IsAction( &ACTIONS::cut ) && !m_isFootprintEditor );
if( aEvent.IsAction( &ACTIONS::cut ) )
sTool->FilterCollectorForLockedItems( aCollector );
} );
if( !selection.Empty() )
{
@ -3395,9 +3393,7 @@ int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent )
if( aEvent.IsAction( &PCB_ACTIONS::copyWithReference ) )
{
if( !pickReferencePoint( _( "Select reference point for the copy..." ),
_( "Selection copied" ),
_( "Copy canceled" ),
refPoint ) )
_( "Selection copied" ), _( "Copy canceled" ), refPoint ) )
{
frame()->PopTool( selectReferencePoint );
return 0;
@ -3430,9 +3426,7 @@ int EDIT_TOOL::copyToClipboardAsText( const TOOL_EVENT& aEvent )
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{
// Anything unsupported will just be ignored
},
// No prompt for locked items
false );
} );
if( selection.IsHover() )
m_selectionTool->ClearSelection();

View File

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

View File

@ -69,8 +69,7 @@ const SELECTION& PCB_EDIT_TABLE_TOOL::getTableCellSelection()
if( !dynamic_cast<PCB_TABLECELL*>( 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,
bool aConfirmLockedItems )
PCB_SELECTION& PCB_SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aClientFilter )
{
bool selectionEmpty = m_selection.Empty();
m_selection.SetIsHover( selectionEmpty );
@ -700,29 +699,6 @@ PCB_SELECTION& PCB_SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aCl
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;
}
@ -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
{
std::unordered_set<EDA_ITEM*> toAdd;

View File

@ -97,11 +97,8 @@ public:
* If the set is empty, performs the legacy-style hover selection.
*
* @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,
bool aConfirmLockedItems = false );
PCB_SELECTION& RequestSelection( CLIENT_SELECTION_FILTER aClientFilter );
///< Select a single item under cursor event handler.
int CursorSelection( const TOOL_EVENT& aEvent );
@ -222,6 +219,11 @@ public:
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
* 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() :
PCB_TOOL_BASE( "pcbnew.PositionRelative" ),
m_dialog( nullptr ),
@ -111,8 +98,13 @@ int POSITION_RELATIVE_TOOL::PositionRelative( const TOOL_EVENT& aEvent )
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
const auto& selection = m_selectionTool->RequestSelection(
positionRelativeClientSelectionFilter,
!m_isFootprintEditor /* prompt user regarding locked items */ );
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{
sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForMarkers( aCollector );
sTool->FilterCollectorForFreePads( aCollector, false );
sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Empty() )
return 0;
@ -164,11 +156,15 @@ int POSITION_RELATIVE_TOOL::PositionRelativeInteractively( const TOOL_EVENT& aEv
REENTRANCY_GUARD guard( &m_inInteractivePosition );
// First, acquire the selection that we will be moving after
// we have the new offset vector.
const auto& selection = m_selectionTool->RequestSelection(
positionRelativeClientSelectionFilter,
!m_isFootprintEditor /* prompt user regarding locked items */ );
// First, acquire the selection that we will be moving after we have the new offset vector.
const PCB_SELECTION& selection = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
{
sTool->FilterCollectorForHierarchy( aCollector, true );
sTool->FilterCollectorForMarkers( aCollector );
sTool->FilterCollectorForFreePads( aCollector, false );
sTool->FilterCollectorForLockedItems( aCollector );
} );
if( selection.Empty() )
return 0;