Pinning for library trees in FPEditor and SymbolEditor.
Fixes https://gitlab.com/kicad/code/kicad/issues/2288
This commit is contained in:
parent
f502208211
commit
2017389f2d
|
@ -519,7 +519,7 @@ std::string FormatStringToGerber( const wxString& aString )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Netname and Pan num fields cannot be empty in Gerber files
|
// Netname and Pan num fields cannot be empty in Gerber files
|
||||||
// Normalized names must be used, if any
|
// m_Normalized names must be used, if any
|
||||||
#define NO_NET_NAME wxT( "N/C" ) // net name of not connected pads (one pad net) (normalized)
|
#define NO_NET_NAME wxT( "N/C" ) // net name of not connected pads (one pad net) (normalized)
|
||||||
#define NO_PAD_NAME wxT( "" ) // pad name of pads without pad name/number (not normalized)
|
#define NO_PAD_NAME wxT( "" ) // pad name of pads without pad name/number (not normalized)
|
||||||
|
|
||||||
|
|
|
@ -51,10 +51,10 @@ static int matchPosScore(int aPosition, int aMaximum)
|
||||||
|
|
||||||
void LIB_TREE_NODE::ResetScore()
|
void LIB_TREE_NODE::ResetScore()
|
||||||
{
|
{
|
||||||
for( auto& child: Children )
|
for( auto& child: m_Children )
|
||||||
child->ResetScore();
|
child->ResetScore();
|
||||||
|
|
||||||
Score = kLowestDefaultScore;
|
m_Score = kLowestDefaultScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,62 +64,65 @@ void LIB_TREE_NODE::AssignIntrinsicRanks( bool presorted )
|
||||||
|
|
||||||
if( presorted )
|
if( presorted )
|
||||||
{
|
{
|
||||||
int max = Children.size() - 1;
|
int max = m_Children.size() - 1;
|
||||||
|
|
||||||
for( int i = 0; i <= max; ++i )
|
for( int i = 0; i <= max; ++i )
|
||||||
Children[i]->IntrinsicRank = max - i;
|
m_Children[i]->m_IntrinsicRank = max - i;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for( auto const& node: Children )
|
for( auto const& node: m_Children )
|
||||||
sort_buf.push_back( &*node );
|
sort_buf.push_back( &*node );
|
||||||
|
|
||||||
std::sort( sort_buf.begin(), sort_buf.end(),
|
std::sort( sort_buf.begin(), sort_buf.end(),
|
||||||
[]( LIB_TREE_NODE* a, LIB_TREE_NODE* b ) -> bool
|
[]( LIB_TREE_NODE* a, LIB_TREE_NODE* b ) -> bool
|
||||||
{ return StrNumCmp( a->Name, b->Name, true ) > 0; } );
|
{
|
||||||
|
return StrNumCmp( a->m_Name, b->m_Name, true ) > 0;
|
||||||
|
} );
|
||||||
|
|
||||||
for( int i = 0; i < (int) sort_buf.size(); ++i )
|
for( int i = 0; i < (int) sort_buf.size(); ++i )
|
||||||
sort_buf[i]->IntrinsicRank = i;
|
sort_buf[i]->m_IntrinsicRank = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_TREE_NODE::SortNodes()
|
void LIB_TREE_NODE::SortNodes()
|
||||||
{
|
{
|
||||||
std::sort( Children.begin(), Children.end(),
|
std::sort( m_Children.begin(), m_Children.end(),
|
||||||
[]( std::unique_ptr<LIB_TREE_NODE>& a, std::unique_ptr<LIB_TREE_NODE>& b )
|
[]( std::unique_ptr<LIB_TREE_NODE>& a, std::unique_ptr<LIB_TREE_NODE>& b )
|
||||||
{
|
{
|
||||||
return Compare( *a, *b ) > 0;
|
return Compare( *a, *b ) > 0;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
for( std::unique_ptr<LIB_TREE_NODE>& node: Children )
|
for( std::unique_ptr<LIB_TREE_NODE>& node: m_Children )
|
||||||
node->SortNodes();
|
node->SortNodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int LIB_TREE_NODE::Compare( LIB_TREE_NODE const& aNode1, LIB_TREE_NODE const& aNode2 )
|
int LIB_TREE_NODE::Compare( LIB_TREE_NODE const& aNode1, LIB_TREE_NODE const& aNode2 )
|
||||||
{
|
{
|
||||||
if( aNode1.Type != aNode2.Type )
|
if( aNode1.m_Type != aNode2.m_Type )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if( aNode1.Score != aNode2.Score )
|
if( aNode1.m_Score != aNode2.m_Score )
|
||||||
return aNode1.Score - aNode2.Score;
|
return aNode1.m_Score - aNode2.m_Score;
|
||||||
|
|
||||||
if( aNode1.Parent != aNode2.Parent )
|
if( aNode1.m_Parent != aNode2.m_Parent )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return aNode1.IntrinsicRank - aNode2.IntrinsicRank;
|
return aNode1.m_IntrinsicRank - aNode2.m_IntrinsicRank;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LIB_TREE_NODE::LIB_TREE_NODE()
|
LIB_TREE_NODE::LIB_TREE_NODE()
|
||||||
: Parent( nullptr ),
|
: m_Parent( nullptr ),
|
||||||
Type( INVALID ),
|
m_Type( INVALID ),
|
||||||
IntrinsicRank( 0 ),
|
m_IntrinsicRank( 0 ),
|
||||||
Score( kLowestDefaultScore ),
|
m_Score( kLowestDefaultScore ),
|
||||||
Normalized( false ),
|
m_Pinned( false ),
|
||||||
Unit( 0 ),
|
m_Normalized( false ),
|
||||||
IsRoot( false )
|
m_Unit( 0 ),
|
||||||
|
m_IsRoot( false )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
@ -136,36 +139,36 @@ LIB_TREE_NODE_UNIT::LIB_TREE_NODE_UNIT( LIB_TREE_NODE* aParent, LIB_TREE_ITEM* a
|
||||||
locale = Pgm().GetLocale();
|
locale = Pgm().GetLocale();
|
||||||
}
|
}
|
||||||
|
|
||||||
Parent = aParent;
|
m_Parent = aParent;
|
||||||
Type = UNIT;
|
m_Type = UNIT;
|
||||||
|
|
||||||
Unit = aUnit;
|
m_Unit = aUnit;
|
||||||
LibId = aParent->LibId;
|
m_LibId = aParent->m_LibId;
|
||||||
|
|
||||||
Name = namePrefix + " " + aItem->GetUnitReference( aUnit );
|
m_Name = namePrefix + " " + aItem->GetUnitReference( aUnit );
|
||||||
Desc = wxEmptyString;
|
m_Desc = wxEmptyString;
|
||||||
MatchName = wxEmptyString;
|
m_MatchName = wxEmptyString;
|
||||||
|
|
||||||
IntrinsicRank = -aUnit;
|
m_IntrinsicRank = -aUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LIB_TREE_NODE_LIB_ID::LIB_TREE_NODE_LIB_ID( LIB_TREE_NODE* aParent, LIB_TREE_ITEM* aItem )
|
LIB_TREE_NODE_LIB_ID::LIB_TREE_NODE_LIB_ID( LIB_TREE_NODE* aParent, LIB_TREE_ITEM* aItem )
|
||||||
{
|
{
|
||||||
Type = LIBID;
|
m_Type = LIBID;
|
||||||
Parent = aParent;
|
m_Parent = aParent;
|
||||||
|
|
||||||
LibId.SetLibNickname( aItem->GetLibNickname() );
|
m_LibId.SetLibNickname( aItem->GetLibNickname() );
|
||||||
LibId.SetLibItemName( aItem->GetName () );
|
m_LibId.SetLibItemName( aItem->GetName () );
|
||||||
|
|
||||||
Name = aItem->GetName();
|
m_Name = aItem->GetName();
|
||||||
Desc = aItem->GetDescription();
|
m_Desc = aItem->GetDescription();
|
||||||
|
|
||||||
MatchName = aItem->GetName();
|
m_MatchName = aItem->GetName();
|
||||||
SearchText = aItem->GetSearchText();
|
m_SearchText = aItem->GetSearchText();
|
||||||
Normalized = false;
|
m_Normalized = false;
|
||||||
|
|
||||||
IsRoot = aItem->IsRoot();
|
m_IsRoot = aItem->IsRoot();
|
||||||
|
|
||||||
if( aItem->GetUnitCount() > 1 )
|
if( aItem->GetUnitCount() > 1 )
|
||||||
{
|
{
|
||||||
|
@ -178,7 +181,7 @@ LIB_TREE_NODE_LIB_ID::LIB_TREE_NODE_LIB_ID( LIB_TREE_NODE* aParent, LIB_TREE_ITE
|
||||||
LIB_TREE_NODE_UNIT& LIB_TREE_NODE_LIB_ID::AddUnit( LIB_TREE_ITEM* aItem, int aUnit )
|
LIB_TREE_NODE_UNIT& LIB_TREE_NODE_LIB_ID::AddUnit( LIB_TREE_ITEM* aItem, int aUnit )
|
||||||
{
|
{
|
||||||
LIB_TREE_NODE_UNIT* unit = new LIB_TREE_NODE_UNIT( this, aItem, aUnit );
|
LIB_TREE_NODE_UNIT* unit = new LIB_TREE_NODE_UNIT( this, aItem, aUnit );
|
||||||
Children.push_back( std::unique_ptr<LIB_TREE_NODE>( unit ) );
|
m_Children.push_back( std::unique_ptr<LIB_TREE_NODE>( unit ) );
|
||||||
return *unit;
|
return *unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,15 +190,15 @@ void LIB_TREE_NODE_LIB_ID::Update( LIB_TREE_ITEM* aItem )
|
||||||
{
|
{
|
||||||
// Update is called when the names match, so just update the other fields.
|
// Update is called when the names match, so just update the other fields.
|
||||||
|
|
||||||
LibId.SetLibNickname( aItem->GetLibId().GetLibNickname() );
|
m_LibId.SetLibNickname( aItem->GetLibId().GetLibNickname() );
|
||||||
|
|
||||||
Desc = aItem->GetDescription();
|
m_Desc = aItem->GetDescription();
|
||||||
|
|
||||||
SearchText = aItem->GetSearchText();
|
m_SearchText = aItem->GetSearchText();
|
||||||
Normalized = false;
|
m_Normalized = false;
|
||||||
|
|
||||||
IsRoot = aItem->IsRoot();
|
m_IsRoot = aItem->IsRoot();
|
||||||
Children.clear();
|
m_Children.clear();
|
||||||
|
|
||||||
for( int u = 1; u <= aItem->GetUnitCount(); ++u )
|
for( int u = 1; u <= aItem->GetUnitCount(); ++u )
|
||||||
AddUnit( aItem, u );
|
AddUnit( aItem, u );
|
||||||
|
@ -204,14 +207,14 @@ void LIB_TREE_NODE_LIB_ID::Update( LIB_TREE_ITEM* aItem )
|
||||||
|
|
||||||
void LIB_TREE_NODE_LIB_ID::UpdateScore( EDA_COMBINED_MATCHER& aMatcher )
|
void LIB_TREE_NODE_LIB_ID::UpdateScore( EDA_COMBINED_MATCHER& aMatcher )
|
||||||
{
|
{
|
||||||
if( Score <= 0 )
|
if( m_Score <= 0 )
|
||||||
return; // Leaf nodes without scores are out of the game.
|
return; // Leaf nodes without scores are out of the game.
|
||||||
|
|
||||||
if( !Normalized )
|
if( !m_Normalized )
|
||||||
{
|
{
|
||||||
MatchName = MatchName.Lower();
|
m_MatchName = m_MatchName.Lower();
|
||||||
SearchText = SearchText.Lower();
|
m_SearchText = m_SearchText.Lower();
|
||||||
Normalized = true;
|
m_Normalized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keywords and description we only count if the match string is at
|
// Keywords and description we only count if the match string is at
|
||||||
|
@ -220,20 +223,20 @@ void LIB_TREE_NODE_LIB_ID::UpdateScore( EDA_COMBINED_MATCHER& aMatcher )
|
||||||
int found_pos = EDA_PATTERN_NOT_FOUND;
|
int found_pos = EDA_PATTERN_NOT_FOUND;
|
||||||
int matchers_fired = 0;
|
int matchers_fired = 0;
|
||||||
|
|
||||||
if( aMatcher.GetPattern() == MatchName )
|
if( aMatcher.GetPattern() == m_MatchName )
|
||||||
{
|
{
|
||||||
Score += 1000; // exact match. High score :)
|
m_Score += 1000; // exact match. High score :)
|
||||||
}
|
}
|
||||||
else if( aMatcher.Find( MatchName, matchers_fired, found_pos ) )
|
else if( aMatcher.Find( m_MatchName, matchers_fired, found_pos ) )
|
||||||
{
|
{
|
||||||
// Substring match. The earlier in the string the better.
|
// Substring match. The earlier in the string the better.
|
||||||
Score += matchPosScore( found_pos, 20 ) + 20;
|
m_Score += matchPosScore( found_pos, 20 ) + 20;
|
||||||
}
|
}
|
||||||
else if( aMatcher.Find( Parent->MatchName, matchers_fired, found_pos ) )
|
else if( aMatcher.Find( m_Parent->m_MatchName, matchers_fired, found_pos ) )
|
||||||
{
|
{
|
||||||
Score += 19; // parent name matches. score += 19
|
m_Score += 19; // parent name matches. score += 19
|
||||||
}
|
}
|
||||||
else if( aMatcher.Find( SearchText, matchers_fired, found_pos ) )
|
else if( aMatcher.Find( m_SearchText, matchers_fired, found_pos ) )
|
||||||
{
|
{
|
||||||
// If we have a very short search term (like one or two letters),
|
// 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
|
// we don't want to accumulate scores if they just happen to be in
|
||||||
|
@ -243,52 +246,52 @@ void LIB_TREE_NODE_LIB_ID::UpdateScore( EDA_COMBINED_MATCHER& aMatcher )
|
||||||
{
|
{
|
||||||
// For longer terms, we add scores 1..18 for positional match
|
// For longer terms, we add scores 1..18 for positional match
|
||||||
// (higher in the front, where the keywords are).
|
// (higher in the front, where the keywords are).
|
||||||
Score += matchPosScore( found_pos, 17 ) + 1;
|
m_Score += matchPosScore( found_pos, 17 ) + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// No match. That's it for this item.
|
// No match. That's it for this item.
|
||||||
Score = 0;
|
m_Score = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// More matchers = better match
|
// More matchers = better match
|
||||||
Score += 2 * matchers_fired;
|
m_Score += 2 * matchers_fired;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LIB_TREE_NODE_LIB::LIB_TREE_NODE_LIB( LIB_TREE_NODE* aParent, wxString const& aName,
|
LIB_TREE_NODE_LIB::LIB_TREE_NODE_LIB( LIB_TREE_NODE* aParent, wxString const& aName,
|
||||||
wxString const& aDesc )
|
wxString const& aDesc )
|
||||||
{
|
{
|
||||||
Type = LIB;
|
m_Type = LIB;
|
||||||
Name = aName;
|
m_Name = aName;
|
||||||
MatchName = aName.Lower();
|
m_MatchName = aName.Lower();
|
||||||
Desc = aDesc;
|
m_Desc = aDesc;
|
||||||
Parent = aParent;
|
m_Parent = aParent;
|
||||||
LibId.SetLibNickname( aName );
|
m_LibId.SetLibNickname( aName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LIB_TREE_NODE_LIB_ID& LIB_TREE_NODE_LIB::AddItem( LIB_TREE_ITEM* aItem )
|
LIB_TREE_NODE_LIB_ID& LIB_TREE_NODE_LIB::AddItem( LIB_TREE_ITEM* aItem )
|
||||||
{
|
{
|
||||||
LIB_TREE_NODE_LIB_ID* item = new LIB_TREE_NODE_LIB_ID( this, aItem );
|
LIB_TREE_NODE_LIB_ID* item = new LIB_TREE_NODE_LIB_ID( this, aItem );
|
||||||
Children.push_back( std::unique_ptr<LIB_TREE_NODE>( item ) );
|
m_Children.push_back( std::unique_ptr<LIB_TREE_NODE>( item ) );
|
||||||
return *item;
|
return *item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_TREE_NODE_LIB::UpdateScore( EDA_COMBINED_MATCHER& aMatcher )
|
void LIB_TREE_NODE_LIB::UpdateScore( EDA_COMBINED_MATCHER& aMatcher )
|
||||||
{
|
{
|
||||||
Score = 0;
|
m_Score = 0;
|
||||||
|
|
||||||
// We need to score leaf nodes, which are usually (but not always) children.
|
// We need to score leaf nodes, which are usually (but not always) children.
|
||||||
|
|
||||||
if( Children.size() )
|
if( m_Children.size() )
|
||||||
{
|
{
|
||||||
for( auto& child: Children )
|
for( auto& child: m_Children )
|
||||||
{
|
{
|
||||||
child->UpdateScore( aMatcher );
|
child->UpdateScore( aMatcher );
|
||||||
Score = std::max( Score, child->Score );
|
m_Score = std::max( m_Score, child->m_Score );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -297,39 +300,39 @@ void LIB_TREE_NODE_LIB::UpdateScore( EDA_COMBINED_MATCHER& aMatcher )
|
||||||
int found_pos = EDA_PATTERN_NOT_FOUND;
|
int found_pos = EDA_PATTERN_NOT_FOUND;
|
||||||
int matchers_fired = 0;
|
int matchers_fired = 0;
|
||||||
|
|
||||||
if( aMatcher.GetPattern() == MatchName )
|
if( aMatcher.GetPattern() == m_MatchName )
|
||||||
{
|
{
|
||||||
Score += 1000; // exact match. High score :)
|
m_Score += 1000; // exact match. High score :)
|
||||||
}
|
}
|
||||||
else if( aMatcher.Find( MatchName, matchers_fired, found_pos ) )
|
else if( aMatcher.Find( m_MatchName, matchers_fired, found_pos ) )
|
||||||
{
|
{
|
||||||
// Substring match. The earlier in the string the better.
|
// Substring match. The earlier in the string the better.
|
||||||
Score += matchPosScore( found_pos, 20 ) + 20;
|
m_Score += matchPosScore( found_pos, 20 ) + 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
// More matchers = better match
|
// More matchers = better match
|
||||||
Score += 2 * matchers_fired;
|
m_Score += 2 * matchers_fired;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LIB_TREE_NODE_ROOT::LIB_TREE_NODE_ROOT()
|
LIB_TREE_NODE_ROOT::LIB_TREE_NODE_ROOT()
|
||||||
{
|
{
|
||||||
Type = ROOT;
|
m_Type = ROOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LIB_TREE_NODE_LIB& LIB_TREE_NODE_ROOT::AddLib( wxString const& aName, wxString const& aDesc )
|
LIB_TREE_NODE_LIB& LIB_TREE_NODE_ROOT::AddLib( wxString const& aName, wxString const& aDesc )
|
||||||
{
|
{
|
||||||
LIB_TREE_NODE_LIB* lib = new LIB_TREE_NODE_LIB( this, aName, aDesc );
|
LIB_TREE_NODE_LIB* lib = new LIB_TREE_NODE_LIB( this, aName, aDesc );
|
||||||
Children.push_back( std::unique_ptr<LIB_TREE_NODE>( lib ) );
|
m_Children.push_back( std::unique_ptr<LIB_TREE_NODE>( lib ) );
|
||||||
return *lib;
|
return *lib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_TREE_NODE_ROOT::UpdateScore( EDA_COMBINED_MATCHER& aMatcher )
|
void LIB_TREE_NODE_ROOT::UpdateScore( EDA_COMBINED_MATCHER& aMatcher )
|
||||||
{
|
{
|
||||||
for( auto& child: Children )
|
for( auto& child: m_Children )
|
||||||
child->UpdateScore( aMatcher );
|
child->UpdateScore( aMatcher );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,17 +62,18 @@ class EDA_COMBINED_MATCHER;
|
||||||
* - `Parent` - parent node, or nullptr if root
|
* - `Parent` - parent node, or nullptr if root
|
||||||
* - `Children` - vector of unique_ptrs to children
|
* - `Children` - vector of unique_ptrs to children
|
||||||
* - `Type` - ROOT, LIB, ALIAS, or UNIT
|
* - `Type` - ROOT, LIB, ALIAS, or UNIT
|
||||||
* - `IntrinsicRank` - cached initial sort order
|
* - `m_IntrinsicRank` - cached initial sort order
|
||||||
* - `Score` - score taking into account search terms. Zero means irrelevant and
|
* - `m_Score` - score taking into account search terms. Zero means irrelevant and
|
||||||
* should be hidden.
|
* should be hidden.
|
||||||
* - `Name` - name of the library/alias/unit, to be displayed
|
* - `Name` - name of the library/alias/unit, to be displayed
|
||||||
* - `Desc` - description of the alias, to be displayed
|
* - `Desc` - description of the alias, to be displayed
|
||||||
* - `MatchName` - Name, normalized to lowercase for matching
|
* - `m_MatchName` - Name, normalized to lowercase for matching
|
||||||
* - `SearchText` - normalized composite of keywords and description
|
* - `m_SearchText` - normalized composite of keywords and description
|
||||||
* - `LibId` - the #LIB_ID this alias or unit is from, or not valid
|
* - `LibId` - the #LIB_ID this alias or unit is from, or not valid
|
||||||
* - `Unit` - the unit number, or zero for non-units
|
* - `Unit` - the unit number, or zero for non-units
|
||||||
*/
|
*/
|
||||||
class LIB_TREE_NODE {
|
class LIB_TREE_NODE
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
enum TYPE {
|
enum TYPE {
|
||||||
ROOT, LIB, LIBID, UNIT, INVALID
|
ROOT, LIB, LIBID, UNIT, INVALID
|
||||||
|
@ -80,31 +81,30 @@ public:
|
||||||
|
|
||||||
typedef std::vector<std::unique_ptr<LIB_TREE_NODE>> PTR_VECTOR;
|
typedef std::vector<std::unique_ptr<LIB_TREE_NODE>> PTR_VECTOR;
|
||||||
|
|
||||||
LIB_TREE_NODE* Parent; ///< Parent node or null
|
LIB_TREE_NODE* m_Parent; // Parent node or null
|
||||||
PTR_VECTOR Children; ///< List of child nodes
|
PTR_VECTOR m_Children; // List of child nodes
|
||||||
enum TYPE Type; ///< Node type
|
enum TYPE m_Type; // Node type
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The rank of the item before any search terms are applied. This is
|
* The rank of the item before any search terms are applied. This is
|
||||||
* a fairly expensive sort (involving string compares) so it helps to
|
* a fairly expensive sort (involving string compares) so it helps to
|
||||||
* store the result of that sort.
|
* store the result of that sort.
|
||||||
*/
|
*/
|
||||||
int IntrinsicRank;
|
int m_IntrinsicRank;
|
||||||
|
|
||||||
/// The score of an item resulting from the search algorithm.
|
int m_Score; // The score of an item resulting from the search algorithm.
|
||||||
int Score;
|
bool m_Pinned; // Item should appear at top when there is no search string
|
||||||
|
|
||||||
wxString Name; ///< Actual name of the part
|
wxString m_Name; // Actual name of the part
|
||||||
wxString Desc; ///< Description to be displayed
|
wxString m_Desc; // Description to be displayed
|
||||||
wxString MatchName; ///< Normalized name for matching
|
wxString m_MatchName; // Normalized name for matching
|
||||||
wxString SearchText; ///< Descriptive text to search
|
wxString m_SearchText; // Descriptive text to search
|
||||||
bool Normalized; ///< Support for lazy normalization.
|
bool m_Normalized; // Support for lazy normalization.
|
||||||
|
|
||||||
|
|
||||||
LIB_ID LibId; ///< LIB_ID determined by the parent library nickname and alias name.
|
LIB_ID m_LibId; // LIB_ID determined by the parent library nickname and alias name.
|
||||||
int Unit; ///< Actual unit, or zero
|
int m_Unit; // Actual unit, or zero
|
||||||
bool IsRoot; ///< Indicates if the symbol is a root symbol instead of an alias.
|
bool m_IsRoot; // Indicates if the symbol is a root symbol instead of an alias.
|
||||||
int VisLen; ///< Length of the string as shown on screen
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the score for this part. This is accumulative - it will be
|
* Update the score for this part. This is accumulative - it will be
|
||||||
|
@ -120,7 +120,7 @@ public:
|
||||||
void ResetScore();
|
void ResetScore();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store intrinsic ranks on all children of this node. See IntrinsicRank
|
* Store intrinsic ranks on all children of this node. See m_IntrinsicRank
|
||||||
* member doc for more information.
|
* member doc for more information.
|
||||||
*/
|
*/
|
||||||
void AssignIntrinsicRanks( bool presorted = false );
|
void AssignIntrinsicRanks( bool presorted = false );
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
|
|
||||||
#define LIST_COLUMN_WIDTH_KEY wxT( "SelectorColumnWidth" )
|
#define LIST_COLUMN_WIDTH_KEY wxT( "SelectorColumnWidth" )
|
||||||
|
#define PINNED_ITEMS_KEY wxT( "PinnedItems" )
|
||||||
|
|
||||||
static const int kDataViewIndent = 20;
|
static const int kDataViewIndent = 20;
|
||||||
|
|
||||||
|
@ -43,9 +44,9 @@ wxDataViewItem LIB_TREE_MODEL_ADAPTER::ToItem( LIB_TREE_NODE const* aNode )
|
||||||
/**
|
/**
|
||||||
* Convert wxDataViewItem -> CMP_TREE_NODE
|
* Convert wxDataViewItem -> CMP_TREE_NODE
|
||||||
*/
|
*/
|
||||||
LIB_TREE_NODE const* LIB_TREE_MODEL_ADAPTER::ToNode( wxDataViewItem aItem )
|
LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ToNode( wxDataViewItem aItem )
|
||||||
{
|
{
|
||||||
return static_cast<LIB_TREE_NODE const*>( aItem.GetID() );
|
return static_cast<LIB_TREE_NODE*>( aItem.GetID() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,9 +58,9 @@ unsigned int LIB_TREE_MODEL_ADAPTER::IntoArray( LIB_TREE_NODE const& aNode,
|
||||||
{
|
{
|
||||||
unsigned int n = 0;
|
unsigned int n = 0;
|
||||||
|
|
||||||
for( auto const& child: aNode.Children )
|
for( auto const& child: aNode.m_Children )
|
||||||
{
|
{
|
||||||
if( child->Score > 0 )
|
if( child->m_Score > 0 )
|
||||||
{
|
{
|
||||||
aChildren.Add( ToItem( &*child ) );
|
aChildren.Add( ToItem( &*child ) );
|
||||||
++n;
|
++n;
|
||||||
|
@ -91,6 +92,10 @@ LIB_TREE_MODEL_ADAPTER::LIB_TREE_MODEL_ADAPTER()
|
||||||
|
|
||||||
if( m_config->Read( m_configPrefix + LIST_COLUMN_WIDTH_KEY, &colWidth ) )
|
if( m_config->Read( m_configPrefix + LIST_COLUMN_WIDTH_KEY, &colWidth ) )
|
||||||
m_colWidths[PART_COL] = colWidth;
|
m_colWidths[PART_COL] = colWidth;
|
||||||
|
|
||||||
|
// JEY TODO NEW SETTINGS ARCH: read pinned items array....
|
||||||
|
//for( UFT8 pinnedItem : pinnedItems )
|
||||||
|
// m_pinnedLibIDs.insert( pinnedItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,6 +116,20 @@ void LIB_TREE_MODEL_ADAPTER::SaveColWidths()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LIB_TREE_MODEL_ADAPTER::SavePinnedItems()
|
||||||
|
{
|
||||||
|
// JEY TODO NEW SETTINGS ARCH: clear pinned items array in settings....
|
||||||
|
|
||||||
|
for( auto& child: m_tree.m_Children )
|
||||||
|
{
|
||||||
|
if( child->m_Pinned )
|
||||||
|
{
|
||||||
|
UTF8 pinnedItem = child->m_LibId.Format();
|
||||||
|
// JEY TODO NEW SETTINGS ARCH: add pinned entry to settings array....
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_TREE_MODEL_ADAPTER::SetFilter( CMP_FILTER_TYPE aFilter )
|
void LIB_TREE_MODEL_ADAPTER::SetFilter( CMP_FILTER_TYPE aFilter )
|
||||||
{
|
{
|
||||||
|
@ -137,6 +156,8 @@ void LIB_TREE_MODEL_ADAPTER::DoAddLibrary( wxString const& aNodeName, wxString c
|
||||||
{
|
{
|
||||||
LIB_TREE_NODE_LIB& lib_node = m_tree.AddLib( aNodeName, aDesc );
|
LIB_TREE_NODE_LIB& lib_node = m_tree.AddLib( aNodeName, aDesc );
|
||||||
|
|
||||||
|
lib_node.m_Pinned = m_pinnedLibIDs.count( lib_node.m_LibId.Format() ) > 0;
|
||||||
|
|
||||||
for( LIB_TREE_ITEM* item: aItemList )
|
for( LIB_TREE_ITEM* item: aItemList )
|
||||||
lib_node.AddItem( item );
|
lib_node.AddItem( item );
|
||||||
|
|
||||||
|
@ -148,6 +169,12 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( wxString const& aSearch )
|
||||||
{
|
{
|
||||||
m_tree.ResetScore();
|
m_tree.ResetScore();
|
||||||
|
|
||||||
|
for( auto& child: m_tree.m_Children )
|
||||||
|
{
|
||||||
|
if( child->m_Pinned )
|
||||||
|
child->m_Score *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
wxStringTokenizer tokenizer( aSearch );
|
wxStringTokenizer tokenizer( aSearch );
|
||||||
|
|
||||||
while( tokenizer.HasMoreTokens() )
|
while( tokenizer.HasMoreTokens() )
|
||||||
|
@ -267,21 +294,27 @@ LIB_ID LIB_TREE_MODEL_ADAPTER::GetAliasFor( const wxDataViewItem& aSelection ) c
|
||||||
if( !node )
|
if( !node )
|
||||||
return emptyId;
|
return emptyId;
|
||||||
|
|
||||||
return node->LibId;
|
return node->m_LibId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int LIB_TREE_MODEL_ADAPTER::GetUnitFor( const wxDataViewItem& aSelection ) const
|
int LIB_TREE_MODEL_ADAPTER::GetUnitFor( const wxDataViewItem& aSelection ) const
|
||||||
{
|
{
|
||||||
const LIB_TREE_NODE* node = ToNode( aSelection );
|
const LIB_TREE_NODE* node = ToNode( aSelection );
|
||||||
return node ? node->Unit : 0;
|
return node ? node->m_Unit : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LIB_TREE_NODE::TYPE LIB_TREE_MODEL_ADAPTER::GetTypeFor( const wxDataViewItem& aSelection ) const
|
LIB_TREE_NODE::TYPE LIB_TREE_MODEL_ADAPTER::GetTypeFor( const wxDataViewItem& aSelection ) const
|
||||||
{
|
{
|
||||||
const LIB_TREE_NODE* node = ToNode( aSelection );
|
const LIB_TREE_NODE* node = ToNode( aSelection );
|
||||||
return node ? node->Type : LIB_TREE_NODE::INVALID;
|
return node ? node->m_Type : LIB_TREE_NODE::INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::GetTreeNodeFor( const wxDataViewItem& aSelection ) const
|
||||||
|
{
|
||||||
|
return ToNode( aSelection );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -289,8 +322,8 @@ int LIB_TREE_MODEL_ADAPTER::GetItemCount() const
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
for( const std::unique_ptr<LIB_TREE_NODE>& lib: m_tree.Children )
|
for( const std::unique_ptr<LIB_TREE_NODE>& lib: m_tree.m_Children )
|
||||||
n += lib->Children.size();
|
n += lib->m_Children.size();
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -298,18 +331,18 @@ int LIB_TREE_MODEL_ADAPTER::GetItemCount() const
|
||||||
|
|
||||||
wxDataViewItem LIB_TREE_MODEL_ADAPTER::FindItem( const LIB_ID& aLibId )
|
wxDataViewItem LIB_TREE_MODEL_ADAPTER::FindItem( const LIB_ID& aLibId )
|
||||||
{
|
{
|
||||||
for( auto& lib: m_tree.Children )
|
for( auto& lib: m_tree.m_Children )
|
||||||
{
|
{
|
||||||
if( lib->Name != aLibId.GetLibNickname() )
|
if( lib->m_Name != aLibId.GetLibNickname() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// if part name is not specified, return the library node
|
// if part name is not specified, return the library node
|
||||||
if( aLibId.GetLibItemName() == "" )
|
if( aLibId.GetLibItemName() == "" )
|
||||||
return ToItem( lib.get() );
|
return ToItem( lib.get() );
|
||||||
|
|
||||||
for( auto& alias: lib->Children )
|
for( auto& alias: lib->m_Children )
|
||||||
{
|
{
|
||||||
if( alias->Name == aLibId.GetLibItemName() )
|
if( alias->m_Name == aLibId.GetLibItemName() )
|
||||||
return ToItem( alias.get() );
|
return ToItem( alias.get() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,8 +358,8 @@ unsigned int LIB_TREE_MODEL_ADAPTER::GetChildren( wxDataViewItem const& aItem,
|
||||||
{
|
{
|
||||||
auto node = ( aItem.IsOk() ? ToNode( aItem ) : &m_tree );
|
auto node = ( aItem.IsOk() ? ToNode( aItem ) : &m_tree );
|
||||||
|
|
||||||
if( node->Type != LIB_TREE_NODE::TYPE::LIBID
|
if( node->m_Type != LIB_TREE_NODE::TYPE::LIBID
|
||||||
|| ( m_show_units && node->Type == LIB_TREE_NODE::TYPE::LIBID ) )
|
|| ( m_show_units && node->m_Type == LIB_TREE_NODE::TYPE::LIBID ) )
|
||||||
return IntoArray( *node, aChildren );
|
return IntoArray( *node, aChildren );
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -342,18 +375,18 @@ bool LIB_TREE_MODEL_ADAPTER::HasContainerColumns( wxDataViewItem const& aItem )
|
||||||
bool LIB_TREE_MODEL_ADAPTER::IsContainer( wxDataViewItem const& aItem ) const
|
bool LIB_TREE_MODEL_ADAPTER::IsContainer( wxDataViewItem const& aItem ) const
|
||||||
{
|
{
|
||||||
auto node = ToNode( aItem );
|
auto node = ToNode( aItem );
|
||||||
return node ? node->Children.size() : true;
|
return node ? node->m_Children.size() : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wxDataViewItem LIB_TREE_MODEL_ADAPTER::GetParent( wxDataViewItem const& aItem ) const
|
wxDataViewItem LIB_TREE_MODEL_ADAPTER::GetParent( wxDataViewItem const& aItem ) const
|
||||||
{
|
{
|
||||||
auto node = ToNode( aItem );
|
auto node = ToNode( aItem );
|
||||||
auto parent = node ? node->Parent : nullptr;
|
auto parent = node ? node->m_Parent : nullptr;
|
||||||
|
|
||||||
// wxDataViewModel has no root node, but rather top-level elements have
|
// wxDataViewModel has no root node, but rather top-level elements have
|
||||||
// an invalid (null) parent.
|
// an invalid (null) parent.
|
||||||
if( !node || !parent || parent->Type == LIB_TREE_NODE::TYPE::ROOT )
|
if( !node || !parent || parent->m_Type == LIB_TREE_NODE::TYPE::ROOT )
|
||||||
return ToItem( nullptr );
|
return ToItem( nullptr );
|
||||||
else
|
else
|
||||||
return ToItem( parent );
|
return ToItem( parent );
|
||||||
|
@ -377,10 +410,10 @@ void LIB_TREE_MODEL_ADAPTER::GetValue( wxVariant& aVariant,
|
||||||
{
|
{
|
||||||
default: // column == -1 is used for default Compare function
|
default: // column == -1 is used for default Compare function
|
||||||
case 0:
|
case 0:
|
||||||
aVariant = node->Name;
|
aVariant = node->m_Name;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
aVariant = node->Desc;
|
aVariant = node->m_Desc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -396,13 +429,13 @@ bool LIB_TREE_MODEL_ADAPTER::GetAttr( wxDataViewItem const& aItem,
|
||||||
auto node = ToNode( aItem );
|
auto node = ToNode( aItem );
|
||||||
wxASSERT( node );
|
wxASSERT( node );
|
||||||
|
|
||||||
if( node->Type != LIB_TREE_NODE::LIBID )
|
if( node->m_Type != LIB_TREE_NODE::LIBID )
|
||||||
{
|
{
|
||||||
// Currently only aliases are formatted at all
|
// Currently only aliases are formatted at all
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !node->IsRoot && aCol == 0 )
|
if( !node->m_IsRoot && aCol == 0 )
|
||||||
{
|
{
|
||||||
// Names of non-root aliases are italicized
|
// Names of non-root aliases are italicized
|
||||||
aAttr.SetItalic( true );
|
aAttr.SetItalic( true );
|
||||||
|
@ -419,14 +452,14 @@ void LIB_TREE_MODEL_ADAPTER::FindAndExpand( LIB_TREE_NODE& aNode,
|
||||||
std::function<bool( LIB_TREE_NODE const* )> aFunc,
|
std::function<bool( LIB_TREE_NODE const* )> aFunc,
|
||||||
LIB_TREE_NODE** aHighScore )
|
LIB_TREE_NODE** aHighScore )
|
||||||
{
|
{
|
||||||
for( auto& node: aNode.Children )
|
for( auto& node: aNode.m_Children )
|
||||||
{
|
{
|
||||||
if( aFunc( &*node ) )
|
if( aFunc( &*node ) )
|
||||||
{
|
{
|
||||||
auto item = wxDataViewItem( &*node );
|
auto item = wxDataViewItem( &*node );
|
||||||
m_widget->ExpandAncestors( item );
|
m_widget->ExpandAncestors( item );
|
||||||
|
|
||||||
if( !(*aHighScore) || node->Score > (*aHighScore)->Score )
|
if( !(*aHighScore) || node->m_Score > (*aHighScore)->m_Score )
|
||||||
(*aHighScore) = &*node;
|
(*aHighScore) = &*node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,7 +476,7 @@ LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowResults()
|
||||||
[]( LIB_TREE_NODE const* n )
|
[]( LIB_TREE_NODE const* n )
|
||||||
{
|
{
|
||||||
// return leaf nodes with some level of matching
|
// return leaf nodes with some level of matching
|
||||||
return n->Type == LIB_TREE_NODE::TYPE::LIBID && n->Score > 1;
|
return n->m_Type == LIB_TREE_NODE::TYPE::LIBID && n->m_Score > 1;
|
||||||
},
|
},
|
||||||
&highScore );
|
&highScore );
|
||||||
|
|
||||||
|
@ -461,10 +494,10 @@ LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowPreselect()
|
||||||
FindAndExpand( m_tree,
|
FindAndExpand( m_tree,
|
||||||
[&]( LIB_TREE_NODE const* n )
|
[&]( LIB_TREE_NODE const* n )
|
||||||
{
|
{
|
||||||
if( n->Type == LIB_TREE_NODE::LIBID && ( n->Children.empty() || !m_preselect_unit ) )
|
if( n->m_Type == LIB_TREE_NODE::LIBID && ( n->m_Children.empty() || !m_preselect_unit ) )
|
||||||
return m_preselect_lib_id == n->LibId;
|
return m_preselect_lib_id == n->m_LibId;
|
||||||
else if( n->Type == LIB_TREE_NODE::UNIT && m_preselect_unit )
|
else if( n->m_Type == LIB_TREE_NODE::UNIT && m_preselect_unit )
|
||||||
return m_preselect_lib_id == n->Parent->LibId && m_preselect_unit == n->Unit;
|
return m_preselect_lib_id == n->m_Parent->m_LibId && m_preselect_unit == n->m_Unit;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
@ -481,8 +514,8 @@ LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowSingleLibrary()
|
||||||
FindAndExpand( m_tree,
|
FindAndExpand( m_tree,
|
||||||
[]( LIB_TREE_NODE const* n )
|
[]( LIB_TREE_NODE const* n )
|
||||||
{
|
{
|
||||||
return n->Type == LIB_TREE_NODE::TYPE::LIBID &&
|
return n->m_Type == LIB_TREE_NODE::TYPE::LIBID &&
|
||||||
n->Parent->Parent->Children.size() == 1;
|
n->m_Parent->m_Parent->m_Children.size() == 1;
|
||||||
},
|
},
|
||||||
&highScore );
|
&highScore );
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <wx/headerctrl.h>
|
#include <wx/headerctrl.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter class in the component selector Model-View-Adapter (mediated MVC)
|
* Adapter class in the component selector Model-View-Adapter (mediated MVC)
|
||||||
|
@ -129,6 +130,7 @@ public:
|
||||||
* valid.
|
* valid.
|
||||||
*/
|
*/
|
||||||
void SaveColWidths();
|
void SaveColWidths();
|
||||||
|
void SavePinnedItems();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the component filter type. Must be set before adding libraries
|
* Set the component filter type. Must be set before adding libraries
|
||||||
|
@ -222,6 +224,8 @@ public:
|
||||||
*/
|
*/
|
||||||
LIB_TREE_NODE::TYPE GetTypeFor( const wxDataViewItem& aSelection ) const;
|
LIB_TREE_NODE::TYPE GetTypeFor( const wxDataViewItem& aSelection ) const;
|
||||||
|
|
||||||
|
LIB_TREE_NODE* GetTreeNodeFor( const wxDataViewItem& aSelection ) const;
|
||||||
|
|
||||||
virtual wxString GenerateInfo( LIB_ID const& aLibId, int aUnit ) { return wxEmptyString; };
|
virtual wxString GenerateInfo( LIB_ID const& aLibId, int aUnit ) { return wxEmptyString; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -234,7 +238,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual int GetLibrariesCount() const
|
virtual int GetLibrariesCount() const
|
||||||
{
|
{
|
||||||
return m_tree.Children.size();
|
return m_tree.m_Children.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -265,7 +269,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static wxDataViewItem ToItem( LIB_TREE_NODE const* aNode );
|
static wxDataViewItem ToItem( LIB_TREE_NODE const* aNode );
|
||||||
static LIB_TREE_NODE const* ToNode( wxDataViewItem aItem );
|
static LIB_TREE_NODE* ToNode( wxDataViewItem aItem );
|
||||||
static unsigned int IntoArray( LIB_TREE_NODE const& aNode, wxDataViewItemArray& aChildren );
|
static unsigned int IntoArray( LIB_TREE_NODE const& aNode, wxDataViewItemArray& aChildren );
|
||||||
|
|
||||||
LIB_TREE_NODE_ROOT m_tree;
|
LIB_TREE_NODE_ROOT m_tree;
|
||||||
|
@ -343,6 +347,8 @@ private:
|
||||||
wxConfigBase* m_config;
|
wxConfigBase* m_config;
|
||||||
wxString m_configPrefix;
|
wxString m_configPrefix;
|
||||||
|
|
||||||
|
std::set<UTF8> m_pinnedLibIDs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find any results worth highlighting and expand them, according to given
|
* Find any results worth highlighting and expand them, according to given
|
||||||
* criteria (f(CMP_TREE_NODE const*) -> bool)
|
* criteria (f(CMP_TREE_NODE const*) -> bool)
|
||||||
|
|
|
@ -356,18 +356,26 @@ TOOL_ACTION ACTIONS::cursorRightFast( "common.Control.cursorRightFast",
|
||||||
TOOL_ACTION ACTIONS::cursorClick( "common.Control.cursorClick",
|
TOOL_ACTION ACTIONS::cursorClick( "common.Control.cursorClick",
|
||||||
AS_GLOBAL,
|
AS_GLOBAL,
|
||||||
WXK_RETURN, LEGACY_HK_NAME( "Mouse Left Click" ),
|
WXK_RETURN, LEGACY_HK_NAME( "Mouse Left Click" ),
|
||||||
_( "Click" ), "Performs left mouse button click",
|
_( "Click" ), _( "Performs left mouse button click" ),
|
||||||
nullptr, AF_NONE, (void*) CURSOR_CLICK );
|
nullptr, AF_NONE, (void*) CURSOR_CLICK );
|
||||||
|
|
||||||
TOOL_ACTION ACTIONS::cursorDblClick( "common.Control.cursorDblClick",
|
TOOL_ACTION ACTIONS::cursorDblClick( "common.Control.cursorDblClick",
|
||||||
AS_GLOBAL,
|
AS_GLOBAL,
|
||||||
WXK_END, LEGACY_HK_NAME( "Mouse Left Double Click" ),
|
WXK_END, LEGACY_HK_NAME( "Mouse Left Double Click" ),
|
||||||
_( "Double-click" ), "Performs left mouse button double-click",
|
_( "Double-click" ), _( "Performs left mouse button double-click" ),
|
||||||
nullptr, AF_NONE, (void*) CURSOR_DBL_CLICK );
|
nullptr, AF_NONE, (void*) CURSOR_DBL_CLICK );
|
||||||
|
|
||||||
TOOL_ACTION ACTIONS::refreshPreview( "common.Control.refreshPreview",
|
TOOL_ACTION ACTIONS::refreshPreview( "common.Control.refreshPreview",
|
||||||
AS_GLOBAL );
|
AS_GLOBAL );
|
||||||
|
|
||||||
|
TOOL_ACTION ACTIONS::pinLibrary( "common.Control.pinLibrary",
|
||||||
|
AS_GLOBAL, 0, "",
|
||||||
|
_( "Pin Library" ), "Keep the library at the top of the list" );
|
||||||
|
|
||||||
|
TOOL_ACTION ACTIONS::unpinLibrary( "common.Control.unpinLibrary",
|
||||||
|
AS_GLOBAL, 0, "",
|
||||||
|
_( "Unpin Library" ), "No longer keep the library at the top of the list" );
|
||||||
|
|
||||||
TOOL_ACTION ACTIONS::panUp( "common.Control.panUp",
|
TOOL_ACTION ACTIONS::panUp( "common.Control.panUp",
|
||||||
AS_GLOBAL,
|
AS_GLOBAL,
|
||||||
MD_SHIFT + WXK_UP, "",
|
MD_SHIFT + WXK_UP, "",
|
||||||
|
|
|
@ -139,6 +139,8 @@ LIB_TREE::~LIB_TREE()
|
||||||
{
|
{
|
||||||
// Save the column widths to the config file
|
// Save the column widths to the config file
|
||||||
m_adapter->SaveColWidths();
|
m_adapter->SaveColWidths();
|
||||||
|
|
||||||
|
m_adapter->SavePinnedItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,6 +162,17 @@ LIB_ID LIB_TREE::GetSelectedLibId( int* aUnit ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_TREE_NODE* LIB_TREE::GetCurrentTreeNode() const
|
||||||
|
{
|
||||||
|
auto sel = m_tree_ctrl->GetSelection();
|
||||||
|
|
||||||
|
if( !sel )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return m_adapter->GetTreeNodeFor( sel );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_TREE::SelectLibId( const LIB_ID& aLibId )
|
void LIB_TREE::SelectLibId( const LIB_ID& aLibId )
|
||||||
{
|
{
|
||||||
selectIfValid( m_adapter->FindItem( aLibId ) );
|
selectIfValid( m_adapter->FindItem( aLibId ) );
|
||||||
|
|
|
@ -71,6 +71,8 @@ public:
|
||||||
*/
|
*/
|
||||||
LIB_ID GetSelectedLibId( int* aUnit = nullptr ) const;
|
LIB_ID GetSelectedLibId( int* aUnit = nullptr ) const;
|
||||||
|
|
||||||
|
LIB_TREE_NODE* GetCurrentTreeNode() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select an item in the tree widget.
|
* Select an item in the tree widget.
|
||||||
*/
|
*/
|
||||||
|
@ -136,6 +138,7 @@ protected:
|
||||||
{
|
{
|
||||||
///> List of expanded nodes
|
///> List of expanded nodes
|
||||||
std::vector<wxDataViewItem> expanded;
|
std::vector<wxDataViewItem> expanded;
|
||||||
|
std::vector<wxString> pinned;
|
||||||
|
|
||||||
///> Current selection, might be not valid if nothing was selected
|
///> Current selection, might be not valid if nothing was selected
|
||||||
LIB_ID selection;
|
LIB_ID selection;
|
||||||
|
|
|
@ -540,6 +540,12 @@ LIB_ID LIB_EDIT_FRAME::getTargetLibId() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_TREE_NODE* LIB_EDIT_FRAME::GetCurrentTreeNode() const
|
||||||
|
{
|
||||||
|
return m_treePane->GetLibTree()->GetCurrentTreeNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString LIB_EDIT_FRAME::getTargetLib() const
|
wxString LIB_EDIT_FRAME::getTargetLib() const
|
||||||
{
|
{
|
||||||
return getTargetLibId().GetLibNickname();
|
return getTargetLibId().GetLibNickname();
|
||||||
|
@ -583,7 +589,7 @@ void LIB_EDIT_FRAME::SyncLibraries( bool aShowProgress )
|
||||||
m_treePane->GetLibTree()->Unselect();
|
m_treePane->GetLibTree()->Unselect();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_treePane->Regenerate();
|
m_treePane->GetLibTree()->Regenerate( true );
|
||||||
|
|
||||||
// Try to select the parent library, in case the part is not found
|
// Try to select the parent library, in case the part is not found
|
||||||
if( !found && selected.IsValid() )
|
if( !found && selected.IsValid() )
|
||||||
|
@ -605,6 +611,17 @@ void LIB_EDIT_FRAME::SyncLibraries( bool aShowProgress )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_FRAME::RegenerateLibraryTree()
|
||||||
|
{
|
||||||
|
LIB_ID target = getTargetLibId();
|
||||||
|
|
||||||
|
m_treePane->GetLibTree()->Regenerate( true );
|
||||||
|
|
||||||
|
if( target.IsValid() )
|
||||||
|
m_treePane->GetLibTree()->CenterLibId( target );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SYMBOL_LIB_TABLE* LIB_EDIT_FRAME::selectSymLibTable( bool aOptional )
|
SYMBOL_LIB_TABLE* LIB_EDIT_FRAME::selectSymLibTable( bool aOptional )
|
||||||
{
|
{
|
||||||
wxArrayString libTableNames;
|
wxArrayString libTableNames;
|
||||||
|
|
|
@ -40,6 +40,7 @@ class LIB_PART;
|
||||||
class LIB_FIELD;
|
class LIB_FIELD;
|
||||||
class DIALOG_LIB_EDIT_TEXT;
|
class DIALOG_LIB_EDIT_TEXT;
|
||||||
class SYMBOL_TREE_PANE;
|
class SYMBOL_TREE_PANE;
|
||||||
|
class LIB_TREE_NODE;
|
||||||
class LIB_ID;
|
class LIB_ID;
|
||||||
class LIB_MANAGER;
|
class LIB_MANAGER;
|
||||||
|
|
||||||
|
@ -146,6 +147,8 @@ public:
|
||||||
/** Sets the current library nickname and returns the old library nickname. */
|
/** Sets the current library nickname and returns the old library nickname. */
|
||||||
wxString SetCurLib( const wxString& aLibNickname );
|
wxString SetCurLib( const wxString& aLibNickname );
|
||||||
|
|
||||||
|
LIB_TREE_NODE* GetCurrentTreeNode() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the LIB_ID of the library or symbol selected in the symbol tree.
|
* Return the LIB_ID of the library or symbol selected in the symbol tree.
|
||||||
*/
|
*/
|
||||||
|
@ -417,6 +420,12 @@ public:
|
||||||
*/
|
*/
|
||||||
void SyncLibraries( bool aShowProgress );
|
void SyncLibraries( bool aShowProgress );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter, sort, and redisplay the library tree. Does NOT synchronize it with libraries
|
||||||
|
* in disk.
|
||||||
|
*/
|
||||||
|
void RegenerateLibraryTree();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows Libedit to install its preferences panel into the preferences dialog.
|
* Allows Libedit to install its preferences panel into the preferences dialog.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -617,7 +617,7 @@ SCH_SHEET* SCH_LEGACY_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway,
|
||||||
if( m_path.IsEmpty() )
|
if( m_path.IsEmpty() )
|
||||||
m_path = aKiway->Prj().GetProjectPath();
|
m_path = aKiway->Prj().GetProjectPath();
|
||||||
|
|
||||||
wxLogTrace( traceSchLegacyPlugin, "Normalized append path \"%s\".", m_path );
|
wxLogTrace( traceSchLegacyPlugin, "m_Normalized append path \"%s\".", m_path );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,7 +56,7 @@ TOOL_INTERACTIVE* SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetContextMenuTool()
|
||||||
bool SYMBOL_TREE_SYNCHRONIZING_ADAPTER::IsContainer( const wxDataViewItem& aItem ) const
|
bool SYMBOL_TREE_SYNCHRONIZING_ADAPTER::IsContainer( const wxDataViewItem& aItem ) const
|
||||||
{
|
{
|
||||||
const LIB_TREE_NODE* node = ToNode( aItem );
|
const LIB_TREE_NODE* node = ToNode( aItem );
|
||||||
return node ? node->Type == LIB_TREE_NODE::LIB : true;
|
return node ? node->m_Type == LIB_TREE_NODE::LIB : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,9 +76,9 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::Sync( bool aForce,
|
||||||
int i = 0, max = GetLibrariesCount();
|
int i = 0, max = GetLibrariesCount();
|
||||||
|
|
||||||
// Process already stored libraries
|
// Process already stored libraries
|
||||||
for( auto it = m_tree.Children.begin(); it != m_tree.Children.end(); /* iteration inside */ )
|
for( auto it = m_tree.m_Children.begin(); it != m_tree.m_Children.end(); /* iteration inside */ )
|
||||||
{
|
{
|
||||||
const wxString& name = it->get()->Name;
|
const wxString& name = it->get()->m_Name;
|
||||||
|
|
||||||
if( wxGetUTCTimeMillis() > nextUpdate )
|
if( wxGetUTCTimeMillis() > nextUpdate )
|
||||||
{
|
{
|
||||||
|
@ -142,25 +142,25 @@ int SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetLibrariesCount() const
|
||||||
|
|
||||||
void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNode )
|
void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNode )
|
||||||
{
|
{
|
||||||
auto hashIt = m_libHashes.find( aLibNode.Name );
|
auto hashIt = m_libHashes.find( aLibNode.m_Name );
|
||||||
|
|
||||||
if( hashIt == m_libHashes.end() )
|
if( hashIt == m_libHashes.end() )
|
||||||
{
|
{
|
||||||
// add a new library
|
// add a new library
|
||||||
for( auto alias : m_libMgr->GetAliases( aLibNode.Name ) )
|
for( auto alias : m_libMgr->GetAliases( aLibNode.m_Name ) )
|
||||||
aLibNode.AddItem( alias );
|
aLibNode.AddItem( alias );
|
||||||
}
|
}
|
||||||
else if( hashIt->second != m_libMgr->GetLibraryHash( aLibNode.Name ) )
|
else if( hashIt->second != m_libMgr->GetLibraryHash( aLibNode.m_Name ) )
|
||||||
{
|
{
|
||||||
// update an existing library
|
// update an existing library
|
||||||
std::list<LIB_PART*> aliases = m_libMgr->GetAliases( aLibNode.Name );
|
std::list<LIB_PART*> aliases = m_libMgr->GetAliases( aLibNode.m_Name );
|
||||||
|
|
||||||
// remove the common part from the aliases list
|
// remove the common part from the aliases list
|
||||||
for( auto nodeIt = aLibNode.Children.begin(); nodeIt != aLibNode.Children.end(); /**/ )
|
for( auto nodeIt = aLibNode.m_Children.begin(); nodeIt != aLibNode.m_Children.end(); /**/ )
|
||||||
{
|
{
|
||||||
auto aliasIt = std::find_if( aliases.begin(), aliases.end(),
|
auto aliasIt = std::find_if( aliases.begin(), aliases.end(),
|
||||||
[&] ( const LIB_PART* a ) {
|
[&] ( const LIB_PART* a ) {
|
||||||
return a->GetName() == (*nodeIt)->Name;
|
return a->GetName() == (*nodeIt)->m_Name;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
if( aliasIt != aliases.end() )
|
if( aliasIt != aliases.end() )
|
||||||
|
@ -174,7 +174,7 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNo
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// node does not exist in the library manager, remove the corresponding node
|
// node does not exist in the library manager, remove the corresponding node
|
||||||
nodeIt = aLibNode.Children.erase( nodeIt );
|
nodeIt = aLibNode.m_Children.erase( nodeIt );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNo
|
||||||
}
|
}
|
||||||
|
|
||||||
aLibNode.AssignIntrinsicRanks();
|
aLibNode.AssignIntrinsicRanks();
|
||||||
m_libHashes[aLibNode.Name] = m_libMgr->GetLibraryHash( aLibNode.Name );
|
m_libHashes[aLibNode.m_Name] = m_libMgr->GetLibraryHash( aLibNode.m_Name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -192,8 +192,8 @@ LIB_TREE_NODE::PTR_VECTOR::iterator SYMBOL_TREE_SYNCHRONIZING_ADAPTER::deleteLib
|
||||||
LIB_TREE_NODE::PTR_VECTOR::iterator& aLibNodeIt )
|
LIB_TREE_NODE::PTR_VECTOR::iterator& aLibNodeIt )
|
||||||
{
|
{
|
||||||
LIB_TREE_NODE* node = aLibNodeIt->get();
|
LIB_TREE_NODE* node = aLibNodeIt->get();
|
||||||
m_libHashes.erase( node->Name );
|
m_libHashes.erase( node->m_Name );
|
||||||
auto it = m_tree.Children.erase( aLibNodeIt );
|
auto it = m_tree.m_Children.erase( aLibNodeIt );
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,25 +213,28 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataVie
|
||||||
switch( aCol )
|
switch( aCol )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
aVariant = node->Name;
|
aVariant = node->m_Name;
|
||||||
|
|
||||||
|
if( node->m_Pinned )
|
||||||
|
aVariant = "☆ " + node->m_Name;
|
||||||
|
|
||||||
// mark modified libs with an asterisk
|
// mark modified libs with an asterisk
|
||||||
if( node->Type == LIB_TREE_NODE::LIB && m_libMgr->IsLibraryModified( node->Name ) )
|
if( node->m_Type == LIB_TREE_NODE::LIB && m_libMgr->IsLibraryModified( node->m_Name ) )
|
||||||
aVariant = node->Name + " *";
|
aVariant = aVariant.GetString() + " *";
|
||||||
|
|
||||||
// mark modified parts with an aster-ix
|
// mark modified parts with an aster-ix
|
||||||
if( node->Type == LIB_TREE_NODE::LIBID
|
if( node->m_Type == LIB_TREE_NODE::LIBID
|
||||||
&& m_libMgr->IsPartModified( node->Name, node->Parent->Name ) )
|
&& m_libMgr->IsPartModified( node->m_Name, node->m_Parent->m_Name ) )
|
||||||
aVariant = node->Name + " *";
|
aVariant = aVariant.GetString() + " *";
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
aVariant = node->Desc;
|
aVariant = node->m_Desc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // column == -1 is used for default Compare function
|
default: // column == -1 is used for default Compare function
|
||||||
aVariant = node->Name;
|
aVariant = node->m_Name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,11 +253,11 @@ bool SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, un
|
||||||
auto node = ToNode( aItem );
|
auto node = ToNode( aItem );
|
||||||
wxCHECK( node, false );
|
wxCHECK( node, false );
|
||||||
|
|
||||||
switch( node->Type )
|
switch( node->m_Type )
|
||||||
{
|
{
|
||||||
case LIB_TREE_NODE::LIB:
|
case LIB_TREE_NODE::LIB:
|
||||||
// mark modified libs with bold font
|
// mark modified libs with bold font
|
||||||
aAttr.SetBold( m_libMgr->IsLibraryModified( node->Name ) );
|
aAttr.SetBold( m_libMgr->IsLibraryModified( node->m_Name ) );
|
||||||
|
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
// The native wxGTK+ impl ignores background colour, so set the text colour instead.
|
// The native wxGTK+ impl ignores background colour, so set the text colour instead.
|
||||||
|
@ -263,7 +266,7 @@ bool SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, un
|
||||||
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
|
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
|
||||||
#else
|
#else
|
||||||
// mark the current library with background color
|
// mark the current library with background color
|
||||||
if( node->Name == m_libMgr->GetCurrentLib() )
|
if( node->m_Name == m_libMgr->GetCurrentLib() )
|
||||||
{
|
{
|
||||||
aAttr.SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
|
aAttr.SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
|
||||||
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT ) );
|
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT ) );
|
||||||
|
@ -273,10 +276,10 @@ bool SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, un
|
||||||
|
|
||||||
case LIB_TREE_NODE::LIBID:
|
case LIB_TREE_NODE::LIBID:
|
||||||
// mark modified part with bold font
|
// mark modified part with bold font
|
||||||
aAttr.SetBold( m_libMgr->IsPartModified( node->Name, node->Parent->Name ) );
|
aAttr.SetBold( m_libMgr->IsPartModified( node->m_Name, node->m_Parent->m_Name ) );
|
||||||
|
|
||||||
// mark aliases with italic font
|
// mark aliases with italic font
|
||||||
aAttr.SetItalic( !node->IsRoot );
|
aAttr.SetItalic( !node->m_IsRoot );
|
||||||
|
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
// The native wxGTK+ impl ignores background colour, so set the text colour instead.
|
// The native wxGTK+ impl ignores background colour, so set the text colour instead.
|
||||||
|
@ -285,7 +288,7 @@ bool SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, un
|
||||||
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
|
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
|
||||||
#else
|
#else
|
||||||
// mark the current part with background color
|
// mark the current part with background color
|
||||||
if( node->LibId == m_libMgr->GetCurrentLibId() )
|
if( node->m_LibId == m_libMgr->GetCurrentLibId() )
|
||||||
{
|
{
|
||||||
aAttr.SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
|
aAttr.SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
|
||||||
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT ) );
|
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT ) );
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <tools/lib_control.h>
|
#include <tools/lib_control.h>
|
||||||
#include <lib_edit_frame.h>
|
#include <lib_edit_frame.h>
|
||||||
#include <lib_view_frame.h>
|
#include <lib_view_frame.h>
|
||||||
|
#include <symbol_tree_model_adapter.h>
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
#include <gestfich.h>
|
#include <gestfich.h>
|
||||||
#include <project.h>
|
#include <project.h>
|
||||||
|
@ -51,11 +52,23 @@ bool LIB_CONTROL::Init()
|
||||||
LIB_ID sel = editFrame->GetTreeLIBID();
|
LIB_ID sel = editFrame->GetTreeLIBID();
|
||||||
return !sel.GetLibNickname().empty() && sel.GetLibItemName().empty();
|
return !sel.GetLibNickname().empty() && sel.GetLibItemName().empty();
|
||||||
};
|
};
|
||||||
|
auto pinnedLibSelectedCondition = [ editFrame ] ( const SELECTION& aSel ) {
|
||||||
|
LIB_TREE_NODE* current = editFrame->GetCurrentTreeNode();
|
||||||
|
return current && current->m_Type == LIB_TREE_NODE::LIB && current->m_Pinned;
|
||||||
|
};
|
||||||
|
auto unpinnedLibSelectedCondition = [ editFrame ] (const SELECTION& aSel ) {
|
||||||
|
LIB_TREE_NODE* current = editFrame->GetCurrentTreeNode();
|
||||||
|
return current && current->m_Type == LIB_TREE_NODE::LIB && !current->m_Pinned;
|
||||||
|
};
|
||||||
auto symbolSelectedCondition = [ editFrame ] ( const SELECTION& aSel ) {
|
auto symbolSelectedCondition = [ editFrame ] ( const SELECTION& aSel ) {
|
||||||
LIB_ID sel = editFrame->GetTreeLIBID();
|
LIB_ID sel = editFrame->GetTreeLIBID();
|
||||||
return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
|
return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ctxMenu.AddItem( ACTIONS::pinLibrary, unpinnedLibSelectedCondition );
|
||||||
|
ctxMenu.AddItem( ACTIONS::unpinLibrary, pinnedLibSelectedCondition );
|
||||||
|
ctxMenu.AddSeparator();
|
||||||
|
|
||||||
ctxMenu.AddItem( ACTIONS::newLibrary, SELECTION_CONDITIONS::ShowAlways );
|
ctxMenu.AddItem( ACTIONS::newLibrary, SELECTION_CONDITIONS::ShowAlways );
|
||||||
ctxMenu.AddItem( ACTIONS::addLibrary, SELECTION_CONDITIONS::ShowAlways );
|
ctxMenu.AddItem( ACTIONS::addLibrary, SELECTION_CONDITIONS::ShowAlways );
|
||||||
ctxMenu.AddItem( ACTIONS::save, libSelectedCondition );
|
ctxMenu.AddItem( ACTIONS::save, libSelectedCondition );
|
||||||
|
@ -220,6 +233,42 @@ int LIB_CONTROL::OnDeMorgan( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_CONTROL::PinLibrary( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
if( m_frame->IsType( FRAME_SCH_LIB_EDITOR ) )
|
||||||
|
{
|
||||||
|
LIB_EDIT_FRAME* editFrame = static_cast<LIB_EDIT_FRAME*>( m_frame );
|
||||||
|
LIB_TREE_NODE* currentNode = editFrame->GetCurrentTreeNode();
|
||||||
|
|
||||||
|
if( currentNode && !currentNode->m_Pinned )
|
||||||
|
{
|
||||||
|
currentNode->m_Pinned = true;
|
||||||
|
editFrame->RegenerateLibraryTree();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_CONTROL::UnpinLibrary( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
if( m_frame->IsType( FRAME_SCH_LIB_EDITOR ) )
|
||||||
|
{
|
||||||
|
LIB_EDIT_FRAME* editFrame = static_cast<LIB_EDIT_FRAME*>( m_frame );
|
||||||
|
LIB_TREE_NODE* currentNode = editFrame->GetCurrentTreeNode();
|
||||||
|
|
||||||
|
if( currentNode && currentNode->m_Pinned )
|
||||||
|
{
|
||||||
|
currentNode->m_Pinned = false;
|
||||||
|
editFrame->RegenerateLibraryTree();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int LIB_CONTROL::ShowComponentTree( const TOOL_EVENT& aEvent )
|
int LIB_CONTROL::ShowComponentTree( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
if( m_frame->IsType( FRAME_SCH_LIB_EDITOR ) )
|
if( m_frame->IsType( FRAME_SCH_LIB_EDITOR ) )
|
||||||
|
@ -435,6 +484,8 @@ void LIB_CONTROL::setTransitions()
|
||||||
Go( &LIB_CONTROL::OnDeMorgan, EE_ACTIONS::showDeMorganAlternate.MakeEvent() );
|
Go( &LIB_CONTROL::OnDeMorgan, EE_ACTIONS::showDeMorganAlternate.MakeEvent() );
|
||||||
|
|
||||||
Go( &LIB_CONTROL::ShowElectricalTypes, EE_ACTIONS::showElectricalTypes.MakeEvent() );
|
Go( &LIB_CONTROL::ShowElectricalTypes, EE_ACTIONS::showElectricalTypes.MakeEvent() );
|
||||||
|
Go( &LIB_CONTROL::PinLibrary, ACTIONS::pinLibrary.MakeEvent() );
|
||||||
|
Go( &LIB_CONTROL::UnpinLibrary, ACTIONS::unpinLibrary.MakeEvent() );
|
||||||
Go( &LIB_CONTROL::ShowComponentTree, EE_ACTIONS::showComponentTree.MakeEvent() );
|
Go( &LIB_CONTROL::ShowComponentTree, EE_ACTIONS::showComponentTree.MakeEvent() );
|
||||||
Go( &LIB_CONTROL::ToggleSyncedPinsMode, EE_ACTIONS::toggleSyncedPinsMode.MakeEvent() );
|
Go( &LIB_CONTROL::ToggleSyncedPinsMode, EE_ACTIONS::toggleSyncedPinsMode.MakeEvent() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,8 @@ public:
|
||||||
int OnDeMorgan( const TOOL_EVENT& aEvent );
|
int OnDeMorgan( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
int ShowElectricalTypes( const TOOL_EVENT& aEvent );
|
int ShowElectricalTypes( const TOOL_EVENT& aEvent );
|
||||||
|
int PinLibrary( const TOOL_EVENT& aEvent );
|
||||||
|
int UnpinLibrary( const TOOL_EVENT& aEvent );
|
||||||
int ShowComponentTree( const TOOL_EVENT& aEvent );
|
int ShowComponentTree( const TOOL_EVENT& aEvent );
|
||||||
int ToggleSyncedPinsMode( const TOOL_EVENT& aEvent );
|
int ToggleSyncedPinsMode( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
|
|
@ -57,13 +57,6 @@ SYMBOL_TREE_PANE::~SYMBOL_TREE_PANE()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SYMBOL_TREE_PANE::Regenerate()
|
|
||||||
{
|
|
||||||
if( m_tree )
|
|
||||||
m_tree->Regenerate( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SYMBOL_TREE_PANE::onComponentSelected( wxCommandEvent& aEvent )
|
void SYMBOL_TREE_PANE::onComponentSelected( wxCommandEvent& aEvent )
|
||||||
{
|
{
|
||||||
m_libEditFrame->GetToolManager()->RunAction( EE_ACTIONS::editSymbol, true );
|
m_libEditFrame->GetToolManager()->RunAction( EE_ACTIONS::editSymbol, true );
|
||||||
|
|
|
@ -48,9 +48,6 @@ public:
|
||||||
return m_tree;
|
return m_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
///> Updates the component tree
|
|
||||||
void Regenerate();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onComponentSelected( wxCommandEvent& aEvent );
|
void onComponentSelected( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
* @param aFilePath is the full file path (path and file name) to be normalized.
|
* @param aFilePath is the full file path (path and file name) to be normalized.
|
||||||
* @param aEnvVars is an optional map of environmental variables to try substition with.
|
* @param aEnvVars is an optional map of environmental variables to try substition with.
|
||||||
* @param aProject is an optional project, to normalize the file path to the project path.
|
* @param aProject is an optional project, to normalize the file path to the project path.
|
||||||
* @return Normalized full file path (path and file name) if succeeded or empty string if the
|
* @return m_Normalized full file path (path and file name) if succeeded or empty string if the
|
||||||
* path could not be normalized.
|
* path could not be normalized.
|
||||||
*/
|
*/
|
||||||
wxString NormalizePath( const wxFileName& aFilePath, const ENV_VAR_MAP* aEnvVars,
|
wxString NormalizePath( const wxFileName& aFilePath, const ENV_VAR_MAP* aEnvVars,
|
||||||
|
@ -45,7 +45,7 @@ wxString NormalizePath( const wxFileName& aFilePath, const ENV_VAR_MAP* aEnvVars
|
||||||
* @param aFilePath is the full file path (path and file name) to be normalized.
|
* @param aFilePath is the full file path (path and file name) to be normalized.
|
||||||
* @param aEnvVars is an optional map of environmental variables to try substition with.
|
* @param aEnvVars is an optional map of environmental variables to try substition with.
|
||||||
* @param aProjectPath is an optional string to normalize the file path to the project path.
|
* @param aProjectPath is an optional string to normalize the file path to the project path.
|
||||||
* @return Normalized full file path (path and file name) if succeeded or empty string if the
|
* @return m_Normalized full file path (path and file name) if succeeded or empty string if the
|
||||||
* path could not be normalized.
|
* path could not be normalized.
|
||||||
*/
|
*/
|
||||||
wxString NormalizePath(
|
wxString NormalizePath(
|
||||||
|
|
|
@ -101,6 +101,9 @@ public:
|
||||||
static TOOL_ACTION refreshPreview; // Similar to a synthetic mouseMoved event, but also
|
static TOOL_ACTION refreshPreview; // Similar to a synthetic mouseMoved event, but also
|
||||||
// used after a rotate, mirror, etc.
|
// used after a rotate, mirror, etc.
|
||||||
|
|
||||||
|
static TOOL_ACTION pinLibrary;
|
||||||
|
static TOOL_ACTION unpinLibrary;
|
||||||
|
|
||||||
/// Cursor control with keyboard
|
/// Cursor control with keyboard
|
||||||
static TOOL_ACTION cursorUp;
|
static TOOL_ACTION cursorUp;
|
||||||
static TOOL_ACTION cursorDown;
|
static TOOL_ACTION cursorDown;
|
||||||
|
|
|
@ -649,7 +649,7 @@ int AR_AUTOPLACER::getOptimalModulePlacement(MODULE* aModule)
|
||||||
fpBBox.SetOrigin( fpBBoxOrg + m_curPosition );
|
fpBBox.SetOrigin( fpBBoxOrg + m_curPosition );
|
||||||
|
|
||||||
min_cost = -1.0;
|
min_cost = -1.0;
|
||||||
// m_frame->SetStatusText( wxT( "Score ??, pos ??" ) );
|
// m_frame->SetStatusText( wxT( "m_Score ??, pos ??" ) );
|
||||||
|
|
||||||
|
|
||||||
for( ; m_curPosition.x < xylimit.x; m_curPosition.x += m_matrix.m_GridRouting )
|
for( ; m_curPosition.x < xylimit.x; m_curPosition.x += m_matrix.m_GridRouting )
|
||||||
|
@ -675,7 +675,7 @@ int AR_AUTOPLACER::getOptimalModulePlacement(MODULE* aModule)
|
||||||
LastPosOK = m_curPosition;
|
LastPosOK = m_curPosition;
|
||||||
min_cost = Score;
|
min_cost = Score;
|
||||||
wxString msg;
|
wxString msg;
|
||||||
/* msg.Printf( wxT( "Score %g, pos %s, %s" ),
|
/* msg.Printf( wxT( "m_Score %g, pos %s, %s" ),
|
||||||
min_cost,
|
min_cost,
|
||||||
GetChars( ::CoordinateToString( LastPosOK.x ) ),
|
GetChars( ::CoordinateToString( LastPosOK.x ) ),
|
||||||
GetChars( ::CoordinateToString( LastPosOK.y ) ) );
|
GetChars( ::CoordinateToString( LastPosOK.y ) ) );
|
||||||
|
|
|
@ -298,6 +298,12 @@ LIB_ID FOOTPRINT_EDIT_FRAME::GetTreeFPID() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_TREE_NODE* FOOTPRINT_EDIT_FRAME::GetCurrentTreeNode() const
|
||||||
|
{
|
||||||
|
return m_treePane->GetLibTree()->GetCurrentTreeNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LIB_ID FOOTPRINT_EDIT_FRAME::GetTargetFPID() const
|
LIB_ID FOOTPRINT_EDIT_FRAME::GetTargetFPID() const
|
||||||
{
|
{
|
||||||
LIB_ID id = GetTreeFPID();
|
LIB_ID id = GetTreeFPID();
|
||||||
|
@ -715,7 +721,7 @@ void FOOTPRINT_EDIT_FRAME::SyncLibraryTree( bool aProgress )
|
||||||
adapter->Sync();
|
adapter->Sync();
|
||||||
|
|
||||||
m_treePane->GetLibTree()->Unselect();
|
m_treePane->GetLibTree()->Unselect();
|
||||||
m_treePane->Regenerate();
|
m_treePane->GetLibTree()->Regenerate( true );
|
||||||
|
|
||||||
if( target.IsValid() )
|
if( target.IsValid() )
|
||||||
{
|
{
|
||||||
|
@ -736,6 +742,17 @@ void FOOTPRINT_EDIT_FRAME::SyncLibraryTree( bool aProgress )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FOOTPRINT_EDIT_FRAME::RegenerateLibraryTree()
|
||||||
|
{
|
||||||
|
LIB_ID target = GetTargetFPID();
|
||||||
|
|
||||||
|
m_treePane->GetLibTree()->Regenerate( true );
|
||||||
|
|
||||||
|
if( target.IsValid() )
|
||||||
|
m_treePane->GetLibTree()->CenterLibId( target );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FOOTPRINT_EDIT_FRAME::FocusOnLibID( const LIB_ID& aLibID )
|
void FOOTPRINT_EDIT_FRAME::FocusOnLibID( const LIB_ID& aLibID )
|
||||||
{
|
{
|
||||||
m_treePane->GetLibTree()->SelectLibId( aLibID );
|
m_treePane->GetLibTree()->SelectLibId( aLibID );
|
||||||
|
|
|
@ -208,6 +208,8 @@ public:
|
||||||
/// Return the LIB_ID of the part or library selected in the footprint tree.
|
/// Return the LIB_ID of the part or library selected in the footprint tree.
|
||||||
LIB_ID GetTreeFPID() const;
|
LIB_ID GetTreeFPID() const;
|
||||||
|
|
||||||
|
LIB_TREE_NODE* GetCurrentTreeNode() const;
|
||||||
|
|
||||||
/// Return the LIB_ID of the part being edited.
|
/// Return the LIB_ID of the part being edited.
|
||||||
LIB_ID GetLoadedFPID() const;
|
LIB_ID GetLoadedFPID() const;
|
||||||
|
|
||||||
|
@ -215,11 +217,6 @@ public:
|
||||||
/// there is no selection in the tree.
|
/// there is no selection in the tree.
|
||||||
LIB_ID GetTargetFPID() const;
|
LIB_ID GetTargetFPID() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform a geometric transform on the current footprint.
|
|
||||||
*/
|
|
||||||
void Transform( MODULE* module, int transform );
|
|
||||||
|
|
||||||
// importing / exporting Footprint
|
// importing / exporting Footprint
|
||||||
/**
|
/**
|
||||||
* Create a file containing only one footprint.
|
* Create a file containing only one footprint.
|
||||||
|
@ -339,6 +336,13 @@ public:
|
||||||
* @param aProgress
|
* @param aProgress
|
||||||
*/
|
*/
|
||||||
void SyncLibraryTree( bool aProgress );
|
void SyncLibraryTree( bool aProgress );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter, sort, and redisplay the library tree. Does NOT synchronize it with libraries
|
||||||
|
* in disk.
|
||||||
|
*/
|
||||||
|
void RegenerateLibraryTree();
|
||||||
|
|
||||||
void FocusOnLibID( const LIB_ID& aLibID );
|
void FocusOnLibID( const LIB_ID& aLibID );
|
||||||
|
|
||||||
void KiwayMailIn( KIWAY_EXPRESS& mail ) override;
|
void KiwayMailIn( KIWAY_EXPRESS& mail ) override;
|
||||||
|
|
|
@ -53,13 +53,6 @@ FOOTPRINT_TREE_PANE::~FOOTPRINT_TREE_PANE()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FOOTPRINT_TREE_PANE::Regenerate()
|
|
||||||
{
|
|
||||||
if( m_tree )
|
|
||||||
m_tree->Regenerate( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void FOOTPRINT_TREE_PANE::onComponentSelected( wxCommandEvent& aEvent )
|
void FOOTPRINT_TREE_PANE::onComponentSelected( wxCommandEvent& aEvent )
|
||||||
{
|
{
|
||||||
m_frame->LoadModuleFromLibrary( GetLibTree()->GetSelectedLibId() );
|
m_frame->LoadModuleFromLibrary( GetLibTree()->GetSelectedLibId() );
|
||||||
|
|
|
@ -47,9 +47,6 @@ public:
|
||||||
return m_tree;
|
return m_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
///> Updates the footprint tree
|
|
||||||
void Regenerate();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onComponentSelected( wxCommandEvent& aEvent );
|
void onComponentSelected( wxCommandEvent& aEvent );
|
||||||
void onUpdateUI( wxUpdateUIEvent& aEvent );
|
void onUpdateUI( wxUpdateUIEvent& aEvent );
|
||||||
|
|
|
@ -57,7 +57,7 @@ TOOL_INTERACTIVE* FP_TREE_SYNCHRONIZING_ADAPTER::GetContextMenuTool()
|
||||||
bool FP_TREE_SYNCHRONIZING_ADAPTER::IsContainer( const wxDataViewItem& aItem ) const
|
bool FP_TREE_SYNCHRONIZING_ADAPTER::IsContainer( const wxDataViewItem& aItem ) const
|
||||||
{
|
{
|
||||||
const LIB_TREE_NODE* node = ToNode( aItem );
|
const LIB_TREE_NODE* node = ToNode( aItem );
|
||||||
return node ? node->Type == LIB_TREE_NODE::LIB : true;
|
return node ? node->m_Type == LIB_TREE_NODE::LIB : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,9 +66,9 @@ bool FP_TREE_SYNCHRONIZING_ADAPTER::IsContainer( const wxDataViewItem& aItem ) c
|
||||||
void FP_TREE_SYNCHRONIZING_ADAPTER::Sync()
|
void FP_TREE_SYNCHRONIZING_ADAPTER::Sync()
|
||||||
{
|
{
|
||||||
// Process already stored libraries
|
// Process already stored libraries
|
||||||
for( auto it = m_tree.Children.begin(); it != m_tree.Children.end(); )
|
for( auto it = m_tree.m_Children.begin(); it != m_tree.m_Children.end(); )
|
||||||
{
|
{
|
||||||
const wxString& name = it->get()->Name;
|
const wxString& name = it->get()->m_Name;
|
||||||
|
|
||||||
if( !m_libs->HasLibrary( name, true ) )
|
if( !m_libs->HasLibrary( name, true ) )
|
||||||
{
|
{
|
||||||
|
@ -107,14 +107,14 @@ int FP_TREE_SYNCHRONIZING_ADAPTER::GetLibrariesCount() const
|
||||||
|
|
||||||
void FP_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNode )
|
void FP_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNode )
|
||||||
{
|
{
|
||||||
std::vector<LIB_TREE_ITEM*> footprints = getFootprints( aLibNode.Name );
|
std::vector<LIB_TREE_ITEM*> footprints = getFootprints( aLibNode.m_Name );
|
||||||
|
|
||||||
// remove the common part from the footprints list
|
// remove the common part from the footprints list
|
||||||
for( auto nodeIt = aLibNode.Children.begin(); nodeIt != aLibNode.Children.end(); )
|
for( auto nodeIt = aLibNode.m_Children.begin(); nodeIt != aLibNode.m_Children.end(); )
|
||||||
{
|
{
|
||||||
// Since the list is sorted we can use a binary search to speed up searches within
|
// Since the list is sorted we can use a binary search to speed up searches within
|
||||||
// libraries with lots of footprints.
|
// libraries with lots of footprints.
|
||||||
FOOTPRINT_INFO_IMPL dummy( wxEmptyString, (*nodeIt)->Name );
|
FOOTPRINT_INFO_IMPL dummy( wxEmptyString, (*nodeIt)->m_Name );
|
||||||
auto footprintIt = std::lower_bound( footprints.begin(), footprints.end(), &dummy,
|
auto footprintIt = std::lower_bound( footprints.begin(), footprints.end(), &dummy,
|
||||||
[]( LIB_TREE_ITEM* a, LIB_TREE_ITEM* b )
|
[]( LIB_TREE_ITEM* a, LIB_TREE_ITEM* b )
|
||||||
{
|
{
|
||||||
|
@ -132,7 +132,7 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNode )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// node does not exist in the library manager, remove the corresponding node
|
// node does not exist in the library manager, remove the corresponding node
|
||||||
nodeIt = aLibNode.Children.erase( nodeIt );
|
nodeIt = aLibNode.m_Children.erase( nodeIt );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNode )
|
||||||
aLibNode.AddItem( footprint );
|
aLibNode.AddItem( footprint );
|
||||||
|
|
||||||
aLibNode.AssignIntrinsicRanks();
|
aLibNode.AssignIntrinsicRanks();
|
||||||
m_libMap.insert( aLibNode.Name );
|
m_libMap.insert( aLibNode.m_Name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,8 +149,8 @@ LIB_TREE_NODE::PTR_VECTOR::iterator FP_TREE_SYNCHRONIZING_ADAPTER::deleteLibrary
|
||||||
LIB_TREE_NODE::PTR_VECTOR::iterator& aLibNodeIt )
|
LIB_TREE_NODE::PTR_VECTOR::iterator& aLibNodeIt )
|
||||||
{
|
{
|
||||||
LIB_TREE_NODE* node = aLibNodeIt->get();
|
LIB_TREE_NODE* node = aLibNodeIt->get();
|
||||||
m_libMap.erase( node->Name );
|
m_libMap.erase( node->m_Name );
|
||||||
auto it = m_tree.Children.erase( aLibNodeIt );
|
auto it = m_tree.m_Children.erase( aLibNodeIt );
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewIte
|
||||||
switch( aCol )
|
switch( aCol )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
if( node->LibId == m_frame->GetLoadedFPID() && !m_frame->IsCurrentFPFromBoard() )
|
if( node->m_LibId == m_frame->GetLoadedFPID() && !m_frame->IsCurrentFPFromBoard() )
|
||||||
{
|
{
|
||||||
auto mod = m_frame->GetBoard()->GetFirstModule();
|
auto mod = m_frame->GetBoard()->GetFirstModule();
|
||||||
|
|
||||||
|
@ -183,16 +183,18 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewIte
|
||||||
else
|
else
|
||||||
aVariant = currentFPName;
|
aVariant = currentFPName;
|
||||||
}
|
}
|
||||||
|
else if( node->m_Pinned )
|
||||||
|
aVariant = "☆ " + node->m_Name;
|
||||||
else
|
else
|
||||||
aVariant = node->Name;
|
aVariant = node->m_Name;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
aVariant = node->Desc;
|
aVariant = node->m_Desc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // column == -1 is used for default Compare function
|
default: // column == -1 is used for default Compare function
|
||||||
aVariant = node->Name;
|
aVariant = node->m_Name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,10 +217,10 @@ bool FP_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsign
|
||||||
auto node = ToNode( aItem );
|
auto node = ToNode( aItem );
|
||||||
wxCHECK( node, false );
|
wxCHECK( node, false );
|
||||||
|
|
||||||
switch( node->Type )
|
switch( node->m_Type )
|
||||||
{
|
{
|
||||||
case LIB_TREE_NODE::LIB:
|
case LIB_TREE_NODE::LIB:
|
||||||
if( node->Name == m_frame->GetLoadedFPID().GetLibNickname() )
|
if( node->m_Name == m_frame->GetLoadedFPID().GetLibNickname() )
|
||||||
{
|
{
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
// The native wxGTK+ impl ignores background colour, so set the text colour
|
// The native wxGTK+ impl ignores background colour, so set the text colour
|
||||||
|
@ -236,7 +238,7 @@ bool FP_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsign
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIB_TREE_NODE::LIBID:
|
case LIB_TREE_NODE::LIBID:
|
||||||
if( node->LibId == m_frame->GetLoadedFPID() )
|
if( node->m_LibId == m_frame->GetLoadedFPID() )
|
||||||
{
|
{
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
// The native wxGTK+ impl ignores background colour, so set the text colour
|
// The native wxGTK+ impl ignores background colour, so set the text colour
|
||||||
|
|
|
@ -82,11 +82,23 @@ bool MODULE_EDITOR_TOOLS::Init()
|
||||||
LIB_ID sel = m_frame->GetTreeFPID();
|
LIB_ID sel = m_frame->GetTreeFPID();
|
||||||
return !sel.GetLibNickname().empty() && sel.GetLibItemName().empty();
|
return !sel.GetLibNickname().empty() && sel.GetLibItemName().empty();
|
||||||
};
|
};
|
||||||
|
auto pinnedLibSelectedCondition = [ this ] ( const SELECTION& aSel ) {
|
||||||
|
LIB_TREE_NODE* current = m_frame->GetCurrentTreeNode();
|
||||||
|
return current && current->m_Type == LIB_TREE_NODE::LIB && current->m_Pinned;
|
||||||
|
};
|
||||||
|
auto unpinnedLibSelectedCondition = [ this ] (const SELECTION& aSel ) {
|
||||||
|
LIB_TREE_NODE* current = m_frame->GetCurrentTreeNode();
|
||||||
|
return current && current->m_Type == LIB_TREE_NODE::LIB && !current->m_Pinned;
|
||||||
|
};
|
||||||
auto fpSelectedCondition = [ this ] ( const SELECTION& aSel ) {
|
auto fpSelectedCondition = [ this ] ( const SELECTION& aSel ) {
|
||||||
LIB_ID sel = m_frame->GetTreeFPID();
|
LIB_ID sel = m_frame->GetTreeFPID();
|
||||||
return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
|
return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ctxMenu.AddItem( ACTIONS::pinLibrary, unpinnedLibSelectedCondition );
|
||||||
|
ctxMenu.AddItem( ACTIONS::unpinLibrary, pinnedLibSelectedCondition );
|
||||||
|
ctxMenu.AddSeparator();
|
||||||
|
|
||||||
ctxMenu.AddItem( ACTIONS::newLibrary, SELECTION_CONDITIONS::ShowAlways );
|
ctxMenu.AddItem( ACTIONS::newLibrary, SELECTION_CONDITIONS::ShowAlways );
|
||||||
ctxMenu.AddItem( ACTIONS::addLibrary, SELECTION_CONDITIONS::ShowAlways );
|
ctxMenu.AddItem( ACTIONS::addLibrary, SELECTION_CONDITIONS::ShowAlways );
|
||||||
ctxMenu.AddItem( ACTIONS::save, libSelectedCondition );
|
ctxMenu.AddItem( ACTIONS::save, libSelectedCondition );
|
||||||
|
@ -256,6 +268,34 @@ int MODULE_EDITOR_TOOLS::EditFootprint( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int MODULE_EDITOR_TOOLS::PinLibrary( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
LIB_TREE_NODE* currentNode = m_frame->GetCurrentTreeNode();
|
||||||
|
|
||||||
|
if( currentNode && !currentNode->m_Pinned )
|
||||||
|
{
|
||||||
|
currentNode->m_Pinned = true;
|
||||||
|
m_frame->RegenerateLibraryTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int MODULE_EDITOR_TOOLS::UnpinLibrary( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
LIB_TREE_NODE* currentNode = m_frame->GetCurrentTreeNode();
|
||||||
|
|
||||||
|
if( currentNode && currentNode->m_Pinned )
|
||||||
|
{
|
||||||
|
currentNode->m_Pinned = false;
|
||||||
|
m_frame->RegenerateLibraryTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int MODULE_EDITOR_TOOLS::ToggleFootprintTree( const TOOL_EVENT& aEvent )
|
int MODULE_EDITOR_TOOLS::ToggleFootprintTree( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
m_frame->ToggleSearchTree();
|
m_frame->ToggleSearchTree();
|
||||||
|
@ -558,6 +598,8 @@ void MODULE_EDITOR_TOOLS::setTransitions()
|
||||||
Go( &MODULE_EDITOR_TOOLS::ImportFootprint, PCB_ACTIONS::importFootprint.MakeEvent() );
|
Go( &MODULE_EDITOR_TOOLS::ImportFootprint, PCB_ACTIONS::importFootprint.MakeEvent() );
|
||||||
Go( &MODULE_EDITOR_TOOLS::ExportFootprint, PCB_ACTIONS::exportFootprint.MakeEvent() );
|
Go( &MODULE_EDITOR_TOOLS::ExportFootprint, PCB_ACTIONS::exportFootprint.MakeEvent() );
|
||||||
|
|
||||||
|
Go( &MODULE_EDITOR_TOOLS::PinLibrary, ACTIONS::pinLibrary.MakeEvent() );
|
||||||
|
Go( &MODULE_EDITOR_TOOLS::UnpinLibrary, ACTIONS::unpinLibrary.MakeEvent() );
|
||||||
Go( &MODULE_EDITOR_TOOLS::ToggleFootprintTree, PCB_ACTIONS::toggleFootprintTree.MakeEvent() );
|
Go( &MODULE_EDITOR_TOOLS::ToggleFootprintTree, PCB_ACTIONS::toggleFootprintTree.MakeEvent() );
|
||||||
Go( &MODULE_EDITOR_TOOLS::Properties, PCB_ACTIONS::footprintProperties.MakeEvent() );
|
Go( &MODULE_EDITOR_TOOLS::Properties, PCB_ACTIONS::footprintProperties.MakeEvent() );
|
||||||
Go( &MODULE_EDITOR_TOOLS::DefaultPadProperties, PCB_ACTIONS::defaultPadProperties.MakeEvent() );
|
Go( &MODULE_EDITOR_TOOLS::DefaultPadProperties, PCB_ACTIONS::defaultPadProperties.MakeEvent() );
|
||||||
|
|
|
@ -61,7 +61,9 @@ public:
|
||||||
int DeleteFootprint( const TOOL_EVENT& aEvent );
|
int DeleteFootprint( const TOOL_EVENT& aEvent );
|
||||||
int ImportFootprint( const TOOL_EVENT& aEvent );
|
int ImportFootprint( const TOOL_EVENT& aEvent );
|
||||||
int ExportFootprint( const TOOL_EVENT& aEvent );
|
int ExportFootprint( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
int PinLibrary( const TOOL_EVENT& aEvent );
|
||||||
|
int UnpinLibrary( const TOOL_EVENT& aEvent );
|
||||||
int ToggleFootprintTree( const TOOL_EVENT& aEvent );
|
int ToggleFootprintTree( const TOOL_EVENT& aEvent );
|
||||||
int Properties( const TOOL_EVENT& aEvent );
|
int Properties( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue