From 27b8946ff5eeb5c5db4616e1819978ce320c22ab Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Fri, 16 Feb 2018 17:51:56 +0100 Subject: [PATCH] more work --- guh-control/discovery/upnpdiscovery.cpp | 11 +- guh-control/jsonrpc/jsontypes.cpp | 1 + guh-control/main.cpp | 13 +- guh-control/resources.qrc | 4 + guh-control/rulemanager.cpp | 5 + guh-control/rulemanager.h | 2 + guh-control/ui/MagicPage.qml | 4 +- .../ui/customviews/NotificationsView.qml | 15 ++- guh-control/ui/images/view-collapse.svg | 18 +++ guh-control/ui/images/view-expand.svg | 19 +++ .../ui/magic/ComposeEventDescriptorPage.qml | 40 ++++++ guh-control/ui/magic/EditRulePage.qml | 22 ++- guh-control/ui/magic/NewRulePage.qml | 126 +++++++++++++++++- guh-control/ui/magic/SelectEventPage.qml | 87 ++++++++++-- guh-control/ui/magic/SelectThingPage.qml | 56 ++++++++ libguh-common/libguh-common.pro | 8 +- libguh-common/types/eventdescriptor.cpp | 40 +++++- libguh-common/types/eventdescriptor.h | 27 +++- libguh-common/types/eventdescriptors.cpp | 14 +- libguh-common/types/eventdescriptors.h | 8 +- libguh-common/types/eventtype.cpp | 10 ++ libguh-common/types/eventtype.h | 7 +- libguh-common/types/eventtypes.cpp | 8 +- libguh-common/types/eventtypes.h | 5 +- libguh-common/types/paramdescriptor.cpp | 19 +++ libguh-common/types/paramdescriptor.h | 33 +++++ libguh-common/types/paramdescriptors.cpp | 49 +++++++ libguh-common/types/paramdescriptors.h | 40 ++++++ libguh-common/types/rule.h | 2 +- libguh-common/types/ruleactionparams.cpp | 1 + 30 files changed, 643 insertions(+), 51 deletions(-) create mode 100644 guh-control/ui/images/view-collapse.svg create mode 100644 guh-control/ui/images/view-expand.svg create mode 100644 guh-control/ui/magic/ComposeEventDescriptorPage.qml create mode 100644 guh-control/ui/magic/SelectThingPage.qml create mode 100644 libguh-common/types/paramdescriptor.cpp create mode 100644 libguh-common/types/paramdescriptor.h create mode 100644 libguh-common/types/paramdescriptors.cpp create mode 100644 libguh-common/types/paramdescriptors.h diff --git a/guh-control/discovery/upnpdiscovery.cpp b/guh-control/discovery/upnpdiscovery.cpp index 73993567..c18d0873 100644 --- a/guh-control/discovery/upnpdiscovery.cpp +++ b/guh-control/discovery/upnpdiscovery.cpp @@ -193,11 +193,11 @@ void UpnpDiscovery::networkReplyFinished(QNetworkReply *reply) { int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + QByteArray data = reply->readAll(); + DiscoveryDevice discoveryDevice = m_runningReplies.take(reply); + switch (status) { case(200):{ - QByteArray data = reply->readAll(); - DiscoveryDevice discoveryDevice = m_runningReplies.take(reply); - // parse XML data QXmlStreamReader xml(data); while (!xml.atEnd() && !xml.hasError()) { @@ -252,9 +252,9 @@ void UpnpDiscovery::networkReplyFinished(QNetworkReply *reply) } } + qDebug() << "discovered device" << discoveryDevice.friendlyName() << discoveryDevice.hostAddress(); - if (discoveryDevice.friendlyName().contains("guh")) { - qDebug() << discoveryDevice; + if (discoveryDevice.manufacturer().contains("guh")) { if (!m_discoveryModel->contains(discoveryDevice.uuid())) { m_discoveryModel->addDevice(discoveryDevice); } @@ -264,7 +264,6 @@ void UpnpDiscovery::networkReplyFinished(QNetworkReply *reply) } default: qWarning() << "HTTP request error " << status; - m_runningReplies.remove(reply); } reply->deleteLater(); diff --git a/guh-control/jsonrpc/jsontypes.cpp b/guh-control/jsonrpc/jsontypes.cpp index 419681fe..e65ee1ce 100644 --- a/guh-control/jsonrpc/jsontypes.cpp +++ b/guh-control/jsonrpc/jsontypes.cpp @@ -152,6 +152,7 @@ EventType *JsonTypes::unpackEventType(const QVariantMap &eventTypeMap, QObject * EventType *eventType = new EventType(parent); eventType->setId(eventTypeMap.value("id").toUuid()); eventType->setName(eventTypeMap.value("name").toString()); + eventType->setDisplayName(eventTypeMap.value("displayName").toString()); eventType->setIndex(eventTypeMap.value("index").toInt()); ParamTypes *paramTypes = new ParamTypes(eventType); foreach (QVariant paramType, eventTypeMap.value("paramTypes").toList()) { diff --git a/guh-control/main.cpp b/guh-control/main.cpp index 5cd505dc..e776a57a 100644 --- a/guh-control/main.cpp +++ b/guh-control/main.cpp @@ -18,7 +18,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include +#include #include #include #include @@ -39,6 +39,8 @@ #include "types/ruleaction.h" #include "types/ruleactionparams.h" #include "types/ruleactionparam.h" +#include "types/eventdescriptors.h" +#include "types/eventdescriptor.h" #include "types/rule.h" #include "models/logsmodel.h" #include "models/valuelogsproxymodel.h" @@ -46,13 +48,14 @@ int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QApplication application(argc, argv); + QCoreApplication application(argc, argv); application.setApplicationName("guh-control"); application.setOrganizationName("guh"); QQuickStyle::setStyle("Material"); const char uri[] = "Guh"; + qmlRegisterSingletonType(uri, 1, 0, "Engine", Engine::qmlInstance); qmlRegisterUncreatableType(uri, 1, 0, "DeviceManager", "Can't create this in QML. Get it from the Core."); @@ -98,6 +101,12 @@ int main(int argc, char *argv[]) qmlRegisterUncreatableType(uri, 1, 0, "RuleActionParams", "Get it from RuleActions"); qmlRegisterUncreatableType(uri, 1, 0, "RuleActionParam", "Get it from RuleActionParams"); qmlRegisterType(uri, 1, 0, "RulesFilterModel"); + qmlRegisterUncreatableType(uri, 1, 0, "EventDescriptors", "Get them from rules"); + qmlRegisterUncreatableType(uri, 1, 0, "EventDescriptor", "Get them from rules"); + qmlRegisterUncreatableType(uri, 1, 0, "ParamTypes", "Uncreatable"); + qmlRegisterUncreatableType(uri, 1, 0, "ParamType", "Uncreatable"); + qmlRegisterUncreatableType(uri, 1, 0, "ParamDescriptor", "Uncreatable"); + qmlRegisterUncreatableType(uri, 1, 0, "ParamDescriptors", "Uncreatable"); qmlRegisterUncreatableType(uri, 1, 0, "Plugin", "Can't create this in QML. Get it from the Plugins."); qmlRegisterUncreatableType(uri, 1, 0, "Plugins", "Can't create this in QML. Get it from the DeviceManager."); diff --git a/guh-control/resources.qrc b/guh-control/resources.qrc index 104513f5..bf861e17 100644 --- a/guh-control/resources.qrc +++ b/guh-control/resources.qrc @@ -108,5 +108,9 @@ ui/magic/SelectEventPage.qml ui/magic/NewThingMagicPage.qml ui/magic/EditRulePage.qml + ui/magic/SelectThingPage.qml + ui/magic/ComposeEventDescriptorPage.qml + ui/images/view-expand.svg + ui/images/view-collapse.svg diff --git a/guh-control/rulemanager.cpp b/guh-control/rulemanager.cpp index 5ee3c3e8..962e531a 100644 --- a/guh-control/rulemanager.cpp +++ b/guh-control/rulemanager.cpp @@ -39,6 +39,11 @@ Rules *RuleManager::rules() const return m_rules; } +Rule *RuleManager::createNewRule() +{ + return new Rule(); +} + void RuleManager::addRule(const QVariantMap params) { m_jsonClient->sendCommand("Rules.AddRule", params, this, "addRuleReply"); diff --git a/guh-control/rulemanager.h b/guh-control/rulemanager.h index 9e24e041..183c99e5 100644 --- a/guh-control/rulemanager.h +++ b/guh-control/rulemanager.h @@ -24,6 +24,8 @@ public: Rules* rules() const; + Q_INVOKABLE Rule* createNewRule(); + Q_INVOKABLE void addRule(const QVariantMap params); Q_INVOKABLE void removeRule(const QUuid &ruleId); diff --git a/guh-control/ui/MagicPage.qml b/guh-control/ui/MagicPage.qml index 4559b23f..3fdfefb4 100644 --- a/guh-control/ui/MagicPage.qml +++ b/guh-control/ui/MagicPage.qml @@ -11,7 +11,7 @@ Page { HeaderButton { imageSource: Qt.resolvedUrl("images/add.svg") - onClicked: pageStack.push(Qt.resolvedUrl("magic/NewRulePage.qml")) + onClicked: pageStack.push(Qt.resolvedUrl("magic/NewRulePage.qml"), {rule: Engine.ruleManager.createNewRule() }) } } @@ -26,7 +26,7 @@ Page { } onClicked: { - pageStack.push(Qt.resolvedUrl("magic/EditRulePage.qml")) + pageStack.push(Qt.resolvedUrl("magic/EditRulePage.qml"), {rule: Engine.ruleManager.rules.get(index) }) } } } diff --git a/guh-control/ui/customviews/NotificationsView.qml b/guh-control/ui/customviews/NotificationsView.qml index ad37e5ef..28d192da 100644 --- a/guh-control/ui/customviews/NotificationsView.qml +++ b/guh-control/ui/customviews/NotificationsView.qml @@ -16,7 +16,13 @@ CustomViewBase { text: "Send a notification now:" } TextArea { - id: textArea + id: titleTextArea + placeholderText: "Title" + Layout.fillWidth: true + } + TextArea { + id: bodyTextArea + placeholderText: "Text" Layout.fillWidth: true } Button { @@ -29,8 +35,13 @@ CustomViewBase { print("bla:", root.deviceClass.actionTypes.findByName("notify").paramTypes) var paramTypeId = root.deviceClass.actionTypes.findByName("notify").paramTypes.findByName("title").id param1.paramTypeId = paramTypeId - param1.value = textArea.text + param1.value = titleTextArea.text params.push(param1) + var param2 = {} + paramTypeId = root.deviceClass.actionTypes.findByName("notify").paramTypes.findByName("body").id + param2.paramTypeId = paramTypeId + param2.value = bodyTextArea.text + params.push(param2) Engine.deviceManager.executeAction(root.device.id, root.deviceClass.actionTypes.findByName("notify").id, params) } } diff --git a/guh-control/ui/images/view-collapse.svg b/guh-control/ui/images/view-collapse.svg new file mode 100644 index 00000000..ad604512 --- /dev/null +++ b/guh-control/ui/images/view-collapse.svg @@ -0,0 +1,18 @@ + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/guh-control/ui/images/view-expand.svg b/guh-control/ui/images/view-expand.svg new file mode 100644 index 00000000..5c049f1c --- /dev/null +++ b/guh-control/ui/images/view-expand.svg @@ -0,0 +1,19 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/guh-control/ui/magic/ComposeEventDescriptorPage.qml b/guh-control/ui/magic/ComposeEventDescriptorPage.qml new file mode 100644 index 00000000..821ef326 --- /dev/null +++ b/guh-control/ui/magic/ComposeEventDescriptorPage.qml @@ -0,0 +1,40 @@ +import QtQuick 2.6 +import QtQuick.Layouts 1.2 +import QtQuick.Controls 2.1 +import "../components" +import Guh 1.0 + +Page { + id: root + property var device: null + + header: GuhHeader { + text: "Select event" + } + + ColumnLayout { + anchors.fill: parent + + ColumnLayout { + visible: root.device == null + Layout.fillWidth: true + + RowLayout { + Layout.fillWidth: true + RadioButton { + text: "A specific thing" + checked: true + } + RadioButton { + text: "A group of things" + } + } + + ListView { +// Layout.fi + } + } + + } + +} diff --git a/guh-control/ui/magic/EditRulePage.qml b/guh-control/ui/magic/EditRulePage.qml index dd77fa60..89b051cc 100644 --- a/guh-control/ui/magic/EditRulePage.qml +++ b/guh-control/ui/magic/EditRulePage.qml @@ -2,8 +2,11 @@ import QtQuick 2.7 import QtQuick.Controls 2.2 import "../components" import QtQuick.Layouts 1.2 +import Guh 1.0 Page { + property var rule: null + header: GuhHeader { text: "Add some magic" onBackPressed: pageStack.pop() @@ -14,6 +17,23 @@ Page { Label { text: "When" } - } + Repeater { + model: rule.eventDescriptors + ItemDelegate { + property var device: Engine.deviceManager.devices.getDevice(model.deviceId) + property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null + property var eventType: deviceClass ? deviceClass.eventTypes.getEventType(model.eventTypeId) : null + contentItem: ColumnLayout { + Label { + text: device ? device.name : "Unknown device" + Layout.fillWidth: true + } + Label { + text: eventType ? eventType.name : "Unknown event" + } + } + } + } + } } diff --git a/guh-control/ui/magic/NewRulePage.qml b/guh-control/ui/magic/NewRulePage.qml index 9f139d54..791bd122 100644 --- a/guh-control/ui/magic/NewRulePage.qml +++ b/guh-control/ui/magic/NewRulePage.qml @@ -1,14 +1,132 @@ import QtQuick 2.8 +import QtQuick.Layouts 1.3 import QtQuick.Controls 2.1 import "../components" +import Guh 1.0 Page { id: root - property var device: null + property var rule: null - header: GuhHeader { - text: "New rule" - onBackPressed: pageStack.pop() + StackView { + id: internalPageStack + anchors.fill: parent + initialItem: newRulePage1 + } + + function addEventDescriptor() { + var eventDescriptor = root.rule.eventDescriptors.createNewEventDescriptor(); + var page = internalPageStack.push(Qt.resolvedUrl("SelectThingPage.qml")); + page.onBackPressed.connect(function() { internalPageStack.pop(); }); + page.onThingSelected.connect(function(device) { + eventDescriptor.deviceId = device.id; + selectEventDescriptorData(eventDescriptor) + }) + page.onInterfaceSelected.connect(function(interfaceName) { + eventDescriptor.interfaceName = interfaceName; + selectEventDescriptorData(eventDescriptor) + }) + } + + function selectEventDescriptorData(eventDescriptor) { + var eventPage = internalPageStack.push(Qt.resolvedUrl("SelectEventPage.qml"), {text: "Select event", eventDescriptor: eventDescriptor}); + eventPage.onBackPressed.connect(function() {internalPageStack.pop()}) + eventPage.onDone.connect(function() { + root.rule.eventDescriptors.addEventDescriptor(eventPage.eventDescriptor); + internalPageStack.pop(newRulePage1) + }) + } + + function addAction() { + + } + + Page { + id: newRulePage1 + + header: GuhHeader { + text: "New rule" + onBackPressed: pageStack.pop() + } + + ColumnLayout { + anchors.fill: parent + RowLayout { + Layout.fillWidth: true + RadioButton { + id: whenButton + text: "When" + checked: true + } + RadioButton { + id: whileButton + text: "While" + } + } + + RowLayout { + Layout.fillWidth: true + visible: eventsRepeater.count == 0 + Label { + Layout.fillWidth: true + text: "Add an event which should trigger the execution of the rule" + } + Button { + text: "+" + onClicked: root.addEventDescriptor(); + } + } + + Repeater { + id: eventsRepeater + model: root.rule.eventDescriptors + delegate: ItemDelegate { + id: eventDelegate + property var device: Engine.deviceManager.devices.getDevice(root.rule.eventDescriptors.get(index).deviceId) + property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null + property var eventType: deviceClass ? deviceClass.eventTypes.getEventType(root.rule.eventDescriptors.get(index).eventTypeId) : null + contentItem: ColumnLayout { + Label { + text: eventDelegate.device ? eventDelegate.device.name : "Unknown device" + root.rule.eventDescriptors.get(index).deviceId + Layout.fillWidth: true + } + Label { + text: eventDelegate.eventType ? eventDelegate.eventType.displayName : "Unknown event" + root.rule.eventDescriptors.get(index).eventTypeId + } + } + } + } + + Label { + text: "do the following:" + } + + RowLayout { + Layout.fillWidth: true + visible: actionsRepeater.count == 0 + Label { + Layout.fillWidth: true + text: "Add action which should be executed when the rule is triggered" + } + Button { + text: "+" + onClicked: root.addAction(); + } + } + + Repeater { + id: actionsRepeater + model: root.rule.actions + delegate: ItemDelegate { + id: actionDelegate + contentItem: ColumnLayout { + Label { + text: "bla" + } + } + } + } + } } } diff --git a/guh-control/ui/magic/SelectEventPage.qml b/guh-control/ui/magic/SelectEventPage.qml index bb49b866..76e2b8a6 100644 --- a/guh-control/ui/magic/SelectEventPage.qml +++ b/guh-control/ui/magic/SelectEventPage.qml @@ -6,41 +6,100 @@ import Guh 1.0 Page { id: root property alias text: header.text - property var device: null - readonly property var deviceClass: Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) + + // an eventDescriptor object needs to be set and prefilled with either deviceId or interfaceName + property var eventDescriptor: null + + readonly property var device: eventDescriptor && eventDescriptor.deviceId ? Engine.deviceManager.devices.getDevice(eventDescriptor.deviceId) : null + readonly property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null + + signal backPressed(); + signal done(); + + onEventDescriptorChanged: buildInterface() + Component.onCompleted: buildInterface() header: GuhHeader { id: header - onBackPressed: pageStack.pop() + onBackPressed: root.backPressed(); + + property bool interfacesMode: true + onInterfacesModeChanged: root.buildInterface() + + HeaderButton { + imageSource: header.interfacesMode ? "../images/view-expand.svg" : "../images/view-collapse.svg" + onClicked: header.interfacesMode = !header.interfacesMode + } } ListModel { - id: eventModel + id: eventTemplateModel ListElement { interfaceName: "temperaturesensor"; text: "When it's freezing..."; event: "freeze"} ListElement { interfaceName: "battery"; text: "When the device runs out of battery..."; event: "lowBattery"} ListElement { interfaceName: "weather"; text: "When it starts raining..."; event: "rain" } } - onDeviceClassChanged: { + function buildInterface() { actualModel.clear() - print("device supports interfaces", deviceClass.interfaces) - for (var i = 0; i < eventModel.count; i++) { - print("event is for interface", eventModel.get(i).interfaceName) - if (deviceClass.interfaces.indexOf(eventModel.get(i).interfaceName) >= 0) { - actualModel.append(eventModel.get(i)) + + if (header.interfacesMode) { + if (root.device) { + print("device supports interfaces", deviceClass.interfaces) + for (var i = 0; i < eventTemplateModel.count; i++) { + print("event is for interface", eventTemplateModel.get(i).interfaceName) + if (deviceClass.interfaces.indexOf(eventTemplateModel.get(i).interfaceName) >= 0) { + actualModel.append(eventTemplateModel.get(i)) + } + } + } else if (root.eventDescriptor.interfaceName !== "") { + for (var i = 0; i < eventTemplateModel.count; i++) { + if (eventTemplateModel.get(i).interfaceName === root.eventDescriptor.interfaceName) { + actualModel.append(eventTemplateModel.get(i)) + } + } + } else { + console.warn("You need to set device or interfaceName"); + } + } else { + if (root.device) { + print("fdsfasdfdsafdas", deviceClass.eventTypes.count) + for (var i = 0; i < deviceClass.eventTypes.count; i++) { + print("bla", deviceClass.eventTypes.get(i).name, deviceClass.eventTypes.get(i).displayName) + actualModel.append({text: deviceClass.eventTypes.get(i).displayName}) + } } } } + ListModel { + id: actualModel + } + ListView { anchors.fill: parent - model: ListModel { - id: actualModel - } + model: actualModel delegate: ItemDelegate { text: model.text + onClicked: { + if (header.interfacesMode) { + if (root.device) { + print("selected:", model.event) + switch (model.event) { + case "lowBattery": + var eventType = root.deviceClass.eventTypes.findByName("batteryCritical") + root.eventDescriptor.eventTypeId = eventType.id; +// root.eventDescriptor.paramDescriptors.setParamDescriptor(eventType.paramTypes.get(0).paramTypeId, 0, ParamDescriptors.ValueOperatorLessOrEqual) + root.done(); + break; + default: + console.warn("FIXME: Unhandled interface event"); + } + } + } else { + console.warn("FIXME: not implemented yet") + } + } } - } } diff --git a/guh-control/ui/magic/SelectThingPage.qml b/guh-control/ui/magic/SelectThingPage.qml new file mode 100644 index 00000000..20514bc9 --- /dev/null +++ b/guh-control/ui/magic/SelectThingPage.qml @@ -0,0 +1,56 @@ +import QtQuick 2.6 +import QtQuick.Layouts 1.2 +import QtQuick.Controls 2.1 +import "../components" +import Guh 1.0 + +Page { + id: root + + signal backPressed(); + signal thingSelected(var device); + signal interfaceSelected(string interfaceName); + + header: GuhHeader { + text: "Select a thing" + onBackPressed: root.backPressed() + } + ColumnLayout { + anchors.fill: parent + + RowLayout { + Layout.fillWidth: true + RadioButton { + id: thingButton + text: "A specific thing" + checked: true + } + RadioButton { + id: interfacesButton + text: "A group of things" + } + } + + ListModel { + id: supportedInterfacesModel + ListElement { interfaceName: "battery"; name: "Battery powered devices" } + ListElement { interfaceName: "temperatureSensor"; name: "Temperature sensors" } + } + + ListView { + Layout.fillWidth: true + Layout.fillHeight: true + model: thingButton.checked ? Engine.deviceManager.devices : supportedInterfacesModel + delegate: ItemDelegate { + text: model.name + onClicked: { + if (thingButton.checked) { + root.thingSelected(Engine.deviceManager.devices.get(index)) + } else { + root.interfaceSelected(supportedInterfacesModel.get(index).interfaceName) + } + } + } + } + } +} diff --git a/libguh-common/libguh-common.pro b/libguh-common/libguh-common.pro index 4675623c..cfa5a301 100644 --- a/libguh-common/libguh-common.pro +++ b/libguh-common/libguh-common.pro @@ -40,7 +40,9 @@ HEADERS += types/types.h \ types/logentry.h \ types/stateevaluators.h \ types/stateevaluator.h \ - types/statedescriptor.h + types/statedescriptor.h \ + types/paramdescriptor.h \ + types/paramdescriptors.h SOURCES += types/vendor.cpp \ types/vendors.cpp \ @@ -72,7 +74,9 @@ SOURCES += types/vendor.cpp \ types/logentry.cpp \ types/stateevaluators.cpp \ types/stateevaluator.cpp \ - types/statedescriptor.cpp + types/statedescriptor.cpp \ + types/paramdescriptor.cpp \ + types/paramdescriptors.cpp # install header file with relative subdirectory for(header, HEADERS) { diff --git a/libguh-common/types/eventdescriptor.cpp b/libguh-common/types/eventdescriptor.cpp index b4c48041..a1820972 100644 --- a/libguh-common/types/eventdescriptor.cpp +++ b/libguh-common/types/eventdescriptor.cpp @@ -2,7 +2,7 @@ EventDescriptor::EventDescriptor(QObject *parent) : QObject(parent) { - + m_paramDescriptors = new ParamDescriptors(this); } QUuid EventDescriptor::deviceId() const @@ -12,7 +12,10 @@ QUuid EventDescriptor::deviceId() const void EventDescriptor::setDeviceId(const QUuid &deviceId) { - m_deviceId = deviceId; + if (m_deviceId != deviceId) { + m_deviceId = deviceId; + emit deviceIdChanged(); + } } QUuid EventDescriptor::eventTypeId() const @@ -22,5 +25,36 @@ QUuid EventDescriptor::eventTypeId() const void EventDescriptor::setEventTypeId(const QUuid &eventTypeId) { - m_eventTypeId = eventTypeId; + if (m_eventTypeId != eventTypeId) { + m_eventTypeId = eventTypeId; + emit eventTypeIdChanged(); + } +} + +QString EventDescriptor::interfaceName() const +{ + return m_interfaceName; +} + +void EventDescriptor::setInterfaceName(const QString &interfaceName) +{ + if (m_interfaceName != interfaceName) { + m_interfaceName = interfaceName; + emit interfaceNameChanged(); + } +} + +QString EventDescriptor::interfaceEvent() const +{ + return m_interfaceEvent; +} + +void EventDescriptor::setInterfaceEvent(const QString &interfaceEvent) +{ + m_interfaceEvent = interfaceEvent; +} + +ParamDescriptors *EventDescriptor::paramDescriptors() const +{ + return m_paramDescriptors; } diff --git a/libguh-common/types/eventdescriptor.h b/libguh-common/types/eventdescriptor.h index 161b999b..e9dc2c34 100644 --- a/libguh-common/types/eventdescriptor.h +++ b/libguh-common/types/eventdescriptor.h @@ -4,11 +4,18 @@ #include #include +#include "paramdescriptors.h" + class EventDescriptor : public QObject { Q_OBJECT - Q_PROPERTY(QUuid deviceId READ deviceId CONSTANT) - Q_PROPERTY(QUuid eventTypeId READ eventTypeId CONSTANT) + Q_PROPERTY(QUuid deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged) + Q_PROPERTY(QUuid eventTypeId READ eventTypeId WRITE setEventTypeId NOTIFY eventTypeIdChanged) + + Q_PROPERTY(QString interfaceName READ interfaceName WRITE setInterfaceName NOTIFY interfaceNameChanged) + Q_PROPERTY(QString interfaceEvent READ interfaceEvent CONSTANT) + + Q_PROPERTY(ParamDescriptors* paramDescriptors READ paramDescriptors CONSTANT) public: explicit EventDescriptor(QObject *parent = nullptr); @@ -19,11 +26,27 @@ public: QUuid eventTypeId() const; void setEventTypeId(const QUuid &eventTypeId); + QString interfaceName() const; + void setInterfaceName(const QString &interfaceName); + + QString interfaceEvent() const; + void setInterfaceEvent(const QString &interfaceEvent); + + ParamDescriptors* paramDescriptors() const; + signals: + void deviceIdChanged(); + void eventTypeIdChanged(); + void interfaceNameChanged(); private: QUuid m_deviceId; QUuid m_eventTypeId; + + QString m_interfaceName; + QString m_interfaceEvent; + + ParamDescriptors *m_paramDescriptors; }; #endif // EVENTDESCRIPTOR_H diff --git a/libguh-common/types/eventdescriptors.cpp b/libguh-common/types/eventdescriptors.cpp index 98e2b211..69b394f1 100644 --- a/libguh-common/types/eventdescriptors.cpp +++ b/libguh-common/types/eventdescriptors.cpp @@ -15,13 +15,20 @@ int EventDescriptors::rowCount(const QModelIndex &parent) const QVariant EventDescriptors::data(const QModelIndex &index, int role) const { + switch (role) { + case RoleDeviceId: + return m_list.at(index.row())->deviceId(); + case RoleEventTypeId: + return m_list.at(index.row())->eventTypeId(); + } return QVariant(); } QHash EventDescriptors::roleNames() const { QHash roles; - roles.insert(RoleName, "name"); + roles.insert(RoleDeviceId, "deviceId"); + roles.insert(RoleEventTypeId, "eventId"); return roles; } @@ -30,6 +37,11 @@ EventDescriptor *EventDescriptors::get(int index) const return m_list.at(index); } +EventDescriptor *EventDescriptors::createNewEventDescriptor() +{ + return new EventDescriptor(); +} + void EventDescriptors::addEventDescriptor(EventDescriptor *eventDescriptor) { eventDescriptor->setParent(this); diff --git a/libguh-common/types/eventdescriptors.h b/libguh-common/types/eventdescriptors.h index 3c9019ce..7da92170 100644 --- a/libguh-common/types/eventdescriptors.h +++ b/libguh-common/types/eventdescriptors.h @@ -11,7 +11,8 @@ class EventDescriptors : public QAbstractListModel Q_PROPERTY(int count READ rowCount NOTIFY countChanged) public: enum Roles { - RoleName + RoleDeviceId, + RoleEventTypeId }; explicit EventDescriptors(QObject *parent = nullptr); @@ -19,9 +20,10 @@ public: QVariant data(const QModelIndex &index, int role) const override; QHash roleNames() const override; - EventDescriptor* get(int index) const; + Q_INVOKABLE EventDescriptor* get(int index) const; - void addEventDescriptor(EventDescriptor *eventDescriptor); + Q_INVOKABLE EventDescriptor* createNewEventDescriptor(); + Q_INVOKABLE void addEventDescriptor(EventDescriptor *eventDescriptor); signals: void countChanged(); diff --git a/libguh-common/types/eventtype.cpp b/libguh-common/types/eventtype.cpp index 7ec61e22..8d42633d 100644 --- a/libguh-common/types/eventtype.cpp +++ b/libguh-common/types/eventtype.cpp @@ -47,6 +47,16 @@ void EventType::setName(const QString &name) m_name = name; } +QString EventType::displayName() const +{ + return m_displayName; +} + +void EventType::setDisplayName(const QString &displayName) +{ + m_displayName = displayName; +} + int EventType::index() const { return m_index; diff --git a/libguh-common/types/eventtype.h b/libguh-common/types/eventtype.h index ebc1a1ff..2f148188 100644 --- a/libguh-common/types/eventtype.h +++ b/libguh-common/types/eventtype.h @@ -33,8 +33,9 @@ class EventType : public QObject Q_OBJECT Q_PROPERTY(QUuid id READ id CONSTANT) Q_PROPERTY(QString name READ name CONSTANT) + Q_PROPERTY(QString displayName READ displayName CONSTANT) Q_PROPERTY(int index READ index CONSTANT) - Q_PROPERTY(ParamTypes paramTypes READ paramTypes CONSTANT) + Q_PROPERTY(ParamTypes* paramTypes READ paramTypes CONSTANT) public: explicit EventType(QObject *parent = 0); @@ -45,6 +46,9 @@ public: QString name() const; void setName(const QString &name); + QString displayName() const; + void setDisplayName(const QString &displayName); + int index() const; void setIndex(const int &index); @@ -54,6 +58,7 @@ public: private: QUuid m_id; QString m_name; + QString m_displayName; int m_index; ParamTypes *m_paramTypes; }; diff --git a/libguh-common/types/eventtypes.cpp b/libguh-common/types/eventtypes.cpp index 25a04388..b3801df7 100644 --- a/libguh-common/types/eventtypes.cpp +++ b/libguh-common/types/eventtypes.cpp @@ -34,11 +34,6 @@ QList EventTypes::eventTypes() return m_eventTypes; } -int EventTypes::count() const -{ - return m_eventTypes.count(); -} - EventType *EventTypes::get(int index) const { return m_eventTypes.at(index); @@ -80,6 +75,7 @@ void EventTypes::addEventType(EventType *eventType) //qDebug() << "EventTypes: loaded eventType" << eventType->name(); m_eventTypes.append(eventType); endInsertRows(); + emit countChanged(); } void EventTypes::clearModel() @@ -87,12 +83,12 @@ void EventTypes::clearModel() beginResetModel(); m_eventTypes.clear(); endResetModel(); + emit countChanged(); } EventType *EventTypes::findByName(const QString &name) const { foreach (EventType *eventType, m_eventTypes) { - qDebug() << "have eventtypoe" << eventType->name(); if (eventType->name() == name) { return eventType; } diff --git a/libguh-common/types/eventtypes.h b/libguh-common/types/eventtypes.h index 4f2197a3..66854cdf 100644 --- a/libguh-common/types/eventtypes.h +++ b/libguh-common/types/eventtypes.h @@ -31,6 +31,7 @@ class EventTypes : public QAbstractListModel { Q_OBJECT + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) public: enum EventTypeRole { @@ -42,7 +43,6 @@ public: QList eventTypes(); - Q_INVOKABLE int count() const; Q_INVOKABLE EventType *get(int index) const; Q_INVOKABLE EventType *getEventType(const QUuid &eventTypeId) const; @@ -55,6 +55,9 @@ public: Q_INVOKABLE EventType *findByName(const QString &name) const; +signals: + void countChanged(); + protected: QHash roleNames() const; diff --git a/libguh-common/types/paramdescriptor.cpp b/libguh-common/types/paramdescriptor.cpp new file mode 100644 index 00000000..b4c03166 --- /dev/null +++ b/libguh-common/types/paramdescriptor.cpp @@ -0,0 +1,19 @@ +#include "paramdescriptor.h" + +ParamDescriptor::ParamDescriptor(const QString &id, const QVariant &value, QObject *parent) : Param(id, value, parent) +{ + +} + +ParamDescriptor::ValueOperator ParamDescriptor::operatorType() const +{ + return m_operator; +} + +void ParamDescriptor::setOperatorType(ParamDescriptor::ValueOperator operatorType) +{ + if (m_operator != operatorType) { + m_operator = operatorType; + emit operatorTypeChanged(); + } +} diff --git a/libguh-common/types/paramdescriptor.h b/libguh-common/types/paramdescriptor.h new file mode 100644 index 00000000..f65f3ba6 --- /dev/null +++ b/libguh-common/types/paramdescriptor.h @@ -0,0 +1,33 @@ +#ifndef PARAMDESCRIPTOR_H +#define PARAMDESCRIPTOR_H + +#include "param.h" + +class ParamDescriptor : public Param +{ + Q_OBJECT + Q_PROPERTY(ValueOperator operatorType READ operatorType WRITE setOperatorType NOTIFY operatorTypeChanged) +public: + enum ValueOperator { + ValueOperatorEquals, + ValueOperatorNotEquals, + ValueOperatorLess, + ValueOperatorGreater, + ValueOperatorLessOrEqual, + ValueOperatorGreaterOrEqual + }; + Q_ENUM(ValueOperator) + + explicit ParamDescriptor(const QString &id = QString(), const QVariant &value = QVariant(), QObject *parent = nullptr); + + ValueOperator operatorType() const; + void setOperatorType(ValueOperator operatorType); + +signals: + void operatorTypeChanged(); + +private: + ValueOperator m_operator; +}; + +#endif // PARAMDESCRIPTOR_H diff --git a/libguh-common/types/paramdescriptors.cpp b/libguh-common/types/paramdescriptors.cpp new file mode 100644 index 00000000..301519ac --- /dev/null +++ b/libguh-common/types/paramdescriptors.cpp @@ -0,0 +1,49 @@ +#include "paramdescriptors.h" +#include "paramdescriptor.h" + +ParamDescriptors::ParamDescriptors(QObject *parent) : QAbstractListModel(parent) +{ + +} + +int ParamDescriptors::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return m_list.count(); +} + +QVariant ParamDescriptors::data(const QModelIndex &index, int role) const +{ + return QVariant(); +} + +ParamDescriptor *ParamDescriptors::createNewParamDescriptor() const +{ + return new ParamDescriptor(); +} + +void ParamDescriptors::addParamDescriptor(ParamDescriptor *paramDescriptor) +{ + paramDescriptor->setParent(this); + beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); + m_list.append(paramDescriptor); + endInsertRows(); + emit countChanged(); +} + +void ParamDescriptors::setParamDescriptor(const QString ¶mTypeId, const QVariant &value, ValueOperator operatorType) +{ + foreach (ParamDescriptor* paramDescriptor, m_list) { + if (paramDescriptor->id() == paramTypeId) { + paramDescriptor->setValue(value); + paramDescriptor->setOperatorType((ParamDescriptor::ValueOperator)operatorType); + return; + } + } + // Still here? need to add a new one + ParamDescriptor* paramDescriptor = createNewParamDescriptor(); + paramDescriptor->setId(paramTypeId); + paramDescriptor->setValue(value); + paramDescriptor->setOperatorType((ParamDescriptor::ValueOperator)operatorType); + addParamDescriptor(paramDescriptor); +} diff --git a/libguh-common/types/paramdescriptors.h b/libguh-common/types/paramdescriptors.h new file mode 100644 index 00000000..5ccb70df --- /dev/null +++ b/libguh-common/types/paramdescriptors.h @@ -0,0 +1,40 @@ +#ifndef PARAMDESCRIPTORS_H +#define PARAMDESCRIPTORS_H + +#include + +#include "paramdescriptor.h" + +class ParamDescriptors : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) +public: + enum ValueOperator { + ValueOperatorEquals, + ValueOperatorNotEquals, + ValueOperatorLess, + ValueOperatorGreater, + ValueOperatorLessOrEqual, + ValueOperatorGreaterOrEqual + }; + Q_ENUM(ValueOperator) + + explicit ParamDescriptors(QObject *parent = nullptr); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; + + ParamDescriptor* createNewParamDescriptor() const; + void addParamDescriptor(ParamDescriptor* paramDescriptor); + + Q_INVOKABLE void setParamDescriptor(const QString ¶mTypeId, const QVariant &value, ValueOperator operatorType); + +signals: + void countChanged(); + +private: + QList m_list; +}; + +#endif // PARAMDESCRIPTORS_H diff --git a/libguh-common/types/rule.h b/libguh-common/types/rule.h index dae6d241..9dfacebc 100644 --- a/libguh-common/types/rule.h +++ b/libguh-common/types/rule.h @@ -18,7 +18,7 @@ class Rule : public QObject Q_PROPERTY(StateEvaluator* stateEvaluator READ stateEvaluator CONSTANT) Q_PROPERTY(RuleActions* ruleActions READ ruleActions CONSTANT) public: - explicit Rule(const QUuid &id, QObject *parent = nullptr); + explicit Rule(const QUuid &id = QUuid(), QObject *parent = nullptr); QUuid id() const; diff --git a/libguh-common/types/ruleactionparams.cpp b/libguh-common/types/ruleactionparams.cpp index abea6b37..ff8df1e0 100644 --- a/libguh-common/types/ruleactionparams.cpp +++ b/libguh-common/types/ruleactionparams.cpp @@ -9,6 +9,7 @@ RuleActionParams::RuleActionParams(QObject *parent) : QAbstractListModel(parent) int RuleActionParams::rowCount(const QModelIndex &parent) const { + Q_UNUSED(parent) return m_list.count(); }