KiCad PCB EDA Suite
Loading...
Searching...
No Matches
footprint_filter.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <footprint_filter.h>
22#include <stdexcept>
23#include <wx/tokenzr.h>
24
26
27
29 m_pos( 0 ),
30 m_filter( nullptr )
31{
32}
33
34
36 m_pos( aOther.m_pos ),
37 m_filter( aOther.m_filter )
38{
39}
40
41
43 m_pos( (size_t) -1 ),
44 m_filter( &aFilter )
45{
46 increment();
47}
48
49
51{
52 if( !m_filter || !m_filter->m_list || m_filter->m_list->GetCount() == 0 )
53 {
54 m_pos = 0;
55 return;
56 }
57
58 int filter_type = m_filter->m_filter_type;
59 FOOTPRINT_LIST* list = m_filter->m_list;
60 wxString& lib_name = m_filter->m_lib_name;
61
62 for( ++m_pos; m_pos < list->GetCount(); ++m_pos )
63 {
64 FOOTPRINT_INFO& candidate = list->GetItem( m_pos );
65
66 if( filter_type == FOOTPRINT_FILTER::UNFILTERED_FP_LIST )
67 break;
68
70 {
71 if( !PinCountMatch( candidate ) )
72 continue;
73 }
74
76 {
77 if( !lib_name.IsEmpty() && !candidate.InLibrary( lib_name ) )
78 continue;
79 }
80
82 {
83 if( !FootprintFilterMatch( candidate ) )
84 continue;
85 }
86
88 {
89 bool exclude = false;
90
91 for( std::unique_ptr<EDA_COMBINED_MATCHER>& matcher : m_filter->m_pattern_filters )
92 {
93 if( !matcher->ScoreTerms( candidate.GetSearchTerms() ) )
94 {
95 exclude = true;
96 break;
97 }
98 }
99
100 if( exclude )
101 continue;
102 }
103
104 // Candidate passed all filters; exit loop
105 break;
106 }
107}
108
109
111{
112 // Invalid iterators are always equal
113 return ( m_pos == aOther.m_pos ) && ( m_filter == aOther.m_filter || m_pos == (size_t) -1 );
114}
115
116
118{
119 if( m_filter && m_filter->m_list && m_pos < m_filter->m_list->GetCount() )
120 return m_filter->m_list->GetItem( m_pos );
121 else
122 throw std::out_of_range( "Attempt to dereference past FOOTPRINT_FILTER::end()" );
123}
124
125
126bool FootprintFilterMatchesName( const EDA_PATTERN_MATCH& aFilter, const wxString& aLibNickname,
127 const wxString& aFootprintName )
128{
129 wxString candidate;
130
131 // If the filter contains a ':' character, include the library nickname in the match
132 // string.
133 if( aFilter.GetPattern().Contains( wxS( ":" ) ) )
134 candidate = aLibNickname.Lower() + wxS( ":" );
135
136 candidate += aFootprintName.Lower();
137
138 return aFilter.Find( candidate ).valid();
139}
140
141
143{
144 if( m_filter->m_footprint_filters.empty() )
145 return true;
146
147 for( const std::unique_ptr<EDA_PATTERN_MATCH>& each_filter : m_filter->m_footprint_filters )
148 {
149 if( FootprintFilterMatchesName( *each_filter, aItem.GetLibNickname(), aItem.GetFootprintName() ) )
150 return true;
151 }
152
153 return false;
154}
155
156
158{
159 return m_filter->m_pin_count >= 0 && (unsigned) m_filter->m_pin_count == aItem.GetNumberedPadCount();
160}
161
162
168
169
176
177
179{
180 m_list = &aList;
181}
182
183
188
189
190void FOOTPRINT_FILTER::FilterByLibrary( const wxString& aLibName )
191{
192 m_lib_name = aLibName;
194}
195
196
198{
199 m_pin_count = aPinCount;
201}
202
203
204void FOOTPRINT_FILTER::FilterByFootprintFilters( const wxArrayString& aFilters )
205{
206 m_footprint_filters.clear();
207
208 for( const wxString& each_pattern : aFilters )
209 {
210 m_footprint_filters.push_back( std::make_unique<EDA_PATTERN_MATCH_WILDCARD_ANCHORED>() );
211 m_footprint_filters.back()->SetPattern( each_pattern.Lower() );
212 }
213
215}
216
217
218void FOOTPRINT_FILTER::FilterByTextPattern( wxString const& aPattern )
219{
220 m_filter_pattern = aPattern;
221
222 wxStringTokenizer tokenizer( aPattern.Lower(), " \t\r\n", wxTOKEN_STRTOK );
223
224 while( tokenizer.HasMoreTokens() )
225 {
226 const wxString term = tokenizer.GetNextToken().Lower();
227 m_pattern_filters.push_back( std::make_unique<EDA_COMBINED_MATCHER>( term, CTX_LIBITEM ) );
228 }
229
231}
232
233
238
239
241{
242 FOOTPRINT_FILTER_IT end_it( *this );
243 end_it.m_pos = m_list ? m_list->GetCount() : 0;
244 return end_it;
245}
Interface for a pattern matcher for which there are several implementations.
virtual wxString const & GetPattern() const =0
Return the pattern passed to SetPattern().
virtual FIND_RESULT Find(const wxString &aCandidate) const =0
Return the location and possibly length of a match if a given candidate string matches the set patter...
Inner iterator class returned by begin() and end().
bool PinCountMatch(FOOTPRINT_INFO &aItem)
Check if the stored component matches an item by pin count.
FOOTPRINT_INFO & dereference() const
bool equal(const ITERATOR &aOther) const
bool FootprintFilterMatch(FOOTPRINT_INFO &aItem)
Check if the stored component matches an item by footprint filter.
FOOTPRINT_FILTER(FOOTPRINT_LIST &aList)
Construct a filter.
FOOTPRINT_FILTER()
Construct a filter without assigning a footprint list.
FOOTPRINT_LIST * m_list
void SetList(FOOTPRINT_LIST &aList)
Set the list to filter.
void FilterByPinCount(int aPinCount)
Set a pin count to filter by.
ITERATOR begin()
Get an iterator to the beginning of the filtered view.
void FilterByTextPattern(const wxString &aPattern)
Add a pattern to filter by name, including wildcards and optionally a colon-delimited library name.
void ClearFilters()
Clear all filter criteria.
void FilterByLibrary(const wxString &aLibName)
Add library name to filter criteria.
ITERATOR end()
Get an iterator to the end of the filtered view.
std::vector< std::unique_ptr< EDA_COMBINED_MATCHER > > m_pattern_filters
std::vector< std::unique_ptr< EDA_PATTERN_MATCH > > m_footprint_filters
void FilterByFootprintFilters(const wxArrayString &aFilters)
Set a list of footprint filters to filter by.
Helper class to handle the list of footprints available in libraries.
bool InLibrary(const wxString &aLibrary) const
Test if the FOOTPRINT_INFO object was loaded from aLibrary.
wxString GetLibNickname() const override
const wxString & GetFootprintName() const
unsigned GetNumberedPadCount() const
std::vector< SEARCH_TERM > & GetSearchTerms() override
Returns the cache itself, not a copy.
A list of FOOTPRINT_INFO objects, along with a list of IO_ERROR objects or PARSE_ERRORs that were thr...
@ CTX_LIBITEM
FOOTPRINT_FILTER::ITERATOR FOOTPRINT_FILTER_IT
bool FootprintFilterMatchesName(const EDA_PATTERN_MATCH &aFilter, const wxString &aLibNickname, const wxString &aFootprintName)
Whether a given footprint matches a specified filter.