Use a temporary file when saving boards/schematics to make the operation more atomic
Fixes https://gitlab.com/kicad/code/kicad/-/issues/4517
This commit is contained in:
parent
dd42a19319
commit
09cb75b8a1
|
@ -110,7 +110,7 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SHEET* aSheet, bool aSaveUnderNewName,
|
|||
if( backupFileName.FileExists() )
|
||||
wxRemoveFile( backupFileName.GetFullPath() );
|
||||
|
||||
if( !wxRenameFile( schematicFileName.GetFullPath(), backupFileName.GetFullPath() ) )
|
||||
if( !wxCopyFile( schematicFileName.GetFullPath(), backupFileName.GetFullPath() ) )
|
||||
{
|
||||
msg.Printf( _( "Could not save backup of file \"%s\"" ),
|
||||
schematicFileName.GetFullPath() );
|
||||
|
@ -118,6 +118,10 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SHEET* aSheet, bool aSaveUnderNewName,
|
|||
}
|
||||
}
|
||||
|
||||
wxFileName tempFile( schematicFileName );
|
||||
tempFile.SetName( wxT( "." ) + tempFile.GetName() );
|
||||
tempFile.SetExt( tempFile.GetExt() + wxT( "$" ) );
|
||||
|
||||
// Save
|
||||
wxLogTrace( traceAutoSave,
|
||||
wxT( "Saving file <" ) + schematicFileName.GetFullPath() + wxT( ">" ) );
|
||||
|
@ -128,7 +132,7 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SHEET* aSheet, bool aSaveUnderNewName,
|
|||
|
||||
try
|
||||
{
|
||||
pi->Save( schematicFileName.GetFullPath(), aSheet, &Schematic() );
|
||||
pi->Save( tempFile.GetFullPath(), aSheet, &Schematic() );
|
||||
success = true;
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
|
@ -137,12 +141,32 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SHEET* aSheet, bool aSaveUnderNewName,
|
|||
schematicFileName.GetFullPath(), ioe.What() );
|
||||
DisplayError( this, msg );
|
||||
|
||||
msg.Printf( _( "Failed to save \"%s\"" ), schematicFileName.GetFullPath() );
|
||||
msg.Printf( _( "Failed to create temporary file \"%s\"" ), tempFile.GetFullPath() );
|
||||
AppendMsgPanel( wxEmptyString, msg, CYAN );
|
||||
|
||||
// In case we started a file but didn't fully write it, clean up
|
||||
wxRemoveFile( tempFile.GetFullPath() );
|
||||
|
||||
success = false;
|
||||
}
|
||||
|
||||
if( success )
|
||||
{
|
||||
// Replace the original with the temporary file we just wrote
|
||||
success = wxRenameFile( tempFile.GetFullPath(), schematicFileName.GetFullPath() );
|
||||
|
||||
if( !success )
|
||||
{
|
||||
msg.Printf( _( "Error saving schematic file \"%s\".\n"
|
||||
"Failed to rename temporary file %s" ),
|
||||
schematicFileName.GetFullPath(), tempFile.GetFullPath() );
|
||||
DisplayError( this, msg );
|
||||
|
||||
msg.Printf( _( "Failed to rename temporary file \"%s\"" ), tempFile.GetFullPath() );
|
||||
AppendMsgPanel( wxEmptyString, msg, CYAN );
|
||||
}
|
||||
}
|
||||
|
||||
if( success )
|
||||
{
|
||||
// Delete auto save file.
|
||||
|
|
|
@ -263,9 +263,27 @@ bool PL_EDITOR_FRAME::InsertPageLayoutDescrFile( const wxString& aFullFileName )
|
|||
|
||||
bool PL_EDITOR_FRAME::SavePageLayoutDescrFile( const wxString& aFullFileName )
|
||||
{
|
||||
if( ! aFullFileName.IsEmpty() )
|
||||
if( !aFullFileName.IsEmpty() )
|
||||
{
|
||||
WS_DATA_MODEL::GetTheInstance().Save( aFullFileName );
|
||||
wxFileName tempFile( aFullFileName );
|
||||
tempFile.SetName( wxT( "." ) + tempFile.GetName() );
|
||||
tempFile.SetExt( tempFile.GetExt() + wxT( "$" ) );
|
||||
|
||||
try
|
||||
{
|
||||
WS_DATA_MODEL::GetTheInstance().Save( tempFile.GetFullPath() );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
// In case we started a file but didn't fully write it, clean up
|
||||
wxRemoveFile( tempFile.GetFullPath() );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !wxRenameFile( tempFile.GetFullPath(), aFullFileName ) )
|
||||
return false;
|
||||
|
||||
GetScreen()->ClrModify();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -685,8 +685,8 @@ wxString PCB_EDIT_FRAME::createBackupFile( const wxString& aFileName )
|
|||
if( backupFileName.FileExists() )
|
||||
wxRemoveFile( backupFileName.GetFullPath() );
|
||||
|
||||
// Rename the current file from <xxx>.kicad_pcb to <xxx>.kicad_pcb-bak
|
||||
if( !wxRenameFile( fn.GetFullPath(), backupFileName.GetFullPath() ) )
|
||||
// Copy the current file from <xxx>.kicad_pcb to <xxx>.kicad_pcb-bak
|
||||
if( !wxCopyFile( fn.GetFullPath(), backupFileName.GetFullPath() ) )
|
||||
{
|
||||
wxString msg = wxString::Format( _(
|
||||
"Warning: unable to create backup file \"%s\"" ),
|
||||
|
@ -729,6 +729,10 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
|
|||
backupFileName = createBackupFile( aFileName );
|
||||
}
|
||||
|
||||
wxFileName tempFile( aFileName );
|
||||
tempFile.SetName( wxT( "." ) + tempFile.GetName() );
|
||||
tempFile.SetExt( tempFile.GetExt() + wxT( "$" ) );
|
||||
|
||||
GetBoard()->SynchronizeNetsAndNetClasses();
|
||||
|
||||
// Select default Netclass before writing file. Useful to save default values in headers.
|
||||
|
@ -747,9 +751,9 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
|
|||
{
|
||||
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::KICAD_SEXP ) );
|
||||
|
||||
wxASSERT( pcbFileName.IsAbsolute() );
|
||||
wxASSERT( tempFile.IsAbsolute() );
|
||||
|
||||
pi->Save( pcbFileName.GetFullPath(), GetBoard(), NULL );
|
||||
pi->Save( tempFile.GetFullPath(), GetBoard(), NULL );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
|
@ -759,7 +763,26 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
|
|||
);
|
||||
DisplayError( this, msg );
|
||||
|
||||
lowerTxt.Printf( _( "Failed to create \"%s\"" ), pcbFileName.GetFullPath() );
|
||||
lowerTxt.Printf( _( "Failed to create temporary file \"%s\"" ), tempFile.GetFullPath() );
|
||||
|
||||
AppendMsgPanel( upperTxt, lowerTxt, CYAN );
|
||||
|
||||
// In case we started a file but didn't fully write it, clean up
|
||||
wxRemoveFile( tempFile.GetFullPath() );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// If save succeeded, replace the original with what we just wrote
|
||||
if( !wxRenameFile( tempFile.GetFullPath(), pcbFileName.GetFullPath() ) )
|
||||
{
|
||||
wxString msg = wxString::Format( _(
|
||||
"Error saving board file \"%s\".\nFailed to rename temporary file \"%s\"" ),
|
||||
pcbFileName.GetFullPath(), tempFile.GetFullPath()
|
||||
);
|
||||
DisplayError( this, msg );
|
||||
|
||||
lowerTxt.Printf( _( "Failed to rename temporary file \"%s\"" ), tempFile.GetFullPath() );
|
||||
|
||||
AppendMsgPanel( upperTxt, lowerTxt, CYAN );
|
||||
|
||||
|
|
Loading…
Reference in New Issue