Improve screenshot path handling (#1815)
* Make --path work correctly with relative paths Relative paths are taken relative to the working directory of the calling command, not relative to the daemon's working directory. * Allow file paths in --path and refactor * Remove some redundancy These actions are already performed in the respective functions in FlameshotDBusAdapter. * Tweak --path error checker a bit more * Rework FileNameHandler and update references The class now has a much simpler interface. - Screenshot paths are now universally determined by the function properScreenshotPath - Some unreferenced methods have been removed - The documentation of properScreenshotPath documents the changes well. * Add crude tests for --path Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix failing build on Windows Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Add a test for invalid path Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Make tests clearer Thanks to @mmahmoudian for his review and contribution. Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fix bug in properScreenshotPath Auto-numeration did not work when the screenshot was automatically saved when copied to clipboard. Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Fall back to default pictures location Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Revert "Remove some redundancy" This was not redundancy. I had actually introduced a bug with this. This reverts commit 011ef737564892e494518443e6b80ccf3d286ae1. * Change default path only on interactive save Previously, the default save path was changed every time a screenshot was saved. Now, that only happens when it gets saved from the GUI. Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Change --path help text Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com> * Allow other image formats Signed-off-by: Haris Gušić <harisgusic.dev@gmail.com>
This commit is contained in:
@@ -5,7 +5,6 @@
|
||||
#include "src/utils/confighandler.h"
|
||||
#include "src/utils/strfparse.h"
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
#include <ctime>
|
||||
#include <exception>
|
||||
#include <locale>
|
||||
@@ -52,65 +51,75 @@ QString FileNameHandler::parseFilename(const QString& name)
|
||||
return res;
|
||||
}
|
||||
|
||||
QString FileNameHandler::generateAbsolutePath(const QString& path)
|
||||
/**
|
||||
* @brief Generate a valid destination path from the possibly incomplete `path`.
|
||||
* The input `path` can be one of:
|
||||
* - empty string
|
||||
* - an existing directory
|
||||
* - a file in an existing directory
|
||||
* In each case, the output path will be an absolute path to a file with a
|
||||
* suffix matching the specified `format`.
|
||||
* @note
|
||||
* - If `path` points to a directory, the file name will be generated from the
|
||||
* formatted file name from the user configuration
|
||||
* - If `path` points to a file, its suffix will be changed to match `format`
|
||||
* - If `format` is not given, the suffix will remain untouched, unless `path`
|
||||
* has no suffix, in which case it will be given the "png" suffix
|
||||
* - If the path generated by the previous steps points to an existing file,
|
||||
* "_NUM" will be appended to its base name, where NUM is the first
|
||||
* available number that produces a non-existent path (starting from 1).
|
||||
* @param path Possibly incomplete file name to transform
|
||||
* @param format Desired output file suffix (excluding an initial '.' character)
|
||||
*/
|
||||
QString FileNameHandler::properScreenshotPath(QString path,
|
||||
const QString& format)
|
||||
{
|
||||
QString directory = path;
|
||||
QString filename = parsedPattern();
|
||||
fixPath(directory, filename);
|
||||
return directory + filename;
|
||||
}
|
||||
// path a images si no existe, add numeration
|
||||
void FileNameHandler::setPattern(const QString& pattern)
|
||||
{
|
||||
ConfigHandler().setFilenamePattern(pattern);
|
||||
}
|
||||
QFileInfo info(path);
|
||||
QString suffix = info.suffix();
|
||||
|
||||
QString FileNameHandler::absoluteSavePath(QString& directory, QString& filename)
|
||||
{
|
||||
ConfigHandler config;
|
||||
directory = config.savePath();
|
||||
if (directory.isEmpty() || !QDir(directory).exists() ||
|
||||
!QFileInfo(directory).isWritable()) {
|
||||
directory =
|
||||
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
|
||||
if (info.isDir()) {
|
||||
// path is a directory => generate filename from configured pattern
|
||||
path = QDir(QDir(path).absolutePath() + "/" + parsedPattern()).path();
|
||||
} else {
|
||||
// path points to a file => strip it of its suffix for now
|
||||
path = QDir(info.dir().absolutePath() + "/" + info.completeBaseName())
|
||||
.path();
|
||||
}
|
||||
filename = parsedPattern();
|
||||
fixPath(directory, filename);
|
||||
return directory + filename;
|
||||
}
|
||||
|
||||
QString FileNameHandler::absoluteSavePath()
|
||||
{
|
||||
QString dir, file;
|
||||
return absoluteSavePath(dir, file);
|
||||
}
|
||||
|
||||
QString FileNameHandler::charArrToQString(const char* c)
|
||||
{
|
||||
return QString::fromLocal8Bit(c, MAX_CHARACTERS);
|
||||
}
|
||||
|
||||
char* FileNameHandler::QStringToCharArr(const QString& s)
|
||||
{
|
||||
QByteArray ba = s.toLocal8Bit();
|
||||
return const_cast<char*>(strdup(ba.constData()));
|
||||
}
|
||||
|
||||
void FileNameHandler::fixPath(QString& directory, QString& filename)
|
||||
{
|
||||
// add '/' at the end of the directory
|
||||
if (!directory.endsWith(QLatin1String("/"))) {
|
||||
directory += QLatin1String("/");
|
||||
if (!format.isEmpty()) {
|
||||
// Override suffix to match format
|
||||
path += "." + format;
|
||||
} else if (!suffix.isEmpty()) {
|
||||
// Leave the suffix as it was
|
||||
path += "." + suffix;
|
||||
} else {
|
||||
path += ".png";
|
||||
}
|
||||
|
||||
if (!QFileInfo::exists(path)) {
|
||||
return path;
|
||||
} else {
|
||||
return autoNumerateDuplicate(path);
|
||||
}
|
||||
}
|
||||
|
||||
QString FileNameHandler::autoNumerateDuplicate(QString path)
|
||||
{
|
||||
// add numeration in case of repeated filename in the directory
|
||||
// find unused name adding _n where n is a number
|
||||
QFileInfo checkFile(directory + filename + ".png");
|
||||
QFileInfo checkFile(path);
|
||||
QString directory = checkFile.dir().absolutePath(),
|
||||
filename = checkFile.completeBaseName(),
|
||||
suffix = checkFile.suffix();
|
||||
if (!suffix.isEmpty()) {
|
||||
suffix = QStringLiteral(".") + suffix;
|
||||
}
|
||||
if (checkFile.exists()) {
|
||||
filename += QLatin1String("_");
|
||||
int i = 1;
|
||||
while (true) {
|
||||
checkFile.setFile(directory + filename + QString::number(i) +
|
||||
".png");
|
||||
checkFile.setFile(directory + "/" + filename + QString::number(i) +
|
||||
suffix);
|
||||
if (!checkFile.exists()) {
|
||||
filename += QString::number(i);
|
||||
break;
|
||||
@@ -118,4 +127,5 @@ void FileNameHandler::fixPath(QString& directory, QString& filename)
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return checkFile.filePath();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user