Commit 60b16714 authored by Henner Zeller's avatar Henner Zeller Committed by jean-pierre charras

Eeschema: Better naming for private struct: public fields uppercase.

* make some more fields 'const' that can.
* Instead of previous/next _visible_ element, Go through
      previous and next element. Otherwise the cursor stops moving
      if the item is only partially visible.
parent 31fea1e7
...@@ -48,29 +48,29 @@ struct COMPONENT_TREE_SEARCH_CONTAINER::TREE_NODE ...@@ -48,29 +48,29 @@ struct COMPONENT_TREE_SEARCH_CONTAINER::TREE_NODE
const wxString& aName, const wxString& aDisplayInfo, const wxString& aName, const wxString& aDisplayInfo,
const wxString& aSearchText, const wxString& aSearchText,
bool aNormallyExpanded = false) bool aNormallyExpanded = false)
: parent( aParent ), : Parent( aParent ),
lib( aOwningLib ), Lib( aOwningLib ),
normally_expanded( aNormallyExpanded ), NormallyExpanded( aNormallyExpanded ),
name( aName ), Name( aName ),
display_info( aDisplayInfo ), DisplayInfo( aDisplayInfo ),
match_name( aName.Lower() ), MatchName( aName.Lower() ),
search_text( aSearchText.Lower() ), SearchText( aSearchText.Lower() ),
match_score( 0 ), previous_score( 0 ) MatchScore( 0 ), PreviousScore( 0 )
{ {
} }
TREE_NODE* parent; // NULL if library, pointer to lib when component. TREE_NODE* const Parent; ///< NULL if library, pointer to lib-node when component.
CMP_LIBRARY* lib; // Owning library of this component. CMP_LIBRARY* const Lib; ///< Owning library of this component.
bool normally_expanded; // If this is a parent node, should it be unfolded ? const bool NormallyExpanded; ///< If this is a parent node, should it be unfolded ?
wxString name; // Exact name as displayed to the user. const wxString Name; ///< Exact name as displayed to the user.
wxString display_info; // Additional info displayed in the tree (description..) const wxString DisplayInfo; ///< Additional info displayed in the tree (description..)
wxString match_name; // Preprocessed: lowercased display name. const wxString MatchName; ///< Preprocessed: lowercased display name.
wxString search_text; // Other lowercase text (keywords, description..) to search in. const wxString SearchText; ///< Other text (keywords, description..) to search in.
unsigned match_score; // Result-Score after UpdateSearchTerm() unsigned MatchScore; ///< Result-Score after UpdateSearchTerm()
unsigned previous_score; // Optimization: used to see if we need any tree update. unsigned PreviousScore; ///< Optimization: used to see if we need any tree update.
wxTreeItemId tree_id; // Tree-ID if stored in the tree (if match_score > 0). wxTreeItemId TreeId; ///< Tree-ID if stored in the tree (if MatchScore > 0).
}; };
...@@ -79,19 +79,19 @@ struct COMPONENT_TREE_SEARCH_CONTAINER::TREE_NODE ...@@ -79,19 +79,19 @@ struct COMPONENT_TREE_SEARCH_CONTAINER::TREE_NODE
// leaf nodes. // leaf nodes.
bool COMPONENT_TREE_SEARCH_CONTAINER::scoreComparator( const TREE_NODE* a1, const TREE_NODE* a2 ) bool COMPONENT_TREE_SEARCH_CONTAINER::scoreComparator( const TREE_NODE* a1, const TREE_NODE* a2 )
{ {
if ( a1->parent == NULL && a2->parent != NULL ) if ( a1->Parent == NULL && a2->Parent != NULL )
return true; return true;
if ( a1->parent != NULL && a2->parent == NULL ) if ( a1->Parent != NULL && a2->Parent == NULL )
return false; return false;
if ( a1->match_score != a2->match_score ) if ( a1->MatchScore != a2->MatchScore )
return a1->match_score > a2->match_score; // biggest first. return a1->MatchScore > a2->MatchScore; // biggest first.
if (a1->parent != a2->parent) if (a1->Parent != a2->Parent)
return a1->parent->match_name.Cmp(a2->parent->match_name) < 0; return a1->Parent->MatchName.Cmp(a2->Parent->MatchName) < 0;
return a1->match_name.Cmp( a2->match_name ) < 0; return a1->MatchName.Cmp( a2->MatchName ) < 0;
} }
COMPONENT_TREE_SEARCH_CONTAINER::COMPONENT_TREE_SEARCH_CONTAINER() COMPONENT_TREE_SEARCH_CONTAINER::COMPONENT_TREE_SEARCH_CONTAINER()
...@@ -186,8 +186,8 @@ LIB_COMPONENT* COMPONENT_TREE_SEARCH_CONTAINER::GetSelectedComponent() ...@@ -186,8 +186,8 @@ LIB_COMPONENT* COMPONENT_TREE_SEARCH_CONTAINER::GetSelectedComponent()
const wxTreeItemId& select_id = tree->GetSelection(); const wxTreeItemId& select_id = tree->GetSelection();
BOOST_FOREACH( TREE_NODE* node, nodes ) BOOST_FOREACH( TREE_NODE* node, nodes )
{ {
if ( node->match_score > 0 && node->tree_id == select_id && node->lib ) if ( node->MatchScore > 0 && node->TreeId == select_id && node->Lib )
return node->lib->FindComponent( node->name ); return node->Lib->FindComponent( node->Name );
} }
return NULL; return NULL;
} }
...@@ -219,8 +219,8 @@ void COMPONENT_TREE_SEARCH_CONTAINER::UpdateSearchTerm( const wxString& aSearch ...@@ -219,8 +219,8 @@ void COMPONENT_TREE_SEARCH_CONTAINER::UpdateSearchTerm( const wxString& aSearch
// Initial AND condition: Leaf nodes are considered to match initially. // Initial AND condition: Leaf nodes are considered to match initially.
BOOST_FOREACH( TREE_NODE* node, nodes ) BOOST_FOREACH( TREE_NODE* node, nodes )
{ {
node->previous_score = node->match_score; node->PreviousScore = node->MatchScore;
node->match_score = node->parent ? kLowestDefaultScore : 0; // start-match for leafs. node->MatchScore = node->Parent ? kLowestDefaultScore : 0; // start-match for leafs.
} }
// Create match scores for each node for all the terms, that come space-separated. // Create match scores for each node for all the terms, that come space-separated.
...@@ -241,10 +241,10 @@ void COMPONENT_TREE_SEARCH_CONTAINER::UpdateSearchTerm( const wxString& aSearch ...@@ -241,10 +241,10 @@ void COMPONENT_TREE_SEARCH_CONTAINER::UpdateSearchTerm( const wxString& aSearch
const wxString term = tokenizer.GetNextToken().Lower(); const wxString term = tokenizer.GetNextToken().Lower();
BOOST_FOREACH( TREE_NODE* node, nodes ) BOOST_FOREACH( TREE_NODE* node, nodes )
{ {
if ( node->parent == NULL) if ( node->Parent == NULL)
continue; // Library nodes are not scored here. continue; // Library nodes are not scored here.
if ( node->match_score == 0) if ( node->MatchScore == 0)
continue; // Leaf node without score are out of the game. continue; // Leaf node without score are out of the game.
// Keywords and description we only count if the match string is at // Keywords and description we only count if the match string is at
...@@ -252,27 +252,28 @@ void COMPONENT_TREE_SEARCH_CONTAINER::UpdateSearchTerm( const wxString& aSearch ...@@ -252,27 +252,28 @@ void COMPONENT_TREE_SEARCH_CONTAINER::UpdateSearchTerm( const wxString& aSearch
// matches. Most abbreviations are at three characters long. // matches. Most abbreviations are at three characters long.
int found_pos; int found_pos;
if ( term == node->match_name ) if ( term == node->MatchName )
node->match_score += 1000; // exact match. High score :) node->MatchScore += 1000; // exact match. High score :)
else if ( (found_pos = node->match_name.Find( term ) ) != wxNOT_FOUND ) else if ( (found_pos = node->MatchName.Find( term ) ) != wxNOT_FOUND )
{ {
// Substring match. The earlier in the string the better. score += 20..40 // Substring match. The earlier in the string the better. score += 20..40
node->match_score += matchPosScore( found_pos, 20 ) + 20; node->MatchScore += matchPosScore( found_pos, 20 ) + 20;
} }
else if ( node->parent->match_name.Find( term ) != wxNOT_FOUND ) else if ( node->Parent->MatchName.Find( term ) != wxNOT_FOUND )
node->match_score += 19; // parent name matches. score += 19 node->MatchScore += 19; // parent name matches. score += 19
else if ( ( found_pos = node->search_text.Find( term ) ) != wxNOT_FOUND ) else if ( ( found_pos = node->SearchText.Find( term ) ) != wxNOT_FOUND )
{ {
// If we have a very short string (like one or two letters), we don't want // If we have a very short search term (like one or two letters), we don't want
// to accumulate scores if they just happen to be in keywords or description. // to accumulate scores if they just happen to be in keywords or description as
// almost any one or two-letter combination shows up in there.
// For longer terms, we add scores 1..18 for positional match (higher in the // For longer terms, we add scores 1..18 for positional match (higher in the
// front, where the keywords are). score += 0..18 // front, where the keywords are). score += 0..18
node->match_score += ( ( term.length() >= 2 ) node->MatchScore += ( ( term.length() >= 2 )
? matchPosScore( found_pos, 17 ) + 1 ? matchPosScore( found_pos, 17 ) + 1
: 0 ); : 0 );
} }
else else
node->match_score = 0; // No match. That's it for this item. node->MatchScore = 0; // No match. That's it for this item.
} }
} }
...@@ -281,12 +282,12 @@ void COMPONENT_TREE_SEARCH_CONTAINER::UpdateSearchTerm( const wxString& aSearch ...@@ -281,12 +282,12 @@ void COMPONENT_TREE_SEARCH_CONTAINER::UpdateSearchTerm( const wxString& aSearch
bool any_change = false; bool any_change = false;
BOOST_FOREACH( TREE_NODE* node, nodes ) BOOST_FOREACH( TREE_NODE* node, nodes )
{ {
if ( node->parent == NULL ) if ( node->Parent == NULL )
continue; continue;
any_change |= (node->previous_score != node->match_score); any_change |= (node->PreviousScore != node->MatchScore);
node->parent->match_score = std::max( node->parent->match_score, node->match_score ); node->Parent->MatchScore = std::max( node->Parent->MatchScore, node->MatchScore );
highest_score_seen = std::max( highest_score_seen, node->match_score ); highest_score_seen = std::max( highest_score_seen, node->MatchScore );
} }
...@@ -301,56 +302,56 @@ void COMPONENT_TREE_SEARCH_CONTAINER::UpdateSearchTerm( const wxString& aSearch ...@@ -301,56 +302,56 @@ void COMPONENT_TREE_SEARCH_CONTAINER::UpdateSearchTerm( const wxString& aSearch
// items is pretty complex, so we just re-build the whole tree. // items is pretty complex, so we just re-build the whole tree.
tree->Freeze(); tree->Freeze();
tree->DeleteAllItems(); tree->DeleteAllItems();
wxTreeItemId root = tree->AddRoot( wxEmptyString ); const wxTreeItemId root_id = tree->AddRoot( wxEmptyString );
const TREE_NODE* first_match = NULL; const TREE_NODE* first_match = NULL;
const TREE_NODE* preselected_node = NULL; const TREE_NODE* preselected_node = NULL;
BOOST_FOREACH( TREE_NODE* node, nodes ) BOOST_FOREACH( TREE_NODE* node, nodes )
{ {
if ( node->match_score == 0 ) if ( node->MatchScore == 0 )
continue; continue;
// If we have nodes that go beyond the default score, suppress nodes that // If we have nodes that go beyond the default score, suppress nodes that
// have the default score. That can happen if they have an honary += 0 score due to // have the default score. That can happen if they have an honary += 0 score due to
// some one-letter match in the keyword or description. In this case, we prefer matches // some one-letter match in the keyword or description. In this case, we prefer matches
// that just have higher scores. Improves confusion (and performance as the tree has to // that just have higher scores. Improves relevancy and performance as the tree has to
// display less items). // display less items.
if ( highest_score_seen > kLowestDefaultScore && node->match_score == kLowestDefaultScore ) if ( highest_score_seen > kLowestDefaultScore && node->MatchScore == kLowestDefaultScore )
continue; continue;
const bool isLeaf = ( node->Parent != NULL );
wxString node_text; wxString node_text;
#if 0 #if 0
// Node text with scoring information for debugging // Node text with scoring information for debugging
node_text.Printf( wxT("%s (s=%u)%s"), GetChars(node->name), node_text.Printf( wxT("%s (s=%u)%s"), GetChars(node->Name),
node->match_score, GetChars(node->display_info)); node->MatchScore, GetChars(node->DisplayInfo));
#else #else
node_text = node->name + node->display_info; node_text = node->Name + node->DisplayInfo;
#endif #endif
node->tree_id = tree->AppendItem( ( node->parent == NULL ) ? root : node->parent->tree_id, node->TreeId = tree->AppendItem( !isLeaf ? root_id : node->Parent->TreeId, node_text );
node_text);
// If we are a child node, we might need to expand. // If we are a leaf node, we might need to expand.
if ( node->parent != NULL ) if ( isLeaf )
{ {
if ( node->match_score > kLowestDefaultScore ) if ( node->MatchScore > kLowestDefaultScore )
{ {
tree->EnsureVisible( node->tree_id ); tree->EnsureVisible( node->TreeId );
if ( first_match == NULL ) if ( first_match == NULL )
first_match = node; // The "I am feeling lucky" element. first_match = node; // The "I am feeling lucky" element.
} }
if ( preselected_node == NULL && node->match_name == preselect_node_name ) if ( preselected_node == NULL && node->MatchName == preselect_node_name )
preselected_node = node; preselected_node = node;
} }
if ( node->parent == NULL && node->normally_expanded ) if ( !isLeaf && node->NormallyExpanded )
tree->Expand( node->tree_id ); tree->Expand( node->TreeId );
} }
if ( first_match ) // Highest score search match pre-selected. if ( first_match ) // Highest score search match pre-selected.
tree->SelectItem( first_match->tree_id ); tree->SelectItem( first_match->TreeId );
else if ( preselected_node ) // No search, so history item preselected. else if ( preselected_node ) // No search, so history item preselected.
tree->SelectItem( preselected_node->tree_id ); tree->SelectItem( preselected_node->TreeId );
tree->Thaw(); tree->Thaw();
} }
...@@ -31,8 +31,9 @@ ...@@ -31,8 +31,9 @@
#include <component_tree_search_container.h> #include <component_tree_search_container.h>
#include <sch_base_frame.h> #include <sch_base_frame.h>
// Work-around broken implementation in wxWidgets <=2.8 tree. // Tree navigation helpers.
static wxTreeItemId fixedGetPrevVisible( const wxTreeCtrl& tree, const wxTreeItemId& item ); static wxTreeItemId GetPrevItem( const wxTreeCtrl& tree, const wxTreeItemId& item );
static wxTreeItemId GetNextItem( const wxTreeCtrl& tree, const wxTreeItemId& item );
// Combine descriptions of all aliases from given component. // Combine descriptions of all aliases from given component.
static wxString combineDescriptions( LIB_COMPONENT* aComponent ) static wxString combineDescriptions( LIB_COMPONENT* aComponent )
...@@ -132,11 +133,11 @@ void DIALOG_CHOOSE_COMPONENT::OnInterceptSearchBoxKey( wxKeyEvent& aKeyStroke ) ...@@ -132,11 +133,11 @@ void DIALOG_CHOOSE_COMPONENT::OnInterceptSearchBoxKey( wxKeyEvent& aKeyStroke )
switch ( aKeyStroke.GetKeyCode() ) switch ( aKeyStroke.GetKeyCode() )
{ {
case WXK_UP: case WXK_UP:
SelectIfValid( fixedGetPrevVisible( *m_libraryComponentTree, sel ) ); SelectIfValid( GetPrevItem( *m_libraryComponentTree, sel ) );
break; break;
case WXK_DOWN: case WXK_DOWN:
SelectIfValid( m_libraryComponentTree->GetNextVisible( sel ) ); SelectIfValid( GetNextItem( *m_libraryComponentTree, sel ) );
break; break;
default: default:
...@@ -230,46 +231,29 @@ void DIALOG_CHOOSE_COMPONENT::updateSelection() ...@@ -230,46 +231,29 @@ void DIALOG_CHOOSE_COMPONENT::updateSelection()
m_componentDetails->SetInsertionPoint( 0 ); // scroll up. m_componentDetails->SetInsertionPoint( 0 ); // scroll up.
} }
static wxTreeItemId GetPrevItem( const wxTreeCtrl& tree, const wxTreeItemId& item )
// The GetPrevVisible() method is broken in at least 2.8 wxWidgets. This is mostly copied
// verbatim from the latest 3.x source in which this is fixed.
// ( wxWidgets/src/generic/treectlg.cpp )
static wxTreeItemId fixedGetPrevVisible( const wxTreeCtrl& tree, const wxTreeItemId& item )
{ {
#if wxCHECK_VERSION( 3, 0, 0 ) wxTreeItemId prevItem = tree.GetPrevSibling( item );
return tree.GetPrevVisible(item);
#else
// find out the starting point
wxTreeItemId prevItem = tree.GetPrevSibling(item);
if ( !prevItem.IsOk() ) if ( !prevItem.IsOk() )
{ {
prevItem = tree.GetItemParent(item); const wxTreeItemId parent = tree.GetItemParent( item );
prevItem = tree.GetLastChild( tree.GetPrevSibling( parent ) );
} }
// find the first visible item after it return prevItem;
while ( prevItem.IsOk() && !tree.IsVisible(prevItem) ) }
{
prevItem = tree.GetNext(prevItem);
if ( !prevItem.IsOk() || prevItem == item ) static wxTreeItemId GetNextItem( const wxTreeCtrl& tree, const wxTreeItemId& item )
{ {
// there are no visible items before item wxTreeItemId nextItem = tree.GetNextSibling( item );
return wxTreeItemId();
}
}
// from there we must be able to navigate until this item if ( !nextItem.IsOk() )
while ( prevItem.IsOk() )
{ {
const wxTreeItemId nextItem = tree.GetNextVisible(prevItem); const wxTreeItemId parent = tree.GetItemParent( item );
wxTreeItemIdValue dummy;
if ( !nextItem.IsOk() || nextItem == item ) nextItem = tree.GetFirstChild( tree.GetNextSibling( parent ), dummy );
break;
prevItem = nextItem;
} }
return prevItem; return nextItem;
#endif
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment