From 8b9eb39b8051fe4ed9e772bf8787c95033087f65 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Mon, 12 Mar 2018 14:25:01 +0100 Subject: [PATCH] more work on rules --- libnymea-common/types/eventdescriptor.cpp | 8 +- libnymea-common/types/eventdescriptor.h | 16 ++-- libnymea-common/types/paramdescriptors.cpp | 5 +- libnymea-common/types/rule.cpp | 4 +- libnymea-common/types/ruleactionparam.cpp | 26 ++++++ libnymea-common/types/ruleactionparam.h | 13 +++ libnymea-common/types/ruleactionparams.cpp | 22 +++++ libnymea-common/types/ruleactionparams.h | 5 +- mea/jsonrpc/jsonrpcclient.cpp | 2 +- mea/jsonrpc/jsontypes.cpp | 7 +- mea/main.cpp | 3 + mea/mea.pro | 6 +- .../eventdescriptorparamsfiltermodel.cpp | 86 +++++++++++++++++++ mea/models/eventdescriptorparamsfiltermodel.h | 44 ++++++++++ mea/models/rulesfiltermodel.cpp | 6 +- mea/models/rulesfiltermodel.h | 8 +- mea/rulemanager.cpp | 28 +++--- mea/ui/magic/EditRulePage.qml | 5 +- .../magic/SelectEventDescriptorParamsPage.qml | 26 +++++- mea/ui/magic/SelectRuleActionPage.qml | 9 +- mea/ui/magic/SelectRuleActionParamsPage.qml | 76 ++++++++++++++-- mea/ui/magic/SimpleStateEvaluatorDelegate.qml | 4 + mea/ui/magic/StateEvaluatorDelegate.qml | 6 +- 23 files changed, 360 insertions(+), 55 deletions(-) create mode 100644 mea/models/eventdescriptorparamsfiltermodel.cpp create mode 100644 mea/models/eventdescriptorparamsfiltermodel.h diff --git a/libnymea-common/types/eventdescriptor.cpp b/libnymea-common/types/eventdescriptor.cpp index e456e305..930f7965 100644 --- a/libnymea-common/types/eventdescriptor.cpp +++ b/libnymea-common/types/eventdescriptor.cpp @@ -5,12 +5,12 @@ EventDescriptor::EventDescriptor(QObject *parent) : QObject(parent) m_paramDescriptors = new ParamDescriptors(this); } -QUuid EventDescriptor::deviceId() const +QString EventDescriptor::deviceId() const { return m_deviceId; } -void EventDescriptor::setDeviceId(const QUuid &deviceId) +void EventDescriptor::setDeviceId(const QString &deviceId) { if (m_deviceId != deviceId) { m_deviceId = deviceId; @@ -18,12 +18,12 @@ void EventDescriptor::setDeviceId(const QUuid &deviceId) } } -QUuid EventDescriptor::eventTypeId() const +QString EventDescriptor::eventTypeId() const { return m_eventTypeId; } -void EventDescriptor::setEventTypeId(const QUuid &eventTypeId) +void EventDescriptor::setEventTypeId(const QString &eventTypeId) { if (m_eventTypeId != eventTypeId) { m_eventTypeId = eventTypeId; diff --git a/libnymea-common/types/eventdescriptor.h b/libnymea-common/types/eventdescriptor.h index 89fc5ae5..0153b815 100644 --- a/libnymea-common/types/eventdescriptor.h +++ b/libnymea-common/types/eventdescriptor.h @@ -9,8 +9,8 @@ class EventDescriptor : public QObject { Q_OBJECT - Q_PROPERTY(QUuid deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged) - Q_PROPERTY(QUuid eventTypeId READ eventTypeId WRITE setEventTypeId NOTIFY eventTypeIdChanged) + Q_PROPERTY(QString deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged) + Q_PROPERTY(QString eventTypeId READ eventTypeId WRITE setEventTypeId NOTIFY eventTypeIdChanged) Q_PROPERTY(QString interfaceName READ interfaceName WRITE setInterfaceName NOTIFY interfaceNameChanged) Q_PROPERTY(QString interfaceEvent READ interfaceEvent WRITE setInterfaceEvent NOTIFY interfaceEventChanged) @@ -20,11 +20,11 @@ class EventDescriptor : public QObject public: explicit EventDescriptor(QObject *parent = nullptr); - QUuid deviceId() const; - void setDeviceId(const QUuid &deviceId); + QString deviceId() const; + void setDeviceId(const QString &deviceId); - QUuid eventTypeId() const; - void setEventTypeId(const QUuid &eventTypeId); + QString eventTypeId() const; + void setEventTypeId(const QString &eventTypeId); QString interfaceName() const; void setInterfaceName(const QString &interfaceName); @@ -43,8 +43,8 @@ signals: void interfaceEventChanged(); private: - QUuid m_deviceId; - QUuid m_eventTypeId; + QString m_deviceId; + QString m_eventTypeId; QString m_interfaceName; QString m_interfaceEvent; diff --git a/libnymea-common/types/paramdescriptors.cpp b/libnymea-common/types/paramdescriptors.cpp index b88e2b96..fcb47fe5 100644 --- a/libnymea-common/types/paramdescriptors.cpp +++ b/libnymea-common/types/paramdescriptors.cpp @@ -36,7 +36,10 @@ QHash ParamDescriptors::roleNames() const ParamDescriptor *ParamDescriptors::get(int index) const { - return m_list.at(index); + if (index >= 0 && index < m_list.count()) { + return m_list.at(index); + } + return nullptr; } ParamDescriptor *ParamDescriptors::createNewParamDescriptor() const diff --git a/libnymea-common/types/rule.cpp b/libnymea-common/types/rule.cpp index f14a2290..40fbdf9c 100644 --- a/libnymea-common/types/rule.cpp +++ b/libnymea-common/types/rule.cpp @@ -88,7 +88,9 @@ void Rule::setStateEvaluator(StateEvaluator *stateEvaluator) m_stateEvaluator->deleteLater(); } m_stateEvaluator = stateEvaluator; - m_stateEvaluator->setParent(this); + if (m_stateEvaluator) { // Might be a nullptr now if cleared + m_stateEvaluator->setParent(this); + } emit stateEvaluatorChanged(); } diff --git a/libnymea-common/types/ruleactionparam.cpp b/libnymea-common/types/ruleactionparam.cpp index 85ad3db3..7558c8f7 100644 --- a/libnymea-common/types/ruleactionparam.cpp +++ b/libnymea-common/types/ruleactionparam.cpp @@ -31,6 +31,32 @@ void RuleActionParam::setValue(const QVariant &value) } } +QString RuleActionParam::eventTypeId() const +{ + return m_eventTypeId; +} + +void RuleActionParam::setEventTypeId(const QString &eventTypeId) +{ + if (m_eventTypeId != eventTypeId) { + m_eventTypeId = eventTypeId; + emit eventTypeIdChanged(); + } +} + +QString RuleActionParam::eventParamTypeId() const +{ + return m_eventParamTypeId; +} + +void RuleActionParam::setEventParamTypeId(const QString &eventParamTypeId) +{ + if (m_eventParamTypeId != eventParamTypeId) { + m_eventParamTypeId = eventParamTypeId; + emit eventParamTypeIdChanged(); + } +} + RuleActionParam *RuleActionParam::clone() const { RuleActionParam *ret = new RuleActionParam(); diff --git a/libnymea-common/types/ruleactionparam.h b/libnymea-common/types/ruleactionparam.h index be9a9a18..57ef93c7 100644 --- a/libnymea-common/types/ruleactionparam.h +++ b/libnymea-common/types/ruleactionparam.h @@ -10,6 +10,8 @@ class RuleActionParam : public QObject Q_OBJECT Q_PROPERTY(QUuid paramTypeId READ paramTypeId NOTIFY paramTypeIdChanged) Q_PROPERTY(QVariant value READ value NOTIFY valueChanged) + Q_PROPERTY(QString eventTypeId READ eventTypeId WRITE setEventTypeId NOTIFY eventTypeIdChanged) + Q_PROPERTY(QString eventParamTypeId READ eventParamTypeId WRITE setEventParamTypeId NOTIFY eventParamTypeIdChanged) public: explicit RuleActionParam(QObject *parent = nullptr); @@ -19,14 +21,25 @@ public: QVariant value() const; void setValue(const QVariant &value); + QString eventTypeId() const; + void setEventTypeId(const QString &eventTypeId); + + QString eventParamTypeId() const; + void setEventParamTypeId(const QString &eventParamTypeId); + RuleActionParam* clone() const; signals: void paramTypeIdChanged(); void valueChanged(); + void eventTypeIdChanged(); + void eventParamTypeIdChanged(); + private: QUuid m_paramTypeId; QVariant m_value; + QString m_eventTypeId; + QString m_eventParamTypeId; }; #endif // RULEACTIONPARAM_H diff --git a/libnymea-common/types/ruleactionparams.cpp b/libnymea-common/types/ruleactionparams.cpp index d557b1ad..24b0b28b 100644 --- a/libnymea-common/types/ruleactionparams.cpp +++ b/libnymea-common/types/ruleactionparams.cpp @@ -20,6 +20,10 @@ QVariant RuleActionParams::data(const QModelIndex &index, int role) const return m_list.at(index.row())->paramTypeId(); case RoleValue: return m_list.at(index.row())->value(); + case RoleEventTypeId: + return m_list.at(index.row())->eventTypeId(); + case RoleEventParamTypeId: + return m_list.at(index.row())->eventParamTypeId(); } return QVariant(); } @@ -29,6 +33,8 @@ QHash RuleActionParams::roleNames() const QHash roles; roles.insert(RoleParamTypeId, "paramTypeId"); roles.insert(RoleValue, "value"); + roles.insert(RoleEventTypeId, "eventTypeId"); + roles.insert(RoleEventParamTypeId, "eventParamTypeId"); return roles; } @@ -56,6 +62,22 @@ void RuleActionParams::setRuleActionParam(const QString ¶mTypeId, const QVar addRuleActionParam(rap); } +void RuleActionParams::setRuleActionParamEvent(const QString ¶mTypeId, const QString &eventTypeId, const QString &eventParamTypeId) +{ + foreach (RuleActionParam *rap, m_list) { + if (rap->paramTypeId() == paramTypeId) { + rap->setEventTypeId(eventTypeId); + rap->setEventParamTypeId(eventParamTypeId); + return; + } + } + RuleActionParam *rap = new RuleActionParam(this); + rap->setParamTypeId(paramTypeId); + rap->setEventTypeId(eventTypeId); + rap->setEventParamTypeId(eventParamTypeId); + addRuleActionParam(rap); +} + RuleActionParam *RuleActionParams::get(int index) const { return m_list.at(index); diff --git a/libnymea-common/types/ruleactionparams.h b/libnymea-common/types/ruleactionparams.h index fea79989..c3a0b6d0 100644 --- a/libnymea-common/types/ruleactionparams.h +++ b/libnymea-common/types/ruleactionparams.h @@ -12,7 +12,9 @@ class RuleActionParams : public QAbstractListModel public: enum Roles { RoleParamTypeId, - RoleValue + RoleValue, + RoleEventTypeId, + RoleEventParamTypeId }; Q_ENUM(Roles) @@ -25,6 +27,7 @@ public: void addRuleActionParam(RuleActionParam* ruleActionParam); Q_INVOKABLE void setRuleActionParam(const QString ¶mTypeId, const QVariant &value); + Q_INVOKABLE void setRuleActionParamEvent(const QString ¶mTypeId, const QString &eventTypeId, const QString &eventParamTypeId); Q_INVOKABLE RuleActionParam* get(int index) const; signals: diff --git a/mea/jsonrpc/jsonrpcclient.cpp b/mea/jsonrpc/jsonrpcclient.cpp index 5726c12e..95237477 100644 --- a/mea/jsonrpc/jsonrpcclient.cpp +++ b/mea/jsonrpc/jsonrpcclient.cpp @@ -158,7 +158,7 @@ void JsonRpcClient::sendRequest(const QVariantMap &request) { QVariantMap newRequest = request; newRequest.insert("token", m_token); -// qDebug() << "Sending request" << QJsonDocument::fromVariant(newRequest).toJson(); + qDebug() << "Sending request" << qUtf8Printable(QJsonDocument::fromVariant(newRequest).toJson()); m_connection->sendData(QJsonDocument::fromVariant(newRequest).toJson()); } diff --git a/mea/jsonrpc/jsontypes.cpp b/mea/jsonrpc/jsontypes.cpp index bb3cf6f2..ebf451d2 100644 --- a/mea/jsonrpc/jsontypes.cpp +++ b/mea/jsonrpc/jsontypes.cpp @@ -256,7 +256,12 @@ QVariantList JsonTypes::packRuleActions(RuleActions *ruleActions) for (int j = 0; j < ruleActions->get(i)->ruleActionParams()->rowCount(); j++) { QVariantMap ruleActionParam; ruleActionParam.insert("paramTypeId", ruleActions->get(i)->ruleActionParams()->get(j)->paramTypeId()); - ruleActionParam.insert("value", ruleActions->get(i)->ruleActionParams()->get(j)->value()); + if (!ruleActions->get(i)->ruleActionParams()->get(j)->eventTypeId().isEmpty() && !ruleActions->get(i)->ruleActionParams()->get(j)->eventParamTypeId().isEmpty()) { + ruleActionParam.insert("eventTypeId", ruleActions->get(i)->ruleActionParams()->get(j)->eventTypeId()); + ruleActionParam.insert("eventParamTypeId", ruleActions->get(i)->ruleActionParams()->get(j)->eventParamTypeId()); + } else { + ruleActionParam.insert("value", ruleActions->get(i)->ruleActionParams()->get(j)->value()); + } ruleActionParams.append(ruleActionParam); } ruleAction.insert("ruleActionParams", ruleActionParams); diff --git a/mea/main.cpp b/mea/main.cpp index 79c69a1d..e03cebd4 100644 --- a/mea/main.cpp +++ b/mea/main.cpp @@ -49,6 +49,7 @@ #include "types/stateevaluators.h" #include "models/logsmodel.h" #include "models/valuelogsproxymodel.h" +#include "models/eventdescriptorparamsfiltermodel.h" #include "basicconfiguration.h" static QObject* interfacesModel_provider(QQmlEngine *engine, QJSEngine *scriptEngine) @@ -150,6 +151,8 @@ int main(int argc, char *argv[]) qmlRegisterType(uri, 1, 0, "NymeaDiscovery"); qmlRegisterUncreatableType(uri, 1, 0, "DiscoveryModel", "Get it from NymeaDiscovery"); + qmlRegisterType(uri, 1, 0, "EventDescriptorParamsFilterModel"); + qmlRegisterType(uri, 1, 0, "LogsModel"); qmlRegisterType(uri, 1, 0, "ValueLogsProxyModel"); qmlRegisterUncreatableType(uri, 1, 0, "LogEntry", "Get them from LogsModel"); diff --git a/mea/mea.pro b/mea/mea.pro index 4062b54d..9fdbc2d3 100644 --- a/mea/mea.pro +++ b/mea/mea.pro @@ -37,7 +37,8 @@ HEADERS += engine.h \ models/valuelogsproxymodel.h \ discovery/nymeadiscovery.h \ logmanager.h \ - basicconfiguration.h + basicconfiguration.h \ + models/eventdescriptorparamsfiltermodel.h SOURCES += main.cpp \ @@ -70,7 +71,8 @@ SOURCES += main.cpp \ models/valuelogsproxymodel.cpp \ discovery/nymeadiscovery.cpp \ logmanager.cpp \ - basicconfiguration.cpp + basicconfiguration.cpp \ + models/eventdescriptorparamsfiltermodel.cpp withavahi { DEFINES += WITH_AVAHI diff --git a/mea/models/eventdescriptorparamsfiltermodel.cpp b/mea/models/eventdescriptorparamsfiltermodel.cpp new file mode 100644 index 00000000..b6d472e4 --- /dev/null +++ b/mea/models/eventdescriptorparamsfiltermodel.cpp @@ -0,0 +1,86 @@ +#include "eventdescriptorparamsfiltermodel.h" + +#include "types/eventdescriptor.h" +#include "engine.h" + +EventDescriptorParamsFilterModel::EventDescriptorParamsFilterModel(QObject *parent) : QSortFilterProxyModel(parent) +{ + +} + +//int EventDescriptorParamsFilterModel::rowCount(const QModelIndex &parent) const +//{ +// Q_UNUSED(parent) +// if (!m_eventDescriptor) { +// return 0; +// } +// foreach (const Param ¶m, m_eventDescriptor->paramDescriptors()->rowCount()) +//} + +EventDescriptor *EventDescriptorParamsFilterModel::eventDescriptor() const +{ + return m_eventDescriptor; +} + +void EventDescriptorParamsFilterModel::setEventDescriptor(EventDescriptor *eventDescriptor) +{ + if (m_eventDescriptor != eventDescriptor) { + m_eventDescriptor = eventDescriptor; + emit eventDescriptorChanged(); + Device *d = Engine::instance()->deviceManager()->devices()->getDevice(eventDescriptor->deviceId()); + if (!d) { + qDebug() << "Can't find a device for this descriptor..."; + return; + } + DeviceClass* dc = Engine::instance()->deviceManager()->deviceClasses()->getDeviceClass(d->deviceClassId()); + if (!dc) { + qDebug() << "Uh oh... No deviceClass for a device!?!11"; + return; + } + EventType* et = dc->eventTypes()->getEventType(eventDescriptor->eventTypeId()); + if (!et) { + qDebug() << "Couldn't find eventtype"; + return; + } + setSourceModel(et->paramTypes()); + qDebug() << "have set source model" << et->paramTypes()->rowCount(); + } +} + +QVariant::Type EventDescriptorParamsFilterModel::type() const +{ + return m_type; +} + +void EventDescriptorParamsFilterModel::setType(QVariant::Type type) +{ + if (type != m_type) { + m_type = type; + emit typeChanged(); + invalidateFilter(); + } +} + +ParamDescriptor *EventDescriptorParamsFilterModel::get(int idx) const +{ +// qDebug() << "...." << m_eventDescriptor->paramDescriptors()->get(mapToSource(index(idx, 0)).row())->paramTypeId() + return m_eventDescriptor->paramDescriptors()->get(mapToSource(index(idx, 0)).row()); +} + +bool EventDescriptorParamsFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +{ + Q_UNUSED(source_parent) + ParamType *pd = dynamic_cast(sourceModel())->get(source_row); + + Device *device = Engine::instance()->deviceManager()->devices()->getDevice(m_eventDescriptor->deviceId()); + if (!device) { + qDebug() << "rejecting entry" << pd->id(); + return false; + } + qDebug() << "accepting entty:" << pd->id(); +// DeviceClass dc = Engine::instance()->deviceManager()->deviceClasses()->getDeviceClass(device->deviceClassId()); +// if (dc.paramTypes()->getParamType(pd->paramTypeId())->type() == m_type) { + return true; +// } +// return false; +} diff --git a/mea/models/eventdescriptorparamsfiltermodel.h b/mea/models/eventdescriptorparamsfiltermodel.h new file mode 100644 index 00000000..7867683d --- /dev/null +++ b/mea/models/eventdescriptorparamsfiltermodel.h @@ -0,0 +1,44 @@ +#ifndef EVENTDESCRIPTORPARAMSFILTERMODEL_H +#define EVENTDESCRIPTORPARAMSFILTERMODEL_H + +#include + +class EventDescriptor; +class ParamDescriptor; + +class EventDescriptorParamsFilterModel : public QSortFilterProxyModel +{ + Q_OBJECT +// Q_PROPERTY(int count READ rowCount NOTIFY countChanged) + Q_PROPERTY(EventDescriptor* eventDescriptor READ eventDescriptor WRITE setEventDescriptor NOTIFY eventDescriptorChanged) + Q_PROPERTY(QVariant::Type type READ type WRITE setType NOTIFY typeChanged) + +public: + explicit EventDescriptorParamsFilterModel(QObject *parent = nullptr); + +// int rowCount(const QModelIndex &parent = QModelIndex()) const override; +// QVariant data(const QModelIndex &index, int role) const override; + + EventDescriptor* eventDescriptor() const; + void setEventDescriptor(EventDescriptor* eventDescriptor); + + QVariant::Type type() const; + void setType(QVariant::Type type); + + Q_INVOKABLE ParamDescriptor* get(int idx) const; + +protected: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; + +signals: + void eventDescriptorChanged(); + void typeChanged(); + +public slots: + +private: + EventDescriptor* m_eventDescriptor = nullptr; + QVariant::Type m_type; +}; + +#endif // EVENTDESCRIPTORPARAMSFILTERMODEL_H diff --git a/mea/models/rulesfiltermodel.cpp b/mea/models/rulesfiltermodel.cpp index ce0e8c45..94bc3055 100644 --- a/mea/models/rulesfiltermodel.cpp +++ b/mea/models/rulesfiltermodel.cpp @@ -29,12 +29,12 @@ void RulesFilterModel::setRules(Rules *rules) } } -QUuid RulesFilterModel::filterDeviceId() const +QString RulesFilterModel::filterDeviceId() const { return m_filterDeviceId; } -void RulesFilterModel::setFilterDeviceId(const QUuid &filterDeviceId) +void RulesFilterModel::setFilterDeviceId(const QString &filterDeviceId) { if (m_filterDeviceId != filterDeviceId) { m_filterDeviceId = filterDeviceId; @@ -62,7 +62,7 @@ bool RulesFilterModel::filterAcceptsRow(int source_row, const QModelIndex &sourc break; } } - if (!found && rule->stateEvaluator()->containsDevice(m_filterDeviceId)) { + if (!found && rule->stateEvaluator() && rule->stateEvaluator()->containsDevice(m_filterDeviceId)) { found = true; } if (!found) { diff --git a/mea/models/rulesfiltermodel.h b/mea/models/rulesfiltermodel.h index 5de1af8d..645b7a2d 100644 --- a/mea/models/rulesfiltermodel.h +++ b/mea/models/rulesfiltermodel.h @@ -11,7 +11,7 @@ class RulesFilterModel : public QSortFilterProxyModel { Q_OBJECT Q_PROPERTY(Rules* rules READ rules WRITE setRules NOTIFY rulesChanged) - Q_PROPERTY(QUuid filterDeviceId READ filterDeviceId WRITE setFilterDeviceId NOTIFY filterDeviceIdChanged) + Q_PROPERTY(QString filterDeviceId READ filterDeviceId WRITE setFilterDeviceId NOTIFY filterDeviceIdChanged) public: explicit RulesFilterModel(QObject *parent = nullptr); @@ -19,8 +19,8 @@ public: Rules* rules() const; void setRules(Rules* rules); - QUuid filterDeviceId() const; - void setFilterDeviceId(const QUuid &filterDeviceId); + QString filterDeviceId() const; + void setFilterDeviceId(const QString &filterDeviceId); Q_INVOKABLE Rule* get(int index) const; @@ -33,7 +33,7 @@ protected: private: Rules *m_rules = nullptr; - QUuid m_filterDeviceId; + QString m_filterDeviceId; }; #endif // RULESFILTERMODEL_H diff --git a/mea/rulemanager.cpp b/mea/rulemanager.cpp index c7640eaf..da69c4ba 100644 --- a/mea/rulemanager.cpp +++ b/mea/rulemanager.cpp @@ -158,7 +158,7 @@ void RuleManager::removeRuleReply(const QVariantMap ¶ms) void RuleManager::onEditRuleReply(const QVariantMap ¶ms) { - qDebug() << "Edit rule reply:" << params.value("params").toMap().value("ruleError").toString(); + qDebug() << "Edit rule reply:" << params; //params.value("params").toMap().value("ruleError").toString(); emit editRuleReply(params.value("params").toMap().value("ruleError").toString()); } @@ -183,8 +183,8 @@ void RuleManager::parseEventDescriptors(const QVariantList &eventDescriptorList, { foreach (const QVariant &eventDescriptorVariant, eventDescriptorList) { EventDescriptor *eventDescriptor = new EventDescriptor(rule); - eventDescriptor->setDeviceId(eventDescriptorVariant.toMap().value("deviceId").toUuid()); - eventDescriptor->setEventTypeId(eventDescriptorVariant.toMap().value("eventTypeId").toUuid()); + eventDescriptor->setDeviceId(eventDescriptorVariant.toMap().value("deviceId").toString()); + eventDescriptor->setEventTypeId(eventDescriptorVariant.toMap().value("eventTypeId").toString()); eventDescriptor->setInterfaceName(eventDescriptorVariant.toMap().value("interface").toString()); eventDescriptor->setInterfaceEvent(eventDescriptorVariant.toMap().value("interfaceEvent").toString()); foreach (const QVariant ¶mDescriptorVariant, eventDescriptorVariant.toMap().value("paramDescriptors").toList()) { @@ -199,20 +199,20 @@ void RuleManager::parseEventDescriptors(const QVariantList &eventDescriptorList, StateEvaluator *RuleManager::parseStateEvaluator(const QVariantMap &stateEvaluatorMap) { - qDebug() << "bla" << stateEvaluatorMap; - StateEvaluator *stateEvaluator = new StateEvaluator(this); - if (stateEvaluatorMap.contains("stateDescriptor")) { - QVariantMap sdMap = stateEvaluatorMap.value("stateDescriptor").toMap(); - QMetaEnum operatorEnum = QMetaEnum::fromType(); - StateDescriptor::ValueOperator op = (StateDescriptor::ValueOperator)operatorEnum.keyToValue(sdMap.value("operator").toByteArray()); - StateDescriptor *sd = new StateDescriptor(sdMap.value("deviceId").toUuid(), op, sdMap.value("stateTypeId").toUuid(), sdMap.value("value"), stateEvaluator); - stateEvaluator->setStateDescriptor(sd); + if (!stateEvaluatorMap.contains("stateDescriptor")) { + return nullptr; } + StateEvaluator *stateEvaluator = new StateEvaluator(this); + QVariantMap sdMap = stateEvaluatorMap.value("stateDescriptor").toMap(); + QMetaEnum operatorEnum = QMetaEnum::fromType(); + StateDescriptor::ValueOperator op = (StateDescriptor::ValueOperator)operatorEnum.keyToValue(sdMap.value("operator").toByteArray()); + StateDescriptor *sd = new StateDescriptor(sdMap.value("deviceId").toUuid(), op, sdMap.value("stateTypeId").toUuid(), sdMap.value("value"), stateEvaluator); + stateEvaluator->setStateDescriptor(sd); foreach (const QVariant &childEvaluatorVariant, stateEvaluatorMap.value("childEvaluators").toList()) { stateEvaluator->childEvaluators()->addStateEvaluator(parseStateEvaluator(childEvaluatorVariant.toMap())); } - QMetaEnum operatorEnum = QMetaEnum::fromType(); + operatorEnum = QMetaEnum::fromType(); stateEvaluator->setStateOperator((StateEvaluator::StateOperator)operatorEnum.keyToValue(stateEvaluatorMap.value("operator").toByteArray())); return stateEvaluator; } @@ -227,6 +227,8 @@ void RuleManager::parseRuleActions(const QVariantList &ruleActions, Rule *rule) RuleActionParam *param = new RuleActionParam(); param->setParamTypeId(ruleActionParamVariant.toMap().value("paramTypeId").toUuid()); param->setValue(ruleActionParamVariant.toMap().value("value")); + param->setEventTypeId(ruleActionParamVariant.toMap().value("eventTypeId").toString()); + param->setEventParamTypeId(ruleActionParamVariant.toMap().value("eventParamTypeId").toString()); ruleAction->ruleActionParams()->addRuleActionParam(param); } rule->actions()->addRuleAction(ruleAction); @@ -243,6 +245,8 @@ void RuleManager::parseRuleExitActions(const QVariantList &ruleActions, Rule *ru RuleActionParam *param = new RuleActionParam(); param->setParamTypeId(ruleActionParamVariant.toMap().value("paramTypeId").toUuid()); param->setValue(ruleActionParamVariant.toMap().value("value")); + param->setEventTypeId(ruleActionParamVariant.toMap().value("eventTypeId").toString()); + param->setEventParamTypeId(ruleActionParamVariant.toMap().value("eventParamTypeId").toString()); ruleAction->ruleActionParams()->addRuleActionParam(param); } rule->exitActions()->addRuleAction(ruleAction); diff --git a/mea/ui/magic/EditRulePage.qml b/mea/ui/magic/EditRulePage.qml index 1f26ac3e..7825fe10 100644 --- a/mea/ui/magic/EditRulePage.qml +++ b/mea/ui/magic/EditRulePage.qml @@ -79,7 +79,7 @@ Page { function selectRuleActionData(ruleActions, ruleAction) { print("opening with ruleAction", ruleAction) - var ruleActionPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionPage.qml"), {text: "Select action", ruleAction: ruleAction }); + var ruleActionPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionPage.qml"), {text: "Select action", ruleAction: ruleAction, rule: rule }); ruleActionPage.onBackPressed.connect(function() { pageStack.pop(root); ruleAction.destroy(); @@ -289,7 +289,8 @@ Page { Repeater { model: actionDelegate.ruleAction.ruleActionParams Label { - text: actionDelegate.actionType.paramTypes.getParamType(model.paramTypeId).displayName + " -> " + model.value + text: actionDelegate.actionType.paramTypes.getParamType(model.paramTypeId).displayName + " -> " + + (model.eventParamTypeId.length > 0 ? "value from event" : model.value) font.pixelSize: app.smallFont } } diff --git a/mea/ui/magic/SelectEventDescriptorParamsPage.qml b/mea/ui/magic/SelectEventDescriptorParamsPage.qml index 752e657b..2cb3ca63 100644 --- a/mea/ui/magic/SelectEventDescriptorParamsPage.qml +++ b/mea/ui/magic/SelectEventDescriptorParamsPage.qml @@ -28,10 +28,26 @@ Page { Repeater { id: delegateRepeater model: root.eventType.paramTypes - delegate: ParamDescriptorDelegateBase { + delegate: ColumnLayout { Layout.fillWidth: true - paramType: root.eventType.paramTypes.get(index) - value: paramType.defaultValue + property alias paramType: paramDescriptorDelegate.paramType + property alias value: paramDescriptorDelegate.value + property alias considerParam: paramCheckBox.checked + CheckBox { + id: paramCheckBox + text: "Only consider event if" + Layout.fillWidth: true + Layout.leftMargin: app.margins + Layout.rightMargin: app.margins + } + + ParamDescriptorDelegateBase { + id: paramDescriptorDelegate + enabled: paramCheckBox.checked + Layout.fillWidth: true + paramType: root.eventType.paramTypes.get(index) + value: paramType.defaultValue + } } } Item { @@ -46,7 +62,9 @@ Page { var params = []; for (var i = 0; i < delegateRepeater.count; i++) { var paramDelegate = delegateRepeater.itemAt(i); - root.eventDescriptor.paramDescriptors.setParamDescriptor(paramDelegate.paramType.id, paramDelegate.value, paramDelegate.operatorType) + if (paramDelegate.considerParam) { + root.eventDescriptor.paramDescriptors.setParamDescriptor(paramDelegate.paramType.id, paramDelegate.value, paramDelegate.operatorType) + } } root.completed() } diff --git a/mea/ui/magic/SelectRuleActionPage.qml b/mea/ui/magic/SelectRuleActionPage.qml index 46b49181..f7a33a0d 100644 --- a/mea/ui/magic/SelectRuleActionPage.qml +++ b/mea/ui/magic/SelectRuleActionPage.qml @@ -10,6 +10,9 @@ Page { // a ruleAction object needs to be set and prefilled with either deviceId or interfaceName property var ruleAction: null + // optionally, a rule which will be used when determining params for the actions + property var rule: null + readonly property var device: ruleAction && ruleAction.deviceId ? Engine.deviceManager.devices.getDevice(ruleAction.deviceId) : null readonly property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null @@ -23,7 +26,7 @@ Page { id: header onBackPressed: root.backPressed(); - property bool interfacesMode: root.ruleAction.interfaceName !== "" + property bool interfacesMode: false//root.ruleAction.interfaceName !== "" onInterfacesModeChanged: root.buildInterface() HeaderButton { @@ -87,7 +90,7 @@ Page { } else if (root.ruleAction.interfaceName != "") { root.ruleAction.interfaceAction = model.name; if (listView.model.get(index).paramTypes.count > 0) { - var paramsPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionParamsPage.qml"), {ruleAction: root.ruleAction}) + var paramsPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionParamsPage.qml"), {ruleAction: root.ruleAction, rule: root.rule}) paramsPage.onBackPressed.connect(function() {pageStack.pop()}); paramsPage.onCompleted.connect(function() { pageStack.pop(); @@ -105,7 +108,7 @@ Page { console.log("ActionType", actionType.id, "selected. Has", actionType.paramTypes.count, "params"); root.ruleAction.actionTypeId = actionType.id; if (actionType.paramTypes.count > 0) { - var paramsPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionParamsPage.qml"), {ruleAction: root.ruleAction}) + var paramsPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionParamsPage.qml"), {ruleAction: root.ruleAction, rule: root.rule}) paramsPage.onBackPressed.connect(function() { pageStack.pop(); }); paramsPage.onCompleted.connect(function() { pageStack.pop(); diff --git a/mea/ui/magic/SelectRuleActionParamsPage.qml b/mea/ui/magic/SelectRuleActionParamsPage.qml index 0d615c92..0a54b284 100644 --- a/mea/ui/magic/SelectRuleActionParamsPage.qml +++ b/mea/ui/magic/SelectRuleActionParamsPage.qml @@ -7,8 +7,11 @@ import Mea 1.0 Page { id: root - // Needs to be set and filled in with deviceId and actionTypeId or interfaceName and interfaceAction - property var ruleAction + // Needs to be set and have rule.ruleActions filled in with deviceId and actionTypeId or interfaceName and interfaceAction + property var ruleAction: null + + // optionally a rule which will be used to propse event's params as param values + property var rule: null readonly property var device: ruleAction && ruleAction.deviceId ? Engine.deviceManager.devices.getDevice(ruleAction.deviceId) : null readonly property var iface: ruleAction && ruleAction.interfaceName ? Interfaces.findByName(ruleAction.interfaceName) : null @@ -28,9 +31,67 @@ Page { Repeater { id: delegateRepeater model: root.actionType.paramTypes - delegate: ParamDelegate { + delegate: ColumnLayout { Layout.fillWidth: true - paramType: root.actionType.paramTypes.get(index) + property string type: { + if (staticParamRadioButton.checked) { + return "static" + } + if (eventParamRadioButton.checked) { + return "event" + } + return "" + } + + property alias paramType: paramDelegate.paramType + property alias value: paramDelegate.value + property alias eventType: eventDescriptorParamsFilterModel.eventType + property alias eventParamTypeId: eventDescriptorParamsFilterModel.paramTypeId + + RadioButton { + id: staticParamRadioButton + text: qsTr("Use static value as parameter") + checked: true + } + ParamDelegate { + id: paramDelegate + Layout.fillWidth: true + paramType: root.actionType.paramTypes.get(index) + enabled: staticParamRadioButton.checked + } + + RadioButton { + id: eventParamRadioButton + text: qsTr("Use event parameter") + visible: eventParamsComboBox.count > 0 + } + ComboBox { + id: eventParamsComboBox + Layout.fillWidth: true + Layout.margins: app.margins + enabled: eventParamRadioButton.checked + visible: count > 0 + Component.onCompleted: currentIndex = 0; + model: EventDescriptorParamsFilterModel { + id: eventDescriptorParamsFilterModel + eventDescriptor: root.rule.eventDescriptors.count === 1 ? root.rule.eventDescriptors.get(0) : null + property var device: Engine.deviceManager.devices.getDevice(eventDescriptor.deviceId) + property var deviceClass: Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) + property var eventType: deviceClass.eventTypes.getEventType(eventDescriptor.eventTypeId) + property var paramDescriptor: eventDescriptorParamsFilterModel.eventType.paramTypes.get(eventParamsComboBox.currentIndex) + property var paramTypeId: paramDescriptor.id + } + delegate: ItemDelegate { + width: parent.width + text: eventDescriptorParamsFilterModel.device.name + " - " + eventDescriptorParamsFilterModel.eventType.displayName + " - " + eventDescriptorParamsFilterModel.eventType.paramTypes.getParamType(model.id).displayName + } + contentItem: Label { + id: eventParamsComboBoxContentItem + anchors.fill: parent + anchors.margins: app.margins + text: eventDescriptorParamsFilterModel.device.name + " - " + eventDescriptorParamsFilterModel.eventType.displayName + " - " + eventDescriptorParamsFilterModel.paramDescriptor.displayName + } + } } } Item { @@ -45,7 +106,12 @@ Page { var params = []; for (var i = 0; i < delegateRepeater.count; i++) { var paramDelegate = delegateRepeater.itemAt(i); - root.ruleAction.ruleActionParams.setRuleActionParam(paramDelegate.paramType.id, paramDelegate.value) + if (paramDelegate.type === "static") { + root.ruleAction.ruleActionParams.setRuleActionParam(paramDelegate.paramType.id, paramDelegate.value) + } else if (paramDelegate.type === "event") { + print("adding event based rule action param", paramDelegate.paramType.id, paramDelegate.eventType.id, paramDelegate.eventParamTypeId) + root.ruleAction.ruleActionParams.setRuleActionParamEvent(paramDelegate.paramType.id, paramDelegate.eventType.id, paramDelegate.eventParamTypeId) + } } root.completed() } diff --git a/mea/ui/magic/SimpleStateEvaluatorDelegate.qml b/mea/ui/magic/SimpleStateEvaluatorDelegate.qml index f1bc59d7..8497cf2a 100644 --- a/mea/ui/magic/SimpleStateEvaluatorDelegate.qml +++ b/mea/ui/magic/SimpleStateEvaluatorDelegate.qml @@ -25,6 +25,10 @@ SwipeDelegate { Label { Layout.fillWidth: true property string operatorString: { + if (!root.stateEvaluator) { + return ""; + } + switch (root.stateEvaluator.stateDescriptor.valueOperator) { case StateDescriptor.ValueOperatorEquals: return "="; diff --git a/mea/ui/magic/StateEvaluatorDelegate.qml b/mea/ui/magic/StateEvaluatorDelegate.qml index 7e8de3de..7559de97 100644 --- a/mea/ui/magic/StateEvaluatorDelegate.qml +++ b/mea/ui/magic/StateEvaluatorDelegate.qml @@ -30,15 +30,15 @@ SwipeDelegate { ComboBox { Layout.fillWidth: true model: ["and all of those", "or any of those"] - currentIndex: root.stateEvaluator.stateOperator === StateEvaluator.StateOperatorAnd ? 0 : 1 - visible: root.stateEvaluator.childEvaluators.count > 0 + currentIndex: root.stateEvaluator && root.stateEvaluator.stateOperator === StateEvaluator.StateOperatorAnd ? 0 : 1 + visible: root.stateEvaluator && root.stateEvaluator.childEvaluators.count > 0 onActivated: { root.stateEvaluator.stateOperator = index == 0 ? StateEvaluator.StateOperatorAnd : StateEvaluator.StateOperatorOr } } Repeater { - model: root.stateEvaluator.childEvaluators + model: root.stateEvaluator ? root.stateEvaluator.childEvaluators : null delegate: SimpleStateEvaluatorDelegate { Layout.fillWidth: true stateEvaluator: root.stateEvaluator.childEvaluators.get(index)