From def87c969e1e9351631066841a0680ce045138c4 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Fri, 22 Jul 2022 09:26:49 +0100 Subject: [PATCH] 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 --- common/lib_tree_model_adapter.cpp | 44 +++---------------- common/settings/common_settings.cpp | 8 +++- common/widgets/lib_tree.cpp | 2 - eeschema/picksymbol.cpp | 16 +++++-- eeschema/symbol_tree_model_adapter.cpp | 44 ++++++++++++------- eeschema/symbol_tree_model_adapter.h | 5 ++- .../symbol_tree_synchronizing_adapter.cpp | 13 +++++- eeschema/tools/symbol_editor_control.cpp | 28 ++++++++++++ include/lib_tree_model_adapter.h | 11 +++-- include/settings/common_settings.h | 2 + pcbnew/footprint_edit_frame.cpp | 2 +- pcbnew/fp_tree_model_adapter.cpp | 16 +++++-- pcbnew/fp_tree_model_adapter.h | 4 +- pcbnew/fp_tree_synchronizing_adapter.cpp | 12 +++-- pcbnew/load_select_footprint.cpp | 4 +- pcbnew/tools/footprint_editor_control.cpp | 30 ++++++++++++- 16 files changed, 156 insertions(+), 85 deletions(-) diff --git a/common/lib_tree_model_adapter.cpp b/common/lib_tree_model_adapter.cpp index f08320e7c3..bc90cf7529 100644 --- a/common/lib_tree_model_adapter.cpp +++ b/common/lib_tree_model_adapter.cpp @@ -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& 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& entries = ( m_pinnedKey == "pinned_symbol_libs" ) ? - project.m_PinnedSymbolLibs : - project.m_PinnedFootprintLibs; - - entries.clear(); - m_pinnedLibs.clear(); - - for( std::unique_ptr& 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& 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 ); diff --git a/common/settings/common_settings.cpp b/common/settings/common_settings.cpp index 2053c0a7fa..2a9f8efdfe 100644 --- a/common/settings/common_settings.cpp +++ b/common/settings/common_settings.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2020 Jon Evans - * 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( "session.remember_open_files", &m_Session.remember_open_files, false ) ); + m_params.emplace_back( new PARAM_LIST( "session.pinned_symbol_libs", + &m_Session.pinned_symbol_libs, {} ) ); + + m_params.emplace_back( new PARAM_LIST( "session.pinned_fp_libs", + &m_Session.pinned_fp_libs, {} ) ); + m_params.emplace_back( new PARAM( "netclass_panel.sash_pos", &m_NetclassPanel.sash_pos, 160 ) ); diff --git a/common/widgets/lib_tree.cpp b/common/widgets/lib_tree.cpp index 5306a0774d..e83e2979b7 100644 --- a/common/widgets/lib_tree.cpp +++ b/common/widgets/lib_tree.cpp @@ -153,8 +153,6 @@ LIB_TREE::~LIB_TREE() // Save the column widths to the config file m_adapter->SaveColWidths(); - - m_adapter->SavePinnedItems(); } diff --git a/eeschema/picksymbol.cpp b/eeschema/picksymbol.cpp index c65faf41f5..fe033e37ff 100644 --- a/eeschema/picksymbol.cpp +++ b/eeschema/picksymbol.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -97,6 +98,8 @@ PICKED_SYMBOL SCH_BASE_FRAME::PickSymbolFromLibTree( const SYMBOL_LIBRARY_FILTER { std::unique_lock 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(); Pgm().GetSettingsManager().GetAppSettings(); + wxObjectDataPtr 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 ); diff --git a/eeschema/symbol_tree_model_adapter.cpp b/eeschema/symbol_tree_model_adapter.cpp index 6d16439345..093fee6a6e 100644 --- a/eeschema/symbol_tree_model_adapter.cpp +++ b/eeschema/symbol_tree_model_adapter.cpp @@ -22,18 +22,21 @@ #include #include #include +#include +#include +#include #include #include #include #include -#include +#include #include +#include #include #include #include #include - 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& aNicknames, - wxWindow* aParent ) + SCH_BASE_FRAME* aFrame ) { - std::unique_ptr prg = nullptr; + std::unique_ptr progressReporter = nullptr; if( m_show_progress ) { - prg = std::make_unique( aParent, _( "Loading Symbol Libraries" ), - aNicknames.size(), true ); + progressReporter = std::make_unique( 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& 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& 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& 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& aNick if( loadedSymbols.size() > 0 ) { + COMMON_SETTINGS* cfg = Pgm().GetCommonSettings(); + PROJECT_FILE& project = aFrame->Prj().GetProjectFile(); + for( const std::pair>& pair : loadedSymbols ) { std::vector 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& 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& 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& 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 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 ); } } diff --git a/eeschema/symbol_tree_model_adapter.h b/eeschema/symbol_tree_model_adapter.h index 95611cd16f..4dfc165029 100644 --- a/eeschema/symbol_tree_model_adapter.h +++ b/eeschema/symbol_tree_model_adapter.h @@ -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& aNicknames, wxWindow* aParent ); + bool AddLibraries( const std::vector& 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; diff --git a/eeschema/symbol_tree_synchronizing_adapter.cpp b/eeschema/symbol_tree_synchronizing_adapter.cpp index eda7a74f8c..223fbafe08 100644 --- a/eeschema/symbol_tree_synchronizing_adapter.cpp +++ b/eeschema/symbol_tree_synchronizing_adapter.cpp @@ -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 * * 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 +#include #include #include #include @@ -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 ); } diff --git a/eeschema/tools/symbol_editor_control.cpp b/eeschema/tools/symbol_editor_control.cpp index a4ba66404f..042b49c4b4 100644 --- a/eeschema/tools/symbol_editor_control.cpp +++ b/eeschema/tools/symbol_editor_control.cpp @@ -23,6 +23,10 @@ */ #include +#include +#include +#include +#include #include #include #include @@ -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(); } diff --git a/include/lib_tree_model_adapter.h b/include/lib_tree_model_adapter.h index f27dd54663..d70cfcf168 100644 --- a/include/lib_tree_model_adapter.h +++ b/include/lib_tree_model_adapter.h @@ -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& aItemList, bool presorted ); + const std::vector& 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 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 diff --git a/include/settings/common_settings.h b/include/settings/common_settings.h index 71427d7663..eb14709282 100644 --- a/include/settings/common_settings.h +++ b/include/settings/common_settings.h @@ -106,6 +106,8 @@ public: struct SESSION { bool remember_open_files; + std::vector pinned_symbol_libs; + std::vector pinned_fp_libs; }; struct SYSTEM diff --git a/pcbnew/footprint_edit_frame.cpp b/pcbnew/footprint_edit_frame.cpp index 3058b1c0f2..30fecdc306 100644 --- a/pcbnew/footprint_edit_frame.cpp +++ b/pcbnew/footprint_edit_frame.cpp @@ -930,7 +930,7 @@ void FOOTPRINT_EDIT_FRAME::initLibraryTree() m_adapter = FP_TREE_SYNCHRONIZING_ADAPTER::Create( this, fpTable ); auto adapter = static_cast( m_adapter.get() ); - adapter->AddLibraries(); + adapter->AddLibraries( this ); } diff --git a/pcbnew/fp_tree_model_adapter.cpp b/pcbnew/fp_tree_model_adapter.cpp index ddfa225125..fa257989f4 100644 --- a/pcbnew/fp_tree_model_adapter.cpp +++ b/pcbnew/fp_tree_model_adapter.cpp @@ -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 . */ +#include +#include +#include +#include +#include #include #include #include @@ -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(); diff --git a/pcbnew/fp_tree_model_adapter.h b/pcbnew/fp_tree_model_adapter.h index 97d0b43a11..f2617dc1ed 100644 --- a/pcbnew/fp_tree_model_adapter.h +++ b/pcbnew/fp_tree_model_adapter.h @@ -3,7 +3,7 @@ * * Copyright (C) 2017 Chris Pavlina * Copyright (C) 2014 Henner Zeller - * 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 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; diff --git a/pcbnew/fp_tree_synchronizing_adapter.cpp b/pcbnew/fp_tree_synchronizing_adapter.cpp index 6a8e681e89..2bb93d2624 100644 --- a/pcbnew/fp_tree_synchronizing_adapter.cpp +++ b/pcbnew/fp_tree_synchronizing_adapter.cpp @@ -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 * * 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 +#include #include #include #include @@ -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 ); } } diff --git a/pcbnew/load_select_footprint.cpp b/pcbnew/load_select_footprint.cpp index d1f789211c..6733a2cb62 100644 --- a/pcbnew/load_select_footprint.cpp +++ b/pcbnew/load_select_footprint.cpp @@ -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() ); diff --git a/pcbnew/tools/footprint_editor_control.cpp b/pcbnew/tools/footprint_editor_control.cpp index 8ff2c6a4a5..4d856e485e 100644 --- a/pcbnew/tools/footprint_editor_control.cpp +++ b/pcbnew/tools/footprint_editor_control.cpp @@ -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 * * 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 #include #include #include @@ -34,12 +35,13 @@ #include #include #include -#include #include #include #include #include #include +#include +#include #include #include #include @@ -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(); }