← Back to team overview

kicad-developers team mailing list archive

Re: [PATCH] Add live footprint filtering in modview window

 

Wayne,

Based on those line numbers I think you are using an old patch set.

Try the attached patch set, I hope this time it works for you :)



On Thu, Nov 23, 2017 at 2:01 AM, Wayne Stambaugh <stambaughw@xxxxxxxxx>
wrote:

> Oliver,
>
> Here is the stack trace after typing 'r' in the search control.
>
> Thread 1 "kicad" received signal SIGSEGV, Segmentation fault.
> 0x00007fffe0e3a250 in std::vector<std::unique_ptr<FOOTPRINT_INFO,
> std::default_delete<FOOTPRINT_INFO> >,
> std::allocator<std::unique_ptr<FOOTPRINT_INFO,
> std::default_delete<FOOTPRINT_INFO> > > >::size (this=0x10)
>     at /usr/include/c++/7/bits/stl_vector.h:671
> 671           { return size_type(this->_M_impl._M_finish -
> this->_M_impl._M_start); }
> (gdb) bt 10
> #0  0x00007fffe0e3a250 in std::vector<std::unique_ptr<FOOTPRINT_INFO,
> std::default_delete<FOOTPRINT_INFO> >,
> std::allocator<std::unique_ptr<FOOTPRINT_INFO,
> std::default_delete<FOOTPRINT_INFO> > > >::size() const (this=0x10)
>     at /usr/include/c++/7/bits/stl_vector.h:671
> #1  0x00007fffe0e573c2 in FOOTPRINT_LIST::GetCount() const (this=0x0)
>     at /home/wayne/src/kicad/kicad-trunk/include/footprint_info.h:199
> #2  0x00007fffe14d4138 in FOOTPRINT_FILTER::end() (this=0x5555595049b8)
>     at /home/wayne/src/kicad/kicad-trunk/common/footprint_filter.cpp:231
> #3  0x00007fffe0bfb006 in FOOTPRINT_VIEWER_FRAME::FilterLibs() (this=
>     0x555559502400)
>     at /home/wayne/src/kicad/kicad-trunk/pcbnew/modview_frame.cpp:382
> #4  0x00007fffe0bfaed0 in
> FOOTPRINT_VIEWER_FRAME::OnFilterUpdated(wxCommandEvent&)
> (this=0x555559502400, event=...)
>     at /home/wayne/src/kicad/kicad-trunk/pcbnew/modview_frame.cpp:362
> #5  0x00007ffff65352ce in
> wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&,
> wxEvtHandler*, wxEvent&) ()
>     at /usr/lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
> #6  0x00007ffff65353d3 in wxEventHashTable::HandleEvent(wxEvent&,
> wxEvtHandler*) () at /usr/lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
> #7  0x00007ffff653579b in wxEvtHandler::TryHereOnly(wxEvent&) ()
>     at /usr/lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
> #8  0x00007fffe1479725 in EDA_BASE_FRAME::ProcessEvent(wxEvent&)
> (this=0x555559502400, aEvent=...)
>     at /home/wayne/src/kicad/kicad-trunk/common/basicframe.cpp:187
> #9  0x00007ffff6535593 in wxEvtHandler::DoTryChain(wxEvent&) ()
>     at /usr/lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
> #10 0x00007ffff6535885 in wxEvtHandler::ProcessEvent(wxEvent&) ()
>     at /usr/lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
>
>
> On 11/22/2017 07:33 AM, Oliver Walters wrote:
> > Wayne,
> >
> > That's disappointing. Any further debug info you can provide?
> >
> > On Wed, Nov 22, 2017 at 11:31 PM, Wayne Stambaugh <stambaughw@xxxxxxxxx
> > <mailto:stambaughw@xxxxxxxxx>> wrote:
> >
> >     Oliver,
> >
> >     I tested your footprint filtering patch set last night and it didn't
> go
> >     very well.  The very first letter I typed ('r') in the filter control
> >     caused kicad to crash so it's not ready just yet.
> >
> >     Cheers,
> >
> >     Wayne
> >
> >     On 11/20/2017 06:57 PM, Oliver Walters wrote:
> >     > Wayne,
> >     >
> >     > Friendly bump in case this has been forgotten - this thread has
> wandered
> >     > around a fair bit. Patches 0001 through 0008 are in the email
> above.
> >     >
> >     > Thanks
> >     >
> >     > On Fri, Nov 17, 2017 at 11:05 PM, Oliver Walters
> >     > <oliver.henry.walters@xxxxxxxxx
> >     <mailto:oliver.henry.walters@xxxxxxxxx>
> >     <mailto:oliver.henry.walters@xxxxxxxxx
> >     <mailto:oliver.henry.walters@xxxxxxxxx>>>
> >     > wrote:
> >     >
> >     >     Wayne,
> >     >
> >     >     Please ignore the previous patch sets. I have made further
> tweaks
> >     >     and the attached patch set 0001 through 0008 should be
> considered
> >     >     canonical.
> >     >     .
> >     >     I have fixed a couple of pointer errors, and have also dropped
> the
> >     >     filter-by-library functionality. It was a bit hooky and I'd
> rather
> >     >     submit a solid functional set of patches and don't have time to
> >     >     investigate further.
> >     >
> >     >     I hope that the attached patch set meets your standards and
> can be
> >     >     merged as-is :)
> >     >
> >     >     Thanks!
> >     >
> >     >     On Wed, Nov 1, 2017 at 11:21 AM, Wayne Stambaugh
> >     >     <stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
> >     <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>> wrote:
> >     >
> >     >         On 10/31/2017 5:01 PM, Oliver Walters wrote:
> >     >         > How should I proceed here then?
> >     >         >
> >     >         > I would like to see the various libraries being "cached"
> >     in the
> >     >         > background, but this is increasing the scope of the work
> >     by a large factor.
> >     >         >
> >     >         > One thing I have noticed:
> >     >         >
> >     >         > In eeschema when you launch the component viewer, it (on
> >     first run) maps
> >     >         > and caches all the footprint libraries. This can take
> >     AGES (especially
> >     >         > on Windows). However on subsequent launches of the
> >     component viewer it
> >     >         > appears instantly. It appears to be keeping a static map
> >     of the
> >     >         > footprint library data.
> >     >         >
> >     >         > a) Would this be an acceptable approach for the
> >     footprint viewer window
> >     >
> >     >         Sure.  Code reuse is a good thing.  I'm pretty sure the
> >     threaded
> >     >         footprint library code is split out from the component
> >     chooser so it
> >     >         should be reusable.
> >     >
> >     >         > b) What happens when the library data changes
> >     externally? Does component
> >     >         > viewer need to be reloaded?
> >     >
> >     >         No, only the library that changed gets reloaded the next
> >     time it's
> >     >         accessed.  It is not automatic.  I thought about using
> >     >         wxFileWatcher but
> >     >         that could be a lot of overhead for little net gain.  See
> the
> >     >         pcb plugin
> >     >         cache() functions.
> >     >
> >     >         > c) Can we globally perform this caching in a background
> >     thread when
> >     >         > KiCad launches? This will hide the large pauses (up to a
> >     minute under
> >     >         > Windows) from the user...
> >     >
> >     >         Yes, this should be done as a project element so that it
> >     can be
> >     >         accessed
> >     >         from all of the main windows.  Please keep in mind, this
> could
> >     >         be a lot
> >     >         of work and given that we are nearing a stable 5 release
> >     feature
> >     >         freeze,
> >     >         so if it's not by then it will not make it into the stable
> 5
> >     >         release.
> >     >
> >     >         >
> >     >         > Oliver
> >     >         >
> >     >         > On Tue, Oct 31, 2017 at 11:32 PM, Wayne Stambaugh
> >     <stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
> >     <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
> >     >         > <mailto:stambaughw@xxxxxxxxx <mailto:
> stambaughw@xxxxxxxxx>
> >     <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>> wrote:
> >     >         >
> >     >         >     On 10/31/2017 1:25 AM, Oliver Walters wrote:
> >     >         >     > Hmm, I had thought that there was a way to load
> only the *names* of
> >     >         >     > footprints, rather than individually parsing each
> footprint file. It
> >     >         >     > appears that this is not the case. Any suggestions
> on how the speed
> >     >         >     > could be improved? Currently I'm reading out all
> the footprint names in
> >     >         >     > each footprint library and only storing the names
> (wxString) rather than
> >     >         >     > the MODULE* objects. However, I still have to
> parse the entire library
> >     >         >     > on load.
> >     >         >     >
> >     >         >     > Ideally, I think it would be good to just read in
> the names, and then
> >     >         >     > load and display individual MODULE objects on
> demand.. Is this possible?
> >     >         >
> >     >         >     This is possible (although not implemented) for
> library types (kicad,
> >     >         >     geda) that use one file per footprint.  You could
> just read the file
> >     >         >     names from the folder and load the files as
> required.  If you want to
> >     >         >     search any other properties of the footprint, then
> you will have to load
> >     >         >     all of the footprints anyway.  I don't know if this
> would be worth the
> >     >         >     effort.
> >     >         >
> >     >         >     For library types that contain multiple footprints
> per file (legacy,
> >     >         >     Eagle), this wouldn't make much sense.  Parsing the
> entire file just to
> >     >         >     pick out the footprint names probably isn't going to
> save you very much
> >     >         >     time.
> >     >         >
> >     >         >     >
> >     >         >     > On Tue, Oct 31, 2017 at 10:40 AM, Wayne Stambaugh <
> stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
> >     <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
> >     >         <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
> >     <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>
> >     >         >     > <mailto:stambaughw@xxxxxxxxx <mailto:
> stambaughw@xxxxxxxxx>
> >     <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
> >     >         <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
> >     <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>>>
> wrote:
> >     >         >     >
> >     >         >     >     On 10/30/2017 5:23 PM, Oliver Walters wrote:
> >     >         >     >     > Thanks for the suggestions on fixing the
> text. I
> >     >         have that sorted.
> >     >         >     >     >
> >     >         >     >     > I will look into different ways of caching
> >     >         footprint data so it is quicker.
> >     >         >     >     >
> >     >         >     >     > Wayne, I didn't know about FOOTPRINT_FILTER
> >     I will
> >     >         switch to using that
> >     >         >     >     > instead (and provide regex search).
> >     >         >     >
> >     >         >     >     Thanks Oliver!
> >     >         >     >
> >     >         >     >     >
> >     >         >     >     > On 31 Oct 2017 06:55, "Seth Hillbrand"
> >     >         <seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx> <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx>>
> >     >         <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx> <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx>>>
> >     >         >     <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx>
> >     >         <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx>>
> >     >         <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx> <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx>>>>
> >     >         >     >     > <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx>
> >     >         <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx>>
> >     >         <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx> <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx>>>
> >     >         >     <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx>
> >     >         <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx>>
> >     >         >     <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx>
> >     >         <mailto:seth.hillbrand@xxxxxxxxx
> >     <mailto:seth.hillbrand@xxxxxxxxx>>>>>> wrote:
> >     >         >     >     >
> >     >         >     >     >     On Mon, Oct 30, 2017 at 11:42 AM, Wayne
> >     Stambaugh
> >     >         >     >     >     <stambaughw@xxxxxxxxx
> >     <mailto:stambaughw@xxxxxxxxx>
> >     >         <mailto:stambaughw@xxxxxxxxx
> >     <mailto:stambaughw@xxxxxxxxx>> <mailto:stambaughw@xxxxxxxxx
> >     <mailto:stambaughw@xxxxxxxxx>
> >     >         <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx
> >>>
> >     >         >     <mailto:stambaughw@xxxxxxxxx
> >     <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
> >     <mailto:stambaughw@xxxxxxxxx>>
> >     >         <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
> >     <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>>
> >     >         >     >     <mailto:stambaughw@xxxxxxxxx
> >     <mailto:stambaughw@xxxxxxxxx>
> >     >         <mailto:stambaughw@xxxxxxxxx
> >     <mailto:stambaughw@xxxxxxxxx>> <mailto:stambaughw@xxxxxxxxx
> >     <mailto:stambaughw@xxxxxxxxx>
> >     >         <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx
> >>>
> >     >         >     <mailto:stambaughw@xxxxxxxxx
> >     <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
> >     <mailto:stambaughw@xxxxxxxxx>>
> >     >         <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
> >     <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
> >>>>wrote:
> >     >         >     >     >
> >     >         >     >     >         On 10/30/2017 1:16 PM, Seth
> >     Hillbrand wrote:
> >     >         >     >     >         > Oliver, this is neat and very
> helpful.
> >     >         >     >     >         >
> >     >         >     >     >         > The greyed-out thing is a wx2.8
> bug.
> >     >         You can work
> >     >         >     >     around it by setting
> >     >         >     >     >         > the foreground color when updating
> the
> >     >         filter like
> >     >         >     this:
> >     >         >     >     >         >
> >     >         >     >     >         >  void
> >     >         FOOTPRINT_VIEWER_FRAME::OnFilterUpdated(
> >     >         >     >     wxCommandEvent& event )
> >     >         >     >     >         >  {
> >     >         >     >     >         > +    // Workaround wx2.8 bug
> showing
> >     >         greyed color
> >     >         >     >     >         > +    if( m_searchBox->GetValue() !=
> >     >         >     >     m_searchBox->GetDescriptiveText() )
> >     >         >     >     >         > +
> >     m_searchBox->SetForegroundColour(
> >     >         >     >     >         >
> >     m_searchBox->GetDefaultAttributes().colFg );
> >     >         >     >     >         > +
> >     >         >     >     >         >      // Filter is non case
> sensitive
> >     >         >     >     >         >      wxString filter =
> >     >         >     m_searchBox->GetValue().Lower();
> >     >         >     >     >         >
> >     >         >     >     >         > The searchbox handles resetting it
> to
> >     >         grey on idle()
> >     >         >     >     when the text is empty.
> >     >         >     >     >
> >     >         >     >     >         Don't you mean wx 3.0?  CMake should
> >     not even
> >     >         >     generate the
> >     >         >     >     build
> >     >         >     >     >         configuration files without wx 3.0
> >     or greater.
> >     >         >     >     >
> >     >         >     >     >
> >     >         >     >     >     Hmm... This was an issue back in 2.8 that
> >     >         appears to be only
> >     >         >     >     partly
> >     >         >     >     >     fixed.  The workaround I suggest above is
> >     >         functional
> >     >         >     but, for
> >     >         >     >     this,
> >     >         >     >     >     we can also execute a cleaner fix by
> setting
> >     >         the descriptive
> >     >         >     >     text in
> >     >         >     >     >     the declaration:
> >     >         >     >     >
> >     >         >     >     >     @@ -67,9 +67,10 @@ void
> >     >         >     FOOTPRINT_VIEWER_FRAME::ReCreateHToolbar()
> >     >         >     >     >
>  KiBitmap(
> >     >         module_xpm ),
> >     >         >     >     >                                      _(
> "Select
> >     >         footprint to
> >     >         >     >     browse" ) );
> >     >         >     >     >
> >     >         >     >     >     -        m_searchBox = new wxSearchCtrl(
> >     >         m_mainToolBar,
> >     >         >     >     >     ID_MODVIEW_SEARCH_TEXT );
> >     >         >     >     >     +        m_searchBox = new wxSearchCtrl(
> >     >         m_mainToolBar,
> >     >         >     >     >     ID_MODVIEW_SEARCH_TEXT,
> >     >         >     >     >     +                _( "Enter filter
> >     string" ) );
> >     >         >     >     >              m_searchBox->SetMinSize(
> >     wxSize( 250,
> >     >         30 ) );
> >     >         >     >     >     -        m_searchBox->SetDescriptiveText(
> _(
> >     >         "Enter filter
> >     >         >     >     string" ) );
> >     >         >     >     >
> >     >         >     >     >
> >     >         >     >     >
> >     >         >     >     >
> >      _______________________________________________
> >     >         >     >     >     Mailing list:
> >     >         https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>
> >     >         >     >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>>
> >     >         >     >     >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>
> >     >         >     >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>>>
> >     >         >     >     >     Post to     :
> >     >         kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>
> >     >         >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>>
> >     >         >     >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>
> >     >         >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>>>
> >     >         >     >     >
> >      <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>
> >     >         >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>>
> >     >         >     >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>
> >     >         >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>>>>
> >     >         >     >     >     Unsubscribe :
> >     >         https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>
> >     >         >     >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>>
> >     >         >     >     >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>
> >     >         >     >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>>>
> >     >         >     >     >     More help   :
> >     >         https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>
> >     >         >     <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>>
> >     >         >     >     <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>
> >     >         >     <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>>>
> >     >         >     >     >     <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>
> >     >         >     <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>>
> >     >         >     >     <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>
> >     >         >     <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>>>>
> >     >         >     >     >
> >     >         >     >     >
> >     >         >     >     >
> >     >         >     >     > ______________________________
> _________________
> >     >         >     >     > Mailing list:
> >     >         https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>
> >     >         >     >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>>
> >     >         >     >     > Post to     :
> >     kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>
> >     >         >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>>
> >     >         >     >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>
> >     >         >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>>>
> >     >         >     >     > Unsubscribe :
> >     >         https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>
> >     >         >     >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>>
> >     >         >     >     > More help   :
> >     https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>
> >     >         >     <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>>
> >     >         >     >     <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>
> >     >         >     <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>>>
> >     >         >     >     >
> >     >         >     >
> >     >         >     >
> >     >         >     >     _____________________________
> __________________
> >     >         >     >     Mailing list:
> >     >         https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>
> >     >         >     >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>>
> >     >         >     >     Post to     :
> >     kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>
> >     >         >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>>
> >     >         >     >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>
> >     >         >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>
> >     >         <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx
> >     <mailto:kicad-developers@xxxxxxxxxxxxxxxxxxx>>>>
> >     >         >     >     Unsubscribe :
> >     >         https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>
> >     >         >     >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>
> >     >         >     <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>
> >     >         <https://launchpad.net/~kicad-developers
> >     <https://launchpad.net/~kicad-developers>>>>
> >     >         >     >     More help   :
> >     https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>
> >     >         >     <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>>
> >     >         >     >     <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>
> >     >         >     <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>
> >     >         <https://help.launchpad.net/ListHelp
> >     <https://help.launchpad.net/ListHelp>>>>
> >     >         >     >
> >     >         >     >
> >     >         >
> >     >         >
> >     >
> >     >
> >     >
> >
> >
>
From 656f22d14fe3a28a66ea80817fc1c5e06429c200 Mon Sep 17 00:00:00 2001
From: Oliver <oliver.henry.walters@xxxxxxxxx>
Date: Thu, 23 Nov 2017 23:51:58 +1100
Subject: [PATCH 9/9] Add extra nullptr catch for FOOTPRINT_FILTER

- FOOTPRINT_FILTER can fail if it does not have an assigned list
- Add "HasList()" function to check
---
 include/footprint_filter.h |  6 ++++++
 pcbnew/modview_frame.cpp   | 14 ++++++++------
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/include/footprint_filter.h b/include/footprint_filter.h
index 7a08dfa..fc7b4d4 100644
--- a/include/footprint_filter.h
+++ b/include/footprint_filter.h
@@ -50,6 +50,12 @@ public:
      */
     void SetList( FOOTPRINT_LIST& aList );
 
+
+    /**
+     * Test if the footprint filter has an associated list
+     */
+    bool HasList() const { return m_list != nullptr; }
+
     /**
      * Clear all filter criteria.
      */
diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp
index 9095872..2cddbfa 100644
--- a/pcbnew/modview_frame.cpp
+++ b/pcbnew/modview_frame.cpp
@@ -375,13 +375,15 @@ void FOOTPRINT_VIEWER_FRAME::FilterLibs()
     m_footprintList->Freeze();
     m_footprintList->Clear();
 
-    m_footprintFilter.ClearFilters();
-
-    m_footprintFilter.FilterByPattern( filter );
-
-    for( auto& it : m_footprintFilter )
+    if( m_footprintFilter.HasList() )
     {
-        m_footprintList->Append( it.GetFootprintName() );
+        m_footprintFilter.ClearFilters();
+        m_footprintFilter.FilterByPattern( filter );
+
+        for( auto& it : m_footprintFilter )
+        {
+            m_footprintList->Append( it.GetFootprintName() );
+        }
     }
 
     m_footprintList->Thaw();
-- 
2.7.4

From b7bed8b1232c2d655954e17c9a32d34c21f32d84 Mon Sep 17 00:00:00 2001
From: Oliver <oliver.henry.walters@xxxxxxxxx>
Date: Fri, 17 Nov 2017 23:00:24 +1100
Subject: [PATCH 8/9] Filtering fixes

- Removed "regular expression" tool tip
- Added busy cursor when loading libraries
---
 pcbnew/modview_frame.cpp | 29 +++++++++++++++++++++--------
 pcbnew/modview_frame.h   |  1 -
 pcbnew/tool_modview.cpp  |  1 -
 3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp
index 3a8452e..9095872 100644
--- a/pcbnew/modview_frame.cpp
+++ b/pcbnew/modview_frame.cpp
@@ -29,6 +29,7 @@
 
 #include <wx/sizer.h>
 #include <wx/progdlg.h>
+#include <wx/utils.h>
 
 #include <fctsys.h>
 #include <pgm_base.h>
@@ -350,8 +351,6 @@ void FOOTPRINT_VIEWER_FRAME::ClearFilter()
     m_searchBox->Clear();
     m_searchBox->SetDescriptiveText( _( "Enter filter string" ) );
 
-    m_filterText.Clear();
-
     // Update filter
     FilterLibs();
 }
@@ -359,8 +358,6 @@ void FOOTPRINT_VIEWER_FRAME::ClearFilter()
 
 void FOOTPRINT_VIEWER_FRAME::OnFilterUpdated( wxCommandEvent& event )
 {
-    m_filterText = m_searchBox->GetValue().Lower();
-
     // Update the selected libraries
     FilterLibs();
 }
@@ -373,12 +370,14 @@ void FOOTPRINT_VIEWER_FRAME::FilterLibs()
         return;
     }
 
+    wxString filter = m_searchBox->GetValue().Lower();
+
     m_footprintList->Freeze();
     m_footprintList->Clear();
 
     m_footprintFilter.ClearFilters();
 
-    m_footprintFilter.FilterByPattern( m_filterText );
+    m_footprintFilter.FilterByPattern( filter );
 
     for( auto& it : m_footprintFilter )
     {
@@ -441,7 +440,10 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
     // Get list of loaded footprint libraries
     m_libraryNicknames = Prj().PcbFootprintLibs()->GetLogicalLibs();
 
-    m_fpList = FOOTPRINT_LIST::GetInstance( Kiway() );
+    if( m_fpList == nullptr )
+    {
+        m_fpList = FOOTPRINT_LIST::GetInstance( Kiway() );
+    }
 
     for( auto nickname : m_libraryNicknames )
     {
@@ -474,17 +476,28 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
 
 void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList()
 {
-    if( !getCurNickname() )
+    if( getCurNickname().IsEmpty() )
     {
         setCurFootprintName( wxEmptyString );
         return;
     }
 
+    if( !m_fpList )
+    {
+        return;
+    }
+
     const wxString nickname = getCurNickname();
 
     auto lib_table = Prj().PcbFootprintLibs();
 
-    if( !m_fpList || !m_fpList->ReadFootprintFiles( lib_table, &nickname ) )
+    wxBeginBusyCursor();
+
+    bool result = m_fpList->ReadFootprintFiles( lib_table, &nickname );
+
+    wxEndBusyCursor();
+
+    if( !result )
     {
         setCurFootprintName( wxEmptyString );
         return;
diff --git a/pcbnew/modview_frame.h b/pcbnew/modview_frame.h
index 790ae03..d7f37b9 100644
--- a/pcbnew/modview_frame.h
+++ b/pcbnew/modview_frame.h
@@ -70,7 +70,6 @@ private:
     FOOTPRINT_FILTER m_footprintFilter;                  // Filter for footprint names
     std::unique_ptr<FOOTPRINT_LIST> m_fpList = nullptr;  // List of footprints within each library
     std::vector<wxString> m_libraryNicknames;            // List of library nicknames gleaned from FP_LIB_TABLE
-    wxString m_filterText;                               // Text used for filtering footprints
 
     wxSearchCtrl*             m_searchBox;
 
diff --git a/pcbnew/tool_modview.cpp b/pcbnew/tool_modview.cpp
index cab0683..ab949af 100644
--- a/pcbnew/tool_modview.cpp
+++ b/pcbnew/tool_modview.cpp
@@ -73,7 +73,6 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateHToolbar()
         m_searchBox->SetToolTip( _( "Filter footprint list\n"
                                     "- Search is not case sensitive\n"
                                     "- Wildcard search (?*) is supported\n"
-                                    "- Regular expression search is supported\n"
                                     "- Use : separator to include library name in search" ) );
 
         m_mainToolBar->AddControl( m_searchBox );
-- 
2.7.4

From d96a3d0cba696c5a334db29c8b5d47e8a454aaeb Mon Sep 17 00:00:00 2001
From: Oliver <oliver.henry.walters@xxxxxxxxx>
Date: Thu, 16 Nov 2017 23:23:47 +1100
Subject: [PATCH 7/9] Switch to use FOOTPRINT_FILTER

- Use existing filter class
- Libraries are loaded as selected
- Filter now works only on selected library
---
 pcbnew/modview_frame.cpp | 208 ++++++++++++-----------------------------------
 pcbnew/modview_frame.h   |  18 ++--
 2 files changed, 57 insertions(+), 169 deletions(-)

diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp
index 12167da..3a8452e 100644
--- a/pcbnew/modview_frame.cpp
+++ b/pcbnew/modview_frame.cpp
@@ -111,9 +111,6 @@ BEGIN_EVENT_TABLE( FOOTPRINT_VIEWER_FRAME, EDA_DRAW_FRAME )
 
     EVT_SEARCHCTRL_CANCEL_BTN( ID_MODVIEW_SEARCH_TEXT, FOOTPRINT_VIEWER_FRAME::OnFilterCleared )
 
-    EVT_TOOL( ID_MODVIEW_FILTER_BY_LIBRARY, FOOTPRINT_VIEWER_FRAME::OnToggleFilterByLibrary )
-
-
     // listbox events
     EVT_LISTBOX( ID_MODVIEW_LIB_LIST, FOOTPRINT_VIEWER_FRAME::ClickOnLibList )
     EVT_LISTBOX( ID_MODVIEW_FOOTPRINT_LIST, FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList )
@@ -347,56 +344,22 @@ void FOOTPRINT_VIEWER_FRAME::OnFilterCleared( wxCommandEvent& event )
 
 void FOOTPRINT_VIEWER_FRAME::ClearFilter()
 {
-    m_libFilter = wxEmptyString;
-    m_fpFilter = wxEmptyString;
-
     // SetFocus must be called first to set the text color to black
     m_searchBox->SetFocus();
 
     m_searchBox->Clear();
     m_searchBox->SetDescriptiveText( _( "Enter filter string" ) );
 
+    m_filterText.Clear();
+
+    // Update filter
     FilterLibs();
 }
 
 
 void FOOTPRINT_VIEWER_FRAME::OnFilterUpdated( wxCommandEvent& event )
 {
-    // Filter is non case sensitive
-    wxString filter = m_searchBox->GetValue().Lower();
-
-    wxArrayString splitFilter = wxSplit( filter, ':' );
-
-    // Include footprint library name in filter?
-    if( splitFilter.size() == 2 )
-    {
-        m_libFilter = splitFilter[0];
-        m_fpFilter = splitFilter[1];
-    }
-    else
-    {
-        m_libFilter = wxEmptyString;
-        m_fpFilter = filter;
-    }
-
-    // Enforce leading and trailing asterisk character
-    // This is required for wxString::Matches to work
-
-    if( !m_fpFilter.IsEmpty() )
-    {
-        if( !m_fpFilter.StartsWith( "*" ) )
-            m_fpFilter.Prepend( "*" );
-        if( !m_fpFilter.EndsWith( "*" ) )
-            m_fpFilter.Append( "*" );
-    }
-
-    if( !m_libFilter.IsEmpty() )
-    {
-        if( !m_libFilter.StartsWith( "*" ) )
-            m_libFilter.Prepend( "*" );
-        if( !m_libFilter.EndsWith( "*" ) )
-            m_libFilter.Append( "*" );
-    }
+    m_filterText = m_searchBox->GetValue().Lower();
 
     // Update the selected libraries
     FilterLibs();
@@ -405,60 +368,24 @@ void FOOTPRINT_VIEWER_FRAME::OnFilterUpdated( wxCommandEvent& event )
 
 void FOOTPRINT_VIEWER_FRAME::FilterLibs()
 {
-
-    wxString fpName;
-    wxString libName;
-
-    // Update the list of libraries
-
-    m_libList->Freeze();
-    m_libList->Clear();
-
-    for( auto it = m_footprintMap.begin(); it != m_footprintMap.end(); ++it )
+    if( !m_fpList )
     {
-        libName = it->first;
-
-        // Skip this library if it does not match the specified library filter
-        if( !m_libFilter.IsEmpty() && !libName.Lower().Matches( m_libFilter ) )
-        {
-            continue;
-        }
-
-        auto& fpNames = it->second;
-
-        // Test if the library contains any footprints that match the footprint filter
+        return;
+    }
 
-        bool anyMatch = false;
+    m_footprintList->Freeze();
+    m_footprintList->Clear();
 
-        for( auto& fp: fpNames )
-        {
-            fpName = fp.Lower();
+    m_footprintFilter.ClearFilters();
 
-            if( m_fpFilter.IsEmpty() || fpName.Lower().Matches( m_fpFilter ) )
-            {
-                anyMatch = true;
-                break;
-            }
-        }
+    m_footprintFilter.FilterByPattern( m_filterText );
 
-        if( anyMatch )
-        {
-            m_libList->Append( libName );
-        }
+    for( auto& it : m_footprintFilter )
+    {
+        m_footprintList->Append( it.GetFootprintName() );
     }
 
-    m_libList->Thaw();
-
-    // Update listed footprints
-    ReCreateFootprintList();
-}
-
-
-void FOOTPRINT_VIEWER_FRAME::OnToggleFilterByLibrary( wxCommandEvent& event )
-{
-    //m_filterByLibrary = m_mainToolBar->GetToolToggled( ID_MODVIEW_FILTER_BY_LIBRARY );
-    //TODO
-    //printf( "Filter? %d\n", (int) m_filterByLibrary );
+    m_footprintList->Thaw();
 }
 
 
@@ -508,72 +435,20 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
 {
     ClearFilter();
 
-    m_footprintMap.clear();
-
+    m_libList->Freeze();
     m_libList->Clear();
 
     // Get list of loaded footprint libraries
-    std::vector< wxString > nicknames = Prj().PcbFootprintLibs()->GetLogicalLibs();
-
-    wxProgressDialog progress( _( "Loading footprint libraries" ),
-                               _( "Reading library data" ),
-                               nicknames.size(),
-                               NULL,
-                               wxPD_APP_MODAL );
+    m_libraryNicknames = Prj().PcbFootprintLibs()->GetLogicalLibs();
 
-    progress.Show();
+    m_fpList = FOOTPRINT_LIST::GetInstance( Kiway() );
 
-    auto lib_table = Prj().PcbFootprintLibs();
-    auto fp_list( FOOTPRINT_LIST::GetInstance( Kiway() ) );
-
-    //TODO - Make this process threaded using 'FOOTPRINT_ASYNC_LOADER' ?
-
-    wxString errors;
-
-    for( unsigned ii = 0; ii < nicknames.size(); ii++ )
+    for( auto nickname : m_libraryNicknames )
     {
-        wxString libName = nicknames[ii];
-        m_libList->Append( libName );
-
-        progress.Update( ii, _( "Loading " + libName ) );
-
-        fp_list->ReadFootprintFiles( lib_table, !libName ? NULL : &libName );
-
-        if( fp_list->GetErrorCount() )
-        {
-            errors += "<p><b>Library: " + libName + "</b></p>";
-
-            while( auto error = fp_list->PopError() )
-            {
-                wxString tmp = error->Problem();
-
-                tmp.Replace( "\n", "<br>" );
-
-                errors += "<p>" + tmp + "</p><br>";
-            }
-        }
-
-        std::vector<wxString> fpNames;
-
-        for( auto& footprint : fp_list->GetList() )
-        {
-            fpNames.push_back( footprint->GetFootprintName() );
-        }
-
-        m_footprintMap[ libName ] = fpNames;
+        m_libList->Append( nickname );
     }
 
-    // Display errors (if there were any)
-    if( !errors.IsEmpty() )
-    {
-        HTML_MESSAGE_BOX dlg( this, _( "Footprint errors" ) );
-
-        dlg.MessageSet( _( "Errors were encountered loading footprints" ) );
-
-        dlg.AddHTML_Text( errors );
-
-        dlg.ShowModal();
-    }
+    m_libList->Thaw();
 
     // Search for a previous selection:
     int index =  m_libList->FindString( getCurNickname() );
@@ -590,8 +465,6 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
         setCurFootprintName( wxEmptyString );
     }
 
-    progress.Destroy();
-
     ReCreateFootprintList();
     ReCreateHToolbar();
 
@@ -601,28 +474,49 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
 
 void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList()
 {
-    m_footprintList->Clear();
-
     if( !getCurNickname() )
     {
         setCurFootprintName( wxEmptyString );
         return;
     }
 
-    std::vector<wxString> fpNames = m_footprintMap[ getCurNickname() ];
+    const wxString nickname = getCurNickname();
 
-    m_footprintList->Freeze();
-    m_footprintList->Clear();
+    auto lib_table = Prj().PcbFootprintLibs();
+
+    if( !m_fpList || !m_fpList->ReadFootprintFiles( lib_table, &nickname ) )
+    {
+        setCurFootprintName( wxEmptyString );
+        return;
+    }
 
-    for( auto& fpName : fpNames )
+    // Display error information if any footprints could not be parsed due to errors
+
+    if( m_fpList->GetErrorCount() )
     {
-        if( m_fpFilter.IsEmpty() || fpName.Lower().Matches( m_fpFilter ) )
+        wxString errors;
+
+        while( auto error = m_fpList->PopError() )
         {
-            m_footprintList->Append( fpName );
+            wxString tmp = error->Problem();
+            tmp.Replace( "\n", "<br>" );
+
+            errors += tmp;
         }
+
+        HTML_MESSAGE_BOX dlg( this, _( "Footprint errors" ) );
+
+        dlg.MessageSet( wxString::Format( _( "Errors were encountered loading library '%s'" ), nickname ) );
+        dlg.AddHTML_Text( errors );
+
+        dlg.ShowModal();
     }
 
-    m_footprintList->Thaw();
+    // Point the footprint filter to the correct footprint list
+    m_footprintFilter.SetList( *m_fpList );
+
+    // Update filter
+    FilterLibs();
 
     int index = m_footprintList->FindString( getCurFootprintName() );
 
diff --git a/pcbnew/modview_frame.h b/pcbnew/modview_frame.h
index 08ff908..790ae03 100644
--- a/pcbnew/modview_frame.h
+++ b/pcbnew/modview_frame.h
@@ -32,6 +32,8 @@
 
 #include <wx/gdicmn.h>
 #include <wx/srchctrl.h>
+#include <footprint_filter.h>
+#include <footprint_info.h>
 
 class wxSashLayoutWindow;
 class wxListBox;
@@ -65,19 +67,13 @@ public:
 
 private:
 
-    /*
-     * Map of all footprint files
-     * libName:fpNames
-     */
-    std::map< wxString, std::vector<wxString> > m_footprintMap;
+    FOOTPRINT_FILTER m_footprintFilter;                  // Filter for footprint names
+    std::unique_ptr<FOOTPRINT_LIST> m_fpList = nullptr;  // List of footprints within each library
+    std::vector<wxString> m_libraryNicknames;            // List of library nicknames gleaned from FP_LIB_TABLE
+    wxString m_filterText;                               // Text used for filtering footprints
 
     wxSearchCtrl*             m_searchBox;
 
-    wxString    m_libFilter;    // Library name filter string
-    wxString    m_fpFilter;     // Footprint name filter string
-
-    bool        m_filterByLibrary = true;   // Filter footprints by currently selected library
-
     wxListBox*              m_libList;          // The list of library names
     wxListBox*              m_footprintList;    // The list of footprint names
 
@@ -120,8 +116,6 @@ private:
 
     void ClearFilter();
 
-    void OnToggleFilterByLibrary( wxCommandEvent& event );
-
     /**
      * Function RedrawActiveWindow
      * Display the current selected component.
-- 
2.7.4

From d91d6c3ba9832199c627c068a3582f05e472ba51 Mon Sep 17 00:00:00 2001
From: Oliver <oliver.henry.walters@xxxxxxxxx>
Date: Tue, 31 Oct 2017 08:07:48 +1100
Subject: [PATCH 6/9] Fixed greyed-out text bug

- Setting the filter text on creation fixed the issue
---
 pcbnew/modview_frame.cpp | 3 +++
 pcbnew/tool_modview.cpp  | 3 ++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp
index 0da8b59..12167da 100644
--- a/pcbnew/modview_frame.cpp
+++ b/pcbnew/modview_frame.cpp
@@ -350,6 +350,9 @@ void FOOTPRINT_VIEWER_FRAME::ClearFilter()
     m_libFilter = wxEmptyString;
     m_fpFilter = wxEmptyString;
 
+    // SetFocus must be called first to set the text color to black
+    m_searchBox->SetFocus();
+
     m_searchBox->Clear();
     m_searchBox->SetDescriptiveText( _( "Enter filter string" ) );
 
diff --git a/pcbnew/tool_modview.cpp b/pcbnew/tool_modview.cpp
index 358c601..cab0683 100644
--- a/pcbnew/tool_modview.cpp
+++ b/pcbnew/tool_modview.cpp
@@ -67,12 +67,13 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateHToolbar()
                                 KiBitmap( module_xpm ),
                                 _( "Select footprint to browse" ) );
 
-        m_searchBox = new wxSearchCtrl( m_mainToolBar, ID_MODVIEW_SEARCH_TEXT );
+        m_searchBox = new wxSearchCtrl( m_mainToolBar, ID_MODVIEW_SEARCH_TEXT, _( "Enter filter string" ) );
         m_searchBox->SetMinSize( wxSize( 250, 30 ) );
         m_searchBox->SetDescriptiveText( _( "Enter filter string" ) );
         m_searchBox->SetToolTip( _( "Filter footprint list\n"
                                     "- Search is not case sensitive\n"
                                     "- Wildcard search (?*) is supported\n"
+                                    "- Regular expression search is supported\n"
                                     "- Use : separator to include library name in search" ) );
 
         m_mainToolBar->AddControl( m_searchBox );
-- 
2.7.4

From 549985c5f21c8040c51937a4400febbd7dcdca2f Mon Sep 17 00:00:00 2001
From: Oliver <oliver.henry.walters@xxxxxxxxx>
Date: Sun, 29 Oct 2017 23:17:12 +1100
Subject: [PATCH 5/9] Added error display

- Displays single list of ALL footprint errors (from all libs)
---
 pcbnew/modview_frame.cpp | 33 +++++++++++++++++++++++----------
 pcbnew/modview_frame.h   |  1 -
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp
index 2906da2..0da8b59 100644
--- a/pcbnew/modview_frame.cpp
+++ b/pcbnew/modview_frame.cpp
@@ -43,6 +43,7 @@
 #include <lib_id.h>
 #include <confirm.h>
 #include <bitmaps.h>
+#include <html_messagebox.h>
 
 #include <class_board.h>
 #include <class_module.h>
@@ -524,6 +525,8 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
 
     //TODO - Make this process threaded using 'FOOTPRINT_ASYNC_LOADER' ?
 
+    wxString errors;
+
     for( unsigned ii = 0; ii < nicknames.size(); ii++ )
     {
         wxString libName = nicknames[ii];
@@ -535,19 +538,16 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
 
         if( fp_list->GetErrorCount() )
         {
-            // TODO - Display errors
+            errors += "<p><b>Library: " + libName + "</b></p>";
 
-            /*
-            if( fp_info_list->GetErrorCount() )
+            while( auto error = fp_list->PopError() )
             {
-                fp_info_list->DisplayErrors( this );
+                wxString tmp = error->Problem();
+
+                tmp.Replace( "\n", "<br>" );
 
-                // For footprint libraries that support one footprint per file, there may have been
-                // valid footprints read so show the footprints that loaded properly.
-                if( fp_info_list->GetList().size() == 0 )
-                    return;
+                errors += "<p>" + tmp + "</p><br>";
             }
-            */
         }
 
         std::vector<wxString> fpNames;
@@ -560,6 +560,18 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
         m_footprintMap[ libName ] = fpNames;
     }
 
+    // Display errors (if there were any)
+    if( !errors.IsEmpty() )
+    {
+        HTML_MESSAGE_BOX dlg( this, _( "Footprint errors" ) );
+
+        dlg.MessageSet( _( "Errors were encountered loading footprints" ) );
+
+        dlg.AddHTML_Text( errors );
+
+        dlg.ShowModal();
+    }
+
     // Search for a previous selection:
     int index =  m_libList->FindString( getCurNickname() );
 
@@ -808,7 +820,8 @@ void FOOTPRINT_VIEWER_FRAME::OnActivate( wxActivateEvent& event )
     }
 
     // If we are here, the library list has changed, rebuild it
-    ReCreateLibraryList();
+    // (This is now handled by the "Reload Footprint Libraries" button)
+    // ReCreateLibraryList();
     UpdateTitle();
 }
 
diff --git a/pcbnew/modview_frame.h b/pcbnew/modview_frame.h
index 9c9a0f5..08ff908 100644
--- a/pcbnew/modview_frame.h
+++ b/pcbnew/modview_frame.h
@@ -169,7 +169,6 @@ private:
 
     void ReloadAllLibraries( wxCommandEvent& event )
     {
-        OnFilterCleared( event );
         ReCreateLibraryList();
     }
 
-- 
2.7.4

From 9deeecfd7f46ac7d5e28ed9f82ffe34e78d983f5 Mon Sep 17 00:00:00 2001
From: Oliver <oliver.henry.walters@xxxxxxxxx>
Date: Sun, 29 Oct 2017 21:26:51 +1100
Subject: [PATCH 4/9] Replaced wxTextCtrl with wxSearchCtrl

- Also added option to display ALL results (even if not in selected library)
Replaced wxTextCtrl with wxSearchCtrl

- Added button to refresh entire library set
- Moved filter input to main tool bar
---
 pcbnew/modview_frame.cpp | 77 ++++++++++++++++++++++++------------------------
 pcbnew/modview_frame.h   | 33 +++++++++++++++------
 pcbnew/pcbnew_id.h       |  1 +
 pcbnew/tool_modview.cpp  | 16 ++++++++++
 4 files changed, 79 insertions(+), 48 deletions(-)

diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp
index 8b7abdc..2906da2 100644
--- a/pcbnew/modview_frame.cpp
+++ b/pcbnew/modview_frame.cpp
@@ -89,6 +89,8 @@ BEGIN_EVENT_TABLE( FOOTPRINT_VIEWER_FRAME, EDA_DRAW_FRAME )
     EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::GetKicadAbout )
 
     // Toolbar events
+    EVT_TOOL( ID_MODVIEW_RELOAD_LIBS,
+              FOOTPRINT_VIEWER_FRAME::ReloadAllLibraries )
     EVT_TOOL( ID_MODVIEW_SELECT_LIB,
               FOOTPRINT_VIEWER_FRAME::SelectCurrentLibrary )
     EVT_TOOL( ID_MODVIEW_SELECT_PART,
@@ -104,6 +106,13 @@ BEGIN_EVENT_TABLE( FOOTPRINT_VIEWER_FRAME, EDA_DRAW_FRAME )
     // Search events
     EVT_TEXT( ID_MODVIEW_SEARCH_TEXT, FOOTPRINT_VIEWER_FRAME::OnFilterUpdated )
 
+    EVT_SEARCHCTRL_SEARCH_BTN( ID_MODVIEW_SEARCH_TEXT, FOOTPRINT_VIEWER_FRAME::OnFilterUpdated )
+
+    EVT_SEARCHCTRL_CANCEL_BTN( ID_MODVIEW_SEARCH_TEXT, FOOTPRINT_VIEWER_FRAME::OnFilterCleared )
+
+    EVT_TOOL( ID_MODVIEW_FILTER_BY_LIBRARY, FOOTPRINT_VIEWER_FRAME::OnToggleFilterByLibrary )
+
+
     // listbox events
     EVT_LISTBOX( ID_MODVIEW_LIB_LIST, FOOTPRINT_VIEWER_FRAME::ClickOnLibList )
     EVT_LISTBOX( ID_MODVIEW_FOOTPRINT_LIST, FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList )
@@ -262,40 +271,9 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent
     EDA_PANEINFO toolbar;
     toolbar.HorizontalToolbarPane();
 
-    if( !m_auxiliaryToolBar )
-    {
-        m_auxiliaryToolBar = new wxAuiToolBar( this, ID_AUX_TOOLBAR, wxDefaultPosition, wxDefaultSize,
-                                               KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT | wxAUI_TB_OVERFLOW );
-
-        m_auxiliaryToolBar->AddTool( ID_MODVIEW_FILTER_BY_LIBRARY,
-                              KiBitmap( module_library_list_xpm ),
-                              wxNullBitmap,
-                              true, NULL,
-                              _( "Filter footprint list by selected library" ),
-                              wxEmptyString );
-
-        m_auxiliaryToolBar->AddSeparator();
-
-        m_searchBox = new wxTextCtrl( m_auxiliaryToolBar, ID_MODVIEW_SEARCH_TEXT );
-        m_searchBox->SetMinSize( wxSize( 250, -1 ) );
-        m_searchBox->SetHint( _( "Enter filter text" ) );
-        m_searchBox->SetToolTip( _( "Filter footprint list\n"
-                                    "- Search is not case sensitive\n"
-                                    "- Wildcard search (?*) is supported\n"
-                                    "- Use : separator to include library name in search" ) );
-
-        m_auxiliaryToolBar->AddControl( m_searchBox );
-
-        m_auxiliaryToolBar->Realize();
-    }
-
     // Manage main toolbar, top pane
     m_auimgr.AddPane( m_mainToolBar, toolbarPaneInfo );
 
-    m_auimgr.AddPane( m_auxiliaryToolBar,
-                      wxAuiPaneInfo( toolbar ).Name( "m_searchToolBar" ).ToolbarPane()
-                      .Top().Row( 2 ).Layer( 1 ).MinSize( minsize ) );
-
     // Manage the list of libraries, left pane.
     m_auimgr.AddPane( m_libList,
                       info.Name( "m_libList" )
@@ -330,11 +308,6 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent
         m_auimgr.GetPane( m_mainToolBar ).BestSize( tbsize );
     }
 
-    // Ensure that toolbars are visible
-    // It seems that auiMgr::LoadPerspective() sometimes hides these
-    m_mainToolBar->Show();
-    m_auxiliaryToolBar->Show();
-
     // after changing something to the aui manager,
     // call Update()() to reflect the changes
     m_auimgr.Update();
@@ -365,6 +338,24 @@ FOOTPRINT_VIEWER_FRAME::~FOOTPRINT_VIEWER_FRAME()
 }
 
 
+void FOOTPRINT_VIEWER_FRAME::OnFilterCleared( wxCommandEvent& event )
+{
+    ClearFilter();
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::ClearFilter()
+{
+    m_libFilter = wxEmptyString;
+    m_fpFilter = wxEmptyString;
+
+    m_searchBox->Clear();
+    m_searchBox->SetDescriptiveText( _( "Enter filter string" ) );
+
+    FilterLibs();
+}
+
+
 void FOOTPRINT_VIEWER_FRAME::OnFilterUpdated( wxCommandEvent& event )
 {
     // Filter is non case sensitive
@@ -459,6 +450,14 @@ void FOOTPRINT_VIEWER_FRAME::FilterLibs()
 }
 
 
+void FOOTPRINT_VIEWER_FRAME::OnToggleFilterByLibrary( wxCommandEvent& event )
+{
+    //m_filterByLibrary = m_mainToolBar->GetToolToggled( ID_MODVIEW_FILTER_BY_LIBRARY );
+    //TODO
+    //printf( "Filter? %d\n", (int) m_filterByLibrary );
+}
+
+
 void FOOTPRINT_VIEWER_FRAME::OnCloseWindow( wxCloseEvent& Event )
 {
     DBG(printf( "%s:\n", __func__ );)
@@ -503,6 +502,8 @@ void FOOTPRINT_VIEWER_FRAME::OnSetRelativeOffset( wxCommandEvent& event )
 
 void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
 {
+    ClearFilter();
+
     m_footprintMap.clear();
 
     m_libList->Clear();
@@ -593,9 +594,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList()
         return;
     }
 
-    wxString libName = getCurNickname();
-
-    auto fpNames = m_footprintMap[ libName ];
+    std::vector<wxString> fpNames = m_footprintMap[ getCurNickname() ];
 
     m_footprintList->Freeze();
     m_footprintList->Clear();
diff --git a/pcbnew/modview_frame.h b/pcbnew/modview_frame.h
index a2f0714..9c9a0f5 100644
--- a/pcbnew/modview_frame.h
+++ b/pcbnew/modview_frame.h
@@ -31,7 +31,7 @@
 
 
 #include <wx/gdicmn.h>
-#include <wx/textctrl.h>
+#include <wx/srchctrl.h>
 
 class wxSashLayoutWindow;
 class wxListBox;
@@ -71,11 +71,13 @@ private:
      */
     std::map< wxString, std::vector<wxString> > m_footprintMap;
 
-    wxTextCtrl*             m_searchBox;
+    wxSearchCtrl*             m_searchBox;
 
     wxString    m_libFilter;    // Library name filter string
     wxString    m_fpFilter;     // Footprint name filter string
 
+    bool        m_filterByLibrary = true;   // Filter footprints by currently selected library
+
     wxListBox*              m_libList;          // The list of library names
     wxListBox*              m_footprintList;    // The list of footprint names
 
@@ -97,21 +99,28 @@ private:
     void UpdateTitle();
 
     /**
-     * Function SetFilterText
+     * Function OnFilterUpdated
      * Update the search string for footprint filtering
+     * Called when the filter text is changed
      */
     void OnFilterUpdated( wxCommandEvent& event );
 
     /**
-     *
+     * Function OnFilterCleared
+     * Clear (reset) the filter text
+     * Called when the search box "cancel" button is pressed
+     */
+    void OnFilterCleared( wxCommandEvent& event );
+
+    /**
+     * Function FilterLibs
+     * Updates the visible libraries and footprints based on search filter
      */
     void FilterLibs();
 
-    void ClearFilter()
-    {
-        m_searchBox->SetValue( wxEmptyString );
-        m_searchBox->SetHint( _( "Enter filter text" ) );
-    }
+    void ClearFilter();
+
+    void OnToggleFilterByLibrary( wxCommandEvent& event );
 
     /**
      * Function RedrawActiveWindow
@@ -158,6 +167,12 @@ private:
      */
     virtual void OnActivate( wxActivateEvent& event ) override;
 
+    void ReloadAllLibraries( wxCommandEvent& event )
+    {
+        OnFilterCleared( event );
+        ReCreateLibraryList();
+    }
+
     void SelectCurrentLibrary( wxCommandEvent& event );
 
     /**
diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h
index 2209d66..9f5ed98 100644
--- a/pcbnew/pcbnew_id.h
+++ b/pcbnew/pcbnew_id.h
@@ -383,6 +383,7 @@ enum pcbnew_ids
     ID_MODVIEW_FOOTPRINT_WINDOW,
     ID_MODVIEW_LIB_LIST,
     ID_MODVIEW_FOOTPRINT_LIST,
+    ID_MODVIEW_RELOAD_LIBS,
     ID_MODVIEW_SELECT_LIB,
     ID_MODVIEW_SELECT_PART,
     ID_MODVIEW_PREVIOUS,
diff --git a/pcbnew/tool_modview.cpp b/pcbnew/tool_modview.cpp
index 0b2aba7..358c601 100644
--- a/pcbnew/tool_modview.cpp
+++ b/pcbnew/tool_modview.cpp
@@ -53,6 +53,12 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateHToolbar()
                                             | wxAUI_TB_OVERFLOW );
 
         // Set up toolbar
+        m_mainToolBar->AddTool( ID_MODVIEW_RELOAD_LIBS, wxEmptyString,
+                                KiBitmap( reload_xpm ),
+                                _( "Reload footprint libraries" ) );
+
+        m_mainToolBar->AddSeparator();
+
         m_mainToolBar->AddTool( ID_MODVIEW_SELECT_LIB, wxEmptyString,
                                 KiBitmap( library_xpm ),
                                 _( "Select library to browse" ) );
@@ -61,6 +67,16 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateHToolbar()
                                 KiBitmap( module_xpm ),
                                 _( "Select footprint to browse" ) );
 
+        m_searchBox = new wxSearchCtrl( m_mainToolBar, ID_MODVIEW_SEARCH_TEXT );
+        m_searchBox->SetMinSize( wxSize( 250, 30 ) );
+        m_searchBox->SetDescriptiveText( _( "Enter filter string" ) );
+        m_searchBox->SetToolTip( _( "Filter footprint list\n"
+                                    "- Search is not case sensitive\n"
+                                    "- Wildcard search (?*) is supported\n"
+                                    "- Use : separator to include library name in search" ) );
+
+        m_mainToolBar->AddControl( m_searchBox );
+
         m_mainToolBar->AddSeparator();
         m_mainToolBar->AddTool( ID_MODVIEW_PREVIOUS, wxEmptyString,
                                 KiBitmap( lib_previous_xpm ),
-- 
2.7.4

From cf189f4b099f24c1c4ebc1454e70a68805d1ed93 Mon Sep 17 00:00:00 2001
From: Oliver <oliver.henry.walters@xxxxxxxxx>
Date: Sat, 28 Oct 2017 10:59:01 +1100
Subject: [PATCH 3/9] Footprint filtering is now working

---
 pcbnew/modview_frame.cpp | 141 ++++++++++++++++++++++++++++++-----------------
 pcbnew/modview_frame.h   |  10 +++-
 2 files changed, 100 insertions(+), 51 deletions(-)

diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp
index b991f79..8b7abdc 100644
--- a/pcbnew/modview_frame.cpp
+++ b/pcbnew/modview_frame.cpp
@@ -102,7 +102,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_VIEWER_FRAME, EDA_DRAW_FRAME )
     EVT_TOOL( ID_MODVIEW_SHOW_3D_VIEW, FOOTPRINT_VIEWER_FRAME::Show3D_Frame )
 
     // Search events
-    EVT_TEXT( ID_MODVIEW_SEARCH_TEXT, FOOTPRINT_VIEWER_FRAME::UpdateFilter )
+    EVT_TEXT( ID_MODVIEW_SEARCH_TEXT, FOOTPRINT_VIEWER_FRAME::OnFilterUpdated )
 
     // listbox events
     EVT_LISTBOX( ID_MODVIEW_LIB_LIST, FOOTPRINT_VIEWER_FRAME::ClickOnLibList )
@@ -331,6 +331,7 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent
     }
 
     // Ensure that toolbars are visible
+    // It seems that auiMgr::LoadPerspective() sometimes hides these
     m_mainToolBar->Show();
     m_auxiliaryToolBar->Show();
 
@@ -364,77 +365,97 @@ FOOTPRINT_VIEWER_FRAME::~FOOTPRINT_VIEWER_FRAME()
 }
 
 
-void FOOTPRINT_VIEWER_FRAME::UpdateFilter( wxCommandEvent& event )
+void FOOTPRINT_VIEWER_FRAME::OnFilterUpdated( wxCommandEvent& event )
 {
     // Filter is non case sensitive
     wxString filter = m_searchBox->GetValue().Lower();
 
     wxArrayString splitFilter = wxSplit( filter, ':' );
 
-    wxString libFilter;
-    wxString fpFilter;
-
-    bool incLibName = splitFilter.size() == 2;
-
     // Include footprint library name in filter?
-    if( incLibName )
+    if( splitFilter.size() == 2 )
     {
-        printf( "Including library name in filter\n");
-        libFilter = splitFilter[0];
-        fpFilter = splitFilter[1];
+        m_libFilter = splitFilter[0];
+        m_fpFilter = splitFilter[1];
     }
     else
     {
-        fpFilter = filter;
+        m_libFilter = wxEmptyString;
+        m_fpFilter = filter;
     }
 
-    // Enfore leading and trailing asterii
+    // Enforce leading and trailing asterisk character
     // This is required for wxString::Matches to work
 
-    if( !fpFilter.IsEmpty() )
+    if( !m_fpFilter.IsEmpty() )
     {
-        if( !fpFilter.StartsWith( "*" ) )
-            fpFilter.Prepend( "*" );
-        if( !fpFilter.EndsWith( "*" ) )
-            fpFilter.Append( "*" );
+        if( !m_fpFilter.StartsWith( "*" ) )
+            m_fpFilter.Prepend( "*" );
+        if( !m_fpFilter.EndsWith( "*" ) )
+            m_fpFilter.Append( "*" );
     }
 
-    if( !libFilter.IsEmpty() )
+    if( !m_libFilter.IsEmpty() )
     {
-        if( !libFilter.StartsWith( "*" ) )
-            libFilter.Prepend( "*" );
-        if( !libFilter.EndsWith( "*" ) )
-            libFilter.Append( "*" );
+        if( !m_libFilter.StartsWith( "*" ) )
+            m_libFilter.Prepend( "*" );
+        if( !m_libFilter.EndsWith( "*" ) )
+            m_libFilter.Append( "*" );
     }
 
+    // Update the selected libraries
+    FilterLibs();
+}
+
+
+void FOOTPRINT_VIEWER_FRAME::FilterLibs()
+{
+
     wxString fpName;
     wxString libName;
 
+    // Update the list of libraries
+
+    m_libList->Freeze();
+    m_libList->Clear();
+
     for( auto it = m_footprintMap.begin(); it != m_footprintMap.end(); ++it )
     {
-        libName = it->first.Lower();
+        libName = it->first;
 
-        if( incLibName )
+        // Skip this library if it does not match the specified library filter
+        if( !m_libFilter.IsEmpty() && !libName.Lower().Matches( m_libFilter ) )
         {
-            // Skip this library if it does not match the specified library filter
-            if( !libFilter.IsEmpty() && !libName.Lower().Matches( libFilter ) )
-            {
-                continue;
-            }
+            continue;
         }
 
         auto& fpNames = it->second;
 
+        // Test if the library contains any footprints that match the footprint filter
+
+        bool anyMatch = false;
+
         for( auto& fp: fpNames )
         {
             fpName = fp.Lower();
 
-            if( fpFilter.IsEmpty() || fpName.Lower().Matches( fpFilter ) )
+            if( m_fpFilter.IsEmpty() || fpName.Lower().Matches( m_fpFilter ) )
             {
-                std::cout << libName << ":" << fpName << std::endl;
+                anyMatch = true;
+                break;
             }
         }
+
+        if( anyMatch )
+        {
+            m_libList->Append( libName );
+        }
     }
+
+    m_libList->Thaw();
+
+    // Update listed footprints
+    ReCreateFootprintList();
 }
 
 
@@ -500,7 +521,8 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
     auto lib_table = Prj().PcbFootprintLibs();
     auto fp_list( FOOTPRINT_LIST::GetInstance( Kiway() ) );
 
-    //TODO - Make this process threaded using 'FOOTPRINT_ASYNC_LOADER'
+    //TODO - Make this process threaded using 'FOOTPRINT_ASYNC_LOADER' ?
+
     for( unsigned ii = 0; ii < nicknames.size(); ii++ )
     {
         wxString libName = nicknames[ii];
@@ -510,7 +532,22 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
 
         fp_list->ReadFootprintFiles( lib_table, !libName ? NULL : &libName );
 
-        // TODO - Display errors
+        if( fp_list->GetErrorCount() )
+        {
+            // TODO - Display errors
+
+            /*
+            if( fp_info_list->GetErrorCount() )
+            {
+                fp_info_list->DisplayErrors( this );
+
+                // For footprint libraries that support one footprint per file, there may have been
+                // valid footprints read so show the footprints that loaded properly.
+                if( fp_info_list->GetList().size() == 0 )
+                    return;
+            }
+            */
+        }
 
         std::vector<wxString> fpNames;
 
@@ -556,33 +593,33 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList()
         return;
     }
 
-    auto fp_info_list( FOOTPRINT_LIST::GetInstance( Kiway() ) );
+    wxString libName = getCurNickname();
 
-    wxString nickname = getCurNickname();
+    auto fpNames = m_footprintMap[ libName ];
 
-    fp_info_list->ReadFootprintFiles( Prj().PcbFootprintLibs(), !nickname ? NULL : &nickname );
+    m_footprintList->Freeze();
+    m_footprintList->Clear();
 
-    if( fp_info_list->GetErrorCount() )
+    for( auto& fpName : fpNames )
     {
-        fp_info_list->DisplayErrors( this );
-
-        // For footprint libraries that support one footprint per file, there may have been
-        // valid footprints read so show the footprints that loaded properly.
-        if( fp_info_list->GetList().size() == 0 )
-            return;
+        if( m_fpFilter.IsEmpty() || fpName.Lower().Matches( m_fpFilter ) )
+        {
+            m_footprintList->Append( fpName );
+        }
     }
 
-    for( auto& footprint : fp_info_list->GetList() )
-    {
-        m_footprintList->Append( footprint->GetFootprintName() );
-    }
+    m_footprintList->Thaw();
 
     int index = m_footprintList->FindString( getCurFootprintName() );
 
     if( index == wxNOT_FOUND )
+    {
         setCurFootprintName( wxEmptyString );
+    }
     else
+    {
         m_footprintList->SetSelection( index, true );
+    }
 }
 
 
@@ -590,8 +627,10 @@ void FOOTPRINT_VIEWER_FRAME::ClickOnLibList( wxCommandEvent& event )
 {
     int ii = m_libList->GetSelection();
 
-    if( ii < 0 )
+    if( ii < 0 || ii >= (int) m_libList->GetCount() )
+    {
         return;
+    }
 
     wxString name = m_libList->GetString( ii );
 
@@ -613,8 +652,10 @@ void FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList( wxCommandEvent& event )
 
     int ii = m_footprintList->GetSelection();
 
-    if( ii < 0 )
+    if( ii < 0 || ii >= (int) m_footprintList->GetCount() )
+    {
         return;
+    }
 
     wxString name = m_footprintList->GetString( ii );
 
diff --git a/pcbnew/modview_frame.h b/pcbnew/modview_frame.h
index d0f65f9..a2f0714 100644
--- a/pcbnew/modview_frame.h
+++ b/pcbnew/modview_frame.h
@@ -73,6 +73,9 @@ private:
 
     wxTextCtrl*             m_searchBox;
 
+    wxString    m_libFilter;    // Library name filter string
+    wxString    m_fpFilter;     // Footprint name filter string
+
     wxListBox*              m_libList;          // The list of library names
     wxListBox*              m_footprintList;    // The list of footprint names
 
@@ -97,7 +100,12 @@ private:
      * Function SetFilterText
      * Update the search string for footprint filtering
      */
-    void UpdateFilter( wxCommandEvent& event );
+    void OnFilterUpdated( wxCommandEvent& event );
+
+    /**
+     *
+     */
+    void FilterLibs();
 
     void ClearFilter()
     {
-- 
2.7.4

From 9d82dced6b3a52eafa5a8ca1b7f9a167c035ffe9 Mon Sep 17 00:00:00 2001
From: Oliver <oliver.henry.walters@xxxxxxxxx>
Date: Sat, 28 Oct 2017 01:13:59 +1100
Subject: [PATCH 2/9] Implement filtering for footprints

- Filter by library:name pair
- Works! Pretty quick too.
---
 pcbnew/modview_frame.cpp | 108 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 104 insertions(+), 4 deletions(-)

diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp
index 4d9527f..b991f79 100644
--- a/pcbnew/modview_frame.cpp
+++ b/pcbnew/modview_frame.cpp
@@ -28,6 +28,7 @@
  */
 
 #include <wx/sizer.h>
+#include <wx/progdlg.h>
 
 #include <fctsys.h>
 #include <pgm_base.h>
@@ -329,6 +330,10 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent
         m_auimgr.GetPane( m_mainToolBar ).BestSize( tbsize );
     }
 
+    // Ensure that toolbars are visible
+    m_mainToolBar->Show();
+    m_auxiliaryToolBar->Show();
+
     // after changing something to the aui manager,
     // call Update()() to reflect the changes
     m_auimgr.Update();
@@ -361,9 +366,75 @@ FOOTPRINT_VIEWER_FRAME::~FOOTPRINT_VIEWER_FRAME()
 
 void FOOTPRINT_VIEWER_FRAME::UpdateFilter( wxCommandEvent& event )
 {
-    wxString filter = m_searchBox->GetValue();
+    // Filter is non case sensitive
+    wxString filter = m_searchBox->GetValue().Lower();
+
+    wxArrayString splitFilter = wxSplit( filter, ':' );
+
+    wxString libFilter;
+    wxString fpFilter;
+
+    bool incLibName = splitFilter.size() == 2;
+
+    // Include footprint library name in filter?
+    if( incLibName )
+    {
+        printf( "Including library name in filter\n");
+        libFilter = splitFilter[0];
+        fpFilter = splitFilter[1];
+    }
+    else
+    {
+        fpFilter = filter;
+    }
+
+    // Enfore leading and trailing asterii
+    // This is required for wxString::Matches to work
+
+    if( !fpFilter.IsEmpty() )
+    {
+        if( !fpFilter.StartsWith( "*" ) )
+            fpFilter.Prepend( "*" );
+        if( !fpFilter.EndsWith( "*" ) )
+            fpFilter.Append( "*" );
+    }
+
+    if( !libFilter.IsEmpty() )
+    {
+        if( !libFilter.StartsWith( "*" ) )
+            libFilter.Prepend( "*" );
+        if( !libFilter.EndsWith( "*" ) )
+            libFilter.Append( "*" );
+    }
+
+    wxString fpName;
+    wxString libName;
+
+    for( auto it = m_footprintMap.begin(); it != m_footprintMap.end(); ++it )
+    {
+        libName = it->first.Lower();
 
-    //TODO
+        if( incLibName )
+        {
+            // Skip this library if it does not match the specified library filter
+            if( !libFilter.IsEmpty() && !libName.Lower().Matches( libFilter ) )
+            {
+                continue;
+            }
+        }
+
+        auto& fpNames = it->second;
+
+        for( auto& fp: fpNames )
+        {
+            fpName = fp.Lower();
+
+            if( fpFilter.IsEmpty() || fpName.Lower().Matches( fpFilter ) )
+            {
+                std::cout << libName << ":" << fpName << std::endl;
+            }
+        }
+    }
 }
 
 
@@ -415,13 +486,40 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
 
     m_libList->Clear();
 
+    // Get list of loaded footprint libraries
     std::vector< wxString > nicknames = Prj().PcbFootprintLibs()->GetLogicalLibs();
 
+    wxProgressDialog progress( _( "Loading footprint libraries" ),
+                               _( "Reading library data" ),
+                               nicknames.size(),
+                               NULL,
+                               wxPD_APP_MODAL );
+
+    progress.Show();
+
+    auto lib_table = Prj().PcbFootprintLibs();
+    auto fp_list( FOOTPRINT_LIST::GetInstance( Kiway() ) );
+
+    //TODO - Make this process threaded using 'FOOTPRINT_ASYNC_LOADER'
     for( unsigned ii = 0; ii < nicknames.size(); ii++ )
     {
-        m_libList->Append( nicknames[ii] );
+        wxString libName = nicknames[ii];
+        m_libList->Append( libName );
+
+        progress.Update( ii, _( "Loading " + libName ) );
+
+        fp_list->ReadFootprintFiles( lib_table, !libName ? NULL : &libName );
+
+        // TODO - Display errors
+
+        std::vector<wxString> fpNames;
 
-        m_footprintMap[ nicknames[ii] ] = std::vector<wxString>();
+        for( auto& footprint : fp_list->GetList() )
+        {
+            fpNames.push_back( footprint->GetFootprintName() );
+        }
+
+        m_footprintMap[ libName ] = fpNames;
     }
 
     // Search for a previous selection:
@@ -439,6 +537,8 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
         setCurFootprintName( wxEmptyString );
     }
 
+    progress.Destroy();
+
     ReCreateFootprintList();
     ReCreateHToolbar();
 
-- 
2.7.4

From af0b3d334f4bcf2902b4808a21050486b1467bc1 Mon Sep 17 00:00:00 2001
From: Oliver <oliver.henry.walters@xxxxxxxxx>
Date: Fri, 27 Oct 2017 14:38:30 +1100
Subject: [PATCH 1/9] Added footprint search box

- No functionality yet
- Playing wih wxAUI settings
---
 pcbnew/modview_frame.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++--
 pcbnew/modview_frame.h   | 25 +++++++++++++++++++--
 pcbnew/pcbnew_id.h       |  3 +++
 3 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp
index 3d9d598..4d9527f 100644
--- a/pcbnew/modview_frame.cpp
+++ b/pcbnew/modview_frame.cpp
@@ -27,6 +27,8 @@
  * @file modview_frame.cpp
  */
 
+#include <wx/sizer.h>
+
 #include <fctsys.h>
 #include <pgm_base.h>
 #include <kiway.h>
@@ -98,6 +100,9 @@ BEGIN_EVENT_TABLE( FOOTPRINT_VIEWER_FRAME, EDA_DRAW_FRAME )
               FOOTPRINT_VIEWER_FRAME::ExportSelectedFootprint )
     EVT_TOOL( ID_MODVIEW_SHOW_3D_VIEW, FOOTPRINT_VIEWER_FRAME::Show3D_Frame )
 
+    // Search events
+    EVT_TEXT( ID_MODVIEW_SEARCH_TEXT, FOOTPRINT_VIEWER_FRAME::UpdateFilter )
+
     // listbox events
     EVT_LISTBOX( ID_MODVIEW_LIB_LIST, FOOTPRINT_VIEWER_FRAME::ClickOnLibList )
     EVT_LISTBOX( ID_MODVIEW_FOOTPRINT_LIST, FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList )
@@ -166,6 +171,7 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent
     m_footprintList = new wxListBox( this, ID_MODVIEW_FOOTPRINT_LIST,
             wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL );
 
+
     SetBoard( new BOARD() );
     // In viewer, the default net clearance is not known (it depends on the actual board).
     // So we do not show the default clearance, by setting it to 0
@@ -252,17 +258,51 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent
     EDA_PANEINFO mesg;
     mesg.MessageToolbarPane();
 
+    EDA_PANEINFO toolbar;
+    toolbar.HorizontalToolbarPane();
+
+    if( !m_auxiliaryToolBar )
+    {
+        m_auxiliaryToolBar = new wxAuiToolBar( this, ID_AUX_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+                                               KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT | wxAUI_TB_OVERFLOW );
+
+        m_auxiliaryToolBar->AddTool( ID_MODVIEW_FILTER_BY_LIBRARY,
+                              KiBitmap( module_library_list_xpm ),
+                              wxNullBitmap,
+                              true, NULL,
+                              _( "Filter footprint list by selected library" ),
+                              wxEmptyString );
+
+        m_auxiliaryToolBar->AddSeparator();
+
+        m_searchBox = new wxTextCtrl( m_auxiliaryToolBar, ID_MODVIEW_SEARCH_TEXT );
+        m_searchBox->SetMinSize( wxSize( 250, -1 ) );
+        m_searchBox->SetHint( _( "Enter filter text" ) );
+        m_searchBox->SetToolTip( _( "Filter footprint list\n"
+                                    "- Search is not case sensitive\n"
+                                    "- Wildcard search (?*) is supported\n"
+                                    "- Use : separator to include library name in search" ) );
+
+        m_auxiliaryToolBar->AddControl( m_searchBox );
+
+        m_auxiliaryToolBar->Realize();
+    }
+
     // Manage main toolbar, top pane
     m_auimgr.AddPane( m_mainToolBar, toolbarPaneInfo );
 
+    m_auimgr.AddPane( m_auxiliaryToolBar,
+                      wxAuiPaneInfo( toolbar ).Name( "m_searchToolBar" ).ToolbarPane()
+                      .Top().Row( 2 ).Layer( 1 ).MinSize( minsize ) );
+
     // Manage the list of libraries, left pane.
     m_auimgr.AddPane( m_libList,
-                      wxAuiPaneInfo( info ).Name( "m_libList" )
+                      info.Name( "m_libList" )
                       .Left().Row( 1 ).MinSize( minsize ) );
 
     // Manage the list of footprints, center pane.
     m_auimgr.AddPane( m_footprintList,
-                      wxAuiPaneInfo( info ).Name( "m_footprintList" )
+                      info.Name( "m_footprintList" )
                       .Left().Row( 2 ).MinSize( minsize ) );
 
     // Manage the draw panel, right pane.
@@ -319,6 +359,13 @@ FOOTPRINT_VIEWER_FRAME::~FOOTPRINT_VIEWER_FRAME()
 }
 
 
+void FOOTPRINT_VIEWER_FRAME::UpdateFilter( wxCommandEvent& event )
+{
+    wxString filter = m_searchBox->GetValue();
+
+    //TODO
+}
+
 
 void FOOTPRINT_VIEWER_FRAME::OnCloseWindow( wxCloseEvent& Event )
 {
@@ -364,13 +411,19 @@ void FOOTPRINT_VIEWER_FRAME::OnSetRelativeOffset( wxCommandEvent& event )
 
 void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
 {
+    m_footprintMap.clear();
+
     m_libList->Clear();
 
     std::vector< wxString > nicknames = Prj().PcbFootprintLibs()->GetLogicalLibs();
 
     for( unsigned ii = 0; ii < nicknames.size(); ii++ )
+    {
         m_libList->Append( nicknames[ii] );
 
+        m_footprintMap[ nicknames[ii] ] = std::vector<wxString>();
+    }
+
     // Search for a previous selection:
     int index =  m_libList->FindString( getCurNickname() );
 
diff --git a/pcbnew/modview_frame.h b/pcbnew/modview_frame.h
index bb6abcb..d0f65f9 100644
--- a/pcbnew/modview_frame.h
+++ b/pcbnew/modview_frame.h
@@ -31,6 +31,7 @@
 
 
 #include <wx/gdicmn.h>
+#include <wx/textctrl.h>
 
 class wxSashLayoutWindow;
 class wxListBox;
@@ -64,8 +65,16 @@ public:
 
 private:
 
-    wxListBox*          m_libList;               // The list of libs names
-    wxListBox*          m_footprintList;         // The list of footprint names
+    /*
+     * Map of all footprint files
+     * libName:fpNames
+     */
+    std::map< wxString, std::vector<wxString> > m_footprintMap;
+
+    wxTextCtrl*             m_searchBox;
+
+    wxListBox*              m_libList;          // The list of library names
+    wxListBox*              m_footprintList;    // The list of footprint names
 
     const wxString      getCurNickname();
     void                setCurNickname( const wxString& aNickname );
@@ -85,6 +94,18 @@ private:
     void UpdateTitle();
 
     /**
+     * Function SetFilterText
+     * Update the search string for footprint filtering
+     */
+    void UpdateFilter( wxCommandEvent& event );
+
+    void ClearFilter()
+    {
+        m_searchBox->SetValue( wxEmptyString );
+        m_searchBox->SetHint( _( "Enter filter text" ) );
+    }
+
+    /**
      * Function RedrawActiveWindow
      * Display the current selected component.
      * If the component is an alias, the ROOT component is displayed
diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h
index 8c1bf27..2209d66 100644
--- a/pcbnew/pcbnew_id.h
+++ b/pcbnew/pcbnew_id.h
@@ -389,6 +389,9 @@ enum pcbnew_ids
     ID_MODVIEW_NEXT,
     ID_MODVIEW_SHOW_3D_VIEW,
     ID_MODVIEW_FOOTPRINT_EXPORT_TO_BOARD,
+    ID_MODVIEW_SEARCH_TEXT,
+    ID_MODVIEW_FILTER_BY_LIBRARY,
+
     ID_FOOTPRINT_WIZARD_WINDOW,
     ID_FOOTPRINT_WIZARD_PAGES,
     ID_FOOTPRINT_WIZARD_PARAMETERS,
-- 
2.7.4


Follow ups

References