41#include <wx/clipbrd.h>
42#include <wx/display.h>
45#include <wx/splitter.h>
50#include <wx/stattext.h>
60 std::vector<PICKED_SYMBOL>& aHistoryList,
61 std::vector<PICKED_SYMBOL>& aAlreadyPlaced,
62 bool aAllowFieldEdits,
bool aShowFootprints,
bool& aCancelled,
63 std::function<
void()> aAcceptHandler,
64 std::function<
void()> aEscapeHandler ) :
65 wxPanel( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize ),
99 for(
const wxString& nickname : liblist )
106 std::optional<LIBRARY_TABLE_ROW*> row = libmgr->
GetRow( nickname );
108 if( row.has_value() && !row.value()->Hidden() )
120 return aNode.m_IsPower;
130 std::vector<LIB_SYMBOL> history_list_storage;
131 std::vector<LIB_TREE_ITEM*> history_list;
132 std::vector<LIB_SYMBOL> already_placed_storage;
133 std::vector<LIB_TREE_ITEM*> already_placed;
137 [&](
const std::vector<PICKED_SYMBOL>& inputList,
138 std::vector<LIB_SYMBOL>& storageList,
139 std::vector<LIB_TREE_ITEM*>& resultList )
141 storageList.reserve( inputList.size() );
149 storageList.emplace_back( *symbol );
151 for(
const auto& [fieldType, fieldValue] : i.Fields )
153 SCH_FIELD* field = storageList.back().GetField( fieldType );
159 resultList.push_back( &storageList.back() );
166 std::sort( aAlreadyPlaced.begin(), aAlreadyPlaced.end(),
169 return a.LibId.GetLibItemName() < b.LibId.GetLibItemName();
172 processList( aHistoryList, history_list_storage, history_list );
173 processList( aAlreadyPlaced, already_placed_storage, already_placed );
175 adapter->
DoAddLibrary( wxT(
"-- " ) +
_(
"Recently Used" ) + wxT(
" --" ), wxEmptyString,
176 history_list,
false,
true )
179 if( !aHistoryList.empty() )
182 adapter->
DoAddLibrary( wxT(
"-- " ) +
_(
"Already Placed" ) + wxT(
" --" ), wxEmptyString,
183 already_placed,
false,
true )
192 wxBoxSizer* sizer =
new wxBoxSizer( wxVERTICAL );
198 m_hsplitter =
new wxSplitterWindow(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
199 wxSP_LIVE_UPDATE | wxSP_NOBORDER | wxSP_3DSASH );
208 m_vsplitter =
new wxSplitterWindow(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
209 wxSP_LIVE_UPDATE | wxSP_NOBORDER | wxSP_3DSASH );
212 wxSP_LIVE_UPDATE | wxSP_NOBORDER | wxSP_3DSASH );
218 wxPanel* detailsPanel =
new wxPanel(
m_vsplitter );
219 wxBoxSizer* detailsSizer =
new wxBoxSizer( wxVERTICAL );
220 detailsPanel->SetSizer( detailsSizer );
223 detailsSizer->Add(
m_details, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
224 detailsPanel->Layout();
225 detailsSizer->Fit( detailsPanel );
231 sizer->Add(
m_vsplitter, 1, wxEXPAND | wxBOTTOM, 5 );
235 wxBoxSizer* treeSizer =
new wxBoxSizer( wxVERTICAL );
236 treePanel->SetSizer( treeSizer );
241 treeSizer->Add(
m_tree, 1, wxALL | wxEXPAND, 5 );
243 treeSizer->Fit( treePanel );
316 cfg->m_SymChooserPanel.width = GetParent()->ToDIP( GetParent()->GetSize().x );
317 cfg->m_SymChooserPanel.height = GetParent()->ToDIP( GetParent()->GetSize().y );
319 cfg->m_SymChooserPanel.sash_pos_h =
m_hsplitter->GetSashPosition();
322 cfg->m_SymChooserPanel.sash_pos_v =
m_vsplitter->GetSashPosition();
324 cfg->m_SymChooserPanel.sort_mode =
m_tree->GetSortMode();
333 m_tree->BlockPreview(
true );
340 m_tree->BlockPreview(
false );
347 if( aEvent.GetKeyCode() == WXK_ESCAPE )
349 wxObject* eventSource = aEvent.GetEventObject();
351 if( wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( eventSource ) )
354 if( textCtrl->GetValue() ==
m_tree->GetSearchString()
355 && !
m_tree->GetSearchString().IsEmpty() )
357 m_tree->SetSearchString( wxEmptyString );
376 backend =
m_frame->GetCanvas()->GetBackend();
380 wxPanel* panel =
new wxPanel( aParent );
381 wxBoxSizer* sizer =
new wxBoxSizer( wxVERTICAL );
386 wxBoxSizer* bodyStyleSizer =
new wxBoxSizer( wxHORIZONTAL );
390 bodyStyleSizer->Add(
m_bodyStyleLabel, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxTOP | wxBOTTOM, 5 );
392 sizer->Add( bodyStyleSizer, 0, wxEXPAND | wxBOTTOM, 5 );
399 sizer->Add(
m_fp_sel_ctrl, 0, wxEXPAND | wxLEFT | wxRIGHT, 5 );
405 sizer->Add(
m_fp_preview, 10, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
412 panel->SetSizer( sizer );
424 auto horizPixelsFromDU =
428 return GetParent()->ConvertDialogToPixels( sz ).x;
436 int w = panelCfg.
width > 40 ? GetParent()->FromDIP( panelCfg.
width ) : horizPixelsFromDU( 440 );
437 int h = panelCfg.
height > 40 ? GetParent()->FromDIP( panelCfg.
height ) : horizPixelsFromDU( 340 );
440 if(
int display = wxDisplay::GetFromWindow( GetParent() ); display != wxNOT_FOUND )
442 wxRect workArea = wxDisplay( display ).GetClientArea();
443 w = std::min( w, workArea.GetWidth() );
444 h = std::min( h, workArea.GetHeight() );
447 GetParent()->SetSize( wxSize( w, h ) );
448 GetParent()->Layout();
454 panelCfg.
sash_pos_h = horizPixelsFromDU( 220 );
457 panelCfg.
sash_pos_v = horizPixelsFromDU( 230 );
480 if(
m_details && e.GetKeyCode() ==
'C' && e.ControlDown() &&
481 !e.AltDown() && !e.ShiftDown() && !e.MetaDown() )
483 wxString txt =
m_details->SelectionToText();
486 if( wxTheClipboard->Open() )
488 wxTheClipboard->SetData(
new wxTextDataObject( txt ) );
489 wxTheClipboard->Flush();
490 wxTheClipboard->Close();
514 m_adapter->SetPreselectNode( aPreselect, 0 );
517 m_tree->SelectLibId( aPreselect );
539 if( bodyStyleCount > 1 )
541 for(
int i = 1; i <= bodyStyleCount; i++ )
579 m_fp_preview->GetPreviewPanel()->GetCanvas()->SetEvtHandlerEnabled(
false );
580 m_fp_preview->GetPreviewPanel()->GetCanvas()->StopDrawing();
590 wxMouseState state = wxGetMouseState();
592 if( state.LeftIsDown() )
608 m_adapter->OpenLibs( cfg->m_LibTree.open_libs );
625 wxLogError(
_(
"Error loading symbol %s from library '%s'." ) + wxS(
"\n%s" ),
635 wxString fp_name = fp_field ? fp_field->
GetFullText() : wxString(
"" );
647 if( aFootprint == wxEmptyString )
649 m_fp_preview->SetStatusText(
_(
"No footprint specified" ) );
655 if( lib_id.
Parse( aFootprint ) == -1 && lib_id.
IsValid() )
662 m_fp_preview->SetStatusText(
_(
"Invalid footprint specified" ) );
685 wxLogError(
_(
"Error loading symbol %s from library '%s'." ) + wxS(
"\n%s" ),
692 if( symbol !=
nullptr )
696 wxString fp_name = fp_field ? fp_field->
GetFullText() : wxString(
"" );
705 m_fp_sel_ctrl->AddAlwaysIncludedFootprint( assoc.m_FootprintLibId );
726 []( std::pair<FIELD_T, wxString>
const& i )
751 wxCommandEvent evt( EVT_FOOTPRINT_SELECTED );
766 if( !issues.empty() )
768 wxString html = wxS(
"<br><b>" ) +
_(
"Compatibility Warnings:" ) + wxS(
"</b><ul>" );
771 html += wxS(
"<li>" ) +
EscapeHTML( issue.detail ) + wxS(
"</li>" );
773 html += wxS(
"</ul>" );
793 if(
m_tree->GetSelectedLibId().IsValid() )
812 m_tree->Regenerate(
true );
815 m_tree->CenterLibId( savedSelection );
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
@ GAL_TYPE_OPENGL
OpenGL implementation.
Add dark theme support to wxHtmlWindow.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library tables.
std::optional< LIBRARY_TABLE_ROW * > GetRow(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
Like LIBRARY_MANAGER::GetRow but filtered to the LIBRARY_TABLE_TYPE of this adapter.
A logical library item identifier and consists of various portions much like a URI.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
bool IsValid() const
Check if this LID_ID is valid.
const UTF8 & GetLibItemName() const
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Define a library symbol object.
std::vector< const SCH_PIN * > GetGraphicalPins(int aUnit=0, int aBodyStyle=0) const
Graphical pins: Return schematic pin objects as drawn (unexpanded), filtered by unit/body.
const std::vector< ASSOCIATED_FOOTPRINT > & GetEffectiveAssociatedFootprints() const
SCH_FIELD * GetField(const wxString &aFieldName)
Find a field within this symbol matching aFieldName; return nullptr if not found.
wxArrayString GetFPFilters() const
int GetBodyStyleCount() const override
The body styles are a property of the drawings, which a derived symbol inherits from its root symbol ...
wxString GetBodyStyleDescription(int aBodyStyle, bool aLabel) const override
void SetPreselectNode(const LIB_ID &aLibId, int aUnit)
Set the symbol name to be selected if there are no search results.
void AssignIntrinsicRanks()
Sort the tree and assign ranks after adding libraries.
LIB_TREE_NODE_LIBRARY & DoAddLibrary(const wxString &aNodeName, const wxString &aDesc, const std::vector< LIB_TREE_ITEM * > &aItemList, bool pinned, bool presorted)
Add the given list of symbols by alias.
void SetFilter(std::function< bool(LIB_TREE_NODE &aNode)> *aFilter)
Set the filter.
Model class in the component selector Model-View-Adapter (mediated MVC) architecture.
bool m_IsAlreadyPlacedGroup
bool m_IsRecentlyUsedGroup
Widget displaying a tree of symbols with optional search text control and description panel.
wxTimer * m_dbl_click_timer
SYMBOL_PREVIEW_WIDGET * m_symbol_preview
PANEL_SYMBOL_CHOOSER(SCH_BASE_FRAME *aFrame, wxWindow *aParent, const SYMBOL_LIBRARY_FILTER *aFilter, std::vector< PICKED_SYMBOL > &aHistoryList, std::vector< PICKED_SYMBOL > &aAlreadyPlaced, bool aAllowFieldEdits, bool aShowFootprints, bool &aCancelled, std::function< void()> aAcceptHandler, std::function< void()> aEscapeHandler)
Create dialog to choose symbol.
wxChoice * m_bodyStyleChoice
void onSymbolSelected(wxCommandEvent &aEvent)
void showFootprintFor(const LIB_ID &aLibId)
Look up the footprint for a given symbol specified in the LIB_ID and display it.
void onMenuClose(wxMenuEvent &aEvent)
wxSplitterWindow * m_hsplitter
void SetCompatibilityCallback(SYMBOL_COMPAT_FUNC aFunc)
FOOTPRINT_SELECT_WIDGET * m_fp_sel_ctrl
std::function< void()> m_escapeHandler
void updateBodyStyleChoice(LIB_SYMBOL *aSymbol)
void onSelectBodyStyle(wxCommandEvent &aEvent)
void OnDetailsCharHook(wxKeyEvent &aEvt)
static wxString g_symbolSearchString
void onMenuOpen(wxMenuEvent &aEvent)
Handle parent frame menu events to block tree preview.
std::vector< std::pair< FIELD_T, wxString > > m_field_edits
wxStaticText * m_bodyStyleLabel
void onCloseTimer(wxTimerEvent &aEvent)
wxSplitterWindow * m_vsplitter
static SCH_BASE_FRAME * m_frame
wxTimer * m_open_libs_timer
void showFootprint(const wxString &aFootprint)
Display the given footprint by name.
void populateFootprintSelector(const LIB_ID &aLibId)
Populate the footprint selector for a given alias.
void onOpenLibsTimer(wxTimerEvent &aEvent)
void onFootprintSelected(wxCommandEvent &aEvent)
static wxString g_powerSearchString
void OnChar(wxKeyEvent &aEvent)
void SetPreselect(const LIB_ID &aPreselect)
std::function< void()> m_acceptHandler
static constexpr int DBLCLICK_DELAY
SYMBOL_COMPAT_FUNC m_compatCallback
FOOTPRINT_PREVIEW_WIDGET * m_fp_preview
LIB_ID GetSelectedLibId(int *aUnit=nullptr, int *aBodyStyle=nullptr) const
To be called after this dialog returns from ShowModal().
wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > m_adapter
void onSymbolChosen(wxCommandEvent &aEvent)
Handle the selection of an item.
wxPanel * constructRightPanel(wxWindow *aParent)
virtual COMMON_SETTINGS * GetCommonSettings() const
The backing store for a PROJECT, in JSON format.
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
wxString GetFullText(int unit=1) const
Return the text of a field.
void SetText(const wxString &aText) override
An interface to the global shared library manager that is schematic-specific and linked to one projec...
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
Helper object to filter a list of libraries.
bool GetFilterPowerSymbols() const
const wxArrayString & GetAllowedLibList() const
void AddLibraries(SCH_BASE_FRAME *aFrame)
Add all the libraries in a SYMBOL_LIB_TABLE to the model.
static wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > Create(SCH_BASE_FRAME *aParent, SYMBOL_LIBRARY_ADAPTER *aLibs)
Factory function: create a model adapter in a reference-counting container.
void AddLibrary(wxString const &aLibNickname, bool pinned)
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
PGM_BASE & Pgm()
The global program "get" accessor.
T * GetAppSettings(const char *aFilename)
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
std::vector< wxString > pinned_symbol_libs
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
std::function< std::vector< VARIANT_COMPAT_RESULT >(const LIB_ID &)> SYMBOL_COMPAT_FUNC
Callback that evaluates variant symbol compatibility for a given candidate LIB_ID.