diff --git a/src/ExportManager.h b/src/ExportManager.h --- a/src/ExportManager.h +++ b/src/ExportManager.h @@ -20,6 +20,7 @@ #ifndef EXPORTMANAGER_H #define EXPORTMANAGER_H +#include #include #include #include @@ -81,8 +82,9 @@ QString makeAutosaveFilename(); using FileNameAlreadyUsedCheck = bool (ExportManager::*)(const QUrl&) const; - QString autoIncrementFilename(const QString &baseName, const QString &extension, - FileNameAlreadyUsedCheck isFileNameUsed); + QUrl autoIncrementFilename(const QDir &baseDir, const QString &fileName, + const QString &extension, + FileNameAlreadyUsedCheck isFileNameUsed); QString makeSaveMimetype(const QUrl &url); bool writeImage(QIODevice *device, const QByteArray &format); bool save(const QUrl &url); diff --git a/src/ExportManager.cpp b/src/ExportManager.cpp --- a/src/ExportManager.cpp +++ b/src/ExportManager.cpp @@ -19,7 +19,6 @@ #include "ExportManager.h" -#include #include #include #include @@ -130,12 +129,9 @@ { const QString baseDir = saveLocation(); const QDir baseDirPath(baseDir); - const QString filename = makeAutosaveFilename(); - const QString fullpath = autoIncrementFilename(baseDirPath.filePath(filename), + const QUrl fileNameUrl = autoIncrementFilename(baseDirPath, makeAutosaveFilename(), SpectacleConfig::instance()->saveImageFormat(), &ExportManager::isFileExists); - - const QUrl fileNameUrl = QUrl::fromUserInput(fullpath); if (fileNameUrl.isValid()) { return fileNameUrl; } else { @@ -160,24 +156,32 @@ .replace(QLatin1String("%S"), timestamp.toString(QStringLiteral("ss"))); } -QString ExportManager::autoIncrementFilename(const QString &baseName, const QString &extension, - FileNameAlreadyUsedCheck isFileNameUsed) +QUrl ExportManager::autoIncrementFilename(const QDir &baseDir, const QString &fileName, + const QString &extension, + FileNameAlreadyUsedCheck isFileNameUsed) { - if (!((this->*isFileNameUsed)(QUrl::fromUserInput(baseName + QLatin1Char('.') + extension)))) { - return baseName + QLatin1Char('.') + extension; + QString resultFileName = fileName.isEmpty() ? QStringLiteral("1") : fileName; + QString resultFilePath = baseDir.filePath(resultFileName) + QLatin1Char('.') + extension; + + QUrl filePath = QUrl::fromUserInput(resultFilePath); + if (!((this->*isFileNameUsed)(filePath))) { + return filePath; } - QString fileNameFmt(baseName + QStringLiteral("-%1.") + extension); + QString fileNameFmt = fileName.isEmpty() ? QStringLiteral("%1") : fileName + QStringLiteral("-%1"); + QString filePathFmt = baseDir.filePath(fileNameFmt) + QLatin1Char('.') + extension; + for (quint64 i = 1; i < std::numeric_limits::max(); i++) { - if (!((this->*isFileNameUsed)(QUrl::fromUserInput(fileNameFmt.arg(i))))) { - return fileNameFmt.arg(i); + QUrl incrementedNumberFilePath = QUrl::fromUserInput(filePathFmt.arg(i)); + if (!((this->*isFileNameUsed)(incrementedNumberFilePath))) { + return incrementedNumberFilePath; } } // unlikely this will ever happen, but just in case we've run // out of numbers - - return fileNameFmt.arg(QStringLiteral("OVERFLOW-") + QString::number(qrand() % 10000)); + QString overflowNumberFilePath = filePathFmt.arg(QStringLiteral("OVERFLOW-") + QString::number(qrand() % 10000)); + return QUrl::fromUserInput(overflowNumberFilePath); } QString ExportManager::makeSaveMimetype(const QUrl &url) @@ -254,10 +258,9 @@ // supports the use-case of creating multiple screenshots in a row // and exporting them to the same destination e.g. via clipboard, // where the temp file name is used as filename suggestion - const QString baseFileName = mTempDir->path() + QDir::separator() + makeAutosaveFilename(); - const QString fileName = autoIncrementFilename(baseFileName, mimetype, - &ExportManager::isTempFileAlreadyUsed); - QFile tmpFile(fileName); + const QUrl filePath = autoIncrementFilename(mTempDir->path(), makeAutosaveFilename(), mimetype, + &ExportManager::isTempFileAlreadyUsed); + QFile tmpFile(filePath.toLocalFile()); if (tmpFile.open(QFile::WriteOnly)) { if(writeImage(&tmpFile, mimetype.toLatin1())) { mTempFile = QUrl::fromLocalFile(tmpFile.fileName()); @@ -341,8 +344,13 @@ QFileDialog dialog(parentWindow); dialog.setAcceptMode(QFileDialog::AcceptSave); dialog.setFileMode(QFileDialog::AnyFile); - dialog.setDirectoryUrl(config->lastSaveAsLocation()); - dialog.selectFile(makeAutosaveFilename() + QStringLiteral(".png")); + const QUrl saveAsLocation = config->lastSaveAsLocation(); + dialog.setDirectoryUrl(saveAsLocation); + const QDir baseDirPath(saveAsLocation.toString()); + const QUrl fullPath = autoIncrementFilename(baseDirPath, makeAutosaveFilename(), + QStringLiteral("png"), + &ExportManager::isFileExists); + dialog.selectFile(fullPath.fileName()); dialog.setDefaultSuffix(QStringLiteral(".png")); dialog.setMimeTypeFilters(supportedFilters); dialog.selectMimeTypeFilter(QStringLiteral("image/png"));