diff options
Diffstat (limited to 'src/corelib/io/qsettings.cpp')
-rw-r--r-- | src/corelib/io/qsettings.cpp | 267 |
1 files changed, 151 insertions, 116 deletions
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 60622e3aaa..6934ca4404 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -44,7 +44,7 @@ # include <shlobj.h> #endif -#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_ANDROID) +#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID) #define Q_XDG_PLATFORM #endif @@ -66,6 +66,7 @@ QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; +using namespace QtMiscUtils; struct QConfFileCustomFormat { @@ -128,12 +129,12 @@ bool QConfFile::isWritable() const { QFileInfo fileInfo(name); -#ifndef QT_NO_TEMPORARYFILE +#if QT_CONFIG(temporaryfile) if (fileInfo.exists()) { #endif QFile file(name); return file.open(QFile::ReadWrite); -#ifndef QT_NO_TEMPORARYFILE +#if QT_CONFIG(temporaryfile) } else { // Create the directories to the file. QDir dir(fileInfo.absolutePath()); @@ -211,9 +212,7 @@ namespace { } QChar *write(QChar *out, QLatin1StringView v) { - for (char ch : v) - *out++ = QLatin1Char(ch); - return out; + return QLatin1::convertToUnicode(out, v); } QChar *write(QChar *out, QStringView v) { @@ -271,7 +270,7 @@ QString QSettingsPrivate::normalizedKey(QAnyStringView key) // see also qsettings_win.cpp and qsettings_mac.cpp -#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC) && !defined(Q_OS_WASM) +#if !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN) && !defined(Q_OS_WASM) QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope, const QString &organization, const QString &application) { @@ -343,7 +342,7 @@ void QSettingsPrivate::requestUpdate() QStringList QSettingsPrivate::variantListToStringList(const QVariantList &l) { QStringList result; - result.reserve(l.count()); + result.reserve(l.size()); for (auto v : l) result.append(variantToString(v)); return result; @@ -356,9 +355,9 @@ QVariant QSettingsPrivate::stringListToVariantList(const QStringList &l) const QString &str = outStringList.at(i); if (str.startsWith(u'@')) { - if (str.length() < 2 || str.at(1) != u'@') { + if (str.size() < 2 || str.at(1) != u'@') { QVariantList variantList; - variantList.reserve(l.count()); + variantList.reserve(l.size()); for (const auto &s : l) variantList.append(stringToVariant(s)); return variantList; @@ -380,9 +379,7 @@ QString QSettingsPrivate::variantToString(const QVariant &v) case QMetaType::QByteArray: { QByteArray a = v.toByteArray(); - result = "@ByteArray("_L1 - + QLatin1StringView(a.constData(), a.size()) - + u')'; + result = "@ByteArray("_L1 + QLatin1StringView(a) + u')'; break; } @@ -511,14 +508,13 @@ QVariant QSettingsPrivate::stringToVariant(const QString &s) void QSettingsPrivate::iniEscapedKey(const QString &key, QByteArray &result) { - result.reserve(result.length() + key.length() * 3 / 2); + result.reserve(result.size() + key.size() * 3 / 2); for (qsizetype i = 0; i < key.size(); ++i) { uint ch = key.at(i).unicode(); if (ch == '/') { result += '\\'; - } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') - || ch == '_' || ch == '-' || ch == '.') { + } else if (isAsciiLetterOrNumber(ch) || ch == '_' || ch == '-' || ch == '.') { result += (char)ch; } else if (ch <= 0xFF) { result += '%'; @@ -540,7 +536,7 @@ bool QSettingsPrivate::iniUnescapedKey(QByteArrayView key, QString &result) { const QString decoded = QString::fromUtf8(key); const qsizetype size = decoded.size(); - result.reserve(result.length() + size); + result.reserve(result.size() + size); qsizetype i = 0; bool lowercaseOnly = true; while (i < size) { @@ -562,7 +558,7 @@ bool QSettingsPrivate::iniUnescapedKey(QByteArrayView key, QString &result) } int numDigits = 2; - int firstDigitPos = i + 1; + qsizetype firstDigitPos = i + 1; ch = decoded.at(i + 1).unicode(); if (ch == 'U') { @@ -597,25 +593,20 @@ void QSettingsPrivate::iniEscapedString(const QString &str, QByteArray &result) { bool needsQuotes = false; bool escapeNextIfDigit = false; - bool useCodec = !str.startsWith("@ByteArray("_L1) - && !str.startsWith("@Variant("_L1) - && !str.startsWith("@DateTime("_L1); + const bool useCodec = !(str.startsWith("@ByteArray("_L1) + || str.startsWith("@Variant("_L1) + || str.startsWith("@DateTime("_L1)); + const qsizetype startPos = result.size(); QStringEncoder toUtf8(QStringEncoder::Utf8); - qsizetype startPos = result.size(); result.reserve(startPos + str.size() * 3 / 2); - - const QChar *unicode = str.unicode(); - for (qsizetype i = 0; i < str.size(); ++i) { - uint ch = unicode[i].unicode(); + for (QChar qch : str) { + uint ch = qch.unicode(); if (ch == ';' || ch == ',' || ch == '=') needsQuotes = true; - if (escapeNextIfDigit - && ((ch >= '0' && ch <= '9') - || (ch >= 'a' && ch <= 'f') - || (ch >= 'A' && ch <= 'F'))) { + if (escapeNextIfDigit && isHexDigit(ch)) { result += "\\x" + QByteArray::number(ch, 16); continue; } @@ -659,7 +650,7 @@ void QSettingsPrivate::iniEscapedString(const QString &str, QByteArray &result) escapeNextIfDigit = true; } else if (useCodec) { // slow - result += toUtf8(unicode[i]); + result += toUtf8(qch); } else { result += (char)ch; } @@ -735,7 +726,7 @@ StSkipSpaces: // fallthrough StNormal: - qsizetype chopLimit = stringResult.length(); + qsizetype chopLimit = stringResult.size(); while (i < str.size()) { switch (str.at(i)) { case '\\': @@ -758,10 +749,10 @@ StNormal: goto end; ch = str.at(i); - if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) + if (isHexDigit(ch)) goto StHexEscape; - } else if (ch >= '0' && ch <= '7') { - escapeVal = ch - '0'; + } else if (const int o = fromOct(ch); o != -1) { + escapeVal = o; goto StOctEscape; } else if (ch == '\n' || ch == '\r') { if (i < str.size()) { @@ -773,7 +764,7 @@ StNormal: } else { // the character is skipped } - chopLimit = stringResult.length(); + chopLimit = stringResult.size(); break; case '"': ++i; @@ -823,11 +814,9 @@ StHexEscape: } ch = str.at(i); - if (ch >= 'a') - ch -= 'a' - 'A'; - if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F')) { + if (const int h = fromHex(ch); h != -1) { escapeVal <<= 4; - escapeVal += QtMiscUtils::fromHex(ch); + escapeVal += h; ++i; goto StHexEscape; } else { @@ -842,9 +831,9 @@ StOctEscape: } ch = str.at(i); - if (ch >= '0' && ch <= '7') { + if (const int o = fromOct(ch); o != -1) { escapeVal <<= 3; - escapeVal += ch - '0'; + escapeVal += o; ++i; goto StOctEscape; } else { @@ -860,7 +849,7 @@ end: QStringList QSettingsPrivate::splitArgs(const QString &s, qsizetype idx) { - qsizetype l = s.length(); + qsizetype l = s.size(); Q_ASSERT(l > 0); Q_ASSERT(s.at(idx) == u'('); Q_ASSERT(s.at(l - 1) == u')'); @@ -889,16 +878,26 @@ QStringList QSettingsPrivate::splitArgs(const QString &s, qsizetype idx) void QConfFileSettingsPrivate::initFormat() { +#if defined(Q_OS_WASM) + extension = (format == QSettings::NativeFormat || format == QSettings::WebIndexedDBFormat) + ? ".conf"_L1 + : ".ini"_L1; +#else extension = (format == QSettings::NativeFormat) ? ".conf"_L1 : ".ini"_L1; +#endif readFunc = nullptr; writeFunc = nullptr; -#if defined(Q_OS_MAC) +#if defined(Q_OS_DARWIN) caseSensitivity = (format == QSettings::NativeFormat) ? Qt::CaseSensitive : IniCaseSensitivity; #else caseSensitivity = IniCaseSensitivity; #endif +#if defined Q_OS_WASM + if (format > QSettings::IniFormat && format != QSettings::WebIndexedDBFormat) { +#else if (format > QSettings::IniFormat) { +#endif const auto locker = qt_scoped_lock(settingsGlobalMutex); const CustomFormatVector *customFormatVector = customFormatVectorFunc(); @@ -916,7 +915,11 @@ void QConfFileSettingsPrivate::initFormat() void QConfFileSettingsPrivate::initAccess() { if (!confFiles.isEmpty()) { +#if defined Q_OS_WASM + if (format > QSettings::IniFormat && format != QSettings::WebIndexedDBFormat) { +#else if (format > QSettings::IniFormat) { +#endif if (!readFunc) setStatus(QSettings::AccessError); } @@ -954,26 +957,43 @@ static inline int pathHashKey(QSettings::Format format, QSettings::Scope scope) } #ifndef Q_OS_WIN -static QString make_user_path() +static constexpr QChar sep = u'/'; + +#if !defined(QSETTINGS_USE_QSTANDARDPATHS) || defined(Q_OS_ANDROID) +static QString make_user_path_without_qstandard_paths() { - static constexpr QChar sep = u'/'; -#ifndef QSETTINGS_USE_QSTANDARDPATHS - // Non XDG platforms (OS X, iOS, Android...) have used this code path erroneously - // for some time now. Moving away from that would require migrating existing settings. QByteArray env = qgetenv("XDG_CONFIG_HOME"); if (env.isEmpty()) { return QDir::homePath() + "/.config/"_L1; } else if (env.startsWith('/')) { return QFile::decodeName(env) + sep; - } else { - return QDir::homePath() + sep + QFile::decodeName(env) + sep; } + + return QDir::homePath() + sep + QFile::decodeName(env) + sep; +} +#endif // !QSETTINGS_USE_QSTANDARDPATHS || Q_OS_ANDROID + +static QString make_user_path() +{ +#ifndef QSETTINGS_USE_QSTANDARDPATHS + // Non XDG platforms (OS X, iOS, Android...) have used this code path erroneously + // for some time now. Moving away from that would require migrating existing settings. + // The migration has already been done for Android. + return make_user_path_without_qstandard_paths(); #else - // When using a proper XDG platform, use QStandardPaths rather than the above hand-written code; - // it makes the use of test mode from unit tests possible. + +#ifdef Q_OS_ANDROID + // If an old settings path exists, use it instead of creating a new one + QString ret = make_user_path_without_qstandard_paths(); + if (QFile(ret).exists()) + return ret; +#endif // Q_OS_ANDROID + + // When using a proper XDG platform or Android platform, use QStandardPaths rather than the + // above hand-written code. It makes the use of test mode from unit tests possible. // Ideally all platforms should use this, but see above for the migration issue. return QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + sep; -#endif +#endif // !QSETTINGS_USE_QSTANDARDPATHS } #endif // !Q_OS_WIN @@ -1009,7 +1029,7 @@ static std::unique_lock<QBasicMutex> initDefaultPaths(std::unique_lock<QBasicMut const QString userPath = make_user_path(); pathHash->insert(pathHashKey(QSettings::IniFormat, QSettings::UserScope), Path(userPath, false)); pathHash->insert(pathHashKey(QSettings::IniFormat, QSettings::SystemScope), Path(systemPath, false)); -#ifndef Q_OS_MAC +#ifndef Q_OS_DARWIN pathHash->insert(pathHashKey(QSettings::NativeFormat, QSettings::UserScope), Path(userPath, false)); pathHash->insert(pathHashKey(QSettings::NativeFormat, QSettings::SystemScope), Path(systemPath, false)); #endif @@ -1085,16 +1105,16 @@ QConfFileSettingsPrivate::QConfFileSettingsPrivate(QSettings::Format format, QStringList paths; if (!application.isEmpty()) { paths.reserve(dirs.size() * 2); - for (const auto &dir : qAsConst(dirs)) + for (const auto &dir : std::as_const(dirs)) paths.append(dir + u'/' + appFile); } else { paths.reserve(dirs.size()); } - for (const auto &dir : qAsConst(dirs)) + for (const auto &dir : std::as_const(dirs)) paths.append(dir + u'/' + orgFile); // Note: No check for existence of files is done intentionally. - for (const auto &path : qAsConst(paths)) + for (const auto &path : std::as_const(paths)) confFiles.append(QConfFile::fromName(path, false)); } else #endif // Q_XDG_PLATFORM && !QT_NO_STANDARDPATHS @@ -1104,9 +1124,7 @@ QConfFileSettingsPrivate::QConfFileSettingsPrivate(QSettings::Format format, confFiles.append(QConfFile::fromName(systemPath.path + orgFile, false)); } -#ifndef Q_OS_WASM // wasm needs to delay access until after file sync initAccess(); -#endif } QConfFileSettingsPrivate::QConfFileSettingsPrivate(const QString &fileName, @@ -1127,7 +1145,7 @@ QConfFileSettingsPrivate::~QConfFileSettingsPrivate() ConfFileHash *usedHash = usedHashFunc(); ConfFileCache *unusedCache = unusedCacheFunc(); - for (auto conf_file : qAsConst(confFiles)) { + for (auto conf_file : std::as_const(confFiles)) { if (!conf_file->ref.deref()) { if (conf_file->size == 0) { delete conf_file; @@ -1201,7 +1219,7 @@ std::optional<QVariant> QConfFileSettingsPrivate::get(const QString &key) const ParsedSettingsMap::const_iterator j; bool found = false; - for (auto confFile : qAsConst(confFiles)) { + for (auto confFile : std::as_const(confFiles)) { const auto locker = qt_scoped_lock(confFile->mutex); if (!confFile->addedKeys.isEmpty()) { @@ -1230,7 +1248,7 @@ QStringList QConfFileSettingsPrivate::children(const QString &prefix, ChildSpec QSettingsKey thePrefix(prefix, caseSensitivity); qsizetype startPos = prefix.size(); - for (auto confFile : qAsConst(confFiles)) { + for (auto confFile : std::as_const(confFiles)) { const auto locker = qt_scoped_lock(confFile->mutex); if (thePrefix.isEmpty()) @@ -1238,17 +1256,17 @@ QStringList QConfFileSettingsPrivate::children(const QString &prefix, ChildSpec else ensureSectionParsed(confFile, thePrefix); - auto j = const_cast<const ParsedSettingsMap *>( - &confFile->originalKeys)->lowerBound( thePrefix); - while (j != confFile->originalKeys.constEnd() && j.key().startsWith(thePrefix)) { - if (!confFile->removedKeys.contains(j.key())) - processChild(QStringView{j.key().originalCaseKey()}.sliced(startPos), spec, result); - ++j; + const auto &originalKeys = confFile->originalKeys; + auto i = originalKeys.lowerBound(thePrefix); + while (i != originalKeys.end() && i.key().startsWith(thePrefix)) { + if (!confFile->removedKeys.contains(i.key())) + processChild(QStringView{i.key().originalCaseKey()}.sliced(startPos), spec, result); + ++i; } - j = const_cast<const ParsedSettingsMap *>( - &confFile->addedKeys)->lowerBound(thePrefix); - while (j != confFile->addedKeys.constEnd() && j.key().startsWith(thePrefix)) { + const auto &addedKeys = confFile->addedKeys; + auto j = addedKeys.lowerBound(thePrefix); + while (j != addedKeys.end() && j.key().startsWith(thePrefix)) { processChild(QStringView{j.key().originalCaseKey()}.sliced(startPos), spec, result); ++j; } @@ -1281,7 +1299,7 @@ void QConfFileSettingsPrivate::sync() // people probably won't be checking the status a whole lot, so in case of // error we just try to go on and make the best of it - for (auto confFile : qAsConst(confFiles)) { + for (auto confFile : std::as_const(confFiles)) { const auto locker = qt_scoped_lock(confFile->mutex); syncConfFile(confFile); } @@ -1303,7 +1321,11 @@ QString QConfFileSettingsPrivate::fileName() const bool QConfFileSettingsPrivate::isWritable() const { +#if defined(Q_OS_WASM) + if (format > QSettings::IniFormat && format != QSettings::WebIndexedDBFormat && !writeFunc) +#else if (format > QSettings::IniFormat && !writeFunc) +#endif return false; if (confFiles.isEmpty()) @@ -1316,13 +1338,13 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile) { bool readOnly = confFile->addedKeys.isEmpty() && confFile->removedKeys.isEmpty(); + QFileInfo fileInfo(confFile->name); /* We can often optimize the read-only case, if the file on disk hasn't changed. */ if (readOnly && confFile->size > 0) { - QFileInfo fileInfo(confFile->name); - if (confFile->size == fileInfo.size() && confFile->timeStamp == fileInfo.lastModified()) + if (confFile->size == fileInfo.size() && confFile->timeStamp == fileInfo.lastModified(QTimeZone::UTC)) return; } @@ -1338,8 +1360,7 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile) // On android and if it is a content URL put the lock file in a // writable location to prevent permissions issues and invalid paths. if (confFile->name.startsWith("content:"_L1)) - lockFileName = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) - + QFileInfo(lockFileName).fileName(); + lockFileName = make_user_path() + QFileInfo(lockFileName).fileName(); # endif /* Use a lockfile in order to protect us against other QSettings instances @@ -1359,13 +1380,13 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile) We hold the lock. Let's reread the file if it has changed since last time we read it. */ - QFileInfo fileInfo(confFile->name); + fileInfo.refresh(); bool mustReadFile = true; bool createFile = !fileInfo.exists(); if (!readOnly) mustReadFile = (confFile->size != fileInfo.size() - || (confFile->size != 0 && confFile->timeStamp != fileInfo.lastModified())); + || (confFile->size != 0 && confFile->timeStamp != fileInfo.lastModified(QTimeZone::UTC))); if (mustReadFile) { confFile->unparsedIniSections.clear(); @@ -1383,7 +1404,14 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile) */ if (file.isReadable() && file.size() != 0) { bool ok = false; -#ifdef Q_OS_MAC + +#ifdef Q_OS_WASM + if (format == QSettings::WebIndexedDBFormat) { + QByteArray data = file.readAll(); + ok = readIniFile(data, &confFile->unparsedIniSections); + } else +#endif +#ifdef Q_OS_DARWIN if (format == QSettings::NativeFormat) { QByteArray data = file.readAll(); ok = readPlistFile(data, &confFile->originalKeys); @@ -1411,7 +1439,7 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile) } confFile->size = fileInfo.size(); - confFile->timeStamp = fileInfo.lastModified(); + confFile->timeStamp = fileInfo.lastModified(QTimeZone::UTC); } /* @@ -1439,7 +1467,12 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile) return; } -#ifdef Q_OS_MAC +#ifdef Q_OS_WASM + if (format == QSettings::WebIndexedDBFormat) { + ok = writeIniFile(sf, mergedKeys); + } else +#endif +#ifdef Q_OS_DARWIN if (format == QSettings::NativeFormat) { ok = writePlistFile(sf, mergedKeys); } else @@ -1468,9 +1501,9 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile) confFile->addedKeys.clear(); confFile->removedKeys.clear(); - QFileInfo fileInfo(confFile->name); + fileInfo.refresh(); confFile->size = fileInfo.size(); - confFile->timeStamp = fileInfo.lastModified(); + confFile->timeStamp = fileInfo.lastModified(QTimeZone::UTC); // If we have created the file, apply the file perms if (createFile) { @@ -1485,6 +1518,8 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile) } } +namespace SettingsImpl { + enum { Space = 0x1, Special = 0x2 }; static const char charTraits[256] = @@ -1511,11 +1546,16 @@ static const char charTraits[256] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +} // namespace SettingsImpl + +using SettingsImpl::charTraits; + bool QConfFileSettingsPrivate::readIniLine(QByteArrayView data, qsizetype &dataPos, qsizetype &lineStart, qsizetype &lineLen, qsizetype &equalsPos) { - qsizetype dataLen = data.length(); + using namespace SettingsImpl; + qsizetype dataLen = data.size(); bool inQuotes = false; equalsPos = -1; @@ -1607,10 +1647,9 @@ bool QConfFileSettingsPrivate::readIniFile(QByteArrayView data, qsizetype sectionPosition = 0; bool ok = true; - // skip potential utf8 BOM - const uchar *dd = (const uchar *)data.constData(); - if (data.size() >= 3 && dd[0] == 0xef && dd[1] == 0xbb && dd[2] == 0xbf) - dataPos = 3; + // Skip possible UTF-8 BOM: + if (data.startsWith("\xef\xbb\xbf")) + data = data.sliced(3); while (readIniLine(data, dataPos, lineStart, lineLen, equalsPos)) { QByteArrayView line = data.sliced(lineStart, lineLen); @@ -1643,7 +1682,7 @@ bool QConfFileSettingsPrivate::readIniFile(QByteArrayView data, ++position; } - Q_ASSERT(lineStart == data.length()); + Q_ASSERT(lineStart == data.size()); FLUSH_CURRENT_SECTION(); return ok; @@ -1682,27 +1721,22 @@ bool QConfFileSettingsPrivate::readIniSection(const QSettingsKey §ion, QByte QByteArrayView value = line.sliced(equalsPos + 1); QString strKey = section.originalCaseKey(); - bool keyIsLowercase = iniUnescapedKey(key, strKey) && sectionIsLowercase; + const Qt::CaseSensitivity casing = iniUnescapedKey(key, strKey) && sectionIsLowercase + ? Qt::CaseSensitive + : IniCaseSensitivity; QString strValue; strValue.reserve(value.size()); - bool isStringList = iniUnescapedStringList(value, strValue, strListValue); - QVariant variant; - if (isStringList) { - variant = stringListToVariantList(strListValue); - } else { - variant = stringToVariant(strValue); - } + QVariant variant = iniUnescapedStringList(value, strValue, strListValue) + ? stringListToVariantList(strListValue) + : stringToVariant(strValue); /* We try to avoid the expensive toLower() call in QSettingsKey by passing Qt::CaseSensitive when the key is already in lowercase. */ - settingsMap->insert(QSettingsKey(strKey, keyIsLowercase ? Qt::CaseSensitive - : IniCaseSensitivity, - position), - variant); + settingsMap->insert(QSettingsKey(strKey, casing, position), std::move(variant)); ++position; } @@ -2094,10 +2128,6 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile, as QString. The numeric value can be recovered using \l QString::toInt(), \l QString::toDouble() and related functions. - The \l{tools/settingseditor}{Settings Editor} example lets you - experiment with different settings location and with fallbacks - turned on or off. - \section1 Restoring the State of a GUI Application QSettings is often used to store the state of a GUI @@ -2123,9 +2153,6 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile, \codeline \snippet settings/settings.cpp 21 - See the \l{mainwindows/application}{Application} example for a - self-contained example that uses QSettings. - \section1 Accessing Settings from Multiple Threads or Processes Simultaneously QSettings is \l{reentrant}. This means that you can use @@ -2167,8 +2194,8 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile, following files are used by default: \list 1 - \li \c{$HOME/.config/MySoft/Star Runner.conf} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft/Star Runner.conf}) - \li \c{$HOME/.config/MySoft.conf} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft.conf}) + \li \c{$HOME/.config/MySoft/Star Runner.conf} + \li \c{$HOME/.config/MySoft.conf} \li for each directory <dir> in $XDG_CONFIG_DIRS: \c{<dir>/MySoft/Star Runner.conf} \li for each directory <dir> in $XDG_CONFIG_DIRS: \c{<dir>/MySoft.conf} \endlist @@ -2205,8 +2232,8 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile, used on Unix, \macos, and iOS: \list 1 - \li \c{$HOME/.config/MySoft/Star Runner.ini} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft/Star Runner.ini}) - \li \c{$HOME/.config/MySoft.ini} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft.ini}) + \li \c{$HOME/.config/MySoft/Star Runner.ini} + \li \c{$HOME/.config/MySoft.ini} \li for each directory <dir> in $XDG_CONFIG_DIRS: \c{<dir>/MySoft/Star Runner.ini} \li for each directory <dir> in $XDG_CONFIG_DIRS: \c{<dir>/MySoft.ini} \endlist @@ -2341,7 +2368,7 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile, \endlist - \sa QVariant, QSessionManager, {Settings Editor Example}, {Qt Widgets - Application Example} + \sa QVariant, QSessionManager */ /*! \enum QSettings::Status @@ -2379,6 +2406,16 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile, lose the distinction between numeric data and the strings used to encode them, so values written as numbers shall be read back as QString. + \value WebLocalStorageFormat + WASM only: Store the settings in window.localStorage for the current + origin. If cookies are not allowed, this falls back to the INI format. + This provides up to 5MiB storage per origin, but access to it is + synchronous and JSPI is not required. + \value WebIndexedDBFormat + WASM only: Store the settings in an Indexed DB for the current + origin. If cookies are not allowed, this falls back to the INI format. + This requires JSPI, but provides more storage than + WebLocalStorageFormat. \value InvalidFormat Special value returned by registerFormat(). \omitvalue CustomFormat1 @@ -3377,8 +3414,6 @@ QSettings::Format QSettings::defaultFormat() \row \li SystemScope \li \c FOLDERID_ProgramData \row \li{1,2} Unix \li{1,2} NativeFormat, IniFormat \li UserScope \li \c $HOME/.config \row \li SystemScope \li \c /etc/xdg - \row \li{1,2} Qt for Embedded Linux \li{1,2} NativeFormat, IniFormat \li UserScope \li \c $HOME/Settings - \row \li SystemScope \li \c /etc/xdg \row \li{1,2} \macos and iOS \li{1,2} IniFormat \li UserScope \li \c $HOME/.config \row \li SystemScope \li \c /etc/xdg \endtable |