From 0d190639f137936286c428731b9b371d7b907227 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Sat, 28 Oct 2017 20:28:14 +0200 Subject: [PATCH] Extracted CMP_TREE_MODEL_ADAPTER_BASE class --- eeschema/CMakeLists.txt | 1 + eeschema/cmp_tree_model.cpp | 1 - eeschema/cmp_tree_model_adapter.cpp | 411 +-------------------- eeschema/cmp_tree_model_adapter.h | 318 +--------------- eeschema/cmp_tree_model_adapter_base.cpp | 442 +++++++++++++++++++++++ eeschema/cmp_tree_model_adapter_base.h | 385 ++++++++++++++++++++ eeschema/widgets/component_tree.cpp | 2 +- eeschema/widgets/component_tree.h | 2 +- 8 files changed, 839 insertions(+), 723 deletions(-) create mode 100644 eeschema/cmp_tree_model_adapter_base.cpp create mode 100644 eeschema/cmp_tree_model_adapter_base.h diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 1a52e7b0d3..90ca44f013 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -124,6 +124,7 @@ set( EESCHEMA_SRCS getpart.cpp cmp_tree_model.cpp cmp_tree_model_adapter.cpp + cmp_tree_model_adapter_base.cpp generate_alias_info.cpp hierarch.cpp highlight_connection.cpp diff --git a/eeschema/cmp_tree_model.cpp b/eeschema/cmp_tree_model.cpp index 20c6f70c1b..994e4aa691 100644 --- a/eeschema/cmp_tree_model.cpp +++ b/eeschema/cmp_tree_model.cpp @@ -133,7 +133,6 @@ CMP_TREE_NODE_LIB_ID::CMP_TREE_NODE_LIB_ID( CMP_TREE_NODE* aParent, LIB_ALIAS* a Type = LIBID; Parent = aParent; - Type = ALIAS; Name = aAlias->GetName(); Desc = aAlias->GetDescription(); diff --git a/eeschema/cmp_tree_model_adapter.cpp b/eeschema/cmp_tree_model_adapter.cpp index e70a4c0c81..01c973564c 100644 --- a/eeschema/cmp_tree_model_adapter.cpp +++ b/eeschema/cmp_tree_model_adapter.cpp @@ -26,51 +26,7 @@ #include #include -CMP_TREE_MODEL_ADAPTER::WIDTH_CACHE CMP_TREE_MODEL_ADAPTER::m_width_cache; - - -static const int kDataViewIndent = 20; - - -/** - * Convert CMP_TREE_NODE -> wxDataViewItem - */ -static wxDataViewItem ToItem( CMP_TREE_NODE const* aNode ) -{ - return wxDataViewItem( const_cast( static_cast( aNode ) ) ); -} - - -/** - * Convert wxDataViewItem -> CMP_TREE_NODE - */ -static CMP_TREE_NODE const* ToNode( wxDataViewItem aItem ) -{ - return static_cast( aItem.GetID() ); -} - - -/** - * Convert CMP_TREE_NODE's children to wxDataViewItemArray - */ -static unsigned int 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::PTR CMP_TREE_MODEL_ADAPTER::Create( SYMBOL_LIB_TABLE* aLibs ) +CMP_TREE_MODEL_ADAPTER_BASE::PTR CMP_TREE_MODEL_ADAPTER::Create( SYMBOL_LIB_TABLE* aLibs ) { auto adapter = new CMP_TREE_MODEL_ADAPTER( aLibs ); auto container = CMP_TREE_MODEL_ADAPTER::PTR( adapter ); @@ -79,13 +35,7 @@ CMP_TREE_MODEL_ADAPTER::PTR CMP_TREE_MODEL_ADAPTER::Create( SYMBOL_LIB_TABLE* aL CMP_TREE_MODEL_ADAPTER::CMP_TREE_MODEL_ADAPTER( SYMBOL_LIB_TABLE* aLibs ) - :m_filter( CMP_FILTER_NONE ), - m_show_units( true ), - m_libs( aLibs ), - m_preselect_unit( 0 ), - m_col_part( nullptr ), - m_col_desc( nullptr ), - m_widget( nullptr ) + : m_libs( aLibs ) {} @@ -93,28 +43,9 @@ CMP_TREE_MODEL_ADAPTER::~CMP_TREE_MODEL_ADAPTER() {} -void CMP_TREE_MODEL_ADAPTER::SetFilter( CMP_FILTER_TYPE aFilter ) -{ - m_filter = aFilter; -} - - -void CMP_TREE_MODEL_ADAPTER::ShowUnits( bool aShow ) -{ - m_show_units = aShow; -} - - -void CMP_TREE_MODEL_ADAPTER::SetPreselectNode( LIB_ID const& aLibId, int aUnit ) -{ - m_preselect_lib_id = aLibId; - m_preselect_unit = aUnit; -} - - void CMP_TREE_MODEL_ADAPTER::AddLibrary( wxString const& aLibNickname ) { - bool onlyPowerSymbols = ( m_filter == CMP_FILTER_POWER ); + bool onlyPowerSymbols = ( GetFilter() == CMP_FILTER_POWER ); wxArrayString aliases; @@ -135,26 +66,6 @@ void CMP_TREE_MODEL_ADAPTER::AddLibrary( wxString const& aLibNickname ) } -void CMP_TREE_MODEL_ADAPTER::AddLibrariesWithProgress( const std::vector& aNicknames, EDA_DRAW_FRAME* 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::AddAliasList( wxString const& aNodeName, wxArrayString const& aAliasNameList ) @@ -182,319 +93,3 @@ void CMP_TREE_MODEL_ADAPTER::AddAliasList( AddAliasList( aNodeName, alias_list ); } - - -void CMP_TREE_MODEL_ADAPTER::AddAliasList( - wxString const& aNodeName, - std::vector 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::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::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::GetAliasFor( const wxDataViewItem& aSelection ) const -{ - auto node = ToNode( aSelection ); - - LIB_ID emptyId; - - if( !node ) - return emptyId; - - return node->LibId; -} - - -int CMP_TREE_MODEL_ADAPTER::GetUnitFor( const wxDataViewItem& aSelection ) const -{ - auto node = ToNode( aSelection ); - return node ? node->Unit : 0; -} - - -CMP_TREE_NODE::TYPE CMP_TREE_MODEL_ADAPTER::GetTypeFor( const wxDataViewItem& aSelection ) const -{ - auto node = ToNode( aSelection ); - return node ? node->Type : CMP_TREE_NODE::INVALID; -} - - -int CMP_TREE_MODEL_ADAPTER::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::HasContainerColumns( wxDataViewItem const& aItem ) const -{ - return IsContainer( aItem ); -} - - -bool CMP_TREE_MODEL_ADAPTER::IsContainer( wxDataViewItem const& aItem ) const -{ - auto node = ToNode( aItem ); - return node ? node->Children.size() : true; -} - - -wxDataViewItem CMP_TREE_MODEL_ADAPTER::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::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::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::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::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::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::WidthFor( wxString const& aHeading, int aCol ) -{ - static std::vector 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::FindAndExpand( - CMP_TREE_NODE& aNode, - std::function aFunc ) -{ - for( auto& node: aNode.Children ) - { - if( aFunc( &*node ) ) - { - auto item = wxDataViewItem( - const_cast( static_cast( &*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::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::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::ShowSingleLibrary() -{ - return FindAndExpand( m_tree, - []( CMP_TREE_NODE const* n ) - { - return n->Type == CMP_TREE_NODE::TYPE::LIBID && - n->Parent->Parent->Children.size() == 1; - } ); -} diff --git a/eeschema/cmp_tree_model_adapter.h b/eeschema/cmp_tree_model_adapter.h index c878ae72f9..17c033370c 100644 --- a/eeschema/cmp_tree_model_adapter.h +++ b/eeschema/cmp_tree_model_adapter.h @@ -22,84 +22,18 @@ #ifndef _CMP_TREE_MODEL_ADAPTER_H #define _CMP_TREE_MODEL_ADAPTER_H -#include - -#include -#include - -#include -#include -#include -#include +#include class SYMBOL_LIB_TABLE; - -/** - * 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: public wxDataViewModel +class CMP_TREE_MODEL_ADAPTER: public CMP_TREE_MODEL_ADAPTER_BASE { public: /** * Reference-counting container for a pointer to CMP_TREE_MODEL_ADAPTER. */ - typedef wxObjectDataPtr PTR; + //typedef wxObjectDataPtr PTR; /** * Destructor. Do NOT delete this class manually; it is reference-counted @@ -115,57 +49,13 @@ public: */ static PTR Create( SYMBOL_LIB_TABLE* aLibs ); - /** - * 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 ); - - /** - * 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 */ - void AddLibrary( wxString const& aLibNickname ); - - - /** - * 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& aNicknames, EDA_DRAW_FRAME* aParent ); - + void AddLibrary( wxString const& aLibNickname ) override; /** * Add the given list of components, by name. To be called in the setup @@ -176,70 +66,9 @@ public: */ void AddAliasList( wxString const& aNodeName, - wxArrayString const& aAliasNameList ); - - /** - * 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 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; + wxArrayString const& aAliasNameList ) override; + using CMP_TREE_MODEL_ADAPTER_BASE::AddAliasList; protected: /** @@ -247,143 +76,8 @@ protected: */ CMP_TREE_MODEL_ADAPTER( SYMBOL_LIB_TABLE* aLibs ); - /** - * 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; SYMBOL_LIB_TABLE* m_libs; - LIB_ID m_preselect_lib_id; - int m_preselect_unit; - - CMP_TREE_NODE_ROOT m_tree; - - wxDataViewColumn* m_col_part; - wxDataViewColumn* m_col_desc; - wxDataViewCtrl* m_widget; - - WX_DECLARE_STRING_HASH_MAP( std::vector, 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 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_H diff --git a/eeschema/cmp_tree_model_adapter_base.cpp b/eeschema/cmp_tree_model_adapter_base.cpp new file mode 100644 index 0000000000..873f56e31f --- /dev/null +++ b/eeschema/cmp_tree_model_adapter_base.cpp @@ -0,0 +1,442 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2017 Chris Pavlina + * Copyright (C) 2014 Henner Zeller + * 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 . + */ + +#include + +#include + +#include +#include + + +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( static_cast( aNode ) ) ); +} + + +/** + * Convert wxDataViewItem -> CMP_TREE_NODE + */ +CMP_TREE_NODE const* CMP_TREE_MODEL_ADAPTER_BASE::ToNode( wxDataViewItem aItem ) +{ + return static_cast( 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& 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 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 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 aFunc ) +{ + for( auto& node: aNode.Children ) + { + if( aFunc( &*node ) ) + { + auto item = wxDataViewItem( + const_cast( static_cast( &*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; + } ); +} diff --git a/eeschema/cmp_tree_model_adapter_base.h b/eeschema/cmp_tree_model_adapter_base.h new file mode 100644 index 0000000000..556a58b499 --- /dev/null +++ b/eeschema/cmp_tree_model_adapter_base.h @@ -0,0 +1,385 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2017 Chris Pavlina + * Copyright (C) 2014 Henner Zeller + * 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 . + */ + +#ifndef _CMP_TREE_MODEL_ADAPTER_BASE_H +#define _CMP_TREE_MODEL_ADAPTER_BASE_H + +#include + +#include + +#include +#include +#include +#include + + +/** + * 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 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& 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 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, 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 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 + diff --git a/eeschema/widgets/component_tree.cpp b/eeschema/widgets/component_tree.cpp index 7a286a732e..c240bdb2ac 100644 --- a/eeschema/widgets/component_tree.cpp +++ b/eeschema/widgets/component_tree.cpp @@ -36,7 +36,7 @@ COMPONENT_TREE::COMPONENT_TREE( wxWindow* aParent, SYMBOL_LIB_TABLE* aSymLibTable, - CMP_TREE_MODEL_ADAPTER::PTR& aAdapter, WIDGETS aWidgets ) + CMP_TREE_MODEL_ADAPTER_BASE::PTR& aAdapter, WIDGETS aWidgets ) : wxPanel( aParent ), m_sym_lib_table( aSymLibTable ), m_adapter( aAdapter ), diff --git a/eeschema/widgets/component_tree.h b/eeschema/widgets/component_tree.h index 04ca143b8b..d2777b6743 100644 --- a/eeschema/widgets/component_tree.h +++ b/eeschema/widgets/component_tree.h @@ -47,7 +47,7 @@ public: enum WIDGETS { NONE = 0x00, SEARCH = 0x01, DETAILS = 0x02, ALL = 0xFF }; COMPONENT_TREE( wxWindow* aParent, SYMBOL_LIB_TABLE* aSymLibTable, - CMP_TREE_MODEL_ADAPTER::PTR& aAdapter, WIDGETS aWidgets = ALL ); + CMP_TREE_MODEL_ADAPTER_BASE::PTR& aAdapter, WIDGETS aWidgets = ALL ); /** * For multi-unit components, if the user selects the component itself