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-2017 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 <make_unique.h>
23 #include <stdexcept>
24 
26 
27 
28 FOOTPRINT_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  bool found = false;
49 
50  if( !m_filter || !m_filter->m_list || m_filter->m_list->GetCount() == 0 )
51  {
52  m_pos = 0;
53  return;
54  }
55 
56  auto filter_type = m_filter->m_filter_type;
57  auto list = m_filter->m_list;
58  auto& lib_name = m_filter->m_lib_name;
59  auto& filter_pattern = m_filter->m_filter_pattern;
60  auto& filter = m_filter->m_filter;
61 
62  for( ++m_pos; m_pos < list->GetCount() && !found; ++m_pos )
63  {
64  found = true;
65 
66  if( ( filter_type & FOOTPRINT_FILTER::FILTERING_BY_LIBRARY ) && !lib_name.IsEmpty()
67  && !list->GetItem( m_pos ).InLibrary( lib_name ) )
68  found = false;
69 
71  && !FootprintFilterMatch( list->GetItem( m_pos ) ) )
72  found = false;
73 
74  if( ( filter_type & FOOTPRINT_FILTER::FILTERING_BY_PIN_COUNT )
75  && !PinCountMatch( list->GetItem( m_pos ) ) )
76  found = false;
77 
78  if( ( filter_type & FOOTPRINT_FILTER::FILTERING_BY_NAME ) && !filter_pattern.IsEmpty() )
79  {
80  wxString currname;
81 
82  // If the search string contains a ':' character,
83  // include the library name in the search string
84  // e.g. LibName:FootprintName
85  if( filter_pattern.Contains( ":" ) )
86  currname = list->GetItem( m_pos ).GetNickname().Lower() + ":";
87 
88  currname += list->GetItem( m_pos ).GetFootprintName().Lower();
89 
90  if( filter.Find( currname ) == EDA_PATTERN_NOT_FOUND )
91  found = false;
92  }
93 
94  if( filter_type == FOOTPRINT_FILTER::UNFILTERED_FP_LIST )
95  {
96  // override
97  found = true;
98  }
99  }
100 
101  // for loop will stop one past the correct item
102  if( found )
103  --m_pos;
104 }
105 
106 
108 {
109  // Invalid iterators are always equal
110  return ( m_pos == aOther.m_pos ) && ( m_filter == aOther.m_filter || m_pos == (size_t) -1 );
111 }
112 
113 
115 {
116  if( m_filter && m_filter->m_list && m_pos < m_filter->m_list->GetCount() )
117  return m_filter->m_list->GetItem( m_pos );
118  else
119  throw std::out_of_range( "Attempt to dereference past FOOTPRINT_FILTER::end()" );
120 }
121 
122 
124 {
125  if( m_filter->m_footprint_filters.empty() )
126  return true;
127 
128  // The matching is case insensitive
129  wxString name;
130 
131  EDA_PATTERN_MATCH_WILDCARD patternFilter;
132 
133  for( auto const& each_filter : m_filter->m_footprint_filters )
134  {
135  name.Empty();
136 
137  // If the filter contains a ':' character, include the library name in the pattern
138  if( each_filter->GetPattern().Contains( ":" ) )
139  {
140  name = aItem.GetNickname().Lower() + ":";
141  }
142 
143  name += aItem.GetFootprintName().Lower();
144 
145  if( each_filter->Find( name ) != EDA_PATTERN_NOT_FOUND )
146  {
147  return true;
148  }
149  }
150 
151  return false;
152 }
153 
154 
156 {
157  return m_filter->m_pin_count >= 0 &&
158  (unsigned) m_filter->m_pin_count == aItem.GetUniquePadCount();
159 }
160 
161 
163 {
164  SetList( aList );
165 }
166 
167 
169  : m_list( nullptr ), m_pin_count( -1 ), m_filter_type( UNFILTERED_FP_LIST )
170 {
171 }
172 
173 
175 {
176  m_list = &aList;
177 }
178 
179 
181 {
183 }
184 
185 
186 void FOOTPRINT_FILTER::FilterByLibrary( wxString const& aLibName )
187 {
188  m_lib_name = aLibName;
190 }
191 
192 
194 {
195  m_pin_count = aPinCount;
197 }
198 
199 
200 void FOOTPRINT_FILTER::FilterByFootprintFilters( wxArrayString const& aFilters )
201 {
202  m_footprint_filters.clear();
203 
204  for( auto const& each_pattern : aFilters )
205  {
206  m_footprint_filters.push_back( std::make_unique<EDA_PATTERN_MATCH_WILDCARD>() );
207  m_footprint_filters.back()->SetPattern( each_pattern.Lower() );
208  }
209 
211 }
212 
213 
214 void FOOTPRINT_FILTER::FilterByPattern( wxString const& aPattern )
215 {
216  m_filter_pattern = aPattern;
217  m_filter.SetPattern( aPattern.Lower() );
219 }
220 
221 
223 {
224  return FOOTPRINT_FILTER_IT( *this );
225 }
226 
227 
229 {
230  FOOTPRINT_FILTER_IT end_it( *this );
231  end_it.m_pos = m_list->GetCount();
232  return end_it;
233 }
void SetList(FOOTPRINT_LIST &aList)
Set the list to filter.
const wxString & GetFootprintName() const
void FilterByPattern(wxString const &aPattern)
Add a pattern to filter by name, including wildcards and optionally a colon-delimited library name...
void FilterByFootprintFilters(wxArrayString const &aFilters)
Set a list of footprint filters to filter by.
void ClearFilters()
Clear all filter criteria.
bool PinCountMatch(FOOTPRINT_INFO &aItem)
Check if the stored component matches an item by pin count.
void FilterByLibrary(wxString const &aLibName)
Add library name to filter criteria.
FOOTPRINT_FILTER::ITERATOR FOOTPRINT_FILTER_IT
virtual bool SetPattern(const wxString &aPattern) override
Set the pattern against which candidates will be matched.
ITERATOR end()
Get an iterator to the end of the filtered view.
void FilterByPinCount(int aPinCount)
Set a pin count to filter by.
unsigned GetCount() const
ITERATOR begin()
Get an iterator to the beginning of the filtered view.
std::vector< std::unique_ptr< EDA_PATTERN_MATCH > > m_footprint_filters
bool FootprintFilterMatch(FOOTPRINT_INFO &aItem)
Check if the stored component matches an item by footprint filter.
bool equal(ITERATOR const &aOther) const
Footprint display filter.
static const int EDA_PATTERN_NOT_FOUND
EDA_PATTERN_MATCH_WILDCARD m_filter
Holds a list of FOOTPRINT_INFO objects, along with a list of IO_ERRORs or PARSE_ERRORs that were thro...
Implementation of std::make_unique for pre C++14 compilation environments.
FOOTPRINT_INFO & dereference() const
FOOTPRINT_LIST * m_list
unsigned GetUniquePadCount()
const char * name
FOOTPRINT_FILTER * m_filter
const wxString & GetNickname() const
FOOTPRINT_FILTER()
Construct a filter without assigning a footprint list.
Inner iterator class returned by begin() and end().