diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp index 057c6531c9..ed114c0b3b 100644 --- a/eeschema/files-io.cpp +++ b/eeschema/files-io.cpp @@ -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. diff --git a/pagelayout_editor/files.cpp b/pagelayout_editor/files.cpp index f8b402559c..c9bdfee0b4 100644 --- a/pagelayout_editor/files.cpp +++ b/pagelayout_editor/files.cpp @@ -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; } diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index 5b543f0cdf..f33cc9b109 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -685,8 +685,8 @@ wxString PCB_EDIT_FRAME::createBackupFile( const wxString& aFileName ) if( backupFileName.FileExists() ) wxRemoveFile( backupFileName.GetFullPath() ); - // Rename the current file from .kicad_pcb to .kicad_pcb-bak - if( !wxRenameFile( fn.GetFullPath(), backupFileName.GetFullPath() ) ) + // Copy the current file from .kicad_pcb to .kicad_pcb-bak + if( !wxCopyFile( fn.GetFullPath(), backupFileName.GetFullPath() ) ) { wxString msg = wxString::Format( _( "Warning: unable to create backup file \"%s\"" ), @@ -707,7 +707,7 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF { // please, keep it simple. prompting goes elsewhere. - wxFileName pcbFileName = aFileName; + wxFileName pcbFileName = aFileName; if( pcbFileName.GetExt() == LegacyPcbFileExtension ) pcbFileName.SetExt( KiCadPcbFileExtension ); @@ -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 );