From bc357dff8a3d5ced991e4dc2fe41095fcf01ff6e Mon Sep 17 00:00:00 2001 From: Fabien Corona Date: Sat, 8 Aug 2020 18:52:14 +0000 Subject: [PATCH] Add "Close project" Allow the user to close a project from the project manager. Distinguish the open project from the file history. Fixes https://gitlab.com/kicad/code/kicad/-/issues/4964 --- include/settings/app_settings.h | 2 + kicad/kicad.cpp | 4 +- kicad/kicad_manager_frame.cpp | 114 ++++++++++++++++++++++---- kicad/kicad_manager_frame.h | 12 +++ kicad/kicad_settings.cpp | 2 + kicad/menubar.cpp | 1 + kicad/tools/kicad_manager_actions.cpp | 6 ++ kicad/tools/kicad_manager_actions.h | 1 + kicad/tools/kicad_manager_control.cpp | 9 +- kicad/tools/kicad_manager_control.h | 1 + kicad/tree_project_frame.cpp | 6 ++ kicad/tree_project_frame.h | 5 ++ 12 files changed, 145 insertions(+), 18 deletions(-) diff --git a/include/settings/app_settings.h b/include/settings/app_settings.h index 44d8a3a764..5d49894ff0 100644 --- a/include/settings/app_settings.h +++ b/include/settings/app_settings.h @@ -128,6 +128,8 @@ public: { bool first_run_shown; int max_undo_items; + std::vector open_projects; // using a vector if in the future + // we want to open multiple projects at once. std::vector file_history; int units; }; diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp index 740cae995a..3d3e66da8f 100644 --- a/kicad/kicad.cpp +++ b/kicad/kicad.cpp @@ -139,9 +139,9 @@ bool PGM_KICAD::OnPgmInit() { projToLoad = App().argv[1]; } - else if( frame->GetFileHistory().GetCount() ) + else if( frame->GetOpenProjects().size() ) // Check that there was a file open. { - wxString last_pro = frame->GetFileHistory().GetHistoryFile( 0 ); + wxString last_pro = frame->PopOpenProjects(); if( !wxFileExists( last_pro ) ) { diff --git a/kicad/kicad_manager_frame.cpp b/kicad/kicad_manager_frame.cpp index 70905170ef..08f6eff84d 100644 --- a/kicad/kicad_manager_frame.cpp +++ b/kicad/kicad_manager_frame.cpp @@ -220,9 +220,53 @@ void KICAD_MANAGER_FRAME::SetProjectFileName( const wxString& aFullProjectProFil } +std::vector KICAD_MANAGER_FRAME::GetOpenProjects() +{ + KICAD_SETTINGS* conf = dynamic_cast( config() ); + + if( conf == NULL ) + { + // Build an empty vector to return + std::vector dummy; + return dummy; + } + + return conf->m_System.open_projects; +} + + +wxString KICAD_MANAGER_FRAME::PopOpenProjects() +{ + KICAD_SETTINGS* conf = dynamic_cast( config() ); + + if( conf == NULL ) + { + return wxString( "" ); + } + + std::vector* vector = &( conf->m_System.open_projects ); + + if( vector->size() > 0 ) + { + wxString value = vector->front(); + vector->erase( vector->begin() ); + return value; + } + else + { + return wxString( "" ); + } +} + + const wxString KICAD_MANAGER_FRAME::GetProjectFileName() const { - return Prj().GetProjectFullName(); + if( m_active_project ) + return Prj().GetProjectFullName(); + else + { + return wxString( "" ); + } } @@ -334,6 +378,51 @@ void KICAD_MANAGER_FRAME::OnExit( wxCommandEvent& event ) } +bool KICAD_MANAGER_FRAME::CloseProject( bool aSave ) +{ + + if( !Kiway().PlayersClose( false ) ) + return false; + + // Save the project file for the currently loaded project. + if( m_active_project ) + { + // Remove the project from the list of active projects + std::vector::iterator ptr; + std::vector* prjList; + + prjList = &( config()->m_System.open_projects ); + + for( ptr = prjList->begin(); ptr < prjList->end(); ptr++ ) + { + if( *ptr == Prj().GetProjectFullName() ) + { + prjList->erase( ptr ); + break; + } + } + + SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager(); + + mgr.TriggerBackupIfNeeded( NULL_REPORTER::GetInstance() ); + + if( aSave ) + { + mgr.SaveProject(); + } + + m_active_project = false; + mgr.UnloadProject( &Prj() ); + } + + ClearMsg(); + + m_leftWin->EmptyTreePrj(); + + return true; +} + + void KICAD_MANAGER_FRAME::LoadProject( const wxFileName& aProjectFileName ) { // The project file should be valid by the time we get here or something has gone wrong. @@ -343,25 +432,17 @@ void KICAD_MANAGER_FRAME::LoadProject( const wxFileName& aProjectFileName ) // Any open KIFACE's must be closed if they are not part of the new project. // (We never want a KIWAY_PLAYER open on a KIWAY that isn't in the same project.) // User is prompted here to close those KIWAY_PLAYERs: - if( !Kiway().PlayersClose( false ) ) - return; - - // Save the project file for the currently loaded project. - if( m_active_project ) - { - SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager(); - - mgr.TriggerBackupIfNeeded( NULL_REPORTER::GetInstance() ); - mgr.SaveProject(); - mgr.UnloadProject( &Prj() ); - } + CloseProject( true ); m_active_project = true; - ClearMsg(); Pgm().GetSettingsManager().LoadProject( aProjectFileName.GetFullPath() ); SetProjectFileName( Prj().GetProjectFullName() ); + std::vector::iterator ptr; + ptr = config()->m_System.open_projects.begin(); + config()->m_System.open_projects.insert( ptr, Prj().GetProjectFullName() ); + if( aProjectFileName.IsDirWritable() ) SetMruPath( Prj().GetProjectPath() ); // Only set MRU path if we have write access. Why? @@ -571,4 +652,7 @@ void KICAD_MANAGER_FRAME::PrintPrjInfo() PrintMsg( msg ); } - +bool KICAD_MANAGER_FRAME::IsProjectActive() +{ + return m_active_project; +} diff --git a/kicad/kicad_manager_frame.h b/kicad/kicad_manager_frame.h index 47cc108c07..fc307af19c 100644 --- a/kicad/kicad_manager_frame.h +++ b/kicad/kicad_manager_frame.h @@ -100,6 +100,12 @@ public: void RecreateBaseHToolbar(); void RecreateLauncher(); + std::vector GetOpenProjects(); + /** + * Get element at index 0, and remove it. + */ + wxString PopOpenProjects(); + wxString GetCurrentFileName() const override { return GetProjectFileName(); @@ -140,6 +146,11 @@ public: * @param aProjectFileName is the absolute path of the project file name. */ void CreateNewProject( const wxFileName& aProjectFileName ); + + /** + * Closes the project, and saves it if aSave is true; + */ + bool CloseProject( bool aSave ); void LoadProject( const wxFileName& aProjectFileName ); @@ -163,6 +174,7 @@ public: void SetProjectFileName( const wxString& aFullProjectProFileName ); const wxString GetProjectFileName() const; + bool IsProjectActive(); // read only accessors const wxString SchFileName(); const wxString SchLegacyFileName(); diff --git a/kicad/kicad_settings.cpp b/kicad/kicad_settings.cpp index 7865cb552a..db3ea5378f 100644 --- a/kicad/kicad_settings.cpp +++ b/kicad/kicad_settings.cpp @@ -29,6 +29,8 @@ const int kicadSchemaVersion = 0; KICAD_SETTINGS::KICAD_SETTINGS() : APP_SETTINGS_BASE( "kicad", kicadSchemaVersion ) { m_params.emplace_back( new PARAM( "appearance.left_frame_width", &m_LeftWinWidth, 200 ) ); + m_params.emplace_back( + new PARAM_LIST( "system.open_projects", &m_System.open_projects, {} ) ); } diff --git a/kicad/menubar.cpp b/kicad/menubar.cpp index 3605632b02..73ba7191e8 100644 --- a/kicad/menubar.cpp +++ b/kicad/menubar.cpp @@ -70,6 +70,7 @@ void KICAD_MANAGER_FRAME::ReCreateMenuBar() fileMenu->AddItem( KICAD_MANAGER_ACTIONS::newProject, SELECTION_CONDITIONS::ShowAlways ); fileMenu->AddItem( KICAD_MANAGER_ACTIONS::newFromTemplate, SELECTION_CONDITIONS::ShowAlways ); fileMenu->AddItem( KICAD_MANAGER_ACTIONS::openProject, SELECTION_CONDITIONS::ShowAlways ); + fileMenu->AddItem( KICAD_MANAGER_ACTIONS::closeProject, SELECTION_CONDITIONS::ShowAlways ); fileMenu->AddMenu( openRecentMenu, FILE_HISTORY::FileHistoryNotEmpty( fileHistory ) ); diff --git a/kicad/tools/kicad_manager_actions.cpp b/kicad/tools/kicad_manager_actions.cpp index 1973936842..0516324bb1 100644 --- a/kicad/tools/kicad_manager_actions.cpp +++ b/kicad/tools/kicad_manager_actions.cpp @@ -53,6 +53,12 @@ TOOL_ACTION KICAD_MANAGER_ACTIONS::openProject( "kicad.Control.openProject", _( "Open Project..." ), _( "Open an existing project" ), directory_xpm ); +TOOL_ACTION KICAD_MANAGER_ACTIONS::closeProject( "kicad.Control.closeProject", + AS_GLOBAL, + 0, LEGACY_HK_NAME( "Close Project" ), + _( "Close Project" ), _( "Close the current project" ), + directory_xpm ); + TOOL_ACTION KICAD_MANAGER_ACTIONS::editSchematic( "kicad.Control.editSchematic", AS_GLOBAL, MD_CTRL + 'E', LEGACY_HK_NAME( "Run Eeschema" ), diff --git a/kicad/tools/kicad_manager_actions.h b/kicad/tools/kicad_manager_actions.h index d693f135c6..a6cf5a0bfe 100644 --- a/kicad/tools/kicad_manager_actions.h +++ b/kicad/tools/kicad_manager_actions.h @@ -41,6 +41,7 @@ public: static TOOL_ACTION newProject; static TOOL_ACTION newFromTemplate; static TOOL_ACTION openProject; + static TOOL_ACTION closeProject; static TOOL_ACTION editSchematic; static TOOL_ACTION editSymbols; diff --git a/kicad/tools/kicad_manager_control.cpp b/kicad/tools/kicad_manager_control.cpp index 6668323399..becd95253b 100644 --- a/kicad/tools/kicad_manager_control.cpp +++ b/kicad/tools/kicad_manager_control.cpp @@ -313,6 +313,12 @@ int KICAD_MANAGER_CONTROL::OpenProject( const TOOL_EVENT& aEvent ) return 0; } +int KICAD_MANAGER_CONTROL::CloseProject( const TOOL_EVENT& aEvent ) +{ + m_frame->CloseProject( true ); + return 0; +} + class SAVE_AS_TRAVERSER : public wxDirTraverser { @@ -706,7 +712,7 @@ int KICAD_MANAGER_CONTROL::Execute( const TOOL_EVENT& aEvent ) if( aEvent.Parameter() ) params = *aEvent.Parameter(); - else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::viewGerbers ) ) + else if( ( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::viewGerbers ) ) && m_frame->IsProjectActive() ) params = m_frame->Prj().GetProjectPath(); if( !params.empty() ) @@ -743,6 +749,7 @@ void KICAD_MANAGER_CONTROL::setTransitions() Go( &KICAD_MANAGER_CONTROL::NewProject, KICAD_MANAGER_ACTIONS::newProject.MakeEvent() ); Go( &KICAD_MANAGER_CONTROL::NewFromTemplate, KICAD_MANAGER_ACTIONS::newFromTemplate.MakeEvent() ); Go( &KICAD_MANAGER_CONTROL::OpenProject, KICAD_MANAGER_ACTIONS::openProject.MakeEvent() ); + Go( &KICAD_MANAGER_CONTROL::CloseProject, KICAD_MANAGER_ACTIONS::closeProject.MakeEvent() ); Go( &KICAD_MANAGER_CONTROL::SaveProjectAs, ACTIONS::saveAs.MakeEvent() ); Go( &KICAD_MANAGER_CONTROL::Refresh, ACTIONS::zoomRedraw.MakeEvent() ); diff --git a/kicad/tools/kicad_manager_control.h b/kicad/tools/kicad_manager_control.h index 0e0789f4a8..a2209b6047 100644 --- a/kicad/tools/kicad_manager_control.h +++ b/kicad/tools/kicad_manager_control.h @@ -50,6 +50,7 @@ public: int NewProject( const TOOL_EVENT& aEvent ); int NewFromTemplate( const TOOL_EVENT& aEvent ); int OpenProject( const TOOL_EVENT& aEvent ); + int CloseProject( const TOOL_EVENT& aEvent ); int SaveProjectAs( const TOOL_EVENT& aEvent ); int Refresh( const TOOL_EVENT& aEvent ); diff --git a/kicad/tree_project_frame.cpp b/kicad/tree_project_frame.cpp index 440921852c..e25f5a996f 100644 --- a/kicad/tree_project_frame.cpp +++ b/kicad/tree_project_frame.cpp @@ -1240,6 +1240,12 @@ void TREE_PROJECT_FRAME::FileWatcherReset() } +void TREE_PROJECT_FRAME::EmptyTreePrj() +{ + m_TreeProject->DeleteAllItems(); +} + + void KICAD_MANAGER_FRAME::OnChangeWatchedPaths( wxCommandEvent& aEvent ) { m_leftWin->FileWatcherReset(); diff --git a/kicad/tree_project_frame.h b/kicad/tree_project_frame.h index 7a81c3f686..a51d1f381c 100644 --- a/kicad/tree_project_frame.h +++ b/kicad/tree_project_frame.h @@ -74,6 +74,11 @@ public: */ void FileWatcherReset(); + /** + * Delete all @ref m_TreeProject entries + */ + void EmptyTreePrj(); + protected: static wxString GetFileExt( TreeFileType type );