diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index b1b2a0eaf5..887e7f3075 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -74,6 +74,7 @@ namespace PCB { struct IFACE; } // KIFACE_I is in pcbnew.cpp */ #define PCB_EDIT_FRAME_NAME wxT( "PcbFrame" ) + class PCB_EDIT_FRAME : public PCB_BASE_EDIT_FRAME { friend struct PCB::IFACE; @@ -224,6 +225,13 @@ public: void OnQuit( wxCommandEvent& event ); + /** + * Function GetAutoSaveFilePrefix + * + * @return the string to prepend to a file name for automatic save. + */ + static wxString GetAutoSaveFilePrefix(); + /** * Execute a remote command send by Eeschema via a socket, * port KICAD_PCB_PORT_SERVICE_NUMBER (currently 4242) diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index 5ee6471877..a560a2f3f9 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2011-2015 Wayne Stambaugh + * Copyright (C) 2011-2016 Wayne Stambaugh * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -64,6 +64,12 @@ static const wxChar backupSuffix[] = wxT( "-bak" ); static const wxChar autosavePrefix[] = wxT( "_autosave-" ); +wxString PCB_EDIT_FRAME::GetAutoSaveFilePrefix() +{ + return wxString( autosavePrefix ); +} + + /** * Function AskLoadBoardFileName * puts up a wxFileDialog asking for a BOARD filename to open. @@ -809,7 +815,7 @@ bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName ) } DisplayInfoMessage( this, wxString::Format( _( "Board copied to:\n'%s'" ), - GetChars( pcbFileName.GetFullPath() ) ) ); + GetChars( pcbFileName.GetFullPath() ) ) ); return true; } @@ -817,19 +823,40 @@ bool PCB_EDIT_FRAME::SavePcbCopy( const wxString& aFileName ) bool PCB_EDIT_FRAME::doAutoSave() { - wxFileName tmpFileName = Prj().AbsolutePath( GetBoard()->GetFileName() ); - wxFileName fn = tmpFileName; + wxFileName tmpFileName; - // Auto save file name is the normal file name prepended with - // autosaveFilePrefix string. - fn.SetName( wxString( autosavePrefix ) + fn.GetName() ); + if( GetBoard()->GetFileName().IsEmpty() ) + { + tmpFileName = wxFileName( wxStandardPaths::Get().GetDocumentsDir(), wxT( "noname" ), + KiCadPcbFileExtension ); + GetBoard()->SetFileName( tmpFileName.GetFullPath() ); + } + else + { + tmpFileName = Prj().AbsolutePath( GetBoard()->GetFileName() ); + } - wxLogTrace( traceAutoSave, - wxT( "Creating auto save file <" + fn.GetFullPath() ) + wxT( ">" ) ); + wxFileName autoSaveFileName = tmpFileName; - if( !fn.IsOk() ) + // Auto save file name is the board file name prepended with autosaveFilePrefix string. + autoSaveFileName.SetName( wxString( autosavePrefix ) + autoSaveFileName.GetName() ); + + if( !autoSaveFileName.IsOk() ) return false; - else if( SavePcbFile( fn.GetFullPath(), NO_BACKUP_FILE ) ) + + // If the board file path is not writable, try writing to a platform specific temp file + // path. If that path isn't writabe, give up. + if( !autoSaveFileName.IsDirWritable() ) + { + autoSaveFileName.SetPath( wxFileName::GetTempDir() ); + + if( !autoSaveFileName.IsOk() || !autoSaveFileName.IsDirWritable() ) + return false; + } + + wxLogTrace( traceAutoSave, "Creating auto save file <" + autoSaveFileName.GetFullPath() + ">" ); + + if( SavePcbFile( autoSaveFileName.GetFullPath(), NO_BACKUP_FILE ) ) { GetScreen()->SetModify(); GetBoard()->SetFileName( tmpFileName.GetFullPath() ); diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 967737732b..89405495c6 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -605,8 +605,15 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) // Delete the auto save file if it exists. wxFileName fn = GetBoard()->GetFileName(); - // Auto save file name is the normal file name prefixed with a '$'. - fn.SetName( wxT( "$" ) + fn.GetName() ); + // Auto save file name is the normal file name prefixed with '_autosave'. + fn.SetName( GetAutoSaveFilePrefix() + fn.GetName() ); + + // When the auto save feature does not have write access to the board file path, it falls + // back to a platform specific user temporary file path. + if( !fn.IsOk() || !fn.IsDirWritable() ) + fn.SetPath( wxFileName::GetTempDir() ); + + wxLogTrace( traceAutoSave, "Deleting auto save file <" + fn.GetFullPath() + ">" ); // Remove the auto save file on a normal close of Pcbnew. if( fn.FileExists() && !wxRemoveFile( fn.GetFullPath() ) )