#include "settings.h" #include #include #include #include #include #include #include #include #include #include namespace LtsUtils { enum class SettingType { String = 1, StringList = 2, Json = 3, FunctionKeys = 4, Boolean = 5, }; QString typeToString(SettingType t) { switch (t) { case SettingType::String: return QStringLiteral("String"); case SettingType::StringList: return QStringLiteral("StringList"); case SettingType::Json: return QStringLiteral("Json"); case SettingType::FunctionKeys: return QStringLiteral("FunctionKeys"); case SettingType::Boolean: return QStringLiteral("Boolean"); } Q_ASSERT(false); return QStringLiteral("Unknown SettingType (%1)").arg(int(t)); } SettingType stringToType(const QString &s) { if (s == typeToString(SettingType::String)) return SettingType::String; if (s == typeToString(SettingType::StringList)) return SettingType::StringList; if (s == typeToString(SettingType::Json)) return SettingType::Json; if (s == typeToString(SettingType::FunctionKeys)) return SettingType::FunctionKeys; if (s == typeToString(SettingType::Boolean)) return SettingType::Boolean; Q_ASSERT(false); return SettingType::String; } static QString craftKey(const QString &group, const QString &identifier) { return group + QLatin1Char('.') + identifier; } static OperatorSettings *s_operatorSettings = nullptr; static void cleanupOperatorSettings() { delete s_operatorSettings; s_operatorSettings = nullptr; } OperatorSettings *OperatorSettings::getInstance() { if (!s_operatorSettings) { s_operatorSettings = new OperatorSettings; qAddPostRoutine(&cleanupOperatorSettings); } return s_operatorSettings; } static ProjectSettings *s_projectSettings = nullptr; static void cleanupProjectSettings() { delete s_projectSettings; s_projectSettings = nullptr; } ProjectSettings *ProjectSettings::getInstance() { if (!s_projectSettings) { s_projectSettings = new ProjectSettings; qAddPostRoutine(&cleanupProjectSettings); } return s_projectSettings; } bool ProjectSettings::initFromFile(const QString &filename) { QFile f(filename); if (!f.open(QIODevice::ReadOnly)) return false; QJsonParseError jErr; const QJsonObject settings = QJsonDocument::fromJson(f.readAll(), &jErr).object(); if (jErr.error != QJsonParseError::NoError) return false; const QJsonObject psObj = settings[QStringLiteral("ProjectSettings")].toObject(); if (psObj.isEmpty()) return false; QHash newData; const QStringList &groupKeys(psObj.keys()); for (const auto &gKey : groupKeys) { const QJsonObject objGroup(psObj[gKey].toObject()); const QStringList &itemKeys(objGroup.keys()); for (const auto &key : itemKeys) { const QJsonObject obj(objGroup[key].toObject()); const auto strType(obj[QStringLiteral("Type")].toString()); const auto type = stringToType(strType); const QJsonValue jVal(obj[QStringLiteral("Default")]); QVariant val; switch (type) { case SettingType::Json: val = QJsonDocument(jVal.toObject()).toJson(); break; case SettingType::StringList: { const QJsonArray arr(jVal.toArray()); QStringList sl; sl.reserve(arr.size()); for (const auto &ele : arr) sl.push_back(ele.toString()); val = sl; break; } case SettingType::FunctionKeys: val = jVal.toVariant(); break; case SettingType::String: val = jVal.toString(); break; case SettingType::Boolean: val = jVal.toBool(); break; } newData[craftKey(gKey, key)] = val; } } getInstance()->m_data = newData; return true; } bool ProjectSettings::isFunctionEnabled(const QString &group, const QString &function) { const QStringList functionNames = getInstance()->value(QStringLiteral("Functionalities"), QStringLiteral("IdentifierList")).toStringList(); return functionNames.contains(group + QLatin1Char(':') + function); } void Settings::init(const QByteArray &settings) { QByteArray uncompressed; try { uncompressed = qUncompress(settings); } catch (...) {} if (uncompressed.isEmpty()) uncompressed = settings; QDataStream stream(uncompressed); stream >> m_data; } QByteArray Settings::exportSettings() const { if (m_data.isEmpty()) return QByteArray(); QByteArray ba; QDataStream stream(&ba, QIODevice::WriteOnly); stream << m_data; return qCompress(ba); } void Settings::clear() { m_data.clear(); } void Settings::dump() { qWarning() << "Settings::m_data: keys=" << m_data.keys(); QHashIterator it(m_data); int i=0; while (it.hasNext()) { it.next(); qWarning() << i++ << ":" << " - key='" << it.key() << "' value -> '" << it.value() << "'"; } qWarning() << "Settings::m_data: ------------------"; } void Settings::setValue(const QString &group, const QString &identifier, const QVariant &value) { m_data.insert(craftKey(group, identifier), value); emit valueChanged(group, identifier, value); } void Settings::removeValue(const QString &group, const QString &identifier) { if (m_data.remove(craftKey(group, identifier))) emit valueRemoved(group, identifier); } QStringList Settings::identifiers(const QString &group) const { QStringList result; for (auto it = m_data.begin(); it != m_data.end(); ++it) { QVector decrafted = it.key().splitRef(QLatin1Char('.')); if (decrafted.size() > 1 && group.compare(decrafted.at(0)) == 0) result.append(decrafted.at(1).toString()); } return result; } QVariant Settings::value(const QString &group, const QString &identifier, const QVariant &defaultValue) const { return m_data.value(craftKey(group, identifier), defaultValue); } }