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
This commit is contained in:
Fabien Corona 2020-08-08 18:52:14 +00:00 committed by Seth Hillbrand
parent ae404e6339
commit bc357dff8a
12 changed files with 145 additions and 18 deletions

View File

@ -128,6 +128,8 @@ public:
{ {
bool first_run_shown; bool first_run_shown;
int max_undo_items; int max_undo_items;
std::vector<wxString> open_projects; // using a vector if in the future
// we want to open multiple projects at once.
std::vector<wxString> file_history; std::vector<wxString> file_history;
int units; int units;
}; };

View File

@ -139,9 +139,9 @@ bool PGM_KICAD::OnPgmInit()
{ {
projToLoad = App().argv[1]; 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 ) ) if( !wxFileExists( last_pro ) )
{ {

View File

@ -220,9 +220,53 @@ void KICAD_MANAGER_FRAME::SetProjectFileName( const wxString& aFullProjectProFil
} }
std::vector<wxString> KICAD_MANAGER_FRAME::GetOpenProjects()
{
KICAD_SETTINGS* conf = dynamic_cast<KICAD_SETTINGS*>( config() );
if( conf == NULL )
{
// Build an empty vector to return
std::vector<wxString> dummy;
return dummy;
}
return conf->m_System.open_projects;
}
wxString KICAD_MANAGER_FRAME::PopOpenProjects()
{
KICAD_SETTINGS* conf = dynamic_cast<KICAD_SETTINGS*>( config() );
if( conf == NULL )
{
return wxString( "" );
}
std::vector<wxString>* 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 const wxString KICAD_MANAGER_FRAME::GetProjectFileName() const
{ {
if( m_active_project )
return Prj().GetProjectFullName(); 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<wxString>::iterator ptr;
std::vector<wxString>* 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 ) 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. // 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. // 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.) // (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: // User is prompted here to close those KIWAY_PLAYERs:
if( !Kiway().PlayersClose( false ) ) CloseProject( true );
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() );
}
m_active_project = true; m_active_project = true;
ClearMsg();
Pgm().GetSettingsManager().LoadProject( aProjectFileName.GetFullPath() ); Pgm().GetSettingsManager().LoadProject( aProjectFileName.GetFullPath() );
SetProjectFileName( Prj().GetProjectFullName() ); SetProjectFileName( Prj().GetProjectFullName() );
std::vector<wxString>::iterator ptr;
ptr = config()->m_System.open_projects.begin();
config()->m_System.open_projects.insert( ptr, Prj().GetProjectFullName() );
if( aProjectFileName.IsDirWritable() ) if( aProjectFileName.IsDirWritable() )
SetMruPath( Prj().GetProjectPath() ); // Only set MRU path if we have write access. Why? SetMruPath( Prj().GetProjectPath() ); // Only set MRU path if we have write access. Why?
@ -571,4 +652,7 @@ void KICAD_MANAGER_FRAME::PrintPrjInfo()
PrintMsg( msg ); PrintMsg( msg );
} }
bool KICAD_MANAGER_FRAME::IsProjectActive()
{
return m_active_project;
}

View File

@ -100,6 +100,12 @@ public:
void RecreateBaseHToolbar(); void RecreateBaseHToolbar();
void RecreateLauncher(); void RecreateLauncher();
std::vector<wxString> GetOpenProjects();
/**
* Get element at index 0, and remove it.
*/
wxString PopOpenProjects();
wxString GetCurrentFileName() const override wxString GetCurrentFileName() const override
{ {
return GetProjectFileName(); return GetProjectFileName();
@ -140,6 +146,11 @@ public:
* @param aProjectFileName is the absolute path of the project file name. * @param aProjectFileName is the absolute path of the project file name.
*/ */
void CreateNewProject( const wxFileName& aProjectFileName ); void CreateNewProject( const wxFileName& aProjectFileName );
/**
* Closes the project, and saves it if aSave is true;
*/
bool CloseProject( bool aSave );
void LoadProject( const wxFileName& aProjectFileName ); void LoadProject( const wxFileName& aProjectFileName );
@ -163,6 +174,7 @@ public:
void SetProjectFileName( const wxString& aFullProjectProFileName ); void SetProjectFileName( const wxString& aFullProjectProFileName );
const wxString GetProjectFileName() const; const wxString GetProjectFileName() const;
bool IsProjectActive();
// read only accessors // read only accessors
const wxString SchFileName(); const wxString SchFileName();
const wxString SchLegacyFileName(); const wxString SchLegacyFileName();

View File

@ -29,6 +29,8 @@ const int kicadSchemaVersion = 0;
KICAD_SETTINGS::KICAD_SETTINGS() : APP_SETTINGS_BASE( "kicad", kicadSchemaVersion ) KICAD_SETTINGS::KICAD_SETTINGS() : APP_SETTINGS_BASE( "kicad", kicadSchemaVersion )
{ {
m_params.emplace_back( new PARAM<int>( "appearance.left_frame_width", &m_LeftWinWidth, 200 ) ); m_params.emplace_back( new PARAM<int>( "appearance.left_frame_width", &m_LeftWinWidth, 200 ) );
m_params.emplace_back(
new PARAM_LIST<wxString>( "system.open_projects", &m_System.open_projects, {} ) );
} }

View File

@ -70,6 +70,7 @@ void KICAD_MANAGER_FRAME::ReCreateMenuBar()
fileMenu->AddItem( KICAD_MANAGER_ACTIONS::newProject, SELECTION_CONDITIONS::ShowAlways ); fileMenu->AddItem( KICAD_MANAGER_ACTIONS::newProject, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddItem( KICAD_MANAGER_ACTIONS::newFromTemplate, 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::openProject, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddItem( KICAD_MANAGER_ACTIONS::closeProject, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentMenu, fileMenu->AddMenu( openRecentMenu,
FILE_HISTORY::FileHistoryNotEmpty( fileHistory ) ); FILE_HISTORY::FileHistoryNotEmpty( fileHistory ) );

View File

@ -53,6 +53,12 @@ TOOL_ACTION KICAD_MANAGER_ACTIONS::openProject( "kicad.Control.openProject",
_( "Open Project..." ), _( "Open an existing project" ), _( "Open Project..." ), _( "Open an existing project" ),
directory_xpm ); 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", TOOL_ACTION KICAD_MANAGER_ACTIONS::editSchematic( "kicad.Control.editSchematic",
AS_GLOBAL, AS_GLOBAL,
MD_CTRL + 'E', LEGACY_HK_NAME( "Run Eeschema" ), MD_CTRL + 'E', LEGACY_HK_NAME( "Run Eeschema" ),

View File

@ -41,6 +41,7 @@ public:
static TOOL_ACTION newProject; static TOOL_ACTION newProject;
static TOOL_ACTION newFromTemplate; static TOOL_ACTION newFromTemplate;
static TOOL_ACTION openProject; static TOOL_ACTION openProject;
static TOOL_ACTION closeProject;
static TOOL_ACTION editSchematic; static TOOL_ACTION editSchematic;
static TOOL_ACTION editSymbols; static TOOL_ACTION editSymbols;

View File

@ -313,6 +313,12 @@ int KICAD_MANAGER_CONTROL::OpenProject( const TOOL_EVENT& aEvent )
return 0; return 0;
} }
int KICAD_MANAGER_CONTROL::CloseProject( const TOOL_EVENT& aEvent )
{
m_frame->CloseProject( true );
return 0;
}
class SAVE_AS_TRAVERSER : public wxDirTraverser class SAVE_AS_TRAVERSER : public wxDirTraverser
{ {
@ -706,7 +712,7 @@ int KICAD_MANAGER_CONTROL::Execute( const TOOL_EVENT& aEvent )
if( aEvent.Parameter<wxString*>() ) if( aEvent.Parameter<wxString*>() )
params = *aEvent.Parameter<wxString*>(); params = *aEvent.Parameter<wxString*>();
else if( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::viewGerbers ) ) else if( ( aEvent.IsAction( &KICAD_MANAGER_ACTIONS::viewGerbers ) ) && m_frame->IsProjectActive() )
params = m_frame->Prj().GetProjectPath(); params = m_frame->Prj().GetProjectPath();
if( !params.empty() ) 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::NewProject, KICAD_MANAGER_ACTIONS::newProject.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::NewFromTemplate, KICAD_MANAGER_ACTIONS::newFromTemplate.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::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::SaveProjectAs, ACTIONS::saveAs.MakeEvent() );
Go( &KICAD_MANAGER_CONTROL::Refresh, ACTIONS::zoomRedraw.MakeEvent() ); Go( &KICAD_MANAGER_CONTROL::Refresh, ACTIONS::zoomRedraw.MakeEvent() );

View File

@ -50,6 +50,7 @@ public:
int NewProject( const TOOL_EVENT& aEvent ); int NewProject( const TOOL_EVENT& aEvent );
int NewFromTemplate( const TOOL_EVENT& aEvent ); int NewFromTemplate( const TOOL_EVENT& aEvent );
int OpenProject( const TOOL_EVENT& aEvent ); int OpenProject( const TOOL_EVENT& aEvent );
int CloseProject( const TOOL_EVENT& aEvent );
int SaveProjectAs( const TOOL_EVENT& aEvent ); int SaveProjectAs( const TOOL_EVENT& aEvent );
int Refresh( const TOOL_EVENT& aEvent ); int Refresh( const TOOL_EVENT& aEvent );

View File

@ -1240,6 +1240,12 @@ void TREE_PROJECT_FRAME::FileWatcherReset()
} }
void TREE_PROJECT_FRAME::EmptyTreePrj()
{
m_TreeProject->DeleteAllItems();
}
void KICAD_MANAGER_FRAME::OnChangeWatchedPaths( wxCommandEvent& aEvent ) void KICAD_MANAGER_FRAME::OnChangeWatchedPaths( wxCommandEvent& aEvent )
{ {
m_leftWin->FileWatcherReset(); m_leftWin->FileWatcherReset();

View File

@ -74,6 +74,11 @@ public:
*/ */
void FileWatcherReset(); void FileWatcherReset();
/**
* Delete all @ref m_TreeProject entries
*/
void EmptyTreePrj();
protected: protected:
static wxString GetFileExt( TreeFileType type ); static wxString GetFileExt( TreeFileType type );