diff --git a/src/ExportManager.h b/src/ExportManager.h --- a/src/ExportManager.h +++ b/src/ExportManager.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "PlatformBackends/ImageGrabber.h" @@ -93,8 +94,10 @@ QString truncatedFilename(const QString &filename); 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 @@ -149,12 +148,11 @@ { const QString baseDir = saveLocation(); const QDir baseDirPath(baseDir); - const QString filename = makeAutosaveFilename(); - const QString fullpath = autoIncrementFilename(baseDirPath.filePath(filename), + const QString fileName = makeAutosaveFilename(); + const QUrl fileNameUrl = autoIncrementFilename(baseDirPath, + fileName, SpectacleConfig::instance()->saveImageFormat(), &ExportManager::isFileExists); - - const QUrl fileNameUrl = QUrl::fromUserInput(fullpath); if (fileNameUrl.isValid()) { return fileNameUrl; } else { @@ -215,27 +213,32 @@ return truncatedFilename(result); } -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) { - QString result = truncatedFilename(baseName) + QLatin1Literal(".") + extension; - if (!((this->*isFileNameUsed)(QUrl::fromUserInput(result)))) { - return result; + const QString resultFileName = fileName.isEmpty() ? QStringLiteral("1") : fileName; + const QString resultFilePath = baseDir.filePath(resultFileName) + QLatin1Char('.') + extension; + + const QUrl filePath = QUrl::fromUserInput(resultFilePath); + if (!((this->*isFileNameUsed)(filePath))) { + return filePath; } - QString fileNameFmt = truncatedFilename(baseName) + QStringLiteral("-%1."); + const QString fileNameFmt = fileName.isEmpty() ? QStringLiteral("%1") : fileName + QStringLiteral("-%1"); + const QString filePathFmt = baseDir.filePath(fileNameFmt) + QLatin1Char('.') + extension; + for (quint64 i = 1; i < std::numeric_limits::max(); i++) { - result = fileNameFmt.arg(i) + extension; - if (!((this->*isFileNameUsed)(QUrl::fromUserInput(result)))) { - return result; + const 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 - - result = fileNameFmt.arg(QStringLiteral("OVERFLOW-") + QString::number(qrand() % 10000)); - return truncatedFilename(result) + extension; + // unlikely this will ever happen, but just in case we've run out of numbers + const QString overflowNumberFilePath = filePathFmt.arg(QStringLiteral("OVERFLOW-") + QString::number(qrand() % 10000)); + return QUrl::fromUserInput(overflowNumberFilePath); } QString ExportManager::makeSaveMimetype(const QUrl &url) @@ -344,10 +347,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()); @@ -430,8 +432,14 @@ 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"));