KiCad PCB EDA Suite
lib_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 (C) 2014-2022 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 along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <eda_base_frame.h>
23#include <eda_pattern_match.h>
24#include <kiface_base.h>
28#include <widgets/ui_common.h>
29#include <wx/tokenzr.h>
30#include <wx/wupdlock.h>
31#include <string_utils.h>
32
33
34static const int kDataViewIndent = 20;
35
36
37wxDataViewItem LIB_TREE_MODEL_ADAPTER::ToItem( const LIB_TREE_NODE* aNode )
38{
39 return wxDataViewItem( const_cast<void*>( static_cast<void const*>( aNode ) ) );
40}
41
42
44{
45 return static_cast<LIB_TREE_NODE*>( aItem.GetID() );
46}
47
48
50 wxDataViewItemArray& aChildren )
51{
52 unsigned int n = 0;
53
54 for( std::unique_ptr<LIB_TREE_NODE> const& child: aNode.m_Children )
55 {
56 if( child->m_Score > 0 )
57 {
58 aChildren.Add( ToItem( &*child ) );
59 ++n;
60 }
61 }
62
63 return n;
64}
65
66
68 const wxString& aPinnedKey ) :
69 m_parent( aParent ),
70 m_filter( SYM_FILTER_NONE ),
71 m_show_units( true ),
72 m_preselect_unit( 0 ),
73 m_freeze( 0 ),
74 m_widget( nullptr )
75{
76 // Default column widths. Do not translate these names.
77 m_colWidths[ wxT( "Item" ) ] = 300;
78 m_colWidths[ wxT( "Description" ) ] = 600;
79
80 m_availableColumns = { wxT( "Item" ), wxT( "Description" ) };
81
83
84 for( const std::pair<const wxString, int>& pair : cfg->m_LibTree.column_widths )
85 m_colWidths[pair.first] = pair.second;
86
88
89 if( m_shownColumns.empty() )
90 m_shownColumns = { wxT( "Item" ), wxT( "Description" ) };
91
92 if( m_shownColumns[0] != wxT( "Item" ) )
93 m_shownColumns.insert( m_shownColumns.begin(), wxT( "Item" ) );
94}
95
96
98{}
99
100
102{
103 if( m_widget )
104 {
106
108 cfg->m_LibTree.column_widths.clear();
109
110 for( const std::pair<const wxString, wxDataViewColumn*>& pair : m_colNameMap )
111 cfg->m_LibTree.column_widths[pair.first] = pair.second->GetWidth();
112 }
113}
114
115
117{
118 m_filter = aFilter;
119}
120
121
123{
124 m_show_units = aShow;
125}
126
127
128void LIB_TREE_MODEL_ADAPTER::SetPreselectNode( const LIB_ID& aLibId, int aUnit )
129{
130 m_preselect_lib_id = aLibId;
131 m_preselect_unit = aUnit;
132}
133
134
136 const wxString& aDesc, bool pinned )
137{
138 LIB_TREE_NODE_LIB& lib_node = m_tree.AddLib( aNodeName, aDesc );
139
140 lib_node.m_Pinned = pinned;
141
142 return lib_node;
143}
144
145
146void LIB_TREE_MODEL_ADAPTER::DoAddLibrary( const wxString& aNodeName, const wxString& aDesc,
147 const std::vector<LIB_TREE_ITEM*>& aItemList,
148 bool pinned, bool presorted )
149{
150 LIB_TREE_NODE_LIB& lib_node = DoAddLibraryNode( aNodeName, aDesc, pinned );
151
152 for( LIB_TREE_ITEM* item: aItemList )
153 lib_node.AddItem( item );
154
155 lib_node.AssignIntrinsicRanks( presorted );
156}
157
158
159void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( const wxString& aSearch, bool aState )
160{
161 {
162 wxWindowUpdateLocker updateLock( m_widget );
163
164 // Even with the updateLock, wxWidgets sometimes ties its knickers in a knot trying to
165 // run a wxdataview_selection_changed_callback() on a row that has been deleted.
166 // https://bugs.launchpad.net/kicad/+bug/1756255
167 m_widget->UnselectAll();
168
169 // This collapse is required before the call to "Freeze()" below. Once Freeze()
170 // is called, GetParent() will return nullptr. While this works for some calls, it
171 // segfaults when we have any expanded elements b/c the sub units in the tree don't
172 // have explicit references that are maintained over a search
173 // The tree will be expanded again below when we get our matches
174 //
175 // Also note that this cannot happen when we have deleted a symbol as GTK will also
176 // iterate over the tree in this case and find a symbol that has an invalid link
177 // and crash https://gitlab.com/kicad/code/kicad/-/issues/6910
178 if( !aState && !aSearch.IsNull() && m_tree.m_Children.size() )
179 {
180 for( std::unique_ptr<LIB_TREE_NODE>& child: m_tree.m_Children )
181 m_widget->Collapse( wxDataViewItem( &*child ) );
182 }
183
184 // DO NOT REMOVE THE FREEZE/THAW. This freeze/thaw is a flag for this model adapter
185 // that tells it when it shouldn't trust any of the data in the model. When set, it will
186 // not return invalid data to the UI, since this invalid data can cause crashes.
187 // This is different than the update locker, which locks the UI aspects only.
188 Freeze();
189 BeforeReset();
190
192
193 wxStringTokenizer tokenizer( aSearch );
194
195 while( tokenizer.HasMoreTokens() )
196 {
197 wxString lib;
198 wxString term = tokenizer.GetNextToken().Lower();
199
200 if( term.Contains( ":" ) )
201 {
202 lib = term.BeforeFirst( ':' );
203 term = term.AfterFirst( ':' );
204 }
205
206 EDA_COMBINED_MATCHER matcher( term, CTX_LIBITEM );
207
208 m_tree.UpdateScore( matcher, lib );
209 }
210
212 AfterReset();
213 Thaw();
214 }
215
216 LIB_TREE_NODE* bestMatch = ShowResults();
217
218 if( !bestMatch )
219 bestMatch = ShowPreselect();
220
221 if( !bestMatch )
222 bestMatch = ShowSingleLibrary();
223
224 if( bestMatch )
225 {
226 wxDataViewItem item = wxDataViewItem( bestMatch );
227 m_widget->Select( item );
228
229 // Make sure the *parent* item is visible. The selected item is the
230 // first (shown) child of the parent. So it's always right below the parent,
231 // and this way the user can also see what library the selected part belongs to,
232 // without having a case where the selection is off the screen (unless the
233 // window is a single row high, which is unlikely)
234 //
235 // This also happens to circumvent https://bugs.launchpad.net/kicad/+bug/1804400
236 // which appears to be a GTK+3 bug.
237 {
238 wxDataViewItem parent = GetParent( item );
239
240 if( parent.IsOk() )
241 m_widget->EnsureVisible( parent );
242 }
243
244 m_widget->EnsureVisible( item );
245 }
246}
247
248
249void LIB_TREE_MODEL_ADAPTER::AttachTo( wxDataViewCtrl* aDataViewCtrl )
250{
251 m_widget = aDataViewCtrl;
252 aDataViewCtrl->SetIndent( kDataViewIndent );
253 aDataViewCtrl->AssociateModel( this );
255}
256
257
259{
260 m_widget->ClearColumns();
261
262 m_columns.clear();
263 m_colIdxMap.clear();
264 m_colNameMap.clear();
265
266 // The Item column is always shown
267 doAddColumn( wxT( "Item" ) );
268
269 for( const wxString& colName : m_shownColumns )
270 {
271 if( !m_colNameMap.count( colName ) )
272 doAddColumn( colName, false );
273 }
274}
275
276
278{
279 Freeze();
280 BeforeReset();
281
283
284 AfterReset();
285 Thaw();
286}
287
288
290{
292 aTreeNode->m_Pinned = true;
293
294 resortTree();
295 m_widget->EnsureVisible( ToItem( aTreeNode ) );
296}
297
298
300{
302 aTreeNode->m_Pinned = false;
303
304 resortTree();
305 // Keep focus at top when unpinning
306}
307
308
309wxDataViewColumn* LIB_TREE_MODEL_ADAPTER::doAddColumn( const wxString& aHeader, bool aTranslate )
310{
311 wxString translatedHeader = aTranslate ? wxGetTranslation( aHeader ) : aHeader;
312
313 // The extent of the text doesn't take into account the space on either side
314 // in the header, so artificially pad it
315 wxSize headerMinWidth = KIUI::GetTextSize( translatedHeader + wxT( "MMM" ), m_widget );
316
317 if( !m_colWidths.count( aHeader ) || m_colWidths[aHeader] < headerMinWidth.x )
318 m_colWidths[aHeader] = headerMinWidth.x;
319
320 int index = m_columns.size();
321
322 wxDataViewColumn* ret = m_widget->AppendTextColumn( translatedHeader, index,
323 wxDATAVIEW_CELL_INERT,
324 m_colWidths[aHeader] );
325 ret->SetMinWidth( headerMinWidth.x );
326
327 m_columns.emplace_back( ret );
328 m_colNameMap[aHeader] = ret;
329 m_colIdxMap[m_columns.size() - 1] = aHeader;
330
331 return ret;
332}
333
334
335void LIB_TREE_MODEL_ADAPTER::addColumnIfNecessary( const wxString& aHeader )
336{
337 if( m_colNameMap.count( aHeader ) )
338 return;
339
340 // Columns will be created later
341 m_colNameMap[aHeader] = nullptr;
342 m_availableColumns.emplace_back( aHeader );
343}
344
345
346void LIB_TREE_MODEL_ADAPTER::SetShownColumns( const std::vector<wxString>& aColumnNames )
347{
348 bool recreate = m_shownColumns != aColumnNames;
349
350 m_shownColumns = aColumnNames;
351
352 if( recreate && m_widget )
354}
355
356
357LIB_ID LIB_TREE_MODEL_ADAPTER::GetAliasFor( const wxDataViewItem& aSelection ) const
358{
359 const LIB_TREE_NODE* node = ToNode( aSelection );
360
361 LIB_ID emptyId;
362
363 if( !node )
364 return emptyId;
365
366 return node->m_LibId;
367}
368
369
370int LIB_TREE_MODEL_ADAPTER::GetUnitFor( const wxDataViewItem& aSelection ) const
371{
372 const LIB_TREE_NODE* node = ToNode( aSelection );
373 return node ? node->m_Unit : 0;
374}
375
376
377LIB_TREE_NODE::TYPE LIB_TREE_MODEL_ADAPTER::GetTypeFor( const wxDataViewItem& aSelection ) const
378{
379 const LIB_TREE_NODE* node = ToNode( aSelection );
380 return node ? node->m_Type : LIB_TREE_NODE::INVALID;
381}
382
383
384LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::GetTreeNodeFor( const wxDataViewItem& aSelection ) const
385{
386 return ToNode( aSelection );
387}
388
389
391{
392 int n = 0;
393
394 for( const std::unique_ptr<LIB_TREE_NODE>& lib: m_tree.m_Children )
395 n += lib->m_Children.size();
396
397 return n;
398}
399
400
401wxDataViewItem LIB_TREE_MODEL_ADAPTER::FindItem( const LIB_ID& aLibId )
402{
403 for( std::unique_ptr<LIB_TREE_NODE>& lib: m_tree.m_Children )
404 {
405 if( lib->m_Name != aLibId.GetLibNickname() )
406 continue;
407
408 // if part name is not specified, return the library node
409 if( aLibId.GetLibItemName() == "" )
410 return ToItem( lib.get() );
411
412 for( std::unique_ptr<LIB_TREE_NODE>& alias: lib->m_Children )
413 {
414 if( alias->m_Name == aLibId.GetLibItemName() )
415 return ToItem( alias.get() );
416 }
417
418 break; // could not find the part in the requested library
419 }
420
421 return wxDataViewItem();
422}
423
424
425unsigned int LIB_TREE_MODEL_ADAPTER::GetChildren( const wxDataViewItem& aItem,
426 wxDataViewItemArray& aChildren ) const
427{
428 const LIB_TREE_NODE* node = ( aItem.IsOk() ? ToNode( aItem ) : &m_tree );
429
430 if( node->m_Type == LIB_TREE_NODE::TYPE::ROOT
431 || node->m_Type == LIB_TREE_NODE::LIB
432 || ( m_show_units && node->m_Type == LIB_TREE_NODE::TYPE::LIBID ) )
433 {
434 return IntoArray( *node, aChildren );
435 }
436 else
437 {
438 return 0;
439 }
440
441}
442
443
445{
446 wxDataViewColumn* col = nullptr;
447 size_t idx = 0;
448 int totalWidth = 0;
449 wxString header;
450
451 for( ; idx < m_columns.size() - 1; idx++ )
452 {
453 wxASSERT( m_colIdxMap.count( idx ) );
454
455 col = m_columns[idx];
456 header = m_colIdxMap[idx];
457
458 wxASSERT( m_colWidths.count( header ) );
459
460 col->SetWidth( m_colWidths[header] );
461 totalWidth += col->GetWidth();
462 }
463
464 int remainingWidth = m_widget->GetSize().x - totalWidth;
465 header = m_columns[idx]->GetTitle();
466
467 m_columns[idx]->SetWidth( std::max( m_colWidths[header], remainingWidth ) );
468}
469
470
471void LIB_TREE_MODEL_ADAPTER::OnSize( wxSizeEvent& aEvent )
472{
473 aEvent.Skip();
474}
475
476
478{
479 // Yes, this is an enormous hack. But it works on all platforms, it doesn't suffer
480 // the On^2 sorting issues that ItemChanged() does on OSX, and it doesn't lose the
481 // user's scroll position (which re-attaching or deleting/re-inserting columns does).
482 static int walk = 1;
483
484 std::vector<int> widths;
485
486 for( const wxDataViewColumn* col : m_columns )
487 widths.emplace_back( col->GetWidth() );
488
489 wxASSERT( widths.size() );
490
491 // Only use the widths read back if they are non-zero.
492 // GTK returns the displayed width of the column, which is not calculated immediately
493 if( widths[0] > 0 )
494 {
495 size_t i = 0;
496
497 for( const auto& [ colName, colPtr ] : m_colNameMap )
498 m_colWidths[ colName ] = widths[i++];
499 }
500
501 auto colIt = m_colWidths.begin();
502
503 colIt->second += walk;
504 colIt++;
505
506 if( colIt != m_colWidths.end() )
507 colIt->second -= walk;
508
509 for( const auto& [ colName, colPtr ] : m_colNameMap )
510 {
511 if( colPtr == m_columns[0] )
512 continue;
513
514 wxASSERT( m_colWidths.count( colName ) );
515 colPtr->SetWidth( m_colWidths[ colName ] );
516 }
517
518 walk = -walk;
519}
520
521
522bool LIB_TREE_MODEL_ADAPTER::HasContainerColumns( const wxDataViewItem& aItem ) const
523{
524 return IsContainer( aItem );
525}
526
527
528bool LIB_TREE_MODEL_ADAPTER::IsContainer( const wxDataViewItem& aItem ) const
529{
530 LIB_TREE_NODE* node = ToNode( aItem );
531 return node ? node->m_Children.size() : true;
532}
533
534
535wxDataViewItem LIB_TREE_MODEL_ADAPTER::GetParent( const wxDataViewItem& aItem ) const
536{
537 if( m_freeze )
538 return ToItem( nullptr );
539
540 LIB_TREE_NODE* node = ToNode( aItem );
541 LIB_TREE_NODE* parent = node ? node->m_Parent : nullptr;
542
543 // wxDataViewModel has no root node, but rather top-level elements have
544 // an invalid (null) parent.
545 if( !node || !parent || parent->m_Type == LIB_TREE_NODE::TYPE::ROOT )
546 return ToItem( nullptr );
547 else
548 return ToItem( parent );
549}
550
551
552void LIB_TREE_MODEL_ADAPTER::GetValue( wxVariant& aVariant,
553 const wxDataViewItem& aItem,
554 unsigned int aCol ) const
555{
556 if( IsFrozen() )
557 {
558 aVariant = wxEmptyString;
559 return;
560 }
561
562 LIB_TREE_NODE* node = ToNode( aItem );
563 wxASSERT( node );
564
565 switch( aCol )
566 {
567 case NAME_COL:
568 if( node->m_Pinned )
569 aVariant = GetPinningSymbol() + UnescapeString( node->m_Name );
570 else
571 aVariant = UnescapeString( node->m_Name );
572
573 break;
574
575 default:
576 if( m_colIdxMap.count( aCol ) )
577 {
578 const wxString& key = m_colIdxMap.at( aCol );
579
580 if( node->m_Fields.count( key ) )
581 aVariant = node->m_Fields.at( key );
582 else if( key == wxT( "Description" ) )
583 aVariant = node->m_Desc;
584 else
585 aVariant = wxEmptyString;
586 }
587
588 break;
589 }
590}
591
592
593bool LIB_TREE_MODEL_ADAPTER::GetAttr( const wxDataViewItem& aItem,
594 unsigned int aCol,
595 wxDataViewItemAttr& aAttr ) const
596{
597 if( IsFrozen() )
598 return false;
599
600 LIB_TREE_NODE* node = ToNode( aItem );
601 wxASSERT( node );
602
603 if( node->m_Type != LIB_TREE_NODE::LIBID )
604 {
605 // Currently only aliases are formatted at all
606 return false;
607 }
608
609 if( !node->m_IsRoot && aCol == 0 )
610 {
611 // Names of non-root aliases are italicized
612 aAttr.SetItalic( true );
613 return true;
614 }
615 else
616 {
617 return false;
618 }
619}
620
621
623 std::function<bool( const LIB_TREE_NODE* )> aFunc,
624 LIB_TREE_NODE** aHighScore )
625{
626 for( std::unique_ptr<LIB_TREE_NODE>& node: aNode.m_Children )
627 {
628 if( aFunc( &*node ) )
629 {
630 if( !(*aHighScore) || node->m_Score > (*aHighScore)->m_Score )
631 (*aHighScore) = &*node;
632 }
633
634 Find( *node, aFunc, aHighScore );
635 }
636}
637
638
640{
641 LIB_TREE_NODE* highScore = nullptr;
642
643 Find( m_tree,
644 []( LIB_TREE_NODE const* n )
645 {
646 // return leaf nodes with some level of matching
647 return n->m_Type == LIB_TREE_NODE::TYPE::LIBID && n->m_Score > 1;
648 },
649 &highScore );
650
651 if( highScore)
652 {
653 wxDataViewItem item = wxDataViewItem( highScore );
654 m_widget->ExpandAncestors( item );
655 }
656
657 return highScore;
658}
659
660
662{
663 LIB_TREE_NODE* highScore = nullptr;
664
666 return highScore;
667
668 Find( m_tree,
669 [&]( LIB_TREE_NODE const* n )
670 {
671 if( n->m_Type == LIB_TREE_NODE::LIBID && ( n->m_Children.empty() ||
673 return m_preselect_lib_id == n->m_LibId;
675 return m_preselect_lib_id == n->m_Parent->m_LibId &&
677 else
678 return false;
679 },
680 &highScore );
681
682 if( highScore)
683 {
684 wxDataViewItem item = wxDataViewItem( highScore );
685 m_widget->ExpandAncestors( item );
686 }
687
688 return highScore;
689}
690
691
693{
694 LIB_TREE_NODE* highScore = nullptr;
695
696 Find( m_tree,
697 []( LIB_TREE_NODE const* n )
698 {
699 return n->m_Type == LIB_TREE_NODE::TYPE::LIBID &&
700 n->m_Parent->m_Parent->m_Children.size() == 1;
701 },
702 &highScore );
703
704 if( highScore)
705 {
706 wxDataViewItem item = wxDataViewItem( highScore );
707 m_widget->ExpandAncestors( item );
708 }
709
710 return highScore;
711}
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Definition: app_settings.h:110
The base frame for deriving all KiCad main window classes.
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_base.h:95
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
bool IsValid() const
Check if this LID_ID is valid.
Definition: lib_id.h:172
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
A mix-in to provide polymorphism between items stored in libraries (symbols, aliases and footprints).
Definition: lib_tree_item.h:40
int GetUnitFor(const wxDataViewItem &aSelection) const
Return the unit for the given item.
LIB_TREE_NODE::TYPE GetTypeFor(const wxDataViewItem &aSelection) const
Return node type for the given item.
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 FinishTreeInitialization()
A final-stage initialization to be called after the window hierarchy has been realized and the window...
void addColumnIfNecessary(const wxString &aHeader)
void PinLibrary(LIB_TREE_NODE *aTreeNode)
void OnSize(wxSizeEvent &aEvent)
LIB_TREE_NODE_LIB & DoAddLibraryNode(const wxString &aNodeName, const wxString &aDesc, bool pinned)
void SetPreselectNode(const LIB_ID &aLibId, int aUnit)
Set the symbol name to be selected if there are no search results.
static LIB_TREE_NODE * ToNode(wxDataViewItem aItem)
Convert wxDataViewItem -> #SYM_TREE_NODE.
LIB_ID GetAliasFor(const wxDataViewItem &aSelection) const
Return the alias for the given item.
void AttachTo(wxDataViewCtrl *aDataViewCtrl)
Attach to a wxDataViewCtrl and initialize it.
void 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 SetShownColumns(const std::vector< wxString > &aColumnNames)
Sets which columns are shown in the widget.
static wxDataViewItem ToItem(const LIB_TREE_NODE *aNode)
Convert #SYM_TREE_NODE -> wxDataViewItem.
void SetFilter(SYM_FILTER_TYPE aFilter)
Set the symbol filter type.
virtual bool isSymbolModel()=0
bool IsContainer(const wxDataViewItem &aItem) const override
Check whether an item can have children.
static const wxString GetPinningSymbol()
void Find(LIB_TREE_NODE &aNode, std::function< bool(const LIB_TREE_NODE *)> aFunc, LIB_TREE_NODE **aHighScore)
Find any results worth highlighting and expand them, according to given criteria The highest-scoring ...
void ShowUnits(bool aShow)
Whether or not to show units.
LIB_TREE_NODE * GetTreeNodeFor(const wxDataViewItem &aSelection) const
unsigned int GetChildren(const wxDataViewItem &aItem, wxDataViewItemArray &aChildren) const override
Populate a list of all the children of an item.
void SaveSettings()
Save the column widths to the config file.
@ NAME_COL
Library or library item name column.
std::map< unsigned, wxString > m_colIdxMap
wxDataViewColumn * doAddColumn(const wxString &aHeader, bool aTranslate=true)
LIB_TREE_MODEL_ADAPTER(EDA_BASE_FRAME *aParent, const wxString &aPinnedKey)
Create the adapter.
LIB_TREE_NODE * ShowPreselect()
Find and expand preselected node.
std::vector< wxDataViewColumn * > m_columns
std::vector< wxString > GetShownColumns() const
int GetItemCount() const
Return the number of symbols loaded in the tree.
std::vector< wxString > m_shownColumns
void GetValue(wxVariant &aVariant, const wxDataViewItem &aItem, unsigned int aCol) const override
Get the value of an item.
void UnpinLibrary(LIB_TREE_NODE *aTreeNode)
LIB_TREE_NODE * ShowSingleLibrary()
Find and expand a library if there is only one.
std::map< wxString, wxDataViewColumn * > m_colNameMap
bool HasContainerColumns(const wxDataViewItem &aItem) const override
Check whether a container has columns too.
wxDataViewItem GetParent(const wxDataViewItem &aItem) const override
Get the parent of an item.
std::vector< wxString > m_availableColumns
static unsigned int IntoArray(const LIB_TREE_NODE &aNode, wxDataViewItemArray &aChildren)
Convert SYM_TREE_NODE's children to wxDataViewItemArray.
LIB_TREE_NODE * ShowResults()
Find and expand successful search results.
wxDataViewItem FindItem(const LIB_ID &aLibId)
Returns tree item corresponding to part.
void UpdateSearchString(const wxString &aSearch, bool aState)
Set the search string provided by the user.
SYM_FILTER_TYPE
This enum allows a selective filtering of symbols to list.
Node type: library.
LIB_TREE_NODE_LIB_ID & AddItem(LIB_TREE_ITEM *aItem)
Construct a new alias node, add it to this library, and return it.
virtual void UpdateScore(EDA_COMBINED_MATCHER &aMatcher, const wxString &aLib) override
Update the score for this part.
LIB_TREE_NODE_LIB & AddLib(wxString const &aName, wxString const &aDesc)
Construct an empty library node, add it to the root, and return it.
Model class in the component selector Model-View-Adapter (mediated MVC) architecture.
void SortNodes()
Sort child nodes quickly and recursively (IntrinsicRanks must have been set).
enum TYPE m_Type
std::map< wxString, wxString > m_Fields
PTR_VECTOR m_Children
LIB_TREE_NODE * m_Parent
void ResetScore()
Initialize score to kLowestDefaultScore, recursively.
void AssignIntrinsicRanks(bool presorted=false)
Store intrinsic ranks on all children of this node.
void UnpinLibrary(const wxString &aLibrary, bool isSymbolLibrary)
Definition: project.cpp:177
void PinLibrary(const wxString &aLibrary, bool isSymbolLibrary)
Definition: project.cpp:156
Base window classes and related definitions.
Abstract pattern-matching tool and implementations.
@ CTX_LIBITEM
static const int kDataViewIndent
wxSize GetTextSize(const wxString &aSingleLine, wxWindow *aWindow)
Return the size of aSingleLine of text when it is rendered in aWindow using whatever font is currentl...
Definition: ui_common.cpp:70
wxString UnescapeString(const wxString &aSource)
std::vector< wxString > columns
Ordered list of visible columns in the tree.
Definition: app_settings.h:139
std::map< wxString, int > column_widths
Column widths, keyed by header name.
Definition: app_settings.h:140
Functions to provide common constants and other functions to assist in making a consistent UI.