Add pinned library support to Footprint and Symbol Viewers.
Also includes adding libraray and symbol filters to Symbol Viewer.
This commit is contained in:
parent
120c5b9ac1
commit
190fb23e88
|
@ -201,6 +201,7 @@ set( COMMON_WIDGET_SRCS
|
|||
widgets/wx_busy_indicator.cpp
|
||||
widgets/wx_ellipsized_static_text.cpp
|
||||
widgets/wx_grid.cpp
|
||||
widgets/wx_listbox.cpp
|
||||
widgets/wx_panel.cpp
|
||||
widgets/wx_progress_reporters.cpp
|
||||
widgets/wx_splitter_window.cpp
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <widgets/wx_listbox.h>
|
||||
#include <lib_tree_model_adapter.h>
|
||||
|
||||
/*
|
||||
* A specialization of wxListBox with support for pinned items.
|
||||
*/
|
||||
|
||||
|
||||
wxString WX_LISTBOX::GetStringSelection() const
|
||||
{
|
||||
wxString str = wxListBox::GetStringSelection();
|
||||
|
||||
if( str.StartsWith( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() ) )
|
||||
str = str.substr( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol().length() );
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
bool WX_LISTBOX::SetStringSelection( const wxString& s )
|
||||
{
|
||||
if( wxListBox::SetStringSelection( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + s ) )
|
||||
return true;
|
||||
|
||||
return wxListBox::SetStringSelection( s );
|
||||
}
|
||||
|
||||
|
||||
bool WX_LISTBOX::SetStringSelection( const wxString& s, bool select )
|
||||
{
|
||||
if( wxListBox::SetStringSelection( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + s, select ) )
|
||||
return true;
|
||||
|
||||
return wxListBox::SetStringSelection( s, select );
|
||||
}
|
||||
|
||||
|
||||
wxString WX_LISTBOX::GetBaseString( int n ) const
|
||||
{
|
||||
wxString str = wxListBox::GetString( n );
|
||||
|
||||
if( str.StartsWith( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() ) )
|
||||
str = str.substr( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol().length() );
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
int WX_LISTBOX::FindString( const wxString& s, bool bCase ) const
|
||||
{
|
||||
int retVal = wxListBox::FindString( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + s, bCase );
|
||||
|
||||
if( retVal == wxNOT_FOUND )
|
||||
retVal = wxListBox::FindString( s, bCase );
|
||||
|
||||
return retVal;
|
||||
}
|
|
@ -70,7 +70,9 @@ enum id_eeschema_frm
|
|||
ID_LIBVIEW_NEXT,
|
||||
ID_LIBVIEW_PREVIOUS,
|
||||
ID_LIBVIEW_SELECT_UNIT_NUMBER,
|
||||
ID_LIBVIEW_LIB_FILTER,
|
||||
ID_LIBVIEW_LIB_LIST,
|
||||
ID_LIBVIEW_SYM_FILTER,
|
||||
ID_LIBVIEW_SYM_LIST,
|
||||
|
||||
ID_SIM_RUN,
|
||||
|
|
|
@ -33,11 +33,13 @@
|
|||
#include <kiway.h>
|
||||
#include <symbol_viewer_frame.h>
|
||||
#include <widgets/msgpanel.h>
|
||||
#include <widgets/wx_listbox.h>
|
||||
#include <sch_view.h>
|
||||
#include <sch_painter.h>
|
||||
#include <symbol_lib_table.h>
|
||||
#include <symbol_tree_model_adapter.h>
|
||||
#include <pgm_base.h>
|
||||
#include <project/project_file.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <tool/action_toolbar.h>
|
||||
#include <tool/common_control.h>
|
||||
|
@ -51,10 +53,11 @@
|
|||
#include <tools/symbol_editor_control.h>
|
||||
#include <tools/ee_inspection_tool.h>
|
||||
#include <view/view_controls.h>
|
||||
#include <wx/listbox.h>
|
||||
#include <wx/srchctrl.h>
|
||||
|
||||
#include <default_values.h>
|
||||
#include <string_utils.h>
|
||||
#include "eda_pattern_match.h"
|
||||
|
||||
// Save previous symbol library viewer state.
|
||||
wxString SYMBOL_VIEWER_FRAME::m_libraryName;
|
||||
|
@ -76,9 +79,11 @@ BEGIN_EVENT_TABLE( SYMBOL_VIEWER_FRAME, EDA_DRAW_FRAME )
|
|||
EVT_CHOICE( ID_LIBVIEW_SELECT_UNIT_NUMBER, SYMBOL_VIEWER_FRAME::onSelectSymbolUnit )
|
||||
|
||||
// listbox events
|
||||
EVT_TEXT( ID_LIBVIEW_LIB_FILTER, SYMBOL_VIEWER_FRAME::OnLibFilter )
|
||||
EVT_LISTBOX( ID_LIBVIEW_LIB_LIST, SYMBOL_VIEWER_FRAME::ClickOnLibList )
|
||||
EVT_LISTBOX( ID_LIBVIEW_SYM_LIST, SYMBOL_VIEWER_FRAME::ClickOnCmpList )
|
||||
EVT_LISTBOX_DCLICK( ID_LIBVIEW_SYM_LIST, SYMBOL_VIEWER_FRAME::DClickOnCmpList )
|
||||
EVT_TEXT( ID_LIBVIEW_SYM_FILTER, SYMBOL_VIEWER_FRAME::OnSymFilter )
|
||||
EVT_LISTBOX( ID_LIBVIEW_SYM_LIST, SYMBOL_VIEWER_FRAME::ClickOnSymbolList )
|
||||
EVT_LISTBOX_DCLICK( ID_LIBVIEW_SYM_LIST, SYMBOL_VIEWER_FRAME::DClickOnSymbolList )
|
||||
|
||||
// Menu (and/or hotkey) events
|
||||
EVT_MENU( wxID_CLOSE, SYMBOL_VIEWER_FRAME::CloseLibraryViewer )
|
||||
|
@ -150,11 +155,46 @@ SYMBOL_VIEWER_FRAME::SYMBOL_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAM
|
|||
ReCreateVToolbar();
|
||||
ReCreateMenuBar();
|
||||
|
||||
m_libList = new wxListBox( this, ID_LIBVIEW_LIB_LIST, wxDefaultPosition, wxDefaultSize,
|
||||
0, nullptr, wxLB_HSCROLL | wxNO_BORDER );
|
||||
wxPanel* libPanel = new wxPanel( this );
|
||||
wxSizer* libSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_symbolList = new wxListBox( this, ID_LIBVIEW_SYM_LIST, wxDefaultPosition, wxDefaultSize,
|
||||
0, nullptr, wxLB_HSCROLL | wxNO_BORDER );
|
||||
m_libFilter = new wxSearchCtrl( libPanel, ID_LIBVIEW_LIB_FILTER, wxEmptyString,
|
||||
wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
|
||||
m_libFilter->SetDescriptiveText( _( "Filter" ) );
|
||||
libSizer->Add( m_libFilter, 0, wxEXPAND, 5 );
|
||||
|
||||
m_libList = new WX_LISTBOX( libPanel, ID_LIBVIEW_LIB_LIST, wxDefaultPosition, wxDefaultSize,
|
||||
0, nullptr, wxLB_HSCROLL | wxNO_BORDER );
|
||||
libSizer->Add( m_libList, 1, wxEXPAND, 5 );
|
||||
|
||||
libPanel->SetSizer( libSizer );
|
||||
libPanel->Fit();
|
||||
|
||||
wxPanel* symbolPanel = new wxPanel( this );
|
||||
wxSizer* symbolSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_symbolFilter = new wxSearchCtrl( symbolPanel, ID_LIBVIEW_SYM_FILTER, wxEmptyString,
|
||||
wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
|
||||
m_symbolFilter->SetDescriptiveText( _( "Filter" ) );
|
||||
m_symbolFilter->SetToolTip(
|
||||
_( "Filter on symbol name, keywords, description and pin count.\n"
|
||||
"Search terms are separated by spaces. All search terms must match.\n"
|
||||
"A term which is a number will also match against the pin count." ) );
|
||||
symbolSizer->Add( m_symbolFilter, 0, wxEXPAND, 5 );
|
||||
|
||||
#ifdef __WXGTK__
|
||||
// wxSearchCtrl vertical height is not calculated correctly on some GTK setups
|
||||
// See https://gitlab.com/kicad/code/kicad/-/issues/9019
|
||||
m_libFilter->SetMinSize( wxSize( -1, GetTextExtent( wxT( "qb" ) ).y + 10 ) );
|
||||
m_symbolFilter->SetMinSize( wxSize( -1, GetTextExtent( wxT( "qb" ) ).y + 10 ) );
|
||||
#endif
|
||||
|
||||
m_symbolList = new WX_LISTBOX( symbolPanel, ID_LIBVIEW_SYM_LIST, wxDefaultPosition, wxDefaultSize,
|
||||
0, nullptr, wxLB_HSCROLL | wxNO_BORDER );
|
||||
symbolSizer->Add( m_symbolList, 1, wxEXPAND, 5 );
|
||||
|
||||
symbolPanel->SetSizer( symbolSizer );
|
||||
symbolPanel->Fit();
|
||||
|
||||
if( aLibraryName.empty() )
|
||||
{
|
||||
|
@ -175,19 +215,17 @@ SYMBOL_VIEWER_FRAME::SYMBOL_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAM
|
|||
m_auimgr.SetManagedWindow( this );
|
||||
|
||||
// Manage main toolbar
|
||||
m_auimgr.AddPane( m_mainToolBar, EDA_PANE().HToolbar().Name( "MainToolbar" ).Top().Layer( 6 ) );
|
||||
m_auimgr.AddPane( m_messagePanel, EDA_PANE().Messages().Name( "MsgPanel" )
|
||||
.Bottom().Layer( 6 ) );
|
||||
m_auimgr.AddPane( m_mainToolBar, EDA_PANE().HToolbar().Name( "MainToolbar" ).Top().Layer(6) );
|
||||
m_auimgr.AddPane( m_messagePanel, EDA_PANE().Messages().Name( "MsgPanel" ) .Bottom().Layer(6) );
|
||||
|
||||
m_auimgr.AddPane( m_libList, EDA_PANE().Palette().Name( "Libraries" ).Left().Layer(3)
|
||||
.CaptionVisible( false ).MinSize( 80, -1 ).BestSize( m_libListWidth, -1 ) );
|
||||
m_auimgr.AddPane( m_symbolList, EDA_PANE().Palette().Name( "Symbols" ).Left().Layer(1)
|
||||
.CaptionVisible( false ).MinSize( 80, -1 )
|
||||
.BestSize( m_symbolListWidth, -1 ) );
|
||||
m_auimgr.AddPane( libPanel, EDA_PANE().Palette().Name( "Libraries" ).Left().Layer(2)
|
||||
.CaptionVisible( false ).MinSize( 100, -1 ).BestSize( m_libListWidth, -1 ) );
|
||||
m_auimgr.AddPane( symbolPanel, EDA_PANE().Palette().Name( "Symbols" ).Left().Layer(1)
|
||||
.CaptionVisible( false ).MinSize( 100, -1 ).BestSize( m_symbolListWidth, -1 ) );
|
||||
|
||||
m_auimgr.AddPane( GetCanvas(), EDA_PANE().Canvas().Name( "DrawFrame" ).Center() );
|
||||
|
||||
m_auimgr.GetPane( m_libList ).Show( aLibraryName.empty() );
|
||||
m_auimgr.GetPane( libPanel ).Show( aLibraryName.empty() );
|
||||
|
||||
m_auimgr.Update();
|
||||
|
||||
|
@ -408,6 +446,7 @@ bool SYMBOL_VIEWER_FRAME::ShowModal( wxString* aSymbol, wxWindow* aParent )
|
|||
}
|
||||
}
|
||||
|
||||
m_libFilter->SetFocus();
|
||||
return KIWAY_PLAYER::ShowModal( aSymbol, aParent );
|
||||
}
|
||||
|
||||
|
@ -483,45 +522,69 @@ bool SYMBOL_VIEWER_FRAME::ReCreateLibList()
|
|||
|
||||
m_libList->Clear();
|
||||
|
||||
PROJECT_FILE& project = Kiway().Prj().GetProjectFile();
|
||||
std::vector<wxString> libs = Prj().SchSymbolLibTable()->GetLogicalLibs();
|
||||
std::set<wxString> pinnedMatches;
|
||||
std::set<wxString> otherMatches;
|
||||
|
||||
// Remove not allowed libs from main list, if the allowed lib list is not empty
|
||||
if( m_allowedLibs.GetCount() )
|
||||
auto process =
|
||||
[&]( const wxString& aLib )
|
||||
{
|
||||
// Remove not allowed libs, if the allowed lib list is not empty
|
||||
if( m_allowedLibs.GetCount() )
|
||||
{
|
||||
if( m_allowedLibs.Index( aLib ) == wxNOT_FOUND )
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove libs which have no power symbols, if this filter is activated
|
||||
if( m_listPowerOnly )
|
||||
{
|
||||
wxArrayString aliasNames;
|
||||
|
||||
Prj().SchSymbolLibTable()->EnumerateSymbolLib( aLib, aliasNames, true );
|
||||
|
||||
if( aliasNames.IsEmpty() )
|
||||
return;
|
||||
}
|
||||
|
||||
if( alg::contains( project.m_PinnedSymbolLibs, aLib ) )
|
||||
pinnedMatches.insert( aLib );
|
||||
else
|
||||
otherMatches.insert( aLib );
|
||||
};
|
||||
|
||||
if( m_libFilter->GetValue().IsEmpty() )
|
||||
{
|
||||
for( unsigned ii = 0; ii < libs.size(); )
|
||||
{
|
||||
if( m_allowedLibs.Index( libs[ii] ) == wxNOT_FOUND )
|
||||
libs.erase( libs.begin() + ii );
|
||||
else
|
||||
ii++;
|
||||
}
|
||||
for( const wxString& lib : libs )
|
||||
process( lib );
|
||||
}
|
||||
|
||||
// Remove libs which have no power symbols, if this filter is activated
|
||||
if( m_listPowerOnly )
|
||||
else
|
||||
{
|
||||
for( unsigned ii = 0; ii < libs.size(); )
|
||||
wxStringTokenizer tokenizer( m_libFilter->GetValue() );
|
||||
|
||||
while( tokenizer.HasMoreTokens() )
|
||||
{
|
||||
wxArrayString aliasNames;
|
||||
const wxString term = tokenizer.GetNextToken().Lower();
|
||||
EDA_COMBINED_MATCHER matcher( term );
|
||||
int matches, position;
|
||||
|
||||
Prj().SchSymbolLibTable()->EnumerateSymbolLib( libs[ii], aliasNames, true );
|
||||
|
||||
if( aliasNames.IsEmpty() )
|
||||
libs.erase( libs.begin() + ii );
|
||||
else
|
||||
ii++;
|
||||
for( const wxString& lib : libs )
|
||||
{
|
||||
if( matcher.Find( lib.Lower(), matches, position ) )
|
||||
process( lib );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( libs.empty() )
|
||||
return true;
|
||||
|
||||
wxArrayString libNames;
|
||||
for( const wxString& name : pinnedMatches )
|
||||
m_libList->Append( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + UnescapeString( name ) );
|
||||
|
||||
for( const auto& name : libs )
|
||||
libNames.Add( UnescapeString( name ) );
|
||||
|
||||
m_libList->Append( libNames );
|
||||
for( const wxString& name : otherMatches )
|
||||
m_libList->Append( UnescapeString( name ) );
|
||||
|
||||
// Search for a previous selection:
|
||||
int index = m_libList->FindString( UnescapeString( m_libraryName ) );
|
||||
|
@ -534,7 +597,7 @@ bool SYMBOL_VIEWER_FRAME::ReCreateLibList()
|
|||
{
|
||||
// If not found, clear current library selection because it can be
|
||||
// deleted after a config change.
|
||||
m_libraryName = libs[0];
|
||||
m_libraryName = m_libList->GetBaseString( 0 );
|
||||
m_entryName = wxEmptyString;
|
||||
m_unit = 1;
|
||||
m_convert = LIB_ITEM::LIB_CONVERT::BASE;
|
||||
|
@ -553,18 +616,53 @@ bool SYMBOL_VIEWER_FRAME::ReCreateSymbolList()
|
|||
if( m_symbolList == nullptr )
|
||||
return false;
|
||||
|
||||
wxArrayString aliasNames;
|
||||
m_symbolList->Clear();
|
||||
|
||||
if( m_libraryName.IsEmpty() )
|
||||
return false;
|
||||
|
||||
std::vector<LIB_SYMBOL*> symbols;
|
||||
|
||||
try
|
||||
{
|
||||
Prj().SchSymbolLibTable()->EnumerateSymbolLib( m_libraryName, aliasNames,
|
||||
m_listPowerOnly );
|
||||
if( Prj().SchSymbolLibTable()->FindRow( m_libraryName ) )
|
||||
Prj().SchSymbolLibTable()->LoadSymbolLib( symbols, m_libraryName, m_listPowerOnly );
|
||||
}
|
||||
catch( const IO_ERROR& ) {} // ignore, it is handled below
|
||||
|
||||
m_symbolList->Clear();
|
||||
std::set<wxString> excludes;
|
||||
|
||||
if( aliasNames.IsEmpty() )
|
||||
if( !m_symbolFilter->GetValue().IsEmpty() )
|
||||
{
|
||||
wxStringTokenizer tokenizer( m_symbolFilter->GetValue() );
|
||||
|
||||
while( tokenizer.HasMoreTokens() )
|
||||
{
|
||||
const wxString term = tokenizer.GetNextToken().Lower();
|
||||
EDA_COMBINED_MATCHER matcher( term );
|
||||
int matches, position;
|
||||
|
||||
for( LIB_SYMBOL* symbol : symbols )
|
||||
{
|
||||
wxString search = symbol->GetName() + wxS( " " ) + symbol->GetSearchText();
|
||||
bool matched = matcher.Find( search.Lower(), matches, position );
|
||||
|
||||
if( !matched && term.IsNumber() )
|
||||
matched = ( wxAtoi( term ) == (int)symbol->GetPinCount() );
|
||||
|
||||
if( !matched )
|
||||
excludes.insert( symbol->GetName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( const LIB_SYMBOL* symbol : symbols )
|
||||
{
|
||||
if( !excludes.count( symbol->GetName() ) )
|
||||
m_symbolList->Append( UnescapeString( symbol->GetName() ) );
|
||||
}
|
||||
|
||||
if( m_symbolList->IsEmpty() )
|
||||
{
|
||||
m_libraryName = wxEmptyString;
|
||||
m_entryName = wxEmptyString;
|
||||
|
@ -573,13 +671,6 @@ bool SYMBOL_VIEWER_FRAME::ReCreateSymbolList()
|
|||
return true;
|
||||
}
|
||||
|
||||
wxArrayString unescapedNames;
|
||||
|
||||
for( const wxString& name : aliasNames )
|
||||
unescapedNames.Add( UnescapeString( name ) );
|
||||
|
||||
m_symbolList->Append( unescapedNames );
|
||||
|
||||
int index = m_symbolList->FindString( UnescapeString( m_entryName ) );
|
||||
bool changed = false;
|
||||
|
||||
|
@ -596,9 +687,6 @@ bool SYMBOL_VIEWER_FRAME::ReCreateSymbolList()
|
|||
|
||||
m_symbolList->SetSelection( index, true );
|
||||
|
||||
wxCommandEvent evt( wxEVT_COMMAND_LISTBOX_SELECTED, ID_LIBVIEW_SYM_LIST );
|
||||
ProcessEvent( evt );
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
@ -612,7 +700,7 @@ void SYMBOL_VIEWER_FRAME::ClickOnLibList( wxCommandEvent& event )
|
|||
|
||||
m_selection_changed = true;
|
||||
|
||||
SetSelectedLibrary( EscapeString( m_libList->GetString( ii ), CTX_LIBID ) );
|
||||
SetSelectedLibrary( EscapeString( m_libList->GetBaseString( ii ), CTX_LIBID ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -639,7 +727,7 @@ void SYMBOL_VIEWER_FRAME::SetSelectedLibrary( const wxString& aLibraryName )
|
|||
}
|
||||
|
||||
|
||||
void SYMBOL_VIEWER_FRAME::ClickOnCmpList( wxCommandEvent& event )
|
||||
void SYMBOL_VIEWER_FRAME::ClickOnSymbolList( wxCommandEvent& event )
|
||||
{
|
||||
int ii = m_symbolList->GetSelection();
|
||||
|
||||
|
@ -648,7 +736,7 @@ void SYMBOL_VIEWER_FRAME::ClickOnCmpList( wxCommandEvent& event )
|
|||
|
||||
m_selection_changed = true;
|
||||
|
||||
SetSelectedSymbol( EscapeString( m_symbolList->GetString( ii ), CTX_LIBID ) );
|
||||
SetSelectedSymbol( EscapeString( m_symbolList->GetBaseString( ii ), CTX_LIBID ) );
|
||||
|
||||
// The m_symbolList has now the focus, in order to be able to use arrow keys
|
||||
// to navigate inside the list.
|
||||
|
@ -666,7 +754,7 @@ void SYMBOL_VIEWER_FRAME::SetSelectedSymbol( const wxString& aSymbolName )
|
|||
|
||||
// Ensure the corresponding line in m_symbolList is selected
|
||||
// (which is not necessarily the case if SetSelectedSymbol is called
|
||||
// by another caller than ClickOnCmpList.
|
||||
// by another caller than ClickOnSymbolList.
|
||||
m_symbolList->SetStringSelection( UnescapeString( aSymbolName ), true );
|
||||
DisplayLibInfos();
|
||||
|
||||
|
@ -682,7 +770,7 @@ void SYMBOL_VIEWER_FRAME::SetSelectedSymbol( const wxString& aSymbolName )
|
|||
}
|
||||
|
||||
|
||||
void SYMBOL_VIEWER_FRAME::DClickOnCmpList( wxCommandEvent& event )
|
||||
void SYMBOL_VIEWER_FRAME::DClickOnSymbolList( wxCommandEvent& event )
|
||||
{
|
||||
m_toolManager->RunAction( EE_ACTIONS::addSymbolToSchematic, true );
|
||||
}
|
||||
|
@ -881,6 +969,96 @@ void SYMBOL_VIEWER_FRAME::OnSelectSymbol( wxCommandEvent& aEvent )
|
|||
}
|
||||
|
||||
|
||||
void SYMBOL_VIEWER_FRAME::OnLibFilter( wxCommandEvent& aEvent )
|
||||
{
|
||||
ReCreateLibList();
|
||||
|
||||
// Required to avoid interaction with SetHint()
|
||||
// See documentation for wxTextEntry::SetHint
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void SYMBOL_VIEWER_FRAME::OnSymFilter( wxCommandEvent& aEvent )
|
||||
{
|
||||
ReCreateSymbolList();
|
||||
|
||||
// Required to avoid interaction with SetHint()
|
||||
// See documentation for wxTextEntry::SetHint
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void SYMBOL_VIEWER_FRAME::OnCharHook( wxKeyEvent& aEvent )
|
||||
{
|
||||
if( aEvent.GetKeyCode() == WXK_UP )
|
||||
{
|
||||
if( m_libFilter->HasFocus() || m_libList->HasFocus() )
|
||||
{
|
||||
int prev = m_libList->GetSelection() - 1;
|
||||
|
||||
if( prev >= 0 )
|
||||
{
|
||||
m_libList->SetSelection( prev );
|
||||
m_libList->EnsureVisible( prev );
|
||||
|
||||
wxCommandEvent dummy;
|
||||
ClickOnLibList( dummy );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxCommandEvent dummy;
|
||||
onSelectPreviousSymbol( dummy );
|
||||
}
|
||||
}
|
||||
else if( aEvent.GetKeyCode() == WXK_DOWN )
|
||||
{
|
||||
if( m_libFilter->HasFocus() || m_libList->HasFocus() )
|
||||
{
|
||||
int next = m_libList->GetSelection() + 1;
|
||||
|
||||
if( next < (int)m_libList->GetCount() )
|
||||
{
|
||||
m_libList->SetSelection( next );
|
||||
m_libList->EnsureVisible( next );
|
||||
|
||||
wxCommandEvent dummy;
|
||||
ClickOnLibList( dummy );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxCommandEvent dummy;
|
||||
onSelectNextSymbol( dummy );
|
||||
}
|
||||
}
|
||||
else if( aEvent.GetKeyCode() == WXK_TAB && m_libFilter->HasFocus() )
|
||||
{
|
||||
if( !aEvent.ShiftDown() )
|
||||
m_symbolFilter->SetFocus();
|
||||
else
|
||||
aEvent.Skip();
|
||||
}
|
||||
else if( aEvent.GetKeyCode() == WXK_TAB && m_symbolFilter->HasFocus() )
|
||||
{
|
||||
if( aEvent.ShiftDown() )
|
||||
m_libFilter->SetFocus();
|
||||
else
|
||||
aEvent.Skip();
|
||||
}
|
||||
else if( aEvent.GetKeyCode() == WXK_RETURN && m_symbolList->GetSelection() >= 0 )
|
||||
{
|
||||
wxCommandEvent dummy;
|
||||
DClickOnSymbolList( dummy );
|
||||
}
|
||||
else
|
||||
{
|
||||
aEvent.Skip();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SYMBOL_VIEWER_FRAME::onSelectNextSymbol( wxCommandEvent& aEvent )
|
||||
{
|
||||
wxCommandEvent evt( wxEVT_COMMAND_LISTBOX_SELECTED, ID_LIBVIEW_SYM_LIST );
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
#include <sch_screen.h>
|
||||
#include <tool/selection.h>
|
||||
|
||||
class wxListBox;
|
||||
class WX_LISTBOX;
|
||||
class wxSearchCtrl;
|
||||
class SYMBOL_LIBRARY_FILTER;
|
||||
class LIB_SYMBOL;
|
||||
class SYMBOL_LIB_TABLE_ROW;
|
||||
|
@ -95,7 +96,7 @@ public:
|
|||
void ReCreateMenuBar() override;
|
||||
|
||||
void ClickOnLibList( wxCommandEvent& event );
|
||||
void ClickOnCmpList( wxCommandEvent& event );
|
||||
void ClickOnSymbolList( wxCommandEvent& event );
|
||||
void OnSelectSymbol( wxCommandEvent& aEvent );
|
||||
|
||||
void LoadSettings( APP_SETTINGS_BASE* aCfg ) override;
|
||||
|
@ -154,10 +155,14 @@ private:
|
|||
*/
|
||||
void OnActivate( wxActivateEvent& event );
|
||||
|
||||
void DClickOnCmpList( wxCommandEvent& event );
|
||||
void DClickOnSymbolList( wxCommandEvent& event );
|
||||
|
||||
void onUpdateUnitChoice( wxUpdateUIEvent& aEvent );
|
||||
|
||||
void OnLibFilter( wxCommandEvent& aEvent );
|
||||
void OnSymFilter( wxCommandEvent& aEvent );
|
||||
void OnCharHook( wxKeyEvent& aEvent ) override;
|
||||
|
||||
void onSelectNextSymbol( wxCommandEvent& aEvent );
|
||||
void onSelectPreviousSymbol( wxCommandEvent& aEvent );
|
||||
void onSelectSymbolUnit( wxCommandEvent& aEvent );
|
||||
|
@ -167,10 +172,12 @@ private:
|
|||
private:
|
||||
wxChoice* m_unitChoice;
|
||||
|
||||
wxListBox* m_libList; // The list of libraries.
|
||||
wxSearchCtrl* m_libFilter;
|
||||
WX_LISTBOX* m_libList; // The list of libraries.
|
||||
int m_libListWidth; // Last width of the window.
|
||||
|
||||
wxListBox* m_symbolList; // The list of symbols.
|
||||
wxSearchCtrl* m_symbolFilter;
|
||||
WX_LISTBOX* m_symbolList; // The list of symbols.
|
||||
int m_symbolListWidth; // Last width of the window.
|
||||
|
||||
// Filters to build list of libs/list of symbols.
|
||||
|
|
|
@ -96,6 +96,16 @@ class EDA_BASE_FRAME;
|
|||
|
||||
class LIB_TREE_MODEL_ADAPTER: public wxDataViewModel
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @return a unicode string to mark a node name like a pinned library name.
|
||||
* This is not an ASCII7 char, but a unicode char.
|
||||
*/
|
||||
static const wxString GetPinningSymbol()
|
||||
{
|
||||
return wxString::FromUTF8( "☆ " );
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Destructor. Do NOT delete this class manually; it is reference-counted
|
||||
|
@ -354,16 +364,6 @@ protected:
|
|||
unsigned int aCol,
|
||||
wxDataViewItemAttr& aAttr ) const override;
|
||||
|
||||
/**
|
||||
* @return a unicode string to mark a node name like
|
||||
* a pinned library name
|
||||
* This is not an ASCII7 char, but a unicode char
|
||||
*/
|
||||
const wxString GetPinningSymbol() const
|
||||
{
|
||||
return wxString::FromUTF8( "☆ " );
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Find any results worth highlighting and expand them, according to given criteria
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef KICAD_WX_LISTBOX_H
|
||||
#define KICAD_WX_LISTBOX_H
|
||||
|
||||
#include <wx/listbox.h>
|
||||
|
||||
|
||||
class WX_LISTBOX : public wxListBox
|
||||
{
|
||||
public:
|
||||
WX_LISTBOX( wxWindow *parent, wxWindowID winid, const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize, int n = 0, const wxString choices[] = NULL,
|
||||
long style = 0 ) :
|
||||
wxListBox( parent, winid, pos, size, n, choices, style )
|
||||
{ }
|
||||
|
||||
wxString GetStringSelection() const override;
|
||||
bool SetStringSelection( const wxString& s ) override;
|
||||
bool SetStringSelection( const wxString& s, bool select ) override;
|
||||
|
||||
wxString GetBaseString( int n ) const;
|
||||
int FindString( const wxString& s, bool bCase = false ) const override;
|
||||
};
|
||||
|
||||
#endif //KICAD_WX_LISTBOX_H
|
|
@ -35,11 +35,13 @@
|
|||
#include <fp_lib_table.h>
|
||||
#include <kiway.h>
|
||||
#include <widgets/msgpanel.h>
|
||||
#include <widgets/wx_listbox.h>
|
||||
#include <pcb_draw_panel_gal.h>
|
||||
#include <pcb_painter.h>
|
||||
#include <pcbnew_id.h>
|
||||
#include <footprint_editor_settings.h>
|
||||
#include <pgm_base.h>
|
||||
#include <project/project_file.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <tool/action_toolbar.h>
|
||||
#include <tool/common_control.h>
|
||||
|
@ -56,7 +58,7 @@
|
|||
#include <tools/pcb_selection_tool.h>
|
||||
#include <tools/board_editor_control.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <wx/listbox.h>
|
||||
#include <lib_tree_model_adapter.h>
|
||||
#include <wx/srchctrl.h>
|
||||
#include <wx/tokenzr.h>
|
||||
#include <wx/choice.h>
|
||||
|
@ -143,8 +145,8 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent
|
|||
m_libFilter->SetDescriptiveText( _( "Filter" ) );
|
||||
libSizer->Add( m_libFilter, 0, wxEXPAND, 5 );
|
||||
|
||||
m_libList = new wxListBox( libPanel, ID_MODVIEW_LIB_LIST, wxDefaultPosition, wxDefaultSize,
|
||||
0, nullptr, wxLB_HSCROLL | wxNO_BORDER );
|
||||
m_libList = new WX_LISTBOX( libPanel, ID_MODVIEW_LIB_LIST, wxDefaultPosition, wxDefaultSize,
|
||||
0, nullptr, wxLB_HSCROLL | wxNO_BORDER );
|
||||
libSizer->Add( m_libList, 1, wxEXPAND, 5 );
|
||||
|
||||
libPanel->SetSizer( libSizer );
|
||||
|
@ -169,8 +171,8 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent
|
|||
m_fpFilter->SetMinSize( wxSize( -1, GetTextExtent( wxT( "qb" ) ).y + 10 ) );
|
||||
#endif
|
||||
|
||||
m_fpList = new wxListBox( fpPanel, ID_MODVIEW_FOOTPRINT_LIST, wxDefaultPosition, wxDefaultSize,
|
||||
0, nullptr, wxLB_HSCROLL | wxNO_BORDER );
|
||||
m_fpList = new WX_LISTBOX( fpPanel, ID_MODVIEW_FOOTPRINT_LIST, wxDefaultPosition, wxDefaultSize,
|
||||
0, nullptr, wxLB_HSCROLL | wxNO_BORDER );
|
||||
|
||||
m_fpList->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( FOOTPRINT_VIEWER_FRAME::DClickOnFootprintList ), nullptr, this );
|
||||
fpSizer->Add( m_fpList, 1, wxEXPAND, 5 );
|
||||
|
@ -266,7 +268,7 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent
|
|||
// Vertical items; layers 1 - 3
|
||||
m_auimgr.AddPane( libPanel, EDA_PANE().Palette().Name( "Libraries" ).Left().Layer(2)
|
||||
.CaptionVisible( false ).MinSize( 100, -1 ).BestSize( 200, -1 ) );
|
||||
m_auimgr.AddPane( fpPanel, EDA_PANE().Palette().Name( "Footprints" ).Left().Layer( 1)
|
||||
m_auimgr.AddPane( fpPanel, EDA_PANE().Palette().Name( "Footprints" ).Left().Layer(1)
|
||||
.CaptionVisible( false ).MinSize( 100, -1 ).BestSize( 300, -1 ) );
|
||||
|
||||
m_auimgr.AddPane( GetCanvas(), EDA_PANE().Canvas().Name( "DrawFrame" ).Center() );
|
||||
|
@ -398,10 +400,26 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
|
|||
{
|
||||
m_libList->Clear();
|
||||
|
||||
PROJECT_FILE& project = Kiway().Prj().GetProjectFile();
|
||||
std::vector<wxString> nicknames = Prj().PcbFootprintLibs()->GetLogicalLibs();
|
||||
std::set<wxString> excludes;
|
||||
std::set<wxString> pinnedMatches;
|
||||
std::set<wxString> otherMatches;
|
||||
|
||||
if( !m_libFilter->GetValue().IsEmpty() )
|
||||
auto process =
|
||||
[&]( const wxString& aNickname )
|
||||
{
|
||||
if( alg::contains( project.m_PinnedFootprintLibs, aNickname ) )
|
||||
pinnedMatches.insert( aNickname );
|
||||
else
|
||||
otherMatches.insert( aNickname );
|
||||
};
|
||||
|
||||
if( m_libFilter->GetValue().IsEmpty() )
|
||||
{
|
||||
for( const wxString& nickname : nicknames )
|
||||
process( nickname );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxStringTokenizer tokenizer( m_libFilter->GetValue() );
|
||||
|
||||
|
@ -413,17 +431,17 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList()
|
|||
|
||||
for( const wxString& nickname : nicknames )
|
||||
{
|
||||
if( !matcher.Find( nickname.Lower(), matches, position ) )
|
||||
excludes.insert( nickname );
|
||||
if( matcher.Find( nickname.Lower(), matches, position ) )
|
||||
process( nickname );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( const wxString& nickname : nicknames )
|
||||
{
|
||||
if( !excludes.count( nickname ) )
|
||||
m_libList->Append( nickname );
|
||||
}
|
||||
for( const wxString& nickname : pinnedMatches )
|
||||
m_libList->Append( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + nickname );
|
||||
|
||||
for( const wxString& nickname : otherMatches )
|
||||
m_libList->Append( nickname );
|
||||
|
||||
// Search for a previous selection:
|
||||
int index = m_libList->FindString( getCurNickname(), true );
|
||||
|
@ -595,7 +613,7 @@ void FOOTPRINT_VIEWER_FRAME::OnCharHook( wxKeyEvent& aEvent )
|
|||
}
|
||||
|
||||
|
||||
void FOOTPRINT_VIEWER_FRAME::selectPrev( wxListBox* aListBox )
|
||||
void FOOTPRINT_VIEWER_FRAME::selectPrev( WX_LISTBOX* aListBox )
|
||||
{
|
||||
int prev = aListBox->GetSelection() - 1;
|
||||
|
||||
|
@ -614,7 +632,7 @@ void FOOTPRINT_VIEWER_FRAME::selectPrev( wxListBox* aListBox )
|
|||
}
|
||||
|
||||
|
||||
void FOOTPRINT_VIEWER_FRAME::selectNext( wxListBox* aListBox )
|
||||
void FOOTPRINT_VIEWER_FRAME::selectNext( WX_LISTBOX* aListBox )
|
||||
{
|
||||
int next = aListBox->GetSelection() + 1;
|
||||
|
||||
|
@ -640,7 +658,7 @@ void FOOTPRINT_VIEWER_FRAME::ClickOnLibList( wxCommandEvent& aEvent )
|
|||
if( ii < 0 )
|
||||
return;
|
||||
|
||||
wxString name = m_libList->GetString( ii );
|
||||
wxString name = m_libList->GetBaseString( ii );
|
||||
|
||||
if( getCurNickname() == name )
|
||||
return;
|
||||
|
@ -662,7 +680,7 @@ void FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList( wxCommandEvent& aEvent )
|
|||
if( ii < 0 )
|
||||
return;
|
||||
|
||||
wxString name = m_fpList->GetString( ii );
|
||||
wxString name = m_fpList->GetBaseString( ii );
|
||||
|
||||
if( getCurFootprintName().CmpNoCase( name ) != 0 )
|
||||
{
|
||||
|
@ -888,7 +906,7 @@ void FOOTPRINT_VIEWER_FRAME::OnActivate( wxActivateEvent& event )
|
|||
{
|
||||
for( unsigned ii = 0; ii < libNicknames.size(); ii++ )
|
||||
{
|
||||
if( libNicknames[ii] != m_libList->GetString( ii ) )
|
||||
if( libNicknames[ii] != m_libList->GetBaseString( ii ) )
|
||||
{
|
||||
stale = true;
|
||||
break;
|
||||
|
@ -1002,13 +1020,17 @@ void FOOTPRINT_VIEWER_FRAME::UpdateTitle()
|
|||
|
||||
if( !getCurNickname().IsEmpty() )
|
||||
{
|
||||
title = getCurNickname();
|
||||
try
|
||||
{
|
||||
FP_LIB_TABLE* libtable = Prj().PcbFootprintLibs();
|
||||
const LIB_TABLE_ROW* row = libtable->FindRow( getCurNickname() );
|
||||
|
||||
FP_LIB_TABLE* libtable = Prj().PcbFootprintLibs();
|
||||
const LIB_TABLE_ROW* row = libtable->FindRow( getCurNickname() );
|
||||
|
||||
if( row )
|
||||
title += wxT( " \u2014 " ) + row->GetFullURI( true );
|
||||
title = getCurNickname() + wxT( " \u2014 " ) + row->GetFullURI( true );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
title = _( "[no library selected]" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1045,7 +1067,7 @@ void FOOTPRINT_VIEWER_FRAME::SelectAndViewFootprint( int aMode )
|
|||
m_fpList->SetSelection( selection );
|
||||
m_fpList->EnsureVisible( selection );
|
||||
|
||||
setCurFootprintName( m_fpList->GetString((unsigned) selection ) );
|
||||
setCurFootprintName( m_fpList->GetBaseString( selection ) );
|
||||
|
||||
// Delete the current footprint
|
||||
GetBoard()->DeleteAllFootprints();
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include <pcbnew_settings.h>
|
||||
|
||||
class wxSashLayoutWindow;
|
||||
class wxListBox;
|
||||
class WX_LISTBOX;
|
||||
class wxSearchCtrl;
|
||||
class FP_LIB_TABLE;
|
||||
class BOARD_ITEM;
|
||||
|
@ -118,8 +118,8 @@ private:
|
|||
void OnFPFilter( wxCommandEvent& aEvent );
|
||||
void OnCharHook( wxKeyEvent& aEvent ) override;
|
||||
|
||||
void selectPrev( wxListBox* aListBox );
|
||||
void selectNext( wxListBox* aListBox );
|
||||
void selectPrev( WX_LISTBOX* aListBox );
|
||||
void selectNext( WX_LISTBOX* aListBox );
|
||||
void ClickOnLibList( wxCommandEvent& aEvent );
|
||||
void ClickOnFootprintList( wxCommandEvent& aEvent );
|
||||
void DClickOnFootprintList( wxMouseEvent& aEvent );
|
||||
|
@ -166,9 +166,9 @@ private:
|
|||
friend struct PCB::IFACE; // constructor called from here only
|
||||
|
||||
wxSearchCtrl* m_libFilter;
|
||||
wxListBox* m_libList; // The list of library names.
|
||||
WX_LISTBOX* m_libList; // The list of library names.
|
||||
wxSearchCtrl* m_fpFilter;
|
||||
wxListBox* m_fpList; // The list of footprint names.
|
||||
WX_LISTBOX* m_fpList; // The list of footprint names.
|
||||
|
||||
bool m_autoZoom;
|
||||
double m_lastZoom;
|
||||
|
|
Loading…
Reference in New Issue