1/*
2 This file is part of the KDE libraries
3
4 SPDX-FileCopyrightText: 2000-2005 David Faure <faure@kde.org>
5 SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lohnau@gmx.de>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#include "kfileutils.h"
11
12#include <QDirIterator>
13#include <QFileInfo>
14#include <QMimeDatabase>
15#include <QRegularExpression>
16
17#include <set>
18
19QString KFileUtils::makeSuggestedName(const QString &oldName)
20{
21 QString basename;
22
23 // Extract the original file extension from the filename
24 QMimeDatabase db;
25 QString nameSuffix = db.suffixForFileName(fileName: oldName);
26
27 if (oldName.lastIndexOf(c: QLatin1Char('.')) == 0) {
28 basename = QStringLiteral(".");
29 nameSuffix = oldName;
30 } else if (nameSuffix.isEmpty()) {
31 const int lastDot = oldName.lastIndexOf(c: QLatin1Char('.'));
32 if (lastDot == -1) {
33 basename = oldName;
34 } else {
35 basename = oldName.left(n: lastDot);
36 nameSuffix = oldName.mid(position: lastDot);
37 }
38 } else {
39 nameSuffix.prepend(c: QLatin1Char('.'));
40 basename = oldName.left(n: oldName.length() - nameSuffix.length());
41 }
42
43 // check if (number) exists at the end of the oldName and increment that number
44 const static QRegularExpression re(QStringLiteral("\\((\\d+)\\)"));
45 QRegularExpressionMatch rmatch;
46 if (oldName.lastIndexOf(re, from: -1, rmatch: &rmatch) != -1) {
47 const int currentNum = rmatch.captured(nth: 1).toInt();
48 const QString number = QString::number(currentNum + 1);
49 basename.replace(i: rmatch.capturedStart(nth: 1), len: rmatch.capturedLength(nth: 1), after: number);
50 } else {
51 // number does not exist, so just append " (1)" to filename
52 basename += QLatin1String(" (1)");
53 }
54
55 return basename + nameSuffix;
56}
57
58QString KFileUtils::suggestName(const QUrl &baseURL, const QString &oldName)
59{
60 QString suggestedName = makeSuggestedName(oldName);
61
62 if (baseURL.isLocalFile()) {
63 const QString basePath = baseURL.toLocalFile() + QLatin1Char('/');
64 while (QFileInfo::exists(file: basePath + suggestedName)) {
65 suggestedName = makeSuggestedName(oldName: suggestedName);
66 }
67 }
68
69 return suggestedName;
70}
71
72QStringList KFileUtils::findAllUniqueFiles(const QStringList &dirs, const QStringList &nameFilters)
73{
74 QStringList foundFilePaths;
75 std::set<QString> foundFileNames;
76 for (const QString &dir : dirs) {
77 QDirIterator it(dir, nameFilters, QDir::Files);
78 while (it.hasNext()) {
79 it.next();
80 const auto [iter, isFirstSeen] = foundFileNames.insert(x: it.fileName());
81 if (isFirstSeen) {
82 foundFilePaths << it.filePath();
83 }
84 }
85 }
86 return foundFilePaths;
87}
88

source code of kcoreaddons/src/lib/io/kfileutils.cpp