diff --git a/libnymea-app-core/devicemanager.cpp b/libnymea-app-core/devicemanager.cpp index d5666ab4..eb0da28f 100644 --- a/libnymea-app-core/devicemanager.cpp +++ b/libnymea-app-core/devicemanager.cpp @@ -457,6 +457,21 @@ void DeviceManager::refreshBrowserItems(BrowserItems *browserItems) m_browsingRequests.insert(id, browserItems); } +BrowserItem *DeviceManager::browserItem(const QUuid &deviceId, const QString &itemId) +{ + QVariantMap params; + params.insert("deviceId", deviceId.toString()); + params.insert("itemId", itemId); + int id = m_jsonClient->sendCommand("Devices.GetBrowserItem", params, this, "browserItemResponse"); + + // Intentionally not parented. The caller takes ownership and needs to destroy when not needed any more. + BrowserItem *item = new BrowserItem(itemId); + QPointer itemPtr(item); + m_browserDetailsRequests.insert(id, itemPtr); + + return item; +} + void DeviceManager::browseDeviceResponse(const QVariantMap ¶ms) { qDebug() << "Browsing response:" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson(QJsonDocument::Indented)); @@ -474,7 +489,6 @@ void DeviceManager::browseDeviceResponse(const QVariantMap ¶ms) QList itemsToRemove = itemModel->list(); - foreach (const QVariant &itemVariant, params.value("params").toMap().value("items").toList()) { QVariantMap itemMap = itemVariant.toMap(); QString itemId = itemMap.value("id").toString(); @@ -507,6 +521,34 @@ void DeviceManager::browseDeviceResponse(const QVariantMap ¶ms) itemModel->setBusy(false); } +void DeviceManager::browserItemResponse(const QVariantMap ¶ms) +{ + qDebug() << "Browser item details response:" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson(QJsonDocument::Indented)); + int id = params.value("id").toInt(); + if (!m_browserDetailsRequests.contains(id)) { + qWarning() << "Received a browser item details reply for an id we don't know."; + return; + } + + QPointer item = m_browserDetailsRequests.take(id); + if (!item) { + qDebug() << "BrowserItem seems to have disappeared. Discarding browser item details result."; + return; + } + + QVariantMap itemMap = params.value("params").toMap().value("item").toMap(); + item->setDisplayName(itemMap.value("displayName").toString()); + item->setDescription(itemMap.value("description").toString()); + item->setIcon(itemMap.value("icon").toString()); + item->setThumbnail(itemMap.value("thumbnail").toString()); + item->setExecutable(itemMap.value("executable").toBool()); + item->setBrowsable(itemMap.value("browsable").toBool()); + item->setDisabled(itemMap.value("disabled").toBool()); + item->setActionTypeIds(itemMap.value("actionTypeIds").toStringList()); + + item->setMediaIcon(itemMap.value("mediaIcon").toString()); +} + int DeviceManager::executeBrowserItem(const QUuid &deviceId, const QString &itemId) { QVariantMap params; diff --git a/libnymea-app-core/devicemanager.h b/libnymea-app-core/devicemanager.h index d26fec3a..57ae3777 100644 --- a/libnymea-app-core/devicemanager.h +++ b/libnymea-app-core/devicemanager.h @@ -30,6 +30,8 @@ #include "types/plugins.h" #include "jsonrpc/jsonhandler.h" #include "jsonrpc/jsonrpcclient.h" + +class BrowserItem; class BrowserItems; class DeviceManager : public JsonHandler @@ -76,6 +78,7 @@ public: Q_INVOKABLE int executeAction(const QUuid &deviceId, const QUuid &actionTypeId, const QVariantList ¶ms = QVariantList()); Q_INVOKABLE BrowserItems* browseDevice(const QUuid &deviceId, const QString &itemId = QString()); Q_INVOKABLE void refreshBrowserItems(BrowserItems *browserItems); + Q_INVOKABLE BrowserItem* browserItem(const QUuid &deviceId, const QString &itemId); Q_INVOKABLE int executeBrowserItem(const QUuid &deviceId, const QString &itemId); Q_INVOKABLE int executeBrowserItemAction(const QUuid &deviceId, const QString &itemId, const QUuid &actionTypeId, const QVariantList ¶ms = QVariantList()); @@ -95,6 +98,7 @@ private: Q_INVOKABLE void executeActionResponse(const QVariantMap ¶ms); Q_INVOKABLE void reconfigureDeviceResponse(const QVariantMap ¶ms); Q_INVOKABLE void browseDeviceResponse(const QVariantMap ¶ms); + Q_INVOKABLE void browserItemResponse(const QVariantMap ¶ms); Q_INVOKABLE void executeBrowserItemResponse(const QVariantMap ¶ms); Q_INVOKABLE void executeBrowserItemActionResponse(const QVariantMap ¶ms); @@ -128,6 +132,7 @@ private: JsonRpcClient *m_jsonClient = nullptr; QHash > m_browsingRequests; + QHash > m_browserDetailsRequests; }; diff --git a/nymea-app/ui/magic/EditRulePage.qml b/nymea-app/ui/magic/EditRulePage.qml index 1a148987..5d749b3c 100644 --- a/nymea-app/ui/magic/EditRulePage.qml +++ b/nymea-app/ui/magic/EditRulePage.qml @@ -603,6 +603,15 @@ Page { implicitWidth: parent.width ruleAction: root.rule.actions.get(index) onRemoveRuleAction: root.rule.actions.removeRuleAction(index) + onClicked: { + var ruleActionPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionPage.qml"), {text: "Select action", ruleAction: ruleAction, rule: root.rule }); + ruleActionPage.onBackPressed.connect(function() { + pageStack.pop(); + }) + ruleActionPage.onDone.connect(function() { + pageStack.pop(root); + }) + } } } diff --git a/nymea-app/ui/magic/RuleActionDelegate.qml b/nymea-app/ui/magic/RuleActionDelegate.qml index f662942c..82eeb2b6 100644 --- a/nymea-app/ui/magic/RuleActionDelegate.qml +++ b/nymea-app/ui/magic/RuleActionDelegate.qml @@ -12,19 +12,22 @@ NymeaListItemDelegate { property RuleAction ruleAction: null - 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(ruleAction.actionTypeId) + readonly property Device device: ruleAction.deviceId ? engine.deviceManager.devices.getDevice(ruleAction.deviceId) : null + readonly property Interface iface: ruleAction.interfaceName ? Interfaces.findByName(ruleAction.interfaceName) : null + readonly property DeviceClass deviceClass: device ? engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null + readonly property ActionType actionType: deviceClass ? deviceClass.actionTypes.getActionType(ruleAction.actionTypeId) : iface ? iface.actionTypes.findByName(ruleAction.interfaceAction) : null - property var browserItemId: ruleAction.browserItemId + readonly property string browserItemId: ruleAction.browserItemId + readonly property BrowserItem browserItem: device && browserItemId.length > 0 ? engine.deviceManager.browserItem(device.id, browserItemId) : null signal removeRuleAction() onDeleteClicked: root.removeRuleAction() iconName: root.device ? (root.browserItemId ? "../images/browser/BrowserIconFolder.svg" : "../images/action.svg") : "../images/action-interface.svg" - text: qsTr("%1 - %2").arg(root.device ? root.device.name : root.iface.displayName).arg(root.actionType ? root.actionType.displayName : qsTr("Launch an item")) + text: qsTr("%1 - %2") + .arg(root.device ? root.device.name : root.iface.displayName) + .arg(root.actionType ? root.actionType.displayName : (root.browserItem.displayName.length > 0 ? root.browserItem.displayName : qsTr("Unknown item"))) subText: { var ret = []; for (var i = 0; i < root.ruleAction.ruleActionParams.count; i++) { diff --git a/nymea-app/ui/magic/SelectRuleActionPage.qml b/nymea-app/ui/magic/SelectRuleActionPage.qml index ec61f756..3d29eadd 100644 --- a/nymea-app/ui/magic/SelectRuleActionPage.qml +++ b/nymea-app/ui/magic/SelectRuleActionPage.qml @@ -100,6 +100,8 @@ Page { if (header.interfacesMode) { if (root.device) { root.ruleAction.actionTypeId = model.actionTypeId; + root.ruleAction.browserItemId = ""; + root.ruleAction.interfaceAction = ""; var actionType = root.deviceClass.actionTypes.getActionType(model.actionTypeId) if (actionType.paramTypes.count > 0) { var paramsPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionParamsPage.qml"), {ruleAction: root.ruleAction, rule: root.rule}) @@ -113,6 +115,8 @@ Page { } } else if (root.ruleAction.interfaceName !== "") { root.ruleAction.interfaceAction = model.name; + root.ruleAction.browserItemId = ""; + root.ruleAction.actionTypeId = ""; if (listView.model.get(index).paramTypes.count > 0) { var paramsPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionParamsPage.qml"), {ruleAction: root.ruleAction, rule: root.rule}) paramsPage.onBackPressed.connect(function() {pageStack.pop()}); @@ -132,13 +136,17 @@ Page { var page = pageStack.push(Qt.resolvedUrl("SelectBrowserItemActionPage.qml"), {device: root.device}); page.selected.connect(function(itemId) { root.ruleAction.browserItemId = itemId; + root.ruleAction.actionTypeId = ""; + root.ruleAction.interfaceAction = ""; pageStack.pop(); root.done(); }) } else { - var actionType = root.deviceClass.actionTypes.getActionType(model.actiontypeId); + var actionType = root.deviceClass.actionTypes.getActionType(model.actionTypeId); console.log("ActionType", actionType.id, "selected. Has", actionType.paramTypes.count, "params"); root.ruleAction.actionTypeId = actionType.id; + root.ruleAction.browserItemId = ""; + root.ruleAction.interfaceAction = ""; if (actionType.paramTypes.count > 0) { var paramsPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionParamsPage.qml"), {ruleAction: root.ruleAction, rule: root.rule}) paramsPage.onBackPressed.connect(function() { pageStack.pop(); });