← Back to team overview

kicad-developers team mailing list archive

[PATCH] Refactor: split footprint filter data model out of cvpcb

 

Hi,

The attached patch pulls the footprint filtering logic out of cvpcb's
GUI code. It adds a FOOTPRINT_FILTER class in common/ that provides an
iterable filtered view onto a collection of footprints. This refactor is
necessary to enable footprint selection within eeschema.

-- 
Chris
>From 76a8578dc2b4b0fae3f5243e40f262f0ddfc5ef2 Mon Sep 17 00:00:00 2001
From: Chris Pavlina <pavlina.chris@xxxxxxxxx>
Date: Sat, 11 Mar 2017 12:28:51 -0500
Subject: [PATCH] Refactor: split footprint filter data model out of cvpcb

---
 common/CMakeLists.txt              |   1 +
 common/footprint_filter.cpp        | 162 +++++++++++++++++++++++++++++++++++++
 cvpcb/class_footprints_listbox.cpp |  59 ++------------
 cvpcb/cvpcb_mainframe.cpp          |  34 ++++----
 cvpcb/listview_classes.h           |  13 +--
 include/footprint_filter.h         | 118 +++++++++++++++++++++++++++
 include/footprint_info.h           |   3 +-
 7 files changed, 310 insertions(+), 80 deletions(-)
 create mode 100644 common/footprint_filter.cpp
 create mode 100644 include/footprint_filter.h

diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index b0b3b66ff..d7f38222e 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -344,6 +344,7 @@ set( PCB_COMMON_SRCS
     class_page_info.cpp
     lset.cpp
     footprint_info.cpp
+    footprint_filter.cpp
     ../pcbnew/basepcbframe.cpp
     ../pcbnew/class_board.cpp
     ../pcbnew/class_board_connected_item.cpp
diff --git a/common/footprint_filter.cpp b/common/footprint_filter.cpp
new file mode 100644
index 000000000..9ea19d0e3
--- /dev/null
+++ b/common/footprint_filter.cpp
@@ -0,0 +1,162 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2017 Chris Pavlina <pavlina.chris@xxxxxxxxx>
+ * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <footprint_filter.h>
+#include <pcb_netlist.h>
+#include <stdexcept>
+
+using FOOTPRINT_FILTER_IT = FOOTPRINT_FILTER::ITERATOR;
+
+
+FOOTPRINT_FILTER::ITERATOR::ITERATOR():
+    m_pos( 0 ),
+    m_filter( nullptr )
+{}
+
+
+FOOTPRINT_FILTER::ITERATOR::ITERATOR( FOOTPRINT_FILTER_IT const& aOther ):
+    m_pos( aOther.m_pos ),
+    m_filter( aOther.m_filter )
+{}
+
+
+FOOTPRINT_FILTER::ITERATOR::ITERATOR( FOOTPRINT_FILTER& aFilter ):
+    m_pos( (size_t) -1 ),
+    m_filter( &aFilter )
+{
+    increment();
+}
+
+
+FOOTPRINT_FILTER::FOOTPRINT_FILTER(
+        FOOTPRINT_LIST& aList,
+        const wxString& aLibName, COMPONENT* aComponent, const wxString& aPattern,
+        int aFilterType ):
+    m_list( &aList ),
+    m_lib_name( aLibName ),
+    m_filter_pattern( aPattern ),
+    m_component( aComponent ),
+    m_filter_type( aFilterType )
+{
+    m_filter.SetPattern( aPattern.Lower() );
+}
+
+
+void FOOTPRINT_FILTER_IT::increment()
+{
+    bool found = false;
+
+    if( !m_filter || !m_filter->m_list || m_filter->m_list->GetCount() == 0 )
+    {
+        m_pos = 0;
+        return;
+    }
+
+    auto filter_type        = m_filter->m_filter_type;
+    auto list               = m_filter->m_list;
+    auto& lib_name          = m_filter->m_lib_name;
+    auto& filter_pattern    = m_filter->m_filter_pattern;
+    auto component          = m_filter->m_component;
+    auto &filter            = m_filter->m_filter;
+
+    for( ++m_pos; m_pos < list->GetCount() && !found; ++m_pos )
+    {
+        found = true;
+
+        if( ( filter_type & FOOTPRINT_FILTER::FILTERING_BY_LIBRARY ) &&
+                !lib_name.IsEmpty() &&
+                !list->GetItem( m_pos ).InLibrary( lib_name ) )
+            found = false;
+
+        if( ( filter_type & FOOTPRINT_FILTER::FILTERING_BY_COMPONENT_KEYWORD ) &&
+                component &&
+                !component->MatchesFootprintFilters(
+                    list->GetItem( m_pos ).GetNickname(),
+                    list->GetItem( m_pos ).GetFootprintName() ) )
+            found = false;
+
+        if( ( filter_type & FOOTPRINT_FILTER::FILTERING_BY_PIN_COUNT ) &&
+                component &&
+                component->GetNetCount() != list->GetItem( m_pos ).GetUniquePadCount() )
+            found = false;
+
+        if( ( filter_type & FOOTPRINT_FILTER::FILTERING_BY_NAME ) &&
+                !filter_pattern.IsEmpty() )
+        {
+            wxString currname;
+
+            // If the search string contains a ':' character,
+            // include the library name in the search string
+            // e.g. LibName:FootprintName
+            if( filter_pattern.Contains( ":" ) )
+                currname = list->GetItem( m_pos ).GetNickname().Lower() + ":";
+
+            currname += list->GetItem( m_pos ).GetFootprintName().Lower();
+
+            if( filter.Find( currname ) == EDA_PATTERN_NOT_FOUND )
+                found = false;
+        }
+
+        if( filter_type == FOOTPRINT_FILTER::UNFILTERED_FP_LIST )
+        {
+            // override
+            found = true;
+        }
+    }
+
+    // for loop will stop one past the correct item
+    if( found )
+        --m_pos;
+}
+
+
+bool FOOTPRINT_FILTER_IT::equal( FOOTPRINT_FILTER_IT const& aOther ) const
+{
+    // Invalid iterators are always equal
+    return
+        ( m_pos == aOther.m_pos ) &&
+        ( m_filter == aOther.m_filter || m_pos == -1 );
+}
+
+
+FOOTPRINT_INFO& FOOTPRINT_FILTER_IT::dereference() const
+{
+    if( m_filter && m_filter->m_list && m_pos < m_filter->m_list->GetCount() )
+        return m_filter->m_list->GetItem( m_pos );
+    else
+        throw std::out_of_range( "Attempt to dereference past FOOTPRINT_FILTER::end()" );
+}
+
+
+
+FOOTPRINT_FILTER_IT FOOTPRINT_FILTER::begin()
+{
+    return FOOTPRINT_FILTER_IT( *this );
+}
+
+
+FOOTPRINT_FILTER_IT FOOTPRINT_FILTER::end()
+{
+    FOOTPRINT_FILTER_IT end_it( *this );
+    end_it.m_pos = m_list->GetCount();
+    return end_it;
+}
+
diff --git a/cvpcb/class_footprints_listbox.cpp b/cvpcb/class_footprints_listbox.cpp
index 4d3f5b0b5..ec5faac96 100644
--- a/cvpcb/class_footprints_listbox.cpp
+++ b/cvpcb/class_footprints_listbox.cpp
@@ -29,12 +29,14 @@
 
 #include <fctsys.h>
 #include <wxstruct.h>
+#include <wx/wupdlock.h>
 
 #include <cvpcb.h>
 #include <cvpcb_mainframe.h>
 #include <listview_classes.h>
 #include <cvpcb_id.h>
 #include <eda_pattern_match.h>
+#include <footprint_filter.h>
 
 
 FOOTPRINTS_LISTBOX::FOOTPRINTS_LISTBOX( CVPCB_MAINFRAME* parent,
@@ -133,62 +135,16 @@ void FOOTPRINTS_LISTBOX::SetFootprints( FOOTPRINT_LIST& aList, const wxString& a
     wxString        msg;
     wxString        oldSelection;
 
-    EDA_PATTERN_MATCH_WILDCARD patternFilter;
-    patternFilter.SetPattern( aFootPrintFilterPattern.Lower() );    // Use case insensitive search
+    FOOTPRINT_FILTER filter( aList, aLibName, aComponent, aFootPrintFilterPattern, aFilterType );
 
     if( GetSelection() >= 0 && GetSelection() < (int)m_footprintList.GetCount() )
         oldSelection = m_footprintList[ GetSelection() ];
 
-    for( unsigned ii = 0; ii < aList.GetCount(); ii++ )
+    for( auto& i: filter )
     {
-        if( aFilterType == UNFILTERED_FP_LIST )
-        {
-            msg.Printf( wxT( "%3d %s:%s" ), int( newList.GetCount() + 1 ),
-                        GetChars( aList.GetItem( ii ).GetNickname() ),
-                        GetChars( aList.GetItem( ii ).GetFootprintName() ) );
-            newList.Add( msg );
-            continue;
-        }
-
-        // Filter footprints by selected library
-        if( (aFilterType & FILTERING_BY_LIBRARY) && !aLibName.IsEmpty()
-            && !aList.GetItem( ii ).InLibrary( aLibName ) )
-            continue;
-
-        // Filter footprints by symbol fp-filters
-        if( (aFilterType & FILTERING_BY_COMPONENT_KEYWORD) && aComponent
-            && !aComponent->MatchesFootprintFilters( aList.GetItem( ii ).GetNickname(), aList.GetItem( ii ).GetFootprintName() ) )
-            continue;
-
-        // Filter footprints by symbol pin-count
-        if( (aFilterType & FILTERING_BY_PIN_COUNT) && aComponent
-            && aComponent->GetNetCount() != aList.GetItem( ii ).GetUniquePadCount() )
-            continue;
-
-        // Filter footprints by text-input
-        if( (aFilterType & FILTERING_BY_NAME ) && !aFootPrintFilterPattern.IsEmpty() )
-        {
-            wxString currname = "";
-
-            // If the search string contains a ':' character,
-            // include the library name in the search string
-            // e.g. LibName:FootprintName
-            if( aFootPrintFilterPattern.Contains( ":" ) )
-            {
-                currname = aList.GetItem( ii ).GetNickname().Lower() + ":";
-            }
-
-            currname += aList.GetItem( ii ).GetFootprintName().Lower();
-
-            if( patternFilter.Find( currname ) == EDA_PATTERN_NOT_FOUND )
-            {
-                continue;
-            }
-        }
-
-        msg.Printf( wxT( "%3d %s:%s" ), int( newList.GetCount() + 1 ),
-                    GetChars( aList.GetItem( ii ).GetNickname() ),
-                    GetChars( aList.GetItem( ii ).GetFootprintName() ) );
+        msg.Printf( "%3d %s:%s", int( newList.GetCount() + 1 ),
+                    GetChars( i.GetNickname() ),
+                    GetChars( i.GetFootprintName() ) );
         newList.Add( msg );
     }
 
@@ -202,6 +158,7 @@ void FOOTPRINTS_LISTBOX::SetFootprints( FOOTPRINT_LIST& aList, const wxString& a
     if( selection == wxNOT_FOUND )
         selection = 0;
 
+    wxWindowUpdateLocker freeze( this );
     DeleteAllItems();
 
     if( m_footprintList.GetCount() )
diff --git a/cvpcb/cvpcb_mainframe.cpp b/cvpcb/cvpcb_mainframe.cpp
index af25c93c2..3defcf53c 100644
--- a/cvpcb/cvpcb_mainframe.cpp
+++ b/cvpcb/cvpcb_mainframe.cpp
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
  * Copyright (C) 2011-2016 Wayne Stambaugh <stambaughw@xxxxxxxxxxx>
- * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -216,7 +216,7 @@ void CVPCB_MAINFRAME::LoadSettings( wxConfigBase* aCfg )
     aCfg->Read( KeepCvpcbOpenEntry, &m_keepCvpcbOpen, true );
     aCfg->Read( FootprintDocFileEntry, &m_DocModulesFileName,
                 DEFAULT_FOOTPRINTS_LIST_FILENAME );
-    aCfg->Read( FilterFootprintEntry, &m_filteringOptions, FOOTPRINTS_LISTBOX::UNFILTERED_FP_LIST );
+    aCfg->Read( FilterFootprintEntry, &m_filteringOptions, FOOTPRINT_FILTER::UNFILTERED_FP_LIST );
 }
 
 
@@ -551,20 +551,20 @@ void CVPCB_MAINFRAME::OnSelectFilteringFootprint( wxCommandEvent& event )
     switch( event.GetId() )
     {
     case ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST:
-        option = FOOTPRINTS_LISTBOX::FILTERING_BY_COMPONENT_KEYWORD;
+        option = FOOTPRINT_FILTER::FILTERING_BY_COMPONENT_KEYWORD;
         break;
 
     case ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST:
-        option = FOOTPRINTS_LISTBOX::FILTERING_BY_PIN_COUNT;
+        option = FOOTPRINT_FILTER::FILTERING_BY_PIN_COUNT;
         break;
 
     case ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST:
-        option = FOOTPRINTS_LISTBOX::FILTERING_BY_LIBRARY;
+        option = FOOTPRINT_FILTER::FILTERING_BY_LIBRARY;
         break;
 
     case ID_CVPCB_FOOTPRINT_DISPLAY_BY_NAME:
         m_currentSearchPattern = m_tcFilterString->GetValue();
-        option = FOOTPRINTS_LISTBOX::FILTERING_BY_NAME;
+        option = FOOTPRINT_FILTER::FILTERING_BY_NAME;
         break;
     }
 
@@ -586,37 +586,37 @@ void CVPCB_MAINFRAME::OnUpdateKeepOpenOnSave( wxUpdateUIEvent& event )
 
 void CVPCB_MAINFRAME::OnFilterFPbyKeywords( wxUpdateUIEvent& event )
 {
-    event.Check( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_COMPONENT_KEYWORD );
+    event.Check( m_filteringOptions & FOOTPRINT_FILTER::FILTERING_BY_COMPONENT_KEYWORD );
 }
 
 
 void CVPCB_MAINFRAME::OnFilterFPbyPinCount( wxUpdateUIEvent& event )
 {
-    event.Check( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_PIN_COUNT );
+    event.Check( m_filteringOptions & FOOTPRINT_FILTER::FILTERING_BY_PIN_COUNT );
 }
 
 
 void CVPCB_MAINFRAME::OnFilterFPbyLibrary( wxUpdateUIEvent& event )
 {
-    event.Check( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_LIBRARY );
+    event.Check( m_filteringOptions & FOOTPRINT_FILTER::FILTERING_BY_LIBRARY );
 }
 
 
 void CVPCB_MAINFRAME::OnFilterFPbyKeyName( wxUpdateUIEvent& event )
 {
-    event.Check( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_NAME );
+    event.Check( m_filteringOptions & FOOTPRINT_FILTER::FILTERING_BY_NAME );
 }
 
 
 void CVPCB_MAINFRAME::OnEnterFilteringText( wxCommandEvent& aEvent )
 {
     // Called when changing the filter string in main toolbar.
-    // If the option FOOTPRINTS_LISTBOX::FILTERING_BY_NAME is set, update the list of
+    // If the option FOOTPRINT_FILTER::FILTERING_BY_NAME is set, update the list of
     // available footprints which match the filter
 
     m_currentSearchPattern = m_tcFilterString->GetValue();
 
-    if( ( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_NAME ) == 0 )
+    if( ( m_filteringOptions & FOOTPRINT_FILTER::FILTERING_BY_NAME ) == 0 )
         return;
 
     OnSelectFilteringFootprint( aEvent );
@@ -674,10 +674,10 @@ void CVPCB_MAINFRAME::DisplayStatus()
 
     if( m_footprintListBox )
     {
-        if( ( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_COMPONENT_KEYWORD ) )
+        if( ( m_filteringOptions & FOOTPRINT_FILTER::FILTERING_BY_COMPONENT_KEYWORD ) )
             filters = _( "key words" );
 
-        if( ( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_PIN_COUNT ) )
+        if( ( m_filteringOptions & FOOTPRINT_FILTER::FILTERING_BY_PIN_COUNT ) )
         {
             if( !filters.IsEmpty() )
                 filters += wxT( "+" );
@@ -685,7 +685,7 @@ void CVPCB_MAINFRAME::DisplayStatus()
             filters += _( "pin count" );
         }
 
-        if( ( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_LIBRARY ) )
+        if( ( m_filteringOptions & FOOTPRINT_FILTER::FILTERING_BY_LIBRARY ) )
         {
             if( !filters.IsEmpty() )
                 filters += wxT( "+" );
@@ -693,7 +693,7 @@ void CVPCB_MAINFRAME::DisplayStatus()
             filters += _( "library" );
         }
 
-        if( ( m_filteringOptions & FOOTPRINTS_LISTBOX::FILTERING_BY_NAME ) )
+        if( ( m_filteringOptions & FOOTPRINT_FILTER::FILTERING_BY_NAME ) )
         {
             if( !filters.IsEmpty() )
                 filters += wxT( "+" );
@@ -863,7 +863,7 @@ void CVPCB_MAINFRAME::BuildFOOTPRINTS_LISTBOX()
     }
 
     m_footprintListBox->SetFootprints( m_FootprintsList, wxEmptyString, NULL,
-                    wxEmptyString, FOOTPRINTS_LISTBOX::UNFILTERED_FP_LIST );
+                    wxEmptyString, FOOTPRINT_FILTER::UNFILTERED_FP_LIST );
     DisplayStatus();
 }
 
diff --git a/cvpcb/listview_classes.h b/cvpcb/listview_classes.h
index 0cb429037..0abe7a6eb 100644
--- a/cvpcb/listview_classes.h
+++ b/cvpcb/listview_classes.h
@@ -1,7 +1,7 @@
 /*
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
- * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -29,7 +29,7 @@
 #define CVSTRUCT_H
 
 #include <wx/listctrl.h>
-
+#include <footprint_filter.h>
 
 /*  Forward declarations of all top-level window classes. */
 class CVPCB_MAINFRAME;
@@ -90,15 +90,6 @@ private:
     wxArrayString  m_footprintList;
 
 public:
-    // OR'ed mask to manage footprint filtering options
-    enum FP_FILTER_T
-    {
-        UNFILTERED_FP_LIST              = 0,
-        FILTERING_BY_COMPONENT_KEYWORD  = 0x0001,
-        FILTERING_BY_PIN_COUNT          = 0x0002,
-        FILTERING_BY_LIBRARY            = 0x0004,
-        FILTERING_BY_NAME               = 0x0008
-    };
 
     FOOTPRINTS_LISTBOX( CVPCB_MAINFRAME* parent, wxWindowID id,
                         const wxPoint& loc, const wxSize& size );
diff --git a/include/footprint_filter.h b/include/footprint_filter.h
new file mode 100644
index 000000000..09f50b946
--- /dev/null
+++ b/include/footprint_filter.h
@@ -0,0 +1,118 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2017 Chris Pavlina <pavlina.chris@xxxxxxxxx>
+ * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FOOTPRINT_FILTER_H
+#define FOOTPRINT_FILTER_H
+
+#include <boost/iterator/iterator_facade.hpp>
+#include <footprint_info.h>
+#include <eda_pattern_match.h>
+
+class COMPONENT;
+
+/**
+ * Footprint display filter. Takes a list of footprints and filtering settings,
+ * and provides an iterable view of the filtered data.
+ */
+class FOOTPRINT_FILTER
+{
+public:
+
+    /**
+     * Filter setting constants. The filter type is a bitwise OR of these flags,
+     * and only footprints matching all selected filter types are shown.
+     */
+    enum FP_FILTER_T: int
+    {
+        UNFILTERED_FP_LIST              = 0,
+        FILTERING_BY_COMPONENT_KEYWORD  = 0x0001,
+        FILTERING_BY_PIN_COUNT          = 0x0002,
+        FILTERING_BY_LIBRARY            = 0x0004,
+        FILTERING_BY_NAME               = 0x0008
+    };
+
+    /**
+     * Construct a filter.
+     *
+     * @param aList         - unfiltered list of footprints
+     * @param aLibName      - library name to filter on, don't care if not
+     *                        FILTERING_BY_LIBRARY
+     * @param aComponent    - component to compare to, don't care if neither
+     *                        FILTERING_BY_COMPONENT_KEYWORD nor
+     *                        FILTERING_BY_PIN_COUNT
+     * @param aPattern      - pattern, including wildcards and optionally a
+     *                        colon-delimited library name; don't care if not
+     *                        FILTERING_BY_NAME
+     * @param aFilterType   - bitwise OR of flags from FP_FILTER_T
+     */
+    FOOTPRINT_FILTER(
+            FOOTPRINT_LIST& aList,
+            const wxString& aLibName, COMPONENT* aComponent, const wxString& aPattern,
+            int aFilterType );
+
+    /**
+     * Inner iterator class returned by begin() and end().
+     */
+    class ITERATOR:
+        public boost::iterator_facade<
+            ITERATOR,
+            FOOTPRINT_INFO,
+            boost::forward_traversal_tag>
+    {
+    public:
+        ITERATOR();
+        ITERATOR( ITERATOR const& aOther );
+        ITERATOR( FOOTPRINT_FILTER& aFilter );
+
+    private:
+        friend class boost::iterator_core_access;
+        friend class FOOTPRINT_FILTER;
+
+        void increment();
+        bool equal( ITERATOR const& aOther ) const;
+        FOOTPRINT_INFO& dereference() const;
+
+        size_t m_pos;
+        FOOTPRINT_FILTER* m_filter;
+    };
+
+    /**
+     * Get an iterator to the beginning of the filtered view.
+     */
+    ITERATOR begin();
+
+    /**
+     * Get an iterator to the end of the filtered view. The end iterator is
+     * invalid and may not be dereferenced, only compared against.
+     */
+    ITERATOR end();
+
+private:
+
+    FOOTPRINT_LIST* m_list;
+
+    wxString m_lib_name;
+    wxString m_filter_pattern;
+    COMPONENT* m_component;
+    int m_filter_type;
+    EDA_PATTERN_MATCH_WILDCARD m_filter;
+};
+
+#endif // FOOTPRINT_FILTER_H
diff --git a/include/footprint_info.h b/include/footprint_info.h
index 2559752f0..7feb75ebc 100644
--- a/include/footprint_info.h
+++ b/include/footprint_info.h
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2011 Jean-Pierre Charras, <jp.charras@xxxxxxxxxx>
- * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -33,6 +33,7 @@
 #include <boost/ptr_container/ptr_vector.hpp>
 
 #include <ki_mutex.h>
+#include <ki_exception.h>
 #include <kicad_string.h>
 
 
-- 
2.12.0


Follow ups