diff --git a/guh-control/ui/DevicesPage.qml b/guh-control/ui/DevicesPage.qml index ee78d1b4..7dcf62de 100644 --- a/guh-control/ui/DevicesPage.qml +++ b/guh-control/ui/DevicesPage.qml @@ -23,7 +23,6 @@ GridView { Pane { anchors.fill: parent anchors.margins: app.margins -// color: "#22000000" Material.elevation: 1 Column { anchors.centerIn: parent diff --git a/guh-control/ui/MainPage.qml b/guh-control/ui/MainPage.qml index 43cce5de..f136675e 100644 --- a/guh-control/ui/MainPage.qml +++ b/guh-control/ui/MainPage.qml @@ -50,14 +50,13 @@ Page { ColumnLayout { anchors.fill: parent - anchors.margins: app.margins SwipeView { id: swipeView Layout.fillWidth: true Layout.fillHeight: true currentIndex: pageIndicator.currentIndex -// clip: true + clip: true DevicesPage { width: parent.view.width diff --git a/guh-control/ui/magic/EditRulePage.qml b/guh-control/ui/magic/EditRulePage.qml index edc3b80c..20c0c6f9 100644 --- a/guh-control/ui/magic/EditRulePage.qml +++ b/guh-control/ui/magic/EditRulePage.qml @@ -142,10 +142,9 @@ Page { Layout.fillWidth: true spacing: app.margins Repeater { - model: root.rule.eventDescriptors.get(index).paramDescriptors + model: eventDelegate.eventDescriptor.paramDescriptors Label { text: { - print("***", eventDelegate.iface, eventDelegate.eventDescriptor.interfaceName, Interfaces.findByName(eventDelegate.eventDescriptor.interfaceName), eventDescriptor.interfaceName ? Interfaces.findByName(eventDescriptor.interfaceName) : null) var ret = eventDelegate.eventType.paramTypes.getParamType(model.id).displayName switch (model.operator) { case ParamDescriptor.ValueOperatorEquals: @@ -216,22 +215,25 @@ Page { delegate: SwipeDelegate { id: actionDelegate Layout.fillWidth: true - property var device: Engine.deviceManager.devices.getDevice(root.rule.ruleActions.get(index).deviceId) + property var ruleAction: root.rule.ruleActions.get(index) + property var device: ruleAction.deviceId ? Engine.deviceManager.devices.getDevice(ruleAction.deviceId) : null + property var iface: ruleAction.interfaceName ? Interfaces.findByName(ruleAction.interfaceName) : null 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 + property var actionType: deviceClass ? deviceClass.actionTypes.getActionType(ruleAction.actionTypeId) + : iface ? iface.actionTypes.findByName(ruleAction.interfaceAction) : null contentItem: ColumnLayout { Label { Layout.fillWidth: true - text: qsTr("%1 - %2").arg(actionDelegate.device.name).arg(actionDelegate.actionType.displayName) + text: qsTr("%1 - %2").arg(actionDelegate.device ? actionDelegate.device.name : actionDelegate.iface.displayName).arg(actionDelegate.actionType.displayName) } RowLayout { Layout.fillWidth: true spacing: app.margins Repeater { - model: root.rule.ruleActions.get(index).ruleActionParams + model: actionDelegate.ruleAction.ruleActionParams Label { - text: actionType.paramTypes.getParamType(model.paramTypeId).displayName + " -> " + model.value + text: actionDelegate.actionType.paramTypes.getParamType(model.paramTypeId).displayName + " -> " + model.value font.pixelSize: app.smallFont } } diff --git a/guh-control/ui/magic/SelectEventDescriptorPage.qml b/guh-control/ui/magic/SelectEventDescriptorPage.qml index faa3492d..a9fa49e7 100644 --- a/guh-control/ui/magic/SelectEventDescriptorPage.qml +++ b/guh-control/ui/magic/SelectEventDescriptorPage.qml @@ -43,9 +43,7 @@ Page { function buildInterface() { if (header.interfacesMode) { if (root.device) { - print("device supports interfaces", deviceClass.interfaces) for (var i = 0; i < Interfaces.count; i++) { - print("event is for interface", Interfaces.get(i).name) if (deviceClass.interfaces.indexOf(Interfaces.get(i).name) >= 0) { actualModel.append(Interfaces.get(i)) } diff --git a/guh-control/ui/magic/SelectRuleActionPage.qml b/guh-control/ui/magic/SelectRuleActionPage.qml index 92eaaac0..46502f8c 100644 --- a/guh-control/ui/magic/SelectRuleActionPage.qml +++ b/guh-control/ui/magic/SelectRuleActionPage.qml @@ -23,71 +23,55 @@ Page { id: header onBackPressed: root.backPressed(); - property bool interfacesMode: false + property bool interfacesMode: root.ruleAction.interfaceName !== "" onInterfacesModeChanged: root.buildInterface() HeaderButton { imageSource: header.interfacesMode ? "../images/view-expand.svg" : "../images/view-collapse.svg" + visible: root.ruleAction.interfaceName === "" 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" } - } +// 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) + for (var i = 0; i < Interfaces.count; i++) { 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)) - } - } + listView.model = Interfaces.findByName(root.ruleAction.interfaceName).actionTypes } 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}) - } + listView.model = deviceClass.actionTypes } } } - ListModel { - id: actualModel - ListElement { text: ""; actionTypeId: "" } - } - ListView { + id: listView anchors.fill: parent - model: actualModel delegate: ItemDelegate { - text: model.text + text: model.displayName width: parent.width onClicked: { if (header.interfacesMode) { @@ -100,10 +84,24 @@ Page { default: console.warn("FIXME: Unhandled interface action"); } + } 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}) + paramsPage.onBackPressed.connect(function() {pageStack.pop()}); + paramsPage.onCompleted.connect(function() { + pageStack.pop(); + root.done(); + }) + } else { + root.done(); + } + } else { + console.warn("Neither deviceId not interfaceName set. Cannot continue..."); } } else { if (root.device) { - var actionType = root.deviceClass.actionTypes.getActionType(model.actionTypeId); + var actionType = root.deviceClass.actionTypes.getActionType(model.id); console.log("ActionType", actionType.id, "selected. Has", actionType.paramTypes.count, "params"); root.ruleAction.actionTypeId = actionType.id; if (actionType.paramTypes.count > 0) { diff --git a/guh-control/ui/magic/SelectRuleActionParamsPage.qml b/guh-control/ui/magic/SelectRuleActionParamsPage.qml index 45cd7e7f..3f8dc779 100644 --- a/guh-control/ui/magic/SelectRuleActionParamsPage.qml +++ b/guh-control/ui/magic/SelectRuleActionParamsPage.qml @@ -11,7 +11,9 @@ Page { 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 + readonly property var iface: ruleAction && ruleAction.interfaceName ? Interfaces.findByName(ruleAction.interfaceName) : null + readonly property var actionType: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId).actionTypes.getActionType(ruleAction.actionTypeId) + : iface ? iface.actionTypes.findByName(ruleAction.interfaceAction) : null signal backPressed(); signal completed(); diff --git a/guh-control/ui/paramdelegates-ng/ParamDelegate.qml b/guh-control/ui/paramdelegates-ng/ParamDelegate.qml index b79435bd..b80ccc85 100644 --- a/guh-control/ui/paramdelegates-ng/ParamDelegate.qml +++ b/guh-control/ui/paramdelegates-ng/ParamDelegate.qml @@ -32,17 +32,18 @@ ItemDelegate { return stringComponent; } - switch (root.paramType.type) { - case "Bool": + switch (root.paramType.type.toLowerCase()) { + case "bool": return boolComponent; - case "Int": + case "int": return stringComponent; - case "String": + case "string": + case "qstring": if (root.paramType.allowedValues.length > 0) { return comboBoxComponent; } return textFieldComponent; - case "Color": + case "color": return colorPreviewComponent; } console.warn("Param Delegate: Fallback to stringComponent", root.paramType.name, root.paramType.type) @@ -53,14 +54,14 @@ ItemDelegate { Loader { Layout.fillWidth: true sourceComponent: { - switch (root.paramType.type) { - case "Int": - case "Double": + switch (root.paramType.type.toLowerCase()) { + case "int": + case "double": if (root.paramType.minValue != undefined && root.paramType.maxValue != undefined) { return sliderComponent } break; - case "Color": + case "color": return colorPickerComponent } return null; @@ -72,8 +73,8 @@ ItemDelegate { id: stringComponent Label { text: { - switch (root.paramType.type) { - case "Int": + switch (root.paramType.type.toLowerCase()) { + case "int": return Math.round(root.param.value); } return root.param.value; diff --git a/guh-control/ui/paramdescriptordelegates/ParamDescriptorDelegateBase.qml b/guh-control/ui/paramdescriptordelegates/ParamDescriptorDelegateBase.qml index 22b44b3e..5b2bc078 100644 --- a/guh-control/ui/paramdescriptordelegates/ParamDescriptorDelegateBase.qml +++ b/guh-control/ui/paramdescriptordelegates/ParamDescriptorDelegateBase.qml @@ -23,6 +23,7 @@ ItemDelegate { switch (paramType.type.toLowerCase()) { case "bool": case "string": + case "qstring": return ["is", "is not"]; case "int": case "double": @@ -71,6 +72,7 @@ ItemDelegate { } return textFieldComponent; case "string": + case "qstring": if (paramType.allowedValues.length > 0) { return comboBoxComponent } @@ -85,9 +87,9 @@ ItemDelegate { Loader { Layout.fillWidth: true sourceComponent: { - switch (paramType.type) { - case "Int": - case "Double": + switch (paramType.type.toLowerCase()) { + case "int": + case "double": if (paramType.minValue !== undefined && paramType.maxValue !== undefined) { return sliderComponent } @@ -102,8 +104,8 @@ ItemDelegate { id: labelComponent Label { text: { - switch (root.paramType.type) { - case "Int": + switch (root.paramType.type.toLowerCase()) { + case "int": return Math.round(root.value) } return root.value diff --git a/libguh-common/types/actiontypes.cpp b/libguh-common/types/actiontypes.cpp index bb62b387..9b1b953d 100644 --- a/libguh-common/types/actiontypes.cpp +++ b/libguh-common/types/actiontypes.cpp @@ -60,10 +60,13 @@ QVariant ActionTypes::data(const QModelIndex &index, int role) const return QVariant(); ActionType *actionType = m_actionTypes.at(index.row()); - if (role == NameRole) { - return actionType->name(); - } else if (role == IdRole) { + switch (role) { + case RoleId: return actionType->id(); + case RoleName: + return actionType->name(); + case RoleDisplayName: + return actionType->displayName(); } return QVariant(); } @@ -98,7 +101,8 @@ void ActionTypes::clearModel() QHash ActionTypes::roleNames() const { QHash roles; - roles[NameRole] = "name"; - roles[IdRole] = "id"; + roles.insert(RoleId, "id"); + roles.insert(RoleName, "name"); + roles.insert(RoleDisplayName, "displayName"); return roles; } diff --git a/libguh-common/types/actiontypes.h b/libguh-common/types/actiontypes.h index 3c3a39ca..0ed019e6 100644 --- a/libguh-common/types/actiontypes.h +++ b/libguh-common/types/actiontypes.h @@ -33,9 +33,10 @@ class ActionTypes : public QAbstractListModel Q_OBJECT Q_PROPERTY(int count READ rowCount NOTIFY countChanged) public: - enum ActionTypeRole { - NameRole = Qt::DisplayRole, - IdRole + enum Roles { + RoleId, + RoleName, + RoleDisplayName }; ActionTypes(QObject *parent = 0); diff --git a/libguh-common/types/interfaces.cpp b/libguh-common/types/interfaces.cpp index edc56c74..2e170966 100644 --- a/libguh-common/types/interfaces.cpp +++ b/libguh-common/types/interfaces.cpp @@ -3,41 +3,63 @@ #include "eventtypes.h" #include "eventtype.h" +#include "actiontypes.h" +#include "actiontype.h" Interfaces::Interfaces(QObject *parent) : QAbstractListModel(parent) { Interface* iface = nullptr; - EventType* ev = nullptr; + EventType* et = nullptr; + ActionType* at = nullptr; ParamType* pt = nullptr; ParamTypes *pts = nullptr; iface = new Interface("battery", "Battery powered devices"); - ev = new EventType(); - pts = new ParamTypes(ev); - ev->setParamTypes(pts); + et = new EventType(); + pts = new ParamTypes(et); + et->setParamTypes(pts); - ev->setName("batteryLevel"); - ev->setDisplayName("Battery level changed"); + et->setName("batteryLevel"); + et->setDisplayName("Battery level changed"); pt = new ParamType("batteryLevel", QVariant::Int, 50); pt->setDisplayName("Battery Level"); qDebug() << "added param" << pt->type(); pt->setMinValue(0); pt->setMaxValue(100); - ev->paramTypes()->addParamType(pt); - iface->eventTypes()->addEventType(ev); + et->paramTypes()->addParamType(pt); + iface->eventTypes()->addEventType(et); - ev = new EventType(); - pts = new ParamTypes(ev); - ev->setParamTypes(pts); - ev->setName("batteryCritical"); - ev->setDisplayName("Battery level critical"); + et = new EventType(); + pts = new ParamTypes(et); + et->setParamTypes(pts); + et->setName("batteryCritical"); + et->setDisplayName("Battery level critical"); pt = new ParamType("batteryCritical", QVariant::Bool, true); pt->setDisplayName("Battery critical"); - ev->paramTypes()->addParamType(pt); - iface->eventTypes()->addEventType(ev); + et->paramTypes()->addParamType(pt); + iface->eventTypes()->addEventType(et); m_list.append(iface); + + + iface = new Interface("notification", "Notification services"); + at = new ActionType(); + pts = new ParamTypes(at); + at->setParamTypes(pts); + + at->setName("notify"); + at->setDisplayName("Send notification"); + pt = new ParamType("title", QVariant::String); + pt->setDisplayName("Title"); + at->paramTypes()->addParamType(pt); + pt = new ParamType("body", QVariant::String); + pt->setDisplayName("Message body"); + at->paramTypes()->addParamType(pt); + iface->actionTypes()->addActionType(at); + + m_list.append(iface); + } int Interfaces::rowCount(const QModelIndex &parent) const