10#include "private/qcore_mac_p.h"
19static const CFStringRef
hostNames[2] = { kCFPreferencesCurrentHost, kCFPreferencesAnyHost };
34 static const int NumKnights = 3;
35 static const char knightsOfTheRoundTable[NumKnights] = {
'/',
'.',
'\xb7' };
39 for (
int j = 0;
j < NumKnights; ++
j) {
64 QVarLengthArray<QCFType<CFPropertyListRef>> cfvalues(
n);
65 for (
int i = 0;
i <
n; ++
i)
67 return CFArrayCreate(kCFAllocatorDefault,
reinterpret_cast<const void **
>(cfvalues.data()),
68 CFIndex(
n), &kCFTypeArrayCallBacks);
73 CFPropertyListRef
result = 0;
75 switch (
value.metaType().id()) {
76 case QMetaType::QByteArray:
79 result = CFDataCreate(kCFAllocatorDefault,
reinterpret_cast<const UInt8 *
>(
ba.
data()),
84 case QMetaType::QVariantList:
85 case QMetaType::QStringList:
86 case QMetaType::QPolygon:
89 case QMetaType::QVariantMap:
94 QVarLengthArray<QCFType<CFPropertyListRef>> cfkeys;
95 cfkeys.reserve(mapSize);
97 std::back_inserter(cfkeys),
98 [](
const auto &
key) { return key.toCFString(); });
100 QVarLengthArray<QCFType<CFPropertyListRef>> cfvalues;
101 cfvalues.reserve(mapSize);
103 std::back_inserter(cfvalues),
104 [](
const auto &
value) { return macValue(value); });
106 result = CFDictionaryCreate(kCFAllocatorDefault,
107 reinterpret_cast<const void **
>(cfkeys.data()),
108 reinterpret_cast<const void **
>(cfvalues.data()),
110 &kCFTypeDictionaryKeyCallBacks,
111 &kCFTypeDictionaryValueCallBacks);
114 case QMetaType::QDateTime:
124 case QMetaType::Bool:
125 result =
value.toBool() ? kCFBooleanTrue : kCFBooleanFalse;
128 case QMetaType::UInt:
131 result = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &
n);
134 case QMetaType::Double:
136 double n =
value.toDouble();
137 result = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &
n);
140 case QMetaType::LongLong:
141 case QMetaType::ULongLong:
144 result = CFNumberCreate(0, kCFNumberLongLongType, &
n);
147 case QMetaType::QString:
152 result = std::move(
string).toUtf8().toCFData();
154 result =
string.toCFString();
164 CFTypeID typeId = CFGetTypeID(cfvalue);
169 if (typeId == CFStringGetTypeID()) {
171 }
else if (typeId == CFNumberGetTypeID()) {
172 CFNumberRef cfnumber =
static_cast<CFNumberRef
>(cfvalue);
173 if (CFNumberIsFloatType(cfnumber)) {
175 CFNumberGetValue(cfnumber, kCFNumberDoubleType, &
d);
181 if (CFNumberGetType(cfnumber) == kCFNumberIntType) {
182 CFNumberGetValue(cfnumber, kCFNumberIntType, &
i);
185 CFNumberGetValue(cfnumber, kCFNumberLongLongType, &ll);
188 }
else if (typeId == CFArrayGetTypeID()) {
189 CFArrayRef cfarray =
static_cast<CFArrayRef
>(cfvalue);
190 QList<QVariant>
list;
191 CFIndex
size = CFArrayGetCount(cfarray);
192 bool metNonString =
false;
193 for (CFIndex
i = 0;
i <
size; ++
i) {
195 if (
value.typeId() != QMetaType::QString)
203 }
else if (typeId == CFBooleanGetTypeID()) {
204 return (
bool)CFBooleanGetValue(
static_cast<CFBooleanRef
>(cfvalue));
205 }
else if (typeId == CFDataGetTypeID()) {
206 QByteArray byteArray = QByteArray::fromRawCFData(
static_cast<CFDataRef
>(cfvalue));
225 }
else if (typeId == CFDictionaryGetTypeID()) {
226 CFDictionaryRef cfdict =
static_cast<CFDictionaryRef
>(cfvalue);
227 CFTypeID arrayTypeId = CFArrayGetTypeID();
228 int size = (int)CFDictionaryGetCount(cfdict);
229 QVarLengthArray<CFPropertyListRef>
keys(
size);
230 QVarLengthArray<CFPropertyListRef>
values(
size);
231 CFDictionaryGetKeysAndValues(cfdict,
keys.data(),
values.data());
234 for (
int i = 0;
i <
size; ++
i) {
235 QString key = QString::fromCFString(
static_cast<CFStringRef
>(
keys[
i]));
237 if (CFGetTypeID(
values[
i]) == arrayTypeId) {
238 CFArrayRef cfarray =
static_cast<CFArrayRef
>(
values[
i]);
239 CFIndex arraySize = CFArrayGetCount(cfarray);
242 for (CFIndex
j = 0;
j < arraySize; ++
j)
250 }
else if (typeId == CFDateGetTypeID()) {
251 return QDateTime::fromCFDate(
static_cast<CFDateRef
>(cfvalue));
258 for (
int i = organization.
size() - 1;
i >= 0; --
i) {
263 if (suffix.
size() == 2 || suffix ==
"com"_L1 || suffix ==
"org"_L1
264 || suffix ==
"net"_L1 || suffix ==
"edu"_L1 || suffix ==
"gov"_L1
265 || suffix ==
"mil"_L1 || suffix ==
"biz"_L1 || suffix ==
"info"_L1
266 || suffix ==
"name"_L1 || suffix ==
"pro"_L1 || suffix ==
"aero"_L1
267 || suffix ==
"coop"_L1 || suffix ==
"museum"_L1) {
274 int uc =
ch.unicode();
275 if ((uc <
'a' || uc >
'z') && (uc <
'A' || uc >
'Z'))
280 for (
int i = 0;
i < organization.
size(); ++
i) {
282 int uc =
ch.unicode();
283 if ((uc >=
'a' && uc <=
'z') || (uc >=
'0' && uc <=
'9')) {
285 }
else if (uc >=
'A' && uc <=
'Z') {
286 domain +=
ch.toLower();
307 std::optional<QVariant>
get(
const QString &
key)
const override;
309 void clear()
override;
310 void sync()
override;
311 void flush()
override;
318 CFStringRef userName;
319 CFStringRef applicationOrSuiteId;
325 SearchDomain domains[6];
340 if (domainName.isEmpty()) {
341 CFBundleRef main_bundle = CFBundleGetMainBundle();
342 if (main_bundle != NULL) {
343 CFStringRef main_bundle_identifier = CFBundleGetIdentifier(main_bundle);
344 if (main_bundle_identifier != NULL) {
345 QString bundle_identifier(
qtKey(main_bundle_identifier));
347 QStringList bundle_identifier_components = bundle_identifier.split(u
'/');
350 for (
int i=0;
i<bundle_identifier_components.size(); ++
i) {
351 const QString &bundle_identifier_component = bundle_identifier_components.
at(
i);
352 bundle_identifier_components_reversed.push_front(bundle_identifier_component);
354 domainName = bundle_identifier_components_reversed.join(u
'.');
359 if (domainName.isEmpty())
360 domainName =
"unknown-organization.trolltech.com"_L1;
362 while ((nextDot = domainName.indexOf(u
'.', curPos)) != -1) {
363 javaPackageName.prepend(
QStringView{domainName}.
mid(curPos, nextDot - curPos));
364 javaPackageName.prepend(u
'.');
365 curPos = nextDot + 1;
368 javaPackageName = std::move(javaPackageName).toLower();
370 javaPackageName.prepend(
"com."_L1);
371 suiteId = javaPackageName;
374 javaPackageName += u
'.' + application;
375 applicationId = javaPackageName;
380 for (
int j = (application.
isEmpty()) ? 1 : 0;
j < 3; ++
j) {
381 SearchDomain &domain = domains[numDomains++];
382 domain.userName = (
i == 0) ? kCFPreferencesCurrentUser : kCFPreferencesAnyUser;
384 domain.applicationOrSuiteId = applicationId;
386 domain.applicationOrSuiteId = suiteId;
388 domain.applicationOrSuiteId = kCFPreferencesAnyApplication;
405 for (
int i = -1;
i <
keys.size(); ++
i) {
409 subKey +=
keys.at(
i);
411 CFPreferencesSetValue(
macKey(subKey), 0, domains[0].applicationOrSuiteId,
412 domains[0].userName, hostName);
419 domains[0].userName, hostName);
425 for (
int i = 0;
i < numDomains; ++
i) {
427 QCFType<CFPropertyListRef>
ret =
428 CFPreferencesCopyValue(k, domains[
i].applicationOrSuiteId, domains[
i].userName,
443 int startPos = prefix.
size();
445 for (
int i = 0;
i < numDomains; ++
i) {
447 QCFType<CFArrayRef> cfarray = CFPreferencesCopyKeyList(domains[
i].applicationOrSuiteId,
451 CFIndex
size = CFArrayGetCount(cfarray);
452 for (CFIndex k = 0; k <
size; ++k) {
454 qtKey(
static_cast<CFStringRef
>(CFArrayGetValueAtIndex(cfarray, k)));
472 QCFType<CFArrayRef> cfarray = CFPreferencesCopyKeyList(domains[0].applicationOrSuiteId,
473 domains[0].userName, hostName);
474 CFPreferencesSetMultiple(0, cfarray, domains[0].applicationOrSuiteId, domains[0].userName,
480 for (
int i = 0;
i < numDomains; ++
i) {
482 Boolean
ok = CFPreferencesSynchronize(domains[
i].applicationOrSuiteId,
500 QString impossibleKey(
"qt_internal/"_L1);
505 that->set(impossibleKey,
QVariant());
508 that->remove(impossibleKey);
511 that->status = oldStatus;
520 result +=
"/Library/Preferences/"_L1;
521 result += QString::fromCFString(domains[0].applicationOrSuiteId);
531#ifndef QT_BOOTSTRAPPED
532 if (organization ==
"Qt"_L1)
560 QCFType<CFDataRef> cfData =
data.toRawCFData();
561 QCFType<CFPropertyListRef> propertyList =
562 CFPropertyListCreateWithData(kCFAllocatorDefault, cfData, kCFPropertyListImmutable,
nullptr,
nullptr);
566 if (CFGetTypeID(propertyList) != CFDictionaryGetTypeID())
569 CFDictionaryRef cfdict =
570 static_cast<CFDictionaryRef
>(
static_cast<CFPropertyListRef
>(propertyList));
571 int size = (int)CFDictionaryGetCount(cfdict);
572 QVarLengthArray<CFPropertyListRef>
keys(
size);
573 QVarLengthArray<CFPropertyListRef>
values(
size);
574 CFDictionaryGetKeysAndValues(cfdict,
keys.data(),
values.data());
576 for (
int i = 0;
i <
size; ++
i) {
585 QVarLengthArray<QCFType<CFStringRef> > cfkeys(
map.
size());
586 QVarLengthArray<QCFType<CFPropertyListRef> > cfvalues(
map.
size());
588 ParsedSettingsMap::const_iterator
j;
595 QCFType<CFDictionaryRef> propertyList =
596 CFDictionaryCreate(kCFAllocatorDefault,
597 reinterpret_cast<const void **
>(cfkeys.data()),
598 reinterpret_cast<const void **
>(cfvalues.data()),
600 &kCFTypeDictionaryKeyCallBacks,
601 &kCFTypeDictionaryValueCallBacks);
603 QCFType<CFDataRef> xmlData = CFPropertyListCreateData(
604 kCFAllocatorDefault, propertyList, kCFPropertyListXMLFormat_v1_0, 0, 0);
606 return file.
write(QByteArray::fromRawCFData(xmlData)) == CFDataGetLength(xmlData);
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
bool startsWith(QByteArrayView bv) const
QString applicationName
the name of this application
QString organizationDomain
the Internet domain of the organization that wrote this application
\inmodule QtCore\reentrant
Qt::TimeSpec timeSpec() const
Returns the time specification of the datetime.
static QString homePath()
Returns the absolute path of the user's home directory.
\inmodule QtCore \reentrant
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
void reserve(qsizetype size)
void append(parameter_type t)
std::optional< QVariant > get(const QString &key) const override
bool isWritable() const override
void remove(const QString &key) override
QString fileName() const override
QMacSettingsPrivate(QSettings::Scope scope, const QString &organization, const QString &application)
void set(const QString &key, const QVariant &value) override
iterator insert(const Key &key, const T &value)
const_iterator constBegin() const
key_iterator keyBegin() const
const_iterator constEnd() const
key_iterator keyEnd() const
static QSettingsPrivate * create(QSettings::Format format, QSettings::Scope scope, const QString &organization, const QString &application)
void setStatus(QSettings::Status status) const
static QVariant stringToVariant(const QString &s)
static QString variantToString(const QVariant &v)
static QString normalizedKey(QAnyStringView key)
static void processChild(QStringView key, ChildSpec spec, QStringList &result)
Format
This enum type specifies the storage format used by QSettings.
Scope
This enum specifies whether settings are user-specific or shared by all users of the same system.
Status
The following status values are possible:
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
QString & replace(qsizetype i, qsizetype len, QChar after)
QString mid(qsizetype position, qsizetype n=-1) const &
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
qsizetype size() const noexcept
Returns the number of characters in this string.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString simplified() const &
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
QString toLower() const &
QString & append(QChar c)
QStringList toStringList() const
Returns the variant as a QStringList if the variant has userType() \l QMetaType::QStringList,...
QMap< QString, QString > map
[6]
Combined button and popup list for selecting options.
static QT_WARNING_DISABLE_FLOAT_COMPARE ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qreal threshold)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static bool contains(const QJsonArray &haystack, unsigned needle)
GLenum GLsizei GLsizei GLint * values
[15]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei GLsizei GLenum format
static QVariant qtValue(CFPropertyListRef cfvalue)
static CFArrayRef macList(const QList< QVariant > &list)
static const int numHostNames
static QCFType< CFStringRef > macKey(const QString &key)
static const CFStringRef hostNames[2]
static QString rotateSlashesDotsAndMiddots(const QString &key, int shift)
static QCFType< CFPropertyListRef > macValue(const QVariant &value)
static QString qtKey(CFStringRef cfkey)
static QString comify(const QString &organization)
QFuture< QSet< QChar > > set
[10]
\inmodule QtCore \reentrant
constexpr char16_t unicode() const noexcept
Converts a Latin-1 character to an 16-bit-encoded Unicode representation of the character.