Add pin/unpin context menu to Symbol Chooser and Footprint Chooser.
Also moves some more code down into common so it can be shared. Fixes https://gitlab.com/kicad/code/kicad/issues/12384
This commit is contained in:
parent
6154a8d5d5
commit
8eb68ee472
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
|
||||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
|
||||
* Copyright (C) 2014-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2014-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
|
@ -22,7 +22,6 @@
|
|||
#include <eda_base_frame.h>
|
||||
#include <eda_pattern_match.h>
|
||||
#include <kiface_base.h>
|
||||
#include <config_params.h>
|
||||
#include <lib_tree_model_adapter.h>
|
||||
#include <project/project_file.h>
|
||||
#include <settings/app_settings.h>
|
||||
|
@ -32,8 +31,6 @@
|
|||
#include <string_utils.h>
|
||||
|
||||
|
||||
#define PINNED_ITEMS_KEY wxT( "PinnedItems" )
|
||||
|
||||
static const int kDataViewIndent = 20;
|
||||
|
||||
|
||||
|
@ -265,6 +262,38 @@ void LIB_TREE_MODEL_ADAPTER::AttachTo( wxDataViewCtrl* aDataViewCtrl )
|
|||
}
|
||||
|
||||
|
||||
void LIB_TREE_MODEL_ADAPTER::resortTree()
|
||||
{
|
||||
Freeze();
|
||||
BeforeReset();
|
||||
|
||||
m_tree.SortNodes();
|
||||
|
||||
AfterReset();
|
||||
Thaw();
|
||||
}
|
||||
|
||||
|
||||
void LIB_TREE_MODEL_ADAPTER::PinLibrary( LIB_TREE_NODE* aTreeNode )
|
||||
{
|
||||
m_parent->Prj().PinLibrary( aTreeNode->m_LibId.GetLibNickname(), isSymbolModel() );
|
||||
aTreeNode->m_Pinned = true;
|
||||
|
||||
resortTree();
|
||||
m_widget->EnsureVisible( ToItem( aTreeNode ) );
|
||||
}
|
||||
|
||||
|
||||
void LIB_TREE_MODEL_ADAPTER::UnpinLibrary( LIB_TREE_NODE* aTreeNode )
|
||||
{
|
||||
m_parent->Prj().UnpinLibrary( aTreeNode->m_LibId.GetLibNickname(), isSymbolModel() );
|
||||
aTreeNode->m_Pinned = false;
|
||||
|
||||
resortTree();
|
||||
// Keep focus at top when unpinning
|
||||
}
|
||||
|
||||
|
||||
wxDataViewColumn* LIB_TREE_MODEL_ADAPTER::doAddColumn( const wxString& aHeader, bool aTranslate )
|
||||
{
|
||||
wxString translatedHeader = aTranslate ? wxGetTranslation( aHeader ) : aHeader;
|
||||
|
@ -529,7 +558,11 @@ void LIB_TREE_MODEL_ADAPTER::GetValue( wxVariant& aVariant,
|
|||
switch( aCol )
|
||||
{
|
||||
case NAME_COL:
|
||||
aVariant = UnescapeString( node->m_Name );
|
||||
if( node->m_Pinned )
|
||||
aVariant = GetPinningSymbol() + UnescapeString( node->m_Name );
|
||||
else
|
||||
aVariant = UnescapeString( node->m_Name );
|
||||
|
||||
break;
|
||||
|
||||
case DESC_COL:
|
||||
|
@ -537,17 +570,18 @@ void LIB_TREE_MODEL_ADAPTER::GetValue( wxVariant& aVariant,
|
|||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
wxCHECK_RET( m_colIdxMap.count( aCol ), wxT( "Invalid column in LIB_TREE_MODEL_ADAPTER" ) );
|
||||
if( m_colIdxMap.count( aCol ) )
|
||||
{
|
||||
const wxString& key = m_colIdxMap.at( aCol );
|
||||
|
||||
if( node->m_Fields.count( m_colIdxMap.at( aCol ) ) )
|
||||
aVariant = node->m_Fields[m_colIdxMap.at( aCol )];
|
||||
else
|
||||
aVariant = wxEmptyString;
|
||||
if( node->m_Fields.count( key ) )
|
||||
aVariant = node->m_Fields.at( key );
|
||||
else
|
||||
aVariant = wxEmptyString;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,8 +24,10 @@
|
|||
#include <wx/log.h>
|
||||
#include <wx/stdpaths.h>
|
||||
|
||||
#include <pgm_base.h>
|
||||
#include <confirm.h>
|
||||
#include <core/arraydim.h>
|
||||
#include <core/kicad_algo.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <string_utils.h>
|
||||
#include <kiface_ids.h>
|
||||
|
@ -35,7 +37,8 @@
|
|||
#include <project/project_file.h>
|
||||
#include <trace_helpers.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#include <settings/common_settings.h>
|
||||
#include <settings/settings_manager.h>
|
||||
|
||||
PROJECT::PROJECT() :
|
||||
m_readOnly( false ),
|
||||
|
@ -149,6 +152,46 @@ const wxString PROJECT::FootprintLibTblName() const
|
|||
}
|
||||
|
||||
|
||||
void PROJECT::PinLibrary( const wxString& aLibrary, bool isSymbolLibrary )
|
||||
{
|
||||
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
||||
PROJECT_FILE& project = GetProjectFile();
|
||||
std::vector<wxString>& pinnedLibs = isSymbolLibrary ? m_projectFile->m_PinnedSymbolLibs
|
||||
: m_projectFile->m_PinnedFootprintLibs;
|
||||
|
||||
if( !alg::contains( pinnedLibs, aLibrary ) )
|
||||
pinnedLibs.push_back( aLibrary );
|
||||
|
||||
Pgm().GetSettingsManager().SaveProject();
|
||||
|
||||
pinnedLibs = isSymbolLibrary ? cfg->m_Session.pinned_symbol_libs
|
||||
: cfg->m_Session.pinned_fp_libs;
|
||||
|
||||
if( !alg::contains( pinnedLibs, aLibrary ) )
|
||||
pinnedLibs.push_back( aLibrary );
|
||||
|
||||
cfg->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( cfg ) );
|
||||
}
|
||||
|
||||
|
||||
void PROJECT::UnpinLibrary( const wxString& aLibrary, bool isSymbolLibrary )
|
||||
{
|
||||
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
||||
PROJECT_FILE& project = GetProjectFile();
|
||||
std::vector<wxString>& pinnedLibs = isSymbolLibrary ? m_projectFile->m_PinnedSymbolLibs
|
||||
: m_projectFile->m_PinnedFootprintLibs;
|
||||
|
||||
alg::delete_matching( pinnedLibs, aLibrary );
|
||||
Pgm().GetSettingsManager().SaveProject();
|
||||
|
||||
pinnedLibs = isSymbolLibrary ? cfg->m_Session.pinned_symbol_libs
|
||||
: cfg->m_Session.pinned_fp_libs;
|
||||
|
||||
alg::delete_matching( pinnedLibs, aLibrary );
|
||||
cfg->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( cfg ) );
|
||||
}
|
||||
|
||||
|
||||
const wxString PROJECT::libTableName( const wxString& aLibTableName ) const
|
||||
{
|
||||
wxFileName fn = GetProjectFullName();
|
||||
|
|
|
@ -29,11 +29,11 @@
|
|||
#include <wx/sizer.h>
|
||||
#include <tool/tool_interactive.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/actions.h>
|
||||
#include <wx/srchctrl.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/timer.h>
|
||||
|
||||
|
||||
constexpr int RECENT_SEARCHES_MAX = 10;
|
||||
|
||||
std::map<wxString, std::vector<wxString>> g_recentSearches;
|
||||
|
@ -575,9 +575,7 @@ void LIB_TREE::onPreselect( wxCommandEvent& aEvent )
|
|||
|
||||
void LIB_TREE::onContextMenu( wxDataViewEvent& aEvent )
|
||||
{
|
||||
TOOL_INTERACTIVE* tool = m_adapter->GetContextMenuTool();
|
||||
|
||||
if( tool )
|
||||
if( TOOL_INTERACTIVE* tool = m_adapter->GetContextMenuTool() )
|
||||
{
|
||||
tool->Activate();
|
||||
tool->GetManager()->VetoContextMenuMouseWarp();
|
||||
|
@ -586,6 +584,30 @@ void LIB_TREE::onContextMenu( wxDataViewEvent& aEvent )
|
|||
TOOL_EVENT evt( TC_MOUSE, TA_MOUSE_CLICK, BUT_RIGHT );
|
||||
tool->GetManager()->DispatchContextMenu( evt );
|
||||
}
|
||||
else
|
||||
{
|
||||
LIB_TREE_NODE* current = GetCurrentTreeNode();
|
||||
|
||||
if( current && current->m_Type == LIB_TREE_NODE::LIB )
|
||||
{
|
||||
ACTION_MENU menu( true, nullptr );
|
||||
|
||||
if( current->m_Pinned )
|
||||
{
|
||||
menu.Add( ACTIONS::unpinLibrary );
|
||||
|
||||
if( GetPopupMenuSelectionFromUser( menu ) )
|
||||
m_adapter->UnpinLibrary( current );
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.Add( ACTIONS::pinLibrary );
|
||||
|
||||
if( GetPopupMenuSelectionFromUser( menu ) )
|
||||
m_adapter->PinLibrary( current );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -182,12 +182,11 @@ bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
|
|||
|
||||
if( progressReporter )
|
||||
{
|
||||
// Force immediate deletion of the APP_PROGRESS_DIALOG
|
||||
// ( do not use Destroy(), or use Destroy() followed by wxSafeYield() )
|
||||
// because on Windows, APP_PROGRESS_DIALOG has some side effects on the event loop
|
||||
// manager. A side effect is the call of ShowModal() of a dialog following
|
||||
// the use of SYMBOL_TREE_MODEL_ADAPTER creating a APP_PROGRESS_DIALOG
|
||||
// has a broken behavior (incorrect modal behavior).
|
||||
// Force immediate deletion of the APP_PROGRESS_DIALOG. Do not use Destroy(), or Destroy()
|
||||
// followed by wxSafeYield() because on Windows, APP_PROGRESS_DIALOG has some side effects
|
||||
// on the event loop manager.
|
||||
// One in particular is the call of ShowModal() following SYMBOL_TREE_MODEL_ADAPTER
|
||||
// creating a APP_PROGRESS_DIALOG (which has incorrect modal behaviour).
|
||||
progressReporter.reset();
|
||||
m_show_progress = false;
|
||||
}
|
||||
|
@ -229,47 +228,3 @@ wxString SYMBOL_TREE_MODEL_ADAPTER::GenerateInfo( LIB_ID const& aLibId, int aUni
|
|||
}
|
||||
|
||||
|
||||
void SYMBOL_TREE_MODEL_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewItem const& aItem,
|
||||
unsigned int aCol ) const
|
||||
{
|
||||
if( IsFrozen() )
|
||||
{
|
||||
aVariant = wxEmptyString;
|
||||
return;
|
||||
}
|
||||
|
||||
LIB_TREE_NODE* node = ToNode( aItem );
|
||||
wxASSERT( node );
|
||||
|
||||
switch( aCol )
|
||||
{
|
||||
case NAME_COL:
|
||||
if( node->m_Pinned )
|
||||
aVariant = GetPinningSymbol() + UnescapeString( node->m_Name );
|
||||
else
|
||||
aVariant = UnescapeString( node->m_Name );
|
||||
|
||||
break;
|
||||
|
||||
case DESC_COL:
|
||||
aVariant = node->m_Desc;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
if( m_colIdxMap.count( aCol ) )
|
||||
{
|
||||
const wxString& key = m_colIdxMap.at( aCol );
|
||||
|
||||
if( node->m_Fields.count( key ) )
|
||||
aVariant = node->m_Fields.at( key );
|
||||
else
|
||||
aVariant = wxEmptyString;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -64,16 +64,7 @@ protected:
|
|||
*/
|
||||
SYMBOL_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent, LIB_TABLE* aLibs );
|
||||
|
||||
/**
|
||||
* Get the value of an item.
|
||||
*
|
||||
* @param aVariant wxVariant to receive the data
|
||||
* @param aItem item whose data will be placed into aVariant
|
||||
* @param aCol column number of the data
|
||||
*/
|
||||
void GetValue( wxVariant& aVariant,
|
||||
const wxDataViewItem& aItem,
|
||||
unsigned int aCol ) const override;
|
||||
bool isSymbolModel() override { return true; }
|
||||
|
||||
private:
|
||||
friend class SYMBOL_ASYNC_LOADER;
|
||||
|
|
|
@ -61,6 +61,8 @@ protected:
|
|||
SYMBOL_TREE_SYNCHRONIZING_ADAPTER( SYMBOL_EDIT_FRAME* aParent,
|
||||
SYMBOL_LIBRARY_MANAGER* aLibMgr );
|
||||
|
||||
bool isSymbolModel() override { return true; }
|
||||
|
||||
protected:
|
||||
SYMBOL_EDIT_FRAME* m_frame;
|
||||
SYMBOL_LIBRARY_MANAGER* m_libMgr;
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
|
||||
#include <kiway.h>
|
||||
#include <pgm_base.h>
|
||||
#include <project.h>
|
||||
#include <project/project_file.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <sch_painter.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/ee_actions.h>
|
||||
|
@ -36,7 +33,6 @@
|
|||
#include <symbol_viewer_frame.h>
|
||||
#include <symbol_tree_model_adapter.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <bitmaps/bitmap_types.h>
|
||||
#include <confirm.h>
|
||||
#include <wx/filedlg.h>
|
||||
|
@ -439,19 +435,7 @@ int SYMBOL_EDITOR_CONTROL::PinLibrary( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( currentNode && !currentNode->m_Pinned )
|
||||
{
|
||||
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
||||
PROJECT_FILE& project = m_frame->Prj().GetProjectFile();
|
||||
wxString nickname = currentNode->m_LibId.GetLibNickname();
|
||||
|
||||
if( !alg::contains( project.m_PinnedSymbolLibs, nickname ) )
|
||||
project.m_PinnedSymbolLibs.push_back( nickname );
|
||||
|
||||
Pgm().GetSettingsManager().SaveProject();
|
||||
|
||||
if( !alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
|
||||
cfg->m_Session.pinned_symbol_libs.push_back( nickname );
|
||||
|
||||
cfg->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( cfg ) );
|
||||
m_frame->Prj().PinLibrary( currentNode->m_LibId.GetLibNickname(), true );
|
||||
|
||||
currentNode->m_Pinned = true;
|
||||
editFrame->RegenerateLibraryTree();
|
||||
|
@ -471,15 +455,7 @@ int SYMBOL_EDITOR_CONTROL::UnpinLibrary( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( currentNode && currentNode->m_Pinned )
|
||||
{
|
||||
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
||||
PROJECT_FILE& project = m_frame->Prj().GetProjectFile();
|
||||
wxString nickname = currentNode->m_LibId.GetLibNickname();
|
||||
|
||||
alg::delete_matching( project.m_PinnedSymbolLibs, nickname );
|
||||
Pgm().GetSettingsManager().SaveProject();
|
||||
|
||||
alg::delete_matching( cfg->m_Session.pinned_symbol_libs, nickname );
|
||||
cfg->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( cfg ) );
|
||||
m_frame->Prj().UnpinLibrary( currentNode->m_LibId.GetLibNickname(), true );
|
||||
|
||||
currentNode->m_Pinned = false;
|
||||
editFrame->RegenerateLibraryTree();
|
||||
|
|
|
@ -290,6 +290,9 @@ public:
|
|||
// Allows subclasses to nominate a context menu handler.
|
||||
virtual TOOL_INTERACTIVE* GetContextMenuTool() { return nullptr; }
|
||||
|
||||
void PinLibrary( LIB_TREE_NODE* aTreeNode );
|
||||
void UnpinLibrary( LIB_TREE_NODE* aTreeNode );
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Convert #SYM_TREE_NODE -> wxDataViewItem.
|
||||
|
@ -372,6 +375,10 @@ protected:
|
|||
unsigned int aCol,
|
||||
wxDataViewItemAttr& aAttr ) const override;
|
||||
|
||||
virtual bool isSymbolModel() = 0;
|
||||
|
||||
void resortTree();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Find any results worth highlighting and expand them, according to given criteria
|
||||
|
@ -404,7 +411,7 @@ protected:
|
|||
std::map<unsigned, wxString> m_colIdxMap;
|
||||
|
||||
private:
|
||||
[[maybe_unused]] EDA_BASE_FRAME* m_parent;
|
||||
EDA_BASE_FRAME* m_parent;
|
||||
|
||||
SYM_FILTER_TYPE m_filter;
|
||||
bool m_show_units;
|
||||
|
|
|
@ -142,6 +142,9 @@ public:
|
|||
*/
|
||||
virtual const wxString SymbolLibTableName() const;
|
||||
|
||||
void PinLibrary( const wxString& aLibrary, bool isSymbolLibrary );
|
||||
void UnpinLibrary( const wxString& aLibrary, bool isSymbolLibrary );
|
||||
|
||||
virtual PROJECT_FILE& GetProjectFile() const
|
||||
{
|
||||
wxASSERT( m_projectFile );
|
||||
|
|
|
@ -92,39 +92,3 @@ wxString FP_TREE_MODEL_ADAPTER::GenerateInfo( LIB_ID const& aLibId, int aUnit )
|
|||
{
|
||||
return GenerateFootprintInfo( m_libs, aLibId );
|
||||
}
|
||||
|
||||
|
||||
void FP_TREE_MODEL_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewItem const& aItem,
|
||||
unsigned int aCol ) const
|
||||
{
|
||||
if( IsFrozen() )
|
||||
{
|
||||
aVariant = wxEmptyString;
|
||||
return;
|
||||
}
|
||||
|
||||
LIB_TREE_NODE* node = ToNode( aItem );
|
||||
wxASSERT( node );
|
||||
|
||||
if( aCol == 0 && node->m_Pinned )
|
||||
aVariant = GetPinningSymbol() + node->m_Name;
|
||||
else
|
||||
aVariant = node->m_Name;
|
||||
|
||||
switch( aCol )
|
||||
{
|
||||
case NAME_COL:
|
||||
if( node->m_Pinned )
|
||||
aVariant = GetPinningSymbol() + UnescapeString( node->m_Name );
|
||||
else
|
||||
aVariant = UnescapeString( node->m_Name );
|
||||
|
||||
break;
|
||||
|
||||
case DESC_COL:
|
||||
aVariant = node->m_Desc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -51,16 +51,7 @@ protected:
|
|||
|
||||
std::vector<LIB_TREE_ITEM*> getFootprints( const wxString& aLibName );
|
||||
|
||||
/**
|
||||
* Get the value of an item.
|
||||
*
|
||||
* @param aVariant wxVariant to receive the data
|
||||
* @param aItem item whose data will be placed into aVariant
|
||||
* @param aCol column number of the data
|
||||
*/
|
||||
void GetValue( wxVariant& aVariant,
|
||||
const wxDataViewItem& aItem,
|
||||
unsigned int aCol ) const override;
|
||||
bool isSymbolModel() override { return false; }
|
||||
|
||||
protected:
|
||||
FP_LIB_TABLE* m_libs;
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include <pgm_base.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <view/view_controls.h>
|
||||
#include <footprint_edit_frame.h>
|
||||
#include <pcbnew_id.h>
|
||||
#include <confirm.h>
|
||||
|
@ -38,9 +37,6 @@
|
|||
#include <pad.h>
|
||||
#include <pcb_group.h>
|
||||
#include <zone.h>
|
||||
#include <project.h>
|
||||
#include <project/project_file.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <dialogs/dialog_cleanup_graphics.h>
|
||||
#include <dialogs/dialog_footprint_checker.h>
|
||||
|
@ -548,19 +544,7 @@ int FOOTPRINT_EDITOR_CONTROL::PinLibrary( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( currentNode && !currentNode->m_Pinned )
|
||||
{
|
||||
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
||||
PROJECT_FILE& project = m_frame->Prj().GetProjectFile();
|
||||
wxString nickname = currentNode->m_LibId.GetLibNickname();
|
||||
|
||||
if( !alg::contains( project.m_PinnedFootprintLibs, nickname ) )
|
||||
project.m_PinnedFootprintLibs.push_back( nickname );
|
||||
|
||||
Pgm().GetSettingsManager().SaveProject();
|
||||
|
||||
if( !alg::contains( cfg->m_Session.pinned_fp_libs, nickname ) )
|
||||
cfg->m_Session.pinned_fp_libs.push_back( nickname );
|
||||
|
||||
cfg->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( cfg ) );
|
||||
m_frame->Prj().PinLibrary( currentNode->m_LibId.GetLibNickname(), false );
|
||||
|
||||
currentNode->m_Pinned = true;
|
||||
m_frame->RegenerateLibraryTree();
|
||||
|
@ -576,15 +560,7 @@ int FOOTPRINT_EDITOR_CONTROL::UnpinLibrary( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( currentNode && currentNode->m_Pinned )
|
||||
{
|
||||
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
||||
PROJECT_FILE& project = m_frame->Prj().GetProjectFile();
|
||||
wxString nickname = currentNode->m_LibId.GetLibNickname();
|
||||
|
||||
alg::delete_matching( project.m_PinnedFootprintLibs, nickname );
|
||||
Pgm().GetSettingsManager().SaveProject();
|
||||
|
||||
alg::delete_matching( cfg->m_Session.pinned_fp_libs, nickname );
|
||||
cfg->SaveToFile( Pgm().GetSettingsManager().GetPathForSettingsFile( cfg ) );
|
||||
m_frame->Prj().UnpinLibrary( currentNode->m_LibId.GetLibNickname(), false );
|
||||
|
||||
currentNode->m_Pinned = false;
|
||||
m_frame->RegenerateLibraryTree();
|
||||
|
|
Loading…
Reference in New Issue