more work on rules

pull/1/head
Michael Zanetti 2018-02-18 19:07:02 +01:00
parent 27b8946ff5
commit 0592ee6133
31 changed files with 520 additions and 46 deletions

View File

@ -85,7 +85,7 @@ void DeviceManager::notificationReceived(const QVariantMap &data)
{
QString notification = data.value("notification").toString();
if (notification == "Devices.StateChanged") {
qDebug() << "Device state changed" << data.value("params");
// qDebug() << "Device state changed" << data.value("params");
Device *dev = m_devices->getDevice(data.value("params").toMap().value("deviceId").toUuid());
if (!dev) {
qWarning() << "Device state change notification received for an unknown device";

View File

@ -120,4 +120,6 @@ DISTFILES += \
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
target.path = /usr/bin
INSTALLS += target

View File

@ -254,10 +254,11 @@ void JsonRpcClient::dataReceived(const QByteArray &data)
JsonHandler *handler = m_notificationHandlers.value(nameSpace).first;
if (!handler) {
qWarning() << "JsonRpc: handler not implemented:" << nameSpace;
// qWarning() << "JsonRpc: handler not implemented:" << nameSpace;
return;
}
// qDebug() << "Incoming notification:" << jsonDoc.toJson();
QMetaObject::invokeMethod(handler, m_notificationHandlers.value(nameSpace).second.toLatin1().data(), Q_ARG(QVariantMap, dataMap));
}
}

View File

@ -24,6 +24,13 @@
#include "deviceclasses.h"
#include "types/params.h"
#include "types/paramtypes.h"
#include "types/rule.h"
#include "types/ruleaction.h"
#include "types/ruleactions.h"
#include "types/eventdescriptor.h"
#include "types/eventdescriptors.h"
#include "types/ruleactionparam.h"
#include "types/ruleactionparams.h"
#include <QMetaEnum>
@ -165,7 +172,7 @@ EventType *JsonTypes::unpackEventType(const QVariantMap &eventTypeMap, QObject *
ActionType *JsonTypes::unpackActionType(const QVariantMap &actionTypeMap, QObject *parent)
{
ActionType *actionType = new ActionType(parent);
actionType->setId(actionTypeMap.value("id").toUuid());
actionType->setId(actionTypeMap.value("id").toString());
actionType->setName(actionTypeMap.value("name").toString());
actionType->setDisplayName(actionTypeMap.value("displayName").toString());
actionType->setIndex(actionTypeMap.value("index").toInt());
@ -207,6 +214,58 @@ Device *JsonTypes::unpackDevice(const QVariantMap &deviceMap, QObject *parent)
return device;
}
QVariantMap JsonTypes::packRule(Rule *rule)
{
QVariantMap ret;
ret.insert("ruleId", rule->id());
ret.insert("name", rule->name());
ret.insert("enabled", true);
if (rule->ruleActions()->rowCount() > 0) {
QVariantList actions;
for (int i = 0; i < rule->ruleActions()->rowCount(); i++) {
QVariantMap ruleAction;
ruleAction.insert("actionTypeId", rule->ruleActions()->get(i)->actionTypeId());
ruleAction.insert("deviceId", rule->ruleActions()->get(i)->deviceId());
if (rule->ruleActions()->get(i)->ruleActionParams()->rowCount() > 0) {
QVariantList ruleActionParams;
for (int j = 0; j < rule->ruleActions()->get(i)->ruleActionParams()->rowCount(); j++) {
QVariantMap ruleActionParam;
ruleActionParam.insert("paramTypeId", rule->ruleActions()->get(i)->ruleActionParams()->get(j)->paramTypeId());
ruleActionParam.insert("value", rule->ruleActions()->get(i)->ruleActionParams()->get(j)->value());
ruleActionParams.append(ruleActionParam);
}
ruleAction.insert("ruleActionParams", ruleActionParams);
}
actions.append(ruleAction);
}
ret.insert("actions", actions);
}
if (rule->eventDescriptors()->rowCount() > 0) {
QVariantList eventDescriptors;
for (int i = 0; i < rule->eventDescriptors()->rowCount(); i++) {
QVariantMap eventDescriptor;
eventDescriptor.insert("eventTypeId", rule->eventDescriptors()->get(i)->eventTypeId());
eventDescriptor.insert("deviceId", rule->eventDescriptors()->get(i)->deviceId());
if (rule->eventDescriptors()->get(i)->paramDescriptors()->rowCount() > 0) {
QVariantList paramDescriptors;
for (int j = 0; j < rule->eventDescriptors()->get(i)->paramDescriptors()->rowCount(); j++) {
QVariantMap paramDescriptor;
paramDescriptor.insert("paramTypeId", rule->eventDescriptors()->get(i)->paramDescriptors()->get(j)->id());
paramDescriptor.insert("value", rule->eventDescriptors()->get(i)->paramDescriptors()->get(j)->value());
paramDescriptors.append(paramDescriptor);
}
eventDescriptor.insert("paramDescriptors", paramDescriptors);
}
eventDescriptors.append(eventDescriptor);
}
ret.insert("eventDescriptors", eventDescriptors);
}
return ret;
}
DeviceClass::SetupMethod JsonTypes::stringToSetupMethod(const QString &setupMethodString)
{
if (setupMethodString == "SetupMethodJustAdd") {

View File

@ -37,6 +37,7 @@
#include "types/actiontype.h"
class Vendor;
class Rule;
class JsonTypes : public QObject
{
@ -54,6 +55,7 @@ public:
static ActionType *unpackActionType(const QVariantMap &actionTypeMap, QObject *parent);
static Device *unpackDevice(const QVariantMap &deviceMap, QObject *parent);
static QVariantMap packRule(Rule* rule);
private:
static DeviceClass::SetupMethod stringToSetupMethod(const QString &setupMethodString);
static QList<DeviceClass::BasicTag> stringListToBasicTags(const QStringList &basicTagsStringList);

View File

@ -18,7 +18,7 @@
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <QCoreApplication>
#include <QGuiApplication>
#include <QCommandLineParser>
#include <QtQml/QQmlContext>
#include <QQmlApplicationEngine>
@ -48,7 +48,7 @@
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication application(argc, argv);
QGuiApplication application(argc, argv);
application.setApplicationName("guh-control");
application.setOrganizationName("guh");

View File

@ -112,5 +112,8 @@
<file>ui/magic/ComposeEventDescriptorPage.qml</file>
<file>ui/images/view-expand.svg</file>
<file>ui/images/view-collapse.svg</file>
<file>ui/magic/SelectRuleActionPage.qml</file>
<file>ui/magic/SelectRuleActionParamsPage.qml</file>
<file>ui/images/tick.svg</file>
</qresource>
</RCC>

View File

@ -1,6 +1,7 @@
#include "rulemanager.h"
#include "jsonrpc/jsonrpcclient.h"
#include "jsonrpc/jsontypes.h"
#include "types/rule.h"
#include "types/eventdescriptor.h"
#include "types/eventdescriptors.h"
@ -49,6 +50,12 @@ void RuleManager::addRule(const QVariantMap params)
m_jsonClient->sendCommand("Rules.AddRule", params, this, "addRuleReply");
}
void RuleManager::addRule(Rule *rule)
{
QVariantMap params = JsonTypes::packRule(rule);
m_jsonClient->sendCommand("Rules.AddRule", params, this, "addRuleReply");
}
void RuleManager::removeRule(const QUuid &ruleId)
{
QVariantMap params;
@ -56,6 +63,13 @@ void RuleManager::removeRule(const QUuid &ruleId)
m_jsonClient->sendCommand("Rules.RemoveRule", params, this, "removeRuleReply");
}
void RuleManager::editRule(Rule *rule)
{
QVariantMap params = JsonTypes::packRule(rule);
m_jsonClient->sendCommand("Rules.EditRule", params, this, "editRuleReply");
}
void RuleManager::handleRulesNotification(const QVariantMap &params)
{
qDebug() << "rules notification received" << params;
@ -124,6 +138,11 @@ void RuleManager::removeRuleReply(const QVariantMap &params)
qDebug() << "Have remove rule reply" << params;
}
void RuleManager::editRuleReply(const QVariantMap &params)
{
qDebug() << "Edit rule reply:" << params;
}
void RuleManager::parseEventDescriptors(const QVariantList &eventDescriptorList, Rule *rule)
{
foreach (const QVariant &eventDescriptorVariant, eventDescriptorList) {
@ -156,9 +175,10 @@ StateEvaluator *RuleManager::parseStateEvaluator(const QVariantMap &stateEvaluat
op = StateDescriptor::ValueOperatorGreaterOrEqual;
}
StateDescriptor *sd = new StateDescriptor(sdMap.value("deviceId").toUuid(), op, sdMap.value("stateTypeId").toUuid(), sdMap.value("value"), stateEvaluator);
// stateEvaluator->
stateEvaluator->setStateDescriptor(sd);
}
return stateEvaluator;
}
void RuleManager::parseRuleActions(const QVariantList &ruleActions, Rule *rule)

View File

@ -27,7 +27,9 @@ public:
Q_INVOKABLE Rule* createNewRule();
Q_INVOKABLE void addRule(const QVariantMap params);
Q_INVOKABLE void addRule(Rule *rule);
Q_INVOKABLE void removeRule(const QUuid &ruleId);
Q_INVOKABLE void editRule(Rule *rule);
private slots:
void handleRulesNotification(const QVariantMap &params);
@ -35,6 +37,7 @@ private slots:
void getRuleDetailsReply(const QVariantMap &params);
void addRuleReply(const QVariantMap &params);
void removeRuleReply(const QVariantMap &params);
void editRuleReply(const QVariantMap &params);
private:
void parseEventDescriptors(const QVariantList &eventDescriptorList, Rule *rule);

View File

@ -11,7 +11,12 @@ Page {
HeaderButton {
imageSource: Qt.resolvedUrl("images/add.svg")
onClicked: pageStack.push(Qt.resolvedUrl("magic/NewRulePage.qml"), {rule: Engine.ruleManager.createNewRule() })
onClicked: {
var newRulePage = pageStack.push(Qt.resolvedUrl("magic/EditRulePage.qml"), {rule: Engine.ruleManager.createNewRule() });
newRulePage.onAccept.connect(function() {
Engine.ruleManager.addRule(newRulePage.rule);
})
}
}
}
@ -19,15 +24,37 @@ Page {
anchors.fill: parent
model: Engine.ruleManager.rules
delegate: ItemDelegate {
delegate: SwipeDelegate {
width: parent.width
Label {
text: model.name
}
text: model.name
onClicked: {
pageStack.push(Qt.resolvedUrl("magic/EditRulePage.qml"), {rule: Engine.ruleManager.rules.get(index) })
var editRulePage = pageStack.push(Qt.resolvedUrl("magic/EditRulePage.qml"), {rule: Engine.ruleManager.rules.get(index) })
editRulePage.onAccept.connect(function() {
Engine.ruleManager.editRule(editRulePage.rule);
})
}
// swipe.right: ColorIcon {
// name: "delete.svg"
// color: "red"
// }
swipe.right: Label {
id: deleteLabel
text: qsTr("Delete")
color: "white"
verticalAlignment: Label.AlignVCenter
padding: 12
height: parent.height
anchors.right: parent.right
SwipeDelegate.onClicked: Engine.ruleManager.removeRule(model.id)
background: Rectangle {
color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
}
}
}
}
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg id="svg4874" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="96" viewBox="0 0 96 96.000001" width="96" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata id="metadata4879">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g id="layer1" transform="translate(67.857 -78.505)">
<rect id="rect4782" style="color:#000000;fill:none" transform="rotate(90)" height="96" width="96" y="-28.143" x="78.505"/>
<path id="path4041-9" style="fill:#808080" d="m21.228 99.016-46.196 41.447-26.606-23.802-4.2834 4.8422 30.878 32.49 49.122-51.691z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 936 B

View File

@ -1,36 +1,167 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick 2.8
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
import "../components"
import QtQuick.Layouts 1.2
import Guh 1.0
Page {
id: root
property var rule: null
signal accept();
function addEventDescriptor() {
var eventDescriptor = root.rule.eventDescriptors.createNewEventDescriptor();
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"));
page.onBackPressed.connect(function() { pageStack.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 = pageStack.push(Qt.resolvedUrl("SelectEventPage.qml"), {text: "Select event", eventDescriptor: eventDescriptor});
eventPage.onBackPressed.connect(function() {pageStack.pop()})
eventPage.onDone.connect(function() {
root.rule.eventDescriptors.addEventDescriptor(eventPage.eventDescriptor);
pageStack.pop(root)
})
}
function addRuleAction() {
var ruleAction = root.rule.ruleActions.createNewRuleAction();
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"));
page.onBackPressed.connect(function() { pageStack.pop() })
page.onThingSelected.connect(function(device) {
ruleAction.deviceId = device.id;
selectRuleActionData(ruleAction)
})
page.onInterfaceSelected.connect(function(interfaceName) {
ruleAction.interfaceName = interfaceName;
selectRuleActionData(ruleAction)
})
}
function selectRuleActionData(ruleAction) {
var ruleActionPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionPage.qml"), {text: "Select action", ruleAction: ruleAction });
ruleActionPage.onBackPressed.connect(function() {
ruleAction.destroy();
pageStack.pop(root);
})
ruleActionPage.onDone.connect(function() {
root.rule.ruleActions.addRuleAction(ruleAction)
pageStack.pop(root);
})
}
header: GuhHeader {
text: "Add some magic"
text: "New rule"
onBackPressed: pageStack.pop()
HeaderButton {
imageSource: "../images/tick.svg"
onClicked: {
root.accept()
}
}
}
ColumnLayout {
anchors.fill: parent
Label {
text: "When"
text: "Rule name"
}
TextField {
Layout.fillWidth: true
text: root.rule.name
onTextChanged: {
root.rule.name = text;
}
}
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 {
model: rule.eventDescriptors
ItemDelegate {
property var device: Engine.deviceManager.devices.getDevice(model.deviceId)
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(model.eventTypeId) : null
property var eventType: deviceClass ? deviceClass.eventTypes.getEventType(root.rule.eventDescriptors.get(index).eventTypeId) : null
contentItem: ColumnLayout {
Label {
text: device ? device.name : "Unknown device"
text: eventDelegate.device ? eventDelegate.device.name : "Unknown device" + root.rule.eventDescriptors.get(index).deviceId
Layout.fillWidth: true
}
Label {
text: eventType ? eventType.name : "Unknown event"
text: eventDelegate.eventType ? eventDelegate.eventType.displayName : "Unknown event" + root.rule.eventDescriptors.get(index).eventTypeId
}
}
}
}
Label {
text: "do the following:" + root.rule.ruleActions.count
}
RowLayout {
Layout.fillWidth: true
visible: actionsRepeater.count == 0
Label {
Layout.fillWidth: true
text: "Add action which should be executed when the rule is triggered"
wrapMode: Text.WordWrap
}
Button {
text: "+"
onClicked: root.addRuleAction();
}
}
Repeater {
id: actionsRepeater
model: root.rule.ruleActions
delegate: ItemDelegate {
id: actionDelegate
property var device: Engine.deviceManager.devices.getDevice(root.rule.ruleActions.get(index).deviceId)
property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
property var actionType: deviceClass ? deviceClass.actionTypes.getActionType(root.rule.ruleActions.get(index).actionTypeId) : null
contentItem: ColumnLayout {
Label {
text: actionDelegate.device.name
}
Label {
text: actionDelegate.actionType.displayName
}
}
}

View File

@ -0,0 +1,122 @@
import QtQuick 2.4
import QtQuick.Controls 2.1
import "../components"
import Guh 1.0
Page {
id: root
property alias text: header.text
// a ruleAction object needs to be set and prefilled with either deviceId or interfaceName
property var ruleAction: 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
signal backPressed();
signal done();
onRuleActionChanged: buildInterface()
Component.onCompleted: buildInterface()
header: GuhHeader {
id: header
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: actionTemplateModel
ListElement { interfaceName: "light"; text: "Switch light"; identifier: "switchLight"}
ListElement { interfaceName: "dimmablelight"; text: "Dim light"; identifier: "dimLight"}
ListElement { interfaceName: "colorlight"; text: "Set light color"; identifier: "colorLight" }
ListElement { interfaceName: "mediacontroller"; text: "Pause playback"; identifier: "pausePlayback" }
ListElement { interfaceName: "mediacontroller"; text: "Resume playback"; identifier: "resumePlayback" }
ListElement { interfaceName: "extendedvolumecontroller"; text: "Set volume"; identifier: "setVolume" }
ListElement { interfaceName: "extendedvolumecontroller"; text: "Mute"; identifier: "mute" }
ListElement { interfaceName: "extendedvolumecontroller"; text: "Unmute"; identifier: "unmute" }
ListElement { interfaceName: "notifications"; text: "Notify me"; identifier: "notify" }
}
function buildInterface() {
actualModel.clear()
if (header.interfacesMode) {
if (root.device) {
print("device supports interfaces", deviceClass.interfaces)
for (var i = 0; i < actionTemplateModel.count; i++) {
print("action is for interface", actionTemplateModel.get(i).interfaceName)
if (deviceClass.interfaces.indexOf(actionTemplateModel.get(i).interfaceName) >= 0) {
actualModel.append(actionTemplateModel.get(i))
}
}
} else if (root.ruleAction.interfaceName !== "") {
for (var i = 0; i < actionTemplateModel.count; i++) {
if (actionTemplateModel.get(i).interfaceName === root.ruleAction.interfaceName) {
actualModel.append(actionTemplateModel.get(i))
}
}
} else {
console.warn("You need to set device or interfaceName");
}
} else {
if (root.device) {
print("fdsfasdfdsafdas", deviceClass.actionTypes.count)
for (var i = 0; i < deviceClass.actionTypes.count; i++) {
print("bla", deviceClass.actionTypes.get(i).name, deviceClass.actionTypes.get(i).displayName, deviceClass.actionTypes.get(i).id)
actualModel.append({text: deviceClass.actionTypes.get(i).displayName, actionTypeId: deviceClass.actionTypes.get(i).id})
}
}
}
}
ListModel {
id: actualModel
ListElement { text: ""; actionTypeId: "" }
}
ListView {
anchors.fill: parent
model: actualModel
delegate: ItemDelegate {
text: model.text
onClicked: {
if (header.interfacesMode) {
if (root.device) {
print("selected:", model.identifier)
switch (model.identfier) {
case "switchLight":
root.done();
break;
default:
console.warn("FIXME: Unhandled interface action");
}
}
} else {
if (root.device) {
var actionType = root.deviceClass.actionTypes.getActionType(model.actionTypeId);
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})
paramsPage.onCompleted.connect(function() {
pageStack.pop();
root.done();
})
} else {
root.done();
}
}
}
}
}
}
}

View File

@ -0,0 +1,53 @@
import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.2
import "../components"
import "../paramdelegates"
import Guh 1.0
Page {
id: root
// Needs to be set and filled in with deviceId and actionTypeId
property var ruleAction
readonly property var device: ruleAction && ruleAction.deviceId ? Engine.deviceManager.devices.getDevice(ruleAction.deviceId) : null
readonly property var actionType: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId).actionTypes.getActionType(ruleAction.actionTypeId) : null
signal backPressed();
signal completed();
header: GuhHeader {
text: "params"
onBackPressed: root.backPressed();
}
ColumnLayout {
anchors.fill: parent
Repeater {
id: delegateRepeater
model: root.actionType.paramTypes
delegate: ParamDelegate {
paramType: root.actionType.paramTypes.get(index)
value: paramType.defaultValue
}
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
}
Button {
text: "OK"
Layout.fillWidth: true
Layout.margins: app.margins
onClicked: {
var params = [];
for (var i = 0; i < delegateRepeater.count; i++) {
var paramDelegate = delegateRepeater.itemAt(i);
root.ruleAction.ruleActionParams.setRuleActionParam(paramDelegate.paramType.id, paramDelegate.value)
}
root.completed()
}
}
}
}

View File

@ -10,6 +10,7 @@ Loader {
var comp;
switch (loader.paramType.type) {
case "bool":
case "Bool":
comp = "Bool";
break;
case "String":

View File

@ -27,12 +27,12 @@ ActionType::ActionType(QObject *parent) :
{
}
QUuid ActionType::id() const
QString ActionType::id() const
{
return m_id;
}
void ActionType::setId(const QUuid &id)
void ActionType::setId(const QString &id)
{
m_id = id;
}

View File

@ -31,7 +31,7 @@
class ActionType : public QObject
{
Q_OBJECT
Q_PROPERTY(QUuid id READ id CONSTANT)
Q_PROPERTY(QString 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)
@ -40,8 +40,8 @@ class ActionType : public QObject
public:
explicit ActionType(QObject *parent = 0);
QUuid id() const;
void setId(const QUuid &id);
QString id() const;
void setId(const QString &id);
QString name() const;
void setName(const QString &name);
@ -56,7 +56,7 @@ public:
void setParamTypes(ParamTypes *paramTypes);
private:
QUuid m_id;
QString m_id;
QString m_name;
QString m_displayName;
int m_index;

View File

@ -33,17 +33,12 @@ QList<ActionType *> ActionTypes::actionTypes()
return m_actionTypes;
}
int ActionTypes::count() const
{
return m_actionTypes.count();
}
ActionType *ActionTypes::get(int index) const
{
return m_actionTypes.at(index);
}
ActionType *ActionTypes::getActionType(const QUuid &actionTypeId) const
ActionType *ActionTypes::getActionType(const QString &actionTypeId) const
{
foreach (ActionType *actionType, m_actionTypes) {
if (actionType->id() == actionTypeId) {
@ -68,7 +63,7 @@ QVariant ActionTypes::data(const QModelIndex &index, int role) const
if (role == NameRole) {
return actionType->name();
} else if (role == IdRole) {
return actionType->id().toString();
return actionType->id();
}
return QVariant();
}
@ -79,6 +74,7 @@ void ActionTypes::addActionType(ActionType *actionType)
//qDebug() << "ActionTypes: loaded actionType" << actionType->name();
m_actionTypes.append(actionType);
endInsertRows();
emit countChanged();
}
ActionType *ActionTypes::findByName(const QString &name) const
@ -96,6 +92,7 @@ void ActionTypes::clearModel()
beginResetModel();
m_actionTypes.clear();
endResetModel();
emit countChanged();
}
QHash<int, QByteArray> ActionTypes::roleNames() const

View File

@ -31,7 +31,7 @@
class ActionTypes : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
public:
enum ActionTypeRole {
NameRole = Qt::DisplayRole,
@ -42,9 +42,8 @@ public:
QList<ActionType *> actionTypes();
Q_INVOKABLE int count() const;
Q_INVOKABLE ActionType *get(int index) const;
Q_INVOKABLE ActionType *getActionType(const QUuid &actionTypeId) const;
Q_INVOKABLE ActionType *getActionType(const QString &actionTypeId) const;
int rowCount(const QModelIndex & parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
@ -55,6 +54,9 @@ public:
void clearModel();
signals:
void countChanged();
protected:
QHash<int, QByteArray> roleNames() const;

View File

@ -184,7 +184,7 @@ void DeviceClass::setActionTypes(ActionTypes *actionTypes)
emit actionTypesChanged();
}
bool DeviceClass::hasActionType(const QUuid &actionTypeId)
bool DeviceClass::hasActionType(const QString &actionTypeId)
{
foreach (ActionType *actionType, m_actionTypes->actionTypes()) {
if (actionType->id() == actionTypeId) {

View File

@ -131,7 +131,7 @@ public:
ActionTypes *actionTypes() const;
void setActionTypes(ActionTypes *actionTypes);
Q_INVOKABLE bool hasActionType(const QUuid &actionTypeId);
Q_INVOKABLE bool hasActionType(const QString &actionTypeId);
static QString basicTagToString(BasicTag basicTag);

View File

@ -17,6 +17,11 @@ QVariant ParamDescriptors::data(const QModelIndex &index, int role) const
return QVariant();
}
ParamDescriptor *ParamDescriptors::get(int index) const
{
return m_list.at(index);
}
ParamDescriptor *ParamDescriptors::createNewParamDescriptor() const
{
return new ParamDescriptor();

View File

@ -25,6 +25,8 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role) const override;
ParamDescriptor* get(int index) const;
ParamDescriptor* createNewParamDescriptor() const;
void addParamDescriptor(ParamDescriptor* paramDescriptor);

View File

@ -12,7 +12,7 @@ class Rule : public QObject
{
Q_OBJECT
Q_PROPERTY(QUuid id READ id CONSTANT)
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged)
Q_PROPERTY(EventDescriptors* eventDescriptors READ eventDescriptors CONSTANT)
Q_PROPERTY(StateEvaluator* stateEvaluator READ stateEvaluator CONSTANT)

View File

@ -9,8 +9,8 @@ class RuleActionParams;
class RuleAction : public QObject
{
Q_OBJECT
Q_PROPERTY(QUuid deviceId READ deviceId NOTIFY deviceIdChanged)
Q_PROPERTY(QUuid actionTypeId READ actionTypeId NOTIFY actionTypeIdChanged)
Q_PROPERTY(QUuid deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged)
Q_PROPERTY(QUuid actionTypeId READ actionTypeId WRITE setActionTypeId NOTIFY actionTypeIdChanged)
Q_PROPERTY(RuleActionParams* ruleActionParams READ ruleActionParams CONSTANT)
public:

View File

@ -26,6 +26,22 @@ void RuleActionParams::addRuleActionParam(RuleActionParam *ruleActionParam)
endInsertRows();
}
void RuleActionParams::setRuleActionParam(const QString &paramTypeId, const QVariant &value)
{
foreach (RuleActionParam *rap, m_list) {
if (rap->paramTypeId() == paramTypeId) {
rap->setValue(value);
return;
}
}
// Still here? Need to add it
RuleActionParam *rap = new RuleActionParam(this);
rap->setParamTypeId(paramTypeId);
rap->setValue(value);
addRuleActionParam(rap);
}
RuleActionParam *RuleActionParams::get(int index) const
{
return m_list.at(index);

View File

@ -17,6 +17,7 @@ public:
void addRuleActionParam(RuleActionParam* ruleActionParam);
Q_INVOKABLE void setRuleActionParam(const QString &paramTypeId, const QVariant &value);
Q_INVOKABLE RuleActionParam* get(int index) const;
signals:

View File

@ -28,3 +28,8 @@ RuleAction *RuleActions::get(int index) const
{
return m_list.at(index);
}
RuleAction *RuleActions::createNewRuleAction() const
{
return new RuleAction();
}

View File

@ -15,9 +15,10 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role) const override;
void addRuleAction(RuleAction* ruleAction);
Q_INVOKABLE void addRuleAction(RuleAction* ruleAction);
Q_INVOKABLE RuleAction* get(int index) const;
Q_INVOKABLE RuleAction* createNewRuleAction() const;
signals:
void countChanged();

View File

@ -23,6 +23,8 @@ QVariant Rules::data(const QModelIndex &index, int role) const
switch (role) {
case RoleName:
return m_list.at(index.row())->name();
case RoleId:
return m_list.at(index.row())->id();
}
return QVariant();
}
@ -31,6 +33,7 @@ QHash<int, QByteArray> Rules::roleNames() const
{
QHash<int, QByteArray> roles;
roles.insert(RoleName, "name");
roles.insert(RoleId, "id");
return roles;
}

View File

@ -10,7 +10,8 @@ class Rules : public QAbstractListModel
Q_OBJECT
public:
enum Roles {
RoleName
RoleName,
RoleId
};
explicit Rules(QObject *parent = nullptr);