kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #31652
Re: [PATCH] Add live footprint filtering in modview window
Wayne,
I have finally found some time to readdress this.
I have reimplemented the filtering using the existing FOOTPRINT_FILTER
class. I have also reverted behaviour to work only on the currently
selected footprint library. This removes the requirement to load all the
libraries when the dialog opens.
I think all requirements are satisfied now. Please find modified patch set
attached.
Regards,
Oliver
On Wed, Nov 1, 2017 at 11:21 AM, Wayne Stambaugh <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>> 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>>>
> 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>>>> 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>>>>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>>>
> > > > 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>>>
> > > > 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>>>
> > > > 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>>>
> > > >
> > > >
> > > >
> > > > _______________________________________________
> > > > Mailing list: 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>>
> > > > Unsubscribe : 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>>
> > > >
> > >
> > >
> > > _______________________________________________
> > > Mailing list: 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>>
> > > Unsubscribe : 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>>
> > >
> > >
> >
> >
>
>
From 8a8b4b7aae931c61f29a0f82a196199952e4cfd6 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/7] 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 5d993e116d73e53b7632be1f41d0c2622ba2d391 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/7] 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 5e918ead557c88765b71b169c74144ac390a0cd2 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/7] 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 b378bb13e2c11f29a5e44efa9eb2721e2d1dc7d1 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/7] 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 a5c001b2604b802bf4e1a7bcd6b2e6efeb9a6c6f 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/7] 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 67b189a54761fd709084ee628d06a48567b2886b 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/7] 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 ed8476c99042ecd71dbde6d214799acfbce6e100 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/7] 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
-
[PATCH] Add live footprint filtering in modview window
From: Oliver Walters, 2017-10-29
-
Re: [PATCH] Add live footprint filtering in modview window
From: Chris Fiege, 2017-10-30
-
Re: [PATCH] Add live footprint filtering in modview window
From: Seth Hillbrand, 2017-10-30
-
Re: [PATCH] Add live footprint filtering in modview window
From: Wayne Stambaugh, 2017-10-30
-
Re: [PATCH] Add live footprint filtering in modview window
From: Seth Hillbrand, 2017-10-30
-
Re: [PATCH] Add live footprint filtering in modview window
From: Oliver Walters, 2017-10-30
-
Re: [PATCH] Add live footprint filtering in modview window
From: Wayne Stambaugh, 2017-10-30
-
Re: [PATCH] Add live footprint filtering in modview window
From: Oliver Walters, 2017-10-31
-
Re: [PATCH] Add live footprint filtering in modview window
From: Wayne Stambaugh, 2017-10-31
-
Re: [PATCH] Add live footprint filtering in modview window
From: Oliver Walters, 2017-10-31
-
Re: [PATCH] Add live footprint filtering in modview window
From: Wayne Stambaugh, 2017-11-01