📄 qsettings.cpp
字号:
} // we treat non-existent files as if they existed but were empty return true; }}void QConfFileSettingsPrivate::initFormat(){ extension = (format == QSettings::NativeFormat) ? QLatin1String(".conf") : QLatin1String(".ini"); readFunc = 0; writeFunc = 0;#ifdef Q_OS_MAC caseSensitivity = (format == QSettings::NativeFormat) ? Qt::CaseSensitive : Qt::CaseInsensitive;#else caseSensitivity = Qt::CaseInsensitive;#endif if (format > QSettings::IniFormat) { QMutexLocker locker(globalMutex()); const CustomFormatVector *customFormatVector = customFormatVectorFunc(); int i = (int)format - (int)QSettings::CustomFormat1; if (i >= 0 && i < customFormatVector->size()) { QConfFileCustomFormat info = customFormatVector->at(i); extension = info.extension; readFunc = info.readFunc; writeFunc = info.writeFunc; caseSensitivity = info.caseSensitivity; } }}void QConfFileSettingsPrivate::initAccess(){ bool readAccess = false; if (confFiles[spec]) { readAccess = checkAccess(confFiles[spec]->name); if (format > QSettings::IniFormat) { if (!readFunc) readAccess = false; } } if (!readAccess) setStatus(QSettings::AccessError); sync(); // loads the files the first time}#ifdef Q_OS_WINstatic QString windowsConfigPath(int type){ QString result;#ifndef QT_NO_QOBJECT // We can't use QLibrary if there is QT_NO_QOBJECT is defined // This only happens when bootstrapping qmake. QLibrary library("shell32"); QT_WA( { typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int, BOOL); GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW"); if (SHGetSpecialFolderPath) { TCHAR path[MAX_PATH]; SHGetSpecialFolderPath(0, path, type, FALSE); result = QString::fromUtf16((ushort*)path); } } , { typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, char*, int, BOOL); GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathA"); if (SHGetSpecialFolderPath) { char path[MAX_PATH]; SHGetSpecialFolderPath(0, path, type, FALSE); result = QString::fromLocal8Bit(path); } } );#endif // QT_NO_QOBJECT if (result.isEmpty()) { switch (type) { case CSIDL_COMMON_APPDATA: result = QLatin1String("C:\\temp\\qt-common"); break; case CSIDL_APPDATA: result = QLatin1String("C:\\temp\\qt-user"); break; default: ; } } return result;}#endif // Q_OS_WINstatic inline int pathHashKey(QSettings::Format format, QSettings::Scope scope){ return int((uint(format) << 1) | uint(scope == QSettings::SystemScope));}static QString getPath(QSettings::Format format, QSettings::Scope scope){ Q_ASSERT((int)QSettings::NativeFormat == 0); Q_ASSERT((int)QSettings::IniFormat == 1); QString homePath = QDir::homePath(); QString systemPath; globalMutex()->lock(); PathHash *pathHash = pathHashFunc(); bool loadSystemPath = pathHash->isEmpty(); globalMutex()->unlock(); if (loadSystemPath) { /* QLibraryInfo::location() uses QSettings, so in order to avoid a dead-lock, we can't hold the global mutex while calling it. */ systemPath = QLibraryInfo::location(QLibraryInfo::SettingsPath); systemPath += QLatin1Char('/'); } QMutexLocker locker(globalMutex()); if (pathHash->isEmpty()) { /* Lazy initialization of pathHash. We initialize the IniFormat paths and (on Unix) the NativeFormat paths. (The NativeFormat paths are not configurable for the Windows registry and the Mac CFPreferences.) */#ifdef Q_OS_WIN pathHash->insert(pathHashKey(QSettings::IniFormat, QSettings::UserScope), windowsConfigPath(CSIDL_APPDATA) + QDir::separator()); pathHash->insert(pathHashKey(QSettings::IniFormat, QSettings::SystemScope), windowsConfigPath(CSIDL_COMMON_APPDATA) + QDir::separator());#else QString userPath; char *env = getenv("XDG_CONFIG_HOME"); if (env == 0) { userPath = homePath; userPath += QLatin1Char('/');#ifdef Q_WS_QWS userPath += QLatin1String("Settings");#else userPath += QLatin1String(".config");#endif } else if (*env == '/') { userPath = QLatin1String(env); } else { userPath = homePath; userPath += QLatin1Char('/'); userPath += QLatin1String(env); } userPath += QLatin1Char('/'); pathHash->insert(pathHashKey(QSettings::IniFormat, QSettings::UserScope), userPath); pathHash->insert(pathHashKey(QSettings::IniFormat, QSettings::SystemScope), systemPath);#ifndef Q_OS_MAC pathHash->insert(pathHashKey(QSettings::NativeFormat, QSettings::UserScope), userPath); pathHash->insert(pathHashKey(QSettings::NativeFormat, QSettings::SystemScope), systemPath);#endif#endif } QString result = pathHash->value(pathHashKey(format, scope)); if (!result.isEmpty()) return result; // fall back on INI path return pathHash->value(pathHashKey(QSettings::IniFormat, scope));}QConfFileSettingsPrivate::QConfFileSettingsPrivate(QSettings::Format format, QSettings::Scope scope, const QString &organization, const QString &application){ int i; this->format = format; initFormat(); for (i = 0; i < NumConfFiles; ++i) confFiles[i] = 0; QString org = organization; if (org.isEmpty()) { setStatus(QSettings::AccessError); org = QLatin1String("Unknown Organization"); } QString appFile = org + QDir::separator() + application + extension; QString orgFile = org + extension; if (scope == QSettings::UserScope) { QString userPath = getPath(format, QSettings::UserScope); if (!application.isEmpty()) confFiles[F_User | F_Application] = QConfFile::fromName(userPath + appFile, true); confFiles[F_User | F_Organization] = QConfFile::fromName(userPath + orgFile, true); } QString systemPath = getPath(format, QSettings::SystemScope); if (!application.isEmpty()) confFiles[F_System | F_Application] = QConfFile::fromName(systemPath + appFile, false); confFiles[F_System | F_Organization] = QConfFile::fromName(systemPath + orgFile, false); for (i = 0; i < NumConfFiles; ++i) { if (confFiles[i]) { spec = i; break; } } initAccess();}QConfFileSettingsPrivate::QConfFileSettingsPrivate(const QString &fileName, QSettings::Format format){ this->format = format; initFormat(); confFiles[0] = QConfFile::fromName(fileName, true); for (int i = 1; i < NumConfFiles; ++i) confFiles[i] = 0; initAccess();}QConfFileSettingsPrivate::~QConfFileSettingsPrivate(){ QMutexLocker locker(globalMutex()); ConfFileHash *usedHash = usedHashFunc(); ConfFileCache *unusedCache = unusedCacheFunc(); for (int i = 0; i < NumConfFiles; ++i) { if (confFiles[i] && !confFiles[i]->ref.deref()) { if (usedHash) usedHash->remove(confFiles[i]->name); if (confFiles[i]->size == 0) { delete confFiles[i]; } else if (unusedCache) { unusedCache->insert(confFiles[i]->name, confFiles[i], 10 + (confFiles[i]->originalKeys.size() / 4)); } } }}void QConfFileSettingsPrivate::remove(const QString &key){ QConfFile *confFile = confFiles[spec]; if (!confFile) return; QSettingsKey theKey(key, caseSensitivity); QSettingsKey prefix(key + QLatin1Char('/'), caseSensitivity); QMutexLocker locker(&confFile->mutex); InternalSettingsMap::iterator i = confFile->addedKeys.lowerBound(prefix); while (i != confFile->addedKeys.end() && i.key().startsWith(prefix)) i = confFile->addedKeys.erase(i); confFile->addedKeys.remove(theKey); InternalSettingsMap::const_iterator j = confFile->originalKeys.lowerBound(prefix); while (j != confFile->originalKeys.constEnd() && j.key().startsWith(prefix)) { confFile->removedKeys.insert(j.key(), QVariant()); ++j; } if (confFile->originalKeys.contains(theKey)) confFile->removedKeys.insert(theKey, QVariant());}void QConfFileSettingsPrivate::set(const QString &key, const QVariant &value){ QConfFile *confFile = confFiles[spec]; if (!confFile) return; QSettingsKey theKey(key, caseSensitivity); QMutexLocker locker(&confFile->mutex); confFile->removedKeys.remove(theKey); confFile->addedKeys.insert(theKey, value);}bool QConfFileSettingsPrivate::get(const QString &key, QVariant *value) const{ QSettingsKey theKey(key, caseSensitivity); InternalSettingsMap::const_iterator j; bool found = false; for (int i = 0; i < NumConfFiles; ++i) { if (QConfFile *confFile = confFiles[i]) { QMutexLocker locker(&confFile->mutex); if (!confFile->addedKeys.isEmpty()) { j = confFile->addedKeys.find(theKey); found = (j != confFile->addedKeys.constEnd()); } if (!found) { j = confFile->originalKeys.find(theKey); found = (j != confFile->originalKeys.constEnd() && !confFile->removedKeys.contains(theKey)); } if (found && value) *value = *j; if (found) return true; if (!fallbacks) break; } } return false;}QStringList QConfFileSettingsPrivate::children(const QString &prefix, ChildSpec spec) const{ QMap<QString, QString> result; InternalSettingsMap::const_iterator j; QSettingsKey thePrefix(prefix, caseSensitivity); int startPos = prefix.size(); for (int i = 0; i < NumConfFiles; ++i) { if (QConfFile *confFile = confFiles[i]) { QMutexLocker locker(&confFile->mutex); j = confFile->originalKeys.lowerBound(thePrefix); while (j != confFile->originalKeys.constEnd() && j.key().startsWith(thePrefix)) { if (!confFile->removedKeys.contains(j.key())) processChild(j.key().realKey().mid(startPos), spec, result); ++j; } j = confFile->addedKeys.lowerBound(thePrefix); while (j != confFile->addedKeys.constEnd() && j.key().startsWith(thePrefix)) { processChild(j.key().realKey().mid(startPos), spec, result); ++j; } if (!fallbacks) break; } } return result.keys();}void QConfFileSettingsPrivate::clear(){ QConfFile *confFile = confFiles[spec]; if (!confFile) return; QMutexLocker locker(&confFile->mutex); confFile->addedKeys.clear(); confFile->removedKeys = confFile->originalKeys;}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 (int i = 0; i < NumConfFiles; ++i) { QConfFile *confFile = confFiles[i]; if (confFile) { QMutexLocker locker(&confFile->mutex); syncConfFile(i); } }}void QConfFileSettingsPrivate::flush(){ sync();}QString QConfFileSettingsPrivate::fileName() const{ QConfFile *confFile = confFiles[spec]; if (!confFile) return QString(); return confFile->name;}bool QConfFileSettingsPrivate::isWritable() const{ if (format > QSettings::IniFormat && !writeFunc) return false; QConfFile *confFile = confFiles[spec]; if (!confFile) return false; if (QFile::exists(confFile->name)) { QFile file(confFile->name);; return file.open(QFile::ReadWrite); } else { // we use a temporary file to avoid race conditions QTemporaryFile file(confFile->name); return file.open(); }}void QConfFileSettingsPrivate::syncConfFile(int confFileNo){ QConfFile *confFile = confFiles[confFileNo]; bool readOnly = confFile->addedKeys.isEmpty() && confFile->removedKeys.isEmpty(); bool ok; /* We can often optimize the read-only case, if the file on disk hasn't changed. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -