Pith - whittle
whittle/src/core/ConfigStore.cpp [5.0 kb]
Modified: 19:51:41 130 026 (27 Jul 026)
0 Days Ago
#include "core/ConfigStore.h"
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QSaveFile>
#include <QStandardPaths>
#include <algorithm>

namespace whittle {
namespace {

QJsonObject readJson(const QString& path) {
    QFile f(path);
    if (!f.open(QIODevice::ReadOnly)) return {};
    const QJsonDocument doc = QJsonDocument::fromJson(f.readAll());
    return doc.isObject() ? doc.object() : QJsonObject{};
}

bool writeJson(const QString& path, const QJsonObject& obj) {
    QDir().mkpath(QFileInfo(path).absolutePath());
    QSaveFile f(path);
    if (!f.open(QIODevice::WriteOnly)) return false;
    f.write(QJsonDocument(obj).toJson(QJsonDocument::Indented));
    return f.commit();
}

QString settingsPath() { return ConfigStore::configDir() + "/settings.json"; }
QString schemesPath()  { return ConfigStore::configDir() + "/schemes.json";  }

constexpr char kSchemes[] = "schemes";

} // namespace

QString ConfigStore::configDir() {
    QString base = QStandardPaths::writableLocation(
                       QStandardPaths::GenericConfigLocation);
    if (base.isEmpty()) base = QDir::homePath() + "/.config";
    const QString dir = base + "/whittle";
    QDir().mkpath(dir);
    return dir;
}

FilterSettings ConfigStore::loadFilter() {
    FilterSettings f;
    const QJsonObject o = readJson(settingsPath());
    if (o.isEmpty()) return f;

    f.compareSize = o.value("compareSize").toBool(f.compareSize);
    f.compareTime = o.value("compareTime").toBool(f.compareTime);
    if (!f.compareSize && !f.compareTime) f.compareSize = f.compareTime = true;

    f.toleranceNs = qint64(o.value("toleranceNs").toDouble(double(f.toleranceNs)));
    f.display = (o.value("display").toString() == QLatin1String("all"))
                    ? FilterSettings::Display::All
                    : FilterSettings::Display::OnlyDiff;
    f.recursive      = o.value("recursive").toBool(f.recursive);
    f.loadLastScheme = o.value("loadLastScheme").toBool(f.loadLastScheme);
    return f;
}

bool ConfigStore::saveFilter(const FilterSettings& f) {
    QJsonObject o = readJson(settingsPath());
    o["compareSize"] = f.compareSize;
    o["compareTime"] = f.compareTime;
    o["toleranceNs"] = double(f.toleranceNs);
    o["display"] = (f.display == FilterSettings::Display::All)
                       ? QStringLiteral("all") : QStringLiteral("diff");
    o["recursive"]      = f.recursive;
    o["loadLastScheme"] = f.loadLastScheme;
    return writeJson(settingsPath(), o);
}

QString ConfigStore::loadLastSchemeName() {
    return readJson(settingsPath()).value("lastScheme").toString();
}

bool ConfigStore::saveLastSchemeName(const QString& name) {
    QJsonObject o = readJson(settingsPath());
    o["lastScheme"] = name;
    return writeJson(settingsPath(), o);
}

QStringList ConfigStore::schemeNames() {
    const QJsonObject all = readJson(schemesPath())
                                .value(kSchemes).toObject();
    QStringList names = all.keys();
    std::sort(names.begin(), names.end(), [](const QString& a, const QString& b) {
        return a.compare(b, Qt::CaseInsensitive) < 0;
    });
    return names;
}

bool ConfigStore::hasScheme(const QString& name) {
    return readJson(schemesPath()).value(kSchemes).toObject().contains(name);
}

bool ConfigStore::saveScheme(const QString& name, const Scheme& s) {
    if (name.trimmed().isEmpty()) return false;

    QJsonObject root = readJson(schemesPath());
    QJsonObject all  = root.value(kSchemes).toObject();

    QJsonArray roots;
    for (const QString& r : s.roots) roots.append(r);

    QJsonArray excluded;
    for (const QString& e : s.excluded) excluded.append(e);

    QJsonObject entry;
    entry["recursive"] = s.recursive;
    entry["roots"]     = roots;
    entry["excluded"]  = excluded;

    all[name] = entry;
    root[kSchemes] = all;
    return writeJson(schemesPath(), root);
}

ConfigStore::Scheme ConfigStore::loadScheme(const QString& name, bool* found) {
    Scheme s;
    const QJsonObject all = readJson(schemesPath()).value(kSchemes).toObject();
    const auto it = all.find(name);
    if (it == all.end()) { if (found) *found = false; return s; }

    const QJsonObject entry = it->toObject();
    s.recursive = entry.value("recursive").toBool(true);
    for (const QJsonValue& v : entry.value("roots").toArray()) {
        const QString p = v.toString();
        if (!p.isEmpty()) s.roots << p;
    }
    for (const QJsonValue& v : entry.value("excluded").toArray()) {
        const QString p = v.toString();
        if (!p.isEmpty()) s.excluded << p;
    }
    if (found) *found = true;
    return s;
}

bool ConfigStore::deleteScheme(const QString& name) {
    QJsonObject root = readJson(schemesPath());
    QJsonObject all  = root.value(kSchemes).toObject();
    if (!all.contains(name)) return false;

    all.remove(name);
    root[kSchemes] = all;
    if (!writeJson(schemesPath(), root)) return false;

    if (loadLastSchemeName() == name) saveLastSchemeName(QString());
    return true;
}

} 
Updates
Whittle - Linux 130.026
Wedge - Android 126.026
Wedge - Linux 124.026
Shim - Android 117.026
Miter - 114.026
Dev
TVShow (227) 'CSA'
TVShow (228) 'APT'
TVProgram (83) 'BXT'
Miter Update(s)
Peen (Messaging)

Menu
Calendar
Project Tin (024/029)
Miter
RSS Feed
User Avatar
@vgmlr
=SUM(parts)