Redo the pinned-libraries storage architecture.

1) always use preferences directly
2) allow nicknames from either preferences or project
3) store-after-modify

Fixes https://gitlab.com/kicad/code/kicad/issues/12000

Fixes https://gitlab.com/kicad/code/kicad/issues/11892
This commit is contained in:
Jeff Young 2022-07-22 09:26:49 +01:00
parent bdffbbd43b
commit def87c969e
16 changed files with 156 additions and 85 deletions

View File

@ -76,9 +76,7 @@ LIB_TREE_MODEL_ADAPTER::LIB_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent,
m_freeze( 0 ),
m_col_part( nullptr ),
m_col_desc( nullptr ),
m_widget( nullptr ),
m_pinnedLibs(),
m_pinnedKey( aPinnedKey )
m_widget( nullptr )
{
// Default column widths
m_colWidths[PART_COL] = 360;
@ -86,16 +84,6 @@ LIB_TREE_MODEL_ADAPTER::LIB_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent,
APP_SETTINGS_BASE* cfg = Kiface().KifaceSettings();
m_colWidths[PART_COL] = cfg->m_LibTree.column_width;
// Read the pinned entries from the project config
PROJECT_FILE& project = m_parent->Kiway().Prj().GetProjectFile();
std::vector<wxString>& entries = ( m_pinnedKey == "pinned_symbol_libs" ) ?
project.m_PinnedSymbolLibs :
project.m_PinnedFootprintLibs;
for( const wxString& entry : entries )
m_pinnedLibs.push_back( entry );
}
@ -113,28 +101,6 @@ void LIB_TREE_MODEL_ADAPTER::SaveColWidths()
}
void LIB_TREE_MODEL_ADAPTER::SavePinnedItems()
{
PROJECT_FILE& project = m_parent->Kiway().Prj().GetProjectFile();
std::vector<wxString>& entries = ( m_pinnedKey == "pinned_symbol_libs" ) ?
project.m_PinnedSymbolLibs :
project.m_PinnedFootprintLibs;
entries.clear();
m_pinnedLibs.clear();
for( std::unique_ptr<LIB_TREE_NODE>& child: m_tree.m_Children )
{
if( child->m_Pinned )
{
m_pinnedLibs.push_back( child->m_LibId.GetLibNickname() );
entries.push_back( child->m_LibId.GetLibNickname() );
}
}
}
void LIB_TREE_MODEL_ADAPTER::SetFilter( SYM_FILTER_TYPE aFilter )
{
m_filter = aFilter;
@ -155,11 +121,11 @@ void LIB_TREE_MODEL_ADAPTER::SetPreselectNode( const LIB_ID& aLibId, int aUnit )
LIB_TREE_NODE_LIB& LIB_TREE_MODEL_ADAPTER::DoAddLibraryNode( const wxString& aNodeName,
const wxString& aDesc )
const wxString& aDesc, bool pinned )
{
LIB_TREE_NODE_LIB& lib_node = m_tree.AddLib( aNodeName, aDesc );
lib_node.m_Pinned = m_pinnedLibs.Index( lib_node.m_LibId.GetLibNickname() ) != wxNOT_FOUND;
lib_node.m_Pinned = pinned;
return lib_node;
}
@ -167,9 +133,9 @@ LIB_TREE_NODE_LIB& LIB_TREE_MODEL_ADAPTER::DoAddLibraryNode( const wxString& aNo
void LIB_TREE_MODEL_ADAPTER::DoAddLibrary( const wxString& aNodeName, const wxString& aDesc,
const std::vector<LIB_TREE_ITEM*>& aItemList,
bool presorted )
bool pinned, bool presorted )
{
LIB_TREE_NODE_LIB& lib_node = DoAddLibraryNode( aNodeName, aDesc );
LIB_TREE_NODE_LIB& lib_node = DoAddLibraryNode( aNodeName, aDesc, pinned );
for( LIB_TREE_ITEM* item: aItemList )
lib_node.AddItem( item );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-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
@ -324,6 +324,12 @@ COMMON_SETTINGS::COMMON_SETTINGS() :
m_params.emplace_back( new PARAM<bool>( "session.remember_open_files",
&m_Session.remember_open_files, false ) );
m_params.emplace_back( new PARAM_LIST<wxString>( "session.pinned_symbol_libs",
&m_Session.pinned_symbol_libs, {} ) );
m_params.emplace_back( new PARAM_LIST<wxString>( "session.pinned_fp_libs",
&m_Session.pinned_fp_libs, {} ) );
m_params.emplace_back( new PARAM<int>( "netclass_panel.sash_pos",
&m_NetclassPanel.sash_pos, 160 ) );

View File

@ -153,8 +153,6 @@ LIB_TREE::~LIB_TREE()
// Save the column widths to the config file
m_adapter->SaveColWidths();
m_adapter->SavePinnedItems();
}

View File

@ -25,6 +25,7 @@
#include <pgm_base.h>
#include <settings/settings_manager.h>
#include <project/project_file.h>
#include <core/kicad_algo.h>
#include <symbol_library_common.h>
#include <confirm.h>
@ -97,6 +98,8 @@ PICKED_SYMBOL SCH_BASE_FRAME::PickSymbolFromLibTree( const SYMBOL_LIBRARY_FILTER
{
std::unique_lock<std::mutex> dialogLock( DIALOG_CHOOSE_SYMBOL::g_Mutex, std::defer_lock );
SYMBOL_LIB_TABLE* libs = Prj().SchSymbolLibTable();
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
PROJECT_FILE& project = Prj().GetProjectFile();
// One DIALOG_CHOOSE_SYMBOL dialog at a time. User probably can't handle more anyway.
if( !dialogLock.try_lock() )
@ -106,6 +109,7 @@ PICKED_SYMBOL SCH_BASE_FRAME::PickSymbolFromLibTree( const SYMBOL_LIBRARY_FILTER
Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> dataPtr
= SYMBOL_TREE_MODEL_ADAPTER::Create( this, libs );
SYMBOL_TREE_MODEL_ADAPTER* modelAdapter
@ -116,12 +120,16 @@ PICKED_SYMBOL SCH_BASE_FRAME::PickSymbolFromLibTree( const SYMBOL_LIBRARY_FILTER
{
const wxArrayString& liblist = aFilter->GetAllowedLibList();
for( unsigned ii = 0; ii < liblist.GetCount(); ii++ )
for( const wxString& nickname : liblist )
{
if( libs->HasLibrary( liblist[ii], true ) )
if( libs->HasLibrary( nickname, true ) )
{
loaded = true;
modelAdapter->AddLibrary( liblist[ii] );
bool pinned = alg::contains( cfg->m_Session.pinned_symbol_libs, nickname )
|| alg::contains( project.m_PinnedSymbolLibs, nickname );
modelAdapter->AddLibrary( nickname, pinned );
}
}
@ -158,7 +166,7 @@ PICKED_SYMBOL SCH_BASE_FRAME::PickSymbolFromLibTree( const SYMBOL_LIBRARY_FILTER
}
modelAdapter->DoAddLibrary( wxT( "-- " ) + _( "Recently Used" ) + wxT( " --" ), wxEmptyString,
history_list, true );
history_list, false, true );
if( !aHistoryList.empty() )
modelAdapter->SetPreselectNode( aHistoryList[0].LibId, aHistoryList[0].Unit );

View File

@ -22,18 +22,21 @@
#include <wx/log.h>
#include <wx/tokenzr.h>
#include <wx/window.h>
#include <core/kicad_algo.h>
#include <pgm_base.h>
#include <project/project_file.h>
#include <widgets/wx_progress_reporters.h>
#include <dialogs/html_message_box.h>
#include <eda_pattern_match.h>
#include <generate_alias_info.h>
#include <lib_symbol.h>
#include <sch_base_frame.h>
#include <locale_io.h>
#include <lib_symbol.h>
#include <symbol_async_loader.h>
#include <symbol_lib_table.h>
#include <symbol_tree_model_adapter.h>
#include <string_utils.h>
bool SYMBOL_TREE_MODEL_ADAPTER::m_show_progress = true;
#define PROGRESS_INTERVAL_MILLIS 33 // 30 FPS refresh rate
@ -58,14 +61,15 @@ SYMBOL_TREE_MODEL_ADAPTER::~SYMBOL_TREE_MODEL_ADAPTER()
bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNicknames,
wxWindow* aParent )
SCH_BASE_FRAME* aFrame )
{
std::unique_ptr<WX_PROGRESS_REPORTER> prg = nullptr;
std::unique_ptr<WX_PROGRESS_REPORTER> progressReporter = nullptr;
if( m_show_progress )
{
prg = std::make_unique<WX_PROGRESS_REPORTER>( aParent, _( "Loading Symbol Libraries" ),
aNicknames.size(), true );
progressReporter = std::make_unique<WX_PROGRESS_REPORTER>( aFrame,
_( "Loading Symbol Libraries" ),
aNicknames.size(), true );
}
// Disable KIID generation: not needed for library parts; sometimes very slow
@ -75,7 +79,7 @@ bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
SYMBOL_ASYNC_LOADER loader( aNicknames, m_libs,
GetFilter() == LIB_TREE_MODEL_ADAPTER::SYM_FILTER_POWER,
&loadedSymbols, prg.get() );
&loadedSymbols, progressReporter.get() );
LOCALE_IO toggle;
@ -83,7 +87,7 @@ bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
while( !loader.Done() )
{
if( prg && !prg->KeepRefreshing() )
if( progressReporter && !progressReporter->KeepRefreshing() )
break;
wxMilliSleep( PROGRESS_INTERVAL_MILLIS );
@ -93,12 +97,12 @@ bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
bool cancelled = false;
if( prg )
cancelled = prg->IsCancelled();
if( progressReporter )
cancelled = progressReporter->IsCancelled();
if( !loader.GetErrors().IsEmpty() )
{
HTML_MESSAGE_BOX dlg( aParent, _( "Load Error" ) );
HTML_MESSAGE_BOX dlg( aFrame, _( "Load Error" ) );
dlg.MessageSet( _( "Errors loading symbols:" ) );
@ -111,10 +115,17 @@ bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
if( loadedSymbols.size() > 0 )
{
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
PROJECT_FILE& project = aFrame->Prj().GetProjectFile();
for( const std::pair<const wxString, std::vector<LIB_SYMBOL*>>& pair : loadedSymbols )
{
std::vector<LIB_TREE_ITEM*> treeItems( pair.second.begin(), pair.second.end() );
DoAddLibrary( pair.first, m_libs->GetDescription( pair.first ), treeItems, false );
bool pinned = alg::contains( cfg->m_Session.pinned_symbol_libs, pair.first )
|| alg::contains( project.m_PinnedSymbolLibs, pair.first );
DoAddLibrary( pair.first, m_libs->GetDescription( pair.first ), treeItems, pinned,
false );
}
}
@ -122,7 +133,7 @@ bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
m_tree.AssignIntrinsicRanks();
if( prg )
if( progressReporter )
{
// Force immediate deletion of the APP_PROGRESS_DIALOG
// ( do not use Destroy(), or use Destroy() followed by wxSafeYield() )
@ -130,7 +141,7 @@ bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
// 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).
prg.reset();
progressReporter.reset();
m_show_progress = false;
}
@ -138,7 +149,7 @@ bool SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
}
void SYMBOL_TREE_MODEL_ADAPTER::AddLibrary( wxString const& aLibNickname )
void SYMBOL_TREE_MODEL_ADAPTER::AddLibrary( wxString const& aLibNickname, bool pinned )
{
bool onlyPowerSymbols = ( GetFilter() == SYM_FILTER_POWER );
std::vector<LIB_SYMBOL*> symbols;
@ -159,7 +170,8 @@ void SYMBOL_TREE_MODEL_ADAPTER::AddLibrary( wxString const& aLibNickname )
if( symbols.size() > 0 )
{
comp_list.assign( symbols.begin(), symbols.end() );
DoAddLibrary( aLibNickname, m_libs->GetDescription( aLibNickname ), comp_list, false );
DoAddLibrary( aLibNickname, m_libs->GetDescription( aLibNickname ), comp_list, pinned,
false );
}
}

View File

@ -26,6 +26,7 @@
class LIB_TABLE;
class SYMBOL_LIB_TABLE;
class SCH_BASE_FRAME;
class SYMBOL_TREE_MODEL_ADAPTER : public LIB_TREE_MODEL_ADAPTER
{
@ -51,9 +52,9 @@ public:
* @param aParent is the parent window to display the progress dialog
* @return false if loading was cancelled by the user
*/
bool AddLibraries( const std::vector<wxString>& aNicknames, wxWindow* aParent );
bool AddLibraries( const std::vector<wxString>& aNicknames, SCH_BASE_FRAME* aFrame );
void AddLibrary( wxString const& aLibNickname );
void AddLibrary( wxString const& aLibNickname, bool pinned );
wxString GenerateInfo( LIB_ID const& aLibId, int aUnit ) override;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -23,6 +23,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <pgm_base.h>
#include <project/project_file.h>
#include <symbol_tree_synchronizing_adapter.h>
#include <symbol_library_manager.h>
#include <symbol_lib_table.h>
@ -105,6 +107,10 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::Sync( const wxString& aForceRefresh,
}
// Look for new libraries
//
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
PROJECT_FILE& project = m_frame->Prj().GetProjectFile();
for( const wxString& libName : m_libMgr->GetLibraryNames() )
{
if( m_libHashes.count( libName ) == 0 )
@ -116,7 +122,10 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::Sync( const wxString& aForceRefresh,
}
SYMBOL_LIB_TABLE_ROW* library = m_libMgr->GetLibrary( libName );
LIB_TREE_NODE_LIB& lib_node = DoAddLibraryNode( libName, library->GetDescr() );
bool pinned = alg::contains( cfg->m_Session.pinned_symbol_libs, libName )
|| alg::contains( project.m_PinnedSymbolLibs, libName );
LIB_TREE_NODE_LIB& lib_node = DoAddLibraryNode( libName, library->GetDescr(), pinned );
updateLibrary( lib_node );
}

View File

@ -23,6 +23,10 @@
*/
#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>
@ -412,6 +416,20 @@ 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 ) );
currentNode->m_Pinned = true;
editFrame->RegenerateLibraryTree();
}
@ -430,6 +448,16 @@ 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 ) );
currentNode->m_Pinned = false;
editFrame->RegenerateLibraryTree();
}

View File

@ -137,7 +137,6 @@ public:
* valid.
*/
void SaveColWidths();
void SavePinnedItems();
/**
* Set the symbol filter type. Must be set before adding libraries
@ -177,7 +176,8 @@ public:
* @param aItemList list of symbols
*/
void DoAddLibrary( const wxString& aNodeName, const wxString& aDesc,
const std::vector<LIB_TREE_ITEM*>& aItemList, bool presorted );
const std::vector<LIB_TREE_ITEM*>& aItemList,
bool pinned, bool presorted );
/**
@ -307,7 +307,8 @@ protected:
*/
LIB_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent, const wxString& aPinnedKey );
LIB_TREE_NODE_LIB& DoAddLibraryNode( const wxString& aNodeName, const wxString& aDesc );
LIB_TREE_NODE_LIB& DoAddLibraryNode( const wxString& aNodeName, const wxString& aDesc,
bool pinned );
/**
* Check whether a container has columns too
@ -370,7 +371,7 @@ private:
* The highest-scoring node is written to aHighScore
*/
void Find( LIB_TREE_NODE& aNode, std::function<bool( const LIB_TREE_NODE* )> aFunc,
LIB_TREE_NODE** aHighScore );
LIB_TREE_NODE** aHighScore );
/**
* Find and expand successful search results. Return the best match (if any).
@ -404,8 +405,6 @@ private:
wxDataViewCtrl* m_widget;
int m_colWidths[NUM_COLS];
wxArrayString m_pinnedLibs;
wxString m_pinnedKey;
};
#endif // LIB_TREE_MODEL_ADAPTER_H

View File

@ -106,6 +106,8 @@ public:
struct SESSION
{
bool remember_open_files;
std::vector<wxString> pinned_symbol_libs;
std::vector<wxString> pinned_fp_libs;
};
struct SYSTEM

View File

@ -930,7 +930,7 @@ void FOOTPRINT_EDIT_FRAME::initLibraryTree()
m_adapter = FP_TREE_SYNCHRONIZING_ADAPTER::Create( this, fpTable );
auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
adapter->AddLibraries();
adapter->AddLibraries( this );
}

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2018-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
@ -17,6 +17,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <pgm_base.h>
#include <eda_base_frame.h>
#include <core/kicad_algo.h>
#include <settings/common_settings.h>
#include <project/project_file.h>
#include <wx/tokenzr.h>
#include <string_utils.h>
#include <eda_pattern_match.h>
@ -42,13 +47,18 @@ FP_TREE_MODEL_ADAPTER::FP_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent, LIB_TABLE
{}
void FP_TREE_MODEL_ADAPTER::AddLibraries()
void FP_TREE_MODEL_ADAPTER::AddLibraries( EDA_BASE_FRAME* aParent )
{
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
PROJECT_FILE& project = aParent->Prj().GetProjectFile();
for( const wxString& libName : m_libs->GetLogicalLibs() )
{
const FP_LIB_TABLE_ROW* library = m_libs->FindRow( libName, true );
bool pinned = alg::contains( cfg->m_Session.pinned_fp_libs, libName )
|| alg::contains( project.m_PinnedFootprintLibs, libName );
DoAddLibrary( libName, library->GetDescr(), getFootprints( libName ), true );
DoAddLibrary( libName, library->GetDescr(), getFootprints( libName ), pinned, true );
}
m_tree.AssignIntrinsicRanks();

View File

@ -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-2017 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
@ -39,7 +39,7 @@ public:
static wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> Create( EDA_BASE_FRAME* aParent,
LIB_TABLE* aLibs );
void AddLibraries();
void AddLibraries( EDA_BASE_FRAME* aParent );
wxString GenerateInfo( LIB_ID const& aLibId, int aUnit ) override;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -23,6 +23,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <pgm_base.h>
#include <project/project_file.h>
#include <fp_tree_synchronizing_adapter.h>
#include <footprint_edit_frame.h>
#include <fp_lib_table.h>
@ -87,15 +89,19 @@ void FP_TREE_SYNCHRONIZING_ADAPTER::Sync()
}
// Look for new libraries
size_t count = m_libMap.size();
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
PROJECT_FILE& project = m_frame->Prj().GetProjectFile();
size_t count = m_libMap.size();
for( const wxString& libName : m_libs->GetLogicalLibs() )
{
if( m_libMap.count( libName ) == 0 )
{
const FP_LIB_TABLE_ROW* library = m_libs->FindRow( libName, true );
bool pinned = alg::contains( cfg->m_Session.pinned_fp_libs, libName )
|| alg::contains( project.m_PinnedFootprintLibs, libName );
DoAddLibrary( libName, library->GetDescr(), getFootprints( libName ), true );
DoAddLibrary( libName, library->GetDescr(), getFootprints( libName ), pinned, true );
m_libMap.insert( libName );
}
}

View File

@ -253,14 +253,14 @@ FOOTPRINT* PCB_BASE_FRAME::SelectFootprintFromLibTree( LIB_ID aPreselect )
}
adapter->DoAddLibrary( wxT( "-- " ) + _( "Recently Used" ) + wxT( " --" ), wxEmptyString,
historyInfos, true );
historyInfos, false, true );
if( aPreselect.IsValid() )
adapter->SetPreselectNode( aPreselect, 0 );
else if( historyInfos.size() )
adapter->SetPreselectNode( historyInfos[0]->GetLibId(), 0 );
adapter->AddLibraries();
adapter->AddLibraries( this );
wxString title;
title.Printf( _( "Choose Footprint (%d items loaded)" ), adapter->GetItemCount() );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014-2019 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -27,6 +27,7 @@
#include "kicad_clipboard.h"
#include "wx/generic/textdlgg.h"
#include "string_utils.h"
#include <pgm_base.h>
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <view/view_controls.h>
@ -34,12 +35,13 @@
#include <pcbnew_id.h>
#include <confirm.h>
#include <widgets/infobar.h>
#include <bitmaps.h>
#include <footprint.h>
#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,6 +550,20 @@ 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 ) );
currentNode->m_Pinned = true;
m_frame->RegenerateLibraryTree();
}
@ -562,6 +578,16 @@ 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 ) );
currentNode->m_Pinned = false;
m_frame->RegenerateLibraryTree();
}