1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the core module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "qplatformdefs.h"
31
#include "qsettings.h"
33
#ifndef QT_NO_SETTINGS
36
#include "qsettings_p.h"
39
#include "qfileinfo.h"
42
#include "qlibraryinfo.h"
43
#include "qtemporaryfile.h"
46
#include "qcoreapplication.h"
48
#ifdef Q_OS_WIN // for homedirpath reading from registry
49
#include "qt_windows.h"
53
#endif // QT_NO_QOBJECT
57
#ifndef CSIDL_COMMON_APPDATA
58
#define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data
62
#define CSIDL_APPDATA 0x001a // <username>\Application Data
65
// ************************************************************************
69
QConfFile objects are explicitly shared within the application.
70
This ensures that modification to the settings done through one
71
QSettings object are immediately reflected in other setting
72
objects of the same application.
75
typedef QHash<QString, QConfFile *> ConfFileHash;
76
typedef QCache<QString, QConfFile> ConfFileCache;
78
Q_GLOBAL_STATIC(ConfFileHash, usedHashFunc)
79
Q_GLOBAL_STATIC(ConfFileCache, unusedCacheFunc)
80
Q_GLOBAL_STATIC(QMutex, mutex)
81
Q_GLOBAL_STATIC(QString, defaultSystemIniPath)
82
Q_GLOBAL_STATIC(QString, defaultUserIniPath)
84
QConfFile::QConfFile(const QString &fileName)
85
: name(fileName), size(0), ref(1)
87
usedHashFunc()->insert(name, this);
93
bool QConfFile::mergeKeyMaps()
95
if (addedKeys.isEmpty() && removedKeys.isEmpty())
98
SettingsKeyMap::const_iterator i;
100
for (i = removedKeys.begin(); i != removedKeys.end(); ++i)
101
originalKeys.remove(i.key());
104
for (i = addedKeys.begin(); i != addedKeys.end(); ++i)
105
originalKeys.insert(i.key(), i.value());
111
QConfFile *QConfFile::fromName(const QString &fileName)
114
QString absPath = QFileInfo(fileName).absoluteFilePath();
116
ConfFileHash *usedHash = usedHashFunc();
117
ConfFileCache *unusedCache = unusedCacheFunc();
119
QMutexLocker locker(mutex());
121
if (!(confFile = usedHash->value(absPath))) {
122
if ((confFile = unusedCache->take(absPath)))
123
usedHash->insert(absPath, confFile);
129
return new QConfFile(absPath);
132
void QConfFile::clearCache()
134
QMutexLocker locker(mutex());
135
unusedCacheFunc()->clear();
138
// ************************************************************************
141
QSettingsPrivate::QSettingsPrivate()
142
: spec(0), fallbacks(true), pendingChanges(false), status(QSettings::NoError)
146
QSettingsPrivate::~QSettingsPrivate()
150
QString QSettingsPrivate::actualKey(const QString &key) const
152
QString n = normalizedKey(key);
153
Q_ASSERT_X(!n.isEmpty(), "QSettings", "empty key");
154
n.prepend(groupPrefix);
159
Returns a string that never starts nor ends with a slash (or an
160
empty string). Examples:
163
"/foo//bar///" becomes "foo/bar"
166
This function is optimized to avoid a QString deep copy in the
167
common case where the key is already normalized.
169
QString QSettingsPrivate::normalizedKey(const QString &key)
171
QString result = key;
174
while (i < result.size()) {
175
while (result.at(i) == QLatin1Char('/')) {
177
if (i == result.size())
180
while (result.at(i) != QLatin1Char('/')) {
182
if (i == result.size())
185
++i; // leave the slash alone
189
if (!result.isEmpty())
190
result.truncate(i - 1); // remove the trailing slash
194
// see also qsettings_win.cpp and qsettings_mac.cpp
196
#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
197
QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format,
198
QSettings::Scope scope,
199
const QString &organization,
200
const QString &application)
202
QConfFileSettingsPrivate *p = new QConfFileSettingsPrivate(format, scope,
203
organization, application);
209
#if !defined(Q_OS_WIN)
210
QSettingsPrivate *QSettingsPrivate::create(const QString &fileName, QSettings::Format format)
212
QConfFileSettingsPrivate *p = new QConfFileSettingsPrivate(fileName, format);
218
void QSettingsPrivate::processChild(QString key, ChildSpec spec, QMap<QString, QString> &result)
220
if (spec != AllKeys) {
221
int slashPos = key.indexOf(QLatin1Char('/'));
222
if (slashPos == -1) {
223
if (spec != ChildKeys)
226
if (spec != ChildGroups)
228
key.truncate(slashPos);
231
result.insert(key, QString());
234
void QSettingsPrivate::beginGroupOrArray(const QSettingsGroup &group)
236
groupStack.push(group);
237
if (!group.name().isEmpty()) {
238
groupPrefix += group.name();
239
groupPrefix += QLatin1Char('/');
244
We only set an error if there isn't one set already. This way the user always gets the
245
first error that occurred. We always allow clearing errors.
248
void QSettingsPrivate::setStatus(QSettings::Status status)
250
if (status == QSettings::NoError || this->status == QSettings::NoError)
251
this->status = status;
254
void QSettingsPrivate::update()
257
pendingChanges = false;
260
void QSettingsPrivate::requestUpdate()
262
if (!pendingChanges) {
263
pendingChanges = true;
264
#ifndef QT_NO_QOBJECT
266
QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest));
273
QStringList QSettingsPrivate::variantListToStringList(const QVariantList &l) const
276
QVariantList::const_iterator it = l.constBegin();
277
for (; it != l.constEnd(); ++it)
278
result.append(variantToString(*it));
282
QVariant QSettingsPrivate::stringListToVariantList(const QStringList &l) const
284
QVariantList variantList;
285
bool foundNonStringItem = false;
286
bool foundEscapedStringItem = false;
288
QStringList::const_iterator it = l.constBegin();
289
for (; it != l.constEnd(); ++it) {
290
QVariant variant = stringToVariant(*it);
291
variantList.append(variant);
293
if (variant.type() != QVariant::String)
294
foundNonStringItem = true;
295
else if (variant.toString() != *it)
296
foundEscapedStringItem = true;
299
if (foundNonStringItem) {
301
} else if (foundEscapedStringItem) {
302
return QVariant(variantList).toStringList();
307
QString &QSettingsPrivate::escapedLeadingAt(QString &s)
309
if (s.length() > 0 && s.at(0) == QLatin1Char('@'))
310
s.prepend(QLatin1Char('@'));
314
QString &QSettingsPrivate::unescapedLeadingAt(QString &s)
316
if (s.startsWith(QLatin1String("@@")))
321
QString QSettingsPrivate::variantToString(const QVariant &v)
326
case QVariant::Invalid:
327
result = QLatin1String("@Invalid()");
330
case QVariant::ByteArray: {
331
QByteArray a = v.toByteArray();
332
result = QLatin1String("@ByteArray(");
333
result += QString::fromLatin1(a.constData(), a.size());
334
result += QLatin1Char(')');
338
case QVariant::String:
339
case QVariant::LongLong:
340
case QVariant::ULongLong:
344
case QVariant::Double: {
345
result = v.toString();
346
result = escapedLeadingAt(result);
349
case QVariant::Rect: {
350
QRect r = qvariant_cast<QRect>(v);
351
result += QLatin1String("@Rect(");
352
result += QString::number(r.x());
353
result += QLatin1Char(' ');
354
result += QString::number(r.y());
355
result += QLatin1Char(' ');
356
result += QString::number(r.width());
357
result += QLatin1Char(' ');
358
result += QString::number(r.height());
359
result += QLatin1Char(')');
362
case QVariant::Size: {
363
QSize s = qvariant_cast<QSize>(v);
364
result += QLatin1String("@Size(");
365
result += QString::number(s.width());
366
result += QLatin1Char(' ');
367
result += QString::number(s.height());
368
result += QLatin1Char(')');
371
case QVariant::Point: {
372
QPoint p = qvariant_cast<QPoint>(v);
373
result += QLatin1String("@Point(");
374
result += QString::number(p.x());
375
result += QLatin1Char(' ');
376
result += QString::number(p.y());
377
result += QLatin1Char(')');
382
#ifndef QT_NO_DATASTREAM
385
QDataStream s(&a, QIODevice::WriteOnly);
389
result = QLatin1String("@Variant(");
390
result += QString::fromLatin1(a.constData(), a.size());
391
result += QLatin1Char(')');
393
Q_ASSERT("QSettings: Cannot save custom types without QDataStream support");
402
QVariant QSettingsPrivate::stringToVariant(const QString &s)
405
&& s.at(0) == QLatin1Char('@')
406
&& s.at(s.length() - 1) == QLatin1Char(')')) {
408
if (s.startsWith(QLatin1String("@ByteArray("))) {
409
return QVariant(s.toLatin1().mid(11, s.size() - 12));
410
} else if (s.startsWith(QLatin1String("@Variant("))) {
411
#ifndef QT_NO_DATASTREAM
412
QByteArray a(s.toLatin1().mid(9));
413
QDataStream stream(&a, QIODevice::ReadOnly);
418
Q_ASSERT("QSettings: Cannot load custom types without QDataStream support");
420
#ifndef QT_NO_GEOM_VARIANT
421
} else if (s.startsWith(QLatin1String("@Rect("))) {
422
QStringList args = QSettingsPrivate::splitArgs(s, 5);
423
if (args.size() == 4) {
424
return QVariant(QRect(args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt()));
426
} else if (s.startsWith(QLatin1String("@Size("))) {
427
QStringList args = QSettingsPrivate::splitArgs(s, 5);
428
if (args.size() == 2) {
429
return QVariant(QSize(args[0].toInt(), args[1].toInt()));
431
} else if (s.startsWith(QLatin1String("@Point("))) {
432
QStringList args = QSettingsPrivate::splitArgs(s, 6);
433
if (args.size() == 2) {
434
return QVariant(QPoint(args[0].toInt(), args[1].toInt()));
437
} else if (s == QLatin1String("@Invalid()")) {
443
return QVariant(unescapedLeadingAt(tmp));
446
static const char hexDigits[] = "0123456789ABCDEF";
448
void QSettingsPrivate::iniEscapedKey(const QString &key, QByteArray &result)
450
for (int i = 0; i < key.size(); ++i) {
451
uint ch = key.at(i).unicode();
455
} else if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9'
456
|| ch == '_' || ch == '-' || ch == '.') {
458
} else if (ch <= 0xFF) {
460
result += hexDigits[ch / 16];
461
result += hexDigits[ch % 16];
465
for (int i = 0; i < 4; ++i) {
466
hexCode.prepend(hexDigits[ch % 16]);
474
bool QSettingsPrivate::iniUnescapedKey(const QByteArray &key, int from, int to, QString &result)
476
bool lowerCaseOnly = true;
479
int ch = (uchar)key.at(i);
482
result += QLatin1Char('/');
487
if (ch != '%' || i == to - 1) {
488
if (isupper((uchar)ch))
489
lowerCaseOnly = false;
490
result += QLatin1Char(ch);
496
int firstDigitPos = i + 1;
504
if (firstDigitPos + numDigits > to) {
505
result += QLatin1Char('%');
511
ch = key.mid(firstDigitPos, numDigits).toInt(&ok, 16);
513
result += QLatin1Char('%');
519
if (qch.toLower() != qch)
520
lowerCaseOnly = false;
522
i = firstDigitPos + numDigits;
524
return lowerCaseOnly;
527
void QSettingsPrivate::iniEscapedString(const QString &str, QByteArray &result)
529
bool needsQuotes = false;
530
bool escapeNextIfDigit = false;
532
int startPos = result.size();
534
for (i = 0; i < str.size(); ++i) {
535
uint ch = str.at(i).unicode();
536
if (ch == ';' || ch == ',' || ch == '=')
539
if (escapeNextIfDigit
540
&& ((ch >= '0' && ch <= '9')
541
|| (ch >= 'a' && ch <= 'f')
542
|| (ch >= 'A' && ch <= 'F'))) {
544
result += QByteArray::number(ch, 16);
548
escapeNextIfDigit = false;
553
escapeNextIfDigit = true;
582
if (ch <= 0x1F || ch >= 0x7F) {
584
result += QByteArray::number(ch, 16);
585
escapeNextIfDigit = true;
593
|| (startPos < result.size() && (result.at(startPos) == ' '
594
|| result.at(result.size() - 1) == ' '))) {
595
result.insert(startPos, '"');
600
void QSettingsPrivate::iniChopTrailingSpaces(QString *str)
604
&& (str->at(n - 1) == QLatin1Char(' ') || str->at(n - 1) == QLatin1Char('\t')))
608
void QSettingsPrivate::iniEscapedStringList(const QStringList &strs, QByteArray &result)
610
for (int i = 0; i < strs.size(); ++i) {
613
iniEscapedString(strs.at(i), result);
617
QStringList *QSettingsPrivate::iniUnescapedStringList(const QByteArray &str, int from, int to,
620
static const char escapeCodes[][2] =
634
static const int numEscapeCodes = sizeof(escapeCodes) / sizeof(escapeCodes[0]);
636
QStringList *strList = 0;
639
enum State { StNormal, StSkipSpaces, StEscape, StHexEscapeFirstChar, StHexEscape,
641
State state = StSkipSpaces;
643
bool inQuotedString = false;
644
bool currentValueIsQuoted = false;
656
currentValueIsQuoted = true;
657
inQuotedString = !inQuotedString;
659
state = StSkipSpaces;
662
if (!inQuotedString) {
663
if (!currentValueIsQuoted)
664
iniChopTrailingSpaces(&result);
666
strList = new QStringList;
667
strList->append(result);
669
currentValueIsQuoted = false;
670
state = StSkipSpaces;
675
result += QLatin1Char(ch);
680
if (ch == ' ' || ch == '\t')
686
for (int j = 0; j < numEscapeCodes; ++j) {
687
if (ch == escapeCodes[j][0]) {
688
result += QLatin1Char(escapeCodes[j][1]);
697
state = StHexEscapeFirstChar;
698
} else if (ch >= '0' && ch <= '7') {
699
escapeVal = ch - '0';
706
case StHexEscapeFirstChar:
707
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F')
708
|| (ch >= 'a' && ch <= 'f'))
716
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F')) {
718
escapeVal += strchr(hexDigits, ch) - hexDigits;
721
result += QChar(escapeVal);
726
if (ch >= '0' && ch <= '7') {
728
escapeVal += ch - '0';
731
result += QChar(escapeVal);
739
if (state == StHexEscape || state == StOctEscape)
740
result += QChar(escapeVal);
741
if (!currentValueIsQuoted)
742
iniChopTrailingSpaces(&result);
744
strList->append(result);
748
QStringList QSettingsPrivate::splitArgs(const QString &s, int idx)
752
Q_ASSERT(s.at(idx) == QLatin1Char('('));
753
Q_ASSERT(s.at(l - 1) == QLatin1Char(')'));
758
for (++idx; idx < l; ++idx) {
760
if (c == QLatin1Char(')')) {
761
Q_ASSERT(idx == l - 1);
763
} else if (c == QLatin1Char(' ')) {
774
// ************************************************************************
775
// QConfFileSettingsPrivate
777
static void checkAccess(const QString &name, bool *read, bool *write)
779
QFileInfo fileInfo(name);
781
if (fileInfo.exists()) {
783
The best way to check that an existing file is
784
writable is to open it for writing.
787
*read = file.open(QIODevice::ReadOnly);
790
*write = file.open(QIODevice::Append);
792
// files that don't exist are considered readable
796
if (QDir::isRelativePath(name))
797
dir = QDir::current();
802
Create the directories to the file.
804
QStringList pathElements = name.split(QLatin1Char('/'), QString::SkipEmptyParts);
805
for (int i = 0; i < pathElements.size() - 1; ++i) {
806
QString elt = pathElements[i];
810
if (!dir.mkdir(elt) || !dir.cd(elt))
815
The best way to check if we can create the file is to
816
try to create a temporary file.
818
QTemporaryFile file(name + QLatin1String(".XXXXXX"));
819
*write = file.open();
823
void QConfFileSettingsPrivate::init()
825
if (confFiles[spec] == 0) {
829
checkAccess(confFiles[spec]->name, &readAccess, &writeAccess);
832
setStatus(QSettings::AccessError);
835
cs = (format == QSettings::NativeFormat) ? Qt::CaseSensitive : Qt::CaseInsensitive;
837
cs = Qt::CaseInsensitive;
839
sync(); // loads the files the first time
843
static QString windowsConfigPath(int type)
847
#ifndef QT_NO_QOBJECT
848
// We can't use QLibrary if there is QT_NO_QOBJECT is defined
849
// This only happens when bootstrapping qmake.
850
QLibrary library("shell32");
852
typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int, BOOL);
853
GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
854
if (SHGetSpecialFolderPath) {
855
TCHAR path[MAX_PATH];
856
SHGetSpecialFolderPath(0, path, type, FALSE);
857
result = QString::fromUtf16((ushort*)path);
860
typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, char*, int, BOOL);
861
GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathA");
862
if (SHGetSpecialFolderPath) {
864
SHGetSpecialFolderPath(0, path, type, FALSE);
865
result = QString::fromLocal8Bit(path);
868
#endif // QT_NO_QOBJECT
870
if (result.isEmpty()) {
872
case CSIDL_COMMON_APPDATA:
873
result = QLatin1String("C:\\temp\\qt-common");
876
result = QLatin1String("C:\\temp\\qt-user");
887
static QString systemIniPath()
891
result = *defaultSystemIniPath();
892
if (result.isEmpty()) {
894
result = windowsConfigPath(CSIDL_COMMON_APPDATA);
896
result = QLibraryInfo::location(QLibraryInfo::SettingsPath);
900
return result + QDir::separator();
903
static QString userIniPath()
907
result = *defaultUserIniPath();
908
if (result.isEmpty()) {
910
result = windowsConfigPath(CSIDL_APPDATA);
912
char *env = getenv("XDG_CONFIG_HOME");
914
result = QDir::homePath() + QDir::separator() + QLatin1String(".config");
915
else if (*env == '/')
916
result = QLatin1String(env);
918
result = QDir::homePath() + QDir::separator() + QLatin1String(env);
922
return result + QDir::separator();
925
QConfFileSettingsPrivate::QConfFileSettingsPrivate(QSettings::Format format,
926
QSettings::Scope scope,
927
const QString &organization,
928
const QString &application)
931
this->format = format;
932
for (i = 0; i < NumConfFiles; ++i)
935
QString org = organization;
937
setStatus(QSettings::AccessError);
938
org = QLatin1String("Unknown Organization");
941
const char *extension = format == QSettings::IniFormat ? ".ini" : ".conf";
943
QString appFile = org + QDir::separator() + application + QLatin1String(extension);
944
QString orgFile = org + QLatin1String(extension);
946
if (scope == QSettings::UserScope) {
947
if (!application.isEmpty())
948
confFiles[F_User | F_Application] = QConfFile::fromName(userIniPath() + appFile);
949
confFiles[F_User | F_Organization] = QConfFile::fromName(userIniPath() + orgFile);
951
if (!application.isEmpty())
952
confFiles[F_Global | F_Application] = QConfFile::fromName(systemIniPath() + appFile);
953
confFiles[F_Global | F_Organization] = QConfFile::fromName(systemIniPath() + orgFile);
955
for (i = 0; i < NumConfFiles; ++i) {
963
QConfFileSettingsPrivate::QConfFileSettingsPrivate(const QString &fileName,
964
QSettings::Format format)
966
confFiles[0] = QConfFile::fromName(fileName);
967
for (int i = 1; i < NumConfFiles; ++i)
969
this->format = format;
972
QConfFileSettingsPrivate::~QConfFileSettingsPrivate()
974
QMutexLocker locker(mutex());
975
ConfFileHash *usedHash = usedHashFunc();
976
ConfFileCache *unusedCache = unusedCacheFunc();
978
for (int i = 0; i < NumConfFiles; ++i) {
979
if (confFiles[i] && !confFiles[i]->ref.deref()) {
981
usedHash->remove(confFiles[i]->name);
983
if (confFiles[i]->size == 0) {
985
} else if (unusedCache) {
986
unusedCache->insert(confFiles[i]->name, confFiles[i],
987
10 + (confFiles[i]->originalKeys.size() / 4));
993
void QConfFileSettingsPrivate::remove(const QString &key)
996
setStatus(QSettings::AccessError);
1000
QSettingsKey theKey(key, cs);
1001
QSettingsKey prefix(key + QLatin1Char('/'), cs);
1003
QConfFile *confFile = confFiles[spec];
1004
QMutexLocker locker(mutex());
1006
SettingsKeyMap::iterator i = confFile->addedKeys.lowerBound(prefix);
1007
while (i != confFile->addedKeys.end() && i.key().startsWith(prefix))
1008
i = confFile->addedKeys.erase(i);
1009
confFile->addedKeys.remove(theKey);
1011
SettingsKeyMap::const_iterator j = confFile->originalKeys.lowerBound(prefix);
1012
while (j != confFile->originalKeys.constEnd() && j.key().startsWith(prefix)) {
1013
confFile->removedKeys.insert(j.key(), QVariant());
1016
if (confFile->originalKeys.contains(theKey))
1017
confFile->removedKeys.insert(theKey, QVariant());
1020
void QConfFileSettingsPrivate::set(const QString &key, const QVariant &value)
1023
setStatus(QSettings::AccessError);
1027
QSettingsKey theKey(key, cs);
1029
QConfFile *confFile = confFiles[spec];
1030
QMutexLocker locker(mutex());
1031
confFile->removedKeys.remove(theKey);
1032
confFile->addedKeys.insert(theKey, value);
1035
bool QConfFileSettingsPrivate::get(const QString &key, QVariant *value) const
1037
QSettingsKey theKey(key, cs);
1038
SettingsKeyMap::const_iterator j;
1041
QMutexLocker locker(mutex());
1043
for (int i = 0; i < NumConfFiles; ++i) {
1044
if (QConfFile *confFile = confFiles[i]) {
1045
if (!confFile->addedKeys.isEmpty()) {
1046
j = confFile->addedKeys.find(theKey);
1047
found = (j != confFile->addedKeys.constEnd());
1050
j = confFile->originalKeys.find(theKey);
1051
found = (j != confFile->originalKeys.constEnd()
1052
&& !confFile->removedKeys.contains(theKey));
1067
QStringList QConfFileSettingsPrivate::children(const QString &prefix, ChildSpec spec) const
1069
QMap<QString, QString> result;
1070
SettingsKeyMap::const_iterator j;
1072
QSettingsKey thePrefix(prefix, cs);
1073
int startPos = prefix.size();
1075
QMutexLocker locker(mutex());
1077
for (int i = 0; i < NumConfFiles; ++i) {
1078
if (QConfFile *confFile = confFiles[i]) {
1079
j = confFile->originalKeys.lowerBound(thePrefix);
1080
while (j != confFile->originalKeys.constEnd() && j.key().startsWith(thePrefix)) {
1081
if (!confFile->removedKeys.contains(j.key()))
1082
processChild(j.key().realKey().mid(startPos), spec, result);
1086
j = confFile->addedKeys.lowerBound(thePrefix);
1087
while (j != confFile->addedKeys.constEnd() && j.key().startsWith(thePrefix)) {
1088
processChild(j.key().realKey().mid(startPos), spec, result);
1096
return result.keys();
1099
void QConfFileSettingsPrivate::clear()
1102
setStatus(QSettings::AccessError);
1106
QConfFile *confFile = confFiles[spec];
1107
QMutexLocker locker(mutex());
1108
confFile->addedKeys.clear();
1109
confFile->removedKeys = confFiles[spec]->originalKeys;
1112
void QConfFileSettingsPrivate::sync()
1114
QMutexLocker locker(mutex());
1116
// people probably won't be checking the status a whole lot, so in case of
1117
// error we just try to go on and make the best of it
1119
for (int i = 0; i < NumConfFiles; ++i) {
1120
QConfFile *confFile = confFiles[i];
1122
if (!readFile(confFile)) {
1123
// Only problems with the file we actually write to change the status. The
1124
// other files are just optional fallbacks.
1126
setStatus(QSettings::FormatError);
1128
if (i == spec && confFile->mergeKeyMaps()) {
1129
if (!writeFile(confFile))
1130
setStatus(QSettings::AccessError);
1136
void QConfFileSettingsPrivate::flush()
1141
QString QConfFileSettingsPrivate::fileName() const
1143
QConfFile *confFile = confFiles[spec];
1146
return confFile->name;
1149
bool QConfFileSettingsPrivate::isWritable() const
1155
The following openFile() and closeFile() functions lock the file
1156
(using fcntl() on Unix and a global mutex on Windows), ensuring
1157
that if two instances of the same applications access the file at
1158
the same time, the file isn't corrupted.
1162
const int ReadFlags = O_RDONLY | O_CREAT;
1163
const int WriteFlags = O_WRONLY | O_CREAT | O_APPEND;
1165
static const int FileLockSemMax = 50;
1166
static const int ReadFlags = 1;
1167
static const int WriteFlags = 2;
1168
const char SemNamePrefix[] = "QSettings semaphore ";
1171
static bool openFile(QFile &file, QConfFile &confFile, int flags)
1175
int fd = QT_OPEN(QFile::encodeName(file.fileName()), flags, S_IRUSR | S_IWUSR);
1180
fl.l_whence = SEEK_SET;
1183
fl.l_type = (flags == WriteFlags) ? F_WRLCK : F_RDLCK;
1184
fcntl(fd, F_SETLKW, &fl);
1186
if (flags == WriteFlags)
1187
QT_FTRUNCATE(fd, 0);
1189
return file.open(fd, flags == WriteFlags ? QIODevice::WriteOnly | QIODevice::Text
1190
: QIODevice::OpenMode(QIODevice::ReadOnly));
1192
// on Windows we use a named semaphore
1193
if (confFile.semHandle == 0) {
1194
QString semName = QString::fromAscii(SemNamePrefix);
1195
semName.append(file.fileName());
1197
confFile.semHandle = CreateSemaphoreW(0, FileLockSemMax, FileLockSemMax, reinterpret_cast<const wchar_t *>(semName.utf16()));
1199
confFile.semHandle = CreateSemaphoreA(0, FileLockSemMax, FileLockSemMax, semName.toLocal8Bit());
1203
if (confFile.semHandle != 0) {
1205
if (flags == ReadFlags)
1208
decrement = FileLockSemMax;
1210
for (int i = 0; i < decrement; ++i)
1211
WaitForSingleObject(confFile.semHandle, INFINITE);
1214
return file.open(flags == WriteFlags ? QIODevice::WriteOnly | QIODevice::Text
1215
: QIODevice::OpenMode(QIODevice::ReadOnly));
1219
static void closeFile(QFile &file, QConfFile &confFile)
1223
int fd = file.handle();
1228
if (file.openMode() & QIODevice::ReadOnly)
1231
increment = FileLockSemMax;
1233
ReleaseSemaphore(confFile.semHandle, increment, 0);
1234
CloseHandle(confFile.semHandle);
1235
confFile.semHandle = 0;
1242
This only returns false on format errors. Files which don't exist, or which
1243
we don't have read permission for, are treated as empty sets of keys.
1245
bool QConfFileSettingsPrivate::readFile(QConfFile *confFile)
1247
QFileInfo fileInfo(confFile->name);
1248
int actualSize = fileInfo.size();
1249
QDateTime actualTimeStamp = fileInfo.lastModified();
1251
if (confFile->size == actualSize) {
1252
// no need to reload the file if the timestamps and file sizes match
1253
if (confFile->timeStamp == actualTimeStamp)
1257
SettingsKeyMap newKeys;
1259
bool ok = true; // we treat unexisting/unreadable files the same as empty files
1261
if (actualSize != 0) {
1263
if (format == QSettings::NativeFormat) {
1264
ok = readPlistFile(confFile->name, &newKeys);
1268
QFile file(confFile->name);
1269
if (openFile(file, *confFile, ReadFlags)) {
1270
ok = readIniFile(file, &newKeys);
1271
closeFile(file, *confFile);
1276
confFile->originalKeys = newKeys;
1277
confFile->size = actualSize;
1278
confFile->timeStamp = actualTimeStamp;
1283
bool QConfFileSettingsPrivate::writeFile(QConfFile *confFile)
1288
if (format == QSettings::NativeFormat) {
1289
ok = writePlistFile(confFile->name, confFile->originalKeys);
1293
QFile file(confFile->name);
1294
if (openFile(file, *confFile, WriteFlags)) {
1295
ok = writeIniFile(file, confFile->originalKeys);
1296
closeFile(file, *confFile);
1302
QFileInfo fileInfo(confFile->name);
1303
confFile->size = fileInfo.size();
1304
confFile->timeStamp = fileInfo.lastModified();
1309
bool QConfFileSettingsPrivate::readIniLine(QIODevice &device, QByteArray &line, int &len,
1312
#define MAYBE_GROW() \
1313
if (pos + 4 > line.size()) { \
1314
line.resize(pos << 1); \
1315
data = line.data(); \
1318
char *data = line.data();
1324
while (device.getChar(&ch)) {
1331
while (!device.getChar(&ch) || ch != '"') {
1334
if (static_cast<signed char>(ch) == -1)
1339
if (!device.getChar(&ch))
1355
According to the specs, a line ends with CF, LF,
1356
CR+LF, or LF+CR. In practice, this is irrelevant and
1357
the ungetch() call is expensive, so let's not do it.
1360
if (!device.getChar(&ch2))
1362
if ((ch2 != '\n' && ch2 != '\r') || ch == ch2)
1363
device.ungetChar(ch2);
1369
if (!device.getChar(&ch))
1372
if (ch == '\n' || ch == '\r') {
1373
if (!device.getChar(&ch2)) {
1374
if ((ch2 != '\n' && ch2 != '\r') || ch == ch2) {
1385
while (device.getChar(&ch)) {
1386
if (ch == '\n' || ch == '\r')
1387
goto process_newline;
1391
if (equalsCharPos == -1) {
1392
while (pos > 0 && (ch = data[pos - 1]) == ' ' || ch == '\t')
1394
equalsCharPos = pos;
1410
Returns false on parse error. However, as many keys are read as
1411
possible, so if the user doesn't check the status he will get the
1412
most out of the file anyway.
1414
bool QConfFileSettingsPrivate::readIniFile(QIODevice &device, SettingsKeyMap *map)
1416
QString currentSection;
1417
bool currentSectionIsLowerCase = true;
1425
while (readIniLine(device, line, len, equalsCharPos)) {
1426
if (line.at(0) == '[') {
1427
// this is a section
1428
QByteArray iniSection;
1429
int idx = line.indexOf(']');
1432
iniSection = line.mid(1);
1434
iniSection = line.mid(1, idx - 1);
1437
iniSection = iniSection.trimmed();
1439
if (qstricmp(iniSection, "general") == 0) {
1440
currentSection.clear();
1441
} else if (qstricmp(iniSection, "%general") == 0) {
1442
currentSection = QLatin1String("general");
1443
currentSection += QLatin1Char('/');
1445
currentSection.clear();
1446
currentSectionIsLowerCase = iniUnescapedKey(iniSection, 0, iniSection.size(),
1448
currentSection += QLatin1Char('/');
1451
if (equalsCharPos < 1) {
1456
QString key = currentSection;
1457
bool keyIsLowerCase = (iniUnescapedKey(line, 0, equalsCharPos, key)
1458
&& currentSectionIsLowerCase);
1461
strValue.reserve(len - equalsCharPos);
1462
QStringList *strListValue = iniUnescapedStringList(line, equalsCharPos + 1, len,
1466
variant = stringListToVariantList(*strListValue);
1467
delete strListValue;
1469
variant = stringToVariant(strValue);
1473
We try to avoid the expensive toLower() call in
1474
QSettingsKey by passing Qt::CaseSensitive when the
1475
key is already in lower-case.
1477
map->insert(QSettingsKey(key, keyIsLowerCase ? Qt::CaseSensitive : Qt::CaseInsensitive),
1485
bool QConfFileSettingsPrivate::writeIniFile(QIODevice &device, const SettingsKeyMap &map)
1487
typedef QMap<QString, QVariantMap> IniMap;
1489
IniMap::const_iterator i;
1491
for (SettingsKeyMap::const_iterator j = map.constBegin(); j != map.constEnd(); ++j) {
1493
QString key = j.key().realKey();
1496
if ((slashPos = key.indexOf(QLatin1Char('/'))) != -1) {
1497
section = key.left(slashPos);
1498
key.remove(0, slashPos + 1);
1500
iniMap[section][key] = j.value();
1503
bool writeError = false;
1504
for (i = iniMap.constBegin(); !writeError && i != iniMap.constEnd(); ++i) {
1505
QByteArray realSection;
1507
iniEscapedKey(i.key(), realSection);
1509
if (realSection.isEmpty()) {
1510
realSection = "[General]";
1511
} else if (qstricmp(realSection, "general") == 0) {
1512
realSection = "[%General]";
1514
realSection.prepend('[');
1515
realSection.append(']');
1518
if (i != iniMap.constBegin())
1519
realSection.prepend('\n');
1520
realSection += '\n';
1522
device.write(realSection);
1524
const QVariantMap &ents = i.value();
1525
for (QVariantMap::const_iterator j = ents.constBegin(); j != ents.constEnd(); ++j) {
1527
iniEscapedKey(j.key(), block);
1530
const QVariant &value = j.value();
1531
if (value.type() == QVariant::StringList || value.type() == QVariant::List) {
1532
iniEscapedStringList(variantListToStringList(value.toList()), block);
1534
iniEscapedString(variantToString(value), block);
1537
if (device.write(block) == -1) {
1548
\brief The QSettings class provides persistent platform-independent application settings.
1555
Users normally expect an application to remember its settings
1556
(window sizes and positions, options, etc.) across sessions. This
1557
information is often stored in the system registry on Windows,
1558
and in XML preferences files on Mac OS X. On X11 and embedded Linux,
1559
in the absense of a standard, many applications (including the KDE
1560
applications) use INI text files.
1562
QSettings is an abstraction around these technologies,
1563
enabling you to save and restore application settings in a
1566
QSettings's API is based on QVariant, allowing you to save
1567
most value-based types, such as QString, QRect, and QImage,
1568
with the minimum of effort.
1570
\tableofcontents section1
1572
\section1 Basic Usage
1574
When creating a QSettings object, you must pass the name of your
1575
company or organization as well as the name of your application.
1576
For example, if your product is called Star Runner and your
1577
company is called MySoft, you would construct the QSettings
1580
\quotefromfile snippets/settings/settings.cpp
1581
\skipuntil snippet_ctor1
1583
\printline QSettings settings
1585
QSettings objects can be created either on the stack or on
1586
the heap (i.e. using \c new). Constructing and destroying a
1587
QSettings object is very fast.
1589
If you use QSettings from many places in your application, you
1590
might want to specify the organization name and the application
1591
name using QCoreApplication::setOrganizationName() and
1592
QCoreApplication::setApplicationName(), and then use the default
1593
QSettings constructor:
1595
\skipuntil snippet_ctor2
1597
\printline setOrganizationName
1598
\printline setOrganizationDomain
1599
\printline setApplicationName
1601
\printline QSettings settings;
1603
(Here, we also specify the organization's Internet domain. When
1604
the Internet domain is set, it is used on Mac OS X instead of the
1605
organization name, since Mac OS X applications conventionally use
1606
Internet domains to identify themselves. If no domain is set, a
1607
fake domain is derived from the organization name. See the
1608
\l{Platform-Specific Notes} below for details.)
1610
QSettings stores settings. Each setting consists of a QString
1611
that specifies the setting's name (the \e key) and a QVariant
1612
that stores the data associated with the key. To write a setting,
1613
use setValue(). For example:
1615
\printline setValue(
1617
If there already exists a setting with the same key, the existing
1618
value is overwritten by the new value. For efficiency, the
1619
changes may not be saved to permanent storage immediately. (You
1620
can always call sync() to commit your changes.)
1622
You can get a setting's value back using value():
1624
\printline settings.value(
1626
If there is no setting with the specified name, QSettings
1627
returns a null QVariant (which can be converted to the integer 0).
1628
You can specify another default value by passing a second
1629
argument to value():
1632
\printline /settings.value\(.*,.*\)/
1635
To test whether a given key exists, call contains(). To remove
1636
the setting associated with a key, call remove(). To obtain the
1637
list of all keys, call allKeys(). To remove all keys, call
1640
\section1 QVariant and GUI Types
1642
Because QVariant is part of the \l QtCore library, it cannot provide
1643
conversion functions to data types such as QColor, QImage, and
1644
QPixmap, which are part of \l QtGui. In other words, there is no
1645
\c QVariant::toColor() function.
1647
Instead, you can use the QVariant::value() or the qVariantValue()
1648
template function. For example:
1651
QSettings settings("MySoft", "Star Runner");
1652
QColor color = settings.value("DataPump/bgcolor").value<QColor>();
1655
The inverse conversion (e.g., from QColor to QVariant) is
1656
automatic for all data types supported by QVariant, including
1660
QSettings settings("MySoft", "Star Runner");
1661
QColor color = palette().background().color();
1662
settings.setValue("DataPump/bgcolor", color);
1665
\section1 Key Syntax
1667
Setting keys can contain any Unicode characters. The Windows
1668
registry and INI files use case-insensitive keys, whereas the
1669
Carbon Preferences API on Mac OS X uses case-sensitive keys. To
1670
avoid portability problems, follow these two simple rules:
1673
\o Always refer to the same key using the same case. For example,
1674
if you refer to a key as "text fonts" in one place in your
1675
code, don't refer to it as "Text Fonts" somewhere else.
1677
\o Avoid key names that are identical except for the case. For
1678
example, if you have a key called "MainWindow", don't try to
1679
save another key as "mainwindow".
1682
You can form hierarchical keys using the '/' character as a
1683
separator, similar to Unix file paths. For example:
1689
If you want to save or restore many settings with the same
1690
prefix, you can specify the prefix using beginGroup() and call
1691
endGroup() at the end. Here's the same example again, but this
1692
time using the group mechanism:
1694
\printline beginGroup
1695
\printuntil endGroup
1696
\printline beginGroup
1697
\printuntil endGroup
1699
If a group is set using beginGroup(), the behavior of most
1700
functions changes consequently. Groups can be set recursively.
1702
In addition to groups, QSettings also supports an "array"
1703
concept. See beginReadArray() and beginWriteArray() for details.
1705
\section1 Fallback Mechanism
1707
Let's assume that you have created a QSettings object with the
1708
organization name MySoft and the application name Star Runner.
1709
When you look up a value, up to four locations are searched in
1713
\o a user-specific location for the Star Runner application
1714
\o a user-spefific location for all applications by MySoft
1715
\o a system-wide location for the Star Runner application
1716
\o a system-wide location for all applications by MySoft
1719
On Unix with X11 and on embedded Linux, these locations are the
1723
\o \c{$HOME/.config/MySoft/Star Runner.conf}
1724
\o \c{$HOME/.config/MySoft.conf}
1725
\o \c{/etc/xdg/MySoft/Star Runner.conf}
1726
\o \c{/etc/xdg/MySoft.conf}
1729
On Mac OS X versions 10.2 and 10.3, these files are used:
1732
\o \c{$HOME/Library/Preferences/com.MySoft.Star Runner.plist}
1733
\o \c{$HOME/Library/Preferences/com.MySoft.plist}
1734
\o \c{/Library/Preferences/com.MySoft.Star Runner.plist}
1735
\o \c{/Library/Preferences/com.MySoft.plist}
1738
On Windows, the settings are stored in the following registry
1742
\o \c{HKEY_CURRENT_USER\Software\MySoft\Star Runner}
1743
\o \c{HKEY_CURRENT_USER\Software\MySoft}
1744
\o \c{HKEY_LOCAL_MACHINE\Software\MySoft\Star Runner}
1745
\o \c{HKEY_LOCAL_MACHINE\Software\MySoft}
1748
If a key cannot be found in the first location, the search goes
1749
on in the second location, and so on. This enables you to store
1750
system-wide or organization-wide settings and to override them on
1751
a per-user or per-application basis. To turn off this mechanism,
1752
call setFallbacksEnabled(false).
1754
Although keys from all four locations are available for reading,
1755
only the first file (the user-specific location for the
1756
application at hand) is accessible for writing. To write to any
1757
of the other files, omit the application name and/or specify
1758
QSettings::SystemScope (as opposed to QSettings::UserScope, the
1761
Let's see with an example:
1763
\skipuntil snippet_locations
1768
The table below summarizes which QSettings objects access
1769
which location. "\bold{X}" means that the location is the main
1770
location associated to the QSettings object and is used both
1771
for reading and for writing; "o" means that the location is used
1772
as a fallback when reading.
1775
\header \o Locations \o \c{obj1} \o \c{obj2} \o \c{obj3} \o \c{obj4}
1776
\row \o 1. User, Application \o \bold{X} \o \o \o
1777
\row \o 2. User, Organization \o o \o \bold{X} \o \o
1778
\row \o 3. System, Application \o o \o \o \bold{X} \o
1779
\row \o 4. System, Organization \o o \o o \o o \o \bold{X}
1782
The beauty of this mechanism is that it works on all platforms
1783
supported by Qt and that it still gives you a lot of flexibility,
1784
without requiring you to specify any file names or registry
1787
If you want to use INI files on all platforms instead of the
1788
native API, you can pass QSettings::IniFormat as the first
1789
argument to the QSettings constructor, followed by the scope, the
1790
organization name, and the application name:
1792
\printline /settings\(.*,$/
1795
Sometimes you do want to access settings stored in a specific
1796
file or registry path. In that case, you can use a constructor
1797
that takes a file name (or registry path) and a file format. For
1800
\printline /QSettings settings.*Ini/
1802
The file format can either be QSettings::IniFormat or QSettings::NativeFormat.
1803
On Mac OS X, the native format is an XML-based format called \e
1804
plist. On Windows, the native format is the Windows registry, and
1805
the first argument is a path in the registry rather than a file
1811
On X11 and embedded Linux, QSettings::IniFormat and QSettings::NativeFormat have
1814
The \l{tools/settingseditor}{Settings Editor} example lets you
1815
experiment with different settings location and with fallbacks
1818
\section1 Restoring the State of a GUI Application
1820
QSettings is often used to store the state of a GUI
1821
application. The following example will illustrate how to use we
1822
will use QSettings to save and restore the geometry of an
1823
application's main window.
1825
\skipto ::writeSettings
1827
\skipto ::readSettings
1830
See \l{Window Geometry} for a discussion on why it is better to
1831
call QWidget::resize() and QWidget::move() rather than QWidget::setGeometry()
1832
to restore a window's geometry.
1834
The \c readSettings() and \c writeSettings() functions must be
1835
called from the main window's constructor and close event handler
1838
\skipto ::MainWindow
1841
\printline readSettings
1844
\skipto ::closeEvent
1847
See the \l{mainwindows/application}{Application} example for a
1848
self-contained example that uses QSettings.
1850
\section1 Accessing Settings from Multiple Threads or Processes Simultaneously
1852
QSettings is \l{reentrant}. This means that you can use
1853
distinct QSettings object in different threads
1854
simultaneously. This guarantee stands even when the QSettings
1855
objects refer to the same files on disk (or to the same entries
1856
in the system registry). If a setting is modified through one
1857
QSettings object, the change will immediately be visible in
1858
any other QSettings objects that operate on the same location
1859
and that live in the same process.
1861
QSettings can safely be used from different processes (which
1862
can be different instances of your application running at the
1863
same time or different applications altogether) to read and write
1864
to the same system locations. It uses a smart merging algorithm
1865
to ensure data integrity. Changes performed by another process
1866
aren't visible in the current process until sync() is called.
1868
\section1 Platform-Specific Notes
1870
While QSettings attempts to smooth over the differences
1871
between the different supported platforms, there are still a few
1872
differences that you should be aware of when porting your
1876
\o The Windows system registry has the following limitations: A
1877
subkey may not exceed 255 characters, an entry's value may
1878
not exceed 16,383 characters, and all the values of a key may
1879
not exceed 65,535 characters. One way to work around these
1880
limitations is to store the settings using the IniFormat
1881
instead of the NativeFormat.
1883
\o On Mac OS X, allKeys() will return some extra keys for global
1884
settings that apply to all applications. These keys can be
1885
read using value() but cannot be changed, only shadowed.
1886
Calling setFallbacksEnabled(false) will hide these global
1889
\o On Mac OS X, the APIs used by QSettings expect an Internet
1890
domain name rather than an organization name. To provide a
1891
uniform API, QSettings derives a fake domain name from the
1892
organization name (unless the organization name already is a
1893
domain name, e.g. OpenOffice.org). The algorithm appends
1894
".com" to the company name and replaces spaces and other
1895
illegal characters with hyphens. If you want to specify a
1896
different domain name, call
1897
QCoreApplication::setOrganizationDomain(),
1898
QCoreApplication::setOrganizationName(), and
1899
QCoreApplication::setApplicationName() in your \c main()
1900
function and then use the default QSettings constructor.
1901
Another solution is to use preprocessor directives, for
1906
QSettings settings("grenoullelogique.fr", "Squash");
1908
QSettings settings("Grenoulle Logique", "Squash");
1913
\sa {tools/settingseditor}{Settings Editor Example},
1914
QVariant, QSessionManager
1917
/*! \enum QSettings::Status
1919
The following status values are possible:
1921
\value NoError No error occurred.
1922
\value AccessError An access error occurred (e.g. trying to write to a read-only file).
1923
\value FormatError A format error occurred (e.g. loading a malformed INI file).
1928
/*! \enum QSettings::Format
1930
This enum type specifies the storage format used by QSettings.
1932
\value NativeFormat Store the settings using the most
1933
appropriate storage format for the platform.
1934
On Windows, this means the system registry;
1935
on Mac OS X, this means the CFPreferences
1936
API; on Unix/X11, this means textual
1937
configuration files in INI format.
1938
\value IniFormat Store the settings in INI files.
1940
On Unix/X11, NativeFormat and IniFormat mean the same
1941
thing, except that the file extension is different (\c .conf for
1942
NativeFormat, \c .ini for IniFormat).
1944
The INI file format is a Windows file format that Qt supports on
1948
/*! \enum QSettings::Scope
1950
This enum specifies whether settings are user-specific or shared
1951
by all users of the same system.
1953
\value UserScope Store settings in a location specific to the
1954
current user (e.g., in the user's home
1956
\value SystemScope Store settings in a global location, so that
1957
all users on the same machine access the same
1963
#ifndef QT_NO_QOBJECT
1965
Constructs a QSettings object for accessing settings of the
1966
application called \a application from the organization called \a
1967
organization, and with parent \a parent.
1971
QSettings settings("Moose Tech", "Facturo-Pro");
1974
The scope is QSettings::UserScope and the format is
1975
QSettings::NativeFormat.
1977
\sa {Fallback Mechanism}
1979
QSettings::QSettings(const QString &organization, const QString &application, QObject *parent)
1980
: QObject(*QSettingsPrivate::create(NativeFormat, UserScope, organization, application),
1986
Constructs a QSettings object for accessing settings of the
1987
application called \a application from the organization called \a
1988
organization, and with parent \a parent.
1990
If \a scope is QSettings::UserScope, the QSettings object searches
1991
user-specific settings first, before it searches system-wide
1992
settings as a fallback. If \a scope is
1993
QSettings::SystemScope, the QSettings object ignores user-specific
1994
settings and provides access to system-wide settings.
1996
The storage format is always QSettings::NativeFormat.
1998
If no application name is given, the QSettings object will
1999
only access the organization-wide \l{Fallback Mechanism}{locations}.
2001
QSettings::QSettings(Scope scope, const QString &organization, const QString &application,
2003
: QObject(*QSettingsPrivate::create(NativeFormat, scope, organization, application), parent)
2008
Constructs a QSettings object for accessing settings of the
2009
application called \a application from the organization called
2010
\a organization, and with parent \a parent.
2012
If \a scope is QSettings::UserScope, the QSettings object searches
2013
user-specific settings first, before it searches system-wide
2014
settings as a fallback. If \a scope is
2015
QSettings::SystemScope, the QSettings object ignores user-specific
2016
settings and provides access to system-wide settings.
2018
If \a format is QSettings::NativeFormat, the native API is used for
2019
storing settings. If \a format is QSettings::IniFormat, the INI format
2022
If no application name is given, the QSettings object will
2023
only access the organization-wide \l{Fallback Mechanism}{locations}.
2025
QSettings::QSettings(Format format, Scope scope, const QString &organization,
2026
const QString &application, QObject *parent)
2027
: QObject(*QSettingsPrivate::create(format, scope, organization, application),
2033
Constructs a QSettings object for accessing the settings
2034
stored in the file called \a fileName, with parent \a parent. If
2035
the file doesn't already exist, it is created.
2037
If \a format is QSettings::NativeFormat, the meaning of \a fileName
2038
depends on the platform. On Unix/X11, \a fileName is the name of
2039
an INI file. On Mac OS X, \a fileName is the name of a .plist
2040
file. On Windows, \a fileName is a path in the system registry.
2042
If \a format is QSettings::IniFormat, \a fileName is the name of an INI
2047
QSettings::QSettings(const QString &fileName, Format format, QObject *parent)
2048
: QObject(*QSettingsPrivate::create(fileName, format), parent)
2053
Constructs a QSettings object for accessing settings of the
2054
application and organization set previously with a call to
2055
QCoreApplication::setOrganizationName(),
2056
QCoreApplication::setOrganizationDomain(), and
2057
QCoreApplication::setApplicationName().
2059
The scope is QSettings::UserScope and the format is QSettings::NativeFormat.
2064
QSettings settings("Moose Soft", "Facturo-Pro");
2070
QCoreApplication::setOrganizationName("Moose Soft");
2071
QCoreApplication::setApplicationName("Facturo-Pro");
2075
If QCoreApplication::setOrganizationName() and
2076
QCoreApplication::setApplicationName() has not been previously
2077
called, the QSettings object will not be able to read or write
2078
any settings, and status() will return AccessError.
2080
On Mac OS X, if both a name and an Internet domain are specified
2081
for the organization, the domain is preferred over the name. On
2082
other platforms, the name is preferred over the domain.
2084
\sa QCoreApplication::setOrganizationName(),
2085
QCoreApplication::setOrganizationDomain(),
2086
QCoreApplication::setApplicationName()
2088
QSettings::QSettings(QObject *parent)
2089
: QObject(*QSettingsPrivate::create(NativeFormat, UserScope,
2091
QCoreApplication::organizationDomain().isEmpty()
2092
? QCoreApplication::organizationName()
2093
: QCoreApplication::organizationDomain()
2095
QCoreApplication::organizationName().isEmpty()
2096
? QCoreApplication::organizationDomain()
2097
: QCoreApplication::organizationName()
2099
, QCoreApplication::applicationName()),
2105
QSettings::QSettings(const QString &organization, const QString &application)
2106
: d_ptr(QSettingsPrivate::create(QSettings::NativeFormat, QSettings::UserScope, organization, application))
2108
d_ptr->q_ptr = this;
2111
QSettings::QSettings(Scope scope, const QString &organization, const QString &application)
2112
: d_ptr(QSettingsPrivate::create(QSettings::NativeFormat, scope, organization, application))
2114
d_ptr->q_ptr = this;
2117
QSettings::QSettings(Format format, Scope scope, const QString &organization,
2118
const QString &application)
2119
: d_ptr(QSettingsPrivate::create(format, scope, organization, application))
2121
d_ptr->q_ptr = this;
2124
QSettings::QSettings(const QString &fileName, Format format)
2125
: d_ptr(QSettingsPrivate::create(fileName, format))
2127
d_ptr->q_ptr = this;
2132
Destroys the QSettings object.
2134
Any unsaved changes will eventually be written to permanent
2139
QSettings::~QSettings()
2142
if (d->pendingChanges)
2144
#ifdef QT_NO_QOBJECT
2150
Removes all entries in the primary location associated to this
2153
Entries in fallback locations are not removed.
2155
If you only want to remove the entries in the current group(),
2156
use remove("") instead.
2158
\sa remove(), setFallbacksEnabled()
2160
void QSettings::clear()
2168
Writes any unsaved changes to permanent storage, and reloads any
2169
settings that have been changed in the meantime by another
2172
Unless you use QSettings as a communication mechanism between
2173
different processes, you normally don't need to call this
2176
void QSettings::sync()
2183
Returns the path where settings written using this QSettings
2186
On Windows, if the format is QSettings::NativeFormat, the return value
2187
is a system registry path, not a file path.
2191
QString QSettings::fileName() const
2193
Q_D(const QSettings);
2194
return d->fileName();
2198
Returns a status code indicating the first error that was met by
2199
QSettings, or QSettings::NoError if no error occurred.
2201
QSettings::Status QSettings::status() const
2203
Q_D(const QSettings);
2208
Appends \a prefix to the current group.
2210
The current group is automatically prepended to all keys
2211
specified to QSettings. In addition, query functions such as
2212
childGroups(), childKeys(), and allKeys() are based on the group.
2213
By default, no group is set.
2215
Groups are useful to avoid typing in the same setting paths over
2216
and over. For example:
2219
settings.beginGroup("mainwindow");
2220
settings.setValue("size", win->size());
2221
settings.setValue("fullScreen", win->isFullScreen());
2222
settings.endGroup();
2224
settings.beginGroup("outputpanel");
2225
settings.setValue("visible", panel->isVisible());
2226
settings.endGroup();
2229
This will set the value of three settings:
2232
\o \c mainwindow/size
2233
\o \c mainwindow/fullScreen
2234
\o \c outputpanel/visible
2237
Call endGroup() to reset the current group to what it was before
2238
the corresponding beginGroup() call. Groups can be nested.
2240
\sa endGroup(), group()
2242
void QSettings::beginGroup(const QString &prefix)
2245
d->beginGroupOrArray(QSettingsGroup(d->normalizedKey(prefix)));
2249
Resets the group to what it was before the corresponding
2255
settings.beginGroup("alpha");
2256
// settings.group() == "alpha"
2258
settings.beginGroup("beta");
2259
// settings.group() == "alpha/beta"
2261
settings.endGroup();
2262
// settings.group() == "alpha"
2264
settings.endGroup();
2265
// settings.group() == ""
2268
\sa beginGroup(), group()
2270
void QSettings::endGroup()
2273
if (d->groupStack.isEmpty()) {
2274
qWarning("QSettings::endGroup: No matching beginGroup()");
2278
QSettingsGroup group = d->groupStack.pop();
2279
int len = group.toString().size();
2281
d->groupPrefix.truncate(d->groupPrefix.size() - (len + 1));
2283
if (group.isArray())
2284
qWarning("QSettings::endGroup: Expected endArray() instead");
2288
Returns the current group.
2290
\sa beginGroup(), endGroup()
2292
QString QSettings::group() const
2294
Q_D(const QSettings);
2295
return d->groupPrefix.left(d->groupPrefix.size() - 1);
2299
Adds \a prefix to the current group and starts reading from an
2300
array. Returns the size of the array.
2309
QList<Login> logins;
2313
int size = settings.beginReadArray("logins");
2314
for (int i = 0; i < size; ++i) {
2315
settings.setArrayIndex(i);
2317
login.userName = settings.value("userName");
2318
login.password = settings.value("password");
2319
logins.append(login);
2321
settings.endArray();
2324
Use beginWriteArray() to write the array in the first place.
2326
\sa beginWriteArray(), endArray(), setArrayIndex()
2328
int QSettings::beginReadArray(const QString &prefix)
2331
d->beginGroupOrArray(QSettingsGroup(d->normalizedKey(prefix), false));
2332
return value(QLatin1String("size")).toInt();
2336
Adds \a prefix to the current group and starts writing an array
2337
of size \a size. If \a size is -1 (the default), it is automatically
2338
determined based on the indexes of the entries written.
2340
If you have many occurrences of a certain set of keys, you can
2341
use arrays to make your life easier. For example, let's suppose
2342
that you want to save a variable-length list of user names and
2343
passwords. You could then write:
2350
QList<Login> logins;
2354
settings.beginWriteArray("logins");
2355
for (int i = 0; i < logins.size(); ++i) {
2356
settings.setArrayIndex(i);
2357
settings.setValue("userName", list.at(i).userName);
2358
settings.setValue("password", list.at(i).password);
2360
settings.endArray();
2363
The generated keys will have the form
2366
\o \c logins/1/userName
2367
\o \c logins/1/password
2368
\o \c logins/2/userName
2369
\o \c logins/2/password
2370
\o \c logins/3/userName
2371
\o \c logins/3/password
2375
To read back an array, use beginReadArray().
2377
\sa beginReadArray(), endArray(), setArrayIndex()
2379
void QSettings::beginWriteArray(const QString &prefix, int size)
2382
d->beginGroupOrArray(QSettingsGroup(d->normalizedKey(prefix), size < 0));
2385
remove(QLatin1String("size"));
2387
setValue(QLatin1String("size"), size);
2391
Closes the array that was started using beginReadArray() or
2394
\sa beginReadArray(), beginWriteArray()
2396
void QSettings::endArray()
2399
if (d->groupStack.isEmpty()) {
2400
qWarning("QSettings::endArray: No matching beginArray()");
2404
QSettingsGroup group = d->groupStack.top();
2405
int len = group.toString().size();
2406
d->groupStack.pop();
2408
d->groupPrefix.truncate(d->groupPrefix.size() - (len + 1));
2410
if (group.arraySizeGuess() != -1)
2411
setValue(group.name() + QLatin1String("/size"), group.arraySizeGuess());
2413
if (!group.isArray())
2414
qWarning("QSettings::endArray: Expected endGroup() instead");
2418
Sets the current array index to \a i. Calls to functions such as
2419
setValue(), value(), remove(), and contains() will operate on the
2420
array entry at that index.
2422
You must call beginReadArray() or beginWriteArray() before you
2423
can call this function.
2425
void QSettings::setArrayIndex(int i)
2428
if (d->groupStack.isEmpty() || !d->groupStack.top().isArray()) {
2429
qWarning("QSettings::setArrayIndex: Missing beginArray()");
2433
QSettingsGroup &top = d->groupStack.top();
2434
int len = top.toString().size();
2435
top.setArrayIndex(qMax(i, 0));
2436
d->groupPrefix.replace(d->groupPrefix.size() - len - 1, len, top.toString());
2440
Returns a list of all keys, including subkeys, that can be read
2441
using the QSettings object.
2447
settings.setValue("fridge/color", Qt::white);
2448
settings.setValue("fridge/size", QSize(32, 96));
2449
settings.setValue("sofa", true);
2450
settings.setValue("tv", false);
2452
QStringList keys = settings.allKeys();
2453
// keys: ["fridge/color", "fridge/size", "sofa", "tv"]
2456
If a group is set using beginGroup(), only the keys in the group
2457
are returned, without the group prefix:
2460
settings.beginGroup("fridge");
2461
keys = settings.allKeys();
2462
// keys: ["color", "size"]
2465
\sa childGroups(), childKeys()
2467
QStringList QSettings::allKeys() const
2469
Q_D(const QSettings);
2470
return d->children(d->groupPrefix, QSettingsPrivate::AllKeys);
2474
Returns a list of all top-level keys that can be read using the
2481
settings.setValue("fridge/color", Qt::white);
2482
settings.setValue("fridge/size", QSize(32, 96));
2483
settings.setValue("sofa", true);
2484
settings.setValue("tv", false);
2486
QStringList keys = settings.childKeys();
2487
// keys: ["sofa", "tv"]
2490
If a group is set using beginGroup(), the top-level keys in that
2491
group are returned, without the group prefix:
2494
settings.beginGroup("fridge");
2495
keys = settings.childKeys();
2496
// keys: ["color", "size"]
2499
You can navigate through the entire setting hierarchy using
2500
childKeys() and childGroups() recursively.
2502
\sa childGroups(), allKeys()
2504
QStringList QSettings::childKeys() const
2506
Q_D(const QSettings);
2507
return d->children(d->groupPrefix, QSettingsPrivate::ChildKeys);
2511
Returns a list of all key top-level groups that contain keys that
2512
can be read using the QSettings object.
2518
settings.setValue("fridge/color", Qt::white);
2519
settings.setValue("fridge/size", QSize(32, 96));
2520
settings.setValue("sofa", true);
2521
settings.setValue("tv", false);
2523
QStringList groups = settings.childGroups();
2524
// group: ["fridge"]
2527
If a group is set using beginGroup(), the first-level keys in
2528
that group are returned, without the group prefix.
2531
settings.beginGroup("fridge");
2532
groups = settings.childGroups();
2536
You can navigate through the entire setting hierarchy using
2537
childKeys() and childGroups() recursively.
2539
\sa childKeys(), allKeys()
2541
QStringList QSettings::childGroups() const
2543
Q_D(const QSettings);
2544
return d->children(d->groupPrefix, QSettingsPrivate::ChildGroups);
2548
Returns true if settings can be written using this QSettings
2549
object; returns false otherwise.
2551
One reason why isWritable() might return false is if
2552
QSettings operates on a read-only file.
2554
\sa fileName(), status()
2556
bool QSettings::isWritable() const
2558
Q_D(const QSettings);
2559
return d->isWritable();
2563
Sets the value of setting \a key to \a value.
2565
If the key already exists, the previous value is overwritten.
2571
settings.setValue("interval", 30);
2572
settings.value("interval").toInt(); // returns 30
2574
settings.setValue("interval", 6.55);
2575
settings.value("interval").toDouble(); // returns 6.55
2578
\sa value(), remove(), contains()
2580
void QSettings::setValue(const QString &key, const QVariant &value)
2583
QString k = d->actualKey(key);
2589
Removes the setting \a key and any sub-settings of \a key.
2595
settings.setValue("ape");
2596
settings.setValue("monkey", 1);
2597
settings.setValue("monkey/sea", 2);
2598
settings.setValue("monkey/doe", 4);
2600
settings.remove("monkey");
2601
QStringList keys = settings.allKeys();
2605
Be aware that if one of the fallback locations contains a setting
2606
with the same key, that setting will be visible after calling
2609
If \a key is an empty string, all keys in the current group() are
2610
removed. For example:
2614
settings.setValue("ape");
2615
settings.setValue("monkey", 1);
2616
settings.setValue("monkey/sea", 2);
2617
settings.setValue("monkey/doe", 4);
2619
settings.beginGroup("monkey");
2620
settings.remove("");
2621
settings.endGroup();
2623
QStringList keys = settings.allKeys();
2627
\sa setValue(), value(), contains()
2629
void QSettings::remove(const QString &key)
2633
We cannot use actualKey(), because remove() supports empty
2634
keys. The code is also tricky because of slash handling.
2636
QString theKey = d->normalizedKey(key);
2637
if (theKey.isEmpty())
2640
theKey.prepend(d->groupPrefix);
2642
if (theKey.isEmpty()) {
2651
Returns true if there exists a setting called \a key; returns
2654
If a group is set using beginGroup(), \a key is taken to be
2655
relative to that group.
2657
\sa value(), setValue()
2659
bool QSettings::contains(const QString &key) const
2661
Q_D(const QSettings);
2662
QString k = d->actualKey(key);
2663
return d->get(k, 0);
2667
Sets whether fallbacks are enabled to \a b.
2669
By default, fallbacks are enabled.
2671
\sa fallbacksEnabled()
2673
void QSettings::setFallbacksEnabled(bool b)
2680
Returns true if fallbacks are enabled; returns false otherwise.
2682
By default, fallbacks are enabled.
2684
\sa setFallbacksEnabled()
2686
bool QSettings::fallbacksEnabled() const
2688
Q_D(const QSettings);
2689
return d->fallbacks;
2692
#ifndef QT_NO_QOBJECT
2696
bool QSettings::event(QEvent *event)
2699
if (event->type() == QEvent::UpdateRequest) {
2703
return QObject::event(event);
2708
Returns the value for setting \a key. If the setting doesn't
2709
exist, returns \a defaultValue.
2711
If no default value is specified, a default QVariant is
2718
settings.setValue("animal/snake", 58);
2719
settings.value("animal/snake", 1024).toInt(); // returns 58
2720
settings.value("animal/zebra", 1024).toInt(); // returns 1024
2721
settings.value("animal/zebra").toInt(); // returns 0
2724
\sa setValue(), contains(), remove()
2726
QVariant QSettings::value(const QString &key, const QVariant &defaultValue) const
2728
Q_D(const QSettings);
2729
QVariant result = defaultValue;
2730
QString k = d->actualKey(key);
2736
Sets the directory where QSettings stores its SystemScope \c .ini files to \a dir.
2738
On Unix systems, the default directory is \c /etc/xdg in accordance with FreeDesktop's
2739
XDG Base Directory Specification. This default can be changed when compiling Qt by passing
2740
the \c --sysconfdir flag to \c configure.
2742
On Windows, the default directory is \c{C:\Documents and Settings\All Users\Application Data}.
2744
A call to this function should precede any instantiations of QSettings objects.
2746
\sa setUserIniPath()
2748
void QSettings::setSystemIniPath(const QString &dir)
2750
*defaultSystemIniPath() = dir;
2754
Sets the directory where QSettings stores its UserScope \c .ini files to \a dir.
2756
On Unix systems, the default directory is read from the \c $XDG_CONFIG_HOME environment
2757
variable. If this variable is empty or unset, \c $HOME/.config is used, in accordance with
2758
the FreeDesktop's XDG Base Directory Specification. Calling this function overrides the
2759
path specified in \c $XDG_CONFIG_HOME.
2761
On Windows, the default directory is \c{C:\Documents and Settings\<username>\Application Data}.
2763
A call to this function should precede any instantiations of QSettings objects.
2765
\sa setSystemIniPath()
2768
void QSettings::setUserIniPath(const QString &dir)
2770
*defaultUserIniPath() = dir;
2774
/*! \fn bool QSettings::writeEntry(const QString &key, bool value)
2776
Sets the value of setting \a key to \a value.
2778
Use setValue() instead.
2781
/*! \fn bool QSettings::writeEntry(const QString &key, double value)
2786
/*! \fn bool QSettings::writeEntry(const QString &key, int value)
2791
/*! \fn bool QSettings::writeEntry(const QString &key, const char *value)
2796
/*! \fn bool QSettings::writeEntry(const QString &key, const QString &value)
2801
/*! \fn bool QSettings::writeEntry(const QString &key, const QStringList &value)
2806
/*! \fn bool QSettings::writeEntry(const QString &key, const QStringList &value, QChar separator)
2810
Use setValue(\a key, \a value) instead. You don't need \a separator.
2813
/*! \fn QStringList QSettings::readListEntry(const QString &key, bool *ok = 0)
2815
Returns the value of setting \a key converted to a QStringList.
2817
If \a ok is not 0, *\a{ok} is set to true if the key exists,
2818
otherwise *\a{ok} is set to false.
2820
Use value() instead.
2824
QStringList list = settings.readListEntry("recentFiles", &ok);
2826
bool ok = settings.contains("recentFiles");
2827
QStringList list = settings.value("recentFiles").toStringList();
2831
/*! \fn QStringList QSettings::readListEntry(const QString &key, QChar separator, bool *ok)
2833
Returns the value of setting \a key converted to a QStringList.
2834
\a separator is ignored.
2836
If \a ok is not 0, *\a{ok} is set to true if the key exists,
2837
otherwise *\a{ok} is set to false.
2839
Use value() instead.
2843
QStringList list = settings.readListEntry("recentFiles", ":", &ok);
2845
bool ok = settings.contains("recentFiles");
2846
QStringList list = settings.value("recentFiles").toStringList();
2850
/*! \fn QString QSettings::readEntry(const QString &key, const QString &defaultValue, bool *ok)
2852
Returns the value for setting \a key converted to a QString. If
2853
the setting doesn't exist, returns \a defaultValue.
2855
If \a ok is not 0, *\a{ok} is set to true if the key exists,
2856
otherwise *\a{ok} is set to false.
2858
Use value() instead.
2862
QString str = settings.readEntry("userName", "administrator", &ok);
2864
bool ok = settings.contains("userName");
2865
QString str = settings.value("userName", "administrator").toString();
2869
/*! \fn int QSettings::readNumEntry(const QString &key, int defaultValue, bool *ok)
2871
Returns the value for setting \a key converted to an \c int. If
2872
the setting doesn't exist, returns \a defaultValue.
2874
If \a ok is not 0, *\a{ok} is set to true if the key exists,
2875
otherwise *\a{ok} is set to false.
2877
Use value() instead.
2881
int max = settings.readNumEntry("maxConnections", 30, &ok);
2883
bool ok = settings.contains("maxConnections");
2884
int max = settings.value("maxConnections", 30).toInt();
2888
/*! \fn double QSettings::readDoubleEntry(const QString &key, double defaultValue, bool *ok)
2890
Returns the value for setting \a key converted to a \c double. If
2891
the setting doesn't exist, returns \a defaultValue.
2893
If \a ok is not 0, *\a{ok} is set to true if the key exists,
2894
otherwise *\a{ok} is set to false.
2896
Use value() instead.
2900
double pi = settings.readDoubleEntry("pi", 3.141592, &ok);
2902
bool ok = settings.contains("pi");
2903
double pi = settings.value("pi", 3.141592).toDouble();
2907
/*! \fn bool QSettings::readBoolEntry(const QString &key, bool defaultValue, bool *ok)
2909
Returns the value for setting \a key converted to a \c bool. If
2910
the setting doesn't exist, returns \a defaultValue.
2912
If \a ok is not 0, *\a{ok} is set to true if the key exists,
2913
otherwise *\a{ok} is set to false.
2915
Use value() instead.
2919
bool grid = settings.readBoolEntry("showGrid", true, &ok);
2921
bool ok = settings.contains("showGrid");
2922
bool grid = settings.value("showGrid", true).toBool();
2926
/*! \fn bool QSettings::removeEntry(const QString &key)
2928
Use remove() instead.
2931
/*! \enum QSettings::System
2934
\value Unix Unix/X11 systems
2935
\value Windows Microsoft Windows systems
2936
\value Mac Mac OS X systems
2938
\sa insertSearchPath(), removeSearchPath()
2941
/*! \fn void QSettings::insertSearchPath(System system, const QString &path)
2943
This function is implemented as a no-op. It is provided for
2944
source compatibility with Qt 3. The new QSettings class has no
2945
concept of "search path".
2948
/*! \fn void QSettings::removeSearchPath(System system, const QString &path)
2950
This function is implemented as a no-op. It is provided for
2951
source compatibility with Qt 3. The new QSettings class has no
2952
concept of "search path".
2955
/*! \fn void QSettings::setPath(const QString &organization, const QString &application, \
2958
Specifies the \a organization, \a application, and \a scope to
2959
use by the QSettings object.
2961
Use the appropriate constructor instead, with QSettings::UserScope
2962
instead of QSettings::User and QSettings::SystemScope instead of
2967
settings.setPath("twikimaster.com", "Kanooth", QSettings::Global);
2969
QSettings settings(QSettings::SystemScope, "twikimaster.com", "Kanooth");
2973
/*! \fn void QSettings::resetGroup()
2975
Sets the current group to be the empty string.
2977
Use endGroup() instead (possibly multiple times).
2981
settings.beginGroup("mainWindow");
2982
settings.beginGroup("leftPanel");
2984
settings.resetGroup();
2987
settings.beginGroup("mainWindow");
2988
settings.beginGroup("leftPanel");
2990
settings.endGroup();
2991
settings.endGroup();
2995
/*! \fn QStringList QSettings::entryList(const QString &key) const
2997
Returns a list of all sub-keys of \a key.
2999
Use childKeys() instead.
3003
QStringList keys = settings.entryList("cities");
3007
settings.beginGroup("cities");
3008
QStringList keys = settings.childKeys();
3010
settings.endGroup();
3014
/*! \fn QStringList QSettings::subkeyList(const QString &key) const
3016
Returns a list of all sub-keys of \a key.
3018
Use childGroups() instead.
3022
QStringList groups = settings.entryList("cities");
3026
settings.beginGroup("cities");
3027
QStringList groups = settings.childKeys();
3029
settings.endGroup();
3034
#endif // QT_NO_SETTINGS