mirror of
https://bitbucket.org/smil3y/katie.git
synced 2025-02-24 10:52:56 +00:00
drop support for storing types that are not QString-convertable via QSettings
I am not interested in custom types feature at all - QMainWindow for example saves its state via QDataStream. ofcourse it involves conversion but that is the case with QVariant aswell. there is also the qreal type thing - it may be float, it may double. streaming QRectF has to be done in such a way to account for both cases but here is the catch - if conversion fails there has to be fallback which QSettings::value() kinda covers for types that are not composed of several more types. Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
2ae0376a53
commit
bc0040b970
3 changed files with 6 additions and 223 deletions
|
@ -111,7 +111,7 @@ static bool ini_settings_read(QIODevice &device, QSettings::SettingsMap &map)
|
||||||
|
|
||||||
const QByteArray key = line.left(separatorpos).trimmed();
|
const QByteArray key = line.left(separatorpos).trimmed();
|
||||||
const QByteArray value = line.mid(separatorpos + 1).trimmed();
|
const QByteArray value = line.mid(separatorpos + 1).trimmed();
|
||||||
const QVariant variantvalue = QSettingsPrivate::stringToVariant(value);
|
const QVariant variantvalue(value);
|
||||||
if (section.isEmpty()) {
|
if (section.isEmpty()) {
|
||||||
map.insert(key, variantvalue);
|
map.insert(key, variantvalue);
|
||||||
} else {
|
} else {
|
||||||
|
@ -154,7 +154,11 @@ static bool ini_settings_write(QIODevice &device, const QSettings::SettingsMap &
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString stringvalue = QSettingsPrivate::variantToString(map.value(key));
|
const QVariant variantvalue = map.value(key);
|
||||||
|
if (!variantvalue.canConvert<QString>()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const QString stringvalue = variantvalue.toString();
|
||||||
const QString datavalue = QLatin1Char('=') + stringvalue + QLatin1Char('\n');
|
const QString datavalue = QLatin1Char('=') + stringvalue + QLatin1Char('\n');
|
||||||
if (!device.write(datavalue.toAscii())) {
|
if (!device.write(datavalue.toAscii())) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -317,152 +321,6 @@ QString QSettingsPrivate::toGroupKey(const QString &key) const
|
||||||
return group + QLatin1Char('/') + key;
|
return group + QLatin1Char('/') + key;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QSettingsPrivate::variantToString(const QVariant &v)
|
|
||||||
{
|
|
||||||
switch (v.type()) {
|
|
||||||
case QVariant::Invalid: {
|
|
||||||
return QLatin1String("@Invalid()");
|
|
||||||
}
|
|
||||||
case QVariant::ByteArray: {
|
|
||||||
QByteArray a = v.toByteArray();
|
|
||||||
QString result = QLatin1String("@ByteArray(");
|
|
||||||
result += QString::fromAscii(a.constData(), a.size());
|
|
||||||
result += QLatin1Char(')');
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
case QVariant::String:
|
|
||||||
case QVariant::LongLong:
|
|
||||||
case QVariant::ULongLong:
|
|
||||||
case QVariant::Int:
|
|
||||||
case QVariant::UInt:
|
|
||||||
case QVariant::Bool:
|
|
||||||
case QVariant::Double:
|
|
||||||
case QVariant::KeySequence: {
|
|
||||||
QString result = v.toString();
|
|
||||||
if (result.startsWith(QLatin1Char('@')))
|
|
||||||
result.prepend(QLatin1Char('@'));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
case QVariant::Rect: {
|
|
||||||
QRect r = qvariant_cast<QRect>(v);
|
|
||||||
QString 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());
|
|
||||||
result += QLatin1Char(')');
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
case QVariant::Size: {
|
|
||||||
QSize s = qvariant_cast<QSize>(v);
|
|
||||||
QString result = QLatin1String("@Size(");
|
|
||||||
result += QString::number(s.width());
|
|
||||||
result += QLatin1Char(' ');
|
|
||||||
result += QString::number(s.height());
|
|
||||||
result += QLatin1Char(')');
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
case QVariant::Point: {
|
|
||||||
QPoint p = qvariant_cast<QPoint>(v);
|
|
||||||
QString result = QLatin1String("@Point(");
|
|
||||||
result += QString::number(p.x());
|
|
||||||
result += QLatin1Char(' ');
|
|
||||||
result += QString::number(p.y());
|
|
||||||
result += QLatin1Char(')');
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
#ifndef QT_NO_DATASTREAM
|
|
||||||
QByteArray a;
|
|
||||||
{
|
|
||||||
QDataStream s(&a, QIODevice::WriteOnly);
|
|
||||||
s << v;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString result = QLatin1String("@Variant(");
|
|
||||||
result += QString::fromAscii(a.constData(), a.size());
|
|
||||||
result += QLatin1Char(')');
|
|
||||||
return result;
|
|
||||||
#else
|
|
||||||
Q_ASSERT(!"QSettings: Cannot save custom types without QDataStream support");
|
|
||||||
return QString();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QVariant QSettingsPrivate::stringToVariant(const QString &s)
|
|
||||||
{
|
|
||||||
if (s.startsWith(QLatin1Char('@'))) {
|
|
||||||
if (s.endsWith(QLatin1Char(')'))) {
|
|
||||||
if (s.startsWith(QLatin1String("@ByteArray("))) {
|
|
||||||
return QVariant(s.toAscii().mid(11, s.size() - 12));
|
|
||||||
} else if (s.startsWith(QLatin1String("@Variant("))) {
|
|
||||||
#ifndef QT_NO_DATASTREAM
|
|
||||||
QByteArray a(s.toAscii().mid(9));
|
|
||||||
QDataStream stream(&a, QIODevice::ReadOnly);
|
|
||||||
QVariant result;
|
|
||||||
stream >> result;
|
|
||||||
return result;
|
|
||||||
#else
|
|
||||||
Q_ASSERT(!"QSettings: Cannot load custom types without QDataStream support");
|
|
||||||
#endif
|
|
||||||
} else if (s.startsWith(QLatin1String("@Rect("))) {
|
|
||||||
QStringList args = QSettingsPrivate::splitArgs(s, 5);
|
|
||||||
if (args.size() == 4)
|
|
||||||
return QVariant(QRect(args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt()));
|
|
||||||
} else if (s.startsWith(QLatin1String("@Size("))) {
|
|
||||||
QStringList args = QSettingsPrivate::splitArgs(s, 5);
|
|
||||||
if (args.size() == 2)
|
|
||||||
return QVariant(QSize(args[0].toInt(), args[1].toInt()));
|
|
||||||
} else if (s.startsWith(QLatin1String("@Point("))) {
|
|
||||||
QStringList args = QSettingsPrivate::splitArgs(s, 6);
|
|
||||||
if (args.size() == 2)
|
|
||||||
return QVariant(QPoint(args[0].toInt(), args[1].toInt()));
|
|
||||||
} else if (s == QLatin1String("@Invalid()")) {
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (s.startsWith(QLatin1String("@@")))
|
|
||||||
return QVariant(s.mid(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
return QVariant(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList QSettingsPrivate::splitArgs(const QString &s, int idx)
|
|
||||||
{
|
|
||||||
int l = s.length();
|
|
||||||
Q_ASSERT(l > 0);
|
|
||||||
Q_ASSERT(s.at(idx) == QLatin1Char('('));
|
|
||||||
Q_ASSERT(s.at(l - 1) == QLatin1Char(')'));
|
|
||||||
|
|
||||||
QStringList result;
|
|
||||||
QString item;
|
|
||||||
|
|
||||||
for (++idx; idx < l; ++idx) {
|
|
||||||
QChar c = s.at(idx);
|
|
||||||
if (c == QLatin1Char(')')) {
|
|
||||||
Q_ASSERT(idx == l - 1);
|
|
||||||
result.append(item);
|
|
||||||
} else if (c == QLatin1Char(' ')) {
|
|
||||||
result.append(item);
|
|
||||||
item.clear();
|
|
||||||
} else {
|
|
||||||
item.append(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class QSettings
|
\class QSettings
|
||||||
\brief The QSettings class provides persistent platform-independent application settings.
|
\brief The QSettings class provides persistent platform-independent application settings.
|
||||||
|
|
|
@ -54,10 +54,6 @@ public:
|
||||||
void notify();
|
void notify();
|
||||||
|
|
||||||
QString toGroupKey(const QString &key) const;
|
QString toGroupKey(const QString &key) const;
|
||||||
// INI parser functions
|
|
||||||
static QString variantToString(const QVariant &v);
|
|
||||||
static QVariant stringToVariant(const QString &s);
|
|
||||||
static QStringList splitArgs(const QString &s, int idx);
|
|
||||||
|
|
||||||
QSettings::Format format;
|
QSettings::Format format;
|
||||||
QSettings::SettingsStatus status;
|
QSettings::SettingsStatus status;
|
||||||
|
|
|
@ -49,8 +49,6 @@ private slots:
|
||||||
void variant();
|
void variant();
|
||||||
void group_data();
|
void group_data();
|
||||||
void group();
|
void group();
|
||||||
void custom_data();
|
|
||||||
void custom();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_QSettings::initTestCase()
|
void tst_QSettings::initTestCase()
|
||||||
|
@ -142,27 +140,12 @@ void tst_QSettings::variant()
|
||||||
const QByteArray qbytearray("abc");
|
const QByteArray qbytearray("abc");
|
||||||
const QByteArray qstring("måndag");
|
const QByteArray qstring("måndag");
|
||||||
const QStringList qstringlist = QStringList() << "a" << "b" << "c";
|
const QStringList qstringlist = QStringList() << "a" << "b" << "c";
|
||||||
const QPoint qpoint(1, 2);
|
|
||||||
const QRect qrect(1, 2, 3, 4);
|
|
||||||
const QSize qsize(1, 2);
|
|
||||||
const QDate qdate = QDate::currentDate();
|
|
||||||
const QColor qcolor(1, 2, 3);
|
|
||||||
const QFont qfont = QApplication::font();
|
|
||||||
|
|
||||||
QVARIANT_TEST(qll);
|
QVARIANT_TEST(qll);
|
||||||
QVARIANT_TEST(qrl);
|
QVARIANT_TEST(qrl);
|
||||||
QVARIANT_TEST(qbytearray);
|
QVARIANT_TEST(qbytearray);
|
||||||
QVARIANT_TEST(qstring);
|
QVARIANT_TEST(qstring);
|
||||||
QVARIANT_TEST(qstringlist);
|
QVARIANT_TEST(qstringlist);
|
||||||
if (format == QSettings::NativeFormat) {
|
|
||||||
QSKIP("Native format does not support some types", SkipAll);
|
|
||||||
}
|
|
||||||
QVARIANT_TEST(qpoint);
|
|
||||||
QVARIANT_TEST(qrect);
|
|
||||||
QVARIANT_TEST(qsize);
|
|
||||||
QVARIANT_TEST(qdate);
|
|
||||||
QVARIANT_TEST(qcolor);
|
|
||||||
QVARIANT_TEST(qfont);
|
|
||||||
}
|
}
|
||||||
#undef QVARIANT_TEST
|
#undef QVARIANT_TEST
|
||||||
|
|
||||||
|
@ -194,60 +177,6 @@ void tst_QSettings::group()
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CustomType {
|
|
||||||
int a;
|
|
||||||
QByteArray b;
|
|
||||||
QSize c;
|
|
||||||
};
|
|
||||||
Q_DECLARE_METATYPE(CustomType);
|
|
||||||
|
|
||||||
QDataStream &operator<<(QDataStream &stream, const CustomType &custom)
|
|
||||||
{
|
|
||||||
stream << custom.a;
|
|
||||||
stream << custom.b;
|
|
||||||
stream << custom.c;
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDataStream &operator>>(QDataStream &stream, CustomType &custom)
|
|
||||||
{
|
|
||||||
stream >> custom.a;
|
|
||||||
stream >> custom.b;
|
|
||||||
stream >> custom.c;
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QSettings::custom_data()
|
|
||||||
{
|
|
||||||
tst_QSettings::value_data();
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QSettings::custom()
|
|
||||||
{
|
|
||||||
QFETCH(QString, filename);
|
|
||||||
QFETCH(QSettings::Format, format);
|
|
||||||
|
|
||||||
if (format == QSettings::NativeFormat) {
|
|
||||||
QSKIP("Native format does not support custom types", SkipAll);
|
|
||||||
}
|
|
||||||
|
|
||||||
qRegisterMetaType<CustomType>();
|
|
||||||
qRegisterMetaTypeStreamOperators<CustomType>();
|
|
||||||
|
|
||||||
CustomType test;
|
|
||||||
test.a = 10;
|
|
||||||
test.b = QByteArray("test");
|
|
||||||
test.c = QSize(10, 10);
|
|
||||||
|
|
||||||
QSettings settings(filename, format);
|
|
||||||
settings.setValue("a", QVariant::fromValue(test));
|
|
||||||
|
|
||||||
CustomType result = qvariant_cast<CustomType>(settings.value("a"));
|
|
||||||
QCOMPARE(result.a, 10);
|
|
||||||
QCOMPARE(result.b, QByteArray("test"));
|
|
||||||
QCOMPARE(result.c, QSize(10, 10));
|
|
||||||
}
|
|
||||||
|
|
||||||
QTEST_MAIN(tst_QSettings)
|
QTEST_MAIN(tst_QSettings)
|
||||||
|
|
||||||
#include "moc_tst_qsettings.cpp"
|
#include "moc_tst_qsettings.cpp"
|
||||||
|
|
Loading…
Add table
Reference in a new issue