swift
Loading...
Searching...
No Matches
swiftdirectories.cpp
1// SPDX-FileCopyrightText: Copyright (C) 2020 swift Project Community / Contributors
2// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3
5
7
8#include <QCoreApplication>
9#include <QDir>
10#include <QRegularExpression>
11#include <QSet>
12#include <QStandardPaths>
13#include <QUrl>
14
15#include "config/buildconfig.h"
16#include "misc/directoryutils.h"
17#include "misc/fileutils.h"
18#include "misc/range.h"
19#include "misc/stringutils.h"
20
21using namespace swift::config;
22
23namespace swift::misc
24{
25 QString binDirectoryImpl()
26 {
27 QString appDirectoryString(qApp->applicationDirPath());
28 if (appDirectoryString.endsWith("Contents/MacOS"))
29 {
30 appDirectoryString += "/../../..";
31 }
32 QDir appDirectory(appDirectoryString);
33 return appDirectory.absolutePath();
34 }
35
36 const QString &CSwiftDirectories::binDirectory()
37 {
38 static const QString binDir(binDirectoryImpl());
39 return binDir;
40 }
41
43 {
44 static const QString pDir(CFileUtils::appendFilePaths(binDirectory(), "plugins"));
45 return pDir;
46 }
47
49 {
50 static const QString pDir(CFileUtils::appendFilePaths(binDirectory(), "audio"));
51 return pDir;
52 }
53
55 {
56 if (!CBuildConfig::isLocalDeveloperDebugBuild())
57 {
58 static const QString e;
59 return e;
60 }
61
62 // the xswiftbus directory in out, not in dist
63 static const QString bd = [] {
64 QDir dir(binDirectory());
65 if (!dir.cdUp())
66 {
67 return QString();
68 }
69 if (!dir.cd("xswiftbus"))
70 {
71 return QString();
72 }
73 return dir.absolutePath();
74 }();
75 return bd;
76 }
77
78 QString CSwiftDirectories::executableFilePath(const QString &executable)
79 {
80 Q_ASSERT_X(!executable.isEmpty(), Q_FUNC_INFO, "Missing executable file path");
81
82 QString s = CFileUtils::appendFilePaths(binDirectory(), executable);
83 if (CBuildConfig::isRunningOnMacOSPlatform())
84 {
85 // MacOS bundle may or may not be a bundle
86 const QDir dir(s + QLatin1String(".app/Contents/MacOS"));
87 if (dir.exists())
88 {
89 s += QLatin1String(".app/Contents/MacOS/") + executable;
90 }
91 }
92 else if (CBuildConfig::isRunningOnWindowsNtPlatform())
93 {
94 s += QLatin1String(".exe");
95 }
96 return s;
97 }
98
99 QString normalizedApplicationDirectoryImpl()
100 {
101 QString appDir = CSwiftDirectories::binDirectory();
102 Q_ASSERT(appDir.size() > 0);
103 // Remove leading '/' on Unix
104 if (appDir.at(0) == '/')
105 {
106 appDir.remove(0, 1);
107 }
108 return QUrl::toPercentEncoding(appDir);
109 }
110
111 const QString &CSwiftDirectories::normalizedApplicationDirectory()
112 {
113 static const QString appDir(normalizedApplicationDirectoryImpl());
114 return appDir;
115 }
116
118 {
119 static const QString p = CFileUtils::appendFilePaths(
121 return p;
122 }
123
125 {
126 static QFileInfoList fileInfoList = currentApplicationDataDirectories();
127 return fileInfoList;
128 }
129
131 {
132 const QDir swiftAppData(applicationDataDirectory()); // contains 1..n subdirs
133 if (!swiftAppData.isReadable())
134 {
135 return {};
136 }
137 return swiftAppData.entryInfoList({}, QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time);
138 }
139
141
142 QStringList CSwiftDirectories::applicationDataDirectoryList(bool withoutCurrent, bool decodedDirName)
143 {
144 QStringList dirs;
145 for (const QFileInfo &info : applicationDataDirectories())
146 {
147 if (withoutCurrent && info.filePath().contains(normalizedApplicationDirectory(), Qt::CaseInsensitive))
148 continue;
149 dirs.append(decodedDirName ? CDirectoryUtils::decodeNormalizedDirectory(info.filePath()) : info.filePath());
150 }
151 return dirs;
152 }
153
155 {
156 static const QString p =
157 CFileUtils::appendFilePaths(applicationDataDirectory(), normalizedApplicationDirectory());
158 return p;
159 }
160
161 const QString &CSwiftDirectories::logDirectory()
162 {
163 static const QString p = CFileUtils::appendFilePaths(normalizedApplicationDataDirectory(), "/logs");
164 return p;
165 }
166
167 QString getSwiftShareDirImpl()
168 {
170 const bool success = dir.cd("../share");
171 if (success)
172 {
173 Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
174 return dir.absolutePath();
175 }
176 Q_ASSERT_X(false, Q_FUNC_INFO, "missing dir");
177 return {};
178 }
179
180 const QString &CSwiftDirectories::shareDirectory()
181 {
182 static const QString s(getSwiftShareDirImpl());
183 return s;
184 }
185
187 {
188 static const QString test(CFileUtils::appendFilePaths(shareDirectory(), "test"));
189 return test;
190 }
191
193 {
194 static const QString tpd(CFileUtils::appendFilePaths(shareDirectory(), "simulator/swiftTerrainProbe"));
195 return tpd;
196 }
197
199 {
200 static const QString ms(CFileUtils::appendFilePaths(shareDirectory(), "matchingscript"));
201 return ms;
202 }
203
205 {
206 static const QString n("bootstrap.json");
207 return n;
208 }
209
210 QString getBootstrapResourceFileImpl()
211 {
212 const QString d(CSwiftDirectories::shareDirectory());
213 if (d.isEmpty())
214 {
215 return {};
216 }
217 const QFile file(
219 [[maybe_unused]] const bool exists = file.exists();
220 Q_ASSERT_X(exists, Q_FUNC_INFO, "missing bootstrap file");
221 return QFileInfo(file).absoluteFilePath();
222 }
223
225 {
226 static const QString s(getBootstrapResourceFileImpl());
227 return s;
228 }
229
230 QString getSwiftStaticDbFilesDirImpl()
231 {
232 const QString d(CSwiftDirectories::shareDirectory());
233 if (d.isEmpty())
234 {
235 return {};
236 }
237 const QDir dir(QDir::cleanPath(d + QDir::separator() + "shared/dbdata"));
238 Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
239 return dir.absolutePath();
240 }
241
243 {
244 static const QString s(getSwiftStaticDbFilesDirImpl());
245 return s;
246 }
247
248 QString getSoundFilesDirImpl()
249 {
250 const QString d(CSwiftDirectories::shareDirectory());
251 if (d.isEmpty())
252 {
253 return {};
254 }
255 const QDir dir(QDir::cleanPath(d + QDir::separator() + "sounds"));
256 Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
257 return dir.absolutePath();
258 }
259
261 {
262 static const QString s(getSoundFilesDirImpl());
263 return s;
264 }
265
266 QString getStylesheetsDirImpl()
267 {
268 const QString d(CSwiftDirectories::shareDirectory());
269 if (d.isEmpty())
270 {
271 return {};
272 }
273 const QDir dir(QDir::cleanPath(d + QDir::separator() + "qss"));
274 Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
275 return dir.absolutePath();
276 }
277
279 {
280 static const QString s(getStylesheetsDirImpl());
281 return s;
282 }
283
284 QString getHtmlDirImpl()
285 {
286 const QString d(CSwiftDirectories::shareDirectory());
287 const QDir dir(QDir::cleanPath(d + QDir::separator() + "html"));
288 Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
289 return dir.absolutePath();
290 }
291
292 const QString &CSwiftDirectories::htmlDirectory()
293 {
294 static const QString s(getHtmlDirImpl());
295 return s;
296 }
297
298 QString getLegalDirImpl()
299 {
300 const QString d(CSwiftDirectories::shareDirectory());
301 const QDir dir(QDir::cleanPath(d + QDir::separator() + "legal"));
302 Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
303 return dir.absolutePath();
304 }
305
306 const QString &CSwiftDirectories::legalDirectory()
307 {
308 static const QString s(getLegalDirImpl());
309 return s;
310 }
311
312 const QString &CSwiftDirectories::aboutFilePath()
313 {
314 static const QString about = QDir::cleanPath(legalDirectory() + QDir::separator() + "about.html");
315 return about;
316 }
317
318 QString testFilesDirImpl()
319 {
320 const QString d(CSwiftDirectories::shareDirectory());
321 if (d.isEmpty())
322 {
323 return {};
324 }
325 const QDir dir(QDir::cleanPath(d + QDir::separator() + "test"));
326 Q_ASSERT_X(dir.exists(), Q_FUNC_INFO, "missing dir");
327 return dir.absolutePath();
328 }
329
331 {
332 static QString s(testFilesDirImpl());
333 return s;
334 }
335
337 {
338 static const QString s(htmlDirectory() + QDir::separator() + "swifttemplate.html");
339 return s;
340 }
341
342 QString getDocumentationDirectoryImpl()
343 {
345 QString d = pathes.first();
347 QDir dir(d);
348 if (dir.exists())
349 {
350 return dir.absolutePath();
351 }
352 return pathes.first();
353 }
354
356 {
357 static const QString d(getDocumentationDirectoryImpl());
358 return d;
359 }
360
362 {
363 static const QString p = CFileUtils::appendFilePaths(normalizedApplicationDataDirectory(), "/crashpad");
364 return p;
365 }
366
368 {
369 static const QString p = CFileUtils::appendFilePaths(crashpadDirectory(), "/database");
370 return p;
371 }
372
374 {
375 static const QString p = CFileUtils::appendFilePaths(crashpadDirectory(), "/metrics");
376 return p;
377 }
378
380 {
381 QStringList failed;
382 QDir d(binDirectory());
383 if (!d.isReadable())
384 {
385 failed.append(d.absolutePath());
386 }
387
388 d = QDir(stylesheetsDirectory());
389 if (!d.isReadable())
390 {
391 failed.append(d.absolutePath());
392 }
393
394 d = QDir(applicationDataDirectory());
395 if (!d.isReadable())
396 {
397 failed.append(d.absolutePath());
398 }
399
400 // check if the executables are avialable
401 QString fn = executableFilePath(CBuildConfig::swiftCoreExecutableName());
402 if (!QFile::exists(fn))
403 {
404 failed.append(fn);
405 }
406
407 fn = executableFilePath(CBuildConfig::swiftDataExecutableName());
408 if (!QFile::exists(fn))
409 {
410 failed.append(fn);
411 }
412
413 fn = executableFilePath(CBuildConfig::swiftGuiExecutableName());
414 if (!QFile::exists(fn))
415 {
416 failed.append(fn);
417 }
418
419 return failed;
420 }
421
422 QString CSwiftDirectories::soundFilePathOrDefaultPath(const QString &directory, const QString &fileName)
423 {
424 if (!directory.isEmpty())
425 {
426 const QString fp = CFileUtils::appendFilePathsAndFixUnc(directory, fileName);
427 const QFileInfo fi(fp);
428 if (fi.exists())
429 {
430 return fi.absoluteFilePath();
431 }
432 }
434 const QFileInfo fi(fp);
435 return (fi.exists()) ? fi.absoluteFilePath() : QString();
436 }
437
438} // namespace swift::misc
439
static QString decodeNormalizedDirectory(const QString &directory)
Virtually the inverse operation of CDirectoryUtils::normalizedApplicationDirectory.
static QString appendFilePathsAndFixUnc(const QString &path1, const QString &path2)
Append file paths.
static QString appendFilePaths(const QString &path1, const QString &path2)
Append file paths.
static const QString & legalDirectory()
Where Legal files are located.
static const QString & stylesheetsDirectory()
Where qss files are located.
static const QString & staticDbFilesDirectory()
Where static DB files are located.
static const QString & normalizedApplicationDataDirectory()
swift application data directory for one specific installation (a version)
static const QString & crashpadDatabaseDirectory()
Directory for crashpad database files.
static const QString & aboutFilePath()
The about document file location.
static const QString & binDirectory()
Returns the bin directory. On Windows/Linux this is the same directory as QCoreApplication::applicati...
static const QString & crashpadMetricsDirectory()
Directory for crashpad metrics files.
static const QString & crashpadDirectory()
Directory for crashpad files.
static const QString & soundFilesDirectory()
Where sound files are located.
static const QFileInfoList & applicationDataDirectories()
swift application data sub directories
static const QString & getXSwiftBusBuildDirectory()
The build directory.
static const QString & htmlDirectory()
Where HTML files are located.
static const QString & bootstrapResourceFilePath()
Bootstrap resource file path.
static const QString & shareMatchingScriptDirectory()
Matching script examples directories.
static const QString & audioPluginDirectory()
Audio plugins directory for Qt audio.
static const QString & documentationDirectory()
Directory where data can be stored.
static const QString & shareTestDirectory()
The test data directory.
static const QString & shareTerrainProbeDirectory()
FSX/P3D terrain probe.
static QStringList applicationDataDirectoryList(bool withoutCurrent=false, bool decodedDirName=false)
swift application data sub directories
static const QString & shareDirectory()
Where resource files (static DB files, ...) etc are located.
static const QString & logDirectory()
Directory for log files.
static QString soundFilePathOrDefaultPath(const QString &directory, const QString &fileName)
File path (with file name) of file name and.
static QString executableFilePath(const QString &executable)
The executable file path.
static const QString & bootstrapFileName()
Bootstrap file name.
static const QString & testFilesDirectory()
Where test files are located.
static int applicationDataDirectoriesCount()
number of data directories (including this version)
static const QString & htmlTemplateFilePath()
HTML template.
static const QString & applicationDataDirectory()
swift application data directory, contains 0..n swift installation directories
static QFileInfoList currentApplicationDataDirectories()
swift application data sub directories
static const QString & pluginsDirectory()
Plugins directory.
static QStringList verifyRuntimeDirectoriesAndFiles()
Check if the (most important) runtime directories are available.
Free functions in swift::misc.
QString cleanPath(const QString &path)
QChar separator()
bool exists() const const
void append(QList< T > &&value)
QStringList standardLocations(QStandardPaths::StandardLocation type)
QString writableLocation(QStandardPaths::StandardLocation type)
const QChar at(qsizetype position) const const
bool isEmpty() const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
qsizetype size() const const
CaseInsensitive
QByteArray toPercentEncoding(const QString &input, const QByteArray &exclude, const QByteArray &include)