From e5d54fc6bc76b32e0f7a69e85d073ab321a45aac Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 14 Sep 2016 13:25:37 -0700 Subject: [PATCH] Move helpers to their own file --- libraries/script-engine/src/ScriptEngines.cpp | 37 --- libraries/shared/src/SettingHelpers.cpp | 284 ++++++++++++++++++ libraries/shared/src/SettingHelpers.h | 35 +++ libraries/shared/src/SettingInterface.cpp | 274 +---------------- 4 files changed, 323 insertions(+), 307 deletions(-) create mode 100644 libraries/shared/src/SettingHelpers.cpp create mode 100644 libraries/shared/src/SettingHelpers.h diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index cb6291a8dc..b3092be55a 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -283,43 +283,6 @@ void ScriptEngines::loadScripts() { // loads all saved scripts Settings settings; - - - // START of backward compatibility code - // This following if statement is only meant to update the settings file still using the old setting key. - // If you read that comment and it has been more than a couple months since it was merged, - // then by all means, feel free to remove it. - if (!settings.childGroups().contains(SETTINGS_KEY)) { - qWarning() << "Detected old script settings config, loading from previous location"; - const QString oldKey = "Settings"; - - // Load old scripts array from settings - int size = settings.beginReadArray(oldKey); - for (int i = 0; i < size; ++i) { - settings.setArrayIndex(i); - QString string = settings.value("script").toString(); - if (!string.isEmpty()) { - loadScript(string); - } - } - settings.endArray(); - - // Cleanup old scripts array from settings - settings.beginWriteArray(oldKey); - for (int i = 0; i < size; ++i) { - settings.setArrayIndex(i); - settings.remove(""); - } - settings.endArray(); - settings.beginGroup(oldKey); - settings.remove("size"); - settings.endGroup(); - - return; - } - // END of backward compatibility code - - int size = settings.beginReadArray(SETTINGS_KEY); for (int i = 0; i < size; ++i) { settings.setArrayIndex(i); diff --git a/libraries/shared/src/SettingHelpers.cpp b/libraries/shared/src/SettingHelpers.cpp new file mode 100644 index 0000000000..2ce23b6cee --- /dev/null +++ b/libraries/shared/src/SettingHelpers.cpp @@ -0,0 +1,284 @@ +// +// SettingHelpers.cpp +// libraries/shared/src +// +// Created by Clement on 9/13/16. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "SettingHelpers.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +QSettings::SettingsMap jsonDocumentToVariantMap(const QJsonDocument& document); +QJsonDocument variantMapToJsonDocument(const QSettings::SettingsMap& map); + +bool readJSONFile(QIODevice& device, QSettings::SettingsMap& map) { + QJsonParseError jsonParseError; + + auto bytesRead = device.readAll(); + auto document = QJsonDocument::fromJson(bytesRead, &jsonParseError); + + if (jsonParseError.error != QJsonParseError::NoError) { + qDebug() << "Error parsing QSettings file:" << jsonParseError.errorString(); + return false; + } + + map = jsonDocumentToVariantMap(document); + + return true; +} + +bool writeJSONFile(QIODevice& device, const QSettings::SettingsMap& map) { + auto document = variantMapToJsonDocument(map); + auto jsonByteArray = document.toJson(QJsonDocument::Indented); + auto bytesWritten = device.write(jsonByteArray); + return bytesWritten == jsonByteArray.size(); +} + +void loadOldINIFile(QSettings& settings) { + QSettings::setDefaultFormat(QSettings::IniFormat); + + QSettings iniSettings; + if (!iniSettings.allKeys().isEmpty()) { + qDebug() << "No data in json settings file, trying to load old ini settings file."; + + for (auto key : iniSettings.allKeys()) { + auto variant = iniSettings.value(key); + + if (variant.type() == QVariant::String) { + auto string = variant.toString(); + if (string == "true") { + variant = true; + } else if (string == "false") { + variant = false; + } else { + bool ok; + double value = string.toDouble(&ok); + if (ok) { + variant = value; + } + } + } + settings.setValue(key, variant); + } + + qDebug() << "Loaded" << settings.allKeys().size() << "keys from ini settings file."; + } + + QSettings::setDefaultFormat(JSON_FORMAT); +} + +QStringList splitArgs(const QString& string, int idx) { + int length = string.length(); + Q_ASSERT(length > 0); + Q_ASSERT(string.at(idx) == QLatin1Char('(')); + Q_ASSERT(string.at(length - 1) == QLatin1Char(')')); + + QStringList result; + QString item; + + for (++idx; idx < length; ++idx) { + QChar c = string.at(idx); + if (c == QLatin1Char(')')) { + Q_ASSERT(idx == length - 1); + result.append(item); + } else if (c == QLatin1Char(' ')) { + result.append(item); + item.clear(); + } else { + item.append(c); + } + } + + return result; +} + +QJsonDocument variantMapToJsonDocument(const QSettings::SettingsMap& map) { + qDebug() << Q_FUNC_INFO << map.size() << "in map"; + + QJsonObject object; + for (auto it = map.cbegin(); it != map.cend(); ++it) { + auto& key = it.key(); + auto& variant = it.value(); + auto variantType = variant.type(); + + // Switch some types so they are readable/modifiable in the json file + if (variantType == QVariant(1.0f).type()) { // float + variantType = QVariant::Double; + } + if (variantType == QVariant((quint16)0).type()) { // uint16 + variantType = QVariant::UInt; + } + + switch (variantType) { + case QVariant::Map: + case QVariant::List: + case QVariant::Hash: { + qCritical() << "Unsupported variant type" << variant.typeName(); + Q_ASSERT(false); + break; + } + + case QVariant::Invalid: + object.insert(key, QJsonValue()); + break; + case QVariant::LongLong: + case QVariant::ULongLong: + case QVariant::Int: + case QVariant::UInt: + case QVariant::Bool: + case QVariant::Double: + object.insert(key, QJsonValue::fromVariant(variant)); + break; + + case QVariant::String: { + QString result = variant.toString(); + if (result.startsWith(QLatin1Char('@'))) { + result.prepend(QLatin1Char('@')); + } + object.insert(key, result); + break; + } + + case QVariant::ByteArray: { + QByteArray a = variant.toByteArray(); + QString result = QLatin1String("@ByteArray("); + result += QString::fromLatin1(a.constData(), a.size()); + result += QLatin1Char(')'); + object.insert(key, result); + break; + } + case QVariant::Rect: { + QRect r = qvariant_cast(variant); + 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(')'); + object.insert(key, result); + break; + } + case QVariant::Size: { + QSize s = qvariant_cast(variant); + QString result = QLatin1String("@Size("); + result += QString::number(s.width()); + result += QLatin1Char(' '); + result += QString::number(s.height()); + result += QLatin1Char(')'); + object.insert(key, result); + break; + } + case QVariant::Point: { + QPoint p = qvariant_cast(variant); + QString result = QLatin1String("@Point("); + result += QString::number(p.x()); + result += QLatin1Char(' '); + result += QString::number(p.y()); + result += QLatin1Char(')'); + object.insert(key, result); + break; + } + + default: { + QByteArray array; + { + QDataStream stream(&array, QIODevice::WriteOnly); + stream.setVersion(QDataStream::Qt_4_0); + stream << variant; + } + + QString result = QLatin1String("@Variant("); + result += QString::fromLatin1(array.constData(), array.size()); + result += QLatin1Char(')'); + object.insert(key, result); + break; + } + } + } + + qDebug() << Q_FUNC_INFO << object.size() << "in json"; + + return QJsonDocument(object); +} + + +QSettings::SettingsMap jsonDocumentToVariantMap(const QJsonDocument& document) { + if (!document.isObject()) { + qWarning() << "Settings file does not contain a JSON object"; + return QSettings::SettingsMap(); + } + auto object = document.object(); + qDebug() << Q_FUNC_INFO << object.size() << "in json"; + QSettings::SettingsMap map; + + for (auto it = object.begin(); it != object.end(); ++it) { + + QVariant result; + + if (!it->isString()) { + result = it->toVariant(); + } else { + auto string = it->toString(); + + if (string.startsWith(QLatin1String("@@"))) { + result = QVariant(string.mid(1)); + + } else if (string.startsWith(QLatin1Char('@'))) { + + if (string.endsWith(QLatin1Char(')'))) { + + if (string.startsWith(QLatin1String("@ByteArray("))) { + result = QVariant(string.toLatin1().mid(11, string.size() - 12)); + + } else if (string.startsWith(QLatin1String("@Variant("))) { + QByteArray a(string.toLatin1().mid(9)); + QDataStream stream(&a, QIODevice::ReadOnly); + stream.setVersion(QDataStream::Qt_4_0); + stream >> result; + + } else if (string.startsWith(QLatin1String("@Rect("))) { + QStringList args = splitArgs(string, 5); + if (args.size() == 4) { + result = QRect(args[0].toInt(), args[1].toInt(), + args[2].toInt(), args[3].toInt()); + } + + } else if (string.startsWith(QLatin1String("@Size("))) { + QStringList args = splitArgs(string, 5); + if (args.size() == 2) { + result = QSize(args[0].toInt(), args[1].toInt()); + } + + } else if (string.startsWith(QLatin1String("@Point("))) { + QStringList args = splitArgs(string, 6); + if (args.size() == 2) { + result = QPoint(args[0].toInt(), args[1].toInt()); + } + } + } + } + } + + map.insert(it.key(), result); + } + + qDebug() << Q_FUNC_INFO << map.size() << "in map"; + return map; +} diff --git a/libraries/shared/src/SettingHelpers.h b/libraries/shared/src/SettingHelpers.h new file mode 100644 index 0000000000..c2f270f5b5 --- /dev/null +++ b/libraries/shared/src/SettingHelpers.h @@ -0,0 +1,35 @@ +// +// SettingHelpers.h +// libraries/shared/src +// +// Created by Clement on 9/13/16. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_SettingHelpers_h +#define hifi_SettingHelpers_h + + + + +#include +#include +#include +#include +#include +#include +#include +#include + +bool readJSONFile(QIODevice& device, QSettings::SettingsMap& map); +bool writeJSONFile(QIODevice& device, const QSettings::SettingsMap& map); + +static const auto JSON_FORMAT = QSettings::registerFormat("json", readJSONFile, writeJSONFile); + +void loadOldINIFile(QSettings& settings); + + +#endif // hifi_SettingHelpers_h diff --git a/libraries/shared/src/SettingInterface.cpp b/libraries/shared/src/SettingInterface.cpp index 1267147b7e..21c0d7c721 100644 --- a/libraries/shared/src/SettingInterface.cpp +++ b/libraries/shared/src/SettingInterface.cpp @@ -17,245 +17,11 @@ #include #include "PathUtils.h" +#include "SettingHelpers.h" #include "SettingManager.h" #include "SharedLogging.h" -#include -#include -#include -#include -#include -#include -#include -#include - -QStringList splitArgs(const QString& string, int idx) { - int length = string.length(); - Q_ASSERT(length > 0); - Q_ASSERT(string.at(idx) == QLatin1Char('(')); - Q_ASSERT(string.at(length - 1) == QLatin1Char(')')); - - QStringList result; - QString item; - - for (++idx; idx < length; ++idx) { - QChar c = string.at(idx); - if (c == QLatin1Char(')')) { - Q_ASSERT(idx == length - 1); - result.append(item); - } else if (c == QLatin1Char(' ')) { - result.append(item); - item.clear(); - } else { - item.append(c); - } - } - - return result; -} - -QJsonDocument variantMapToJsonDocument(const QSettings::SettingsMap& map) { - qDebug() << Q_FUNC_INFO << map.size() << "in map"; - - QJsonObject object; - for (auto it = map.cbegin(); it != map.cend(); ++it) { - auto& key = it.key(); - auto& variant = it.value(); - auto variantType = variant.type(); - - // Switch some types so they are readable/modifiable in the json file - if (variantType == QVariant(1.0f).type()) { // float - variantType = QVariant::Double; - } - if (variantType == QVariant((quint16)0).type()) { // uint16 - variantType = QVariant::UInt; - } - - switch (variantType) { - case QVariant::Map: - case QVariant::List: - case QVariant::Hash: { - qCritical() << "Unsupported variant type" << variant.typeName(); - Q_ASSERT(false); - break; - } - - case QVariant::Invalid: - object.insert(key, QJsonValue()); - break; - case QVariant::LongLong: - case QVariant::ULongLong: - case QVariant::Int: - case QVariant::UInt: - case QVariant::Bool: - case QVariant::Double: - object.insert(key, QJsonValue::fromVariant(variant)); - break; - - case QVariant::String: { - QString result = variant.toString(); - if (result.startsWith(QLatin1Char('@'))) { - result.prepend(QLatin1Char('@')); - } - object.insert(key, result); - break; - } - - case QVariant::ByteArray: { - QByteArray a = variant.toByteArray(); - QString result = QLatin1String("@ByteArray("); - result += QString::fromLatin1(a.constData(), a.size()); - result += QLatin1Char(')'); - object.insert(key, result); - break; - } - case QVariant::Rect: { - QRect r = qvariant_cast(variant); - 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(')'); - object.insert(key, result); - break; - } - case QVariant::Size: { - QSize s = qvariant_cast(variant); - QString result = QLatin1String("@Size("); - result += QString::number(s.width()); - result += QLatin1Char(' '); - result += QString::number(s.height()); - result += QLatin1Char(')'); - object.insert(key, result); - break; - } - case QVariant::Point: { - QPoint p = qvariant_cast(variant); - QString result = QLatin1String("@Point("); - result += QString::number(p.x()); - result += QLatin1Char(' '); - result += QString::number(p.y()); - result += QLatin1Char(')'); - object.insert(key, result); - break; - } - - default: { - QByteArray array; - { - QDataStream stream(&array, QIODevice::WriteOnly); - stream.setVersion(QDataStream::Qt_4_0); - stream << variant; - } - - QString result = QLatin1String("@Variant("); - result += QString::fromLatin1(array.constData(), array.size()); - result += QLatin1Char(')'); - object.insert(key, result); - break; - } - } - } - - qDebug() << Q_FUNC_INFO << object.size() << "in json"; - - return QJsonDocument(object); -} - - -QSettings::SettingsMap jsonDocumentToVariantMap(const QJsonDocument& document) { - if (!document.isObject()) { - qWarning() << "Settings file does not contain a JSON object"; - return QSettings::SettingsMap(); - } - auto object = document.object(); - qDebug() << Q_FUNC_INFO << object.size() << "in json"; - QSettings::SettingsMap map; - - for (auto it = object.begin(); it != object.end(); ++it) { - - QVariant result; - - if (!it->isString()) { - result = it->toVariant(); - } else { - auto string = it->toString(); - - if (string.startsWith(QLatin1String("@@"))) { - result = QVariant(string.mid(1)); - - } else if (string.startsWith(QLatin1Char('@'))) { - - if (string.endsWith(QLatin1Char(')'))) { - - if (string.startsWith(QLatin1String("@ByteArray("))) { - result = QVariant(string.toLatin1().mid(11, string.size() - 12)); - - } else if (string.startsWith(QLatin1String("@Variant("))) { - QByteArray a(string.toLatin1().mid(9)); - QDataStream stream(&a, QIODevice::ReadOnly); - stream.setVersion(QDataStream::Qt_4_0); - stream >> result; - - } else if (string.startsWith(QLatin1String("@Rect("))) { - QStringList args = splitArgs(string, 5); - if (args.size() == 4) { - result = QRect(args[0].toInt(), args[1].toInt(), - args[2].toInt(), args[3].toInt()); - } - - } else if (string.startsWith(QLatin1String("@Size("))) { - QStringList args = splitArgs(string, 5); - if (args.size() == 2) { - result = QSize(args[0].toInt(), args[1].toInt()); - } - - } else if (string.startsWith(QLatin1String("@Point("))) { - QStringList args = splitArgs(string, 6); - if (args.size() == 2) { - result = QPoint(args[0].toInt(), args[1].toInt()); - } - } - } - } - } - - map.insert(it.key(), result); - } - - qDebug() << Q_FUNC_INFO << map.size() << "in map"; - return map; -} - -bool readJSONFile(QIODevice& device, QSettings::SettingsMap& map) { - QJsonParseError jsonParseError; - - auto bytesRead = device.readAll(); - auto document = QJsonDocument::fromJson(bytesRead, &jsonParseError); - - if (jsonParseError.error != QJsonParseError::NoError) { - qDebug() << "Error parsing QSettings file:" << jsonParseError.errorString(); - return false; - } - - map = jsonDocumentToVariantMap(document); - - return true; -} -bool writeJSONFile(QIODevice& device, const QSettings::SettingsMap& map) { - auto document = variantMapToJsonDocument(map); - auto jsonByteArray = document.toJson(QJsonDocument::Indented); - auto bytesWritten = device.write(jsonByteArray); - return bytesWritten == jsonByteArray.size(); -} - -const auto jsonFormat = QSettings::registerFormat("json", readJSONFile, writeJSONFile); - namespace Setting { static QSharedPointer globalManager; @@ -279,45 +45,13 @@ namespace Setting { // Sets up the settings private instance. Should only be run once at startup. preInit() must be run beforehand, void init() { // Set settings format - QSettings::setDefaultFormat(jsonFormat); + QSettings::setDefaultFormat(JSON_FORMAT); QSettings settings; - if (settings.allKeys().size() == 0) { - - QSettings::setDefaultFormat(QSettings::IniFormat); - QSettings iniSettings; - if (iniSettings.allKeys().size()) { - qDebug() << "No data in json settings file, trying to load old ini settings file."; - - for (auto key : iniSettings.allKeys()) { - auto variant = iniSettings.value(key); - - if (variant.type() == QVariant::String) { - auto string = variant.toString(); - if (string == "true") { - variant = true; - } else if (string == "false") { - variant = false; - } else { - bool ok; - double value = string.toDouble(&ok); - if (ok) { - variant = value; - } - } - } - settings.setValue(key, variant); - } - - qDebug() << "Loaded" << settings.allKeys().size() << "keys from ini settings file."; - } - - QSettings::setDefaultFormat(jsonFormat); + if (settings.allKeys().isEmpty()) { + loadOldINIFile(settings); } - - qDebug() << "First run:" << settings.contains("firstRun") << settings.value("firstRun", true); - // Delete Interface.ini.lock file if it exists, otherwise Interface freezes. QString settingsLockFilename = settings.fileName() + ".lock"; QFile settingsLockFile(settingsLockFilename);