KiCad PCB EDA Suite
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 (C) 1992-2022 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 along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <footprint_filter.h>
22#include <stdexcept>
23#include <wx/tokenzr.h>
24
26
27
28FOOTPRINT_FILTER::ITERATOR::ITERATOR() : m_pos( 0 ), m_filter( nullptr )
29{
30}
31
32
34 : m_pos( aOther.m_pos ), m_filter( aOther.m_filter )
35{
36}
37
38
40 : m_pos( (size_t) -1 ), m_filter( &aFilter )
41{
42 increment();
43}
44
45
47{
48 if( !m_filter || !m_filter->m_list || m_filter->m_list->GetCount() == 0 )
49 {
50 m_pos = 0;
51 return;
52 }
53
54 int filter_type = m_filter->m_filter_type;
55 FOOTPRINT_LIST* list = m_filter->m_list;
56 wxString& lib_name = m_filter->m_lib_name;
57
58 for( ++m_pos; m_pos < list->GetCount(); ++m_pos )
59 {
60 FOOTPRINT_INFO& candidate = list->GetItem( m_pos );
61
62 if( filter_type == FOOTPRINT_FILTER::UNFILTERED_FP_LIST )
63 break;
64
66 {
67 if( !PinCountMatch( candidate ) )
68 continue;
69 }
70
72 {
73 if( !lib_name.IsEmpty() && !candidate.InLibrary( lib_name ) )
74 continue;
75 }
76
78 {
79 if( !FootprintFilterMatch( candidate ) )
80 continue;
81 }
82
84 {
85 wxString searchStr = wxString::Format( wxT( "%s:%s %s" ),
86 candidate.GetLibNickname(),
87 candidate.GetFootprintName(),
88 candidate.GetSearchText() );
89 int matches, position;
90 bool exclude = false;
91
92 for( std::unique_ptr<EDA_COMBINED_MATCHER>& matcher : m_filter->m_pattern_filters )
93 {
94 if( !matcher->Find( searchStr.Lower(), matches, position ) )
95 {
96 exclude = true;
97 break;
98 }
99 }
100
101 if( exclude )
102 continue;
103 }
104
105 // Candidate passed all filters; exit loop
106 break;
107 }
108}
109
110
112{
113 // Invalid iterators are always equal
114 return ( m_pos == aOther.m_pos ) && ( m_filter == aOther.m_filter || m_pos == (size_t) -1 );
115}
116
117
119{
120 if( m_filter && m_filter->m_list && m_pos < m_filter->m_list->GetCount() )
121 return m_filter->m_list->GetItem( m_pos );
122 else
123 throw std::out_of_range( "Attempt to dereference past FOOTPRINT_FILTER::end()" );
124}
125
126
128{
129 if( m_filter->m_footprint_filters.empty() )
130 return true;
131
132 // The matching is case insensitive
133 wxString name;
134
135 for( const std::unique_ptr<EDA_PATTERN_MATCH>& each_filter : m_filter->m_footprint_filters )
136 {
137 name.Empty();
138
139 // If the filter contains a ':' character, include the library name in the pattern
140 if( each_filter->GetPattern().Contains( wxS( ":" ) ) )
141 {
142 name = aItem.GetLibNickname().Lower() + wxS( ":" );
143 }
144
145 name += aItem.GetFootprintName().Lower();
146
147 if( each_filter->Find( name ) )
148 {
149 return true;
150 }
151 }
152
153 return false;
154}
155
156
158{
159 return m_filter->m_pin_count >= 0 &&
160 (unsigned) m_filter->m_pin_count == aItem.GetUniquePadCount();
161}
162
163
165{
166 SetList( aList );
167}
168
169
171 : m_list( nullptr ), m_pin_count( -1 ), m_filter_type( UNFILTERED_FP_LIST )
172{
173}
174
175
177{
178 m_list = &aList;
179}
180
181
183{
185}
186
187
188void FOOTPRINT_FILTER::FilterByLibrary( const wxString& aLibName )
189{
190 m_lib_name = aLibName;
192}
193
194
196{
197 m_pin_count = aPinCount;
199}
200
201
202void FOOTPRINT_FILTER::FilterByFootprintFilters( const wxArrayString& aFilters )
203{
204 m_footprint_filters.clear();
205
206 for( const wxString& each_pattern : aFilters )
207 {
208 m_footprint_filters.push_back( std::make_unique<EDA_PATTERN_MATCH_WILDCARD_EXPLICIT>() );
209 m_footprint_filters.back()->SetPattern( each_pattern.Lower() );
210 }
211
213}
214
215
216void FOOTPRINT_FILTER::FilterByTextPattern( wxString const& aPattern )
217{
218 m_filter_pattern = aPattern;
219
220 wxStringTokenizer tokenizer( aPattern.Lower() );
221
222 while( tokenizer.HasMoreTokens() )
223 {
224 const wxString term = tokenizer.GetNextToken().Lower();
225 m_pattern_filters.push_back( std::make_unique<EDA_COMBINED_MATCHER>( term, CTX_LIBITEM ) );
226 }
227
229}
230
231
233{
234 return FOOTPRINT_FILTER_IT( *this );
235}
236
237
239{
240 FOOTPRINT_FILTER_IT end_it( *this );
241 end_it.m_pos = m_list ? m_list->GetCount() : 0;
242 return end_it;
243}
const char * name
Definition: DXF_plotter.cpp:56
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
FOOTPRINT_FILTER * m_filter
bool FootprintFilterMatch(FOOTPRINT_INFO &aItem)
Check if the stored component matches an item by footprint filter.
Footprint display 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.
wxString GetSearchText() override
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 GetUniquePadCount()
Holds a list of FOOTPRINT_INFO objects, along with a list of IO_ERRORs or PARSE_ERRORs that were thro...
unsigned GetCount() const
FOOTPRINT_INFO & GetItem(unsigned aIdx) const
Get info for a footprint by index.
@ CTX_LIBITEM
FOOTPRINT_FILTER::ITERATOR FOOTPRINT_FILTER_IT
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200