Utils: Make FileSaver somewhat work for remote files

Write to a local file first, transfer content when finalizing.

Change-Id: I4740838e049f5a556e286b2a8944634ff7d2b0c7
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2021-07-23 16:30:40 +02:00
parent dea2d9886f
commit f1b45ca775

View File

@@ -197,7 +197,7 @@ FileSaver::FileSaver(const FilePath &filePath, QIODevice::OpenMode mode)
{ {
m_filePath = filePath; m_filePath = filePath;
// Workaround an assert in Qt -- and provide a useful error message, too: // Workaround an assert in Qt -- and provide a useful error message, too:
if (HostOsInfo::isWindowsHost()) { if (m_filePath.osType() == OsType::OsTypeWindows) {
// Taken from: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx // Taken from: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
static const QStringList reservedNames static const QStringList reservedNames
= {"CON", "PRN", "AUX", "NUL", = {"CON", "PRN", "AUX", "NUL",
@@ -206,16 +206,23 @@ FileSaver::FileSaver(const FilePath &filePath, QIODevice::OpenMode mode)
const QString fn = filePath.baseName().toUpper(); const QString fn = filePath.baseName().toUpper();
if (reservedNames.contains(fn)) { if (reservedNames.contains(fn)) {
m_errorString = tr("%1: Is a reserved filename on Windows. Cannot save.") m_errorString = tr("%1: Is a reserved filename on Windows. Cannot save.")
.arg(filePath.toString()); .arg(filePath.toUserOutput());
m_hasError = true; m_hasError = true;
return; return;
} }
} }
if (mode & (QIODevice::ReadOnly | QIODevice::Append)) { if (filePath.needsDevice()) {
m_file.reset(new QFile{filePath.toString()}); // Write to a local temporary file first. Actual saving to the selected location
// is done via m_filePath.writeFileContents() in finalize()
m_isSafe = false;
auto tf = new QTemporaryFile(QDir::tempPath() + "/remotefilesaver-XXXXXX");
tf->setAutoRemove(false);
m_file.reset(tf);
} else if (mode & (QIODevice::ReadOnly | QIODevice::Append)) {
m_file.reset(new QFile{filePath.path()});
m_isSafe = false; m_isSafe = false;
} else { } else {
m_file.reset(new SaveFile{filePath.toString()}); m_file.reset(new SaveFile{filePath.path()});
m_isSafe = true; m_isSafe = true;
} }
if (!m_file->open(QIODevice::WriteOnly | mode)) { if (!m_file->open(QIODevice::WriteOnly | mode)) {
@@ -228,6 +235,16 @@ FileSaver::FileSaver(const FilePath &filePath, QIODevice::OpenMode mode)
bool FileSaver::finalize() bool FileSaver::finalize()
{ {
if (m_filePath.needsDevice()) {
m_file->close();
m_file->open(QIODevice::ReadOnly);
const QByteArray data = m_file->readAll();
const bool res = m_filePath.writeFileContents(data);
m_file->remove();
m_file.reset();
return res;
}
if (!m_isSafe) if (!m_isSafe)
return FileSaverBase::finalize(); return FileSaverBase::finalize();