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_mac.mm
Go to the documentation of this file.
1// Copyright (C) 2016 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// Qt-Security score:critical reason:provides-trusted-directory-paths
4
6
7#ifndef QT_NO_STANDARDPATHS
8
9#include <qdir.h>
10#include <qurl.h>
11#include <private/qcore_mac_p.h>
12
13#ifndef QT_BOOTSTRAPPED
14#include <qcoreapplication.h>
15#endif
16
17#import <Foundation/Foundation.h>
18
20
21using namespace Qt::StringLiterals;
22
23static QString pathForDirectory(NSSearchPathDirectory directory,
24 NSSearchPathDomainMask mask)
25{
26 return QString::fromNSString(
27 [NSSearchPathForDirectoriesInDomains(directory, mask, YES) lastObject]);
28}
29
30static NSSearchPathDirectory searchPathDirectory(QStandardPaths::StandardLocation type)
31{
32 switch (type) {
33 case QStandardPaths::DesktopLocation:
34 return NSDesktopDirectory;
35 case QStandardPaths::DocumentsLocation:
36 return NSDocumentDirectory;
37 case QStandardPaths::ApplicationsLocation:
38 return NSApplicationDirectory;
39 case QStandardPaths::MusicLocation:
40 return NSMusicDirectory;
41 case QStandardPaths::MoviesLocation:
42 return NSMoviesDirectory;
43 case QStandardPaths::PicturesLocation:
44 return NSPicturesDirectory;
45 case QStandardPaths::GenericDataLocation:
46 case QStandardPaths::RuntimeLocation:
47 case QStandardPaths::AppDataLocation:
48 case QStandardPaths::AppLocalDataLocation:
49 return NSApplicationSupportDirectory;
50 case QStandardPaths::GenericCacheLocation:
51 case QStandardPaths::CacheLocation:
52 return NSCachesDirectory;
53 case QStandardPaths::DownloadLocation:
54 return NSDownloadsDirectory;
55 case QStandardPaths::PublicShareLocation:
56 return NSSharedPublicDirectory;
57 case QStandardPaths::TemplatesLocation:
58 default:
59 return (NSSearchPathDirectory)0;
60 }
61}
62
63static void appendOrganizationAndApp(QString &path)
64{
65#ifndef QT_BOOTSTRAPPED
66 const QString org = QCoreApplication::organizationName();
67 if (!org.isEmpty())
68 path += u'/' + org;
69 const QString appName = QCoreApplication::applicationName();
70 if (!appName.isEmpty())
71 path += u'/' + appName;
72#else
73 Q_UNUSED(path);
74#endif
75}
76
77static QString baseWritableLocation(QStandardPaths::StandardLocation type,
78 NSSearchPathDomainMask mask = NSUserDomainMask,
79 bool appendOrgAndApp = false)
80{
81 QString path;
82 const NSSearchPathDirectory dir = searchPathDirectory(type);
83 switch (type) {
84 case QStandardPaths::HomeLocation:
85 path = QDir::homePath();
86 break;
87 case QStandardPaths::TempLocation:
88 path = QDir::tempPath();
89 break;
90#if defined(QT_PLATFORM_UIKIT)
91 // These locations point to non-existing write-protected paths. Use sensible fallbacks.
92 case QStandardPaths::MusicLocation:
93 path = pathForDirectory(NSDocumentDirectory, mask) + "/Music"_L1;
94 break;
95 case QStandardPaths::MoviesLocation:
96 path = pathForDirectory(NSDocumentDirectory, mask) + "/Movies"_L1;
97 break;
98 case QStandardPaths::PicturesLocation:
99 path = pathForDirectory(NSDocumentDirectory, mask) + "/Pictures"_L1;
100 break;
101 case QStandardPaths::DownloadLocation:
102 path = pathForDirectory(NSDocumentDirectory, mask) + "/Downloads"_L1;
103 break;
104 case QStandardPaths::DesktopLocation:
105 path = pathForDirectory(NSDocumentDirectory, mask) + "/Desktop"_L1;
106 break;
107 case QStandardPaths::ApplicationsLocation:
108 break;
109#endif
110 case QStandardPaths::FontsLocation:
111 path = pathForDirectory(NSLibraryDirectory, mask) + "/Fonts"_L1;
112 break;
113 case QStandardPaths::ConfigLocation:
114 case QStandardPaths::GenericConfigLocation:
115 case QStandardPaths::AppConfigLocation:
116 path = pathForDirectory(NSLibraryDirectory, mask) + "/Preferences"_L1;
117 break;
118 case QStandardPaths::StateLocation:
119 if (appendOrgAndApp) { break; }
120 Q_FALLTHROUGH();
121 case QStandardPaths::GenericStateLocation:
122 path = pathForDirectory(NSLibraryDirectory, mask) + "/Preferences/State"_L1;
123 break;
124 default:
125 path = pathForDirectory(dir, mask);
126 break;
127 }
128
129 if (appendOrgAndApp) {
130 switch (type) {
131 case QStandardPaths::AppDataLocation:
132 case QStandardPaths::AppLocalDataLocation:
133 case QStandardPaths::AppConfigLocation:
134 case QStandardPaths::CacheLocation:
136 break;
137 case QStandardPaths::StateLocation:
138 path = pathForDirectory(NSLibraryDirectory, mask) + "/Preferences"_L1;
140 path += "/State"_L1;
141 break;
142 default:
143 break;
144 }
145 }
146
147 return path;
148}
149
150QString QStandardPaths::writableLocation(StandardLocation type)
151{
152 QString location = baseWritableLocation(type, NSUserDomainMask, true);
153 if (isTestModeEnabled())
154 location = location.replace(QDir::homePath(), QDir::homePath() + "/.qttest"_L1);
155
156 return location;
157}
158
159QStringList QStandardPaths::standardLocations(StandardLocation type)
160{
161 QStringList dirs;
162
163#if defined(QT_PLATFORM_UIKIT)
164 if (type == PicturesLocation)
165 dirs << "assets-library://"_L1;
166#endif
167
168 if (type == GenericDataLocation || type == FontsLocation || type == ApplicationsLocation
169 || type == AppDataLocation || type == AppLocalDataLocation
170 || type == GenericCacheLocation || type == CacheLocation
171 || type == ConfigLocation || type == GenericConfigLocation
172 || type == AppConfigLocation) {
173 QList<NSSearchPathDomainMask> masks;
174 masks << NSLocalDomainMask;
175 if (type == FontsLocation || type == GenericCacheLocation)
176 masks << NSSystemDomainMask;
177
178 for (QList<NSSearchPathDomainMask>::const_iterator it = masks.begin();
179 it != masks.end(); ++it) {
180 const QString path = baseWritableLocation(type, *it, true);
181 if (!path.isEmpty() && !dirs.contains(path))
182 dirs.append(path);
183 }
184 }
185
186 if (type == AppDataLocation || type == AppLocalDataLocation) {
187 CFBundleRef mainBundle = CFBundleGetMainBundle();
188 if (mainBundle) {
189 if (QCFType<CFURLRef> resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle)) {
190 if (QCFType<CFURLRef> absoluteResouresURL = CFURLCopyAbsoluteURL(resourcesURL)) {
191 if (QCFType<CFStringRef> path = CFURLCopyFileSystemPath(absoluteResouresURL,
192 kCFURLPOSIXPathStyle)) {
193 dirs.append(QString::fromCFString(path));
194 }
195 }
196 }
197 }
198 }
199
200 const QString localDir = writableLocation(type);
201 if (!localDir.isEmpty())
202 dirs.prepend(localDir);
203 return dirs;
204}
205
206#ifndef QT_BOOTSTRAPPED
207QString QStandardPaths::displayName(StandardLocation type)
208{
209 // Use "Home" instead of the user's Unix username
210 if (QStandardPaths::HomeLocation == type)
211 return QCoreApplication::translate("QStandardPaths", "Home");
212
213 // The temporary directory returned by the old Carbon APIs is ~/Library/Caches/TemporaryItems,
214 // the display name of which ("TemporaryItems") isn't translated by the system. The standard
215 // temporary directory has no reasonable display name either, so use something more sensible.
216 if (QStandardPaths::TempLocation == type) {
217 //: macOS: Temporary directory
218 return QCoreApplication::translate("QStandardPaths", "Temporary Items");
219 }
220
221 // standardLocations() may return an empty list on some platforms
222 if (QStandardPaths::ApplicationsLocation == type)
223 return QCoreApplication::translate("QStandardPaths", "Applications");
224
225 const QCFString fsPath(standardLocations(type).constFirst());
226 if (QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
227 fsPath, kCFURLPOSIXPathStyle, true)) {
228 QCFString name;
229 CFURLCopyResourcePropertyForKey(url, kCFURLLocalizedNameKey, &name, NULL);
230 if (name && CFStringGetLength(name))
231 return QString::fromCFString(name);
232 }
233
234 return QFileInfo(baseWritableLocation(type)).fileName();
235}
236#endif
237
238QT_END_NAMESPACE
239
240#endif // QT_NO_STANDARDPATHS
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:177
Combined button and popup list for selecting options.
static QString baseWritableLocation(QStandardPaths::StandardLocation type, NSSearchPathDomainMask mask=NSUserDomainMask, bool appendOrgAndApp=false)
static NSSearchPathDirectory searchPathDirectory(QStandardPaths::StandardLocation type)
static void appendOrganizationAndApp(QString &path)
static QString pathForDirectory(NSSearchPathDirectory directory, NSSearchPathDomainMask mask)