Files

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