7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-20 14:31:41 +00:00

Enhance library pinning functionality to support pin/unpin multiple libraries in the library editor

This commit is contained in:
Dmitry Rezvanov 2025-02-17 15:48:28 +05:00 committed by Jon Evans
parent ca21a35bfc
commit c7aaf8b6e1
4 changed files with 102 additions and 65 deletions

View File

@ -40,23 +40,41 @@ void LIBRARY_EDITOR_CONTROL::Reset( RESET_REASON aReason )
void LIBRARY_EDITOR_CONTROL::AddContextMenuItems( CONDITIONAL_MENU* aMenu )
{
auto pinnedLibSelectedCondition =
[this]( const SELECTION& aSel )
{
LIB_TREE* libTree = m_frame->GetLibTree();
LIB_TREE_NODE* current = libTree ? libTree->GetCurrentTreeNode() : nullptr;
return current && current->m_Type == LIB_TREE_NODE::TYPE::LIBRARY
&& current->m_Pinned;
};
auto checkPinnedStatus = [this]( bool aPin )
{
bool result = true;
LIB_TREE* libTree = m_frame->GetLibTree();
if( libTree )
{
std::vector<LIB_TREE_NODE*> selection;
libTree->GetSelectedTreeNodes( selection );
auto unpinnedLibSelectedCondition =
[this](const SELECTION& aSel )
for( const LIB_TREE_NODE* lib : selection )
{
LIB_TREE* libTree = m_frame->GetLibTree();
LIB_TREE_NODE* current = libTree ? libTree->GetCurrentTreeNode() : nullptr;
return current && current->m_Type == LIB_TREE_NODE::TYPE::LIBRARY
&& !current->m_Pinned;
};
if( lib && lib->m_Type == LIB_TREE_NODE::TYPE::LIBRARY && lib->m_Pinned != aPin )
{
result = false;
break;
}
}
}
else
{
result = false;
}
return result;
};
auto pinnedLibSelectedCondition = [checkPinnedStatus]( const SELECTION& aSel )
{
return checkPinnedStatus( true );
};
auto unpinnedLibSelectedCondition = [checkPinnedStatus]( const SELECTION& aSel )
{
return checkPinnedStatus( false );
};
aMenu->AddItem( ACTIONS::pinLibrary, unpinnedLibSelectedCondition, 1 );
aMenu->AddItem( ACTIONS::unpinLibrary, pinnedLibSelectedCondition, 1 );
@ -78,34 +96,49 @@ void LIBRARY_EDITOR_CONTROL::regenerateLibraryTree()
libTree->CenterLibId( target );
}
void LIBRARY_EDITOR_CONTROL::changeSelectedPinStatus( const bool aPin )
{
LIB_TREE* libTree = m_frame->GetLibTree();
if( libTree )
{
std::vector<LIB_TREE_NODE*> selection;
libTree->GetSelectedTreeNodes( selection );
for( LIB_TREE_NODE* lib : selection )
{
if( lib && lib->m_Type == LIB_TREE_NODE::TYPE::LIBRARY && lib->m_Pinned != aPin )
{
const KIWAY::FACE_T kifaceType = KIWAY::KifaceType( m_frame->GetFrameType() );
if( kifaceType == KIWAY::FACE_SCH || kifaceType == KIWAY::FACE_PCB )
{
if( aPin )
m_frame->Prj().PinLibrary( lib->m_LibId.GetLibNickname(),
kifaceType == KIWAY::FACE_SCH
? PROJECT::LIB_TYPE_T::SYMBOL_LIB
: PROJECT::LIB_TYPE_T::FOOTPRINT_LIB );
else
m_frame->Prj().UnpinLibrary( lib->m_LibId.GetLibNickname(),
kifaceType == KIWAY::FACE_SCH
? PROJECT::LIB_TYPE_T::SYMBOL_LIB
: PROJECT::LIB_TYPE_T::FOOTPRINT_LIB );
lib->m_Pinned = aPin;
}
else
{
wxFAIL_MSG( wxT( "Unsupported frame type for library pinning." ) );
}
}
}
regenerateLibraryTree();
}
}
int LIBRARY_EDITOR_CONTROL::PinLibrary( const TOOL_EVENT& aEvent )
{
LIB_TREE* libTree = m_frame->GetLibTree();
LIB_TREE_NODE* current = libTree ? libTree->GetCurrentTreeNode() : nullptr;
if( current && !current->m_Pinned )
{
switch( KIWAY::KifaceType( m_frame->GetFrameType() ) )
{
case KIWAY::FACE_SCH:
m_frame->Prj().PinLibrary( current->m_LibId.GetLibNickname(),
PROJECT::LIB_TYPE_T::SYMBOL_LIB );
break;
case KIWAY::FACE_PCB:
m_frame->Prj().PinLibrary( current->m_LibId.GetLibNickname(),
PROJECT::LIB_TYPE_T::FOOTPRINT_LIB );
break;
default:
wxFAIL_MSG( wxT( "Unsupported frame type for library pinning." ) );
break;
}
current->m_Pinned = true;
regenerateLibraryTree();
}
changeSelectedPinStatus( true );
return 0;
}
@ -113,31 +146,7 @@ int LIBRARY_EDITOR_CONTROL::PinLibrary( const TOOL_EVENT& aEvent )
int LIBRARY_EDITOR_CONTROL::UnpinLibrary( const TOOL_EVENT& aEvent )
{
LIB_TREE* libTree = m_frame->GetLibTree();
LIB_TREE_NODE* current = libTree ? libTree->GetCurrentTreeNode() : nullptr;
if( current && current->m_Pinned )
{
switch( KIWAY::KifaceType( m_frame->GetFrameType() ) )
{
case KIWAY::FACE_SCH:
m_frame->Prj().UnpinLibrary( current->m_LibId.GetLibNickname(),
PROJECT::LIB_TYPE_T::SYMBOL_LIB );
break;
case KIWAY::FACE_PCB:
m_frame->Prj().UnpinLibrary( current->m_LibId.GetLibNickname(),
PROJECT::LIB_TYPE_T::FOOTPRINT_LIB );
break;
default:
wxFAIL_MSG( wxT( "Unsupported frame type for library pinning." ) );
break;
}
current->m_Pinned = false;
regenerateLibraryTree();
}
changeSelectedPinStatus( false );
return 0;
}

View File

@ -46,6 +46,8 @@ public:
std::function<bool( const wxString& aNewName )> aValidator );
private:
void changeSelectedPinStatus( const bool aPin );
/// Set up handlers for various events.
void setTransitions() override;

View File

@ -345,6 +345,19 @@ LIB_TREE_NODE* LIB_TREE::GetCurrentTreeNode() const
return m_adapter->GetTreeNodeFor( sel );
}
int LIB_TREE::GetSelectedTreeNodes( std::vector<LIB_TREE_NODE*>& aSelection ) const
{
wxDataViewItemArray selection;
int count = m_tree_ctrl->GetSelections( selection );
for( const wxDataViewItem& item : selection )
{
aSelection.push_back( m_adapter->GetTreeNodeFor( item ) );
}
return count;
}
void LIB_TREE::SelectLibId( const LIB_ID& aLibId )
{

View File

@ -104,8 +104,21 @@ public:
int GetSelectedLibIds( std::vector<LIB_ID>& aSelection,
std::vector<int>* aUnit = nullptr ) const;
/**
* Retrieve the tree node for the first selected item.
*
* @return the tree node for the first selected item.
*/
LIB_TREE_NODE* GetCurrentTreeNode() const;
/**
* Retrieve a list of pointers to selected tree nodes for trees that allow multi-selection.
*
* @param aSelection will be filled with a list of pointers of selected tree nodes.
* @return the number of selected items.
*/
int GetSelectedTreeNodes( std::vector<LIB_TREE_NODE*>& aSelection ) const;
/**
* Select an item in the tree widget.
*/