Skip to content

Commit 4530c2a

Browse files
committed
improve project saving to network shares (fixes #13299)
1 parent 8949c44 commit 4530c2a

File tree

1 file changed

+41
-13
lines changed

1 file changed

+41
-13
lines changed

src/core/qgsproject.cpp

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@
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"
@@ -44,9 +41,16 @@
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
5155
QgsProject *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

Comments
 (0)