diff --git a/include/pcb_group.h b/include/pcb_group.h index bb0d363c0b..0f426f5cdb 100644 --- a/include/pcb_group.h +++ b/include/pcb_group.h @@ -95,12 +95,12 @@ public: * Search for highest level group containing item. * * @param aScope restricts the search to groups within the group scope. - * @param aFootprintEditor true if we should stop promoting at the footprint level + * @param isFootprintEditor true if we should stop promoting at the footprint level * @return group containing item, if it exists, otherwise, NULL */ - static PCB_GROUP* TopLevelGroup( BOARD_ITEM* aItem, PCB_GROUP* aScope, bool aFootprintEditor ); + static PCB_GROUP* TopLevelGroup( BOARD_ITEM* aItem, PCB_GROUP* aScope, bool isFootprintEditor ); - static bool WithinScope( BOARD_ITEM* item, PCB_GROUP* scope ); + static bool WithinScope( BOARD_ITEM* aItem, PCB_GROUP* aScope, bool isFootprintEditor ); #if defined( DEBUG ) void Show( int nestLevel, std::ostream& os ) const override diff --git a/pcbnew/pcb_group.cpp b/pcbnew/pcb_group.cpp index 98a22d442b..6c91c0d70c 100644 --- a/pcbnew/pcb_group.cpp +++ b/pcbnew/pcb_group.cpp @@ -69,45 +69,46 @@ void PCB_GROUP::RemoveAll() } -PCB_GROUP* PCB_GROUP::TopLevelGroup( BOARD_ITEM* aItem, PCB_GROUP* aScope, bool aFootprintEditor ) +PCB_GROUP* getTopLevelGroup( BOARD_ITEM* aItem, PCB_GROUP* aScope, bool isFootprintEditor ) { - PCB_GROUP* candidate = aItem->GetParentGroup(); + PCB_GROUP* group = nullptr; - // Don't get the footprint's group if we are in the footprint editor - if( !candidate && aItem->GetParent() && aItem->GetParent()->Type() == PCB_FOOTPRINT_T - && !aFootprintEditor ) - candidate = aItem->GetParent()->GetParentGroup(); - - while( candidate && candidate->GetParentGroup() && candidate->GetParentGroup() != aScope ) + if( isFootprintEditor ) { - if( candidate->GetParent()->Type() == PCB_FOOTPRINT_T && aFootprintEditor ) + group = aItem->GetParentGroup(); + } + else + { + if( aItem->GetParent() && aItem->GetParent()->Type() == PCB_FOOTPRINT_T ) + group = aItem->GetParent()->GetParentGroup(); + else + group = aItem->GetParentGroup(); + } + + while( group && group->GetParentGroup() && group->GetParentGroup() != aScope ) + { + if( group->GetParent()->Type() == PCB_FOOTPRINT_T && isFootprintEditor ) break; - candidate = candidate->GetParentGroup(); + group = group->GetParentGroup(); } + return group; +} + +PCB_GROUP* PCB_GROUP::TopLevelGroup( BOARD_ITEM* aItem, PCB_GROUP* aScope, bool isFootprintEditor ) +{ + PCB_GROUP* candidate = getTopLevelGroup( aItem, aScope, isFootprintEditor ); + return candidate == aScope ? nullptr : candidate; } -bool PCB_GROUP::WithinScope( BOARD_ITEM* item, PCB_GROUP* scope ) +bool PCB_GROUP::WithinScope( BOARD_ITEM* aItem, PCB_GROUP* aScope, bool isFootprintEditor ) { - for( PCB_GROUP* parent = item->GetParentGroup(); parent; parent = parent->GetParentGroup() ) - { - if( parent == scope ) - return true; - } + PCB_GROUP* candidate = getTopLevelGroup( aItem, aScope, isFootprintEditor ); - if( item->GetParent() && item->GetParent()->Type() == PCB_FOOTPRINT_T ) - item = item->GetParent(); - - for( PCB_GROUP* parent = item->GetParentGroup(); parent; parent = parent->GetParentGroup() ) - { - if( parent == scope ) - return true; - } - - return false; + return candidate == aScope; } diff --git a/pcbnew/tools/pcb_selection_tool.cpp b/pcbnew/tools/pcb_selection_tool.cpp index 951db64809..56f72414a8 100644 --- a/pcbnew/tools/pcb_selection_tool.cpp +++ b/pcbnew/tools/pcb_selection_tool.cpp @@ -2509,15 +2509,12 @@ void PCB_SELECTION_TOOL::FilterCollectorForGroups( GENERAL_COLLECTOR& aCollector { BOARD_ITEM* item = aCollector[j]; BOARD_ITEM* parent = item->GetParent(); + BOARD_ITEM* start = item; - // Ignore footprint groups in board editor if( !m_isFootprintEditor && parent && parent->Type() == PCB_FOOTPRINT_T ) - { - ++j; - continue; - } + start = parent; - PCB_GROUP* aTop = PCB_GROUP::TopLevelGroup( item, m_enteredGroup, m_isFootprintEditor ); + PCB_GROUP* aTop = PCB_GROUP::TopLevelGroup( start, m_enteredGroup, m_isFootprintEditor ); if( aTop ) { @@ -2528,7 +2525,8 @@ void PCB_SELECTION_TOOL::FilterCollectorForGroups( GENERAL_COLLECTOR& aCollector continue; } } - else if( m_enteredGroup && !PCB_GROUP::WithinScope( item, m_enteredGroup ) ) + else if( m_enteredGroup + && !PCB_GROUP::WithinScope( item, m_enteredGroup, m_isFootprintEditor ) ) { // If a group is entered, disallow selections of objects outside the group. aCollector.Remove( item );