diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index ec0bddd5b0..e5fb025f30 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -356,45 +356,48 @@ PCBNEW_SELECTION& SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aCli if( aClientFilter ) { - GENERAL_COLLECTOR collector; + enum DISPOSITION { BEFORE = 1, AFTER, BOTH }; - for( auto item : m_selection ) + std::map itemDispositions; + GENERAL_COLLECTOR collector; + + for( EDA_ITEM* item : m_selection ) + { collector.Append( item ); + itemDispositions[ item ] = BEFORE; + } aClientFilter( VECTOR2I(), collector ); - /* - * The first step is to find the items that may have been added by the client filter - * This can happen if the locked pads select the module instead - */ - std::vector new_items; - std::set_difference( collector.begin(), collector.end(), - m_selection.begin(), m_selection.end(), - std::back_inserter( new_items ) ); - - /** - * The second step is to find the items that were removed by the client filter - */ - std::vector diff; - std::set_difference( m_selection.begin(), m_selection.end(), - collector.begin(), collector.end(), - std::back_inserter( diff ) ); - - if( aFiltered ) + for( EDA_ITEM* item : collector ) { - for( auto item : diff ) - aFiltered->push_back( static_cast( item ) ); + if( itemDispositions.count( item ) ) + itemDispositions[ item ] = BOTH; + else + itemDispositions[ item ] = AFTER; } - /** - * Once we find the adjustments to m_selection that are required by the client filter, we - * apply them both - */ - for( auto item : diff ) - unhighlight( static_cast( item ), SELECTED, &m_selection ); + for( std::pair itemDisposition : itemDispositions ) + { + BOARD_ITEM* item = static_cast( itemDisposition.first ); + DISPOSITION disposition = itemDisposition.second; - for( auto item : new_items ) - highlight( static_cast( item ), SELECTED, &m_selection ); + if( disposition == BEFORE ) + { + if( aFiltered ) + aFiltered->push_back( item ); + + unhighlight( item, SELECTED, &m_selection ); + } + else if( disposition == AFTER ) + { + highlight( item, SELECTED, &m_selection ); + } + else if( disposition == BOTH ) + { + // nothing to do + } + } m_frame->GetCanvas()->ForceRefresh(); }