1717
1818#include " qgsproject.h"
1919
20- #include < deque>
21- #include < memory>
22-
2320#include " qgsdatasourceuri.h"
2421#include " qgsexception.h"
2522#include " qgslayertree.h"
4441#include < QDomNode>
4542#include < QObject>
4643#include < QTextStream>
44+ #include < QTemporaryFile>
4745#include < QDir>
4846#include < QUrl>
4947
48+ #ifdef Q_OS_UNIX
49+ #include < utime.h>
50+ #elif _MSC_VER
51+ #include < sys/utime.h>
52+ #endif
53+
5054// canonical project instance
5155QgsProject *QgsProject::theProject_ = nullptr ;
5256
@@ -1004,7 +1008,16 @@ bool QgsProject::write()
10041008 QString backup = fileName () + ' ~' ;
10051009 if ( QFile::exists ( backup ) )
10061010 QFile::remove ( backup );
1007- QFile::rename ( fileName (), backup );
1011+
1012+ if ( !QFile::copy ( fileName (), backup ) )
1013+ {
1014+ setError ( tr ( " Unable to create backup file %1" ).arg ( backup ) );
1015+ return false ;
1016+ }
1017+
1018+ QFileInfo fi ( fileName () );
1019+ struct utimbuf tb = { fi.lastRead ().toTime_t (), fi.lastModified ().toTime_t () };
1020+ utime ( backup.toUtf8 ().constData (), &tb );
10081021 }
10091022
10101023 // if we have problems creating or otherwise writing to the project file,
@@ -1018,6 +1031,7 @@ bool QgsProject::write()
10181031 setError ( tr ( " Unable to save to file %1" ).arg ( imp_->file .fileName () ) );
10191032 return false ;
10201033 }
1034+
10211035 QFileInfo myFileInfo ( imp_->file );
10221036 if ( !myFileInfo.isWritable () )
10231037 {
@@ -1029,8 +1043,6 @@ bool QgsProject::write()
10291043 return false ;
10301044 }
10311045
1032-
1033-
10341046 QDomImplementation DomImplementation;
10351047 DomImplementation.setInvalidDataPolicy ( QDomImplementation::DropInvalidChars );
10361048
@@ -1126,15 +1138,31 @@ bool QgsProject::write()
11261138 // now wrap it up and ship it to the project file
11271139 doc->normalize (); // XXX I'm not entirely sure what this does
11281140
1129- QTextStream projectFileStream ( &imp_->file );
1141+ QTemporaryFile tempFile;
1142+ bool ok = tempFile.open ();
1143+ if ( ok )
1144+ {
1145+ QTextStream projectFileStream ( &tempFile );
1146+ doc->save ( projectFileStream, 2 ); // save as utf-8
1147+ ok &= projectFileStream.pos () > -1 ;
11301148
1131- doc->save ( projectFileStream, 2 ); // save as utf-8
1132- imp_->file .close ();
1149+ ok &= tempFile.seek ( 0 );
1150+
1151+ QByteArray ba;
1152+ while ( ok && !tempFile.atEnd () )
1153+ {
1154+ ba = tempFile.read ( 10240 );
1155+ ok &= imp_->file .write ( ba ) == ba.size ();
1156+ }
1157+
1158+ ok &= imp_->file .error () == QFile::NoError;
1159+
1160+ imp_->file .close ();
1161+ }
1162+
1163+ tempFile.close ();
11331164
1134- // check if the text stream had no error - if it does
1135- // the user will get a message so they can try to resolve the
1136- // situation e.g. by saving project to a volume with more space
1137- if ( projectFileStream.pos () == -1 || imp_->file .error () != QFile::NoError )
1165+ if ( !ok )
11381166 {
11391167 setError ( tr ( " Unable to save to file %1. Your project "
11401168 " may be corrupted on disk. Try clearing some space on the volume and "
0 commit comments