1 | // Copyright (C) 2021 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qmediastoragelocation_p.h" |
5 | |
6 | #include <QStandardPaths> |
7 | #include <QUrl> |
8 | |
9 | QT_BEGIN_NAMESPACE |
10 | |
11 | QDir QMediaStorageLocation::defaultDirectory(QStandardPaths::StandardLocation type) |
12 | { |
13 | QStringList dirCandidates; |
14 | |
15 | #if QT_CONFIG(mmrenderer) |
16 | dirCandidates << QLatin1String("shared/camera" ); |
17 | #endif |
18 | |
19 | dirCandidates << QStandardPaths::writableLocation(type); |
20 | dirCandidates << QStandardPaths::writableLocation(type: QStandardPaths::DocumentsLocation); |
21 | dirCandidates << QDir::homePath(); |
22 | dirCandidates << QDir::currentPath(); |
23 | dirCandidates << QDir::tempPath(); |
24 | |
25 | for (const QString &path : std::as_const(t&: dirCandidates)) { |
26 | QDir dir(path); |
27 | if (dir.exists() && QFileInfo(path).isWritable()) |
28 | return dir; |
29 | } |
30 | |
31 | return QDir(); |
32 | } |
33 | |
34 | static QString generateFileName(const QDir &dir, const QString &prefix, const QString &extension) |
35 | { |
36 | auto lastMediaIndex = 0; |
37 | const auto list = dir.entryList(nameFilters: { QStringLiteral("%1*.%2" ).arg(args: prefix, args: extension) }); |
38 | for (const QString &fileName : list) { |
39 | auto mediaIndex = QStringView{fileName}.mid(pos: prefix.size(), n: fileName.size() - prefix.size() - extension.size() - 1).toInt(); |
40 | lastMediaIndex = qMax(a: lastMediaIndex, b: mediaIndex); |
41 | } |
42 | |
43 | const QString name = QStringLiteral("%1%2.%3" ) |
44 | .arg(a: prefix) |
45 | .arg(a: lastMediaIndex + 1, fieldWidth: 4, base: 10, fillChar: QLatin1Char('0')) |
46 | .arg(a: extension); |
47 | |
48 | return dir.absoluteFilePath(fileName: name); |
49 | } |
50 | |
51 | |
52 | QString QMediaStorageLocation::generateFileName(const QString &requestedName, |
53 | QStandardPaths::StandardLocation type, |
54 | const QString &extension) |
55 | { |
56 | using namespace Qt::StringLiterals; |
57 | |
58 | if (QUrl(requestedName).scheme() == "content"_L1 ) |
59 | return requestedName; |
60 | |
61 | auto prefix = "clip_"_L1 ; |
62 | switch (type) { |
63 | case QStandardPaths::PicturesLocation: prefix = "image_"_L1 ; break; |
64 | case QStandardPaths::MoviesLocation: prefix = "video_"_L1 ; break; |
65 | case QStandardPaths::MusicLocation: prefix = "record_"_L1 ; break; |
66 | default: break; |
67 | } |
68 | |
69 | if (requestedName.isEmpty()) |
70 | return generateFileName(dir: defaultDirectory(type), prefix, extension); |
71 | |
72 | QString path = requestedName; |
73 | |
74 | const QFileInfo fileInfo{ path }; |
75 | |
76 | if (fileInfo.isRelative() && QUrl(path).isRelative()) |
77 | path = defaultDirectory(type).absoluteFilePath(fileName: path); |
78 | |
79 | if (fileInfo.isDir()) |
80 | return generateFileName(dir: QDir(path), prefix, extension); |
81 | |
82 | if (fileInfo.suffix().isEmpty() && !extension.isEmpty()) { |
83 | // File does not have an extension, so add the suggested one |
84 | if (!path.endsWith(c: u'.')) |
85 | path.append(c: u'.'); |
86 | path.append(s: extension); |
87 | } |
88 | return path; |
89 | } |
90 | |
91 | QT_END_NAMESPACE |
92 | |