BrowserItemActions, yay!
This commit is contained in:
parent
968f1fe2fa
commit
aee554a1ee
@ -734,7 +734,19 @@ Device::BrowseResult DeviceManagerImplementation::browseDevice(const DeviceId &d
|
||||
return result;
|
||||
}
|
||||
|
||||
Device::DeviceError DeviceManagerImplementation::executeBrowserItem(const BrowserItemAction &browserItemAction)
|
||||
Device::DeviceError DeviceManagerImplementation::executeBrowserItem(const BrowserAction &browserAction)
|
||||
{
|
||||
Device *device = m_configuredDevices.value(browserAction.deviceId());
|
||||
if (!device) {
|
||||
return Device::DeviceErrorDeviceNotFound;
|
||||
}
|
||||
if (!device->deviceClass().browsable()) {
|
||||
return Device::DeviceErrorUnsupportedFeature;
|
||||
}
|
||||
return device->plugin()->executeBrowserItem(device, browserAction);
|
||||
}
|
||||
|
||||
Device::DeviceError DeviceManagerImplementation::executeBrowserItemAction(const BrowserItemAction &browserItemAction)
|
||||
{
|
||||
Device *device = m_configuredDevices.value(browserItemAction.deviceId());
|
||||
if (!device) {
|
||||
@ -743,7 +755,9 @@ Device::DeviceError DeviceManagerImplementation::executeBrowserItem(const Browse
|
||||
if (!device->deviceClass().browsable()) {
|
||||
return Device::DeviceErrorUnsupportedFeature;
|
||||
}
|
||||
return device->plugin()->executeBrowserItem(device, browserItemAction);
|
||||
// TODO: check browserItemAction.params with deviceClass
|
||||
|
||||
return device->plugin()->executeBrowserItemAction(device, browserItemAction);
|
||||
}
|
||||
|
||||
QString DeviceManagerImplementation::translate(const PluginId &pluginId, const QString &string, const QLocale &locale)
|
||||
@ -879,6 +893,7 @@ void DeviceManagerImplementation::loadPlugins()
|
||||
loader.setFileName(fi.absoluteFilePath());
|
||||
loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
|
||||
|
||||
qCDebug(dcDeviceManager()) << "Loading plugin from:" << fi.absoluteFilePath();
|
||||
if (!loader.load()) {
|
||||
qCWarning(dcDeviceManager) << "Could not load plugin data of" << entry << "\n" << loader.errorString();
|
||||
continue;
|
||||
|
||||
@ -100,7 +100,8 @@ public:
|
||||
Device::DeviceError executeAction(const Action &action) override;
|
||||
|
||||
Device::BrowseResult browseDevice(const DeviceId &deviceId, const QString &itemId = QString()) override;
|
||||
Device::DeviceError executeBrowserItem(const BrowserItemAction &browserItemAction) override;
|
||||
Device::DeviceError executeBrowserItem(const BrowserAction &browserAction) override;
|
||||
Device::DeviceError executeBrowserItemAction(const BrowserItemAction &browserItemAction) override;
|
||||
|
||||
QString translate(const PluginId &pluginId, const QString &string, const QLocale &locale) override;
|
||||
|
||||
|
||||
@ -65,11 +65,21 @@ ActionHandler::ActionHandler(QObject *parent) :
|
||||
params.clear(); returns.clear();
|
||||
setDescription("ExecuteBrowserItem", "Execute the item identified by itemId on the given device.");
|
||||
params.insert("deviceId", JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
||||
params.insert("o:itemId", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
params.insert("itemId", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
setParams("ExecuteBrowserItem", params);
|
||||
returns.insert("deviceError", JsonTypes::deviceErrorRef());
|
||||
setReturns("ExecuteBrowserItem", returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
setDescription("ExecuteBrowserItemAction", "Execute the action for the browser item identified by actionTypeId and the itemId on the given device.");
|
||||
params.insert("deviceId", JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
||||
params.insert("itemId", JsonTypes::basicTypeToString(JsonTypes::String));
|
||||
params.insert("actionTypeId", JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
||||
params.insert("o:params", QVariantList() << JsonTypes::paramRef());
|
||||
setParams("ExecuteBrowserItemAction", params);
|
||||
returns.insert("deviceError", JsonTypes::deviceErrorRef());
|
||||
setReturns("ExecuteBrowserItemAction", returns);
|
||||
|
||||
connect(NymeaCore::instance(), &NymeaCore::actionExecuted, this, &ActionHandler::actionExecuted);
|
||||
connect(NymeaCore::instance(), &NymeaCore::browserItemExecuted, this, &ActionHandler::browserItemExecuted);
|
||||
}
|
||||
@ -132,7 +142,7 @@ JsonReply *ActionHandler::ExecuteBrowserItem(const QVariantMap ¶ms)
|
||||
{
|
||||
DeviceId deviceId = DeviceId(params.value("deviceId").toString());
|
||||
QString itemId = params.value("itemId").toString();
|
||||
BrowserItemAction action(deviceId, itemId);
|
||||
BrowserAction action(deviceId, itemId);
|
||||
Device::DeviceError status = NymeaCore::instance()->executeBrowserItem(action);
|
||||
if (status == Device::DeviceErrorAsync) {
|
||||
JsonReply *reply = createAsyncReply("ExecuteBrowserItem");
|
||||
@ -144,6 +154,25 @@ JsonReply *ActionHandler::ExecuteBrowserItem(const QVariantMap ¶ms)
|
||||
return createReply(statusToReply(status));
|
||||
}
|
||||
|
||||
JsonReply *ActionHandler::ExecuteBrowserItemAction(const QVariantMap ¶ms)
|
||||
{
|
||||
DeviceId deviceId = DeviceId(params.value("deviceId").toString());
|
||||
QString itemId = params.value("itemId").toString();
|
||||
ActionTypeId actionTypeId = ActionTypeId(params.value("actionTypeId").toString());
|
||||
ParamList paramList = JsonTypes::unpackParams(params.value("params").toList());
|
||||
BrowserItemAction browserItemAction(deviceId, itemId, actionTypeId, paramList);
|
||||
Device::DeviceError status = NymeaCore::instance()->executeBrowserItemAction(browserItemAction);
|
||||
if (status == Device::DeviceErrorAsync) {
|
||||
JsonReply *reply = createAsyncReply("ExecuteBrowserItemAction");
|
||||
ActionId id = browserItemAction.id();
|
||||
connect(reply, &JsonReply::finished, [this, id](){ m_asyncActionExecutions.remove(id); });
|
||||
m_asyncActionExecutions.insert(id, reply);
|
||||
return reply;
|
||||
}
|
||||
return createReply(statusToReply(status));
|
||||
|
||||
}
|
||||
|
||||
void ActionHandler::browserItemExecuted(const ActionId &id, Device::DeviceError status)
|
||||
{
|
||||
if (!m_asyncActionExecutions.contains(id)) {
|
||||
@ -155,5 +184,16 @@ void ActionHandler::browserItemExecuted(const ActionId &id, Device::DeviceError
|
||||
reply->finished();
|
||||
}
|
||||
|
||||
void ActionHandler::browserItemActionExecuted(const ActionId &id, Device::DeviceError status)
|
||||
{
|
||||
if (!m_asyncActionExecutions.contains(id)) {
|
||||
return; // Not the action we are waiting for.
|
||||
}
|
||||
|
||||
JsonReply *reply = m_asyncActionExecutions.take(id);
|
||||
reply->setData(statusToReply(status));
|
||||
reply->finished();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -39,10 +39,12 @@ public:
|
||||
Q_INVOKABLE JsonReply *GetActionType(const QVariantMap ¶ms) const;
|
||||
|
||||
Q_INVOKABLE JsonReply *ExecuteBrowserItem(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE JsonReply *ExecuteBrowserItemAction(const QVariantMap ¶ms);
|
||||
|
||||
private slots:
|
||||
void actionExecuted(const ActionId &id, Device::DeviceError status);
|
||||
void browserItemExecuted(const ActionId &id, Device::DeviceError status);
|
||||
void browserItemActionExecuted(const ActionId &id, Device::DeviceError status);
|
||||
|
||||
private:
|
||||
QHash<ActionId, JsonReply *> m_asyncActionExecutions;
|
||||
|
||||
@ -286,6 +286,7 @@ void JsonTypes::init()
|
||||
s_deviceClass.insert("stateTypes", QVariantList() << stateTypeRef());
|
||||
s_deviceClass.insert("eventTypes", QVariantList() << eventTypeRef());
|
||||
s_deviceClass.insert("actionTypes", QVariantList() << actionTypeRef());
|
||||
s_deviceClass.insert("browserItemActionTypes", QVariantList() << actionTypeRef());
|
||||
s_deviceClass.insert("paramTypes", QVariantList() << paramTypeRef());
|
||||
s_deviceClass.insert("settingsTypes", QVariantList() << paramTypeRef());
|
||||
s_deviceClass.insert("discoveryParamTypes", QVariantList() << paramTypeRef());
|
||||
@ -436,6 +437,8 @@ void JsonTypes::init()
|
||||
s_browserItem.insert("thumbnail", basicTypeToString(QVariant::String));
|
||||
s_browserItem.insert("executable", basicTypeToString(QVariant::Bool));
|
||||
s_browserItem.insert("browsable", basicTypeToString(QVariant::Bool));
|
||||
s_browserItem.insert("disabled", basicTypeToString(QVariant::Bool));
|
||||
s_browserItem.insert("actionTypeIds", QVariantList() << basicTypeToString(QVariant::Uuid));
|
||||
s_browserItem.insert("o:mediaIcon", mediaBrowserIconRef());
|
||||
|
||||
s_initialized = true;
|
||||
@ -743,6 +746,12 @@ QVariantMap JsonTypes::packBrowserItem(const BrowserItem &item)
|
||||
ret.insert("thumbnail", item.thumbnail());
|
||||
ret.insert("executable", item.executable());
|
||||
ret.insert("browsable", item.browsable());
|
||||
ret.insert("disabled", item.disabled());
|
||||
QVariantList actionTypeIds;
|
||||
foreach (const ActionTypeId &id, item.actionTypeIds()) {
|
||||
actionTypeIds.append(id.toString());
|
||||
}
|
||||
ret.insert("actionTypeIds", actionTypeIds);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -844,6 +853,10 @@ QVariantMap JsonTypes::packDeviceClass(const DeviceClass &deviceClass, const QLo
|
||||
foreach (const ActionType &actionType, deviceClass.actionTypes())
|
||||
actionTypes.append(packActionType(actionType, deviceClass.pluginId(), locale));
|
||||
|
||||
QVariantList browserItemActionTypes;
|
||||
foreach (const ActionType &actionType, deviceClass.browserItemActionTypes())
|
||||
browserItemActionTypes.append(packActionType(actionType, deviceClass.pluginId(), locale));
|
||||
|
||||
QVariantList paramTypes;
|
||||
foreach (const ParamType ¶mType, deviceClass.paramTypes())
|
||||
paramTypes.append(packParamType(paramType, deviceClass.pluginId(), locale));
|
||||
@ -862,6 +875,7 @@ QVariantMap JsonTypes::packDeviceClass(const DeviceClass &deviceClass, const QLo
|
||||
variant.insert("stateTypes", stateTypes);
|
||||
variant.insert("eventTypes", eventTypes);
|
||||
variant.insert("actionTypes", actionTypes);
|
||||
variant.insert("browserItemActionTypes", browserItemActionTypes);
|
||||
variant.insert("createMethods", packCreateMethods(deviceClass.createMethods()));
|
||||
variant.insert("setupMethod", s_setupMethod.at(deviceClass.setupMethod()));
|
||||
return variant;
|
||||
|
||||
@ -314,10 +314,19 @@ void LogEngine::logAction(const Action &action, Logging::LoggingLevel level, int
|
||||
appendLogEntry(entry);
|
||||
}
|
||||
|
||||
void LogEngine::logBrowserAction(const BrowserItemAction &browserItemAction, Logging::LoggingLevel level, int errorCode)
|
||||
void LogEngine::logBrowserAction(const BrowserAction &browserAction, Logging::LoggingLevel level, int errorCode)
|
||||
{
|
||||
LogEntry entry(level, Logging::LoggingSourceBrowserActions, errorCode);
|
||||
entry.setDeviceId(browserAction.deviceId());
|
||||
entry.setValue(browserAction.itemId());
|
||||
appendLogEntry(entry);
|
||||
}
|
||||
|
||||
void LogEngine::logBrowserItemAction(const BrowserItemAction &browserItemAction, Logging::LoggingLevel level, int errorCode)
|
||||
{
|
||||
LogEntry entry(level, Logging::LoggingSourceBrowserActions, errorCode);
|
||||
entry.setDeviceId(browserItemAction.deviceId());
|
||||
entry.setTypeId(browserItemAction.actionTypeId());
|
||||
entry.setValue(browserItemAction.itemId());
|
||||
appendLogEntry(entry);
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "types/event.h"
|
||||
#include "types/action.h"
|
||||
#include "types/browseritemaction.h"
|
||||
#include "types/browseraction.h"
|
||||
#include "ruleengine/rule.h"
|
||||
|
||||
#include <QObject>
|
||||
@ -50,7 +51,8 @@ public:
|
||||
void logSystemEvent(const QDateTime &dateTime, bool active, Logging::LoggingLevel level = Logging::LoggingLevelInfo);
|
||||
void logEvent(const Event &event);
|
||||
void logAction(const Action &action, Logging::LoggingLevel level = Logging::LoggingLevelInfo, int errorCode = 0);
|
||||
void logBrowserAction(const BrowserItemAction &browserItemAction, Logging::LoggingLevel level = Logging::LoggingLevelInfo, int errorCode = 0);
|
||||
void logBrowserAction(const BrowserAction &browserAction, Logging::LoggingLevel level = Logging::LoggingLevelInfo, int errorCode = 0);
|
||||
void logBrowserItemAction(const BrowserItemAction &browserItemAction, Logging::LoggingLevel level = Logging::LoggingLevelInfo, int errorCode = 0);
|
||||
void logRuleTriggered(const Rule &rule);
|
||||
void logRuleActiveChanged(const Rule &rule);
|
||||
void logRuleEnabledChanged(const Rule &rule, const bool &enabled);
|
||||
|
||||
@ -448,15 +448,28 @@ Device::DeviceError NymeaCore::executeAction(const Action &action)
|
||||
return ret;
|
||||
}
|
||||
|
||||
Device::DeviceError NymeaCore::executeBrowserItem(const BrowserItemAction &browserItemAction)
|
||||
Device::DeviceError NymeaCore::executeBrowserItem(const BrowserAction &browserAction)
|
||||
{
|
||||
Device::DeviceError ret = m_deviceManager->executeBrowserItem(browserItemAction);
|
||||
Device::DeviceError ret = m_deviceManager->executeBrowserItem(browserAction);
|
||||
if (ret == Device::DeviceErrorNoError) {
|
||||
m_logger->logBrowserAction(browserItemAction);
|
||||
m_logger->logBrowserAction(browserAction);
|
||||
} else if (ret == Device::DeviceErrorAsync) {
|
||||
m_pendingBrowserActions.insert(browserAction.id(), browserAction);
|
||||
} else {
|
||||
m_logger->logBrowserAction(browserAction, Logging::LoggingLevelAlert, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Device::DeviceError NymeaCore::executeBrowserItemAction(const BrowserItemAction &browserItemAction)
|
||||
{
|
||||
Device::DeviceError ret = m_deviceManager->executeBrowserItemAction(browserItemAction);
|
||||
if (ret == Device::DeviceErrorNoError) {
|
||||
m_logger->logBrowserItemAction(browserItemAction);
|
||||
} else if (ret == Device::DeviceErrorAsync) {
|
||||
m_pendingBrowserItemActions.insert(browserItemAction.id(), browserItemAction);
|
||||
} else {
|
||||
m_logger->logBrowserAction(browserItemAction, Logging::LoggingLevelAlert, ret);
|
||||
m_logger->logBrowserItemAction(browserItemAction, Logging::LoggingLevelAlert, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -814,8 +827,15 @@ void NymeaCore::actionExecutionFinished(const ActionId &id, Device::DeviceError
|
||||
void NymeaCore::browserItemExecutionFinished(const ActionId &id, Device::DeviceError status)
|
||||
{
|
||||
emit browserItemExecuted(id, status);
|
||||
Action action = m_pendingActions.take(id);
|
||||
m_logger->logAction(action, status == Device::DeviceErrorNoError ? Logging::LoggingLevelInfo : Logging::LoggingLevelAlert, status);
|
||||
BrowserAction action = m_pendingBrowserActions.take(id);
|
||||
m_logger->logBrowserAction(action, status == Device::DeviceErrorNoError ? Logging::LoggingLevelInfo : Logging::LoggingLevelAlert, status);
|
||||
}
|
||||
|
||||
void NymeaCore::browserItemActionExecutionFinished(const ActionId &id, Device::DeviceError status)
|
||||
{
|
||||
emit browserItemActionExecuted(id, status);
|
||||
BrowserItemAction action = m_pendingBrowserItemActions.take(id);
|
||||
m_logger->logBrowserItemAction(action, status == Device::DeviceErrorNoError ? Logging::LoggingLevelInfo : Logging::LoggingLevelAlert, status);
|
||||
}
|
||||
|
||||
void NymeaCore::onDeviceDisappeared(const DeviceId &deviceId)
|
||||
|
||||
@ -72,7 +72,8 @@ public:
|
||||
Device::DeviceError removeConfiguredDevice(const DeviceId &deviceId, const RuleEngine::RemovePolicy &removePolicy);
|
||||
|
||||
Device::DeviceError executeAction(const Action &action);
|
||||
Device::DeviceError executeBrowserItem(const BrowserItemAction &browserItemAction);
|
||||
Device::DeviceError executeBrowserItem(const BrowserAction &browserAction);
|
||||
Device::DeviceError executeBrowserItemAction(const BrowserItemAction &browserItemAction);
|
||||
|
||||
void executeRuleActions(const QList<RuleAction> ruleActions);
|
||||
|
||||
@ -108,6 +109,7 @@ signals:
|
||||
void deviceSettingChanged(const DeviceId deviceId, const ParamTypeId &settingParamTypeId, const QVariant &value);
|
||||
void actionExecuted(const ActionId &id, Device::DeviceError status);
|
||||
void browserItemExecuted(const ActionId &id, Device::DeviceError status);
|
||||
void browserItemActionExecuted(const ActionId &id, Device::DeviceError status);
|
||||
|
||||
void devicesDiscovered(const DeviceClassId &deviceClassId, const QList<DeviceDescriptor> deviceDescriptors);
|
||||
void deviceSetupFinished(Device *device, Device::DeviceError status);
|
||||
@ -141,6 +143,7 @@ private:
|
||||
System *m_system;
|
||||
|
||||
QHash<ActionId, Action> m_pendingActions;
|
||||
QHash<ActionId, BrowserAction> m_pendingBrowserActions;
|
||||
QHash<ActionId, BrowserItemAction> m_pendingBrowserItemActions;
|
||||
QList<RuleId> m_executingRules;
|
||||
|
||||
@ -149,6 +152,7 @@ private slots:
|
||||
void onDateTimeChanged(const QDateTime &dateTime);
|
||||
void actionExecutionFinished(const ActionId &id, Device::DeviceError status);
|
||||
void browserItemExecutionFinished(const ActionId &id, Device::DeviceError status);
|
||||
void browserItemActionExecutionFinished(const ActionId &id, Device::DeviceError status);
|
||||
void onDeviceDisappeared(const DeviceId &deviceId);
|
||||
void deviceManagerLoaded();
|
||||
|
||||
|
||||
@ -71,6 +71,7 @@ public:
|
||||
DeviceErrorDeviceIsChild,
|
||||
DeviceErrorPairingTransactionIdNotFound,
|
||||
DeviceErrorParameterNotWritable,
|
||||
DeviceErrorItemNotFound,
|
||||
DeviceErrorUnsupportedFeature,
|
||||
};
|
||||
Q_ENUM(DeviceError)
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "types/interface.h"
|
||||
#include "types/vendor.h"
|
||||
#include "types/browseritem.h"
|
||||
#include "types/browseraction.h"
|
||||
#include "types/browseritemaction.h"
|
||||
|
||||
class DeviceManager : public QObject
|
||||
@ -74,7 +75,8 @@ public:
|
||||
virtual Device::DeviceError executeAction(const Action &action) = 0;
|
||||
|
||||
virtual Device::BrowseResult browseDevice(const DeviceId &deviceId, const QString &itemId = QString()) = 0;
|
||||
virtual Device::DeviceError executeBrowserItem(const BrowserItemAction &browserItemAction) = 0;
|
||||
virtual Device::DeviceError executeBrowserItem(const BrowserAction &browserAction) = 0;
|
||||
virtual Device::DeviceError executeBrowserItemAction(const BrowserItemAction &browserItemAction) = 0;
|
||||
|
||||
virtual QString translate(const PluginId &pluginId, const QString &string, const QLocale &locale) = 0;
|
||||
|
||||
@ -94,6 +96,7 @@ signals:
|
||||
void actionExecutionFinished(const ActionId &actionId, Device::DeviceError status);
|
||||
void browseRequestFinished(const Device::BrowseResult &result);
|
||||
void browserItemExecutionFinished(const ActionId &actionId, Device::DeviceError status);
|
||||
void browserItemActionExecutionFinished(const ActionId &actionId, Device::DeviceError status);
|
||||
|
||||
protected:
|
||||
Device::BrowseResult createBrowseResult();
|
||||
|
||||
@ -248,16 +248,43 @@ Device::DeviceError DevicePlugin::executeAction(Device *device, const Action &ac
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
Device::BrowseResult DevicePlugin::browseDevice(Device *device, Device::BrowseResult result, const QString &nodeId)
|
||||
/*! Implement this if your devices support browsing. When the system calls this method,
|
||||
* fill the \a result object's items list with entries from the browser. If \a itemId is empty
|
||||
* it means that the root node of the file system should be returned. Each item in the result set
|
||||
* shall be uniquely identifiable using its \l{BrowserItem::id}{id} property.
|
||||
* The system might call this method again, with an \a itemId returned in a previous query, provided
|
||||
* that item's \l{BrowserItem::browsable} property is true. In this case all children of the given
|
||||
* item shall be returned.
|
||||
* When done, set the \l{BrowserResult::status}{result's status} field approprietly. Set the result's
|
||||
* status to Device::DeviceErrorAsync if this operation requires async behavior and emit
|
||||
* \l{browseRequestFinished} when done.
|
||||
*/
|
||||
Device::BrowseResult DevicePlugin::browseDevice(Device *device, Device::BrowseResult result, const QString &itemId)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
Q_UNUSED(nodeId)
|
||||
Q_UNUSED(itemId)
|
||||
|
||||
result.status = Device::DeviceErrorUnsupportedFeature;
|
||||
return result;
|
||||
}
|
||||
|
||||
Device::DeviceError DevicePlugin::executeBrowserItem(Device *device, const BrowserItemAction &browserItemAction)
|
||||
/*! Implement this if your devices support browsing and execute the itemId defined in \a browserAction.
|
||||
* Return Device::DeviceErrorAsync if this operation requires async behavior and emit
|
||||
* \l{browserItemExecutionFinished} when done.
|
||||
*/
|
||||
Device::DeviceError DevicePlugin::executeBrowserItem(Device *device, const BrowserAction &browserAction)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
Q_UNUSED(browserAction)
|
||||
return Device::DeviceErrorUnsupportedFeature;
|
||||
}
|
||||
|
||||
/*! Implement this if your devices support browsing and execute the item's action for the itemId defined
|
||||
* in \a browserItemAction.
|
||||
* Return Device::DeviceErrorAsync if this operation requires async behavior and emit
|
||||
* \l{browserItemActionExecutionFinished} when done.
|
||||
*/
|
||||
Device::DeviceError DevicePlugin::executeBrowserItemAction(Device *device, const BrowserItemAction &browserItemAction)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
Q_UNUSED(browserItemAction)
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
#include "types/vendor.h"
|
||||
#include "types/param.h"
|
||||
#include "types/interface.h"
|
||||
#include "types/browseraction.h"
|
||||
#include "types/browseritemaction.h"
|
||||
|
||||
#include "hardwaremanager.h"
|
||||
@ -80,7 +81,8 @@ public:
|
||||
virtual Device::DeviceError executeAction(Device *device, const Action &action);
|
||||
|
||||
virtual Device::BrowseResult browseDevice(Device *device, Device::BrowseResult result, const QString &nodeId = QString());
|
||||
virtual Device::DeviceError executeBrowserItem(Device *device, const BrowserItemAction &browserItemAction);
|
||||
virtual Device::DeviceError executeBrowserItem(Device *device, const BrowserAction &browserAction);
|
||||
virtual Device::DeviceError executeBrowserItemAction(Device *device, const BrowserItemAction &browserItemAction);
|
||||
|
||||
// Configuration
|
||||
ParamTypes configurationDescription() const;
|
||||
@ -102,6 +104,7 @@ signals:
|
||||
void autoDeviceDisappeared(const DeviceId &deviceId);
|
||||
void browseRequestFinished(const Device::BrowseResult &result);
|
||||
void browserItemExecutionFinished(const ActionId &actionid, Device::DeviceError status);
|
||||
void browserItemActionExecutionFinished(const ActionId &actionid, Device::DeviceError status);
|
||||
|
||||
protected:
|
||||
Devices myDevices() const;
|
||||
|
||||
@ -163,7 +163,7 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
||||
/*! Returns a list of all valid JSON properties a DeviceClass JSON definition can have. */
|
||||
QStringList deviceClassProperties = QStringList() << "id" << "name" << "displayName" << "createMethods" << "setupMethod"
|
||||
<< "interfaces" << "browsable" << "pairingInfo" << "discoveryParamTypes" << "discoveryParamTypes"
|
||||
<< "paramTypes" << "settingsTypes" << "stateTypes" << "actionTypes" << "eventTypes";
|
||||
<< "paramTypes" << "settingsTypes" << "stateTypes" << "actionTypes" << "eventTypes" << "browserItemActionTypes";
|
||||
QStringList mandatoryDeviceClassProperties = QStringList() << "id" << "name" << "displayName";
|
||||
|
||||
QPair<QStringList, QStringList> verificationResult = verifyFields(deviceClassProperties, mandatoryDeviceClassProperties, deviceClassObject);
|
||||
@ -261,9 +261,10 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
||||
// Read pairing info
|
||||
deviceClass.setPairingInfo(deviceClassObject.value("pairingInfo").toString());
|
||||
|
||||
QList<ActionType> actionTypes;
|
||||
QList<StateType> stateTypes;
|
||||
QList<EventType> eventTypes;
|
||||
ActionTypes actionTypes;
|
||||
StateTypes stateTypes;
|
||||
EventTypes eventTypes;
|
||||
ActionTypes browserItemActionTypes;
|
||||
|
||||
// Read StateTypes
|
||||
int index = 0;
|
||||
@ -458,6 +459,48 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
||||
}
|
||||
deviceClass.setEventTypes(eventTypes);
|
||||
|
||||
// BrowserItemActionTypes
|
||||
index = 0;
|
||||
foreach (const QJsonValue &browserItemActionTypesJson, deviceClassObject.value("browserItemActionTypes").toArray()) {
|
||||
QJsonObject at = browserItemActionTypesJson.toObject();
|
||||
QPair<QStringList, QStringList> verificationResult = verifyFields(ActionType::typeProperties(), ActionType::mandatoryTypeProperties(), at);
|
||||
|
||||
// Check mandatory fields
|
||||
if (!verificationResult.first.isEmpty()) {
|
||||
qCWarning(dcPluginMetadata()) << "Device class" << deviceClass.name() << " has missing fields" << verificationResult.first.join(", ") << "in browser item action type:" << endl << at;
|
||||
hasError = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if there are any unknown fields
|
||||
if (!verificationResult.second.isEmpty()) {
|
||||
qCWarning(dcPluginMetadata()) << pluginName() << "Device class" << deviceClass.name() << "has unknown fields:" << verificationResult.second.join(", ") << "in browser item action type:" << endl << at;
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
ActionTypeId actionTypeId = ActionTypeId(at.value("id").toString());
|
||||
QString actionTypeName = at.value("name").toString();
|
||||
if (!verifyDuplicateUuid(actionTypeId)) {
|
||||
qCWarning(dcPluginMetadata()) << "Browser Action Type" << actionTypeName << "has duplicate UUID:" << actionTypeId.toString();
|
||||
hasError = true;
|
||||
}
|
||||
ActionType actionType(actionTypeId);
|
||||
actionType.setName(actionTypeName);
|
||||
actionType.setDisplayName(at.value("displayName").toString());
|
||||
actionType.setIndex(index++);
|
||||
|
||||
QPair<bool, QList<ParamType> > paramVerification = parseParamTypes(at.value("paramTypes").toArray());
|
||||
if (!paramVerification.first) {
|
||||
hasError = true;
|
||||
break;
|
||||
} else {
|
||||
actionType.setParamTypes(paramVerification.second);
|
||||
}
|
||||
|
||||
browserItemActionTypes.append(actionType);
|
||||
}
|
||||
deviceClass.setBrowserItemActionTypes(browserItemActionTypes);
|
||||
|
||||
// Read interfaces
|
||||
QStringList interfaces;
|
||||
foreach (const QJsonValue &value, deviceClassObject.value("interfaces").toArray()) {
|
||||
@ -617,6 +660,7 @@ QPair<QStringList, QStringList> PluginMetadata::verifyFields(const QStringList &
|
||||
|
||||
QPair<bool, ParamTypes> PluginMetadata::parseParamTypes(const QJsonArray &array)
|
||||
{
|
||||
bool hasErrors = false;
|
||||
int index = 0;
|
||||
QList<ParamType> paramTypes;
|
||||
foreach (const QJsonValue ¶mTypesJson, array) {
|
||||
@ -627,13 +671,14 @@ QPair<bool, ParamTypes> PluginMetadata::parseParamTypes(const QJsonArray &array)
|
||||
// Check mandatory fields
|
||||
if (!verificationResult.first.isEmpty()) {
|
||||
qCWarning(dcPluginMetadata()) << pluginName() << "Error parsing ParamType: missing fields:" << verificationResult.first.join(", ") << endl << pt;
|
||||
return QPair<bool, QList<ParamType> >(false, QList<ParamType>());
|
||||
hasErrors = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if there are any unknown fields
|
||||
if (!verificationResult.second.isEmpty()) {
|
||||
qCWarning(dcPluginMetadata()) << pluginName() << "Error parsing ParamType: unknown fields:" << verificationResult.second.join(", ") << endl << pt;
|
||||
return QPair<bool, QList<ParamType> >(false, QList<ParamType>());
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
// Check type
|
||||
@ -642,14 +687,14 @@ QPair<bool, ParamTypes> PluginMetadata::parseParamTypes(const QJsonArray &array)
|
||||
qCWarning(dcPluginMetadata()) << pluginName() << QString("Invalid type %1 for param %2 in json file.")
|
||||
.arg(pt.value("type").toString())
|
||||
.arg(pt.value("name").toString()).toLatin1().data();
|
||||
return QPair<bool, QList<ParamType> >(false, QList<ParamType>());
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
ParamTypeId paramTypeId = ParamTypeId(pt.value("id").toString());
|
||||
QString paramName = pt.value("name").toString();
|
||||
if (!verifyDuplicateUuid(paramTypeId)) {
|
||||
qCWarning(dcPluginMetadata()) << "Param" << paramName << "has duplicate UUID:" << paramTypeId.toString();
|
||||
return QPair<bool, QList<ParamType> >(false, QList<ParamType>());
|
||||
hasErrors = true;
|
||||
}
|
||||
ParamType paramType(paramTypeId, paramName, t, pt.value("defaultValue").toVariant());
|
||||
paramType.setDisplayName(pt.value("displayName").toString());
|
||||
@ -666,7 +711,7 @@ QPair<bool, ParamTypes> PluginMetadata::parseParamTypes(const QJsonArray &array)
|
||||
QPair<bool, Types::InputType> inputTypeVerification = loadAndVerifyInputType(pt.value("inputType").toString());
|
||||
if (!inputTypeVerification.first) {
|
||||
qCWarning(dcPluginMetadata()) << pluginName() << QString("Invalid inputType for paramType") << pt;
|
||||
return QPair<bool, QList<ParamType> >(false, QList<ParamType>());
|
||||
hasErrors = true;
|
||||
} else {
|
||||
paramType.setInputType(inputTypeVerification.second);
|
||||
}
|
||||
@ -677,7 +722,7 @@ QPair<bool, ParamTypes> PluginMetadata::parseParamTypes(const QJsonArray &array)
|
||||
QPair<bool, Types::Unit> unitVerification = loadAndVerifyUnit(pt.value("unit").toString());
|
||||
if (!unitVerification.first) {
|
||||
qCWarning(dcPluginMetadata()) << pluginName() << QString("Invalid unit type for paramType") << pt;
|
||||
return QPair<bool, QList<ParamType> >(false, QList<ParamType>());
|
||||
hasErrors = true;
|
||||
} else {
|
||||
paramType.setUnit(unitVerification.second);
|
||||
}
|
||||
@ -693,7 +738,7 @@ QPair<bool, ParamTypes> PluginMetadata::parseParamTypes(const QJsonArray &array)
|
||||
paramTypes.append(paramType);
|
||||
}
|
||||
|
||||
return QPair<bool, QList<ParamType> >(true, paramTypes);
|
||||
return QPair<bool, QList<ParamType> >(!hasErrors, paramTypes);
|
||||
}
|
||||
|
||||
QPair<bool, Types::InputType> PluginMetadata::loadAndVerifyInputType(const QString &inputType)
|
||||
|
||||
@ -16,7 +16,8 @@ HEADERS += \
|
||||
platform/package.h \
|
||||
platform/repository.h \
|
||||
types/browseritem.h \
|
||||
types/browseritemaction.h \
|
||||
types/browseritemaction.h \
|
||||
types/browseraction.h \
|
||||
types/mediabrowseritem.h \
|
||||
typeutils.h \
|
||||
loggingcategories.h \
|
||||
@ -114,7 +115,8 @@ SOURCES += \
|
||||
coap/corelink.cpp \
|
||||
coap/coapobserveresource.cpp \
|
||||
types/browseritem.cpp \
|
||||
types/browseritemaction.cpp \
|
||||
types/browseritemaction.cpp \
|
||||
types/browseraction.cpp \
|
||||
types/mediabrowseritem.cpp \
|
||||
types/deviceclass.cpp \
|
||||
types/action.cpp \
|
||||
|
||||
@ -142,3 +142,9 @@ ActionType ActionTypes::findById(const ActionTypeId &id)
|
||||
}
|
||||
return ActionType(ActionTypeId());
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const ActionType &actionType)
|
||||
{
|
||||
dbg.nospace().noquote() << "ActionType: " << actionType.name() << actionType.displayName() << actionType.id();
|
||||
return dbg;
|
||||
}
|
||||
|
||||
@ -60,6 +60,8 @@ private:
|
||||
ParamTypes m_paramTypes;
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug dbg, const ActionType &actionType);
|
||||
|
||||
class ActionTypes: public QList<ActionType>
|
||||
{
|
||||
public:
|
||||
|
||||
66
libnymea/types/browseraction.cpp
Normal file
66
libnymea/types/browseraction.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2019 Michael Zanetti <michael.zanetti@nymea.io> *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Lesser General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2.1 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "browseraction.h"
|
||||
|
||||
BrowserAction::BrowserAction(const DeviceId &deviceId, const QString &itemId):
|
||||
m_id(ActionId::createActionId()),
|
||||
m_deviceId(deviceId),
|
||||
m_itemId(itemId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BrowserAction::BrowserAction(const BrowserAction &other):
|
||||
m_id(other.id()),
|
||||
m_deviceId(other.deviceId()),
|
||||
m_itemId(other.itemId())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ActionId BrowserAction::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
bool BrowserAction::isValid() const
|
||||
{
|
||||
return !m_id.isNull() && !m_deviceId.isNull() && !m_itemId.isNull();
|
||||
}
|
||||
|
||||
DeviceId BrowserAction::deviceId() const
|
||||
{
|
||||
return m_deviceId;
|
||||
}
|
||||
|
||||
QString BrowserAction::itemId() const
|
||||
{
|
||||
return m_itemId;
|
||||
}
|
||||
|
||||
void BrowserAction::operator=(const BrowserAction &other)
|
||||
{
|
||||
m_id = other.id();
|
||||
m_deviceId = other.deviceId();
|
||||
m_itemId = other.itemId();
|
||||
}
|
||||
48
libnymea/types/browseraction.h
Normal file
48
libnymea/types/browseraction.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2019 Michael Zanetti <michael.zanetti@nymea.io> *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Lesser General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2.1 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef BROWSERACTION_H
|
||||
#define BROWSERACTION_H
|
||||
|
||||
#include "typeutils.h"
|
||||
|
||||
class BrowserAction
|
||||
{
|
||||
public:
|
||||
explicit BrowserAction(const DeviceId &deviceId = DeviceId(), const QString &itemId = QString());
|
||||
BrowserAction(const BrowserAction &other);
|
||||
|
||||
ActionId id() const;
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
DeviceId deviceId() const;
|
||||
QString itemId() const;
|
||||
|
||||
void operator=(const BrowserAction &other);
|
||||
private:
|
||||
ActionId m_id;
|
||||
DeviceId m_deviceId;
|
||||
QString m_itemId;
|
||||
};
|
||||
|
||||
#endif // BROWSERACTION_H
|
||||
@ -77,6 +77,16 @@ void BrowserItem::setBrowsable(bool browsable)
|
||||
m_browsable = browsable;
|
||||
}
|
||||
|
||||
bool BrowserItem::disabled() const
|
||||
{
|
||||
return m_disabled;
|
||||
}
|
||||
|
||||
void BrowserItem::setDisabled(bool disabled)
|
||||
{
|
||||
m_disabled = disabled;
|
||||
}
|
||||
|
||||
BrowserItem::BrowserIcon BrowserItem::icon() const
|
||||
{
|
||||
return m_icon;
|
||||
|
||||
@ -73,6 +73,9 @@ public:
|
||||
bool browsable() const;
|
||||
void setBrowsable(bool browsable);
|
||||
|
||||
bool disabled() const;
|
||||
void setDisabled(bool disabled);
|
||||
|
||||
BrowserIcon icon() const;
|
||||
void setIcon(BrowserIcon icon);
|
||||
|
||||
@ -91,6 +94,7 @@ private:
|
||||
QString m_description;
|
||||
bool m_browsable = false;
|
||||
bool m_executable = false;
|
||||
bool m_disabled = false;
|
||||
BrowserIcon m_icon = BrowserIconNone;
|
||||
QString m_thumbnail;
|
||||
|
||||
|
||||
@ -22,10 +22,13 @@
|
||||
|
||||
#include "browseritemaction.h"
|
||||
|
||||
BrowserItemAction::BrowserItemAction(const DeviceId &deviceId, const QString &itemId):
|
||||
|
||||
BrowserItemAction::BrowserItemAction(const DeviceId &deviceId, const QString &itemId, const ActionTypeId &actionTypeId, const ParamList ¶ms):
|
||||
m_id(ActionId::createActionId()),
|
||||
m_deviceId(deviceId),
|
||||
m_itemId(itemId)
|
||||
m_itemId(itemId),
|
||||
m_actionTypeId(actionTypeId),
|
||||
m_params(params)
|
||||
{
|
||||
|
||||
}
|
||||
@ -33,7 +36,9 @@ BrowserItemAction::BrowserItemAction(const DeviceId &deviceId, const QString &it
|
||||
BrowserItemAction::BrowserItemAction(const BrowserItemAction &other):
|
||||
m_id(other.id()),
|
||||
m_deviceId(other.deviceId()),
|
||||
m_itemId(other.itemId())
|
||||
m_itemId(other.itemId()),
|
||||
m_actionTypeId(other.actionTypeId()),
|
||||
m_params(other.params())
|
||||
{
|
||||
|
||||
}
|
||||
@ -58,9 +63,21 @@ QString BrowserItemAction::itemId() const
|
||||
return m_itemId;
|
||||
}
|
||||
|
||||
ActionTypeId BrowserItemAction::actionTypeId() const
|
||||
{
|
||||
return m_actionTypeId;
|
||||
}
|
||||
|
||||
ParamList BrowserItemAction::params() const
|
||||
{
|
||||
return m_params;
|
||||
}
|
||||
|
||||
void BrowserItemAction::operator=(const BrowserItemAction &other)
|
||||
{
|
||||
m_id = other.id();
|
||||
m_deviceId = other.deviceId();
|
||||
m_itemId = other.itemId();
|
||||
m_actionTypeId = other.actionTypeId();
|
||||
m_params = other.params();
|
||||
}
|
||||
|
||||
@ -24,13 +24,12 @@
|
||||
#define BROWSERITEMACTION_H
|
||||
|
||||
#include "typeutils.h"
|
||||
#include "types/param.h"
|
||||
|
||||
class BrowserItemAction
|
||||
{
|
||||
public:
|
||||
BrowserItemAction();
|
||||
|
||||
explicit BrowserItemAction(const DeviceId &deviceId = DeviceId(), const QString &itemId = QString());
|
||||
explicit BrowserItemAction(const DeviceId &deviceId = DeviceId(), const QString &itemId = QString(), const ActionTypeId &actionTypeId = ActionTypeId(), const ParamList ¶ms = ParamList());
|
||||
BrowserItemAction(const BrowserItemAction &other);
|
||||
|
||||
ActionId id() const;
|
||||
@ -39,12 +38,19 @@ public:
|
||||
|
||||
DeviceId deviceId() const;
|
||||
QString itemId() const;
|
||||
ActionTypeId actionTypeId() const;
|
||||
|
||||
ParamList params() const;
|
||||
void setParams(const ParamList ¶ms);
|
||||
Param param(const ParamTypeId ¶mTypeId) const;
|
||||
|
||||
void operator=(const BrowserItemAction &other);
|
||||
private:
|
||||
ActionId m_id;
|
||||
DeviceId m_deviceId;
|
||||
QString m_itemId;
|
||||
ActionTypeId m_actionTypeId;
|
||||
ParamList m_params;
|
||||
};
|
||||
|
||||
#endif // BROWSERITEMACTION_H
|
||||
|
||||
@ -213,24 +213,24 @@ bool DeviceClass::hasActionType(const ActionTypeId &actionTypeId)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! Returns the browserActionTypes of this DeviceClass. \{Device}{Devices} created
|
||||
/*! Returns the browserItemActionTypes of this DeviceClass. \{Device}{Devices} created
|
||||
from this \l{DeviceClass} may set those actions to their browser items. */
|
||||
ActionTypes DeviceClass::browserActionTypes() const
|
||||
ActionTypes DeviceClass::browserItemActionTypes() const
|
||||
{
|
||||
return m_browserActionTypes;
|
||||
return m_browserItemActionTypes;
|
||||
}
|
||||
|
||||
/*! Set the \a browserActionTypes of this DeviceClass. \{Device}{Devices} created
|
||||
from this \l{DeviceClass} may set those actions to their browser items. */
|
||||
void DeviceClass::setBrowserActionTypes(const ActionTypes &browserActionTypes)
|
||||
void DeviceClass::setBrowserItemActionTypes(const ActionTypes &browserItemActionTypes)
|
||||
{
|
||||
m_browserActionTypes = browserActionTypes;
|
||||
m_browserItemActionTypes = browserItemActionTypes;
|
||||
}
|
||||
|
||||
/*! Returns true if this DeviceClass has a \l{ActionType} with the given \a actionTypeId. */
|
||||
bool DeviceClass::hasBrowserActionType(const ActionTypeId &actionTypeId)
|
||||
bool DeviceClass::hasBrowserItemActionType(const ActionTypeId &actionTypeId)
|
||||
{
|
||||
foreach (const ActionType &actionType, m_actionTypes) {
|
||||
foreach (const ActionType &actionType, m_browserItemActionTypes) {
|
||||
if (actionType.id() == actionTypeId) {
|
||||
return true;
|
||||
}
|
||||
@ -333,11 +333,13 @@ void DeviceClass::setInterfaces(const QStringList &interfaces)
|
||||
m_interfaces = interfaces;
|
||||
}
|
||||
|
||||
/*! Returns whether \l{Device}{Devices} created from this \l{DeviceClass} are browsable */
|
||||
bool DeviceClass::browsable() const
|
||||
{
|
||||
return m_browsable;
|
||||
}
|
||||
|
||||
/*! Sets whether \l{Device}{Devices} created from this \l{DeviceClass} are browsable */
|
||||
void DeviceClass::setBrowsable(bool browsable)
|
||||
{
|
||||
m_browsable = browsable;
|
||||
|
||||
@ -82,9 +82,12 @@ public:
|
||||
void setActionTypes(const ActionTypes &actionTypes);
|
||||
bool hasActionType(const ActionTypeId &actionTypeId);
|
||||
|
||||
ActionTypes browserActionTypes() const;
|
||||
void setBrowserActionTypes(const ActionTypes &browserActionTypes);
|
||||
bool hasBrowserActionType(const ActionTypeId &actionTypeId);
|
||||
bool browsable() const;
|
||||
void setBrowsable(bool browsable);
|
||||
|
||||
ActionTypes browserItemActionTypes() const;
|
||||
void setBrowserItemActionTypes(const ActionTypes &browserItemActionTypes);
|
||||
bool hasBrowserItemActionType(const ActionTypeId &actionTypeId);
|
||||
|
||||
ParamTypes paramTypes() const;
|
||||
void setParamTypes(const ParamTypes ¶mTypes);
|
||||
@ -107,9 +110,6 @@ public:
|
||||
QStringList interfaces() const;
|
||||
void setInterfaces(const QStringList &interfaces);
|
||||
|
||||
bool browsable() const;
|
||||
void setBrowsable(bool browsable);
|
||||
|
||||
bool operator==(const DeviceClass &device) const;
|
||||
|
||||
private:
|
||||
@ -122,7 +122,7 @@ private:
|
||||
StateTypes m_stateTypes;
|
||||
EventTypes m_eventTypes;
|
||||
ActionTypes m_actionTypes;
|
||||
ActionTypes m_browserActionTypes;
|
||||
ActionTypes m_browserItemActionTypes;
|
||||
ParamTypes m_paramTypes;
|
||||
ParamTypes m_settingsTypes;
|
||||
ParamTypes m_discoveryParamTypes;
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
|
||||
DevicePluginMock::DevicePluginMock()
|
||||
{
|
||||
|
||||
generateBrowseItems();
|
||||
}
|
||||
|
||||
DevicePluginMock::~DevicePluginMock()
|
||||
@ -239,17 +239,21 @@ Device::DeviceError DevicePluginMock::displayPin(const PairingTransactionId &pai
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
Device::BrowseResult DevicePluginMock::browseDevice(Device *device, Device::BrowseResult result, const QString &nodeId)
|
||||
Device::BrowseResult DevicePluginMock::browseDevice(Device *device, Device::BrowseResult result, const QString &itemId)
|
||||
{
|
||||
qCDebug(dcMockDevice()) << "Browse device called" << device;
|
||||
if (device->deviceClassId() == mockDeviceClassId) {
|
||||
if (device->paramValue(mockDeviceAsyncParamTypeId).toBool()) {
|
||||
result.status = Device::DeviceErrorAsync;
|
||||
QTimer::singleShot(1000, device, [this, device, result, nodeId]() mutable {
|
||||
QTimer::singleShot(1000, device, [this, device, result, itemId]() mutable {
|
||||
if (device->paramValue(mockDeviceBrokenParamTypeId).toBool()) {
|
||||
result.status = Device::DeviceErrorHardwareFailure;
|
||||
} else {
|
||||
result = generateBrowseItems(nodeId, result);
|
||||
VirtualFsNode *node = m_virtualFs->findNode(itemId);
|
||||
foreach (VirtualFsNode *child, node->childs) {
|
||||
result.items.append(child->item);
|
||||
}
|
||||
result.status = Device::DeviceErrorNoError;
|
||||
}
|
||||
emit browseRequestFinished(result);
|
||||
});
|
||||
@ -257,7 +261,11 @@ Device::BrowseResult DevicePluginMock::browseDevice(Device *device, Device::Brow
|
||||
else if (device->paramValue(mockDeviceBrokenParamTypeId).toBool()) {
|
||||
result.status = Device::DeviceErrorHardwareFailure;
|
||||
} else {
|
||||
result = generateBrowseItems(nodeId, result);
|
||||
VirtualFsNode *node = m_virtualFs->findNode(itemId);
|
||||
foreach (VirtualFsNode *child, node->childs) {
|
||||
result.items.append(child->item);
|
||||
}
|
||||
result.status = Device::DeviceErrorNoError;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -393,8 +401,9 @@ Device::DeviceError DevicePluginMock::executeAction(Device *device, const Action
|
||||
return Device::DeviceErrorDeviceClassNotFound;
|
||||
}
|
||||
|
||||
Device::DeviceError DevicePluginMock::executeBrowserItem(Device *device, const BrowserItemAction &browserItemAction)
|
||||
Device::DeviceError DevicePluginMock::executeBrowserItem(Device *device, const BrowserAction &browserAction)
|
||||
{
|
||||
qCDebug(dcMockDevice()) << "ExecuteBrowserItem called";
|
||||
bool broken = device->paramValue(mockDeviceBrokenParamTypeId).toBool();
|
||||
bool async = device->paramValue(mockDeviceAsyncParamTypeId).toBool();
|
||||
|
||||
@ -405,12 +414,46 @@ Device::DeviceError DevicePluginMock::executeBrowserItem(Device *device, const B
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
QTimer::singleShot(2000, device, [this, broken, browserItemAction](){
|
||||
emit this->browserItemExecutionFinished(browserItemAction.id(), broken ? Device::DeviceErrorHardwareFailure : Device::DeviceErrorNoError);
|
||||
QTimer::singleShot(2000, device, [this, broken, browserAction](){
|
||||
emit this->browserItemExecutionFinished(browserAction.id(), broken ? Device::DeviceErrorHardwareFailure : Device::DeviceErrorNoError);
|
||||
});
|
||||
return Device::DeviceErrorAsync;
|
||||
}
|
||||
|
||||
Device::DeviceError DevicePluginMock::executeBrowserItemAction(Device *device, const BrowserItemAction &browserItemAction)
|
||||
{
|
||||
qCDebug(dcMockDevice()) << "TODO" << device << browserItemAction.id();
|
||||
if (browserItemAction.actionTypeId() == mockAddToFavoritesBrowserItemActionTypeId) {
|
||||
|
||||
VirtualFsNode *node = m_virtualFs->findNode(browserItemAction.itemId());
|
||||
if (!node) {
|
||||
return Device::DeviceErrorInvalidParameter;
|
||||
}
|
||||
VirtualFsNode *favoritesNode = m_virtualFs->findNode("favorites");
|
||||
if (favoritesNode->findNode(browserItemAction.itemId())) {
|
||||
return Device::DeviceErrorDeviceInUse;
|
||||
}
|
||||
BrowserItem newItem = node->item;
|
||||
newItem.setActionTypeIs({mockRemoveFromFavoritesBrowserItemActionTypeId});
|
||||
VirtualFsNode *newNode = new VirtualFsNode(newItem);
|
||||
favoritesNode->addChild(newNode);
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
if (browserItemAction.actionTypeId() == mockRemoveFromFavoritesBrowserItemActionTypeId) {
|
||||
VirtualFsNode *favoritesNode = m_virtualFs->findNode("favorites");
|
||||
VirtualFsNode *nodeToRemove = favoritesNode->findNode(browserItemAction.itemId());
|
||||
if (!nodeToRemove) {
|
||||
return Device::DeviceErrorItemNotFound;
|
||||
}
|
||||
int idx = favoritesNode->childs.indexOf(nodeToRemove);
|
||||
delete favoritesNode->childs.takeAt(idx);
|
||||
return Device::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
return Device::DeviceErrorActionTypeNotFound;
|
||||
}
|
||||
|
||||
void DevicePluginMock::setState(const StateTypeId &stateTypeId, const QVariant &value)
|
||||
{
|
||||
HttpDaemon *daemon = qobject_cast<HttpDaemon*>(sender());
|
||||
@ -609,58 +652,42 @@ void DevicePluginMock::onPluginConfigChanged()
|
||||
|
||||
}
|
||||
|
||||
Device::BrowseResult DevicePluginMock::generateBrowseItems(const QString &itemId, Device::BrowseResult result)
|
||||
void DevicePluginMock::generateBrowseItems()
|
||||
{
|
||||
result.status = Device::DeviceErrorNoError;
|
||||
m_virtualFs = new VirtualFsNode(BrowserItem());
|
||||
|
||||
if (itemId.isEmpty()) {
|
||||
BrowserItem item = BrowserItem("0", "Item 0", true);
|
||||
item.setDescription("I'm a folder");
|
||||
item.setIcon(BrowserItem::BrowserIconFolder);
|
||||
result.items.append(item);
|
||||
BrowserItem item = BrowserItem(QUuid::createUuid().toString(), "Item 0", true);
|
||||
item.setDescription("I'm a folder");
|
||||
item.setIcon(BrowserItem::BrowserIconFolder);
|
||||
m_virtualFs->addChild(new VirtualFsNode(item));
|
||||
|
||||
item = BrowserItem("1", "Item 1", false, true);
|
||||
item.setDescription("I'm executable");
|
||||
item.setIcon(BrowserItem::BrowserIconApplication);
|
||||
result.items.append(item);
|
||||
item = BrowserItem(QUuid::createUuid().toString(), "Item 1", false, true);
|
||||
item.setDescription("I'm executable");
|
||||
item.setIcon(BrowserItem::BrowserIconApplication);
|
||||
item.setActionTypeIs({mockAddToFavoritesBrowserItemActionTypeId});
|
||||
m_virtualFs->addChild(new VirtualFsNode(item));
|
||||
|
||||
item = BrowserItem("2", "Item 2", false, true);
|
||||
item.setDescription("I'm a file");
|
||||
item.setIcon(BrowserItem::BrowserIconFile);
|
||||
result.items.append(item);
|
||||
item = BrowserItem(QUuid::createUuid().toString(), "Item 2", false, true);
|
||||
item.setDescription("I'm a file");
|
||||
item.setIcon(BrowserItem::BrowserIconFile);
|
||||
item.setActionTypeIs({mockAddToFavoritesBrowserItemActionTypeId});
|
||||
m_virtualFs->addChild(new VirtualFsNode(item));
|
||||
|
||||
item = BrowserItem("3", "Item 3", false, true);
|
||||
item.setDescription("I have a nice thumbnail");
|
||||
item.setIcon(BrowserItem::BrowserIconFile);
|
||||
item.setThumbnail("https://github.com/guh/nymea/raw/master/icons/nymea-logo-256x256.png");
|
||||
result.items.append(item);
|
||||
item = BrowserItem(QUuid::createUuid().toString(), "Item 3", false, true);
|
||||
item.setDescription("I have a nice thumbnail");
|
||||
item.setIcon(BrowserItem::BrowserIconFile);
|
||||
item.setThumbnail("https://github.com/guh/nymea/raw/master/icons/nymea-logo-256x256.png");
|
||||
item.setActionTypeIs({mockAddToFavoritesBrowserItemActionTypeId});
|
||||
m_virtualFs->addChild(new VirtualFsNode(item));
|
||||
|
||||
item = BrowserItem("4", "Item 4", false, false);
|
||||
item.setDescription("I'm disabled");
|
||||
item.setIcon(BrowserItem::BrowserIconFile);
|
||||
result.items.append(item);
|
||||
item = BrowserItem(QUuid::createUuid().toString(), "Item 4", false, false);
|
||||
item.setDescription("I'm disabled");
|
||||
item.setDisabled(true);
|
||||
item.setIcon(BrowserItem::BrowserIconFile);
|
||||
m_virtualFs->addChild(new VirtualFsNode(item));
|
||||
|
||||
}
|
||||
else if (itemId == "0") {
|
||||
result.items.append(BrowserItem("5", "Item 5"));
|
||||
result.items.append(BrowserItem("6", "Item 6"));
|
||||
result.items.append(BrowserItem("7", "Item 7"));
|
||||
result.items.append(BrowserItem("8", "Item 8"));
|
||||
result.items.append(BrowserItem("9", "Item 9"));
|
||||
}
|
||||
else if (itemId == "2") {
|
||||
result.items.append(BrowserItem("10", "Item 10", true));
|
||||
result.items.append(BrowserItem("11", "Item 11"));
|
||||
result.items.append(BrowserItem("12", "Item 12"));
|
||||
result.items.append(BrowserItem("13", "Item 13"));
|
||||
result.items.append(BrowserItem("14", "Item 14"));
|
||||
}
|
||||
else if (itemId == "10") {
|
||||
result.items.append(BrowserItem("15", "Item 15"));
|
||||
result.items.append(BrowserItem("16", "Item 16"));
|
||||
} else {
|
||||
result.status = Device::DeviceErrorInvalidParameter;
|
||||
}
|
||||
|
||||
return result;
|
||||
item = BrowserItem("favorites", "Favorites", true, false);
|
||||
item.setDescription("Yay! I'm the best!");
|
||||
item.setIcon(BrowserItem::BrowserIconFavorites);
|
||||
m_virtualFs->addChild(new VirtualFsNode(item));
|
||||
}
|
||||
|
||||
@ -52,11 +52,12 @@ public:
|
||||
Device::DeviceSetupStatus confirmPairing(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList ¶ms, const QString &secret) override;
|
||||
Device::DeviceError displayPin(const PairingTransactionId &pairingTransactionId, const DeviceDescriptor &deviceDescriptor) override;
|
||||
|
||||
Device::BrowseResult browseDevice(Device *device, Device::BrowseResult result, const QString &nodeId = QString()) override;
|
||||
Device::BrowseResult browseDevice(Device *device, Device::BrowseResult result, const QString &itemId = QString()) override;
|
||||
|
||||
public slots:
|
||||
Device::DeviceError executeAction(Device *device, const Action &action) override;
|
||||
Device::DeviceError executeBrowserItem(Device *device, const BrowserItemAction &browserItemAction) override;
|
||||
Device::DeviceError executeBrowserItem(Device *device, const BrowserAction &browserAction) override;
|
||||
Device::DeviceError executeBrowserItemAction(Device *device, const BrowserItemAction &browserItemAction) override;
|
||||
|
||||
private slots:
|
||||
void setState(const StateTypeId &stateTypeId, const QVariant &value);
|
||||
@ -76,9 +77,25 @@ private slots:
|
||||
void onPluginConfigChanged();
|
||||
|
||||
private:
|
||||
Device::BrowseResult generateBrowseItems(const QString &itemId, Device::BrowseResult result);
|
||||
void generateBrowseItems();
|
||||
|
||||
private:
|
||||
class VirtualFsNode {
|
||||
public:
|
||||
VirtualFsNode(const BrowserItem &item):item(item) {}
|
||||
BrowserItem item;
|
||||
QList<VirtualFsNode*> childs;
|
||||
void addChild(VirtualFsNode* child) {childs.append(child); }
|
||||
VirtualFsNode *findNode(const QString &id) {
|
||||
if (item.id() == id) return this;
|
||||
foreach (VirtualFsNode *child, childs) {
|
||||
VirtualFsNode *node = child->findNode(id);
|
||||
if (node) return node;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
QHash<Device*, HttpDaemon*> m_daemons;
|
||||
QList<Device*> m_asyncSetupDevices;
|
||||
QList<QPair<Action, Device*> > m_asyncActions;
|
||||
@ -87,6 +104,8 @@ private:
|
||||
|
||||
int m_discoveredDeviceCount;
|
||||
bool m_pushbuttonPressed;
|
||||
|
||||
VirtualFsNode* m_virtualFs = nullptr;
|
||||
};
|
||||
|
||||
#endif // DEVICEPLUGINMOCK_H
|
||||
|
||||
@ -195,11 +195,16 @@
|
||||
"displayName": "Mock Action 5 (async, broken)"
|
||||
}
|
||||
],
|
||||
"brwserItemActionTypes": [
|
||||
"browserItemActionTypes": [
|
||||
{
|
||||
"id": "00b8f0a8-99ca-4aa4-833d-59eb8d4d6de3",
|
||||
"name": "addToFolder",
|
||||
"displayName": "Add to Favorites"
|
||||
"name": "addToFavorites",
|
||||
"displayName": "Add to favorites"
|
||||
},
|
||||
{
|
||||
"id": "da6faef8-2816-430e-93bb-57e8f9582d29",
|
||||
"name": "removeFromFavorites",
|
||||
"displayName": "Remove from favorites"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@ -50,6 +50,8 @@ extern ActionTypeId mockWithoutParamsActionTypeId;
|
||||
extern ActionTypeId mockAsyncActionTypeId;
|
||||
extern ActionTypeId mockFailingActionTypeId;
|
||||
extern ActionTypeId mockAsyncFailingActionTypeId;
|
||||
extern ActionTypeId mockAddToFavoritesBrowserItemActionTypeId;
|
||||
extern ActionTypeId mockRemoveFromFavoritesBrowserItemActionTypeId;
|
||||
extern DeviceClassId mockDeviceAutoDeviceClassId;
|
||||
extern ParamTypeId mockDeviceAutoDeviceHttpportParamTypeId;
|
||||
extern ParamTypeId mockDeviceAutoDeviceAsyncParamTypeId;
|
||||
|
||||
@ -54,6 +54,8 @@ ActionTypeId mockWithoutParamsActionTypeId = ActionTypeId("{defd3ed6-1a0d-400b-8
|
||||
ActionTypeId mockAsyncActionTypeId = ActionTypeId("{fbae06d3-7666-483e-a39e-ec50fe89054e}");
|
||||
ActionTypeId mockFailingActionTypeId = ActionTypeId("{df3cf33d-26d5-4577-9132-9823bd33fad0}");
|
||||
ActionTypeId mockAsyncFailingActionTypeId = ActionTypeId("{bfe89a1d-3497-4121-8318-e77c37537219}");
|
||||
ActionTypeId mockAddToFavoritesBrowserItemActionTypeId = ActionTypeId("{00b8f0a8-99ca-4aa4-833d-59eb8d4d6de3}");
|
||||
ActionTypeId mockRemoveFromFavoritesBrowserItemActionTypeId = ActionTypeId("{da6faef8-2816-430e-93bb-57e8f9582d29}");
|
||||
DeviceClassId mockDeviceAutoDeviceClassId = DeviceClassId("{ab4257b3-7548-47ee-9bd4-7dc3004fd197}");
|
||||
ParamTypeId mockDeviceAutoDeviceHttpportParamTypeId = ParamTypeId("{bfeb0613-dab6-408c-aa27-c362c921d0d1}");
|
||||
ParamTypeId mockDeviceAutoDeviceAsyncParamTypeId = ParamTypeId("{a5c4315f-0624-4971-87c1-4bbfbfdbd16e}");
|
||||
@ -247,6 +249,9 @@ ActionTypeId mockInputTypeWritableTimestampUIntActionTypeId = ActionTypeId("{45d
|
||||
ParamTypeId mockInputTypeWritableTimestampUIntActionWritableTimestampUIntParamTypeId = ParamTypeId("{45d0069a-63ac-4265-8170-8152778608ee}");
|
||||
|
||||
const QString translations[] {
|
||||
//: The name of the Browser Item ActionType ({00b8f0a8-99ca-4aa4-833d-59eb8d4d6de3}) of DeviceClass mock
|
||||
QT_TRANSLATE_NOOP("mockDevice", "Add to favorites"),
|
||||
|
||||
//: The name of the ParamType (DeviceClass: mockInputType, EventType: bool, ID: {3bad3a09-5826-4ed7-a832-10e3e2ee2a7d})
|
||||
QT_TRANSLATE_NOOP("mockDevice", "Bool"),
|
||||
|
||||
@ -412,6 +417,9 @@ const QString translations[] {
|
||||
//: The pairing info of deviceClass mockDisplayPin
|
||||
QT_TRANSLATE_NOOP("mockDevice", "Please enter the secret which normaly will be displayed on the device. For the mockdevice the pin is 243681."),
|
||||
|
||||
//: The name of the Browser Item ActionType ({da6faef8-2816-430e-93bb-57e8f9582d29}) of DeviceClass mock
|
||||
QT_TRANSLATE_NOOP("mockDevice", "Remove from favorites"),
|
||||
|
||||
//: The name of the ParamType (DeviceClass: mockInputType, Type: device, ID: {22add8c9-ee4f-43ad-8931-58e999313ac3})
|
||||
QT_TRANSLATE_NOOP("mockDevice", "Search text"),
|
||||
|
||||
|
||||
@ -228,6 +228,7 @@ void PluginInfoCompiler::writeDeviceClass(const DeviceClass &deviceClass)
|
||||
writeStateTypes(deviceClass.stateTypes(), deviceClass.name());
|
||||
writeEventTypes(deviceClass.eventTypes(), deviceClass.name());
|
||||
writeActionTypes(deviceClass.actionTypes(), deviceClass.name());
|
||||
writeBrowserItemActionTypes(deviceClass.browserItemActionTypes(), deviceClass.name());
|
||||
}
|
||||
|
||||
void PluginInfoCompiler::writeStateTypes(const StateTypes &stateTypes, const QString &deviceClassName)
|
||||
@ -276,8 +277,24 @@ void PluginInfoCompiler::writeActionTypes(const ActionTypes &actionTypes, const
|
||||
writeExtern(QString("extern ActionTypeId %1;").arg(variableName));
|
||||
|
||||
writeParams(actionType.paramTypes(), deviceClassName, "Action", actionType.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PluginInfoCompiler::writeBrowserItemActionTypes(const ActionTypes &actionTypes, const QString &deviceClassName)
|
||||
{
|
||||
foreach (const ActionType &actionType, actionTypes) {
|
||||
QString variableName = QString("%1%2BrowserItemActionTypeId").arg(deviceClassName, actionType.name()[0].toUpper() + actionType.name().right(actionType.name().length() - 1));
|
||||
if (m_variableNames.contains(variableName)) {
|
||||
qWarning().nospace() << "Error: Duplicate name " << variableName << " for Browser Item ActionType " << actionType.name() << " in DeviceClass " << deviceClassName << ". Skipping entry.";
|
||||
return;
|
||||
}
|
||||
m_variableNames.append(variableName);
|
||||
write(QString("ActionTypeId %1 = ActionTypeId(\"%2\");").arg(variableName).arg(actionType.id().toString()));
|
||||
m_translationStrings.insert(actionType.displayName(), QString("The name of the Browser Item ActionType (%1) of DeviceClass %2").arg(actionType.id().toString()).arg(deviceClassName));
|
||||
writeExtern(QString("extern ActionTypeId %1;").arg(variableName));
|
||||
|
||||
writeParams(actionType.paramTypes(), deviceClassName, "BrowserItemAction", actionType.name());
|
||||
}
|
||||
}
|
||||
|
||||
void PluginInfoCompiler::write(const QString &line)
|
||||
|
||||
@ -45,6 +45,7 @@ private:
|
||||
void writeStateTypes(const StateTypes &stateTypes, const QString &deviceClassName);
|
||||
void writeEventTypes(const EventTypes &eventTypes, const QString &deviceClassName);
|
||||
void writeActionTypes(const ActionTypes &actionTypes, const QString &deviceClassName);
|
||||
void writeBrowserItemActionTypes(const ActionTypes &actionTypes, const QString &deviceClassName);
|
||||
|
||||
void write(const QString &line = QString());
|
||||
void writeExtern(const QString &line = QString());
|
||||
|
||||
Reference in New Issue
Block a user