File indexing completed on 2025-01-05 04:54:58
0001 /* 0002 Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> 0003 0004 This library is free software; you can redistribute it and/or modify it 0005 under the terms of the GNU Library General Public License as published by 0006 the Free Software Foundation; either version 2 of the License, or (at your 0007 option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, but WITHOUT 0010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 0012 License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to the 0016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0017 02110-1301, USA. 0018 */ 0019 #pragma once 0020 #include "kube_export.h" 0021 #include <QObject> 0022 #include <QVariant> 0023 #include <QAbstractItemModel> 0024 #include <QStandardItemModel> 0025 #include <QQmlParserStatus> 0026 #include <KAsync/Async> 0027 0028 #define KUBE_CONTROLLER_PROPERTY(TYPE, NAME, LOWERCASENAME) \ 0029 public: Q_PROPERTY(TYPE LOWERCASENAME READ get##NAME WRITE setInternal##NAME NOTIFY LOWERCASENAME##Changed) \ 0030 Q_SIGNALS: void LOWERCASENAME##Changed(); \ 0031 private: TYPE m##NAME; \ 0032 public: \ 0033 struct NAME { \ 0034 static constexpr const char *name = #LOWERCASENAME; \ 0035 typedef TYPE Type; \ 0036 }; \ 0037 void set##NAME(const TYPE &value) { setProperty(NAME::name, QVariant::fromValue(value)); } \ 0038 void setInternal##NAME(const TYPE &value) { if (m##NAME != value) {m##NAME = value; emit LOWERCASENAME##Changed(); propertyChanged(NAME::name);} } \ 0039 void clear##NAME() { setProperty(NAME::name, QVariant{}); } \ 0040 TYPE get##NAME() const { return m##NAME; } \ 0041 0042 0043 #define KUBE_CONTROLLER_ACTION(NAME) \ 0044 Q_PROPERTY (Kube::ControllerAction* NAME##Action READ NAME##Action CONSTANT) \ 0045 private: QScopedPointer<Kube::ControllerAction> action_##NAME; \ 0046 public: Kube::ControllerAction* NAME##Action() const { Q_ASSERT(action_##NAME); return action_##NAME.data(); } \ 0047 private slots: void NAME(); \ 0048 0049 #define KUBE_CONTROLLER_LISTCONTROLLER(NAME) \ 0050 Q_PROPERTY (Kube::ListPropertyController* NAME READ NAME##Controller CONSTANT) \ 0051 private: QScopedPointer<Kube::ListPropertyController> controller_##NAME; \ 0052 public: Kube::ListPropertyController* NAME##Controller() const { Q_ASSERT(controller_##NAME); return controller_##NAME.data(); } \ 0053 0054 0055 namespace Kube { 0056 0057 class ControllerState : public QObject { 0058 Q_OBJECT 0059 Q_PROPERTY(bool enabled MEMBER mEnabled NOTIFY enabledChanged) 0060 public: 0061 ControllerState(); 0062 ~ControllerState() = default; 0063 0064 void setEnabled(bool enabled) { setProperty("enabled", enabled); } 0065 0066 signals: 0067 void enabledChanged(); 0068 0069 private: 0070 bool mEnabled = false; 0071 }; 0072 0073 class KUBE_EXPORT ControllerAction : public ControllerState { 0074 Q_OBJECT 0075 public: 0076 ControllerAction(); 0077 template <typename Func> 0078 ControllerAction(const typename QtPrivate::FunctionPointer<Func>::Object *obj, Func slot) 0079 : ControllerAction() 0080 { 0081 QObject::connect(this, &ControllerAction::triggered, obj, slot); 0082 } 0083 0084 ~ControllerAction() = default; 0085 0086 Q_INVOKABLE void execute(); 0087 0088 signals: 0089 void triggered(); 0090 }; 0091 0092 class Controller : public QObject, public QQmlParserStatus { 0093 Q_OBJECT 0094 Q_INTERFACES(QQmlParserStatus) 0095 Q_PROPERTY(bool modified READ modified WRITE setModified NOTIFY modifiedChanged) 0096 0097 public: 0098 Controller() = default; 0099 virtual ~Controller() = default; 0100 0101 virtual void init(); 0102 0103 void classBegin() override; 0104 void componentComplete() override; 0105 bool modified() const; 0106 void setModified(bool); 0107 void propertyChanged(const QByteArray &); 0108 0109 public slots: 0110 virtual void clear(); 0111 0112 signals: 0113 void done(); 0114 void error(); 0115 void cleared(); 0116 void modifiedChanged(); 0117 0118 protected: 0119 void run(const KAsync::Job<void> &job); 0120 0121 private: 0122 bool mModified{false}; 0123 }; 0124 0125 class KUBE_EXPORT ListPropertyController : public QObject 0126 { 0127 Q_OBJECT 0128 Q_PROPERTY(QAbstractItemModel* model READ model CONSTANT) 0129 Q_PROPERTY(bool empty READ empty NOTIFY emptyChanged) 0130 0131 public: 0132 ListPropertyController(const QStringList &roles); 0133 Q_INVOKABLE virtual void add(const QVariantMap &value); 0134 Q_INVOKABLE virtual void remove(const QByteArray &id); 0135 Q_INVOKABLE void clear(); 0136 0137 QAbstractItemModel *model(); 0138 0139 void setValue(const QByteArray &id, const QString &key, const QVariant &); 0140 void setValues(const QByteArray &id, const QVariantMap &values); 0141 QVariant value(const QByteArray &id, const QString &key); 0142 void traverse(const std::function<void(const QVariantMap &)> &f); 0143 0144 QByteArray findByProperty(const QByteArray &key, const QVariant &) const; 0145 0146 template<typename T> 0147 QList<T> getList(const QString &property) 0148 { 0149 QList<T> list; 0150 traverse([&] (const QVariantMap &map) { 0151 list << map[property].value<T>(); 0152 }); 0153 return list; 0154 } 0155 0156 bool empty() const; 0157 0158 Q_SIGNALS: 0159 void added(QByteArray, QVariantMap); 0160 void removed(QByteArray); 0161 void emptyChanged(); 0162 0163 protected: 0164 QScopedPointer<QStandardItemModel> mModel; 0165 0166 private: 0167 QHash<QString, int> mRoles; 0168 }; 0169 0170 0171 }