diff --git a/common/footprint_filter.cpp b/common/footprint_filter.cpp index bf6d063fe3..649fa3888a 100644 --- a/common/footprint_filter.cpp +++ b/common/footprint_filter.cpp @@ -20,6 +20,7 @@ #include #include +#include using FOOTPRINT_FILTER_IT = FOOTPRINT_FILTER::ITERATOR; @@ -44,62 +45,66 @@ FOOTPRINT_FILTER::ITERATOR::ITERATOR( FOOTPRINT_FILTER& aFilter ) void FOOTPRINT_FILTER_IT::increment() { - bool found = false; - if( !m_filter || !m_filter->m_list || m_filter->m_list->GetCount() == 0 ) { m_pos = 0; return; } - auto filter_type = m_filter->m_filter_type; - auto list = m_filter->m_list; - auto& lib_name = m_filter->m_lib_name; - auto& filter_pattern = m_filter->m_filter_pattern; - auto& filter = m_filter->m_filter; + int filter_type = m_filter->m_filter_type; + FOOTPRINT_LIST* list = m_filter->m_list; + wxString& lib_name = m_filter->m_lib_name; - for( ++m_pos; m_pos < list->GetCount() && !found; ++m_pos ) + for( ++m_pos; m_pos < list->GetCount(); ++m_pos ) { - found = true; - - if( ( filter_type & FOOTPRINT_FILTER::FILTERING_BY_LIBRARY ) && !lib_name.IsEmpty() - && !list->GetItem( m_pos ).InLibrary( lib_name ) ) - found = false; - - if( ( filter_type & FOOTPRINT_FILTER::FILTERING_BY_COMPONENT_KEYWORD ) - && !FootprintFilterMatch( list->GetItem( m_pos ) ) ) - found = false; - - if( ( filter_type & FOOTPRINT_FILTER::FILTERING_BY_PIN_COUNT ) - && !PinCountMatch( list->GetItem( m_pos ) ) ) - found = false; - - if( ( filter_type & FOOTPRINT_FILTER::FILTERING_BY_NAME ) && !filter_pattern.IsEmpty() ) - { - wxString currname; - - // If the search string contains a ':' character, - // include the library name in the search string - // e.g. LibName:FootprintName - if( filter_pattern.Contains( ":" ) ) - currname = list->GetItem( m_pos ).GetLibNickname().Lower() + ":"; - - currname += list->GetItem( m_pos ).GetFootprintName().Lower(); - - if( filter.Find( currname ) == EDA_PATTERN_NOT_FOUND ) - found = false; - } + FOOTPRINT_INFO& candidate = list->GetItem( m_pos ); if( filter_type == FOOTPRINT_FILTER::UNFILTERED_FP_LIST ) - { - // override - found = true; - } - } + break; - // for loop will stop one past the correct item - if( found ) - --m_pos; + if( filter_type & FOOTPRINT_FILTER::FILTERING_BY_LIBRARY ) + { + if( !lib_name.IsEmpty() && !candidate.InLibrary( lib_name ) ) + continue; + } + + if( filter_type & FOOTPRINT_FILTER::FILTERING_BY_COMPONENT_KEYWORD ) + { + if( !FootprintFilterMatch( candidate ) ) + continue; + } + + if( filter_type & FOOTPRINT_FILTER::FILTERING_BY_PIN_COUNT ) + { + if( !PinCountMatch( candidate ) ) + continue; + } + + if( ( filter_type & FOOTPRINT_FILTER::FILTERING_BY_NAME ) ) + { + wxString searchStr = wxString::Format( wxT( "%s:%s %s" ), + candidate.GetLibNickname(), + candidate.GetFootprintName(), + candidate.GetSearchText() ); + int matches, position; + bool exclude = false; + + for( auto& matcher : m_filter->m_pattern_filters ) + { + if( !matcher->Find( searchStr.Lower(), matches, position ) ) + { + exclude = true; + break; + } + } + + if( exclude ) + continue; + } + + // Candidate passed all filters; exit loop + break; + } } @@ -180,7 +185,7 @@ void FOOTPRINT_FILTER::ClearFilters() } -void FOOTPRINT_FILTER::FilterByLibrary( wxString const& aLibName ) +void FOOTPRINT_FILTER::FilterByLibrary( const wxString& aLibName ) { m_lib_name = aLibName; m_filter_type |= FILTERING_BY_LIBRARY; @@ -194,11 +199,11 @@ void FOOTPRINT_FILTER::FilterByPinCount( int aPinCount ) } -void FOOTPRINT_FILTER::FilterByFootprintFilters( wxArrayString const& aFilters ) +void FOOTPRINT_FILTER::FilterByFootprintFilters( const wxArrayString& aFilters ) { m_footprint_filters.clear(); - for( auto const& each_pattern : aFilters ) + for( const wxString& each_pattern : aFilters ) { m_footprint_filters.push_back( std::make_unique() ); m_footprint_filters.back()->SetPattern( each_pattern.Lower() ); @@ -211,7 +216,15 @@ void FOOTPRINT_FILTER::FilterByFootprintFilters( wxArrayString const& aFilters ) void FOOTPRINT_FILTER::FilterByPattern( wxString const& aPattern ) { m_filter_pattern = aPattern; - m_filter.SetPattern( aPattern.Lower() ); + + wxStringTokenizer tokenizer( aPattern.Lower() ); + + while( tokenizer.HasMoreTokens() ) + { + const wxString term = tokenizer.GetNextToken().Lower(); + m_pattern_filters.push_back( std::make_unique( term ) ); + } + m_filter_type |= FILTERING_BY_NAME; } diff --git a/include/footprint_filter.h b/include/footprint_filter.h index 5a14ca9ce1..e7da8ede6c 100644 --- a/include/footprint_filter.h +++ b/include/footprint_filter.h @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2017-2019 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -136,13 +136,13 @@ private: FOOTPRINT_LIST* m_list; - wxString m_lib_name; - wxString m_filter_pattern; - int m_pin_count; - int m_filter_type; - EDA_PATTERN_MATCH_WILDCARD m_filter; + wxString m_lib_name; + wxString m_filter_pattern; + int m_pin_count; + int m_filter_type; - std::vector> m_footprint_filters; + std::vector> m_pattern_filters; + std::vector> m_footprint_filters; }; #endif // FOOTPRINT_FILTER_H diff --git a/pcbnew/footprint_viewer_frame.cpp b/pcbnew/footprint_viewer_frame.cpp index 6df6828ee0..6aadab8638 100644 --- a/pcbnew/footprint_viewer_frame.cpp +++ b/pcbnew/footprint_viewer_frame.cpp @@ -401,7 +401,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList() for( const unique_ptr& footprint : fp_info_list->GetList() ) { - wxString search = footprint->GetFootprintName() + footprint->GetSearchText(); + wxString search = footprint->GetFootprintName() + " " + footprint->GetSearchText(); bool matched = matcher.Find( search.Lower(), matches, position ); if( !matched && term.IsNumber() )