moar work on it

This commit is contained in:
Michael Zanetti 2018-04-18 09:17:48 +02:00
parent f89b68973e
commit 3283a80018
25 changed files with 1027 additions and 234 deletions

View File

@ -33,7 +33,7 @@ public:
QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
ParamDescriptor* get(int index) const;
Q_INVOKABLE ParamDescriptor* get(int index) const;
ParamDescriptor* createNewParamDescriptor() const;
void addParamDescriptor(ParamDescriptor* paramDescriptor);

View File

@ -40,6 +40,7 @@ void DevicesProxy::setDevices(Devices *devices)
m_devices = devices;
setSourceModel(devices);
sort(0);
connect(devices, &Devices::countChanged, this, &DevicesProxy::countChanged);
emit devicesChanged();
emit countChanged();
}
@ -104,119 +105,3 @@ bool DevicesProxy::filterAcceptsRow(int source_row, const QModelIndex &source_pa
}
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}
DevicesBasicTagsModel::DevicesBasicTagsModel(QObject *parent):
QAbstractListModel(parent)
{
}
int DevicesBasicTagsModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_tags.count();
}
QVariant DevicesBasicTagsModel::data(const QModelIndex &index, int role) const
{
switch (role) {
case RoleTag:
return m_tags.at(index.row());
case RoleTagLabel:
return DeviceClass::basicTagToString(m_tags.at(index.row()));
}
return QVariant();
}
QHash<int, QByteArray> DevicesBasicTagsModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles.insert(RoleTag, "tag");
roles.insert(RoleTagLabel, "tagLabel");
return roles;
}
Devices *DevicesBasicTagsModel::devices() const
{
return m_devices;
}
void DevicesBasicTagsModel::setDevices(Devices *devices)
{
if (m_devices != devices) {
m_devices = devices;
syncTags();
connect(devices, &Devices::rowsInserted, this, &DevicesBasicTagsModel::rowsChanged);
connect(devices, &Devices::rowsRemoved, this, &DevicesBasicTagsModel::rowsChanged);
}
}
bool DevicesBasicTagsModel::hideSystemTags() const
{
return m_hideSystemTags;
}
void DevicesBasicTagsModel::setHideSystemTags(bool hideSystemTags)
{
if (m_hideSystemTags != hideSystemTags) {
m_hideSystemTags = hideSystemTags;
emit hideSystemTagsChanged();
syncTags();
}
}
QString DevicesBasicTagsModel::basicTagToString(DeviceClass::BasicTag basicTag) const
{
return DeviceClass::basicTagToString(basicTag);
}
void DevicesBasicTagsModel::rowsChanged(const QModelIndex &index, int first, int last)
{
Q_UNUSED(index)
Q_UNUSED(first)
Q_UNUSED(last)
syncTags();
}
void DevicesBasicTagsModel::syncTags()
{
if (!m_devices) {
return;
}
QList<DeviceClass::BasicTag> tagsInSource;
for (int i = 0; i < m_devices->rowCount(); i++) {
DeviceClass *dc = Engine::instance()->deviceManager()->deviceClasses()->getDeviceClass(m_devices->get(i)->deviceClassId());
foreach (DeviceClass::BasicTag tag, dc->basicTags()) {
if (!tagsInSource.contains(tag)) {
tagsInSource.append(tag);
}
}
}
QList<DeviceClass::BasicTag> tagsToAdd = tagsInSource;
if (m_hideSystemTags) {
tagsToAdd.removeAll(DeviceClass::BasicTagActuator);
tagsToAdd.removeAll(DeviceClass::BasicTagDevice);
tagsToAdd.removeAll(DeviceClass::BasicTagService);
}
for (QList<DeviceClass::BasicTag>::iterator i = m_tags.begin(); i != m_tags.end();) {
if (!tagsInSource.contains(*i)) {
int idx = m_tags.indexOf(*i);
beginRemoveRows(QModelIndex(), idx, idx);
m_tags.takeAt(idx);
endRemoveRows();
continue;
}
tagsToAdd.removeAll(*i);
++i;
}
if (!tagsToAdd.isEmpty()) {
beginInsertRows(QModelIndex(), m_tags.count(), m_tags.count() + tagsToAdd.count() - 1);
m_tags.append(tagsToAdd);
endInsertRows();
}
}

View File

@ -29,45 +29,6 @@
#include "devices.h"
class DevicesBasicTagsModel: public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(Devices* devices READ devices WRITE setDevices NOTIFY devicesChanged)
Q_PROPERTY(bool hideSystemTags READ hideSystemTags WRITE setHideSystemTags NOTIFY hideSystemTagsChanged)
public:
enum Roles {
RoleTag,
RoleTagLabel
};
DevicesBasicTagsModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
Devices* devices() const;
void setDevices(Devices *devices);
bool hideSystemTags() const;
void setHideSystemTags(bool hideSystemTags);
Q_INVOKABLE QString basicTagToString(DeviceClass::BasicTag basicTag) const;
signals:
void devicesChanged();
void hideSystemTagsChanged();
private:
void rowsChanged(const QModelIndex &index, int first, int last);
void syncTags();
private:
Devices* m_devices = nullptr;
QList<DeviceClass::BasicTag> m_tags;
bool m_hideSystemTags = false;
};
class DevicesProxy : public QSortFilterProxyModel
{
Q_OBJECT

View File

@ -309,7 +309,7 @@ void JsonRpcClient::dataReceived(const QByteArray &data)
int commandId = dataMap.value("id").toInt();
JsonRpcReply *reply = m_replies.take(commandId);
if (reply) {
qDebug() << QString("JsonRpc: got response for %1.%2: %3").arg(reply->nameSpace(), reply->method(), QString::fromUtf8(jsonDoc.toJson(QJsonDocument::Indented))) << reply->callback() << reply->callback();
// qDebug() << QString("JsonRpc: got response for %1.%2: %3").arg(reply->nameSpace(), reply->method(), QString::fromUtf8(jsonDoc.toJson(QJsonDocument::Indented))) << reply->callback() << reply->callback();
if (dataMap.value("status").toString() == "unauthorized") {
qWarning() << "Something's off with the token";

View File

@ -115,7 +115,6 @@ int main(int argc, char *argv[])
qmlRegisterUncreatableType<Device>(uri, 1, 0, "Device", "Can't create this in QML. Get it from the Devices.");
qmlRegisterUncreatableType<Devices>(uri, 1, 0, "Devices", "Can't create this in QML. Get it from the DeviceManager.");
qmlRegisterType<DevicesProxy>(uri, 1, 0, "DevicesProxy");
qmlRegisterType<DevicesBasicTagsModel>(uri, 1, 0, "DevicesBasicTagsModel");
qmlRegisterType<InterfacesModel>(uri, 1, 0, "InterfacesModel");
qmlRegisterUncreatableType<DeviceClass>(uri, 1, 0, "DeviceClass", "Can't create this in QML. Get it from the DeviceClasses.");

View File

@ -187,11 +187,19 @@ void LogsModel::newLogEntryReceived(const QVariantMap &data)
return;
}
beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
QVariantMap entryMap = data;
QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong());
QString deviceId = entryMap.value("deviceId").toString();
if (!m_deviceId.isNull() && deviceId != m_deviceId) {
return;
}
QString typeId = entryMap.value("typeId").toString();
if (!m_typeId.isNull() && typeId != m_typeId) {
return;
}
beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong());
QMetaEnum sourceEnum = QMetaEnum::fromType<LogEntry::LoggingSource>();
LogEntry::LoggingSource loggingSource = (LogEntry::LoggingSource)sourceEnum.keyToValue(entryMap.value("source").toByteArray());
QMetaEnum loggingEventTypeEnum = QMetaEnum::fromType<LogEntry::LoggingEventType>();

View File

@ -26,6 +26,7 @@ void RulesFilterModel::setRules(Rules *rules)
setSourceModel(rules);
emit rulesChanged();
invalidateFilter();
emit countChanged();
}
}
@ -40,6 +41,7 @@ void RulesFilterModel::setFilterDeviceId(const QString &filterDeviceId)
m_filterDeviceId = filterDeviceId;
emit filterDeviceIdChanged();
invalidateFilter();
emit countChanged();
}
}

View File

@ -10,6 +10,7 @@ class Rule;
class RulesFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(Rules* rules READ rules WRITE setRules NOTIFY rulesChanged)
Q_PROPERTY(QString filterDeviceId READ filterDeviceId WRITE setFilterDeviceId NOTIFY filterDeviceIdChanged)
@ -27,6 +28,7 @@ public:
signals:
void rulesChanged();
void filterDeviceIdChanged();
void countChanged();
protected:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;

View File

@ -144,5 +144,11 @@
<file>ui/images/edit.svg</file>
<file>ui/PushButtonAuthPage.qml</file>
<file>ui/images/dialog-error-symbolic.svg</file>
<file>ui/images/send.svg</file>
<file>ui/images/mail-mark-important.svg</file>
<file>ui/devicepages/InputTriggerDevicePage.qml</file>
<file>ui/images/clock-app-symbolic.svg</file>
<file>ui/devicepages/StateLogPage.qml</file>
<file>ui/customviews/GenericTypeLogView.qml</file>
</qresource>
</RCC>

View File

@ -140,7 +140,7 @@ void RuleManager::getRuleDetailsReply(const QVariantMap &params)
qDebug() << "Got rule details for a rule we don't know";
return;
}
qDebug() << "got rule details for rule" << ruleMap;
// qDebug() << "got rule details for rule" << ruleMap;
parseEventDescriptors(ruleMap.value("eventDescriptors").toList(), rule);
parseRuleActions(ruleMap.value("actions").toList(), rule);
parseRuleExitActions(ruleMap.value("exitActions").toList(), rule);

View File

@ -1,59 +1,238 @@
import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Controls.Material 2.1
import QtQuick.Layouts 1.2
import Mea 1.0
import "components"
GridView {
id: interfacesGridView
Item {
id: root
property alias count: interfacesGridView.count
property alias model: interfacesGridView.model
property alias shownInterfaces: interfacesModel.shownInterfaces
property int tilesPerRow: Math.ceil(Math.sqrt(interfacesGridView.count))
GridView {
id: interfacesGridView
anchors.fill: parent
anchors.margins: app.margins / 2
model: InterfacesModel {
id: interfacesModel
devices: Engine.deviceManager.devices
}
cellWidth: width / tilesPerRow
cellHeight: height / tilesPerRow
delegate: Item {
width: interfacesGridView.cellWidth
height: interfacesGridView.cellHeight
Pane {
anchors.fill: parent
anchors.margins: app.margins
Material.elevation: 1
Column {
anchors.centerIn: parent
spacing: app.margins
ColorIcon {
height: app.iconSize * 2
width: height
color: app.guhAccent
anchors.horizontalCenter: parent.horizontalCenter
name: interfaceToIcon(model.name)
}
readonly property int minTileWidth: 180
readonly property int minTileHeight: 240
readonly property int tilesPerRow: root.width / minTileWidth
Label {
text: interfaceToString(model.name).toUpperCase()
anchors.horizontalCenter: parent.horizontalCenter
}
}
MouseArea {
model: InterfacesModel {
id: interfacesModel
devices: Engine.deviceManager.devices
}
cellWidth: width / tilesPerRow
cellHeight: Math.max(cellWidth, minTileHeight)
delegate: Item {
width: interfacesGridView.cellWidth
height: interfacesGridView.cellHeight
Pane {
anchors.fill: parent
onClicked: {
var page;
switch (model.name) {
case "light":
page = "LightsDeviceListPage.qml"
break;
default:
page = "GenericDeviceListPage.qml"
anchors.margins: app.margins / 2
Material.elevation: 1
Column {
width: parent.width
anchors.centerIn: parent
anchors.verticalCenterOffset: -app.iconSize
spacing: app.margins
ColorIcon {
height: app.iconSize * 2
width: height
color: app.guhAccent
anchors.horizontalCenter: parent.horizontalCenter
name: interfaceToIcon(model.name)
}
pageStack.push(Qt.resolvedUrl("devicelistpages/" + page), {filterInterface: model.name})
Label {
text: interfaceToString(model.name).toUpperCase()
width: parent.width
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
}
}
MouseArea {
anchors.fill: parent
onClicked: {
var page;
switch (model.name) {
case "light":
page = "LightsDeviceListPage.qml"
break;
default:
page = "GenericDeviceListPage.qml"
}
pageStack.push(Qt.resolvedUrl("devicelistpages/" + page), {filterInterface: model.name})
}
}
DevicesProxy {
id: devicesProxy
devices: Engine.deviceManager.devices
filterInterface: model.name
}
}
Item {
id: inlineControlPane
anchors { left: parent.left; bottom: parent.bottom; right: parent.right; margins: app.margins / 2 }
height: app.iconSize + app.margins * 2
Rectangle {
anchors.fill: parent
// color: app.guhAccent
color: "black"
opacity: .05
}
Loader {
id: inlineControlLoader
anchors {
fill: parent
leftMargin: app.margins
rightMargin: app.margins
topMargin: app.margins / 2
bottomMargin: app.margins / 2
}
sourceComponent: {
switch (model.name) {
case "sensor":
case "weather":
return labelComponent;
case "light":
case "media":
return buttonComponent
}
}
}
}
Component {
id: buttonComponent
MouseArea {
onClicked: {
switch (model.name) {
case "light":
for (var i = 0; i < devicesProxy.count; i++) {
var device = devicesProxy.get(i);
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
var actionType = deviceClass.actionTypes.findByName("power");
var params = [];
var param1 = {};
param1["paramTypeId"] = actionType.paramTypes.get(0).id;
param1["value"] = false;
params.push(param1)
Engine.deviceManager.executeAction(device.id, actionType.id, params)
}
break;
case "media":
var device = devicesProxy.get(0)
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
var stateType = deviceClass.stateTypes.findByName("playbackStatus");
var state = device.states.getState(stateType.id)
var actionName
switch (state.value) {
case "PLAYING":
actionName = "pause";
break;
case "PAUSED":
actionName = "play";
break;
}
var actionTypeId = deviceClass.actionTypes.findByName(actionName).id;
print("executing", device, device.id, actionTypeId, actionName, deviceClass.actionTypes)
Engine.deviceManager.executeAction(device.id, actionTypeId)
}
}
ColumnLayout {
anchors.fill: parent
Label {
id: label
Layout.fillWidth: true
text: {
switch (model.name) {
case "media":
return devicesProxy.get(0).name;
case "light":
var count = 0;
for (var i = 0; i < devicesProxy.count; i++) {
var device = devicesProxy.get(i);
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
var stateType = deviceClass.stateTypes.findByName("power")
if (device.states.getState(stateType.id).value === true) {
count++;
}
}
return count === 0 ? qsTr("All off") : qsTr("%1 on").arg(count)
}
}
font.pixelSize: app.smallFont
elide: Text.ElideRight
}
ColorIcon {
id: icon
width: app.largeFont
height: width
color: app.guhAccent
anchors.right: parent.right
name: {
switch (model.name) {
case "media":
var device = devicesProxy.get(0)
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
var stateType = deviceClass.stateTypes.findByName("playbackStatus");
var state = device.states.getState(stateType.id)
return state.value === "PLAYING" ? "../images/media-playback-pause.svg" :
state.value === "PAUSED" ? "../images/media-playback-start.svg" :
""
case "light":
return "../images/system-shutdown.svg"
}
}
}
}
}
}
Component {
id: labelComponent
ColumnLayout {
property var device: devicesProxy.get(0)
property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
property var state: deviceClass ? device.states.getState(deviceClass.stateTypes.findByName("temperature").id) : null
Label {
text: parent.device.name
font.pixelSize: app.smallFont
Layout.fillWidth: true
elide: Text.ElideRight
}
Label {
font.pixelSize: app.largeFont
color: app.guhAccent
Layout.fillWidth: true
horizontalAlignment: Text.AlignRight
text: {
if (devicesProxy.count > 0) {
var stateName;
// switch (model.name) {
// case "sensor":
// }
return parent.state.value + "°C";
}
}
}
}
}
}

View File

@ -58,7 +58,7 @@ Page {
InterfacesModel {
id: page2Model
devices: Engine.deviceManager.devices
shownInterfaces: ["gateway", "button", "notifications"]
shownInterfaces: ["gateway", "button", "notifications", "inputtrigger", "outputtrigger"]
property var view: null
onCountChanged: buildView()
}
@ -69,7 +69,6 @@ Page {
width: swipeView.width
height: swipeView.height
visible: count > 0
shownInterfaces: ["light", "weather", "sensor", "media", "garagegate"]
}
}

View File

@ -39,7 +39,8 @@ ItemDelegate {
if (paramType.allowedValues.length > 0) {
return comboBoxComponent;
}
return textFieldComponent;
return buttonComponent;
// return textFieldComponent;
case "color":
return colorPreviewComponent;
}
@ -78,8 +79,11 @@ ItemDelegate {
case "color":
return colorPickerComponent
case "string":
return paramType.allowedValues.length === 0 ? textFieldComponent : null
return paramType.allowedValues.length === 0 ? textFieldComponent :
root.actionType.paramTypes.count === 1 ? null : comboBoxComponent
}
console.warn("WARNING", root.actionType.paramTypes.get(index).name, "not implemented")
return null;
}
@ -170,6 +174,7 @@ ItemDelegate {
Component {
id: textFieldComponent
RowLayout {
id: textFieldRow
property alias value: textField.text
property var paramType: null
spacing: app.margins
@ -271,9 +276,11 @@ ItemDelegate {
text: "Do it"
onClicked: {
var params = [];
print("fooo", root.actionType.paramTypes.count)
for (var i = 0; i < root.actionType.paramTypes.count; i++) {
var param = new Object();
param["paramTypeId"] = root.actionType.paramTypes.get(i).id;
print("bla", paramRepeater.itemAt(i), root.actionType.paramTypes.get(i).name)
param["value"] = paramRepeater.itemAt(i).item.value;
params.push(param)
}

View File

@ -0,0 +1,110 @@
import QtQuick 2.5
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.1
import Mea 1.0
import "../components"
Item {
id: root
property var device: null
property alias typeId: logs.typeId
// %1 will be replaced with count
property string text
signal addRuleClicked(var value)
readonly property var deviceClass: Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId)
LogsModel {
id: logs
deviceId: root.device.id
live: true
Component.onCompleted: update()
}
ColumnLayout {
anchors.fill: parent
Label {
id: titleLabel
Layout.fillWidth: true
Layout.margins: app.margins
wrapMode: Text.WordWrap
text: root.text.arg(logs.count)
}
ThinDivider {}
RulesFilterModel {
id: rulesFilterModel
rules: Engine.ruleManager.rules
filterDeviceId: root.device.id
}
ListView {
Layout.fillWidth: true
Layout.fillHeight: true
model: logs
clip: true
delegate: ItemDelegate {
width: parent.width
contentItem: RowLayout {
ColumnLayout {
Layout.fillWidth: true
RowLayout {
Layout.fillWidth: true
ColorIcon {
Layout.preferredHeight: timeStampLabel.height
Layout.preferredWidth: height
name: "../images/clock-app-symbolic.svg"
}
Label {
id: timeStampLabel
Layout.fillWidth: true
text: Qt.formatDateTime(model.timestamp,"dd.MM.yy - hh:mm:ss")
}
}
RowLayout {
Layout.fillWidth: true
Label {
text: qsTr("Data:")
}
Label {
Layout.fillWidth: true
text: model.value.trim()
elide: Text.ElideRight
}
}
}
HeaderButton {
imageSource: "../images/magic.svg"
color: {
for (var i = 0; i < rulesFilterModel.count; i++) {
var rule = rulesFilterModel.get(i);
for (var j = 0; j < rule.eventDescriptors.count; j++) {
var eventDescriptor = rule.eventDescriptors.get(j);
if (eventDescriptor.eventTypeId === root.deviceClass.eventTypes.findByName("triggered").id) {
var matching = true;
for (var k = 0; k < eventDescriptor.paramDescriptors.count; k++) {
var paramDescriptor = eventDescriptor.paramDescriptors.get(k);
if (paramDescriptor.value == model.value) {
return app.guhAccent;
}
}
}
}
}
return keyColor;
}
onClicked: root.addRuleClicked(model.value)
}
}
}
}
}
}

View File

@ -6,7 +6,6 @@ import "../components"
Page {
id: subPage
property alias filterTag: devicesProxy.filterTag
property alias filterInterface: devicesProxy.filterInterface
Component.onCompleted: {
@ -17,9 +16,7 @@ Page {
header: GuhHeader {
text: {
if (subPage.filterTag != DeviceClass.BasicTagNone) {
return qsTr("My %1 things").arg(devicesBasicTagsModel.basicTagToString(subPage.filterTag))
} else if (subPage.filterInterface.length > 0) {
if (subPage.filterInterface.length > 0) {
return qsTr("My %1 things").arg(interfaceToString(subPage.filterInterface))
}
return qsTr("All my things")
@ -35,14 +32,16 @@ Page {
var device = devicesProxy.get(index);
var deviceClass = Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
var page;
/* if (deviceClass.interfaces.indexOf("media") >= 0) {
if (deviceClass.interfaces.indexOf("media") >= 0) {
page = "MediaDevicePage.qml";
} else */if (deviceClass.interfaces.indexOf("button") >= 0) {
} else if (deviceClass.interfaces.indexOf("button") >= 0) {
page = "ButtonDevicePage.qml";
} else if (deviceClass.interfaces.indexOf("weather") >= 0) {
page = "WeatherDevicePage.qml";
} else if (deviceClass.interfaces.indexOf("sensor") >= 0) {
page = "SensorDevicePage.qml";
} else if (deviceClass.interfaces.indexOf("inputtrigger") >= 0) {
page = "InputTriggerDevicePage.qml";
} else {
page = "GenericDevicePage.qml";
}

View File

@ -30,7 +30,7 @@ Page {
var params = [];
var param1 = {};
param1["paramTypeId"] = actionType.paramTypes.get(0).id;
param1["value"] = checked;
param1["value"] = false;
params.push(param1)
Engine.deviceManager.executeAction(device.id, actionType.id, params)
}

View File

@ -26,40 +26,51 @@ Page {
}
}
Pane {
Rectangle {
id: infoPane
visible: batteryState !== null || (connectedState !== null && connectedState.value === false)
height: visible ? implicitHeight : 0
height: visible ? contentRow.implicitHeight : 0
anchors { left: parent.left; top: parent.top; right: parent.right }
property var batteryState: deviceClass.interfaces.indexOf("battery") >= 0 ? device.states.getState(deviceClass.stateTypes.findByName("batteryLevel").id) : null
property var batteryCriticalState: deviceClass.interfaces.indexOf("battery") >= 0 ? device.states.getState(deviceClass.stateTypes.findByName("batteryCritical").id) : null
// property var connectedState: deviceClass.interfaces.indexOf("connectable") >= 0 ? device.states.getState(deviceClass.stateTypes.findByName("connected").id) : null
property var connectedState: deviceClass.interfaces.indexOf("connectable") >= 0 ? device.states.getState(deviceClass.stateTypes.findByName("connected").id) : null
property bool alertState: (connectedState !== null && connectedState.value === false) ||
(batteryCriticalState !== null && batteryCriticalState.value === true)
color: alertState ? "red" : "transparent"
z: 1000
RowLayout {
anchors { left: parent.left; top: parent.top; right: parent.right }
id: contentRow
anchors { left: parent.left; top: parent.top; right: parent.right; leftMargin: app.margins; rightMargin: app.margins }
Item {
Layout.fillWidth: true
height: app.iconSize
}
Label {
text: qsTr("Thing is not connected!")
visible: infoPane.connectedState !== null && infoPane.connectedState.value === false
text: (infoPane.connectedState !== null && infoPane.connectedState.value === false) ?
qsTr("Thing is not connected!")
: qsTr("Thing runs out of battery!")
visible: infoPane.alertState
font.pixelSize: app.smallFont
color: "white"
}
ColorIcon {
height: app.iconSize
height: app.iconSize / 2
width: height
visible: infoPane.connectedState !== null && infoPane.connectedState.value === false
color: "red"
color: "white"
name: "../images/dialog-warning-symbolic.svg"
}
ColorIcon {
height: app.iconSize
height: app.iconSize / 2
width: height * 1.23
name: infoPane.batteryState !== null ? "../images/battery/battery-" + ("00" + (Math.floor(infoPane.batteryState.value / 10) * 10)).slice(-3) + ".svg" : ""
visible: infoPane.batteryState !== null
color: infoPane.alertState ? "white" : keyColor
}
}
}
@ -68,5 +79,6 @@ Page {
id: contentItem
anchors.fill: parent
anchors.topMargin: infoPane.height
clip: true
}
}

View File

@ -67,6 +67,18 @@ Page {
}
}
ColorIcon {
Layout.fillHeight: true
Layout.preferredWidth: height
name: "../images/info.svg"
MouseArea {
anchors.fill: parent
onClicked: pageStack.push(Qt.resolvedUrl("StateLogPage.qml"),
{device: root.device, stateType: stateType})
}
}
Binding {
target: placeHolder.item
when: placeHolder.item

View File

@ -0,0 +1,33 @@
import QtQuick 2.5
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.1
import Mea 1.0
import "../components"
import "../customviews"
GenericDevicePage {
id: root
GenericTypeLogView {
anchors.fill: parent
text: qsTr("This event has appeared %1 times in the last 24 hours.")
onAddRuleClicked: {
var rule = Engine.ruleManager.createNewRule();
var eventDescriptor = rule.eventDescriptors.createNewEventDescriptor();
eventDescriptor.deviceId = device.id;
var eventType = root.deviceClass.eventTypes.findByName("triggered");
eventDescriptor.eventTypeId = eventType.id;
rule.name = root.device.name + " - " + eventType.displayName;
if (eventType.paramTypes.count === 1) {
var paramType = eventType.paramTypes.get(0);
eventDescriptor.paramDescriptors.setParamDescriptor(paramType.id, value, ParamDescriptor.ValueOperatorEquals);
rule.eventDescriptors.addEventDescriptor(eventDescriptor);
rule.name = rule.name + " - " + value
}
var rulePage = pageStack.push(Qt.resolvedUrl("../magic/DeviceRulesPage.qml"), {device: root.device});
rulePage.addRule(rule);
}
}
}

View File

@ -0,0 +1,40 @@
import QtQuick 2.5
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.1
import Mea 1.0
import "../components"
import "../customviews"
Page {
id: root
property var device: null
property var stateType: null
header: GuhHeader {
text: qsTr("History")
onBackPressed: pageStack.pop()
}
GenericTypeLogView {
anchors.fill: parent
device: root.device
typeId: root.stateType.id
text: qsTr("%1, %2 has changed %3 times in the last 24h").arg(device.name).arg(stateType.displayName)
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;
rule.name = root.device.name + " - " + stateType.displayName + " = " + value;
var rulePage = pageStack.push(Qt.resolvedUrl("../magic/DeviceRulesPage.qml"), {device: root.device});
rulePage.addRule(rule);
}
}
}

View File

@ -0,0 +1,183 @@
<?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.91+devel r"
viewBox="0 0 96 96.000001"
sodipodi:docname="clock-app-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="5.6199992"
inkscape:cx="6.6636952"
inkscape:cy="20.738415"
inkscape:document-units="px"
inkscape:current-layer="g4780"
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:grid
type="xygrid"
id="grid5451"
empspacing="8" />
<sodipodi:guide
orientation="1,0"
position="8,-8.0000001"
id="guide4063" />
<sodipodi:guide
orientation="1,0"
position="4,-8.0000001"
id="guide4065" />
<sodipodi:guide
orientation="0,1"
position="-8,88.000001"
id="guide4067" />
<sodipodi:guide
orientation="0,1"
position="-8,92.000001"
id="guide4069" />
<sodipodi:guide
orientation="0,1"
position="104,4"
id="guide4071" />
<sodipodi:guide
orientation="0,1"
position="-5,8.0000001"
id="guide4073" />
<sodipodi:guide
orientation="1,0"
position="88,-8.0000001"
id="guide4077" />
<sodipodi:guide
orientation="0,1"
position="-8,84.000001"
id="guide4074" />
<sodipodi:guide
orientation="1,0"
position="12,-8.0000001"
id="guide4076" />
<sodipodi:guide
orientation="1,0"
position="84,-8.0000001"
id="guide4080" />
<sodipodi:guide
position="48,-8.0000001"
orientation="1,0"
id="guide4170" />
<sodipodi:guide
position="-8,48"
orientation="0,1"
id="guide4172" />
<sodipodi:guide
position="92,-8.0000001"
orientation="1,0"
id="guide4760" />
</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)">
<g
transform="matrix(0,-1,-1,0,373.50506,516.50504)"
id="g4845"
style="display:inline">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="next01.png"
transform="matrix(-0.9996045,0,0,1,575.94296,-611.00001)"
id="g4778"
inkscape:label="Layer 1">
<g
transform="matrix(-1,0,0,1,575.99999,611)"
id="g4780"
style="display:inline">
<rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"
id="rect4782"
width="96.037987"
height="96"
x="-438.00244"
y="345.36221"
transform="scale(-1,1)" />
<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;direction:ltr;block-progression:tb;writing-mode:lr-tb;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:4.00079107;stroke-linecap:round;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 432,393.36133 c 0,23.17282 -18.83492,42 -42.01562,42 -23.18071,0 -42.01563,-18.82718 -42.01563,-42 0,-23.17282 18.83492,-42 42.01563,-42 23.1807,0 42.01562,18.82718 42.01562,42 z m -4,0 c 0,-21.00978 -16.99625,-38 -38.01562,-38 -21.01938,0 -38.01563,16.99022 -38.01563,38 0,21.00978 16.99625,38 38.01563,38 21.01937,0 38.01562,-16.99022 38.01562,-38 z"
id="path4116"
inkscape:connector-curvature="0" />
<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;direction:ltr;block-progression:tb;writing-mode:lr-tb;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:4.00079107;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 391.71484,392.36133 -3.46289,2.00195 10.21875,17.69141 3.46289,-2 -10.21875,-17.69336 z"
id="path4219"
inkscape:connector-curvature="0" />
<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;direction:ltr;block-progression:tb;writing-mode:lr-tb;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:4.00079107;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 404.04492,365.01953 -15.79297,27.3418 3.46289,2.00195 15.79297,-27.34375 -3.46289,-2 z"
id="path4231"
inkscape:connector-curvature="0" />
<ellipse
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.00078917;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path4221"
cx="-393.36221"
cy="-389.98346"
rx="4.9999971"
ry="5.0019755"
transform="matrix(0,-1,-1,0,0,0)" />
<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;direction:ltr;block-progression:tb;writing-mode:lr-tb;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:2.0113318;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 362.39453,392.35742 0,2.00977 35.5918,0 0,-2.00977 -35.5918,0 z"
id="path4223"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,168 @@
<?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.91+devel r"
viewBox="0 0 96 96.000001"
sodipodi:docname="mail-mark-important.svg">
<defs
id="defs4876" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8774396"
inkscape:cx="-0.88621718"
inkscape:cy="69.228167"
inkscape:document-units="px"
inkscape:current-layer="g4780"
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="8" />
<sodipodi:guide
orientation="1,0"
position="8,-8.0000001"
id="guide4063" />
<sodipodi:guide
orientation="1,0"
position="4,-8.0000001"
id="guide4065" />
<sodipodi:guide
orientation="0,1"
position="-8,88.000001"
id="guide4067" />
<sodipodi:guide
orientation="0,1"
position="-8,92.000001"
id="guide4069" />
<sodipodi:guide
orientation="0,1"
position="104,4"
id="guide4071" />
<sodipodi:guide
orientation="0,1"
position="-5,8.0000001"
id="guide4073" />
<sodipodi:guide
orientation="1,0"
position="92,-8.0000001"
id="guide4075" />
<sodipodi:guide
orientation="1,0"
position="88,-8.0000001"
id="guide4077" />
<sodipodi:guide
orientation="0,1"
position="-8,84.000001"
id="guide4074" />
<sodipodi:guide
orientation="1,0"
position="12,-8.0000001"
id="guide4076" />
<sodipodi:guide
orientation="0,1"
position="-5,12"
id="guide4078" />
<sodipodi:guide
orientation="1,0"
position="84,-9.0000001"
id="guide4080" />
<sodipodi:guide
position="48,-8.0000001"
orientation="1,0"
id="guide4170" />
<sodipodi:guide
position="-8,48"
orientation="0,1"
id="guide4172" />
</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)">
<g
transform="matrix(0,-1,-1,0,373.50506,516.50504)"
id="g4845"
style="display:inline">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="next01.png"
transform="matrix(-0.9996045,0,0,1,575.94296,-611.00001)"
id="g4778"
inkscape:label="Layer 1">
<g
transform="matrix(-1,0,0,1,575.99999,611)"
id="g4780"
style="display:inline">
<rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"
id="rect4782"
width="96.037987"
height="96"
x="-438.00244"
y="345.36221"
transform="scale(-1,1)" />
<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;direction:ltr;block-progression:tb;writing-mode:lr-tb;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:4.00079107;stroke-linecap:round;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 432,393.36133 c 0,23.17268 -18.83506,42 -42.01562,42 -23.18057,0 -42.01758,-18.82732 -42.01758,-42 0,-23.17268 18.83701,-42 42.01758,-42 23.18056,0 42.01562,18.82732 42.01562,42 z m -4.00195,0 c 0,-21.00964 -16.99444,-37.99805 -38.01367,-37.99805 -21.01924,0 -38.01563,16.98841 -38.01563,37.99805 0,21.00963 16.99639,38 38.01563,38 21.01923,0 38.01367,-16.99037 38.01367,-38 z"
id="path4116"
inkscape:connector-curvature="0" />
<path
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;display:inline;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1.00019777"
d="m 410.99171,396.36133 h -10.92425 c -3.21031,0 -6.18293,-0.0933 -8.92345,-0.2793 -2.70138,-0.18602 -5.42285,-0.43607 -8.16338,-0.74609 v -3.99805 c 2.74053,-0.27903 5.462,-0.51126 8.16338,-0.69726 2.70138,-0.18602 5.67399,-0.2793 8.92345,-0.2793 h 10.92425 z m -34.01346,-3 c 0,1.10006 -0.38681,2.04956 -1.15866,2.84961 -0.73829,0.76673 -1.69183,1.15039 -2.86637,1.15039 -1.17456,0 -2.13199,-0.38366 -2.87027,-1.15039 -0.73828,-0.80005 -1.10786,-1.74955 -1.10786,-2.84961 0,-1.13341 0.36958,-2.08291 1.10786,-2.84961 0.73828,-0.76673 1.69571,-1.15039 2.87027,-1.15039 1.17454,0 2.12808,0.38366 2.86637,1.15039 0.77185,0.7667 1.15866,1.7162 1.15866,2.84961 z"
id="path4942"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.1 KiB

173
mea/ui/images/send.svg Normal file
View File

@ -0,0 +1,173 @@
<?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.91+devel r"
viewBox="0 0 96 96.000001"
sodipodi:docname="send.svg">
<defs
id="defs4876">
<inkscape:path-effect
effect="powerstroke"
id="path-effect4213"
is_visible="true"
offset_points="0,2.8284271"
sort_points="true"
interpolator_type="CubicBezierJohan"
interpolator_beta="0.2"
start_linecap_type="zerowidth"
linejoin_type="extrp_arc"
miter_limit="4"
end_linecap_type="zerowidth"
cusp_linecap_type="round" />
<inkscape:path-effect
effect="powerstroke"
id="path-effect4205"
is_visible="true"
offset_points="1,4"
sort_points="true"
interpolator_type="CubicBezierJohan"
interpolator_beta="0.2"
start_linecap_type="zerowidth"
linejoin_type="extrp_arc"
miter_limit="4"
end_linecap_type="zerowidth"
cusp_linecap_type="round" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.5967995"
inkscape:cx="73.412477"
inkscape:cy="42.593387"
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:grid
type="xygrid"
id="grid5451"
empspacing="8" />
<sodipodi:guide
orientation="1,0"
position="8,-8.0000001"
id="guide4063" />
<sodipodi:guide
orientation="1,0"
position="4,-8.0000001"
id="guide4065" />
<sodipodi:guide
orientation="0,1"
position="-8,88.000001"
id="guide4067" />
<sodipodi:guide
orientation="0,1"
position="-8,92.000001"
id="guide4069" />
<sodipodi:guide
orientation="0,1"
position="104,4"
id="guide4071" />
<sodipodi:guide
orientation="0,1"
position="-5,8.0000001"
id="guide4073" />
<sodipodi:guide
orientation="1,0"
position="88,-8.0000001"
id="guide4077" />
<sodipodi:guide
orientation="0,1"
position="-8,84.000001"
id="guide4074" />
<sodipodi:guide
orientation="1,0"
position="12,-8.0000001"
id="guide4076" />
<sodipodi:guide
orientation="1,0"
position="84,-8.0000001"
id="guide4080" />
<sodipodi:guide
position="48,-8.0000001"
orientation="1,0"
id="guide4170" />
<sodipodi:guide
position="-8,48"
orientation="0,1"
id="guide4172" />
<sodipodi:guide
position="92,-8.0000001"
orientation="1,0"
id="guide4760" />
</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.142857"
x="78.505051"
height="96"
width="96"
id="rect4782"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;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:3;marker:none;enable-background:accumulate"
d="M 91.871094 4 C 45.62034 19.587542 4.0175781 41.701172 4.0175781 41.701172 L 37.521484 58.443359 L 54.273438 91.935547 L 54.306641 91.96875 L 54.337891 92 C 54.337891 92 77.534478 48.179866 91.982422 4.0195312 C 91.977522 4.0147312 91.970441 4.009845 91.957031 4.015625 C 91.951431 4.010025 91.938278 4.0132188 91.929688 4.0117188 C 91.924087 4.0061187 91.904717 4.0117245 91.898438 4.0078125 C 91.893538 4.0030125 91.876184 4.0051 91.871094 4 z M 85.462891 10.537109 C 74.674218 41.379954 60.733202 70.471839 54.359375 83.162109 L 40.503906 55.458984 L 12.880859 41.658203 C 25.443504 35.353803 53.797835 21.81196 85.462891 10.537109 z "
transform="translate(-67.857146,78.50504)"
id="path4193" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:8;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 -29.857146,136.50504 c 0,0 2,2 2,2 7.8,-7.8 29.2,-33.2 37,-41 -7.8,7.8 -33.2,29.2 -41,37 0,0 2,2 2,2 z"
id="path4211" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -20,17 +20,22 @@ Page {
}
}
function addRule() {
// pageStack.push(Qt.resolvedUrl("NewThingMagicPage.qml"), {device: root.device, text: "Add magic"})
var rule = Engine.ruleManager.createNewRule();
// Rule is optional and might be initialized with anything wanted. A new, empty one will be created if null
function addRule(rule) {
if (rule === null || rule === undefined) {
rule = Engine.ruleManager.createNewRule();
}
var page = pageStack.push(Qt.resolvedUrl("EditRulePage.qml"), {rule: rule});
var eventDescriptor = rule.eventDescriptors.createNewEventDescriptor();
eventDescriptor.deviceId = device.id;
page.selectEventDescriptorData(eventDescriptor);
page.onAccept.connect(function() {
Engine.ruleManager.addRule(page.rule);
})
// if (rule.eventDescriptors.count === 0) {
// var eventDescriptor = rule.eventDescriptors.createNewEventDescriptor();
// eventDescriptor.deviceId = device.id;
// page.selectEventDescriptorData(eventDescriptor);
// }
}
Connections {

View File

@ -8,8 +8,8 @@ import Mea 1.0
ApplicationWindow {
id: app
visible: true
width: 270 * 1.5
height: 480 * 1.5
width: 360
height: 580
visibility: settings.viewMode
font: Qt.application.font
@ -112,8 +112,10 @@ ApplicationWindow {
onClosing: {
if (Qt.platform.os == "android") {
close.accepted = false;
if (pageStack.depth > 1) pageStack.pop();
if (pageStack.depth > 1) {
close.accepted = false;
pageStack.pop();
}
}
}
@ -152,6 +154,10 @@ ApplicationWindow {
return "Temperature";
case "humiditysensor":
return "Humidity";
case "inputtrigger":
return "Incoming Events";
case "outputtrigger":
return "Events";
}
}
@ -195,6 +201,10 @@ ApplicationWindow {
return Qt.resolvedUrl("images/notification.svg")
case "connectable":
return Qt.resolvedUrl("images/stock_link.svg")
case "inputtrigger":
return Qt.resolvedUrl("images/mail-mark-important.svg")
case "outputtrigger":
return Qt.resolvedUrl("images/send.svg")
}
return "";
}