diff --git a/common/lib_tree_model_adapter.cpp b/common/lib_tree_model_adapter.cpp index c8e170dccb..5a4a06873a 100644 --- a/common/lib_tree_model_adapter.cpp +++ b/common/lib_tree_model_adapter.cpp @@ -155,6 +155,38 @@ LIB_TREE_MODEL_ADAPTER::~LIB_TREE_MODEL_ADAPTER() {} +std::vector LIB_TREE_MODEL_ADAPTER::GetOpenLibs() const +{ + std::vector openLibs; + wxDataViewItem rootItem( nullptr ); + wxDataViewItemArray children; + + GetChildren( rootItem, children ); + + for( const wxDataViewItem& child : children ) + { + if( m_widget->IsExpanded( child ) ) + openLibs.emplace_back( ToNode( child )->m_LibId.GetLibNickname() ); + } + + return openLibs; +} + + +void LIB_TREE_MODEL_ADAPTER::OpenLibs( const std::vector& aLibs ) +{ + wxWindowUpdateLocker updateLock( m_widget ); + + for( const wxString& lib : aLibs ) + { + wxDataViewItem item = FindItem( LIB_ID( lib, wxEmptyString ) ); + + if( item.IsOk() ) + m_widget->Expand( item ); + } +} + + void LIB_TREE_MODEL_ADAPTER::SaveSettings() { if( m_widget ) @@ -166,6 +198,8 @@ void LIB_TREE_MODEL_ADAPTER::SaveSettings() for( const std::pair& pair : m_colNameMap ) cfg->m_LibTree.column_widths[pair.first] = pair.second->GetWidth(); + + cfg->m_LibTree.open_libs = GetOpenLibs(); } } diff --git a/common/settings/app_settings.cpp b/common/settings/app_settings.cpp index 790b7b85d5..7fd7e19192 100644 --- a/common/settings/app_settings.cpp +++ b/common/settings/app_settings.cpp @@ -109,6 +109,9 @@ APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaV }, {} ) ); + m_params.emplace_back( + new PARAM_LIST( "lib_tree.open_libs", &m_LibTree.open_libs, {} ) ); + m_params.emplace_back( new PARAM( "printing.background", &m_Printing.background, false ) ); diff --git a/eeschema/symbol_tree_synchronizing_adapter.cpp b/eeschema/symbol_tree_synchronizing_adapter.cpp index 47f7fe01d1..bdeb8bd3a2 100644 --- a/eeschema/symbol_tree_synchronizing_adapter.cpp +++ b/eeschema/symbol_tree_synchronizing_adapter.cpp @@ -403,4 +403,4 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::ShowPreview( wxWindow* aPare } preview->DisplaySymbol( node->m_LibId, node->m_Unit ); -} \ No newline at end of file +} diff --git a/eeschema/widgets/panel_symbol_chooser.cpp b/eeschema/widgets/panel_symbol_chooser.cpp index 3968605e91..11a05c3029 100644 --- a/eeschema/widgets/panel_symbol_chooser.cpp +++ b/eeschema/widgets/panel_symbol_chooser.cpp @@ -253,12 +253,14 @@ PANEL_SYMBOL_CHOOSER::PANEL_SYMBOL_CHOOSER( SCH_BASE_FRAME* aFrame, wxWindow* aP m_hsplitter->SplitVertically( treePanel, constructRightPanel( m_hsplitter ) ); m_dbl_click_timer = new wxTimer( this ); + m_open_libs_timer = new wxTimer( this ); SetSizer( sizer ); Layout(); Bind( wxEVT_TIMER, &PANEL_SYMBOL_CHOOSER::onCloseTimer, this, m_dbl_click_timer->GetId() ); + Bind( wxEVT_TIMER, &PANEL_SYMBOL_CHOOSER::onOpenLibsTimer, this, m_open_libs_timer->GetId() ); Bind( EVT_LIBITEM_SELECTED, &PANEL_SYMBOL_CHOOSER::onSymbolSelected, this ); Bind( EVT_LIBITEM_CHOSEN, &PANEL_SYMBOL_CHOOSER::onSymbolChosen, this ); Bind( wxEVT_CHAR_HOOK, &PANEL_SYMBOL_CHOOSER::OnChar, this ); @@ -275,6 +277,11 @@ PANEL_SYMBOL_CHOOSER::PANEL_SYMBOL_CHOOSER( SCH_BASE_FRAME* aFrame, wxWindow* aP wxKeyEventHandler( PANEL_SYMBOL_CHOOSER::OnDetailsCharHook ), nullptr, this ); } + + // Open the user's previously opened libraries on timer expiration. + // This is done on a timer because we need a gross hack to keep GTK from garbling the + // display. Must be longer than the search debounce timer. + m_open_libs_timer->StartOnce( 300 ); } @@ -287,7 +294,9 @@ PANEL_SYMBOL_CHOOSER::~PANEL_SYMBOL_CHOOSER() // Stop the timer during destruction early to avoid potential race conditions (that do happen) m_dbl_click_timer->Stop(); + m_open_libs_timer->Stop(); delete m_dbl_click_timer; + delete m_open_libs_timer; if( m_showPower ) g_powerSearchString = m_tree->GetSearchString(); @@ -506,6 +515,13 @@ void PANEL_SYMBOL_CHOOSER::onCloseTimer( wxTimerEvent& aEvent ) } +void PANEL_SYMBOL_CHOOSER::onOpenLibsTimer( wxTimerEvent& aEvent ) +{ + if( EESCHEMA_SETTINGS* cfg = dynamic_cast( Kiface().KifaceSettings() ) ) + m_adapter->OpenLibs( cfg->m_LibTree.open_libs ); +} + + void PANEL_SYMBOL_CHOOSER::showFootprintFor( LIB_ID const& aLibId ) { if( !m_fp_preview || !m_fp_preview->IsInitialized() ) diff --git a/eeschema/widgets/panel_symbol_chooser.h b/eeschema/widgets/panel_symbol_chooser.h index c67f9ddf0a..6c0a6d66e9 100644 --- a/eeschema/widgets/panel_symbol_chooser.h +++ b/eeschema/widgets/panel_symbol_chooser.h @@ -105,6 +105,7 @@ protected: void OnDetailsCharHook( wxKeyEvent& aEvt ); void onCloseTimer( wxTimerEvent& aEvent ); + void onOpenLibsTimer( wxTimerEvent& aEvent ); void onFootprintSelected( wxCommandEvent& aEvent ); void onSymbolSelected( wxCommandEvent& aEvent ); @@ -142,6 +143,7 @@ protected: static wxString g_powerSearchString; wxTimer* m_dbl_click_timer; + wxTimer* m_open_libs_timer; SYMBOL_PREVIEW_WIDGET* m_symbol_preview; wxSplitterWindow* m_hsplitter; wxSplitterWindow* m_vsplitter; diff --git a/include/lib_tree_model_adapter.h b/include/lib_tree_model_adapter.h index bcc8a8d8cd..6aa50aa12e 100644 --- a/include/lib_tree_model_adapter.h +++ b/include/lib_tree_model_adapter.h @@ -185,6 +185,9 @@ public: std::vector GetShownColumns() const { return m_shownColumns; } + std::vector GetOpenLibs() const; + void OpenLibs( const std::vector& aLibs ); + /** * Sets which columns are shown in the widget. Invalid column names are discarded. * @param aColumnNames is an ordered list of column names to show diff --git a/include/settings/app_settings.h b/include/settings/app_settings.h index 48bb12322f..f7d4b7264d 100644 --- a/include/settings/app_settings.h +++ b/include/settings/app_settings.h @@ -120,6 +120,7 @@ public: { std::vector columns; ///< Ordered list of visible columns in the tree std::map column_widths; ///< Column widths, keyed by header name + std::vector open_libs; ///< list of libraries the user has open in the tree }; struct PRINTING diff --git a/include/widgets/lib_tree.h b/include/widgets/lib_tree.h index 9c5c315909..84f17c56ca 100644 --- a/include/widgets/lib_tree.h +++ b/include/widgets/lib_tree.h @@ -188,7 +188,6 @@ protected: { ///< List of expanded nodes std::vector expanded; - std::vector pinned; ///< Current selection, might be not valid if nothing was selected LIB_ID selection; diff --git a/pcbnew/widgets/panel_footprint_chooser.cpp b/pcbnew/widgets/panel_footprint_chooser.cpp index be44e3029c..61968866e0 100644 --- a/pcbnew/widgets/panel_footprint_chooser.cpp +++ b/pcbnew/widgets/panel_footprint_chooser.cpp @@ -41,6 +41,7 @@ #include #include #include +#include PANEL_FOOTPRINT_CHOOSER::PANEL_FOOTPRINT_CHOOSER( PCB_BASE_FRAME* aFrame, wxTopLevelWindow* aParent, @@ -147,12 +148,14 @@ PANEL_FOOTPRINT_CHOOSER::PANEL_FOOTPRINT_CHOOSER( PCB_BASE_FRAME* aFrame, wxTopL m_hsplitter->SplitVertically( m_tree, rightPanel ); m_dbl_click_timer = new wxTimer( this ); + m_open_libs_timer = new wxTimer( this ); SetSizer( sizer ); m_adapter->FinishTreeInitialization(); Bind( wxEVT_TIMER, &PANEL_FOOTPRINT_CHOOSER::onCloseTimer, this, m_dbl_click_timer->GetId() ); + Bind( wxEVT_TIMER, &PANEL_FOOTPRINT_CHOOSER::onOpenLibsTimer, this, m_open_libs_timer->GetId() ); Bind( EVT_LIBITEM_SELECTED, &PANEL_FOOTPRINT_CHOOSER::onFootprintSelected, this ); Bind( EVT_LIBITEM_CHOSEN, &PANEL_FOOTPRINT_CHOOSER::onFootprintChosen, this ); @@ -192,6 +195,11 @@ PANEL_FOOTPRINT_CHOOSER::PANEL_FOOTPRINT_CHOOSER( PCB_BASE_FRAME* aFrame, wxTopL } ); Layout(); + + // Open the user's previously opened libraries on timer expiration. + // This is done on a timer because we need a gross hack to keep GTK from garbling the + // display. Must be longer than the search debounce timer. + m_open_libs_timer->StartOnce( 300 ); } @@ -207,7 +215,9 @@ PANEL_FOOTPRINT_CHOOSER::~PANEL_FOOTPRINT_CHOOSER() // I am not sure the following two lines are necessary, but they will not hurt anyone m_dbl_click_timer->Stop(); + m_open_libs_timer->Stop(); delete m_dbl_click_timer; + delete m_open_libs_timer; PCBNEW_SETTINGS* cfg = nullptr; try @@ -305,6 +315,13 @@ void PANEL_FOOTPRINT_CHOOSER::onCloseTimer( wxTimerEvent& aEvent ) } +void PANEL_FOOTPRINT_CHOOSER::onOpenLibsTimer( wxTimerEvent& aEvent ) +{ + if( PCBNEW_SETTINGS* cfg = dynamic_cast( Kiface().KifaceSettings() ) ) + m_adapter->OpenLibs( cfg->m_LibTree.open_libs ); +} + + void PANEL_FOOTPRINT_CHOOSER::onFootprintSelected( wxCommandEvent& aEvent ) { if( !m_preview_ctrl || !m_preview_ctrl->IsInitialized() ) diff --git a/pcbnew/widgets/panel_footprint_chooser.h b/pcbnew/widgets/panel_footprint_chooser.h index 0e6372f7b0..d32647634d 100644 --- a/pcbnew/widgets/panel_footprint_chooser.h +++ b/pcbnew/widgets/panel_footprint_chooser.h @@ -76,6 +76,7 @@ protected: void OnDetailsCharHook( wxKeyEvent& aEvt ); void onCloseTimer( wxTimerEvent& aEvent ); + void onOpenLibsTimer( wxTimerEvent& aEvent ); void onFootprintSelected( wxCommandEvent& aEvent ); @@ -89,6 +90,7 @@ protected: protected: wxTimer* m_dbl_click_timer; + wxTimer* m_open_libs_timer; wxSplitterWindow* m_hsplitter; wxSplitterWindow* m_vsplitter;