Select best-matching component when filtering.

This also fixes the old bug of scrolling to the selected best
match.

Fixes: lp:1774110
* https://bugs.launchpad.net/kicad/+bug/1774110

Fixes: lp:1744703
* https://bugs.launchpad.net/kicad/+bug/1744703
This commit is contained in:
Jeff Young 2018-06-10 23:20:06 +01:00
parent 0e3be5776c
commit 9edfd25b95
3 changed files with 67 additions and 44 deletions

View File

@ -193,7 +193,20 @@ void CMP_TREE_MODEL_ADAPTER_BASE::UpdateSearchString( wxString const& aSearch )
#endif
}
ShowResults() || ShowPreselect() || ShowSingleLibrary();
CMP_TREE_NODE* bestMatch = ShowResults();
if( !bestMatch )
bestMatch = ShowPreselect();
if( !bestMatch )
bestMatch = ShowSingleLibrary();
if( bestMatch )
{
auto item = wxDataViewItem( bestMatch );
m_widget->Select( item );
m_widget->EnsureVisible( item );
}
}
@ -442,47 +455,51 @@ int CMP_TREE_MODEL_ADAPTER_BASE::WidthFor( wxString const& aHeading, int aCol )
}
bool CMP_TREE_MODEL_ADAPTER_BASE::FindAndExpand(
CMP_TREE_NODE& aNode,
std::function<bool( CMP_TREE_NODE const* )> aFunc )
void CMP_TREE_MODEL_ADAPTER_BASE::FindAndExpand( CMP_TREE_NODE& aNode,
std::function<bool( CMP_TREE_NODE const* )> aFunc,
CMP_TREE_NODE** aHighScore )
{
for( auto& node: aNode.Children )
{
if( aFunc( &*node ) )
{
auto item = wxDataViewItem(
const_cast<void*>( static_cast<void const*>( &*node ) ) );
auto item = wxDataViewItem( &*node );
m_widget->ExpandAncestors( item );
m_widget->EnsureVisible( item );
m_widget->Select( item );
return true;
if( !(*aHighScore) || node->Score > (*aHighScore)->Score )
(*aHighScore) = &*node;
}
else if( FindAndExpand( *node, aFunc ) )
else
{
return true;
FindAndExpand( *node, aFunc, aHighScore );
}
}
return false;
}
bool CMP_TREE_MODEL_ADAPTER_BASE::ShowResults()
CMP_TREE_NODE* 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;
} );
CMP_TREE_NODE* highScore = nullptr;
FindAndExpand( m_tree,
[]( CMP_TREE_NODE const* n )
{
return n->Type == CMP_TREE_NODE::TYPE::LIBID && n->Score > 1;
},
&highScore );
return highScore;
}
bool CMP_TREE_MODEL_ADAPTER_BASE::ShowPreselect()
CMP_TREE_NODE* CMP_TREE_MODEL_ADAPTER_BASE::ShowPreselect()
{
CMP_TREE_NODE* highScore = nullptr;
if( !m_preselect_lib_id.IsValid() )
return false;
return highScore;
return FindAndExpand( m_tree,
FindAndExpand( m_tree,
[&]( CMP_TREE_NODE const* n )
{
if( n->Type == CMP_TREE_NODE::LIBID && ( n->Children.empty() || !m_preselect_unit ) )
@ -491,16 +508,24 @@ bool CMP_TREE_MODEL_ADAPTER_BASE::ShowPreselect()
return m_preselect_lib_id == n->Parent->LibId && m_preselect_unit == n->Unit;
else
return false;
} );
},
&highScore );
return highScore;
}
bool CMP_TREE_MODEL_ADAPTER_BASE::ShowSingleLibrary()
CMP_TREE_NODE* 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;
} );
CMP_TREE_NODE* highScore = nullptr;
FindAndExpand( m_tree,
[]( CMP_TREE_NODE const* n )
{
return n->Type == CMP_TREE_NODE::TYPE::LIBID &&
n->Parent->Parent->Children.size() == 1;
},
&highScore );
return highScore;
}

View File

@ -389,27 +389,26 @@ private:
/**
* Find any results worth highlighting and expand them, according to given
* criteria (f(CMP_TREE_NODE const*) -> bool)
*
* @return whether a node was expanded
* The highest-scoring node is written to aHighScore
*/
bool FindAndExpand(
CMP_TREE_NODE& aNode,
std::function<bool( CMP_TREE_NODE const* )> aFunc );
void FindAndExpand( CMP_TREE_NODE& aNode,
std::function<bool( CMP_TREE_NODE const* )> aFunc,
CMP_TREE_NODE** aHighScore );
/**
* Find and expand successful search results
* Find and expand successful search results. Return the best match (if any).
*/
bool ShowResults();
CMP_TREE_NODE* ShowResults();
/**
* Find and expand preselected node
* Find and expand preselected node. Return the best match (if any).
*/
bool ShowPreselect();
CMP_TREE_NODE* ShowPreselect();
/**
* Find and expand a library if there is only one
* Find and expand a library if there is only one. Return the best match (if any).
*/
bool ShowSingleLibrary();
CMP_TREE_NODE* ShowSingleLibrary();
};
#endif // _CMP_TREE_MODEL_ADAPTER_BASE_H

View File

@ -169,8 +169,6 @@ void COMPONENT_TREE::Regenerate()
// Store the state
if( !m_filtering )
m_unfilteredState = getState();
else
current = getState();
wxString filter = m_query_ctrl->GetValue();
m_adapter->UpdateSearchString( filter );
@ -178,7 +176,8 @@ void COMPONENT_TREE::Regenerate()
postPreselectEvent();
// Restore the state
setState( m_filtering ? current : m_unfilteredState );
if( !m_filtering )
setState( m_unfilteredState );
}