Wayne, Patch set now goes to 0009 (all patches re-attached to this email).
Most recent patch adds the following: - Busy cursor while loading each library (otherwise it feels like KiCad is just sleepy) - Further nullptr checks, trying to fix Seth's error - Removed a tooltip that erroneously suggested that regex was supported. Cheers On Wed, Nov 1, 2017 at 11:21 AM, Wayne Stambaugh <stambau...@gmail.com> 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 <stambau...@gmail.com > > <mailto:stambau...@gmail.com>> 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 < > stambau...@gmail.com <mailto:stambau...@gmail.com> > > > <mailto:stambau...@gmail.com <mailto:stambau...@gmail.com>>> > 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.hillbr...@gmail.com <mailto:seth.hillbr...@gmail.com> > > <mailto:seth.hillbr...@gmail.com <mailto:seth.hillbr...@gmail.com>> > > > > <mailto:seth.hillbr...@gmail.com <mailto: > seth.hillbr...@gmail.com> > > <mailto:seth.hillbr...@gmail.com > > <mailto:seth.hillbr...@gmail.com>>>> wrote: > > > > > > > > On Mon, Oct 30, 2017 at 11:42 AM, Wayne Stambaugh > > > > <stambau...@gmail.com <mailto:stambau...@gmail.com> > > <mailto:stambau...@gmail.com <mailto:stambau...@gmail.com>> > > > <mailto:stambau...@gmail.com <mailto:stambau...@gmail.com> > > <mailto:stambau...@gmail.com <mailto:stambau...@gmail.com>>>>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@lists.launchpad.net > > <mailto:kicad-developers@lists.launchpad.net> > > > <mailto:kicad-developers@lists.launchpad.net > > <mailto:kicad-developers@lists.launchpad.net>> > > > > <mailto:kicad-developers@lists.launchpad.net > > <mailto:kicad-developers@lists.launchpad.net> > > > <mailto:kicad-developers@lists.launchpad.net > > <mailto:kicad-developers@lists.launchpad.net>>> > > > > 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@lists.launchpad.net > > <mailto:kicad-developers@lists.launchpad.net> > > > <mailto:kicad-developers@lists.launchpad.net > > <mailto:kicad-developers@lists.launchpad.net>> > > > > 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@lists.launchpad.net > > <mailto:kicad-developers@lists.launchpad.net> > > > <mailto:kicad-developers@lists.launchpad.net > > <mailto:kicad-developers@lists.launchpad.net>> > > > 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 ca7867bceb7d086e83df4bfc415754a7347a3bde Mon Sep 17 00:00:00 2001 From: Oliver <oliver.henry.walt...@gmail.com> Date: Fri, 17 Nov 2017 08:23:15 +1100 Subject: [PATCH 9/9] Tweaks to footprint filtering - Further nullptr checking - Added busy cursor while loading library - Removed 'regular expression' tooltip --- pcbnew/modview_frame.cpp | 22 +++++++++++++++++----- pcbnew/tool_modview.cpp | 1 - 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index 283a119..ceac8e6 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> @@ -487,7 +488,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 ) { @@ -526,11 +530,22 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList() 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; @@ -762,9 +777,6 @@ void FOOTPRINT_VIEWER_FRAME::OnActivate( wxActivateEvent& event ) return; } - // If we are here, the library list has changed, rebuild it - // (This is now handled by the "Reload Footprint Libraries" button) - // ReCreateLibraryList(); UpdateTitle(); } 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 a14a71e2170054a4037aa87296e68d58861141a1 Mon Sep 17 00:00:00 2001 From: Oliver <oliver.henry.walt...@gmail.com> Date: Fri, 17 Nov 2017 00:00:11 +1100 Subject: [PATCH 8/9] Reimplmented library filtering - Filtering with the ':' character includes the library name in the filter - Catching a nullptr --- pcbnew/modview_frame.cpp | 62 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index 3a8452e..283a119 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -373,19 +373,65 @@ void FOOTPRINT_VIEWER_FRAME::FilterLibs() return; } - m_footprintList->Freeze(); - m_footprintList->Clear(); + wxString libFilter; - m_footprintFilter.ClearFilters(); + /* + * If the filter includes the ':' character, + * that means that the library nickname should be also filtered! + */ + if( m_filterText.Contains( ":" ) ) + { + wxArrayString split = wxSplit( m_filterText, ':' ); + + if( split.Count() > 0 ) + { + libFilter = split.Item( 0 ); + } + } - m_footprintFilter.FilterByPattern( m_filterText ); + m_libList->Freeze(); + m_libList->Clear(); - for( auto& it : m_footprintFilter ) + for( auto lib : m_libraryNicknames ) { - m_footprintList->Append( it.GetFootprintName() ); + // Only show libraries that match the library filter (if there is one) + if( libFilter.IsEmpty() || lib.Lower().Matches( libFilter ) ) + { + m_libList->Append( lib ); + } } - m_footprintList->Thaw(); + m_libList->Thaw(); + + // If a previously selected library was filtered out, deselect + int index = m_libList->FindString( getCurNickname() ); + + if( index != wxNOT_FOUND ) + { + m_libList->SetSelection( index, true ); + } + else + { + setCurNickname( wxEmptyString ); + setCurFootprintName( wxEmptyString ); + } + + if( !getCurNickname().IsEmpty() && m_fpList != nullptr ) + { + m_footprintList->Freeze(); + m_footprintList->Clear(); + + m_footprintFilter.ClearFilters(); + + m_footprintFilter.FilterByPattern( m_filterText ); + + for( auto& it : m_footprintFilter ) + { + m_footprintList->Append( it.GetFootprintName() ); + } + + m_footprintList->Thaw(); + } } @@ -474,7 +520,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList() void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList() { - if( !getCurNickname() ) + if( getCurNickname().IsEmpty() ) { setCurFootprintName( wxEmptyString ); return; -- 2.7.4
From 2467d9cf21bd3aec7484ef8a0d65ab4205b9a0fc Mon Sep 17 00:00:00 2001 From: Oliver <oliver.henry.walt...@gmail.com> 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 b5971916191a02ce722fb2dd071cf726390e4c06 Mon Sep 17 00:00:00 2001 From: Oliver <oliver.henry.walt...@gmail.com> 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 c77afcb88623fd9e69c7661365008db2ee188ba1 Mon Sep 17 00:00:00 2001 From: Oliver <oliver.henry.walt...@gmail.com> 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 f0d6b058479cc5e408f78e3189056af08715b3c9 Mon Sep 17 00:00:00 2001 From: Oliver <oliver.henry.walt...@gmail.com> 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 79aa3b78a59584aca43c978f3f8e32e310082603 Mon Sep 17 00:00:00 2001 From: Oliver <oliver.henry.walt...@gmail.com> 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 b955843e6d2d1d7e029009df2cac1de792bc3458 Mon Sep 17 00:00:00 2001 From: Oliver <oliver.henry.walt...@gmail.com> 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 4269aa6f612b4818959c7d51f2e143d1c85d158c Mon Sep 17 00:00:00 2001 From: Oliver <oliver.henry.walt...@gmail.com> 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
_______________________________________________ Mailing list: https://launchpad.net/~kicad-developers Post to : kicad-developers@lists.launchpad.net Unsubscribe : https://launchpad.net/~kicad-developers More help : https://help.launchpad.net/ListHelp