?? qsettings.cpp
字號:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtCore module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <qdebug.h>#include "qplatformdefs.h"#include "qsettings.h"#ifndef QT_NO_SETTINGS#include "qsettings_p.h"#include "qcache.h"#include "qfile.h"#include "qdir.h"#include "qfileinfo.h"#include "qmutex.h"#include "qlibraryinfo.h"#include "qtemporaryfile.h"#ifndef QT_NO_GEOM_VARIANT#include "qsize.h"#include "qpoint.h"#include "qrect.h"#endif // !QT_NO_GEOM_VARIANT#ifndef QT_NO_QOBJECT#include "qcoreapplication.h"#ifdef Q_OS_WIN // for homedirpath reading from registry#include "qt_windows.h"#include "qlibrary.h"#endif // Q_OS_WIN#endif // QT_NO_QOBJECT#include <stdlib.h>#ifndef CSIDL_COMMON_APPDATA#define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data#endif#ifndef CSIDL_APPDATA#define CSIDL_APPDATA 0x001a // <username>\Application Data#endif// ************************************************************************// QConfFile/* QConfFile objects are explicitly shared within the application. This ensures that modification to the settings done through one QSettings object are immediately reflected in other setting objects of the same application.*/struct QConfFileCustomFormat{ QString extension; QSettings::ReadFunc readFunc; QSettings::WriteFunc writeFunc; Qt::CaseSensitivity caseSensitivity;};typedef QHash<QString, QConfFile *> ConfFileHash;typedef QCache<QString, QConfFile> ConfFileCache;typedef QHash<int, QString> PathHash;typedef QVector<QConfFileCustomFormat> CustomFormatVector;Q_GLOBAL_STATIC(ConfFileHash, usedHashFunc)Q_GLOBAL_STATIC(ConfFileCache, unusedCacheFunc)Q_GLOBAL_STATIC(PathHash, pathHashFunc)Q_GLOBAL_STATIC(CustomFormatVector, customFormatVectorFunc)Q_GLOBAL_STATIC(QMutex, globalMutex)#ifndef Q_OS_WINinline bool qt_isEvilFsTypeName(const char *name){ return (qstrncmp(name, "nfs", 3) == 0 || qstrncmp(name, "autofs", 6) == 0 || qstrncmp(name, "cachefs", 7) == 0);}#if defined(Q_OS_BSD4)# include <sys/param.h># include <sys/mount.h>static bool isLikelyToBeNfs(int handle){ struct statfs buf; if (fstatfs(handle, &buf) != 0) return false; return qt_isEvilFsTypeName(buf.f_fstypename);}#elif (defined(Q_OS_LINUX) || defined(Q_OS_HURD)) && !defined(QT_LSB)# include <sys/vfs.h># ifndef NFS_SUPER_MAGIC# define NFS_SUPER_MAGIC 0x00006969# endif# ifndef AUTOFS_SUPER_MAGIC# define AUTOFS_SUPER_MAGIC 0x00000187# endif# ifndef AUTOFSNG_SUPER_MAGIC# define AUTOFSNG_SUPER_MAGIC 0x7d92b1a0# endifstatic bool isLikelyToBeNfs(int handle){ struct statfs buf; if (fstatfs(handle, &buf) != 0) return false; return buf.f_type == NFS_SUPER_MAGIC || buf.f_type == AUTOFS_SUPER_MAGIC || buf.f_type == AUTOFSNG_SUPER_MAGIC;}#elif defined(Q_OS_SOLARIS) || defined(Q_OS_IRIX) || defined(Q_OS_AIX) || defined(Q_OS_HPUX) \ || defined(Q_OS_OSF) || defined(Q_OS_QNX) || defined(Q_OS_QNX6) || defined(Q_OS_SCO) \ || defined(Q_OS_UNIXWARE) || defined(Q_OS_RELIANT)# include <sys/statvfs.h>static bool isLikelyToBeNfs(int handle){ struct statvfs buf; if (fstatvfs(handle, &buf) != 0) return false; return qt_isEvilFsTypeName(buf.f_basetype);}#elsestatic inline bool isLikelyToBeNfs(int /* handle */){ return true;}#endifstatic bool unixLock(int handle, int lockType){ /* NFS hangs on the fcntl() call below when statd or lockd isn't running. There's no way to detect this. Our work-around for now is to disable locking when we detect NFS (or AutoFS or CacheFS, which are probably wrapping NFS). */ if (isLikelyToBeNfs(handle)) return false; struct flock fl; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_type = lockType; return fcntl(handle, F_SETLKW, &fl) == 0;}#endifQConfFile::QConfFile(const QString &fileName, bool _userPerms) : name(fileName), size(0), ref(1), userPerms(_userPerms){ usedHashFunc()->insert(name, this);}ParsedSettingsMap QConfFile::mergedKeyMap() const{ ParsedSettingsMap result = originalKeys; ParsedSettingsMap::const_iterator i; for (i = removedKeys.begin(); i != removedKeys.end(); ++i) result.remove(i.key()); for (i = addedKeys.begin(); i != addedKeys.end(); ++i) result.insert(i.key(), i.value()); return result;}QConfFile *QConfFile::fromName(const QString &fileName, bool _userPerms){ QString absPath = QFileInfo(fileName).absoluteFilePath(); ConfFileHash *usedHash = usedHashFunc(); ConfFileCache *unusedCache = unusedCacheFunc(); QConfFile *confFile; QMutexLocker locker(globalMutex()); if (!(confFile = usedHash->value(absPath))) { if ((confFile = unusedCache->take(absPath))) usedHash->insert(absPath, confFile); } if (confFile) { confFile->ref.ref(); return confFile; } return new QConfFile(absPath, _userPerms);}void QConfFile::clearCache(){ QMutexLocker locker(globalMutex()); unusedCacheFunc()->clear();}// ************************************************************************// QSettingsPrivateQSettingsPrivate::QSettingsPrivate() : spec(0), fallbacks(true), pendingChanges(false), status(QSettings::NoError){}QSettingsPrivate::~QSettingsPrivate(){}QString QSettingsPrivate::actualKey(const QString &key) const{ QString n = normalizedKey(key); Q_ASSERT_X(!n.isEmpty(), "QSettings", "empty key"); n.prepend(groupPrefix); return n;}/* Returns a string that never starts nor ends with a slash (or an empty string). Examples: "foo" becomes "foo" "/foo//bar///" becomes "foo/bar" "///" becomes "" This function is optimized to avoid a QString deep copy in the common case where the key is already normalized.*/QString QSettingsPrivate::normalizedKey(const QString &key){ QString result = key; int i = 0; while (i < result.size()) { while (result.at(i) == QLatin1Char('/')) { result.remove(i, 1); if (i == result.size()) goto after_loop; } while (result.at(i) != QLatin1Char('/')) { ++i; if (i == result.size()) return result; } ++i; // leave the slash alone }after_loop: if (!result.isEmpty()) result.truncate(i - 1); // remove the trailing slash return result;}// see also qsettings_win.cpp and qsettings_mac.cpp#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope, const QString &organization, const QString &application){ return new QConfFileSettingsPrivate(format, scope, organization, application);}#endif#if !defined(Q_OS_WIN)QSettingsPrivate *QSettingsPrivate::create(const QString &fileName, QSettings::Format format){ return new QConfFileSettingsPrivate(fileName, format);}#endifvoid QSettingsPrivate::processChild(QString key, ChildSpec spec, QMap<QString, QString> &result){ if (spec != AllKeys) { int slashPos = key.indexOf(QLatin1Char('/')); if (slashPos == -1) { if (spec != ChildKeys) return; } else { if (spec != ChildGroups) return; key.truncate(slashPos); } } result.insert(key, QString());}void QSettingsPrivate::beginGroupOrArray(const QSettingsGroup &group){ groupStack.push(group); if (!group.name().isEmpty()) { groupPrefix += group.name(); groupPrefix += QLatin1Char('/'); }}/* We only set an error if there isn't one set already. This way the user always gets the first error that occurred. We always allow clearing errors.*/void QSettingsPrivate::setStatus(QSettings::Status status) const{ if (status == QSettings::NoError || this->status == QSettings::NoError) this->status = status;}void QSettingsPrivate::update(){ flush(); pendingChanges = false;}void QSettingsPrivate::requestUpdate(){ if (!pendingChanges) { pendingChanges = true;#ifndef QT_NO_QOBJECT Q_Q(QSettings); QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest));#else update();#endif }}QStringList QSettingsPrivate::variantListToStringList(const QVariantList &l){ QStringList result; QVariantList::const_iterator it = l.constBegin(); for (; it != l.constEnd(); ++it) result.append(variantToString(*it)); return result;}QVariant QSettingsPrivate::stringListToVariantList(const QStringList &l){ QStringList outStringList = l; for (int i = 0; i < outStringList.count(); ++i) { const QString &str = outStringList.at(i); if (str.startsWith(QLatin1Char('@'))) { if (str.length() >= 2 && str.at(1) == QLatin1Char('@')) { outStringList[i].remove(0, 1); } else { QVariantList variantList; for (int j = 0; j < l.count(); ++j) variantList.append(stringToVariant(l.at(j))); return variantList; } } } return outStringList;}QString QSettingsPrivate::variantToString(const QVariant &v){ QString result; switch (v.type()) { case QVariant::Invalid: result = QLatin1String("@Invalid()"); break; case QVariant::ByteArray: { QByteArray a = v.toByteArray(); result = QLatin1String("@ByteArray("); result += QString::fromLatin1(a.constData(), a.size()); result += QLatin1Char(')'); break; } case QVariant::String: case QVariant::LongLong: case QVariant::ULongLong: case QVariant::Int: case QVariant::UInt: case QVariant::Bool: case QVariant::Double: case QVariant::KeySequence: { result = v.toString(); if (result.startsWith(QLatin1Char('@'))) result.prepend(QLatin1Char('@')); break; }#ifndef QT_NO_GEOM_VARIANT case QVariant::Rect: { QRect r = qvariant_cast<QRect>(v); result += QLatin1String("@Rect("); result += QString::number(r.x()); result += QLatin1Char(' '); result += QString::number(r.y()); result += QLatin1Char(' '); result += QString::number(r.width()); result += QLatin1Char(' '); result += QString::number(r.height());
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -