Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qstandardpaths.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:critical reason:provides-trusted-directory-paths
5
7
8#include <qdir.h>
9#include <qfileinfo.h>
10#include <qvarlengtharray.h>
11
12#ifndef QT_BOOTSTRAPPED
13#include <qobject.h>
14#include <qcoreapplication.h>
15#endif
16
17#if __has_include(<paths.h>)
18#include <paths.h>
19#endif
20
21#ifdef Q_OS_UNIX
22#include <unistd.h>
23#endif
24
25#ifndef QT_NO_STANDARDPATHS
26
28
29using namespace Qt::StringLiterals;
30/*!
31 \class QStandardPaths
32 \inmodule QtCore
33 \brief The QStandardPaths class provides methods for accessing standard paths.
34 \since 5.0
35
36 This class contains functions to query standard locations on the local
37 filesystem, for common tasks such as user-specific directories or system-wide
38 configuration directories.
39*/
40
41/*!
42 \enum QStandardPaths::StandardLocation
43
44 This enum describes the different locations that can be queried using
45 methods such as QStandardPaths::writableLocation, QStandardPaths::standardLocations,
46 and QStandardPaths::displayName.
47
48 QStandardPaths describes each location along two independent axes:
49 app scope (private to the calling application or shared between
50 applications) and user scope (rooted in the calling user's directories
51 or system-wide). Each enum value below indicates its app scope; the
52 platform tables further down show its user scope.
53
54 Data interchange with other users is out of the scope of QStandardPaths.
55
56 \section2 App scope
57
58 A location is either \e application-specific (private to the calling
59 application) or \e generic (shared between applications run by the
60 same user). Application-specific locations should be assumed to be
61 unreachable by other applications, even when run by the same user.
62
63 \section3 Sandboxed applications
64
65 For sandboxed applications, on platforms such as iOS, Android, or macOS,
66 even generic locations can be rooted in the application's sandbox container
67 (\c{<APPROOT>} in the tables below). In practice this collapses the
68 app-scope distinction, with every location becoming effectively
69 application-specific, and the user's system-wide shared directories reachable
70 only through system-provided pickers, for example, QFileDialog.
71
72 \section2 User scope
73
74 A location is either \e user-local (rooted in the calling user's
75 home or per-user directories) or \e system-wide (populated by the OS
76 or by package managers, shared across users, and usually read-only to
77 applications).
78
79 Querying writableLocation() returns the directory where files should be
80 written, which is typically user-scoped. For application-specific locations
81 it is also scoped to the calling application.
82
83 Querying standardLocations() returns the writable path first (if it can be
84 determined), followed by zero or more additional locations, including both
85 user-local and system-wide fallbacks. The additional locations are used by
86 locate() and locateAll() to find existing files.
87
88 \section3 Sandboxed applications
89
90 For sandboxed applications, system-wide locations typically fall outside
91 the application's sandbox container, and may not exist from the
92 application's point of view, let alone be readable or writable. They are
93 still listed in the platform tables below for symmetry with the
94 non-sandboxed case, and to cover applications that have been granted access
95 through entitlements or user-driven pickers. Callers should not assume that
96 every entry returned by standardLocations() exists or is accessible.
97
98 \value DesktopLocation The user's desktop directory. On systems with no
99 concept of a desktop, this is the same as HomeLocation. Generic.
100 \value DocumentsLocation Directory containing document files. The
101 returned path is never empty, except on Android 11 and later when
102 shared storage isn't available. Generic.
103 \value FontsLocation Directory containing fonts. Note that installing
104 fonts may require additional, platform-specific operations.
105 Generic.
106 \value ApplicationsLocation Directory containing applications (either
107 executables, application bundles, or shortcuts to them). Note
108 that installing applications may require additional,
109 platform-specific operations. Files, folders, or shortcuts in this
110 directory are platform-specific. Generic.
111 \value MusicLocation Directory containing music or other audio files.
112 If no such directory exists, a sensible fallback for storing
113 documents is returned. Generic.
114 \value MoviesLocation Directory containing movies and videos. If no
115 such directory exists, a sensible fallback for storing documents
116 is returned. Generic.
117 \value PicturesLocation Directory containing pictures or photos. If no
118 such directory exists, a sensible fallback for storing documents
119 is returned. Generic.
120 \value TempLocation Directory where temporary files can be stored. The
121 returned value might be application-specific, shared among other
122 applications for this user, or even system-wide. The returned
123 path is never empty. Varies.
124 \value HomeLocation The user's home directory (the same as
125 QDir::homePath()). On Unix systems, this is equal to the HOME
126 environment variable. The returned path is never empty. Generic.
127 \value AppLocalDataLocation The local data path on Windows. On all
128 other platforms, the same as AppDataLocation. Application-specific.
129 This enum value was added in Qt 5.4.
130 \value CacheLocation Directory where non-essential (cached) data should
131 be written. The returned path is never empty.
132 Application-specific.
133 \value GenericCacheLocation Directory where non-essential (cached) data
134 shared across applications should be written. Note that the
135 returned path may be empty if the system has no concept of
136 shared cache. Generic.
137 \value GenericDataLocation Directory where persistent data shared
138 across applications can be stored. The returned path is never
139 empty, except on Android 11 and later when shared storage isn't
140 available. Generic.
141 \value RuntimeLocation Directory where runtime communication files
142 should be written, like Unix local sockets. The returned path
143 may be empty on some systems. Generic.
144 \value ConfigLocation Directory where configuration files should be
145 written. The returned path is never empty. May be generic or
146 application-specific (see AppConfigLocation and
147 GenericConfigLocation for explicit variants). Varies.
148 \value DownloadLocation Directory for downloaded files. If no such
149 directory exists, a sensible fallback for storing documents is
150 returned. Generic.
151 \value GenericConfigLocation Directory where configuration files shared
152 between multiple applications should be written. The returned
153 path is never empty. Generic.
154 \value AppDataLocation Directory where persistent application data can
155 be stored. To obtain a path to store data to be shared with
156 other applications, use GenericDataLocation. The returned path
157 is never empty. On Windows, this returns the roaming path.
158 Application-specific.
159 This enum value was added in Qt 5.4.
160 \value AppConfigLocation Directory where configuration files should be
161 written. The returned path is never empty.
162 Application-specific.
163 This enum value was added in Qt 5.5.
164 \value PublicShareLocation Directory where publicly shared files and
165 directories can be stored. Note that the returned path may be
166 empty if the system has no concept of a publicly shared location.
167 Generic.
168 This enum value was added in Qt 6.4.
169 \value TemplatesLocation Directory where template files can be stored.
170 Note that the returned path may be empty if the system has no
171 concept of a templates location. Generic.
172 This enum value was added in Qt 6.4.
173 \value [since 6.7] StateLocation Directory where application state data
174 files should be written. The returned path is never empty.
175 Application-specific.
176 \value [since 6.7] GenericStateLocation Directory where shared state
177 data files across applications should be written. The returned
178 path is never empty. Generic.
179
180 The following table gives examples of paths on different operating systems.
181 The first path is the writable path (unless noted). Other, additional
182 paths, if any, represent non-writable locations.
183
184 \table
185 \header \li Path type \li \macos \li Windows
186 \row \li DesktopLocation
187 \li "~/Desktop"
188 \li "C:/Users/<USER>/Desktop"
189 \row \li DocumentsLocation
190 \li "~/Documents"
191 \li "C:/Users/<USER>/Documents"
192 \row \li FontsLocation
193 \li "~/Library/Fonts", "/Library/Fonts", "/System/Library/Fonts"
194 \li "C:/Windows/Fonts" (not writable)
195 \row \li ApplicationsLocation
196 \li "~/Applications", "/Applications"
197 \li "C:/Users/<USER>/AppData/Roaming/Microsoft/Windows/Start Menu/Programs"
198 \row \li MusicLocation
199 \li "~/Music"
200 \li "C:/Users/<USER>/Music"
201 \row \li MoviesLocation
202 \li "~/Movies"
203 \li "C:/Users/<USER>/Videos"
204 \row \li PicturesLocation
205 \li "~/Pictures"
206 \li "C:/Users/<USER>/Pictures"
207 \row \li TempLocation
208 \li randomly generated by the OS
209 \li "C:/Users/<USER>/AppData/Local/Temp"
210 \row \li HomeLocation
211 \li "~"
212 \li "C:/Users/<USER>"
213 \row \li AppLocalDataLocation
214 \li "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>". "<APPDIR>/../Resources"
215 \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>", "<APPDIR>", "<APPDIR>/data", "<APPDIR>/data/<APPNAME>"
216 \row \li CacheLocation
217 \li "~/Library/Caches/<APPNAME>", "/Library/Caches/<APPNAME>"
218 \li "C:/Users/<USER>/AppData/Local/<APPNAME>/cache"
219 \row \li StateLocation
220 \li "~/Library/Preferences/<APPNAME>/State"
221 \li "C:/Users/<USER>/AppData/Local/<APPNAME>/State", "C:/ProgramData/<APPNAME>/State"
222 \row \li GenericDataLocation
223 \li "~/Library/Application Support", "/Library/Application Support"
224 \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData", "<APPDIR>", "<APPDIR>/data"
225 \row \li RuntimeLocation
226 \li "~/Library/Application Support"
227 \li "C:/Users/<USER>"
228 \row \li ConfigLocation
229 \li "~/Library/Preferences", "/Library/Preferences"
230 \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>"
231 \row \li GenericConfigLocation
232 \li "~/Library/Preferences", "/Library/Preferences"
233 \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData"
234 \row \li DownloadLocation
235 \li "~/Downloads"
236 \li "C:/Users/<USER>/Downloads"
237 \row \li GenericCacheLocation
238 \li "~/Library/Caches", "/Library/Caches", "/System/Library/Caches"
239 \li "C:/Users/<USER>/AppData/Local/cache"
240 \row \li GenericStateLocation
241 \li "~/Library/Preferences/State"
242 \li "C:/Users/<USER>/AppData/Local/State", "C:/ProgramData/State"
243 \row \li AppDataLocation
244 \li "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>". "<APPDIR>/../Resources"
245 \li "C:/Users/<USER>/AppData/Roaming/<APPNAME>", "C:/ProgramData/<APPNAME>", "<APPDIR>", "<APPDIR>/data", "<APPDIR>/data/<APPNAME>"
246 \row \li AppConfigLocation
247 \li "~/Library/Preferences/<APPNAME>", "/Library/Preferences/<APPNAME>"
248 \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>"
249 \row \li PublicShareLocation
250 \li "~/Public"
251 \li "C:/Users/Public"
252 \row \li TemplatesLocation
253 \li not supported
254 \li "C:/Users/<USER>/AppData/Roaming/Microsoft/Windows/Templates"
255 \endtable
256
257 \note On macOS, when the application is sandboxed, the operating system
258 transparently redirects the user's home directory to a per-application
259 container at \c {~/Library/Containers/<BUNDLE-ID>/Data}. The macOS table
260 above still applies, with \c ~ effectively resolving to \c <APPROOT> for
261 user-rooted entries. System-wide fallbacks such as \c{/Library/...},
262 \c{/System/Library/...}, and \c{<APPDIR>/../Resources} are listed for
263 symmetry but are typically not reachable without explicit entitlements.
264
265 \table
266 \header \li Path type \li Linux and other UNIX operating systems
267 \row \li DesktopLocation
268 \li "~/Desktop"
269 \row \li DocumentsLocation
270 \li "~/Documents"
271 \row \li FontsLocation
272 \li "~/.fonts", "~/.local/share/fonts", "/usr/local/share/fonts", "/usr/share/fonts"
273 \row \li ApplicationsLocation
274 \li "~/.local/share/applications", "/usr/local/share/applications", "/usr/share/applications"
275 \row \li MusicLocation
276 \li "~/Music"
277 \row \li MoviesLocation
278 \li "~/Videos"
279 \row \li PicturesLocation
280 \li "~/Pictures"
281 \row \li TempLocation
282 \li "/tmp"
283 \row \li HomeLocation
284 \li "~"
285 \row \li AppLocalDataLocation
286 \li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
287 \row \li CacheLocation
288 \li "~/.cache/<APPNAME>"
289 \row \li StateLocation
290 \li "~/.local/state/<APPNAME>"
291 \row \li GenericDataLocation
292 \li "~/.local/share", "/usr/local/share", "/usr/share"
293 \row \li RuntimeLocation
294 \li "/run/user/<USER>"
295 \row \li ConfigLocation
296 \li "~/.config", "/etc/xdg"
297 \row \li GenericConfigLocation
298 \li "~/.config", "/etc/xdg"
299 \row \li DownloadLocation
300 \li "~/Downloads"
301 \row \li GenericCacheLocation
302 \li "~/.cache"
303 \row \li GenericStateLocation
304 \li "~/.local/state"
305 \row \li AppDataLocation
306 \li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
307 \row \li AppConfigLocation
308 \li "~/.config/<APPNAME>", "/etc/xdg/<APPNAME>"
309 \row \li PublicShareLocation
310 \li "~/Public"
311 \row \li TemplatesLocation
312 \li "~/Templates"
313 \endtable
314
315 \table
316 \header \li Path type \li Android \li iOS
317 \row \li DesktopLocation
318 \li "<APPROOT>/files"
319 \li "<APPROOT>/Documents/Desktop"
320 \row \li DocumentsLocation
321 \li "<USER>/Documents" [*], "<USER>/<APPNAME>/Documents"
322 \li "<APPROOT>/Documents"
323 \row \li FontsLocation
324 \li "/system/fonts" (not writable)
325 \li "<APPROOT>/Library/Fonts"
326 \row \li ApplicationsLocation
327 \li not supported (directory not readable)
328 \li not supported
329 \row \li MusicLocation
330 \li "<USER>/Music" [*], "<USER>/<APPNAME>/Music"
331 \li "<APPROOT>/Documents/Music"
332 \row \li MoviesLocation
333 \li "<USER>/Movies" [*], "<USER>/<APPNAME>/Movies"
334 \li "<APPROOT>/Documents/Movies"
335 \row \li PicturesLocation
336 \li "<USER>/Pictures" [*], "<USER>/<APPNAME>/Pictures"
337 \li "<APPROOT>/Documents/Pictures", "assets-library://"
338 \row \li TempLocation
339 \li "<APPROOT>/cache"
340 \li "<APPROOT>/tmp"
341 \row \li HomeLocation
342 \li "<APPROOT>/files"
343 \li system defined
344 \row \li AppLocalDataLocation
345 \li "<APPROOT>/files", "<USER>/<APPNAME>/files"
346 \li "<APPROOT>/Library/Application Support"
347 \row \li CacheLocation
348 \li "<APPROOT>/cache", "<USER>/<APPNAME>/cache"
349 \li "<APPROOT>/Library/Caches"
350 \row \li StateLocation
351 \li "<APPROOT>/files/state"
352 \li "<APPROOT>/Library/Preferences/<APPNAME>/State"
353 \row \li GenericStateLocation (there is shared state)
354 \li "<APPROOT>/files/state"
355 \li "<APPROOT>/Library/Preferences/State"
356 \row \li GenericDataLocation
357 \li "<USER>" [*] or "<USER>/<APPNAME>/files"
358 \li "<APPROOT>/Library/Application Support"
359 \row \li RuntimeLocation
360 \li "<APPROOT>/cache"
361 \li "<APPROOT>/Library/Application Support"
362 \row \li ConfigLocation
363 \li "<APPROOT>/files/settings"
364 \li "<APPROOT>/Library/Preferences"
365 \row \li GenericConfigLocation
366 \li "<APPROOT>/files/settings" (there is no shared settings)
367 \li "<APPROOT>/Library/Preferences"
368 \row \li DownloadLocation
369 \li "<USER>/Downloads" [*], "<USER>/<APPNAME>/Downloads"
370 \li "<APPROOT>/Documents/Downloads"
371 \row \li GenericCacheLocation
372 \li "<APPROOT>/cache" (there is no shared cache)
373 \li "<APPROOT>/Library/Caches"
374 \row \li AppDataLocation
375 \li "<APPROOT>/files", "<USER>/<APPNAME>/files"
376 \li "<APPROOT>/Library/Application Support"
377 \row \li AppConfigLocation
378 \li "<APPROOT>/files/settings"
379 \li "<APPROOT>/Library/Preferences/<APPNAME>"
380 \row \li PublicShareLocation
381 \li not supported
382 \li "<APPROOT>/Public"
383 \row \li TemplatesLocation
384 \li not supported
385 \li not supported
386 \endtable
387
388 In the table above, \c <APPNAME> is usually the organization name, the
389 application name, or both, or a unique name generated at packaging.
390 Similarly, <APPROOT> is the location where this application is installed
391 (often a sandbox). <APPDIR> is the directory containing the application
392 executable.
393
394 The paths above should not be relied upon, as they may change according to
395 OS configuration, locale, or they may change in future Qt versions.
396
397 \note On Android, applications with open files on the external storage (<USER> locations),
398 will be killed if the external storage is unmounted.
399
400 \note On Android 6.0 (API 23) or higher, the "WRITE_EXTERNAL_STORAGE" permission must be
401 requested at runtime when using QStandardPaths::writableLocation or QStandardPaths::standardLocations.
402
403 \note On Android, reading/writing to GenericDataLocation needs the READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE permission granted.
404
405 \note [*] On Android 11 and above, public directories are no longer directly accessible
406 in scoped storage mode. Thus, paths of the form \c "<USER>/DirName" are not returned.
407 Instead, you can use \l QFileDialog which uses the Storage Access Framework (SAF)
408 to access such directories.
409
410 \note On iOS, if you do pass \c {QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).last()}
411 as argument to \l{QFileDialog::setDirectory()},
412 a native image picker dialog will be used for accessing the user's photo album.
413 The filename returned can be loaded using QFile and related APIs.
414 This feature was added in Qt 5.5.
415
416 \sa writableLocation(), standardLocations(), displayName(), locate(), locateAll()
417*/
418
419/*!
420 \fn QString QStandardPaths::writableLocation(StandardLocation type)
421
422 \include standardpath/functiondocs.qdocinc writableLocation
423*/
424
425
426/*!
427 \fn QStringList QStandardPaths::standardLocations(StandardLocation type)
428
429 \include standardpath/functiondocs.qdocinc standardLocations
430
431 \sa writableLocation()
432 */
433
434/*!
435 \enum QStandardPaths::LocateOption
436
437 This enum describes the different flags that can be used for
438 controlling the behavior of QStandardPaths::locate and
439 QStandardPaths::locateAll.
440
441 \value LocateFile return only files
442 \value LocateDirectory return only directories
443*/
444
445static bool existsAsSpecified(const QString &path, QStandardPaths::LocateOptions options)
446{
447 if (options & QStandardPaths::LocateDirectory)
448 return QDir(path).exists();
449 return QFileInfo(path).isFile();
450}
451
452/*!
453 \include standardpath/functiondocs.qdocinc locate
454 */
455QString QStandardPaths::locate(StandardLocation type, const QString &fileName, LocateOptions options)
456{
457 const QStringList &dirs = standardLocations(type);
458 for (QStringList::const_iterator dir = dirs.constBegin(); dir != dirs.constEnd(); ++dir) {
459 const QString path = *dir + u'/' + fileName;
460 if (existsAsSpecified(path, options))
461 return path;
462 }
463 return QString();
464}
465
466/*!
467 \include standardpath/functiondocs.qdocinc locateAll
468 */
469QStringList QStandardPaths::locateAll(StandardLocation type, const QString &fileName, LocateOptions options)
470{
471 const QStringList &dirs = standardLocations(type);
472 QStringList result;
473 for (QStringList::const_iterator dir = dirs.constBegin(); dir != dirs.constEnd(); ++dir) {
474 const QString path = *dir + u'/' + fileName;
475 if (existsAsSpecified(path, options))
476 result.append(path);
477 }
478 return result;
479}
480
481static Q_DECL_COLD_FUNCTION QString fallbackPathVariable()
482{
483#if defined(_PATH_DEFPATH)
484 // BSD API.
485 return QString::fromLocal8Bit(_PATH_DEFPATH);
486#endif
487#if defined(_CS_PATH)
488 // POSIX API.
489 size_t n = confstr(_CS_PATH, nullptr, 0);
490 if (n) {
491 // n includes the terminating null
492 QVarLengthArray<char, 1024> rawpath(n);
493 confstr(_CS_PATH, rawpath.data(), n);
494 return QString::fromLocal8Bit(QByteArrayView(rawpath.data(), n - 1));
495 }
496#else
497 // Windows SDK's execvpe() does not have a fallback, so we won't
498 // apply one either.
499#endif
500 return {};
501}
502
503#ifdef Q_OS_WIN
504static QStringList executableExtensions()
505{
506 // If %PATHEXT% does not contain .exe, it is either empty, malformed, or distorted in ways that we cannot support, anyway.
507 const QStringList pathExt = QString::fromLocal8Bit(qgetenv("PATHEXT")).toLower().split(u';');
508 return pathExt.contains(".exe"_L1, Qt::CaseInsensitive) ?
509 pathExt : QStringList{".exe"_L1, ".com"_L1, ".bat"_L1, ".cmd"_L1};
510}
511#endif
512
513static QString checkExecutable(const QString &path)
514{
515 const QFileInfo info(path);
516 if (info.isBundle())
517 return info.bundleName();
518 if (info.isFile() && info.isExecutable())
519 return QDir::cleanPath(path);
520 return QString();
521}
522
523static inline QString searchExecutable(const QStringList &searchPaths,
524 const QString &executableName)
525{
526 const QDir currentDir = QDir::current();
527 for (const QString &searchPath : searchPaths) {
528 const QString candidate = currentDir.absoluteFilePath(searchPath + u'/' + executableName);
529 const QString absPath = checkExecutable(candidate);
530 if (!absPath.isEmpty())
531 return absPath;
532 }
533 return QString();
534}
535
536#ifdef Q_OS_WIN
537
538// Find executable appending candidate suffixes, used for suffix-less executables
539// on Windows.
540static inline QString
541 searchExecutableAppendSuffix(const QStringList &searchPaths,
542 const QString &executableName,
543 const QStringList &suffixes)
544{
545 const QDir currentDir = QDir::current();
546 for (const QString &searchPath : searchPaths) {
547 const QString candidateRoot = currentDir.absoluteFilePath(searchPath + u'/' + executableName);
548 for (const QString &suffix : suffixes) {
549 const QString absPath = checkExecutable(candidateRoot + suffix);
550 if (!absPath.isEmpty())
551 return absPath;
552 }
553 }
554 return QString();
555}
556
557#endif // Q_OS_WIN
558
559/*!
560 \include standardpath/functiondocs.qdocinc findExecutable
561 */
562QString QStandardPaths::findExecutable(const QString &executableName, const QStringList &paths)
563{
564 if (QFileInfo(executableName).isAbsolute())
565 return checkExecutable(executableName);
566
567 QStringList searchPaths = paths;
568 if (paths.isEmpty()) {
569 QString pEnv = qEnvironmentVariable("PATH");
570 if (Q_UNLIKELY(pEnv.isNull())) {
571 // Get a default path. POSIX.1 does not actually require this, but
572 // most Unix libc fall back to confstr(_CS_PATH) if the PATH
573 // environment variable isn't set. Let's try to do the same.
574 pEnv = fallbackPathVariable();
575 }
576
577 // Remove trailing slashes, which occur on Windows.
578 searchPaths.reserve(pEnv.count(QDir::listSeparator()));
579 auto tokenizer = qTokenize(pEnv, QDir::listSeparator(), Qt::SkipEmptyParts);
580 for (QStringView rawPath : tokenizer) {
581 QString cleanPath = QDir::cleanPath(rawPath.toString());
582 if (cleanPath.size() > 1 && cleanPath.endsWith(u'/'))
583 cleanPath.truncate(cleanPath.size() - 1);
584 searchPaths.push_back(cleanPath);
585 }
586 }
587
588#ifdef Q_OS_WIN
589 // On Windows, if the name does not have a suffix or a suffix not
590 // in PATHEXT ("xx.foo"), append suffixes from PATHEXT.
591 static const QStringList executable_extensions = executableExtensions();
592 if (executableName.contains(u'.')) {
593 const QString suffix = QFileInfo(executableName).suffix();
594 if (suffix.isEmpty() || !executable_extensions.contains(u'.' + suffix, Qt::CaseInsensitive))
595 return searchExecutableAppendSuffix(searchPaths, executableName, executable_extensions);
596 } else {
597 return searchExecutableAppendSuffix(searchPaths, executableName, executable_extensions);
598 }
599#endif
600 return searchExecutable(searchPaths, executableName);
601}
602
603/*!
604 \fn QString QStandardPaths::displayName(StandardLocation type)
605
606 \include standardpath/functiondocs.qdocinc displayName
607*/
608
609#if !defined(Q_OS_DARWIN) && !defined(QT_BOOTSTRAPPED)
610QString QStandardPaths::displayName(StandardLocation type)
611{
612 switch (type) {
613 case DesktopLocation:
614 return QCoreApplication::translate("QStandardPaths", "Desktop");
615 case DocumentsLocation:
616 return QCoreApplication::translate("QStandardPaths", "Documents");
617 case FontsLocation:
618 return QCoreApplication::translate("QStandardPaths", "Fonts");
619 case ApplicationsLocation:
620 return QCoreApplication::translate("QStandardPaths", "Applications");
621 case MusicLocation:
622 return QCoreApplication::translate("QStandardPaths", "Music");
623 case MoviesLocation:
624 return QCoreApplication::translate("QStandardPaths", "Movies");
625 case PicturesLocation:
626 return QCoreApplication::translate("QStandardPaths", "Pictures");
627 case TempLocation:
628 return QCoreApplication::translate("QStandardPaths", "Temporary Directory");
629 case HomeLocation:
630 return QCoreApplication::translate("QStandardPaths", "Home");
631 case AppLocalDataLocation:
632 return QCoreApplication::translate("QStandardPaths", "Application Data");
633 case CacheLocation:
634 return QCoreApplication::translate("QStandardPaths", "Cache");
635 case StateLocation:
636 return QCoreApplication::translate("QStandardPaths", "State");
637 case GenericDataLocation:
638 return QCoreApplication::translate("QStandardPaths", "Shared Data");
639 case RuntimeLocation:
640 return QCoreApplication::translate("QStandardPaths", "Runtime");
641 case ConfigLocation:
642 return QCoreApplication::translate("QStandardPaths", "Configuration");
643 case GenericConfigLocation:
644 return QCoreApplication::translate("QStandardPaths", "Shared Configuration");
645 case GenericCacheLocation:
646 return QCoreApplication::translate("QStandardPaths", "Shared Cache");
647 case GenericStateLocation:
648 return QCoreApplication::translate("QStandardPaths", "Shared State");
649 case DownloadLocation:
650 return QCoreApplication::translate("QStandardPaths", "Downloads");
651 case AppDataLocation:
652 case AppConfigLocation:
653 return QCoreApplication::translate("QStandardPaths", "Application Configuration");
654 case PublicShareLocation:
655 return QCoreApplication::translate("QStandardPaths", "Public");
656 case TemplatesLocation:
657 return QCoreApplication::translate("QStandardPaths", "Templates");
658 }
659 // not reached
660 return QString();
661}
662#endif
663
664/*!
665 \fn void QStandardPaths::setTestModeEnabled(bool testMode)
666
667 \include standardpath/functiondocs.qdocinc setTestModeEnabled
668*/
669
670Q_CONSTINIT static bool qsp_testMode = false;
671
672void QStandardPaths::setTestModeEnabled(bool testMode)
673{
674 qsp_testMode = testMode;
675}
676
677/*!
678 \fn void QStandardPaths::isTestModeEnabled()
679
680 \internal
681
682 Returns \c true if test mode is enabled in QStandardPaths; otherwise returns \c false.
683*/
684
685bool QStandardPaths::isTestModeEnabled()
686{
687 return qsp_testMode;
688}
689
690
691QT_END_NAMESPACE
692
693#ifndef QT_NO_QOBJECT
694#include "moc_qstandardpaths.cpp"
695#endif
696
697#endif // QT_NO_STANDARDPATHS
Combined button and popup list for selecting options.
#define __has_include(x)
static bool existsAsSpecified(const QString &path, QStandardPaths::LocateOptions options)
static QString searchExecutable(const QStringList &searchPaths, const QString &executableName)
static Q_CONSTINIT bool qsp_testMode
static QString checkExecutable(const QString &path)
#define _PATH_DEFPATH