From 6f630f7054b4547934b678534e36f5aae0e87b0f Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sat, 26 Nov 2022 03:47:41 +0100 Subject: [PATCH] Sim: Make library path textbox editable Load the library from the path if enter is pressed or focus is lost if the library exists. If a library under the same path as previously is to be loaded this way, don't do anything. Fixes https://gitlab.com/kicad/code/kicad/issues/12970 --- eeschema/dialogs/dialog_sim_model.cpp | 50 +++++++++++++++++++--- eeschema/dialogs/dialog_sim_model.h | 4 +- eeschema/dialogs/dialog_sim_model_base.cpp | 12 ++++-- eeschema/dialogs/dialog_sim_model_base.fbp | 6 ++- eeschema/dialogs/dialog_sim_model_base.h | 4 +- eeschema/sim/sim_lib_mgr.cpp | 12 ++++++ eeschema/sim/sim_lib_mgr.h | 1 + 7 files changed, 75 insertions(+), 14 deletions(-) diff --git a/eeschema/dialogs/dialog_sim_model.cpp b/eeschema/dialogs/dialog_sim_model.cpp index 1ec8590e63..07d76ee3e3 100644 --- a/eeschema/dialogs/dialog_sim_model.cpp +++ b/eeschema/dialogs/dialog_sim_model.cpp @@ -613,10 +613,16 @@ void DIALOG_SIM_MODEL::removeOrphanedPinAssignments() template -void DIALOG_SIM_MODEL::loadLibrary( const wxString& aLibraryPath ) +void DIALOG_SIM_MODEL::loadLibrary( const wxString& aLibraryPath, bool aForceReload ) { - m_libraryModelsMgr.Clear(); - m_libraryModelsMgr.CreateLibrary( std::string( aLibraryPath.ToUTF8() ) ); + auto libraries = m_libraryModelsMgr.GetLibraries(); + + // Loading the same library as previously should normally be a no-op except when done using the + // library browse button. + if( !aForceReload && libraries.size() >= 1 && libraries.begin()->first == aLibraryPath ) + return; + + m_libraryModelsMgr.SetLibrary( std::string( aLibraryPath.ToUTF8() ) ); try { @@ -645,7 +651,7 @@ void DIALOG_SIM_MODEL::loadLibrary( const wxString& aLibraryPath ) if( validator ) validator->SetIncludes( modelNames ); - m_tclibraryPathName->ChangeValue( aLibraryPath ); + m_libraryPathText->ChangeValue( aLibraryPath ); m_modelNameCombobox->Set( modelNames ); m_useLibraryModelRadioButton->SetValue( true ); @@ -920,7 +926,7 @@ void DIALOG_SIM_MODEL::onRadioButton( wxCommandEvent& aEvent ) bool fromLibrary = m_useLibraryModelRadioButton->GetValue(); m_pathLabel->Enable( fromLibrary ); - m_tclibraryPathName->Enable( fromLibrary ); + m_libraryPathText->Enable( fromLibrary ); m_browseButton->Enable( fromLibrary ); m_modelNameLabel->Enable( fromLibrary ); m_modelNameCombobox->Enable( fromLibrary ); @@ -938,6 +944,38 @@ void DIALOG_SIM_MODEL::onRadioButton( wxCommandEvent& aEvent ) } +template +void DIALOG_SIM_MODEL::onLibraryPathTextEnter( wxCommandEvent& aEvent ) +{ + if( m_useLibraryModelRadioButton->GetValue() ) + { + wxString path = m_libraryPathText->GetValue(); + wxFileName fn( path ); + + if( fn.MakeRelativeTo( Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith( ".." ) ) + path = fn.GetFullPath(); + + try + { + loadLibrary( path ); + updateWidgets(); + } + catch( const IO_ERROR& ) + { + // TODO: Add an infobar to report the error? + } + } +} + + +template +void DIALOG_SIM_MODEL::onLibraryPathTextKillFocus( wxFocusEvent& aEvent ) +{ + wxCommandEvent dummy; + onLibraryPathTextEnter( dummy ); +} + + template void DIALOG_SIM_MODEL::onBrowseButtonClick( wxCommandEvent& aEvent ) { @@ -952,7 +990,7 @@ void DIALOG_SIM_MODEL::onBrowseButtonClick( wxCommandEvent& aEvent ) if( fn.MakeRelativeTo( Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith( ".." ) ) path = fn.GetFullPath(); - loadLibrary( path ); + loadLibrary( path, true ); updateWidgets(); } diff --git a/eeschema/dialogs/dialog_sim_model.h b/eeschema/dialogs/dialog_sim_model.h index 81f7b82e61..e67dffb77c 100644 --- a/eeschema/dialogs/dialog_sim_model.h +++ b/eeschema/dialogs/dialog_sim_model.h @@ -99,7 +99,7 @@ private: void removeOrphanedPinAssignments(); - void loadLibrary( const wxString& aLibraryPath ); + void loadLibrary( const wxString& aLibraryPath, bool aForceReload = false ); void addParamPropertyIfRelevant( int aParamIndex ); wxPGProperty* newParamProperty( int aParamIndex ) const; @@ -114,6 +114,8 @@ private: int getModelPinIndex( const wxString& aModelPinString ) const; void onRadioButton( wxCommandEvent& aEvent ) override; + void onLibraryPathTextEnter( wxCommandEvent& aEvent ) override; + void onLibraryPathTextKillFocus( wxFocusEvent& aEvent ) override; void onBrowseButtonClick( wxCommandEvent& aEvent ) override; void onModelNameCombobox( wxCommandEvent& aEvent ) override; void onModelNameComboboxKillFocus( wxFocusEvent& event ) override; diff --git a/eeschema/dialogs/dialog_sim_model_base.cpp b/eeschema/dialogs/dialog_sim_model_base.cpp index d8c85c5231..60c5c0f257 100644 --- a/eeschema/dialogs/dialog_sim_model_base.cpp +++ b/eeschema/dialogs/dialog_sim_model_base.cpp @@ -41,8 +41,8 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c wxBoxSizer* bSizer7; bSizer7 = new wxBoxSizer( wxHORIZONTAL ); - m_tclibraryPathName = new wxTextCtrl( m_modelPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY ); - bSizer7->Add( m_tclibraryPathName, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 ); + m_libraryPathText = new wxTextCtrl( m_modelPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); + bSizer7->Add( m_libraryPathText, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 ); m_browseButton = new wxBitmapButton( m_modelPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); bSizer7->Add( m_browseButton, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); @@ -285,7 +285,9 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c // Connect Events m_useLibraryModelRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this ); m_pathLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathLabelUpdate ), NULL, this ); - m_tclibraryPathName->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathUpdate ), NULL, this ); + m_libraryPathText->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextKillFocus ), NULL, this ); + m_libraryPathText->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextEnter ), NULL, this ); + m_libraryPathText->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathUpdate ), NULL, this ); m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonClick ), NULL, this ); m_browseButton->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonUpdate ), NULL, this ); m_modelNameLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameLabelUpdate ), NULL, this ); @@ -324,7 +326,9 @@ DIALOG_SIM_MODEL_BASE::~DIALOG_SIM_MODEL_BASE() // Disconnect Events m_useLibraryModelRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this ); m_pathLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathLabelUpdate ), NULL, this ); - m_tclibraryPathName->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathUpdate ), NULL, this ); + m_libraryPathText->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextKillFocus ), NULL, this ); + m_libraryPathText->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextEnter ), NULL, this ); + m_libraryPathText->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathUpdate ), NULL, this ); m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonClick ), NULL, this ); m_browseButton->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonUpdate ), NULL, this ); m_modelNameLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameLabelUpdate ), NULL, this ); diff --git a/eeschema/dialogs/dialog_sim_model_base.fbp b/eeschema/dialogs/dialog_sim_model_base.fbp index f73a840d86..58b0b9e46e 100644 --- a/eeschema/dialogs/dialog_sim_model_base.fbp +++ b/eeschema/dialogs/dialog_sim_model_base.fbp @@ -384,7 +384,7 @@ 0 -1,-1 1 - m_tclibraryPathName + m_libraryPathText 1 @@ -394,7 +394,7 @@ Resizable 1 - wxTE_READONLY + wxTE_PROCESS_ENTER ; ; forward_declare 0 @@ -406,6 +406,8 @@ + onLibraryPathTextKillFocus + onLibraryPathTextEnter onLibraryPathUpdate diff --git a/eeschema/dialogs/dialog_sim_model_base.h b/eeschema/dialogs/dialog_sim_model_base.h index 31da663305..823509fcff 100644 --- a/eeschema/dialogs/dialog_sim_model_base.h +++ b/eeschema/dialogs/dialog_sim_model_base.h @@ -56,7 +56,7 @@ class DIALOG_SIM_MODEL_BASE : public DIALOG_SHIM wxPanel* m_modelPanel; wxRadioButton* m_useLibraryModelRadioButton; wxStaticText* m_pathLabel; - wxTextCtrl* m_tclibraryPathName; + wxTextCtrl* m_libraryPathText; wxBitmapButton* m_browseButton; wxStaticText* m_modelNameLabel; wxComboBox* m_modelNameCombobox; @@ -88,6 +88,8 @@ class DIALOG_SIM_MODEL_BASE : public DIALOG_SHIM // Virtual event handlers, override them in your derived class virtual void onRadioButton( wxCommandEvent& event ) { event.Skip(); } virtual void onLibraryPathLabelUpdate( wxUpdateUIEvent& event ) { event.Skip(); } + virtual void onLibraryPathTextKillFocus( wxFocusEvent& event ) { event.Skip(); } + virtual void onLibraryPathTextEnter( wxCommandEvent& event ) { event.Skip(); } virtual void onLibraryPathUpdate( wxUpdateUIEvent& event ) { event.Skip(); } virtual void onBrowseButtonClick( wxCommandEvent& event ) { event.Skip(); } virtual void onBrowseButtonUpdate( wxUpdateUIEvent& event ) { event.Skip(); } diff --git a/eeschema/sim/sim_lib_mgr.cpp b/eeschema/sim/sim_lib_mgr.cpp index 1b16b5eb9f..0f123ded26 100644 --- a/eeschema/sim/sim_lib_mgr.cpp +++ b/eeschema/sim/sim_lib_mgr.cpp @@ -52,6 +52,18 @@ SIM_LIBRARY& SIM_LIB_MGR::CreateLibrary( const std::string& aLibraryPath ) return *it->second; } +SIM_LIBRARY& SIM_LIB_MGR::SetLibrary( const std::string& aLibraryPath ) +{ + std::string absolutePath = std::string( m_project.AbsolutePath( aLibraryPath ).ToUTF8() ); + + // May throw an exception. + std::unique_ptr library = SIM_LIBRARY::Create( absolutePath ); + + Clear(); + m_libraries[aLibraryPath] = std::move( library ); + return *m_libraries.at( aLibraryPath ); +} + SIM_MODEL& SIM_LIB_MGR::CreateModel( SIM_MODEL::TYPE aType, int aSymbolPinCount ) { diff --git a/eeschema/sim/sim_lib_mgr.h b/eeschema/sim/sim_lib_mgr.h index e8008ca9b2..bd52da1657 100644 --- a/eeschema/sim/sim_lib_mgr.h +++ b/eeschema/sim/sim_lib_mgr.h @@ -46,6 +46,7 @@ public: void Clear(); SIM_LIBRARY& CreateLibrary( const std::string& aLibraryPath ); + SIM_LIBRARY& SetLibrary( const std::string& aLibraryPath ); SIM_MODEL& CreateModel( SIM_MODEL::TYPE aType, int aSymbolPinCount );