Merge remote-tracking branch 'origin/interfaced-based-rules' into landing-silo
This commit is contained in:
commit
aae0d3584a
@ -224,7 +224,7 @@ void DeviceManager::getConfiguredDevicesResponse(const QVariantMap ¶ms)
|
||||
// set initial state values
|
||||
QVariantList stateVariantList = deviceVariant.toMap().value("states").toList();
|
||||
foreach (const QVariant &stateMap, stateVariantList) {
|
||||
QUuid stateTypeId = stateMap.toMap().value("stateTypeId").toUuid();
|
||||
QString stateTypeId = stateMap.toMap().value("stateTypeId").toString();
|
||||
StateType *st = dc->stateTypes()->getStateType(stateTypeId);
|
||||
if (!st) {
|
||||
qWarning() << "Can't find a statetype for this state";
|
||||
|
||||
@ -134,6 +134,21 @@ bool JsonRpcClient::pushButtonAuthAvailable() const
|
||||
return m_pushButtonAuthAvailable;
|
||||
}
|
||||
|
||||
QString JsonRpcClient::serverVersion() const
|
||||
{
|
||||
return m_serverVersion;
|
||||
}
|
||||
|
||||
QString JsonRpcClient::jsonRpcVersion() const
|
||||
{
|
||||
return m_jsonRpcVersion.toString();
|
||||
}
|
||||
|
||||
QString JsonRpcClient::serverUuid() const
|
||||
{
|
||||
return m_serverUuid;
|
||||
}
|
||||
|
||||
int JsonRpcClient::createUser(const QString &username, const QString &password)
|
||||
{
|
||||
QVariantMap params;
|
||||
@ -168,6 +183,10 @@ int JsonRpcClient::requestPushButtonAuth(const QString &deviceName)
|
||||
return reply->commandId();
|
||||
}
|
||||
|
||||
bool JsonRpcClient::ensureServerVersion(const QString &jsonRpcVersion)
|
||||
{
|
||||
return QVersionNumber(m_jsonRpcVersion) >= QVersionNumber::fromString(jsonRpcVersion);
|
||||
}
|
||||
|
||||
void JsonRpcClient::processAuthenticate(const QVariantMap &data)
|
||||
{
|
||||
@ -224,7 +243,7 @@ void JsonRpcClient::sendRequest(const QVariantMap &request)
|
||||
{
|
||||
QVariantMap newRequest = request;
|
||||
newRequest.insert("token", m_token);
|
||||
// qDebug() << "Sending request" << qUtf8Printable(QJsonDocument::fromVariant(newRequest).toJson());
|
||||
qDebug() << "Sending request" << qUtf8Printable(QJsonDocument::fromVariant(newRequest).toJson());
|
||||
m_connection->sendData(QJsonDocument::fromVariant(newRequest).toJson());
|
||||
}
|
||||
|
||||
@ -259,7 +278,7 @@ void JsonRpcClient::dataReceived(const QByteArray &data)
|
||||
// qWarning() << "Could not parse json data from mea" << data << error.errorString();
|
||||
return;
|
||||
}
|
||||
// qDebug() << "received response" << m_receiveBuffer.left(splitIndex);
|
||||
qDebug() << "received response" << m_receiveBuffer.left(splitIndex);
|
||||
m_receiveBuffer = m_receiveBuffer.right(m_receiveBuffer.length() - splitIndex - 1);
|
||||
if (!m_receiveBuffer.isEmpty()) {
|
||||
staticMetaObject.invokeMethod(this, "dataReceived", Qt::QueuedConnection, Q_ARG(QByteArray, QByteArray()));
|
||||
@ -274,24 +293,28 @@ void JsonRpcClient::dataReceived(const QByteArray &data)
|
||||
m_initialSetupRequired = dataMap.value("initialSetupRequired").toBool();
|
||||
m_authenticationRequired = dataMap.value("authenticationRequired").toBool();
|
||||
m_pushButtonAuthAvailable = dataMap.value("pushButtonAuthAvailable").toBool();
|
||||
emit pushButtonAuthAvailableChanged();
|
||||
|
||||
qDebug() << "Handshake received" << "initRequired:" << m_initialSetupRequired << "authRequired:" << m_authenticationRequired << "pushButtonAvailable:" << m_pushButtonAuthAvailable;;
|
||||
m_serverUuid = dataMap.value("uuid").toString();
|
||||
emit pushButtonAuthAvailableChanged();
|
||||
m_serverVersion = dataMap.value("version").toString();
|
||||
|
||||
QString protoVersionString = dataMap.value("protocol version").toString();
|
||||
if (!protoVersionString.contains('.')) {
|
||||
protoVersionString.prepend("0.");
|
||||
}
|
||||
m_jsonRpcVersion = QVersionNumber::fromString(protoVersionString);
|
||||
|
||||
QVersionNumber minimumRequiredVersion = QVersionNumber(1, 0);
|
||||
QVersionNumber protocolVersion = QVersionNumber::fromString(protoVersionString);
|
||||
if (protocolVersion < minimumRequiredVersion) {
|
||||
qWarning() << "Nymea box doesn't support minimum required version. Required:" << minimumRequiredVersion << "Found:" << protocolVersion;
|
||||
if (m_jsonRpcVersion < minimumRequiredVersion) {
|
||||
qWarning() << "Nymea box doesn't support minimum required version. Required:" << minimumRequiredVersion << "Found:" << m_jsonRpcVersion;
|
||||
m_connection->disconnect();
|
||||
emit invalidProtocolVersion(protocolVersion.toString(), minimumRequiredVersion.toString());
|
||||
emit invalidProtocolVersion(m_jsonRpcVersion.toString(), minimumRequiredVersion.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
emit handshakeReceived();
|
||||
|
||||
if (m_initialSetupRequired) {
|
||||
emit initialSetupRequiredChanged();
|
||||
return;
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
#include <QPointer>
|
||||
#include <QVersionNumber>
|
||||
|
||||
#include "nymeaconnection.h"
|
||||
#include "jsonhandler.h"
|
||||
@ -39,6 +40,9 @@ class JsonRpcClient : public JsonHandler
|
||||
Q_PROPERTY(bool initialSetupRequired READ initialSetupRequired NOTIFY initialSetupRequiredChanged)
|
||||
Q_PROPERTY(bool authenticationRequired READ authenticationRequired NOTIFY authenticationRequiredChanged)
|
||||
Q_PROPERTY(bool pushButtonAuthAvailable READ pushButtonAuthAvailable NOTIFY pushButtonAuthAvailableChanged)
|
||||
Q_PROPERTY(QString serverVersion READ serverVersion NOTIFY handshakeReceived)
|
||||
Q_PROPERTY(QString jsonRpcVersion READ jsonRpcVersion NOTIFY handshakeReceived)
|
||||
Q_PROPERTY(QString serverUuid READ serverUuid NOTIFY handshakeReceived)
|
||||
|
||||
public:
|
||||
explicit JsonRpcClient(NymeaConnection *connection, QObject *parent = 0);
|
||||
@ -56,13 +60,19 @@ public:
|
||||
bool authenticationRequired() const;
|
||||
bool pushButtonAuthAvailable() const;
|
||||
|
||||
QString serverVersion() const;
|
||||
QString jsonRpcVersion() const;
|
||||
QString serverUuid() const;
|
||||
|
||||
// ui methods
|
||||
Q_INVOKABLE int createUser(const QString &username, const QString &password);
|
||||
Q_INVOKABLE int authenticate(const QString &username, const QString &password, const QString &deviceName);
|
||||
Q_INVOKABLE int requestPushButtonAuth(const QString &deviceName);
|
||||
|
||||
Q_INVOKABLE bool ensureServerVersion(const QString &jsonRpcVersion);
|
||||
|
||||
signals:
|
||||
void handshakeReceived();
|
||||
void initialSetupRequiredChanged();
|
||||
void authenticationRequiredChanged();
|
||||
void pushButtonAuthAvailableChanged();
|
||||
@ -94,6 +104,8 @@ private:
|
||||
bool m_pushButtonAuthAvailable = false;
|
||||
int m_pendingPushButtonTransaction = -1;
|
||||
QString m_serverUuid;
|
||||
QVersionNumber m_jsonRpcVersion;
|
||||
QString m_serverVersion;
|
||||
QByteArray m_token;
|
||||
QByteArray m_receiveBuffer;
|
||||
|
||||
|
||||
@ -152,7 +152,7 @@ ParamType *JsonTypes::unpackParamType(const QVariantMap ¶mTypeMap, QObject *
|
||||
StateType *JsonTypes::unpackStateType(const QVariantMap &stateTypeMap, QObject *parent)
|
||||
{
|
||||
StateType *stateType = new StateType(parent);
|
||||
stateType->setId(stateTypeMap.value("id").toUuid());
|
||||
stateType->setId(stateTypeMap.value("id").toString());
|
||||
stateType->setName(stateTypeMap.value("name").toString());
|
||||
stateType->setDisplayName(stateTypeMap.value("displayName").toString());
|
||||
stateType->setIndex(stateTypeMap.value("index").toInt());
|
||||
@ -267,18 +267,29 @@ QVariantList JsonTypes::packRuleActions(RuleActions *ruleActions)
|
||||
QVariantList ret;
|
||||
for (int i = 0; i < ruleActions->rowCount(); i++) {
|
||||
QVariantMap ruleAction;
|
||||
ruleAction.insert("actionTypeId", ruleActions->get(i)->actionTypeId());
|
||||
ruleAction.insert("deviceId", ruleActions->get(i)->deviceId());
|
||||
if (ruleActions->get(i)->ruleActionParams()->rowCount() > 0) {
|
||||
RuleAction *ra = ruleActions->get(i);
|
||||
if (!ra->actionTypeId().isNull() && !ra->deviceId().isNull()) {
|
||||
ruleAction.insert("deviceId", ra->deviceId());
|
||||
ruleAction.insert("actionTypeId", ra->actionTypeId());
|
||||
} else {
|
||||
ruleAction.insert("interface", ra->interfaceName());
|
||||
ruleAction.insert("interfaceAction", ra->interfaceAction());
|
||||
}
|
||||
if (ra->ruleActionParams()->rowCount() > 0) {
|
||||
QVariantList ruleActionParams;
|
||||
for (int j = 0; j < ruleActions->get(i)->ruleActionParams()->rowCount(); j++) {
|
||||
for (int j = 0; j < ra->ruleActionParams()->rowCount(); j++) {
|
||||
QVariantMap ruleActionParam;
|
||||
ruleActionParam.insert("paramTypeId", ruleActions->get(i)->ruleActionParams()->get(j)->paramTypeId());
|
||||
if (!ruleActions->get(i)->ruleActionParams()->get(j)->eventTypeId().isEmpty() && !ruleActions->get(i)->ruleActionParams()->get(j)->eventParamTypeId().isEmpty()) {
|
||||
ruleActionParam.insert("eventTypeId", ruleActions->get(i)->ruleActionParams()->get(j)->eventTypeId());
|
||||
ruleActionParam.insert("eventParamTypeId", ruleActions->get(i)->ruleActionParams()->get(j)->eventParamTypeId());
|
||||
RuleActionParam *rap = ruleActions->get(i)->ruleActionParams()->get(j);
|
||||
if (!rap->paramTypeId().isNull()) {
|
||||
ruleActionParam.insert("paramTypeId", rap->paramTypeId());
|
||||
} else {
|
||||
ruleActionParam.insert("value", ruleActions->get(i)->ruleActionParams()->get(j)->value());
|
||||
ruleActionParam.insert("paramName", rap->paramName());
|
||||
}
|
||||
if (!rap->eventTypeId().isEmpty() && !rap->eventParamTypeId().isEmpty()) {
|
||||
ruleActionParam.insert("eventTypeId", rap->eventTypeId());
|
||||
ruleActionParam.insert("eventParamTypeId", rap->eventParamTypeId());
|
||||
} else {
|
||||
ruleActionParam.insert("value", rap->value());
|
||||
}
|
||||
ruleActionParams.append(ruleActionParam);
|
||||
}
|
||||
@ -307,7 +318,11 @@ QVariantList JsonTypes::packEventDescriptors(EventDescriptors *eventDescriptors)
|
||||
QVariantList paramDescriptors;
|
||||
for (int j = 0; j < eventDescriptor->paramDescriptors()->rowCount(); j++) {
|
||||
QVariantMap paramDescriptor;
|
||||
paramDescriptor.insert("paramTypeId", eventDescriptor->paramDescriptors()->get(j)->paramTypeId());
|
||||
if (!eventDescriptor->paramDescriptors()->get(j)->paramTypeId().isEmpty()) {
|
||||
paramDescriptor.insert("paramTypeId", eventDescriptor->paramDescriptors()->get(j)->paramTypeId());
|
||||
} else {
|
||||
paramDescriptor.insert("paramName", eventDescriptor->paramDescriptors()->get(j)->paramName());
|
||||
}
|
||||
paramDescriptor.insert("value", eventDescriptor->paramDescriptors()->get(j)->value());
|
||||
QMetaEnum operatorEnum = QMetaEnum::fromType<ParamDescriptor::ValueOperator>();
|
||||
paramDescriptor.insert("operator", operatorEnum.valueToKey(eventDescriptor->paramDescriptors()->get(j)->operatorType()));
|
||||
@ -334,10 +349,15 @@ QVariantMap JsonTypes::packStateEvaluator(StateEvaluator *stateEvaluator)
|
||||
QMetaEnum stateOperatorEnum = QMetaEnum::fromType<StateEvaluator::StateOperator>();
|
||||
ret.insert("operator", stateOperatorEnum.valueToKey(stateEvaluator->stateOperator()));
|
||||
QVariantMap stateDescriptor;
|
||||
stateDescriptor.insert("deviceId", stateEvaluator->stateDescriptor()->deviceId());
|
||||
if (!stateEvaluator->stateDescriptor()->deviceId().isNull() && !stateEvaluator->stateDescriptor()->stateTypeId().isNull()) {
|
||||
stateDescriptor.insert("deviceId", stateEvaluator->stateDescriptor()->deviceId());
|
||||
stateDescriptor.insert("stateTypeId", stateEvaluator->stateDescriptor()->stateTypeId());
|
||||
} else {
|
||||
stateDescriptor.insert("interface", stateEvaluator->stateDescriptor()->interfaceName());
|
||||
stateDescriptor.insert("interfaceState", stateEvaluator->stateDescriptor()->interfaceState());
|
||||
}
|
||||
QMetaEnum valueOperatorEnum = QMetaEnum::fromType<StateDescriptor::ValueOperator>();
|
||||
stateDescriptor.insert("operator", valueOperatorEnum.valueToKeys(stateEvaluator->stateDescriptor()->valueOperator()));
|
||||
stateDescriptor.insert("stateTypeId", stateEvaluator->stateDescriptor()->stateTypeId());
|
||||
stateDescriptor.insert("value", stateEvaluator->stateDescriptor()->value());
|
||||
ret.insert("stateDescriptor", stateDescriptor);
|
||||
QVariantList childEvaluators;
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
#include "models/logsmodelng.h"
|
||||
#include "models/valuelogsproxymodel.h"
|
||||
#include "models/eventdescriptorparamsfiltermodel.h"
|
||||
#include "models/interfacesproxy.h"
|
||||
#include "basicconfiguration.h"
|
||||
#include "wifisetup/networkmanagercontroler.h"
|
||||
|
||||
@ -119,6 +120,7 @@ void registerQmlTypes() {
|
||||
|
||||
qmlRegisterUncreatableType<Interface>(uri, 1, 0, "Interface", "Uncreatable");
|
||||
qmlRegisterSingletonType<Interfaces>(uri, 1, 0, "Interfaces", interfacesModel_provider);
|
||||
qmlRegisterType<InterfacesProxy>(uri, 1, 0, "InterfacesProxy");
|
||||
|
||||
qmlRegisterUncreatableType<Plugin>(uri, 1, 0, "Plugin", "Can't create this in QML. Get it from the Plugins.");
|
||||
qmlRegisterUncreatableType<Plugins>(uri, 1, 0, "Plugins", "Can't create this in QML. Get it from the DeviceManager.");
|
||||
|
||||
@ -56,7 +56,8 @@ SOURCES += \
|
||||
wifisetup/wirelessaccesspoints.cpp \
|
||||
wifisetup/wirelesssetupmanager.cpp \
|
||||
wifisetup/networkmanagercontroler.cpp \
|
||||
models/logsmodelng.cpp
|
||||
models/logsmodelng.cpp \
|
||||
models/interfacesproxy.cpp
|
||||
|
||||
HEADERS += \
|
||||
engine.h \
|
||||
@ -99,7 +100,8 @@ HEADERS += \
|
||||
wifisetup/wirelesssetupmanager.h \
|
||||
wifisetup/networkmanagercontroler.h \
|
||||
libmea-core.h \
|
||||
models/logsmodelng.h
|
||||
models/logsmodelng.h \
|
||||
models/interfacesproxy.h
|
||||
|
||||
unix {
|
||||
target.path = /usr/lib
|
||||
|
||||
113
libmea-core/models/interfacesproxy.cpp
Normal file
113
libmea-core/models/interfacesproxy.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
#include "interfacesproxy.h"
|
||||
|
||||
#include "types/interface.h"
|
||||
#include "types/interfaces.h"
|
||||
#include "types/device.h"
|
||||
|
||||
#include "devices.h"
|
||||
#include "engine.h"
|
||||
|
||||
InterfacesProxy::InterfacesProxy(QObject *parent): QSortFilterProxyModel(parent)
|
||||
{
|
||||
m_interfaces = new Interfaces(this);
|
||||
setSourceModel(m_interfaces);
|
||||
}
|
||||
|
||||
bool InterfacesProxy::showEvents() const
|
||||
{
|
||||
return m_showEvents;
|
||||
}
|
||||
|
||||
void InterfacesProxy::setShowEvents(bool showEvents)
|
||||
{
|
||||
if (m_showEvents != showEvents) {
|
||||
m_showEvents = showEvents;
|
||||
emit showEventsChanged();
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
bool InterfacesProxy::showActions() const
|
||||
{
|
||||
return m_showActions;
|
||||
}
|
||||
|
||||
void InterfacesProxy::setShowActions(bool showActions)
|
||||
{
|
||||
if (m_showActions != showActions) {
|
||||
m_showActions = showActions;
|
||||
emit showActionsChanged();
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
bool InterfacesProxy::showStates() const
|
||||
{
|
||||
return m_showStates;
|
||||
}
|
||||
|
||||
void InterfacesProxy::setShowStates(bool showStates)
|
||||
{
|
||||
if (m_showStates != showStates) {
|
||||
m_showStates = showStates;
|
||||
emit showStatesChanged();
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
bool InterfacesProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
Q_UNUSED(source_parent)
|
||||
qDebug() << "filterAcceptsRow";
|
||||
QString interfaceName = m_interfaces->get(source_row)->name();
|
||||
if (!m_shownInterfaces.isEmpty()) {
|
||||
if (!m_shownInterfaces.contains(interfaceName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_devicesFilter != nullptr) {
|
||||
// TODO: This could be improved *a lot* by caching interfaces in the devices model...
|
||||
bool found = false;
|
||||
for (int i = 0; i < m_devicesFilter->rowCount(); i++) {
|
||||
Device *d = m_devicesFilter->get(i);
|
||||
DeviceClass *dc = Engine::instance()->deviceManager()->deviceClasses()->getDeviceClass(d->deviceClassId());
|
||||
if (!dc) {
|
||||
qWarning() << "Cannot find DeviceClass for device:" << d->id() << d->name();
|
||||
return false;
|
||||
}
|
||||
if (dc->interfaces().contains(interfaceName)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Interface* iface = m_interfaces->get(source_row);
|
||||
if (m_showEvents) {
|
||||
if (iface->eventTypes()->rowCount() > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_showActions) {
|
||||
if (iface->actionTypes()->rowCount() > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (m_showStates) {
|
||||
if (iface->stateTypes()->rowCount() > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Interface *InterfacesProxy::get(int index) const
|
||||
{
|
||||
return m_interfaces->get(mapToSource(this->index(index, 0)).row());
|
||||
}
|
||||
58
libmea-core/models/interfacesproxy.h
Normal file
58
libmea-core/models/interfacesproxy.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef INTERFACESPROXY_H
|
||||
#define INTERFACESPROXY_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class Devices;
|
||||
class Interface;
|
||||
class Interfaces;
|
||||
|
||||
class InterfacesProxy: public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QStringList shownInterfaces READ shownInterfaces WRITE setShownInterfaces NOTIFY shownInterfacesChanged)
|
||||
Q_PROPERTY(Devices* devicesFilter READ devicesFilter WRITE setDevicesFilter NOTIFY devicesFilterChanged)
|
||||
Q_PROPERTY(bool showEvents READ showEvents WRITE setShowEvents NOTIFY showEventsChanged)
|
||||
Q_PROPERTY(bool showActions READ showActions WRITE setShowActions NOTIFY showActionsChanged)
|
||||
Q_PROPERTY(bool showStates READ showStates WRITE setShowStates NOTIFY showStatesChanged)
|
||||
|
||||
public:
|
||||
InterfacesProxy(QObject *parent = nullptr);
|
||||
|
||||
QStringList shownInterfaces() const { return m_shownInterfaces; }
|
||||
void setShownInterfaces(const QStringList &shownInterfaces) { m_shownInterfaces = shownInterfaces; emit shownInterfacesChanged(); invalidateFilter(); }
|
||||
|
||||
Devices* devicesFilter() const { return m_devicesFilter; }
|
||||
void setDevicesFilter(Devices *devices) { m_devicesFilter = devices; emit devicesFilterChanged(); invalidateFilter(); }
|
||||
|
||||
bool showEvents() const;
|
||||
void setShowEvents(bool showEvents);
|
||||
|
||||
bool showActions() const;
|
||||
void setShowActions(bool showActions);
|
||||
|
||||
bool showStates() const;
|
||||
void setShowStates(bool showStates);
|
||||
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||
|
||||
Q_INVOKABLE Interface* get(int index) const;
|
||||
|
||||
signals:
|
||||
void shownInterfacesChanged();
|
||||
void devicesFilterChanged();
|
||||
void showEventsChanged();
|
||||
void showActionsChanged();
|
||||
void showStatesChanged();
|
||||
|
||||
private:
|
||||
Interfaces *m_interfaces = nullptr;
|
||||
QStringList m_shownInterfaces;
|
||||
Devices* m_devicesFilter = nullptr;
|
||||
bool m_showEvents = false;
|
||||
bool m_showActions = false;
|
||||
bool m_showStates = false;
|
||||
};
|
||||
|
||||
#endif // INTERFACESPROXY_H
|
||||
@ -198,7 +198,10 @@ void RuleManager::parseEventDescriptors(const QVariantList &eventDescriptorList,
|
||||
eventDescriptor->setInterfaceName(eventDescriptorVariant.toMap().value("interface").toString());
|
||||
eventDescriptor->setInterfaceEvent(eventDescriptorVariant.toMap().value("interfaceEvent").toString());
|
||||
foreach (const QVariant ¶mDescriptorVariant, eventDescriptorVariant.toMap().value("paramDescriptors").toList()) {
|
||||
ParamDescriptor *paramDescriptor = new ParamDescriptor(paramDescriptorVariant.toMap().value("paramTypeId").toString(), paramDescriptorVariant.toMap().value("value"));
|
||||
ParamDescriptor *paramDescriptor = new ParamDescriptor();
|
||||
paramDescriptor->setParamTypeId(paramDescriptorVariant.toMap().value("paramTypeId").toString());
|
||||
paramDescriptor->setParamName(paramDescriptorVariant.toMap().value("paramName").toString());
|
||||
paramDescriptor->setValue(paramDescriptorVariant.toMap().value("value"));
|
||||
QMetaEnum operatorEnum = QMetaEnum::fromType<ParamDescriptor::ValueOperator>();
|
||||
paramDescriptor->setOperatorType((ParamDescriptor::ValueOperator)operatorEnum.keyToValue(paramDescriptorVariant.toMap().value("operator").toString().toLocal8Bit()));
|
||||
eventDescriptor->paramDescriptors()->addParamDescriptor(paramDescriptor);
|
||||
@ -216,7 +219,14 @@ StateEvaluator *RuleManager::parseStateEvaluator(const QVariantMap &stateEvaluat
|
||||
QVariantMap sdMap = stateEvaluatorMap.value("stateDescriptor").toMap();
|
||||
QMetaEnum operatorEnum = QMetaEnum::fromType<StateDescriptor::ValueOperator>();
|
||||
StateDescriptor::ValueOperator op = (StateDescriptor::ValueOperator)operatorEnum.keyToValue(sdMap.value("operator").toByteArray());
|
||||
StateDescriptor *sd = new StateDescriptor(sdMap.value("deviceId").toUuid(), op, sdMap.value("stateTypeId").toUuid(), sdMap.value("value"), stateEvaluator);
|
||||
|
||||
StateDescriptor *sd = nullptr;
|
||||
if (sdMap.contains("deviceId") && sdMap.contains("stateTypeId")) {
|
||||
sd = new StateDescriptor(sdMap.value("deviceId").toUuid(), sdMap.value("stateTypeId").toUuid(), op, sdMap.value("value"), stateEvaluator);
|
||||
} else {
|
||||
sd = new StateDescriptor(sdMap.value("interface").toString(), sdMap.value("interfaceState").toString(), op, sdMap.value("value"), stateEvaluator);
|
||||
}
|
||||
qDebug() << "Created StateDescriptor:" << sd->interfaceName() << sd->interfaceState() << sd->deviceId() << sd->stateTypeId();
|
||||
stateEvaluator->setStateDescriptor(sd);
|
||||
|
||||
foreach (const QVariant &childEvaluatorVariant, stateEvaluatorMap.value("childEvaluators").toList()) {
|
||||
@ -230,39 +240,39 @@ StateEvaluator *RuleManager::parseStateEvaluator(const QVariantMap &stateEvaluat
|
||||
void RuleManager::parseRuleActions(const QVariantList &ruleActions, Rule *rule)
|
||||
{
|
||||
foreach (const QVariant &ruleActionVariant, ruleActions) {
|
||||
RuleAction *ruleAction = new RuleAction();
|
||||
ruleAction->setDeviceId(ruleActionVariant.toMap().value("deviceId").toUuid());
|
||||
ruleAction->setActionTypeId(ruleActionVariant.toMap().value("actionTypeId").toUuid());
|
||||
foreach (const QVariant &ruleActionParamVariant, ruleActionVariant.toMap().value("ruleActionParams").toList()) {
|
||||
RuleActionParam *param = new RuleActionParam();
|
||||
param->setParamTypeId(ruleActionParamVariant.toMap().value("paramTypeId").toUuid());
|
||||
param->setValue(ruleActionParamVariant.toMap().value("value"));
|
||||
param->setEventTypeId(ruleActionParamVariant.toMap().value("eventTypeId").toString());
|
||||
param->setEventParamTypeId(ruleActionParamVariant.toMap().value("eventParamTypeId").toString());
|
||||
ruleAction->ruleActionParams()->addRuleActionParam(param);
|
||||
}
|
||||
rule->actions()->addRuleAction(ruleAction);
|
||||
rule->actions()->addRuleAction(parseRuleAction(ruleActionVariant.toMap()));
|
||||
}
|
||||
}
|
||||
|
||||
void RuleManager::parseRuleExitActions(const QVariantList &ruleActions, Rule *rule)
|
||||
{
|
||||
foreach (const QVariant &ruleActionVariant, ruleActions) {
|
||||
RuleAction *ruleAction = new RuleAction();
|
||||
ruleAction->setDeviceId(ruleActionVariant.toMap().value("deviceId").toUuid());
|
||||
ruleAction->setActionTypeId(ruleActionVariant.toMap().value("actionTypeId").toUuid());
|
||||
foreach (const QVariant &ruleActionParamVariant, ruleActionVariant.toMap().value("ruleActionParams").toList()) {
|
||||
RuleActionParam *param = new RuleActionParam();
|
||||
param->setParamTypeId(ruleActionParamVariant.toMap().value("paramTypeId").toUuid());
|
||||
param->setValue(ruleActionParamVariant.toMap().value("value"));
|
||||
param->setEventTypeId(ruleActionParamVariant.toMap().value("eventTypeId").toString());
|
||||
param->setEventParamTypeId(ruleActionParamVariant.toMap().value("eventParamTypeId").toString());
|
||||
ruleAction->ruleActionParams()->addRuleActionParam(param);
|
||||
}
|
||||
rule->exitActions()->addRuleAction(ruleAction);
|
||||
rule->exitActions()->addRuleAction(parseRuleAction(ruleActionVariant.toMap()));
|
||||
}
|
||||
}
|
||||
|
||||
RuleAction *RuleManager::parseRuleAction(const QVariantMap &ruleAction)
|
||||
{
|
||||
RuleAction *ret = new RuleAction();
|
||||
if (ruleAction.contains("deviceId") && ruleAction.contains("actionTypeId")) {
|
||||
ret->setDeviceId(ruleAction.value("deviceId").toUuid());
|
||||
ret->setActionTypeId(ruleAction.value("actionTypeId").toUuid());
|
||||
} else {
|
||||
ret->setInterfaceName(ruleAction.value("interface").toString());
|
||||
ret->setInterfaceAction(ruleAction.value("interfaceAction").toString());
|
||||
}
|
||||
foreach (const QVariant &ruleActionParamVariant, ruleAction.value("ruleActionParams").toList()) {
|
||||
RuleActionParam *param = new RuleActionParam();
|
||||
param->setParamTypeId(ruleActionParamVariant.toMap().value("paramTypeId").toString());
|
||||
param->setParamName(ruleActionParamVariant.toMap().value("paramName").toString());
|
||||
param->setValue(ruleActionParamVariant.toMap().value("value"));
|
||||
param->setEventTypeId(ruleActionParamVariant.toMap().value("eventTypeId").toString());
|
||||
param->setEventParamTypeId(ruleActionParamVariant.toMap().value("eventParamTypeId").toString());
|
||||
ret->ruleActionParams()->addRuleActionParam(param);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void RuleManager::parseTimeDescriptor(const QVariantMap &timeDescriptor, Rule *rule)
|
||||
{
|
||||
foreach (const QVariant &timeEventItemVariant, timeDescriptor.value("timeEventItems").toList()) {
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
class JsonRpcClient;
|
||||
class StateEvaluator;
|
||||
class RuleAction;
|
||||
|
||||
class RuleManager : public JsonHandler
|
||||
{
|
||||
@ -45,6 +46,7 @@ private:
|
||||
StateEvaluator* parseStateEvaluator(const QVariantMap &stateEvaluatorMap);
|
||||
void parseRuleActions(const QVariantList &ruleActions, Rule *rule);
|
||||
void parseRuleExitActions(const QVariantList &ruleActions, Rule *rule);
|
||||
RuleAction* parseRuleAction(const QVariantMap &ruleAction);
|
||||
void parseTimeDescriptor(const QVariantMap &timeDescriptor, Rule *rule);
|
||||
|
||||
signals:
|
||||
|
||||
@ -56,9 +56,6 @@ int ActionTypes::rowCount(const QModelIndex &parent) const
|
||||
|
||||
QVariant ActionTypes::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (index.row() < 0 || index.row() >= m_actionTypes.count())
|
||||
return QVariant();
|
||||
|
||||
ActionType *actionType = m_actionTypes.at(index.row());
|
||||
switch (role) {
|
||||
case RoleId:
|
||||
|
||||
@ -5,61 +5,39 @@
|
||||
#include "eventtype.h"
|
||||
#include "actiontypes.h"
|
||||
#include "actiontype.h"
|
||||
#include "statetype.h"
|
||||
#include "statetypes.h"
|
||||
|
||||
#include "device.h"
|
||||
|
||||
#include "paramtypes.h"
|
||||
|
||||
Interfaces::Interfaces(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
|
||||
Interface* iface = nullptr;
|
||||
EventType* et = nullptr;
|
||||
ActionType* at = nullptr;
|
||||
ParamType* pt = nullptr;
|
||||
ParamTypes *pts = nullptr;
|
||||
|
||||
iface = new Interface("battery", "Battery powered devices", this);
|
||||
et = new EventType();
|
||||
pts = new ParamTypes(et);
|
||||
et->setParamTypes(pts);
|
||||
|
||||
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);
|
||||
et->paramTypes()->addParamType(pt);
|
||||
iface->eventTypes()->addEventType(et);
|
||||
|
||||
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");
|
||||
et->paramTypes()->addParamType(pt);
|
||||
iface->eventTypes()->addEventType(et);
|
||||
|
||||
m_list.append(iface);
|
||||
addInterface("battery", tr("Battery powered devices"));
|
||||
addStateType("battery", "batteryCritical", QVariant::Bool, false,
|
||||
tr("Battery level is critical"),
|
||||
tr("Battery level entered critical state"));
|
||||
|
||||
|
||||
iface = new Interface("notification", "Notification services", this);
|
||||
at = new ActionType();
|
||||
pts = new ParamTypes(at);
|
||||
at->setParamTypes(pts);
|
||||
addInterface("notifications", tr("Notification services"));
|
||||
pts = createParamTypes("title", tr("Title"), QVariant::String);
|
||||
addParamType(pts, "body", tr("Message body"), QVariant::String);
|
||||
addActionType("notifications", "notify", tr("Send notification"), 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);
|
||||
addInterface("light", tr("Lights"));
|
||||
addStateType("light", "power", QVariant::Bool, true,
|
||||
tr("Light is turned on"),
|
||||
tr("A light is turned on or off"),
|
||||
tr("Turn lights on or off"));
|
||||
|
||||
addInterface("temperaturesensor", tr("Temperature sensors"));
|
||||
addStateType("temperaturesensor", "temperature", QVariant::Double, false,
|
||||
tr("Temperature"),
|
||||
tr("Temperature has changed"));
|
||||
}
|
||||
|
||||
int Interfaces::rowCount(const QModelIndex &parent) const
|
||||
@ -101,3 +79,85 @@ Interface *Interfaces::findByName(const QString &name) const
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Interfaces::addInterface(const QString &name, const QString &displayName)
|
||||
{
|
||||
Interface *iface = new Interface(name, displayName, this);
|
||||
m_list.append(iface);
|
||||
}
|
||||
|
||||
void Interfaces::addEventType(const QString &interfaceName, const QString &name, const QString &displayName, ParamTypes *paramTypes)
|
||||
{
|
||||
Interface *iface = nullptr;
|
||||
foreach (Interface* i, m_list) {
|
||||
if (i->name() == interfaceName) {
|
||||
iface = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Q_ASSERT_X(iface != nullptr, "Interfaces", "Interface not found");
|
||||
EventType *et = new EventType();
|
||||
et->setName(name);
|
||||
et->setDisplayName(displayName);
|
||||
et->setParamTypes(paramTypes);
|
||||
iface->eventTypes()->addEventType(et);
|
||||
}
|
||||
|
||||
void Interfaces::addActionType(const QString &interfaceName, const QString &name, const QString &displayName, ParamTypes *paramTypes)
|
||||
{
|
||||
Interface *iface = nullptr;
|
||||
foreach (Interface* i, m_list) {
|
||||
if (i->name() == interfaceName) {
|
||||
iface = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Q_ASSERT_X(iface != nullptr, "Interfaces", "Interface not found");
|
||||
ActionType *at = new ActionType();
|
||||
at->setName(name);
|
||||
at->setDisplayName(displayName);
|
||||
at->setParamTypes(paramTypes);
|
||||
iface->actionTypes()->addActionType(at);
|
||||
}
|
||||
|
||||
void Interfaces::addStateType(const QString &interfaceName, const QString &name, QVariant::Type type, bool writable, const QString &displayName, const QString &displayNameEvent, const QString &displayNameAction)
|
||||
{
|
||||
Interface *iface = nullptr;
|
||||
foreach (Interface* i, m_list) {
|
||||
if (i->name() == interfaceName) {
|
||||
iface = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Q_ASSERT_X(iface != nullptr, "Interfaces", "Interface not found");
|
||||
StateType *st = new StateType();
|
||||
st->setName(name);
|
||||
st->setDisplayName(displayName);
|
||||
st->setType(type);
|
||||
iface->stateTypes()->addStateType(st);
|
||||
ParamTypes *pts = createParamTypes(name, displayName, type);
|
||||
addEventType(interfaceName, name, displayNameEvent, pts);
|
||||
if (writable) {
|
||||
addActionType(interfaceName, name, displayNameAction, pts);
|
||||
}
|
||||
}
|
||||
|
||||
ParamTypes *Interfaces::createParamTypes(const QString &name, const QString &displayName, QVariant::Type type, const QVariant &defaultValue, const QVariant &minValue, const QVariant &maxValue)
|
||||
{
|
||||
ParamTypes *pts = new ParamTypes();
|
||||
ParamType *pt = new ParamType(name, type, defaultValue);
|
||||
pt->setDisplayName(displayName);
|
||||
pt->setMinValue(minValue);
|
||||
pt->setMaxValue(maxValue);
|
||||
pts->addParamType(pt);
|
||||
return pts;
|
||||
}
|
||||
|
||||
void Interfaces::addParamType(ParamTypes *paramTypes, const QString &name, const QString &displayName, QVariant::Type type, const QVariant &defaultValue, const QVariant &minValue, const QVariant &maxValue)
|
||||
{
|
||||
ParamType *pt = new ParamType(name, type, defaultValue);
|
||||
pt->setDisplayName(displayName);
|
||||
pt->setMinValue(minValue);
|
||||
pt->setMaxValue(maxValue);
|
||||
paramTypes->addParamType(pt);
|
||||
}
|
||||
|
||||
@ -2,8 +2,13 @@
|
||||
#define INTERFACES_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QVariant>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class Interface;
|
||||
class ParamType;
|
||||
class ParamTypes;
|
||||
class Devices;
|
||||
|
||||
class Interfaces : public QAbstractListModel
|
||||
{
|
||||
@ -26,6 +31,16 @@ public:
|
||||
|
||||
private:
|
||||
QList<Interface*> m_list;
|
||||
|
||||
// helpers to populate the model
|
||||
void addInterface(const QString &name, const QString &displayName);
|
||||
void addEventType(const QString &interfaceName, const QString &name, const QString &displayName, ParamTypes *paramTypes);
|
||||
void addActionType(const QString &interfaceName, const QString &name, const QString &displayName, ParamTypes *paramTypes);
|
||||
void addStateType(const QString &interfaceName, const QString &name, QVariant::Type type, bool writable, const QString &displayName, const QString &displayNameEvent, const QString &displayNameAction = QString());
|
||||
|
||||
ParamTypes* createParamTypes(const QString &name, const QString &displayName, QVariant::Type type, const QVariant &defaultValue = QVariant(), const QVariant &minValue = QVariant(), const QVariant &maxValue = QVariant());
|
||||
void addParamType(ParamTypes* paramTypes, const QString &name, const QString &displayName, QVariant::Type type, const QVariant &defaultValue = QVariant(), const QVariant &minValue = QVariant(), const QVariant &maxValue = QVariant());
|
||||
};
|
||||
|
||||
|
||||
#endif // INTERFACES_H
|
||||
|
||||
@ -29,6 +29,12 @@ Param::Param(const QString ¶mTypeId, const QVariant &value, QObject *parent)
|
||||
{
|
||||
}
|
||||
|
||||
Param::Param(QObject *parent):
|
||||
QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString Param::paramTypeId() const
|
||||
{
|
||||
return m_paramTypeId;
|
||||
|
||||
@ -35,6 +35,7 @@ class Param : public QObject
|
||||
|
||||
public:
|
||||
Param(const QString ¶mTypeId = QString(), const QVariant &value = QVariant(), QObject *parent = 0);
|
||||
Param(QObject *parent);
|
||||
|
||||
QString paramTypeId() const;
|
||||
void setParamTypeId(const QString ¶mTypeId);
|
||||
@ -42,14 +43,13 @@ public:
|
||||
QVariant value() const;
|
||||
void setValue(const QVariant &value);
|
||||
|
||||
private:
|
||||
QString m_paramTypeId;
|
||||
QVariant m_value;
|
||||
|
||||
signals:
|
||||
void paramTypeIdChanged();
|
||||
void valueChanged();
|
||||
|
||||
private:
|
||||
QString m_paramTypeId;
|
||||
QVariant m_value;
|
||||
};
|
||||
|
||||
#endif // PARAM_H
|
||||
|
||||
@ -1,10 +1,23 @@
|
||||
#include "paramdescriptor.h"
|
||||
|
||||
ParamDescriptor::ParamDescriptor(const QString &id, const QVariant &value, QObject *parent) : Param(id, value, parent)
|
||||
ParamDescriptor::ParamDescriptor(QObject *parent) : Param(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString ParamDescriptor::paramName() const
|
||||
{
|
||||
return m_paramName;
|
||||
}
|
||||
|
||||
void ParamDescriptor::setParamName(const QString ¶mName)
|
||||
{
|
||||
if (m_paramName != paramName) {
|
||||
m_paramName = paramName;
|
||||
emit paramNameChanged();
|
||||
}
|
||||
}
|
||||
|
||||
ParamDescriptor::ValueOperator ParamDescriptor::operatorType() const
|
||||
{
|
||||
return m_operator;
|
||||
@ -20,7 +33,10 @@ void ParamDescriptor::setOperatorType(ParamDescriptor::ValueOperator operatorTyp
|
||||
|
||||
ParamDescriptor *ParamDescriptor::clone() const
|
||||
{
|
||||
ParamDescriptor *ret = new ParamDescriptor(this->paramTypeId(), this->value());
|
||||
ParamDescriptor *ret = new ParamDescriptor();
|
||||
ret->setParamTypeId(this->paramTypeId());
|
||||
ret->setParamName(this->paramName());
|
||||
ret->setValue(this->value());
|
||||
ret->setOperatorType(this->operatorType());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
class ParamDescriptor : public Param
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString paramName READ paramName WRITE setParamName NOTIFY paramNameChanged)
|
||||
Q_PROPERTY(ValueOperator operatorType READ operatorType WRITE setOperatorType NOTIFY operatorTypeChanged)
|
||||
public:
|
||||
enum ValueOperator {
|
||||
@ -18,16 +19,22 @@ public:
|
||||
};
|
||||
Q_ENUM(ValueOperator)
|
||||
|
||||
explicit ParamDescriptor(const QString &id = QString(), const QVariant &value = QVariant(), QObject *parent = nullptr);
|
||||
explicit ParamDescriptor(QObject *parent = nullptr);
|
||||
|
||||
QString paramName() const;
|
||||
void setParamName(const QString ¶mName);
|
||||
|
||||
ValueOperator operatorType() const;
|
||||
void setOperatorType(ValueOperator operatorType);
|
||||
|
||||
ParamDescriptor* clone() const;
|
||||
|
||||
signals:
|
||||
void paramNameChanged();
|
||||
void operatorTypeChanged();
|
||||
|
||||
private:
|
||||
QString m_paramName;
|
||||
ValueOperator m_operator;
|
||||
};
|
||||
|
||||
|
||||
@ -72,3 +72,29 @@ void ParamDescriptors::setParamDescriptor(const QString ¶mTypeId, const QVar
|
||||
paramDescriptor->setOperatorType((ParamDescriptor::ValueOperator)operatorType);
|
||||
addParamDescriptor(paramDescriptor);
|
||||
}
|
||||
|
||||
void ParamDescriptors::setParamDescriptorByName(const QString ¶mName, const QVariant &value, ParamDescriptors::ValueOperator operatorType)
|
||||
{
|
||||
foreach (ParamDescriptor* paramDescriptor, m_list) {
|
||||
if (paramDescriptor->paramName() == paramName) {
|
||||
paramDescriptor->setValue(value);
|
||||
paramDescriptor->setOperatorType((ParamDescriptor::ValueOperator)operatorType);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Still here? need to add a new one
|
||||
ParamDescriptor* paramDescriptor = createNewParamDescriptor();
|
||||
paramDescriptor->setParamName(paramName);
|
||||
paramDescriptor->setValue(value);
|
||||
paramDescriptor->setOperatorType((ParamDescriptor::ValueOperator)operatorType);
|
||||
addParamDescriptor(paramDescriptor);
|
||||
}
|
||||
|
||||
void ParamDescriptors::clear()
|
||||
{
|
||||
beginResetModel();
|
||||
qDeleteAll(m_list);
|
||||
m_list.clear();
|
||||
endResetModel();
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
@ -39,6 +39,8 @@ public:
|
||||
void addParamDescriptor(ParamDescriptor* paramDescriptor);
|
||||
|
||||
Q_INVOKABLE void setParamDescriptor(const QString ¶mTypeId, const QVariant &value, ValueOperator operatorType);
|
||||
Q_INVOKABLE void setParamDescriptorByName(const QString ¶mName, const QVariant &value, ValueOperator operatorType);
|
||||
Q_INVOKABLE void clear();
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
|
||||
@ -113,9 +113,9 @@ void Rule::setStateEvaluator(StateEvaluator *stateEvaluator)
|
||||
emit stateEvaluatorChanged();
|
||||
}
|
||||
|
||||
void Rule::createStateEvaluator()
|
||||
StateEvaluator* Rule::createStateEvaluator() const
|
||||
{
|
||||
setStateEvaluator(new StateEvaluator(this));
|
||||
return new StateEvaluator();
|
||||
}
|
||||
|
||||
Rule *Rule::clone() const
|
||||
|
||||
@ -17,7 +17,7 @@ class Rule : public QObject
|
||||
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
|
||||
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
|
||||
Q_PROPERTY(EventDescriptors* eventDescriptors READ eventDescriptors CONSTANT)
|
||||
Q_PROPERTY(StateEvaluator* stateEvaluator READ stateEvaluator NOTIFY stateEvaluatorChanged)
|
||||
Q_PROPERTY(StateEvaluator* stateEvaluator READ stateEvaluator WRITE setStateEvaluator NOTIFY stateEvaluatorChanged)
|
||||
Q_PROPERTY(RuleActions* actions READ actions CONSTANT)
|
||||
Q_PROPERTY(RuleActions* exitActions READ exitActions CONSTANT)
|
||||
Q_PROPERTY(TimeDescriptor* timeDescriptor READ timeDescriptor CONSTANT)
|
||||
@ -42,9 +42,9 @@ public:
|
||||
RuleActions* exitActions() const;
|
||||
TimeDescriptor* timeDescriptor() const;
|
||||
|
||||
void setStateEvaluator(StateEvaluator* stateEvaluator);
|
||||
Q_INVOKABLE StateEvaluator* createStateEvaluator() const;
|
||||
|
||||
Q_INVOKABLE void createStateEvaluator();
|
||||
Q_INVOKABLE void setStateEvaluator(StateEvaluator* stateEvaluator);
|
||||
|
||||
Q_INVOKABLE Rule *clone() const;
|
||||
|
||||
|
||||
@ -34,6 +34,32 @@ void RuleAction::setActionTypeId(const QUuid &actionTypeId)
|
||||
}
|
||||
}
|
||||
|
||||
QString RuleAction::interfaceName() const
|
||||
{
|
||||
return m_interfaceName;
|
||||
}
|
||||
|
||||
void RuleAction::setInterfaceName(const QString &interfaceName)
|
||||
{
|
||||
if (m_interfaceName != interfaceName) {
|
||||
m_interfaceName = interfaceName;
|
||||
emit interfaceNameChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QString RuleAction::interfaceAction() const
|
||||
{
|
||||
return m_interfaceAction;
|
||||
}
|
||||
|
||||
void RuleAction::setInterfaceAction(const QString &interfaceAction)
|
||||
{
|
||||
if (m_interfaceAction != interfaceAction) {
|
||||
m_interfaceAction = interfaceAction;
|
||||
emit interfaceActionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
RuleActionParams *RuleAction::ruleActionParams() const
|
||||
{
|
||||
return m_ruleActionParams;
|
||||
@ -42,8 +68,10 @@ RuleActionParams *RuleAction::ruleActionParams() const
|
||||
RuleAction *RuleAction::clone() const
|
||||
{
|
||||
RuleAction *ret = new RuleAction();
|
||||
ret->setActionTypeId(actionTypeId());
|
||||
ret->setDeviceId(deviceId());
|
||||
ret->setActionTypeId(actionTypeId());
|
||||
ret->setInterfaceName(interfaceName());
|
||||
ret->setInterfaceAction(interfaceAction());
|
||||
for (int i = 0; i < ruleActionParams()->rowCount(); i++) {
|
||||
ret->ruleActionParams()->addRuleActionParam(ruleActionParams()->get(i)->clone());
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@ class RuleAction : public QObject
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUuid deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged)
|
||||
Q_PROPERTY(QUuid actionTypeId READ actionTypeId WRITE setActionTypeId NOTIFY actionTypeIdChanged)
|
||||
Q_PROPERTY(QString interfaceName READ interfaceName WRITE setInterfaceName NOTIFY interfaceNameChanged)
|
||||
Q_PROPERTY(QString interfaceAction READ interfaceAction WRITE setInterfaceAction NOTIFY interfaceActionChanged)
|
||||
Q_PROPERTY(RuleActionParams* ruleActionParams READ ruleActionParams CONSTANT)
|
||||
|
||||
public:
|
||||
@ -22,6 +24,12 @@ public:
|
||||
QUuid actionTypeId() const;
|
||||
void setActionTypeId(const QUuid &actionTypeId);
|
||||
|
||||
QString interfaceName() const;
|
||||
void setInterfaceName(const QString &interfaceName);
|
||||
|
||||
QString interfaceAction() const;
|
||||
void setInterfaceAction(const QString &interfaceAction);
|
||||
|
||||
RuleActionParams* ruleActionParams() const;
|
||||
|
||||
RuleAction *clone() const;
|
||||
@ -29,10 +37,14 @@ public:
|
||||
signals:
|
||||
void deviceIdChanged();
|
||||
void actionTypeIdChanged();
|
||||
void interfaceNameChanged();
|
||||
void interfaceActionChanged();
|
||||
|
||||
private:
|
||||
QUuid m_deviceId;
|
||||
QUuid m_actionTypeId;
|
||||
QString m_interfaceName;
|
||||
QString m_interfaceAction;
|
||||
RuleActionParams *m_ruleActionParams;
|
||||
};
|
||||
|
||||
|
||||
@ -1,33 +1,20 @@
|
||||
#include "ruleactionparam.h"
|
||||
|
||||
RuleActionParam::RuleActionParam(QObject *parent) : QObject(parent)
|
||||
RuleActionParam::RuleActionParam(QObject *parent) : Param(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QUuid RuleActionParam::paramTypeId() const
|
||||
QString RuleActionParam::paramName() const
|
||||
{
|
||||
return m_paramTypeId;
|
||||
return m_paramName;
|
||||
}
|
||||
|
||||
void RuleActionParam::setParamTypeId(const QUuid ¶mTypeId)
|
||||
void RuleActionParam::setParamName(const QString ¶mName)
|
||||
{
|
||||
if (m_paramTypeId != paramTypeId) {
|
||||
m_paramTypeId = paramTypeId;
|
||||
emit paramTypeIdChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant RuleActionParam::value() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void RuleActionParam::setValue(const QVariant &value)
|
||||
{
|
||||
if (m_value != value) {
|
||||
m_value = value;
|
||||
emit valueChanged();
|
||||
if (m_paramName != paramName) {
|
||||
m_paramName = paramName;
|
||||
emit paramNameChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,6 +48,7 @@ RuleActionParam *RuleActionParam::clone() const
|
||||
{
|
||||
RuleActionParam *ret = new RuleActionParam();
|
||||
ret->setParamTypeId(paramTypeId());
|
||||
ret->setParamName(paramName());
|
||||
ret->setValue(value());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -5,21 +5,19 @@
|
||||
#include <QUuid>
|
||||
#include <QVariant>
|
||||
|
||||
class RuleActionParam : public QObject
|
||||
#include "param.h"
|
||||
|
||||
class RuleActionParam : public Param
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUuid paramTypeId READ paramTypeId NOTIFY paramTypeIdChanged)
|
||||
Q_PROPERTY(QVariant value READ value NOTIFY valueChanged)
|
||||
Q_PROPERTY(QString paramName READ paramName WRITE setParamName NOTIFY paramNameChanged)
|
||||
Q_PROPERTY(QString eventTypeId READ eventTypeId WRITE setEventTypeId NOTIFY eventTypeIdChanged)
|
||||
Q_PROPERTY(QString eventParamTypeId READ eventParamTypeId WRITE setEventParamTypeId NOTIFY eventParamTypeIdChanged)
|
||||
public:
|
||||
explicit RuleActionParam(QObject *parent = nullptr);
|
||||
|
||||
QUuid paramTypeId() const;
|
||||
void setParamTypeId(const QUuid ¶mTypeId);
|
||||
|
||||
QVariant value() const;
|
||||
void setValue(const QVariant &value);
|
||||
QString paramName() const;
|
||||
void setParamName(const QString ¶mName);
|
||||
|
||||
QString eventTypeId() const;
|
||||
void setEventTypeId(const QString &eventTypeId);
|
||||
@ -29,15 +27,12 @@ public:
|
||||
|
||||
RuleActionParam* clone() const;
|
||||
signals:
|
||||
void paramTypeIdChanged();
|
||||
void valueChanged();
|
||||
void paramNameChanged();
|
||||
void eventTypeIdChanged();
|
||||
void eventParamTypeIdChanged();
|
||||
|
||||
|
||||
private:
|
||||
QUuid m_paramTypeId;
|
||||
QVariant m_value;
|
||||
QString m_paramName;
|
||||
QString m_eventTypeId;
|
||||
QString m_eventParamTypeId;
|
||||
};
|
||||
|
||||
@ -62,6 +62,22 @@ void RuleActionParams::setRuleActionParam(const QString ¶mTypeId, const QVar
|
||||
addRuleActionParam(rap);
|
||||
}
|
||||
|
||||
void RuleActionParams::setRuleActionParamByName(const QString ¶mName, const QVariant &value)
|
||||
{
|
||||
foreach (RuleActionParam *rap, m_list) {
|
||||
if (rap->paramName() == paramName) {
|
||||
rap->setValue(value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Still here? Need to add it
|
||||
RuleActionParam *rap = new RuleActionParam(this);
|
||||
rap->setParamName(paramName);
|
||||
rap->setValue(value);
|
||||
addRuleActionParam(rap);
|
||||
}
|
||||
|
||||
void RuleActionParams::setRuleActionParamEvent(const QString ¶mTypeId, const QString &eventTypeId, const QString &eventParamTypeId)
|
||||
{
|
||||
foreach (RuleActionParam *rap, m_list) {
|
||||
|
||||
@ -27,6 +27,7 @@ public:
|
||||
void addRuleActionParam(RuleActionParam* ruleActionParam);
|
||||
|
||||
Q_INVOKABLE void setRuleActionParam(const QString ¶mTypeId, const QVariant &value);
|
||||
Q_INVOKABLE void setRuleActionParamByName(const QString ¶mName, const QVariant &value);
|
||||
Q_INVOKABLE void setRuleActionParamEvent(const QString ¶mTypeId, const QString &eventTypeId, const QString &eventParamTypeId);
|
||||
Q_INVOKABLE RuleActionParam* get(int index) const;
|
||||
|
||||
|
||||
@ -1,10 +1,20 @@
|
||||
#include "statedescriptor.h"
|
||||
|
||||
StateDescriptor::StateDescriptor(const QUuid &deviceId, StateDescriptor::ValueOperator valueOperator, const QUuid &stateTypeId, const QVariant &value, QObject *parent):
|
||||
StateDescriptor::StateDescriptor(const QUuid &deviceId, const QUuid &stateTypeId, StateDescriptor::ValueOperator valueOperator, const QVariant &value, QObject *parent):
|
||||
QObject(parent),
|
||||
m_deviceId(deviceId),
|
||||
m_operator(valueOperator),
|
||||
m_stateTypeId(stateTypeId),
|
||||
m_operator(valueOperator),
|
||||
m_value(value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
StateDescriptor::StateDescriptor(const QString &interfaceName, const QString &interfaceState, StateDescriptor::ValueOperator valueOperator, const QVariant &value, QObject *parent):
|
||||
QObject(parent),
|
||||
m_interfaceName(interfaceName),
|
||||
m_interfaceState(interfaceState),
|
||||
m_operator(valueOperator),
|
||||
m_value(value)
|
||||
{
|
||||
|
||||
@ -54,6 +64,32 @@ void StateDescriptor::setStateTypeId(const QUuid &stateTypeId)
|
||||
}
|
||||
}
|
||||
|
||||
QString StateDescriptor::interfaceName() const
|
||||
{
|
||||
return m_interfaceName;
|
||||
}
|
||||
|
||||
void StateDescriptor::setInterfaceName(const QString &interfaceName)
|
||||
{
|
||||
if (m_interfaceName != interfaceName) {
|
||||
m_interfaceName = interfaceName;
|
||||
emit interfaceNameChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QString StateDescriptor::interfaceState() const
|
||||
{
|
||||
return m_interfaceState;
|
||||
}
|
||||
|
||||
void StateDescriptor::setInterfaceState(const QString &interfaceState)
|
||||
{
|
||||
if (m_interfaceState != interfaceState) {
|
||||
m_interfaceState = interfaceState;
|
||||
emit interfaceStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant StateDescriptor::value() const
|
||||
{
|
||||
return m_value;
|
||||
@ -69,6 +105,8 @@ void StateDescriptor::setValue(const QVariant &value)
|
||||
|
||||
StateDescriptor *StateDescriptor::clone() const
|
||||
{
|
||||
StateDescriptor *ret = new StateDescriptor(deviceId(), valueOperator(), stateTypeId(), value());
|
||||
StateDescriptor *ret = new StateDescriptor(deviceId(), stateTypeId(), valueOperator(), value());
|
||||
ret->setInterfaceName(interfaceName());
|
||||
ret->setInterfaceState(interfaceState());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -9,8 +9,10 @@ class StateDescriptor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUuid deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged)
|
||||
Q_PROPERTY(ValueOperator valueOperator READ valueOperator WRITE setValueOperator NOTIFY valueOperatorChanged)
|
||||
Q_PROPERTY(QUuid stateTypeId READ stateTypeId WRITE setStateTypeId NOTIFY stateTypeIdChanged)
|
||||
Q_PROPERTY(QString interfaceName READ interfaceName WRITE setInterfaceName NOTIFY interfaceNameChanged)
|
||||
Q_PROPERTY(QString interfaceState READ interfaceState WRITE setInterfaceState NOTIFY interfaceStateChanged)
|
||||
Q_PROPERTY(ValueOperator valueOperator READ valueOperator WRITE setValueOperator NOTIFY valueOperatorChanged)
|
||||
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
|
||||
|
||||
public:
|
||||
@ -24,18 +26,25 @@ public:
|
||||
};
|
||||
Q_ENUM(ValueOperator)
|
||||
|
||||
explicit StateDescriptor(const QUuid &deviceId, ValueOperator valueOperator, const QUuid &stateTypeId, const QVariant &value, QObject *parent = nullptr);
|
||||
explicit StateDescriptor(const QUuid &deviceId, const QUuid &stateTypeId, ValueOperator valueOperator, const QVariant &value, QObject *parent = nullptr);
|
||||
explicit StateDescriptor(const QString &interfaceName, const QString &interfaceState, ValueOperator valueOperator, const QVariant &value, QObject *parent = nullptr);
|
||||
StateDescriptor(QObject *parent = nullptr);
|
||||
|
||||
QUuid deviceId() const;
|
||||
void setDeviceId(const QUuid &deviceId);
|
||||
|
||||
ValueOperator valueOperator() const;
|
||||
void setValueOperator(ValueOperator valueOperator);
|
||||
|
||||
QUuid stateTypeId() const;
|
||||
void setStateTypeId(const QUuid &stateTypeId);
|
||||
|
||||
QString interfaceName() const;
|
||||
void setInterfaceName(const QString &interfaceName);
|
||||
|
||||
QString interfaceState() const;
|
||||
void setInterfaceState(const QString &interfaceState);
|
||||
|
||||
ValueOperator valueOperator() const;
|
||||
void setValueOperator(ValueOperator valueOperator);
|
||||
|
||||
QVariant value() const;
|
||||
void setValue(const QVariant &value);
|
||||
|
||||
@ -43,14 +52,18 @@ public:
|
||||
|
||||
signals:
|
||||
void deviceIdChanged();
|
||||
void valueOperatorChanged();
|
||||
void stateTypeIdChanged();
|
||||
void interfaceNameChanged();
|
||||
void interfaceStateChanged();
|
||||
void valueOperatorChanged();
|
||||
void valueChanged();
|
||||
|
||||
private:
|
||||
QUuid m_deviceId;
|
||||
ValueOperator m_operator = ValueOperatorEquals;
|
||||
QUuid m_stateTypeId;
|
||||
QString m_interfaceName;
|
||||
QString m_interfaceState;
|
||||
ValueOperator m_operator = ValueOperatorEquals;
|
||||
QVariant m_value;
|
||||
};
|
||||
|
||||
|
||||
@ -66,6 +66,8 @@ StateEvaluator *StateEvaluator::clone() const
|
||||
ret->m_operator = this->m_operator;
|
||||
ret->m_stateDescriptor->setDeviceId(this->m_stateDescriptor->deviceId());
|
||||
ret->m_stateDescriptor->setStateTypeId(this->m_stateDescriptor->stateTypeId());
|
||||
ret->m_stateDescriptor->setInterfaceName(this->m_stateDescriptor->interfaceName());
|
||||
ret->m_stateDescriptor->setInterfaceState(this->m_stateDescriptor->interfaceState());
|
||||
ret->m_stateDescriptor->setValueOperator(this->m_stateDescriptor->valueOperator());
|
||||
ret->m_stateDescriptor->setValue(this->m_stateDescriptor->value());
|
||||
for (int i = 0; i < this->m_childEvaluators->rowCount(); i++) {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include "stateevaluators.h"
|
||||
#include "stateevaluator.h"
|
||||
|
||||
StateEvaluators::StateEvaluators(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
@ -34,13 +35,23 @@ void StateEvaluators::addStateEvaluator(StateEvaluator *stateEvaluator)
|
||||
|
||||
StateEvaluator *StateEvaluators::get(int index) const
|
||||
{
|
||||
if (index < 0 || index >= m_list.count()) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_list.at(index);
|
||||
}
|
||||
|
||||
StateEvaluator *StateEvaluators::take(int index)
|
||||
{
|
||||
beginRemoveRows(QModelIndex(), index, index);
|
||||
return m_list.takeAt(index);
|
||||
endInsertRows();
|
||||
StateEvaluator* ret = m_list.takeAt(index);
|
||||
endRemoveRows();
|
||||
emit countChanged();
|
||||
ret->setParent(nullptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void StateEvaluators::remove(int index)
|
||||
{
|
||||
take(index)->deleteLater();
|
||||
}
|
||||
|
||||
@ -19,7 +19,12 @@ public:
|
||||
|
||||
void addStateEvaluator(StateEvaluator* stateEvaluator);
|
||||
Q_INVOKABLE StateEvaluator* get(int index) const;
|
||||
StateEvaluator* take(int index);
|
||||
|
||||
// Caller takes ownership, is responsible for deleting
|
||||
Q_INVOKABLE StateEvaluator* take(int index);
|
||||
|
||||
// StateEvaluator will be deleted
|
||||
Q_INVOKABLE void remove(int index);
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
|
||||
@ -27,12 +27,12 @@ StateType::StateType(QObject *parent) :
|
||||
{
|
||||
}
|
||||
|
||||
QUuid StateType::id() const
|
||||
QString StateType::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void StateType::setId(const QUuid &id)
|
||||
void StateType::setId(const QString &id)
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
@ -67,6 +67,11 @@ void StateType::setType(const QString &type)
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
void StateType::setType(QVariant::Type type)
|
||||
{
|
||||
m_type = QVariant::typeToName(type);
|
||||
}
|
||||
|
||||
int StateType::index() const
|
||||
{
|
||||
return m_index;
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
class StateType : 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(QString type READ type CONSTANT)
|
||||
@ -44,8 +44,8 @@ class StateType : public QObject
|
||||
public:
|
||||
StateType(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);
|
||||
@ -55,6 +55,7 @@ public:
|
||||
|
||||
QString type() const;
|
||||
void setType(const QString &type);
|
||||
void setType(QVariant::Type type);
|
||||
|
||||
int index() const;
|
||||
void setIndex(const int &index);
|
||||
@ -69,7 +70,7 @@ public:
|
||||
void setUnitString(const QString &unitString);
|
||||
|
||||
private:
|
||||
QUuid m_id;
|
||||
QString m_id;
|
||||
QString m_name;
|
||||
QString m_displayName;
|
||||
QString m_type;
|
||||
|
||||
@ -34,17 +34,13 @@ QList<StateType *> StateTypes::stateTypes()
|
||||
return m_stateTypes;
|
||||
}
|
||||
|
||||
int StateTypes::count() const
|
||||
{
|
||||
return m_stateTypes.count();
|
||||
}
|
||||
|
||||
StateType *StateTypes::get(int index) const
|
||||
{
|
||||
qDebug() << "returning" << m_stateTypes.at(index);
|
||||
return m_stateTypes.at(index);
|
||||
}
|
||||
|
||||
StateType *StateTypes::getStateType(const QUuid &stateTypeId) const
|
||||
StateType *StateTypes::getStateType(const QString &stateTypeId) const
|
||||
{
|
||||
foreach (StateType *stateType, m_stateTypes) {
|
||||
if (stateType->id() == stateTypeId) {
|
||||
@ -68,7 +64,7 @@ QVariant StateTypes::data(const QModelIndex &index, int role) const
|
||||
StateType *stateType = m_stateTypes.at(index.row());
|
||||
switch (role) {
|
||||
case RoleId:
|
||||
return stateType->id().toString();
|
||||
return stateType->id();
|
||||
case RoleName:
|
||||
return stateType->name();
|
||||
case RoleDisplayName:
|
||||
@ -87,10 +83,11 @@ QVariant StateTypes::data(const QModelIndex &index, int role) const
|
||||
|
||||
void StateTypes::addStateType(StateType *stateType)
|
||||
{
|
||||
stateType->setParent(this);
|
||||
beginInsertRows(QModelIndex(), m_stateTypes.count(), m_stateTypes.count());
|
||||
//qDebug() << "StateTypes: loaded stateType" << stateType->name();
|
||||
m_stateTypes.append(stateType);
|
||||
endInsertRows();
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
StateType *StateTypes::findByName(const QString &name) const
|
||||
@ -110,6 +107,7 @@ void StateTypes::clearModel()
|
||||
qDeleteAll(m_stateTypes);
|
||||
m_stateTypes.clear();
|
||||
endResetModel();
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> StateTypes::roleNames() const
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
class StateTypes : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||
|
||||
public:
|
||||
enum Role {
|
||||
@ -47,9 +48,8 @@ public:
|
||||
|
||||
QList<StateType *> stateTypes();
|
||||
|
||||
Q_INVOKABLE int count() const;
|
||||
Q_INVOKABLE StateType *get(int index) const;
|
||||
Q_INVOKABLE StateType *getStateType(const QUuid &stateTypeId) const;
|
||||
Q_INVOKABLE StateType *getStateType(const QString &stateTypeId) const;
|
||||
|
||||
int rowCount(const QModelIndex & parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||
@ -63,6 +63,9 @@ public:
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const;
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
|
||||
private:
|
||||
QList<StateType *> m_stateTypes;
|
||||
|
||||
|
||||
@ -198,5 +198,12 @@
|
||||
<file>ui/images/action.svg</file>
|
||||
<file>ui/images/event.svg</file>
|
||||
<file>ui/images/state.svg</file>
|
||||
<file>ui/images/event-interface.svg</file>
|
||||
<file>ui/components/MeaListItemDelegate.qml</file>
|
||||
<file>ui/images/state-interface.svg</file>
|
||||
<file>ui/images/action-interface.svg</file>
|
||||
<file>ui/system/AboutNymeaPage.qml</file>
|
||||
<file>ui/images/logs.svg</file>
|
||||
<file>ui/images/plugin.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -110,24 +110,11 @@ Page {
|
||||
}
|
||||
}
|
||||
ThinDivider {}
|
||||
ItemDelegate {
|
||||
MeaListItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
|
||||
contentItem: RowLayout {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("About %1").arg(app.appName)
|
||||
}
|
||||
Image {
|
||||
source: "images/next.svg"
|
||||
Layout.preferredHeight: parent.height
|
||||
Layout.preferredWidth: height
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
pageStack.push(Qt.resolvedUrl("AboutPage.qml"))
|
||||
}
|
||||
text: qsTr("About %1").arg(app.appName)
|
||||
iconName: "../images/info.svg"
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("AboutPage.qml"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -61,24 +61,15 @@ Page {
|
||||
anchors.fill: parent
|
||||
|
||||
model: Engine.ruleManager.rules
|
||||
delegate: SwipeDelegate {
|
||||
delegate: MeaListItemDelegate {
|
||||
id: ruleDelegate
|
||||
width: parent.width
|
||||
iconName: "../images/magic.svg"
|
||||
iconColor: !model.enabled ? "red" : (model.active ? app.guhAccent : "grey")
|
||||
text: model.name
|
||||
canDelete: true
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: app.margins
|
||||
ColorIcon {
|
||||
height: app.iconSize
|
||||
width: height
|
||||
name: "../images/magic.svg"
|
||||
color: !model.enabled ? "red" : (model.active ? app.guhAccent : "grey")
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: model.name
|
||||
}
|
||||
}
|
||||
onDeleteClicked: Engine.ruleManager.removeRule(model.id)
|
||||
|
||||
onClicked: {
|
||||
d.editRulePage = pageStack.push(Qt.resolvedUrl("magic/EditRulePage.qml"), {rule: Engine.ruleManager.rules.get(index).clone()})
|
||||
@ -88,25 +79,12 @@ Page {
|
||||
})
|
||||
d.editRulePage.onAccept.connect(function() {
|
||||
d.editRulePage.busy = true;
|
||||
Engine.ruleManager.editRule(editRulePage.rule);
|
||||
Engine.ruleManager.editRule(d.editRulePage.rule);
|
||||
})
|
||||
d.editRulePage.onCancel.connect(function() {
|
||||
pageStack.pop();
|
||||
})
|
||||
}
|
||||
|
||||
swipe.right: MouseArea {
|
||||
height: ruleDelegate.height
|
||||
width: height
|
||||
anchors.right: parent.right
|
||||
ColorIcon {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins
|
||||
name: "../images/delete.svg"
|
||||
color: "red"
|
||||
}
|
||||
onClicked: Engine.ruleManager.removeRule(model.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ ApplicationWindow {
|
||||
|
||||
property int margins: 14
|
||||
property int bigMargins: 20
|
||||
property int smallFont: 14
|
||||
property int smallFont: 13
|
||||
property int mediumFont: 16
|
||||
property int largeFont: 20
|
||||
property int iconSize: 30
|
||||
@ -220,6 +220,8 @@ ApplicationWindow {
|
||||
return Qt.resolvedUrl("images/sort-listitem.svg")
|
||||
case "garagegate":
|
||||
return Qt.resolvedUrl("images/shutter-10.svg")
|
||||
case "battery":
|
||||
return Qt.resolvedUrl("images/battery/battery-050.svg")
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -89,41 +89,25 @@ Page {
|
||||
|
||||
}
|
||||
|
||||
ItemDelegate {
|
||||
MeaListItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
contentItem: RowLayout {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Plugins")
|
||||
}
|
||||
Image {
|
||||
source: "images/next.svg"
|
||||
Layout.preferredHeight: parent.height
|
||||
Layout.preferredWidth: height
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
pageStack.push(Qt.resolvedUrl("system/PluginsPage.qml"))
|
||||
}
|
||||
iconName: "../images/plugin.svg"
|
||||
text: qsTr("Plugins")
|
||||
onClicked:pageStack.push(Qt.resolvedUrl("system/PluginsPage.qml"))
|
||||
}
|
||||
|
||||
ItemDelegate {
|
||||
MeaListItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
contentItem: RowLayout {
|
||||
Label {
|
||||
text: qsTr("Log viewer")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Image {
|
||||
source: "images/next.svg"
|
||||
Layout.preferredHeight: parent.height
|
||||
Layout.preferredWidth: height
|
||||
}
|
||||
}
|
||||
|
||||
iconName: "../images/logs.svg"
|
||||
text: qsTr("Log viewer")
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("system/LogViewerPage.qml"))
|
||||
}
|
||||
|
||||
MeaListItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
iconName: "../images/info.svg"
|
||||
text: qsTr("About nymea")
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("system/AboutNymeaPage.qml"))
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
|
||||
@ -10,7 +10,7 @@ ToolBar {
|
||||
property string text
|
||||
property alias backButtonVisible: backButton.visible
|
||||
property alias menuButtonVisible: menuButton.visible
|
||||
default property alias data: layout.data
|
||||
default property alias children: layout.data
|
||||
|
||||
signal backPressed();
|
||||
signal menuPressed();
|
||||
|
||||
79
mea/ui/components/MeaListItemDelegate.qml
Normal file
79
mea/ui/components/MeaListItemDelegate.qml
Normal file
@ -0,0 +1,79 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
SwipeDelegate {
|
||||
id: root
|
||||
|
||||
property string subText
|
||||
property bool progressive: true
|
||||
property bool canDelete: false
|
||||
|
||||
property string iconName
|
||||
property int iconSize: app.iconSize
|
||||
property color iconColor: app.guhAccent
|
||||
|
||||
signal deleteClicked()
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: app.margins
|
||||
ColorIcon {
|
||||
id: icon
|
||||
Layout.preferredHeight: root.iconSize
|
||||
Layout.preferredWidth: height
|
||||
name: root.iconName
|
||||
color: root.iconColor
|
||||
visible: root.iconName
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: root.text
|
||||
wrapMode: Text.WordWrap
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: root.subText
|
||||
font.pixelSize: app.smallFont
|
||||
wrapMode: Text.WordWrap
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
visible: root.subText.length > 0
|
||||
}
|
||||
}
|
||||
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: app.iconSize
|
||||
Layout.preferredWidth: height
|
||||
name: "../images/next.svg"
|
||||
visible: root.progressive
|
||||
}
|
||||
}
|
||||
|
||||
swipe.enabled: canDelete
|
||||
swipe.right: MouseArea {
|
||||
height: root.height
|
||||
width: height
|
||||
anchors.right: parent.right
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "red"
|
||||
}
|
||||
|
||||
ColorIcon {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins
|
||||
name: "../images/delete.svg"
|
||||
color: "white"
|
||||
}
|
||||
onClicked: {
|
||||
swipe.close();
|
||||
root.deleteClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,30 +3,13 @@ import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.2
|
||||
import "../components"
|
||||
|
||||
ItemDelegate {
|
||||
MeaListItemDelegate {
|
||||
id: root
|
||||
width: parent.width
|
||||
iconName: app.interfacesToIcon(root.interfaces)
|
||||
text: root.name
|
||||
progressive: true
|
||||
|
||||
property var interfaces: []
|
||||
property var name: ""
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: app.margins
|
||||
ColorIcon {
|
||||
height: app.iconSize
|
||||
width: height
|
||||
name: app.interfacesToIcon(root.interfaces)
|
||||
color: app.guhAccent
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: root.name
|
||||
}
|
||||
Image {
|
||||
source: "../images/next.svg"
|
||||
Layout.preferredHeight: parent.height
|
||||
Layout.preferredWidth: height
|
||||
}
|
||||
}
|
||||
property string name: ""
|
||||
}
|
||||
|
||||
@ -78,11 +78,12 @@ Page {
|
||||
|
||||
onAddRuleClicked: {
|
||||
var rule = Engine.ruleManager.createNewRule();
|
||||
rule.createStateEvaluator();
|
||||
rule.stateEvaluator.stateDescriptor.deviceId = device.id;
|
||||
rule.stateEvaluator.stateDescriptor.stateTypeId = root.stateType.id;
|
||||
rule.stateEvaluator.stateDescriptor.value = value;
|
||||
rule.stateEvaluator.stateDescriptor.valueOperator = StateDescriptor.ValueOperatorEquals;
|
||||
var stateEvaluator = rule.createStateEvaluator();
|
||||
stateEvaluator.stateDescriptor.deviceId = device.id;
|
||||
stateEvaluator.stateDescriptor.stateTypeId = root.stateType.id;
|
||||
stateEvaluator.stateDescriptor.value = value;
|
||||
stateEvaluator.stateDescriptor.valueOperator = StateDescriptor.ValueOperatorEquals;
|
||||
rule.setStateEvaluator(stateEvaluator);
|
||||
rule.name = root.device.name + " - " + stateType.displayName + " = " + value;
|
||||
|
||||
var rulePage = pageStack.push(Qt.resolvedUrl("../magic/DeviceRulesPage.qml"), {device: root.device});
|
||||
|
||||
209
mea/ui/images/action-interface.svg
Normal file
209
mea/ui/images/action-interface.svg
Normal file
@ -0,0 +1,209 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="96"
|
||||
height="96"
|
||||
id="svg4874"
|
||||
version="1.1"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
viewBox="0 0 96 96.000001"
|
||||
sodipodi:docname="action-interface.svg">
|
||||
<defs
|
||||
id="defs4876" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="14.049998"
|
||||
inkscape:cx="69.993806"
|
||||
inkscape:cy="44.483695"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
showborder="true"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:snap-midpoints="true"
|
||||
inkscape:snap-object-midpoints="true"
|
||||
inkscape:snap-center="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:window-width="2880"
|
||||
inkscape:window-height="1698"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="44"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid5451"
|
||||
empspacing="8" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="8,-8.0000001"
|
||||
id="guide4063"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="4,-8.0000001"
|
||||
id="guide4065"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,88.000001"
|
||||
id="guide4067"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,92.000001"
|
||||
id="guide4069"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="104,4"
|
||||
id="guide4071"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-5,8.0000001"
|
||||
id="guide4073"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="88,-8.0000001"
|
||||
id="guide4077"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,84.000001"
|
||||
id="guide4074"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="12,-8.0000001"
|
||||
id="guide4076"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="84,-8.0000001"
|
||||
id="guide4080"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="48,-8.0000001"
|
||||
orientation="1,0"
|
||||
id="guide4170"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="-8,48"
|
||||
orientation="0,1"
|
||||
id="guide4172"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="92,-8.0000001"
|
||||
orientation="1,0"
|
||||
id="guide4760"
|
||||
inkscape:locked="false" />
|
||||
</sodipodi:namedview>
|
||||
<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></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(67.857146,-78.50504)">
|
||||
<rect
|
||||
transform="rotate(90)"
|
||||
y="-28.142855"
|
||||
x="78.505043"
|
||||
height="96"
|
||||
width="96"
|
||||
id="rect4782-637"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:3.99999976;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect4747-4"
|
||||
d="m 18.142883,124.50503 1.000025,3.99998 h -32.999999 v -3.99998 z"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;stroke:none;stroke-width:8.99999905;marker:none;enable-background:accumulate"
|
||||
inkscape:transform-center-x="-26.500014" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:none;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999976;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="M 5.6230724,101.05661 C -4.6712646,90.767855 -20.167327,87.685805 -33.61715,93.253885 c -13.44979,5.56807 -22.23047,18.700765 -22.23047,33.251945 0,14.55118 8.78068,27.68194 22.23047,33.25002 13.449823,5.56804 28.9458854,2.48602 39.2402224,-7.80276 l -2.828107,-2.82811 c -9.158173,9.15322 -22.9166364,11.88745 -34.8828054,6.93358 -11.96618,-4.95383 -19.75979,-16.60879 -19.75979,-29.55273 0,-12.94393 7.79361,-24.60083 19.75979,-29.554705 11.966169,-4.95382 25.7246324,-2.2196 34.8828054,6.933635 z"
|
||||
id="path4145"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5837"
|
||||
d="m 9.5430153,119.30443 0.00456,14.4 c 2.1900247,-1.00124 4.4195527,-2.12156 6.6895137,-3.35923 2.248645,-1.24067 4.417693,-2.5203 6.505716,-3.84016 -2.088023,-1.29345 -4.257071,-2.56083 -6.505716,-3.8015 -2.271209,-1.23836 -4.502007,-2.37113 -6.6931875,-3.39911 z"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79964399;marker:none;enable-background:accumulate" />
|
||||
<rect
|
||||
transform="scale(1,-1)"
|
||||
y="-174.50505"
|
||||
x="-67.857147"
|
||||
height="96"
|
||||
width="96.000008"
|
||||
id="rect4782-0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:3.99920893;marker:none;enable-background:accumulate" />
|
||||
<g
|
||||
id="g1546">
|
||||
<path
|
||||
sodipodi:nodetypes="sccccccsccs"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:none;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999976;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m -14.85739,128.50594 c 8.51248,0 14.61615,-1.67112 18.89488,-4.54103 4.27876,-2.86991 6.59021,-6.93883 7.55365,-11.13672 0.481728,-2.09895 0.627128,-6.33371 0.627128,-6.33371 l -4.0339524,0.0815 c 0,0 -0.096796,3.64414 -0.4900656,5.35769 -0.78655,3.42713 -2.47562,6.42067 -5.88438,8.70705 -3.40876,2.28635 -8.67972,3.86521 -16.66726,3.86521 H -47.858 v 4.00003 z"
|
||||
id="path4116"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1542"
|
||||
d="m 1.9230841,111.7131 14.1821019,2.49562 c -0.605737,-2.33062 -1.321885,-4.72081 -2.146577,-7.17122 -0.831349,-2.42991 -1.714887,-4.78821 -2.652114,-7.073694 -1.6363806,1.831694 -3.2611572,3.747714 -4.8734519,5.746744 -1.6139397,2.02168 -3.1168728,4.02187 -4.50973,6.00126 z"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79964399;marker:none;enable-background:accumulate" />
|
||||
</g>
|
||||
<g
|
||||
id="g1552"
|
||||
transform="matrix(1,0,0,-1,8.54e-4,253.01099)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1548"
|
||||
d="m -14.85739,128.50594 c 8.51248,0 14.61615,-1.67112 18.89488,-4.54103 4.27876,-2.86991 6.59021,-6.93883 7.55365,-11.13672 0.481728,-2.09895 0.627128,-6.33371 0.627128,-6.33371 l -4.0339524,0.0815 c 0,0 -0.096796,3.64414 -0.4900656,5.35769 -0.78655,3.42713 -2.47562,6.42067 -5.88438,8.70705 -3.40876,2.28635 -8.67972,3.86521 -16.66726,3.86521 H -47.858 v 4.00003 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:none;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999976;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
sodipodi:nodetypes="sccccccsccs" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.79964399;marker:none;enable-background:accumulate"
|
||||
d="m 1.9230841,111.7131 14.1821019,2.49562 c -0.605737,-2.33062 -1.321885,-4.72081 -2.146577,-7.17122 -0.831349,-2.42991 -1.714887,-4.78821 -2.652114,-7.073694 -1.6363806,1.831694 -3.2611572,3.747714 -4.8734519,5.746744 -1.6139397,2.02168 -3.1168728,4.02187 -4.50973,6.00126 z"
|
||||
id="path1550"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
177
mea/ui/images/event-interface.svg
Normal file
177
mea/ui/images/event-interface.svg
Normal file
@ -0,0 +1,177 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="96"
|
||||
height="96"
|
||||
id="svg4874"
|
||||
version="1.1"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
viewBox="0 0 96 96.000001"
|
||||
sodipodi:docname="event-interface.svg">
|
||||
<defs
|
||||
id="defs4876" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="7.024999"
|
||||
inkscape:cx="70.049325"
|
||||
inkscape:cy="25.941564"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
showborder="true"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:snap-midpoints="true"
|
||||
inkscape:snap-object-midpoints="true"
|
||||
inkscape:snap-center="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:window-width="2880"
|
||||
inkscape:window-height="1698"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="44"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid5451"
|
||||
empspacing="8" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="8,-8.0000001"
|
||||
id="guide4063"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="4,-8.0000001"
|
||||
id="guide4065"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,88.000001"
|
||||
id="guide4067"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,92.000001"
|
||||
id="guide4069"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="104,4"
|
||||
id="guide4071"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-5,8.0000001"
|
||||
id="guide4073"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="88,-8.0000001"
|
||||
id="guide4077"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,84.000001"
|
||||
id="guide4074"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="12,-8.0000001"
|
||||
id="guide4076"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="84,-8.0000001"
|
||||
id="guide4080"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="48,-8.0000001"
|
||||
orientation="1,0"
|
||||
id="guide4170"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="-8,48"
|
||||
orientation="0,1"
|
||||
id="guide4172"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="92,-8.0000001"
|
||||
orientation="1,0"
|
||||
id="guide4760"
|
||||
inkscape:locked="false" />
|
||||
</sodipodi:namedview>
|
||||
<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
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(67.857146,-78.50504)">
|
||||
<rect
|
||||
transform="rotate(90)"
|
||||
y="-28.142855"
|
||||
x="78.505043"
|
||||
height="96"
|
||||
width="96"
|
||||
id="rect4782-637"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:3.99999976;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:none;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999976;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m -45.337483,101.05663 c 10.294337,-10.288755 25.790399,-13.370805 39.240222,-7.802725 13.44979,5.56807 22.23047,18.700765 22.23047,33.251945 0,14.55118 -8.78068,27.68194 -22.23047,33.25002 -13.449823,5.56804 -28.945885,2.48602 -39.240222,-7.80276 l 2.828107,-2.82811 c 9.158173,9.15322 22.916636,11.88745 34.882805,6.93358 11.96618,-4.95383 19.75979,-16.60879 19.75979,-29.55273 0,-12.94393 -7.79361,-24.60083 -19.75979,-29.554705 -11.966169,-4.95382 -25.724632,-2.2196 -34.882805,6.933635 z"
|
||||
id="path4145"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4116"
|
||||
d="m -28.791428,128.51885 c -8.51248,0 -14.61615,-1.67112 -18.89488,-4.54103 -4.27876,-2.86991 -6.59021,-6.93884 -7.55365,-11.13672 -0.481727,-2.09895 -0.627128,-6.33371 -0.627128,-6.33371 l 4.033952,0.0815 c 0,0 0.0968,3.64414 0.490066,5.35769 0.78655,3.42713 2.47562,6.42066 5.88438,8.70705 3.40876,2.28635 8.67972,3.86521 16.66726,3.86521 h 5.00061 v 4.00003 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:none;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999976;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
sodipodi:nodetypes="sccccccsccs" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4118"
|
||||
d="m -55.867086,146.58106 c 0,0 0.145401,-4.23476 0.627128,-6.3337 0.96344,-4.19788 3.27489,-8.26488 7.55365,-11.13479 4.27873,-2.86987 10.3824,-4.54295 18.89488,-4.54295 h 6.00062 v 3.99998 h -6.00062 c -7.98754,0 -13.2585,1.5789 -16.66726,3.86525 -3.40876,2.28635 -5.09783,5.27993 -5.88438,8.70701 -0.39327,1.71356 -0.490066,5.35772 -0.490066,5.35772 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:none;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999976;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
sodipodi:nodetypes="cccsccssccc" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.99940658;marker:none;enable-background:accumulate"
|
||||
d="m -31.791338,114.51796 0.008,24 c 3.65004,-1.66877 7.365923,-3.53593 11.149193,-5.59872 3.74774,-2.06778 7.36282,-4.20053 10.84286,-6.40029 -3.48004,-2.15573 -7.09512,-4.26804 -10.84286,-6.33581 -3.78535,-2.06393 -7.503353,-3.95192 -11.155363,-5.66518 z"
|
||||
id="path5588-9-2-96-5"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.9 KiB |
177
mea/ui/images/logs.svg
Normal file
177
mea/ui/images/logs.svg
Normal file
@ -0,0 +1,177 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="90"
|
||||
height="90"
|
||||
id="svg4874"
|
||||
version="1.1"
|
||||
inkscape:version="0.48+devel r"
|
||||
viewBox="0 0 90 90.000001"
|
||||
sodipodi:docname="text-x-generic-symbolic.svg">
|
||||
<defs
|
||||
id="defs4876" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.259629"
|
||||
inkscape:cx="5.0926006"
|
||||
inkscape:cy="70.49882"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g5283"
|
||||
showgrid="true"
|
||||
showborder="true"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:snap-midpoints="true"
|
||||
inkscape:snap-object-midpoints="true"
|
||||
inkscape:snap-center="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid5451"
|
||||
empspacing="6" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="6,77"
|
||||
id="guide4063" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="3,78"
|
||||
id="guide4065" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="55,84"
|
||||
id="guide4067" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="53,87"
|
||||
id="guide4069" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="20,3"
|
||||
id="guide4071" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="20,6"
|
||||
id="guide4073" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="87,7"
|
||||
id="guide4075" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="84,7"
|
||||
id="guide4077" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="58,81"
|
||||
id="guide4074" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="9,74"
|
||||
id="guide4076" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="21,9"
|
||||
id="guide4078" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="81,4"
|
||||
id="guide4080" />
|
||||
</sodipodi:namedview>
|
||||
<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></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(67.857146,-84.50504)">
|
||||
<g
|
||||
transform="matrix(0,-1,-1,0,373.50506,516.50504)"
|
||||
id="g4845"
|
||||
style="display:inline">
|
||||
<g
|
||||
id="g5283"
|
||||
transform="matrix(0,-1,-1,0,-293.63782,2219.3622)">
|
||||
<rect
|
||||
y="-725.63782"
|
||||
x="1778"
|
||||
height="90"
|
||||
width="90"
|
||||
id="rect5285"
|
||||
style="fill:none;stroke:none" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"
|
||||
d="m 9,3 0,84 51,0 3,0 18,-18 0,-3 0,-63 z m 6,6 60,0 0,57 -15,0 0,15 -45,0 z"
|
||||
transform="translate(1778,-725.63782)"
|
||||
id="path5289"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect5293"
|
||||
d="m 1802,-707.63781 42,0 0,3.99999 -42,0 z"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;enable-background:accumulate"
|
||||
d="m 1802,-699.63781 42,0 0,3.99999 -42,0 z"
|
||||
id="path4615"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4617"
|
||||
d="m 1802,-691.63781 42,0 0,3.99999 -42,0 z"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;enable-background:accumulate"
|
||||
d="m 1802,-683.63781 42,0 0,3.99999 -42,0 z"
|
||||
id="path4619"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4621"
|
||||
d="m 1802,-675.63781 21,0 0,3.99999 -21,0 z"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;enable-background:accumulate" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
164
mea/ui/images/plugin.svg
Normal file
164
mea/ui/images/plugin.svg
Normal file
@ -0,0 +1,164 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="90"
|
||||
height="90"
|
||||
id="svg4874"
|
||||
version="1.1"
|
||||
inkscape:version="0.48+devel r"
|
||||
viewBox="0 0 90 90.000001"
|
||||
sodipodi:docname="package-x-generic-symbolic.svg">
|
||||
<defs
|
||||
id="defs4876" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4.0745362"
|
||||
inkscape:cx="-10.320196"
|
||||
inkscape:cy="41.857524"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g5283"
|
||||
showgrid="false"
|
||||
showborder="true"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:snap-midpoints="true"
|
||||
inkscape:snap-object-midpoints="true"
|
||||
inkscape:snap-center="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid5451"
|
||||
empspacing="6" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="6,77"
|
||||
id="guide4063" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="3,78"
|
||||
id="guide4065" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="55,84"
|
||||
id="guide4067" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="53,87"
|
||||
id="guide4069" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="20,3"
|
||||
id="guide4071" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="20,6"
|
||||
id="guide4073" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="87,7"
|
||||
id="guide4075" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="84,7"
|
||||
id="guide4077" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="58,81"
|
||||
id="guide4074" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="9,74"
|
||||
id="guide4076" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="21,9"
|
||||
id="guide4078" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="81,4"
|
||||
id="guide4080" />
|
||||
</sodipodi:namedview>
|
||||
<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></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(67.857146,-84.50504)">
|
||||
<g
|
||||
transform="matrix(0,-1,-1,0,373.50506,516.50504)"
|
||||
id="g4845"
|
||||
style="display:inline">
|
||||
<g
|
||||
id="g5283"
|
||||
transform="matrix(0,-1,-1,0,-293.63782,2219.3622)">
|
||||
<rect
|
||||
y="-725.63782"
|
||||
x="1778"
|
||||
height="90"
|
||||
width="90"
|
||||
id="rect5285"
|
||||
style="fill:none;stroke:none" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#808080;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="m 1823,-639.00386 -38.8426,-19.35382 0,-41.47248 38.8426,19.35383 38.8426,-19.35383 0,41.47248 z"
|
||||
id="path4170"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4174"
|
||||
d="m 1861.8426,-664.67723 0,-38.2407 -38.8426,-19.35382 -38.8426,19.35382 0,38.2407"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#808080;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#808080;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="m 1823,-680.6378 0,41.63394"
|
||||
id="path4176"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;color-interpolation:sRGB;color-interpolation-filters:linearRGB;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:#808080;stroke-width:2.00000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 1836.3594,-712.26282 -38.1485,19.01563 0,22.12304 6.4668,3.22461 0,-21.34765 38.9297,-19.4043 z"
|
||||
id="path4178"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.4 KiB |
91
mea/ui/images/state-interface.svg
Normal file
91
mea/ui/images/state-interface.svg
Normal file
@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg4874"
|
||||
width="96"
|
||||
height="96"
|
||||
version="1.1"
|
||||
viewBox="0 0 96 96"
|
||||
sodipodi:docname="state-interface.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<defs
|
||||
id="defs1598" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2880"
|
||||
inkscape:window-height="1698"
|
||||
id="namedview1596"
|
||||
showgrid="true"
|
||||
inkscape:zoom="13.906433"
|
||||
inkscape:cx="42.524831"
|
||||
inkscape:cy="54.157101"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="44"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4874">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid2159" />
|
||||
</sodipodi:namedview>
|
||||
<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></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<rect
|
||||
style="color:#000000;fill:none"
|
||||
height="96"
|
||||
width="96"
|
||||
y="-96"
|
||||
x="-2.7465819e-06"
|
||||
transform="rotate(90)"
|
||||
id="rect4782-2" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#808080;color-rendering:auto;image-rendering:auto;shape-rendering:auto"
|
||||
d="m 27.988,19.999 -0.01134,0.002 c -5.0328,0.0582 -8.7136,-0.12019 -11.725,1.541 -1.5055,0.83062 -2.6968,2.2356 -3.3555,3.9902 -0.65866,1.7546 -0.89647,3.8364 -0.89647,6.4668 v 48.002 c 0,2.6304 0.23773,4.7122 0.89647,6.4668 0.65866,1.7546 1.85,3.1596 3.3555,3.9902 3.011,1.6613 6.6918,1.4848 11.725,1.543 h 0.01134 40.023 0.01134 c 5.0328,-0.0582 8.7136,0.1183 11.725,-1.543 1.5055,-0.83066 2.6968,-2.2356 3.3555,-3.9902 0.65866,-1.7546 0.8965,-3.8364 0.8965,-6.4668 V 31.999 c 0,-2.6304 -0.23773,-4.7122 -0.8965,-6.4668 -0.65866,-1.7547 -1.85,-3.1596 -3.3555,-3.9902 -3.011,-1.6613 -6.6918,-1.4829 -11.725,-1.5411 l -0.01134,-0.002 -12.012,0.002 v 4 l 11.977,-0.002 c 5.0542,0.0586 8.3726,0.23547 9.8398,1.0449 0.73364,0.40479 1.1527,0.85493 1.543,1.8945 0.39024,1.0396 0.64059,2.691 0.64059,5.0606 v 48.002 c 0,2.3695 -0.2502,4.0209 -0.64059,5.0605 -0.39027,1.0396 -0.80935,1.4898 -1.543,1.8945 -1.4645,0.80806 -4.7782,0.98615 -9.8164,1.0449 h -39.977 -0.02268 c -5.0383,-0.059 -8.3519,-0.23697 -9.8164,-1.0449 -0.73364,-0.40475 -1.1508,-0.85489 -1.541,-1.8945 -0.39027,-1.0396 -0.6426,-2.691 -0.6426,-5.0605 v -48.002 c 0,-2.3696 0.25247,-4.0209 0.6426,-5.0606 0.39024,-1.0396 0.80734,-1.4897 1.541,-1.8945 1.4645,-0.80807 4.7782,-0.98616 9.8164,-1.0449 l 12,0.002 v -4 z"
|
||||
id="path4643-2" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;fill:#808080"
|
||||
d="m 59.9999,46.005 -24,0.008 c 1.6687,3.6501 3.5359,7.366 5.5987,11.149 2.0678,3.7477 4.2005,7.3628 6.4003,10.843 2.1557,-3.48 4.268,-7.0951 6.3358,-10.843 2.0639,-3.7854 3.9519,-7.5033 5.6652,-11.155 z"
|
||||
id="path5588-9-2-96-04" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4116"
|
||||
d="m 50.000025,30.99939 c 0,-8.51248 -1.671118,-14.61615 -4.541027,-18.89488 C 42.589089,7.82575 38.520163,5.5143 34.32228,4.55086 25.926475,2.62395 16.909393,5.58849 12.367195,7.10257 l 1.265612,3.79344 C 18.090646,9.41005 26.573531,6.87467 33.427741,8.44775 36.854866,9.2343 39.848403,10.92337 42.13479,14.33213 44.42114,17.74089 46,23.01185 46,30.99939 V 64 h 4.000025 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:none;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999976;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4118"
|
||||
d="M 83.683627,7.10257 C 79.141429,5.58849 70.124308,2.62395 61.728541,4.55086 57.530658,5.5143 53.463659,7.82575 50.593751,12.10451 47.72388,16.38324 46.050796,22.48691 46.050796,30.99939 v 20.00062 h 3.999988 V 30.99939 c 0,-7.98754 1.578897,-13.2585 3.865247,-16.66726 2.28635,-3.40876 5.279924,-5.09783 8.707011,-5.88438 6.854249,-1.57308 15.337133,0.9623 19.794935,2.44826 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:none;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999976;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
sodipodi:nodetypes="cccsccssccc" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.99940658;marker:none;enable-background:accumulate"
|
||||
d="m 35.999143,45.99948 24,0.008 c -1.668775,3.65004 -3.535937,7.365923 -5.598728,11.149193 -2.067779,3.74774 -4.200529,7.36282 -6.400289,10.84286 -2.15573,-3.48004 -4.268032,-7.09512 -6.335811,-10.84286 C 39.60039,53.371323 37.712403,49.65332 35.999143,46.00131 Z"
|
||||
id="path5588-9-2-96-5"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.7 KiB |
@ -4,9 +4,11 @@ import QtQuick.Layouts 1.3
|
||||
import Mea 1.0
|
||||
import "../components"
|
||||
|
||||
SwipeDelegate {
|
||||
MeaListItemDelegate {
|
||||
id: root
|
||||
implicitHeight: app.delegateHeight
|
||||
progressive: false
|
||||
canDelete: true
|
||||
|
||||
property var calendarItem: null
|
||||
|
||||
@ -15,90 +17,7 @@ SwipeDelegate {
|
||||
|
||||
signal removeCalendarItem();
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: app.margins
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: app.iconSize
|
||||
Layout.preferredWidth: app.iconSize
|
||||
name: "../images/clock-app-symbolic.svg"
|
||||
color: app.guhAccent
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
text: qsTr("From %1 to %2")
|
||||
.arg(root.isDateBased ? Qt.formatDateTime(root.calendarItem.dateTime) : Qt.formatTime(root.calendarItem.startTime))
|
||||
.arg(root.isDateBased ? Qt.formatDateTime(new Date(root.calendarItem.dateTime.getTime() + root.calendarItem.duration * 60000)) : Qt.formatTime(new Date(root.calendarItem.startTime.getTime() + root.calendarItem.duration * 60000)))
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: app.smallFont
|
||||
text: qsTr("repeated %3")
|
||||
.arg(repeatingString)
|
||||
|
||||
property string repeatingString: {
|
||||
switch (root.calendarItem.repeatingOption.repeatingMode) {
|
||||
case RepeatingOption.RepeatingModeNone:
|
||||
return qsTr("never");
|
||||
case RepeatingOption.RepeatingModeHourly:
|
||||
return qsTr("hourly");
|
||||
case RepeatingOption.RepeatingModeDaily:
|
||||
return qsTr("daily");
|
||||
case RepeatingOption.RepeatingModeWeekly:
|
||||
var weekdays = []
|
||||
for (var i = 0; i < root.calendarItem.repeatingOption.weekDays.length; i++) {
|
||||
switch (root.calendarItem.repeatingOption.weekDays[i]) {
|
||||
case 1:
|
||||
weekdays.push(qsTr("Mon"));
|
||||
break;
|
||||
case 2:
|
||||
weekdays.push(qsTr("Tue"));
|
||||
break;
|
||||
case 3:
|
||||
weekdays.push(qsTr("Wed"));
|
||||
break;
|
||||
case 4:
|
||||
weekdays.push(qsTr("Thu"));
|
||||
break;
|
||||
case 5:
|
||||
weekdays.push(qsTr("Fri"));
|
||||
break;
|
||||
case 6:
|
||||
weekdays.push(qsTr("Sat"));
|
||||
break;
|
||||
case 7:
|
||||
weekdays.push(qsTr("Sun"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return qsTr("weekly on %1").arg(weekdays.join(', '));
|
||||
case RepeatingOption.RepeatingModeMonthly:
|
||||
return qsTr("monthly on the %1").arg(root.calendarItem.repeatingOption.monthDays.join(', '));
|
||||
case RepeatingOption.RepeatingModeYearly:
|
||||
return qsTr("every year");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
swipe.right: MouseArea {
|
||||
height: root.height
|
||||
width: height
|
||||
anchors.right: parent.right
|
||||
ColorIcon {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins
|
||||
name: "../images/delete.svg"
|
||||
color: "red"
|
||||
}
|
||||
onClicked: root.removeCalendarItem()
|
||||
}
|
||||
onDeleteClicked: root.removeCalendarItem()
|
||||
|
||||
onClicked: {
|
||||
var page = pageStack.push(Qt.resolvedUrl("EditCalendarItemPage.qml"), {calendarItem: root.calendarItem})
|
||||
@ -108,4 +27,59 @@ SwipeDelegate {
|
||||
print("calendarItem.time is now", root.calendarItem.time)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
iconName: "../images/clock-app-symbolic.svg"
|
||||
|
||||
text: qsTr("From %1 to %2")
|
||||
.arg(root.isDateBased ? Qt.formatDateTime(root.calendarItem.dateTime) : Qt.formatTime(root.calendarItem.startTime))
|
||||
.arg(root.isDateBased ? Qt.formatDateTime(new Date(root.calendarItem.dateTime.getTime() + root.calendarItem.duration * 60000)) : Qt.formatTime(new Date(root.calendarItem.startTime.getTime() + root.calendarItem.duration * 60000)))
|
||||
|
||||
subText: qsTr("repeated %3")
|
||||
.arg(repeatingString)
|
||||
|
||||
property string repeatingString: {
|
||||
switch (root.calendarItem.repeatingOption.repeatingMode) {
|
||||
case RepeatingOption.RepeatingModeNone:
|
||||
return qsTr("never");
|
||||
case RepeatingOption.RepeatingModeHourly:
|
||||
return qsTr("hourly");
|
||||
case RepeatingOption.RepeatingModeDaily:
|
||||
return qsTr("daily");
|
||||
case RepeatingOption.RepeatingModeWeekly:
|
||||
var weekdays = []
|
||||
for (var i = 0; i < root.calendarItem.repeatingOption.weekDays.length; i++) {
|
||||
switch (root.calendarItem.repeatingOption.weekDays[i]) {
|
||||
case 1:
|
||||
weekdays.push(qsTr("Mon"));
|
||||
break;
|
||||
case 2:
|
||||
weekdays.push(qsTr("Tue"));
|
||||
break;
|
||||
case 3:
|
||||
weekdays.push(qsTr("Wed"));
|
||||
break;
|
||||
case 4:
|
||||
weekdays.push(qsTr("Thu"));
|
||||
break;
|
||||
case 5:
|
||||
weekdays.push(qsTr("Fri"));
|
||||
break;
|
||||
case 6:
|
||||
weekdays.push(qsTr("Sat"));
|
||||
break;
|
||||
case 7:
|
||||
weekdays.push(qsTr("Sun"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return qsTr("weekly on %1").arg(weekdays.join(', '));
|
||||
case RepeatingOption.RepeatingModeMonthly:
|
||||
return qsTr("monthly on the %1").arg(root.calendarItem.repeatingOption.monthDays.join(', '));
|
||||
case RepeatingOption.RepeatingModeYearly:
|
||||
return qsTr("every year");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -20,23 +20,39 @@ Page {
|
||||
signal accept();
|
||||
signal cancel();
|
||||
|
||||
function addEventDescriptor() {
|
||||
var eventDescriptor = root.rule.eventDescriptors.createNewEventDescriptor();
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"));
|
||||
page.onBackPressed.connect(function() { pageStack.pop(); });
|
||||
function addEventDescriptor(interfaceMode) {
|
||||
if (interfaceMode === undefined) {
|
||||
interfaceMode = false;
|
||||
}
|
||||
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {selectInterface: interfaceMode, showEvents: true});
|
||||
page.onBackPressed.connect(function() {
|
||||
pageStack.pop();
|
||||
});
|
||||
page.onThingSelected.connect(function(device) {
|
||||
var eventDescriptor = root.rule.eventDescriptors.createNewEventDescriptor();
|
||||
eventDescriptor.deviceId = device.id;
|
||||
selectEventDescriptorData(eventDescriptor)
|
||||
selectEventDescriptorData(eventDescriptor);
|
||||
})
|
||||
page.onInterfaceSelected.connect(function(interfaceName) {
|
||||
var eventDescriptor = root.rule.eventDescriptors.createNewEventDescriptor();
|
||||
eventDescriptor.interfaceName = interfaceName;
|
||||
selectEventDescriptorData(eventDescriptor)
|
||||
selectEventDescriptorData(eventDescriptor);
|
||||
})
|
||||
}
|
||||
|
||||
function addInterfaceEventDescriptor() {
|
||||
addEventDescriptor(true);
|
||||
}
|
||||
|
||||
function selectEventDescriptorData(eventDescriptor) {
|
||||
var eventPage = pageStack.push(Qt.resolvedUrl("SelectEventDescriptorPage.qml"), {text: "Select event", eventDescriptor: eventDescriptor});
|
||||
eventPage.onBackPressed.connect(function() {pageStack.pop()})
|
||||
eventPage.onBackPressed.connect(function() {
|
||||
eventPage.StackView.onRemoved.connect(function() {
|
||||
eventDescriptor.destroy();
|
||||
});
|
||||
pageStack.pop();
|
||||
})
|
||||
eventPage.onDone.connect(function() {
|
||||
root.rule.eventDescriptors.addEventDescriptor(eventPage.eventDescriptor);
|
||||
pageStack.pop(root)
|
||||
@ -47,8 +63,10 @@ Page {
|
||||
var timeEventItem = root.rule.timeDescriptor.timeEventItems.createNewTimeEventItem();
|
||||
var page = pageStack.push(Qt.resolvedUrl("EditTimeEventItemPage.qml"), {timeEventItem: timeEventItem});
|
||||
page.onBackPressed.connect(function() {
|
||||
page.StackView.onRemoved.connect(function() {
|
||||
timeEventItem.destroy();
|
||||
});
|
||||
pageStack.pop()
|
||||
timeEventItem.destroy();
|
||||
})
|
||||
page.onDone.connect(function() {
|
||||
root.rule.timeDescriptor.timeEventItems.addTimeEventItem(timeEventItem);
|
||||
@ -60,8 +78,10 @@ Page {
|
||||
var calendarItem = root.rule.timeDescriptor.calendarItems.createNewCalendarItem();
|
||||
var page = pageStack.push(Qt.resolvedUrl("EditCalendarItemPage.qml"), {calendarItem: calendarItem});
|
||||
page.onBackPressed.connect(function() {
|
||||
page.StackView.onRemoved.connect(function() {
|
||||
calendarItem.destroy();
|
||||
});
|
||||
pageStack.pop();
|
||||
calendarItem.destroy();
|
||||
})
|
||||
page.onDone.connect(function() {
|
||||
root.rule.timeDescriptor.calendarItems.addCalendarItem(calendarItem);
|
||||
@ -69,48 +89,109 @@ Page {
|
||||
})
|
||||
}
|
||||
|
||||
function createStateEvaluator(interfaceMode) {
|
||||
if (interfaceMode === undefined) {
|
||||
interfaceMode = false;
|
||||
}
|
||||
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {selectInterface: interfaceMode, showStates: true});
|
||||
page.backPressed.connect(function() {
|
||||
pageStack.pop();
|
||||
});
|
||||
page.interfaceSelected.connect(function(interfaceName) {
|
||||
var stateEvaluator = root.rule.createStateEvaluator();
|
||||
stateEvaluator.stateDescriptor.interfaceName = interfaceName;
|
||||
selectStateDescriptorData(stateEvaluator)
|
||||
});
|
||||
page.thingSelected.connect(function(device) {
|
||||
var stateEvaluator = root.rule.createStateEvaluator();
|
||||
stateEvaluator.stateDescriptor.deviceId = device.id
|
||||
selectStateDescriptorData(stateEvaluator)
|
||||
})
|
||||
}
|
||||
|
||||
function selectStateDescriptorData(stateEvaluator) {
|
||||
print("Selecting stateDescriptorData for", stateEvaluator.stateDescriptor.deviceId, stateEvaluator.stateDescriptor.interfaceName)
|
||||
var statePage = pageStack.push(Qt.resolvedUrl("SelectStateDescriptorPage.qml"), {text: "Select state", stateDescriptor: stateEvaluator.stateDescriptor})
|
||||
statePage.backPressed.connect(function() {
|
||||
statePage.StackView.onRemoved.connect(function() {
|
||||
stateEvaluator.destroy();
|
||||
})
|
||||
pageStack.pop()
|
||||
})
|
||||
statePage.done.connect(function() {
|
||||
root.rule.setStateEvaluator(stateEvaluator)
|
||||
pageStack.pop();
|
||||
pageStack.pop();
|
||||
pageStack.pop();
|
||||
})
|
||||
}
|
||||
|
||||
function createInterfaceStateEvaluator() {
|
||||
createStateEvaluator(true)
|
||||
}
|
||||
|
||||
function editStateEvaluator() {
|
||||
print("opening page", root.rule.stateEvaluator)
|
||||
var page = pageStack.push(Qt.resolvedUrl("EditStateEvaluatorPage.qml"), { stateEvaluator: root.rule.stateEvaluator })
|
||||
}
|
||||
|
||||
function addAction() {
|
||||
var ruleAction = root.rule.actions.createNewRuleAction();
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"));
|
||||
page.onBackPressed.connect(function() { pageStack.pop() })
|
||||
function addRuleAction(interfaceMode) {
|
||||
if (interfaceMode === undefined) {
|
||||
interfaceMode = false;
|
||||
}
|
||||
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {selectInterface: interfaceMode, showActions: true});
|
||||
page.onBackPressed.connect(function() {
|
||||
pageStack.pop();
|
||||
})
|
||||
page.onThingSelected.connect(function(device) {
|
||||
print("thing selected", device.name, device.id)
|
||||
var ruleAction = root.rule.actions.createNewRuleAction();
|
||||
ruleAction.deviceId = device.id;
|
||||
selectRuleActionData(root.rule.actions, ruleAction)
|
||||
})
|
||||
page.onInterfaceSelected.connect(function(interfaceName) {
|
||||
print("interface selected", interfaceName)
|
||||
var ruleAction = root.rule.actions.createNewRuleAction();
|
||||
ruleAction.interfaceName = interfaceName;
|
||||
selectRuleActionData(root.rule.actions, ruleAction)
|
||||
})
|
||||
}
|
||||
function addExitAction() {
|
||||
var ruleAction = root.rule.exitActions.createNewRuleAction();
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"));
|
||||
page.onBackPressed.connect(function() { pageStack.pop() })
|
||||
function addInterfaceRuleAction() {
|
||||
addRuleAction(true);
|
||||
}
|
||||
|
||||
function addRuleExitAction(interfaceMode) {
|
||||
if (interfaceMode === undefined) {
|
||||
interfaceMode = false;
|
||||
}
|
||||
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {selectInterface: interfaceMode, showActions: true});
|
||||
page.onBackPressed.connect(function() {
|
||||
pageStack.pop();
|
||||
})
|
||||
page.onThingSelected.connect(function(device) {
|
||||
print("thing selected", device.name, device.id)
|
||||
var ruleAction = root.rule.exitActions.createNewRuleAction();
|
||||
ruleAction.deviceId = device.id;
|
||||
selectRuleActionData(root.rule.exitActions, ruleAction)
|
||||
})
|
||||
page.onInterfaceSelected.connect(function(interfaceName) {
|
||||
print("interface selected", interfaceName)
|
||||
var ruleAction = root.rule.exitActions.createNewRuleAction();
|
||||
ruleAction.interfaceName = interfaceName;
|
||||
selectRuleActionData(root.rule.exitActions, ruleAction)
|
||||
})
|
||||
}
|
||||
function addInterfaceRuleExitAction() {
|
||||
addRuleExitAction(true);
|
||||
}
|
||||
|
||||
function selectRuleActionData(ruleActions, ruleAction) {
|
||||
print("opening with ruleAction", ruleAction)
|
||||
print("opening with ruleAction", ruleAction, ruleAction.interfaceName)
|
||||
var ruleActionPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionPage.qml"), {text: "Select action", ruleAction: ruleAction, rule: rule });
|
||||
ruleActionPage.onBackPressed.connect(function() {
|
||||
pageStack.pop(root);
|
||||
ruleAction.destroy();
|
||||
ruleActionPage.StackView.onRemoved.connect(function() {
|
||||
ruleAction.destroy();
|
||||
});
|
||||
pageStack.pop();
|
||||
})
|
||||
ruleActionPage.onDone.connect(function() {
|
||||
ruleActions.addRuleAction(ruleAction)
|
||||
@ -246,8 +327,7 @@ Page {
|
||||
if (root.rule.timeDescriptor.calendarItems.count > 0) {
|
||||
root.addEventDescriptor()
|
||||
} else {
|
||||
var popup = eventQuestionDialogComponent.createObject(root)
|
||||
popup.open();
|
||||
pageStack.push(eventQuestionPageComponent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -298,6 +378,9 @@ Page {
|
||||
Layout.fillWidth: true
|
||||
stateEvaluator: root.rule.stateEvaluator
|
||||
visible: root.rule.stateEvaluator !== null
|
||||
onDeleteClicked: {
|
||||
root.rule.stateEvaluator = null
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
@ -331,12 +414,11 @@ Page {
|
||||
visible: root.rule.timeDescriptor.timeEventItems.count === 0 || root.rule.stateEvaluator === null
|
||||
onClicked: {
|
||||
if (root.rule.timeDescriptor.timeEventItems.count > 0) {
|
||||
root.rule.createStateEvaluator()
|
||||
root.rule.setStateEvaluator(root.rule.createStateEvaluator());
|
||||
} else if (root.rule.stateEvaluator !== null) {
|
||||
root.addCalendarItem();
|
||||
} else {
|
||||
var popup = stateQuestionDialogComponent.createObject(root)
|
||||
popup.open()
|
||||
pageStack.push(stateQuestionPageComponent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -369,7 +451,9 @@ Page {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
text: actionsRepeater.count == 0 ? qsTr("Add an action...") : qsTr("Add another action...")
|
||||
onClicked: root.addAction();
|
||||
onClicked: {
|
||||
var page = pageStack.push(ruleActionQuestionPageComponent, {exitAction: false});
|
||||
}
|
||||
visible: root.actionsVisible
|
||||
}
|
||||
|
||||
@ -400,7 +484,9 @@ Page {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
text: actionsRepeater.count == 0 ? qsTr("Add an action...") : qsTr("Add another action...")
|
||||
onClicked: root.addExitAction();
|
||||
onClicked: {
|
||||
var page = pageStack.push(ruleActionQuestionPageComponent, {exitAction: true});
|
||||
}
|
||||
visible: root.exitActionsVisible
|
||||
}
|
||||
}
|
||||
@ -419,134 +505,162 @@ Page {
|
||||
}
|
||||
|
||||
Component {
|
||||
id: eventQuestionDialogComponent
|
||||
MeaDialog {
|
||||
id: questionDialog
|
||||
title: qsTr("Add event...")
|
||||
standardButtons: Dialog.Cancel
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: (app.largeFont * 2) + (app.margins * 3)
|
||||
contentItem: RowLayout {
|
||||
spacing: app.margins
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: app.iconSize
|
||||
Layout.preferredWidth: height
|
||||
name: "../images/event.svg"
|
||||
color: "black"
|
||||
}
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: qsTr("When one of my things triggers an event")
|
||||
wrapMode: Text.WordWrap
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
root.addEventDescriptor()
|
||||
questionDialog.close()
|
||||
}
|
||||
id: eventQuestionPageComponent
|
||||
Page {
|
||||
header: GuhHeader {
|
||||
text: qsTr("Add event")
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("or")
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: (app.largeFont * 2) + (app.margins * 3)
|
||||
contentItem: RowLayout {
|
||||
spacing: app.margins
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: app.iconSize
|
||||
Layout.preferredWidth: height
|
||||
name: "../images/alarm-clock.svg"
|
||||
color: "black"
|
||||
Repeater {
|
||||
model: ListModel {
|
||||
ListElement {
|
||||
iconName: "../images/event.svg"
|
||||
text: qsTr("When one of my things triggers an event")
|
||||
method: "addEventDescriptor"
|
||||
minimumJsonRpcVersion: "1.0"
|
||||
}
|
||||
ListElement {
|
||||
iconName: "../images/event-interface.svg"
|
||||
text: qsTr("When a thing of a given type triggers an event")
|
||||
method: "addInterfaceEventDescriptor"
|
||||
minimumJsonRpcVersion: "1.5"
|
||||
}
|
||||
ListElement {
|
||||
iconName: "../images/alarm-clock.svg"
|
||||
text: qsTr("At a particular time or date")
|
||||
method: "addTimeEventItem"
|
||||
minimumJsonRpcVersion: "1.0"
|
||||
}
|
||||
}
|
||||
Label {
|
||||
delegate: MeaListItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: qsTr("At a particular time or date")
|
||||
wrapMode: Text.WordWrap
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
iconName: model.iconName
|
||||
text: model.text
|
||||
progressive: true
|
||||
iconSize: app.iconSize * 2
|
||||
visible: Engine.jsonRpcClient.ensureServerVersion(model.minimumJsonRpcVersion)
|
||||
|
||||
onClicked: {
|
||||
root[model.method]()
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
root.addTimeEventItem()
|
||||
questionDialog.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: stateQuestionDialogComponent
|
||||
MeaDialog {
|
||||
id: questionDialog
|
||||
title: qsTr("Add condition...")
|
||||
standardButtons: Dialog.Cancel
|
||||
id: stateQuestionPageComponent
|
||||
Page {
|
||||
header: GuhHeader {
|
||||
text: qsTr("Add condition...")
|
||||
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: (app.largeFont * 2) + (app.margins * 3)
|
||||
contentItem: RowLayout {
|
||||
spacing: app.margins
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: app.iconSize
|
||||
Layout.preferredWidth: height
|
||||
name: "../images/state.svg"
|
||||
color: "black"
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: qsTr("When one of my things is in a certain state")
|
||||
wrapMode: Text.WordWrap
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
root.rule.createStateEvaluator()
|
||||
questionDialog.close()
|
||||
}
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("or")
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: (app.largeFont * 2) + (app.margins * 3)
|
||||
contentItem: RowLayout {
|
||||
spacing: app.margins
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: app.iconSize
|
||||
Layout.preferredWidth: height
|
||||
name: "../images/clock-app-symbolic.svg"
|
||||
color: "black"
|
||||
Repeater {
|
||||
model: ListModel {
|
||||
ListElement {
|
||||
iconName: "../images/state.svg"
|
||||
text: qsTr("When one of my things is in a certain state")
|
||||
method: "createStateEvaluator"
|
||||
minimumJsonRpcVersion: "1.0"
|
||||
}
|
||||
ListElement {
|
||||
iconName: "../images/state-interface.svg"
|
||||
text: qsTr("When a thing of a given type enters a state")
|
||||
method: "createInterfaceStateEvaluator"
|
||||
minimumJsonRpcVersion: "1.5"
|
||||
}
|
||||
ListElement {
|
||||
iconName: "../images/clock-app-symbolic.svg"
|
||||
text: qsTr("During a given time")
|
||||
method: "addCalendarItem"
|
||||
minimumJsonRpcVersion: "1.0"
|
||||
}
|
||||
}
|
||||
Label {
|
||||
delegate: MeaListItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: qsTr("During a given time")
|
||||
wrapMode: Text.WordWrap
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
iconName: model.iconName
|
||||
text: model.text
|
||||
progressive: true
|
||||
iconSize: app.iconSize * 2
|
||||
visible: Engine.jsonRpcClient.ensureServerVersion(model.minimumJsonRpcVersion)
|
||||
|
||||
onClicked: {
|
||||
root[model.method]()
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
root.addCalendarItem()
|
||||
questionDialog.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: ruleActionQuestionPageComponent
|
||||
Page {
|
||||
id: ruleActionQuestionPage
|
||||
property bool exitAction: false
|
||||
|
||||
header: GuhHeader {
|
||||
text: qsTr("Add action...")
|
||||
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
Repeater {
|
||||
model: ListModel {
|
||||
ListElement {
|
||||
iconName: "../images/action.svg"
|
||||
text: qsTr("Execute an action on of my things")
|
||||
method: "addRuleAction"
|
||||
isExitAction: false
|
||||
minimumJsonRpcVersion: "1.0"
|
||||
}
|
||||
ListElement {
|
||||
iconName: "../images/action-interface.svg"
|
||||
text: qsTr("Execute an action on an entire kind of things")
|
||||
method: "addInterfaceRuleAction"
|
||||
isExitAction: false
|
||||
minimumJsonRpcVersion: "1.5"
|
||||
}
|
||||
ListElement {
|
||||
iconName: "../images/action.svg"
|
||||
text: qsTr("Execute an action on of my things")
|
||||
method: "addRuleExitAction"
|
||||
isExitAction: true
|
||||
minimumJsonRpcVersion: "1.0"
|
||||
}
|
||||
ListElement {
|
||||
iconName: "../images/action-interface.svg"
|
||||
text: qsTr("Execute an action on an entire kind of things")
|
||||
method: "addInterfaceRuleExitAction"
|
||||
isExitAction: true
|
||||
minimumJsonRpcVersion: "1.5"
|
||||
}
|
||||
}
|
||||
delegate: MeaListItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
iconName: model.iconName
|
||||
text: model.text
|
||||
progressive: true
|
||||
iconSize: app.iconSize * 2
|
||||
visible: ruleActionQuestionPage.exitAction === model.isExitAction && Engine.jsonRpcClient.ensureServerVersion(model.minimumJsonRpcVersion)
|
||||
|
||||
onClicked: {
|
||||
root[model.method]()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,5 +16,6 @@ Page {
|
||||
StateEvaluatorDelegate {
|
||||
width: parent.width
|
||||
stateEvaluator: root.stateEvaluator
|
||||
canDelete: false
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,96 +4,68 @@ import QtQuick.Layouts 1.3
|
||||
import Mea 1.0
|
||||
import "../components"
|
||||
|
||||
SwipeDelegate {
|
||||
MeaListItemDelegate {
|
||||
id: root
|
||||
implicitHeight: app.delegateHeight
|
||||
canDelete: true
|
||||
progressive: false
|
||||
|
||||
property var eventDescriptor: null
|
||||
readonly property var device: eventDescriptor ? Engine.deviceManager.devices.getDevice(eventDescriptor.deviceId) : null
|
||||
readonly property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
readonly property var iface: eventDescriptor.interfaceName ? Interfaces.findByName(eventDescriptor.interfaceName) : null
|
||||
readonly property var eventType: deviceClass ? deviceClass.eventTypes.getEventType(eventDescriptor.eventTypeId)
|
||||
: iface ? iface.eventTypes.findByName(eventDescriptor.interfaceEvent) : null
|
||||
: iface ? iface.eventTypes.findByName(eventDescriptor.interfaceEvent) : null
|
||||
|
||||
signal removeEventDescriptor()
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: app.margins
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: app.iconSize
|
||||
Layout.preferredWidth: app.iconSize
|
||||
name: "../images/event.svg"
|
||||
color: app.guhAccent
|
||||
}
|
||||
onDeleteClicked: root.removeEventDescriptor()
|
||||
|
||||
ColumnLayout {
|
||||
Label {
|
||||
text: qsTr("%1 - %2").arg(root.device ? root.device.name : root.iface.displayName).arg(root.eventType.displayName)
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
iconName: root.device ? "../images/event.svg" : "../images/event-interface.svg"
|
||||
text: qsTr("%1 - %2").arg(root.device ? root.device.name : root.iface.displayName).arg(root.eventType.displayName)
|
||||
subText: {
|
||||
var ret = qsTr("anytime");
|
||||
for (var i = 0; i < root.eventDescriptor.paramDescriptors.count; i++) {
|
||||
var paramDescriptor = root.eventDescriptor.paramDescriptors.get(i)
|
||||
var operatorString;
|
||||
switch (paramDescriptor.operatorType) {
|
||||
case ParamDescriptor.ValueOperatorEquals:
|
||||
operatorString = " = ";
|
||||
break;
|
||||
case ParamDescriptor.ValueOperatorNotEquals:
|
||||
operatorString = " != ";
|
||||
break;
|
||||
case ParamDescriptor.ValueOperatorGreater:
|
||||
operatorString = " > ";
|
||||
break;
|
||||
case ParamDescriptor.ValueOperatorGreaterOrEqual:
|
||||
operatorString = " >= ";
|
||||
break;
|
||||
case ParamDescriptor.ValueOperatorLess:
|
||||
operatorString = " < ";
|
||||
break;
|
||||
case ParamDescriptor.ValueOperatorLessOrEqual:
|
||||
operatorString = " <= ";
|
||||
break;
|
||||
default:
|
||||
operatorString = " ? ";
|
||||
}
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: app.smallFont
|
||||
text: {
|
||||
var ret = qsTr("anytime");
|
||||
for (var i = 0; i < root.eventDescriptor.paramDescriptors.count; i++) {
|
||||
var paramDescriptor = root.eventDescriptor.paramDescriptors.get(i)
|
||||
var operatorString;
|
||||
switch (paramDescriptor.operatorType) {
|
||||
case ParamDescriptor.ValueOperatorEquals:
|
||||
operatorString = " = ";
|
||||
break;
|
||||
case ParamDescriptor.ValueOperatorNotEquals:
|
||||
operatorString = " != ";
|
||||
break;
|
||||
case ParamDescriptor.ValueOperatorGreater:
|
||||
operatorString = " > ";
|
||||
break;
|
||||
case ParamDescriptor.ValueOperatorGreaterOrEqual:
|
||||
operatorString = " >= ";
|
||||
break;
|
||||
case ParamDescriptor.ValueOperatorLess:
|
||||
operatorString = " < ";
|
||||
break;
|
||||
case ParamDescriptor.ValueOperatorLessOrEqual:
|
||||
operatorString = " <= ";
|
||||
break;
|
||||
default:
|
||||
operatorString = " ? ";
|
||||
}
|
||||
|
||||
if (i === 0) {
|
||||
// TRANSLATORS: example: "only if temperature > 5"
|
||||
ret = qsTr("only if %1 %2 %3")
|
||||
.arg(root.eventType.paramTypes.getParamType(paramDescriptor.paramTypeId).displayName)
|
||||
.arg(operatorString)
|
||||
.arg(paramDescriptor.value)
|
||||
} else {
|
||||
// TRANSLATORS: example: "and temperature > 5"
|
||||
ret += " " + qsTr("and %1 %2 %3")
|
||||
.arg(root.eventType.paramTypes.getParamType(paramDescriptor.paramTypeId).displayName)
|
||||
.arg(operatorString)
|
||||
.arg(model.value)
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
if (i === 0) {
|
||||
// TRANSLATORS: example: "only if temperature > 5"
|
||||
ret = qsTr("only if %1 %2 %3")
|
||||
.arg(root.eventType.paramTypes.getParamType(paramDescriptor.paramTypeId).displayName)
|
||||
.arg(operatorString)
|
||||
.arg(paramDescriptor.value)
|
||||
} else {
|
||||
// TRANSLATORS: example: "and temperature > 5"
|
||||
ret += " " + qsTr("and %1 %2 %3")
|
||||
.arg(root.eventType.paramTypes.getParamType(paramDescriptor.paramTypeId).displayName)
|
||||
.arg(operatorString)
|
||||
.arg(model.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
swipe.right: MouseArea {
|
||||
height: root.height
|
||||
width: height
|
||||
anchors.right: parent.right
|
||||
ColorIcon {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins
|
||||
name: "../images/delete.svg"
|
||||
color: "red"
|
||||
}
|
||||
onClicked: root.removeEventDescriptor()
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,9 +4,12 @@ import QtQuick.Layouts 1.3
|
||||
import Mea 1.0
|
||||
import "../components"
|
||||
|
||||
SwipeDelegate {
|
||||
MeaListItemDelegate {
|
||||
id: root
|
||||
implicitHeight: app.delegateHeight
|
||||
canDelete: true
|
||||
progressive: false
|
||||
|
||||
property var ruleAction: null
|
||||
|
||||
property var device: ruleAction.deviceId ? Engine.deviceManager.devices.getDevice(ruleAction.deviceId) : null
|
||||
@ -17,50 +20,19 @@ SwipeDelegate {
|
||||
|
||||
signal removeRuleAction()
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: app.margins
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: app.iconSize
|
||||
Layout.preferredWidth: app.iconSize
|
||||
name: "../images/action.svg"
|
||||
color: app.guhAccent
|
||||
}
|
||||
onDeleteClicked: root.removeRuleAction()
|
||||
|
||||
ColumnLayout {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
text: qsTr("%1 - %2").arg(root.device ? root.device.name : root.iface.displayName).arg(root.actionType.displayName)
|
||||
}
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: app.smallFont
|
||||
text: {
|
||||
var ret = [];
|
||||
for (var i = 0; i < root.ruleAction.ruleActionParams.count; i++) {
|
||||
var ruleActionParam = root.ruleAction.ruleActionParams.get(i)
|
||||
var paramString = qsTr("%1: %2")
|
||||
.arg(root.actionType.paramTypes.getParamType(ruleActionParam.paramTypeId).displayName)
|
||||
.arg(ruleActionParam.eventParamTypeId.length > 0 ? qsTr("value from event") : ruleActionParam.value)
|
||||
ret.push(paramString)
|
||||
}
|
||||
return ret.join(', ')
|
||||
}
|
||||
|
||||
}
|
||||
iconName: root.device ? "../images/action.svg" : "../images/action-interface.svg"
|
||||
text: qsTr("%1 - %2").arg(root.device ? root.device.name : root.iface.displayName).arg(root.actionType.displayName)
|
||||
subText: {
|
||||
var ret = [];
|
||||
for (var i = 0; i < root.ruleAction.ruleActionParams.count; i++) {
|
||||
var ruleActionParam = root.ruleAction.ruleActionParams.get(i)
|
||||
var paramString = qsTr("%1: %2")
|
||||
.arg(root.actionType.paramTypes.getParamType(ruleActionParam.paramTypeId).displayName)
|
||||
.arg(ruleActionParam.eventParamTypeId.length > 0 ? qsTr("value from event") : ruleActionParam.value)
|
||||
ret.push(paramString)
|
||||
}
|
||||
}
|
||||
swipe.right: MouseArea {
|
||||
height: root.height
|
||||
width: height
|
||||
anchors.right: parent.right
|
||||
ColorIcon {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins
|
||||
name: "../images/delete.svg"
|
||||
color: "red"
|
||||
}
|
||||
onClicked: root.removeRuleAction()
|
||||
return ret.join(', ')
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,20 +34,25 @@ Page {
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: eventTemplateModel
|
||||
ListElement { interfaceName: "temperaturesensor"; text: qsTr("When it's freezing..."); event: "freeze"}
|
||||
ListElement { interfaceName: "battery"; text: qsTr("When the device runs out of battery..."); event: "lowBattery"}
|
||||
ListElement { interfaceName: "weather"; text: qsTr("When it starts raining..."); event: "rain" }
|
||||
id: generatedModel
|
||||
ListElement { displayName: ""; eventTypeId: "" }
|
||||
}
|
||||
|
||||
function buildInterface() {
|
||||
if (header.interfacesMode) {
|
||||
if (root.device) {
|
||||
generatedModel.clear();
|
||||
for (var i = 0; i < Interfaces.count; i++) {
|
||||
if (deviceClass.interfaces.indexOf(Interfaces.get(i).name) >= 0) {
|
||||
actualModel.append(Interfaces.get(i))
|
||||
var iface = Interfaces.get(i);
|
||||
if (root.deviceClass.interfaces.indexOf(iface.name) >= 0) {
|
||||
for (var j = 0; j < iface.eventTypes.count; j++) {
|
||||
var ifaceEt = iface.eventTypes.get(j);
|
||||
var dcEt = root.deviceClass.eventTypes.findByName(ifaceEt.name)
|
||||
generatedModel.append({displayName: ifaceEt.displayName, eventTypeId: dcEt.id})
|
||||
}
|
||||
}
|
||||
}
|
||||
listView.model = generatedModel
|
||||
} else if (root.eventDescriptor.interfaceName !== "") {
|
||||
listView.model = Interfaces.findByName(root.eventDescriptor.interfaceName).eventTypes
|
||||
} else {
|
||||
@ -70,16 +75,17 @@ Page {
|
||||
onClicked: {
|
||||
if (header.interfacesMode) {
|
||||
if (root.device) {
|
||||
print("selected:", model.event)
|
||||
switch (model.event) {
|
||||
case "lowBattery":
|
||||
var eventType = root.deviceClass.eventTypes.findByName("batteryCritical")
|
||||
root.eventDescriptor.eventTypeId = eventType.id;
|
||||
// root.eventDescriptor.paramDescriptors.setParamDescriptor(eventType.paramTypes.get(0).paramTypeId, 0, ParamDescriptors.ValueOperatorLessOrEqual)
|
||||
root.eventDescriptor.eventTypeId = model.eventTypeId;
|
||||
var eventType = root.deviceClass.eventTypes.getEventType(model.eventTypeId)
|
||||
if (eventType.paramTypes.count > 0) {
|
||||
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectEventDescriptorParamsPage.qml"), {eventDescriptor: root.eventDescriptor})
|
||||
paramsPage.onBackPressed.connect(function() {pageStack.pop()});
|
||||
paramsPage.onCompleted.connect(function() {
|
||||
pageStack.pop();
|
||||
root.done();
|
||||
})
|
||||
} else {
|
||||
root.done();
|
||||
break;
|
||||
default:
|
||||
console.warn("FIXME: Unhandled interface event");
|
||||
}
|
||||
} else if (root.eventDescriptor.interfaceName !== "") {
|
||||
root.eventDescriptor.interfaceEvent = model.name;
|
||||
|
||||
@ -19,7 +19,7 @@ Page {
|
||||
signal completed();
|
||||
|
||||
header: GuhHeader {
|
||||
text: "params"
|
||||
text: "Options"
|
||||
onBackPressed: root.backPressed();
|
||||
}
|
||||
|
||||
@ -60,11 +60,16 @@ Page {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
onClicked: {
|
||||
var params = [];
|
||||
root.eventDescriptor.paramDescriptors.clear();
|
||||
for (var i = 0; i < delegateRepeater.count; i++) {
|
||||
var paramDelegate = delegateRepeater.itemAt(i);
|
||||
if (paramDelegate.considerParam) {
|
||||
root.eventDescriptor.paramDescriptors.setParamDescriptor(paramDelegate.paramType.id, paramDelegate.value, paramDelegate.operatorType)
|
||||
if (root.device) {
|
||||
root.eventDescriptor.paramDescriptors.setParamDescriptor(paramDelegate.paramType.id, paramDelegate.value, paramDelegate.operatorType)
|
||||
} else if (root.iface) {
|
||||
print("setting param descriptors by name", root.eventType.paramTypes.get(i), root.eventType.paramTypes.get(i).name)
|
||||
root.eventDescriptor.paramDescriptors.setParamDescriptorByName(root.eventType.paramTypes.get(i).name, paramDelegate.value, paramDelegate.operatorType)
|
||||
}
|
||||
}
|
||||
}
|
||||
root.completed()
|
||||
|
||||
@ -26,38 +26,39 @@ Page {
|
||||
id: header
|
||||
onBackPressed: root.backPressed();
|
||||
|
||||
property bool interfacesMode: false//root.ruleAction.interfaceName !== ""
|
||||
property bool interfacesMode: root.ruleAction.interfaceName !== ""
|
||||
onInterfacesModeChanged: root.buildInterface()
|
||||
|
||||
HeaderButton {
|
||||
imageSource: header.interfacesMode ? "../images/view-expand.svg" : "../images/view-collapse.svg"
|
||||
visible: root.ruleAction.deviceId || root.ruleAction.interfaceName === ""
|
||||
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: generatedModel
|
||||
ListElement { displayName: ""; actionTypeId: "" }
|
||||
}
|
||||
|
||||
function buildInterface() {
|
||||
print("building iface", root.ruleAction, root.ruleAction.interfaceName, header.interfacesMode, root.ruleAction.interfaceName === "")
|
||||
if (header.interfacesMode) {
|
||||
if (root.device) {
|
||||
generatedModel.clear();
|
||||
for (var i = 0; i < Interfaces.count; i++) {
|
||||
if (deviceClass.interfaces.indexOf(Interfaces.get(i).interfaceName) >= 0) {
|
||||
actualModel.append(Interfaces.get(i))
|
||||
var iface = Interfaces.get(i);
|
||||
if (root.deviceClass.interfaces.indexOf(iface.name) >= 0) {
|
||||
for (var j = 0; j < iface.actionTypes.count; j++) {
|
||||
var ifaceAt = iface.actionTypes.get(j);
|
||||
var dcAt = root.deviceClass.actionTypes.findByName(ifaceAt.name)
|
||||
generatedModel.append({displayName: ifaceAt.displayName, actionTypeId: dcAt.id})
|
||||
}
|
||||
}
|
||||
}
|
||||
listView.model = generatedModel
|
||||
} else if (root.ruleAction.interfaceName !== "") {
|
||||
print("showing actions for interface", root.ruleAction.interfaceName)
|
||||
listView.model = Interfaces.findByName(root.ruleAction.interfaceName).actionTypes
|
||||
} else {
|
||||
console.warn("You need to set device or interfaceName");
|
||||
@ -79,13 +80,17 @@ Page {
|
||||
onClicked: {
|
||||
if (header.interfacesMode) {
|
||||
if (root.device) {
|
||||
print("selected:", model.identifier)
|
||||
switch (model.identfier) {
|
||||
case "switchLight":
|
||||
root.ruleAction.actionTypeId = model.actionTypeId;
|
||||
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})
|
||||
paramsPage.onBackPressed.connect(function() {pageStack.pop()});
|
||||
paramsPage.onCompleted.connect(function() {
|
||||
pageStack.pop();
|
||||
root.done();
|
||||
})
|
||||
} else {
|
||||
root.done();
|
||||
break;
|
||||
default:
|
||||
console.warn("FIXME: Unhandled interface action");
|
||||
}
|
||||
} else if (root.ruleAction.interfaceName !== "") {
|
||||
root.ruleAction.interfaceAction = model.name;
|
||||
|
||||
@ -10,7 +10,7 @@ Page {
|
||||
// Needs to be set and have rule.ruleActions filled in with deviceId and actionTypeId or interfaceName and interfaceAction
|
||||
property var ruleAction: null
|
||||
|
||||
// optionally a rule which will be used to propse event's params as param values
|
||||
// optionally a rule which will be used to propose event's params as param values
|
||||
property var rule: null
|
||||
|
||||
readonly property var device: ruleAction && ruleAction.deviceId ? Engine.deviceManager.devices.getDevice(ruleAction.deviceId) : null
|
||||
@ -81,9 +81,9 @@ Page {
|
||||
model: EventDescriptorParamsFilterModel {
|
||||
id: eventDescriptorParamsFilterModel
|
||||
eventDescriptor: root.rule.eventDescriptors.count === 1 ? root.rule.eventDescriptors.get(0) : null
|
||||
property var device: Engine.deviceManager.devices.getDevice(eventDescriptor.deviceId)
|
||||
property var deviceClass: Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId)
|
||||
property var eventType: deviceClass.eventTypes.getEventType(eventDescriptor.eventTypeId)
|
||||
property var device: eventDescriptor ? Engine.deviceManager.devices.getDevice(eventDescriptor.deviceId) : null
|
||||
property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
property var eventType: deviceClass ? deviceClass.eventTypes.getEventType(eventDescriptor.eventTypeId) : null
|
||||
property var paramDescriptor: eventDescriptorParamsFilterModel.eventType.paramTypes.get(eventParamsComboBox.currentIndex)
|
||||
property var paramTypeId: paramDescriptor.id
|
||||
}
|
||||
@ -116,7 +116,11 @@ Page {
|
||||
for (var i = 0; i < delegateRepeater.count; i++) {
|
||||
var paramDelegate = delegateRepeater.itemAt(i);
|
||||
if (paramDelegate.type === "static") {
|
||||
root.ruleAction.ruleActionParams.setRuleActionParam(paramDelegate.paramType.id, paramDelegate.value)
|
||||
if (root.device) {
|
||||
root.ruleAction.ruleActionParams.setRuleActionParam(paramDelegate.paramType.id, paramDelegate.value)
|
||||
} else if (root.iface) {
|
||||
root.ruleAction.ruleActionParams.setRuleActionParamByName(root.actionType.paramTypes.get(i).name, paramDelegate.value)
|
||||
}
|
||||
} else if (paramDelegate.type === "event") {
|
||||
print("adding event based rule action param", paramDelegate.paramType.id, paramDelegate.eventType.id, paramDelegate.eventParamTypeId)
|
||||
root.ruleAction.ruleActionParams.setRuleActionParamEvent(paramDelegate.paramType.id, paramDelegate.eventType.id, paramDelegate.eventParamTypeId)
|
||||
|
||||
@ -16,29 +16,105 @@ Page {
|
||||
signal backPressed();
|
||||
signal done();
|
||||
|
||||
onStateDescriptorChanged: buildInterface()
|
||||
Component.onCompleted: buildInterface()
|
||||
|
||||
header: GuhHeader {
|
||||
id: header
|
||||
onBackPressed: root.backPressed();
|
||||
|
||||
property bool interfacesMode: root.stateDescriptor && root.stateDescriptor.interfaceName && root.stateDescriptor.interfaceName.length > 0
|
||||
onInterfacesModeChanged: root.buildInterface()
|
||||
|
||||
HeaderButton {
|
||||
imageSource: header.interfacesMode ? "../images/view-expand.svg" : "../images/view-collapse.svg"
|
||||
visible: root.stateDescriptor && root.stateDescriptor.interfaceName.length === 0
|
||||
onClicked: header.interfacesMode = !header.interfacesMode
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: generatedModel
|
||||
ListElement { displayName: ""; stateTypeId: "" }
|
||||
}
|
||||
|
||||
function buildInterface() {
|
||||
print("building interface:", header.interfacesMode, root.stateDescriptor, root.stateDescriptor.interfaceName)
|
||||
if (header.interfacesMode) {
|
||||
if (root.device) {
|
||||
generatedModel.clear();
|
||||
for (var i = 0; i < Interfaces.count; i++) {
|
||||
var iface = Interfaces.get(i);
|
||||
if (root.deviceClass.interfaces.indexOf(iface.name) >= 0) {
|
||||
print("root has device class:", iface.name, iface.stateTypes.count)
|
||||
for (var j = 0; j < iface.stateTypes.count; j++) {
|
||||
var ifaceSt = iface.stateTypes.get(j);
|
||||
print("ifaceSt:", ifaceSt, j, iface.stateTypes.count)
|
||||
var dcSt = root.deviceClass.stateTypes.findByName(ifaceSt.name)
|
||||
print("adding:", ifaceSt.displayName, dcSt.id)
|
||||
generatedModel.append({displayName: ifaceSt.displayName, stateTypeId: dcSt.id})
|
||||
}
|
||||
}
|
||||
}
|
||||
listView.model = generatedModel
|
||||
} else if (root.stateDescriptor.interfaceName !== "") {
|
||||
listView.model = Interfaces.findByName(root.stateDescriptor.interfaceName).stateTypes
|
||||
} else {
|
||||
console.warn("You need to set device or interfaceName");
|
||||
}
|
||||
} else {
|
||||
if (root.device) {
|
||||
listView.model = deviceClass.stateTypes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
anchors.fill: parent
|
||||
model: root.deviceClass.stateTypes
|
||||
|
||||
delegate: ItemDelegate {
|
||||
text: model.displayName
|
||||
width: parent.width
|
||||
onClicked: {
|
||||
var stateType = root.deviceClass.stateTypes.getStateType(model.id);
|
||||
console.log("StateType", stateType.id, "selected.")
|
||||
root.stateDescriptor.stateTypeId = stateType.id;
|
||||
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectStateDescriptorParamsPage.qml"), {stateDescriptor: root.stateDescriptor})
|
||||
paramsPage.onBackPressed.connect(function() { pageStack.pop(); });
|
||||
paramsPage.onCompleted.connect(function() {
|
||||
pageStack.pop();
|
||||
root.done();
|
||||
})
|
||||
if (header.interfacesMode) {
|
||||
if (root.device) {
|
||||
print("selected:", model.stateTypeId)
|
||||
root.stateDescriptor.stateTypeId = model.stateTypeId;
|
||||
var stateType = root.deviceClass.stateTypes.getStateType(model.stateTypeId)
|
||||
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectStateDescriptorParamsPage.qml"), {stateDescriptor: root.stateDescriptor})
|
||||
paramsPage.onBackPressed.connect(function() {pageStack.pop()});
|
||||
paramsPage.onCompleted.connect(function() {
|
||||
pageStack.pop();
|
||||
root.done();
|
||||
})
|
||||
} else if (root.stateDescriptor.interfaceName !== "") {
|
||||
root.stateDescriptor.interfaceState = model.name;
|
||||
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectStateDescriptorParamsPage.qml"), {stateDescriptor: root.stateDescriptor})
|
||||
paramsPage.onBackPressed.connect(function() {pageStack.pop()});
|
||||
paramsPage.onCompleted.connect(function() {
|
||||
pageStack.pop();
|
||||
root.done();
|
||||
})
|
||||
} else {
|
||||
console.warn("Neither deviceId not interfaceName set. Cannot continue...");
|
||||
}
|
||||
} else {
|
||||
if (root.device) {
|
||||
var stateType = root.deviceClass.stateTypes.getStateType(model.id);
|
||||
root.stateDescriptor.stateTypeId = model.id;
|
||||
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectStateDescriptorParamsPage.qml"), {stateDescriptor: root.stateDescriptor})
|
||||
paramsPage.onBackPressed.connect(function() {pageStack.pop()});
|
||||
paramsPage.onCompleted.connect(function() {
|
||||
pageStack.pop();
|
||||
root.done();
|
||||
})
|
||||
|
||||
print("have type", stateType.id)
|
||||
} else {
|
||||
console.warn("FIXME: not implemented yet");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,13 +11,15 @@ Page {
|
||||
property var stateDescriptor: null
|
||||
|
||||
readonly property var device: stateDescriptor && stateDescriptor.deviceId ? Engine.deviceManager.devices.getDevice(stateDescriptor.deviceId) : null
|
||||
readonly property var stateType: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId).stateTypes.getStateType(stateDescriptor.stateTypeId) : null
|
||||
readonly property var iface: stateDescriptor && stateDescriptor.interfaceName ? Interfaces.findByName(stateDescriptor.interfaceName) : null
|
||||
readonly property var stateType: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId).stateTypes.getStateType(stateDescriptor.stateTypeId)
|
||||
: iface ? iface.stateTypes.findByName(stateDescriptor.interfaceState) : null
|
||||
|
||||
signal backPressed();
|
||||
signal completed();
|
||||
|
||||
header: GuhHeader {
|
||||
text: qsTr("params")
|
||||
text: qsTr("Options")
|
||||
onBackPressed: root.backPressed();
|
||||
}
|
||||
|
||||
|
||||
@ -8,45 +8,41 @@ import Mea 1.0
|
||||
Page {
|
||||
id: root
|
||||
|
||||
property bool selectInterface: false
|
||||
signal backPressed();
|
||||
signal thingSelected(var device);
|
||||
signal interfaceSelected(string interfaceName);
|
||||
property alias showEvents: interfacesProxy.showEvents
|
||||
property alias showActions: interfacesProxy.showActions
|
||||
property alias showStates: interfacesProxy.showStates
|
||||
|
||||
header: GuhHeader {
|
||||
text: qsTr("Select a thing")
|
||||
text: root.selectInterface ? qsTr("Select a kind of things") : qsTr("Select a thing")
|
||||
onBackPressed: root.backPressed()
|
||||
}
|
||||
|
||||
InterfacesProxy {
|
||||
id: interfacesProxy
|
||||
devicesFilter: Engine.deviceManager.devices
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
// TODO: unfinished, disabled for now
|
||||
visible: false
|
||||
RadioButton {
|
||||
id: thingButton
|
||||
text: qsTr("A specific thing")
|
||||
checked: true
|
||||
}
|
||||
RadioButton {
|
||||
id: interfacesButton
|
||||
text: qsTr("A group of things")
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
model: thingButton.checked ? Engine.deviceManager.devices : Interfaces
|
||||
model: root.selectInterface ? interfacesProxy : Engine.deviceManager.devices
|
||||
clip: true
|
||||
delegate: ThingDelegate {
|
||||
name: thingButton.checked ? model.name : model.displayName
|
||||
interfaces: model.interfaces
|
||||
delegate: MeaListItemDelegate {
|
||||
width: parent.width
|
||||
text: root.selectInterface ? model.displayName : model.name
|
||||
iconName: root.selectInterface ? app.interfaceToIcon(model.name) : app.interfacesToIcon(model.interfaces)
|
||||
onClicked: {
|
||||
if (thingButton.checked) {
|
||||
root.thingSelected(Engine.deviceManager.devices.get(index))
|
||||
if (root.selectInterface) {
|
||||
root.interfaceSelected(interfacesProxy.get(index).name)
|
||||
} else {
|
||||
root.interfaceSelected(Interfaces.get(index).name)
|
||||
root.thingSelected(Engine.deviceManager.devices.get(index))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,17 +2,23 @@ import QtQuick 2.8
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.2
|
||||
import Mea 1.0
|
||||
import "../components"
|
||||
|
||||
SwipeDelegate {
|
||||
id: root
|
||||
Layout.fillWidth: true
|
||||
clip: true
|
||||
|
||||
property var stateEvaluator: null
|
||||
property bool showChilds: false
|
||||
|
||||
readonly property var device: stateEvaluator ? Engine.deviceManager.devices.getDevice(stateEvaluator.stateDescriptor.deviceId) : null
|
||||
readonly property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
readonly property var stateType: deviceClass ? deviceClass.stateTypes.getStateType(stateEvaluator.stateDescriptor.stateTypeId) : null
|
||||
readonly property var iface: stateEvaluator ? Interfaces.findByName(stateEvaluator.stateDescriptor.interfaceName) : null
|
||||
readonly property var stateType: deviceClass ? deviceClass.stateTypes.getStateType(stateEvaluator.stateDescriptor.stateTypeId)
|
||||
: iface ? iface.stateTypes.findByName(stateEvaluator.stateDescriptor.interfaceState) : null
|
||||
|
||||
signal deleteClicked();
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
@ -22,49 +28,24 @@ SwipeDelegate {
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
Label {
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
property string operatorString: {
|
||||
if (!root.stateEvaluator) {
|
||||
return "";
|
||||
}
|
||||
|
||||
switch (root.stateEvaluator.stateDescriptor.valueOperator) {
|
||||
case StateDescriptor.ValueOperatorEquals:
|
||||
return "=";
|
||||
case StateDescriptor.ValueOperatorNotEquals:
|
||||
return "!=";
|
||||
case StateDescriptor.ValueOperatorGreater:
|
||||
return ">";
|
||||
case StateDescriptor.ValueOperatorGreaterOrEqual:
|
||||
return ">=";
|
||||
case StateDescriptor.ValueOperatorLess:
|
||||
return "<";
|
||||
case StateDescriptor.ValueOperatorLessOrEqual:
|
||||
return "<=";
|
||||
}
|
||||
return "FIXME"
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: childEvaluatorsRepeater.count > 0 ? app.iconSize * .6 : app.iconSize
|
||||
Layout.preferredWidth: height
|
||||
name: root.stateEvaluator.stateDescriptor.interfaceName.length === 0 ? "../images/state.svg" : "../images/state-interface.svg"
|
||||
color: app.guhAccent
|
||||
}
|
||||
|
||||
text: {
|
||||
if (!root.device) {
|
||||
return qsTr("Press to edit condition")
|
||||
}
|
||||
return qsTr("%1: %2 %3 %4").arg(root.device.name).arg(root.stateType.displayName).arg(operatorString).arg(root.stateEvaluator.stateDescriptor.value)
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
model: root.showChilds ? root.stateEvaluator.childEvaluators : null
|
||||
delegate: Label {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
property var stateEvaluator: root.stateEvaluator.childEvaluators.get(index)
|
||||
property var stateDescriptor: stateEvaluator.stateDescriptor
|
||||
readonly property var device: Engine.deviceManager.devices.getDevice(stateDescriptor.deviceId)
|
||||
readonly property var deviceClass: Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId)
|
||||
readonly property var stateType: deviceClass.stateTypes.getStateType(stateDescriptor.stateTypeId)
|
||||
|
||||
font.pixelSize: childEvaluatorsRepeater.count > 0 ? app.smallFont : app.mediumFont
|
||||
property string operatorString: {
|
||||
switch (stateDescriptor.valueOperator) {
|
||||
if (!root.stateEvaluator) {
|
||||
return "";
|
||||
}
|
||||
|
||||
switch (root.stateEvaluator.stateDescriptor.valueOperator) {
|
||||
case StateDescriptor.ValueOperatorEquals:
|
||||
return "=";
|
||||
case StateDescriptor.ValueOperatorNotEquals:
|
||||
@ -80,8 +61,90 @@ SwipeDelegate {
|
||||
}
|
||||
return "FIXME"
|
||||
}
|
||||
text: qsTr("%1 %2: %3 %4 %5%6").arg(root.stateEvaluator.stateOperator === StateEvaluator.StateOperatorAnd ? "and" : "or").arg(device.name).arg(stateType.displayName).arg(operatorString).arg(stateDescriptor.value).arg(stateEvaluator.childEvaluators.count > 0 ? "..." : "")
|
||||
|
||||
text: {
|
||||
if (!root.stateType) {
|
||||
return qsTr("Press to edit condition")
|
||||
}
|
||||
if (root.device) {
|
||||
return qsTr("%1: %2 %3 %4").arg(root.device.name).arg(root.stateType.displayName).arg(operatorString).arg(root.stateEvaluator.stateDescriptor.value)
|
||||
} else if (root.iface) {
|
||||
return qsTr("%1: %2 %3 %4").arg(root.iface.displayName).arg(root.stateType.displayName).arg(operatorString).arg(root.stateEvaluator.stateDescriptor.value)
|
||||
}
|
||||
return "--";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: childEvaluatorsRepeater
|
||||
model: root.showChilds ? root.stateEvaluator.childEvaluators : null
|
||||
delegate: RowLayout {
|
||||
id: childEvaluatorDelegate
|
||||
Layout.fillWidth: true
|
||||
|
||||
property var stateEvaluator: root.stateEvaluator.childEvaluators.get(index)
|
||||
property var stateDescriptor: stateEvaluator.stateDescriptor
|
||||
readonly property var device: Engine.deviceManager.devices.getDevice(stateDescriptor.deviceId)
|
||||
readonly property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
readonly property var iface: Interfaces.findByName(stateEvaluator.stateDescriptor.interfaceName)
|
||||
readonly property var stateType: device ? deviceClass.stateTypes.getStateType(stateDescriptor.stateTypeId)
|
||||
: iface ? iface.stateTypes.findByName(stateEvaluator.stateDescriptor.interfaceState)
|
||||
: null
|
||||
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: app.iconSize * .6
|
||||
Layout.preferredWidth: height
|
||||
name: childEvaluatorDelegate.stateDescriptor.interfaceName.length === 0 ? "../images/state.svg" : "../images/state-interface.svg"
|
||||
color: app.guhAccent
|
||||
}
|
||||
Label {
|
||||
font.pixelSize: app.smallFont
|
||||
Layout.fillWidth: true
|
||||
|
||||
property string operatorString: {
|
||||
switch (childEvaluatorDelegate.stateDescriptor.valueOperator) {
|
||||
case StateDescriptor.ValueOperatorEquals:
|
||||
return "=";
|
||||
case StateDescriptor.ValueOperatorNotEquals:
|
||||
return "!=";
|
||||
case StateDescriptor.ValueOperatorGreater:
|
||||
return ">";
|
||||
case StateDescriptor.ValueOperatorGreaterOrEqual:
|
||||
return ">=";
|
||||
case StateDescriptor.ValueOperatorLess:
|
||||
return "<";
|
||||
case StateDescriptor.ValueOperatorLessOrEqual:
|
||||
return "<=";
|
||||
}
|
||||
return "FIXME"
|
||||
}
|
||||
text: device ? ("%1 %2: %3 %4 %5%6").arg(root.stateEvaluator.stateOperator === StateEvaluator.StateOperatorAnd ? "and" : "or").arg(childEvaluatorDelegate.device.name).arg(childEvaluatorDelegate.stateType.displayName).arg(operatorString).arg(childEvaluatorDelegate.stateDescriptor.value).arg(childEvaluatorDelegate.stateEvaluator.childEvaluators.count > 0 ? "..." : "")
|
||||
: iface ? ("%1 %2: %3 %4 %5%6").arg(root.stateEvaluator.stateOperator === StateEvaluator.StateOperatorAnd ? "and" : "or").arg(childEvaluatorDelegate.iface.displayName).arg(childEvaluatorDelegate.stateType.displayName).arg(operatorString).arg(childEvaluatorDelegate.stateDescriptor.value).arg(childEvaluatorDelegate.stateEvaluator.childEvaluators.count > 0 ? "..." : "")
|
||||
: "???"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
swipe.right: MouseArea {
|
||||
height: parent.height
|
||||
width: height
|
||||
anchors.right: parent.right
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "red"
|
||||
}
|
||||
|
||||
ColorIcon {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins
|
||||
name: "../images/delete.svg"
|
||||
color: "white"
|
||||
}
|
||||
onClicked: {
|
||||
swipe.close()
|
||||
root.deleteClicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,9 @@ import QtQuick 2.8
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.2
|
||||
import Mea 1.0
|
||||
import "../components"
|
||||
|
||||
SwipeDelegate {
|
||||
ItemDelegate {
|
||||
|
||||
id: root
|
||||
property var stateEvaluator: null
|
||||
@ -11,19 +12,54 @@ SwipeDelegate {
|
||||
readonly property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
readonly property var stateType: deviceClass ? deviceClass.stateTypes.getStateType(stateEvaluator.stateDescriptor.stateTypeId) : null
|
||||
|
||||
property bool canDelete: true
|
||||
signal deleteClicked()
|
||||
|
||||
function editStateDescriptor(interfaceMode) {
|
||||
if (interfaceMode === undefined) {
|
||||
interfaceMode = false;
|
||||
}
|
||||
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {selectInterface: interfaceMode, showStates: true});
|
||||
page.backPressed.connect(function() {
|
||||
pageStack.pop()
|
||||
})
|
||||
page.thingSelected.connect(function(device) {
|
||||
root.stateEvaluator.stateDescriptor.interfaceName = "";
|
||||
root.stateEvaluator.stateDescriptor.deviceId = device.id;
|
||||
selectStateDescriptorData()
|
||||
});
|
||||
page.interfaceSelected.connect(function(interfaceName) {
|
||||
root.stateEvaluator.stateDescriptor.deviceId = "";
|
||||
root.stateEvaluator.stateDescriptor.interfaceName = interfaceName;
|
||||
selectStateDescriptorData();
|
||||
});
|
||||
}
|
||||
function editInterfaceStateDescriptor() {
|
||||
editStateDescriptor(true)
|
||||
}
|
||||
function selectStateDescriptorData() {
|
||||
var statePage = pageStack.push(Qt.resolvedUrl("SelectStateDescriptorPage.qml"), {text: "Select state", stateDescriptor: root.stateEvaluator.stateDescriptor})
|
||||
statePage.backPressed.connect(function() {
|
||||
pageStack.pop();
|
||||
})
|
||||
statePage.done.connect(function() {
|
||||
pageStack.pop();
|
||||
pageStack.pop();
|
||||
pageStack.pop();
|
||||
})
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
SimpleStateEvaluatorDelegate {
|
||||
Layout.fillWidth: true
|
||||
stateEvaluator: root.stateEvaluator
|
||||
swipe.enabled: root.canDelete
|
||||
onClicked: {
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"));
|
||||
page.backPressed.connect(function() {pageStack.pop()})
|
||||
page.thingSelected.connect(function(device) {
|
||||
root.stateEvaluator.stateDescriptor.deviceId = device.id
|
||||
var statePage = pageStack.push(Qt.resolvedUrl("SelectStateDescriptorPage.qml"), {text: "Select state", stateDescriptor: root.stateEvaluator.stateDescriptor})
|
||||
statePage.backPressed.connect(function() {pageStack.pop()})
|
||||
statePage.done.connect(function() {pageStack.pop(); pageStack.pop()})
|
||||
})
|
||||
var page = pageStack.push(stateQuestionPageComponent);
|
||||
}
|
||||
onDeleteClicked: {
|
||||
root.deleteClicked()
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,6 +82,9 @@ SwipeDelegate {
|
||||
onClicked: {
|
||||
pageStack.push(Qt.resolvedUrl("EditStateEvaluatorPage.qml"), {stateEvaluator: stateEvaluator})
|
||||
}
|
||||
onDeleteClicked: {
|
||||
root.stateEvaluator.childEvaluators.remove(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,7 +93,48 @@ SwipeDelegate {
|
||||
text: qsTr("Add a condition")
|
||||
onClicked: {
|
||||
root.stateEvaluator.addChildEvaluator()
|
||||
// root.editStateEvaluator()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: stateQuestionPageComponent
|
||||
Page {
|
||||
header: GuhHeader {
|
||||
text: qsTr("Edit condition...")
|
||||
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
Repeater {
|
||||
model: ListModel {
|
||||
ListElement {
|
||||
iconName: "../images/state.svg"
|
||||
text: qsTr("When one of my things is in a certain state")
|
||||
method: "editStateDescriptor"
|
||||
|
||||
}
|
||||
ListElement {
|
||||
iconName: "../images/state-interface.svg"
|
||||
text: qsTr("When a thing of a given type enters a state")
|
||||
method: "editInterfaceStateDescriptor"
|
||||
}
|
||||
}
|
||||
delegate: MeaListItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
iconName: model.iconName
|
||||
text: model.text
|
||||
progressive: true
|
||||
iconSize: app.iconSize * 2
|
||||
|
||||
onClicked: {
|
||||
root[model.method]()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,9 +4,11 @@ import QtQuick.Layouts 1.3
|
||||
import Mea 1.0
|
||||
import "../components"
|
||||
|
||||
SwipeDelegate {
|
||||
MeaListItemDelegate{
|
||||
id: root
|
||||
implicitHeight: app.delegateHeight
|
||||
progressive: false
|
||||
canDelete: true
|
||||
|
||||
property var timeEventItem: null
|
||||
|
||||
@ -15,88 +17,7 @@ SwipeDelegate {
|
||||
|
||||
signal removeTimeEventItem();
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: app.margins
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: app.iconSize
|
||||
Layout.preferredWidth: app.iconSize
|
||||
name: "../images/alarm-clock.svg"
|
||||
color: app.guhAccent
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
text: qsTr("At %1").arg(root.isDateBased ? Qt.formatDateTime(root.timeEventItem.dateTime) : Qt.formatTime(root.timeEventItem.time))
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("repeated %1").arg(repeatingString)
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: app.smallFont
|
||||
|
||||
property string repeatingString: {
|
||||
switch (root.timeEventItem.repeatingOption.repeatingMode) {
|
||||
case RepeatingOption.RepeatingModeNone:
|
||||
return qsTr("never");
|
||||
case RepeatingOption.RepeatingModeHourly:
|
||||
return qsTr("hourly");
|
||||
case RepeatingOption.RepeatingModeDaily:
|
||||
return qsTr("daily");
|
||||
case RepeatingOption.RepeatingModeWeekly:
|
||||
var weekdays = []
|
||||
for (var i = 0; i < root.timeEventItem.repeatingOption.weekDays.length; i++) {
|
||||
switch (root.timeEventItem.repeatingOption.weekDays[i]) {
|
||||
case 1:
|
||||
weekdays.push(qsTr("Mon"));
|
||||
break;
|
||||
case 2:
|
||||
weekdays.push(qsTr("Tue"));
|
||||
break;
|
||||
case 3:
|
||||
weekdays.push(qsTr("Wed"));
|
||||
break;
|
||||
case 4:
|
||||
weekdays.push(qsTr("Thu"));
|
||||
break;
|
||||
case 5:
|
||||
weekdays.push(qsTr("Fri"));
|
||||
break;
|
||||
case 6:
|
||||
weekdays.push(qsTr("Sat"));
|
||||
break;
|
||||
case 7:
|
||||
weekdays.push(qsTr("Sun"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return qsTr("weekly on %1").arg(weekdays.join(', '));
|
||||
case RepeatingOption.RepeatingModeMonthly:
|
||||
return qsTr("monthly on the %1").arg(root.timeEventItem.repeatingOption.monthDays.join(', '));
|
||||
case RepeatingOption.RepeatingModeYearly:
|
||||
return qsTr("every year");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
swipe.right: MouseArea {
|
||||
height: root.height
|
||||
width: height
|
||||
anchors.right: parent.right
|
||||
ColorIcon {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins
|
||||
name: "../images/delete.svg"
|
||||
color: "red"
|
||||
}
|
||||
onClicked: root.removeTimeEventItem()
|
||||
}
|
||||
onDeleteClicked: root.removeTimeEventItem()
|
||||
|
||||
onClicked: {
|
||||
var page = pageStack.push(Qt.resolvedUrl("EditTimeEventItemPage.qml"), {timeEventItem: root.timeEventItem})
|
||||
@ -106,4 +27,52 @@ SwipeDelegate {
|
||||
print("timeeventItem.time is now", root.timeEventItem.time)
|
||||
})
|
||||
}
|
||||
|
||||
iconName: "../images/alarm-clock.svg"
|
||||
text: qsTr("At %1").arg(root.isDateBased ? Qt.formatDateTime(root.timeEventItem.dateTime) : Qt.formatTime(root.timeEventItem.time))
|
||||
subText: qsTr("repeated %1").arg(repeatingString)
|
||||
|
||||
property string repeatingString: {
|
||||
switch (root.timeEventItem.repeatingOption.repeatingMode) {
|
||||
case RepeatingOption.RepeatingModeNone:
|
||||
return qsTr("never");
|
||||
case RepeatingOption.RepeatingModeHourly:
|
||||
return qsTr("hourly");
|
||||
case RepeatingOption.RepeatingModeDaily:
|
||||
return qsTr("daily");
|
||||
case RepeatingOption.RepeatingModeWeekly:
|
||||
var weekdays = []
|
||||
for (var i = 0; i < root.timeEventItem.repeatingOption.weekDays.length; i++) {
|
||||
switch (root.timeEventItem.repeatingOption.weekDays[i]) {
|
||||
case 1:
|
||||
weekdays.push(qsTr("Mon"));
|
||||
break;
|
||||
case 2:
|
||||
weekdays.push(qsTr("Tue"));
|
||||
break;
|
||||
case 3:
|
||||
weekdays.push(qsTr("Wed"));
|
||||
break;
|
||||
case 4:
|
||||
weekdays.push(qsTr("Thu"));
|
||||
break;
|
||||
case 5:
|
||||
weekdays.push(qsTr("Fri"));
|
||||
break;
|
||||
case 6:
|
||||
weekdays.push(qsTr("Sat"));
|
||||
break;
|
||||
case 7:
|
||||
weekdays.push(qsTr("Sun"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return qsTr("weekly on %1").arg(weekdays.join(', '));
|
||||
case RepeatingOption.RepeatingModeMonthly:
|
||||
return qsTr("monthly on the %1").arg(root.timeEventItem.repeatingOption.monthDays.join(', '));
|
||||
case RepeatingOption.RepeatingModeYearly:
|
||||
return qsTr("every year");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
39
mea/ui/system/AboutNymeaPage.qml
Normal file
39
mea/ui/system/AboutNymeaPage.qml
Normal file
@ -0,0 +1,39 @@
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import Mea 1.0
|
||||
import "../components"
|
||||
|
||||
Page {
|
||||
|
||||
id: root
|
||||
header: GuhHeader {
|
||||
text: qsTr("About %1").arg(app.systemName)
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors { left: parent.left; top: parent.top; right: parent.right }
|
||||
|
||||
MeaListItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Server UUID:")
|
||||
subText: Engine.jsonRpcClient.serverUuid
|
||||
progressive: false
|
||||
}
|
||||
|
||||
MeaListItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Server version:")
|
||||
subText: Engine.jsonRpcClient.serverVersion
|
||||
progressive: false
|
||||
}
|
||||
|
||||
MeaListItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Protocol version:")
|
||||
subText: Engine.jsonRpcClient.jsonRpcVersion
|
||||
progressive: false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -18,21 +18,11 @@ Page {
|
||||
model: Engine.deviceManager.plugins
|
||||
clip: true
|
||||
|
||||
delegate: ItemDelegate {
|
||||
delegate: MeaListItemDelegate {
|
||||
width: parent.width
|
||||
contentItem: RowLayout {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: model.name
|
||||
}
|
||||
Image {
|
||||
source: "../images/next.svg"
|
||||
Layout.preferredHeight: parent.height
|
||||
Layout.preferredWidth: height
|
||||
}
|
||||
}
|
||||
iconName: "../images/plugin.svg"
|
||||
text: model.name
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("PluginParamsPage.qml"), {plugin: Engine.deviceManager.plugins.get(index)})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user