Allow creating new projects when doing a Save As in eeschema

This commit is contained in:
Jon Evans 2020-10-05 22:13:06 -04:00
parent d23d5510e7
commit 76bfa47a77
6 changed files with 80 additions and 17 deletions

View File

@ -704,7 +704,7 @@ bool SETTINGS_MANAGER::LoadProject( const wxString& aFullPath, bool aSetActive )
// No MDI yet
if( aSetActive && !m_projects.empty() )
{
PROJECT* oldProject = m_projects.begin()->second.get();
PROJECT* oldProject = m_projects.begin()->second;
unloadProjectFile( oldProject, true );
m_projects.erase( m_projects.begin() );
}
@ -716,12 +716,13 @@ bool SETTINGS_MANAGER::LoadProject( const wxString& aFullPath, bool aSetActive )
bool success = loadProjectFile( *project );
m_projects[fullPath].reset( project.release() );
m_projects_list.push_back( std::move( project ) );
m_projects[fullPath] = m_projects_list.back().get();
wxString fn( path.GetName() );
PROJECT_LOCAL_SETTINGS* settings = static_cast<PROJECT_LOCAL_SETTINGS*>(
RegisterSettings( new PROJECT_LOCAL_SETTINGS( m_projects[fullPath].get(), fn ) ) );
RegisterSettings( new PROJECT_LOCAL_SETTINGS( m_projects[fullPath], fn ) ) );
m_projects[fullPath]->setLocalSettings( settings );
@ -740,9 +741,20 @@ bool SETTINGS_MANAGER::UnloadProject( PROJECT* aProject, bool aSave )
if( !unloadProjectFile( aProject, aSave ) )
return false;
wxLogTrace( traceSettings, "Unload project %s", aProject->GetProjectFullName() );
wxString projectPath = aProject->GetProjectFullName();
wxLogTrace( traceSettings, "Unload project %s", projectPath );
m_projects.erase( aProject->GetProjectFullName() );
PROJECT* toRemove = m_projects.at( projectPath );
auto it = std::find_if( m_projects_list.begin(), m_projects_list.end(),
[&]( const std::unique_ptr<PROJECT>& ptr )
{
return ptr.get() == toRemove;
} );
wxASSERT( it != m_projects_list.end() );
m_projects_list.erase( it );
m_projects.erase( projectPath );
// Immediately reload a null project; this is required until the rest of the application
// is refactored to not assume that Prj() always works
@ -775,7 +787,7 @@ bool SETTINGS_MANAGER::IsProjectOpen() const
PROJECT* SETTINGS_MANAGER::GetProject( const wxString& aFullPath ) const
{
if( m_projects.count( aFullPath ) )
return m_projects.at( aFullPath ).get();
return m_projects.at( aFullPath );
return nullptr;
}
@ -785,7 +797,7 @@ std::vector<wxString> SETTINGS_MANAGER::GetOpenProjects() const
{
std::vector<wxString> ret;
for( const std::pair<const wxString, std::unique_ptr<PROJECT>>& pair : m_projects )
for( const std::pair<const wxString, PROJECT*>& pair : m_projects )
ret.emplace_back( pair.first );
return ret;
@ -816,6 +828,30 @@ bool SETTINGS_MANAGER::SaveProject( const wxString& aFullPath )
}
void SETTINGS_MANAGER::SaveProjectAs( const wxString& aFullPath )
{
wxString oldName = Prj().GetProjectFullName();
// Changing this will cause UnloadProject to not save over the "old" project when loading below
Prj().setProjectFullName( aFullPath );
wxFileName fn( aFullPath );
PROJECT_FILE* project = m_project_files.at( oldName );
project->SetFilename( fn.GetName() );
project->SaveToFile( fn.GetPath() );
Prj().GetLocalSettings().SetFilename( fn.GetName() );
Prj().GetLocalSettings().SaveToFile( fn.GetPath() );
m_project_files[fn.GetFullPath()] = project;
m_project_files.erase( oldName );
m_projects[fn.GetFullPath()] = m_projects[oldName];
m_projects.erase( oldName );
}
bool SETTINGS_MANAGER::loadProjectFile( PROJECT& aProject )
{
wxFileName fullFn( aProject.GetProjectFullName() );

View File

@ -198,6 +198,15 @@ void SCH_EDIT_FRAME::Save_File( bool doSaveAs )
if( fn.GetExt() == LegacySchematicFileExtension )
CreateArchiveLibraryCacheFile( true );
// If we are saving under a new name, and don't have a real project yet, create one
fn.SetExt( ProjectFileExtension );
if( fn.IsDirWritable() && !fn.FileExists() )
{
Prj().SetReadOnly( false );
GetSettingsManager()->SaveProjectAs( fn.GetFullPath() );
}
}
}
else
@ -291,8 +300,8 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
GetSettingsManager()->LoadProject( pro.GetFullPath() );
// Do not allow saving a project if one doesn't exist. This normally happens if we are
// standalone and opening a board that has been moved from its project folder.
if( !pro.Exists() )
// standalone and opening a schematic that has been moved from its project folder.
if( !pro.Exists() && !( aCtl & KICTL_CREATE ) )
Prj().SetReadOnly();
CreateScreens();
@ -342,6 +351,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
{
// mark new, unsaved file as modified.
GetScreen()->SetModify();
GetScreen()->SetFileName( fullFileName );
}
else
{

View File

@ -65,6 +65,8 @@ public:
wxString GetFullFilename() const;
void SetFilename( const wxString& aFilename ) { m_filename = aFilename; }
SETTINGS_LOC GetLocation() const { return m_location; }
void SetLegacyFilename( const wxString& aFilename ) { m_legacy_filename = aFilename; }

View File

@ -254,6 +254,12 @@ public:
*/
bool SaveProject( const wxString& aFullPath = wxEmptyString );
/**
* Sets the currently loaded project path and saves it (pointers remain valid)
* @param aFullPath is the full filename to set for the project
*/
void SaveProjectAs( const wxString& aFullPath );
/**
* @return the full path to where project backups should be stored
*/
@ -390,8 +396,11 @@ private:
/// True if settings loaded successfully at construction
bool m_ok;
/// Loaded projects (ownership here)
std::vector<std::unique_ptr<PROJECT>> m_projects_list;
/// Loaded projects, mapped according to project full name
std::map<wxString, std::unique_ptr<PROJECT>> m_projects;
std::map<wxString, PROJECT*> m_projects;
/// Loaded project files, mapped according to project full name
std::map<wxString, PROJECT_FILE*> m_project_files;

View File

@ -33,6 +33,7 @@
4,
5,
6,
7,
8,
9,
10,
@ -56,13 +57,10 @@
28,
29,
30,
31,
32,
33,
34,
35
36,
37
],
"visible_layers": "7ffff_ffffffff"
"visible_layers": "007ffff_ffffffff"
},
"meta": {
"filename": "complex_hierarchy.kicad_prl",

View File

@ -64,6 +64,8 @@
"clearance": "error",
"copper_edge_clearance": "error",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_too_small": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
@ -73,6 +75,7 @@
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"keepout": "error",
"length_out_of_range": "error",
"malformed_courtyard": "error",
"microvia_drill_too_small": "error",
"missing_courtyard": "ignore",
@ -82,6 +85,10 @@
"padstack": "error",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_over_copper": "error",
"silk_overlap": "error",
"skew_out_of_range": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
@ -192,7 +199,8 @@
"netlist": "",
"specctra_dsn": "",
"step": "",
"vmrl": ""
"vmrl": "",
"vrml": ""
},
"page_layout_descr_file": ""
},