Don't allow selection crossing a parent/child relationship.
Fixes https://gitlab.com/kicad/code/kicad/issues/8292 Fixes https://gitlab.com/kicad/code/kicad/issues/7255
This commit is contained in:
parent
e06a3cf3b4
commit
5bf37a9b24
|
@ -296,7 +296,7 @@ int EDIT_TOOL::Drag( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
}
|
||||
|
||||
sTool->FilterCollectorForGroups( aCollector );
|
||||
sTool->FilterCollectorForHierarchy( aCollector );
|
||||
},
|
||||
!m_isFootprintEditor /* prompt user regarding locked items */ );
|
||||
|
||||
|
@ -1439,7 +1439,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
|||
for( BOARD_ITEM* item : added_items )
|
||||
aCollector.Append( item );
|
||||
|
||||
sTool->FilterCollectorForGroups( aCollector );
|
||||
sTool->FilterCollectorForHierarchy( aCollector );
|
||||
},
|
||||
!m_dragging && !m_isFootprintEditor /* prompt user regarding locked items */ );
|
||||
|
||||
|
@ -1574,7 +1574,7 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
|||
for( BOARD_ITEM* item : added_items )
|
||||
aCollector.Append( item );
|
||||
|
||||
sTool->FilterCollectorForGroups( aCollector );
|
||||
sTool->FilterCollectorForHierarchy( aCollector );
|
||||
},
|
||||
!m_dragging && !m_isFootprintEditor /* prompt user regarding locked items */ );
|
||||
|
||||
|
@ -1698,7 +1698,7 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
|
|||
for( BOARD_ITEM* item : added_items )
|
||||
aCollector.Append( item );
|
||||
|
||||
sTool->FilterCollectorForGroups( aCollector );
|
||||
sTool->FilterCollectorForHierarchy( aCollector );
|
||||
},
|
||||
!m_dragging && !m_isFootprintEditor/* prompt user regarding locked items */ );
|
||||
|
||||
|
@ -1991,7 +1991,7 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
|
|||
for( BOARD_ITEM* item : added_items )
|
||||
aCollector.Append( item );
|
||||
|
||||
sTool->FilterCollectorForGroups( aCollector );
|
||||
sTool->FilterCollectorForHierarchy( aCollector );
|
||||
},
|
||||
!m_isFootprintEditor /* prompt user regarding locked items */ );
|
||||
|
||||
|
@ -2113,7 +2113,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
|||
for( BOARD_ITEM* item : added_items )
|
||||
aCollector.Append( item );
|
||||
|
||||
sTool->FilterCollectorForGroups( aCollector );
|
||||
sTool->FilterCollectorForHierarchy( aCollector );
|
||||
} );
|
||||
|
||||
if( selection.Empty() )
|
||||
|
@ -2280,7 +2280,7 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
|
|||
for( BOARD_ITEM* item : added_items )
|
||||
aCollector.Append( item );
|
||||
|
||||
sTool->FilterCollectorForGroups( aCollector );
|
||||
sTool->FilterCollectorForHierarchy( aCollector );
|
||||
} );
|
||||
|
||||
if( selection.Empty() )
|
||||
|
|
|
@ -202,7 +202,7 @@ int GLOBAL_EDIT_TOOL::RemoveUnusedPads( const TOOL_EVENT& aEvent )
|
|||
PCB_SELECTION& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
|
||||
{
|
||||
sTool->FilterCollectorForGroups( aCollector );
|
||||
sTool->FilterCollectorForHierarchy( aCollector );
|
||||
} );
|
||||
DIALOG_UNUSED_PAD_LAYERS dlg( editFrame, selection, *m_commit );
|
||||
|
||||
|
|
|
@ -707,7 +707,7 @@ bool PCB_SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag,
|
|||
// Apply the stateful filter
|
||||
FilterCollectedItems( collector );
|
||||
|
||||
FilterCollectorForGroups( collector );
|
||||
FilterCollectorForHierarchy( collector );
|
||||
|
||||
// Apply some ugly heuristics to avoid disambiguation menus whenever possible
|
||||
if( collector.GetCount() > 1 && !m_skip_heuristics )
|
||||
|
@ -809,8 +809,8 @@ bool PCB_SELECTION_TOOL::selectMultiple()
|
|||
if( view->IsMirroredX() )
|
||||
windowSelection = !windowSelection;
|
||||
|
||||
m_frame->GetCanvas()->SetCurrentCursor(
|
||||
windowSelection ? KICURSOR::SELECT_WINDOW : KICURSOR::SELECT_LASSO );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( windowSelection ? KICURSOR::SELECT_WINDOW
|
||||
: KICURSOR::SELECT_LASSO );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsActivate() )
|
||||
{
|
||||
|
@ -872,7 +872,7 @@ bool PCB_SELECTION_TOOL::selectMultiple()
|
|||
// Apply the stateful filter
|
||||
FilterCollectedItems( collector );
|
||||
|
||||
FilterCollectorForGroups( collector );
|
||||
FilterCollectorForHierarchy( collector );
|
||||
|
||||
for( EDA_ITEM* i : collector )
|
||||
{
|
||||
|
@ -2515,11 +2515,22 @@ void PCB_SELECTION_TOOL::GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector
|
|||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::FilterCollectorForGroups( GENERAL_COLLECTOR& aCollector ) const
|
||||
void PCB_SELECTION_TOOL::FilterCollectorForHierarchy( GENERAL_COLLECTOR& aCollector ) const
|
||||
{
|
||||
std::unordered_set<BOARD_ITEM*> toAdd;
|
||||
|
||||
// If any element is a member of a group, replace those elements with the top containing group.
|
||||
// Set TEMP_SELECTED on all parents which are included in the GENERAL_COLLECTOR. This
|
||||
// algorithm is O3n, whereas checking for the parent inclusion could potentially be On^2.
|
||||
|
||||
for( int j = 0; j < aCollector.GetCount(); j++ )
|
||||
{
|
||||
if( aCollector[j]->GetParent() )
|
||||
aCollector[j]->GetParent()->ClearFlags( TEMP_SELECTED );
|
||||
}
|
||||
|
||||
for( int j = 0; j < aCollector.GetCount(); j++ )
|
||||
aCollector[j]->SetFlags( TEMP_SELECTED );
|
||||
|
||||
for( int j = 0; j < aCollector.GetCount(); )
|
||||
{
|
||||
BOARD_ITEM* item = aCollector[j];
|
||||
|
@ -2529,6 +2540,8 @@ void PCB_SELECTION_TOOL::FilterCollectorForGroups( GENERAL_COLLECTOR& aCollector
|
|||
if( !m_isFootprintEditor && parent && parent->Type() == PCB_FOOTPRINT_T )
|
||||
start = parent;
|
||||
|
||||
// If any element is a member of a group, replace those elements with the top containing
|
||||
// group.
|
||||
PCB_GROUP* aTop = PCB_GROUP::TopLevelGroup( start, m_enteredGroup, m_isFootprintEditor );
|
||||
|
||||
if( aTop )
|
||||
|
@ -2536,6 +2549,8 @@ void PCB_SELECTION_TOOL::FilterCollectorForGroups( GENERAL_COLLECTOR& aCollector
|
|||
if( aTop != item )
|
||||
{
|
||||
toAdd.insert( aTop );
|
||||
aTop->SetFlags( TEMP_SELECTED );
|
||||
|
||||
aCollector.Remove( item );
|
||||
continue;
|
||||
}
|
||||
|
@ -2548,6 +2563,14 @@ void PCB_SELECTION_TOOL::FilterCollectorForGroups( GENERAL_COLLECTOR& aCollector
|
|||
continue;
|
||||
}
|
||||
|
||||
// Footprints are a bit easier as they can't be nested.
|
||||
if( parent && parent->GetFlags() & TEMP_SELECTED )
|
||||
{
|
||||
// Remove children of selected items
|
||||
aCollector.Remove( item );
|
||||
continue;
|
||||
}
|
||||
|
||||
++j;
|
||||
}
|
||||
|
||||
|
|
|
@ -186,10 +186,14 @@ public:
|
|||
*/
|
||||
void ExitGroup( bool aSelectGroup = false );
|
||||
|
||||
void FilterCollectorForGroups( GENERAL_COLLECTOR& aCollector ) const;
|
||||
|
||||
PCB_GROUP* GetEnteredGroup() { return m_enteredGroup; }
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void FilterCollectorForHierarchy( GENERAL_COLLECTOR& aCollector ) const;
|
||||
|
||||
///< Apply the SELECTION_FILTER_OPTIONS to a collection of items
|
||||
void FilterCollectedItems( GENERAL_COLLECTOR& aCollector );
|
||||
|
||||
|
|
Loading…
Reference in New Issue