KiCad PCB EDA Suite
Loading...
Searching...
No Matches
symbol_tree_model_adapter.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2017 Chris Pavlina <[email protected]>
5 * Copyright (C) 2014 Henner Zeller <[email protected]>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
23
24#include <wx/colour.h>
25#include <wx/log.h>
26#include <wx/tokenzr.h>
27#include <wx/window.h>
28#include <core/kicad_algo.h>
29#include <pgm_base.h>
34#include <generate_alias_info.h>
35#include <sch_base_frame.h>
36#include <locale_io.h>
37#include <string_utils.h>
38#include <trace_helpers.h>
40
41
42wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>
44{
45 auto* adapter = new SYMBOL_TREE_MODEL_ADAPTER( aParent, aManager );
46 return wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>( adapter );
47}
48
49
51 LIB_TREE_MODEL_ADAPTER( aParent, "pinned_symbol_libs", aParent->GetViewerSettingsBase()->m_LibTree ),
52 m_adapter( aLibs ),
54{
57
60}
61
62
65
66
68{
69 for( const std::pair<const wxString, int>& pair : m_cfg.column_widths )
70 m_colWidths[pair.first] = pair.second;
71
72 m_shownColumns = m_cfg.columns;
73
74 if( m_shownColumns.empty() )
75 m_shownColumns = { _HKI( "Item" ), _HKI( "Description" ), GetDefaultFieldName( FIELD_T::VALUE, false ) };
76
77 if( m_shownColumns[0] != _HKI( "Item" ) )
78 m_shownColumns.insert( m_shownColumns.begin(), _HKI( "Item" ) );
79}
80
81
83{
84 m_compatCache.clear();
85
88
89 std::unordered_set<wxString> pinned;
90 std::ranges::copy( cfg->m_Session.pinned_symbol_libs, std::inserter( pinned, pinned.begin() ) );
91 std::ranges::copy( project.m_PinnedSymbolLibs, std::inserter( pinned, pinned.begin() ) );
92
93 auto addFunc =
94 [&]( const wxString& aLibName, const std::vector<LIB_SYMBOL*>& aSymbolList,
95 const wxString& aDescription )
96 {
97 LIB_TREE_NODE_LIBRARY& lib_node =
98 DoAddLibraryNode( aLibName, aDescription, pinned.contains( aLibName ) );
99
100 for( LIB_TREE_ITEM* item: aSymbolList )
101 {
102 if( item )
103 lib_node.AddItem( item );
104 }
105
106 lib_node.AssignIntrinsicRanks( m_shownColumns, false );
107 };
108
110
111 std::vector<wxString> toLoad;
112
113 std::ranges::copy( m_pending_load_libraries, std::back_inserter( toLoad ) );
114
115 bool isLazyLoad = !m_pending_load_libraries.empty();
117
118 if( toLoad.empty() )
119 {
120 for( const LIBRARY_TABLE_ROW* row : manager.Rows( LIBRARY_TABLE_TYPE::SYMBOL ) )
121 {
122 if( row->Disabled() || row->Hidden() )
123 continue;
124
125 toLoad.emplace_back( row->Nickname() );
126 }
127 }
128
129 bool anyLoaded = false;
130
131 for( const wxString& lib : toLoad )
132 {
133 std::optional<LIB_STATUS> status = m_adapter->GetLibraryStatus( lib );
134
135 if( status && status->load_status == LOAD_STATUS::LOAD_ERROR )
136 continue;
137
138 if( !status || status->load_status != LOAD_STATUS::LOADED )
139 {
140 m_pending_load_libraries.insert( lib );
141 continue;
142 }
143
144 anyLoaded = true;
145
146 std::optional<const LIBRARY_TABLE_ROW*> rowResult = manager.GetRow( LIBRARY_TABLE_TYPE::SYMBOL, lib );
147
148 wxCHECK2( rowResult, continue );
149
150 wxString libDescription = ( *rowResult )->Description();
151
152 std::vector<LIB_SYMBOL*> libSymbols = m_adapter->GetSymbols( lib );
153
154 for( const wxString& column : m_adapter->GetAvailableExtraFields( lib ) )
155 addColumnIfNecessary( column );
156
157 if( m_adapter->SupportsSubLibraries( lib ) )
158 {
159 for( const auto& [nickname, description] : m_adapter->GetSubLibraries( lib ) )
160 {
161 wxString suffix = lib.IsEmpty() ? wxString( wxT( "" ) )
162 : wxString::Format( wxT( " - %s" ), nickname );
163 wxString name = wxString::Format( wxT( "%s%s" ), lib, suffix );
164 wxString desc = description;
165
166 if( !libDescription.IsEmpty() )
167 {
168 desc = wxString::Format( wxT( "%s (%s)" ),
169 libDescription,
170 desc.IsEmpty() ? lib : desc );
171 }
172
173 UTF8 utf8Lib( nickname );
174
175 std::vector<LIB_SYMBOL*> symbols;
176
177 std::copy_if( libSymbols.begin(), libSymbols.end(),
178 std::back_inserter( symbols ),
179 [&utf8Lib]( LIB_SYMBOL* aSym )
180 {
181 return utf8Lib == aSym->GetLibId().GetSubLibraryName();
182 } );
183
184 addFunc( name, symbols, desc );
185 }
186 }
187 else
188 {
189 addFunc( lib, libSymbols, libDescription );
190 }
191 }
192
194 {
195 m_check_pending_libraries_timer = std::make_unique<wxTimer>( aFrame );
196
197 wxLogTrace( traceLibraries, "%zu pending libraries, starting lazy load...", m_pending_load_libraries.size() );
198
199 aFrame->Bind( wxEVT_TIMER,
200 [&, aFrame]( wxTimerEvent& )
201 {
202 AddLibraries( aFrame );
203
204 if( m_pending_load_libraries.empty() )
205 {
208 wxLogTrace( traceLibraries, "Done lazy-loading libraries" );
209 }
210 },
212
213 m_check_pending_libraries_timer->Start( 1000 );
214 }
215
216 m_tree.AssignIntrinsicRanks( m_shownColumns );
217
218 if( isLazyLoad && anyLoaded && m_lazyLoadHandler )
219 {
222 }
223}
224
225
226void SYMBOL_TREE_MODEL_ADAPTER::AddLibrary( wxString const& aLibNickname, bool pinned )
227{
230 std::vector<LIB_SYMBOL*> symbols = m_adapter->GetSymbols( aLibNickname, type );
231 std::optional<const LIBRARY_TABLE_ROW*> row = Pgm().GetLibraryManager().GetRow( LIBRARY_TABLE_TYPE::SYMBOL,
232 aLibNickname );
233 std::vector<LIB_TREE_ITEM*> comp_list;
234
235 if( row && symbols.size() > 0 )
236 {
237 comp_list.assign( symbols.begin(), symbols.end() );
238 DoAddLibrary( aLibNickname, ( *row )->Description(), comp_list, pinned, false );
239 }
240}
241
242
243bool SYMBOL_TREE_MODEL_ADAPTER::GetAttr( const wxDataViewItem& aItem, unsigned int aCol,
244 wxDataViewItemAttr& aAttr ) const
245{
246 bool base = LIB_TREE_MODEL_ADAPTER::GetAttr( aItem, aCol, aAttr );
247
248 if( m_compatCallback && aCol == NAME_COL )
249 {
250 LIB_TREE_NODE* node = ToNode( aItem );
251
252 if( node && node->m_Type == LIB_TREE_NODE::TYPE::ITEM )
253 {
254 auto it = m_compatCache.find( node->m_LibId );
255
256 if( it == m_compatCache.end() )
257 {
258 std::vector<VARIANT_COMPAT_RESULT> issues = m_compatCallback( node->m_LibId );
259 it = m_compatCache.emplace( node->m_LibId, !issues.empty() ).first;
260 }
261
262 if( it->second )
263 {
264 aAttr.SetColour( wxColour( 200, 120, 0 ) );
265 return true;
266 }
267 }
268 }
269
270 return base;
271}
272
273
274wxString SYMBOL_TREE_MODEL_ADAPTER::GenerateInfo( LIB_ID const& aLibId, int aUnit )
275{
276 return GenerateAliasInfo( m_adapter, aLibId, aUnit );
277}
const char * name
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
std::vector< LIBRARY_TABLE_ROW * > Rows(LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH, bool aIncludeInvalid=false) const
Returns a flattened list of libraries of the given type.
std::optional< LIBRARY_TABLE_ROW * > GetRow(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH)
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
Define a library symbol object.
Definition lib_symbol.h:114
A mix-in to provide polymorphism between items stored in libraries (symbols, aliases and footprints).
LIB_TREE_MODEL_ADAPTER(EDA_BASE_FRAME *aParent, const wxString &aPinnedKey, APP_SETTINGS_BASE::LIB_TREE &aSettingsStruct)
Create the adapter.
APP_SETTINGS_BASE::LIB_TREE & m_cfg
bool GetAttr(const wxDataViewItem &aItem, unsigned int aCol, wxDataViewItemAttr &aAttr) const override
Get any formatting for an item.
std::map< wxString, int > m_colWidths
void addColumnIfNecessary(const wxString &aHeader)
static LIB_TREE_NODE * ToNode(wxDataViewItem aItem)
Convert wxDataViewItem -> #SYM_TREE_NODE.
std::function< void()> m_lazyLoadHandler
@ NAME_COL
Library or library item name column.
std::function< bool(LIB_TREE_NODE &aNode)> * GetFilter() const
Return the active filter.
std::vector< wxString > m_shownColumns
LIB_TREE_NODE_LIBRARY & DoAddLibraryNode(const wxString &aNodeName, const wxString &aDesc, bool pinned)
std::vector< wxString > m_availableColumns
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.
Node type: library.
LIB_TREE_NODE_ITEM & AddItem(LIB_TREE_ITEM *aItem)
Construct a new alias node, add it to this library, and return it.
Model class in the component selector Model-View-Adapter (mediated MVC) architecture.
void AssignIntrinsicRanks(const std::vector< wxString > &aShownColumns, bool presorted=false)
Store intrinsic ranks on all children of this node.
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:562
virtual LIBRARY_MANAGER & GetLibraryManager() const
Definition pgm_base.h:126
The backing store for a PROJECT, in JSON format.
virtual PROJECT_FILE & GetProjectFile() const
Definition project.h:201
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
An interface to the global shared library manager that is schematic-specific and linked to one projec...
wxString GenerateInfo(LIB_ID const &aLibId, int aUnit) override
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.
std::unique_ptr< wxTimer > m_check_pending_libraries_timer
std::map< LIB_ID, bool > m_compatCache
void AddLibrary(wxString const &aLibNickname, bool pinned)
SYMBOL_LIBRARY_ADAPTER * m_adapter
std::set< wxString > m_pending_load_libraries
bool GetAttr(const wxDataViewItem &aItem, unsigned int aCol, wxDataViewItemAttr &aAttr) const override
SYMBOL_TREE_MODEL_ADAPTER(SCH_BASE_FRAME *aParent, SYMBOL_LIBRARY_ADAPTER *aManager)
Constructor; takes a set of libraries to be included in the search.
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition utf8.h:67
wxString GenerateAliasInfo(SYMBOL_LIBRARY_ADAPTER *aLibs, LIB_ID const &aLibId, int aUnit)
Return an HTML page describing a LIB_ID in a #SYMBOL_LIB_TABLE.
const wxChar *const traceLibraries
Flag to enable library table and library manager tracing.
#define _HKI(x)
Definition page_info.cpp:40
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
std::vector< wxString > pinned_symbol_libs
wxString GetDefaultFieldName(FIELD_T aFieldId, bool aTranslateForHI)
Return a default symbol field name for a mandatory field type.
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ VALUE
Field Value of part, i.e. "3.3K".
wxLogTrace helper definitions.