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
makeSuggestedName(const QString & oldName)19 QString 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(oldName);
26
27 if (oldName.lastIndexOf(QLatin1Char('.')) == 0) {
28 basename = QStringLiteral(".");
29 nameSuffix = oldName;
30 } else if (nameSuffix.isEmpty()) {
31 const int lastDot = oldName.lastIndexOf(QLatin1Char('.'));
32 if (lastDot == -1) {
33 basename = oldName;
34 } else {
35 basename = oldName.left(lastDot);
36 nameSuffix = oldName.mid(lastDot);
37 }
38 } else {
39 nameSuffix.prepend(QLatin1Char('.'));
40 basename = oldName.left(oldName.length() - nameSuffix.length());
41 }
42
43 // check if (number) exists at the end of the oldName and increment that number
44 const QRegularExpression re(QStringLiteral("\\((\\d+)\\)"));
45 QRegularExpressionMatch rmatch;
46 oldName.lastIndexOf(re, -1, &rmatch);
47 if (rmatch.hasMatch()) {
48 const int currentNum = rmatch.captured(1).toInt();
49 const QString number = QString::number(currentNum + 1);
50 basename.replace(rmatch.capturedStart(1), rmatch.capturedLength(1), number);
51 } else {
52 // number does not exist, so just append " (1)" to filename
53 basename += QLatin1String(" (1)");
54 }
55
56 return basename + nameSuffix;
57 }
58
suggestName(const QUrl & baseURL,const QString & oldName)59 QString KFileUtils::suggestName(const QUrl &baseURL, const QString &oldName)
60 {
61 QString suggestedName = makeSuggestedName(oldName);
62
63 if (baseURL.isLocalFile()) {
64 const QString basePath = baseURL.toLocalFile() + QLatin1Char('/');
65 while (QFileInfo::exists(basePath + suggestedName)) {
66 suggestedName = makeSuggestedName(suggestedName);
67 }
68 }
69
70 return suggestedName;
71 }
72
findAllUniqueFiles(const QStringList & dirs,const QStringList & nameFilters)73 QStringList KFileUtils::findAllUniqueFiles(const QStringList &dirs, const QStringList &nameFilters)
74 {
75 QStringList foundFilePaths;
76 std::set<QString> foundFileNames;
77 for (const QString &dir : dirs) {
78 QDirIterator it(dir, nameFilters, QDir::Files);
79 while (it.hasNext()) {
80 it.next();
81 const auto [iter, isFirstSeen] = foundFileNames.insert(it.fileName());
82 if (isFirstSeen) {
83 foundFilePaths << it.filePath();
84 }
85 }
86 }
87 return foundFilePaths;
88 }
89