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 ).GetLibNickname().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  for( auto const& each_filter : m_filter->m_footprint_filters )
132  {
133  name.Empty();
134 
135  // If the filter contains a ':' character, include the library name in the pattern
136  if( each_filter->GetPattern().Contains( ":" ) )
137  {
138  name = aItem.GetLibNickname().Lower() + ":";
139  }
140 
141  name += aItem.GetFootprintName().Lower();
142 
143  if( each_filter->Find( name ) != EDA_PATTERN_NOT_FOUND )
144  {
145  return true;
146  }
147  }
148 
149  return false;
150 }
151 
152 
154 {
155  return m_filter->m_pin_count >= 0 &&
156  (unsigned) m_filter->m_pin_count == aItem.GetUniquePadCount();
157 }
158 
159 
161 {
162  SetList( aList );
163 }
164 
165 
167  : m_list( nullptr ), m_pin_count( -1 ), m_filter_type( UNFILTERED_FP_LIST )
168 {
169 }
170 
171 
173 {
174  m_list = &aList;
175 }
176 
177 
179 {
181 }
182 
183 
184 void FOOTPRINT_FILTER::FilterByLibrary( wxString const& aLibName )
185 {
186  m_lib_name = aLibName;
188 }
189 
190 
192 {
193  m_pin_count = aPinCount;
195 }
196 
197 
198 void FOOTPRINT_FILTER::FilterByFootprintFilters( wxArrayString const& aFilters )
199 {
200  m_footprint_filters.clear();
201 
202  for( auto const& each_pattern : aFilters )
203  {
204  m_footprint_filters.push_back( std::make_unique<EDA_PATTERN_MATCH_WILDCARD_EXPLICIT>() );
205  m_footprint_filters.back()->SetPattern( each_pattern.Lower() );
206  }
207 
209 }
210 
211 
212 void FOOTPRINT_FILTER::FilterByPattern( wxString const& aPattern )
213 {
214  m_filter_pattern = aPattern;
215  m_filter.SetPattern( aPattern.Lower() );
217 }
218 
219 
221 {
222  return FOOTPRINT_FILTER_IT( *this );
223 }
224 
225 
227 {
228  FOOTPRINT_FILTER_IT end_it( *this );
229  end_it.m_pos = m_list ? m_list->GetCount() : 0;
230  return end_it;
231 }
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...
wxString GetLibNickname() const override
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
FOOTPRINT_INFO & GetItem(unsigned aIdx)
Get info for a module by index.
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.
const char * name
Definition: DXF_plotter.cpp:61
FOOTPRINT_INFO & dereference() const
FOOTPRINT_LIST * m_list
unsigned GetUniquePadCount()
FOOTPRINT_FILTER * m_filter
FOOTPRINT_FILTER()
Construct a filter without assigning a footprint list.
Inner iterator class returned by begin() and end().