You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							371 lines
						
					
					
						
							12 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							371 lines
						
					
					
						
							12 KiB
						
					
					
				
								/*
							 | 
						|
								 * 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_H
							 | 
						|
								#define _CMP_TREE_MODEL_ADAPTER_H
							 | 
						|
								
							 | 
						|
								#include <cmp_tree_model.h>
							 | 
						|
								
							 | 
						|
								#include <wx/hashmap.h>
							 | 
						|
								#include <wx/dataview.h>
							 | 
						|
								#include <vector>
							 | 
						|
								#include <functional>
							 | 
						|
								
							 | 
						|
								class LIB_ALIAS;
							 | 
						|
								class PART_LIB;
							 | 
						|
								class PART_LIBS;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * 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
							 | 
						|
								{
							 | 
						|
								public:
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * Reference-counting container for a pointer to CMP_TREE_MODEL_ADAPTER.
							 | 
						|
								     */
							 | 
						|
								    typedef wxObjectDataPtr<CMP_TREE_MODEL_ADAPTER> PTR;
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * Destructor. Do NOT delete this class manually; it is reference-counted
							 | 
						|
								     * by wxObject.
							 | 
						|
								     */
							 | 
						|
								    ~CMP_TREE_MODEL_ADAPTER();
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * Factory function: create a model adapter in a reference-counting
							 | 
						|
								     * container.
							 | 
						|
								     *
							 | 
						|
								     * @param aLibs library set from which parts will be loaded
							 | 
						|
								     */
							 | 
						|
								    static PTR Create( PART_LIBS* 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 aName     component name to be selected
							 | 
						|
								     * @param aUnit     unit to be selected, if > 0 (0 selects the alias itself)
							 | 
						|
								     */
							 | 
						|
								    void SetPreselectNode( wxString const& aName, int aUnit );
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * Add all the components and their aliases in this library. To be called
							 | 
						|
								     * in the setup phase.
							 | 
						|
								     *
							 | 
						|
								     * @param aLib  reference to a library
							 | 
						|
								     */
							 | 
						|
								    void AddLibrary( PART_LIB& aLib );
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * 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
							 | 
						|
								     * @param aOptionalLib      library to look up names in (null = global)
							 | 
						|
								     */
							 | 
						|
								    void AddAliasList(
							 | 
						|
								            wxString const&         aNodeName,
							 | 
						|
								            wxArrayString const&    aAliasNameList,
							 | 
						|
								            PART_LIB*               aOptionalLib = nullptr );
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * 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
							 | 
						|
								     * @param aOptionalLib  library to look up names in (null = global)
							 | 
						|
								     */
							 | 
						|
								    void AddAliasList(
							 | 
						|
								            wxString const&         aNodeName,
							 | 
						|
								            std::vector<LIB_ALIAS*> const&  aAliasList,
							 | 
						|
								            PART_LIB*               aOptionalLib = nullptr );
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * 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_ALIAS* GetAliasFor( 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( wxDataViewItem aSelection ) const;
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * Return the number of components loaded in the tree.
							 | 
						|
								     */
							 | 
						|
								    int GetComponentsCount() const;
							 | 
						|
								
							 | 
						|
								protected:
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * Constructor; takes a set of libraries to be included in the search.
							 | 
						|
								     */
							 | 
						|
								    CMP_TREE_MODEL_ADAPTER( PART_LIBS* 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;
							 | 
						|
								    PART_LIBS*          m_libs;
							 | 
						|
								    wxString            m_preselect_name;
							 | 
						|
								    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<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_H
							 |