140 lines
5.1 KiB
C++
140 lines
5.1 KiB
C++
#pragma once
|
|
|
|
#include "configobject.hpp"
|
|
|
|
#include <QJsonArray>
|
|
#include <QJsonObject>
|
|
#include <QQmlEngine>
|
|
#include <QVariantList>
|
|
|
|
namespace ZShell::config {
|
|
|
|
class ConfigList : public ConfigNode {
|
|
Q_OBJECT
|
|
QML_ANONYMOUS
|
|
|
|
Q_PROPERTY(int count READ count NOTIFY countChanged)
|
|
Q_PROPERTY(QVariantList values READ values NOTIFY valuesChanged)
|
|
|
|
public:
|
|
explicit ConfigList(
|
|
QObject* parent = nullptr, const QVariantList& defaults = {});
|
|
|
|
[[nodiscard]] int count() const;
|
|
[[nodiscard]] QVariantList values() const;
|
|
[[nodiscard]] ConfigObject* itemAt(int index) const;
|
|
[[nodiscard]] const QList<ConfigObject*>& items() const;
|
|
|
|
Q_INVOKABLE void remove(int index);
|
|
Q_INVOKABLE void move(int from, int to);
|
|
Q_INVOKABLE void clear();
|
|
|
|
void loadFromJson(const QJsonValue& json) override;
|
|
[[nodiscard]] QJsonValue toJson() const override;
|
|
void clearLoadedKeys() override;
|
|
[[nodiscard]] QStringList unknownKeys() const override;
|
|
void materializeDefaults() override;
|
|
void resyncFromGlobal() override;
|
|
|
|
signals:
|
|
void countChanged();
|
|
void valuesChanged();
|
|
|
|
protected:
|
|
virtual ConfigObject* createItem() = 0;
|
|
|
|
void resetToDefaults();
|
|
|
|
ConfigObject* insertItem(const QVariantMap& props, int index = -1);
|
|
|
|
[[nodiscard]] QJsonArray elementsToJson() const;
|
|
|
|
void syncValuesFromGlobal() override;
|
|
void onGlobalPropertiesChanged(
|
|
const QMap<QString, QVariant>& changed) override;
|
|
[[nodiscard]] QString childPath(const ConfigNode* child) const override;
|
|
|
|
private:
|
|
void populate(const QJsonArray& arr);
|
|
static bool sameElement(
|
|
const ConfigObject* item,
|
|
const QJsonValue& current,
|
|
const QJsonValue& json);
|
|
void appendItem(const QJsonValue& json);
|
|
void destroyItems();
|
|
void destroyItem(ConfigObject* item);
|
|
void rejectGlobalOnlyElement(const ConfigObject* item) const;
|
|
void connectItem(ConfigNode* node);
|
|
void disconnectItem(ConfigNode* node);
|
|
void onItemChanged();
|
|
void notifyChanged();
|
|
|
|
QJsonArray m_defaults;
|
|
QList<ConfigObject*> m_items;
|
|
bool m_loaded = false;
|
|
};
|
|
|
|
} // namespace ZShell::config
|
|
|
|
#define CONFIG_LIST_TYPE(Element, Name) \
|
|
class Name : public ZShell::config::ConfigList { \
|
|
Q_OBJECT \
|
|
QML_ANONYMOUS \
|
|
\
|
|
public: \
|
|
explicit Name( \
|
|
QObject* parent = nullptr, const QVariantList& defaults = {}) \
|
|
: ZShell::config::ConfigList(parent, defaults) { \
|
|
resetToDefaults(); \
|
|
} \
|
|
\
|
|
Q_INVOKABLE ZShell::config::Element* at(int index) const { \
|
|
return static_cast<ZShell::config::Element*>(itemAt(index)); \
|
|
} \
|
|
Q_INVOKABLE ZShell::config::Element* insert( \
|
|
const QVariantMap& props, int index = -1) { \
|
|
return static_cast<ZShell::config::Element*>( \
|
|
insertItem(props, index)); \
|
|
} \
|
|
\
|
|
protected: \
|
|
[[nodiscard]] ZShell::config::ConfigObject* createItem() override { \
|
|
return new ZShell::config::Element(this); \
|
|
} \
|
|
};
|
|
|
|
#define CONFIG_LIST(Type, name, ...) \
|
|
Q_PROPERTY(ZShell::config::Type* name READ name CONSTANT) \
|
|
\
|
|
public: \
|
|
[[nodiscard]] Type* name() const { \
|
|
return m_##name; \
|
|
} \
|
|
\
|
|
private: \
|
|
Type* m_##name = new Type(this __VA_OPT__(, __VA_ARGS__));
|
|
|
|
#define LIST_ENTRY(id, enabled) \
|
|
vmap({{"id", QString::fromUtf8(#id)}, {"enabled", enabled}})
|
|
|
|
namespace ZShell::config {
|
|
|
|
class ListEntry : public ConfigObject {
|
|
Q_OBJECT
|
|
QML_ANONYMOUS
|
|
|
|
CFG_PROPERTY(QString, id)
|
|
CFG_PROPERTY(bool, enabled, true)
|
|
|
|
public:
|
|
explicit ListEntry(QObject* parent = nullptr) : ConfigObject(parent) {}
|
|
|
|
[[nodiscard]] QStringList identityKeys() const override {
|
|
return {QStringLiteral("id")};
|
|
}
|
|
};
|
|
|
|
CONFIG_LIST_TYPE(ListEntry, EntryList)
|
|
|
|
} // namespace ZShell::config
|