8 changed files with 839 additions and 723 deletions
-
1eeschema/CMakeLists.txt
-
1eeschema/cmp_tree_model.cpp
-
411eeschema/cmp_tree_model_adapter.cpp
-
318eeschema/cmp_tree_model_adapter.h
-
442eeschema/cmp_tree_model_adapter_base.cpp
-
385eeschema/cmp_tree_model_adapter_base.h
-
2eeschema/widgets/component_tree.cpp
-
2eeschema/widgets/component_tree.h
@ -0,0 +1,442 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com> |
|||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org> |
|||
* Copyright (C) 2014-2017 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, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include <cmp_tree_model_adapter_base.h>
|
|||
|
|||
#include <eda_pattern_match.h>
|
|||
|
|||
#include <wx/progdlg.h>
|
|||
#include <wx/tokenzr.h>
|
|||
|
|||
|
|||
CMP_TREE_MODEL_ADAPTER_BASE::WIDTH_CACHE CMP_TREE_MODEL_ADAPTER_BASE::m_width_cache; |
|||
|
|||
|
|||
static const int kDataViewIndent = 20; |
|||
|
|||
|
|||
/**
|
|||
* Convert CMP_TREE_NODE -> wxDataViewItem |
|||
*/ |
|||
wxDataViewItem CMP_TREE_MODEL_ADAPTER_BASE::ToItem( CMP_TREE_NODE const* aNode ) |
|||
{ |
|||
return wxDataViewItem( const_cast<void*>( static_cast<void const*>( aNode ) ) ); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Convert wxDataViewItem -> CMP_TREE_NODE |
|||
*/ |
|||
CMP_TREE_NODE const* CMP_TREE_MODEL_ADAPTER_BASE::ToNode( wxDataViewItem aItem ) |
|||
{ |
|||
return static_cast<CMP_TREE_NODE const*>( aItem.GetID() ); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* Convert CMP_TREE_NODE's children to wxDataViewItemArray |
|||
*/ |
|||
unsigned int CMP_TREE_MODEL_ADAPTER_BASE::IntoArray( |
|||
CMP_TREE_NODE const& aNode, wxDataViewItemArray& aChildren ) |
|||
{ |
|||
unsigned int n = 0; |
|||
|
|||
for( auto const& child: aNode.Children ) |
|||
{ |
|||
if( child->Score > 0 ) |
|||
{ |
|||
aChildren.Add( ToItem( &*child ) ); |
|||
++n; |
|||
} |
|||
} |
|||
|
|||
return n; |
|||
} |
|||
|
|||
|
|||
CMP_TREE_MODEL_ADAPTER_BASE::CMP_TREE_MODEL_ADAPTER_BASE() |
|||
:m_filter( CMP_FILTER_NONE ), |
|||
m_show_units( true ), |
|||
m_preselect_unit( 0 ), |
|||
m_col_part( nullptr ), |
|||
m_col_desc( nullptr ), |
|||
m_widget( nullptr ) |
|||
{} |
|||
|
|||
|
|||
CMP_TREE_MODEL_ADAPTER_BASE::~CMP_TREE_MODEL_ADAPTER_BASE() |
|||
{} |
|||
|
|||
|
|||
void CMP_TREE_MODEL_ADAPTER_BASE::SetFilter( CMP_FILTER_TYPE aFilter ) |
|||
{ |
|||
m_filter = aFilter; |
|||
} |
|||
|
|||
|
|||
void CMP_TREE_MODEL_ADAPTER_BASE::ShowUnits( bool aShow ) |
|||
{ |
|||
m_show_units = aShow; |
|||
} |
|||
|
|||
|
|||
void CMP_TREE_MODEL_ADAPTER_BASE::SetPreselectNode( LIB_ID const& aLibId, int aUnit ) |
|||
{ |
|||
m_preselect_lib_id = aLibId; |
|||
m_preselect_unit = aUnit; |
|||
} |
|||
|
|||
|
|||
void CMP_TREE_MODEL_ADAPTER_BASE::AddLibrariesWithProgress( |
|||
const std::vector<wxString>& aNicknames, wxWindow* aParent ) |
|||
{ |
|||
auto* prg = new wxProgressDialog( |
|||
_( "Loading symbol libraries" ), |
|||
wxEmptyString, |
|||
aNicknames.size(), |
|||
aParent ); |
|||
|
|||
unsigned int ii = 0; |
|||
|
|||
for( auto nickname : aNicknames ) |
|||
{ |
|||
prg->Update( ii++, wxString::Format( _( "Loading library '%s'" ), nickname ) ); |
|||
AddLibrary( nickname ); |
|||
} |
|||
|
|||
prg->Destroy(); |
|||
} |
|||
|
|||
|
|||
void CMP_TREE_MODEL_ADAPTER_BASE::AddAliasList( |
|||
wxString const& aNodeName, |
|||
std::vector<LIB_ALIAS*> const& aAliasList ) |
|||
{ |
|||
auto& lib_node = m_tree.AddLib( aNodeName ); |
|||
|
|||
for( auto a: aAliasList ) |
|||
{ |
|||
lib_node.AddAlias( a ); |
|||
} |
|||
|
|||
lib_node.AssignIntrinsicRanks(); |
|||
m_tree.AssignIntrinsicRanks(); |
|||
} |
|||
|
|||
|
|||
void CMP_TREE_MODEL_ADAPTER_BASE::UpdateSearchString( wxString const& aSearch ) |
|||
{ |
|||
m_tree.ResetScore(); |
|||
|
|||
wxStringTokenizer tokenizer( aSearch ); |
|||
|
|||
while( tokenizer.HasMoreTokens() ) |
|||
{ |
|||
const wxString term = tokenizer.GetNextToken().Lower(); |
|||
EDA_COMBINED_MATCHER matcher( term ); |
|||
|
|||
m_tree.UpdateScore( matcher ); |
|||
} |
|||
|
|||
m_tree.SortNodes(); |
|||
Cleared(); |
|||
AttachTo( m_widget ); |
|||
|
|||
ShowResults() || ShowPreselect() || ShowSingleLibrary(); |
|||
} |
|||
|
|||
|
|||
void CMP_TREE_MODEL_ADAPTER_BASE::AttachTo( wxDataViewCtrl* aDataViewCtrl ) |
|||
{ |
|||
m_widget = aDataViewCtrl; |
|||
aDataViewCtrl->Freeze(); |
|||
aDataViewCtrl->SetIndent( kDataViewIndent ); |
|||
aDataViewCtrl->AssociateModel( this ); |
|||
aDataViewCtrl->ClearColumns(); |
|||
|
|||
wxString part_head = _( "Part" ); |
|||
wxString desc_head = _( "Desc" ); |
|||
|
|||
m_col_part = aDataViewCtrl->AppendTextColumn( part_head, 0, wxDATAVIEW_CELL_INERT, |
|||
ColWidth( m_tree, 0, part_head ) ); |
|||
m_col_desc = aDataViewCtrl->AppendTextColumn( desc_head, 1, wxDATAVIEW_CELL_INERT, |
|||
ColWidth( m_tree, 1, desc_head ) ); |
|||
aDataViewCtrl->Thaw(); |
|||
} |
|||
|
|||
|
|||
LIB_ID CMP_TREE_MODEL_ADAPTER_BASE::GetAliasFor( const wxDataViewItem& aSelection ) const |
|||
{ |
|||
auto node = ToNode( aSelection ); |
|||
|
|||
LIB_ID emptyId; |
|||
|
|||
if( !node ) |
|||
return emptyId; |
|||
|
|||
return node->LibId; |
|||
} |
|||
|
|||
|
|||
int CMP_TREE_MODEL_ADAPTER_BASE::GetUnitFor( const wxDataViewItem& aSelection ) const |
|||
{ |
|||
auto node = ToNode( aSelection ); |
|||
return node ? node->Unit : 0; |
|||
} |
|||
|
|||
|
|||
CMP_TREE_NODE::TYPE CMP_TREE_MODEL_ADAPTER_BASE::GetTypeFor( const wxDataViewItem& aSelection ) const |
|||
{ |
|||
auto node = ToNode( aSelection ); |
|||
return node ? node->Type : CMP_TREE_NODE::INVALID; |
|||
} |
|||
|
|||
|
|||
int CMP_TREE_MODEL_ADAPTER_BASE::GetComponentsCount() const |
|||
{ |
|||
int n = 0; |
|||
|
|||
for( auto& lib: m_tree.Children ) |
|||
{ |
|||
for( auto& alias: lib->Children ) |
|||
{ |
|||
(void) alias; |
|||
++n; |
|||
} |
|||
} |
|||
|
|||
return n; |
|||
} |
|||
|
|||
|
|||
bool CMP_TREE_MODEL_ADAPTER_BASE::HasContainerColumns( wxDataViewItem const& aItem ) const |
|||
{ |
|||
return IsContainer( aItem ); |
|||
} |
|||
|
|||
|
|||
bool CMP_TREE_MODEL_ADAPTER_BASE::IsContainer( wxDataViewItem const& aItem ) const |
|||
{ |
|||
auto node = ToNode( aItem ); |
|||
return node ? node->Children.size() : true; |
|||
} |
|||
|
|||
|
|||
wxDataViewItem CMP_TREE_MODEL_ADAPTER_BASE::GetParent( wxDataViewItem const& aItem ) const |
|||
{ |
|||
auto node = ToNode( aItem ); |
|||
auto parent = node ? node->Parent : nullptr; |
|||
|
|||
// wxDataViewModel has no root node, but rather top-level elements have
|
|||
// an invalid (null) parent.
|
|||
if( !node || !parent || parent->Type == CMP_TREE_NODE::TYPE::ROOT ) |
|||
{ |
|||
return ToItem( nullptr ); |
|||
} |
|||
else |
|||
{ |
|||
return ToItem( parent ); |
|||
} |
|||
} |
|||
|
|||
|
|||
unsigned int CMP_TREE_MODEL_ADAPTER_BASE::GetChildren( |
|||
wxDataViewItem const& aItem, |
|||
wxDataViewItemArray& aChildren ) const |
|||
{ |
|||
auto node = ( aItem.IsOk() ? ToNode( aItem ) : &m_tree ); |
|||
|
|||
if( node->Type != CMP_TREE_NODE::TYPE::LIBID || m_show_units ) |
|||
return IntoArray( *node, aChildren ); |
|||
else |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
void CMP_TREE_MODEL_ADAPTER_BASE::GetValue( |
|||
wxVariant& aVariant, |
|||
wxDataViewItem const& aItem, |
|||
unsigned int aCol ) const |
|||
{ |
|||
auto node = ToNode( aItem ); |
|||
wxASSERT( node ); |
|||
|
|||
switch( aCol ) |
|||
{ |
|||
case 0: |
|||
aVariant = node->Name; |
|||
break; |
|||
case 1: |
|||
aVariant = node->Desc; |
|||
break; |
|||
default: |
|||
wxFAIL_MSG( "Invalid column ID!" ); |
|||
} |
|||
} |
|||
|
|||
|
|||
bool CMP_TREE_MODEL_ADAPTER_BASE::GetAttr( |
|||
wxDataViewItem const& aItem, |
|||
unsigned int aCol, |
|||
wxDataViewItemAttr& aAttr ) const |
|||
{ |
|||
auto node = ToNode( aItem ); |
|||
wxASSERT( node ); |
|||
|
|||
if( node->Type != CMP_TREE_NODE::LIBID ) |
|||
{ |
|||
// Currently only aliases are formatted at all
|
|||
return false; |
|||
} |
|||
|
|||
if( !node->IsRoot && aCol == 0 ) |
|||
{ |
|||
// Names of non-root aliases are italicized
|
|||
aAttr.SetItalic( true ); |
|||
return true; |
|||
} |
|||
else |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
int CMP_TREE_MODEL_ADAPTER_BASE::ColWidth( CMP_TREE_NODE& aTree, int aCol, wxString const& aHeading ) |
|||
{ |
|||
const int indent = aCol ? 0 : kDataViewIndent; |
|||
|
|||
int min_width = WidthFor( aHeading, aCol ); |
|||
int width = std::max( aTree.Score > 0 ? WidthFor( aTree, aCol ) : 0, min_width ); |
|||
|
|||
if( aTree.Score > 0 ) |
|||
{ |
|||
for( auto& node: aTree.Children ) |
|||
{ |
|||
width = std::max( width, ColWidth( *node, aCol, aHeading ) + indent ); |
|||
} |
|||
} |
|||
|
|||
return width; |
|||
} |
|||
|
|||
|
|||
int CMP_TREE_MODEL_ADAPTER_BASE::WidthFor( CMP_TREE_NODE& aNode, int aCol ) |
|||
{ |
|||
auto result = m_width_cache.find( aNode.Name ); |
|||
|
|||
if( result != m_width_cache.end() ) |
|||
{ |
|||
return result->second[aCol]; |
|||
} |
|||
else |
|||
{ |
|||
int wname = m_widget->GetTextExtent( aNode.Name ).x + kDataViewIndent; |
|||
int wdesc = m_widget->GetTextExtent( aNode.Desc ).x; |
|||
|
|||
auto& val = m_width_cache[aNode.Name]; |
|||
val.push_back( wname ); |
|||
val.push_back( wdesc ); |
|||
return val[aCol]; |
|||
} |
|||
} |
|||
|
|||
|
|||
int CMP_TREE_MODEL_ADAPTER_BASE::WidthFor( wxString const& aHeading, int aCol ) |
|||
{ |
|||
static std::vector<int> widths; |
|||
|
|||
for( int i = (int) widths.size(); i <= aCol; ++i ) |
|||
{ |
|||
widths.push_back( 0 ); |
|||
} |
|||
|
|||
if( widths[aCol] == 0 ) |
|||
{ |
|||
widths[aCol] = m_widget->GetTextExtent( aHeading ).x; |
|||
} |
|||
|
|||
return widths[aCol]; |
|||
} |
|||
|
|||
|
|||
bool CMP_TREE_MODEL_ADAPTER_BASE::FindAndExpand( |
|||
CMP_TREE_NODE& aNode, |
|||
std::function<bool( CMP_TREE_NODE const* )> aFunc ) |
|||
{ |
|||
for( auto& node: aNode.Children ) |
|||
{ |
|||
if( aFunc( &*node ) ) |
|||
{ |
|||
auto item = wxDataViewItem( |
|||
const_cast<void*>( static_cast<void const*>( &*node ) ) ); |
|||
m_widget->ExpandAncestors( item ); |
|||
m_widget->EnsureVisible( item ); |
|||
m_widget->Select( item ); |
|||
return true; |
|||
} |
|||
else if( FindAndExpand( *node, aFunc ) ) |
|||
{ |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
|
|||
bool CMP_TREE_MODEL_ADAPTER_BASE::ShowResults() |
|||
{ |
|||
return FindAndExpand( m_tree, |
|||
[]( CMP_TREE_NODE const* n ) |
|||
{ |
|||
return n->Type == CMP_TREE_NODE::TYPE::LIBID && n->Score > 1; |
|||
} ); |
|||
} |
|||
|
|||
|
|||
bool CMP_TREE_MODEL_ADAPTER_BASE::ShowPreselect() |
|||
{ |
|||
if( !m_preselect_lib_id.IsValid() ) |
|||
return false; |
|||
|
|||
return FindAndExpand( m_tree, |
|||
[&]( CMP_TREE_NODE const* n ) |
|||
{ |
|||
if( n->Type == CMP_TREE_NODE::LIBID && ( n->Children.empty() || !m_preselect_unit ) ) |
|||
return m_preselect_lib_id == n->LibId; |
|||
else if( n->Type == CMP_TREE_NODE::UNIT && m_preselect_unit ) |
|||
return m_preselect_lib_id == n->Parent->LibId && m_preselect_unit == n->Unit; |
|||
else |
|||
return false; |
|||
} ); |
|||
} |
|||
|
|||
|
|||
bool CMP_TREE_MODEL_ADAPTER_BASE::ShowSingleLibrary() |
|||
{ |
|||
return FindAndExpand( m_tree, |
|||
[]( CMP_TREE_NODE const* n ) |
|||
{ |
|||
return n->Type == CMP_TREE_NODE::TYPE::LIBID && |
|||
n->Parent->Parent->Children.size() == 1; |
|||
} ); |
|||
} |
@ -0,0 +1,385 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com> |
|||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org> |
|||
* Copyright (C) 2014-2017 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, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#ifndef _CMP_TREE_MODEL_ADAPTER_BASE_H |
|||
#define _CMP_TREE_MODEL_ADAPTER_BASE_H |
|||
|
|||
#include <lib_id.h> |
|||
|
|||
#include <cmp_tree_model.h> |
|||
|
|||
#include <wx/hashmap.h> |
|||
#include <wx/dataview.h> |
|||
#include <vector> |
|||
#include <functional> |
|||
|
|||
|
|||
/** |
|||
* Adapter class in the component selector Model-View-Adapter (mediated MVC) |
|||
* architecture. The other pieces are in: |
|||
* |
|||
* - Model: CMP_TREE_NODE and descendants in eeschema/cmp_tree_model.h |
|||
* - View: |
|||
* - DIALOG_CHOOSE_COMPONENT in eeschema/dialogs/dialog_choose_component.h |
|||
* - wxDataViewCtrl |
|||
* |
|||
* This adapter presents the interface specified by wxDataViewModel to the |
|||
* wxDataViewCtrl: |
|||
* |
|||
* +---+ +------------------+ |
|||
* +---+ Generates | A | | VIEW | |
|||
* | M | from libs | D | wxDataViewModel |------------------| |
|||
* | O | <---------- | A | <------------------> | wxDataViewCtrl | |
|||
* | D | | P | |------------------| |
|||
* | E | <---------> | T | <------------------- | wxTextCtrl | |
|||
* | L | UpdateScore | E | UpdateSearchString() |------------------| |
|||
* +---+ | R | | | |
|||
* +---+ +------------------+ |
|||
* |
|||
* Because this adapter is a wxDataViewModel, it is reference-counted by |
|||
* wxObject. To ensure this interface is used correctly, the constructor |
|||
* is private; CMP_TREE_MODEL_ADAPTER should be created by the static |
|||
* factory method CMP_TREE_MODEL_ADAPTER::Create(). |
|||
* |
|||
* Quick summary of methods used to drive this class: |
|||
* |
|||
* - `SetFilter()` - set whether the view is restricted to power parts |
|||
* - `ShowUnits()` - set whether units are displayed |
|||
* - `SetPreselectNode()` - set a node to highlight when not searching |
|||
* - `AddLibrary()` - populate the model with all aliases in a library |
|||
* - `AddAliasList()` - populate the model with a specific list of aliases |
|||
* |
|||
* Quick summary of methods used by the View: |
|||
* |
|||
* - `UpdateSearchString()` - pass in the user's search text |
|||
* - `AttachTo()` - pass in the wxDataViewCtrl |
|||
* - `GetAliasFor()` - get the LIB_ALIAS* for a selected item |
|||
* - `GetUnitFor()` - get the unit for a selected item |
|||
* - `GetComponentsCount()` - count the aliases loaded |
|||
* |
|||
* Methods implemented as part of wxDataViewModel: |
|||
* |
|||
* - `HasContainerColumns()` - whether a parent item has more than one column |
|||
* - `IsContainer()` - whether an item is a parent |
|||
* - `GetParent()` - return the parent of an item, or invalid if root |
|||
* - `GetChildren()` - get the children of an item |
|||
* - `GetColumnCount()` - get the number of columns in the view |
|||
* - `GetColumnType()` - get the data type shown in each column |
|||
* - `GetValue()` - get the data shown in a cell |
|||
* - `SetValue()` - edit the data in a cell (does nothing) |
|||
* - `GetAttr()` - get any per-item formatting |
|||
* - `Compare()` - compare two rows, for sorting |
|||
* - `HasDefaultCompare()` - whether sorted by default |
|||
*/ |
|||
class CMP_TREE_MODEL_ADAPTER_BASE: public wxDataViewModel |
|||
{ |
|||
public: |
|||
|
|||
/** |
|||
* Reference-counting container for a pointer to CMP_TREE_MODEL_ADAPTER_BASE. |
|||
*/ |
|||
typedef wxObjectDataPtr<CMP_TREE_MODEL_ADAPTER_BASE> PTR; |
|||
|
|||
/** |
|||
* Destructor. Do NOT delete this class manually; it is reference-counted |
|||
* by wxObject. |
|||
*/ |
|||
~CMP_TREE_MODEL_ADAPTER_BASE(); |
|||
|
|||
/** |
|||
* This enum allows a selective filtering of components to list |
|||
*/ |
|||
enum CMP_FILTER_TYPE |
|||
{ |
|||
CMP_FILTER_NONE, ///< no filtering |
|||
CMP_FILTER_POWER, ///< list components flagged PWR |
|||
}; |
|||
|
|||
/** |
|||
* Set the component filter type. Must be set before adding libraries |
|||
* |
|||
* @param aFilter if CMP_FILTER_POWER, only power parts are loaded |
|||
*/ |
|||
void SetFilter( CMP_FILTER_TYPE aFilter ); |
|||
|
|||
/** |
|||
* Return the active filter. |
|||
*/ |
|||
CMP_FILTER_TYPE GetFilter() const { return m_filter; } |
|||
|
|||
/** |
|||
* Whether or not to show units. May be set at any time; updates at the next |
|||
* UpdateSearchString() |
|||
* |
|||
* @param aShow if true, units are displayed |
|||
*/ |
|||
void ShowUnits( bool aShow ); |
|||
|
|||
/** |
|||
* Set the component name to be selected if there are no search results. |
|||
* May be set at any time; updates at the next UpdateSearchString(). |
|||
* |
|||
* @param aLibId symbol #LIB_ID to be selected |
|||
* @param aUnit unit to be selected, if > 0 (0 selects the alias itself) |
|||
*/ |
|||
void SetPreselectNode( LIB_ID const& aLibId, int aUnit ); |
|||
|
|||
/** |
|||
* Add all the components and their aliases in this library. To be called |
|||
* in the setup phase. |
|||
* |
|||
* @param aLibNickname reference to a symbol library nickname |
|||
*/ |
|||
virtual void AddLibrary( wxString const& aLibNickname ) = 0; |
|||
|
|||
/** |
|||
* Add all the libraries in a SYMBOL_LIB_TABLE to the model, |
|||
* displaying a progress dialog attached to the parent frame |
|||
* |
|||
* @param aNicknames is the list of library nicknames |
|||
* @param aParent is the parent window to display the progress dialog |
|||
*/ |
|||
void AddLibrariesWithProgress( const std::vector<wxString>& aNicknames, |
|||
wxWindow* aParent ); |
|||
|
|||
/** |
|||
* Add the given list of components, by name. To be called in the setup |
|||
* phase. |
|||
* |
|||
* @param aNodeName the parent node the components will appear under |
|||
* @param aAliasNameList list of alias names |
|||
*/ |
|||
virtual void AddAliasList( |
|||
wxString const& aNodeName, |
|||
wxArrayString const& aAliasNameList ) = 0; |
|||
|
|||
/** |
|||
* Add the given list of components by alias. To be called in the setup |
|||
* phase. |
|||
* |
|||
* @param aNodeName the parent node the components will appear under |
|||
* @param aAliasList list of aliases |
|||
*/ |
|||
void AddAliasList( |
|||
wxString const& aNodeName, |
|||
std::vector<LIB_ALIAS*> const& aAliasList ); |
|||
|
|||
/** |
|||
* Set the search string provided by the user. |
|||
* |
|||
* @param aSearch full, unprocessed search text |
|||
*/ |
|||
void UpdateSearchString( wxString const& aSearch ); |
|||
|
|||
/** |
|||
* Attach to a wxDataViewCtrl and initialize it. This will set up columns |
|||
* and associate the model via the adapter. |
|||
* |
|||
* @param aDataViewCtrl the view component in the dialog |
|||
*/ |
|||
void AttachTo( wxDataViewCtrl* aDataViewCtrl ); |
|||
|
|||
/** |
|||
* Return the alias for the given item. |
|||
* |
|||
* @param aSelection item from the wxDataViewCtrl |
|||
* (see wxDataViewCtrl::GetSelection()) |
|||
* |
|||
* @return alias, or nullptr if none is selected |
|||
*/ |
|||
LIB_ID GetAliasFor( const wxDataViewItem& aSelection ) const; |
|||
|
|||
/** |
|||
* Return the unit for the given item. |
|||
* |
|||
* @param aSelection item from the wxDataViewCtrl |
|||
* (see wxDataViewCtrl::GetSelection()) |
|||
* |
|||
* @return Unit, or zero if the alias itself is selected. Return valid is |
|||
* invalid if GetAliasFor() returns nullptr. |
|||
*/ |
|||
int GetUnitFor( const wxDataViewItem& aSelection ) const; |
|||
|
|||
/** |
|||
* Return node type for the given item. |
|||
* |
|||
* @param aSelection item from the wxDataViewCtrl |
|||
* (see wxDataViewCtrl::GetSelection()) |
|||
* |
|||
* @return Type of the selected node, might be INVALID. |
|||
*/ |
|||
CMP_TREE_NODE::TYPE GetTypeFor( const wxDataViewItem& aSelection ) const; |
|||
|
|||
/** |
|||
* Return the number of components loaded in the tree. |
|||
*/ |
|||
int GetComponentsCount() const; |
|||
|
|||
protected: |
|||
static wxDataViewItem ToItem( CMP_TREE_NODE const* aNode ); |
|||
static CMP_TREE_NODE const* ToNode( wxDataViewItem aItem ); |
|||
static unsigned int IntoArray( CMP_TREE_NODE const& aNode, wxDataViewItemArray& aChildren ); |
|||
|
|||
CMP_TREE_NODE_ROOT m_tree; |
|||
|
|||
/** |
|||
* Constructor |
|||
*/ |
|||
CMP_TREE_MODEL_ADAPTER_BASE(); |
|||
|
|||
/** |
|||
* Check whether a container has columns too |
|||
*/ |
|||
virtual bool HasContainerColumns( wxDataViewItem const& aItem ) const override; |
|||
|
|||
/** |
|||
* Check whether an item can have children. |
|||
*/ |
|||
virtual bool IsContainer( wxDataViewItem const& aItem ) const override; |
|||
|
|||
/** |
|||
* Get the parent of an item. |
|||
* |
|||
* @param aItem item to get the parent of |
|||
* @return parent of aItem, or an invalid wxDataViewItem if parent is root |
|||
*/ |
|||
virtual wxDataViewItem GetParent( wxDataViewItem const& aItem ) const override; |
|||
|
|||
/** |
|||
* Populate a list of all the children of an item |
|||
* |
|||
* @return number of children |
|||
*/ |
|||
virtual unsigned int GetChildren( |
|||
wxDataViewItem const& aItem, |
|||
wxDataViewItemArray& aChildren ) const override; |
|||
|
|||
/** |
|||
* Return the number of columns in the model |
|||
*/ |
|||
virtual unsigned int GetColumnCount() const override { return 2; } |
|||
|
|||
/** |
|||
* Return the type of data stored in the column |
|||
* |
|||
* @return type of data as indicated by wxVariant::GetType() |
|||
*/ |
|||
virtual wxString GetColumnType( unsigned int aCol ) const override { return "string"; } |
|||
|
|||
/** |
|||
* Get the value of an item. |
|||
* |
|||
* @param aVariant wxVariant to receive the data |
|||
* @param aItem item whose data will be placed into aVariant |
|||
* @param aCol column number of the data |
|||
*/ |
|||
virtual void GetValue( |
|||
wxVariant& aVariant, |
|||
wxDataViewItem const& aItem, |
|||
unsigned int aCol ) const override; |
|||
|
|||
/** |
|||
* Set the value of an item. Does nothing - this model doesn't support |
|||
* editing. |
|||
*/ |
|||
virtual bool SetValue( |
|||
wxVariant const& aVariant, |
|||
wxDataViewItem const& aItem, |
|||
unsigned int aCol ) override { return false; } |
|||
|
|||
/** |
|||
* Get any formatting for an item. |
|||
* |
|||
* @param aItem item to get formatting for |
|||
* @param aCol column number of interest |
|||
* @param aAttr receiver for attributes |
|||
* @return true iff the item has non-default attributes |
|||
*/ |
|||
virtual bool GetAttr( |
|||
wxDataViewItem const& aItem, |
|||
unsigned int aCol, |
|||
wxDataViewItemAttr& aAttr ) const override; |
|||
|
|||
private: |
|||
CMP_FILTER_TYPE m_filter; |
|||
bool m_show_units; |
|||
LIB_ID m_preselect_lib_id; |
|||
int m_preselect_unit; |
|||
|
|||
wxDataViewColumn* m_col_part; |
|||
wxDataViewColumn* m_col_desc; |
|||
wxDataViewCtrl* m_widget; |
|||
|
|||
WX_DECLARE_STRING_HASH_MAP( std::vector<int>, WIDTH_CACHE ); |
|||
|
|||
static WIDTH_CACHE m_width_cache; |
|||
|
|||
/** |
|||
* Compute the width required for the given column of a node and its |
|||
* children. |
|||
* |
|||
* @param aTree - root node of the tree |
|||
* @param aCol - column number |
|||
* @param aHeading - heading text, to set the minimum width |
|||
*/ |
|||
int ColWidth( CMP_TREE_NODE& aTree, int aCol, wxString const& aHeading ); |
|||
|
|||
/** |
|||
* Return the width required to display a single row's aCol text. |
|||
* This is cached for efficiency as it's very slow on some platforms |
|||
* (*cough* macOS) |
|||
*/ |
|||
int WidthFor( CMP_TREE_NODE& aNode, int aCol ); |
|||
|
|||
/** |
|||
* Return the width required to display a column's heading. This is |
|||
* cached by column number for the same reason as the width per cell. |
|||
*/ |
|||
int WidthFor( wxString const& aHeading, int aCol ); |
|||
|
|||
/** |
|||
* Find any results worth highlighting and expand them, according to given |
|||
* criteria (f(CMP_TREE_NODE const*) -> bool) |
|||
* |
|||
* @return whether a node was expanded |
|||
*/ |
|||
bool FindAndExpand( |
|||
CMP_TREE_NODE& aNode, |
|||
std::function<bool( CMP_TREE_NODE const* )> aFunc ); |
|||
|
|||
/** |
|||
* Find and expand successful search results |
|||
*/ |
|||
bool ShowResults(); |
|||
|
|||
/** |
|||
* Find and expand preselected node |
|||
*/ |
|||
bool ShowPreselect(); |
|||
|
|||
/** |
|||
* Find and expand a library if there is only one |
|||
*/ |
|||
bool ShowSingleLibrary(); |
|||
}; |
|||
|
|||
#endif // _CMP_TREE_MODEL_ADAPTER_BASE_H |
|||
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue