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 (unsigned) m_filter->m_pin_count == aItem.GetUniquePadCount();
158 }
159 
160 
162 {
163  SetList( aList );
164 }
165 
166 
168  : m_list( nullptr ), m_pin_count( -1 ), m_filter_type( UNFILTERED_FP_LIST )
169 {
170 }
171 
172 
174 {
175  m_list = &aList;
176 }
177 
178 
180 {
182 }
183 
184 
185 void FOOTPRINT_FILTER::FilterByLibrary( wxString const& aLibName )
186 {
187  m_lib_name = aLibName;
189 }
190 
191 
193 {
194  m_pin_count = aPinCount;
196 }
197 
198 
199 void FOOTPRINT_FILTER::FilterByFootprintFilters( wxArrayString const& aFilters )
200 {
201  m_footprint_filters.clear();
202 
203  for( auto const& each_pattern : aFilters )
204  {
205  m_footprint_filters.push_back( std::make_unique<EDA_PATTERN_MATCH_WILDCARD>() );
206  m_footprint_filters.back()->SetPattern( each_pattern.Lower() );
207  }
208 
210 }
211 
212 
213 void FOOTPRINT_FILTER::FilterByPattern( wxString const& aPattern )
214 {
215  m_filter_pattern = aPattern;
216  m_filter.SetPattern( aPattern.Lower() );
218 }
219 
220 
222 {
223  return FOOTPRINT_FILTER_IT( *this );
224 }
225 
226 
228 {
229  FOOTPRINT_FILTER_IT end_it( *this );
230  end_it.m_pos = m_list->GetCount();
231  return end_it;
232 }
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().